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