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.
This commit is contained in:
parent
d6ea496960
commit
d7785060fb
3 changed files with 64 additions and 39 deletions
|
@ -9,8 +9,6 @@ enum {
|
||||||
UINTN MK;
|
UINTN MK;
|
||||||
EFI_HANDLE IH;
|
EFI_HANDLE IH;
|
||||||
EFI_SYSTEM_TABLE *ST;
|
EFI_SYSTEM_TABLE *ST;
|
||||||
|
|
||||||
EFI_GRAPHICS_OUTPUT_PROTOCOL *gop;
|
|
||||||
EFI_FILE_PROTOCOL *root;
|
EFI_FILE_PROTOCOL *root;
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -45,12 +43,6 @@ unload(void)
|
||||||
eficall(2, ST->BootServices->ExitBootServices, IH, MK);
|
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
|
void
|
||||||
fsinit(void)
|
fsinit(void)
|
||||||
{
|
{
|
||||||
|
@ -58,7 +50,8 @@ fsinit(void)
|
||||||
|
|
||||||
fs = nil;
|
fs = nil;
|
||||||
root = 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;
|
return;
|
||||||
if(eficall(2, fs->OpenVolume, fs, &root)){
|
if(eficall(2, fs->OpenVolume, fs, &root)){
|
||||||
root = nil;
|
root = nil;
|
||||||
|
@ -227,47 +220,72 @@ lowbit(ulong mask)
|
||||||
static void
|
static void
|
||||||
screenconf(char **cfg)
|
screenconf(char **cfg)
|
||||||
{
|
{
|
||||||
|
EFI_GRAPHICS_OUTPUT_PROTOCOL *gop;
|
||||||
|
EFI_HANDLE *Handles;
|
||||||
|
UINTN Count;
|
||||||
|
|
||||||
EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *info;
|
EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *info;
|
||||||
ulong mr, mg, mb, mx, mc;
|
ulong mr, mg, mb, mx, mc;
|
||||||
int bits, depth;
|
int i, bits, depth;
|
||||||
char *s;
|
char *s;
|
||||||
|
|
||||||
gop = nil;
|
Count = 0;
|
||||||
if(LocateProtocol(&EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID, nil, &gop) || gop == nil)
|
Handles = nil;
|
||||||
|
if(eficall(5, ST->BootServices->LocateHandleBuffer,
|
||||||
|
ByProtocol, &EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID, nil, &Count, &Handles))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if((info = gop->Mode->Info) == nil)
|
for(i=0; i<Count; i++){
|
||||||
return;
|
gop = nil;
|
||||||
|
if(eficall(3, ST->BootServices->HandleProtocol,
|
||||||
|
Handles[i], &EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID, &gop))
|
||||||
|
continue;
|
||||||
|
|
||||||
switch(info->PixelFormat){
|
if(gop == nil)
|
||||||
default:
|
continue;
|
||||||
return; /* unsupported */
|
if((info = gop->Mode->Info) == nil)
|
||||||
|
continue;
|
||||||
|
|
||||||
case PixelRedGreenBlueReserved8BitPerColor:
|
switch(info->PixelFormat){
|
||||||
mr = 0x000000ff;
|
default:
|
||||||
mg = 0x0000ff00;
|
continue; /* unsupported */
|
||||||
mb = 0x00ff0000;
|
|
||||||
mx = 0xff000000;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PixelBlueGreenRedReserved8BitPerColor:
|
case PixelRedGreenBlueReserved8BitPerColor:
|
||||||
mb = 0x000000ff;
|
mr = 0x000000ff;
|
||||||
mg = 0x0000ff00;
|
mg = 0x0000ff00;
|
||||||
mr = 0x00ff0000;
|
mb = 0x00ff0000;
|
||||||
mx = 0xff000000;
|
mx = 0xff000000;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PixelBitMask:
|
case PixelBlueGreenRedReserved8BitPerColor:
|
||||||
mr = info->PixelInformation.RedMask;
|
mb = 0x000000ff;
|
||||||
mg = info->PixelInformation.GreenMask;
|
mg = 0x0000ff00;
|
||||||
mb = info->PixelInformation.BlueMask;
|
mr = 0x00ff0000;
|
||||||
mx = info->PixelInformation.ReservedMask;
|
mx = 0xff000000;
|
||||||
break;
|
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;
|
||||||
|
|
||||||
if((depth = topbit(mr | mg | mb | mx)) == 0)
|
Found:
|
||||||
return;
|
|
||||||
|
|
||||||
s = *cfg;
|
s = *cfg;
|
||||||
memmove(s, "*bootscreen=", 12), s += 12;
|
memmove(s, "*bootscreen=", 12), s += 12;
|
||||||
s = decfmt(s, 0, info->PixelsPerScanLine), *s++ = 'x';
|
s = decfmt(s, 0, info->PixelsPerScanLine), *s++ = 'x';
|
||||||
|
@ -297,7 +315,7 @@ screenconf(char **cfg)
|
||||||
*s++ = ' ';
|
*s++ = ' ';
|
||||||
|
|
||||||
*s++ = '0', *s++ = 'x';
|
*s++ = '0', *s++ = 'x';
|
||||||
s = hexfmt(s, 0, gop->Mode->FrameBufferBase), *s++ = '\n';
|
s = hexfmt(s, 16, gop->Mode->FrameBufferBase), *s++ = '\n';
|
||||||
*s = '\0';
|
*s = '\0';
|
||||||
|
|
||||||
print(*cfg);
|
print(*cfg);
|
||||||
|
|
|
@ -10,6 +10,12 @@ typedef uintptr UINTN;
|
||||||
typedef void* EFI_HANDLE;
|
typedef void* EFI_HANDLE;
|
||||||
typedef UINT32 EFI_STATUS;
|
typedef UINT32 EFI_STATUS;
|
||||||
|
|
||||||
|
enum {
|
||||||
|
AllHandles,
|
||||||
|
ByRegisterNotify,
|
||||||
|
ByProtocol,
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
UINT32 Data1;
|
UINT32 Data1;
|
||||||
UINT16 Data2;
|
UINT16 Data2;
|
||||||
|
|
|
@ -367,6 +367,7 @@ bootkern(void *f)
|
||||||
memset(d, 0, t - d);
|
memset(d, 0, t - d);
|
||||||
|
|
||||||
close(f);
|
close(f);
|
||||||
|
print("boot\n");
|
||||||
unload();
|
unload();
|
||||||
|
|
||||||
jump(e);
|
jump(e);
|
||||||
|
|
Loading…
Reference in a new issue