]> code.delx.au - refind/blob - EfiLib/BdsHelper.c
40f44831549173f6cd2624aaf9283f64a87347fa
[refind] / EfiLib / BdsHelper.c
1 /*
2 * EfiLib/BdsHelper.c
3 * Functions to call legacy BIOS API.
4 *
5 */
6
7
8 #include "BdsHelper.h"
9 #include "legacy.h"
10 #include "../refind/screen.h"
11
12 EFI_GUID gEfiLegacyBootProtocolGuid = { 0xdb9a1e3d, 0x45cb, 0x4abb, { 0x85, 0x3b, 0xe5, 0x38, 0x7f, 0xdb, 0x2e, 0x2d }};
13
14 /**
15 Internal helper function.
16
17 Update the BBS Table so that devices of DeviceType have their boot priority
18 updated to a high/bootable value.
19
20 See "DeviceType values" in
21 http://www.intel.com/content/dam/doc/reference-guide/efi-compatibility-support-module-specification-v097.pdf
22
23 NOTE: This function should probably be refactored! Currently, all devices of
24 type are enabled. This should be updated so that only a specific device is
25 enabled. The wrong device could boot if there are multiple targets of the same
26 type.
27
28 @param DeviceType The device type that we wish to enable
29 **/
30 VOID UpdateBbsTable (BDS_COMMON_OPTION *Option) {
31 UINT16 Idx;
32 EFI_LEGACY_BIOS_PROTOCOL *LegacyBios;
33 EFI_STATUS Status;
34 UINT16 HddCount = 0;
35 HDD_INFO *HddInfo = NULL;
36 UINT16 BbsCount = 0;
37 BBS_TABLE *LocalBbsTable = NULL;
38 BBS_BBS_DEVICE_PATH *OptionBBS;
39 CHAR16 Desc[100];
40
41 Status = gBS->LocateProtocol (&gEfiLegacyBootProtocolGuid, NULL, (VOID **) &LegacyBios);
42 if (EFI_ERROR (Status) || (Option == NULL)) {
43 return;
44 }
45
46 OptionBBS = (BBS_BBS_DEVICE_PATH *) Option->DevicePath;
47 Status = LegacyBios->GetBbsInfo (LegacyBios, &HddCount, &HddInfo, &BbsCount, &LocalBbsTable);
48
49 // Print (L"\n");
50 // Print (L" NO Prio bb/dd/ff cl/sc Type Stat segm:offs\n");
51 // Print (L"=============================================\n");
52
53 for (Idx = 0; Idx < BbsCount; Idx++) {
54 if(LocalBbsTable[Idx].DeviceType == 0) {
55 continue;
56 }
57
58 BdsBuildLegacyDevNameString (&LocalBbsTable[Idx], Idx, sizeof (Desc), Desc);
59
60 // Set devices of a particular type to BootPriority of 0 or 1. 0 is the highest priority.
61 if (LocalBbsTable[Idx].DeviceType == OptionBBS->DeviceType) {
62 if (StriCmp(Desc, Option->Description) == 0) {
63 // This entry exactly matches what we're looking for; make it highest priority
64 LocalBbsTable[Idx].BootPriority = 0;
65 } else {
66 // This entry doesn't exactly match, but is the right disk type; make it a bit lower
67 // in priority. Done mainly as a fallback in case of string-matching weirdness.
68 LocalBbsTable[Idx].BootPriority = 1;
69 } // if/else
70 } // if
71
72 // Print (
73 // L" %02x: %04x %02x/%02x/%02x %02x/%02x %04x %04x %04x:%04x\n",
74 // (UINTN) Idx,
75 // (UINTN) LocalBbsTable[Idx].BootPriority,
76 // (UINTN) LocalBbsTable[Idx].Bus,
77 // (UINTN) LocalBbsTable[Idx].Device,
78 // (UINTN) LocalBbsTable[Idx].Function,
79 // (UINTN) LocalBbsTable[Idx].Class,
80 // (UINTN) LocalBbsTable[Idx].SubClass,
81 // (UINTN) LocalBbsTable[Idx].DeviceType,
82 // (UINTN) * (UINT16 *) &LocalBbsTable[Idx].StatusFlags,
83 // (UINTN) LocalBbsTable[Idx].BootHandlerSegment,
84 // (UINTN) LocalBbsTable[Idx].BootHandlerOffset,
85 // (UINTN) ((LocalBbsTable[Idx].MfgStringSegment << 4) + LocalBbsTable[Idx].MfgStringOffset),
86 // (UINTN) ((LocalBbsTable[Idx].DescStringSegment << 4) + LocalBbsTable[Idx].DescStringOffset)
87 // );
88 // Print(L"%s\n", Desc);
89
90 } // for
91 }
92
93 /**
94 Boot the legacy system with the boot option
95
96 @param Option The legacy boot option which have BBS device path
97
98 @retval EFI_UNSUPPORTED There is no legacybios protocol, do not support
99 legacy boot.
100 @retval EFI_STATUS Return the status of LegacyBios->LegacyBoot ().
101
102 **/
103 EFI_STATUS
104 BdsLibDoLegacyBoot (
105 IN BDS_COMMON_OPTION *Option
106 )
107 {
108 EFI_STATUS Status;
109 EFI_LEGACY_BIOS_PROTOCOL *LegacyBios;
110
111 Status = gBS->LocateProtocol (&gEfiLegacyBootProtocolGuid, NULL, (VOID **) &LegacyBios);
112 if (EFI_ERROR (Status)) {
113 return EFI_UNSUPPORTED;
114 }
115
116 UpdateBbsTable(Option);
117
118 return LegacyBios->LegacyBoot(LegacyBios, (BBS_BBS_DEVICE_PATH *) Option->DevicePath,
119 Option->LoadOptionsSize, Option->LoadOptions);
120 }