Compare commits

...

82 Commits

Author SHA1 Message Date
Jeremy Soller
a3c4616449 Fix compilation on impish 2021-09-09 11:51:27 -06:00
Bob Feng
e0e9606523 BaseTools: Fix the issue caused by tostring() removal on Py39
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3136

Python 3.9 remove the array.array.tostring and
array.array.fromstring() function. This patch
is to use other method to replace tostring() and
fromstring()

Signed-off-by: Bob Feng <bob.c.feng@intel.com>

Cc: Liming Gao <gaoliming@byosoft.com.cn>
Cc: Yuwei Chen <yuwei.chen@intel.com>
Cc: Mingyue Liang <mingyuex.liang@intel.com>
Reviewed-by: Liming Gao <gaoliming@byosoft.com.cn>
2021-05-12 11:10:32 -06:00
Cole Robinson
38519af0dc BaseTools: Work around array.array.tostring() removal in python 3.9
In python3, array.array.tostring() was a compat alias for tobytes().
tostring() was removed in python 3.9.

Convert this to use tolist() which should be valid for all python
versions.

This fixes this build error on python3.9:

(Python 3.9.0b5 on linux) Traceback (most recent call last):
  File "/root/edk2/edk2-edk2-stable202002/BaseTools/BinWrappers/PosixLike/../../Source/Python/Trim/Trim.py", line 593, in Main
    GenerateVfrBinSec(CommandOptions.ModuleName, CommandOptions.DebugDir, CommandOptions.OutputFile)
  File "/root/edk2/edk2-edk2-stable202002/BaseTools/BinWrappers/PosixLike/../../Source/Python/Trim/Trim.py", line 449, in GenerateVfrBinSec
    VfrUniOffsetList = GetVariableOffset(MapFileName, EfiFileName, VfrNameList)
  File "/root/edk2/edk2-edk2-stable202002/BaseTools/Source/Python/Common/Misc.py", line 88, in GetVariableOffset
    return _parseForGCC(lines, efifilepath, varnames)
  File "/root/edk2/edk2-edk2-stable202002/BaseTools/Source/Python/Common/Misc.py", line 151, in _parseForGCC
    efisecs = PeImageClass(efifilepath).SectionHeaderList
  File "/root/edk2/edk2-edk2-stable202002/BaseTools/Source/Python/Common/Misc.py", line 1638, in __init__
    if ByteArray.tostring() != b'PE\0\0':
AttributeError: 'array.array' object has no attribute 'tostring'

Signed-off-by: Cole Robinson <crobinso@redhat.com>
Reviewed-by: Yuwei Chen <yuwei.chen@intel.com>
Reviewed-by: Bob Feng <bob.c.feng@intel.com>
2021-05-12 11:10:32 -06:00
Cole Robinson
0ab8646c67 BaseTools: fix ucs-2 lookup on python 3.9
python3.9 changed/fixed codec.register behavior to always replace
hyphen with underscore for passed in codec names:

  https://bugs.python.org/issue37751

So the custom Ucs2Search needs to be adapted to handle 'ucs_2' in
addition to existing 'ucs-2' for back compat.

This fixes test failures on python3.9, example:

======================================================================
FAIL: testUtf16InUniFile (CheckUnicodeSourceFiles.Tests)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/builddir/build/BUILD/edk2-edk2-stable202002/BaseTools/Source/Python/AutoGen/UniClassObject.py", line 375, in PreProcess
    FileIn = UniFileClassObject.OpenUniFile(LongFilePath(File.Path))
  File "/builddir/build/BUILD/edk2-edk2-stable202002/BaseTools/Source/Python/AutoGen/UniClassObject.py", line 303, in OpenUniFile
    UniFileClassObject.VerifyUcs2Data(FileIn, FileName, Encoding)
  File "/builddir/build/BUILD/edk2-edk2-stable202002/BaseTools/Source/Python/AutoGen/UniClassObject.py", line 312, in VerifyUcs2Data
    Ucs2Info = codecs.lookup('ucs-2')
LookupError: unknown encoding: ucs-2

Signed-off-by: Cole Robinson <crobinso@redhat.com>
Reviewed-by: Yuwei Chen <yuwei.chen@intel.com>
Reviewed-by: Bob Feng <bob.c.feng@intel.com>
2021-05-12 11:10:32 -06:00
Jeremy Soller
7b5e832086 Do not store ErrOut variable 2020-12-05 15:41:18 -07:00
Tim Crawford
f81f3474b3 MdeModulePkg/UiApp: Check for CSME device on PCI bus 2020-12-03 17:38:34 -07:00
Tim Crawford
996c3c4b40 MdeModulePkg/BM: Update boot options on device change
Register an event to trigger when a block device is added or removed
that will update the list of boot options. Use a refreshguid to force
the form to display the changes if it already open.
2020-11-25 11:43:01 -07:00
Tim Crawford
386fd08814 MdeModulePkg/Core: Signal notify events on protocol removal
In order for BootManager to maintain a valid list of boot options, it
must know when the BlockIo protocol is also removed, not just added.
2020-11-25 11:43:01 -07:00
Jon Hunter
07b51d4361 MdeModulePkg/XhciDxe: Retry device slot init on failure
With some super-speed USB mass storage devices it has been observed
that a USB transaction error may occur when attempting the set the
device address during enumeration.

According the the xHCI specification (section 4.6.5) ...

"A USB Transaction ErrorCompletion Code for an Address Device Command
 may be due to a Stall response from a device. Software should issue a
 Disable Slot Commandfor the Device Slot then an Enable Slot Command
 to recover from this error."

To fix this, retry the device slot initialization if it fails due to a
device error.

Change was verified using a superspeed mass storage device that was
occasionally failing to enumerate in UEFI. With this change this failure
to enumerate was resolved. This failure was also only seen in UEFI and not
in the OS.

Signed-off-by: Jon Hunter <jonathanh@nvidia.com>
Signed-off-by: Jeff Brasen <jbrasen@nvidia.com>
Reviewed-by: Hao A Wu <hao.a.wu@intel.com>
2020-11-25 11:36:42 -07:00
Luo, Heng
ea0e6d960e MdeModulePkg/XhciDxe: Error handle for USB slot initialization failure
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3007

Currently UsbDevContext is not cleaned up if USB slot initialization is
failed, the wrong context data will affect next USB devices and
the USB devices can not be enumerated.
Need to disable slot if USB slot initialization is failed.

Below test cases are passed on UpXtreme:
a. USB 3.0 thumb drives can be recognized in UEFI shell
b. SUT can boot to Puppylinux  from USB3.0 mass storage,
 the storage can be recognized in linux
c. Plug in a USB  keyboard (hot plug) and enumeration is OK
 in UEFI shell and linux
d. Plug in a USB mouse(hot plug) and enumeration is OK in linux.

Cc: Ray Ni <ray.ni@intel.com>
Cc: Hao A Wu <hao.a.wu@intel.com>
Signed-off-by: Heng Luo <heng.luo@intel.com>
Tested-by: Jon Hunter <jonathanh@nvidia.com>
Reviewed-by: Jon Hunter <jonathanh@nvidia.com>
Reviewed-by: Hao A Wu <hao.a.wu@intel.com>
2020-11-25 11:36:42 -07:00
Tim Crawford
22744e7305 MdeModulePkg/BootManagerUiLib: Fix line endings
edk2 stores files with CRLF. This file got converted to LF.
2020-11-25 11:35:49 -07:00
Jeremy Soller
8ad6d7b14f Do not store SystemSleepCheckpoint variable 2020-11-25 11:31:48 -07:00
Patrick Rudolph
6ad3ee1be8 UefiPayloadPkg: Fix build with TPM enabled
Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com>
2020-10-19 13:34:44 -06:00
Patrick Rudolph
37ec7ab62f UefiPayloadPkg: Fix TPM1.2 detection
Check the actual TPM1.2 command response to prevent a false positive
when talking to a TPM2.0.

Tested using a ST33TPHF TPM 2.0.

Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com>
2020-10-19 13:34:44 -06:00
Patrick Rudolph
83c68bbe1d UefiCpuPkg: Disable MTRR programming for UefiPayloadPkg
The MTRRs have already been programmed by FSB.

Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com>
2020-10-19 13:34:44 -06:00
Patrick Rudolph
599f4a4ddd UefiPayloadPkg/Library/PciHostBridgeLib: Add warning for coreboot/EDK2 incompability
EDK2 expects PCI bars to be continously be allocated without "gaps" of reserverd
memory in between.
coreboot places PCI bars anyware in the PCI MMIO space, interleaved with MMCONF
and reserved I/O MMIO space.

Warn about this behaviour and refuse to add the BAR to the PCI aperature as it would
cause the PciHostBridgeDxe fo fail.

Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com>
2020-10-19 13:34:44 -06:00
Patrick Rudolph
d90d84a4f7 UefipayloadPkg: Protect coreboot tables
Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com>
2020-10-19 13:34:44 -06:00
Patrick Rudolph
876c1d36b3 UefiPayloadPkg: Make TerminalDxe build time configurable
As the TerminalDxe significantly slows down the boot menu rendering,
disable it but default and add the option SERIAL_TERMINAL to enabled
it for headless platforms.

Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com>
2020-10-19 13:34:44 -06:00
Patrick Rudolph
e88dc61df6 UefiPayloadPkg: Do not use made up UART defaults
Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com>
2020-10-19 13:34:44 -06:00
Patrick Rudolph
6a78d4f41d HACK: BmMisc: Remove S4 memory check until VariableStore is implemented
Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com>
2020-08-13 12:30:45 -06:00
Christian Walter
97394de0f7 UefiPayloadPkg: Add TPM2 Support in EDK2 2020-08-13 12:30:45 -06:00
Tim Crawford
995df206c3 UefiPayloadPkg: Stall before connecting devices
USB devices are not being detected when booting. Pause a bit for them to
be initialized and detected by EfiBootManagerConnectAll().
2020-08-07 14:43:12 -06:00
Jeremy Soller
fa0e9ec925 Use video control interface as evidence of webcam 2020-08-06 16:03:47 -06:00
Jeremy Soller
00e2cc7a69 Add darp5 camera 2020-08-06 16:03:47 -06:00
Jeremy Soller
975d5b02da Add even more matching models, add default interface info 2020-08-06 16:03:47 -06:00
Jeremy Soller
86d6b0ca91 Add more matching models 2020-08-06 16:03:47 -06:00
Jeremy Soller
74b3823b0c Add webcam disconnect test 2020-08-06 16:03:47 -06:00
Jeremy Soller
4f29b65fbe Use CPUID instead of control registers for virtualization test 2020-08-06 16:03:47 -06:00
Jeremy Soller
26279e8f9a Dynamically generated firmware configuration information page 2020-08-06 16:03:47 -06:00
Patrick Rudolph
d46c7763aa [HACK] Load OptionROMs immediately
This will make sure the ConsoleInit is able to connect the driver installed
by the VGA Option ROMs.

Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com>
2020-07-24 06:47:15 -06:00
Patrick Rudolph
46521fafea UefiPayloadPkg: Scan for Option ROMs
Install the gPciPlatformProtocol to scan for Option ROMs.

For every device we probe the Option ROM and provide a pointer
to the activated BAR if found.

It's safe to assume that all ROM bars have been enumerated,
reserved in the bridge resources and are disabled by default.

Enabling them and leaving them enabled will do no harm.

Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com>
2020-07-24 06:47:15 -06:00
Patrick Rudolph
28d4682274 MdeModulePkg: Fix OptionROM scanning
The Option ROM scanner can't work as enumeration was done by the
first stage bootloader. Running it will disable the ability of the
PCIPlatform code to scan for ROMs.

Required for the following patch that enables custom Option ROM
scanning using gPciPlatformProtocol.

Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com>
2020-07-24 06:47:15 -06:00
Tim Crawford
168bf9514f MdeModulePkg/BMM: Unregister F9 and F10 hotkeys 2020-07-21 12:42:46 -06:00
Tim Crawford
f17c7a730c MdeModulePkg/BMM: Disable Commit/Discard buttons 2020-07-21 12:42:46 -06:00
Tim Crawford
e807bc67b6 MdeModulePkg/BMM: Save BootOrder on list update 2020-07-21 12:42:46 -06:00
Tim Crawford
de23a37ab2 MdeModulePkg/BMM: Add some debug logging 2020-07-21 12:42:46 -06:00
Jeremy Soller
e30d17a0d2 Implement SerialPortLib and PlatformHookLib with System76EcLib 2020-07-02 11:15:13 -07:00
Jeremy Soller
c6f1c4e654 Use 0x7600 as FRONT_PAGE_ID to prevent conflicts with Device Manager 2020-07-02 11:15:13 -07:00
Jeremy Soller
0e66ac75c3 Merge pull request #11 from system76/skip-console-vars
MdeModulePkg/EmuRuntimeDxe: skip console NVRAM variables
2020-06-22 15:49:31 -06:00
Matt DeVillier
e10ad1c874 MdeModulePkg/EmuRuntimeDxe: skip console NVRAM variables
Tianocore currently reads/writes a lot of NVRAM variables that
don't actually need to be saved. Occasionally some, specifically
related to the graphical/serial consoles, can become corrupted,
leading to a bricked device. To avoid this, temporarily restrict
the reading/writing of variables to skip console related ones
(starting with 'Con') until a better solution can be found.

Test: build/boot google/eve, inject "bad" NVRAM data, observe
device boots normally instead of hanging with no display detected.

Signed-off-by: Matt DeVillier <matt.devillier@gmail.com>
2020-06-22 09:37:18 -06:00
Jeremy Soller
e3e4f6ddd5 Add EXT4 and NTFS drivers 2020-06-11 11:10:19 -06:00
Tim Crawford
e61bb9222c MdeModulePkg/BM: Initialize variable before use 2020-05-20 16:26:41 -06:00
Matt DeVillier
8222473c5d MdeModulePkg: load boot logo into BGRT table
This is a shoehorned-in implementation of an ACPI BGRT
table, ported pretty much directly from the version used
under CorebootPayloadPkg.

EDK2 provides a facility to do this already, but it assumes
the ACPI tables already exist as EFI structures, so would need
to write code to populate those using the tables already in RAM
created by coreboot. This seemed like the easier option ATM.

Signed-off-by: Matt DeVillier <matt.devillier@gmail.com>
2020-04-27 10:34:28 -06:00
ReddestDream
d52c0b860b BlSupportPei: prevent lower coreboot table from being overwritten
Exclude the bottom 4kb from being included in System Memory HoB
2020-04-17 14:58:30 -06:00
Tim Crawford
4984cdcb36 UefiPayloadPkg: Add library for logging to EC
Make use of the SMFI command interface to forward logs from edk2 to
System76 EC.
2020-04-17 10:45:17 -06:00
Tim Crawford
331d92a8ba UefiPayloadPkg: Add PCI support from DuetPkg
Skip PCI enumeration, which is already handled by Coreboot, by using
PciBusNoEnumerationDxe and PciRootBridgeNoEnumerationDxe from the
deleted DuetPkg.
2020-04-14 09:20:45 -06:00
Tim Crawford
5bbb149f55 UefiPayloadPkg: Reduce timeout to 2s
Current firmware does not honor PcdPlatformBootTimeOut and hard-codes a
timeout of 2s.
2020-04-13 13:01:31 -06:00
Tim Crawford
f4424abfe9 UefiPayloadPkg: Use EmuRuntimeDxe 2020-04-10 08:01:33 -06:00
Jeremy Soller
9a25338c4a MdeModulePkg/EmuRuntimeDxe: Delete SMMSTORE variable by appending it with size 0 2020-04-10 08:01:33 -06:00
Jeremy Soller
3cc1bab6db MdeModulePkg/EmuRuntimeDxe: Ignore keysizes of 0 2020-04-10 08:01:33 -06:00
Patrick Rudolph
394dfa9302 MdeModulePkg/EmuRuntimeDxe: Check SMM store return codes
Check SMM store return code and return on error.

Fixes significant boot delay in case no SMM store is present.
This can happend quite often if the tianocore payload is build standalone
and patched into a coreboot ROM.

Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com>
2020-04-10 08:01:33 -06:00
Matt DeVillier
e32cbe0cab WIP: MdeModulePkg/EmuRuntimeDxe: Sync data with coreboot SMMSTORE
changed: buffer size from 64k to 256k

Change-Id: I7f443b9f36612f79787e1b4b1075176a91107686
Signed-off-by: Patrick Georgi <pgeorgi@google.com>
Signed-off-by: Matt DeVillier <matt.devillier@gmail.com>
2020-04-10 08:01:33 -06:00
Tim Crawford
5d853c79de Revert "MdeModulePkg: Remove EmuVariableRuntimeDxe"
This reverts commit 4a7aa8d34a.
2020-04-10 08:01:33 -06:00
Tim Crawford
71ce340b44 MdeModulePkg/UefiBootManager: Remove serial number from description 2020-04-10 08:01:33 -06:00
Tim Crawford
67c4655bea MdeModulePkg/UefiBootManager: Remove 'UEFI' description prefix 2020-04-10 08:01:33 -06:00
Tim Crawford
ecaa4a790a MdeModulePkg/UefiBootManager: Skip non-EFI devices 2020-04-10 08:01:33 -06:00
Tim Crawford
40b9ce83bf MdeModulePkg/UiApp: Add warning if no bootable options found 2020-04-10 08:01:33 -06:00
Tim Crawford
b1bed529dc MdeModulePkg/BM: Add warning if no bootable options found 2020-04-10 08:01:33 -06:00
Tim Crawford
f189c6191b MdeModulePkg/BdsDxe: Forward any key for booting
Pressing escape will bring a user to the boot manager. Pressing any
other key will continue booting, forwarding the key to systemd-boot.
2020-04-10 08:01:33 -06:00
Tim Crawford
4249b8eb5b MdeModulePkg: Wait for input on each boot failure 2020-04-10 08:01:33 -06:00
Tim Crawford
e458f432b6 UefiPayloadPkg: Clear screen on boot error 2020-04-10 08:01:33 -06:00
Tim Crawford
65bb2a9982 UefiPayloadPkg: Copy PlatformBootManagerUnableToBoot() from OvmfPkg 2020-04-10 08:01:33 -06:00
Tim Crawford
f0b1403f40 MdeModulePkg/BootMaintenanceManagerUiLib: Make it look like current BMM 2020-04-10 08:01:33 -06:00
Tim Crawford
98633064c4 MdeModulePkg/UiApp: Fix reporting model/version
Use the SMBIOS table directly instead of the EFI SMBIOS protocol.
2020-04-10 08:01:33 -06:00
Tim Crawford
65d7e5bfaa MdeModulePkg/UiApp: Make it look like current FrontPage 2020-04-10 08:01:33 -06:00
Tim Crawford
9773fdd270 MdeModulePkg/BootManagerUiLib: Make it look like current BootMngr 2020-04-10 08:01:33 -06:00
Tim Crawford
f017dd1e1a MdeModulePkg/BootLogoLib: Center logo 38.2% from top of screen
Use Microsoft's recommended positioning [1] for the boot logo.

> We recommend that the logo is placed with its center at 38.2% from the
> screen's top edge. This positioning is based on the golden ratio's
> visual aesthetics and matches the Windows 10 design proportions.

[1]: https://docs.microsoft.com/en-us/windows-hardware/drivers/bringup/boot-screen-components#position-the-logo-during-post
2020-04-10 08:01:33 -06:00
Tim Crawford
2c57af8da4 MdeModulePkg/Logo: Use System76 boot logo 2020-04-10 08:01:33 -06:00
Tim Crawford
e3754a7631 UefiPayloadPkg: Show boot message as progress text 2020-04-10 08:01:33 -06:00
Tim Crawford
d04e564e95 UefiPayloadPkg: Enable boot logo 2020-04-10 08:01:33 -06:00
Tim Crawford
dc0e568d10 UefiPayloadPkg: Disable Device Manager 2020-04-10 08:01:33 -06:00
Tim Crawford
bff3319ae5 UefiPayloadPkg: Disable EFI shell 2020-04-10 08:01:33 -06:00
Tim Crawford
68e4fc4a10 UefiPayloadPkg: Map ESC to boot manager 2020-04-10 08:01:33 -06:00
Tim Crawford
b3d4910fbd UefiPayloadPkg: Enable NVMe support 2020-04-10 08:01:33 -06:00
Jeremy Soller
cc4f44d4e7 UefiPayloadPkg: Load firmware-smmstore driver 2020-04-10 08:01:33 -06:00
Jeremy Soller
e106197ec2 MdeModulePkg/PartitionDxe: Prioritize UDF/ElTorito over MBR partitions
Fixes ISO boots.
2020-04-10 08:01:33 -06:00
Jeremy Soller
df3e6a4032 UefiCpuPkg: Ignore DEBUG interrupt (happens on gaze14) 2020-04-10 08:01:33 -06:00
Jeremy Soller
1bd847bd22 UefiPayloadPkg: Update serial port to use 2020-04-10 08:01:33 -06:00
Jeremy Soller
a258434cd8 UefiPayloadPkg: Add Intel GOP driver 2020-04-10 08:01:33 -06:00
Jeremy Soller
b99c14feb4 UefiPayloadPkg: Add System76 Setup menu 2020-04-10 08:01:33 -06:00
Tim Crawford
84d9737f71 UefiPayloadPkg: Enable PS2 keyboard 2020-04-10 08:01:33 -06:00
Tim Crawford
cf97530eea UefiPayloadPkg: Default to coreboot 2020-04-10 08:01:33 -06:00
107 changed files with 18585 additions and 935 deletions

View File

@@ -1942,8 +1942,8 @@ static uint32_t BrotliMaxDistanceSymbol(uint32_t ndirect, uint32_t npostfix) {
}
BrotliDecoderResult BrotliDecoderDecompress(
size_t encoded_size, const uint8_t* encoded_buffer, size_t* decoded_size,
uint8_t* decoded_buffer) {
size_t encoded_size, const uint8_t encoded_buffer[BROTLI_ARRAY_PARAM(encoded_size)], size_t* decoded_size,
uint8_t decoded_buffer[BROTLI_ARRAY_PARAM(*decoded_size)]) {
BrotliDecoderState s;
BrotliDecoderResult result;
size_t total_out = 0;

View File

@@ -1432,8 +1432,8 @@ static size_t MakeUncompressedStream(
BROTLI_BOOL BrotliEncoderCompress(
int quality, int lgwin, BrotliEncoderMode mode, size_t input_size,
const uint8_t* input_buffer, size_t* encoded_size,
uint8_t* encoded_buffer) {
const uint8_t input_buffer[BROTLI_ARRAY_PARAM(input_size)], size_t* encoded_size,
uint8_t encoded_buffer[BROTLI_ARRAY_PARAM(*encoded_size)]) {
BrotliEncoderState* s;
size_t out_size = *encoded_size;
const uint8_t* input_start = input_buffer;

View File

@@ -152,7 +152,7 @@ class Ucs2Codec(codecs.Codec):
TheUcs2Codec = Ucs2Codec()
def Ucs2Search(name):
if name == 'ucs-2':
if name in ['ucs-2', 'ucs_2']:
return codecs.CodecInfo(
name=name,
encode=TheUcs2Codec.encode,

View File

@@ -1635,7 +1635,7 @@ class PeImageClass():
ByteArray = array.array('B')
ByteArray.fromfile(PeObject, 4)
# PE signature should be 'PE\0\0'
if ByteArray.tostring() != b'PE\0\0':
if ByteArray.tolist() != [ord('P'), ord('E'), 0, 0]:
self.ErrorInfo = self.FileName + ' has no valid PE signature PE00'
return

View File

@@ -27,10 +27,11 @@ from Common.TargetTxtClassObject import TargetTxtDict
from Common.ToolDefClassObject import ToolDefDict
from AutoGen.BuildEngine import ToolBuildRule
import Common.DataType as DataType
from Common.Misc import PathClass
from Common.Misc import PathClass,CreateDirectory
from Common.LongFilePathSupport import OpenLongFilePath as open
from Common.MultipleWorkspace import MultipleWorkspace as mws
import Common.GlobalData as GlobalData
from Common.BuildToolError import *
## Global variables
#
@@ -463,12 +464,28 @@ class GenFdsGlobalVariable:
GenFdsGlobalVariable.SecCmdList.append(' '.join(Cmd).strip())
else:
SectionData = array('B', [0, 0, 0, 0])
SectionData.fromstring(Ui.encode("utf_16_le"))
SectionData.fromlist(array('B',Ui.encode('utf-16-le')).tolist())
SectionData.append(0)
SectionData.append(0)
Len = len(SectionData)
GenFdsGlobalVariable.SectionHeader.pack_into(SectionData, 0, Len & 0xff, (Len >> 8) & 0xff, (Len >> 16) & 0xff, 0x15)
SaveFileOnChange(Output, SectionData.tostring())
DirName = os.path.dirname(Output)
if not CreateDirectory(DirName):
EdkLogger.error(None, FILE_CREATE_FAILURE, "Could not create directory %s" % DirName)
else:
if DirName == '':
DirName = os.getcwd()
if not os.access(DirName, os.W_OK):
EdkLogger.error(None, PERMISSION_FAILURE, "Do not have write permission on directory %s" % DirName)
try:
with open(Output, "wb") as Fd:
SectionData.tofile(Fd)
Fd.flush()
except IOError as X:
EdkLogger.error(None, FILE_CREATE_FAILURE, ExtraData='IOError %s' % X)
elif Ver:
Cmd += ("-n", Ver)

BIN
FSDrivers/X64/ext4.efi Normal file

Binary file not shown.

BIN
FSDrivers/X64/ntfs.efi Normal file

Binary file not shown.

22
FSDrivers/ext4.inf Normal file
View File

@@ -0,0 +1,22 @@
#
##
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = ext4
FILE_GUID = 9d380387-a15a-4053-ae19-ff3495b6d0d5
MODULE_TYPE = UEFI_DRIVER
VERSION_STRING = 1.0
#
# The following information is for reference only and not required by the build tools.
#
# VALID_ARCHITECTURES = IA32 X64 IPF EBC
#
VALID_ARCHITECTURES = X64
[Binaries.X64]
PE32|X64/ext4.efi|*

22
FSDrivers/ntfs.inf Normal file
View File

@@ -0,0 +1,22 @@
#
##
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = ntfs
FILE_GUID = 2282efd0-678b-4753-8d06-200d5940285d
MODULE_TYPE = UEFI_DRIVER
VERSION_STRING = 1.0
#
# The following information is for reference only and not required by the build tools.
#
# VALID_ARCHITECTURES = IA32 X64 IPF EBC
#
VALID_ARCHITECTURES = X64
[Binaries.X64]
PE32|X64/ntfs.efi|*

View File

@@ -7,6 +7,14 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include <IndustryStandard/Pci.h>
#include <Protocol/PciIo.h>
#include <Protocol/PciRootBridgeIo.h>
#include <Protocol/UsbIo.h>
#include <Register/Amd/Cpuid.h>
#include <Register/Intel/Cpuid.h>
#include <Register/Intel/Msr.h>
#include "FrontPage.h"
#include "FrontPageCustomizedUi.h"
@@ -17,7 +25,6 @@ EFI_GUID mFrontPageGuid = FRONT_PAGE_FORMSET_GUID;
BOOLEAN mResetRequired = FALSE;
EFI_FORM_BROWSER2_PROTOCOL *gFormBrowser2;
CHAR8 *mLanguageString;
BOOLEAN mModeInitialized = FALSE;
//
// Boot video resolution and text mode.
@@ -34,11 +41,12 @@ UINT32 mSetupTextModeRow = 0;
UINT32 mSetupHorizontalResolution = 0;
UINT32 mSetupVerticalResolution = 0;
EFI_SYSTEM_TABLE * gSystemTable = NULL;
FRONT_PAGE_CALLBACK_DATA gFrontPagePrivate = {
FRONT_PAGE_CALLBACK_DATA_SIGNATURE,
NULL,
NULL,
NULL,
{
FakeExtractConfig,
FakeRouteConfig,
@@ -72,11 +80,11 @@ HII_VENDOR_DEVICE_PATH mFrontPageHiiVendorDevicePath = {
};
/**
Update the banner information for the Front Page based on Smbios information.
Update the information for the Front Page based on Smbios information.
**/
VOID
UpdateFrontPageBannerStrings (
UpdateFrontPageStrings (
VOID
);
@@ -211,7 +219,7 @@ UpdateFrontPageForm (
//
StartGuidLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
StartGuidLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
StartGuidLabel->Number = LABEL_FRANTPAGE_INFORMATION;
StartGuidLabel->Number = LABEL_FRONTPAGE_INFORMATION;
//
// Create Hii Extend Label OpCode as the end opcode
//
@@ -288,9 +296,9 @@ InitializeFrontPage (
ASSERT (gFrontPagePrivate.HiiHandle != NULL);
//
//Updata Front Page banner strings
//Updata Front Page strings
//
UpdateFrontPageBannerStrings ();
UpdateFrontPageStrings ();
//
// Update front page menus.
@@ -367,10 +375,6 @@ FreeFrontPage(
// Publish our HII data
//
HiiRemovePackages (gFrontPagePrivate.HiiHandle);
if (gFrontPagePrivate.LanguageToken != NULL) {
FreePool (gFrontPagePrivate.LanguageToken);
gFrontPagePrivate.LanguageToken = NULL;
}
}
/**
@@ -493,164 +497,536 @@ GetOptionalStringByIndex (
}
UINT16 SmbiosTableLength (SMBIOS_STRUCTURE_POINTER SmbiosTableN)
{
CHAR8 *AChar;
UINT16 Length;
AChar = (CHAR8 *)(SmbiosTableN.Raw + SmbiosTableN.Hdr->Length);
while ((*AChar != 0) || (*(AChar + 1) != 0)) {
AChar ++; //stop at 00 - first 0
}
Length = (UINT16)((UINTN)AChar - (UINTN)SmbiosTableN.Raw + 2); //length includes 00
return Length;
}
SMBIOS_STRUCTURE_POINTER GetSmbiosTableFromType (
SMBIOS_TABLE_ENTRY_POINT *SmbiosPoint, UINT8 SmbiosType, UINTN IndexTable)
{
SMBIOS_STRUCTURE_POINTER SmbiosTableN;
UINTN SmbiosTypeIndex;
SmbiosTypeIndex = 0;
SmbiosTableN.Raw = (UINT8 *)((UINTN)SmbiosPoint->TableAddress);
if (SmbiosTableN.Raw == NULL) {
return SmbiosTableN;
}
while ((SmbiosTypeIndex != IndexTable) || (SmbiosTableN.Hdr->Type != SmbiosType)) {
if (SmbiosTableN.Hdr->Type == SMBIOS_TYPE_END_OF_TABLE) {
SmbiosTableN.Raw = NULL;
return SmbiosTableN;
}
if (SmbiosTableN.Hdr->Type == SmbiosType) {
SmbiosTypeIndex++;
}
SmbiosTableN.Raw = (UINT8 *)(SmbiosTableN.Raw + SmbiosTableLength (SmbiosTableN));
}
return SmbiosTableN;
}
STATIC
VOID
WarnNoBootableMedia (
VOID
)
{
CHAR16 *String;
EFI_STRING_ID Token;
EFI_BOOT_MANAGER_LOAD_OPTION *BootOption;
UINTN BootOptionCount;
UINTN Index;
UINTN Count = 0;
String = AllocateZeroPool (0x60);
BootOption = EfiBootManagerGetLoadOptions (&BootOptionCount, LoadOptionTypeBoot);
for (Index = 0; Index < BootOptionCount; Index++) {
//
// Don't count the hidden/inactive boot option
//
if (((BootOption[Index].Attributes & LOAD_OPTION_HIDDEN) != 0) || ((BootOption[Index].Attributes & LOAD_OPTION_ACTIVE) == 0)) {
continue;
}
Count++;
}
EfiBootManagerFreeLoadOptions (BootOption, BootOptionCount);
if (Count == 0) {
StrCatS (String, 0x60 / sizeof (CHAR16), L"Warning: No bootable media found");
} else {
StrCatS (String, 0x60 / sizeof (CHAR16), L"");
}
Token = STRING_TOKEN (STR_NO_BOOTABLE_MEDIA);
HiiSetString (gFrontPagePrivate.HiiHandle, Token, String, NULL);
FreePool(String);
}
BOOLEAN
StandardSignatureIsAuthenticAMD (
VOID
)
{
UINT32 RegEbx;
UINT32 RegEcx;
UINT32 RegEdx;
AsmCpuid (CPUID_SIGNATURE, NULL, &RegEbx, &RegEcx, &RegEdx);
return (RegEbx == CPUID_SIGNATURE_AUTHENTIC_AMD_EBX &&
RegEcx == CPUID_SIGNATURE_AUTHENTIC_AMD_ECX &&
RegEdx == CPUID_SIGNATURE_AUTHENTIC_AMD_EDX);
}
BOOLEAN
StandardSignatureIsGenuineIntel (
VOID
)
{
UINT32 RegEbx;
UINT32 RegEcx;
UINT32 RegEdx;
AsmCpuid (CPUID_SIGNATURE, NULL, &RegEbx, &RegEcx, &RegEdx);
return (RegEbx == CPUID_SIGNATURE_GENUINE_INTEL_EBX &&
RegEcx == CPUID_SIGNATURE_GENUINE_INTEL_ECX &&
RegEdx == CPUID_SIGNATURE_GENUINE_INTEL_EDX);
}
typedef struct {
CHAR8 Signature[8];
UINT8 Checksum;
CHAR8 OemId[6];
UINT8 Revision;
UINT32 RsdtAddress;
} ACPI_RSDP;
CHAR8 RSDP_SIGNATURE[8] = {'R', 'S', 'D', ' ', 'P', 'T', 'R', ' '};
typedef struct {
CHAR8 Signature[4];
UINT32 Length;
UINT8 Revision;
UINT8 Checksum;
CHAR8 OemId[6];
CHAR8 OemTableId[8];
UINT32 OemRevision;
UINT32 CreatorId;
UINT32 CreatorRevision;
} ACPI_SDT_HEADER;
CHAR8 RSDT_SIGNATURE[4] = {'R', 'S', 'D', 'T'};
STATIC ACPI_SDT_HEADER* FindAcpiTable(CHAR8 Name[4]) {
UINTN Index;
EFI_CONFIGURATION_TABLE* ConfigurationTable;
UINTN RsdpPtr;
ACPI_RSDP* Rsdp;
UINTN RsdtPtr;
ACPI_SDT_HEADER* Rsdt;
UINTN TablePtr;
ACPI_SDT_HEADER* Table;
DEBUG ((EFI_D_INFO, "FindAcpiTable: '%c%c%c%c'\n",
Name[0],
Name[1],
Name[2],
Name[3]
));
if (gSystemTable == NULL) {
DEBUG ((EFI_D_INFO, " System Table missing\n"));
return NULL;
}
// Search the table for an entry that matches the ACPI Table Guid
for (Index = 0; Index < gSystemTable->NumberOfTableEntries; Index++) {
if (CompareGuid (&gEfiAcpiTableGuid, &(gSystemTable->ConfigurationTable[Index].VendorGuid))) {
ConfigurationTable = &gSystemTable->ConfigurationTable[Index];
break;
}
}
if (ConfigurationTable == NULL) {
DEBUG ((EFI_D_INFO, " ACPI Configuration Table missing\n"));
return NULL;
}
RsdpPtr = (UINTN)ConfigurationTable->VendorTable;
DEBUG ((EFI_D_INFO, " RSDP 0x%x\n", RsdpPtr));
Rsdp = (ACPI_RSDP*)RsdpPtr;
DEBUG ((EFI_D_INFO, " Signature: '%c%c%c%c%c%c%c%c'\n",
Rsdp->Signature[0],
Rsdp->Signature[1],
Rsdp->Signature[2],
Rsdp->Signature[3],
Rsdp->Signature[4],
Rsdp->Signature[5],
Rsdp->Signature[6],
Rsdp->Signature[7]
));
if (CompareMem(Rsdp->Signature, RSDP_SIGNATURE, 8) != 0) {
DEBUG ((EFI_D_INFO, " RSDP invalid signature\n"));
return NULL;
}
DEBUG ((EFI_D_INFO, " Revision: 0x%x\n", Rsdp->Revision));
RsdtPtr = (UINTN)Rsdp->RsdtAddress;
DEBUG ((EFI_D_INFO, " RSDT 0x%x\n", RsdpPtr));
Rsdt = (ACPI_SDT_HEADER*)RsdtPtr;
DEBUG ((EFI_D_INFO, " Signature: '%c%c%c%c'\n",
Rsdt->Signature[0],
Rsdt->Signature[1],
Rsdt->Signature[2],
Rsdt->Signature[3]
));
if (CompareMem(Rsdt->Signature, RSDT_SIGNATURE, 4) != 0) {
DEBUG ((EFI_D_INFO, " RSDT invalid signature\n"));
return NULL;
}
DEBUG ((EFI_D_INFO, " Revision: 0x%x\n", Rsdt->Revision));
DEBUG ((EFI_D_INFO, " Length: 0x%x\n", Rsdt->Length));
for (Index = sizeof(ACPI_SDT_HEADER); Index < Rsdt->Length; Index += 4) {
TablePtr = (UINTN)(*(UINT32*)(RsdtPtr + Index));
DEBUG ((EFI_D_INFO, " Table %d: 0x%x\n", Index, TablePtr));
Table = (ACPI_SDT_HEADER*)TablePtr;
DEBUG ((EFI_D_INFO, " Signature: '%c%c%c%c'\n",
Table->Signature[0],
Table->Signature[1],
Table->Signature[2],
Table->Signature[3]
));
DEBUG ((EFI_D_INFO, " Revision: 0x%x\n", Table->Revision));
DEBUG ((EFI_D_INFO, " Length: 0x%x\n", Table->Length));
if (CompareMem(Table->Signature, Name, 4) == 0) {
DEBUG ((EFI_D_INFO, " Match found\n"));
return Table;
}
}
DEBUG ((EFI_D_INFO, " No match found\n"));
return NULL;
}
// From PciBusDxe
STATIC
EFI_STATUS
PciDevicePresent(
OUT PCI_TYPE00 *Pci,
IN UINT8 Bus,
IN UINT8 Device,
IN UINT8 Func
)
{
UINT64 Address = EFI_PCI_ADDRESS(Bus, Device, Func, 0);
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;
EFI_STATUS Status;
EFI_HANDLE *PciIoBuffer;
UINTN PciIoHandleCount = 0;
Status = gBS->LocateHandleBuffer(
ByProtocol,
&gEfiPciRootBridgeIoProtocolGuid,
NULL,
&PciIoHandleCount,
&PciIoBuffer
);
if (EFI_ERROR(Status)) {
DEBUG((EFI_D_INFO, "%a: Failed to get PciRootBridgeIo handles: %r\n", __FUNCTION__, Status));
return Status;
}
for (UINTN Index = 0; Index < PciIoHandleCount; Index++) {
Status = gBS->OpenProtocol(
PciIoBuffer[Index],
&gEfiPciRootBridgeIoProtocolGuid,
(VOID *)&PciRootBridgeIo,
NULL,
NULL,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
if (EFI_ERROR(Status)) {
DEBUG((EFI_D_INFO, "%a: Failed to open PciRootBridgeIo protocol: %r\n", __FUNCTION__, Status));
continue;
}
// Read the Vendor ID register
Status = PciRootBridgeIo->Pci.Read(
PciRootBridgeIo,
EfiPciWidthUint32,
Address,
1,
Pci
);
if (EFI_ERROR(Status)) {
DEBUG((EFI_D_INFO, "%a: Failed to read vendor ID: %r\n", __FUNCTION__, Status));
continue;
}
// Read the entire config header for the device
Status = PciRootBridgeIo->Pci.Read(
PciRootBridgeIo,
EfiPciWidthUint32,
Address,
sizeof(PCI_TYPE00) / sizeof(UINT32),
Pci
);
FreePool(PciIoBuffer);
return Status;
}
FreePool(PciIoBuffer);
return EFI_NOT_FOUND;
}
/*
* Check for Intel device with class [0780] at 00:16.0.
*/
STATIC
BOOLEAN
HasCsmeDevice(VOID)
{
PCI_TYPE00 Pci;
if (!EFI_ERROR(PciDevicePresent(&Pci, 0x00, 0x16, 0x00))) {
DEBUG((EFI_D_INFO, "%a: vid=0x%04X, class=[%02X,%02X,%02X]\n", __FUNCTION__,
Pci.Hdr.VendorId, Pci.Hdr.ClassCode[0], Pci.Hdr.ClassCode[1], Pci.Hdr.ClassCode[2]));
return Pci.Hdr.VendorId == 0x8086 &&
Pci.Hdr.ClassCode[2] == PCI_CLASS_SCC &&
Pci.Hdr.ClassCode[1] == PCI_SUBCLASS_SCC_OTHER;
}
return FALSE;
}
STATIC VOID FirmwareConfigurationInformation(VOID) {
EFI_STRING_ID Token;
Token = STRING_TOKEN (STR_VIRTUALIZATION);
if (StandardSignatureIsGenuineIntel()) {
HiiSetString (gFrontPagePrivate.HiiHandle, Token, L"Intel Virtualization", NULL);
Token = STRING_TOKEN (STR_VIRTUALIZATION_STATUS);
CPUID_VERSION_INFO_ECX VersionInfoEcx;
AsmCpuid (CPUID_VERSION_INFO, NULL, NULL, &VersionInfoEcx.Uint32, NULL);
if (VersionInfoEcx.Bits.VMX) {
HiiSetString (gFrontPagePrivate.HiiHandle, Token, L"VT-x: Active", NULL);
} else {
HiiSetString (gFrontPagePrivate.HiiHandle, Token, L"VT-x: Deactivated", NULL);
}
Token = STRING_TOKEN (STR_IOMMU_STATUS);
CHAR8 TableName[4] = {'D', 'M', 'A', 'R'};
if (FindAcpiTable(TableName)) {
HiiSetString (gFrontPagePrivate.HiiHandle, Token, L"VT-d: Active", NULL);
} else {
HiiSetString (gFrontPagePrivate.HiiHandle, Token, L"VT-d: Deactivated", NULL);
}
Token = STRING_TOKEN(STR_ME_STATUS);
if (HasCsmeDevice()) {
HiiSetString (gFrontPagePrivate.HiiHandle, Token, L"The Intel Management Engine is enabled.", NULL);
} else {
HiiSetString (gFrontPagePrivate.HiiHandle, Token, L"The Intel Management Engine is disabled at runtime to increase security.", NULL);
}
} else if (StandardSignatureIsAuthenticAMD()) {
//TODO: verify AMD tests
HiiSetString (gFrontPagePrivate.HiiHandle, Token, L"AMD Virtualization", NULL);
Token = STRING_TOKEN (STR_VIRTUALIZATION_STATUS);
CPUID_AMD_EXTENDED_CPU_SIG_ECX AmdExtendedCpuSigEcx;
AsmCpuid (CPUID_EXTENDED_CPU_SIG, NULL, NULL, &AmdExtendedCpuSigEcx.Uint32, NULL);
if (AmdExtendedCpuSigEcx.Bits.SVM) {
HiiSetString (gFrontPagePrivate.HiiHandle, Token, L"AMD-V: Active", NULL);
} else {
HiiSetString (gFrontPagePrivate.HiiHandle, Token, L"AMD-V: Deactivated", NULL);
}
Token = STRING_TOKEN (STR_IOMMU_STATUS);
//TODO: proper test for AMD IOMMU
BOOLEAN iommu_active = FALSE;
if (iommu_active) {
HiiSetString (gFrontPagePrivate.HiiHandle, Token, L"AMD-Vi: Active", NULL);
} else {
HiiSetString (gFrontPagePrivate.HiiHandle, Token, L"AMD-Vi: Deactivated", NULL);
}
}
Token = STRING_TOKEN (STR_TPM_STATUS);
CHAR8 TableName[4] = {'T', 'P', 'M', '2'};
if (FindAcpiTable(TableName)) {
HiiSetString (gFrontPagePrivate.HiiHandle, Token, L"Trusted Platform Module: Active", NULL);
} else {
HiiSetString (gFrontPagePrivate.HiiHandle, Token, L"Trusted Platform Module: Deactivated", NULL);
}
}
VOID WebcamStatus(VOID) {
EFI_STATUS Status;
UINTN UsbIoHandleCount;
EFI_HANDLE *UsbIoBuffer;
UINTN Index;
EFI_USB_IO_PROTOCOL *UsbIo;
EFI_USB_DEVICE_DESCRIPTOR DevDesc;
EFI_USB_INTERFACE_DESCRIPTOR IntfDesc;
UINTN Webcams;
EFI_STRING_ID Token;
//
// Get all Usb IO handles in system
//
UsbIoHandleCount = 0;
Status = gBS->LocateHandleBuffer (ByProtocol, &gEfiUsbIoProtocolGuid, NULL, &UsbIoHandleCount, &UsbIoBuffer);
if (EFI_ERROR(Status)) {
DEBUG ((EFI_D_INFO, "Failed to read UsbIo handles: 0x%x\n", Status));
return;
}
Webcams = 0;
for (Index = 0; Index < UsbIoHandleCount; Index++) {
DEBUG ((EFI_D_INFO, "UsbIo Handle %d\n", Index));
//
// Get the child Usb IO interface
//
Status = gBS->HandleProtocol(
UsbIoBuffer[Index],
&gEfiUsbIoProtocolGuid,
(VOID **) &UsbIo
);
if (EFI_ERROR (Status)) {
DEBUG ((EFI_D_INFO, " Failed to find UsbIo protocol\n"));
continue;
}
Status = UsbIo->UsbGetDeviceDescriptor (UsbIo, &DevDesc);
if (EFI_ERROR (Status)) {
DEBUG ((EFI_D_INFO, " Failed to get device descriptor\n"));
continue;
}
DEBUG ((EFI_D_INFO, " ID: 0x%04X:0x%04X\n", DevDesc.IdVendor, DevDesc.IdProduct));
DEBUG ((EFI_D_INFO, " DeviceClass: %d\n", DevDesc.DeviceClass));
DEBUG ((EFI_D_INFO, " DeviceSubClass: %d\n", DevDesc.DeviceSubClass));
DEBUG ((EFI_D_INFO, " DeviceProtocol: %d\n", DevDesc.DeviceProtocol));
Status = UsbIo->UsbGetInterfaceDescriptor (UsbIo, &IntfDesc);
if (EFI_ERROR (Status)) {
DEBUG ((EFI_D_INFO, " Failed to get interface descriptor\n"));
continue;
}
DEBUG ((EFI_D_INFO, " Interface: %d\n", IntfDesc.InterfaceNumber));
DEBUG ((EFI_D_INFO, " InterfaceClass: %d\n", IntfDesc.InterfaceClass));
DEBUG ((EFI_D_INFO, " InterfaceSubClass: %d\n", IntfDesc.InterfaceSubClass));
DEBUG ((EFI_D_INFO, " InterfaceProtocol: %d\n", IntfDesc.InterfaceProtocol));
if (IntfDesc.InterfaceClass == 14 && IntfDesc.InterfaceSubClass == 1) {
DEBUG ((EFI_D_INFO, " Detected Video Control interface\n"));
Webcams++;
}
}
FreePool (UsbIoBuffer);
//TODO: logic for not showing the warning on desktops
Token = STRING_TOKEN (STR_WEBCAM_STATUS);
if (Webcams == 0) {
HiiSetString (gFrontPagePrivate.HiiHandle, Token, L"Info: Webcam Module Disconnected", NULL);
}
}
/**
Update the banner information for the Front Page based on Smbios information.
Update the information for the Front Page based on Smbios information.
**/
VOID
UpdateFrontPageBannerStrings (
UpdateFrontPageStrings (
VOID
)
{
UINT8 StrIndex;
UINT8 Str2Index;
CHAR16 *NewString;
CHAR16 *FirmwareVersionString;
CHAR16 *NewString2;
CHAR16 *NewString3;
EFI_STATUS Status;
EFI_SMBIOS_HANDLE SmbiosHandle;
EFI_SMBIOS_PROTOCOL *Smbios;
SMBIOS_TABLE_TYPE0 *Type0Record;
SMBIOS_TABLE_TYPE1 *Type1Record;
SMBIOS_TABLE_TYPE4 *Type4Record;
SMBIOS_TABLE_TYPE19 *Type19Record;
EFI_SMBIOS_TABLE_HEADER *Record;
UINT64 InstalledMemory;
BOOLEAN FoundCpu;
EFI_STRING_ID TokenToUpdate;
EFI_PHYSICAL_ADDRESS *Table;
SMBIOS_TABLE_ENTRY_POINT *EntryPoint;
SMBIOS_STRUCTURE_POINTER SmbiosTable;
InstalledMemory = 0;
FoundCpu = 0;
FirmwareConfigurationInformation();
WarnNoBootableMedia ();
WebcamStatus();
//
// Update default banner string.
//
NewString = HiiGetString (gFrontPagePrivate.HiiHandle, STRING_TOKEN (STR_CUSTOMIZE_BANNER_LINE4_LEFT), NULL);
UiCustomizeFrontPageBanner (4, TRUE, &NewString);
HiiSetString (gFrontPagePrivate.HiiHandle, STRING_TOKEN (STR_CUSTOMIZE_BANNER_LINE4_LEFT), NewString, NULL);
FreePool (NewString);
NewString = HiiGetString (gFrontPagePrivate.HiiHandle, STRING_TOKEN (STR_CUSTOMIZE_BANNER_LINE4_RIGHT), NULL);
UiCustomizeFrontPageBanner (4, FALSE, &NewString);
HiiSetString (gFrontPagePrivate.HiiHandle, STRING_TOKEN (STR_CUSTOMIZE_BANNER_LINE4_RIGHT), NewString, NULL);
FreePool (NewString);
NewString = HiiGetString (gFrontPagePrivate.HiiHandle, STRING_TOKEN (STR_CUSTOMIZE_BANNER_LINE5_LEFT), NULL);
UiCustomizeFrontPageBanner (5, TRUE, &NewString);
HiiSetString (gFrontPagePrivate.HiiHandle, STRING_TOKEN (STR_CUSTOMIZE_BANNER_LINE5_LEFT), NewString, NULL);
FreePool (NewString);
NewString = HiiGetString (gFrontPagePrivate.HiiHandle, STRING_TOKEN (STR_CUSTOMIZE_BANNER_LINE5_RIGHT), NULL);
UiCustomizeFrontPageBanner (5, FALSE, &NewString);
HiiSetString (gFrontPagePrivate.HiiHandle, STRING_TOKEN (STR_CUSTOMIZE_BANNER_LINE5_RIGHT), NewString, NULL);
FreePool (NewString);
//
// Update Front Page banner strings base on SmBios Table.
//
Status = gBS->LocateProtocol (&gEfiSmbiosProtocolGuid, NULL, (VOID **) &Smbios);
if (EFI_ERROR (Status)) {
//
// Smbios protocol not found, get the default value.
//
NewString = HiiGetString (gFrontPagePrivate.HiiHandle, STRING_TOKEN (STR_FRONT_PAGE_COMPUTER_MODEL), NULL);
UiCustomizeFrontPageBanner (1, TRUE, &NewString);
HiiSetString (gFrontPagePrivate.HiiHandle, STRING_TOKEN (STR_FRONT_PAGE_COMPUTER_MODEL), NewString, NULL);
FreePool (NewString);
NewString = HiiGetString (gFrontPagePrivate.HiiHandle, STRING_TOKEN (STR_FRONT_PAGE_CPU_MODEL), NULL);
UiCustomizeFrontPageBanner (2, TRUE, &NewString);
HiiSetString (gFrontPagePrivate.HiiHandle, STRING_TOKEN (STR_FRONT_PAGE_CPU_MODEL), NewString, NULL);
FreePool (NewString);
NewString = HiiGetString (gFrontPagePrivate.HiiHandle, STRING_TOKEN (STR_FRONT_PAGE_CPU_SPEED), NULL);
UiCustomizeFrontPageBanner (2, FALSE, &NewString);
HiiSetString (gFrontPagePrivate.HiiHandle, STRING_TOKEN (STR_FRONT_PAGE_CPU_SPEED), NewString, NULL);
FreePool (NewString);
NewString = HiiGetString (gFrontPagePrivate.HiiHandle, STRING_TOKEN (STR_FRONT_PAGE_BIOS_VERSION), NULL);
UiCustomizeFrontPageBanner (3, TRUE, &NewString);
HiiSetString (gFrontPagePrivate.HiiHandle, STRING_TOKEN (STR_FRONT_PAGE_BIOS_VERSION), NewString, NULL);
FreePool (NewString);
NewString = HiiGetString (gFrontPagePrivate.HiiHandle, STRING_TOKEN (STR_FRONT_PAGE_MEMORY_SIZE), NULL);
UiCustomizeFrontPageBanner (3, FALSE, &NewString);
HiiSetString (gFrontPagePrivate.HiiHandle, STRING_TOKEN (STR_FRONT_PAGE_MEMORY_SIZE), NewString, NULL);
FreePool (NewString);
return;
Status = EfiGetSystemConfigurationTable (&gEfiSmbiosTableGuid, (VOID **) &Table);
if (EFI_ERROR (Status) || Table == NULL) {
return;
}
SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
Status = Smbios->GetNext (Smbios, &SmbiosHandle, NULL, &Record, NULL);
while (!EFI_ERROR(Status)) {
if (Record->Type == SMBIOS_TYPE_BIOS_INFORMATION) {
Type0Record = (SMBIOS_TABLE_TYPE0 *) Record;
StrIndex = Type0Record->BiosVersion;
GetOptionalStringByIndex ((CHAR8*)((UINT8*)Type0Record + Type0Record->Hdr.Length), StrIndex, &NewString);
EntryPoint = (SMBIOS_TABLE_ENTRY_POINT*)Table;
FirmwareVersionString = (CHAR16 *) PcdGetPtr (PcdFirmwareVersionString);
if (*FirmwareVersionString != 0x0000 ) {
FreePool (NewString);
NewString = (CHAR16 *) PcdGetPtr (PcdFirmwareVersionString);
UiCustomizeFrontPageBanner (3, TRUE, &NewString);
HiiSetString (gFrontPagePrivate.HiiHandle, STRING_TOKEN (STR_FRONT_PAGE_BIOS_VERSION), NewString, NULL);
} else {
UiCustomizeFrontPageBanner (3, TRUE, &NewString);
HiiSetString (gFrontPagePrivate.HiiHandle, STRING_TOKEN (STR_FRONT_PAGE_BIOS_VERSION), NewString, NULL);
FreePool (NewString);
}
}
SmbiosTable = GetSmbiosTableFromType (EntryPoint, EFI_SMBIOS_TYPE_BIOS_INFORMATION , 0);
if (SmbiosTable.Raw != NULL) {
NewString2 = AllocateZeroPool (0xC0);
if (Record->Type == SMBIOS_TYPE_SYSTEM_INFORMATION) {
Type1Record = (SMBIOS_TABLE_TYPE1 *) Record;
StrIndex = Type1Record->ProductName;
GetOptionalStringByIndex ((CHAR8*)((UINT8*)Type1Record + Type1Record->Hdr.Length), StrIndex, &NewString);
UiCustomizeFrontPageBanner (1, TRUE, &NewString);
HiiSetString (gFrontPagePrivate.HiiHandle, STRING_TOKEN (STR_FRONT_PAGE_COMPUTER_MODEL), NewString, NULL);
FreePool (NewString);
}
if ((Record->Type == SMBIOS_TYPE_PROCESSOR_INFORMATION) && !FoundCpu) {
Type4Record = (SMBIOS_TABLE_TYPE4 *) Record;
//
// The information in the record should be only valid when the CPU Socket is populated.
//
if ((Type4Record->Status & SMBIOS_TYPE4_CPU_SOCKET_POPULATED) == SMBIOS_TYPE4_CPU_SOCKET_POPULATED) {
StrIndex = Type4Record->ProcessorVersion;
GetOptionalStringByIndex ((CHAR8*)((UINT8*)Type4Record + Type4Record->Hdr.Length), StrIndex, &NewString);
UiCustomizeFrontPageBanner (2, TRUE, &NewString);
HiiSetString (gFrontPagePrivate.HiiHandle, STRING_TOKEN (STR_FRONT_PAGE_CPU_MODEL), NewString, NULL);
FreePool (NewString);
ConvertProcessorToString(Type4Record->CurrentSpeed, 6, &NewString);
UiCustomizeFrontPageBanner (2, FALSE, &NewString);
HiiSetString (gFrontPagePrivate.HiiHandle, STRING_TOKEN (STR_FRONT_PAGE_CPU_SPEED), NewString, NULL);
FreePool (NewString);
FoundCpu = TRUE;
}
}
if ( Record->Type == SMBIOS_TYPE_MEMORY_ARRAY_MAPPED_ADDRESS ) {
Type19Record = (SMBIOS_TABLE_TYPE19 *) Record;
if (Type19Record->StartingAddress != 0xFFFFFFFF ) {
InstalledMemory += RShiftU64(Type19Record->EndingAddress -
Type19Record->StartingAddress + 1, 10);
} else {
InstalledMemory += RShiftU64(Type19Record->ExtendedEndingAddress -
Type19Record->ExtendedStartingAddress + 1, 20);
}
}
Status = Smbios->GetNext (Smbios, &SmbiosHandle, NULL, &Record, NULL);
StrIndex = SmbiosTable.Type0->BiosVersion;
GetOptionalStringByIndex ((CHAR8*)((UINT8*)SmbiosTable.Raw + SmbiosTable.Hdr->Length), StrIndex, &NewString);
StrCatS (NewString2, 0x80 / sizeof (CHAR16), L"Version: ");
StrCatS (NewString2, 0x80 / sizeof (CHAR16), NewString);
TokenToUpdate = STRING_TOKEN (STR_FRONT_PAGE_BIOS_VERSION);
HiiSetString (gFrontPagePrivate.HiiHandle, TokenToUpdate, NewString2, NULL);
FreePool (NewString);
FreePool (NewString2);
}
//
// Now update the total installed RAM size
//
ConvertMemorySizeToString ((UINT32)InstalledMemory, &NewString );
UiCustomizeFrontPageBanner (3, FALSE, &NewString);
HiiSetString (gFrontPagePrivate.HiiHandle, STRING_TOKEN (STR_FRONT_PAGE_MEMORY_SIZE), NewString, NULL);
FreePool (NewString);
SmbiosTable = GetSmbiosTableFromType (EntryPoint, SMBIOS_TYPE_SYSTEM_INFORMATION , 0);
if (SmbiosTable.Raw != NULL) {
NewString3 = AllocateZeroPool (0x60);
StrIndex = SmbiosTable.Type1->ProductName;
Str2Index = SmbiosTable.Type1->Manufacturer;
GetOptionalStringByIndex ((CHAR8*)((UINT8*)SmbiosTable.Raw + SmbiosTable.Hdr->Length), StrIndex, &NewString);
GetOptionalStringByIndex ((CHAR8*)((UINT8*)SmbiosTable.Raw + SmbiosTable.Hdr->Length), Str2Index, &NewString2);
StrCatS (NewString3, 0x60 / sizeof (CHAR16), NewString2);
StrCatS (NewString3, 0x60 / sizeof (CHAR16), L" ");
StrCatS (NewString3, 0x60 / sizeof (CHAR16), NewString);
TokenToUpdate = STRING_TOKEN (STR_FRONT_PAGE_TITLE);
HiiSetString (gFrontPagePrivate.HiiHandle, TokenToUpdate, NewString3, NULL);
FreePool (NewString);
NewString3 = AllocateZeroPool (0x60);
StrIndex = SmbiosTable.Type1->Version;
GetOptionalStringByIndex ((CHAR8*)((UINT8*)SmbiosTable.Raw + SmbiosTable.Hdr->Length), StrIndex, &NewString);
StrCatS (NewString3, 0x60 / sizeof (CHAR16), L"Model: ");
StrCatS (NewString3, 0x60 / sizeof (CHAR16), NewString);
TokenToUpdate = STRING_TOKEN (STR_FRONT_PAGE_COMPUTER_MODEL);
HiiSetString (gFrontPagePrivate.HiiHandle, TokenToUpdate, NewString3, NULL);
FreePool (NewString);
FreePool (NewString2);
FreePool (NewString3);
}
}
/**
@@ -892,6 +1268,8 @@ InitializeUserInterface (
UINTN BootTextColumn;
UINTN BootTextRow;
gSystemTable = SystemTable;
if (!mModeInitialized) {
//
// After the console is ready, get current video resolution
@@ -1017,11 +1395,6 @@ UiEntry (
FreeFrontPage ();
if (mLanguageString != NULL) {
FreePool (mLanguageString);
mLanguageString = NULL;
}
//
//Will leave browser, check any reset required change is applied? if yes, reset system
//
@@ -1034,10 +1407,6 @@ UiEntry (
// user change any option setting which needs a reset to be effective, and the reset will be applied according to the user selection.
//
/**
Record the info that a reset is required.
A module boolean variable is used to record whether a reset is required.
@@ -1052,10 +1421,6 @@ EnableResetRequired (
mResetRequired = TRUE;
}
/**
Check if user changed any option setting which needs a system reset to be effective.
@@ -1110,4 +1475,3 @@ SetupResetReminder (
gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL);
}
}

View File

@@ -32,9 +32,9 @@ extern EFI_FORM_BROWSER2_PROTOCOL *gFormBrowser2;
//
// These are defined as the same with vfr file
//
#define FRONT_PAGE_FORM_ID 0x1000
#define FRONT_PAGE_FORM_ID 0x7600
#define LABEL_FRANTPAGE_INFORMATION 0x1000
#define LABEL_FRONTPAGE_INFORMATION 0x1000
#define LABEL_END 0xffff
#define FRONT_PAGE_FORMSET_GUID \
@@ -52,7 +52,6 @@ typedef struct {
//
EFI_HII_HANDLE HiiHandle;
EFI_HANDLE DriverHandle;
EFI_STRING_ID *LanguageToken;
//
// Produced protocols
@@ -210,4 +209,3 @@ ExtractDevicePathFromHiiHandle (
);
#endif // _FRONT_PAGE_H_

View File

@@ -29,35 +29,15 @@ UiCustomizeFrontPage (
IN VOID *StartOpCodeHandle
)
{
//
// Create "Select Language" menu with Oneof opcode.
//
UiCreateLanguageMenu (HiiHandle, StartOpCodeHandle);
//
// Create empty line.
//
UiCreateEmptyLine(HiiHandle, StartOpCodeHandle);
//
// Find third party drivers which need to be shown in the front page.
//
UiListThirdPartyDrivers (HiiHandle, &gEfiIfrFrontPageGuid, NULL, StartOpCodeHandle);
//
// Create empty line.
//
UiCreateEmptyLine(HiiHandle, StartOpCodeHandle);
//
// Create "Continue" menu.
//
UiCreateContinueMenu(HiiHandle, StartOpCodeHandle);
//
// Create reset menu.
// Find third party drivers which need to be shown in the front page.
//
UiCreateResetMenu(HiiHandle, StartOpCodeHandle);
UiListThirdPartyDrivers (HiiHandle, &gEfiIfrFrontPageGuid, NULL, StartOpCodeHandle);
}
/**
@@ -96,44 +76,3 @@ UiFrontPageCallbackHandler (
return EFI_UNSUPPORTED;
}
/**
Update the banner string in the front page.
Current layout for the banner string like below:
PS: Totally only 5 lines of banner supported.
Line 1: Left BannerStr RightBannerStr
Line 2: Left BannerStr RightBannerStr
Line 3: Left BannerStr RightBannerStr
Line 4: Left BannerStr RightBannerStr
Line 5: Left BannerStr RightBannerStr
<EmptyLine>
First menu in front page.
...
@param LineIndex The line index of the banner need to check.
@param LeftOrRight The left or right banner need to check.
@param BannerStr Banner string need to update.
Input the current string and user can update
it and return the new string.
**/
VOID
UiCustomizeFrontPageBanner (
IN UINTN LineIndex,
IN BOOLEAN LeftOrRight,
IN OUT EFI_STRING *BannerStr
)
{
if ((LineIndex == 5) && LeftOrRight) {
// Update STR_CUSTOMIZE_BANNER_LINE5_LEFT
if (PcdGetBool(PcdTestKeyUsed)) {
if (BannerStr != NULL) {
FreePool(*BannerStr);
}
*BannerStr = HiiGetString(gFrontPagePrivate.HiiHandle, STRING_TOKEN(STR_TEST_KEY_USED), NULL);
}
}
return;
}

View File

@@ -9,35 +9,6 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#ifndef __FRONTPAGE_CUSTOMIZED_UI_H__
#define __FRONTPAGE_CUSTOMIZED_UI_H__
/**
Update the banner string in the front page.
Current layout for the banner string like below:
PS: Totally only 5 lines of banner supported.
Line 1: Left BannerStr RightBannerStr
Line 2: Left BannerStr RightBannerStr
Line 3: Left BannerStr RightBannerStr
Line 4: Left BannerStr RightBannerStr
Line 5: Left BannerStr RightBannerStr
<EmptyLine>
First menu in front page.
...
@param LineIndex The line index of the banner need to check.
@param LeftOrRight The left or right banner need to check.
@param BannerStr Banner string need to update.
Input the current string and user can update
it and return the new string.
**/
VOID
UiCustomizeFrontPageBanner (
IN UINTN LineIndex,
IN BOOLEAN LeftOrRight,
IN OUT EFI_STRING *BannerStr
);
/**
Customize menus in the page.

View File

@@ -35,8 +35,6 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#define UI_HII_DRIVER_LIST_SIZE 0x8
#define FRONT_PAGE_KEY_CONTINUE 0x1000
#define FRONT_PAGE_KEY_RESET 0x1001
#define FRONT_PAGE_KEY_LANGUAGE 0x1002
#define FRONT_PAGE_KEY_DRIVER 0x2000
typedef struct {
@@ -47,112 +45,10 @@ typedef struct {
BOOLEAN EmptyLineAfter;
} UI_HII_DRIVER_INSTANCE;
CHAR8 *gLanguageString;
EFI_STRING_ID *gLanguageToken;
UI_HII_DRIVER_INSTANCE *gHiiDriverList;
extern EFI_HII_HANDLE gStringPackHandle;
UINT8 gCurrentLanguageIndex;
/**
Get next language from language code list (with separator ';').
If LangCode is NULL, then ASSERT.
If Lang is NULL, then ASSERT.
@param LangCode On input: point to first language in the list. On
output: point to next language in the list, or
NULL if no more language in the list.
@param Lang The first language in the list.
**/
VOID
GetNextLanguage (
IN OUT CHAR8 **LangCode,
OUT CHAR8 *Lang
)
{
UINTN Index;
CHAR8 *StringPtr;
ASSERT (LangCode != NULL);
ASSERT (*LangCode != NULL);
ASSERT (Lang != NULL);
Index = 0;
StringPtr = *LangCode;
while (StringPtr[Index] != 0 && StringPtr[Index] != ';') {
Index++;
}
CopyMem (Lang, StringPtr, Index);
Lang[Index] = 0;
if (StringPtr[Index] == ';') {
Index++;
}
*LangCode = StringPtr + Index;
}
/**
This function processes the language changes in configuration.
@param Value A pointer to the data being sent to the original exporting driver.
@retval TRUE The callback successfully handled the action.
@retval FALSE The callback not supported in this handler.
**/
EFI_STATUS
LanguageChangeHandler (
IN EFI_IFR_TYPE_VALUE *Value
)
{
CHAR8 *LangCode;
CHAR8 *Lang;
UINTN Index;
EFI_STATUS Status;
//
// Allocate working buffer for RFC 4646 language in supported LanguageString.
//
Lang = AllocatePool (AsciiStrSize (gLanguageString));
ASSERT (Lang != NULL);
Index = 0;
LangCode = gLanguageString;
while (*LangCode != 0) {
GetNextLanguage (&LangCode, Lang);
if (Index == Value->u8) {
gCurrentLanguageIndex = Value->u8;
break;
}
Index++;
}
if (Index == Value->u8) {
Status = gRT->SetVariable (
L"PlatformLang",
&gEfiGlobalVariableGuid,
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
AsciiStrSize (Lang),
Lang
);
if (EFI_ERROR (Status)) {
FreePool (Lang);
return EFI_DEVICE_ERROR;
}
} else {
ASSERT (FALSE);
}
FreePool (Lang);
return EFI_SUCCESS;
}
/**
This function processes the results of changes in configuration.
@@ -181,19 +77,12 @@ UiSupportLibCallbackHandler (
OUT EFI_STATUS *Status
)
{
if (QuestionId != FRONT_PAGE_KEY_CONTINUE &&
QuestionId != FRONT_PAGE_KEY_RESET &&
QuestionId != FRONT_PAGE_KEY_LANGUAGE) {
if (QuestionId != FRONT_PAGE_KEY_CONTINUE) {
return FALSE;
}
if (Action == EFI_BROWSER_ACTION_RETRIEVE) {
if (QuestionId == FRONT_PAGE_KEY_LANGUAGE) {
Value->u8 = gCurrentLanguageIndex;
*Status = EFI_SUCCESS;
} else {
*Status = EFI_UNSUPPORTED;
}
*Status = EFI_UNSUPPORTED;
return TRUE;
}
@@ -220,17 +109,6 @@ UiSupportLibCallbackHandler (
*ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;
break;
case FRONT_PAGE_KEY_LANGUAGE:
*Status = LanguageChangeHandler(Value);
break;
case FRONT_PAGE_KEY_RESET:
//
// Reset
//
gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL);
*Status = EFI_UNSUPPORTED;
default:
break;
}
@@ -239,156 +117,6 @@ UiSupportLibCallbackHandler (
return TRUE;
}
/**
Create Select language menu in the front page with oneof opcode.
@param[in] HiiHandle The hii handle for the Uiapp driver.
@param[in] StartOpCodeHandle The opcode handle to save the new opcode.
**/
VOID
UiCreateLanguageMenu (
IN EFI_HII_HANDLE HiiHandle,
IN VOID *StartOpCodeHandle
)
{
CHAR8 *LangCode;
CHAR8 *Lang;
UINTN LangSize;
CHAR8 *CurrentLang;
UINTN OptionCount;
CHAR16 *StringBuffer;
VOID *OptionsOpCodeHandle;
UINTN StringSize;
EFI_STATUS Status;
EFI_HII_STRING_PROTOCOL *HiiString;
Lang = NULL;
StringBuffer = NULL;
//
// Init OpCode Handle and Allocate space for creation of UpdateData Buffer
//
OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();
ASSERT (OptionsOpCodeHandle != NULL);
GetEfiGlobalVariable2 (L"PlatformLang", (VOID**)&CurrentLang, NULL);
//
// Get Support language list from variable.
//
GetEfiGlobalVariable2 (L"PlatformLangCodes", (VOID**)&gLanguageString, NULL);
if (gLanguageString == NULL) {
gLanguageString = AllocateCopyPool (
AsciiStrSize ((CHAR8 *) PcdGetPtr (PcdUefiVariableDefaultPlatformLangCodes)),
(CHAR8 *) PcdGetPtr (PcdUefiVariableDefaultPlatformLangCodes)
);
ASSERT (gLanguageString != NULL);
}
if (gLanguageToken == NULL) {
//
// Count the language list number.
//
LangCode = gLanguageString;
Lang = AllocatePool (AsciiStrSize (gLanguageString));
ASSERT (Lang != NULL);
OptionCount = 0;
while (*LangCode != 0) {
GetNextLanguage (&LangCode, Lang);
OptionCount ++;
}
//
// Allocate extra 1 as the end tag.
//
gLanguageToken = AllocateZeroPool ((OptionCount + 1) * sizeof (EFI_STRING_ID));
ASSERT (gLanguageToken != NULL);
Status = gBS->LocateProtocol (&gEfiHiiStringProtocolGuid, NULL, (VOID **) &HiiString);
ASSERT_EFI_ERROR (Status);
LangCode = gLanguageString;
OptionCount = 0;
while (*LangCode != 0) {
GetNextLanguage (&LangCode, Lang);
StringSize = 0;
Status = HiiString->GetString (HiiString, Lang, HiiHandle, PRINTABLE_LANGUAGE_NAME_STRING_ID, StringBuffer, &StringSize, NULL);
if (Status == EFI_BUFFER_TOO_SMALL) {
StringBuffer = AllocateZeroPool (StringSize);
ASSERT (StringBuffer != NULL);
Status = HiiString->GetString (HiiString, Lang, HiiHandle, PRINTABLE_LANGUAGE_NAME_STRING_ID, StringBuffer, &StringSize, NULL);
ASSERT_EFI_ERROR (Status);
}
if (EFI_ERROR (Status)) {
LangSize = AsciiStrSize (Lang);
StringBuffer = AllocatePool (LangSize * sizeof (CHAR16));
ASSERT (StringBuffer != NULL);
AsciiStrToUnicodeStrS (Lang, StringBuffer, LangSize);
}
ASSERT (StringBuffer != NULL);
gLanguageToken[OptionCount] = HiiSetString (HiiHandle, 0, StringBuffer, NULL);
FreePool (StringBuffer);
OptionCount++;
}
}
ASSERT (gLanguageToken != NULL);
LangCode = gLanguageString;
OptionCount = 0;
if (Lang == NULL) {
Lang = AllocatePool (AsciiStrSize (gLanguageString));
ASSERT (Lang != NULL);
}
while (*LangCode != 0) {
GetNextLanguage (&LangCode, Lang);
if (CurrentLang != NULL && AsciiStrCmp (Lang, CurrentLang) == 0) {
HiiCreateOneOfOptionOpCode (
OptionsOpCodeHandle,
gLanguageToken[OptionCount],
EFI_IFR_OPTION_DEFAULT,
EFI_IFR_NUMERIC_SIZE_1,
(UINT8) OptionCount
);
gCurrentLanguageIndex = (UINT8) OptionCount;
} else {
HiiCreateOneOfOptionOpCode (
OptionsOpCodeHandle,
gLanguageToken[OptionCount],
0,
EFI_IFR_NUMERIC_SIZE_1,
(UINT8) OptionCount
);
}
OptionCount++;
}
if (CurrentLang != NULL) {
FreePool (CurrentLang);
}
FreePool (Lang);
HiiCreateOneOfOpCode (
StartOpCodeHandle,
FRONT_PAGE_KEY_LANGUAGE,
0,
0,
STRING_TOKEN (STR_LANGUAGE_SELECT),
STRING_TOKEN (STR_LANGUAGE_SELECT_HELP),
EFI_IFR_FLAG_CALLBACK,
EFI_IFR_NUMERIC_SIZE_1,
OptionsOpCodeHandle,
NULL
);
}
/**
Create continue menu in the front page.
@@ -405,8 +133,8 @@ UiCreateContinueMenu (
HiiCreateActionOpCode (
StartOpCodeHandle,
FRONT_PAGE_KEY_CONTINUE,
STRING_TOKEN (STR_CONTINUE_PROMPT),
STRING_TOKEN (STR_CONTINUE_PROMPT),
STRING_TOKEN (STR_BOOT_DEFAULT_PROMPT),
STRING_TOKEN (STR_BOOT_DEFAULT_HELP),
EFI_IFR_FLAG_CALLBACK,
0
);
@@ -425,30 +153,7 @@ UiCreateEmptyLine (
IN VOID *StartOpCodeHandle
)
{
HiiCreateSubTitleOpCode (StartOpCodeHandle, STRING_TOKEN (STR_NULL_STRING), 0, 0, 0);
}
/**
Create Reset menu in the front page.
@param[in] HiiHandle The hii handle for the Uiapp driver.
@param[in] StartOpCodeHandle The opcode handle to save the new opcode.
**/
VOID
UiCreateResetMenu (
IN EFI_HII_HANDLE HiiHandle,
IN VOID *StartOpCodeHandle
)
{
HiiCreateActionOpCode (
StartOpCodeHandle,
FRONT_PAGE_KEY_RESET,
STRING_TOKEN (STR_RESET_STRING),
STRING_TOKEN (STR_RESET_STRING),
EFI_IFR_FLAG_CALLBACK,
0
);
HiiCreateSubTitleOpCode (StartOpCodeHandle, STRING_TOKEN (STR_EMPTY_STRING), 0, 0, 0);
}
/**

View File

@@ -35,32 +35,6 @@ UiCreateEmptyLine (
IN VOID *StartOpCodeHandle
);
/**
Create Select language menu in the front page with oneof opcode.
@param[in] HiiHandle The hii handle for the Uiapp driver.
@param[in] StartOpCodeHandle The opcode handle to save the new opcode.
**/
VOID
UiCreateLanguageMenu (
IN EFI_HII_HANDLE HiiHandle,
IN VOID *StartOpCodeHandle
);
/**
Create Reset menu.
@param[in] HiiHandle The hii handle for the Uiapp driver.
@param[in] StartOpCodeHandle The opcode handle to save the new opcode.
**/
VOID
UiCreateResetMenu (
IN EFI_HII_HANDLE HiiHandle,
IN VOID *StartOpCodeHandle
);
/**
Rename the driver name if necessary.

View File

@@ -10,59 +10,19 @@
/=#
#langdef en-US "English"
#langdef fr-FR "Français"
#langdef en "Standard English"
#langdef fr "Standard Français"
#string STR_FRONT_PAGE_TITLE #language en-US "Front Page"
#language fr-FR "Front Page"
#string STR_FRONT_PAGE_COMPUTER_MODEL #language en-US ""
#language fr-FR ""
#string STR_FRONT_PAGE_CPU_MODEL #language en-US ""
#language fr-FR ""
#string STR_FRONT_PAGE_CPU_SPEED #language en-US ""
#language fr-FR ""
#string STR_FRONT_PAGE_MEMORY_SIZE #language en-US ""
#language fr-FR ""
#string STR_FRONT_PAGE_BIOS_VERSION #language en-US ""
#language fr-FR ""
#string STR_FRONT_PAGE_BANNER_0_LEFT #language en-US "Wonder Computer Model 1000Z Manufactured by Intel®"
#language fr-FR "Demander le Modèle d'Ordinateur 1000Z A Fabriqué par Intel®"
#string STR_FRONT_PAGE_BANNER_0_RIGHT #language en-US "OK"
#language fr-FR "Bon"
#string STR_FRONT_PAGE_BANNER_1_LEFT #language en-US "2 Pentium® X Xeon processors running at 800Thz"
#language fr-FR "2 processeurs Pentium® X Xeon tournants à 800Thz"
#string STR_FRONT_PAGE_BANNER_1_RIGHT #language en-US "24 TB System RAM"
#language fr-FR "24 TB RAM de Système"
#string STR_FRONT_PAGE_BANNER_2_LEFT #language en-US "ACME® EFI BIOS Version 13.5 Release 1039.92"
#language fr-FR "ACME® EFI BIOS Version 13.5 Release 1039.92"
#string STR_FRONT_PAGE_BANNER_3_LEFT #language en-US "Serial Number: 1Z123456789MARMAR (Need SMBIOS entries)"
#language fr-FR "Numéro de série: 1Z123456789MARMAR (Les entrées de SMBIOS de besoin)"
#string STR_CONTINUE_PROMPT #language en-US "Continue"
#language fr-FR "Continuer"
#string STR_CONTINUE_HELP #language en-US "This selection will direct the system to continue to booting process"
#language fr-FR "Cette sélection dirigera le système pour continuer au processus d'amorçage"
#string STR_LANGUAGE_SELECT #language en-US "Select Language"
#language fr-FR "Choisir la Langue"
#string STR_LANGUAGE_SELECT_HELP #language en-US "This is the option one adjusts to change the language for the current system"
#language fr-FR "Ceci est l'option qu'on ajuste pour changer la langue pour le système actuel"
#string STR_FRONT_PAGE_COMPUTER_MODEL #language en-US "<model>"
#string STR_FRONT_PAGE_BIOS_VERSION #language en-US "<bios>"
#string STR_FIRMWARE_INFO #language en-US "Firmware Configuration Information"
#string STR_BOOT_DEFAULT_PROMPT #language en-US "Boot Default"
#string STR_BOOT_DEFAULT_HELP #language en-US "Boot the default entry"
#string STR_MISSING_STRING #language en-US "Missing String"
#language fr-FR "Missing String"
#string STR_NO_BOOTABLE_MEDIA #language en-US ""
#string STR_WEBCAM_STATUS #language en-US ""
#string STR_EMPTY_STRING #language en-US ""
#language fr-FR ""
#string STR_RESET_STRING #language en-US "Reset"
#language fr-FR "Reset"
#string STR_RESET_STRING_HELP #language en-US "Reset the current setting."
#language fr-FR "Reset the current setting."
#string STR_CUSTOMIZE_BANNER_LINE4_LEFT #language en-US ""
#language fr-FR ""
#string STR_CUSTOMIZE_BANNER_LINE4_RIGHT #language en-US ""
#language fr-FR ""
#string STR_CUSTOMIZE_BANNER_LINE5_LEFT #language en-US ""
#language fr-FR ""
#string STR_CUSTOMIZE_BANNER_LINE5_RIGHT #language en-US ""
#language fr-FR ""
#string STR_TEST_KEY_USED #language en-US "WARNING: Test key detected."
#language fr-FR "WARNING: Test key detected."
#string STR_NULL_STRING #language en-US " "
#language fr-FR " "
#string STR_VIRTUALIZATION #language en-US ""
#string STR_VIRTUALIZATION_STATUS #language en-US ""
#string STR_IOMMU_STATUS #language en-US ""
#string STR_TPM_STATUS #language en-US ""
#string STR_ME_STATUS #language en-US ""

View File

@@ -9,72 +9,53 @@
#define FORMSET_GUID { 0x9e0c30bc, 0x3f06, 0x4ba6, 0x82, 0x88, 0x9, 0x17, 0x9b, 0x85, 0x5d, 0xbe }
#define FRONT_PAGE_FORM_ID 0x1000
#define FRONT_PAGE_FORM_ID 0x7600
#define FIRMWARE_INFO_FORM_ID 0x7601
#define LABEL_FRANTPAGE_INFORMATION 0x1000
#define LABEL_FRONTPAGE_INFORMATION 0x1000
#define LABEL_END 0xffff
formset
guid = FORMSET_GUID,
title = STRING_TOKEN(STR_FRONT_PAGE_TITLE),
help = STRING_TOKEN(STR_EMPTY_STRING ),
guid = FORMSET_GUID,
title = STRING_TOKEN(STR_FRONT_PAGE_TITLE),
help = STRING_TOKEN(STR_EMPTY_STRING),
classguid = FORMSET_GUID,
form formid = FRONT_PAGE_FORM_ID,
title = STRING_TOKEN(STR_FRONT_PAGE_TITLE);
title = STRING_TOKEN(STR_FRONT_PAGE_TITLE);
banner
title = STRING_TOKEN(STR_FRONT_PAGE_COMPUTER_MODEL),
line 1,
align left;
subtitle text = STRING_TOKEN(STR_FRONT_PAGE_COMPUTER_MODEL);
subtitle text = STRING_TOKEN(STR_FRONT_PAGE_BIOS_VERSION);
subtitle text = STRING_TOKEN(STR_EMPTY_STRING);
banner
title = STRING_TOKEN(STR_FRONT_PAGE_CPU_MODEL),
line 2,
align left;
banner
title = STRING_TOKEN(STR_FRONT_PAGE_CPU_SPEED),
line 2,
align right;
banner
title = STRING_TOKEN(STR_FRONT_PAGE_BIOS_VERSION),
line 3,
align left;
banner
title = STRING_TOKEN(STR_FRONT_PAGE_MEMORY_SIZE),
line 3,
align right;
banner
title = STRING_TOKEN(STR_CUSTOMIZE_BANNER_LINE4_LEFT),
line 4,
align left;
banner
title = STRING_TOKEN(STR_CUSTOMIZE_BANNER_LINE4_RIGHT),
line 4,
align right;
banner
title = STRING_TOKEN(STR_CUSTOMIZE_BANNER_LINE5_LEFT),
line 5,
align left;
banner
title = STRING_TOKEN(STR_CUSTOMIZE_BANNER_LINE5_RIGHT),
line 5,
align right;
label LABEL_FRANTPAGE_INFORMATION;
label LABEL_FRONTPAGE_INFORMATION;
//
// This is where we will dynamically add a Action type op-code to show
// the platform information.
//
label LABEL_END;
subtitle text = STRING_TOKEN(STR_EMPTY_STRING);
goto FIRMWARE_INFO_FORM_ID,
prompt = STRING_TOKEN(STR_FIRMWARE_INFO),
help = STRING_TOKEN(STR_EMPTY_STRING);
subtitle text = STRING_TOKEN(STR_EMPTY_STRING);
subtitle text = STRING_TOKEN(STR_NO_BOOTABLE_MEDIA);
subtitle text = STRING_TOKEN(STR_WEBCAM_STATUS);
endform;
form formid = FIRMWARE_INFO_FORM_ID,
title = STRING_TOKEN(STR_FIRMWARE_INFO);
subtitle text = STRING_TOKEN(STR_VIRTUALIZATION);
subtitle text = STRING_TOKEN(STR_VIRTUALIZATION_STATUS);
subtitle text = STRING_TOKEN(STR_IOMMU_STATUS);
subtitle text = STRING_TOKEN(STR_EMPTY_STRING);
subtitle text = STRING_TOKEN(STR_TPM_STATUS);
subtitle text = STRING_TOKEN(STR_EMPTY_STRING);
subtitle text = STRING_TOKEN(STR_ME_STATUS);
endform;
endformset;

View File

@@ -56,8 +56,10 @@
UefiBootManagerLib
[Guids]
gEfiAcpiTableGuid ## CONSUMES ## GUID
gEfiIfrTianoGuid ## CONSUMES ## GUID (Extended IFR Guid Opcode)
gEfiIfrFrontPageGuid ## CONSUMES ## GUID
gEfiSmbiosTableGuid ## CONSUMES
[Protocols]
gEfiSmbiosProtocolGuid ## CONSUMES

View File

@@ -2530,10 +2530,12 @@ PciEnumeratorLight (
//
RemoveRejectedPciDevices (RootBridgeDev->Handle, RootBridgeDev);
//
// Process option rom light
//
ProcessOptionRomLight (RootBridgeDev);
if (!PcdGetBool (PcdPciDisableBusEnumeration)) {
//
// Process option rom light
//
ProcessOptionRomLight (RootBridgeDev);
}
//
// Determine attributes for all devices under this root bridge

View File

@@ -2,7 +2,8 @@
XHCI transfer scheduling routines.
Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2011 - 2020, Intel Corporation. All rights reserved.<BR>
Copyright (c) Microsoft Corporation.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
@@ -1683,9 +1684,11 @@ XhcPollPortStatusChange (
EFI_STATUS Status;
UINT8 Speed;
UINT8 SlotId;
UINT8 Retries;
USB_DEV_ROUTE RouteChart;
Status = EFI_SUCCESS;
Retries = XHC_INIT_DEVICE_SLOT_RETRIES;
if ((PortState->PortChangeStatus & (USB_PORT_STAT_C_CONNECTION | USB_PORT_STAT_C_ENABLE | USB_PORT_STAT_C_OVERCURRENT | USB_PORT_STAT_C_RESET)) == 0) {
return EFI_SUCCESS;
@@ -1727,17 +1730,29 @@ XhcPollPortStatusChange (
} else if ((PortState->PortStatus & USB_PORT_STAT_SUPER_SPEED) != 0) {
Speed = EFI_USB_SPEED_SUPER;
}
//
// Execute Enable_Slot cmd for attached device, initialize device context and assign device address.
//
SlotId = XhcRouteStringToSlotId (Xhc, RouteChart);
if ((SlotId == 0) && ((PortState->PortChangeStatus & USB_PORT_STAT_C_RESET) != 0)) {
if (Xhc->HcCParams.Data.Csz == 0) {
Status = XhcInitializeDeviceSlot (Xhc, ParentRouteChart, Port, RouteChart, Speed);
} else {
Status = XhcInitializeDeviceSlot64 (Xhc, ParentRouteChart, Port, RouteChart, Speed);
do {
//
// Execute Enable_Slot cmd for attached device, initialize device context and assign device address.
//
SlotId = XhcRouteStringToSlotId (Xhc, RouteChart);
if ((SlotId == 0) && ((PortState->PortChangeStatus & USB_PORT_STAT_C_RESET) != 0)) {
if (Xhc->HcCParams.Data.Csz == 0) {
Status = XhcInitializeDeviceSlot (Xhc, ParentRouteChart, Port, RouteChart, Speed);
} else {
Status = XhcInitializeDeviceSlot64 (Xhc, ParentRouteChart, Port, RouteChart, Speed);
}
}
}
//
// According to the xHCI specification (section 4.6.5), "a USB Transaction
// Error Completion Code for an Address Device Command may be due to a Stall
// response from a device. Software should issue a Disable Slot Command for
// the Device Slot then an Enable Slot Command to recover from this error."
// Therefore, retry the device slot initialization if it fails due to a
// device error.
//
} while ((Status == EFI_DEVICE_ERROR) && (Retries-- != 0));
}
return Status;
@@ -2245,6 +2260,9 @@ XhcInitializeDeviceSlot (
DeviceAddress = (UINT8) ((DEVICE_CONTEXT *) OutputContext)->Slot.DeviceAddress;
DEBUG ((EFI_D_INFO, " Address %d assigned successfully\n", DeviceAddress));
Xhc->UsbDevContext[SlotId].XhciDevAddr = DeviceAddress;
} else {
DEBUG ((DEBUG_INFO, " Address %d assigned unsuccessfully\n"));
XhcDisableSlotCmd (Xhc, SlotId);
}
return Status;
@@ -2455,7 +2473,11 @@ XhcInitializeDeviceSlot64 (
DeviceAddress = (UINT8) ((DEVICE_CONTEXT_64 *) OutputContext)->Slot.DeviceAddress;
DEBUG ((EFI_D_INFO, " Address %d assigned successfully\n", DeviceAddress));
Xhc->UsbDevContext[SlotId].XhciDevAddr = DeviceAddress;
} else {
DEBUG ((DEBUG_INFO, " Address %d assigned unsuccessfully\n"));
XhcDisableSlotCmd64 (Xhc, SlotId);
}
return Status;
}

View File

@@ -11,6 +11,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#define _EFI_XHCI_SCHED_H_
#define XHC_URB_SIG SIGNATURE_32 ('U', 'S', 'B', 'R')
#define XHC_INIT_DEVICE_SLOT_RETRIES 1
//
// Transfer types, used in URB to identify the transfer type

View File

@@ -70,6 +70,10 @@ CoreRemoveInterfaceFromProtocol (
for(Link = ProtEntry->Notify.ForwardLink; Link != &ProtEntry->Notify; Link=Link->ForwardLink) {
ProtNotify = CR(Link, PROTOCOL_NOTIFY, Link, PROTOCOL_NOTIFY_SIGNATURE);
// Signal notify events before removing the protocol too.
// XXX: What effect does this have on other code?
CoreSignalEvent (ProtNotify->Event);
if (ProtNotify->Position == &Prot->ByProtocol) {
ProtNotify->Position = Prot->ByProtocol.BackLink;
}

View File

@@ -61,4 +61,14 @@ BootLogoUpdateProgress (
IN UINTN PreviousValue
);
/**
Install Boot Logo into BGRT table
**/
VOID
AddBGRT (
VOID
);
#endif

View File

@@ -0,0 +1,283 @@
#include <IndustryStandard/Acpi.h>
#include <IndustryStandard/Bmp.h>
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/BootLogoLib.h>
#include <Library/DebugLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Protocol/FirmwareVolume2.h>
#include <Protocol/SimpleFileSystem.h>
/** RSDP (Root System Description Pointer) */
typedef struct {
CHAR8 signature[8];
UINT8 checksum;
CHAR8 oem_id[6];
UINT8 revision;
UINT32 rsdt_address;
UINT32 length;
UINT64 xsdt_address;
UINT8 extended_checksum;
UINT8 reserved[3];
} ACPI_20_RSDP;
/** SDT (System Description Table) entry header */
typedef struct {
CHAR8 signature[4];
UINT32 length;
UINT8 revision;
UINT8 checksum;
CHAR8 oem_id[6];
CHAR8 oem_table_id[8];
UINT32 oem_revision;
UINT32 asl_compiler_id;
UINT32 asl_compiler_revision;
} ACPI_SDT_HEADER;
/** BGRT structure */
typedef struct {
ACPI_SDT_HEADER header;
UINT16 version;
UINT8 status;
UINT8 image_type;
UINT64 image_address;
UINT32 image_offset_x;
UINT32 image_offset_y;
} ACPI_BGRT;
EFI_STATUS
EFIAPI
LoadBmp(
OUT EFI_PHYSICAL_ADDRESS *BmpAddress,
OUT UINT32 *BmpSize
)
{
EFI_STATUS Status;
UINTN FvProtocolCount;
EFI_HANDLE *FvHandles;
EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv;
UINTN Index;
UINT32 AuthenticationStatus;
UINT8 *Buffer;
UINTN BmpBufferSize;
Buffer = 0;
FvHandles = NULL;
Status = gBS->LocateHandleBuffer (
ByProtocol,
&gEfiFirmwareVolume2ProtocolGuid,
NULL,
&FvProtocolCount,
&FvHandles
);
if (!EFI_ERROR (Status)) {
for (Index = 0; Index < FvProtocolCount; Index++) {
Status = gBS->HandleProtocol (
FvHandles[Index],
&gEfiFirmwareVolume2ProtocolGuid,
(VOID **) &Fv
);
BmpBufferSize = 0;
Status = Fv->ReadSection (
Fv,
(EFI_GUID *)PcdGetPtr(PcdLogoFile),
EFI_SECTION_RAW,
0,
(void **)&Buffer,
&BmpBufferSize,
&AuthenticationStatus
);
if (!EFI_ERROR (Status)) {
*BmpAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)Buffer;
*BmpSize = (UINT32)BmpBufferSize;
Status = EFI_SUCCESS;
break;
}
}
} else {
Status = EFI_NOT_FOUND;
}
if (FvHandles != NULL) {
gBS->FreePool (FvHandles);
FvHandles = NULL;
}
return Status;
}
UINT8 SumBytes(const UINT8* arr, UINTN size) {
UINT8 sum = 0;
UINTN i;
for (i = 0; i < size; ++i) {
sum += arr[i];
}
return sum;
}
int VerifyAcpiRsdp2Checksums(const void* data) {
const UINT8* arr = data;
UINTN size = *(const UINT32*)&arr[20];
return SumBytes(arr, 20) == 0 && SumBytes(arr, size) == 0;
}
void SetAcpiRsdp2Checksums(void* data) {
UINT8* arr = data;
UINTN size = *(const UINT32*)&arr[20];
arr[9] = 0;
arr[32] = 0;
arr[9] = -SumBytes(arr, 20);
arr[32] = -SumBytes(arr, size);
}
int VerifyAcpiSdtChecksum(const void* data) {
const UINT8* arr = data;
UINTN size = *(const UINT32*)&arr[4];
return SumBytes(arr, size) == 0;
}
void SetAcpiSdtChecksum(void* data) {
UINT8* arr = data;
UINTN size = *(const UINT32*)&arr[4];
arr[9] = 0;
arr[9] = -SumBytes(arr, size);
}
const CHAR16* TmpStr(CHAR8 *src, int length) {
static CHAR16 arr[4][16];
static int j;
CHAR16* dest = arr[j = (j+1) % 4];
int i;
for (i = 0; i < length && i < 16-1 && src[i]; ++i) {
dest[i] = src[i];
}
dest[i] = 0;
return dest;
}
static UINT32 min(UINT32 first, UINT32 second){
if (first < second)
return first;
return second;
}
ACPI_SDT_HEADER* CreateXsdt(ACPI_SDT_HEADER* xsdt0, UINTN entries) {
ACPI_SDT_HEADER* xsdt = 0;
UINT32 xsdt_len = (UINT32)(sizeof(ACPI_SDT_HEADER) + entries * sizeof(UINT64));
gBS->AllocatePool(EfiACPIReclaimMemory, xsdt_len, (void**)&xsdt);
if (!xsdt) {
DEBUG ((EFI_D_INFO, "HackBGRT: Failed to allocate memory for XSDT.\n"));
return 0;
}
ZeroMem(xsdt, xsdt_len);
CopyMem(xsdt, xsdt0, min(xsdt0->length, xsdt_len));
xsdt->length = xsdt_len;
SetAcpiSdtChecksum(xsdt);
return xsdt;
}
static ACPI_BGRT* HandleAcpiTables(ACPI_BGRT* bgrt) {
int i;
for (i = 0; i < gST->NumberOfTableEntries; i++) {
EFI_GUID* vendor_guid = &gST->ConfigurationTable[i].VendorGuid;
ACPI_20_RSDP *rsdp;
ACPI_SDT_HEADER *xsdt;
UINT64 *entry_arr;
UINT32 entry_arr_length;
if (!CompareGuid(vendor_guid, &gEfiAcpiTableGuid) && !CompareGuid(vendor_guid, &gEfiAcpi20TableGuid)) {
continue;
}
rsdp = (ACPI_20_RSDP *) gST->ConfigurationTable[i].VendorTable;
if (CompareMem(rsdp->signature, "RSD PTR ", 8) != 0 || rsdp->revision < 2 || !VerifyAcpiRsdp2Checksums(rsdp)) {
continue;
}
DEBUG ((EFI_D_INFO, "RSDP: revision = %d, OEM ID = %s\n", rsdp->revision, TmpStr(rsdp->oem_id, 6)));
xsdt = (ACPI_SDT_HEADER *) (UINTN) rsdp->xsdt_address;
if (!xsdt || CompareMem(xsdt->signature, "XSDT", 4) != 0 || !VerifyAcpiSdtChecksum(xsdt)) {
DEBUG ((EFI_D_INFO, "* XSDT: missing or invalid\n"));
continue;
}
entry_arr = (UINT64*)&xsdt[1];
entry_arr_length = (xsdt->length - sizeof(*xsdt)) / sizeof(UINT64);
DEBUG ((EFI_D_INFO, "* XSDT: OEM ID = %s, entry count = %d\n", TmpStr(xsdt->oem_id, 6), entry_arr_length));
if (bgrt) {
DEBUG ((EFI_D_INFO, " - Adding missing BGRT.\n"));
xsdt = CreateXsdt(xsdt, entry_arr_length + 1);
entry_arr = (UINT64*)&xsdt[1];
entry_arr[entry_arr_length++] = (UINTN) bgrt;
rsdp->xsdt_address = (UINTN) xsdt;
SetAcpiRsdp2Checksums(rsdp);
}
SetAcpiSdtChecksum(xsdt);
}
return bgrt;
}
VOID
AddBGRT (
VOID
)
{
EFI_STATUS Status;
ACPI_BGRT *bgrt;
EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
EFI_PHYSICAL_ADDRESS BmpAddress;
UINT32 BmpSize;
BMP_IMAGE_HEADER *BmpHeader;
const char data[0x38] =
"BGRT" "\x38\x00\x00\x00" "\x00" "\xd6" "INTEL " " EDK2"
"\x20\x17\x00\x00" "PTL " "\x02\x00\x00\x00"
"\x01\x00" "\x00" "\x00";
BmpAddress = 0;
DEBUG ((EFI_D_INFO, "HackBGRT Start\n"));
Status = gBS->HandleProtocol (
gST->ConsoleOutHandle,
&gEfiGraphicsOutputProtocolGuid,
(VOID**)&GraphicsOutput
);
// Replace missing = allocate new.
gBS->AllocatePool(EfiACPIReclaimMemory, sizeof(*bgrt), (void**)&bgrt);
if (!bgrt) {
DEBUG ((EFI_D_INFO, "HackBGRT MEM ERR\n"));
return;
}
DEBUG ((EFI_D_INFO, "HackBGRT Load Bmp\n"));
Status = LoadBmp(&BmpAddress, &BmpSize);
if (EFI_ERROR(Status)){
DEBUG ((EFI_D_INFO, "HackBGRT BMP Load ERR\n"));
return;
}
DEBUG ((EFI_D_INFO, "HackBGRT Set Table; BMP Size: %d\n", BmpSize));
// Clear the BGRT.
CopyMem(bgrt, data, sizeof(data));
if (GraphicsOutput != NULL && GraphicsOutput->Mode != NULL && GraphicsOutput->Mode->Info != NULL)
{
BmpHeader = (BMP_IMAGE_HEADER *)BmpAddress;
bgrt->image_address = (UINTN)BmpAddress;
bgrt->image_offset_x = (GraphicsOutput->Mode->Info->HorizontalResolution - BmpHeader->PixelWidth) / 2;
bgrt->image_offset_y = ((GraphicsOutput->Mode->Info->VerticalResolution * 382) / 1000) -
(BmpHeader->PixelHeight / 2);
DEBUG ((EFI_D_INFO, "HackBGRT Set checksum\n"));
SetAcpiSdtChecksum(bgrt);
DEBUG ((EFI_D_INFO, "HackBGRT Add Table\n"));
HandleAcpiTables(bgrt);
} else {
DEBUG ((EFI_D_INFO, "HackBGRT no display connected, skip adding table\n"));
}
}

View File

@@ -175,7 +175,7 @@ BootLogoEnableLogo (
break;
case EdkiiPlatformLogoDisplayAttributeCenter:
DestX = (SizeOfX - Image.Width) / 2;
DestY = (SizeOfY - Image.Height) / 2;
DestY = (SizeOfY * 382) / 1000 - Image.Height / 2;
break;
case EdkiiPlatformLogoDisplayAttributeCenterRight:
DestX = SizeOfX - Image.Width;

View File

@@ -24,6 +24,7 @@
#
[Sources]
Bgrt.c
BootLogoLib.c
[Packages]
@@ -48,5 +49,12 @@
gEfiUserManagerProtocolGuid ## CONSUMES
gEdkiiPlatformLogoProtocolGuid ## CONSUMES
[Guids]
gEfiAcpiTableGuid ## CONSUMES ## GUID
gEfiAcpi20TableGuid ## CONSUMES ## GUID
[FeaturePcd]
gEfiMdePkgTokenSpaceGuid.PcdUgaConsumeSupport ## CONSUMES
[Pcd]
gEfiMdeModulePkgTokenSpaceGuid.PcdLogoFile ## CONSUMES

View File

@@ -722,6 +722,7 @@ BootMaintExtractConfig (
*Progress = Request + StrLen (Request);
}
DEBUG ((EFI_D_INFO, "%a complete: %r\n", __FUNCTION__, Status));
return Status;
}
@@ -1033,6 +1034,7 @@ BootMaintRouteConfig (
//
CopyMem (OldBmmData, NewBmmData, sizeof (BMM_FAKE_NV_DATA));
DEBUG ((EFI_D_INFO, "%a complete: %r\n", __FUNCTION__, Status));
return EFI_SUCCESS;
Exit:
@@ -1093,6 +1095,8 @@ BootMaintCallback (
Private = BMM_CALLBACK_DATA_FROM_THIS (This);
if (Action == EFI_BROWSER_ACTION_FORM_OPEN) {
DEBUG ((EFI_D_INFO, "EFI_BROWSER_ACTION_FORM_OPEN: 0x%0X\n", QuestionId));
if (QuestionId == KEY_VALUE_TRIGGER_FORM_OPEN_ACTION) {
if (!mFirstEnterBMMForm) {
//
@@ -1104,7 +1108,9 @@ BootMaintCallback (
// 1. Update the menus (including legacy munu) show in BootMiantenanceManager page.
// 2. Re-scan the BootOption menus (including the legacy boot option).
//
CustomizeMenus ();
//CustomizeMenus ();
UpdatePageId (Private, FORM_BOOT_CHG_ID);
UpdatePageBody (FORM_BOOT_CHG_ID, Private);
EfiBootManagerRefreshAllBootOption ();
BOpt_GetBootOptions (Private);
mFirstEnterBMMForm = TRUE;
@@ -1119,6 +1125,8 @@ BootMaintCallback (
HiiGetBrowserData (&mBootMaintGuid, mBootMaintStorageName, sizeof (BMM_FAKE_NV_DATA), (UINT8 *) CurrentFakeNVMap);
if (Action == EFI_BROWSER_ACTION_CHANGING) {
DEBUG ((EFI_D_INFO, "EFI_BROWSER_ACTION_CHANGING: 0x%0X\n", QuestionId));
if (Value == NULL) {
return EFI_INVALID_PARAMETER;
}
@@ -1204,6 +1212,8 @@ BootMaintCallback (
ChooseFile (NULL, L".efi", BootFromFile, &File);
}
} else if (Action == EFI_BROWSER_ACTION_CHANGED) {
DEBUG ((EFI_D_INFO, "EFI_BROWSER_ACTION_CHANGED: 0x%0X\n", QuestionId));
if ((Value == NULL) || (ActionRequest == NULL)) {
return EFI_INVALID_PARAMETER;
}
@@ -1243,6 +1253,11 @@ BootMaintCallback (
CurrentFakeNVMap->DriverOptionChanged = TRUE;
}
if (QuestionId == BOOT_OPTION_ORDER_QUESTION_ID) {
// Save BootOrder on list update
*ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY;
}
if ((QuestionId >= BOOT_OPTION_DEL_QUESTION_ID) && (QuestionId < BOOT_OPTION_DEL_QUESTION_ID + MAX_MENU_NUMBER)) {
if (Value->b){
//
@@ -1306,6 +1321,7 @@ BootMaintCallback (
//
HiiSetBrowserData (&mBootMaintGuid, mBootMaintStorageName, sizeof (BMM_FAKE_NV_DATA), (UINT8 *) CurrentFakeNVMap, NULL);
DEBUG ((EFI_D_INFO, "%a complete: %r\n", __FUNCTION__, EFI_SUCCESS));
return EFI_SUCCESS;
}
@@ -1630,6 +1646,28 @@ BmmInitialBootModeInfo (
mBmmModeInitialized = TRUE;
}
STATIC
EFI_STATUS
UnregisterHotKeys(VOID)
{
EFI_STATUS Status;
EFI_INPUT_KEY HotKey;
EDKII_FORM_BROWSER_EXTENSION2_PROTOCOL *FormBrowserEx2;
Status = gBS->LocateProtocol (&gEdkiiFormBrowserEx2ProtocolGuid, NULL, (VOID **) &FormBrowserEx2);
if (!EFI_ERROR (Status)) {
HotKey.UnicodeChar = CHAR_NULL;
HotKey.ScanCode = SCAN_F9;
FormBrowserEx2->RegisterHotKey(&HotKey, BROWSER_ACTION_UNREGISTER, 0, NULL);
HotKey.ScanCode = SCAN_F10;
FormBrowserEx2->RegisterHotKey(&HotKey, BROWSER_ACTION_UNREGISTER, 0, NULL);
}
return Status;
}
/**
Install Boot Maintenance Manager Menu driver.
@@ -1705,8 +1743,8 @@ BootMaintenanceManagerUiLibConstructor (
mBmmCallbackInfo->MenuEntry = (BM_MENU_ENTRY *) Ptr;
mBmmCallbackInfo->BmmPreviousPageId = FORM_MAIN_ID;
mBmmCallbackInfo->BmmCurrentPageId = FORM_MAIN_ID;
mBmmCallbackInfo->BmmPreviousPageId = FORM_BOOT_CHG_ID;
mBmmCallbackInfo->BmmCurrentPageId = FORM_BOOT_CHG_ID;
InitAllMenu (mBmmCallbackInfo);
@@ -1718,6 +1756,11 @@ BootMaintenanceManagerUiLibConstructor (
BmmInitialBootModeInfo();
//
// Remove the F9 and F10 hotkeys
//
UnregisterHotKeys();
return EFI_SUCCESS;
}

View File

@@ -19,19 +19,28 @@ formset
name = BmmData,
guid = BOOT_MAINT_FORMSET_GUID;
form formid = FORM_BOOT_CHG_ID,
title = STRING_TOKEN(STR_FORM_BOOT_CHG_TITLE);
//
// Add this invisible text in order to indicate enter Boot Maintenance Manager form.
// To trigger the form open action.
//
suppressif TRUE;
text
help = STRING_TOKEN(STR_NONE),
text = STRING_TOKEN(STR_NONE),
flags = INTERACTIVE,
key = KEY_VALUE_TRIGGER_FORM_OPEN_ACTION;
endif;
label FORM_BOOT_CHG_ID;
label LABEL_END;
endform;
form formid = FORM_MAIN_ID,
title = STRING_TOKEN(STR_FORM_MAIN_TITLE);
//
// Add this invisible text in order to indicate enter Boot Maintenance Manager form.
// To trigger the form open action.
//
suppressif TRUE;
text
help = STRING_TOKEN(STR_NONE),
text = STRING_TOKEN(STR_NONE),
flags = INTERACTIVE,
key = KEY_VALUE_TRIGGER_FORM_OPEN_ACTION;
endif;
label LABEL_FORM_MAIN_START;
//
@@ -148,14 +157,6 @@ formset
label LABEL_END;
endform;
form formid = FORM_BOOT_CHG_ID,
title = STRING_TOKEN(STR_FORM_BOOT_CHG_TITLE);
label FORM_BOOT_CHG_ID;
label LABEL_END;
endform;
form formid = FORM_DRV_ADD_ID,
title = STRING_TOKEN(STR_FORM_DRV_ADD_TITLE);

View File

@@ -17,11 +17,11 @@
#language fr-FR "NONE"
#string STR_MISSING_STRING #language en-US "Missing String"
#language fr-FR "Missing String"
#string STR_FORM_MAIN_TITLE #language en-US "Boot Maintenance Manager"
#string STR_FORM_MAIN_TITLE #language en-US "Change Boot Order"
#language fr-FR "Boot Maintenance Manager"
#string STR_FORM_BOOT_SETUP_TITLE #language en-US "Boot Options"
#language fr-FR "Boot Options"
#string STR_BOOT_MAINT_MANAGER_HELP #language en-US "This selection will take you to the Boot Maintenance Manager"
#string STR_BOOT_MAINT_MANAGER_HELP #language en-US "Change the order of boot entries"
#language fr-FR "This selection will take you to the Boot Maintenance Manager"
#string STR_FORM_BOOT_SETUP_HELP #language en-US "Modify system boot options"
#language fr-FR "Modify system boot options"
@@ -251,7 +251,7 @@
#language fr-FR "Boot system from a file or device"
#string STR_OPTIONAL_DATA #language en-US "Input Optional Data"
#language fr-FR "Input Optional Data"
#string STR_CHANGE_ORDER #language en-US "Change the order"
#string STR_CHANGE_ORDER #language en-US "Change Boot Order"
#language fr-FR "Change the order"
#string STR_BOOT_LEGACY #language en-US "Boot Legacy System"
#language fr-FR "Boot Legacy System"

View File

@@ -115,36 +115,36 @@ UpdatePageEnd (
//
// Create the "Apply changes" and "Discard changes" tags.
//
if (CallbackData->BmmAskSaveOrNot) {
HiiCreateSubTitleOpCode (
mStartOpCodeHandle,
STRING_TOKEN (STR_NULL_STRING),
0,
0,
0
);
//if (CallbackData->BmmAskSaveOrNot) {
// HiiCreateSubTitleOpCode (
// mStartOpCodeHandle,
// STRING_TOKEN (STR_NULL_STRING),
// 0,
// 0,
// 0
// );
HiiCreateActionOpCode (
mStartOpCodeHandle,
KEY_VALUE_SAVE_AND_EXIT,
STRING_TOKEN (STR_SAVE_AND_EXIT),
STRING_TOKEN (STR_NULL_STRING),
EFI_IFR_FLAG_CALLBACK,
0
);
}
// HiiCreateActionOpCode (
// mStartOpCodeHandle,
// KEY_VALUE_SAVE_AND_EXIT,
// STRING_TOKEN (STR_SAVE_AND_EXIT),
// STRING_TOKEN (STR_NULL_STRING),
// EFI_IFR_FLAG_CALLBACK,
// 0
// );
//}
//
// Ensure user can return to the main page.
//
HiiCreateActionOpCode (
mStartOpCodeHandle,
KEY_VALUE_NO_SAVE_AND_EXIT,
STRING_TOKEN (STR_NO_SAVE_AND_EXIT),
STRING_TOKEN (STR_NULL_STRING),
EFI_IFR_FLAG_CALLBACK,
0
);
//HiiCreateActionOpCode (
// mStartOpCodeHandle,
// KEY_VALUE_NO_SAVE_AND_EXIT,
// STRING_TOKEN (STR_NO_SAVE_AND_EXIT),
// STRING_TOKEN (STR_NULL_STRING),
// EFI_IFR_FLAG_CALLBACK,
// 0
// );
HiiUpdateForm (
CallbackData->BmmHiiHandle,
@@ -642,7 +642,7 @@ UpdateOrderPage (
VarOffset, // Offset in Buffer Storage
STRING_TOKEN (STR_CHANGE_ORDER), // Question prompt text
STRING_TOKEN (STR_CHANGE_ORDER), // Question help text
0, // Question flag
EFI_IFR_FLAG_CALLBACK, // Question flag
0, // Ordered list flag, e.g. EFI_IFR_UNIQUE_SET
EFI_IFR_TYPE_NUM_SIZE_32, // Data type of Question value
100, // Maximum container
@@ -1143,8 +1143,8 @@ UpdatePageId (
NewPageId = FORM_CON_COM_SETUP_ID;
}
if ((NewPageId > 0) && (NewPageId < MAXIMUM_FORM_ID)) {
Private->BmmPreviousPageId = Private->BmmCurrentPageId;
Private->BmmCurrentPageId = NewPageId;
}
//if ((NewPageId > 0) && (NewPageId < MAXIMUM_FORM_ID)) {
// Private->BmmPreviousPageId = Private->BmmCurrentPageId;
// Private->BmmCurrentPageId = NewPageId;
//}
}

View File

@@ -631,6 +631,7 @@ Var_UpdateBootOrder (
BOpt_FreeMenu (&BootOptionMenu);
BOpt_GetBootOptions (CallbackData);
DEBUG ((EFI_D_INFO, "Updated BootOrder: %r\n", Status));
return Status;
}

View File

@@ -8,6 +8,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include "BootManager.h"
#include <Protocol/BlockIo.h>
UINT16 mKeyInput;
EFI_GUID mBootManagerGuid = BOOT_MANAGER_FORMSET_GUID;
//
@@ -27,6 +29,10 @@ UINT32 mBmSetupVerticalResolution = 0;
BOOLEAN mBmModeInitialized = FALSE;
STATIC EFI_EVENT mBmRefreshEvent;
STATIC CONST EFI_GUID mBmRefreshGuid = BOOT_MANAGER_REFRESH_GUID;
STATIC VOID *mBlockIoRegistration; // Unused
CHAR16 *mDeviceTypeStr[] = {
L"Legacy BEV",
L"Legacy Floppy",
@@ -484,22 +490,10 @@ UpdateBootManager (
BOOLEAN IsLegacyOption;
BOOLEAN NeedEndOp;
UINTN MaxLen;
UINTN OptionCount = 0;
DeviceType = (UINT16) -1;
//
// for better user experience
// 1. User changes HD configuration (e.g.: unplug HDD), here we have a chance to remove the HDD boot option
// 2. User enables/disables UEFI PXE, here we have a chance to add/remove EFI Network boot option
//
EfiBootManagerRefreshAllBootOption ();
//
// BdsDxe doesn't group the legacy boot options for the same device type
// It's UI's choice.
//
GroupMultipleLegacyBootOption4SameType ();
BootOption = EfiBootManagerGetLoadOptions (&BootOptionCount, LoadOptionTypeBoot);
HiiHandle = gBootManagerPrivate.HiiHandle;
@@ -526,6 +520,7 @@ UpdateBootManager (
EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (EndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
EndLabel->Number = LABEL_BOOT_OPTION_END;
mKeyInput = 0;
NeedEndOp = FALSE;
for (Index = 0; Index < BootOptionCount; Index++) {
@@ -541,6 +536,8 @@ UpdateBootManager (
continue;
}
OptionCount++;
//
// Group the legacy boot option in the sub title created dynamically
//
@@ -596,6 +593,10 @@ UpdateBootManager (
);
}
if (OptionCount == 0) {
HiiCreateSubTitleOpCode (StartOpCodeHandle, STRING_TOKEN (STR_NO_BOOTABLE_MEDIA), 0, 0, 0);
}
if (NeedEndOp) {
HiiCreateEndOpCode (StartOpCodeHandle);
}
@@ -787,7 +788,7 @@ BootManagerCallback (
{
EFI_BOOT_MANAGER_LOAD_OPTION *BootOption;
UINTN BootOptionCount;
EFI_INPUT_KEY Key;
//EFI_INPUT_KEY Key;
if (Action == EFI_BROWSER_ACTION_FORM_OPEN) {
//
@@ -831,19 +832,39 @@ BootManagerCallback (
EfiBootManagerBoot (&BootOption[QuestionId - 1]);
BmSetConsoleMode (TRUE);
if (EFI_ERROR (BootOption[QuestionId - 1].Status)) {
gST->ConOut->OutputString (
gST->ConOut,
HiiGetString (gBootManagerPrivate.HiiHandle, STRING_TOKEN (STR_ANY_KEY_CONTINUE), NULL)
);
gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
}
//if (EFI_ERROR (BootOption[QuestionId - 1].Status)) {
// gST->ConOut->OutputString (
// gST->ConOut,
// HiiGetString (gBootManagerPrivate.HiiHandle, STRING_TOKEN (STR_ANY_KEY_CONTINUE), NULL)
// );
// gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
//}
EfiBootManagerFreeLoadOptions (BootOption, BootOptionCount);
return EFI_SUCCESS;
}
STATIC
VOID
EFIAPI
RefreshBootOptions(
IN EFI_EVENT Event,
IN VOID *Context
)
{
EFI_TPL OldTpl = gBS->RaiseTPL(TPL_CALLBACK);
EfiBootManagerRefreshAllBootOption();
// BdsDxe doesn't group the legacy boot options for the same device type. It's UI's choice.
GroupMultipleLegacyBootOption4SameType();
UpdateBootManager();
gBS->RestoreTPL (OldTpl);
}
/**
Install Boot Manager Menu driver.
@@ -892,6 +913,23 @@ BootManagerUiLibConstructor (
BmInitialBootModeInfo ();
Status = gBS->CreateEventEx(
EVT_NOTIFY_SIGNAL,
TPL_CALLBACK,
RefreshBootOptions,
NULL,
&mBmRefreshGuid,
&mBmRefreshEvent
);
ASSERT_EFI_ERROR(Status);
Status = gBS->RegisterProtocolNotify (
&gEfiBlockIoProtocolGuid,
mBmRefreshEvent,
&mBlockIoRegistration
);
ASSERT_EFI_ERROR (Status);
return EFI_SUCCESS;
}
@@ -912,6 +950,8 @@ BootManagerUiLibDestructor (
{
EFI_STATUS Status;
gBS->CloseEvent(mBmRefreshEvent);
Status = gBS->UninstallMultipleProtocolInterfaces (
gBootManagerPrivate.DriverHandle,
&gEfiDevicePathProtocolGuid,

View File

@@ -46,7 +46,12 @@ typedef struct {
0x847bc3fe, 0xb974, 0x446d, {0x94, 0x49, 0x5a, 0xd5, 0x41, 0x2e, 0x99, 0x3b} \
}
#define BOOT_MANAGER_FORM_ID 0x1000
#define BOOT_MANAGER_REFRESH_GUID \
{ \
0x7648C827, 0xBE32, 0x44D2, { 0xA1, 0x33, 0xF1, 0x7F, 0x93, 0x76, 0xC7, 0x00 } \
}
#define BOOT_MANAGER_FORM_ID 0x1030
#define LABEL_BOOT_OPTION 0x00
#define LABEL_BOOT_OPTION_END 0x01

View File

@@ -17,20 +17,9 @@
/=#
#langdef en-US "English"
#langdef fr-FR "Français"
#string STR_BM_BANNER #language en-US "Boot Manager"
#language fr-FR "Boot Manager"
#string STR_BOOT_MANAGER_HELP #language en-US "This selection will take you to the Boot Manager"
#language fr-FR "This selection will take you to the Boot Manager"
#string STR_HELP_FOOTER #language en-US "Use the <↑> and <↓> keys to choose a boot option, the <Enter> key to select a boot option, and the <Esc> key to exit the Boot Manager Menu."
#language fr-FR "<↑> pour <↓> changer l'option, <ENTRER> choisir une option, <ESC> pour sortir"
#string STR_AND #language en-US " and "
#language fr-FR " et "
#string STR_BOOT_OPTION_BANNER #language en-US "Boot Manager Menu"
#language fr-FR "le Menu d'Option de Botte"
#string STR_BM_BANNER #language en-US "One Time Boot"
#string STR_BOOT_MANAGER_HELP #language en-US "Boot an entry one time"
#string STR_ANY_KEY_CONTINUE #language en-US "Press any key to continue..."
#language fr-FR "Appuie n'importe quelle pour continuer..."
#string STR_LAST_STRING #language en-US ""
#language fr-FR ""
#string STR_NO_BOOTABLE_MEDIA #language en-US "No bootable media found"
#string STR_EMPTY_STRING #language en-US ""

View File

@@ -51,6 +51,7 @@
gEfiHiiConfigAccessProtocolGuid ## CONSUMES
gEfiDevicePathToTextProtocolGuid ## CONSUMES
gEdkiiFormBrowserEx2ProtocolGuid ## CONSUMES
gEfiBlockIoProtocolGuid
[FeaturePcd]

View File

@@ -7,8 +7,9 @@
//
//**/
#define FORMSET_GUID { 0x847bc3fe, 0xb974, 0x446d, 0x94, 0x49, 0x5a, 0xd5, 0x41, 0x2e, 0x99, 0x3b }
#define BOOT_MANAGER_REFRESH_GUID { 0x7648C827, 0xBE32, 0x44D2, { 0xA1, 0x33, 0xF1, 0x7F, 0x93, 0x76, 0xC7, 0x00 }}
#define BOOT_MANAGER_FORM_ID 0x1000
#define BOOT_MANAGER_FORM_ID 0x1030
#define LABEL_BOOT_OPTION 0x00
#define LABEL_BOOT_OPTION_END 0x01
@@ -20,22 +21,19 @@ formset
classguid = gEfiIfrFrontPageGuid,
form formid = BOOT_MANAGER_FORM_ID,
title = STRING_TOKEN(STR_BM_BANNER);
subtitle text = STRING_TOKEN(STR_LAST_STRING);
subtitle text = STRING_TOKEN(STR_BOOT_OPTION_BANNER);
subtitle text = STRING_TOKEN(STR_LAST_STRING);
title = STRING_TOKEN(STR_BM_BANNER);
refreshguid = BOOT_MANAGER_REFRESH_GUID;
//
//Add this invisable text in order to indicate enter Boot Manager form.
//
suppressif TRUE;
text
help = STRING_TOKEN(STR_LAST_STRING ),
text = STRING_TOKEN(STR_LAST_STRING ),
flags = INTERACTIVE,
key = 0x1212;
endif;
text
help = STRING_TOKEN(STR_EMPTY_STRING),
text = STRING_TOKEN(STR_EMPTY_STRING),
flags = INTERACTIVE,
key = 0x1212;
endif;
//
// This is where we will dynamically add choices for the Boot Manager
@@ -43,9 +41,6 @@ formset
label LABEL_BOOT_OPTION;
label LABEL_BOOT_OPTION_END;
subtitle text = STRING_TOKEN(STR_LAST_STRING);
subtitle text = STRING_TOKEN(STR_HELP_FOOTER);
endform;
endformset;

View File

@@ -1779,6 +1779,8 @@ EfiBootManagerBoot (
UINTN FileSize;
EFI_BOOT_LOGO_PROTOCOL *BootLogo;
EFI_EVENT LegacyBootEvent;
EFI_INPUT_KEY Key;
UINTN Index;
if (BootOption == NULL) {
return;
@@ -1914,6 +1916,19 @@ EfiBootManagerBoot (
BmDestroyRamDisk (RamDiskDevicePath);
FreePool (RamDiskDevicePath);
}
if (gST->ConIn != NULL) {
gST->ConOut->ClearScreen (gST->ConOut);
AsciiPrint (
"Boot Failed. %s\n"
"Press any key to continue...\n",
BootOption->Description);
Status = gBS->WaitForEvent (1, &gST->ConIn->WaitForKey, &Index);
ASSERT_EFI_ERROR (Status);
ASSERT (Index == 0);
while (!EFI_ERROR (gST->ConIn->ReadKeyStroke (gST->ConIn, &Key))) {}
}
return;
}
}
@@ -2085,6 +2100,322 @@ BmMatchPartitionDevicePathNode (
return FALSE;
}
/**
Get the headers (dos, image, optional header) from an image
@param Device SimpleFileSystem device handle
@param FileName File name for the image
@param DosHeader Pointer to dos header
@param Hdr The buffer in which to return the PE32, PE32+, or TE header.
@retval EFI_SUCCESS Successfully get the machine type.
@retval EFI_NOT_FOUND The file is not found.
@retval EFI_LOAD_ERROR File is not a valid image file.
**/
STATIC
EFI_STATUS
EFIAPI
BdsLibGetImageHeader (
IN EFI_HANDLE Device,
IN CHAR16 *FileName,
OUT EFI_IMAGE_DOS_HEADER *DosHeader,
OUT EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr
)
{
EFI_STATUS Status;
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *Volume;
EFI_FILE_HANDLE Root;
EFI_FILE_HANDLE ThisFile;
UINTN BufferSize;
UINT64 FileSize;
EFI_FILE_INFO *Info;
Root = NULL;
ThisFile = NULL;
//
// Handle the file system interface to the device
//
Status = gBS->HandleProtocol (
Device,
&gEfiSimpleFileSystemProtocolGuid,
(VOID *) &Volume
);
if (EFI_ERROR (Status)) {
goto Done;
}
Status = Volume->OpenVolume (
Volume,
&Root
);
if (EFI_ERROR (Status)) {
Root = NULL;
goto Done;
}
ASSERT (Root != NULL);
Status = Root->Open (Root, &ThisFile, FileName, EFI_FILE_MODE_READ, 0);
if (EFI_ERROR (Status)) {
goto Done;
}
ASSERT (ThisFile != NULL);
//
// Get file size
//
BufferSize = SIZE_OF_EFI_FILE_INFO + 200;
do {
Info = NULL;
Status = gBS->AllocatePool (EfiBootServicesData, BufferSize, (VOID **) &Info);
if (EFI_ERROR (Status)) {
goto Done;
}
Status = ThisFile->GetInfo (
ThisFile,
&gEfiFileInfoGuid,
&BufferSize,
Info
);
if (!EFI_ERROR (Status)) {
break;
}
if (Status != EFI_BUFFER_TOO_SMALL) {
FreePool (Info);
goto Done;
}
FreePool (Info);
} while (TRUE);
FileSize = Info->FileSize;
FreePool (Info);
//
// Read dos header
//
BufferSize = sizeof (EFI_IMAGE_DOS_HEADER);
Status = ThisFile->Read (ThisFile, &BufferSize, DosHeader);
if (EFI_ERROR (Status) ||
BufferSize < sizeof (EFI_IMAGE_DOS_HEADER) ||
FileSize <= DosHeader->e_lfanew ||
DosHeader->e_magic != EFI_IMAGE_DOS_SIGNATURE) {
Status = EFI_LOAD_ERROR;
goto Done;
}
//
// Move to PE signature
//
Status = ThisFile->SetPosition (ThisFile, DosHeader->e_lfanew);
if (EFI_ERROR (Status)) {
Status = EFI_LOAD_ERROR;
goto Done;
}
//
// Read and check PE signature
//
BufferSize = sizeof (EFI_IMAGE_OPTIONAL_HEADER_UNION);
Status = ThisFile->Read (ThisFile, &BufferSize, Hdr.Pe32);
if (EFI_ERROR (Status) ||
BufferSize < sizeof (EFI_IMAGE_OPTIONAL_HEADER_UNION) ||
Hdr.Pe32->Signature != EFI_IMAGE_NT_SIGNATURE) {
Status = EFI_LOAD_ERROR;
goto Done;
}
//
// Check PE32 or PE32+ magic
//
if (Hdr.Pe32->OptionalHeader.Magic != EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC &&
Hdr.Pe32->OptionalHeader.Magic != EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {
Status = EFI_LOAD_ERROR;
goto Done;
}
Done:
if (ThisFile != NULL) {
ThisFile->Close (ThisFile);
}
if (Root != NULL) {
Root->Close (Root);
}
return Status;
}
/**
Return the bootable media handle.
First, check the device is connected
Second, check whether the device path point to a device which support SimpleFileSystemProtocol,
Third, detect the the default boot file in the Media, and return the removable Media handle.
@param DevicePath Device Path to a bootable device
@return The bootable media handle. If the media on the DevicePath is not bootable, NULL will return.
**/
EFI_HANDLE
EFIAPI
BdsLibGetBootableHandle (
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
)
{
EFI_STATUS Status;
EFI_TPL OldTpl;
EFI_DEVICE_PATH_PROTOCOL *UpdatedDevicePath;
EFI_DEVICE_PATH_PROTOCOL *DupDevicePath;
EFI_HANDLE Handle;
EFI_BLOCK_IO_PROTOCOL *BlockIo;
VOID *Buffer;
EFI_DEVICE_PATH_PROTOCOL *TempDevicePath;
UINTN Size;
UINTN TempSize;
EFI_HANDLE ReturnHandle;
EFI_HANDLE *SimpleFileSystemHandles;
UINTN NumberSimpleFileSystemHandles;
UINTN Index;
EFI_IMAGE_DOS_HEADER DosHeader;
EFI_IMAGE_OPTIONAL_HEADER_UNION HdrData;
EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr;
UpdatedDevicePath = DevicePath;
//
// Enter to critical section to protect the acquired BlockIo instance
// from getting released due to the USB mass storage hotplug event
//
OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
//
// Check whether the device is connected
//
Status = gBS->LocateDevicePath (&gEfiBlockIoProtocolGuid, &UpdatedDevicePath, &Handle);
if (EFI_ERROR (Status)) {
//
// Skip the case that the boot option point to a simple file protocol which does not consume block Io protocol,
//
Status = gBS->LocateDevicePath (&gEfiSimpleFileSystemProtocolGuid, &UpdatedDevicePath, &Handle);
if (EFI_ERROR (Status)) {
//
// Fail to find the proper BlockIo and simple file protocol, maybe because device not present, we need to connect it firstly
//
UpdatedDevicePath = DevicePath;
Status = gBS->LocateDevicePath (&gEfiDevicePathProtocolGuid, &UpdatedDevicePath, &Handle);
gBS->ConnectController (Handle, NULL, NULL, TRUE);
}
} else {
//
// For removable device boot option, its contained device path only point to the removable device handle,
// should make sure all its children handles (its child partion or media handles) are created and connected.
//
gBS->ConnectController (Handle, NULL, NULL, TRUE);
//
// Get BlockIo protocol and check removable attribute
//
Status = gBS->HandleProtocol (Handle, &gEfiBlockIoProtocolGuid, (VOID **)&BlockIo);
ASSERT_EFI_ERROR (Status);
//
// Issue a dummy read to the device to check for media change.
// When the removable media is changed, any Block IO read/write will
// cause the BlockIo protocol be reinstalled and EFI_MEDIA_CHANGED is
// returned. After the Block IO protocol is reinstalled, subsequent
// Block IO read/write will success.
//
Buffer = AllocatePool (BlockIo->Media->BlockSize);
if (Buffer != NULL) {
BlockIo->ReadBlocks (
BlockIo,
BlockIo->Media->MediaId,
0,
BlockIo->Media->BlockSize,
Buffer
);
FreePool(Buffer);
}
}
//
// Detect the the default boot file from removable Media
//
//
// If fail to get bootable handle specified by a USB boot option, the BDS should try to find other bootable device in the same USB bus
// Try to locate the USB node device path first, if fail then use its previous PCI node to search
//
DupDevicePath = DuplicateDevicePath (DevicePath);
ASSERT (DupDevicePath != NULL);
UpdatedDevicePath = DupDevicePath;
Status = gBS->LocateDevicePath (&gEfiDevicePathProtocolGuid, &UpdatedDevicePath, &Handle);
//
// if the resulting device path point to a usb node, and the usb node is a dummy node, should only let device path only point to the previous Pci node
// Acpi()/Pci()/Usb() --> Acpi()/Pci()
//
if ((DevicePathType (UpdatedDevicePath) == MESSAGING_DEVICE_PATH) &&
(DevicePathSubType (UpdatedDevicePath) == MSG_USB_DP)) {
//
// Remove the usb node, let the device path only point to PCI node
//
SetDevicePathEndNode (UpdatedDevicePath);
UpdatedDevicePath = DupDevicePath;
} else {
UpdatedDevicePath = DevicePath;
}
//
// Get the device path size of boot option
//
Size = GetDevicePathSize(UpdatedDevicePath) - sizeof (EFI_DEVICE_PATH_PROTOCOL); // minus the end node
ReturnHandle = NULL;
gBS->LocateHandleBuffer (
ByProtocol,
&gEfiSimpleFileSystemProtocolGuid,
NULL,
&NumberSimpleFileSystemHandles,
&SimpleFileSystemHandles
);
for (Index = 0; Index < NumberSimpleFileSystemHandles; Index++) {
//
// Get the device path size of SimpleFileSystem handle
//
TempDevicePath = DevicePathFromHandle (SimpleFileSystemHandles[Index]);
TempSize = GetDevicePathSize (TempDevicePath)- sizeof (EFI_DEVICE_PATH_PROTOCOL); // minus the end node
//
// Check whether the device path of boot option is part of the SimpleFileSystem handle's device path
//
if (Size <= TempSize && CompareMem (TempDevicePath, UpdatedDevicePath, Size)==0) {
//
// Load the default boot file \EFI\BOOT\boot{machinename}.EFI from removable Media
// machinename is ia32, ia64, x64, ...
//
Hdr.Union = &HdrData;
Status = BdsLibGetImageHeader (
SimpleFileSystemHandles[Index],
EFI_REMOVABLE_MEDIA_FILE_NAME,
&DosHeader,
Hdr
);
if (!EFI_ERROR (Status) &&
EFI_IMAGE_MACHINE_TYPE_SUPPORTED (Hdr.Pe32->FileHeader.Machine) &&
Hdr.Pe32->OptionalHeader.Subsystem == EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION) {
ReturnHandle = SimpleFileSystemHandles[Index];
break;
}
}
}
FreePool(DupDevicePath);
if (SimpleFileSystemHandles != NULL) {
FreePool(SimpleFileSystemHandles);
}
gBS->RestoreTPL (OldTpl);
return ReturnHandle;
}
/**
Emuerate all possible bootable medias in the following order:
1. Removable BlockIo - The boot option only points to the removable media
@@ -2115,6 +2446,7 @@ BmEnumerateBootOptions (
UINTN Removable;
UINTN Index;
CHAR16 *Description;
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
ASSERT (BootOptionCount != NULL);
@@ -2150,6 +2482,12 @@ BmEnumerateBootOptions (
continue;
}
// Skip devices that do not have an EFI volume
DevicePath = DevicePathFromHandle (Handles[Index]);
if (BdsLibGetBootableHandle (DevicePath) == NULL) {
continue;
}
//
// Skip the fixed block io then the removable block io
//

View File

@@ -15,7 +15,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#define PRODUCT_IDENTIFICATION_LENGTH 16
CONST UINT16 mBmUsbLangId = 0x0409; // English
CHAR16 mBmUefiPrefix[] = L"UEFI ";
//CHAR16 mBmUefiPrefix[] = L"UEFI ";
LIST_ENTRY mPlatformBootDescriptionHandlers = INITIALIZE_LIST_HEAD_VARIABLE (mPlatformBootDescriptionHandlers);
@@ -179,15 +179,15 @@ BmGetDescriptionFromDiskInfo (
}
Length = Index;
Description[Length++] = L' ';
//Description[Length++] = L' ';
for (Index = 0; Index + 1 < SerialNumberLength; Index += 2) {
Description[Length + Index] = (CHAR16) IdentifyData.SerialNo[Index + 1];
Description[Length + Index + 1] = (CHAR16) IdentifyData.SerialNo[Index];
}
Length += Index;
//for (Index = 0; Index + 1 < SerialNumberLength; Index += 2) {
// Description[Length + Index] = (CHAR16) IdentifyData.SerialNo[Index + 1];
// Description[Length + Index + 1] = (CHAR16) IdentifyData.SerialNo[Index];
//}
//Length += Index;
Description[Length++] = L'\0';
ASSERT (Length == ModelNameLength + SerialNumberLength + 2);
//ASSERT (Length == ModelNameLength + SerialNumberLength + 2);
BmEliminateExtraSpaces (Description);
}
@@ -309,15 +309,16 @@ BmGetUsbDescription (
Product = &NullChar;
}
Status = UsbIo->UsbGetStringDescriptor (
UsbIo,
mBmUsbLangId,
DevDesc.StrSerialNumber,
&SerialNumber
);
if (EFI_ERROR (Status)) {
SerialNumber = &NullChar;
}
//Status = UsbIo->UsbGetStringDescriptor (
// UsbIo,
// mBmUsbLangId,
// DevDesc.StrSerialNumber,
// &SerialNumber
// );
//if (EFI_ERROR (Status)) {
// SerialNumber = &NullChar;
//}
SerialNumber = &NullChar;
if ((Manufacturer == &NullChar) &&
(Product == &NullChar) &&
@@ -630,15 +631,15 @@ BmGetNvmeDescription (
for (Index = 0; Index < ARRAY_SIZE (ControllerData.Mn); Index++) {
*(Char++) = (CHAR16) ControllerData.Mn[Index];
}
*(Char++) = L' ';
for (Index = 0; Index < ARRAY_SIZE (ControllerData.Sn); Index++) {
*(Char++) = (CHAR16) ControllerData.Sn[Index];
}
*(Char++) = L' ';
UnicodeValueToStringS (
Char, sizeof (CHAR16) * (MAXIMUM_VALUE_CHARACTERS + 1),
0, DevicePath.NvmeNamespace->NamespaceId, 0
);
//*(Char++) = L' ';
//for (Index = 0; Index < ARRAY_SIZE (ControllerData.Sn); Index++) {
// *(Char++) = (CHAR16) ControllerData.Sn[Index];
//}
//*(Char++) = L' ';
//UnicodeValueToStringS (
// Char, sizeof (CHAR16) * (MAXIMUM_VALUE_CHARACTERS + 1),
// 0, DevicePath.NvmeNamespace->NamespaceId, 0
// );
BmEliminateExtraSpaces (Description);
}
@@ -785,10 +786,12 @@ BmGetBootDescription (
// Avoid description confusion between UEFI & Legacy boot option by adding "UEFI " prefix
// ONLY for core provided boot description handler.
//
Temp = AllocatePool (StrSize (DefaultDescription) + sizeof (mBmUefiPrefix));
//Temp = AllocatePool (StrSize (DefaultDescription) + sizeof (mBmUefiPrefix));
Temp = AllocatePool (StrSize (DefaultDescription));
ASSERT (Temp != NULL);
StrCpyS (Temp, (StrSize (DefaultDescription) + sizeof (mBmUefiPrefix)) / sizeof (CHAR16), mBmUefiPrefix);
StrCatS (Temp, (StrSize (DefaultDescription) + sizeof (mBmUefiPrefix)) / sizeof (CHAR16), DefaultDescription);
//StrCpyS (Temp, (StrSize (DefaultDescription) + sizeof (mBmUefiPrefix)) / sizeof (CHAR16), mBmUefiPrefix);
//StrCatS (Temp, (StrSize (DefaultDescription) + sizeof (mBmUefiPrefix)) / sizeof (CHAR16), DefaultDescription);
StrCpyS (Temp, StrSize (DefaultDescription) / sizeof (CHAR16), DefaultDescription);
FreePool (DefaultDescription);
DefaultDescription = Temp;
break;

View File

@@ -155,7 +155,7 @@ BmSetMemoryTypeInformationVariable (
if (BootMode == BOOT_IN_RECOVERY_MODE) {
return;
}
return;
//
// Only check the the Memory Type Information variable in the boot mode
// other than BOOT_WITH_DEFAULT_SETTINGS because the Memory Type

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 315 KiB

View File

@@ -2092,3 +2092,8 @@
[UserExtensions.TianoCore."ExtraFiles"]
MdeModulePkgExtra.uni
[PcdsFixedAtBuild, PcdsPatchableInModule]
## FFS filename to find the default BMP Logo file.
# @Prompt FFS Name of Boot Logo File
gEfiMdeModulePkgTokenSpaceGuid.PcdLogoFile |{ 0x99, 0x8b, 0xB2, 0x7B, 0xBB, 0x61, 0xD5, 0x11, 0x9A, 0x5D, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D }|VOID*|0x40000003

View File

@@ -2,7 +2,7 @@
# EFI/PI Reference Module Package for All Architectures
#
# (C) Copyright 2014 Hewlett-Packard Development Company, L.P.<BR>
# Copyright (c) 2007 - 2019, Intel Corporation. All rights reserved.<BR>
# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
@@ -444,6 +444,9 @@
MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.inf
!endif
[Components.IA32, Components.X64, Components.Ebc]
MdeModulePkg/Universal/Variable/EmuRuntimeDxe/EmuVariableRuntimeDxe.inf
[Components.IA32, Components.X64]
MdeModulePkg/Universal/DebugSupportDxe/DebugSupportDxe.inf
MdeModulePkg/Application/SmiHandlerProfileInfo/SmiHandlerProfileInfo.inf

View File

@@ -325,7 +325,8 @@ BdsWait (
// Can be removed after all keyboard drivers invoke callback in timer callback.
if (HotkeyTriggered != NULL) {
Status = BdsWaitForSingleEvent (HotkeyTriggered, EFI_TIMER_PERIOD_SECONDS (1));
//Status = BdsWaitForSingleEvent (HotkeyTriggered, EFI_TIMER_PERIOD_SECONDS (1));
Status = BdsWaitForSingleEvent (gST->ConIn->WaitForKey, EFI_TIMER_PERIOD_SECONDS (1));
if (!EFI_ERROR (Status)) {
break;
}
@@ -1014,7 +1015,7 @@ BdsEntry (
//
// BdsReadKeys() can be removed after all keyboard drivers invoke callback in timer callback.
//
BdsReadKeys ();
//BdsReadKeys ();
EfiBootManagerHotkeyBoot ();

View File

@@ -38,8 +38,8 @@ EFI_DRIVER_BINDING_PROTOCOL gPartitionDriverBinding = {
//
PARTITION_DETECT_ROUTINE mPartitionDetectRoutineTable[] = {
PartitionInstallGptChildHandles,
PartitionInstallMbrChildHandles,
PartitionInstallUdfChildHandles,
PartitionInstallMbrChildHandles,
NULL
};

View File

@@ -25,7 +25,7 @@ typedef struct {
} DEFERRED_3RD_PARTY_IMAGE_TABLE;
BOOLEAN mImageLoadedAfterEndOfDxe = FALSE;
BOOLEAN mEndOfDxe = FALSE;
BOOLEAN mEndOfDxe = TRUE;
DEFERRED_3RD_PARTY_IMAGE_TABLE mDeferred3rdPartyImage = {
0, // Deferred image count
NULL // The deferred image info

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,88 @@
## @file
# Emulation Variable for EFI_RUNTIME_SERVICES.
#
# This module installs variable arch protocol and variable write arch protocol to provide
# four EFI_RUNTIME_SERVICES: SetVariable, GetVariable, GetNextVariableName and QueryVariableInfo.
#
# Copyright (c) 2006 - 2018, 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.
#
#
##
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = EmuVariableRuntimeDxe
MODULE_UNI_FILE = EmuVariableRuntimeDxe.uni
FILE_GUID = 02B01AD5-7E59-43e8-A6D8-238180613A5A
MODULE_TYPE = DXE_RUNTIME_DRIVER
VERSION_STRING = 1.0
ENTRY_POINT = VariableServiceInitialize
#
# The following information is for reference only and not required by the build tools.
#
# VALID_ARCHITECTURES = IA32 X64 EBC
#
[Sources]
InitVariable.c
EmuVariable.c
Variable.h
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
[LibraryClasses]
BaseLib
UefiLib
UefiBootServicesTableLib
UefiDriverEntryPoint
UefiRuntimeLib
DebugLib
MemoryAllocationLib
BaseMemoryLib
HobLib
PcdLib
[Protocols]
gEfiVariableArchProtocolGuid ## PRODUCES
gEfiVariableWriteArchProtocolGuid ## PRODUCES
[Guids]
gEfiEventVirtualAddressChangeGuid ## CONSUMES ## Event
## SOMETIMES_CONSUMES ## Variable:L"PlatformLang"
## SOMETIMES_PRODUCES ## Variable:L"PlatformLang"
## SOMETIMES_CONSUMES ## Variable:L"Lang"
## SOMETIMES_PRODUCES ## Variable:L"Lang"
gEfiGlobalVariableGuid
## PRODUCES ## GUID # Signature of Variable store header
## CONSUMES ## GUID # Signature of Variable store header
## SOMETIMES_CONSUMES ## HOB
## SOMETIMES_PRODUCES ## SystemTable
gEfiVariableGuid
[Pcd]
gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvStoreReserved ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdMaxHardwareErrorVariableSize ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdHwErrStorageSize ## CONSUMES
[FeaturePcd]
gEfiMdeModulePkgTokenSpaceGuid.PcdVariableCollectStatistics ## CONSUMES # statistic the information of variable.
[Depex]
TRUE
[UserExtensions.TianoCore."ExtraFiles"]
EmuVariableRuntimeDxeExtra.uni

View File

@@ -0,0 +1,22 @@
// /** @file
// Emulation Variable for EFI_RUNTIME_SERVICES.
//
// This module installs variable arch protocol and variable write arch protocol to provide
// four EFI_RUNTIME_SERVICES: SetVariable, GetVariable, GetNextVariableName and QueryVariableInfo.
//
// Copyright (c) 2006 - 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.
//
// **/
#string STR_MODULE_ABSTRACT #language en-US "Emulation Variable for EFI_RUNTIME_SERVICES"
#string STR_MODULE_DESCRIPTION #language en-US "This module installs variable arch protocol and variable write arch protocol to provide four EFI_RUNTIME_SERVICES: SetVariable, GetVariable, GetNextVariableName and QueryVariableInfo."

View File

@@ -0,0 +1,19 @@
// /** @file
// EmuVariableRuntimeDxe Localized Strings and Content
//
// Copyright (c) 2013 - 2018, 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.
//
// **/
#string STR_PROPERTIES_MODULE_NAME
#language en-US
"Emulation Variable DXE Driver"

View File

@@ -0,0 +1,259 @@
/** @file
Implment all four UEFI runtime variable services and
install variable architeture protocol.
Copyright (c) 2006 - 2018, 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 "Variable.h"
EFI_EVENT mVirtualAddressChangeEvent = NULL;
/**
This code finds variable in storage blocks (Volatile or Non-Volatile).
@param VariableName Name of Variable to be found.
@param VendorGuid Variable vendor GUID.
@param Attributes Attribute value of the variable found.
@param DataSize Size of Data found. If size is less than the
data, this value contains the required size.
@param Data The buffer to return the contents of the variable. May be NULL
with a zero DataSize in order to determine the size buffer needed.
@return EFI_INVALID_PARAMETER Invalid parameter
@return EFI_SUCCESS Find the specified variable
@return EFI_NOT_FOUND Not found
@return EFI_BUFFER_TO_SMALL DataSize is too small for the result
**/
EFI_STATUS
EFIAPI
RuntimeServiceGetVariable (
IN CHAR16 *VariableName,
IN EFI_GUID *VendorGuid,
OUT UINT32 *Attributes OPTIONAL,
IN OUT UINTN *DataSize,
OUT VOID *Data OPTIONAL
)
{
return EmuGetVariable (
VariableName,
VendorGuid,
Attributes OPTIONAL,
DataSize,
Data,
&mVariableModuleGlobal->VariableGlobal[Physical]
);
}
/**
This code Finds the Next available variable.
@param VariableNameSize The size of the VariableName buffer. The size must be large enough to fit input
string supplied in VariableName buffer.
@param VariableName On input, supplies the last VariableName that was returned by GetNextVariableName().
On output, returns the Null-terminated Unicode string of the current variable.
@param VendorGuid On input, supplies the last VendorGuid that was returned by GetNextVariableName().
On output, returns the VendorGuid of the current variable.
@retval EFI_SUCCESS The function completed successfully.
@retval EFI_NOT_FOUND The next variable was not found.
@retval EFI_BUFFER_TOO_SMALL The VariableNameSize is too small for the result.
VariableNameSize has been updated with the size needed to complete the request.
@retval EFI_INVALID_PARAMETER VariableNameSize or VariableName or VendorGuid is NULL.
@retval EFI_INVALID_PARAMETER The input values of VariableName and VendorGuid are not a name and
GUID of an existing variable.
@retval EFI_INVALID_PARAMETER Null-terminator is not found in the first VariableNameSize bytes of
the input VariableName buffer.
**/
EFI_STATUS
EFIAPI
RuntimeServiceGetNextVariableName (
IN OUT UINTN *VariableNameSize,
IN OUT CHAR16 *VariableName,
IN OUT EFI_GUID *VendorGuid
)
{
return EmuGetNextVariableName (
VariableNameSize,
VariableName,
VendorGuid,
&mVariableModuleGlobal->VariableGlobal[Physical]
);
}
/**
This code sets variable in storage blocks (Volatile or Non-Volatile).
@param VariableName Name of Variable to be found
@param VendorGuid Variable vendor GUID
@param Attributes Attribute value of the variable found
@param DataSize Size of Data found. If size is less than the
data, this value contains the required size.
@param Data Data pointer
@return EFI_INVALID_PARAMETER Invalid parameter
@return EFI_SUCCESS Set successfully
@return EFI_OUT_OF_RESOURCES Resource not enough to set variable
@return EFI_NOT_FOUND Not found
@return EFI_WRITE_PROTECTED Variable is read-only
**/
EFI_STATUS
EFIAPI
RuntimeServiceSetVariable (
IN CHAR16 *VariableName,
IN EFI_GUID *VendorGuid,
IN UINT32 Attributes,
IN UINTN DataSize,
IN VOID *Data
)
{
return EmuSetVariable (
VariableName,
VendorGuid,
Attributes,
DataSize,
Data,
&mVariableModuleGlobal->VariableGlobal[Physical],
&mVariableModuleGlobal->VolatileLastVariableOffset,
&mVariableModuleGlobal->NonVolatileLastVariableOffset
);
}
/**
This code returns information about the EFI variables.
@param Attributes Attributes bitmask to specify the type of variables
on which to return information.
@param MaximumVariableStorageSize Pointer to the maximum size of the storage space available
for the EFI variables associated with the attributes specified.
@param RemainingVariableStorageSize Pointer to the remaining size of the storage space available
for EFI variables associated with the attributes specified.
@param MaximumVariableSize Pointer to the maximum size of an individual EFI variables
associated with the attributes specified.
@return EFI_INVALID_PARAMETER An invalid combination of attribute bits was supplied.
@return EFI_SUCCESS Query successfully.
@return EFI_UNSUPPORTED The attribute is not supported on this platform.
**/
EFI_STATUS
EFIAPI
RuntimeServiceQueryVariableInfo (
IN UINT32 Attributes,
OUT UINT64 *MaximumVariableStorageSize,
OUT UINT64 *RemainingVariableStorageSize,
OUT UINT64 *MaximumVariableSize
)
{
return EmuQueryVariableInfo (
Attributes,
MaximumVariableStorageSize,
RemainingVariableStorageSize,
MaximumVariableSize,
&mVariableModuleGlobal->VariableGlobal[Physical]
);
}
/**
Notification function of EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE.
This is a notification function registered on EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE event.
It convers pointer to new virtual address.
@param Event Event whose notification function is being invoked.
@param Context Pointer to the notification function's context.
**/
VOID
EFIAPI
VariableClassAddressChangeEvent (
IN EFI_EVENT Event,
IN VOID *Context
)
{
EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->PlatformLangCodes);
EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->LangCodes);
EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->PlatformLang);
EfiConvertPointer (
0x0,
(VOID **) &mVariableModuleGlobal->VariableGlobal[Physical].NonVolatileVariableBase
);
EfiConvertPointer (
0x0,
(VOID **) &mVariableModuleGlobal->VariableGlobal[Physical].VolatileVariableBase
);
EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal);
}
/**
EmuVariable Driver main entry point. The Variable driver places the 4 EFI
runtime services in the EFI System Table and installs arch protocols
for variable read and write services being available. It also registers
notification function for EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE event.
@param[in] ImageHandle The firmware allocated handle for the EFI image.
@param[in] SystemTable A pointer to the EFI System Table.
@retval EFI_SUCCESS Variable service successfully initialized.
**/
EFI_STATUS
EFIAPI
VariableServiceInitialize (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EFI_HANDLE NewHandle;
EFI_STATUS Status;
Status = VariableCommonInitialize (ImageHandle, SystemTable);
ASSERT_EFI_ERROR (Status);
SystemTable->RuntimeServices->GetVariable = RuntimeServiceGetVariable;
SystemTable->RuntimeServices->GetNextVariableName = RuntimeServiceGetNextVariableName;
SystemTable->RuntimeServices->SetVariable = RuntimeServiceSetVariable;
SystemTable->RuntimeServices->QueryVariableInfo = RuntimeServiceQueryVariableInfo;
//
// Now install the Variable Runtime Architectural Protocol on a new handle
//
NewHandle = NULL;
Status = gBS->InstallMultipleProtocolInterfaces (
&NewHandle,
&gEfiVariableArchProtocolGuid,
NULL,
&gEfiVariableWriteArchProtocolGuid,
NULL,
NULL
);
ASSERT_EFI_ERROR (Status);
Status = gBS->CreateEventEx (
EVT_NOTIFY_SIGNAL,
TPL_NOTIFY,
VariableClassAddressChangeEvent,
NULL,
&gEfiEventVirtualAddressChangeGuid,
&mVirtualAddressChangeEvent
);
ASSERT_EFI_ERROR (Status);
return EFI_SUCCESS;
}

View File

@@ -0,0 +1,277 @@
/** @file
The internal header file includes the common header files, defines
internal structure and functions used by EmuVariable module.
Copyright (c) 2006 - 2018, 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.
**/
#ifndef _VARIABLE_H_
#define _VARIABLE_H_
#include <Uefi.h>
#include <Protocol/VariableWrite.h>
#include <Protocol/Variable.h>
#include <Library/BaseMemoryLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/DebugLib.h>
#include <Library/UefiRuntimeLib.h>
#include <Library/UefiDriverEntryPoint.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiLib.h>
#include <Library/BaseLib.h>
#include <Library/PcdLib.h>
#include <Library/HobLib.h>
#include <Guid/VariableFormat.h>
#include <Guid/GlobalVariable.h>
#include <Guid/EventGroup.h>
#define GET_VARIABLE_NAME_PTR(a) (CHAR16 *) ((UINTN) (a) + sizeof (VARIABLE_HEADER))
///
/// The size of a 3 character ISO639 language code.
///
#define ISO_639_2_ENTRY_SIZE 3
typedef enum {
Physical,
Virtual
} VARIABLE_POINTER_TYPE;
typedef struct {
VARIABLE_HEADER *CurrPtr;
VARIABLE_HEADER *EndPtr;
VARIABLE_HEADER *StartPtr;
BOOLEAN Volatile;
} VARIABLE_POINTER_TRACK;
typedef struct {
EFI_PHYSICAL_ADDRESS VolatileVariableBase;
EFI_PHYSICAL_ADDRESS NonVolatileVariableBase;
EFI_LOCK VariableServicesLock;
} VARIABLE_GLOBAL;
typedef struct {
VARIABLE_GLOBAL VariableGlobal[2];
UINTN VolatileLastVariableOffset;
UINTN NonVolatileLastVariableOffset;
UINTN CommonVariableTotalSize;
UINTN HwErrVariableTotalSize;
CHAR8 *PlatformLangCodes;
CHAR8 *LangCodes;
CHAR8 *PlatformLang;
CHAR8 Lang[ISO_639_2_ENTRY_SIZE + 1];
} ESAL_VARIABLE_GLOBAL;
///
/// Don't use module globals after the SetVirtualAddress map is signaled
///
extern ESAL_VARIABLE_GLOBAL *mVariableModuleGlobal;
/**
Initializes variable store area for non-volatile and volatile variable.
This function allocates and initializes memory space for global context of ESAL
variable service and variable store area for non-volatile and volatile variable.
@param ImageHandle The Image handle of this driver.
@param SystemTable The pointer of EFI_SYSTEM_TABLE.
@retval EFI_SUCCESS Function successfully executed.
@retval EFI_OUT_OF_RESOURCES Fail to allocate enough memory resource.
**/
EFI_STATUS
EFIAPI
VariableCommonInitialize (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
);
/**
Entry point of EmuVariable service module.
This function is the entry point of EmuVariable service module.
It registers all interfaces of Variable Services, initializes
variable store for non-volatile and volatile variables, and registers
notification function for EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE event.
@param ImageHandle The Image handle of this driver.
@param SystemTable The pointer of EFI_SYSTEM_TABLE.
@retval EFI_SUCCESS Variable service successfully initialized.
**/
EFI_STATUS
EFIAPI
VariableServiceInitialize (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
);
/**
Notification function of EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE.
This is a notification function registered on EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE event.
It convers pointer to new virtual address.
@param Event Event whose notification function is being invoked.
@param Context Pointer to the notification function's context.
**/
VOID
EFIAPI
VariableClassAddressChangeEvent (
IN EFI_EVENT Event,
IN VOID *Context
);
/**
This code finds variable in storage blocks (Volatile or Non-Volatile).
@param VariableName A Null-terminated Unicode string that is the name of
the vendor's variable.
@param VendorGuid A unique identifier for the vendor.
@param Attributes If not NULL, a pointer to the memory location to return the
attributes bitmask for the variable.
@param DataSize Size of Data found. If size is less than the
data, this value contains the required size.
@param Data On input, the size in bytes of the return Data buffer.
On output, the size of data returned in Data.
@param Global Pointer to VARIABLE_GLOBAL structure
@retval EFI_SUCCESS The function completed successfully.
@retval EFI_NOT_FOUND The variable was not found.
@retval EFI_BUFFER_TOO_SMALL DataSize is too small for the result. DataSize has
been updated with the size needed to complete the request.
@retval EFI_INVALID_PARAMETER VariableName or VendorGuid or DataSize is NULL.
**/
EFI_STATUS
EFIAPI
EmuGetVariable (
IN CHAR16 *VariableName,
IN EFI_GUID *VendorGuid,
OUT UINT32 *Attributes OPTIONAL,
IN OUT UINTN *DataSize,
OUT VOID *Data,
IN VARIABLE_GLOBAL *Global
);
/**
This code finds the next available variable.
@param VariableNameSize The size of the VariableName buffer. The size must be large enough to fit input
string supplied in VariableName buffer.
@param VariableName On input, supplies the last VariableName that was returned by GetNextVariableName().
On output, returns the Null-terminated Unicode string of the current variable.
@param VendorGuid On input, supplies the last VendorGuid that was returned by GetNextVariableName().
On output, returns the VendorGuid of the current variable.
@param Global Pointer to VARIABLE_GLOBAL structure.
@retval EFI_SUCCESS The function completed successfully.
@retval EFI_NOT_FOUND The next variable was not found.
@retval EFI_BUFFER_TOO_SMALL The VariableNameSize is too small for the result.
VariableNameSize has been updated with the size needed to complete the request.
@retval EFI_INVALID_PARAMETER VariableNameSize or VariableName or VendorGuid is NULL.
@retval EFI_INVALID_PARAMETER The input values of VariableName and VendorGuid are not a name and
GUID of an existing variable.
@retval EFI_INVALID_PARAMETER Null-terminator is not found in the first VariableNameSize bytes of
the input VariableName buffer.
**/
EFI_STATUS
EFIAPI
EmuGetNextVariableName (
IN OUT UINTN *VariableNameSize,
IN OUT CHAR16 *VariableName,
IN OUT EFI_GUID *VendorGuid,
IN VARIABLE_GLOBAL *Global
);
/**
This code sets variable in storage blocks (Volatile or Non-Volatile).
@param VariableName A Null-terminated Unicode string that is the name of the vendor's
variable. Each VariableName is unique for each
VendorGuid. VariableName must contain 1 or more
Unicode characters. If VariableName is an empty Unicode
string, then EFI_INVALID_PARAMETER is returned.
@param VendorGuid A unique identifier for the vendor
@param Attributes Attributes bitmask to set for the variable
@param DataSize The size in bytes of the Data buffer. A size of zero causes the
variable to be deleted.
@param Data The contents for the variable
@param Global Pointer to VARIABLE_GLOBAL structure
@param VolatileOffset The offset of last volatile variable
@param NonVolatileOffset The offset of last non-volatile variable
@retval EFI_SUCCESS The firmware has successfully stored the variable and its data as
defined by the Attributes.
@retval EFI_INVALID_PARAMETER An invalid combination of attribute bits was supplied, or the
DataSize exceeds the maximum allowed, or VariableName is an empty
Unicode string, or VendorGuid is NULL.
@retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the variable and its data.
@retval EFI_DEVICE_ERROR The variable could not be saved due to a hardware failure.
@retval EFI_WRITE_PROTECTED The variable in question is read-only or cannot be deleted.
@retval EFI_NOT_FOUND The variable trying to be updated or deleted was not found.
**/
EFI_STATUS
EFIAPI
EmuSetVariable (
IN CHAR16 *VariableName,
IN EFI_GUID *VendorGuid,
IN UINT32 Attributes,
IN UINTN DataSize,
IN VOID *Data,
IN VARIABLE_GLOBAL *Global,
IN UINTN *VolatileOffset,
IN UINTN *NonVolatileOffset
);
/**
This code returns information about the EFI variables.
@param Attributes Attributes bitmask to specify the type of variables
on which to return information.
@param MaximumVariableStorageSize On output the maximum size of the storage space available for
the EFI variables associated with the attributes specified.
@param RemainingVariableStorageSize Returns the remaining size of the storage space available for EFI
variables associated with the attributes specified.
@param MaximumVariableSize Returns the maximum size of an individual EFI variable
associated with the attributes specified.
@param Global Pointer to VARIABLE_GLOBAL structure.
@retval EFI_SUCCESS Valid answer returned.
@retval EFI_INVALID_PARAMETER An invalid combination of attribute bits was supplied
@retval EFI_UNSUPPORTED The attribute is not supported on this platform, and the
MaximumVariableStorageSize, RemainingVariableStorageSize,
MaximumVariableSize are undefined.
**/
EFI_STATUS
EFIAPI
EmuQueryVariableInfo (
IN UINT32 Attributes,
OUT UINT64 *MaximumVariableStorageSize,
OUT UINT64 *RemainingVariableStorageSize,
OUT UINT64 *MaximumVariableSize,
IN VARIABLE_GLOBAL *Global
);
#endif

View File

@@ -6378,7 +6378,11 @@ typedef union {
/// [Bit 11] Execute Disable Bit Enable: IA32_EFER.NXE (R/W).
///
UINT32 NXE:1;
UINT32 Reserved3:20;
///
/// [ Bit 12] Secure Virtual Machine Enable (AMD only)
///
UINT32 SVME:1;
UINT32 Reserved3:19;
UINT32 Reserved4:32;
} Bits;
///

View File

@@ -111,7 +111,7 @@ CommonExceptionHandlerWorker (
//
// Enter a dead loop if needn't to execute old IDT handler further
//
if (ReservedVectors[ExceptionType].Attribute != EFI_VECTOR_HANDOFF_HOOK_BEFORE) {
if (ReservedVectors[ExceptionType].Attribute != EFI_VECTOR_HANDOFF_HOOK_BEFORE && ExceptionType != EXCEPT_IA32_DEBUG) {
CpuDeadLoop ();
}
}
@@ -293,4 +293,3 @@ RegisterCpuInterruptHandlerWorker (
ExternalInterruptHandler[InterruptType] = InterruptHandler;
return EFI_SUCCESS;
}

View File

@@ -2763,6 +2763,10 @@ IsMtrrSupported (
CPUID_VERSION_INFO_EDX Edx;
MSR_IA32_MTRRCAP_REGISTER MtrrCap;
if (PcdGetBool(PcdCpuDisableMtrrProgramming)) {
return FALSE;
}
//
// Check CPUID(1).EDX[12] for MTRR capability
//

View File

@@ -37,4 +37,4 @@
[Pcd]
gUefiCpuPkgTokenSpaceGuid.PcdCpuNumberOfReservedVariableMtrrs ## SOMETIMES_CONSUMES
gUefiCpuPkgTokenSpaceGuid.PcdCpuDisableMtrrProgramming ## CONSUMES

View File

@@ -197,6 +197,10 @@
# @Prompt SMM Code Access Check.
gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmCodeAccessCheckEnable|TRUE|BOOLEAN|0x60000013
## Disables MTRR programming in case it's already programmed by FSB.
# @Prompt Disable MTRR programming.
gUefiCpuPkgTokenSpaceGuid.PcdCpuDisableMtrrProgramming|FALSE|BOOLEAN|0x00000017
## Specifies the number of variable MTRRs reserved for OS use. The default number of
# MTRRs reserved for OS use is 2.
# @Prompt Number of reserved variable MTRRs.

View File

@@ -140,9 +140,13 @@
#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuHotPlugDataAddress_HELP #language en-US "Contains the pointer to a CPU Hot Plug Data structure if CPU hot-plug is supported."
#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuNumberOfReservedVariableMtrrs_PROMPT #language en-US "Number of reserved variable MTRRs"
#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuDisableMtrrProgramming_PROMPT #language en-US "Number of reserved variable MTRRs"
#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuNumberOfReservedVariableMtrrs_HELP #language en-US "Specifies the number of variable MTRRs reserved for OS use."
#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuDisableMtrrProgramming_HELP #language en-US "Specifies the number of variable MTRRs reserved for OS use."
#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuNumberOfReservedVariableMtrrs_PROMPT #language en-US "Disable MTRR programming."
#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuNumberOfReservedVariableMtrrs_HELP #language en-US "Disables MTRR programming in case it's already programmed by FSB."
#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuApLoopMode_PROMPT #language en-US "The AP wait loop state"

View File

@@ -390,12 +390,24 @@ BlPeiEntryPoint (
EFI_PEI_GRAPHICS_DEVICE_INFO_HOB GfxDeviceInfo;
EFI_PEI_GRAPHICS_DEVICE_INFO_HOB *NewGfxDeviceInfo;
// Report lower 640KB of RAM.
// Mark memory as reserved to keep coreboot header in place.
//
BuildResourceDescriptorHob (
EFI_RESOURCE_MEMORY_RESERVED,
(
EFI_RESOURCE_ATTRIBUTE_PRESENT |
EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
EFI_RESOURCE_ATTRIBUTE_TESTED |
EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE
),
(EFI_PHYSICAL_ADDRESS)(0),
(UINT64)(0x1000)
);
//
// Report lower 640KB of RAM. Attribute EFI_RESOURCE_ATTRIBUTE_TESTED
// is intentionally omitted to prevent erasing of the coreboot header
// record before it is processed by ParseMemoryInfo.
//
BuildResourceDescriptorHob (
EFI_RESOURCE_SYSTEM_MEMORY,
(
@@ -406,8 +418,8 @@ BlPeiEntryPoint (
EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE
),
(EFI_PHYSICAL_ADDRESS)(0),
(UINT64)(0xA0000)
(EFI_PHYSICAL_ADDRESS)(0x1000),
(UINT64)(0x9F000)
);
BuildResourceDescriptorHob (

View File

@@ -0,0 +1,46 @@
/** @file
Copyright (c) 2006, 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.
Module Name:
PciExpressBaseAddress.h
Abstract:
GUIDs used for PciExpress Base Address
**/
#ifndef _EFI_PCI_EXPRESS_BASE_ADDRESS_H_
#define _EFI_PCI_EXPRESS_BASE_ADDRESS_H_
#define EFI_PCI_EXPRESS_BASE_ADDRESS_GUID \
{ \
0x3677d529, 0x326f, 0x4603, {0xa9, 0x26, 0xea, 0xac, 0xe0, 0x1d, 0xcb, 0xb0} \
}
//
// Following structure defines PCI Express Base Address information.
// This information is platform specific, and built into hob in PEI phase.
// It can be consumed by PEI PCI driver and DXE PCI driver.
//
#pragma pack(1)
typedef struct _EFI_PCI_EXPRESS_BASE_ADDRESS_INFORMATION {
UINT32 HostBridgeNumber;
UINT32 RootBridgeNumber;
UINT64 PciExpressBaseAddress;
} EFI_PCI_EXPRESS_BASE_ADDRESS_INFORMATION;
#pragma pack()
extern EFI_GUID gEfiPciExpressBaseAddressGuid;
#endif

View File

@@ -0,0 +1,41 @@
/** @file
GUID and data structure used to describe the list of PCI Option ROMs present in a system.
Copyright (c) 2006, 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.
**/
#ifndef __PCI_OPTION_ROM_TABLE_GUID_H_
#define __PCI_OPTION_ROM_TABLE_GUID_H_
#define EFI_PCI_OPTION_ROM_TABLE_GUID \
{ 0x7462660f, 0x1cbd, 0x48da, {0xad, 0x11, 0x91, 0x71, 0x79, 0x13, 0x83, 0x1c } }
extern EFI_GUID gEfiPciOptionRomTableGuid;
typedef struct {
EFI_PHYSICAL_ADDRESS RomAddress;
EFI_MEMORY_TYPE MemoryType;
UINT32 RomLength;
UINT32 Seg;
UINT8 Bus;
UINT8 Dev;
UINT8 Func;
BOOLEAN ExecutedLegacyBiosImage;
BOOLEAN DontLoadEfiRom;
} EFI_PCI_OPTION_ROM_DESCRIPTOR;
typedef struct {
UINT64 PciOptionRomCount;
EFI_PCI_OPTION_ROM_DESCRIPTOR *PciOptionRomDescriptors;
} EFI_PCI_OPTION_ROM_TABLE;
#endif // __PCI_OPTION_ROM_TABLE_GUID_H_

View File

@@ -39,3 +39,4 @@
DevicePathLib
MemoryAllocationLib
PciLib
DxeServicesTableLib

View File

@@ -16,6 +16,7 @@
#include <Library/MemoryAllocationLib.h>
#include <Library/PciHostBridgeLib.h>
#include <Library/PciLib.h>
#include <Library/DxeServicesTableLib.h>
#include "PciHostBridge.h"
/**
@@ -139,6 +140,55 @@ PcatPciRootBridgeBarExisted (
EnableInterrupts ();
}
STATIC
EFI_STATUS
PcatPciRootBridgeWarnAboutBrokenFW (
IN UINT64 Start,
IN UINT64 Limit
)
{
EFI_STATUS Status;
UINTN Index;
UINT64 IntersectionBase;
UINT64 IntersectionEnd;
UINTN NumberOfDescriptors;
EFI_GCD_MEMORY_SPACE_DESCRIPTOR *Map;
Status = gDS->GetMemorySpaceMap (&NumberOfDescriptors, &Map);
if (EFI_ERROR (Status)) {
DEBUG ((EFI_D_ERROR, "%a: %a: GetMemorySpaceMap(): %r\n",
gEfiCallerBaseName, __FUNCTION__, Status));
return Status;
}
for (Index = 0; Index < NumberOfDescriptors; Index++) {
if (Map[Index].GcdMemoryType == EfiGcdMemoryTypeNonExistent) {
//
// Ignore non existent entries
//
continue;
}
IntersectionBase = MAX (Start, Map[Index].BaseAddress);
IntersectionEnd = MIN (Limit, Map[Index].BaseAddress + Map[Index].Length);
if (IntersectionBase >= IntersectionEnd) {
//
// The descriptor and the aperture don't overlap.
//
continue;
}
if (Map[Index].GcdMemoryType == EfiGcdMemoryTypeReserved) {
DEBUG ((EFI_D_ERROR, "%a: PCI aperature overlaps reserved memory region\n",
__FUNCTION__));
DEBUG ((EFI_D_ERROR, "%a: Please consider fixing EDK2 or your firmware\n",
__FUNCTION__));
return EFI_ACCESS_DENIED;
}
}
return EFI_SUCCESS;
}
/**
Parse PCI bar and collect the assigned PCI resource information.
@@ -192,6 +242,9 @@ PcatPciRootBridgeParseBars (
UINT64 Length;
UINT64 Limit;
PCI_ROOT_BRIDGE_APERTURE *MemAperture;
UINT64 NewBase;
UINT64 NewLength;
EFI_STATUS Status;
for (Offset = BarOffsetBase; Offset < BarOffsetEnd; Offset += sizeof (UINT32)) {
PcatPciRootBridgeBarExisted (
@@ -271,6 +324,33 @@ PcatPciRootBridgeParseBars (
Limit = Base + Length - 1;
if ((Base > 0) && (Base < Limit)) {
NewBase = MemAperture->Base;
if (MemAperture->Base > Base) {
NewBase = Base;
}
NewLength = MemAperture->Base;
if (MemAperture->Limit < Limit) {
NewLength = Base;
}
//
// In case the BAR is placed on "the other side" of the MMCONF window
// this would cause the aperature to cover the MMCONF window, which
// isn't supported by EDK2.
//
Status = PcatPciRootBridgeWarnAboutBrokenFW(NewBase, NewLength);
if (EFI_ERROR (Status)) {
DEBUG ((EFI_D_ERROR, "%a: Not adding PCI %x:%x.%x BAR@%d %x:%x to aperature\n",
__FUNCTION__,
Bus,
Device,
Function,
Offset,
Base,
Limit));
continue;
}
if (MemAperture->Base > Base) {
MemAperture->Base = Base;
}

View File

@@ -152,35 +152,18 @@ PlatformBootManagerBeforeConsole (
VOID
)
{
EFI_INPUT_KEY Enter;
EFI_INPUT_KEY F2;
EFI_INPUT_KEY Down;
EFI_INPUT_KEY Escape;
EFI_BOOT_MANAGER_LOAD_OPTION BootOption;
PlatformConsoleInit ();
//
// Register ENTER as CONTINUE key
// Map Escape to Boot Manager Menu
//
Enter.ScanCode = SCAN_NULL;
Enter.UnicodeChar = CHAR_CARRIAGE_RETURN;
EfiBootManagerRegisterContinueKeyOption (0, &Enter, NULL);
//
// Map F2 to Boot Manager Menu
//
F2.ScanCode = SCAN_F2;
F2.UnicodeChar = CHAR_NULL;
Escape.ScanCode = SCAN_ESC;
Escape.UnicodeChar = CHAR_NULL;
EfiBootManagerGetBootManagerMenu (&BootOption);
EfiBootManagerAddKeyOptionVariable (NULL, (UINT16) BootOption.OptionNumber, 0, &F2, NULL);
//
// Also add Down key to Boot Manager Menu since some serial terminals don't support F2 key.
//
Down.ScanCode = SCAN_DOWN;
Down.UnicodeChar = CHAR_NULL;
EfiBootManagerGetBootManagerMenu (&BootOption);
EfiBootManagerAddKeyOptionVariable (NULL, (UINT16) BootOption.OptionNumber, 0, &Down, NULL);
EfiBootManagerAddKeyOptionVariable (NULL, (UINT16) BootOption.OptionNumber, 0, &Escape, NULL);
//
// Install ready to lock.
@@ -210,11 +193,11 @@ PlatformBootManagerAfterConsole (
VOID
)
{
EFI_GRAPHICS_OUTPUT_BLT_PIXEL Black;
EFI_GRAPHICS_OUTPUT_BLT_PIXEL White;
gST->ConOut->ClearScreen (gST->ConOut);
BootLogoEnableLogo ();
Black.Blue = Black.Green = Black.Red = Black.Reserved = 0;
White.Blue = White.Green = White.Red = White.Reserved = 0xFF;
// FIXME: USB devices are not being detected unless we wait a bit.
gBS->Stall (100 * 1000);
EfiBootManagerConnectAll ();
EfiBootManagerRefreshAllBootOption ();
@@ -222,15 +205,10 @@ PlatformBootManagerAfterConsole (
//
// Register UEFI Shell
//
PlatformRegisterFvBootOption (PcdGetPtr (PcdShellFile), L"UEFI Shell", LOAD_OPTION_ACTIVE);
Print (
L"\n"
L"F2 or Down to enter Boot Manager Menu.\n"
L"ENTER to boot directly.\n"
L"\n"
);
//PlatformRegisterFvBootOption (PcdGetPtr (PcdShellFile), L"UEFI Shell", LOAD_OPTION_ACTIVE);
// Inject boot logo into BGRT table
AddBGRT();
}
/**
@@ -244,7 +222,20 @@ PlatformBootManagerWaitCallback (
UINT16 TimeoutRemain
)
{
return;
EFI_GRAPHICS_OUTPUT_BLT_PIXEL Black;
EFI_GRAPHICS_OUTPUT_BLT_PIXEL White;
Black.Blue = Black.Green = Black.Red = Black.Reserved = 0;
White.Blue = White.Green = White.Red = White.Reserved = 0xFF;
BootLogoUpdateProgress (
White,
Black,
L"Press ESC for Boot Options/Settings, or SPACE for Pop!_OS Recovery",
White,
0,
0
);
}
/**
@@ -260,6 +251,51 @@ PlatformBootManagerUnableToBoot (
VOID
)
{
return;
EFI_STATUS Status;
EFI_INPUT_KEY Key;
EFI_BOOT_MANAGER_LOAD_OPTION BootManagerMenu;
UINTN Index;
//
// BootManagerMenu doesn't contain the correct information when return status
// is EFI_NOT_FOUND.
//
Status = EfiBootManagerGetBootManagerMenu (&BootManagerMenu);
if (EFI_ERROR (Status)) {
return;
}
//
// Normally BdsDxe does not print anything to the system console, but this is
// a last resort -- the end-user will likely not see any DEBUG messages
// logged in this situation.
//
// AsciiPrint() will NULL-check gST->ConOut internally. We check gST->ConIn
// here to see if it makes sense to request and wait for a keypress.
//
if (gST->ConOut != NULL && gST->ConIn != NULL) {
gST->ConOut->ClearScreen (gST->ConOut);
AsciiPrint (
"%a: No bootable option or device was found.\n"
"%a: Press any key to enter the Boot Manager Menu.\n",
gEfiCallerBaseName,
gEfiCallerBaseName
);
Status = gBS->WaitForEvent (1, &gST->ConIn->WaitForKey, &Index);
ASSERT_EFI_ERROR (Status);
ASSERT (Index == 0);
//
// Drain any queued keys.
//
while (!EFI_ERROR (gST->ConIn->ReadKeyStroke (gST->ConIn, &Key))) {
//
// just throw away Key
//
}
}
for (;;) {
EfiBootManagerBoot (&BootManagerMenu);
}
}

View File

@@ -39,6 +39,7 @@
UefiRuntimeServicesTableLib
UefiLib
UefiBootManagerLib
BootLogoLib
PcdLib
DxeServicesLib
MemoryAllocationLib

View File

@@ -0,0 +1,144 @@
/** @file
System76 EC logging
Copyright (c) 2020 System76, Inc.
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include <Library/IoLib.h>
// From coreboot/src/drivers/system76_ec/system76_ec.c {
#define SYSTEM76_EC_BASE 0x0E00
static inline UINT8 system76_ec_read(UINT8 addr) {
return IoRead8(SYSTEM76_EC_BASE + (UINT16)addr);
}
static inline void system76_ec_write(UINT8 addr, UINT8 data) {
IoWrite8(SYSTEM76_EC_BASE + (UINT16)addr, data);
}
void system76_ec_init(void) {
// Clear entire command region
for (int i = 0; i < 256; i++) {
system76_ec_write((UINT8)i, 0);
}
}
void system76_ec_flush(void) {
// Send command
system76_ec_write(0, 4);
// Wait for command completion
while (system76_ec_read(0) != 0) {}
// Clear length
system76_ec_write(3, 0);
}
void system76_ec_print(UINT8 byte) {
// Read length
UINT8 len = system76_ec_read(3);
// Write data at offset
system76_ec_write(len + 4, byte);
// Update length
system76_ec_write(3, len + 1);
// If we hit the end of the buffer, or were given a newline, flush
if (byte == '\n' || len >= 128) {
system76_ec_flush();
}
}
// } From coreboot/src/drivers/system76_ec/system76_ec.c
// Implement SerialPortLib {
#include <Library/SerialPortLib.h>
RETURN_STATUS
EFIAPI
SerialPortInitialize (
VOID
)
{
system76_ec_init();
return RETURN_SUCCESS;
}
UINTN
EFIAPI
SerialPortWrite (
IN UINT8 *Buffer,
IN UINTN NumberOfBytes
)
{
if (Buffer == NULL) {
return 0;
}
if (NumberOfBytes == 0) {
system76_ec_flush();
return 0;
}
for(UINTN i = 0; i < NumberOfBytes; i++) {
system76_ec_print(Buffer[i]);
}
return NumberOfBytes;
}
BOOLEAN
EFIAPI
SerialPortPoll (
VOID
)
{
return FALSE;
}
RETURN_STATUS
EFIAPI
SerialPortGetControl (
OUT UINT32 *Control
)
{
return RETURN_UNSUPPORTED;
}
RETURN_STATUS
EFIAPI
SerialPortSetControl (
IN UINT32 Control
)
{
return RETURN_UNSUPPORTED;
}
RETURN_STATUS
EFIAPI
SerialPortSetAttributes (
IN OUT UINT64 *BaudRate,
IN OUT UINT32 *ReceiveFifoDepth,
IN OUT UINT32 *Timeout,
IN OUT EFI_PARITY_TYPE *Parity,
IN OUT UINT8 *DataBits,
IN OUT EFI_STOP_BITS_TYPE *StopBits
)
{
return RETURN_UNSUPPORTED;
}
// } Implement SerialPortLib
// Implement PlatformHookLib {
#include <Library/PlatformHookLib.h>
RETURN_STATUS
EFIAPI
PlatformHookSerialPortInitialize (
VOID
)
{
return RETURN_SUCCESS;
}
// } Implement PlatformHookLib

View File

@@ -0,0 +1,28 @@
## @file
# System76 EC logging.
#
# Copyright (c) 2020, System76, Inc.
# SPDX-License-Identifier: BSD-2-Clause-Patent
##
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = System76EcLib
MODULE_UNI_FILE = System76EcLib.uni
FILE_GUID = 76ECF0DD-148B-4E48-8589-FC998823F8C2
MODULE_TYPE = BASE
VERSION_STRING = 0.1
LIBRARY_CLASS = System76EcLib
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
UefiPayloadPkg/UefiPayloadPkg.dec
[LibraryClasses]
IoLib
[Sources]
System76EcLib.c
[Pcd]

View File

@@ -0,0 +1,13 @@
// /** @file
// System76 EC logging.
//
// Copyright (c) 2020, System76, Inc.
// SPDX-License-Identifier: BSD-2-Clause-Patent
//
// **/
#string STR_MODULE_ABSTRACT #language en-US "System76 EC logging"
#string STR_MODULE_DESCRIPTION #language en-US "System76 EC logging."

View File

@@ -0,0 +1,161 @@
/*++
Copyright (c) 2005 - 2007, 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.
Module Name:
ComponentName.c
Abstract:
--*/
#include "PciBus.h"
//
// EFI Component Name Functions
//
EFI_STATUS
EFIAPI
PciBusComponentNameGetDriverName (
IN EFI_COMPONENT_NAME_PROTOCOL *This,
IN CHAR8 *Language,
OUT CHAR16 **DriverName
);
EFI_STATUS
EFIAPI
PciBusComponentNameGetControllerName (
IN EFI_COMPONENT_NAME_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN EFI_HANDLE ChildHandle OPTIONAL,
IN CHAR8 *Language,
OUT CHAR16 **ControllerName
);
//
// EFI Component Name Protocol
//
GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL gPciBusComponentName = {
PciBusComponentNameGetDriverName,
PciBusComponentNameGetControllerName,
"eng"
};
GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gPciBusComponentName2 = {
(EFI_COMPONENT_NAME2_GET_DRIVER_NAME) PciBusComponentNameGetDriverName,
(EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) PciBusComponentNameGetControllerName,
"en"
};
EFI_UNICODE_STRING_TABLE mPciBusDriverNameTable[] = {
{ "eng;en", L"PCI Bus Driver" },
{ NULL, NULL }
};
EFI_STATUS
EFIAPI
PciBusComponentNameGetDriverName (
IN EFI_COMPONENT_NAME_PROTOCOL *This,
IN CHAR8 *Language,
OUT CHAR16 **DriverName
)
/*++
Routine Description:
Retrieves a Unicode string that is the user readable name of the EFI Driver.
Arguments:
This - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.
Language - A pointer to a three character ISO 639-2 language identifier.
This is the language of the driver name that that the caller
is requesting, and it must match one of the languages specified
in SupportedLanguages. The number of languages supported by a
driver is up to the driver writer.
DriverName - A pointer to the Unicode string to return. This Unicode string
is the name of the driver specified by This in the language
specified by Language.
Returns:
EFI_SUCCESS - The Unicode string for the Driver specified by This
and the language specified by Language was returned
in DriverName.
EFI_INVALID_PARAMETER - Language is NULL.
EFI_INVALID_PARAMETER - DriverName is NULL.
EFI_UNSUPPORTED - The driver specified by This does not support the
language specified by Language.
--*/
{
return LookupUnicodeString2 (
Language,
This->SupportedLanguages,
mPciBusDriverNameTable,
DriverName,
(BOOLEAN)(This == &gPciBusComponentName)
);
}
EFI_STATUS
EFIAPI
PciBusComponentNameGetControllerName (
IN EFI_COMPONENT_NAME_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN EFI_HANDLE ChildHandle OPTIONAL,
IN CHAR8 *Language,
OUT CHAR16 **ControllerName
)
/*++
Routine Description:
Retrieves a Unicode string that is the user readable name of the controller
that is being managed by an EFI Driver.
Arguments:
This - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.
ControllerHandle - The handle of a controller that the driver specified by
This is managing. This handle specifies the controller
whose name is to be returned.
ChildHandle - The handle of the child controller to retrieve the name
of. This is an optional parameter that may be NULL. It
will be NULL for device drivers. It will also be NULL
for a bus drivers that wish to retrieve the name of the
bus controller. It will not be NULL for a bus driver
that wishes to retrieve the name of a child controller.
Language - A pointer to a three character ISO 639-2 language
identifier. This is the language of the controller name
that that the caller is requesting, and it must match one
of the languages specified in SupportedLanguages. The
number of languages supported by a driver is up to the
driver writer.
ControllerName - A pointer to the Unicode string to return. This Unicode
string is the name of the controller specified by
ControllerHandle and ChildHandle in the language specified
by Language from the point of view of the driver specified
by This.
Returns:
EFI_SUCCESS - The Unicode string for the user readable name in the
language specified by Language for the driver
specified by This was returned in DriverName.
EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE.
EFI_INVALID_PARAMETER - ChildHandle is not NULL and it is not a valid EFI_HANDLE.
EFI_INVALID_PARAMETER - Language is NULL.
EFI_INVALID_PARAMETER - ControllerName is NULL.
EFI_UNSUPPORTED - The driver specified by This is not currently managing
the controller specified by ControllerHandle and
ChildHandle.
EFI_UNSUPPORTED - The driver specified by This does not support the
language specified by Language.
--*/
{
return EFI_UNSUPPORTED;
}

View File

@@ -0,0 +1,346 @@
/*++
Copyright (c) 2005 - 2006, 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.
Module Name:
PciBus.c
Abstract:
PCI Bus Driver
Revision History
--*/
#include "PciBus.h"
//
// PCI Bus Support Function Prototypes
//
EFI_STATUS
EFIAPI
PciBusEntryPoint (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
);
EFI_STATUS
EFIAPI
PciBusDriverBindingSupported (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE Controller,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
);
EFI_STATUS
EFIAPI
PciBusDriverBindingStart (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE Controller,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
);
EFI_STATUS
EFIAPI
PciBusDriverBindingStop (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE Controller,
IN UINTN NumberOfChildren,
IN EFI_HANDLE *ChildHandleBuffer
);
//
// PCI Bus Driver Global Variables
//
EFI_DRIVER_BINDING_PROTOCOL gPciBusDriverBinding = {
PciBusDriverBindingSupported,
PciBusDriverBindingStart,
PciBusDriverBindingStop,
0xa,
NULL,
NULL
};
BOOLEAN gFullEnumeration;
UINT64 gAllOne = 0xFFFFFFFFFFFFFFFFULL;
UINT64 gAllZero = 0;
//
// PCI Bus Driver Support Functions
//
EFI_STATUS
EFIAPI
PciBusEntryPoint (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
/*++
Routine Description:
Initialize the global variables
publish the driver binding protocol
Arguments:
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
Returns:
EFI_SUCCESS
EFI_DEVICE_ERROR
--*/
{
EFI_STATUS Status;
//
// Initialize the EFI Driver Library
//
Status = EfiLibInstallDriverBindingComponentName2 (
ImageHandle,
SystemTable,
&gPciBusDriverBinding,
ImageHandle,
&gPciBusComponentName,
&gPciBusComponentName2
);
ASSERT_EFI_ERROR (Status);
InitializePciDevicePool ();
gFullEnumeration = TRUE;
return Status;
}
EFI_STATUS
EFIAPI
PciBusDriverBindingSupported (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE Controller,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
)
/*++
Routine Description:
Check to see if pci bus driver supports the given controller
Arguments:
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE Controller,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
Returns:
EFI_SUCCESS
--*/
{
EFI_STATUS Status;
EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;
EFI_DEV_PATH_PTR Node;
if (RemainingDevicePath != NULL) {
Node.DevPath = RemainingDevicePath;
if (Node.DevPath->Type != HARDWARE_DEVICE_PATH ||
Node.DevPath->SubType != HW_PCI_DP ||
DevicePathNodeLength(Node.DevPath) != sizeof(PCI_DEVICE_PATH)) {
return EFI_UNSUPPORTED;
}
}
//
// Open the IO Abstraction(s) needed to perform the supported test
//
Status = gBS->OpenProtocol (
Controller,
&gEfiDevicePathProtocolGuid,
(VOID **) &ParentDevicePath,
This->DriverBindingHandle,
Controller,
EFI_OPEN_PROTOCOL_BY_DRIVER
);
if (Status == EFI_ALREADY_STARTED) {
return EFI_SUCCESS;
}
if (EFI_ERROR (Status)) {
return Status;
}
gBS->CloseProtocol (
Controller,
&gEfiDevicePathProtocolGuid,
This->DriverBindingHandle,
Controller
);
Status = gBS->OpenProtocol (
Controller,
&gEfiPciRootBridgeIoProtocolGuid,
(VOID **) &PciRootBridgeIo,
This->DriverBindingHandle,
Controller,
EFI_OPEN_PROTOCOL_BY_DRIVER
);
if (Status == EFI_ALREADY_STARTED) {
return EFI_SUCCESS;
}
if (EFI_ERROR (Status)) {
return Status;
}
gBS->CloseProtocol (
Controller,
&gEfiPciRootBridgeIoProtocolGuid,
This->DriverBindingHandle,
Controller
);
return EFI_SUCCESS;
}
EFI_STATUS
EFIAPI
PciBusDriverBindingStart (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE Controller,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
)
/*++
Routine Description:
Start to management the controller passed in
Arguments:
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE Controller,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
Returns:
--*/
{
EFI_STATUS Status;
//
// Enumerate the entire host bridge
// After enumeration, a database that records all the device information will be created
//
//
Status = PciEnumerator (Controller);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Enable PCI device specified by remaining device path. BDS or other driver can call the
// start more than once.
//
StartPciDevices (Controller, RemainingDevicePath);
return EFI_SUCCESS;
}
EFI_STATUS
EFIAPI
PciBusDriverBindingStop (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE Controller,
IN UINTN NumberOfChildren,
IN EFI_HANDLE *ChildHandleBuffer
)
/*++
Routine Description:
Stop one or more children created at start of pci bus driver
if all the the children get closed, close the protocol
Arguments:
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE Controller,
IN UINTN NumberOfChildren,
IN EFI_HANDLE *ChildHandleBuffer
Returns:
--*/
{
EFI_STATUS Status;
UINTN Index;
BOOLEAN AllChildrenStopped;
if (NumberOfChildren == 0) {
//
// Close the bus driver
//
gBS->CloseProtocol (
Controller,
&gEfiDevicePathProtocolGuid,
This->DriverBindingHandle,
Controller
);
gBS->CloseProtocol (
Controller,
&gEfiPciRootBridgeIoProtocolGuid,
This->DriverBindingHandle,
Controller
);
DestroyRootBridgeByHandle (
Controller
);
return EFI_SUCCESS;
}
//
// Stop all the children
//
AllChildrenStopped = TRUE;
for (Index = 0; Index < NumberOfChildren; Index++) {
//
// De register all the pci device
//
Status = DeRegisterPciDevice (Controller, ChildHandleBuffer[Index]);
if (EFI_ERROR (Status)) {
AllChildrenStopped = FALSE;
}
}
if (!AllChildrenStopped) {
return EFI_DEVICE_ERROR;
}
return EFI_SUCCESS;
}

View File

@@ -0,0 +1,225 @@
/*++
Copyright (c) 2005 - 2007, 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.
Module Name:
PciBus.h
Abstract:
PCI Bus Driver
Revision History
--*/
#ifndef _EFI_PCI_BUS_H
#define _EFI_PCI_BUS_H
#include <PiDxe.h>
#include <Protocol/PciIo.h>
#include <Protocol/PciRootBridgeIo.h>
#include <Protocol/DevicePath.h>
#include <Protocol/Decompress.h>
#include <Protocol/UgaIo.h>
#include <Protocol/LoadedImage.h>
#include <Protocol/BusSpecificDriverOverride.h>
#include <Guid/PciOptionRomTable.h>
#include <IndustryStandard/Pci.h>
#include <IndustryStandard/Acpi.h>
#include <IndustryStandard/PeImage.h>
#include <Library/DebugLib.h>
#include <Library/UefiDriverEntryPoint.h>
#include <Library/BaseLib.h>
#include <Library/UefiLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/ReportStatusCodeLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/DevicePathLib.h>
#include <Library/PcdLib.h>
#include <Library/PeCoffLib.h>
//
// Driver Produced Protocol Prototypes
//
#define VGABASE1 0x3B0
#define VGALIMIT1 0x3BB
#define VGABASE2 0x3C0
#define VGALIMIT2 0x3DF
#define ISABASE 0x100
#define ISALIMIT 0x3FF
typedef enum {
PciBarTypeUnknown = 0,
PciBarTypeIo16,
PciBarTypeIo32,
PciBarTypeMem32,
PciBarTypePMem32,
PciBarTypeMem64,
PciBarTypePMem64,
PciBarTypeIo,
PciBarTypeMem,
PciBarTypeMaxType
} PCI_BAR_TYPE;
typedef struct {
UINT64 BaseAddress;
UINT64 Length;
UINT64 Alignment;
PCI_BAR_TYPE BarType;
BOOLEAN Prefetchable;
UINT8 MemType;
UINT8 Offset;
} PCI_BAR;
#define PCI_IO_DEVICE_SIGNATURE SIGNATURE_32 ('p','c','i','o')
#define EFI_BRIDGE_IO32_DECODE_SUPPORTED 0x0001
#define EFI_BRIDGE_PMEM32_DECODE_SUPPORTED 0x0002
#define EFI_BRIDGE_PMEM64_DECODE_SUPPORTED 0x0004
#define EFI_BRIDGE_IO16_DECODE_SUPPORTED 0x0008
#define EFI_BRIDGE_PMEM_MEM_COMBINE_SUPPORTED 0x0010
#define EFI_BRIDGE_MEM64_DECODE_SUPPORTED 0x0020
#define EFI_BRIDGE_MEM32_DECODE_SUPPORTED 0x0040
typedef struct _PCI_IO_DEVICE {
UINT32 Signature;
EFI_HANDLE Handle;
EFI_PCI_IO_PROTOCOL PciIo;
LIST_ENTRY Link;
EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL PciDriverOverride;
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;
//
// PCI configuration space header type
//
PCI_TYPE00 Pci;
//
// Bus number, Device number, Function number
//
UINT8 BusNumber;
UINT8 DeviceNumber;
UINT8 FunctionNumber;
//
// BAR for this PCI Device
//
PCI_BAR PciBar[PCI_MAX_BAR];
//
// The bridge device this pci device is subject to
//
struct _PCI_IO_DEVICE *Parent;
//
// A linked list for children Pci Device if it is bridge device
//
LIST_ENTRY ChildList;
//
// TRUE if the PCI bus driver creates the handle for this PCI device
//
BOOLEAN Registered;
//
// TRUE if the PCI bus driver successfully allocates the resource required by
// this PCI device
//
BOOLEAN Allocated;
//
// The attribute this PCI device currently set
//
UINT64 Attributes;
//
// The attributes this PCI device actually supports
//
UINT64 Supports;
//
// The resource decode the bridge supports
//
UINT32 Decodes;
//
// The OptionRom Size
//
UINT64 RomSize;
//
// TRUE if there is any EFI driver in the OptionRom
//
BOOLEAN BusOverride;
//
// A list tracking reserved resource on a bridge device
//
LIST_ENTRY ReservedResourceList;
//
// A list tracking image handle of platform specific overriding driver
//
LIST_ENTRY OptionRomDriverList;
BOOLEAN IsPciExp;
} PCI_IO_DEVICE;
#define PCI_IO_DEVICE_FROM_PCI_IO_THIS(a) \
CR (a, PCI_IO_DEVICE, PciIo, PCI_IO_DEVICE_SIGNATURE)
#define PCI_IO_DEVICE_FROM_PCI_DRIVER_OVERRIDE_THIS(a) \
CR (a, PCI_IO_DEVICE, PciDriverOverride, PCI_IO_DEVICE_SIGNATURE)
#define PCI_IO_DEVICE_FROM_LINK(a) \
CR (a, PCI_IO_DEVICE, Link, PCI_IO_DEVICE_SIGNATURE)
//
// Global Variables
//
extern EFI_COMPONENT_NAME_PROTOCOL gPciBusComponentName;
extern EFI_COMPONENT_NAME2_PROTOCOL gPciBusComponentName2;
extern EFI_DRIVER_BINDING_PROTOCOL gPciBusDriverBinding;
extern BOOLEAN gFullEnumeration;
extern UINT64 gAllOne;
extern UINT64 gAllZero;
#include "PciIo.h"
#include "PciCommand.h"
#include "PciDeviceSupport.h"
#include "PciEnumerator.h"
#include "PciEnumeratorSupport.h"
#include "PciDriverOverride.h"
#include "PciRomTable.h"
#include "PciOptionRomSupport.h"
#include "PciPowerManagement.h"
#define IS_ISA_BRIDGE(_p) IS_CLASS2 (_p, PCI_CLASS_BRIDGE, PCI_CLASS_BRIDGE_ISA)
#define IS_INTEL_ISA_BRIDGE(_p) (IS_CLASS2 (_p, PCI_CLASS_BRIDGE, PCI_CLASS_BRIDGE_ISA_PDECODE) && ((_p)->Hdr.VendorId == 0x8086) && ((_p)->Hdr.DeviceId == 0x7110))
#define IS_PCI_GFX(_p) IS_CLASS2 (_p, PCI_CLASS_DISPLAY, PCI_CLASS_DISPLAY_OTHER)
#endif

View File

@@ -0,0 +1,72 @@
## @file
#
# Copyright (c) 2005 - 2010, 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.
#
# Module Name:
#
# Abstract:
#
##
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = PciBusNoEnumerationDxe
FILE_GUID = 35C0C168-2607-4e51-BB53-448E3ED1A87F
MODULE_TYPE = UEFI_DRIVER
VERSION_STRING = 1.0
ENTRY_POINT = PciBusEntryPoint
[Packages]
MdePkg/MdePkg.dec
UefiPayloadPkg/UefiPayloadPkg.dec
[LibraryClasses]
DebugLib
BaseLib
UefiLib
UefiBootServicesTableLib
UefiDriverEntryPoint
BaseMemoryLib
ReportStatusCodeLib
DevicePathLib
PeCoffLib
[Sources]
PciBus.h
PciIo.h
PciCommand.h
PciDeviceSupport.h
PciEnumerator.h
PciEnumeratorSupport.h
PciOptionRomSupport.h
PciRomTable.h
PciPowerManagement.h
PciPowerManagement.c
PciRomTable.c
PciDriverOverride.h
PciDriverOverride.c
PciOptionRomSupport.c
PciEnumerator.c
PciEnumeratorSupport.c
PciCommand.c
ComponentName.c
PciDeviceSupport.c
PciBus.c
PciIo.c
[Protocols]
gEfiPciRootBridgeIoProtocolGuid
gEfiPciIoProtocolGuid
gEfiDevicePathProtocolGuid
gEfiBusSpecificDriverOverrideProtocolGuid
gEfiDecompressProtocolGuid
[Guids]
gEfiPciOptionRomTableGuid

View File

@@ -0,0 +1,453 @@
/*++
Copyright (c) 2005 - 2006, 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.
Module Name:
PciCommand.c
Abstract:
PCI Bus Driver
Revision History
--*/
#include "PciBus.h"
EFI_STATUS
PciReadCommandRegister (
IN PCI_IO_DEVICE *PciIoDevice,
OUT UINT16 *Command
)
/*++
Routine Description:
Arguments:
Returns:
None
--*/
{
EFI_PCI_IO_PROTOCOL *PciIo;
*Command = 0;
PciIo = &PciIoDevice->PciIo;
return PciIo->Pci.Read (
PciIo,
EfiPciIoWidthUint16,
PCI_COMMAND_OFFSET,
1,
Command
);
}
EFI_STATUS
PciSetCommandRegister (
IN PCI_IO_DEVICE *PciIoDevice,
IN UINT16 Command
)
/*++
Routine Description:
Arguments:
Returns:
None
--*/
{
UINT16 Temp;
EFI_PCI_IO_PROTOCOL *PciIo;
Temp = Command;
PciIo = &PciIoDevice->PciIo;
return PciIo->Pci.Write (
PciIo,
EfiPciIoWidthUint16,
PCI_COMMAND_OFFSET,
1,
&Temp
);
}
EFI_STATUS
PciEnableCommandRegister (
IN PCI_IO_DEVICE *PciIoDevice,
IN UINT16 Command
)
/*++
Routine Description:
Arguments:
Returns:
None
--*/
{
UINT16 OldCommand;
EFI_PCI_IO_PROTOCOL *PciIo;
OldCommand = 0;
PciIo = &PciIoDevice->PciIo;
PciIo->Pci.Read (
PciIo,
EfiPciIoWidthUint16,
PCI_COMMAND_OFFSET,
1,
&OldCommand
);
OldCommand = (UINT16) (OldCommand | Command);
return PciIo->Pci.Write (
PciIo,
EfiPciIoWidthUint16,
PCI_COMMAND_OFFSET,
1,
&OldCommand
);
}
EFI_STATUS
PciDisableCommandRegister (
IN PCI_IO_DEVICE *PciIoDevice,
IN UINT16 Command
)
/*++
Routine Description:
Arguments:
Returns:
None
--*/
{
UINT16 OldCommand;
EFI_PCI_IO_PROTOCOL *PciIo;
OldCommand = 0;
PciIo = &PciIoDevice->PciIo;
PciIo->Pci.Read (
PciIo,
EfiPciIoWidthUint16,
PCI_COMMAND_OFFSET,
1,
&OldCommand
);
OldCommand = (UINT16) (OldCommand & ~(Command));
return PciIo->Pci.Write (
PciIo,
EfiPciIoWidthUint16,
PCI_COMMAND_OFFSET,
1,
&OldCommand
);
}
EFI_STATUS
PciSetBridgeControlRegister (
IN PCI_IO_DEVICE *PciIoDevice,
IN UINT16 Command
)
/*++
Routine Description:
Arguments:
Returns:
None
--*/
{
UINT16 Temp;
EFI_PCI_IO_PROTOCOL *PciIo;
Temp = Command;
PciIo = &PciIoDevice->PciIo;
return PciIo->Pci.Write (
PciIo,
EfiPciIoWidthUint16,
PCI_BRIDGE_CONTROL_REGISTER_OFFSET,
1,
&Temp
);
}
EFI_STATUS
PciEnableBridgeControlRegister (
IN PCI_IO_DEVICE *PciIoDevice,
IN UINT16 Command
)
/*++
Routine Description:
Arguments:
Returns:
None
--*/
{
UINT16 OldCommand;
EFI_PCI_IO_PROTOCOL *PciIo;
OldCommand = 0;
PciIo = &PciIoDevice->PciIo;
PciIo->Pci.Read (
PciIo,
EfiPciIoWidthUint16,
PCI_BRIDGE_CONTROL_REGISTER_OFFSET,
1,
&OldCommand
);
OldCommand = (UINT16) (OldCommand | Command);
return PciIo->Pci.Write (
PciIo,
EfiPciIoWidthUint16,
PCI_BRIDGE_CONTROL_REGISTER_OFFSET,
1,
&OldCommand
);
}
EFI_STATUS
PciDisableBridgeControlRegister (
IN PCI_IO_DEVICE *PciIoDevice,
IN UINT16 Command
)
/*++
Routine Description:
Arguments:
Returns:
None
--*/
{
UINT16 OldCommand;
EFI_PCI_IO_PROTOCOL *PciIo;
OldCommand = 0;
PciIo = &PciIoDevice->PciIo;
PciIo->Pci.Read (
PciIo,
EfiPciIoWidthUint16,
PCI_BRIDGE_CONTROL_REGISTER_OFFSET,
1,
&OldCommand
);
OldCommand = (UINT16) (OldCommand & ~(Command));
return PciIo->Pci.Write (
PciIo,
EfiPciIoWidthUint16,
PCI_BRIDGE_CONTROL_REGISTER_OFFSET,
1,
&OldCommand
);
}
EFI_STATUS
PciReadBridgeControlRegister (
IN PCI_IO_DEVICE *PciIoDevice,
OUT UINT16 *Command
)
/*++
Routine Description:
Arguments:
Returns:
None
--*/
{
EFI_PCI_IO_PROTOCOL *PciIo;
*Command = 0;
PciIo = &PciIoDevice->PciIo;
return PciIo->Pci.Read (
PciIo,
EfiPciIoWidthUint16,
PCI_BRIDGE_CONTROL_REGISTER_OFFSET,
1,
Command
);
}
BOOLEAN
PciCapabilitySupport (
IN PCI_IO_DEVICE *PciIoDevice
)
/*++
Routine Description:
Arguments:
Returns:
None
--*/
// TODO: PciIoDevice - add argument and description to function comment
{
if (PciIoDevice->Pci.Hdr.Status & EFI_PCI_STATUS_CAPABILITY) {
return TRUE;
}
return FALSE;
}
EFI_STATUS
LocateCapabilityRegBlock (
IN PCI_IO_DEVICE *PciIoDevice,
IN UINT8 CapId,
IN OUT UINT8 *Offset,
OUT UINT8 *NextRegBlock OPTIONAL
)
/*++
Routine Description:
Locate Capability register.
Arguments:
PciIoDevice - A pointer to the PCI_IO_DEVICE.
CapId - The capability ID.
Offset - A pointer to the offset.
As input: the default offset;
As output: the offset of the found block.
NextRegBlock - An optional pointer to return the value of next block.
Returns:
EFI_UNSUPPORTED - The Pci Io device is not supported.
EFI_NOT_FOUND - The Pci Io device cannot be found.
EFI_SUCCESS - The Pci Io device is successfully located.
--*/
{
UINT8 CapabilityPtr;
UINT16 CapabilityEntry;
UINT8 CapabilityID;
//
// To check the capability of this device supports
//
if (!PciCapabilitySupport (PciIoDevice)) {
return EFI_UNSUPPORTED;
}
if (*Offset != 0) {
CapabilityPtr = *Offset;
} else {
CapabilityPtr = 0;
if (IS_CARDBUS_BRIDGE (&PciIoDevice->Pci)) {
PciIoDevice->PciIo.Pci.Read (
&PciIoDevice->PciIo,
EfiPciIoWidthUint8,
EFI_PCI_CARDBUS_BRIDGE_CAPABILITY_PTR,
1,
&CapabilityPtr
);
} else {
PciIoDevice->PciIo.Pci.Read (
&PciIoDevice->PciIo,
EfiPciIoWidthUint8,
PCI_CAPBILITY_POINTER_OFFSET,
1,
&CapabilityPtr
);
}
}
while ((CapabilityPtr >= 0x40) && ((CapabilityPtr & 0x03) == 0x00)) {
PciIoDevice->PciIo.Pci.Read (
&PciIoDevice->PciIo,
EfiPciIoWidthUint16,
CapabilityPtr,
1,
&CapabilityEntry
);
CapabilityID = (UINT8) CapabilityEntry;
if (CapabilityID == CapId) {
*Offset = CapabilityPtr;
if (NextRegBlock != NULL) {
*NextRegBlock = (UINT8) (CapabilityEntry >> 8);
}
return EFI_SUCCESS;
}
CapabilityPtr = (UINT8) (CapabilityEntry >> 8);
}
return EFI_NOT_FOUND;
}

View File

@@ -0,0 +1,167 @@
/*++
Copyright (c) 2005 - 2006, 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.
Module Name:
PciCommand.h
Abstract:
PCI Bus Driver
Revision History
--*/
#ifndef _EFI_PCI_COMMAND_H
#define _EFI_PCI_COMMAND_H
#include "PciBus.h"
//
// The PCI Command register bits owned by PCI Bus driver.
//
// They should be cleared at the beginning. The other registers
// are owned by chipset, we should not touch them.
//
#define EFI_PCI_COMMAND_BITS_OWNED ( \
EFI_PCI_COMMAND_IO_SPACE | \
EFI_PCI_COMMAND_MEMORY_SPACE | \
EFI_PCI_COMMAND_BUS_MASTER | \
EFI_PCI_COMMAND_MEMORY_WRITE_AND_INVALIDATE | \
EFI_PCI_COMMAND_VGA_PALETTE_SNOOP | \
EFI_PCI_COMMAND_FAST_BACK_TO_BACK \
)
//
// The PCI Bridge Control register bits owned by PCI Bus driver.
//
// They should be cleared at the beginning. The other registers
// are owned by chipset, we should not touch them.
//
#define EFI_PCI_BRIDGE_CONTROL_BITS_OWNED ( \
EFI_PCI_BRIDGE_CONTROL_ISA | \
EFI_PCI_BRIDGE_CONTROL_VGA | \
EFI_PCI_BRIDGE_CONTROL_VGA_16 | \
EFI_PCI_BRIDGE_CONTROL_FAST_BACK_TO_BACK \
)
//
// The PCCard Bridge Control register bits owned by PCI Bus driver.
//
// They should be cleared at the beginning. The other registers
// are owned by chipset, we should not touch them.
//
#define EFI_PCCARD_BRIDGE_CONTROL_BITS_OWNED ( \
EFI_PCI_BRIDGE_CONTROL_ISA | \
EFI_PCI_BRIDGE_CONTROL_VGA | \
EFI_PCI_BRIDGE_CONTROL_FAST_BACK_TO_BACK \
)
EFI_STATUS
PciReadCommandRegister (
IN PCI_IO_DEVICE *PciIoDevice,
OUT UINT16 *Command
);
EFI_STATUS
PciSetCommandRegister (
IN PCI_IO_DEVICE *PciIoDevice,
IN UINT16 Command
);
EFI_STATUS
PciEnableCommandRegister (
IN PCI_IO_DEVICE *PciIoDevice,
IN UINT16 Command
);
EFI_STATUS
PciDisableCommandRegister (
IN PCI_IO_DEVICE *PciIoDevice,
IN UINT16 Command
);
EFI_STATUS
PciDisableBridgeControlRegister (
IN PCI_IO_DEVICE *PciIoDevice,
IN UINT16 Command
);
EFI_STATUS
PciEnableBridgeControlRegister (
IN PCI_IO_DEVICE *PciIoDevice,
IN UINT16 Command
);
EFI_STATUS
PciReadBridgeControlRegister (
IN PCI_IO_DEVICE *PciIoDevice,
OUT UINT16 *Command
);
BOOLEAN
PciCapabilitySupport (
IN PCI_IO_DEVICE *PciIoDevice
)
/*++
Routine Description:
TODO: Add function description
Arguments:
PciIoDevice - TODO: add argument description
Returns:
TODO: add return values
--*/
;
EFI_STATUS
LocateCapabilityRegBlock (
IN PCI_IO_DEVICE *PciIoDevice,
IN UINT8 CapId,
IN OUT UINT8 *Offset,
OUT UINT8 *NextRegBlock OPTIONAL
)
/*++
Routine Description:
Locate Capability register.
Arguments:
PciIoDevice - A pointer to the PCI_IO_DEVICE.
CapId - The capability ID.
Offset - A pointer to the offset.
As input: the default offset;
As output: the offset of the found block.
NextRegBlock - An optional pointer to return the value of next block.
Returns:
EFI_UNSUPPORTED - The Pci Io device is not supported.
EFI_NOT_FOUND - The Pci Io device cannot be found.
EFI_SUCCESS - The Pci Io device is successfully located.
--*/
;
#endif

View File

@@ -0,0 +1,973 @@
/*++
Copyright (c) 2005 - 2006, 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.
Module Name:
PciDeviceSupport.c
Abstract:
This file provides routine to support Pci device node manipulation
Revision History
--*/
#include "PciBus.h"
//
// This device structure is serviced as a header.
// Its Next field points to the first root bridge device node
//
LIST_ENTRY gPciDevicePool;
EFI_STATUS
InitializePciDevicePool (
VOID
)
/*++
Routine Description:
Initialize the gPciDevicePool
Arguments:
Returns:
None
--*/
{
InitializeListHead (&gPciDevicePool);
return EFI_SUCCESS;
}
EFI_STATUS
InsertRootBridge (
IN PCI_IO_DEVICE *RootBridge
)
/*++
Routine Description:
Insert a root bridge into PCI device pool
Arguments:
RootBridge - A pointer to the PCI_IO_DEVICE.
Returns:
None
--*/
{
InsertTailList (&gPciDevicePool, &(RootBridge->Link));
return EFI_SUCCESS;
}
EFI_STATUS
InsertPciDevice (
PCI_IO_DEVICE *Bridge,
PCI_IO_DEVICE *PciDeviceNode
)
/*++
Routine Description:
This function is used to insert a PCI device node under
a bridge
Arguments:
Bridge - A pointer to the PCI_IO_DEVICE.
PciDeviceNode - A pointer to the PCI_IO_DEVICE.
Returns:
None
--*/
{
InsertTailList (&Bridge->ChildList, &(PciDeviceNode->Link));
PciDeviceNode->Parent = Bridge;
return EFI_SUCCESS;
}
EFI_STATUS
DestroyRootBridge (
IN PCI_IO_DEVICE *RootBridge
)
/*++
Routine Description:
Arguments:
RootBridge - A pointer to the PCI_IO_DEVICE.
Returns:
None
--*/
{
DestroyPciDeviceTree (RootBridge);
gBS->FreePool (RootBridge);
return EFI_SUCCESS;
}
EFI_STATUS
DestroyPciDeviceTree (
IN PCI_IO_DEVICE *Bridge
)
/*++
Routine Description:
Destroy all the pci device node under the bridge.
Bridge itself is not included.
Arguments:
Bridge - A pointer to the PCI_IO_DEVICE.
Returns:
None
--*/
{
LIST_ENTRY *CurrentLink;
PCI_IO_DEVICE *Temp;
while (!IsListEmpty (&Bridge->ChildList)) {
CurrentLink = Bridge->ChildList.ForwardLink;
//
// Remove this node from the linked list
//
RemoveEntryList (CurrentLink);
Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);
if (IS_PCI_BRIDGE (&(Temp->Pci))) {
DestroyPciDeviceTree (Temp);
}
gBS->FreePool (Temp);
}
return EFI_SUCCESS;
}
EFI_STATUS
DestroyRootBridgeByHandle (
EFI_HANDLE Controller
)
/*++
Routine Description:
Destroy all device nodes under the root bridge
specified by Controller.
The root bridge itself is also included.
Arguments:
Controller - An efi handle.
Returns:
None
--*/
{
LIST_ENTRY *CurrentLink;
PCI_IO_DEVICE *Temp;
CurrentLink = gPciDevicePool.ForwardLink;
while (CurrentLink && CurrentLink != &gPciDevicePool) {
Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);
if (Temp->Handle == Controller) {
RemoveEntryList (CurrentLink);
DestroyPciDeviceTree (Temp);
gBS->FreePool(Temp);
return EFI_SUCCESS;
}
CurrentLink = CurrentLink->ForwardLink;
}
return EFI_NOT_FOUND;
}
EFI_STATUS
RegisterPciDevice (
IN EFI_HANDLE Controller,
IN PCI_IO_DEVICE *PciIoDevice,
OUT EFI_HANDLE *Handle OPTIONAL
)
/*++
Routine Description:
This function registers the PCI IO device. It creates a handle for this PCI IO device
(if the handle does not exist), attaches appropriate protocols onto the handle, does
necessary initialization, and sets up parent/child relationship with its bus controller.
Arguments:
Controller - An EFI handle for the PCI bus controller.
PciIoDevice - A PCI_IO_DEVICE pointer to the PCI IO device to be registered.
Handle - A pointer to hold the EFI handle for the PCI IO device.
Returns:
EFI_SUCCESS - The PCI device is successfully registered.
Others - An error occurred when registering the PCI device.
--*/
{
EFI_STATUS Status;
UINT8 PciExpressCapRegOffset;
//
// Install the pciio protocol, device path protocol and
// Bus Specific Driver Override Protocol
//
if (PciIoDevice->BusOverride) {
Status = gBS->InstallMultipleProtocolInterfaces (
&PciIoDevice->Handle,
&gEfiDevicePathProtocolGuid,
PciIoDevice->DevicePath,
&gEfiPciIoProtocolGuid,
&PciIoDevice->PciIo,
&gEfiBusSpecificDriverOverrideProtocolGuid,
&PciIoDevice->PciDriverOverride,
NULL
);
} else {
Status = gBS->InstallMultipleProtocolInterfaces (
&PciIoDevice->Handle,
&gEfiDevicePathProtocolGuid,
PciIoDevice->DevicePath,
&gEfiPciIoProtocolGuid,
&PciIoDevice->PciIo,
NULL
);
}
if (EFI_ERROR (Status)) {
return Status;
} else {
Status = gBS->OpenProtocol (
Controller,
&gEfiPciRootBridgeIoProtocolGuid,
(VOID **)&(PciIoDevice->PciRootBridgeIo),
gPciBusDriverBinding.DriverBindingHandle,
PciIoDevice->Handle,
EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
);
if (EFI_ERROR (Status)) {
return Status;
}
}
if (Handle != NULL) {
*Handle = PciIoDevice->Handle;
}
//
// Detect if PCI Express Device
//
PciExpressCapRegOffset = 0;
Status = LocateCapabilityRegBlock (
PciIoDevice,
EFI_PCI_CAPABILITY_ID_PCIEXP,
&PciExpressCapRegOffset,
NULL
);
if (!EFI_ERROR (Status)) {
PciIoDevice->IsPciExp = TRUE;
DEBUG ((EFI_D_ERROR, "PciExp - %x (B-%x, D-%x, F-%x)\n", PciIoDevice->IsPciExp, PciIoDevice->BusNumber, PciIoDevice->DeviceNumber, PciIoDevice->FunctionNumber));
}
//
// Indicate the pci device is registered
//
PciIoDevice->Registered = TRUE;
return EFI_SUCCESS;
}
EFI_STATUS
DeRegisterPciDevice (
IN EFI_HANDLE Controller,
IN EFI_HANDLE Handle
)
/*++
Routine Description:
This function is used to de-register the PCI device from the EFI,
That includes un-installing PciIo protocol from the specified PCI
device handle.
Arguments:
Controller - An efi handle.
Handle - An efi handle.
Returns:
None
--*/
{
EFI_PCI_IO_PROTOCOL *PciIo;
EFI_STATUS Status;
PCI_IO_DEVICE *PciIoDevice;
PCI_IO_DEVICE *Node;
LIST_ENTRY *CurrentLink;
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;
Status = gBS->OpenProtocol (
Handle,
&gEfiPciIoProtocolGuid,
(VOID **) &PciIo,
gPciBusDriverBinding.DriverBindingHandle,
Controller,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
if (!EFI_ERROR (Status)) {
PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (PciIo);
//
// If it is already de-registered
//
if (!PciIoDevice->Registered) {
return EFI_SUCCESS;
}
//
// If it is PPB, first de-register its children
//
if (IS_PCI_BRIDGE (&(PciIoDevice->Pci))) {
CurrentLink = PciIoDevice->ChildList.ForwardLink;
while (CurrentLink && CurrentLink != &PciIoDevice->ChildList) {
Node = PCI_IO_DEVICE_FROM_LINK (CurrentLink);
Status = DeRegisterPciDevice (Controller, Node->Handle);
if (EFI_ERROR (Status)) {
return Status;
}
CurrentLink = CurrentLink->ForwardLink;
}
}
//
// First disconnect this device
//
// PciIoDevice->PciIo.Attributes(&(PciIoDevice->PciIo),
// EfiPciIoAttributeOperationDisable,
// EFI_PCI_DEVICE_ENABLE,
// NULL
// );
//
// Close the child handle
//
Status = gBS->CloseProtocol (
Controller,
&gEfiPciRootBridgeIoProtocolGuid,
gPciBusDriverBinding.DriverBindingHandle,
Handle
);
//
// Un-install the device path protocol and pci io protocol
//
if (PciIoDevice->BusOverride) {
Status = gBS->UninstallMultipleProtocolInterfaces (
Handle,
&gEfiDevicePathProtocolGuid,
PciIoDevice->DevicePath,
&gEfiPciIoProtocolGuid,
&PciIoDevice->PciIo,
&gEfiBusSpecificDriverOverrideProtocolGuid,
&PciIoDevice->PciDriverOverride,
NULL
);
} else {
Status = gBS->UninstallMultipleProtocolInterfaces (
Handle,
&gEfiDevicePathProtocolGuid,
PciIoDevice->DevicePath,
&gEfiPciIoProtocolGuid,
&PciIoDevice->PciIo,
NULL
);
}
if (EFI_ERROR (Status)) {
gBS->OpenProtocol (
Controller,
&gEfiPciRootBridgeIoProtocolGuid,
(VOID **) &PciRootBridgeIo,
gPciBusDriverBinding.DriverBindingHandle,
Handle,
EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
);
return Status;
}
//
// The Device Driver should disable this device after disconnect
// so the Pci Bus driver will not touch this device any more.
// Restore the register field to the original value
//
PciIoDevice->Registered = FALSE;
PciIoDevice->Handle = NULL;
} else {
//
// Handle may be closed before
//
return EFI_SUCCESS;
}
return EFI_SUCCESS;
}
EFI_STATUS
EnableBridgeAttributes (
IN PCI_IO_DEVICE *PciIoDevice
)
{
PCI_TYPE01 PciData;
//
// NOTE: We should not set EFI_PCI_DEVICE_ENABLE for a bridge
// directly, because some legacy BIOS will NOT assign
// IO or Memory resource for a bridge who has no child
// device. So we add check IO or Memory here.
//
PciIoDevice->PciIo.Pci.Read (
&PciIoDevice->PciIo,
EfiPciIoWidthUint8,
0,
sizeof (PciData),
&PciData
);
if ((((PciData.Bridge.IoBase & 0xF) == 0) &&
(PciData.Bridge.IoBase != 0 || PciData.Bridge.IoLimit != 0)) ||
(((PciData.Bridge.IoBase & 0xF) == 1) &&
((PciData.Bridge.IoBase & 0xF0) != 0 || (PciData.Bridge.IoLimit & 0xF0) != 0 || PciData.Bridge.IoBaseUpper16 != 0 || PciData.Bridge.IoLimitUpper16 != 0))) {
PciIoDevice->PciIo.Attributes(
&(PciIoDevice->PciIo),
EfiPciIoAttributeOperationEnable,
(EFI_PCI_IO_ATTRIBUTE_IO | EFI_PCI_IO_ATTRIBUTE_BUS_MASTER),
NULL
);
}
if ((PciData.Bridge.MemoryBase & 0xFFF0) != 0 || (PciData.Bridge.MemoryLimit & 0xFFF0) != 0) {
PciIoDevice->PciIo.Attributes(
&(PciIoDevice->PciIo),
EfiPciIoAttributeOperationEnable,
(EFI_PCI_IO_ATTRIBUTE_MEMORY | EFI_PCI_IO_ATTRIBUTE_BUS_MASTER),
NULL
);
}
if ((((PciData.Bridge.PrefetchableMemoryBase & 0xF) == 0) &&
(PciData.Bridge.PrefetchableMemoryBase != 0 || PciData.Bridge.PrefetchableMemoryLimit != 0)) ||
(((PciData.Bridge.PrefetchableMemoryBase & 0xF) == 1) &&
((PciData.Bridge.PrefetchableMemoryBase & 0xFFF0) != 0 || (PciData.Bridge.PrefetchableMemoryLimit & 0xFFF0) != 0 || PciData.Bridge.PrefetchableBaseUpper32 != 0 || PciData.Bridge.PrefetchableLimitUpper32 != 0))) {
PciIoDevice->PciIo.Attributes(
&(PciIoDevice->PciIo),
EfiPciIoAttributeOperationEnable,
(EFI_PCI_IO_ATTRIBUTE_MEMORY | EFI_PCI_IO_ATTRIBUTE_BUS_MASTER),
NULL
);
}
return EFI_SUCCESS;
}
EFI_STATUS
StartPciDevicesOnBridge (
IN EFI_HANDLE Controller,
IN PCI_IO_DEVICE *RootBridge,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
)
/*++
Routine Description:
Start to manage the PCI device on specified the root bridge or PCI-PCI Bridge
Arguments:
Controller - An efi handle.
RootBridge - A pointer to the PCI_IO_DEVICE.
RemainingDevicePath - A pointer to the EFI_DEVICE_PATH_PROTOCOL.
NumberOfChildren - Children number.
ChildHandleBuffer - A pointer to the child handle buffer.
Returns:
None
--*/
{
PCI_IO_DEVICE *Temp;
PCI_IO_DEVICE *PciIoDevice;
EFI_DEV_PATH_PTR Node;
EFI_DEVICE_PATH_PROTOCOL *CurrentDevicePath;
EFI_STATUS Status;
LIST_ENTRY *CurrentLink;
CurrentLink = RootBridge->ChildList.ForwardLink;
while (CurrentLink && CurrentLink != &RootBridge->ChildList) {
Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);
if (RemainingDevicePath != NULL) {
Node.DevPath = RemainingDevicePath;
if (Node.Pci->Device != Temp->DeviceNumber ||
Node.Pci->Function != Temp->FunctionNumber) {
CurrentLink = CurrentLink->ForwardLink;
continue;
}
//
// Check if the device has been assigned with required resource
//
if (!Temp->Allocated) {
return EFI_NOT_READY;
}
//
// Check if the current node has been registered before
// If it is not, register it
//
if (!Temp->Registered) {
PciIoDevice = Temp;
Status = RegisterPciDevice (
Controller,
PciIoDevice,
NULL
);
}
//
// Get the next device path
//
CurrentDevicePath = NextDevicePathNode (RemainingDevicePath);
if (IsDevicePathEnd (CurrentDevicePath)) {
return EFI_SUCCESS;
}
//
// If it is a PPB
//
if (IS_PCI_BRIDGE (&(Temp->Pci))) {
Status = StartPciDevicesOnBridge (
Controller,
Temp,
CurrentDevicePath
);
EnableBridgeAttributes (Temp);
return Status;
} else {
//
// Currently, the PCI bus driver only support PCI-PCI bridge
//
return EFI_UNSUPPORTED;
}
} else {
//
// If remaining device path is NULL,
// try to enable all the pci devices under this bridge
//
if (!Temp->Registered && Temp->Allocated) {
PciIoDevice = Temp;
Status = RegisterPciDevice (
Controller,
PciIoDevice,
NULL
);
}
if (IS_PCI_BRIDGE (&(Temp->Pci))) {
Status = StartPciDevicesOnBridge (
Controller,
Temp,
RemainingDevicePath
);
EnableBridgeAttributes (Temp);
}
CurrentLink = CurrentLink->ForwardLink;
continue;
}
}
return EFI_NOT_FOUND;
}
EFI_STATUS
StartPciDevices (
IN EFI_HANDLE Controller,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
)
/*++
Routine Description:
Start to manage the PCI device according to RemainingDevicePath
If RemainingDevicePath == NULL, the PCI bus driver will start
to manage all the PCI devices it found previously
Arguments:
Controller - An efi handle.
RemainingDevicePath - A pointer to the EFI_DEVICE_PATH_PROTOCOL.
Returns:
None
--*/
{
EFI_DEV_PATH_PTR Node;
PCI_IO_DEVICE *RootBridge;
LIST_ENTRY *CurrentLink;
if (RemainingDevicePath != NULL) {
//
// Check if the RemainingDevicePath is valid
//
Node.DevPath = RemainingDevicePath;
if (Node.DevPath->Type != HARDWARE_DEVICE_PATH ||
Node.DevPath->SubType != HW_PCI_DP ||
DevicePathNodeLength (Node.DevPath) != sizeof (PCI_DEVICE_PATH)
) {
return EFI_UNSUPPORTED;
}
}
CurrentLink = gPciDevicePool.ForwardLink;
while (CurrentLink && CurrentLink != &gPciDevicePool) {
RootBridge = PCI_IO_DEVICE_FROM_LINK (CurrentLink);
//
// Locate the right root bridge to start
//
if (RootBridge->Handle == Controller) {
StartPciDevicesOnBridge (
Controller,
RootBridge,
RemainingDevicePath
);
}
CurrentLink = CurrentLink->ForwardLink;
}
return EFI_SUCCESS;
}
PCI_IO_DEVICE *
CreateRootBridge (
IN EFI_HANDLE RootBridgeHandle
)
/*++
Routine Description:
Arguments:
RootBridgeHandle - An efi handle.
Returns:
None
--*/
{
EFI_STATUS Status;
PCI_IO_DEVICE *Dev;
Dev = NULL;
Status = gBS->AllocatePool (
EfiBootServicesData,
sizeof (PCI_IO_DEVICE),
(VOID **) &Dev
);
if (EFI_ERROR (Status)) {
return NULL;
}
ZeroMem (Dev, sizeof (PCI_IO_DEVICE));
Dev->Signature = PCI_IO_DEVICE_SIGNATURE;
Dev->Handle = RootBridgeHandle;
InitializeListHead (&Dev->ChildList);
return Dev;
}
PCI_IO_DEVICE *
GetRootBridgeByHandle (
EFI_HANDLE RootBridgeHandle
)
/*++
Routine Description:
Arguments:
RootBridgeHandle - An efi handle.
Returns:
None
--*/
{
PCI_IO_DEVICE *RootBridgeDev;
LIST_ENTRY *CurrentLink;
CurrentLink = gPciDevicePool.ForwardLink;
while (CurrentLink && CurrentLink != &gPciDevicePool) {
RootBridgeDev = PCI_IO_DEVICE_FROM_LINK (CurrentLink);
if (RootBridgeDev->Handle == RootBridgeHandle) {
return RootBridgeDev;
}
CurrentLink = CurrentLink->ForwardLink;
}
return NULL;
}
BOOLEAN
RootBridgeExisted (
IN EFI_HANDLE RootBridgeHandle
)
/*++
Routine Description:
This function searches if RootBridgeHandle has already existed
in current device pool.
If so, it means the given root bridge has been already enumerated.
Arguments:
RootBridgeHandle - An efi handle.
Returns:
None
--*/
{
PCI_IO_DEVICE *Bridge;
Bridge = GetRootBridgeByHandle (RootBridgeHandle);
if (Bridge != NULL) {
return TRUE;
}
return FALSE;
}
BOOLEAN
PciDeviceExisted (
IN PCI_IO_DEVICE *Bridge,
IN PCI_IO_DEVICE *PciIoDevice
)
/*++
Routine Description:
Arguments:
Bridge - A pointer to the PCI_IO_DEVICE.
PciIoDevice - A pointer to the PCI_IO_DEVICE.
Returns:
None
--*/
{
PCI_IO_DEVICE *Temp;
LIST_ENTRY *CurrentLink;
CurrentLink = Bridge->ChildList.ForwardLink;
while (CurrentLink && CurrentLink != &Bridge->ChildList) {
Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);
if (Temp == PciIoDevice) {
return TRUE;
}
if (!IsListEmpty (&Temp->ChildList)) {
if (PciDeviceExisted (Temp, PciIoDevice)) {
return TRUE;
}
}
CurrentLink = CurrentLink->ForwardLink;
}
return FALSE;
}
PCI_IO_DEVICE *
ActiveVGADeviceOnTheSameSegment (
IN PCI_IO_DEVICE *VgaDevice
)
/*++
Routine Description:
Arguments:
VgaDevice - A pointer to the PCI_IO_DEVICE.
Returns:
None
--*/
{
LIST_ENTRY *CurrentLink;
PCI_IO_DEVICE *Temp;
CurrentLink = gPciDevicePool.ForwardLink;
while (CurrentLink && CurrentLink != &gPciDevicePool) {
Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);
if (Temp->PciRootBridgeIo->SegmentNumber == VgaDevice->PciRootBridgeIo->SegmentNumber) {
Temp = ActiveVGADeviceOnTheRootBridge (Temp);
if (Temp != NULL) {
return Temp;
}
}
CurrentLink = CurrentLink->ForwardLink;
}
return NULL;
}
PCI_IO_DEVICE *
ActiveVGADeviceOnTheRootBridge (
IN PCI_IO_DEVICE *RootBridge
)
/*++
Routine Description:
Arguments:
RootBridge - A pointer to the PCI_IO_DEVICE.
Returns:
None
--*/
{
LIST_ENTRY *CurrentLink;
PCI_IO_DEVICE *Temp;
CurrentLink = RootBridge->ChildList.ForwardLink;
while (CurrentLink && CurrentLink != &RootBridge->ChildList) {
Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);
if (IS_PCI_VGA(&Temp->Pci) &&
(Temp->Attributes &
(EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY |
EFI_PCI_IO_ATTRIBUTE_VGA_IO |
EFI_PCI_IO_ATTRIBUTE_VGA_IO_16))) {
return Temp;
}
if (IS_PCI_BRIDGE (&Temp->Pci)) {
Temp = ActiveVGADeviceOnTheRootBridge (Temp);
if (Temp != NULL) {
return Temp;
}
}
CurrentLink = CurrentLink->ForwardLink;
}
return NULL;
}

View File

@@ -0,0 +1,324 @@
/*++
Copyright (c) 2005 - 2006, 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.
Module Name:
PciDeviceSupport.h
Abstract:
Revision History
--*/
#ifndef _EFI_PCI_DEVICE_SUPPORT_H
#define _EFI_PCI_DEVICE_SUPPORT_H
EFI_STATUS
InitializePciDevicePool (
VOID
)
/*++
Routine Description:
TODO: Add function description
Arguments:
None
Returns:
TODO: add return values
--*/
;
EFI_STATUS
InsertPciDevice (
PCI_IO_DEVICE *Bridge,
PCI_IO_DEVICE *PciDeviceNode
)
/*++
Routine Description:
TODO: Add function description
Arguments:
Bridge - TODO: add argument description
PciDeviceNode - TODO: add argument description
Returns:
TODO: add return values
--*/
;
EFI_STATUS
DestroyPciDeviceTree (
IN PCI_IO_DEVICE *Bridge
)
/*++
Routine Description:
TODO: Add function description
Arguments:
Bridge - TODO: add argument description
Returns:
TODO: add return values
--*/
;
EFI_STATUS
DestroyRootBridgeByHandle (
EFI_HANDLE Controller
)
/*++
Routine Description:
TODO: Add function description
Arguments:
Controller - TODO: add argument description
Returns:
TODO: add return values
--*/
;
EFI_STATUS
RegisterPciDevice (
IN EFI_HANDLE Controller,
IN PCI_IO_DEVICE *PciIoDevice,
OUT EFI_HANDLE *Handle OPTIONAL
)
/*++
Routine Description:
This function registers the PCI IO device. It creates a handle for this PCI IO device
(if the handle does not exist), attaches appropriate protocols onto the handle, does
necessary initialization, and sets up parent/child relationship with its bus controller.
Arguments:
Controller - An EFI handle for the PCI bus controller.
PciIoDevice - A PCI_IO_DEVICE pointer to the PCI IO device to be registered.
Handle - A pointer to hold the EFI handle for the PCI IO device.
Returns:
EFI_SUCCESS - The PCI device is successfully registered.
Others - An error occurred when registering the PCI device.
--*/
;
EFI_STATUS
DeRegisterPciDevice (
IN EFI_HANDLE Controller,
IN EFI_HANDLE Handle
)
/*++
Routine Description:
TODO: Add function description
Arguments:
Controller - TODO: add argument description
Handle - TODO: add argument description
Returns:
TODO: add return values
--*/
;
EFI_STATUS
StartPciDevices (
IN EFI_HANDLE Controller,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
)
/*++
Routine Description:
TODO: Add function description
Arguments:
Controller - TODO: add argument description
RemainingDevicePath - TODO: add argument description
Returns:
TODO: add return values
--*/
;
PCI_IO_DEVICE *
CreateRootBridge (
IN EFI_HANDLE RootBridgeHandle
)
/*++
Routine Description:
TODO: Add function description
Arguments:
RootBridgeHandle - TODO: add argument description
Returns:
TODO: add return values
--*/
;
PCI_IO_DEVICE *
GetRootBridgeByHandle (
EFI_HANDLE RootBridgeHandle
)
/*++
Routine Description:
TODO: Add function description
Arguments:
RootBridgeHandle - TODO: add argument description
Returns:
TODO: add return values
--*/
;
EFI_STATUS
InsertRootBridge (
PCI_IO_DEVICE *RootBridge
);
EFI_STATUS
DestroyRootBridge (
IN PCI_IO_DEVICE *RootBridge
);
BOOLEAN
RootBridgeExisted (
IN EFI_HANDLE RootBridgeHandle
)
/*++
Routine Description:
TODO: Add function description
Arguments:
RootBridgeHandle - TODO: add argument description
Returns:
TODO: add return values
--*/
;
BOOLEAN
PciDeviceExisted (
IN PCI_IO_DEVICE *Bridge,
IN PCI_IO_DEVICE *PciIoDevice
)
/*++
Routine Description:
TODO: Add function description
Arguments:
Bridge - TODO: add argument description
PciIoDevice - TODO: add argument description
Returns:
TODO: add return values
--*/
;
PCI_IO_DEVICE *
ActiveVGADeviceOnTheSameSegment (
IN PCI_IO_DEVICE *VgaDevice
)
/*++
Routine Description:
TODO: Add function description
Arguments:
VgaDevice - TODO: add argument description
Returns:
TODO: add return values
--*/
;
PCI_IO_DEVICE *
ActiveVGADeviceOnTheRootBridge (
IN PCI_IO_DEVICE *RootBridge
)
/*++
Routine Description:
TODO: Add function description
Arguments:
RootBridge - TODO: add argument description
Returns:
TODO: add return values
--*/
;
#endif

View File

@@ -0,0 +1,176 @@
/*++
Copyright (c) 2005 - 2007, 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.
Module Name:
PciDriverOverride.c
Abstract:
PCI Bus Driver
Revision History
--*/
#include "PciBus.h"
EFI_STATUS
EFIAPI
GetDriver(
IN EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL *This,
IN OUT EFI_HANDLE *DriverImageHandle
);
EFI_STATUS
InitializePciDriverOverrideInstance (
PCI_IO_DEVICE *PciIoDevice
)
/*++
Routine Description:
Initializes a PCI Driver Override Instance
Arguments:
Returns:
None
--*/
{
PciIoDevice->PciDriverOverride.GetDriver = GetDriver;
return EFI_SUCCESS;
}
EFI_STATUS
EFIAPI
GetDriver (
IN EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL *This,
IN OUT EFI_HANDLE *DriverImageHandle
)
/*++
Routine Description:
Get a overriding driver image
Arguments:
Returns:
None
--*/
{
PCI_IO_DEVICE *PciIoDevice;
LIST_ENTRY *CurrentLink;
PCI_DRIVER_OVERRIDE_LIST *Node;
PciIoDevice = PCI_IO_DEVICE_FROM_PCI_DRIVER_OVERRIDE_THIS (This);
CurrentLink = PciIoDevice->OptionRomDriverList.ForwardLink;
while (CurrentLink && CurrentLink != &PciIoDevice->OptionRomDriverList) {
Node = DRIVER_OVERRIDE_FROM_LINK (CurrentLink);
if (*DriverImageHandle == NULL) {
*DriverImageHandle = Node->DriverImageHandle;
return EFI_SUCCESS;
}
if (*DriverImageHandle == Node->DriverImageHandle) {
if (CurrentLink->ForwardLink == &PciIoDevice->OptionRomDriverList ||
CurrentLink->ForwardLink == NULL) {
return EFI_NOT_FOUND;
}
//
// Get next node
//
Node = DRIVER_OVERRIDE_FROM_LINK (CurrentLink->ForwardLink);
*DriverImageHandle = Node->DriverImageHandle;
return EFI_SUCCESS;
}
CurrentLink = CurrentLink->ForwardLink;
}
return EFI_INVALID_PARAMETER;
}
EFI_STATUS
AddDriver (
IN PCI_IO_DEVICE *PciIoDevice,
IN EFI_HANDLE DriverImageHandle
)
/*++
Routine Description:
Add a overriding driver image
Arguments:
Returns:
None
--*/
{
EFI_STATUS Status;
EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
PCI_DRIVER_OVERRIDE_LIST *Node;
Status = gBS->HandleProtocol (DriverImageHandle, &gEfiLoadedImageProtocolGuid, (VOID **) &LoadedImage);
if (EFI_ERROR (Status)) {
return Status;
}
Node = AllocatePool (sizeof (PCI_DRIVER_OVERRIDE_LIST));
if (Node == NULL) {
return EFI_OUT_OF_RESOURCES;
}
Node->Signature = DRIVER_OVERRIDE_SIGNATURE;
Node->DriverImageHandle = DriverImageHandle;
InsertTailList (&PciIoDevice->OptionRomDriverList, &(Node->Link));
PciIoDevice->BusOverride = TRUE;
ImageContext.Handle = LoadedImage->ImageBase;
ImageContext.ImageRead = PeCoffLoaderImageReadFromMemory;
//
// Get information about the image
//
Status = PeCoffLoaderGetImageInfo (&ImageContext);
if (EFI_ERROR (Status)) {
return EFI_SUCCESS;
}
if (ImageContext.Machine != EFI_IMAGE_MACHINE_EBC) {
return EFI_SUCCESS;
}
return EFI_SUCCESS;
}

View File

@@ -0,0 +1,110 @@
/*++
Copyright (c) 2005 - 2006, 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.
Module Name:
PciDriverOverride.h
Abstract:
Revision History
--*/
#ifndef _EFI_PCI_DRIVER_OVERRRIDE_H
#define _EFI_PCI_DRIVER_OVERRRIDE_H
#include "PciBus.h"
#define DRIVER_OVERRIDE_SIGNATURE SIGNATURE_32 ('d', 'r', 'o', 'v')
typedef struct {
UINT32 Signature;
LIST_ENTRY Link;
EFI_HANDLE DriverImageHandle;
} PCI_DRIVER_OVERRIDE_LIST;
#define DRIVER_OVERRIDE_FROM_LINK(a) \
CR (a, PCI_DRIVER_OVERRIDE_LIST, Link, DRIVER_OVERRIDE_SIGNATURE)
EFI_STATUS
InitializePciDriverOverrideInstance (
PCI_IO_DEVICE *PciIoDevice
)
/*++
Routine Description:
TODO: Add function description
Arguments:
PciIoDevice - TODO: add argument description
Returns:
TODO: add return values
--*/
;
EFI_STATUS
AddDriver (
IN PCI_IO_DEVICE *PciIoDevice,
IN EFI_HANDLE DriverImageHandle
)
/*++
Routine Description:
TODO: Add function description
Arguments:
PciIoDevice - TODO: add argument description
DriverImageHandle - TODO: add argument description
Returns:
TODO: add return values
--*/
;
EFI_STATUS
EFIAPI
GetDriver (
IN EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL *This,
IN OUT EFI_HANDLE *DriverImageHandle
)
/*++
Routine Description:
TODO: Add function description
Arguments:
This - TODO: add argument description
DriverImageHandle - TODO: add argument description
Returns:
TODO: add return values
--*/
;
#endif

View File

@@ -0,0 +1,57 @@
/*++
Copyright (c) 2005 - 2006, 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.
Module Name:
PciEnumerator.c
Abstract:
PCI Bus Driver
Revision History
--*/
#include "PciBus.h"
EFI_STATUS
PciEnumerator (
IN EFI_HANDLE Controller
)
/*++
Routine Description:
This routine is used to enumerate entire pci bus system
in a given platform
Arguments:
Returns:
None
--*/
{
//
// This PCI bus driver depends on the legacy BIOS
// to do the resource allocation
//
gFullEnumeration = FALSE;
return PciEnumeratorLight (Controller) ;
}

View File

@@ -0,0 +1,47 @@
/*++
Copyright (c) 2005 - 2006, 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.
Module Name:
PciEnumerator.h
Abstract:
PCI Bus Driver
Revision History
--*/
#ifndef _EFI_PCI_ENUMERATOR_H
#define _EFI_PCI_ENUMERATOR_H
EFI_STATUS
PciEnumerator (
IN EFI_HANDLE Controller
)
/*++
Routine Description:
TODO: Add function description
Arguments:
Controller - TODO: add argument description
Returns:
TODO: add return values
--*/
;
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,108 @@
/*++
Copyright (c) 2005 - 2006, 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.
Module Name:
PciEnumeratorSupport.h
Abstract:
PCI Bus Driver
Revision History
--*/
#ifndef _EFI_PCI_ENUMERATOR_SUPPORT_H
#define _EFI_PCI_ENUMERATOR_SUPPORT_H
#include "PciBus.h"
EFI_STATUS
PciPciDeviceInfoCollector (
IN PCI_IO_DEVICE *Bridge,
UINT8 StartBusNumber
)
/*++
Routine Description:
TODO: Add function description
Arguments:
Bridge - TODO: add argument description
StartBusNumber - TODO: add argument description
Returns:
TODO: add return values
--*/
;
EFI_STATUS
PciDevicePresent(
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo,
PCI_TYPE00 *Pci,
UINT8 Bus,
UINT8 Device,
UINT8 Func
);
EFI_STATUS
PciEnumeratorLight (
IN EFI_HANDLE Controller
)
/*++
Routine Description:
TODO: Add function description
Arguments:
Controller - TODO: add argument description
Returns:
TODO: add return values
--*/
;
EFI_STATUS
PciGetBusRange (
IN EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR **Descriptors,
OUT UINT16 *MinBus,
OUT UINT16 *MaxBus,
OUT UINT16 *BusRange
)
/*++
Routine Description:
TODO: Add function description
Arguments:
Descriptors - TODO: add argument description
MinBus - TODO: add argument description
MaxBus - TODO: add argument description
BusRange - TODO: add argument description
Returns:
TODO: add return values
--*/
;
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,48 @@
/*++
Copyright (c) 2005 - 2006, 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.
Module Name:
PciIo.h
Abstract:
PCI Bus Driver
Revision History
--*/
#ifndef _EFI_PCI_IO_PROTOCOL_H
#define _EFI_PCI_IO_PROTOCOL_H
EFI_STATUS
InitializePciIoInstance (
PCI_IO_DEVICE *PciIoDevice
)
/*++
Routine Description:
TODO: Add function description
Arguments:
PciIoDevice - TODO: add argument description
Returns:
TODO: add return values
--*/
;
#endif

View File

@@ -0,0 +1,557 @@
/*++
Copyright (c) 2005 - 2012, 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.
Module Name:
PciOptionRomSupport.c
Abstract:
PCI Bus Driver
Revision History
--*/
#include "PciBus.h"
EFI_STATUS
RomDecode (
IN PCI_IO_DEVICE *PciDevice,
IN UINT8 RomBarIndex,
IN UINT32 RomBar,
IN BOOLEAN Enable
);
EFI_STATUS
GetOpRomInfo (
IN PCI_IO_DEVICE *PciIoDevice
)
/*++
Routine Description:
Arguments:
Returns:
--*/
{
UINT8 RomBarIndex;
UINT32 AllOnes;
UINT64 Address;
EFI_STATUS Status;
UINT8 Bus;
UINT8 Device;
UINT8 Function;
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;
Bus = PciIoDevice->BusNumber;
Device = PciIoDevice->DeviceNumber;
Function = PciIoDevice->FunctionNumber;
PciRootBridgeIo = PciIoDevice->PciRootBridgeIo;
//
// offset is 0x30 if is not ppb
//
//
// 0x30
//
RomBarIndex = PCI_EXPANSION_ROM_BASE;
if (IS_PCI_BRIDGE (&PciIoDevice->Pci)) {
//
// if is ppb
//
//
// 0x38
//
RomBarIndex = PCI_BRIDGE_ROMBAR;
}
//
// the bit0 is 0 to prevent the enabling of the Rom address decoder
//
AllOnes = 0xfffffffe;
Address = EFI_PCI_ADDRESS (Bus, Device, Function, RomBarIndex);
Status = PciRootBridgeIo->Pci.Write (
PciRootBridgeIo,
EfiPciWidthUint32,
Address,
1,
&AllOnes
);
if (EFI_ERROR (Status)) {
return Status;
}
//
// read back
//
Status = PciRootBridgeIo->Pci.Read (
PciRootBridgeIo,
EfiPciWidthUint32,
Address,
1,
&AllOnes
);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Bits [1, 10] are reserved
//
AllOnes &= 0xFFFFF800;
if ((AllOnes == 0) || (AllOnes == 0xFFFFF800)) {
return EFI_NOT_FOUND;
}
DEBUG ((EFI_D_ERROR, "PCIBUS: GetOpRomInfo: OPROM detected!\n"));
DEBUG ((EFI_D_ERROR, "PCIBUS: GetOpRomInfo: B-%x, D-%x, F-%x\n", (UINTN)Bus, (UINTN)Device, (UINTN)Function));
PciIoDevice->RomSize = (UINT64) ((~AllOnes) + 1);
return EFI_SUCCESS;
}
EFI_STATUS
LoadOpRomImage (
IN PCI_IO_DEVICE *PciDevice,
IN UINT64 ReservedMemoryBase
)
/*++
Routine Description:
Load option rom image for specified PCI device
Arguments:
Returns:
--*/
{
UINT8 RomBarIndex;
UINT8 Indicator;
UINT16 OffsetPcir;
UINT32 RomBarOffset;
UINT32 RomBar;
EFI_STATUS retStatus;
BOOLEAN FirstCheck;
UINT8 *Image;
PCI_EXPANSION_ROM_HEADER *RomHeader;
PCI_DATA_STRUCTURE *RomPcir;
UINT64 RomSize;
UINT64 RomImageSize;
UINT32 LegacyImageLength;
UINT8 *RomInMemory;
UINT8 CodeType;
RomSize = PciDevice->RomSize;
Indicator = 0;
RomImageSize = 0;
RomInMemory = NULL;
CodeType = 0xFF;
//
// Get the RomBarIndex
//
//
// 0x30
//
RomBarIndex = PCI_EXPANSION_ROM_BASE;
if (IS_PCI_BRIDGE (&(PciDevice->Pci))) {
//
// if is ppb
//
//
// 0x38
//
RomBarIndex = PCI_BRIDGE_ROMBAR;
}
//
// Allocate memory for Rom header and PCIR
//
RomHeader = AllocatePool (sizeof (PCI_EXPANSION_ROM_HEADER));
if (RomHeader == NULL) {
return EFI_OUT_OF_RESOURCES;
}
RomPcir = AllocatePool (sizeof (PCI_DATA_STRUCTURE));
if (RomPcir == NULL) {
gBS->FreePool (RomHeader);
return EFI_OUT_OF_RESOURCES;
}
RomBar = (UINT32)ReservedMemoryBase;
//
// Enable RomBar
//
RomDecode (PciDevice, RomBarIndex, RomBar, TRUE);
RomBarOffset = RomBar;
retStatus = EFI_NOT_FOUND;
FirstCheck = TRUE;
LegacyImageLength = 0;
do {
PciDevice->PciRootBridgeIo->Mem.Read (
PciDevice->PciRootBridgeIo,
EfiPciWidthUint8,
RomBarOffset,
sizeof (PCI_EXPANSION_ROM_HEADER),
(UINT8 *) RomHeader
);
if (RomHeader->Signature != PCI_EXPANSION_ROM_HEADER_SIGNATURE) {
RomBarOffset = RomBarOffset + 512;
if (FirstCheck) {
break;
} else {
RomImageSize = RomImageSize + 512;
continue;
}
}
FirstCheck = FALSE;
OffsetPcir = RomHeader->PcirOffset;
//
// If the pointer to the PCI Data Structure is invalid, no further images can be located.
// The PCI Data Structure must be DWORD aligned.
//
if (OffsetPcir == 0 ||
(OffsetPcir & 3) != 0 ||
RomImageSize + OffsetPcir + sizeof (PCI_DATA_STRUCTURE) > RomSize) {
break;
}
PciDevice->PciRootBridgeIo->Mem.Read (
PciDevice->PciRootBridgeIo,
EfiPciWidthUint8,
RomBarOffset + OffsetPcir,
sizeof (PCI_DATA_STRUCTURE),
(UINT8 *) RomPcir
);
//
// If a valid signature is not present in the PCI Data Structure, no further images can be located.
//
if (RomPcir->Signature != PCI_DATA_STRUCTURE_SIGNATURE) {
break;
}
if (RomImageSize + RomPcir->ImageLength * 512 > RomSize) {
break;
}
if (RomPcir->CodeType == PCI_CODE_TYPE_PCAT_IMAGE) {
CodeType = PCI_CODE_TYPE_PCAT_IMAGE;
LegacyImageLength = ((UINT32)((EFI_LEGACY_EXPANSION_ROM_HEADER *)RomHeader)->Size512) * 512;
}
Indicator = RomPcir->Indicator;
RomImageSize = RomImageSize + RomPcir->ImageLength * 512;
RomBarOffset = RomBarOffset + RomPcir->ImageLength * 512;
} while (((Indicator & 0x80) == 0x00) && ((RomBarOffset - RomBar) < RomSize));
//
// Some Legacy Cards do not report the correct ImageLength so used the maximum
// of the legacy length and the PCIR Image Length
//
if (CodeType == PCI_CODE_TYPE_PCAT_IMAGE) {
RomImageSize = MAX (RomImageSize, LegacyImageLength);
}
if (RomImageSize > 0) {
retStatus = EFI_SUCCESS;
Image = AllocatePool ((UINT32) RomImageSize);
if (Image == NULL) {
RomDecode (PciDevice, RomBarIndex, RomBar, FALSE);
gBS->FreePool (RomHeader);
gBS->FreePool (RomPcir);
return EFI_OUT_OF_RESOURCES;
}
//
// Copy Rom image into memory
//
PciDevice->PciRootBridgeIo->Mem.Read (
PciDevice->PciRootBridgeIo,
EfiPciWidthUint8,
RomBar,
(UINT32) RomImageSize,
Image
);
RomInMemory = Image;
}
RomDecode (PciDevice, RomBarIndex, RomBar, FALSE);
PciDevice->PciIo.RomSize = RomImageSize;
PciDevice->PciIo.RomImage = RomInMemory;
//
// Free allocated memory
//
gBS->FreePool (RomHeader);
gBS->FreePool (RomPcir);
return retStatus;
}
EFI_STATUS
RomDecode (
IN PCI_IO_DEVICE *PciDevice,
IN UINT8 RomBarIndex,
IN UINT32 RomBar,
IN BOOLEAN Enable
)
/*++
Routine Description:
Arguments:
Returns:
--*/
{
UINT16 CommandValue;
UINT32 Value32;
UINT64 Address;
//EFI_STATUS Status;
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;
PciRootBridgeIo = PciDevice->PciRootBridgeIo;
if (Enable) {
Address = EFI_PCI_ADDRESS (PciDevice->BusNumber, PciDevice->DeviceNumber, PciDevice->FunctionNumber, RomBarIndex);
//
// set the Rom base address: now is hardcode
//
PciRootBridgeIo->Pci.Write(
PciRootBridgeIo,
EfiPciWidthUint32,
Address,
1,
&RomBar);
//
// enable its decoder
//
Value32 = RomBar | 0x1;
PciRootBridgeIo->Pci.Write(
PciRootBridgeIo,
EfiPciWidthUint32,
Address,
1,
&Value32);
//
//setting the memory space bit in the function's command register
//
Address = EFI_PCI_ADDRESS (PciDevice->BusNumber, PciDevice->DeviceNumber, PciDevice->FunctionNumber, 0x04);
PciRootBridgeIo->Pci.Read(
PciRootBridgeIo,
EfiPciWidthUint16,
Address,
1,
&CommandValue);
CommandValue = (UINT16)(CommandValue | 0x0002); //0x0003
PciRootBridgeIo->Pci.Write(
PciRootBridgeIo,
EfiPciWidthUint16,
Address,
1,
&CommandValue);
} else {
//
// disable rom decode
//
Address = EFI_PCI_ADDRESS (PciDevice->BusNumber, PciDevice->DeviceNumber, PciDevice->FunctionNumber, RomBarIndex);
Value32 = 0xfffffffe;
PciRootBridgeIo->Pci.Write(
PciRootBridgeIo,
EfiPciWidthUint32,
Address,
1,
&Value32);
}
return EFI_SUCCESS;
}
EFI_STATUS
ProcessOpRomImage (
PCI_IO_DEVICE *PciDevice
)
/*++
Routine Description:
Process the oprom image.
Arguments:
PciDevice A pointer to a pci device.
Returns:
EFI Status.
--*/
{
UINT8 Indicator;
UINT32 ImageSize;
UINT16 ImageOffset;
VOID *RomBar;
UINT8 *RomBarOffset;
EFI_HANDLE ImageHandle;
EFI_STATUS Status;
EFI_STATUS retStatus;
BOOLEAN SkipImage;
UINT32 DestinationSize;
UINT32 ScratchSize;
UINT8 *Scratch;
VOID *ImageBuffer;
VOID *DecompressedImageBuffer;
UINT32 ImageLength;
EFI_DECOMPRESS_PROTOCOL *Decompress;
EFI_PCI_EXPANSION_ROM_HEADER *EfiRomHeader;
PCI_DATA_STRUCTURE *Pcir;
UINT32 InitializationSize;
Indicator = 0;
//
// Get the Address of the Rom image
//
RomBar = PciDevice->PciIo.RomImage;
RomBarOffset = (UINT8 *) RomBar;
retStatus = EFI_NOT_FOUND;
if (RomBarOffset == NULL) {
return retStatus;
}
ASSERT (((EFI_PCI_EXPANSION_ROM_HEADER *) RomBarOffset)->Signature == PCI_EXPANSION_ROM_HEADER_SIGNATURE);
do {
EfiRomHeader = (EFI_PCI_EXPANSION_ROM_HEADER *) RomBarOffset;
if (EfiRomHeader->Signature != PCI_EXPANSION_ROM_HEADER_SIGNATURE) {
RomBarOffset = RomBarOffset + 512;
continue;
}
Pcir = (PCI_DATA_STRUCTURE *) (RomBarOffset + EfiRomHeader->PcirOffset);
ASSERT (Pcir->Signature == PCI_DATA_STRUCTURE_SIGNATURE);
ImageSize = (UINT32) (Pcir->ImageLength * 512);
Indicator = Pcir->Indicator;
if ((Pcir->CodeType == PCI_CODE_TYPE_EFI_IMAGE) &&
(EfiRomHeader->EfiSignature == EFI_PCI_EXPANSION_ROM_HEADER_EFISIGNATURE) &&
((EfiRomHeader->EfiSubsystem == EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER) ||
(EfiRomHeader->EfiSubsystem == EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER))) {
ImageOffset = EfiRomHeader->EfiImageHeaderOffset;
InitializationSize = EfiRomHeader->InitializationSize * 512;
if (InitializationSize <= ImageSize && ImageOffset < InitializationSize) {
ImageBuffer = (VOID *) (RomBarOffset + ImageOffset);
ImageLength = InitializationSize - (UINT32)ImageOffset;
DecompressedImageBuffer = NULL;
//
// decompress here if needed
//
SkipImage = FALSE;
if (EfiRomHeader->CompressionType > EFI_PCI_EXPANSION_ROM_HEADER_COMPRESSED) {
SkipImage = TRUE;
}
if (EfiRomHeader->CompressionType == EFI_PCI_EXPANSION_ROM_HEADER_COMPRESSED) {
Status = gBS->LocateProtocol (&gEfiDecompressProtocolGuid, NULL, (VOID **) &Decompress);
if (EFI_ERROR (Status)) {
SkipImage = TRUE;
} else {
SkipImage = TRUE;
Status = Decompress->GetInfo (
Decompress,
ImageBuffer,
ImageLength,
&DestinationSize,
&ScratchSize
);
if (!EFI_ERROR (Status)) {
DecompressedImageBuffer = NULL;
DecompressedImageBuffer = AllocatePool (DestinationSize);
if (DecompressedImageBuffer != NULL) {
Scratch = AllocatePool (ScratchSize);
if (Scratch != NULL) {
Status = Decompress->Decompress (
Decompress,
ImageBuffer,
ImageLength,
DecompressedImageBuffer,
DestinationSize,
Scratch,
ScratchSize
);
if (!EFI_ERROR (Status)) {
ImageBuffer = DecompressedImageBuffer;
ImageLength = DestinationSize;
SkipImage = FALSE;
}
gBS->FreePool (Scratch);
}
}
}
}
}
if (!SkipImage) {
//
// load image and start image
//
Status = gBS->LoadImage (
FALSE,
gPciBusDriverBinding.DriverBindingHandle,
NULL,
ImageBuffer,
ImageLength,
&ImageHandle
);
if (!EFI_ERROR (Status)) {
Status = gBS->StartImage (ImageHandle, NULL, NULL);
if (!EFI_ERROR (Status)) {
AddDriver (PciDevice, ImageHandle);
retStatus = EFI_SUCCESS;
}
}
}
RomBarOffset = RomBarOffset + ImageSize;
} else {
RomBarOffset = RomBarOffset + ImageSize;
}
} else {
RomBarOffset = RomBarOffset + ImageSize;
}
} while (((Indicator & 0x80) == 0x00) && ((UINTN) (RomBarOffset - (UINT8 *) RomBar) < PciDevice->RomSize));
return retStatus;
}

View File

@@ -0,0 +1,92 @@
/*++
Copyright (c) 2005 - 2006, 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.
Module Name:
PciOptionRomSupport.h
Abstract:
PCI Bus Driver
Revision History
--*/
#ifndef _EFI_PCI_OP_ROM_SUPPORT_H
#define _EFI_PCI_OP_ROM_SUPPORT_H
EFI_STATUS
GetOpRomInfo (
IN PCI_IO_DEVICE *PciIoDevice
)
/*++
Routine Description:
TODO: Add function description
Arguments:
PciIoDevice - TODO: add argument description
Returns:
TODO: add return values
--*/
;
EFI_STATUS
LoadOpRomImage (
IN PCI_IO_DEVICE *PciDevice,
IN UINT64 ReservedMemoryBase
)
/*++
Routine Description:
TODO: Add function description
Arguments:
PciDevice - TODO: add argument description
RomBase - TODO: add argument description
Returns:
TODO: add return values
--*/
;
EFI_STATUS
ProcessOpRomImage (
PCI_IO_DEVICE *PciDevice
)
/*++
Routine Description:
TODO: Add function description
Arguments:
PciDevice - TODO: add argument description
Returns:
TODO: add return values
--*/
;
#endif

View File

@@ -0,0 +1,100 @@
/*++
Copyright (c) 2005 - 2012, 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.
Module Name:
PciPowerManagement.c
Abstract:
PCI Bus Driver
Revision History
--*/
#include "PciBus.h"
EFI_STATUS
EFIAPI
ResetPowerManagementFeature (
IN PCI_IO_DEVICE *PciIoDevice
)
/*++
Routine Description:
This function is intended to turn off PWE assertion and
put the device to D0 state if the device supports
PCI Power Management.
Arguments:
Returns:
None
--*/
{
EFI_STATUS Status;
UINT8 PowerManagementRegBlock;
UINT16 PowerManagementCSR;
PowerManagementRegBlock = 0;
Status = LocateCapabilityRegBlock (
PciIoDevice,
EFI_PCI_CAPABILITY_ID_PMI,
&PowerManagementRegBlock,
NULL
);
if (EFI_ERROR (Status)) {
return EFI_UNSUPPORTED;
}
//
// Turn off the PWE assertion and put the device into D0 State
//
//
// Read PMCSR
//
Status = PciIoDevice->PciIo.Pci.Read (
&PciIoDevice->PciIo,
EfiPciIoWidthUint16,
PowerManagementRegBlock + 4,
1,
&PowerManagementCSR
);
if (!EFI_ERROR (Status)) {
//
// Clear PME_Status bit
//
PowerManagementCSR |= BIT15;
//
// Clear PME_En bit. PowerState = D0.
//
PowerManagementCSR &= ~(BIT8 | BIT1 | BIT0);
//
// Write PMCSR
//
Status = PciIoDevice->PciIo.Pci.Write (
&PciIoDevice->PciIo,
EfiPciIoWidthUint16,
PowerManagementRegBlock + 4,
1,
&PowerManagementCSR
);
}
return Status;
}

View File

@@ -0,0 +1,49 @@
/*++
Copyright (c) 2005 - 2006, 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.
Module Name:
PciPowerManagement.h
Abstract:
PCI Bus Driver
Revision History
--*/
#ifndef _EFI_PCI_POWER_MANAGEMENT_H
#define _EFI_PCI_POWER_MANAGEMENT_H
EFI_STATUS
EFIAPI
ResetPowerManagementFeature (
IN PCI_IO_DEVICE *PciIoDevice
)
/*++
Routine Description:
TODO: Add function description
Arguments:
PciIoDevice - TODO: add argument description
Returns:
TODO: add return values
--*/
;
#endif

View File

@@ -0,0 +1,393 @@
/*++
Copyright (c) 2005 - 2012, 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.
Module Name:
PciRomTable.c
Abstract:
Option Rom Support for PCI Bus Driver
Revision History
--*/
#include "PciBus.h"
typedef struct {
EFI_HANDLE ImageHandle;
UINTN Seg;
UINT8 Bus;
UINT8 Dev;
UINT8 Func;
} EFI_PCI_ROM_IMAGE_MAPPING;
UINTN mNumberOfPciRomImages = 0;
UINTN mMaxNumberOfPciRomImages = 0;
EFI_PCI_ROM_IMAGE_MAPPING *mRomImageTable = NULL;
CHAR16 mHexDigit[17] = L"0123456789ABCDEF";
VOID
PciRomAddImageMapping (
IN EFI_HANDLE ImageHandle,
IN UINTN Seg,
IN UINT8 Bus,
IN UINT8 Dev,
IN UINT8 Func
)
{
EFI_PCI_ROM_IMAGE_MAPPING *TempMapping;
if (mNumberOfPciRomImages >= mMaxNumberOfPciRomImages) {
mMaxNumberOfPciRomImages += 0x20;
TempMapping = NULL;
TempMapping = AllocatePool (mMaxNumberOfPciRomImages * sizeof (EFI_PCI_ROM_IMAGE_MAPPING));
if (TempMapping == NULL) {
return ;
}
CopyMem (TempMapping, mRomImageTable, mNumberOfPciRomImages * sizeof (EFI_PCI_ROM_IMAGE_MAPPING));
if (mRomImageTable != NULL) {
gBS->FreePool (mRomImageTable);
}
mRomImageTable = TempMapping;
}
mRomImageTable[mNumberOfPciRomImages].ImageHandle = ImageHandle;
mRomImageTable[mNumberOfPciRomImages].Seg = Seg;
mRomImageTable[mNumberOfPciRomImages].Bus = Bus;
mRomImageTable[mNumberOfPciRomImages].Dev = Dev;
mRomImageTable[mNumberOfPciRomImages].Func = Func;
mNumberOfPciRomImages++;
}
VOID
HexToString (
CHAR16 *String,
UINTN Value,
UINTN Digits
)
{
for (; Digits > 0; Digits--, String++) {
*String = mHexDigit[((Value >> (4*(Digits-1))) & 0x0f)];
}
}
EFI_STATUS
PciRomLoadEfiDriversFromRomImage (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_PCI_OPTION_ROM_DESCRIPTOR *PciOptionRomDescriptor
)
/*++
Routine Description:
Command entry point.
Arguments:
ImageHandle The image handle.
SystemTable The system table.
Returns:
EFI_SUCCESS - The command completed successfully
EFI_INVALID_PARAMETER - Command usage error
EFI_UNSUPPORTED - Protocols unsupported
EFI_OUT_OF_RESOURCES - Out of memory
Other value - Unknown error
--*/
{
VOID *RomBar;
UINTN RomSize;
CHAR16 *FileName;
EFI_PCI_EXPANSION_ROM_HEADER *EfiRomHeader;
PCI_DATA_STRUCTURE *Pcir;
UINTN ImageIndex;
UINTN RomBarOffset;
UINT32 ImageSize;
UINT16 ImageOffset;
EFI_HANDLE ImageHandle;
EFI_STATUS Status;
EFI_STATUS retStatus;
EFI_DEVICE_PATH_PROTOCOL *FilePath;
BOOLEAN SkipImage;
UINT32 DestinationSize;
UINT32 ScratchSize;
UINT8 *Scratch;
VOID *ImageBuffer;
VOID *DecompressedImageBuffer;
UINT32 ImageLength;
EFI_DECOMPRESS_PROTOCOL *Decompress;
UINT32 InitializationSize;
RomBar = (VOID *) (UINTN) PciOptionRomDescriptor->RomAddress;
RomSize = (UINTN) PciOptionRomDescriptor->RomLength;
FileName = L"PciRom Seg=00000000 Bus=00 Dev=00 Func=00 Image=0000";
HexToString (&FileName[11], PciOptionRomDescriptor->Seg, 8);
HexToString (&FileName[24], PciOptionRomDescriptor->Bus, 2);
HexToString (&FileName[31], PciOptionRomDescriptor->Dev, 2);
HexToString (&FileName[39], PciOptionRomDescriptor->Func, 2);
ImageIndex = 0;
retStatus = EFI_NOT_FOUND;
RomBarOffset = (UINTN) RomBar;
do {
EfiRomHeader = (EFI_PCI_EXPANSION_ROM_HEADER *) (UINTN) RomBarOffset;
if (EfiRomHeader->Signature != PCI_EXPANSION_ROM_HEADER_SIGNATURE) {
return retStatus;
}
//
// If the pointer to the PCI Data Structure is invalid, no further images can be located.
// The PCI Data Structure must be DWORD aligned.
//
if (EfiRomHeader->PcirOffset == 0 ||
(EfiRomHeader->PcirOffset & 3) != 0 ||
RomBarOffset - (UINTN)RomBar + EfiRomHeader->PcirOffset + sizeof (PCI_DATA_STRUCTURE) > RomSize) {
break;
}
Pcir = (PCI_DATA_STRUCTURE *) (UINTN) (RomBarOffset + EfiRomHeader->PcirOffset);
//
// If a valid signature is not present in the PCI Data Structure, no further images can be located.
//
if (Pcir->Signature != PCI_DATA_STRUCTURE_SIGNATURE) {
break;
}
ImageSize = Pcir->ImageLength * 512;
if (RomBarOffset - (UINTN)RomBar + ImageSize > RomSize) {
break;
}
if ((Pcir->CodeType == PCI_CODE_TYPE_EFI_IMAGE) &&
(EfiRomHeader->EfiSignature == EFI_PCI_EXPANSION_ROM_HEADER_EFISIGNATURE) &&
((EfiRomHeader->EfiSubsystem == EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER) ||
(EfiRomHeader->EfiSubsystem == EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER))) {
ImageOffset = EfiRomHeader->EfiImageHeaderOffset;
InitializationSize = EfiRomHeader->InitializationSize * 512;
if (InitializationSize <= ImageSize && ImageOffset < InitializationSize) {
ImageBuffer = (VOID *) (UINTN) (RomBarOffset + ImageOffset);
ImageLength = InitializationSize - ImageOffset;
DecompressedImageBuffer = NULL;
//
// decompress here if needed
//
SkipImage = FALSE;
if (EfiRomHeader->CompressionType > EFI_PCI_EXPANSION_ROM_HEADER_COMPRESSED) {
SkipImage = TRUE;
}
if (EfiRomHeader->CompressionType == EFI_PCI_EXPANSION_ROM_HEADER_COMPRESSED) {
Status = gBS->LocateProtocol (&gEfiDecompressProtocolGuid, NULL, (VOID **) &Decompress);
if (EFI_ERROR (Status)) {
SkipImage = TRUE;
} else {
SkipImage = TRUE;
Status = Decompress->GetInfo (
Decompress,
ImageBuffer,
ImageLength,
&DestinationSize,
&ScratchSize
);
if (!EFI_ERROR (Status)) {
DecompressedImageBuffer = NULL;
DecompressedImageBuffer = AllocatePool (DestinationSize);
if (DecompressedImageBuffer != NULL) {
Scratch = AllocatePool (ScratchSize);
if (Scratch != NULL) {
Status = Decompress->Decompress (
Decompress,
ImageBuffer,
ImageLength,
DecompressedImageBuffer,
DestinationSize,
Scratch,
ScratchSize
);
if (!EFI_ERROR (Status)) {
ImageBuffer = DecompressedImageBuffer;
ImageLength = DestinationSize;
SkipImage = FALSE;
}
gBS->FreePool (Scratch);
}
}
}
}
}
if (!SkipImage) {
//
// load image and start image
//
HexToString (&FileName[48], ImageIndex, 4);
FilePath = FileDevicePath (NULL, FileName);
Status = gBS->LoadImage (
FALSE,
This->ImageHandle,
FilePath,
ImageBuffer,
ImageLength,
&ImageHandle
);
if (!EFI_ERROR (Status)) {
Status = gBS->StartImage (ImageHandle, NULL, NULL);
if (!EFI_ERROR (Status)) {
PciRomAddImageMapping (
ImageHandle,
PciOptionRomDescriptor->Seg,
PciOptionRomDescriptor->Bus,
PciOptionRomDescriptor->Dev,
PciOptionRomDescriptor->Func
);
retStatus = Status;
}
}
if (FilePath != NULL) {
gBS->FreePool (FilePath);
}
}
if (DecompressedImageBuffer != NULL) {
gBS->FreePool (DecompressedImageBuffer);
}
}
}
RomBarOffset = RomBarOffset + ImageSize;
ImageIndex++;
} while (((Pcir->Indicator & 0x80) == 0x00) && ((RomBarOffset - (UINTN) RomBar) < RomSize));
return retStatus;
}
EFI_STATUS
PciRomLoadEfiDriversFromOptionRomTable (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo
)
/*++
Routine Description:
Arguments:
Returns:
--*/
{
EFI_STATUS Status;
EFI_PCI_OPTION_ROM_TABLE *PciOptionRomTable;
EFI_PCI_OPTION_ROM_DESCRIPTOR *PciOptionRomDescriptor;
UINTN Index;
EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptors;
UINT16 MinBus;
UINT16 MaxBus;
Status = EfiGetSystemConfigurationTable (&gEfiPciOptionRomTableGuid, (VOID **) &PciOptionRomTable);
if (EFI_ERROR (Status)) {
return EFI_NOT_FOUND;
}
Status = EFI_NOT_FOUND;
for (Index = 0; Index < PciOptionRomTable->PciOptionRomCount; Index++) {
PciOptionRomDescriptor = &PciOptionRomTable->PciOptionRomDescriptors[Index];
if (!PciOptionRomDescriptor->DontLoadEfiRom) {
if (PciOptionRomDescriptor->Seg == PciRootBridgeIo->SegmentNumber) {
Status = PciRootBridgeIo->Configuration (PciRootBridgeIo, (VOID **) &Descriptors);
if (EFI_ERROR (Status)) {
return Status;
}
PciGetBusRange (&Descriptors, &MinBus, &MaxBus, NULL);
if ((MinBus <= PciOptionRomDescriptor->Bus) && (PciOptionRomDescriptor->Bus <= MaxBus)) {
Status = PciRomLoadEfiDriversFromRomImage (This, PciOptionRomDescriptor);
PciOptionRomDescriptor->DontLoadEfiRom |= 2;
}
}
}
}
return Status;
}
EFI_STATUS
PciRomGetRomResourceFromPciOptionRomTable (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo,
PCI_IO_DEVICE *PciIoDevice
)
/*++
Routine Description:
Arguments:
Returns:
--*/
{
EFI_STATUS Status;
EFI_PCI_OPTION_ROM_TABLE *PciOptionRomTable;
EFI_PCI_OPTION_ROM_DESCRIPTOR *PciOptionRomDescriptor;
UINTN Index;
Status = EfiGetSystemConfigurationTable (&gEfiPciOptionRomTableGuid, (VOID **) &PciOptionRomTable);
if (EFI_ERROR (Status)) {
return EFI_NOT_FOUND;
}
for (Index = 0; Index < PciOptionRomTable->PciOptionRomCount; Index++) {
PciOptionRomDescriptor = &PciOptionRomTable->PciOptionRomDescriptors[Index];
if (PciOptionRomDescriptor->Seg == PciRootBridgeIo->SegmentNumber &&
PciOptionRomDescriptor->Bus == PciIoDevice->BusNumber &&
PciOptionRomDescriptor->Dev == PciIoDevice->DeviceNumber &&
PciOptionRomDescriptor->Func == PciIoDevice->FunctionNumber ) {
PciIoDevice->PciIo.RomImage = (VOID *) (UINTN) PciOptionRomDescriptor->RomAddress;
PciIoDevice->PciIo.RomSize = (UINTN) PciOptionRomDescriptor->RomLength;
}
}
for (Index = 0; Index < mNumberOfPciRomImages; Index++) {
if (mRomImageTable[Index].Seg == PciRootBridgeIo->SegmentNumber &&
mRomImageTable[Index].Bus == PciIoDevice->BusNumber &&
mRomImageTable[Index].Dev == PciIoDevice->DeviceNumber &&
mRomImageTable[Index].Func == PciIoDevice->FunctionNumber ) {
AddDriver (PciIoDevice, mRomImageTable[Index].ImageHandle);
}
}
return EFI_SUCCESS;
}

View File

@@ -0,0 +1,58 @@
/*++
Copyright (c) 2005 - 2006, 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.
Module Name:
PciRomTable.h
Abstract:
Option Rom Support for PCI Bus Driver
Revision History
--*/
#ifndef _EFI_PCI_ROM_TABLE_H
#define _EFI_PCI_ROM_TABLE_H
EFI_STATUS
PciRomLoadEfiDriversFromOptionRomTable (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo
);
EFI_STATUS
PciRomGetRomResourceFromPciOptionRomTable (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo,
PCI_IO_DEVICE *PciIoDevice
)
/*++
Routine Description:
TODO: Add function description
Arguments:
This - TODO: add argument description
PciRootBridgeIo - TODO: add argument description
PciIoDevice - TODO: add argument description
Returns:
TODO: add return values
--*/
;
#endif

View File

@@ -0,0 +1,365 @@
/** @file
Implementation for a generic GOP driver.
Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include "PciPlatformDxe.h"
#include <Bus/Pci/PciBusDxe/PciBus.h>
#include <Bus/Pci/PciBusDxe/PciOptionRomSupport.h>
//
// The driver should only start on one graphics controller.
// So a global flag is used to remember that the driver is already started.
//
EFI_HANDLE mDriverHandle = NULL;
EFI_STATUS
EFIAPI
PciPlatformNotify(
IN EFI_PCI_PLATFORM_PROTOCOL *This,
IN EFI_HANDLE HostBridge,
IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PHASE Phase,
IN EFI_PCI_EXECUTION_PHASE ExecPhase
)
{
return EFI_UNSUPPORTED;
}
EFI_STATUS
EFIAPI
PciPlatformPrepController(
IN EFI_PCI_PLATFORM_PROTOCOL *This,
IN EFI_HANDLE HostBridge,
IN EFI_HANDLE RootBridge,
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS PciAddress,
IN EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE Phase,
IN EFI_PCI_EXECUTION_PHASE ExecPhase
)
{
return EFI_UNSUPPORTED;
}
EFI_STATUS
EFIAPI
PciGetPciRom (
IN CONST EFI_PCI_PLATFORM_PROTOCOL *This,
IN EFI_HANDLE PciHandle,
OUT VOID **RomImage,
OUT UINTN *RomSize
)
{
EFI_STATUS Status;
IN EFI_PCI_IO_PROTOCOL *PciIo;
UINTN PciSegment;
UINTN PciBus;
UINTN PciDevice;
UINTN PciFunction;
UINTN RomBarIndex;
UINT32 Buffer;
UINT32 AllOnes;
PCI_IO_DEVICE *PciIoDevice;
UINT8 Indicator;
UINT16 OffsetPcir;
UINT32 RomBarOffset;
UINT32 RomBar;
BOOLEAN FirstCheck;
PCI_EXPANSION_ROM_HEADER *RomHeader;
PCI_DATA_STRUCTURE *RomPcir;
UINT64 RomImageSize;
UINT32 LegacyImageLength;
UINT8 *RomInMemory;
UINT8 CodeType;
if (!RomImage || !RomSize) {
return EFI_INVALID_PARAMETER;
}
*RomImage = NULL;
*RomSize = 0;
Status = gBS->HandleProtocol (
PciHandle,
&gEfiPciIoProtocolGuid,
(VOID **) &PciIo
);
if (EFI_ERROR (Status)) {
DEBUG ((EFI_D_INFO, "%a: Failed to open gEfiPciIoProtocolGuid\n", __FUNCTION__));
return EFI_UNSUPPORTED;
}
PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (PciIo);
//
// Get the location of the PCI device
//
PciIo->GetLocation (
PciIo,
&PciSegment,
&PciBus,
&PciDevice,
&PciFunction
);
DEBUG ((EFI_D_INFO, "%a: Searching Option ROM on device:\n", __FUNCTION__));
DEBUG ((EFI_D_INFO, " PciSegment - %02x\n", PciSegment));
DEBUG ((EFI_D_INFO, " PciBus - %02x\n", PciBus));
DEBUG ((EFI_D_INFO, " PciDevice - %02x\n", PciDevice));
DEBUG ((EFI_D_INFO, " PciFunction - %02x\n", PciFunction));
//
// 0x30
//
RomBarIndex = PCI_EXPANSION_ROM_BASE;
if (IS_PCI_BRIDGE (&PciIoDevice->Pci)) {
//
// If is ppb, 0x38
//
RomBarIndex = PCI_BRIDGE_ROMBAR;
}
//
// Backup BAR
//
Status = PciIo->Pci.Read (
PciIo,
EfiPciWidthUint32,
RomBarIndex,
1,
&Buffer
);
if (EFI_ERROR (Status)) {
goto CloseAndReturn;
return Status;
}
//
// The bit0 is 0 to prevent the enabling of the Rom address decoder
//
AllOnes = 0xfffffffe;
Status = PciIo->Pci.Write (
PciIo,
EfiPciWidthUint32,
RomBarIndex,
1,
&AllOnes
);
if (EFI_ERROR (Status)) {
goto CloseAndReturn;
}
//
// Read back
//
Status = PciIo->Pci.Read(
PciIo,
EfiPciWidthUint32,
RomBarIndex,
1,
&AllOnes
);
if (EFI_ERROR (Status)) {
goto CloseAndReturn;
}
//
// Bits [1, 10] are reserved
//
AllOnes &= 0xFFFFF800;
if ((AllOnes == 0) || (AllOnes == 0xFFFFF800)) {
DEBUG ((EFI_D_INFO, "%a: No Option ROM found\n", __FUNCTION__));
return EFI_NOT_FOUND;
}
*RomSize = (~AllOnes) + 1;
DEBUG ((EFI_D_INFO, "%a: Option ROM with size %d\n", __FUNCTION__, *RomSize));
//
// Restore BAR and enable it
//
Buffer |= 1;
Status = PciIo->Pci.Write (
PciIo,
EfiPciWidthUint32,
RomBarIndex,
1,
&Buffer
);
if (EFI_ERROR (Status)) {
goto CloseAndReturn;
}
//
// Allocate memory for Rom header and PCIR
//
RomHeader = AllocatePool (sizeof (PCI_EXPANSION_ROM_HEADER));
if (RomHeader == NULL) {
Status = EFI_OUT_OF_RESOURCES;
goto CloseAndReturn;
}
RomPcir = AllocatePool (sizeof (PCI_DATA_STRUCTURE));
if (RomPcir == NULL) {
FreePool (RomHeader);
Status = EFI_OUT_OF_RESOURCES;
goto CloseAndReturn;
}
// FIXME: Use gEfiPciRootBridgeIoProtocolGuid
RomBar = (UINT32) Buffer &~1;
RomBarOffset = RomBar;
FirstCheck = TRUE;
LegacyImageLength = 0;
RomImageSize = 0;
do {
// FIXME: Use gEfiPciRootBridgeIoProtocolGuid
CopyMem(RomHeader, (VOID *)(UINTN)RomBarOffset, sizeof (PCI_EXPANSION_ROM_HEADER));
DEBUG ((EFI_D_INFO, "%a: RomHeader->Signature %x\n", __FUNCTION__, RomHeader->Signature));
if (RomHeader->Signature != PCI_EXPANSION_ROM_HEADER_SIGNATURE) {
RomBarOffset = RomBarOffset + 512;
if (FirstCheck) {
break;
} else {
RomImageSize = RomImageSize + 512;
continue;
}
}
FirstCheck = FALSE;
OffsetPcir = RomHeader->PcirOffset;
//
// If the pointer to the PCI Data Structure is invalid, no further images can be located.
// The PCI Data Structure must be DWORD aligned.
//
if (OffsetPcir == 0 ||
(OffsetPcir & 3) != 0 ||
RomImageSize + OffsetPcir + sizeof (PCI_DATA_STRUCTURE) > *RomSize) {
break;
}
// FIXME: Use gEfiPciRootBridgeIoProtocolGuid
CopyMem(RomPcir, (VOID *)(UINTN)RomBarOffset + OffsetPcir, sizeof (PCI_DATA_STRUCTURE));
DEBUG ((EFI_D_INFO, "%a: RomPcir->Signature %x\n", __FUNCTION__, RomPcir->Signature));
//
// If a valid signature is not present in the PCI Data Structure, no further images can be located.
//
if (RomPcir->Signature != PCI_DATA_STRUCTURE_SIGNATURE) {
break;
}
if (RomImageSize + RomPcir->ImageLength * 512 > *RomSize) {
break;
}
if (RomPcir->CodeType == PCI_CODE_TYPE_PCAT_IMAGE) {
CodeType = PCI_CODE_TYPE_PCAT_IMAGE;
LegacyImageLength = ((UINT32)((EFI_LEGACY_EXPANSION_ROM_HEADER *)RomHeader)->Size512) * 512;
}
Indicator = RomPcir->Indicator;
RomImageSize = RomImageSize + RomPcir->ImageLength * 512;
RomBarOffset = RomBarOffset + RomPcir->ImageLength * 512;
} while (((Indicator & 0x80) == 0x00) && ((RomBarOffset - RomBar) < *RomSize));
//
// Some Legacy Cards do not report the correct ImageLength so used the maximum
// of the legacy length and the PCIR Image Length
//
if (CodeType == PCI_CODE_TYPE_PCAT_IMAGE) {
RomImageSize = MAX (RomImageSize, LegacyImageLength);
}
if (RomImageSize > 0) {
// FIXME: Use gEfiPciRootBridgeIoProtocolGuid
RomInMemory = (VOID *)(UINTN)RomBar;
}
//
// Free allocated memory
//
FreePool (RomHeader);
FreePool (RomPcir);
if (RomImageSize > 0) {
*RomImage = RomInMemory;
*RomSize = RomImageSize;
DEBUG ((EFI_D_INFO, "%a: Found Option ROM at %p, length 0x%x\n", __FUNCTION__,
RomInMemory, RomImageSize));
Status = EFI_SUCCESS;
} else {
Status = EFI_NOT_FOUND;
}
CloseAndReturn:
//
// Close the I/O Abstraction(s) used to perform the supported test
//
gBS->CloseProtocol (
PciHandle,
&gEfiPciIoProtocolGuid,
PciIo,
PciHandle
);
return Status;
}
EFI_STATUS
EFIAPI
PciGetPlatformPolicy (
IN CONST EFI_PCI_PLATFORM_PROTOCOL *This,
OUT EFI_PCI_PLATFORM_POLICY *PciPolicy
)
{
if (PciPolicy == NULL)
return EFI_INVALID_PARAMETER;
*PciPolicy = 0;
return EFI_SUCCESS;
}
EFI_PCI_PLATFORM_PROTOCOL mPciPlatformProtocol = {
PciPlatformNotify,
PciPlatformPrepController,
PciGetPlatformPolicy,
PciGetPciRom,
};
/**
The Entry Point for Option ROM driver.
It installs DriverBinding.
@retval EFI_SUCCESS The entry point is executed successfully.
@retval other Some error occurs when executing this entry point.
**/
EFI_STATUS
EFIAPI
InstallPciPlatformProtocol (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EFI_STATUS Status;
Status = gBS->InstallProtocolInterface (
&mDriverHandle,
&gEfiPciPlatformProtocolGuid,
EFI_NATIVE_INTERFACE,
&mPciPlatformProtocol
);
return Status;
}

View File

@@ -0,0 +1,19 @@
/** @file
Header file for a PCI platform driver.
Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#ifndef _PCI_PLATFORM_DXE_H_
#define _PCI_PLATFORM_DXE_H_
#include <PiDxe.h>
#include <IndustryStandard/Pci.h>
#include <IndustryStandard/Acpi.h>
#include <IndustryStandard/Pci22.h>
#include <Protocol/PciIo.h>
#include <Protocol/PciPlatform.h>
#endif

View File

@@ -0,0 +1,46 @@
## @file
# This driver produces gEfiPciPlatform protocol to load PCI Option ROMs
#
# Copyright (c) 2020, 9elements Agency GmbH
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
#
##
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = PciPlatformDxe
FILE_GUID = 86D58F7B-6E7C-401F-BDD4-E32E6D582AAD
MODULE_TYPE = UEFI_DRIVER
VERSION_STRING = 1.0
ENTRY_POINT = InstallPciPlatformProtocol
#
# The following information is for reference only and not required by the build tools.
#
# VALID_ARCHITECTURES = IA32 X64
#
[Sources.common]
PciPlatformDxe.h
PciPlatformDxe.c
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
[LibraryClasses]
UefiDriverEntryPoint
UefiBootServicesTableLib
DxeServicesTableLib
DebugLib
MemoryAllocationLib
BaseMemoryLib
DevicePathLib
UefiLib
HobLib
[Protocols]
gEfiPciPlatformProtocolGuid ## PRODUCES
gEfiPciIoProtocolGuid ## COMSUMES

View File

@@ -0,0 +1,845 @@
/*++
Copyright (c) 2006 - 2012, 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.
Module Name:
DeviceIo.c
Abstract:
EFI PC-AT PCI Device IO driver
--*/
#include "PcatPciRootBridge.h"
#include "DeviceIo.h"
EFI_STATUS
DeviceIoConstructor (
IN EFI_HANDLE Handle,
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo,
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
IN UINT16 PrimaryBus,
IN UINT16 SubordinateBus
)
/*++
Routine Description:
Initialize and install a Device IO protocol on a empty device path handle.
Arguments:
Handle - Handle of PCI RootBridge IO instance
PciRootBridgeIo - PCI RootBridge IO instance
DevicePath - Device Path of PCI RootBridge IO instance
PrimaryBus - Primary Bus
SubordinateBus - Subordinate Bus
Returns:
EFI_SUCCESS - This driver is added to ControllerHandle.
EFI_ALREADY_STARTED - This driver is already running on ControllerHandle.
Others - This driver does not support this device.
--*/
{
EFI_STATUS Status;
DEVICE_IO_PRIVATE_DATA *Private;
//
// Initialize the Device IO device instance.
//
Private = AllocateZeroPool (sizeof (DEVICE_IO_PRIVATE_DATA));
if (Private == NULL) {
return EFI_OUT_OF_RESOURCES;
}
Private->Signature = DEVICE_IO_PRIVATE_DATA_SIGNATURE;
Private->Handle = Handle;
Private->PciRootBridgeIo = PciRootBridgeIo;
Private->DevicePath = DevicePath;
Private->PrimaryBus = PrimaryBus;
Private->SubordinateBus = SubordinateBus;
Private->DeviceIo.Mem.Read = DeviceIoMemRead;
Private->DeviceIo.Mem.Write = DeviceIoMemWrite;
Private->DeviceIo.Io.Read = DeviceIoIoRead;
Private->DeviceIo.Io.Write = DeviceIoIoWrite;
Private->DeviceIo.Pci.Read = DeviceIoPciRead;
Private->DeviceIo.Pci.Write = DeviceIoPciWrite;
Private->DeviceIo.PciDevicePath = DeviceIoPciDevicePath;
Private->DeviceIo.Map = DeviceIoMap;
Private->DeviceIo.Unmap = DeviceIoUnmap;
Private->DeviceIo.AllocateBuffer = DeviceIoAllocateBuffer;
Private->DeviceIo.Flush = DeviceIoFlush;
Private->DeviceIo.FreeBuffer = DeviceIoFreeBuffer;
//
// Install protocol interfaces for the Device IO device.
//
Status = gBS->InstallMultipleProtocolInterfaces (
&Private->Handle,
&gEfiDeviceIoProtocolGuid,
&Private->DeviceIo,
NULL
);
ASSERT_EFI_ERROR (Status);
return Status;
}
EFI_STATUS
EFIAPI
DeviceIoMemRead (
IN EFI_DEVICE_IO_PROTOCOL *This,
IN EFI_IO_WIDTH Width,
IN UINT64 Address,
IN UINTN Count,
IN OUT VOID *Buffer
)
/*++
Routine Description:
Perform reading memory mapped I/O space of device.
Arguments:
This - A pointer to EFI_DEVICE_IO protocol instance.
Width - Width of I/O operations.
Address - The base address of I/O operations.
Count - The number of I/O operations to perform.
Bytes moves is Width size * Count, starting at Address.
Buffer - The destination buffer to store results.
Returns:
EFI_SUCCESS - The data was read from the device.
EFI_INVALID_PARAMETER - Width is invalid.
EFI_OUT_OF_RESOURCES - The request could not be completed due to lack of resources.
--*/
{
EFI_STATUS Status;
DEVICE_IO_PRIVATE_DATA *Private;
Private = DEVICE_IO_PRIVATE_DATA_FROM_THIS (This);
if (Width > MMIO_COPY_UINT64) {
return EFI_INVALID_PARAMETER;
}
if (Width >= MMIO_COPY_UINT8) {
Width = (EFI_IO_WIDTH) (Width - MMIO_COPY_UINT8);
Status = Private->PciRootBridgeIo->CopyMem (
Private->PciRootBridgeIo,
(EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,
(UINT64)(UINTN) Buffer,
Address,
Count
);
} else {
Status = Private->PciRootBridgeIo->Mem.Read (
Private->PciRootBridgeIo,
(EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,
Address,
Count,
Buffer
);
}
return Status;
}
EFI_STATUS
EFIAPI
DeviceIoMemWrite (
IN EFI_DEVICE_IO_PROTOCOL *This,
IN EFI_IO_WIDTH Width,
IN UINT64 Address,
IN UINTN Count,
IN OUT VOID *Buffer
)
/*++
Routine Description:
Perform writing memory mapped I/O space of device.
Arguments:
This - A pointer to EFI_DEVICE_IO protocol instance.
Width - Width of I/O operations.
Address - The base address of I/O operations.
Count - The number of I/O operations to perform.
Bytes moves is Width size * Count, starting at Address.
Buffer - The source buffer of data to be written.
Returns:
EFI_SUCCESS - The data was written to the device.
EFI_INVALID_PARAMETER - Width is invalid.
EFI_OUT_OF_RESOURCES - The request could not be completed due to lack of resources.
--*/
{
EFI_STATUS Status;
DEVICE_IO_PRIVATE_DATA *Private;
Private = DEVICE_IO_PRIVATE_DATA_FROM_THIS (This);
if (Width > MMIO_COPY_UINT64) {
return EFI_INVALID_PARAMETER;
}
if (Width >= MMIO_COPY_UINT8) {
Width = (EFI_IO_WIDTH) (Width - MMIO_COPY_UINT8);
Status = Private->PciRootBridgeIo->CopyMem (
Private->PciRootBridgeIo,
(EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,
Address,
(UINT64)(UINTN) Buffer,
Count
);
} else {
Status = Private->PciRootBridgeIo->Mem.Write (
Private->PciRootBridgeIo,
(EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,
Address,
Count,
Buffer
);
}
return Status;
}
EFI_STATUS
EFIAPI
DeviceIoIoRead (
IN EFI_DEVICE_IO_PROTOCOL *This,
IN EFI_IO_WIDTH Width,
IN UINT64 Address,
IN UINTN Count,
IN OUT VOID *Buffer
)
/*++
Routine Description:
Perform reading I/O space of device.
Arguments:
This - A pointer to EFI_DEVICE_IO protocol instance.
Width - Width of I/O operations.
Address - The base address of I/O operations.
Count - The number of I/O operations to perform.
Bytes moves is Width size * Count, starting at Address.
Buffer - The destination buffer to store results.
Returns:
EFI_SUCCESS - The data was read from the device.
EFI_INVALID_PARAMETER - Width is invalid.
EFI_OUT_OF_RESOURCES - The request could not be completed due to lack of resources.
--*/
{
EFI_STATUS Status;
DEVICE_IO_PRIVATE_DATA *Private;
Private = DEVICE_IO_PRIVATE_DATA_FROM_THIS (This);
if (Width >= MMIO_COPY_UINT8) {
return EFI_INVALID_PARAMETER;
}
Status = Private->PciRootBridgeIo->Io.Read (
Private->PciRootBridgeIo,
(EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,
Address,
Count,
Buffer
);
return Status;
}
EFI_STATUS
EFIAPI
DeviceIoIoWrite (
IN EFI_DEVICE_IO_PROTOCOL *This,
IN EFI_IO_WIDTH Width,
IN UINT64 Address,
IN UINTN Count,
IN OUT VOID *Buffer
)
/*++
Routine Description:
Perform writing I/O space of device.
Arguments:
This - A pointer to EFI_DEVICE_IO protocol instance.
Width - Width of I/O operations.
Address - The base address of I/O operations.
Count - The number of I/O operations to perform.
Bytes moves is Width size * Count, starting at Address.
Buffer - The source buffer of data to be written.
Returns:
EFI_SUCCESS - The data was written to the device.
EFI_INVALID_PARAMETER - Width is invalid.
EFI_OUT_OF_RESOURCES - The request could not be completed due to lack of resources.
--*/
{
EFI_STATUS Status;
DEVICE_IO_PRIVATE_DATA *Private;
Private = DEVICE_IO_PRIVATE_DATA_FROM_THIS (This);
if (Width >= MMIO_COPY_UINT8) {
return EFI_INVALID_PARAMETER;
}
Status = Private->PciRootBridgeIo->Io.Write (
Private->PciRootBridgeIo,
(EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,
Address,
Count,
Buffer
);
return Status;
}
EFI_STATUS
EFIAPI
DeviceIoPciRead (
IN EFI_DEVICE_IO_PROTOCOL *This,
IN EFI_IO_WIDTH Width,
IN UINT64 Address,
IN UINTN Count,
IN OUT VOID *Buffer
)
/*++
Routine Description:
Perform reading PCI configuration space of device
Arguments:
This - A pointer to EFI_DEVICE_IO protocol instance.
Width - Width of I/O operations.
Address - The base address of I/O operations.
Count - The number of I/O operations to perform.
Bytes moves is Width size * Count, starting at Address.
Buffer - The destination buffer to store results.
Returns:
EFI_SUCCESS - The data was read from the device.
EFI_INVALID_PARAMETER - Width is invalid.
EFI_OUT_OF_RESOURCES - The request could not be completed due to lack of resources.
--*/
{
EFI_STATUS Status;
DEVICE_IO_PRIVATE_DATA *Private;
Private = DEVICE_IO_PRIVATE_DATA_FROM_THIS (This);
if ((UINT32)Width >= MMIO_COPY_UINT8) {
return EFI_INVALID_PARAMETER;
}
Status = Private->PciRootBridgeIo->Pci.Read (
Private->PciRootBridgeIo,
(EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,
Address,
Count,
Buffer
);
return Status;
}
EFI_STATUS
EFIAPI
DeviceIoPciWrite (
IN EFI_DEVICE_IO_PROTOCOL *This,
IN EFI_IO_WIDTH Width,
IN UINT64 Address,
IN UINTN Count,
IN OUT VOID *Buffer
)
/*++
Routine Description:
Perform writing PCI configuration space of device.
Arguments:
This - A pointer to EFI_DEVICE_IO protocol instance.
Width - Width of I/O operations.
Address - The base address of I/O operations.
Count - The number of I/O operations to perform.
Bytes moves is Width size * Count, starting at Address.
Buffer - The source buffer of data to be written.
Returns:
EFI_SUCCESS - The data was written to the device.
EFI_INVALID_PARAMETER - Width is invalid.
EFI_OUT_OF_RESOURCES - The request could not be completed due to lack of resources.
--*/
{
EFI_STATUS Status;
DEVICE_IO_PRIVATE_DATA *Private;
Private = DEVICE_IO_PRIVATE_DATA_FROM_THIS (This);
if ((UINT32)Width >= MMIO_COPY_UINT8) {
return EFI_INVALID_PARAMETER;
}
Status = Private->PciRootBridgeIo->Pci.Write (
Private->PciRootBridgeIo,
(EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,
Address,
Count,
Buffer
);
return Status;
}
EFI_DEVICE_PATH_PROTOCOL *
AppendPciDevicePath (
IN DEVICE_IO_PRIVATE_DATA *Private,
IN UINT8 Bus,
IN UINT8 Device,
IN UINT8 Function,
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
IN OUT UINT16 *BridgePrimaryBus,
IN OUT UINT16 *BridgeSubordinateBus
)
/*++
Routine Description:
Append a PCI device path node to another device path.
Arguments:
Private - A pointer to DEVICE_IO_PRIVATE_DATA instance.
Bus - PCI bus number of the device.
Device - PCI device number of the device.
Function - PCI function number of the device.
DevicePath - Original device path which will be appended a PCI device path node.
BridgePrimaryBus - Primary bus number of the bridge.
BridgeSubordinateBus - Subordinate bus number of the bridge.
Returns:
Pointer to the appended PCI device path.
--*/
{
UINT16 ThisBus;
UINT8 ThisDevice;
UINT8 ThisFunc;
UINT64 Address;
PCI_TYPE01 PciBridge;
PCI_TYPE01 *PciPtr;
EFI_DEVICE_PATH_PROTOCOL *ReturnDevicePath;
PCI_DEVICE_PATH PciNode;
PciPtr = &PciBridge;
for (ThisBus = *BridgePrimaryBus; ThisBus <= *BridgeSubordinateBus; ThisBus++) {
for (ThisDevice = 0; ThisDevice <= PCI_MAX_DEVICE; ThisDevice++) {
for (ThisFunc = 0; ThisFunc <= PCI_MAX_FUNC; ThisFunc++) {
Address = EFI_PCI_ADDRESS (ThisBus, ThisDevice, ThisFunc, 0);
ZeroMem (PciPtr, sizeof (PCI_TYPE01));
Private->DeviceIo.Pci.Read (
&Private->DeviceIo,
IO_UINT32,
Address,
1,
&(PciPtr->Hdr.VendorId)
);
if ((PciPtr->Hdr.VendorId == 0xffff) && (ThisFunc == 0)) {
break;
}
if (PciPtr->Hdr.VendorId == 0xffff) {
continue;
}
Private->DeviceIo.Pci.Read (
&Private->DeviceIo,
IO_UINT32,
Address,
sizeof (PCI_TYPE01) / sizeof (UINT32),
PciPtr
);
if (IS_PCI_BRIDGE (PciPtr)) {
if (Bus >= PciPtr->Bridge.SecondaryBus && Bus <= PciPtr->Bridge.SubordinateBus) {
PciNode.Header.Type = HARDWARE_DEVICE_PATH;
PciNode.Header.SubType = HW_PCI_DP;
SetDevicePathNodeLength (&PciNode.Header, sizeof (PciNode));
PciNode.Device = ThisDevice;
PciNode.Function = ThisFunc;
ReturnDevicePath = AppendDevicePathNode (DevicePath, &PciNode.Header);
*BridgePrimaryBus = PciPtr->Bridge.SecondaryBus;
*BridgeSubordinateBus = PciPtr->Bridge.SubordinateBus;
return ReturnDevicePath;
}
}
if ((ThisFunc == 0) && ((PciPtr->Hdr.HeaderType & HEADER_TYPE_MULTI_FUNCTION) == 0x0)) {
//
// Skip sub functions, this is not a multi function device
//
break;
}
}
}
}
ZeroMem (&PciNode, sizeof (PciNode));
PciNode.Header.Type = HARDWARE_DEVICE_PATH;
PciNode.Header.SubType = HW_PCI_DP;
SetDevicePathNodeLength (&PciNode.Header, sizeof (PciNode));
PciNode.Device = Device;
PciNode.Function = Function;
ReturnDevicePath = AppendDevicePathNode (DevicePath, &PciNode.Header);
*BridgePrimaryBus = 0xffff;
*BridgeSubordinateBus = 0xffff;
return ReturnDevicePath;
}
EFI_STATUS
EFIAPI
DeviceIoPciDevicePath (
IN EFI_DEVICE_IO_PROTOCOL *This,
IN UINT64 Address,
IN OUT EFI_DEVICE_PATH_PROTOCOL **PciDevicePath
)
/*++
Routine Description:
Provides an EFI Device Path for a PCI device with the given PCI configuration space address.
Arguments:
This - A pointer to the EFI_DEVICE_IO_INTERFACE instance.
Address - The PCI configuration space address of the device whose Device Path
is going to be returned.
PciDevicePath - A pointer to the pointer for the EFI Device Path for PciAddress.
Memory for the Device Path is allocated from the pool.
Returns:
EFI_SUCCESS - The PciDevicePath returns a pointer to a valid EFI Device Path.
EFI_UNSUPPORTED - The PciAddress does not map to a valid EFI Device Path.
EFI_OUT_OF_RESOURCES - The request could not be completed due to a lack of resources.
--*/
{
DEVICE_IO_PRIVATE_DATA *Private;
UINT16 PrimaryBus;
UINT16 SubordinateBus;
UINT8 Bus;
UINT8 Device;
UINT8 Func;
Private = DEVICE_IO_PRIVATE_DATA_FROM_THIS (This);
Bus = (UINT8) (((UINT32) Address >> 24) & 0xff);
Device = (UINT8) (((UINT32) Address >> 16) & 0xff);
Func = (UINT8) (((UINT32) Address >> 8) & 0xff);
if (Bus < Private->PrimaryBus || Bus > Private->SubordinateBus) {
return EFI_UNSUPPORTED;
}
*PciDevicePath = Private->DevicePath;
PrimaryBus = Private->PrimaryBus;
SubordinateBus = Private->SubordinateBus;
do {
*PciDevicePath = AppendPciDevicePath (
Private,
Bus,
Device,
Func,
*PciDevicePath,
&PrimaryBus,
&SubordinateBus
);
if (*PciDevicePath == NULL) {
return EFI_OUT_OF_RESOURCES;
}
} while (PrimaryBus != 0xffff);
return EFI_SUCCESS;
}
EFI_STATUS
EFIAPI
DeviceIoMap (
IN EFI_DEVICE_IO_PROTOCOL *This,
IN EFI_IO_OPERATION_TYPE Operation,
IN EFI_PHYSICAL_ADDRESS *HostAddress,
IN OUT UINTN *NumberOfBytes,
OUT EFI_PHYSICAL_ADDRESS *DeviceAddress,
OUT VOID **Mapping
)
/*++
Routine Description:
Provides the device-specific addresses needed to access system memory.
Arguments:
This - A pointer to the EFI_DEVICE_IO_INTERFACE instance.
Operation - Indicates if the bus master is going to read or write to system memory.
HostAddress - The system memory address to map to the device.
NumberOfBytes - On input the number of bytes to map. On output the number of bytes
that were mapped.
DeviceAddress - The resulting map address for the bus master device to use to access the
hosts HostAddress.
Mapping - A resulting value to pass to Unmap().
Returns:
EFI_SUCCESS - The range was mapped for the returned NumberOfBytes.
EFI_INVALID_PARAMETER - The Operation or HostAddress is undefined.
EFI_UNSUPPORTED - The HostAddress cannot be mapped as a common buffer.
EFI_DEVICE_ERROR - The system hardware could not map the requested address.
EFI_OUT_OF_RESOURCES - The request could not be completed due to a lack of resources.
--*/
{
EFI_STATUS Status;
DEVICE_IO_PRIVATE_DATA *Private;
Private = DEVICE_IO_PRIVATE_DATA_FROM_THIS (This);
if ((UINT32)Operation > EfiBusMasterCommonBuffer) {
return EFI_INVALID_PARAMETER;
}
if (((UINTN) (*HostAddress) != (*HostAddress)) && Operation == EfiBusMasterCommonBuffer) {
return EFI_UNSUPPORTED;
}
Status = Private->PciRootBridgeIo->Map (
Private->PciRootBridgeIo,
(EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION) Operation,
(VOID *) (UINTN) (*HostAddress),
NumberOfBytes,
DeviceAddress,
Mapping
);
return Status;
}
EFI_STATUS
EFIAPI
DeviceIoUnmap (
IN EFI_DEVICE_IO_PROTOCOL *This,
IN VOID *Mapping
)
/*++
Routine Description:
Completes the Map() operation and releases any corresponding resources.
Arguments:
This - A pointer to the EFI_DEVICE_IO_INTERFACE instance.
Mapping - The mapping value returned from Map().
Returns:
EFI_SUCCESS - The range was unmapped.
EFI_DEVICE_ERROR - The data was not committed to the target system memory.
--*/
{
EFI_STATUS Status;
DEVICE_IO_PRIVATE_DATA *Private;
Private = DEVICE_IO_PRIVATE_DATA_FROM_THIS (This);
Status = Private->PciRootBridgeIo->Unmap (
Private->PciRootBridgeIo,
Mapping
);
return Status;
}
EFI_STATUS
EFIAPI
DeviceIoAllocateBuffer (
IN EFI_DEVICE_IO_PROTOCOL *This,
IN EFI_ALLOCATE_TYPE Type,
IN EFI_MEMORY_TYPE MemoryType,
IN UINTN Pages,
IN OUT EFI_PHYSICAL_ADDRESS *PhysicalAddress
)
/*++
Routine Description:
Allocates pages that are suitable for an EFIBusMasterCommonBuffer mapping.
Arguments:
This - A pointer to the EFI_DEVICE_IO_INTERFACE instance.
Type - The type allocation to perform.
MemoryType - The type of memory to allocate, EfiBootServicesData or
EfiRuntimeServicesData.
Pages - The number of pages to allocate.
PhysicalAddress - A pointer to store the base address of the allocated range.
Returns:
EFI_SUCCESS - The requested memory pages were allocated.
EFI_OUT_OF_RESOURCES - The memory pages could not be allocated.
EFI_INVALID_PARAMETER - The requested memory type is invalid.
EFI_UNSUPPORTED - The requested PhysicalAddress is not supported on
this platform.
--*/
{
EFI_STATUS Status;
EFI_PHYSICAL_ADDRESS HostAddress;
HostAddress = *PhysicalAddress;
if ((MemoryType != EfiBootServicesData) && (MemoryType != EfiRuntimeServicesData)) {
return EFI_INVALID_PARAMETER;
}
if ((UINT32)Type >= MaxAllocateType) {
return EFI_INVALID_PARAMETER;
}
if ((Type == AllocateAddress) && (HostAddress + EFI_PAGES_TO_SIZE (Pages) - 1 > MAX_COMMON_BUFFER)) {
return EFI_UNSUPPORTED;
}
if ((AllocateAnyPages == Type) || (AllocateMaxAddress == Type && HostAddress > MAX_COMMON_BUFFER)) {
Type = AllocateMaxAddress;
HostAddress = MAX_COMMON_BUFFER;
}
Status = gBS->AllocatePages (
Type,
MemoryType,
Pages,
&HostAddress
);
if (EFI_ERROR (Status)) {
return Status;
}
*PhysicalAddress = HostAddress;
return EFI_SUCCESS;
}
EFI_STATUS
EFIAPI
DeviceIoFlush (
IN EFI_DEVICE_IO_PROTOCOL *This
)
/*++
Routine Description:
Flushes any posted write data to the device.
Arguments:
This - A pointer to the EFI_DEVICE_IO_INTERFACE instance.
Returns:
EFI_SUCCESS - The buffers were flushed.
EFI_DEVICE_ERROR - The buffers were not flushed due to a hardware error.
--*/
{
EFI_STATUS Status;
DEVICE_IO_PRIVATE_DATA *Private;
Private = DEVICE_IO_PRIVATE_DATA_FROM_THIS (This);
Status = Private->PciRootBridgeIo->Flush (Private->PciRootBridgeIo);
return Status;
}
EFI_STATUS
EFIAPI
DeviceIoFreeBuffer (
IN EFI_DEVICE_IO_PROTOCOL *This,
IN UINTN Pages,
IN EFI_PHYSICAL_ADDRESS HostAddress
)
/*++
Routine Description:
Frees pages that were allocated with AllocateBuffer().
Arguments:
This - A pointer to the EFI_DEVICE_IO_INTERFACE instance.
Pages - The number of pages to free.
HostAddress - The base address of the range to free.
Returns:
EFI_SUCCESS - The requested memory pages were freed.
EFI_NOT_FOUND - The requested memory pages were not allocated with
AllocateBuffer().
EFI_INVALID_PARAMETER - HostAddress is not page aligned or Pages is invalid.
--*/
{
if (((HostAddress & EFI_PAGE_MASK) != 0) || (Pages <= 0)) {
return EFI_INVALID_PARAMETER;
}
return gBS->FreePages (HostAddress, Pages);
}

View File

@@ -0,0 +1,449 @@
/*++
Copyright (c) 2006, 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.
Module Name:
DeviceIo.h
Abstract:
Private Data definition for Device IO driver
--*/
#ifndef _DEVICE_IO_H
#define _DEVICE_IO_H
#define DEVICE_IO_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('d', 'e', 'v', 'I')
#define MAX_COMMON_BUFFER 0x00000000FFFFFFFF
typedef struct {
UINTN Signature;
EFI_HANDLE Handle;
EFI_DEVICE_IO_PROTOCOL DeviceIo;
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
UINT16 PrimaryBus;
UINT16 SubordinateBus;
} DEVICE_IO_PRIVATE_DATA;
#define DEVICE_IO_PRIVATE_DATA_FROM_THIS(a) CR (a, DEVICE_IO_PRIVATE_DATA, DeviceIo, DEVICE_IO_PRIVATE_DATA_SIGNATURE)
EFI_STATUS
DeviceIoConstructor (
IN EFI_HANDLE Handle,
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo,
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
IN UINT16 PrimaryBus,
IN UINT16 SubordinateBus
)
/*++
Routine Description:
Initialize and install a Device IO protocol on a empty device path handle.
Arguments:
Handle - Handle of PCI RootBridge IO instance
PciRootBridgeIo - PCI RootBridge IO instance
DevicePath - Device Path of PCI RootBridge IO instance
PrimaryBus - Primary Bus
SubordinateBus - Subordinate Bus
Returns:
EFI_SUCCESS - This driver is added to ControllerHandle.
EFI_ALREADY_STARTED - This driver is already running on ControllerHandle.
Others - This driver does not support this device.
--*/
;
EFI_STATUS
EFIAPI
DeviceIoMemRead (
IN EFI_DEVICE_IO_PROTOCOL *This,
IN EFI_IO_WIDTH Width,
IN UINT64 Address,
IN UINTN Count,
IN OUT VOID *Buffer
)
/*++
Routine Description:
Perform reading memory mapped I/O space of device.
Arguments:
This - A pointer to EFI_DEVICE_IO protocol instance.
Width - Width of I/O operations.
Address - The base address of I/O operations.
Count - The number of I/O operations to perform.
Bytes moves is Width size * Count, starting at Address.
Buffer - The destination buffer to store results.
Returns:
EFI_SUCCESS - The data was read from the device.
EFI_INVALID_PARAMETER - Width is invalid.
EFI_OUT_OF_RESOURCES - The request could not be completed due to lack of resources.
--*/
;
EFI_STATUS
EFIAPI
DeviceIoMemWrite (
IN EFI_DEVICE_IO_PROTOCOL *This,
IN EFI_IO_WIDTH Width,
IN UINT64 Address,
IN UINTN Count,
IN OUT VOID *Buffer
)
/*++
Routine Description:
Perform writing memory mapped I/O space of device.
Arguments:
This - A pointer to EFI_DEVICE_IO protocol instance.
Width - Width of I/O operations.
Address - The base address of I/O operations.
Count - The number of I/O operations to perform.
Bytes moves is Width size * Count, starting at Address.
Buffer - The source buffer of data to be written.
Returns:
EFI_SUCCESS - The data was written to the device.
EFI_INVALID_PARAMETER - Width is invalid.
EFI_OUT_OF_RESOURCES - The request could not be completed due to lack of resources.
--*/
;
EFI_STATUS
EFIAPI
DeviceIoIoRead (
IN EFI_DEVICE_IO_PROTOCOL *This,
IN EFI_IO_WIDTH Width,
IN UINT64 Address,
IN UINTN Count,
IN OUT VOID *Buffer
)
/*++
Routine Description:
Perform reading I/O space of device.
Arguments:
This - A pointer to EFI_DEVICE_IO protocol instance.
Width - Width of I/O operations.
Address - The base address of I/O operations.
Count - The number of I/O operations to perform.
Bytes moves is Width size * Count, starting at Address.
Buffer - The destination buffer to store results.
Returns:
EFI_SUCCESS - The data was read from the device.
EFI_INVALID_PARAMETER - Width is invalid.
EFI_OUT_OF_RESOURCES - The request could not be completed due to lack of resources.
--*/
;
EFI_STATUS
EFIAPI
DeviceIoIoWrite (
IN EFI_DEVICE_IO_PROTOCOL *This,
IN EFI_IO_WIDTH Width,
IN UINT64 Address,
IN UINTN Count,
IN OUT VOID *Buffer
)
/*++
Routine Description:
Perform writing I/O space of device.
Arguments:
This - A pointer to EFI_DEVICE_IO protocol instance.
Width - Width of I/O operations.
Address - The base address of I/O operations.
Count - The number of I/O operations to perform.
Bytes moves is Width size * Count, starting at Address.
Buffer - The source buffer of data to be written.
Returns:
EFI_SUCCESS - The data was written to the device.
EFI_INVALID_PARAMETER - Width is invalid.
EFI_OUT_OF_RESOURCES - The request could not be completed due to lack of resources.
--*/
;
EFI_STATUS
EFIAPI
DeviceIoPciRead (
IN EFI_DEVICE_IO_PROTOCOL *This,
IN EFI_IO_WIDTH Width,
IN UINT64 Address,
IN UINTN Count,
IN OUT VOID *Buffer
)
/*++
Routine Description:
Perform reading PCI configuration space of device
Arguments:
This - A pointer to EFI_DEVICE_IO protocol instance.
Width - Width of I/O operations.
Address - The base address of I/O operations.
Count - The number of I/O operations to perform.
Bytes moves is Width size * Count, starting at Address.
Buffer - The destination buffer to store results.
Returns:
EFI_SUCCESS - The data was read from the device.
EFI_INVALID_PARAMETER - Width is invalid.
EFI_OUT_OF_RESOURCES - The request could not be completed due to lack of resources.
--*/
;
EFI_STATUS
EFIAPI
DeviceIoPciWrite (
IN EFI_DEVICE_IO_PROTOCOL *This,
IN EFI_IO_WIDTH Width,
IN UINT64 Address,
IN UINTN Count,
IN OUT VOID *Buffer
)
/*++
Routine Description:
Perform writing PCI configuration space of device.
Arguments:
This - A pointer to EFI_DEVICE_IO protocol instance.
Width - Width of I/O operations.
Address - The base address of I/O operations.
Count - The number of I/O operations to perform.
Bytes moves is Width size * Count, starting at Address.
Buffer - The source buffer of data to be written.
Returns:
EFI_SUCCESS - The data was written to the device.
EFI_INVALID_PARAMETER - Width is invalid.
EFI_OUT_OF_RESOURCES - The request could not be completed due to lack of resources.
--*/
;
EFI_STATUS
EFIAPI
DeviceIoPciDevicePath (
IN EFI_DEVICE_IO_PROTOCOL *This,
IN UINT64 Address,
IN OUT EFI_DEVICE_PATH_PROTOCOL **PciDevicePath
)
/*++
Routine Description:
Append a PCI device path node to another device path.
Arguments:
This - A pointer to EFI_DEVICE_IO_PROTOCOL.
Address - PCI bus,device, function.
PciDevicePath - PCI device path.
Returns:
Pointer to the appended PCI device path.
--*/
;
EFI_STATUS
EFIAPI
DeviceIoMap (
IN EFI_DEVICE_IO_PROTOCOL *This,
IN EFI_IO_OPERATION_TYPE Operation,
IN EFI_PHYSICAL_ADDRESS *HostAddress,
IN OUT UINTN *NumberOfBytes,
OUT EFI_PHYSICAL_ADDRESS *DeviceAddress,
OUT VOID **Mapping
)
/*++
Routine Description:
Provides the device-specific addresses needed to access system memory.
Arguments:
This - A pointer to the EFI_DEVICE_IO_INTERFACE instance.
Operation - Indicates if the bus master is going to read or write to system memory.
HostAddress - The system memory address to map to the device.
NumberOfBytes - On input the number of bytes to map. On output the number of bytes
that were mapped.
DeviceAddress - The resulting map address for the bus master device to use to access the
hosts HostAddress.
Mapping - A resulting value to pass to Unmap().
Returns:
EFI_SUCCESS - The range was mapped for the returned NumberOfBytes.
EFI_INVALID_PARAMETER - The Operation or HostAddress is undefined.
EFI_UNSUPPORTED - The HostAddress cannot be mapped as a common buffer.
EFI_DEVICE_ERROR - The system hardware could not map the requested address.
EFI_OUT_OF_RESOURCES - The request could not be completed due to a lack of resources.
--*/
;
EFI_STATUS
EFIAPI
DeviceIoUnmap (
IN EFI_DEVICE_IO_PROTOCOL *This,
IN VOID *Mapping
)
/*++
Routine Description:
Completes the Map() operation and releases any corresponding resources.
Arguments:
This - A pointer to the EFI_DEVICE_IO_INTERFACE instance.
Mapping - The mapping value returned from Map().
Returns:
EFI_SUCCESS - The range was unmapped.
EFI_DEVICE_ERROR - The data was not committed to the target system memory.
--*/
;
EFI_STATUS
EFIAPI
DeviceIoAllocateBuffer (
IN EFI_DEVICE_IO_PROTOCOL *This,
IN EFI_ALLOCATE_TYPE Type,
IN EFI_MEMORY_TYPE MemoryType,
IN UINTN Pages,
IN OUT EFI_PHYSICAL_ADDRESS *HostAddress
)
/*++
Routine Description:
Allocates pages that are suitable for an EFIBusMasterCommonBuffer mapping.
Arguments:
This - A pointer to the EFI_DEVICE_IO_INTERFACE instance.
Type - The type allocation to perform.
MemoryType - The type of memory to allocate, EfiBootServicesData or
EfiRuntimeServicesData.
Pages - The number of pages to allocate.
HostAddress - A pointer to store the base address of the allocated range.
Returns:
EFI_SUCCESS - The requested memory pages were allocated.
EFI_OUT_OF_RESOURCES - The memory pages could not be allocated.
EFI_INVALID_PARAMETER - The requested memory type is invalid.
EFI_UNSUPPORTED - The requested PhysicalAddress is not supported on
this platform.
--*/
;
EFI_STATUS
EFIAPI
DeviceIoFlush (
IN EFI_DEVICE_IO_PROTOCOL *This
)
/*++
Routine Description:
Flushes any posted write data to the device.
Arguments:
This - A pointer to the EFI_DEVICE_IO_INTERFACE instance.
Returns:
EFI_SUCCESS - The buffers were flushed.
EFI_DEVICE_ERROR - The buffers were not flushed due to a hardware error.
--*/
;
EFI_STATUS
EFIAPI
DeviceIoFreeBuffer (
IN EFI_DEVICE_IO_PROTOCOL *This,
IN UINTN Pages,
IN EFI_PHYSICAL_ADDRESS HostAddress
)
/*++
Routine Description:
Frees pages that were allocated with AllocateBuffer().
Arguments:
This - A pointer to the EFI_DEVICE_IO_INTERFACE instance.
Pages - The number of pages to free.
HostAddress - The base address of the range to free.
Returns:
EFI_SUCCESS - The requested memory pages were freed.
EFI_NOT_FOUND - The requested memory pages were not allocated with
AllocateBuffer().
EFI_INVALID_PARAMETER - HostAddress is not page aligned or Pages is invalid.
--*/
;
#endif

View File

@@ -0,0 +1,738 @@
/*++
Copyright (c) 2005 - 2012, 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.
Module Name:
PcatPciRootBridgeIo.c
Abstract:
EFI PC AT PCI Root Bridge Io Protocol
Revision History
--*/
#include "PcatPciRootBridge.h"
BOOLEAN mPciOptionRomTableInstalled = FALSE;
EFI_PCI_OPTION_ROM_TABLE mPciOptionRomTable = {0, NULL};
EFI_STATUS
EFIAPI
PcatRootBridgeIoIoRead (
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
IN UINT64 UserAddress,
IN UINTN Count,
IN OUT VOID *UserBuffer
)
{
return gCpuIo->Io.Read (
gCpuIo,
(EFI_CPU_IO_PROTOCOL_WIDTH) Width,
UserAddress,
Count,
UserBuffer
);
}
EFI_STATUS
EFIAPI
PcatRootBridgeIoIoWrite (
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
IN UINT64 UserAddress,
IN UINTN Count,
IN OUT VOID *UserBuffer
)
{
return gCpuIo->Io.Write (
gCpuIo,
(EFI_CPU_IO_PROTOCOL_WIDTH) Width,
UserAddress,
Count,
UserBuffer
);
}
EFI_STATUS
PcatRootBridgeIoGetIoPortMapping (
OUT EFI_PHYSICAL_ADDRESS *IoPortMapping,
OUT EFI_PHYSICAL_ADDRESS *MemoryPortMapping
)
/*++
Get the IO Port Mapping. For IA-32 it is always 0.
--*/
{
*IoPortMapping = 0;
*MemoryPortMapping = 0;
return EFI_SUCCESS;
}
EFI_STATUS
PcatRootBridgeIoPciRW (
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
IN BOOLEAN Write,
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
IN UINT64 UserAddress,
IN UINTN Count,
IN OUT VOID *UserBuffer
)
{
PCI_CONFIG_ACCESS_CF8 Pci;
PCI_CONFIG_ACCESS_CF8 PciAligned;
UINT32 InStride;
UINT32 OutStride;
UINTN PciData;
UINTN PciDataStride;
PCAT_PCI_ROOT_BRIDGE_INSTANCE *PrivateData;
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS PciAddress;
UINT64 PciExpressRegAddr;
BOOLEAN UsePciExpressAccess;
if ((UINT32)Width >= EfiPciWidthMaximum) {
return EFI_INVALID_PARAMETER;
}
if ((Width & 0x03) >= EfiPciWidthUint64) {
return EFI_INVALID_PARAMETER;
}
PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS(This);
InStride = 1 << (Width & 0x03);
OutStride = InStride;
if (Width >= EfiPciWidthFifoUint8 && Width <= EfiPciWidthFifoUint64) {
InStride = 0;
}
if (Width >= EfiPciWidthFillUint8 && Width <= EfiPciWidthFillUint64) {
OutStride = 0;
}
UsePciExpressAccess = FALSE;
CopyMem (&PciAddress, &UserAddress, sizeof(UINT64));
if (PciAddress.ExtendedRegister > 0xFF) {
//
// Check PciExpressBaseAddress
//
if ((PrivateData->PciExpressBaseAddress == 0) ||
(PrivateData->PciExpressBaseAddress >= MAX_ADDRESS)) {
return EFI_UNSUPPORTED;
} else {
UsePciExpressAccess = TRUE;
}
} else {
if (PciAddress.ExtendedRegister != 0) {
Pci.Bits.Reg = PciAddress.ExtendedRegister & 0xFF;
} else {
Pci.Bits.Reg = PciAddress.Register;
}
//
// Note: We can also use PciExpress access here, if wanted.
//
}
if (!UsePciExpressAccess) {
Pci.Bits.Func = PciAddress.Function;
Pci.Bits.Dev = PciAddress.Device;
Pci.Bits.Bus = PciAddress.Bus;
Pci.Bits.Reserved = 0;
Pci.Bits.Enable = 1;
//
// PCI Config access are all 32-bit alligned, but by accessing the
// CONFIG_DATA_REGISTER (0xcfc) with different widths more cycle types
// are possible on PCI.
//
// To read a byte of PCI config space you load 0xcf8 and
// read 0xcfc, 0xcfd, 0xcfe, 0xcff
//
PciDataStride = Pci.Bits.Reg & 0x03;
while (Count) {
PciAligned = Pci;
PciAligned.Bits.Reg &= 0xfc;
PciData = (UINTN)PrivateData->PciData + PciDataStride;
EfiAcquireLock(&PrivateData->PciLock);
This->Io.Write (This, EfiPciWidthUint32, PrivateData->PciAddress, 1, &PciAligned);
if (Write) {
This->Io.Write (This, Width, PciData, 1, UserBuffer);
} else {
This->Io.Read (This, Width, PciData, 1, UserBuffer);
}
EfiReleaseLock(&PrivateData->PciLock);
UserBuffer = ((UINT8 *)UserBuffer) + OutStride;
PciDataStride = (PciDataStride + InStride) % 4;
Pci.Bits.Reg += InStride;
Count -= 1;
}
} else {
//
// Access PCI-Express space by using memory mapped method.
//
PciExpressRegAddr = (PrivateData->PciExpressBaseAddress) |
(PciAddress.Bus << 20) |
(PciAddress.Device << 15) |
(PciAddress.Function << 12);
if (PciAddress.ExtendedRegister != 0) {
PciExpressRegAddr += PciAddress.ExtendedRegister;
} else {
PciExpressRegAddr += PciAddress.Register;
}
while (Count) {
if (Write) {
This->Mem.Write (This, Width, (UINTN) PciExpressRegAddr, 1, UserBuffer);
} else {
This->Mem.Read (This, Width, (UINTN) PciExpressRegAddr, 1, UserBuffer);
}
UserBuffer = ((UINT8 *) UserBuffer) + OutStride;
PciExpressRegAddr += InStride;
Count -= 1;
}
}
return EFI_SUCCESS;
}
VOID
ScanPciBus(
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev,
UINT16 MinBus,
UINT16 MaxBus,
UINT16 MinDevice,
UINT16 MaxDevice,
UINT16 MinFunc,
UINT16 MaxFunc,
EFI_PCI_BUS_SCAN_CALLBACK Callback,
VOID *Context
)
{
UINT16 Bus;
UINT16 Device;
UINT16 Func;
UINT64 Address;
PCI_TYPE00 PciHeader;
//
// Loop through all busses
//
for (Bus = MinBus; Bus <= MaxBus; Bus++) {
//
// Loop 32 devices per bus
//
for (Device = MinDevice; Device <= MaxDevice; Device++) {
//
// Loop through 8 functions per device
//
for (Func = MinFunc; Func <= MaxFunc; Func++) {
//
// Compute the EFI Address required to access the PCI Configuration Header of this PCI Device
//
Address = EFI_PCI_ADDRESS (Bus, Device, Func, 0);
//
// Read the VendorID from this PCI Device's Confioguration Header
//
IoDev->Pci.Read (IoDev, EfiPciWidthUint16, Address, 1, &PciHeader.Hdr.VendorId);
//
// If VendorId = 0xffff, there does not exist a device at this
// location. For each device, if there is any function on it,
// there must be 1 function at Function 0. So if Func = 0, there
// will be no more functions in the same device, so we can break
// loop to deal with the next device.
//
if (PciHeader.Hdr.VendorId == 0xffff && Func == 0) {
break;
}
if (PciHeader.Hdr.VendorId != 0xffff) {
//
// Read the HeaderType to determine if this is a multi-function device
//
IoDev->Pci.Read (IoDev, EfiPciWidthUint8, Address + 0x0e, 1, &PciHeader.Hdr.HeaderType);
//
// Call the callback function for the device that was found
//
Callback(
IoDev,
MinBus, MaxBus,
MinDevice, MaxDevice,
MinFunc, MaxFunc,
Bus,
Device,
Func,
Context
);
//
// If this is not a multi-function device, we can leave the loop
// to deal with the next device.
//
if ((PciHeader.Hdr.HeaderType & HEADER_TYPE_MULTI_FUNCTION) == 0x00 && Func == 0) {
break;
}
}
}
}
}
}
VOID
CheckForRom (
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev,
UINT16 MinBus,
UINT16 MaxBus,
UINT16 MinDevice,
UINT16 MaxDevice,
UINT16 MinFunc,
UINT16 MaxFunc,
UINT16 Bus,
UINT16 Device,
UINT16 Func,
IN VOID *VoidContext
)
{
EFI_STATUS Status;
PCAT_PCI_ROOT_BRIDGE_SCAN_FOR_ROM_CONTEXT *Context;
UINT64 Address;
PCI_TYPE00 PciHeader;
PCI_TYPE01 *PciBridgeHeader;
UINT32 Register;
UINT32 RomBar;
UINT32 RomBarSize;
EFI_PHYSICAL_ADDRESS RomBuffer;
UINT32 MaxRomSize;
EFI_PCI_EXPANSION_ROM_HEADER EfiRomHeader;
PCI_DATA_STRUCTURE Pcir;
EFI_PCI_OPTION_ROM_DESCRIPTOR *TempPciOptionRomDescriptors;
BOOLEAN LastImage;
Context = (PCAT_PCI_ROOT_BRIDGE_SCAN_FOR_ROM_CONTEXT *)VoidContext;
Address = EFI_PCI_ADDRESS (Bus, Device, Func, 0);
//
// Save the contents of the PCI Configuration Header
//
IoDev->Pci.Read (IoDev, EfiPciWidthUint32, Address, sizeof(PciHeader)/sizeof(UINT32), &PciHeader);
if (IS_PCI_BRIDGE(&PciHeader)) {
PciBridgeHeader = (PCI_TYPE01 *)(&PciHeader);
//
// See if the PCI-PCI Bridge has its secondary interface enabled.
//
if (PciBridgeHeader->Bridge.SubordinateBus >= PciBridgeHeader->Bridge.SecondaryBus) {
//
// Disable the Prefetchable Memory Window
//
Register = 0x00000000;
IoDev->Pci.Write (IoDev, EfiPciWidthUint16, Address + 0x26, 1, &Register);
IoDev->Pci.Write (IoDev, EfiPciWidthUint32, Address + 0x2c, 1, &Register);
Register = 0xffffffff;
IoDev->Pci.Write (IoDev, EfiPciWidthUint16, Address + 0x24, 1, &Register);
IoDev->Pci.Write (IoDev, EfiPciWidthUint16, Address + 0x28, 1, &Register);
//
// Program Memory Window to the PCI Root Bridge Memory Window
//
IoDev->Pci.Write (IoDev, EfiPciWidthUint16, Address + 0x20, 4, &Context->PpbMemoryWindow);
//
// Enable the Memory decode for the PCI-PCI Bridge
//
IoDev->Pci.Read (IoDev, EfiPciWidthUint16, Address + 4, 1, &Register);
Register |= 0x02;
IoDev->Pci.Write (IoDev, EfiPciWidthUint16, Address + 4, 1, &Register);
//
// Recurse on the Secondary Bus Number
//
ScanPciBus(
IoDev,
PciBridgeHeader->Bridge.SecondaryBus, PciBridgeHeader->Bridge.SecondaryBus,
0, PCI_MAX_DEVICE,
0, PCI_MAX_FUNC,
CheckForRom, Context
);
}
} else {
//
// Check if an Option ROM Register is present and save the Option ROM Window Register
//
RomBar = 0xffffffff;
IoDev->Pci.Write (IoDev, EfiPciWidthUint32, Address + 0x30, 1, &RomBar);
IoDev->Pci.Read (IoDev, EfiPciWidthUint32, Address + 0x30, 1, &RomBar);
RomBarSize = (~(RomBar & 0xfffff800)) + 1;
//
// Make sure the size of the ROM is between 0 and 16 MB
//
if (RomBarSize > 0 && RomBarSize <= 0x01000000) {
//
// Program Option ROM Window Register to the PCI Root Bridge Window and Enable the Option ROM Window
//
RomBar = (Context->PpbMemoryWindow & 0xffff) << 16;
RomBar = ((RomBar - 1) & (~(RomBarSize - 1))) + RomBarSize;
if (RomBar < (Context->PpbMemoryWindow & 0xffff0000)) {
MaxRomSize = (Context->PpbMemoryWindow & 0xffff0000) - RomBar;
RomBar = RomBar + 1;
IoDev->Pci.Write (IoDev, EfiPciWidthUint32, Address + 0x30, 1, &RomBar);
IoDev->Pci.Read (IoDev, EfiPciWidthUint32, Address + 0x30, 1, &RomBar);
RomBar = RomBar - 1;
//
// Enable the Memory decode for the PCI Device
//
IoDev->Pci.Read (IoDev, EfiPciWidthUint16, Address + 4, 1, &Register);
Register |= 0x02;
IoDev->Pci.Write (IoDev, EfiPciWidthUint16, Address + 4, 1, &Register);
//
// Follow the chain of images to determine the size of the Option ROM present
// Keep going until the last image is found by looking at the Indicator field
// or the size of an image is 0, or the size of all the images is bigger than the
// size of the window programmed into the PPB.
//
RomBarSize = 0;
do {
LastImage = TRUE;
ZeroMem (&EfiRomHeader, sizeof(EfiRomHeader));
IoDev->Mem.Read (
IoDev,
EfiPciWidthUint8,
RomBar + RomBarSize,
sizeof(EfiRomHeader),
&EfiRomHeader
);
Pcir.ImageLength = 0;
if (EfiRomHeader.Signature == PCI_EXPANSION_ROM_HEADER_SIGNATURE &&
EfiRomHeader.PcirOffset != 0 &&
(EfiRomHeader.PcirOffset & 3) == 0 &&
RomBarSize + EfiRomHeader.PcirOffset + sizeof (PCI_DATA_STRUCTURE) <= MaxRomSize) {
ZeroMem (&Pcir, sizeof(Pcir));
IoDev->Mem.Read (
IoDev,
EfiPciWidthUint8,
RomBar + RomBarSize + EfiRomHeader.PcirOffset,
sizeof(Pcir),
&Pcir
);
if (Pcir.Signature != PCI_DATA_STRUCTURE_SIGNATURE) {
break;
}
if (RomBarSize + Pcir.ImageLength * 512 > MaxRomSize) {
break;
}
if ((Pcir.Indicator & 0x80) == 0x00) {
LastImage = FALSE;
}
RomBarSize += Pcir.ImageLength * 512;
}
} while (!LastImage && RomBarSize < MaxRomSize && Pcir.ImageLength !=0);
if (RomBarSize > 0) {
//
// Allocate a memory buffer for the Option ROM contents.
//
Status = gBS->AllocatePages(
AllocateAnyPages,
EfiBootServicesData,
EFI_SIZE_TO_PAGES(RomBarSize),
&RomBuffer
);
if (!EFI_ERROR (Status)) {
//
// Copy the contents of the Option ROM to the memory buffer
//
IoDev->Mem.Read (IoDev, EfiPciWidthUint32, RomBar, RomBarSize / sizeof(UINT32), (VOID *)(UINTN)RomBuffer);
Status = gBS->AllocatePool(
EfiBootServicesData,
((UINT32)mPciOptionRomTable.PciOptionRomCount + 1) * sizeof(EFI_PCI_OPTION_ROM_DESCRIPTOR),
(VOID*)&TempPciOptionRomDescriptors
);
if (mPciOptionRomTable.PciOptionRomCount > 0) {
CopyMem(
TempPciOptionRomDescriptors,
mPciOptionRomTable.PciOptionRomDescriptors,
(UINT32)mPciOptionRomTable.PciOptionRomCount * sizeof(EFI_PCI_OPTION_ROM_DESCRIPTOR)
);
gBS->FreePool(mPciOptionRomTable.PciOptionRomDescriptors);
}
mPciOptionRomTable.PciOptionRomDescriptors = TempPciOptionRomDescriptors;
TempPciOptionRomDescriptors = &(mPciOptionRomTable.PciOptionRomDescriptors[(UINT32)mPciOptionRomTable.PciOptionRomCount]);
TempPciOptionRomDescriptors->RomAddress = RomBuffer;
TempPciOptionRomDescriptors->MemoryType = EfiBootServicesData;
TempPciOptionRomDescriptors->RomLength = RomBarSize;
TempPciOptionRomDescriptors->Seg = (UINT32)IoDev->SegmentNumber;
TempPciOptionRomDescriptors->Bus = (UINT8)Bus;
TempPciOptionRomDescriptors->Dev = (UINT8)Device;
TempPciOptionRomDescriptors->Func = (UINT8)Func;
TempPciOptionRomDescriptors->ExecutedLegacyBiosImage = TRUE;
TempPciOptionRomDescriptors->DontLoadEfiRom = FALSE;
mPciOptionRomTable.PciOptionRomCount++;
}
}
//
// Disable the Memory decode for the PCI-PCI Bridge
//
IoDev->Pci.Read (IoDev, EfiPciWidthUint16, Address + 4, 1, &Register);
Register &= (~0x02);
IoDev->Pci.Write (IoDev, EfiPciWidthUint16, Address + 4, 1, &Register);
}
}
}
//
// Restore the PCI Configuration Header
//
IoDev->Pci.Write (IoDev, EfiPciWidthUint32, Address, sizeof(PciHeader)/sizeof(UINT32), &PciHeader);
}
VOID
SaveCommandRegister (
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev,
UINT16 MinBus,
UINT16 MaxBus,
UINT16 MinDevice,
UINT16 MaxDevice,
UINT16 MinFunc,
UINT16 MaxFunc,
UINT16 Bus,
UINT16 Device,
UINT16 Func,
IN VOID *VoidContext
)
{
PCAT_PCI_ROOT_BRIDGE_SCAN_FOR_ROM_CONTEXT *Context;
UINT64 Address;
UINTN Index;
UINT16 Command;
Context = (PCAT_PCI_ROOT_BRIDGE_SCAN_FOR_ROM_CONTEXT *)VoidContext;
Address = EFI_PCI_ADDRESS (Bus, Device, Func, 4);
Index = (Bus - MinBus) * (PCI_MAX_DEVICE+1) * (PCI_MAX_FUNC+1) + Device * (PCI_MAX_FUNC+1) + Func;
IoDev->Pci.Read (IoDev, EfiPciWidthUint16, Address, 1, &Context->CommandRegisterBuffer[Index]);
//
// Clear the memory enable bit
//
Command = (UINT16) (Context->CommandRegisterBuffer[Index] & (~0x02));
IoDev->Pci.Write (IoDev, EfiPciWidthUint16, Address, 1, &Command);
}
VOID
RestoreCommandRegister (
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev,
UINT16 MinBus,
UINT16 MaxBus,
UINT16 MinDevice,
UINT16 MaxDevice,
UINT16 MinFunc,
UINT16 MaxFunc,
UINT16 Bus,
UINT16 Device,
UINT16 Func,
IN VOID *VoidContext
)
{
PCAT_PCI_ROOT_BRIDGE_SCAN_FOR_ROM_CONTEXT *Context;
UINT64 Address;
UINTN Index;
Context = (PCAT_PCI_ROOT_BRIDGE_SCAN_FOR_ROM_CONTEXT *)VoidContext;
Address = EFI_PCI_ADDRESS (Bus, Device, Func, 4);
Index = (Bus - MinBus) * (PCI_MAX_DEVICE+1) * (PCI_MAX_FUNC+1) + Device * (PCI_MAX_FUNC+1) + Func;
IoDev->Pci.Write (IoDev, EfiPciWidthUint16, Address, 1, &Context->CommandRegisterBuffer[Index]);
}
EFI_STATUS
ScanPciRootBridgeForRoms(
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev
)
{
EFI_STATUS Status;
EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptors;
UINT16 MinBus;
UINT16 MaxBus;
UINT64 RootWindowBase;
UINT64 RootWindowLimit;
PCAT_PCI_ROOT_BRIDGE_SCAN_FOR_ROM_CONTEXT Context;
if (mPciOptionRomTableInstalled == FALSE) {
gBS->InstallConfigurationTable(&gEfiPciOptionRomTableGuid, &mPciOptionRomTable);
mPciOptionRomTableInstalled = TRUE;
}
Status = IoDev->Configuration(IoDev, (VOID **)&Descriptors);
if (EFI_ERROR (Status) || Descriptors == NULL) {
return EFI_NOT_FOUND;
}
MinBus = 0xffff;
MaxBus = 0xffff;
RootWindowBase = 0;
RootWindowLimit = 0;
while (Descriptors->Desc != ACPI_END_TAG_DESCRIPTOR) {
//
// Find bus range
//
if (Descriptors->ResType == ACPI_ADDRESS_SPACE_TYPE_BUS) {
MinBus = (UINT16)Descriptors->AddrRangeMin;
MaxBus = (UINT16)Descriptors->AddrRangeMax;
}
//
// Find memory descriptors that are not prefetchable
//
if (Descriptors->ResType == ACPI_ADDRESS_SPACE_TYPE_MEM && Descriptors->SpecificFlag == 0) {
//
// Find Memory Descriptors that are less than 4GB, so the PPB Memory Window can be used for downstream devices
//
if (Descriptors->AddrRangeMax < 0x100000000ULL) {
//
// Find the largest Non-Prefetchable Memory Descriptor that is less than 4GB
//
if ((Descriptors->AddrRangeMax - Descriptors->AddrRangeMin) > (RootWindowLimit - RootWindowBase)) {
RootWindowBase = Descriptors->AddrRangeMin;
RootWindowLimit = Descriptors->AddrRangeMax;
}
}
}
Descriptors ++;
}
//
// Make sure a bus range was found
//
if (MinBus == 0xffff || MaxBus == 0xffff) {
return EFI_NOT_FOUND;
}
//
// Make sure a non-prefetchable memory region was found
//
if (RootWindowBase == 0 && RootWindowLimit == 0) {
return EFI_NOT_FOUND;
}
//
// Round the Base and Limit values to 1 MB boudaries
//
RootWindowBase = ((RootWindowBase - 1) & 0xfff00000) + 0x00100000;
RootWindowLimit = ((RootWindowLimit + 1) & 0xfff00000) - 1;
//
// Make sure that the size of the rounded window is greater than zero
//
if (RootWindowLimit <= RootWindowBase) {
return EFI_NOT_FOUND;
}
//
// Allocate buffer to save the Command register from all the PCI devices
//
Context.CommandRegisterBuffer = NULL;
Status = gBS->AllocatePool(
EfiBootServicesData,
sizeof(UINT16) * (MaxBus - MinBus + 1) * (PCI_MAX_DEVICE+1) * (PCI_MAX_FUNC+1),
(VOID **)&Context.CommandRegisterBuffer
);
if (EFI_ERROR (Status)) {
return Status;
}
Context.PpbMemoryWindow = (((UINT32)RootWindowBase) >> 16) | ((UINT32)RootWindowLimit & 0xffff0000);
//
// Save the Command register from all the PCI devices, and disable the I/O, Mem, and BusMaster bits
//
ScanPciBus(
IoDev,
MinBus, MaxBus,
0, PCI_MAX_DEVICE,
0, PCI_MAX_FUNC,
SaveCommandRegister, &Context
);
//
// Recursively scan all the busses for PCI Option ROMs
//
ScanPciBus(
IoDev,
MinBus, MinBus,
0, PCI_MAX_DEVICE,
0, PCI_MAX_FUNC,
CheckForRom, &Context
);
//
// Restore the Command register in all the PCI devices
//
ScanPciBus(
IoDev,
MinBus, MaxBus,
0, PCI_MAX_DEVICE,
0, PCI_MAX_FUNC,
RestoreCommandRegister, &Context
);
//
// Free the buffer used to save all the Command register values
//
gBS->FreePool(Context.CommandRegisterBuffer);
return EFI_SUCCESS;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,244 @@
/*++
Copyright (c) 2005 - 2006, 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.
Module Name:
PcatPciRootBridge.h
Abstract:
The driver for the host to pci bridge (root bridge).
--*/
#ifndef _PCAT_PCI_ROOT_BRIDGE_H_
#define _PCAT_PCI_ROOT_BRIDGE_H_
#include <PiDxe.h>
#include <Protocol/PciRootBridgeIo.h>
#include <Protocol/DeviceIo.h>
#include <Protocol/CpuIo2.h>
#include <Library/UefiLib.h>
#include <Library/BaseLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/DebugLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DevicePathLib.h>
#include <Library/HobLib.h>
#include <Guid/PciOptionRomTable.h>
#include <Guid/HobList.h>
#include <Guid/PciExpressBaseAddress.h>
#include <IndustryStandard/Acpi.h>
#include <IndustryStandard/Pci.h>
#define PCI_MAX_SEGMENT 0
//
// Driver Instance Data Prototypes
//
#define PCAT_PCI_ROOT_BRIDGE_SIGNATURE SIGNATURE_32('p', 'c', 'r', 'b')
typedef struct {
UINT32 Signature;
EFI_HANDLE Handle;
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL Io;
EFI_CPU_IO2_PROTOCOL *CpuIo;
UINT32 RootBridgeNumber;
UINT32 PrimaryBus;
UINT32 SubordinateBus;
UINT64 MemBase; // Offsets host to bus memory addr.
UINT64 MemLimit; // Max allowable memory access
UINT64 IoBase; // Offsets host to bus io addr.
UINT64 IoLimit; // Max allowable io access
UINT64 PciAddress;
UINT64 PciData;
UINT64 PhysicalMemoryBase;
UINT64 PhysicalIoBase;
EFI_LOCK PciLock;
UINT64 Attributes;
UINT64 Mem32Base;
UINT64 Mem32Limit;
UINT64 Pmem32Base;
UINT64 Pmem32Limit;
UINT64 Mem64Base;
UINT64 Mem64Limit;
UINT64 Pmem64Base;
UINT64 Pmem64Limit;
UINT64 PciExpressBaseAddress;
EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Configuration;
LIST_ENTRY MapInfo;
} PCAT_PCI_ROOT_BRIDGE_INSTANCE;
//
// Driver Instance Data Macros
//
#define DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS(a) \
CR(a, PCAT_PCI_ROOT_BRIDGE_INSTANCE, Io, PCAT_PCI_ROOT_BRIDGE_SIGNATURE)
//
// Private data types
//
typedef union {
UINT8 volatile *buf;
UINT8 volatile *ui8;
UINT16 volatile *ui16;
UINT32 volatile *ui32;
UINT64 volatile *ui64;
UINTN volatile ui;
} PTR;
typedef struct {
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION Operation;
UINTN NumberOfBytes;
UINTN NumberOfPages;
EFI_PHYSICAL_ADDRESS HostAddress;
EFI_PHYSICAL_ADDRESS MappedHostAddress;
} MAP_INFO;
typedef struct {
LIST_ENTRY Link;
MAP_INFO * Map;
} MAP_INFO_INSTANCE;
typedef
VOID
(*EFI_PCI_BUS_SCAN_CALLBACK) (
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev,
UINT16 MinBus,
UINT16 MaxBus,
UINT16 MinDevice,
UINT16 MaxDevice,
UINT16 MinFunc,
UINT16 MaxFunc,
UINT16 Bus,
UINT16 Device,
UINT16 Func,
IN VOID *Context
);
typedef struct {
UINT16 *CommandRegisterBuffer;
UINT32 PpbMemoryWindow;
} PCAT_PCI_ROOT_BRIDGE_SCAN_FOR_ROM_CONTEXT;
typedef struct {
UINT8 Register;
UINT8 Function;
UINT8 Device;
UINT8 Bus;
UINT8 Reserved[4];
} DEFIO_PCI_ADDR;
//
// Driver Protocol Constructor Prototypes
//
EFI_STATUS
ConstructConfiguration(
IN OUT PCAT_PCI_ROOT_BRIDGE_INSTANCE *PrivateData
);
EFI_STATUS
PcatPciRootBridgeParseBars (
IN PCAT_PCI_ROOT_BRIDGE_INSTANCE *PrivateData,
IN UINT16 Command,
IN UINTN Bus,
IN UINTN Device,
IN UINTN Function
);
EFI_STATUS
ScanPciRootBridgeForRoms(
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev
);
EFI_STATUS
PcatRootBridgeDevicePathConstructor (
IN EFI_DEVICE_PATH_PROTOCOL **Protocol,
IN UINTN RootBridgeNumber,
IN BOOLEAN IsPciExpress
);
EFI_STATUS
PcatRootBridgeIoConstructor (
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *Protocol,
IN UINTN SegmentNumber
);
EFI_STATUS
PcatRootBridgeIoGetIoPortMapping (
OUT EFI_PHYSICAL_ADDRESS *IoPortMapping,
OUT EFI_PHYSICAL_ADDRESS *MemoryPortMapping
);
EFI_STATUS
PcatRootBridgeIoPciRW (
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
IN BOOLEAN Write,
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
IN UINT64 UserAddress,
IN UINTN Count,
IN OUT VOID *UserBuffer
);
UINT64
GetPciExpressBaseAddressForRootBridge (
IN UINTN HostBridgeNumber,
IN UINTN RootBridgeNumber
);
EFI_STATUS
EFIAPI
PcatRootBridgeIoIoRead (
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
IN UINT64 UserAddress,
IN UINTN Count,
IN OUT VOID *UserBuffer
);
EFI_STATUS
EFIAPI
PcatRootBridgeIoIoWrite (
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
IN UINT64 UserAddress,
IN UINTN Count,
IN OUT VOID *UserBuffer
);
//
// Driver entry point prototype
//
EFI_STATUS
EFIAPI
InitializePcatPciRootBridge (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
);
extern EFI_CPU_IO2_PROTOCOL *gCpuIo;
#endif

View File

@@ -0,0 +1,93 @@
/*++
Copyright (c) 2005 - 2006, 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.
Module Name:
PcatPciRootBridgeDevicePath.c
Abstract:
EFI PCAT PCI Root Bridge Device Path Protocol
Revision History
--*/
#include "PcatPciRootBridge.h"
//
// Static device path declarations for this driver.
//
typedef struct {
ACPI_HID_DEVICE_PATH AcpiDevicePath;
EFI_DEVICE_PATH_PROTOCOL EndDevicePath;
} EFI_PCI_ROOT_BRIDGE_DEVICE_PATH;
EFI_PCI_ROOT_BRIDGE_DEVICE_PATH mEfiPciRootBridgeDevicePath = {
{
{
ACPI_DEVICE_PATH,
ACPI_DP,
{
(UINT8) (sizeof(ACPI_HID_DEVICE_PATH)),
(UINT8) ((sizeof(ACPI_HID_DEVICE_PATH)) >> 8),
}
},
EISA_PNP_ID(0x0A03),
0
},
{
END_DEVICE_PATH_TYPE,
END_ENTIRE_DEVICE_PATH_SUBTYPE,
{
END_DEVICE_PATH_LENGTH,
0
}
}
};
EFI_STATUS
PcatRootBridgeDevicePathConstructor (
IN EFI_DEVICE_PATH_PROTOCOL **Protocol,
IN UINTN RootBridgeNumber,
IN BOOLEAN IsPciExpress
)
/*++
Routine Description:
Construct the device path protocol
Arguments:
Protocol - protocol to initialize
Returns:
None
--*/
{
ACPI_HID_DEVICE_PATH *AcpiDevicePath;
*Protocol = DuplicateDevicePath((EFI_DEVICE_PATH_PROTOCOL *)(&mEfiPciRootBridgeDevicePath));
AcpiDevicePath = (ACPI_HID_DEVICE_PATH *)(*Protocol);
AcpiDevicePath->UID = (UINT32)RootBridgeNumber;
if (IsPciExpress) {
AcpiDevicePath->HID = EISA_PNP_ID(0x0A08);
}
return EFI_SUCCESS;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,66 @@
## @file
#
# Copyright (c) 2005 - 2018, 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.
#
# Module Name:
#
# Abstract:
#
##
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = PcatPciRootBridge
FILE_GUID = 0F7EC77A-1EE1-400f-A99D-7CBD1FEB181E
MODULE_TYPE = DXE_DRIVER
VERSION_STRING = 1.0
ENTRY_POINT = InitializePcatPciRootBridge
[Packages]
MdePkg/MdePkg.dec
UefiPayloadPkg/UefiPayloadPkg.dec
[LibraryClasses]
UefiDriverEntryPoint
UefiLib
MemoryAllocationLib
UefiBootServicesTableLib
DebugLib
BaseMemoryLib
DevicePathLib
HobLib
[Sources]
PcatPciRootBridge.h
PcatPciRootBridge.c
PcatPciRootBridgeDevicePath.c
PcatPciRootBridgeIo.c
DeviceIo.h
DeviceIo.c
[Sources.ia32]
Ia32/PcatIo.c
[Sources.x64]
X64/PcatIo.c
[Protocols]
gEfiPciRootBridgeIoProtocolGuid
gEfiDeviceIoProtocolGuid
gEfiCpuIo2ProtocolGuid
[Guids]
gEfiPciOptionRomTableGuid
gEfiPciExpressBaseAddressGuid
[Depex]
gEfiCpuIo2ProtocolGuid

Some files were not shown because too many files have changed in this diff Show More