diff --git a/src/boot/uefi.asm b/src/boot/uefi.asm index 6817592..cf5ba8d 100644 --- a/src/boot/uefi.asm +++ b/src/boot/uefi.asm @@ -11,9 +11,6 @@ ; dd if=PAYLOAD of=BOOTX64.EFI bs=4096 seek=1 conv=notrunc > /dev/null 2>&1 ; ============================================================================= -; Set the desired screen resolution values below -Horizontal_Resolution equ 1024 -Vertical_Resolution equ 768 BITS 64 ORG 0x00400000 @@ -158,6 +155,65 @@ nextentry: lodsq ; Load the address of the ACPI table mov [ACPI], rax ; Save the address + ; Find the interface to EFI_EDID_ACTIVE_PROTOCOL_GUID via its GUID + mov rcx, EFI_EDID_ACTIVE_PROTOCOL_GUID ; IN EFI_GUID *Protocol + mov rdx, 0 ; IN VOID *Registration OPTIONAL + mov r8, EDID ; OUT VOID **Interface + mov rax, [BS] + mov rax, [rax + EFI_BOOT_SERVICES_LOCATEPROTOCOL] + call rax + cmp rax, EFI_SUCCESS + je get_EDID ; If it exists, process EDID + + ; Find the interface to EFI_EDID_DISCOVERED_PROTOCOL_GUID via its GUID + mov rcx, EFI_EDID_DISCOVERED_PROTOCOL_GUID ; IN EFI_GUID *Protocol + mov rdx, 0 ; IN VOID *Registration OPTIONAL + mov r8, EDID ; OUT VOID **Interface + mov rax, [BS] + mov rax, [rax + EFI_BOOT_SERVICES_LOCATEPROTOCOL] + call rax + cmp rax, EFI_SUCCESS + je get_EDID ; If it exists, process EDID + jmp use_GOP ; If not found, or other error, use GOP + + ; Gather preferred screen resolution +get_EDID: + ; Parse the EDID information + ; 0 UINT32 - SizeOfEdid + ; 4 UINT8 - *Edid + mov rax, [EDID] + mov ebx, [rax] + cmp ebx, 128 ; Minimum size of 128 bytes + jb use_GOP ; Fail out to GOP with default resolution + mov rbx, [rax+8] ; Pointer to EDID. Why not +4? + mov rax, [rbx] ; Load RAX with EDID header + mov rcx, 0x00FFFFFFFFFFFF00 ; Required EDID header + cmp rax, rcx ; Verify 8-byte header at 0x00 is 0x00FFFFFFFFFFFF00 + jne use_GOP ; Fail out to GOP with default resolution + ; Preferred Timing Mode starts at 0x36 + ; 0x38 - Lower 8 bits of Horizontal pixels in bits 7:0 + ; 0x3A - Upper 4 bits of Horizontal pixels in bits 7:4 + ; 0x3B - Lower 8 bits of Vertical pixels in bits 7:0 + ; 0x3D - Upper 4 bits of Vertical pixels in bits 7:4 + xor eax, eax + xor ecx, ecx + mov al, [rbx+0x38] + mov cl, [rbx+0x3A] + and cl, 0xF0 ; Keep bits 7:4 + shl ecx, 4 + or eax, ecx + mov [Horizontal_Resolution], eax + xor eax, eax + xor ecx, ecx + mov al, [rbx+0x3B] + mov cl, [rbx+0x3D] + and cl, 0xF0 ; Keep bits 7:4 + shl ecx, 4 + or eax, ecx + mov [Vertical_Resolution], eax + + ; Set video to desired resolution. By default it is 1024x768 unless EDID was found +use_GOP: ; Find the interface to GRAPHICS_OUTPUT_PROTOCOL via its GUID mov rcx, EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID ; IN EFI_GUID *Protocol mov rdx, 0 ; IN VOID *Registration OPTIONAL @@ -203,10 +259,10 @@ vid_query: mov rsi, [vid_info] lodsd ; UINT32 - Version lodsd ; UINT32 - HorizontalResolution - cmp eax, Horizontal_Resolution + cmp eax, [Horizontal_Resolution] jne next_video_mode lodsd ; UINT32 - VerticalResolution - cmp eax, Vertical_Resolution + cmp eax, [Vertical_Resolution] jne next_video_mode lodsd ; EFI_GRAPHICS_PIXEL_FORMAT - PixelFormat (UINT32) bt eax, 0 ; Bit 0 is set for 32-bit colour mode @@ -339,6 +395,8 @@ get_memmap: stosq ; EFI_MEMORY_DESCRIPTOR version mov rax, [ACPI] stosq ; ACPI Table Address + mov rax, [EDID] + stosq ; EDID Data (Size and Address) ; Set screen to black before jumping to Pure64 mov rdi, [FB] @@ -436,6 +494,7 @@ CONFIG: dq 0 ; Config Table address ACPI: dq 0 ; ACPI table address OUTPUT: dq 0 ; Output services VIDEO: dq 0 ; Video services +EDID: dq 0 FB: dq 0 ; Frame buffer base address FBS: dq 0 ; Frame buffer size HR: dq 0 ; Horizontal Resolution @@ -452,12 +511,24 @@ vid_index: dq 0 vid_max: dq 0 vid_size: dq 0 vid_info: dq 0 +Horizontal_Resolution: dd 1024 ; Default resolution X - If no EDID found +Vertical_Resolution: dd 768 ; Default resolution Y - If no EDID found ACPI_TABLE_GUID: dd 0xeb9d2d30 dw 0x2d88, 0x11d3 db 0x9a, 0x16, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d +EFI_EDID_ACTIVE_PROTOCOL_GUID: +dd 0xbd8c1056 +dw 0x9f36, 0x44ec +db 0x92, 0xa8, 0xa6, 0x33, 0x7f, 0x81, 0x79, 0x86 + +EFI_EDID_DISCOVERED_PROTOCOL_GUID: +dd 0x1c0c34f6 +dw 0xd380, 0x41fa +db 0xa0, 0x49, 0x8a, 0xd0, 0x6c, 0x1a, 0x66, 0xaa + EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID: dd 0x9042a9de dw 0x23dc, 0x4a38