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