diff options
author | cinap_lenrek <cinap_lenrek@felloff.net> | 2014-10-19 19:55:45 +0200 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@felloff.net> | 2014-10-19 19:55:45 +0200 |
commit | d7785060fb66c9c4fc19475668bd861fb6462941 (patch) | |
tree | 10d6634296660d04715eca5534716bc4eb6af89b | |
parent | d6ea4969607d9d6b33ae5a40a947f8a2aa2c0845 (diff) | |
download | plan9front-d7785060fb66c9c4fc19475668bd861fb6462941.tar.xz |
efi: use LocateHandle() and HandleProtocol() to check for multiple gop protocols to find a usable one
the gop returned by LocateProtocol() is not usable on thinkpad x230,
so iterate over all handles to find a usable one.
-rw-r--r-- | sys/src/boot/efi/efi.c | 102 | ||||
-rw-r--r-- | sys/src/boot/efi/efi.h | 6 | ||||
-rw-r--r-- | sys/src/boot/efi/sub.c | 1 |
3 files changed, 67 insertions, 42 deletions
diff --git a/sys/src/boot/efi/efi.c b/sys/src/boot/efi/efi.c index 8ace417d8..a16260d6f 100644 --- a/sys/src/boot/efi/efi.c +++ b/sys/src/boot/efi/efi.c @@ -9,8 +9,6 @@ enum { UINTN MK; EFI_HANDLE IH; EFI_SYSTEM_TABLE *ST; - -EFI_GRAPHICS_OUTPUT_PROTOCOL *gop; EFI_FILE_PROTOCOL *root; void @@ -45,12 +43,6 @@ unload(void) eficall(2, ST->BootServices->ExitBootServices, IH, MK); } -EFI_STATUS -LocateProtocol(EFI_GUID *guid, void *reg, void **pif) -{ - return eficall(3, ST->BootServices->LocateProtocol, guid, reg, pif); -} - void fsinit(void) { @@ -58,7 +50,8 @@ fsinit(void) fs = nil; root = nil; - if(LocateProtocol(&EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID, nil, &fs)) + if(eficall(3, ST->BootServices->LocateProtocol, + &EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID, nil, &fs)) return; if(eficall(2, fs->OpenVolume, fs, &root)){ root = nil; @@ -227,47 +220,72 @@ lowbit(ulong mask) static void screenconf(char **cfg) { + EFI_GRAPHICS_OUTPUT_PROTOCOL *gop; + EFI_HANDLE *Handles; + UINTN Count; + EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *info; ulong mr, mg, mb, mx, mc; - int bits, depth; + int i, bits, depth; char *s; - gop = nil; - if(LocateProtocol(&EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID, nil, &gop) || gop == nil) + Count = 0; + Handles = nil; + if(eficall(5, ST->BootServices->LocateHandleBuffer, + ByProtocol, &EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID, nil, &Count, &Handles)) return; - if((info = gop->Mode->Info) == nil) - return; + for(i=0; i<Count; i++){ + gop = nil; + if(eficall(3, ST->BootServices->HandleProtocol, + Handles[i], &EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID, &gop)) + continue; - switch(info->PixelFormat){ - default: - return; /* unsupported */ - - case PixelRedGreenBlueReserved8BitPerColor: - mr = 0x000000ff; - mg = 0x0000ff00; - mb = 0x00ff0000; - mx = 0xff000000; - break; - - case PixelBlueGreenRedReserved8BitPerColor: - mb = 0x000000ff; - mg = 0x0000ff00; - mr = 0x00ff0000; - mx = 0xff000000; - break; - - case PixelBitMask: - mr = info->PixelInformation.RedMask; - mg = info->PixelInformation.GreenMask; - mb = info->PixelInformation.BlueMask; - mx = info->PixelInformation.ReservedMask; - break; - } + if(gop == nil) + continue; + if((info = gop->Mode->Info) == nil) + continue; - if((depth = topbit(mr | mg | mb | mx)) == 0) - return; + switch(info->PixelFormat){ + default: + continue; /* unsupported */ + + case PixelRedGreenBlueReserved8BitPerColor: + mr = 0x000000ff; + mg = 0x0000ff00; + mb = 0x00ff0000; + mx = 0xff000000; + break; + + case PixelBlueGreenRedReserved8BitPerColor: + mb = 0x000000ff; + mg = 0x0000ff00; + mr = 0x00ff0000; + mx = 0xff000000; + break; + + case PixelBitMask: + mr = info->PixelInformation.RedMask; + mg = info->PixelInformation.GreenMask; + mb = info->PixelInformation.BlueMask; + mx = info->PixelInformation.ReservedMask; + break; + } + + if((depth = topbit(mr | mg | mb | mx)) == 0) + continue; + + /* make sure we have linear framebuffer */ + if(gop->Mode->FrameBufferBase == 0) + continue; + if(gop->Mode->FrameBufferSize == 0) + continue; + + goto Found; + } + return; +Found: s = *cfg; memmove(s, "*bootscreen=", 12), s += 12; s = decfmt(s, 0, info->PixelsPerScanLine), *s++ = 'x'; @@ -297,7 +315,7 @@ screenconf(char **cfg) *s++ = ' '; *s++ = '0', *s++ = 'x'; - s = hexfmt(s, 0, gop->Mode->FrameBufferBase), *s++ = '\n'; + s = hexfmt(s, 16, gop->Mode->FrameBufferBase), *s++ = '\n'; *s = '\0'; print(*cfg); diff --git a/sys/src/boot/efi/efi.h b/sys/src/boot/efi/efi.h index 545635690..142385af3 100644 --- a/sys/src/boot/efi/efi.h +++ b/sys/src/boot/efi/efi.h @@ -10,6 +10,12 @@ typedef uintptr UINTN; typedef void* EFI_HANDLE; typedef UINT32 EFI_STATUS; +enum { + AllHandles, + ByRegisterNotify, + ByProtocol, +}; + typedef struct { UINT32 Data1; UINT16 Data2; diff --git a/sys/src/boot/efi/sub.c b/sys/src/boot/efi/sub.c index 29be948b1..a7fd5d4c3 100644 --- a/sys/src/boot/efi/sub.c +++ b/sys/src/boot/efi/sub.c @@ -367,6 +367,7 @@ bootkern(void *f) memset(d, 0, t - d); close(f); + print("boot\n"); unload(); jump(e); |