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