Compare commits

...

47 Commits

Author SHA1 Message Date
2dc1e51593 UefiPayloadPkg: Add Secure Boot support
Cc: Guo Dong <guo.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Maurice Ma <maurice.ma@intel.com>
Cc: Benjamin You <benjamin.you@intel.com>
Signed-off-by: Sean Rhodes <sean@starlabs.systems>
Change-Id: I4f44e29bc967b7d2208193e21aeeef8b96afcc69
2022-06-03 09:03:42 -06:00
35dde2452d MdeModulePkg/FaultTolerantWriteDxe: Don't check for address alignment
WorkSpaceAddress and SpareAreaAddress point into MMIO, which isn't
always aligned. Remove the check for block alignment to avoid
false assertions.

Signed-off-by: Sean Rhodes <sean@starlabs.systems>
Change-Id: Ia1c1f44b6a0e7f32cac0d7806e74d729e5d83a6d
2022-06-03 09:03:42 -06:00
0f49a3fc87 Ps2KbdCtrller: Make wait for SUCCESS after BAT non-fatal
Recent model Chromebooks only return ACK, but not
BAT_SUCCESS, which causes hanging and failed ps2k init.
To mitigate this, make the absence of BAT_SUCCESS reply
non-fatal, and reduce the no-reply timeout from 4s to 1s.

Tested on google/dracia and purism/librem_14

Cc: Hao A Wu <hao.a.wu@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Signed-off-by: Matt DeVillier <matt.devillier@gmail.com>
Signed-off-by: Sean Rhodes <sean@starlabs.systems>
Change-Id: Ib644f6797eb50eb3bb75235ac48ddb6096a7bd6d
2022-06-03 09:03:42 -06:00
792844cb3b UefiPayloadPkg: Hook up RNG support
Hoop Up RNG from SecurityPkg.

Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Jian J Wang <jian.j.wang@intel.com>
Cc: Guo Dong <guo.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Maurice Ma <maurice.ma@intel.com>
Cc: Benjamin You <benjamin.you@intel.com>
Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com>
Change-Id: I9fadc2f36b0601b8a2f5b8a9abc3f208e7987e6c
2022-06-03 09:03:42 -06:00
136138411f SecurityPkg: Add RNG support
Uses the RDRAND instruction if available and install EfiRngProtocol.
The protocol may be used by iPXE or the Linux kernel to gather entropy.

Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Jian J Wang <jian.j.wang@intel.com>
Cc: Guo Dong <guo.dong@intel.com>
Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com>
Change-Id: I0f74b64c6a7e8fc6fdd8ea8f2a416d8b7c0334f4
2022-06-03 09:03:42 -06:00
1f31c0e81e UefiPayloadPkg: Add support for Firmware Volume Block Protocol
This adds support for FVB in order to support a platform independent
and non-volatile variable store on UefiPayloadPkg. The variable store
makes use the SmmStoreLib to provide an unauthenticed variable store.

Since commit bc744f5893fc4d53275ed26dd8d968011c6a09c1 coreboot supports
the SMMSTORE v2 feature. It implements a SMI handler that is able to
write, read and erase pages in the boot media (SPI flash).
The communication is done using a fixed communication buffer that is
allocated in CBMEM. The existence of this optional feature is advertised
by a coreboot table.
When the SMMSTORE feature is not available the variable emulation is used
by setting PcdEmuVariableNvModeEnable to TRUE.

The DXE component provides runtime services and takes care of virtual to
physical mapping the communication buffers between SMM and OS.

The contents of the variable store can be accessed and modified by any
priviledged application. As authentication is done by runtime services
only the store shouldn't be used to store authenticated variables.

Tested on Linux and Windows 10 on real hardware.
Currently this cannot be tested on coreboot and qemu as it doesn't support
the SMMSTORE on qemu.

Cc: Guo Dong <guo.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Maurice Ma <maurice.ma@intel.com>
Cc: Benjamin You <benjamin.you@intel.com>
Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com>
Signed-off-by: Sean Rhodes <sean@starlabs.systems>
Change-Id: I79a234275e25961869edf959cfbf4f8d17df2383
2022-06-03 09:03:42 -06:00
dcdfb2f083 UefiPayloadPkg: Add SmmStoreLib
Implement all of the FVB protocol functions on top of the SmmStore
as a library. The library consumes the introduced gEfiSmmStoreInfoHobGuid.

The SMI handler uses a fixed communication buffer in reserved DRAM.
To initiate a transaction you must write to the I/O APM_CNT port.

Tests on Intel(R) Xeon(R) E-2288G CPU @ 3.70G showed that the SMI isn't
triggered with a probability of 1:40 of all cases when called in a tight
loop. The CPU continues running and the SMI is triggeres asynchronously
a few clock cycles later. coreboot only handels synchronous APM request
and does nothing on asynchronous APM triggers.

As there's no livesign from SMM it's impossible to tell if the handler
has run. Just wait a bit and try again to trigger a synchronous SMI.

Tests confirmed that out of 5 million tries the SMI is now always handled.

When a synchronous SMI happens with the correct write to the APM_CNT port,
the ebx register is checked first that it doesn't point to SMRAM.
If it doesn't it's used to read in the arguments that define a SmmStore
transaction.

The SMI handler will only operate on a predefined and memory mapped region in
the boot media.

Cc: Guo Dong <guo.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Maurice Ma <maurice.ma@intel.com>
Cc: Benjamin You <benjamin.you@intel.com>
Cc: Sean Rhodes <sean@starlabs.systems>
Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com>
Change-Id: Id4182623e4198c6512d3fe6ec20adf6738586d9b
2022-06-03 09:03:42 -06:00
13dd54ae32 UefiPayloadPkg: Add SmmStoreInfoGuid
Add a new InfoHob that contains the SmmStore information passed from
coreboot tables when the SMMSTOREV2 feature is enabled.

This will be used to implement the FVB in top of the MM installed by
coreboot.

Cc: Guo Dong <guo.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Maurice Ma <maurice.ma@intel.com>
Cc: Benjamin You <benjamin.you@intel.com>
Cc: Sean Rhodes <sean@starlabs.systems>
Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com>
Change-Id: Ia3f7eef27d4758768c1a6736afe1cb77ee6a2f8f
2022-06-03 09:03:42 -06:00
bb19b4bc30 UefiPayloadPkg/Include/Coreboot: Add headers for SMMSTOREv2 table
Since commit bc744f5893fc4d53275ed26dd8d968011c6a09c1 coreboot supports
the SMMSTORE v2 feature. It implements a SMI handler that is able to
write, read and erase pages in the boot media (SPI flash).
The existence of this optional feature is advertised by a coreboot table.

Add the tag and headers to parse the table.

Cc: Guo Dong <guo.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Maurice Ma <maurice.ma@intel.com>
Cc: Benjamin You <benjamin.you@intel.com>
Cc: Sean Rhodes <sean@starlabs.systems>
Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com>
Change-Id: I02be3fa8d5d6ff47d56b81876590afef8f6c43c0
2022-06-03 09:03:42 -06:00
7693804ed1 UefiPayloadPkg: Increase FV size to 8MB
The following commits need additional space.

Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com>
Change-Id: I6b757f73fe4e90282b4bfb84469545ab1af9d1bb
Reviewed-on: https://review.coreboot.org/c/edk2/+/58630
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Matt DeVillier <matt.devillier@gmail.com>
2022-06-03 09:03:42 -06:00
626f1a3273 UefiPayloadPkg: Add System76 Setup menu 2022-06-03 09:03:42 -06:00
0420529401 UefiPayloadPkg: Add Intel GOP driver 2022-06-03 09:03:42 -06:00
13e6178201 UefiPayloadPkg: Add Pop!_OS Recovery to boot text
Preserve existing UI and add the note about pressing Space to go to
the systemd-boot menu for Pop!_OS Recovery.

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2022-06-03 09:03:42 -06:00
cbff8f0510 MdeModulePkg/BmBootDesciption: Remove device prefixes
Remove the device prefixes to match current System76 firmware UI in the
One Time Boot menu.

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2022-06-03 09:03:42 -06:00
601bcb9ce2 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.
2022-06-03 09:03:42 -06:00
6468032370 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.
2022-06-03 09:03:42 -06:00
7b3153b1cb UiApp: Dynamically generated firmware configuration information page
Signed-off-by: Jeremy Soller <jeremy@system76.com>
Signed-off-by: Tim Crawford <tcrawford@system76.com>
2022-06-03 09:03:42 -06:00
f2e99ad7b6 MdeModulePkg/BMM: Unregister F9 and F10 hotkeys 2022-06-03 09:03:42 -06:00
ae93abfcbf MdeModulePkg/BMM: Remove Commit/Discard buttons 2022-06-03 09:03:42 -06:00
de3e52e5d3 MdeModulePkg/BMM: Save BootOrder on list update 2022-06-03 09:03:42 -06:00
260b22ed3e MdeModulePkg/BMM: Add some debug logging 2022-06-03 09:03:42 -06:00
b79d3f9599 MdeModulePkg/UiApp: Add warning if no bootable options found 2022-06-03 09:03:42 -06:00
49dad2f15d MdeModulePkg/BootMaintenanceManagerUiLib: Make it look like current BMM 2022-06-03 09:03:42 -06:00
21bbc9ae0e MdeModulePkg/UiApp: Make it look like current FrontPage
Signed-off-by: Jeremy Soller <jeremy@system76.com>
Signed-off-by: Tim Crawford <tcrawford@system76.com>
2022-06-03 09:03:42 -06:00
52d9ce76db MdeModulePkg/BM: Make it look like current BootMngr 2022-06-03 09:03:42 -06:00
0d209e3a81 UefiPayloadPkg: Disable EFI shell 2022-06-03 09:03:42 -06:00
c418d4eb9e UefiPayloadPkg: Add library for logging to EC
Make use of the SMFI command interface to forward logs from edk2 to
System76 EC.

Signed-off-by: Jeremy Soller <jeremy@system76.com>
Signed-off-by: Tim Crawford <tcrawford@system76.com>
2022-06-03 09:03:42 -06:00
648620d59d UefiPayloadPkg: Scan for Option ROMs
Scanning for PCI Option ROMs on UEFI works with full PCI enumeration.
On platforms where the bootloader has done PCI enumeration a
platform specific driver needs to provide the Option ROMs.

As this is not specific to any platform, but rather to the UEFI as
payload concept, add the PCI platform driver to UefiPayloadPkg.

On coreboot the ROM BAR is part of the PCI bridge MMIO window and
can safely enabled if existing.

The Option ROMs are not passed in by bootloader in a HOB as:
- they might not fit into a HOB
- this is EDK2 specific and would just bloat the bootloader code
- would waste lot's of non reclaimable memory if placed in e820
  reserved DRAM space

Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com>
2022-06-03 09:03:42 -06:00
6284b7fe6f UefiPayloadPkg: Use new filesystem drivers
Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com>
2022-06-03 09:03:42 -06:00
e3ac04f774 Add filesystem drivers
Add EXT2/EXT4, exFAT, NTFS filesystem drivers.
Do not add ISO9115 drivers as it breaks El Torito boot.
2022-06-03 09:03:42 -06:00
5f7a6fe58b 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().
2022-06-03 09:03:42 -06:00
4f9743107d 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.
2022-06-03 09:03:42 -06:00
f300ed8297 MdeModulePkg: Wait for input after boot failure
Signed-off-by: Matt DeVillier <matt.devillier@gmail.com>
2022-06-03 09:03:42 -06:00
1fd1cf3dfb UefiPayloadPkg: Clear screen on boot error 2022-06-03 09:03:42 -06:00
053e8aed4d UefiPayloadPkg: Copy PlatformBootManagerUnableToBoot() from OvmfPkg 2022-06-03 09:03:42 -06:00
b219d5c94f UefiPayloadPkg: Set ResetOnMemoryTypeInformationChange to FALSE
the default value, TRUE, causes reboots if a device boots to the
shell, exits, and then attempts to boot from another source.

Signed-off-by: Matt DeVillier <matt.devillier@gmail.com>
2022-06-03 09:03:42 -06:00
20a7334a96 MdeModulePkg/GraphicsConsole: don't draw cursor at 0,0
Prevents cursor from flashing on screen when
changing modes or clearing the screen.

Signed-off-by: Matt DeVillier <matt.devillier@gmail.com>
2022-06-03 09:03:42 -06:00
a8abddc10a MdeModulePkg/BmBootDesciption: Improve device descriptions
Add device type prefixes for USB, IDE, SATA, and NVMe drives.
Remove UEFI prefix, remove serial numbers.

Signed-off-by: Matt DeVillier <matt.devillier@gmail.com>
2022-06-03 09:03:42 -06:00
93688ae1e5 MdeModulePkg/BmBoot: skip secondary eMMC entries
Internal eMMC devices often show multiple entries, so skip
any after the initial entry.

Signed-off-by: Matt DeVillier <matt.devillier@gmail.com>
2022-06-03 09:03:42 -06:00
38a3b6f58d MdeModulePkg/Frontpage: get SMBIOS Data from table directly
rather than getting it from the EFI SMBIOS protocol

Signed-off-by: Matt DeVillier <matt.devillier@gmail.com>
2022-06-03 09:03:41 -06:00
85f616be1b UefiPayloadPkg: Disable Device Manager 2022-06-03 09:03:41 -06:00
1aed3a3e36 BmpSupportLib: fix BMP validation
BMP files by tools other than MS paint can have a
variable number of padding bytes, which results in
the DataSize being less than (ImageSize - HeaderSize).
Fix the check to be less stringent.

Test: use BMP created by/saved by Photoshop

Signed-off-by: Matt DeVillier <matt.devillier@gmail.com>
2022-06-03 09:03:41 -06:00
f8d5dcd99b 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>
2022-06-03 09:03:41 -06:00
2046be8d5e 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
2022-06-03 09:03:41 -06:00
57ed7e7151 MdeModulePkg/Logo: Use System76 boot logo 2022-06-03 09:03:41 -06:00
a8285c29d8 UefiPayloadPkg: Enable boot logo
Signed-off-by: Tim Crawford <tcrawford@system76.com>
2022-06-03 09:03:41 -06:00
be10ebabba UefiPayloadPkg: Show boot message as progress text
Signed-off-by: Tim Crawford <tcrawford@system76.com>
2022-06-03 09:03:41 -06:00
95 changed files with 6102 additions and 924 deletions

View File

@ -0,0 +1,47 @@
Licensing for the filesystem drivers is complex. Three different licenses
apply to various parts of the code:
* Christoph Pfisterer's original file system wrapper (FSW) code is covered
by a BSD-style license. Many of the source files with names that take the
form fsw_*.[ch] are so licensed, but this is NOT generally true of
filesystem-specific files (e.g., fsw_ext2.c or fsw_btrfs.c).
* Certain filesystem drivers are licensed under the GPLv2, either because
they borrow code from the Linux kernel or because a developer (typically
Oracle) applied the GPLv2 license to them. This is true of the ext2fs,
ext4fs, ReiserFS, HFS+, and ISO-9660 drivers.
* At least one filesystem driver (Btrfs) uses code taken from GRUB, and so
uses the GPLv3 (or later) license.
Note that the GPLv2 and GPLv3 are, ironically, not compatible licenses.
Thus, code from GPLv2 and GPLv3 projects should not be mixed. The BSD
license used by Pfisterer's original code is compatible with both versions
of the GPL, so the fact that both GPLv2 and GPLv3 drivers is built upon it
is OK. If you intend to contribute to this project's drivers or use the
code yourself, please keep this fact in mind.
The below was written by Christoph Pfisterer with respect to his original
code:
File System Wrapper License
=============================
The various parts of the File System Wrapper source code come from
different sources and may carry different licenses. Here's a quick
account of the situation:
* The core code was written from scratch and is covered by a
BSD-style license.
* The EFI host driver was written from scratch, possibly using code
from the TianoCore project and Intel's EFI Application Toolkit. It
is covered by a BSD-style license.
* The ext2 and reiserfs file system drivers use definitions from the
Linux kernel source. The actual code was written from scratch,
using multiple sources for reference. These drivers are covered by
the GNU GPL.
For more details, see each file's boilerplate comment. The full text
of the GNU GPL is in the file LICENSE_GPL.txt.

View File

@ -0,0 +1,340 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

47
FSDrivers/X64/LICENSE.txt Normal file
View File

@ -0,0 +1,47 @@
Licensing for the filesystem drivers is complex. Three different licenses
apply to various parts of the code:
* Christoph Pfisterer's original file system wrapper (FSW) code is covered
by a BSD-style license. Many of the source files with names that take the
form fsw_*.[ch] are so licensed, but this is NOT generally true of
filesystem-specific files (e.g., fsw_ext2.c or fsw_btrfs.c).
* Certain filesystem drivers are licensed under the GPLv2, either because
they borrow code from the Linux kernel or because a developer (typically
Oracle) applied the GPLv2 license to them. This is true of the ext2fs,
ext4fs, ReiserFS, HFS+, and ISO-9660 drivers.
* At least one filesystem driver (Btrfs) uses code taken from GRUB, and so
uses the GPLv3 (or later) license.
Note that the GPLv2 and GPLv3 are, ironically, not compatible licenses.
Thus, code from GPLv2 and GPLv3 projects should not be mixed. The BSD
license used by Pfisterer's original code is compatible with both versions
of the GPL, so the fact that both GPLv2 and GPLv3 drivers is built upon it
is OK. If you intend to contribute to this project's drivers or use the
code yourself, please keep this fact in mind.
The below was written by Christoph Pfisterer with respect to his original
code:
File System Wrapper License
=============================
The various parts of the File System Wrapper source code come from
different sources and may carry different licenses. Here's a quick
account of the situation:
* The core code was written from scratch and is covered by a
BSD-style license.
* The EFI host driver was written from scratch, possibly using code
from the TianoCore project and Intel's EFI Application Toolkit. It
is covered by a BSD-style license.
* The ext2 and reiserfs file system drivers use definitions from the
Linux kernel source. The actual code was written from scratch,
using multiple sources for reference. These drivers are covered by
the GNU GPL.
For more details, see each file's boilerplate comment. The full text
of the GNU GPL is in the file LICENSE_GPL.txt.

View File

@ -0,0 +1,340 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.

Binary file not shown.

BIN
FSDrivers/X64/exfat_x64.efi Normal file

Binary file not shown.

BIN
FSDrivers/X64/ext2_x64.efi Normal file

Binary file not shown.

BIN
FSDrivers/X64/ext4_x64.efi Normal file

Binary file not shown.

BIN
FSDrivers/X64/ntfs_x64.efi Normal file

Binary file not shown.

27
FSDrivers/exfat.inf Normal file
View File

@ -0,0 +1,27 @@
# ReadOnly exFAT filesystem driver
# From https://efi.akeo.ie/ v1.5
##
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = exfat
FILE_GUID = CB683001-379F-48C7-B7B6-707D29454BF5
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 IA32
[Binaries.X64]
PE32|X64/exfat_x64.efi|*
[Binaries.IA32]
PE32|IA32/exfat_ia32.efi|*

25
FSDrivers/ext2.inf Normal file
View File

@ -0,0 +1,25 @@
# EXT2 filesystem driver. See */LICENSE.txt for details.
# https://www.rodsbooks.com/refind/ v0.12
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = ext2
FILE_GUID = 8EC49C43-D1C4-4E6C-98BF-232CA5D89A1B
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 IA32
[Binaries.X64]
PE32|X64/ext2_x64.efi|*
[Binaries.IA32]
PE32|IA32/ext2_ia32.efi|*

25
FSDrivers/ext4.inf Normal file
View File

@ -0,0 +1,25 @@
# EXT4 filesystem driver. See */LICENSE.txt for details.
# https://www.rodsbooks.com/refind/ v0.12
[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 IA32
[Binaries.X64]
PE32|X64/ext4_x64.efi|*
[Binaries.IA32]
PE32|IA32/ext4_ia32.efi|*

27
FSDrivers/ntfs.inf Normal file
View File

@ -0,0 +1,27 @@
# ReadOnly NTFS filesystem driver
# From https://efi.akeo.ie/ v1.5
##
[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 IA32
[Binaries.X64]
PE32|X64/ntfs_x64.efi|*
[Binaries.IA32]
PE32|IA32/ntfs_ia32.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,
@ -371,10 +379,6 @@ FreeFrontPage (
// Publish our HII data
//
HiiRemovePackages (gFrontPagePrivate.HiiHandle);
if (gFrontPagePrivate.LanguageToken != NULL) {
FreePool (gFrontPagePrivate.LanguageToken);
gFrontPagePrivate.LanguageToken = NULL;
}
}
/**
@ -496,6 +500,463 @@ GetOptionalStringByIndex (
return EFI_SUCCESS;
}
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.
@ -506,160 +967,86 @@ UpdateFrontPageBannerStrings (
VOID
)
{
UINT8 StrIndex;
CHAR16 *NewString;
CHAR16 *FirmwareVersionString;
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_STATUS Status;
EFI_STRING_ID TokenToUpdate;
EFI_PHYSICAL_ADDRESS *Table;
SMBIOS_TABLE_ENTRY_POINT *EntryPoint;
SMBIOS_STRUCTURE_POINTER SmbiosTable;
InstalledMemory = 0;
FoundCpu = 0;
//
// 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);
FirmwareConfigurationInformation();
WarnNoBootableMedia ();
WebcamStatus();
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) {
CHAR16 *FwVersion;
CHAR16 *TmpBuffer;
UINT8 VersionIdx;
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);
}
TmpBuffer = AllocateZeroPool (0x60);
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);
VersionIdx = SmbiosTable.Type0->BiosVersion;
GetOptionalStringByIndex ((CHAR8*)((UINT8*)SmbiosTable.Raw + SmbiosTable.Hdr->Length), VersionIdx, &FwVersion);
ConvertProcessorToString (Type4Record->CurrentSpeed, 6, &NewString);
UiCustomizeFrontPageBanner (2, FALSE, &NewString);
HiiSetString (gFrontPagePrivate.HiiHandle, STRING_TOKEN (STR_FRONT_PAGE_CPU_SPEED), NewString, NULL);
FreePool (NewString);
StrCatS (TmpBuffer, 0x60 / sizeof (CHAR16), L"Version: ");
StrCatS (TmpBuffer, 0x60 / sizeof (CHAR16), FwVersion);
FoundCpu = TRUE;
}
}
TokenToUpdate = STRING_TOKEN (STR_FRONT_PAGE_BIOS_VERSION);
HiiSetString (gFrontPagePrivate.HiiHandle, TokenToUpdate, TmpBuffer, NULL);
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);
FreePool (FwVersion);
FreePool (TmpBuffer);
}
//
// 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) {
CHAR16 *Manufacturer;
CHAR16 *ProductName;
CHAR16 *ProductVersion;
CHAR16 *Title;
CHAR16 *Model;
UINT8 ModelIdx;
UINT8 ManIdx;
UINT8 VersionIdx;
Title = AllocateZeroPool (0x60);
Model = AllocateZeroPool (0x60);
ManIdx = SmbiosTable.Type1->Manufacturer;
ModelIdx = SmbiosTable.Type1->ProductName;
GetOptionalStringByIndex ((CHAR8*)((UINT8*)SmbiosTable.Raw + SmbiosTable.Hdr->Length), ModelIdx, &ProductName);
GetOptionalStringByIndex ((CHAR8*)((UINT8*)SmbiosTable.Raw + SmbiosTable.Hdr->Length), ManIdx, &Manufacturer);
StrCatS (Title, 0x60 / sizeof (CHAR16), Manufacturer);
StrCatS (Title, 0x60 / sizeof (CHAR16), L" ");
StrCatS (Title, 0x60 / sizeof (CHAR16), ProductName);
TokenToUpdate = STRING_TOKEN (STR_FRONT_PAGE_TITLE);
HiiSetString (gFrontPagePrivate.HiiHandle, TokenToUpdate, Title, NULL);
VersionIdx = SmbiosTable.Type1->Version;
GetOptionalStringByIndex ((CHAR8*)((UINT8*)SmbiosTable.Raw + SmbiosTable.Hdr->Length), VersionIdx, &ProductVersion);
StrCatS (Model, 0x60 / sizeof (CHAR16), L"Model: ");
StrCatS (Model, 0x60 / sizeof (CHAR16), ProductVersion);
TokenToUpdate = STRING_TOKEN (STR_FRONT_PAGE_COMPUTER_MODEL);
HiiSetString (gFrontPagePrivate.HiiHandle, TokenToUpdate, Model, NULL);
FreePool (Model);
FreePool (Title);
FreePool (ProductVersion);
FreePool (ProductName);
FreePool (Manufacturer);
}
}
/**
@ -907,6 +1294,8 @@ InitializeUserInterface (
UINTN BootTextColumn;
UINTN BootTextRow;
gSystemTable = SystemTable;
if (!mModeInitialized) {
//
// After the console is ready, get current video resolution
@ -1032,11 +1421,6 @@ UiEntry (
FreeFrontPage ();
if (mLanguageString != NULL) {
FreePool (mLanguageString);
mLanguageString = NULL;
}
//
// Will leave browser, check any reset required change is applied? if yes, reset system
//

View File

@ -31,7 +31,7 @@ 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_FRONTPAGE_INFORMATION 0x1000
#define LABEL_END 0xffff
@ -51,7 +51,6 @@ typedef struct {
//
EFI_HII_HANDLE HiiHandle;
EFI_HANDLE DriverHandle;
EFI_STRING_ID *LanguageToken;
//
// Produced protocols

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,46 +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,8 @@ 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.
@ -182,21 +76,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;
}
@ -223,17 +108,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;
}
@ -242,158 +116,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.
@ -410,8 +132,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
);
@ -430,30 +152,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,64 +9,24 @@
#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_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;
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;
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);
label LABEL_FRONTPAGE_INFORMATION;
//
@ -75,6 +35,27 @@ formset
//
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 ## GUID
[Protocols]
gEfiSmbiosProtocolGuid ## CONSUMES

View File

@ -1733,11 +1733,7 @@ InitKeyboard (
//
mWaitForValueTimeOut = KEYBOARD_BAT_TIMEOUT;
Status = KeyboardWaitForValue (ConsoleIn, KEYBOARD_8048_RETURN_8042_BAT_SUCCESS);
if (EFI_ERROR (Status)) {
KeyboardError (ConsoleIn, L"Keyboard self test failed!\n\r");
goto Done;
}
KeyboardWaitForValue (ConsoleIn, KEYBOARD_8048_RETURN_8042_BAT_SUCCESS);
mWaitForValueTimeOut = KEYBOARD_WAITFORVALUE_TIMEOUT;

View File

@ -157,7 +157,7 @@ InstallPs2KeyboardDriver (
#define KEYBOARD_MAX_TRY 256 // 256
#define KEYBOARD_TIMEOUT 65536 // 0.07s
#define KEYBOARD_WAITFORVALUE_TIMEOUT 1000000 // 1s
#define KEYBOARD_BAT_TIMEOUT 4000000 // 4s
#define KEYBOARD_BAT_TIMEOUT 1000000 // 1s
#define KEYBOARD_TIMER_INTERVAL 200000 // 0.02s
#define SCANCODE_EXTENDED0 0xE0
#define SCANCODE_EXTENDED1 0xE1

View File

@ -67,6 +67,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

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

View File

@ -216,7 +216,7 @@ TranslateBmpToGopBlt (
if ((BmpHeader->Size != BmpImageSize) ||
(BmpHeader->Size < BmpHeader->ImageOffset) ||
(BmpHeader->Size - BmpHeader->ImageOffset != DataSize))
(BmpHeader->Size - BmpHeader->ImageOffset < DataSize))
{
DEBUG ((DEBUG_ERROR, "TranslateBmpToGopBlt: invalid BmpImage... \n"));
DEBUG ((DEBUG_ERROR, " BmpHeader->Size: 0x%x\n", BmpHeader->Size));

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

@ -176,7 +176,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

@ -733,6 +733,7 @@ BootMaintExtractConfig (
*Progress = Request + StrLen (Request);
}
DEBUG ((EFI_D_INFO, "%a complete: %r\n", __FUNCTION__, Status));
return Status;
}
@ -1059,6 +1060,7 @@ BootMaintRouteConfig (
//
CopyMem (OldBmmData, NewBmmData, sizeof (BMM_FAKE_NV_DATA));
DEBUG ((EFI_D_INFO, "%a complete: %r\n", __FUNCTION__, Status));
return EFI_SUCCESS;
Exit:
@ -1119,6 +1121,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) {
//
@ -1130,7 +1134,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;
@ -1146,6 +1152,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;
}
@ -1231,6 +1239,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;
}
@ -1270,6 +1280,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) {
//
@ -1336,6 +1351,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;
}
@ -1665,6 +1681,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.
@ -1740,8 +1778,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);
@ -1753,6 +1791,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

@ -111,40 +111,6 @@ UpdatePageEnd (
IN BMM_CALLBACK_DATA *CallbackData
)
{
//
// Create the "Apply changes" and "Discard changes" tags.
//
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
);
}
//
// 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
);
HiiUpdateForm (
CallbackData->BmmHiiHandle,
&mBootMaintGuid,
@ -651,7 +617,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
@ -1155,9 +1121,4 @@ UpdatePageId (
} else if ((NewPageId >= TERMINAL_OPTION_OFFSET) && (NewPageId < CONSOLE_OPTION_OFFSET)) {
NewPageId = FORM_CON_COM_SETUP_ID;
}
if ((NewPageId > 0) && (NewPageId < MAXIMUM_FORM_ID)) {
Private->BmmPreviousPageId = Private->BmmCurrentPageId;
Private->BmmCurrentPageId = NewPageId;
}
}

View File

@ -633,6 +633,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",
@ -493,22 +499,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;
@ -550,6 +544,8 @@ UpdateBootManager (
continue;
}
OptionCount++;
//
// Group the legacy boot option in the sub title created dynamically
//
@ -605,6 +601,10 @@ UpdateBootManager (
);
}
if (OptionCount == 0) {
HiiCreateSubTitleOpCode (StartOpCodeHandle, STRING_TOKEN (STR_NO_BOOTABLE_MEDIA), 0, 0, 0);
}
if (NeedEndOp) {
HiiCreateEndOpCode (StartOpCodeHandle);
}
@ -797,7 +797,6 @@ BootManagerCallback (
{
EFI_BOOT_MANAGER_LOAD_OPTION *BootOption;
UINTN BootOptionCount;
EFI_INPUT_KEY Key;
if (Action == EFI_BROWSER_ACTION_FORM_OPEN) {
//
@ -842,19 +841,31 @@ 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);
}
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.
@ -903,6 +914,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;
}
@ -923,6 +951,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

@ -1831,6 +1831,8 @@ EfiBootManagerBoot (
UINTN FileSize;
EFI_BOOT_LOGO_PROTOCOL *BootLogo;
EFI_EVENT LegacyBootEvent;
EFI_INPUT_KEY Key;
UINTN Index;
if (BootOption == NULL) {
return;
@ -1971,6 +1973,23 @@ EfiBootManagerBoot (
//
BmReportLoadFailure (EFI_SW_DXE_BS_EC_BOOT_OPTION_LOAD_ERROR, Status);
BootOption->Status = Status;
if (gST->ConOut != NULL) {
gST->ConOut->ClearScreen (gST->ConOut);
AsciiPrint (
"Booting from '%s' failed; verify it contains a 64-bit UEFI OS.\n"
"\nPress any key to continue booting...\n",
BootOption->Description);
}
if (gST->ConIn != NULL) {
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;
}
}
@ -2175,12 +2194,14 @@ BmEnumerateBootOptions (
EFI_BLOCK_IO_PROTOCOL *BlkIo;
UINTN Removable;
UINTN Index;
UINTN EmmcCount;
CHAR16 *Description;
ASSERT (BootOptionCount != NULL);
*BootOptionCount = 0;
BootOptions = NULL;
EmmcCount = 0;
//
// Parse removable block io followed by fixed block io
@ -2219,6 +2240,17 @@ BmEnumerateBootOptions (
}
Description = BmGetBootDescription (Handles[Index]);
//
// Skip secondary entries for internal eMMC devices
//
if (StrCmp(Description, L"eMMC Device") == 0) {
EmmcCount++;
if (EmmcCount > 1) {
continue;
}
}
BootOptions = ReallocatePool (
sizeof (EFI_BOOT_MANAGER_LOAD_OPTION) * (*BootOptionCount),
sizeof (EFI_BOOT_MANAGER_LOAD_OPTION) * (*BootOptionCount + 1),

View File

@ -15,7 +15,6 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#define PRODUCT_IDENTIFICATION_LENGTH 16
CONST UINT16 mBmUsbLangId = 0x0409; // English
CHAR16 mBmUefiPrefix[] = L"UEFI ";
LIST_ENTRY mPlatformBootDescriptionHandlers = INITIALIZE_LIST_HEAD_VARIABLE (mPlatformBootDescriptionHandlers);
@ -146,9 +145,8 @@ BmGetDescriptionFromDiskInfo (
EFI_ATAPI_IDENTIFY_DATA IdentifyData;
EFI_SCSI_INQUIRY_DATA InquiryData;
CHAR16 *Description;
UINTN Length;
CHAR16 *DescTemp;
CONST UINTN ModelNameLength = 40;
CONST UINTN SerialNumberLength = 20;
CHAR8 *StrPtr;
UINT8 Temp;
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
@ -174,26 +172,19 @@ BmGetDescriptionFromDiskInfo (
&BufferSize
);
if (!EFI_ERROR (Status)) {
Description = AllocateZeroPool ((ModelNameLength + SerialNumberLength + 2) * sizeof (CHAR16));
Description = AllocateZeroPool (ModelNameLength * sizeof (CHAR16));
ASSERT (Description != NULL);
for (Index = 0; Index + 1 < ModelNameLength; Index += 2) {
Description[Index] = (CHAR16)IdentifyData.ModelName[Index + 1];
Description[Index + 1] = (CHAR16)IdentifyData.ModelName[Index];
}
Length = Index;
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;
Description[Length++] = L'\0';
ASSERT (Length == ModelNameLength + SerialNumberLength + 2);
Description[Index] = L'\0';
BmEliminateExtraSpaces (Description);
DescTemp = AllocateZeroPool (0x60);
StrCatS (DescTemp, 0x60 / sizeof (CHAR16), Description);
StrCpyS(Description, StrSize (DescTemp) / sizeof (CHAR16), DescTemp);
FreePool (DescTemp);
}
} else if (CompareGuid (&DiskInfo->Interface, &gEfiDiskInfoScsiInterfaceGuid)) {
BufferSize = sizeof (EFI_SCSI_INQUIRY_DATA);
@ -273,7 +264,6 @@ BmGetUsbDescription (
CHAR16 NullChar;
CHAR16 *Manufacturer;
CHAR16 *Product;
CHAR16 *SerialNumber;
CHAR16 *Description;
EFI_USB_DEVICE_DESCRIPTOR DevDesc;
UINTN DescMaxSize;
@ -314,25 +304,12 @@ BmGetUsbDescription (
Product = &NullChar;
}
Status = UsbIo->UsbGetStringDescriptor (
UsbIo,
mBmUsbLangId,
DevDesc.StrSerialNumber,
&SerialNumber
);
if (EFI_ERROR (Status)) {
SerialNumber = &NullChar;
}
if ((Manufacturer == &NullChar) &&
(Product == &NullChar) &&
(SerialNumber == &NullChar)
)
{
(Product == &NullChar)) {
return NULL;
}
DescMaxSize = StrSize (Manufacturer) + StrSize (Product) + StrSize (SerialNumber);
DescMaxSize = StrSize (Manufacturer) + StrSize (Product);
Description = AllocateZeroPool (DescMaxSize);
ASSERT (Description != NULL);
StrCatS (Description, DescMaxSize/sizeof (CHAR16), Manufacturer);
@ -341,8 +318,6 @@ BmGetUsbDescription (
StrCatS (Description, DescMaxSize/sizeof (CHAR16), Product);
StrCatS (Description, DescMaxSize/sizeof (CHAR16), L" ");
StrCatS (Description, DescMaxSize/sizeof (CHAR16), SerialNumber);
if (Manufacturer != &NullChar) {
FreePool (Manufacturer);
}
@ -351,10 +326,6 @@ BmGetUsbDescription (
FreePool (Product);
}
if (SerialNumber != &NullChar) {
FreePool (SerialNumber);
}
BmEliminateExtraSpaces (Description);
return Description;
@ -584,6 +555,7 @@ BmGetNvmeDescription (
EFI_NVM_EXPRESS_COMPLETION Completion;
NVME_ADMIN_CONTROLLER_DATA ControllerData;
CHAR16 *Description;
CHAR16 *DescTemp;
CHAR16 *Char;
UINTN Index;
@ -653,20 +625,11 @@ BmGetNvmeDescription (
*(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
);
BmEliminateExtraSpaces (Description);
DescTemp = AllocateZeroPool (0x60);
StrCatS (DescTemp, 0x60 / sizeof (CHAR16), Description);
StrCpyS(Description, StrSize (DescTemp) / sizeof (CHAR16), DescTemp);
FreePool (DescTemp);
}
return Description;
@ -801,7 +764,6 @@ BmGetBootDescription (
BM_BOOT_DESCRIPTION_ENTRY *Entry;
CHAR16 *Description;
CHAR16 *DefaultDescription;
CHAR16 *Temp;
UINTN Index;
//
@ -811,16 +773,6 @@ BmGetBootDescription (
for (Index = 0; Index < ARRAY_SIZE (mBmBootDescriptionHandlers); Index++) {
DefaultDescription = mBmBootDescriptionHandlers[Index](Handle);
if (DefaultDescription != NULL) {
//
// 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));
ASSERT (Temp != NULL);
StrCpyS (Temp, (StrSize (DefaultDescription) + sizeof (mBmUefiPrefix)) / sizeof (CHAR16), mBmUefiPrefix);
StrCatS (Temp, (StrSize (DefaultDescription) + sizeof (mBmUefiPrefix)) / sizeof (CHAR16), DefaultDescription);
FreePool (DefaultDescription);
DefaultDescription = Temp;
break;
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 315 KiB

View File

@ -2175,3 +2175,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

@ -330,7 +330,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;
}
@ -1044,7 +1045,7 @@ BdsEntry (
//
// BdsReadKeys() can be removed after all keyboard drivers invoke callback in timer callback.
//
BdsReadKeys ();
//BdsReadKeys ();
EfiBootManagerHotkeyBoot ();

View File

@ -1943,7 +1943,8 @@ FlushCursor (
CurrentMode = This->Mode;
if (!CurrentMode->CursorVisible) {
if (!CurrentMode->CursorVisible ||
(CurrentMode->CursorColumn == 0 && CurrentMode->CursorRow == 0 )) {
return EFI_SUCCESS;
}

View File

@ -1119,8 +1119,8 @@ FindFvbForFtw (
// To get the LBA of work space
//
for (LbaIndex = 1; LbaIndex <= NumberOfBlocks; LbaIndex += 1) {
if ( (FtwDevice->WorkSpaceAddress >= (FvbBaseAddress + BlockSize * (LbaIndex - 1)))
&& (FtwDevice->WorkSpaceAddress < (FvbBaseAddress + BlockSize * LbaIndex)))
if (FtwDevice->WorkSpaceAddress - FvbBaseAddress >= BlockSize * (LbaIndex - 1) &&
(FtwDevice->WorkSpaceAddress - FvbBaseAddress) / BlockSize >= LbaIndex - 1)
{
FtwDevice->FtwWorkSpaceLba = LbaIndex - 1;
//
@ -1132,12 +1132,10 @@ FindFvbForFtw (
FtwDevice->NumberOfWorkSpaceBlock = FTW_BLOCKS (FtwDevice->FtwWorkSpaceBase + FtwDevice->FtwWorkSpaceSize, FtwDevice->WorkBlockSize);
if (FtwDevice->FtwWorkSpaceSize >= FtwDevice->WorkBlockSize) {
//
// Check the alignment of work space address and length, they should be block size aligned when work space size is larger than one block size.
// Check the alignment of work space length, it should be block size aligned when work space size is larger than one block size.
//
if (((FtwDevice->WorkSpaceAddress & (FtwDevice->WorkBlockSize - 1)) != 0) ||
((FtwDevice->WorkSpaceLength & (FtwDevice->WorkBlockSize - 1)) != 0))
{
DEBUG ((DEBUG_ERROR, "Ftw: Work space address or length is not block size aligned when work space size is larger than one block size\n"));
if ((FtwDevice->WorkSpaceLength & (FtwDevice->WorkBlockSize - 1)) != 0) {
DEBUG ((EFI_D_ERROR, "Ftw: Work space length is not block size aligned when work space size is larger than one block size\n"));
FreePool (HandleBuffer);
ASSERT (FALSE);
return EFI_ABORTED;
@ -1182,12 +1180,10 @@ FindFvbForFtw (
}
//
// Check the alignment of spare area address and length, they should be block size aligned
// Check the alignment of spare area length, it should be block size aligned
//
if (((FtwDevice->SpareAreaAddress & (FtwDevice->SpareBlockSize - 1)) != 0) ||
((FtwDevice->SpareAreaLength & (FtwDevice->SpareBlockSize - 1)) != 0))
{
DEBUG ((DEBUG_ERROR, "Ftw: Spare area address or length is not block size aligned\n"));
if ((FtwDevice->SpareAreaLength & (FtwDevice->SpareBlockSize - 1)) != 0) {
DEBUG ((EFI_D_ERROR, "Ftw: Spare area address or length is not block size aligned\n"));
FreePool (HandleBuffer);
//
// Report Status Code EFI_SW_EC_ABORTED.

View File

@ -6239,9 +6239,13 @@ typedef union {
///
/// [Bit 11] Execute Disable Bit Enable: IA32_EFER.NXE (R/W).
///
UINT32 NXE : 1;
UINT32 Reserved3 : 20;
UINT32 Reserved4 : 32;
UINT32 NXE:1;
///
/// [ Bit 12] Secure Virtual Machine Enable (AMD only)
///
UINT32 SVME:1;
UINT32 Reserved3:19;
UINT32 Reserved4:32;
} Bits;
///
/// All bit fields as a 32-bit value

View File

@ -0,0 +1,199 @@
/** @file
Random number generator services that uses RdRand instruction access
to provide high-quality random numbers.
Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include <Library/BaseLib.h>
#include <Library/DebugLib.h>
#include <Register/Intel/Cpuid.h>
STATIC BOOLEAN mHasRdRand;
//
// Bit mask used to determine if RdRand instruction is supported.
//
#define RDRAND_MASK BIT30
//
// Limited retry number when valid random data is returned.
// Uses the recommended value defined in Section 7.3.17 of "Intel 64 and IA-32
// Architectures Software Developer's Mannual".
//
#define RDRAND_RETRY_LIMIT 10
/**
The constructor function checks whether or not RDRAND instruction is supported
by the host hardware.
The constructor function checks whether or not RDRAND instruction is supported.
It will always return RETURN_SUCCESS.
@retval RETURN_SUCCESS The constructor always returns EFI_SUCCESS.
**/
RETURN_STATUS
EFIAPI
BaseRngLibConstructor (
VOID
)
{
UINT32 RegEax;
UINT32 RegEcx;
AsmCpuid (CPUID_SIGNATURE, &RegEax, NULL, NULL, NULL);
if (RegEax < 1) {
mHasRdRand = FALSE;
return RETURN_SUCCESS;
}
//
// Determine RDRAND support by examining bit 30 of the ECX register returned by
// CPUID. A value of 1 indicates that processor support RDRAND instruction.
//
AsmCpuid (CPUID_VERSION_INFO, 0, 0, &RegEcx, 0);
mHasRdRand = ((RegEcx & RDRAND_MASK) == RDRAND_MASK);
return RETURN_SUCCESS;
}
/**
Generates a 16-bit random number.
if Rand is NULL, then ASSERT().
@param[out] Rand Buffer pointer to store the 16-bit random value.
@retval TRUE Random number generated successfully.
@retval FALSE Failed to generate the random number.
**/
BOOLEAN
EFIAPI
GetRandomNumber16 (
OUT UINT16 *Rand
)
{
UINT32 Index;
ASSERT (Rand != NULL);
if (mHasRdRand) {
//
// A loop to fetch a 16 bit random value with a retry count limit.
//
for (Index = 0; Index < RDRAND_RETRY_LIMIT; Index++) {
if (AsmRdRand16 (Rand)) {
return TRUE;
}
}
}
return FALSE;
}
/**
Generates a 32-bit random number.
if Rand is NULL, then ASSERT().
@param[out] Rand Buffer pointer to store the 32-bit random value.
@retval TRUE Random number generated successfully.
@retval FALSE Failed to generate the random number.
**/
BOOLEAN
EFIAPI
GetRandomNumber32 (
OUT UINT32 *Rand
)
{
UINT32 Index;
ASSERT (Rand != NULL);
if (mHasRdRand) {
//
// A loop to fetch a 32 bit random value with a retry count limit.
//
for (Index = 0; Index < RDRAND_RETRY_LIMIT; Index++) {
if (AsmRdRand32 (Rand)) {
return TRUE;
}
}
}
return FALSE;
}
/**
Generates a 64-bit random number.
if Rand is NULL, then ASSERT().
@param[out] Rand Buffer pointer to store the 64-bit random value.
@retval TRUE Random number generated successfully.
@retval FALSE Failed to generate the random number.
**/
BOOLEAN
EFIAPI
GetRandomNumber64 (
OUT UINT64 *Rand
)
{
UINT32 Index;
ASSERT (Rand != NULL);
if (mHasRdRand) {
//
// A loop to fetch a 64 bit random value with a retry count limit.
//
for (Index = 0; Index < RDRAND_RETRY_LIMIT; Index++) {
if (AsmRdRand64 (Rand)) {
return TRUE;
}
}
}
return FALSE;
}
/**
Generates a 128-bit random number.
if Rand is NULL, then ASSERT().
@param[out] Rand Buffer pointer to store the 128-bit random value.
@retval TRUE Random number generated successfully.
@retval FALSE Failed to generate the random number.
**/
BOOLEAN
EFIAPI
GetRandomNumber128 (
OUT UINT64 *Rand
)
{
ASSERT (Rand != NULL);
//
// Read first 64 bits
//
if (!GetRandomNumber64 (Rand)) {
return FALSE;
}
//
// Read second 64 bits
//
return GetRandomNumber64 (++Rand);
}

View File

@ -0,0 +1,32 @@
## @file
# Instance of RNG (Random Number Generator) Library.
#
# Copyright (c) 2020 9elements Agency GmbH.<BR>
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
##
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = BaseRngLib
MODULE_UNI_FILE = BaseRngLib.uni
FILE_GUID = 05C48431-DE18-4550-931A-3350E8551498
MODULE_TYPE = BASE
VERSION_STRING = 1.0
LIBRARY_CLASS = RngLib
CONSTRUCTOR = BaseRngLibConstructor
#
# VALID_ARCHITECTURES = IA32 X64
#
[Sources.Ia32, Sources.X64]
BaseRng.c
[Packages]
MdePkg/MdePkg.dec
[LibraryClasses]
BaseLib
DebugLib

View File

@ -0,0 +1,17 @@
// /** @file
// Instance of RNG (Random Number Generator) Library.
//
// BaseRng Library that uses CPU RdRand instruction access to provide
// high-quality random numbers.
//
// Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
//
// SPDX-License-Identifier: BSD-2-Clause-Patent
//
// **/
#string STR_MODULE_ABSTRACT #language en-US "Instance of RNG Library"
#string STR_MODULE_DESCRIPTION #language en-US "BaseRng Library that uses CPU RdRand instruction access to provide high-quality random numbers"

View File

@ -19,6 +19,7 @@
#include <Library/UefiRuntimeServicesTableLib.h>
#include <Library/SecureBootVariableLib.h>
#include <Library/SecureBootVariableProvisionLib.h>
#include <Library/DxeServicesLib.h>
/**
Enroll a key/certificate based on a default variable.
@ -117,6 +118,7 @@ SecureBootInitPKDefault (
}
if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) {
DEBUG ((DEBUG_INFO, "Variable %s read error.\n", EFI_PK_DEFAULT_VARIABLE_NAME));
return Status;
}
@ -264,10 +266,10 @@ SecureBootInitDbxDefault (
IN VOID
)
{
EFI_SIGNATURE_LIST *EfiSig;
UINTN SigListsSize;
UINTN Size;
EFI_STATUS Status;
UINT8 *Data;
UINT8 *Data;
VOID *Buffer;
UINTN DataSize;
//
@ -289,7 +291,13 @@ SecureBootInitDbxDefault (
//
DEBUG ((DEBUG_INFO, "Variable %s does not exist.\n", EFI_DBX_DEFAULT_VARIABLE_NAME));
Status = SecureBootFetchData (&gDefaultdbxFileGuid, &SigListsSize, &EfiSig);
Status = GetSectionFromAnyFv (
&gDefaultdbxFileGuid,
EFI_SECTION_RAW,
0,
&Buffer,
&Size
);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_INFO, "Content for %s not found\n", EFI_DBX_DEFAULT_VARIABLE_NAME));
return Status;
@ -299,15 +307,13 @@ SecureBootInitDbxDefault (
EFI_DBX_DEFAULT_VARIABLE_NAME,
&gEfiGlobalVariableGuid,
EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS,
SigListsSize,
(VOID *)EfiSig
Size,
(VOID *)Buffer
);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_INFO, "Failed to set %s\n", EFI_DBX_DEFAULT_VARIABLE_NAME));
}
FreePool (EfiSig);
return Status;
}

View File

@ -236,6 +236,19 @@ struct cb_cbmem_tab {
UINT64 cbmem_tab;
};
#define CB_TAG_SMMSTOREV2 0x0039
struct cb_smmstorev2 {
UINT32 tag;
UINT32 size;
UINT32 num_blocks; /* Number of writeable blocks in Smm */
UINT32 block_size; /* Size of a block in byte. Default: 64 KiB */
UINT32 mmap_addr; /* MMIO address of the store for read only access */
UINT32 com_buffer; /* Physical address of the communication buffer */
UINT32 com_buffer_size; /* Size of the communication buffer in byte */
UINT8 apm_cmd; /* The command byte to write to the APM I/O port */
UINT8 unused[3]; /* Set to zero */
};
/* Helpful macros */
#define MEM_RANGE_COUNT(_rec) \

View File

@ -0,0 +1,27 @@
/** @file
This file defines the hob structure for coreboot's SmmStore.
Copyright (c) 2022, 9elements GmbH<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#ifndef SMMSTORE_GUID_H_
#define SMMSTORE_GUID_H_
///
/// System Table Information GUID
///
extern EFI_GUID gEfiSmmStoreInfoHobGuid;
typedef struct {
UINT64 ComBuffer;
UINT32 ComBufferSize;
UINT32 NumBlocks;
UINT32 BlockSize;
UINT64 MmioAddress;
UINT8 ApmCmd;
UINT8 Reserved0[3];
} SMMSTORE_INFO;
#endif // SMMSTORE_GUID_H_

View File

@ -0,0 +1,120 @@
/** @file SmmStoreLib.h
Copyright (c) 2022, 9elements GmbH<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#ifndef SMM_STORE_LIB_H_
#define SMM_STORE_LIB_H_
#include <Base.h>
#include <Uefi/UefiBaseType.h>
#include <Guid/SmmStoreInfoGuid.h>
#define SMMSTORE_COMBUF_SIZE 16
/**
Get the SmmStore block size
@param BlockSize The pointer to store the block size in.
**/
EFI_STATUS
SmmStoreLibGetBlockSize (
OUT UINTN *BlockSize
);
/**
Get the SmmStore number of blocks
@param NumBlocks The pointer to store the number of blocks in.
**/
EFI_STATUS
SmmStoreLibGetNumBlocks (
OUT UINTN *NumBlocks
);
/**
Get the SmmStore MMIO address
@param MmioAddress The pointer to store the address in.
**/
EFI_STATUS
SmmStoreLibGetMmioAddress (
OUT EFI_PHYSICAL_ADDRESS *MmioAddress
);
/**
Read from SmmStore
@param[in] Lba The starting logical block index to read from.
@param[in] Offset Offset into the block at which to begin reading.
@param[in] NumBytes On input, indicates the requested read size. On
output, indicates the actual number of bytes read
@param[in] Buffer Pointer to the buffer to read into.
**/
EFI_STATUS
SmmStoreLibRead (
IN EFI_LBA Lba,
IN UINTN Offset,
IN UINTN *NumBytes,
IN UINT8 *Buffer
);
/**
Write to SmmStore
@param[in] Lba The starting logical block index to write to.
@param[in] Offset Offset into the block at which to begin writing.
@param[in] NumBytes On input, indicates the requested write size. On
output, indicates the actual number of bytes written
@param[in] Buffer Pointer to the data to write.
**/
EFI_STATUS
SmmStoreLibWrite (
IN EFI_LBA Lba,
IN UINTN Offset,
IN UINTN *NumBytes,
IN UINT8 *Buffer
);
/**
Erase a block using the SmmStore
@param Lba The logical block index to erase.
**/
EFI_STATUS
SmmStoreLibEraseBlock (
IN EFI_LBA Lba
);
/**
Initializes SmmStore support
@retval EFI_WRITE_PROTECTED The SmmStore is not present.
@retval EFI_UNSUPPORTED The SmmStoreInfo HOB wasn't found.
@retval EFI_SUCCESS The SmmStore is supported.
**/
EFI_STATUS
SmmStoreLibInitialize (
VOID
);
/**
Denitializes SmmStore support
**/
VOID
EFIAPI
SmmStoreLibDeinitialize (
VOID
);
#endif /* SMM_STORE_LIB_H_ */

View File

@ -0,0 +1,29 @@
/** @file
This library will parse the coreboot table in memory and extract those required
information.
Copyright (c) 2021, Star Labs Systems. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#ifndef SMM_STORE_PARSE_LIB_H_
#define SMM_STORE_PARSE_LIB_H_
#include <Guid/SmmStoreInfoGuid.h>
/**
Find the SmmStore HOB.
@param SmmStoreInfo Pointer to the SMMSTORE_INFO structure
@retval RETURN_SUCCESS Successfully find the Smm store buffer information.
@retval RETURN_NOT_FOUND Failed to find the Smm store buffer information .
**/
RETURN_STATUS
EFIAPI
ParseSmmStoreInfo (
OUT SMMSTORE_INFO *SmmStoreInfo
);
#endif // SMM_STORE_PARSE_LIB_H_

View File

@ -14,6 +14,7 @@
#include <Library/PcdLib.h>
#include <Library/IoLib.h>
#include <Library/BlParseLib.h>
#include <Library/SmmStoreParseLib.h>
#include <IndustryStandard/Acpi.h>
#include <Coreboot.h>
@ -604,3 +605,45 @@ ParseMiscInfo (
{
return RETURN_SUCCESS;
}
/**
Find the SmmStore HOB.
@param SmmStoreInfo Pointer to the SMMSTORE_INFO structure
@retval RETURN_SUCCESS Successfully find the Smm store buffer information.
@retval RETURN_NOT_FOUND Failed to find the Smm store buffer information .
**/
RETURN_STATUS
EFIAPI
ParseSmmStoreInfo (
OUT SMMSTORE_INFO *SmmStoreInfo
)
{
struct cb_smmstorev2 *CbSSRec;
if (SmmStoreInfo == NULL) {
return RETURN_INVALID_PARAMETER;
}
CbSSRec = FindCbTag (CB_TAG_SMMSTOREV2);
if (CbSSRec == NULL) {
return RETURN_NOT_FOUND;
}
DEBUG ((DEBUG_INFO, "Found Smm Store information\n"));
DEBUG ((DEBUG_INFO, "block size: 0x%x\n", CbSSRec->block_size));
DEBUG ((DEBUG_INFO, "number of blocks: 0x%x\n", CbSSRec->num_blocks));
DEBUG ((DEBUG_INFO, "communication buffer: 0x%x\n", CbSSRec->com_buffer));
DEBUG ((DEBUG_INFO, "communication buffer size: 0x%x\n", CbSSRec->com_buffer_size));
DEBUG ((DEBUG_INFO, "MMIO address of store: 0x%x\n", CbSSRec->mmap_addr));
SmmStoreInfo->ComBuffer = CbSSRec->com_buffer;
SmmStoreInfo->ComBufferSize = CbSSRec->com_buffer_size;
SmmStoreInfo->BlockSize = CbSSRec->block_size;
SmmStoreInfo->NumBlocks = CbSSRec->num_blocks;
SmmStoreInfo->MmioAddress = CbSSRec->mmap_addr;
SmmStoreInfo->ApmCmd = CbSSRec->apm_cmd;
return RETURN_SUCCESS;
}

View File

@ -252,29 +252,32 @@ PlatformBootManagerAfterConsole (
Black.Blue = Black.Green = Black.Red = Black.Reserved = 0;
White.Blue = White.Green = White.Red = White.Reserved = 0xFF;
gST->ConOut->ClearScreen (gST->ConOut);
BootLogoEnableLogo ();
// FIXME: USB devices are not being detected unless we wait a bit.
gBS->Stall (100 * 1000);
EfiBootManagerConnectAll ();
EfiBootManagerRefreshAllBootOption ();
//
// Register UEFI Shell
//
PlatformRegisterFvBootOption (PcdGetPtr (PcdShellFile), L"UEFI Shell", LOAD_OPTION_ACTIVE);
//PlatformRegisterFvBootOption (PcdGetPtr (PcdShellFile), L"UEFI Shell", LOAD_OPTION_ACTIVE);
if (FixedPcdGetBool (PcdBootManagerEscape)) {
Print (
L"\n"
L"Esc or Down to enter Boot Manager Menu.\n"
L"ENTER to boot directly.\n"
L"\n"
// Show prompt at bottom center
BootLogoUpdateProgress (
White,
Black,
L"Press ESC for Boot Options/Settings, or SPACE for Pop!_OS Recovery",
White,
0,
0
);
} else {
Print (
L"\n"
L"F2 or Down to enter Boot Manager Menu.\n"
L"ENTER to boot directly.\n"
L"\n"
);
}
// Inject boot logo into BGRT table
AddBGRT();
}
/**
@ -308,11 +311,57 @@ PlatformBootManagerUnableToBoot (
VOID
)
{
EFI_STATUS Status;
EFI_INPUT_KEY Key;
EFI_BOOT_MANAGER_LOAD_OPTION BootManagerMenu;
UINTN Index;
if (mUniversalPayloadPlatformBootManagerOverrideInstance != NULL) {
mUniversalPayloadPlatformBootManagerOverrideInstance->UnableToBoot ();
return;
}
return;
//
// 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

@ -14,6 +14,7 @@
#include <Library/IoLib.h>
#include <Library/HobLib.h>
#include <Library/BlParseLib.h>
#include <Library/SmmStoreParseLib.h>
#include <IndustryStandard/Acpi.h>
#include <UniversalPayload/PciRootBridges.h>
@ -289,3 +290,20 @@ ParseMiscInfo (
return Status;
}
/**
Find the SmmStore HOB.
@param SmmStoreInfo Pointer to the SMMSTORE_INFO structure
@retval RETURN_SUCCESS Successfully find the Smm store buffer information.
@retval RETURN_NOT_FOUND Failed to find the Smm store buffer information .
**/
RETURN_STATUS
EFIAPI
ParseSmmStoreInfo (
OUT SMMSTORE_INFO *SmmStoreInfo
)
{
return RETURN_NOT_FOUND;
}

View File

@ -0,0 +1,473 @@
/** @file SmmStore.c
Copyright (c) 2022, 9elements GmbH<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include <PiDxe.h>
#include <Library/DebugLib.h>
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DxeServicesTableLib.h>
#include <Library/HobLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/UefiRuntimeLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/SmmStoreLib.h>
#include "SmmStore.h"
/*
* A memory buffer to place arguments in.
*/
STATIC SMM_STORE_COM_BUF *mArgComBuf;
STATIC EFI_PHYSICAL_ADDRESS mArgComBufPhys;
/*
* Metadata provided by the first stage bootloader.
*/
STATIC SMMSTORE_INFO *mSmmStoreInfo;
STATIC EFI_EVENT mSmmStoreLibVirtualAddrChangeEvent;
/**
Calls into SMM to use the SMMSTOREv2 implementation for persistent storage.
@param Cmd The command to write into the APM port. This allows to enter the
Smi special command handler.
@param SubCmd The subcommand to execute in the Smi handler.
@param Arg Optional argument to pass to the Smi handler. Typically a pointer
in 'flat' memory mode, which points to read only memory.
@retval EFI_NO_RESPONSE The SmmStore is not present or didn't response.
@retval EFI_UNSUPPORTED The request isn't suppored.
@retval EFI_DEVICE_ERROR An error occured while executing the request.
@retval EFI_SUCCESS The operation was executed successfully.
**/
STATIC
EFI_STATUS
CallSmm (
UINT8 Cmd,
UINT8 SubCmd,
UINTN Arg
)
{
CONST UINTN Rax = ((SubCmd << 8) | Cmd);
CONST UINTN Rbx = Arg;
UINTN Result;
Result = TriggerSmi (Rax, Rbx, 5);
if (Result == Rax) {
return EFI_NO_RESPONSE;
} else if (Result == SMMSTORE_RET_SUCCESS) {
return EFI_SUCCESS;
} else if (Result == SMMSTORE_RET_UNSUPPORTED) {
return EFI_UNSUPPORTED;
}
return EFI_DEVICE_ERROR;
}
/**
Get the SmmStore block size
@param BlockSize The pointer to store the block size in.
**/
EFI_STATUS
SmmStoreLibGetBlockSize (
OUT UINTN *BlockSize
)
{
if (mSmmStoreInfo == NULL) {
return EFI_NO_MEDIA;
}
if (BlockSize == NULL) {
return EFI_INVALID_PARAMETER;
}
*BlockSize = mSmmStoreInfo->BlockSize;
return EFI_SUCCESS;
}
/**
Get the SmmStore number of blocks
@param NumBlocks The pointer to store the number of blocks in.
**/
EFI_STATUS
SmmStoreLibGetNumBlocks (
OUT UINTN *NumBlocks
)
{
if (mSmmStoreInfo == NULL) {
return EFI_NO_MEDIA;
}
if (NumBlocks == NULL) {
return EFI_INVALID_PARAMETER;
}
*NumBlocks = mSmmStoreInfo->NumBlocks;
return EFI_SUCCESS;
}
/**
Get the SmmStore MMIO address
@param MmioAddress The pointer to store the address in.
**/
EFI_STATUS
SmmStoreLibGetMmioAddress (
OUT EFI_PHYSICAL_ADDRESS *MmioAddress
)
{
if (mSmmStoreInfo == NULL) {
return EFI_NO_MEDIA;
}
if (MmioAddress == NULL) {
return EFI_INVALID_PARAMETER;
}
*MmioAddress = mSmmStoreInfo->MmioAddress;
return EFI_SUCCESS;
}
/**
Read from SmmStore
@param[in] Lba The starting logical block index to read from.
@param[in] Offset Offset into the block at which to begin reading.
@param[in] NumBytes On input, indicates the requested read size. On
output, indicates the actual number of bytes read
@param[in] Buffer Pointer to the buffer to read into.
**/
EFI_STATUS
SmmStoreLibRead (
IN EFI_LBA Lba,
IN UINTN Offset,
IN UINTN *NumBytes,
IN UINT8 *Buffer
)
{
EFI_STATUS Status;
if (mSmmStoreInfo == NULL) {
return EFI_NO_MEDIA;
}
if (Lba >= mSmmStoreInfo->NumBlocks) {
return EFI_INVALID_PARAMETER;
}
if (((*NumBytes + Offset) > mSmmStoreInfo->BlockSize) ||
((*NumBytes + Offset) > mSmmStoreInfo->ComBufferSize))
{
return EFI_INVALID_PARAMETER;
}
mArgComBuf->Read.BufSize = *NumBytes;
mArgComBuf->Read.BufOffset = Offset;
mArgComBuf->Read.BlockId = Lba;
Status = CallSmm (mSmmStoreInfo->ApmCmd, SMMSTORE_CMD_RAW_READ, mArgComBufPhys);
if (EFI_ERROR (Status)) {
return Status;
}
CopyMem (Buffer, (VOID *)(UINTN)(mSmmStoreInfo->ComBuffer + Offset), *NumBytes);
return EFI_SUCCESS;
}
/**
Write to SmmStore
@param[in] Lba The starting logical block index to write to.
@param[in] Offset Offset into the block at which to begin writing.
@param[in] NumBytes On input, indicates the requested write size. On
output, indicates the actual number of bytes written
@param[in] Buffer Pointer to the data to write.
**/
EFI_STATUS
SmmStoreLibWrite (
IN EFI_LBA Lba,
IN UINTN Offset,
IN UINTN *NumBytes,
IN UINT8 *Buffer
)
{
if (mSmmStoreInfo == NULL) {
return EFI_NO_MEDIA;
}
if (Lba >= mSmmStoreInfo->NumBlocks) {
return EFI_INVALID_PARAMETER;
}
if (((*NumBytes + Offset) > mSmmStoreInfo->BlockSize) ||
((*NumBytes + Offset) > mSmmStoreInfo->ComBufferSize))
{
return EFI_INVALID_PARAMETER;
}
mArgComBuf->Write.BufSize = *NumBytes;
mArgComBuf->Write.BufOffset = Offset;
mArgComBuf->Write.BlockId = Lba;
CopyMem ((VOID *)(UINTN)(mSmmStoreInfo->ComBuffer + Offset), Buffer, *NumBytes);
return CallSmm (mSmmStoreInfo->ApmCmd, SMMSTORE_CMD_RAW_WRITE, mArgComBufPhys);
}
/**
Erase a SmmStore block
@param Lba The logical block index to erase.
**/
EFI_STATUS
SmmStoreLibEraseBlock (
IN EFI_LBA Lba
)
{
if (mSmmStoreInfo == NULL) {
return EFI_NO_MEDIA;
}
if (Lba >= mSmmStoreInfo->NumBlocks) {
return EFI_INVALID_PARAMETER;
}
mArgComBuf->Clear.BlockId = Lba;
return CallSmm (mSmmStoreInfo->ApmCmd, SMMSTORE_CMD_RAW_CLEAR, mArgComBufPhys);
}
/**
Fixup internal data so that EFI can be call in virtual mode.
Call the passed in Child Notify event and convert any pointers in
lib to virtual mode.
@param[in] Event The Event that is being processed
@param[in] Context Event Context
**/
STATIC
VOID
EFIAPI
SmmStoreLibVirtualNotifyEvent (
IN EFI_EVENT Event,
IN VOID *Context
)
{
EfiConvertPointer (0x0, (VOID **)&mArgComBuf);
if (mSmmStoreInfo != NULL) {
EfiConvertPointer (0x0, (VOID **)&mSmmStoreInfo->ComBuffer);
EfiConvertPointer (0x0, (VOID **)&mSmmStoreInfo);
}
return;
}
/**
Initializes SmmStore support
@retval EFI_WRITE_PROTECTED The SmmStore is not present.
@retval EFI_OUT_OF_RESOURCES Run out of memory.
@retval EFI_SUCCESS The SmmStore is supported.
**/
EFI_STATUS
SmmStoreLibInitialize (
VOID
)
{
EFI_STATUS Status;
VOID *GuidHob;
EFI_GCD_MEMORY_SPACE_DESCRIPTOR GcdDescriptor;
//
// Find the SmmStore information guid hob
//
GuidHob = GetFirstGuidHob (&gEfiSmmStoreInfoHobGuid);
if (GuidHob == NULL) {
DEBUG ((DEBUG_WARN, "SmmStore not supported! Skipping driver init.\n"));
return EFI_UNSUPPORTED;
}
//
// Place SmmStore information hob in a runtime buffer
//
mSmmStoreInfo = AllocateRuntimePool (GET_GUID_HOB_DATA_SIZE (GuidHob));
if (mSmmStoreInfo == NULL) {
return EFI_OUT_OF_RESOURCES;
}
CopyMem (mSmmStoreInfo, GET_GUID_HOB_DATA (GuidHob), GET_GUID_HOB_DATA_SIZE (GuidHob));
//
// Validate input
//
if ((mSmmStoreInfo->MmioAddress == 0) ||
(mSmmStoreInfo->ComBuffer == 0) ||
(mSmmStoreInfo->BlockSize == 0) ||
(mSmmStoreInfo->NumBlocks == 0))
{
DEBUG ((DEBUG_ERROR, "%a: Invalid data in SmmStore Info hob\n", __FUNCTION__));
FreePool (mSmmStoreInfo);
mSmmStoreInfo = NULL;
return EFI_WRITE_PROTECTED;
}
//
// Allocate Communication Buffer for arguments to pass to SMM.
// The argument com buffer is only read by SMM, but never written.
// The FVB data send/retrieved will be placed in a separate bootloader
// pre-allocated memory region, the ComBuffer.
//
if (mSmmStoreInfo->ComBuffer < BASE_4GB) {
//
// Assume that SMM handler is running in 32-bit mode when ComBuffer is
// is placed below BASE_4GB.
//
mArgComBufPhys = BASE_4GB - 1;
} else {
mArgComBufPhys = BASE_8EB - 1;
}
Status = gBS->AllocatePages (
AllocateMaxAddress,
EfiRuntimeServicesData,
EFI_SIZE_TO_PAGES (sizeof (SMM_STORE_COM_BUF)),
&mArgComBufPhys
);
if (EFI_ERROR (Status)) {
FreePool (mSmmStoreInfo);
mSmmStoreInfo = NULL;
return EFI_OUT_OF_RESOURCES;
}
mArgComBuf = (VOID *)mArgComBufPhys;
//
// Register for the virtual address change event
//
Status = gBS->CreateEventEx (
EVT_NOTIFY_SIGNAL,
TPL_NOTIFY,
SmmStoreLibVirtualNotifyEvent,
NULL,
&gEfiEventVirtualAddressChangeGuid,
&mSmmStoreLibVirtualAddrChangeEvent
);
ASSERT_EFI_ERROR (Status);
//
// Finally mark the SMM communication buffer provided by CB or SBL as runtime memory
//
Status = gDS->GetMemorySpaceDescriptor (mSmmStoreInfo->ComBuffer, &GcdDescriptor);
if (EFI_ERROR (Status) || (GcdDescriptor.GcdMemoryType != EfiGcdMemoryTypeReserved)) {
DEBUG (
(
DEBUG_INFO,
"%a: No memory space descriptor for com buffer found\n",
__FUNCTION__
)
);
//
// Add a new entry if not covered by existing mapping
//
Status = gDS->AddMemorySpace (
EfiGcdMemoryTypeReserved,
mSmmStoreInfo->ComBuffer,
mSmmStoreInfo->ComBufferSize,
EFI_MEMORY_WB | EFI_MEMORY_RUNTIME
);
ASSERT_EFI_ERROR (Status);
}
//
// Mark as runtime service
//
Status = gDS->SetMemorySpaceAttributes (
mSmmStoreInfo->ComBuffer,
mSmmStoreInfo->ComBufferSize,
EFI_MEMORY_RUNTIME
);
ASSERT_EFI_ERROR (Status);
//
// Mark the memory mapped store as MMIO memory
//
Status = gDS->GetMemorySpaceDescriptor (mSmmStoreInfo->MmioAddress, &GcdDescriptor);
if (EFI_ERROR (Status) || (GcdDescriptor.GcdMemoryType != EfiGcdMemoryTypeMemoryMappedIo)) {
DEBUG (
(
DEBUG_INFO,
"%a: No memory space descriptor for com buffer found\n",
__FUNCTION__
)
);
//
// Add a new entry if not covered by existing mapping
//
Status = gDS->AddMemorySpace (
EfiGcdMemoryTypeMemoryMappedIo,
mSmmStoreInfo->MmioAddress,
mSmmStoreInfo->NumBlocks * mSmmStoreInfo->BlockSize,
EFI_MEMORY_UC | EFI_MEMORY_RUNTIME
);
ASSERT_EFI_ERROR (Status);
}
//
// Mark as runtime service
//
Status = gDS->SetMemorySpaceAttributes (
mSmmStoreInfo->MmioAddress,
mSmmStoreInfo->NumBlocks * mSmmStoreInfo->BlockSize,
EFI_MEMORY_RUNTIME
);
ASSERT_EFI_ERROR (Status);
return EFI_SUCCESS;
}
/**
Denitializes SmmStore support by freeing allocated memory and unregistering
the virtual address change event.
**/
VOID
EFIAPI
SmmStoreLibDeinitialize (
VOID
)
{
if (mArgComBuf != NULL) {
gBS->FreePages (mArgComBufPhys, EFI_SIZE_TO_PAGES (sizeof (SMM_STORE_COM_BUF)));
mArgComBuf = NULL;
}
if (mSmmStoreInfo != NULL) {
FreePool (mSmmStoreInfo);
mSmmStoreInfo = NULL;
}
if (mSmmStoreLibVirtualAddrChangeEvent != NULL) {
gBS->CloseEvent (mSmmStoreLibVirtualAddrChangeEvent);
mSmmStoreLibVirtualAddrChangeEvent = NULL;
}
}

View File

@ -0,0 +1,81 @@
/** @file SmmStore.h
Copyright (c) 2022, 9elements GmbH<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#ifndef COREBOOT_SMMSTORE_H_
#define COREBOOT_SMMSTORE_H_
#define SMMSTORE_RET_SUCCESS 0
#define SMMSTORE_RET_FAILURE 1
#define SMMSTORE_RET_UNSUPPORTED 2
/* Version 2 only */
#define SMMSTORE_CMD_INIT 4
#define SMMSTORE_CMD_RAW_READ 5
#define SMMSTORE_CMD_RAW_WRITE 6
#define SMMSTORE_CMD_RAW_CLEAR 7
/*
* This allows the payload to store raw data in the flash regions.
* This can be used by a FaultTolerantWrite implementation, that uses at least
* two regions in an A/B update scheme.
*/
#pragma pack(1)
/*
* Reads a chunk of raw data with size BufSize from the block specified by
* block_id starting at BufOffset.
* The read data is placed in buf.
*
* block_id must be less than num_blocks
* BufOffset + BufSize must be less than block_size
*/
typedef struct {
UINT32 BufSize;
UINT32 BufOffset;
UINT32 BlockId;
} SMM_STORE_PARAMS_WRITE;
/*
* Writes a chunk of raw data with size BufSize to the block specified by
* block_id starting at BufOffset.
*
* block_id must be less than num_blocks
* BufOffset + BufSize must be less than block_size
*/
typedef struct {
UINT32 BufSize;
UINT32 BufOffset;
UINT32 BlockId;
} SMM_STORE_PARAMS_READ;
/*
* Erases the specified block.
*
* block_id must be less than num_blocks
*/
typedef struct {
UINT32 BlockId;
} SMM_STORE_PARAMS_CLEAR;
typedef union {
SMM_STORE_PARAMS_WRITE Write;
SMM_STORE_PARAMS_READ Read;
SMM_STORE_PARAMS_CLEAR Clear;
} SMM_STORE_COM_BUF;
#pragma pack(0)
UINTN
EFIAPI
TriggerSmi (
IN UINTN Cmd,
IN UINTN Arg,
IN UINTN Retry
);
#endif // COREBOOT_SMMSTORE_H_

View File

@ -0,0 +1,41 @@
## @file
# SmmStore library for coreboot
#
# Copyright (c) 2022 9elements GmbH.<BR>
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
##
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = SmmStoreLib
FILE_GUID = 40A2CBC6-CFB8-447b-A90E-298E88FD345E
MODULE_TYPE = DXE_DRIVER
VERSION_STRING = 1.0
LIBRARY_CLASS = SmmStoreLib
[Sources]
SmmStore.c
SmmStore.h
[Sources.X64]
X64/SmmStore.nasm
[LibraryClasses]
BaseMemoryLib
DebugLib
DxeServicesTableLib
HobLib
MemoryAllocationLib
UefiBootServicesTableLib
UefiRuntimeLib
[Guids]
gEfiSmmStoreInfoHobGuid ## CONSUMES
gEfiEventVirtualAddressChangeGuid ## CONSUMES
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
UefiPayloadPkg/UefiPayloadPkg.dec

View File

@ -0,0 +1,48 @@
;------------------------------------------------------------------------------ ;
; Copyright (c) 2022, 9elements GmbH. All rights reserved.<BR>
; SPDX-License-Identifier: BSD-2-Clause-Patent
;
;-------------------------------------------------------------------------------
%include "Nasm.inc"
DEFAULT REL
SECTION .text
;UINTN
;EFIAPI
;TriggerSmi (
; UINTN Cmd,
; UINTN Arg,
; UINTN Retry
; )
global ASM_PFX(TriggerSmi)
ASM_PFX(TriggerSmi):
push rbx
mov rax, rcx ; Smi handler expect Cmd in RAX
mov rbx, rdx ; Smi handler expect Argument in RBX
@Trigger:
out 0b2h, al ; write to APM port to trigger SMI
; There might ba a delay between writing the Smi trigger register and
; entering SMM, in which case the Smi handler will do nothing as only
; synchronous Smis are handled. In addition when there's no Smi handler
; or the SmmStore feature isn't compiled in, no register will be modified.
; As there's no livesign from SMM, just wait a bit for the handler to fire,
; and then try again.
cmp rax, rcx ; Check if rax was modified by SMM
jne @Return ; SMM modified rax, return now
push rcx ; save rcx to stack
mov rcx, 10000
rep pause ; add a small delay
pop rcx ; restore rcx
cmp r8, 0
je @Return
dec r8
jmp @Trigger
@Return:
pop rbx
ret

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,563 @@
/** @file
Implementation to provide Option ROMs on platforms having
a PCI resource allocator that includes the read-only Option ROM
BAR into the parent PCI bridge MMIO window.
Copyright (c) 2022 9elements GmbH
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include "PciPlatformDxe.h"
#include <Bus/Pci/PciBusDxe/PciBus.h>
#include <Bus/Pci/PciBusDxe/PciOptionRomSupport.h>
#define PCI_IO_DEVICE_ROM_BAR_INDEX(x) \
(IS_PCI_BRIDGE (&(PCI_IO_DEVICE_FROM_PCI_IO_THIS (x))->Pci) ? \
PCI_BRIDGE_ROMBAR: PCI_EXPANSION_ROM_BASE)
/**
The notification from the PCI bus enumerator to the platform that it is
about to enter a certain phase during the enumeration process.
The PlatformNotify() function can be used to notify the platform driver so that
it can perform platform-specific actions. No specific actions are required.
Eight notification points are defined at this time. More synchronization points
may be added as required in the future. The PCI bus driver calls the platform driver
twice for every Phase-once before the PCI Host Bridge Resource Allocation Protocol
driver is notified, and once after the PCI Host Bridge Resource Allocation Protocol
driver has been notified.
This member function may not perform any error checking on the input parameters. It
also does not return any error codes. If this member function detects any error condition,
it needs to handle those errors on its own because there is no way to surface any
errors to the caller.
@param[in] This The pointer to the EFI_PCI_PLATFORM_PROTOCOL instance.
@param[in] HostBridge The handle of the host bridge controller.
@param[in] Phase The phase of the PCI bus enumeration.
@param[in] ExecPhase Defines the execution phase of the PCI chipset driver.
@retval EFI_SUCCESS The function completed successfully.
**/
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;
}
/**
The notification from the PCI bus enumerator to the platform for each PCI
controller at several predefined points during PCI controller initialization.
The PlatformPrepController() function can be used to notify the platform driver so that
it can perform platform-specific actions. No specific actions are required.
Several notification points are defined at this time. More synchronization points may be
added as required in the future. The PCI bus driver calls the platform driver twice for
every PCI controller-once before the PCI Host Bridge Resource Allocation Protocol driver
is notified, and once after the PCI Host Bridge Resource Allocation Protocol driver has
been notified.
This member function may not perform any error checking on the input parameters. It also
does not return any error codes. If this member function detects any error condition, it
needs to handle those errors on its own because there is no way to surface any errors to
the caller.
@param[in] This The pointer to the EFI_PCI_PLATFORM_PROTOCOL instance.
@param[in] HostBridge The associated PCI host bridge handle.
@param[in] RootBridge The associated PCI root bridge handle.
@param[in] PciAddress The address of the PCI device on the PCI bus.
@param[in] Phase The phase of the PCI controller enumeration.
@param[in] ExecPhase Defines the execution phase of the PCI chipset driver.
@retval EFI_SUCCESS The function completed successfully.
**/
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;
}
/**
Returns the size of the ROM BAR.
@param[in] PciIo A pointer to the EFI_PCI_IO_PROTOCOL instance.
@param[out] RomSize The variable to write the ROM BAR size to.
@param[out] Address The variable to write the ROM BAR MIO address to.
@retval EFI_SUCCESS The function completed successfully.
@retval EFI_INVALID_PARAMETER A NULL pointer was provided.
**/
STATIC
EFI_STATUS
EFIAPI
PciGetROMBar (
IN EFI_PCI_IO_PROTOCOL *PciIo,
OUT UINTN *RomSize,
OUT UINT32 *Address
)
{
UINT32 RomBarIndex;
UINT32 Buffer;
UINT32 AllOnes;
EFI_STATUS Status;
if ((PciIo == NULL) || (RomSize == NULL) || (Address == NULL)) {
return EFI_INVALID_PARAMETER;
}
RomBarIndex = PCI_IO_DEVICE_ROM_BAR_INDEX (PciIo);
//
// Backup BAR
//
Status = PciIo->Pci.Read (
PciIo,
EfiPciWidthUint32,
RomBarIndex,
1,
&Buffer
);
if (EFI_ERROR (Status)) {
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)) {
return Status;
}
//
// Read back
//
Status = PciIo->Pci.Read (
PciIo,
EfiPciWidthUint32,
RomBarIndex,
1,
&AllOnes
);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Bits [1, 10] are reserved
//
AllOnes &= 0xFFFFF800;
if (AllOnes == 0xFFFFF800) {
AllOnes = 0;
}
//
// Restore BAR
//
Status = PciIo->Pci.Write (
PciIo,
EfiPciWidthUint32,
RomBarIndex,
1,
&Buffer
);
if (EFI_ERROR (Status)) {
return Status;
}
*RomSize = AllOnes;
*Address = Buffer& 0xFFFFF800;
return EFI_SUCCESS;
}
/**
Toggles the MMIO decoding of the ROM BAR. It assumes that
- the PCI device ROM BAR is valid
- the PCI device ROM BAR is covered by the parent PCI bridge MMIO aperture
and thus it can safely be enabled.
@param[in] PciIo A pointer to the EFI_PCI_IO_PROTOCOL instance.
@param[in] Enable Enable/disable ROM decode.
@retval EFI_SUCCESS The function completed successfully.
@retval EFI_INVALID_PARAMETER A NULL pointer was provided.
**/
EFI_STATUS
EFIAPI
PciROMDecode (
IN EFI_PCI_IO_PROTOCOL *PciIo,
IN BOOLEAN Enable
)
{
UINT32 RomBarIndex;
UINT32 Buffer;
EFI_STATUS Status;
if (PciIo == NULL) {
return EFI_INVALID_PARAMETER;
}
RomBarIndex = PCI_IO_DEVICE_ROM_BAR_INDEX (PciIo);
//
// Read BAR
//
Status = PciIo->Pci.Read (
PciIo,
EfiPciWidthUint32,
RomBarIndex,
1,
&Buffer
);
if (EFI_ERROR (Status)) {
return Status;
}
if (Enable) {
Buffer |= 1;
} else {
Buffer &= 0xFFFFFFFE;
}
//
// Write BAR
//
Status = PciIo->Pci.Write (
PciIo,
EfiPciWidthUint32,
RomBarIndex,
1,
&Buffer
);
return Status;
}
/**
Gets the PCI device's option ROM from a platform-specific location.
The GetPciRom() function gets the PCI device's option ROM from a platform-specific location.
The option ROM will be loaded into memory. This member function is used to return an image
that is packaged as a PCI 2.2 option ROM. The image may contain both legacy and EFI option
ROMs. See the UEFI 2.0 Specification for details. This member function can be used to return
option ROM images for embedded controllers. Option ROMs for embedded controllers are typically
stored in platform-specific storage, and this member function can retrieve it from that storage
and return it to the PCI bus driver. The PCI bus driver will call this member function before
scanning the ROM that is attached to any controller, which allows a platform to specify a ROM
image that is different from the ROM image on a PCI card.
@param[in] This The pointer to the EFI_PCI_PLATFORM_PROTOCOL instance.
@param[in] PciHandle The handle of the PCI device.
@param[out] RomImage If the call succeeds, the pointer to the pointer to the option ROM image.
Otherwise, this field is undefined. The memory for RomImage is allocated
by EFI_PCI_PLATFORM_PROTOCOL.GetPciRom() using the EFI Boot Service AllocatePool().
It is the caller's responsibility to free the memory using the EFI Boot Service
FreePool(), when the caller is done with the option ROM.
@param[out] RomSize If the call succeeds, a pointer to the size of the option ROM size. Otherwise,
this field is undefined.
@retval EFI_SUCCESS The option ROM was available for this device and loaded into memory.
@retval EFI_NOT_FOUND No option ROM was available for this device.
@retval EFI_OUT_OF_RESOURCES No memory was available to load the option ROM.
@retval EFI_DEVICE_ERROR An error occurred in obtaining the option ROM.
**/
EFI_STATUS
EFIAPI
PciGetPciRom (
IN CONST EFI_PCI_PLATFORM_PROTOCOL *This,
IN EFI_HANDLE PciHandle,
OUT VOID **RomImage,
OUT UINTN *RomSize
)
{
EFI_STATUS Status;
EFI_PCI_IO_PROTOCOL *PciIo;
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 CodeType;
if ((This == NULL) || (RomImage == NULL) || (RomSize == NULL)) {
return EFI_INVALID_PARAMETER;
}
*RomImage = NULL;
*RomSize = 0;
Status = gBS->HandleProtocol (
PciHandle,
&gEfiPciIoProtocolGuid,
(VOID **)&PciIo
);
if (EFI_ERROR (Status)) {
DEBUG ((
DEBUG_ERROR,
"%a: Failed to open gEfiPciIoProtocolGuid: %r\n",
__FUNCTION__,
Status
));
return Status;
}
PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (PciIo);
Status = PciGetROMBar (PciIo, RomSize, &RomBar);
if (EFI_ERROR (Status)) {
goto CloseAndReturn;
}
if (*RomSize == 0) {
DEBUG ((DEBUG_INFO, "%a: No Option ROM found\n", __FUNCTION__));
Status = EFI_NOT_FOUND;
goto CloseAndReturn;
}
Status = PciROMDecode (PciIo, TRUE);
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;
}
RomBarOffset = RomBar;
FirstCheck = TRUE;
LegacyImageLength = 0;
RomImageSize = 0;
CodeType = 0xFF;
do {
PciIoDevice->PciRootBridgeIo->Mem.Read (
PciIoDevice->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;
}
PciIoDevice->PciRootBridgeIo->Mem.Read (
PciIoDevice->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);
}
//
// Free allocated memory
//
FreePool (RomHeader);
FreePool (RomPcir);
if (RomImageSize > 0) {
Status = EFI_SUCCESS;
*RomImage = AllocatePool ((UINT32)RomImageSize);
if (*RomImage == NULL) {
Status = EFI_OUT_OF_RESOURCES;
} else {
//
// Copy Rom image into memory
//
PciIoDevice->PciRootBridgeIo->Mem.Read (
PciIoDevice->PciRootBridgeIo,
EfiPciWidthUint32,
RomBar,
(UINT32)RomImageSize/sizeof (UINT32),
*RomImage
);
*RomSize = RomImageSize;
DEBUG ((
DEBUG_INFO,
"%a: Found Option ROM at 0x%x, length 0x%x\n",
__FUNCTION__,
RomBar,
RomImageSize
));
}
} else {
Status = EFI_NOT_FOUND;
}
CloseAndReturn:
PciROMDecode (PciIo, FALSE);
//
// Close the I/O Abstraction(s) used to perform the supported test
//
gBS->CloseProtocol (
PciHandle,
&gEfiPciIoProtocolGuid,
PciIo,
PciHandle
);
return Status;
}
/**
Retrieves the platform policy regarding enumeration.
The GetPlatformPolicy() function retrieves the platform policy regarding PCI
enumeration. The PCI bus driver and the PCI Host Bridge Resource Allocation Protocol
driver can call this member function to retrieve the policy.
@param[in] This The pointer to the EFI_PCI_PLATFORM_PROTOCOL instance.
@param[out] PciPolicy The platform policy with respect to VGA and ISA aliasing.
@retval EFI_SUCCESS The function completed successfully.
@retval EFI_INVALID_PARAMETER PciPolicy is NULL.
**/
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.
@param ImageHandle The firmware allocated handle for the EFI image.
@param SystemTable A pointer to the EFI System Table.
@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 (
&ImageHandle,
&gEfiPciPlatformProtocolGuid,
EFI_NATIVE_INTERFACE,
&mPciPlatformProtocol
);
return Status;
}

View File

@ -0,0 +1,20 @@
/** @file
Header file for a PCI platform driver.
Copyright (c) 2022 9elements GmbH
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) 2022, 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,410 @@
/** @file
Enroll default PK, KEK, DB and DBX
Copyright (C) 2014, Red Hat, Inc.
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.
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 <Guid/AuthenticatedVariableFormat.h>
#include <Guid/GlobalVariable.h>
#include <Guid/ImageAuthentication.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/UefiRuntimeServicesTableLib.h>
#include <Library/DxeServicesLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiLib.h>
#include <Library/SecureBootVariableProvisionLib.h>
#include <Library/SecureBootVariableLib.h>
STATIC
EFI_STATUS
EFIAPI
GetExact (
IN CHAR16 *VariableName,
IN EFI_GUID *VendorGuid,
OUT VOID *Data,
IN UINTN DataSize,
IN BOOLEAN AllowMissing
)
{
UINTN Size;
EFI_STATUS Status;
Size = DataSize;
Status = gRT->GetVariable (VariableName, VendorGuid, NULL, &Size, Data);
if (EFI_ERROR (Status)) {
if ((Status == EFI_NOT_FOUND) && AllowMissing) {
ZeroMem (Data, DataSize);
return EFI_SUCCESS;
}
DEBUG ((
EFI_D_ERROR,
"SecureBootSetup: GetVariable(\"%s\", %g): %r\n",
VariableName,
VendorGuid,
Status
));
return Status;
}
if (Size != DataSize) {
DEBUG ((
EFI_D_INFO,
"SecureBootSetup: GetVariable(\"%s\", %g): expected size 0x%Lx, "
"got 0x%Lx\n",
VariableName,
VendorGuid,
(UINT64)DataSize,
(UINT64)Size
));
return EFI_PROTOCOL_ERROR;
}
return EFI_SUCCESS;
}
typedef struct {
UINT8 SetupMode;
UINT8 SecureBoot;
UINT8 SecureBootEnable;
UINT8 CustomMode;
UINT8 VendorKeys;
} SETTINGS;
STATIC
EFI_STATUS
EFIAPI
GetSettings (
OUT SETTINGS *Settings,
BOOLEAN AllowMissing
)
{
EFI_STATUS Status;
ZeroMem (Settings, sizeof (SETTINGS));
Status = GetExact (
EFI_SETUP_MODE_NAME,
&gEfiGlobalVariableGuid,
&Settings->SetupMode,
sizeof Settings->SetupMode,
AllowMissing
);
if (EFI_ERROR (Status)) {
return Status;
}
Status = GetExact (
EFI_SECURE_BOOT_MODE_NAME,
&gEfiGlobalVariableGuid,
&Settings->SecureBoot,
sizeof Settings->SecureBoot,
AllowMissing
);
if (EFI_ERROR (Status)) {
return Status;
}
Status = GetExact (
EFI_SECURE_BOOT_ENABLE_NAME,
&gEfiSecureBootEnableDisableGuid,
&Settings->SecureBootEnable,
sizeof Settings->SecureBootEnable,
AllowMissing
);
if (EFI_ERROR (Status)) {
return Status;
}
Status = GetExact (
EFI_CUSTOM_MODE_NAME,
&gEfiCustomModeEnableGuid,
&Settings->CustomMode,
sizeof Settings->CustomMode,
AllowMissing
);
if (EFI_ERROR (Status)) {
return Status;
}
Status = GetExact (
EFI_VENDOR_KEYS_VARIABLE_NAME,
&gEfiGlobalVariableGuid,
&Settings->VendorKeys,
sizeof Settings->VendorKeys,
AllowMissing
);
return Status;
}
STATIC
VOID
EFIAPI
PrintSettings (
IN CONST SETTINGS *Settings
)
{
DEBUG ((
EFI_D_INFO,
"SecureBootSetup: SetupMode=%d SecureBoot=%d SecureBootEnable=%d "
"CustomMode=%d VendorKeys=%d\n",
Settings->SetupMode,
Settings->SecureBoot,
Settings->SecureBootEnable,
Settings->CustomMode,
Settings->VendorKeys
));
}
/**
Install SecureBoot certificates once the VariableDriver is running.
@param[in] Event Event whose notification function is being invoked
@param[in] Context Pointer to the notification function's context
**/
VOID
EFIAPI
InstallSecureBootHook (
IN EFI_EVENT Event,
IN VOID *Context
)
{
EFI_STATUS Status;
VOID *Protocol;
SETTINGS Settings;
Status = gBS->LocateProtocol (&gEfiVariableWriteArchProtocolGuid, NULL, (VOID **)&Protocol);
if (EFI_ERROR (Status)) {
return;
}
Status = GetSettings (&Settings, TRUE);
if (EFI_ERROR (Status)) {
DEBUG ((EFI_D_ERROR, "SecureBootSetup: Failed to get current settings\n"));
return;
}
if (Settings.SetupMode != SETUP_MODE) {
DEBUG ((EFI_D_ERROR, "SecureBootSetup: already in User Mode\n"));
return;
}
if (Settings.SecureBootEnable != SECURE_BOOT_MODE_ENABLE) {
DEBUG ((EFI_D_ERROR, "SecureBootSetup: SecureBootEnable is disabled.\n"));
return;
}
PrintSettings (&Settings);
if (Settings.CustomMode != CUSTOM_SECURE_BOOT_MODE) {
Settings.CustomMode = CUSTOM_SECURE_BOOT_MODE;
Status = gRT->SetVariable (
EFI_CUSTOM_MODE_NAME,
&gEfiCustomModeEnableGuid,
(EFI_VARIABLE_NON_VOLATILE |
EFI_VARIABLE_BOOTSERVICE_ACCESS),
sizeof Settings.CustomMode,
&Settings.CustomMode
);
if (EFI_ERROR (Status)) {
DEBUG ((
EFI_D_ERROR,
"SecureBootSetup: SetVariable(\"%s\", %g): %r\n",
EFI_CUSTOM_MODE_NAME,
&gEfiCustomModeEnableGuid,
Status
));
ASSERT_EFI_ERROR (Status);
}
}
// Enroll all the keys from default variables
Status = EnrollDbFromDefault ();
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "Cannot enroll db: %r\n", Status));
goto error;
}
Status = EnrollDbxFromDefault ();
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "Cannot enroll dbx: %r\n", Status));
}
Status = EnrollDbtFromDefault ();
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "Cannot enroll dbt: %r\n", Status));
}
Status = EnrollKEKFromDefault ();
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "Cannot enroll KEK: %r\n", Status));
goto cleardbs;
}
Status = EnrollPKFromDefault ();
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "Cannot enroll PK: %r\n", Status));
goto clearKEK;
}
Status = SetSecureBootMode (STANDARD_SECURE_BOOT_MODE);
if (EFI_ERROR (Status)) {
DEBUG ((
DEBUG_ERROR,
"Cannot set CustomMode to STANDARD_SECURE_BOOT_MODE\n"
"Please do it manually, otherwise system can be easily compromised\n"
));
}
// FIXME: Force SecureBoot to ON. The AuthService will do this if authenticated variables
// are supported, which aren't as the SMM handler isn't able to verify them.
Settings.SecureBootEnable = SECURE_BOOT_ENABLE;
Status = gRT->SetVariable (
EFI_SECURE_BOOT_ENABLE_NAME,
&gEfiSecureBootEnableDisableGuid,
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
sizeof Settings.SecureBootEnable,
&Settings.SecureBootEnable
);
if (EFI_ERROR (Status)) {
DEBUG ((
EFI_D_ERROR,
"SecureBootSetup: SetVariable(\"%s\", %g): %r\n",
EFI_SECURE_BOOT_ENABLE_NAME,
&gEfiSecureBootEnableDisableGuid,
Status
));
ASSERT_EFI_ERROR (Status);
}
Settings.SecureBoot = SECURE_BOOT_ENABLE;
Status = gRT->SetVariable (
EFI_SECURE_BOOT_MODE_NAME,
&gEfiGlobalVariableGuid,
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
sizeof Settings.SecureBoot,
&Settings.SecureBoot
);
if (EFI_ERROR (Status)) {
DEBUG ((
EFI_D_ERROR,
"SecureBootSetup: SetVariable(\"%s\", %g): %r\n",
EFI_SECURE_BOOT_MODE_NAME,
&gEfiGlobalVariableGuid,
Status
));
ASSERT_EFI_ERROR (Status);
}
Status = GetSettings (&Settings, FALSE);
ASSERT_EFI_ERROR (Status);
//
// Final sanity check:
//
// [SetupMode]
// (read-only, standardized by UEFI)
// / \_
// 0 1, default
// / \_
// PK enrolled no PK enrolled yet,
// (this is called "User Mode") PK enrollment possible
// |
// |
// [SecureBootEnable]
// (read-write, edk2-specific, boot service only)
// / \_
// 0 1, default
// / \_
// [SecureBoot]=0 [SecureBoot]=1
// (read-only, standardized by UEFI) (read-only, standardized by UEFI)
// images are not verified images are verified, platform is
// operating in Secure Boot mode
// |
// |
// [CustomMode]
// (read-write, edk2-specific, boot service only)
// / \_
// 0, default 1
// / \_
// PK, KEK, db, dbx PK, KEK, db, dbx
// updates are verified updates are not verified
//
PrintSettings (&Settings);
if ((Settings.SetupMode != 0) || (Settings.SecureBoot != 1) ||
(Settings.SecureBootEnable != 1) || (Settings.CustomMode != 0) ||
(Settings.VendorKeys != 0))
{
DEBUG ((EFI_D_ERROR, "SecureBootSetup: disabled\n"));
return;
}
DEBUG ((EFI_D_INFO, "SecureBootSetup: SecureBoot enabled\n"));
return;
clearKEK:
DeleteKEK ();
cleardbs:
DeleteDbt ();
DeleteDbx ();
DeleteDb ();
error:
if (SetSecureBootMode (STANDARD_SECURE_BOOT_MODE) != EFI_SUCCESS) {
DEBUG ((DEBUG_ERROR, "Cannot set mode to Secure: %r\n", Status));
}
DEBUG ((EFI_D_ERROR, "SecureBootSetup: disabled\n"));
}
EFI_STATUS
EFIAPI
DriverEntry (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EFI_STATUS Status;
VOID *TcgProtocol;
VOID *Registration;
Status = gBS->LocateProtocol (&gEfiTcgProtocolGuid, NULL, (VOID **)&TcgProtocol);
if (!EFI_ERROR (Status)) {
DEBUG ((
EFI_D_ERROR,
"SecureBootSetup: Started too late."
"TPM is already running!\n"
));
return EFI_DEVICE_ERROR;
}
//
// Create event callback, because we need access variable on SecureBootPolicyVariable
// We should use VariableWriteArch instead of VariableArch, because Variable driver
// may update SecureBoot value based on last setting.
//
EfiCreateProtocolNotifyEvent (
&gEfiVariableWriteArchProtocolGuid,
TPL_CALLBACK,
InstallSecureBootHook,
NULL,
&Registration
);
return EFI_SUCCESS;
}

View File

@ -0,0 +1,56 @@
## @file
# This file handels SecureBoot setup.
#
# Copyright (c) 2013 - 2019, Intel Corporation. All rights reserved.<BR>
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
#
##
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = SecureBootSetup
MODULE_UNI_FILE = SecureBootSetup.uni
FILE_GUID = 14693BD4-D114-4177-979E-37F279BAD620
MODULE_TYPE = DXE_DRIVER
VERSION_STRING = 0.1
ENTRY_POINT = DriverEntry
#
# VALID_ARCHITECTURES = IA32 X64
#
[Sources]
SecureBootSetup.c
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
SecurityPkg/SecurityPkg.dec
[Guids]
gEfiCertPkcs7Guid
gEfiCertX509Guid
gEfiCustomModeEnableGuid
gEfiGlobalVariableGuid
gEfiImageSecurityDatabaseGuid
gEfiSecureBootEnableDisableGuid
[LibraryClasses]
BaseMemoryLib
DebugLib
MemoryAllocationLib
UefiRuntimeServicesTableLib
UefiDriverEntryPoint
DxeServicesLib
UefiBootServicesTableLib
SecureBootVariableProvisionLib
SecureBootVariableLib
[Protocols]
gEfiTcgProtocolGuid ## CONSUMES
gEfiVariableWriteArchProtocolGuid ## CONSUMES
[Depex]
TRUE

View File

@ -0,0 +1,21 @@
// /** @file
// Provides authenticated variable service for IPF platform
//
// This module installs variable arch protocol and variable write arch protocol to provide
// four EFI_RUNTIME_SERVICES: SetVariable, GetVariable, GetNextVariableName and QueryVariableInfo.
//
// Copyright (c) 2009 - 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 "Provides authenticated variable service for IPF platform"
#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,17 @@
// /** @file
// EsalVariableDxeSal Localized Strings and Content
//
// Copyright (c) 2013 - 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_PROPERTIES_MODULE_NAME
#language en-US
"9elements Secure Boot DXE"

View File

@ -0,0 +1,282 @@
/** @file SmmStoreFvbRuntime.c
Copyright (c) 2022, 9elements GmbH<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include <Library/UefiLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/DxeServicesTableLib.h>
#include <Library/DevicePathLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/PcdLib.h>
#include <Library/SmmStoreLib.h>
#include "SmmStoreFvbRuntime.h"
STATIC EFI_EVENT mSmmStoreVirtualAddrChangeEvent;
//
// Global variable declarations
//
SMMSTORE_INSTANCE *mSmmStoreInstance;
SMMSTORE_INSTANCE mSmmStoreInstanceTemplate = {
SMMSTORE_SIGNATURE, // Signature
NULL, // Handle ... NEED TO BE FILLED
{
FvbGetAttributes, // GetAttributes
FvbSetAttributes, // SetAttributes
FvbGetPhysicalAddress, // GetPhysicalAddress
FvbGetBlockSize, // GetBlockSize
FvbRead, // Read
FvbWrite, // Write
FvbEraseBlocks, // EraseBlocks
NULL, // ParentHandle
}, // FvbProtoccol
0, // BlockSize ... NEED TO BE FILLED
0, // LastBlock ... NEED TO BE FILLED
0, // MmioAddress ... NEED TO BE FILLED
{
{
{
HARDWARE_DEVICE_PATH,
HW_MEMMAP_DP,
{
(UINT8)(sizeof (MEMMAP_DEVICE_PATH)),
(UINT8)(sizeof (MEMMAP_DEVICE_PATH) >> 8)
}
},
EfiMemoryMappedIO,
(EFI_PHYSICAL_ADDRESS)0, // NEED TO BE FILLED
(EFI_PHYSICAL_ADDRESS)0, // NEED TO BE FILLED
},
{
END_DEVICE_PATH_TYPE,
END_ENTIRE_DEVICE_PATH_SUBTYPE,
{
END_DEVICE_PATH_LENGTH,
0
}
}
} // DevicePath
};
/**
Initialize the SmmStore instance.
@param[in] FvBase The physical MMIO base address of the FV containing
the variable store.
@param[in] NumberofBlocks Number of blocks within the FV.
@param[in] BlockSize The size in bytes of one block within the FV.
@param[in, out] Instance The SmmStore instace to initialize
**/
STATIC
EFI_STATUS
SmmStoreInitInstance (
IN EFI_PHYSICAL_ADDRESS FvBase,
IN UINTN NumberofBlocks,
IN UINTN BlockSize,
IN OUT SMMSTORE_INSTANCE *Instance
)
{
EFI_STATUS Status;
FV_MEMMAP_DEVICE_PATH *FvDevicePath;
ASSERT (Instance != NULL);
Instance->BlockSize = BlockSize;
Instance->LastBlock = NumberofBlocks - 1;
Instance->MmioAddress = FvBase;
FvDevicePath = &Instance->DevicePath;
FvDevicePath->MemMapDevPath.StartingAddress = FvBase;
FvDevicePath->MemMapDevPath.EndingAddress = FvBase + BlockSize * NumberofBlocks - 1;
Status = FvbInitialize (Instance);
if (EFI_ERROR (Status)) {
return Status;
}
Status = gBS->InstallMultipleProtocolInterfaces (
&Instance->Handle,
&gEfiDevicePathProtocolGuid,
&Instance->DevicePath,
&gEfiFirmwareVolumeBlockProtocolGuid,
&Instance->FvbProtocol,
NULL
);
if (EFI_ERROR (Status)) {
return Status;
}
DEBUG ((DEBUG_INFO, "%a: Created a new instance\n", __FUNCTION__));
return Status;
}
/**
Fixup internal data so that EFI can be call in virtual mode.
Call the passed in Child Notify event and convert any pointers in
lib to virtual mode.
@param[in] Event The Event that is being processed
@param[in] Context Event Context
**/
STATIC
VOID
EFIAPI
SmmStoreVirtualNotifyEvent (
IN EFI_EVENT Event,
IN VOID *Context
)
{
// Convert Fvb
EfiConvertPointer (0x0, (VOID **)&mSmmStoreInstance->FvbProtocol.EraseBlocks);
EfiConvertPointer (0x0, (VOID **)&mSmmStoreInstance->FvbProtocol.GetAttributes);
EfiConvertPointer (0x0, (VOID **)&mSmmStoreInstance->FvbProtocol.GetBlockSize);
EfiConvertPointer (0x0, (VOID **)&mSmmStoreInstance->FvbProtocol.GetPhysicalAddress);
EfiConvertPointer (0x0, (VOID **)&mSmmStoreInstance->FvbProtocol.Read);
EfiConvertPointer (0x0, (VOID **)&mSmmStoreInstance->FvbProtocol.SetAttributes);
EfiConvertPointer (0x0, (VOID **)&mSmmStoreInstance->FvbProtocol.Write);
EfiConvertPointer (0x0, (VOID **)&mSmmStoreInstance->MmioAddress);
EfiConvertPointer (0x0, (VOID **)&mSmmStoreInstance);
return;
}
/**
The user Entry Point for module SmmStoreFvbRuntimeDxe. The user code starts with this function.
@param[in] ImageHandle The firmware allocated handle for the EFI image.
@param[in] SystemTable A pointer to the EFI System Table.
@retval EFI_SUCCESS The entry point is executed successfully.
@retval other Some error occurs when executing this entry point.
**/
EFI_STATUS
EFIAPI
SmmStoreInitialize (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EFI_STATUS Status;
EFI_PHYSICAL_ADDRESS MmioAddress;
UINTN BlockSize;
UINTN BlockCount;
UINT32 NvStorageBase;
UINT32 NvStorageSize;
UINT32 NvVariableSize;
UINT32 FtwWorkingSize;
UINT32 FtwSpareSize;
Status = SmmStoreLibInitialize ();
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "%a: Failed to initialize SmmStoreLib\n", __FUNCTION__));
return Status;
}
Status = SmmStoreLibGetMmioAddress (&MmioAddress);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "%a: Failed to get SmmStore MMIO address\n", __FUNCTION__));
SmmStoreLibDeinitialize ();
return Status;
}
Status = SmmStoreLibGetNumBlocks (&BlockCount);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "%a: Failed to get SmmStore No. blocks\n", __FUNCTION__));
SmmStoreLibDeinitialize ();
return Status;
}
Status = SmmStoreLibGetBlockSize (&BlockSize);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "%a: Failed to get SmmStore block size\n", __FUNCTION__));
SmmStoreLibDeinitialize ();
return Status;
}
NvStorageSize = BlockCount * BlockSize;
NvStorageBase = MmioAddress;
FtwSpareSize = (BlockCount / 2) * BlockSize;
FtwWorkingSize = BlockSize;
NvVariableSize = NvStorageSize - FtwSpareSize - FtwWorkingSize;
DEBUG ((DEBUG_INFO, "NvStorageBase:0x%x, NvStorageSize:0x%x\n", NvStorageBase, NvStorageSize));
if (NvVariableSize >= 0x80000000) {
SmmStoreLibDeinitialize ();
return EFI_INVALID_PARAMETER;
}
Status = PcdSet32S (PcdFlashNvStorageVariableSize, NvVariableSize);
ASSERT_EFI_ERROR (Status);
Status = PcdSet32S (PcdFlashNvStorageVariableBase, NvStorageBase);
ASSERT_EFI_ERROR (Status);
Status = PcdSet64S (PcdFlashNvStorageVariableBase64, NvStorageBase);
ASSERT_EFI_ERROR (Status);
Status = PcdSet32S (PcdFlashNvStorageFtwWorkingSize, FtwWorkingSize);
ASSERT_EFI_ERROR (Status);
Status = PcdSet32S (PcdFlashNvStorageFtwWorkingBase, NvStorageBase + NvVariableSize);
ASSERT_EFI_ERROR (Status);
Status = PcdSet64S (PcdFlashNvStorageFtwWorkingBase64, NvStorageBase + NvVariableSize);
ASSERT_EFI_ERROR (Status);
Status = PcdSet32S (PcdFlashNvStorageFtwSpareSize, FtwSpareSize);
ASSERT_EFI_ERROR (Status);
Status = PcdSet32S (PcdFlashNvStorageFtwSpareBase, NvStorageBase + NvVariableSize + FtwWorkingSize);
ASSERT_EFI_ERROR (Status);
Status = PcdSet64S (PcdFlashNvStorageFtwSpareBase64, NvStorageBase + NvVariableSize + FtwWorkingSize);
ASSERT_EFI_ERROR (Status);
mSmmStoreInstance = AllocateRuntimeCopyPool (sizeof (SMMSTORE_INSTANCE), &mSmmStoreInstanceTemplate);
if (mSmmStoreInstance == NULL) {
SmmStoreLibDeinitialize ();
DEBUG ((DEBUG_ERROR, "%a: Out of resources\n", __FUNCTION__));
return EFI_OUT_OF_RESOURCES;
}
Status = SmmStoreInitInstance (
MmioAddress,
BlockCount,
BlockSize,
mSmmStoreInstance
);
if (EFI_ERROR (Status)) {
DEBUG (
(
DEBUG_ERROR,
"%a: Fail to create instance for SmmStore\n",
__FUNCTION__
)
);
FreePool (mSmmStoreInstance);
SmmStoreLibDeinitialize ();
return Status;
}
//
// Register for the virtual address change event
//
Status = gBS->CreateEventEx (
EVT_NOTIFY_SIGNAL,
TPL_NOTIFY,
SmmStoreVirtualNotifyEvent,
NULL,
&gEfiEventVirtualAddressChangeGuid,
&mSmmStoreVirtualAddrChangeEvent
);
ASSERT_EFI_ERROR (Status);
return Status;
}

View File

@ -0,0 +1,111 @@
/** @file SmmStoreFvbRuntime.h
Copyright (c) 2022, 9elements GmbH<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#ifndef SMM_STORE_DXE_H_
#define SMM_STORE_DXE_H_
#include <Base.h>
#include <PiDxe.h>
#include <Guid/EventGroup.h>
#include <Protocol/FirmwareVolumeBlock.h>
#include <Library/DebugLib.h>
#include <Library/IoLib.h>
#include <Library/UefiLib.h>
#include <Library/UefiRuntimeLib.h>
#define SMMSTORE_SIGNATURE SIGNATURE_32('S', 'M', 'M', 'S')
#define INSTANCE_FROM_FVB_THIS(a) CR(a, SMMSTORE_INSTANCE, FvbProtocol, SMMSTORE_SIGNATURE)
typedef struct _SMMSTORE_INSTANCE SMMSTORE_INSTANCE;
typedef struct {
MEMMAP_DEVICE_PATH MemMapDevPath;
EFI_DEVICE_PATH_PROTOCOL EndDevPath;
} FV_MEMMAP_DEVICE_PATH;
struct _SMMSTORE_INSTANCE {
UINT32 Signature;
EFI_HANDLE Handle;
EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL FvbProtocol;
UINTN BlockSize;
UINTN LastBlock;
EFI_PHYSICAL_ADDRESS MmioAddress;
FV_MEMMAP_DEVICE_PATH DevicePath;
};
//
// SmmStoreFvbRuntimeDxe.c
//
EFI_STATUS
EFIAPI
FvbInitialize (
IN SMMSTORE_INSTANCE *Instance
);
EFI_STATUS
EFIAPI
FvbGetAttributes (
IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,
OUT EFI_FVB_ATTRIBUTES_2 *Attributes
);
EFI_STATUS
EFIAPI
FvbSetAttributes (
IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,
IN OUT EFI_FVB_ATTRIBUTES_2 *Attributes
);
EFI_STATUS
EFIAPI
FvbGetPhysicalAddress (
IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,
OUT EFI_PHYSICAL_ADDRESS *Address
);
EFI_STATUS
EFIAPI
FvbGetBlockSize (
IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,
IN EFI_LBA Lba,
OUT UINTN *BlockSize,
OUT UINTN *NumberOfBlocks
);
EFI_STATUS
EFIAPI
FvbRead (
IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,
IN EFI_LBA Lba,
IN UINTN Offset,
IN OUT UINTN *NumBytes,
IN OUT UINT8 *Buffer
);
EFI_STATUS
EFIAPI
FvbWrite (
IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,
IN EFI_LBA Lba,
IN UINTN Offset,
IN OUT UINTN *NumBytes,
IN UINT8 *Buffer
);
EFI_STATUS
EFIAPI
FvbEraseBlocks (
IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,
...
);
#endif // SMM_STORE_DXE_H_

View File

@ -0,0 +1,849 @@
/** @file SmmStoreFvbRuntimeDxe.c
Copyright (c) 2022, 9elements GmbH<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include <PiDxe.h>
#include <Library/PcdLib.h>
#include <Library/BaseLib.h>
#include <Library/HobLib.h>
#include <Library/UefiLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/DxeServicesTableLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/SmmStoreLib.h>
#include <Guid/VariableFormat.h>
#include <Guid/SystemNvDataGuid.h>
#include <Guid/NvVarStoreFormatted.h>
#include "SmmStoreFvbRuntime.h"
///
/// The Firmware Volume Block Protocol is the low-level interface
/// to a firmware volume. File-level access to a firmware volume
/// should not be done using the Firmware Volume Block Protocol.
/// Normal access to a firmware volume must use the Firmware
/// Volume Protocol. Typically, only the file system driver that
/// produces the Firmware Volume Protocol will bind to the
/// Firmware Volume Block Protocol.
///
/**
Initialises the FV Header and Variable Store Header
to support variable operations.
@param[in] Instance - Pointer to SmmStore instance
**/
EFI_STATUS
InitializeFvAndVariableStoreHeaders (
IN SMMSTORE_INSTANCE *Instance
)
{
EFI_STATUS Status;
VOID *Headers;
UINTN HeadersLength;
EFI_FIRMWARE_VOLUME_HEADER *FirmwareVolumeHeader;
VARIABLE_STORE_HEADER *VariableStoreHeader;
UINT32 NvStorageFtwSpareSize;
UINT32 NvStorageFtwWorkingSize;
UINT32 NvStorageVariableSize;
UINT64 NvStorageFtwSpareBase;
UINT64 NvStorageFtwWorkingBase;
UINT64 NvStorageVariableBase;
HeadersLength = sizeof (EFI_FIRMWARE_VOLUME_HEADER) + sizeof (EFI_FV_BLOCK_MAP_ENTRY) + sizeof (VARIABLE_STORE_HEADER);
Headers = AllocateZeroPool (HeadersLength);
NvStorageFtwWorkingSize = PcdGet32 (PcdFlashNvStorageFtwWorkingSize);
NvStorageFtwSpareSize = PcdGet32 (PcdFlashNvStorageFtwSpareSize);
NvStorageVariableSize = PcdGet32 (PcdFlashNvStorageVariableSize);
NvStorageFtwSpareBase = (PcdGet64 (PcdFlashNvStorageFtwSpareBase64) != 0) ?
PcdGet64 (PcdFlashNvStorageFtwSpareBase64) : PcdGet32 (PcdFlashNvStorageFtwSpareBase);
NvStorageFtwWorkingBase = (PcdGet64 (PcdFlashNvStorageFtwWorkingBase64) != 0) ?
PcdGet64 (PcdFlashNvStorageFtwWorkingBase64) : PcdGet32 (PcdFlashNvStorageFtwWorkingBase);
NvStorageVariableBase = (PcdGet64 (PcdFlashNvStorageVariableBase64) != 0) ?
PcdGet64 (PcdFlashNvStorageVariableBase64) : PcdGet32 (PcdFlashNvStorageVariableBase);
// FirmwareVolumeHeader->FvLength is declared to have the Variable area AND the FTW working area AND the FTW Spare contiguous.
if ((NvStorageVariableBase + NvStorageVariableSize) != NvStorageFtwWorkingBase) {
DEBUG ((
DEBUG_ERROR,
"%a: NvStorageFtwWorkingBase is not contiguous with NvStorageVariableBase region\n",
__FUNCTION__
));
return EFI_INVALID_PARAMETER;
}
if ((NvStorageFtwWorkingBase + NvStorageFtwWorkingSize) != NvStorageFtwSpareBase) {
DEBUG ((
DEBUG_ERROR,
"%a: NvStorageFtwSpareBase is not contiguous with NvStorageFtwWorkingBase region\n",
__FUNCTION__
));
return EFI_INVALID_PARAMETER;
}
// Check if the size of the area is at least one block size
if ((NvStorageVariableSize <= 0) || (NvStorageVariableSize / Instance->BlockSize <= 0)) {
DEBUG ((
DEBUG_ERROR,
"%a: NvStorageVariableSize is 0x%x, should be atleast one block size\n",
__FUNCTION__,
NvStorageVariableSize
));
return EFI_INVALID_PARAMETER;
}
if ((NvStorageFtwWorkingSize <= 0) || (NvStorageFtwWorkingSize / Instance->BlockSize <= 0)) {
DEBUG ((
DEBUG_ERROR,
"%a: NvStorageFtwWorkingSize is 0x%x, should be atleast one block size\n",
__FUNCTION__,
NvStorageFtwWorkingSize
));
return EFI_INVALID_PARAMETER;
}
if ((NvStorageFtwSpareSize <= 0) || (NvStorageFtwSpareSize / Instance->BlockSize <= 0)) {
DEBUG ((
DEBUG_ERROR,
"%a: NvStorageFtwSpareSize is 0x%x, should be atleast one block size\n",
__FUNCTION__,
NvStorageFtwSpareSize
));
return EFI_INVALID_PARAMETER;
}
// Ensure the Variable area Base Addresses are aligned on a block size boundaries
if ((NvStorageVariableBase % Instance->BlockSize != 0) ||
(NvStorageFtwWorkingBase % Instance->BlockSize != 0) ||
(NvStorageFtwSpareBase % Instance->BlockSize != 0))
{
DEBUG ((DEBUG_ERROR, "%a: NvStorage Base addresses must be aligned to block size boundaries", __FUNCTION__));
return EFI_INVALID_PARAMETER;
}
//
// EFI_FIRMWARE_VOLUME_HEADER
//
FirmwareVolumeHeader = (EFI_FIRMWARE_VOLUME_HEADER *)Headers;
CopyGuid (&FirmwareVolumeHeader->FileSystemGuid, &gEfiSystemNvDataFvGuid);
FirmwareVolumeHeader->FvLength =
PcdGet32 (PcdFlashNvStorageVariableSize) +
PcdGet32 (PcdFlashNvStorageFtwWorkingSize) +
PcdGet32 (PcdFlashNvStorageFtwSpareSize);
FirmwareVolumeHeader->Signature = EFI_FVH_SIGNATURE;
FirmwareVolumeHeader->Attributes = (EFI_FVB_ATTRIBUTES_2)(
EFI_FVB2_READ_ENABLED_CAP | // Reads may be enabled
EFI_FVB2_READ_STATUS | // Reads are currently enabled
EFI_FVB2_STICKY_WRITE | // A block erase is required to flip bits into EFI_FVB2_ERASE_POLARITY
EFI_FVB2_MEMORY_MAPPED | // It is memory mapped
EFI_FVB2_ERASE_POLARITY | // After erasure all bits take this value (i.e. '1')
EFI_FVB2_WRITE_STATUS | // Writes are currently enabled
EFI_FVB2_WRITE_ENABLED_CAP // Writes may be enabled
);
FirmwareVolumeHeader->HeaderLength = sizeof (EFI_FIRMWARE_VOLUME_HEADER) + sizeof (EFI_FV_BLOCK_MAP_ENTRY);
FirmwareVolumeHeader->Revision = EFI_FVH_REVISION;
FirmwareVolumeHeader->BlockMap[0].NumBlocks = Instance->LastBlock + 1;
FirmwareVolumeHeader->BlockMap[0].Length = Instance->BlockSize;
FirmwareVolumeHeader->BlockMap[1].NumBlocks = 0;
FirmwareVolumeHeader->BlockMap[1].Length = 0;
FirmwareVolumeHeader->Checksum = CalculateCheckSum16 ((UINT16 *)FirmwareVolumeHeader, FirmwareVolumeHeader->HeaderLength);
//
// VARIABLE_STORE_HEADER
//
VariableStoreHeader = (VARIABLE_STORE_HEADER *)((UINTN)Headers + FirmwareVolumeHeader->HeaderLength);
CopyGuid (&VariableStoreHeader->Signature, &gEfiVariableGuid);
VariableStoreHeader->Size = PcdGet32 (PcdFlashNvStorageVariableSize) - FirmwareVolumeHeader->HeaderLength;
VariableStoreHeader->Format = VARIABLE_STORE_FORMATTED;
VariableStoreHeader->State = VARIABLE_STORE_HEALTHY;
// Install the combined super-header in the NorFlash
Status = FvbWrite (&Instance->FvbProtocol, 0, 0, &HeadersLength, Headers);
FreePool (Headers);
return Status;
}
/**
Check the integrity of firmware volume header.
@retval EFI_SUCCESS - The firmware volume is consistent
@retval EFI_NOT_FOUND - The firmware volume has been corrupted.
**/
EFI_STATUS
ValidateFvHeader (
VOID
)
{
UINT16 Checksum;
EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader;
VARIABLE_STORE_HEADER *VariableStoreHeader;
UINTN VariableStoreLength;
UINTN FvLength;
EFI_STATUS TempStatus;
UINTN BufferSize;
UINTN BufferSizeReqested;
BufferSizeReqested = sizeof (EFI_FIRMWARE_VOLUME_HEADER);
FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *)AllocatePool (BufferSizeReqested);
if (!FwVolHeader) {
return EFI_OUT_OF_RESOURCES;
}
BufferSize = BufferSizeReqested;
TempStatus = SmmStoreLibRead (0, 0, &BufferSize, (UINT8 *)FwVolHeader);
if (EFI_ERROR (TempStatus) || (BufferSizeReqested != BufferSize)) {
FreePool (FwVolHeader);
return EFI_DEVICE_ERROR;
}
FvLength = PcdGet32 (PcdFlashNvStorageVariableSize) + PcdGet32 (PcdFlashNvStorageFtwWorkingSize) +
PcdGet32 (PcdFlashNvStorageFtwSpareSize);
//
// Verify the header revision, header signature, length
// Length of FvBlock cannot be 2**64-1
// HeaderLength cannot be an odd number
//
if ( (FwVolHeader->Revision != EFI_FVH_REVISION)
|| (FwVolHeader->Signature != EFI_FVH_SIGNATURE)
|| (FwVolHeader->FvLength != FvLength)
)
{
DEBUG ((
DEBUG_INFO,
"%a: No Firmware Volume header present\n",
__FUNCTION__
));
FreePool (FwVolHeader);
return EFI_NOT_FOUND;
}
// Check the Firmware Volume Guid
if ( CompareGuid (&FwVolHeader->FileSystemGuid, &gEfiSystemNvDataFvGuid) == FALSE ) {
DEBUG ((
DEBUG_INFO,
"%a: Firmware Volume Guid non-compatible\n",
__FUNCTION__
));
FreePool (FwVolHeader);
return EFI_NOT_FOUND;
}
BufferSizeReqested = FwVolHeader->HeaderLength;
FreePool (FwVolHeader);
FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *)AllocatePool (BufferSizeReqested);
if (!FwVolHeader) {
return EFI_OUT_OF_RESOURCES;
}
BufferSize = BufferSizeReqested;
TempStatus = SmmStoreLibRead (0, 0, &BufferSize, (UINT8 *)FwVolHeader);
if (EFI_ERROR (TempStatus) || (BufferSizeReqested != BufferSize)) {
FreePool (FwVolHeader);
return EFI_DEVICE_ERROR;
}
// Verify the header checksum
Checksum = CalculateSum16 ((UINT16 *)FwVolHeader, FwVolHeader->HeaderLength);
if (Checksum != 0) {
DEBUG ((
DEBUG_INFO,
"%a: FV checksum is invalid (Checksum:0x%X)\n",
__FUNCTION__,
Checksum
));
FreePool (FwVolHeader);
return EFI_NOT_FOUND;
}
BufferSizeReqested = sizeof (VARIABLE_STORE_HEADER);
VariableStoreHeader = (VARIABLE_STORE_HEADER *)AllocatePool (BufferSizeReqested);
if (!VariableStoreHeader) {
return EFI_OUT_OF_RESOURCES;
}
BufferSize = BufferSizeReqested;
TempStatus = SmmStoreLibRead (0, FwVolHeader->HeaderLength, &BufferSize, (UINT8 *)VariableStoreHeader);
if (EFI_ERROR (TempStatus) || (BufferSizeReqested != BufferSize)) {
FreePool (VariableStoreHeader);
FreePool (FwVolHeader);
return EFI_DEVICE_ERROR;
}
// Check the Variable Store Guid
if (!CompareGuid (&VariableStoreHeader->Signature, &gEfiVariableGuid) &&
!CompareGuid (&VariableStoreHeader->Signature, &gEfiAuthenticatedVariableGuid))
{
DEBUG ((
DEBUG_INFO,
"%a: Variable Store Guid non-compatible\n",
__FUNCTION__
));
FreePool (FwVolHeader);
FreePool (VariableStoreHeader);
return EFI_NOT_FOUND;
}
VariableStoreLength = PcdGet32 (PcdFlashNvStorageVariableSize) - FwVolHeader->HeaderLength;
if (VariableStoreHeader->Size != VariableStoreLength) {
DEBUG ((
DEBUG_INFO,
"%a: Variable Store Length does not match\n",
__FUNCTION__
));
FreePool (FwVolHeader);
FreePool (VariableStoreHeader);
return EFI_NOT_FOUND;
}
FreePool (FwVolHeader);
FreePool (VariableStoreHeader);
return EFI_SUCCESS;
}
/**
The GetAttributes() function retrieves the attributes and
current settings of the block.
@param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance.
@param Attributes Pointer to EFI_FVB_ATTRIBUTES_2 in which the attributes and
current settings are returned.
Type EFI_FVB_ATTRIBUTES_2 is defined in EFI_FIRMWARE_VOLUME_HEADER.
@retval EFI_SUCCESS The firmware volume attributes were returned.
**/
EFI_STATUS
EFIAPI
FvbGetAttributes (
IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,
OUT EFI_FVB_ATTRIBUTES_2 *Attributes
)
{
EFI_FVB_ATTRIBUTES_2 FlashFvbAttributes;
FlashFvbAttributes = (EFI_FVB_ATTRIBUTES_2)(
EFI_FVB2_READ_STATUS | // Reads are currently enabled
EFI_FVB2_WRITE_STATUS | // Writes are enabled
EFI_FVB2_STICKY_WRITE | // A block erase is required to flip bits into EFI_FVB2_ERASE_POLARITY
EFI_FVB2_MEMORY_MAPPED | // It is memory mapped
EFI_FVB2_ERASE_POLARITY // After erasure all bits take this value (i.e. '1')
);
*Attributes = FlashFvbAttributes;
DEBUG ((DEBUG_BLKIO, "FvbGetAttributes(0x%X)\n", *Attributes));
return EFI_SUCCESS;
}
/**
The SetAttributes() function sets configurable firmware volume attributes
and returns the new settings of the firmware volume.
@param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance.
@param Attributes On input, Attributes is a pointer to EFI_FVB_ATTRIBUTES_2
that contains the desired firmware volume settings.
On successful return, it contains the new settings of
the firmware volume.
Type EFI_FVB_ATTRIBUTES_2 is defined in EFI_FIRMWARE_VOLUME_HEADER.
@retval EFI_SUCCESS The firmware volume attributes were returned.
@retval EFI_INVALID_PARAMETER The attributes requested are in conflict with the capabilities
as declared in the firmware volume header.
**/
EFI_STATUS
EFIAPI
FvbSetAttributes (
IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,
IN OUT EFI_FVB_ATTRIBUTES_2 *Attributes
)
{
DEBUG ((DEBUG_ERROR, "FvbSetAttributes(0x%X) is not supported\n", *Attributes));
return EFI_UNSUPPORTED;
}
/**
The GetPhysicalAddress() function retrieves the base address of
a memory-mapped firmware volume. This function should be called
only for memory-mapped firmware volumes.
@param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance.
@param Address Pointer to a caller-allocated
EFI_PHYSICAL_ADDRESS that, on successful
return from GetPhysicalAddress(), contains the
base address of the firmware volume.
@retval EFI_SUCCESS The firmware volume base address was returned.
@retval EFI_NOT_SUPPORTED The firmware volume is not memory mapped.
**/
EFI_STATUS
EFIAPI
FvbGetPhysicalAddress (
IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,
OUT EFI_PHYSICAL_ADDRESS *Address
)
{
SMMSTORE_INSTANCE *Instance;
Instance = INSTANCE_FROM_FVB_THIS (This);
ASSERT (Address != NULL);
*Address = Instance->MmioAddress;
return EFI_SUCCESS;
}
/**
The GetBlockSize() function retrieves the size of the requested
block. It also returns the number of additional blocks with
the identical size. The GetBlockSize() function is used to
retrieve the block map (see EFI_FIRMWARE_VOLUME_HEADER).
@param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance.
@param Lba Indicates the block for which to return the size.
@param BlockSize Pointer to a caller-allocated UINTN in which
the size of the block is returned.
@param NumberOfBlocks Pointer to a caller-allocated UINTN in
which the number of consecutive blocks,
starting with Lba, is returned. All
blocks in this range have a size of
BlockSize.
@retval EFI_SUCCESS The firmware volume base address was returned.
@retval EFI_INVALID_PARAMETER The requested LBA is out of range.
**/
EFI_STATUS
EFIAPI
FvbGetBlockSize (
IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,
IN EFI_LBA Lba,
OUT UINTN *BlockSize,
OUT UINTN *NumberOfBlocks
)
{
EFI_STATUS Status;
SMMSTORE_INSTANCE *Instance;
Instance = INSTANCE_FROM_FVB_THIS (This);
DEBUG ((DEBUG_BLKIO, "FvbGetBlockSize(Lba=%ld, BlockSize=0x%x, LastBlock=%ld)\n", Lba, Instance->BlockSize, Instance->LastBlock));
if (Lba > Instance->LastBlock) {
DEBUG ((DEBUG_ERROR, "FvbGetBlockSize: ERROR - Parameter LBA %ld is beyond the last Lba (%ld).\n", Lba, Instance->LastBlock));
Status = EFI_INVALID_PARAMETER;
} else {
*BlockSize = (UINTN)Instance->BlockSize;
*NumberOfBlocks = (UINTN)(Instance->LastBlock - Lba + 1);
DEBUG ((DEBUG_BLKIO, "FvbGetBlockSize: *BlockSize=0x%x, *NumberOfBlocks=0x%x.\n", *BlockSize, *NumberOfBlocks));
Status = EFI_SUCCESS;
}
return Status;
}
/**
Reads the specified number of bytes into a buffer from the specified block.
The Read() function reads the requested number of bytes from the
requested block and stores them in the provided buffer.
Implementations should be mindful that the firmware volume
might be in the ReadDisabled state. If it is in this state,
the Read() function must return the status code
EFI_ACCESS_DENIED without modifying the contents of the
buffer. The Read() function must also prevent spanning block
boundaries. If a read is requested that would span a block
boundary, the read must read up to the boundary but not
beyond. The output parameter NumBytes must be set to correctly
indicate the number of bytes actually read. The caller must be
aware that a read may be partially completed.
@param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance.
@param Lba The starting logical block index from which to read.
@param Offset Offset into the block at which to begin reading.
@param NumBytes Pointer to a UINTN.
At entry, *NumBytes contains the total size of the buffer.
At exit, *NumBytes contains the total number of bytes read.
@param Buffer Pointer to a caller-allocated buffer that will be used
to hold the data that is read.
@retval EFI_SUCCESS The firmware volume was read successfully, and contents are
in Buffer.
@retval EFI_BAD_BUFFER_SIZE Read attempted across an LBA boundary.
On output, NumBytes contains the total number of bytes
returned in Buffer.
@retval EFI_ACCESS_DENIED The firmware volume is in the ReadDisabled state.
@retval EFI_DEVICE_ERROR The block device is not functioning correctly and could not be read.
**/
EFI_STATUS
EFIAPI
FvbRead (
IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,
IN EFI_LBA Lba,
IN UINTN Offset,
IN OUT UINTN *NumBytes,
IN OUT UINT8 *Buffer
)
{
UINTN BlockSize;
SMMSTORE_INSTANCE *Instance;
Instance = INSTANCE_FROM_FVB_THIS (This);
DEBUG ((DEBUG_BLKIO, "FvbRead(Parameters: Lba=%ld, Offset=0x%x, *NumBytes=0x%x, Buffer @ 0x%08x)\n", Lba, Offset, *NumBytes, Buffer));
// Cache the block size to avoid de-referencing pointers all the time
BlockSize = Instance->BlockSize;
// The read must not span block boundaries.
// We need to check each variable individually because adding two large values together overflows.
if ((Offset >= BlockSize) ||
(*NumBytes > BlockSize) ||
((Offset + *NumBytes) > BlockSize))
{
DEBUG ((DEBUG_ERROR, "FvbRead: ERROR - EFI_BAD_BUFFER_SIZE: (Offset=0x%x + NumBytes=0x%x) > BlockSize=0x%x\n", Offset, *NumBytes, BlockSize));
return EFI_BAD_BUFFER_SIZE;
}
// We must have some bytes to read
if (*NumBytes == 0) {
return EFI_BAD_BUFFER_SIZE;
}
return SmmStoreLibRead (Lba, Offset, NumBytes, Buffer);
}
/**
Writes the specified number of bytes from the input buffer to the block.
The Write() function writes the specified number of bytes from
the provided buffer to the specified block and offset. If the
firmware volume is sticky write, the caller must ensure that
all the bits of the specified range to write are in the
EFI_FVB_ERASE_POLARITY state before calling the Write()
function, or else the result will be unpredictable. This
unpredictability arises because, for a sticky-write firmware
volume, a write may negate a bit in the EFI_FVB_ERASE_POLARITY
state but cannot flip it back again. Before calling the
Write() function, it is recommended for the caller to first call
the EraseBlocks() function to erase the specified block to
write. A block erase cycle will transition bits from the
(NOT)EFI_FVB_ERASE_POLARITY state back to the
EFI_FVB_ERASE_POLARITY state. Implementations should be
mindful that the firmware volume might be in the WriteDisabled
state. If it is in this state, the Write() function must
return the status code EFI_ACCESS_DENIED without modifying the
contents of the firmware volume. The Write() function must
also prevent spanning block boundaries. If a write is
requested that spans a block boundary, the write must store up
to the boundary but not beyond. The output parameter NumBytes
must be set to correctly indicate the number of bytes actually
written. The caller must be aware that a write may be
partially completed. All writes, partial or otherwise, must be
fully flushed to the hardware before the Write() service
returns.
@param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance.
@param Lba The starting logical block index to write to.
@param Offset Offset into the block at which to begin writing.
@param NumBytes The pointer to a UINTN.
At entry, *NumBytes contains the total size of the buffer.
At exit, *NumBytes contains the total number of bytes actually written.
@param Buffer The pointer to a caller-allocated buffer that contains the source for the write.
@retval EFI_SUCCESS The firmware volume was written successfully.
@retval EFI_BAD_BUFFER_SIZE The write was attempted across an LBA boundary.
On output, NumBytes contains the total number of bytes
actually written.
@retval EFI_ACCESS_DENIED The firmware volume is in the WriteDisabled state.
@retval EFI_DEVICE_ERROR The block device is malfunctioning and could not be written.
**/
EFI_STATUS
EFIAPI
FvbWrite (
IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,
IN EFI_LBA Lba,
IN UINTN Offset,
IN OUT UINTN *NumBytes,
IN UINT8 *Buffer
)
{
UINTN BlockSize;
SMMSTORE_INSTANCE *Instance;
Instance = INSTANCE_FROM_FVB_THIS (This);
DEBUG ((DEBUG_BLKIO, "FvbWrite(Parameters: Lba=%ld, Offset=0x%x, *NumBytes=0x%x, Buffer @ 0x%08x)\n", Lba, Offset, *NumBytes, Buffer));
// Cache the block size to avoid de-referencing pointers all the time
BlockSize = Instance->BlockSize;
// The read must not span block boundaries.
// We need to check each variable individually because adding two large values together overflows.
if ((Offset >= BlockSize) ||
(*NumBytes > BlockSize) ||
((Offset + *NumBytes) > BlockSize))
{
DEBUG ((DEBUG_ERROR, "FvbRead: ERROR - EFI_BAD_BUFFER_SIZE: (Offset=0x%x + NumBytes=0x%x) > BlockSize=0x%x\n", Offset, *NumBytes, BlockSize));
return EFI_BAD_BUFFER_SIZE;
}
// We must have some bytes to read
if (*NumBytes == 0) {
return EFI_BAD_BUFFER_SIZE;
}
return SmmStoreLibWrite (Lba, Offset, NumBytes, Buffer);
}
/**
Erases and initialises a firmware volume block.
The EraseBlocks() function erases one or more blocks as denoted
by the variable argument list. The entire parameter list of
blocks must be verified before erasing any blocks. If a block is
requested that does not exist within the associated firmware
volume (it has a larger index than the last block of the
firmware volume), the EraseBlocks() function must return the
status code EFI_INVALID_PARAMETER without modifying the contents
of the firmware volume. Implementations should be mindful that
the firmware volume might be in the WriteDisabled state. If it
is in this state, the EraseBlocks() function must return the
status code EFI_ACCESS_DENIED without modifying the contents of
the firmware volume. All calls to EraseBlocks() must be fully
flushed to the hardware before the EraseBlocks() service
returns.
@param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL
instance.
@param ... The variable argument list is a list of tuples.
Each tuple describes a range of LBAs to erase
and consists of the following:
- An EFI_LBA that indicates the starting LBA
- A UINTN that indicates the number of blocks to erase.
The list is terminated with an EFI_LBA_LIST_TERMINATOR.
For example, the following indicates that two ranges of blocks
(5-7 and 10-11) are to be erased:
EraseBlocks (This, 5, 3, 10, 2, EFI_LBA_LIST_TERMINATOR);
@retval EFI_SUCCESS The erase request successfully completed.
@retval EFI_ACCESS_DENIED The firmware volume is in the WriteDisabled state.
@retval EFI_DEVICE_ERROR The block device is not functioning correctly and could not be written.
The firmware device may have been partially erased.
@retval EFI_INVALID_PARAMETER One or more of the LBAs listed in the variable argument list do
not exist in the firmware volume.
**/
EFI_STATUS
EFIAPI
FvbEraseBlocks (
IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,
...
)
{
EFI_STATUS Status;
VA_LIST Args;
EFI_LBA StartingLba; // Lba from which we start erasing
UINTN NumOfLba; // Number of Lba blocks to erase
SMMSTORE_INSTANCE *Instance;
Instance = INSTANCE_FROM_FVB_THIS (This);
Status = EFI_SUCCESS;
// Before erasing, check the entire list of parameters to ensure all specified blocks are valid
VA_START (Args, This);
do {
// Get the Lba from which we start erasing
StartingLba = VA_ARG (Args, EFI_LBA);
// Have we reached the end of the list?
if (StartingLba == EFI_LBA_LIST_TERMINATOR) {
// Exit the while loop
break;
}
// How many Lba blocks are we requested to erase?
NumOfLba = VA_ARG (Args, UINTN);
// All blocks must be within range
DEBUG ((
DEBUG_BLKIO,
"FvbEraseBlocks: Check if: ( StartingLba=%ld + NumOfLba=%Lu - 1 ) > LastBlock=%ld.\n",
StartingLba,
(UINT64)NumOfLba,
Instance->LastBlock
));
if ((NumOfLba == 0) || ((StartingLba + NumOfLba - 1) > Instance->LastBlock)) {
VA_END (Args);
DEBUG ((DEBUG_ERROR, "FvbEraseBlocks: ERROR - Lba range goes past the last Lba.\n"));
Status = EFI_INVALID_PARAMETER;
goto EXIT;
}
} while (TRUE);
VA_END (Args);
//
// To get here, all must be ok, so start erasing
//
VA_START (Args, This);
do {
// Get the Lba from which we start erasing
StartingLba = VA_ARG (Args, EFI_LBA);
// Have we reached the end of the list?
if (StartingLba == EFI_LBA_LIST_TERMINATOR) {
// Exit the while loop
break;
}
// How many Lba blocks are we requested to erase?
NumOfLba = VA_ARG (Args, UINTN);
// Go through each one and erase it
while (NumOfLba > 0) {
// Erase it
DEBUG ((DEBUG_BLKIO, "FvbEraseBlocks: Erasing Lba=%ld\n", StartingLba));
Status = SmmStoreLibEraseBlock (StartingLba);
if (EFI_ERROR (Status)) {
VA_END (Args);
Status = EFI_DEVICE_ERROR;
goto EXIT;
}
// Move to the next Lba
StartingLba++;
NumOfLba--;
}
} while (TRUE);
VA_END (Args);
EXIT:
return Status;
}
/**
Initialized the Firmware Volume if necessary and installs the
gEdkiiNvVarStoreFormattedGuid protocol.
@param Instance Pointer to SmmStore instance
**/
EFI_STATUS
EFIAPI
FvbInitialize (
IN SMMSTORE_INSTANCE *Instance
)
{
EFI_STATUS Status;
UINT32 FvbNumLba;
EFI_BOOT_MODE BootMode;
ASSERT ((Instance != NULL));
BootMode = GetBootModeHob ();
if (BootMode == BOOT_WITH_DEFAULT_SETTINGS) {
Status = EFI_INVALID_PARAMETER;
} else {
// Determine if there is a valid header at the beginning of the NorFlash
Status = ValidateFvHeader ();
}
// Install the Default FVB header if required
if (EFI_ERROR (Status)) {
// There is no valid header, so time to install one.
DEBUG ((DEBUG_INFO, "%a: The FVB Header is not valid.\n", __FUNCTION__));
DEBUG ((
DEBUG_INFO,
"%a: Installing a correct one for this volume.\n",
__FUNCTION__
));
// Erase all the NorFlash that is reserved for variable storage
FvbNumLba = (PcdGet32 (PcdFlashNvStorageVariableSize) +
PcdGet32 (PcdFlashNvStorageFtwWorkingSize) +
PcdGet32 (PcdFlashNvStorageFtwSpareSize)) / Instance->BlockSize;
Status = FvbEraseBlocks (&Instance->FvbProtocol, (EFI_LBA)0, FvbNumLba, EFI_LBA_LIST_TERMINATOR);
if (EFI_ERROR (Status)) {
return Status;
}
// Install all appropriate headers
Status = InitializeFvAndVariableStoreHeaders (Instance);
if (EFI_ERROR (Status)) {
return Status;
}
} else {
DEBUG ((DEBUG_INFO, "%a: FVB header is valid\n", __FUNCTION__));
}
//
// The driver implementing the variable read service can now be dispatched;
// the varstore headers are in place.
//
Status = gBS->InstallProtocolInterface (
&gImageHandle,
&gEdkiiNvVarStoreFormattedGuid,
EFI_NATIVE_INTERFACE,
NULL
);
ASSERT_EFI_ERROR (Status);
return Status;
}

View File

@ -0,0 +1,63 @@
## @file
# The component description file for SmmStore module
#
# Copyright (c) 2022, 9elements GmbH.<BR>
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
##
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = SmmStoreFvbRuntimeDxe
FILE_GUID = A0402FCA-6B25-4CEA-B7DD-C08F99714B29
MODULE_TYPE = DXE_RUNTIME_DRIVER
VERSION_STRING = 1.0
ENTRY_POINT = SmmStoreInitialize
[Sources.common]
SmmStoreFvbRuntimeDxe.c
SmmStoreFvbRuntime.h
SmmStoreFvbRuntime.c
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
EmbeddedPkg/EmbeddedPkg.dec
UefiPayloadPkg/UefiPayloadPkg.dec
[LibraryClasses]
BaseLib
DebugLib
HobLib
SmmStoreLib
UefiLib
UefiDriverEntryPoint
UefiBootServicesTableLib
UefiRuntimeLib
DxeServicesTableLib
[Guids]
gEfiSystemNvDataFvGuid
gEfiVariableGuid ## PRODUCES ## PROTOCOL
gEfiAuthenticatedVariableGuid
gEfiEventVirtualAddressChangeGuid
gEdkiiNvVarStoreFormattedGuid ## PRODUCES ## PROTOCOL
[Protocols]
gEfiDevicePathProtocolGuid ## BY_START
gEfiFirmwareVolumeBlockProtocolGuid ## BY_START
[Pcd]
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase64
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase64
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase64
[Depex]
TRUE

View File

@ -259,6 +259,8 @@ BuildHobFromBl (
{
EFI_STATUS Status;
ACPI_BOARD_INFO *AcpiBoardInfo;
SMMSTORE_INFO SmmStoreInfo;
SMMSTORE_INFO *NewSmmStoreInfo;
EFI_PEI_GRAPHICS_INFO_HOB GfxInfo;
EFI_PEI_GRAPHICS_INFO_HOB *NewGfxInfo;
EFI_PEI_GRAPHICS_DEVICE_INFO_HOB GfxDeviceInfo;
@ -305,6 +307,17 @@ BuildHobFromBl (
DEBUG ((DEBUG_INFO, "Created graphics device info hob\n"));
}
//
// Create guid hob for SmmStore
//
Status = ParseSmmStoreInfo (&SmmStoreInfo);
if (!EFI_ERROR (Status)) {
NewSmmStoreInfo = BuildGuidHob (&gEfiSmmStoreInfoHobGuid, sizeof (SmmStoreInfo));
ASSERT (NewSmmStoreInfo != NULL);
CopyMem (NewSmmStoreInfo, &SmmStoreInfo, sizeof (SmmStoreInfo));
DEBUG ((DEBUG_INFO, "Created SmmStore info hob\n"));
}
//
// Creat SmBios table Hob
//

View File

@ -22,6 +22,7 @@
#include <Library/IoLib.h>
#include <Library/PeCoffLib.h>
#include <Library/BlParseLib.h>
#include <Library/SmmStoreParseLib.h>
#include <Library/PlatformSupportLib.h>
#include <Library/CpuLib.h>
#include <Library/UefiCpuLib.h>
@ -37,6 +38,7 @@
#include <UniversalPayload/ExtraData.h>
#include <UniversalPayload/SerialPortInfo.h>
#include <Guid/PcdDataBaseSignatureGuid.h>
#include <Guid/SmmStoreInfoGuid.h>
#define LEGACY_8259_MASK_REGISTER_MASTER 0x21
#define LEGACY_8259_MASK_REGISTER_SLAVE 0xA1

View File

@ -66,6 +66,7 @@
gUniversalPayloadSmbiosTableGuid
gUniversalPayloadAcpiTableGuid
gUniversalPayloadSerialPortInfoGuid
gEfiSmmStoreInfoHobGuid
[FeaturePcd.IA32]
gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSwitchToLongMode ## CONSUMES

View File

@ -43,6 +43,8 @@
gSmmRegisterInfoGuid = { 0xaa9bd7a7, 0xcafb, 0x4499, { 0xa4, 0xa9, 0xb, 0x34, 0x6b, 0x40, 0xa6, 0x22 } }
gS3CommunicationGuid = { 0x88e31ba1, 0x1856, 0x4b8b, { 0xbb, 0xdf, 0xf8, 0x16, 0xdd, 0x94, 0xa, 0xef } }
gEfiSmmStoreInfoHobGuid = { 0xf585ca19, 0x881b, 0x44fb, { 0x3f, 0x3d, 0x81, 0x89, 0x7c, 0x57, 0xbb, 0x01 } }
[Ppis]
gEfiPayLoadHobBasePpiGuid = { 0xdbe23aa1, 0xa342, 0x4b97, {0x85, 0xb6, 0xb2, 0x26, 0xf1, 0x61, 0x73, 0x89} }

View File

@ -37,6 +37,11 @@
DEFINE ABOVE_4G_MEMORY = TRUE
DEFINE BOOT_MANAGER_ESCAPE = FALSE
DEFINE SD_MMC_TIMEOUT = 1000000
#
# Send logs to System76 EC
#
DEFINE SYSTEM76_EC_LOGGING = FALSE
#
# SBL: UEFI payload for Slim Bootloader
# COREBOOT: UEFI payload for coreboot
@ -94,9 +99,15 @@
#
DEFINE SHELL_TYPE = BUILD_SHELL
#
# Security options:
#
DEFINE SECURE_BOOT_ENABLE = FALSE
#
# EMU: UEFI payload with EMU variable
# SPI: UEFI payload with SPI NV variable support
# SMMSTORE: UEFI payload with coreboot SMM NV variable support
# NONE: UEFI payload with no variable modules
#
DEFINE VARIABLE_SUPPORT = EMU
@ -180,6 +191,10 @@
CacheMaintenanceLib|MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.inf
SafeIntLib|MdePkg/Library/BaseSafeIntLib/BaseSafeIntLib.inf
DxeHobListLib|UefiPayloadPkg/Library/DxeHobListLib/DxeHobListLib.inf
!if $(SECURE_BOOT_ENABLE) == TRUE
SecureBootVariableLib|SecurityPkg/Library/SecureBootVariableLib/SecureBootVariableLib.inf
SecureBootVariableProvisionLib|SecurityPkg/Library/SecureBootVariableProvisionLib/SecureBootVariableProvisionLib.inf
!endif
BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
TlsLib|CryptoPkg/Library/TlsLib/TlsLib.inf
IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf
@ -212,6 +227,7 @@
CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf
SecurityManagementLib|MdeModulePkg/Library/DxeSecurityManagementLib/DxeSecurityManagementLib.inf
UefiBootManagerLib|MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf
BootLogoLib|MdeModulePkg/Library/BootLogoLib/BootLogoLib.inf
CustomizedDisplayLib|MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.inf
FrameBufferBltLib|MdeModulePkg/Library/FrameBufferBltLib/FrameBufferBltLib.inf
@ -231,8 +247,13 @@
TimerLib|UefiPayloadPkg/Library/AcpiTimerLib/AcpiTimerLib.inf
!endif
ResetSystemLib|UefiPayloadPkg/Library/ResetSystemLib/ResetSystemLib.inf
!if $(SYSTEM76_EC_LOGGING) == TRUE
SerialPortLib|UefiPayloadPkg/Library/System76EcLib/System76EcLib.inf
PlatformHookLib|UefiPayloadPkg/Library/System76EcLib/System76EcLib.inf
!else
SerialPortLib|MdeModulePkg/Library/BaseSerialPortLib16550/BaseSerialPortLib16550.inf
PlatformHookLib|UefiPayloadPkg/Library/PlatformHookLib/PlatformHookLib.inf
!endif
PlatformBootManagerLib|UefiPayloadPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
IoApicLib|PcAtChipsetPkg/Library/BaseIoApicLib/BaseIoApicLib.inf
@ -260,9 +281,11 @@
DebugLib|MdeModulePkg/Library/PeiDxeDebugLibReportStatusCode/PeiDxeDebugLibReportStatusCode.inf
LockBoxLib|MdeModulePkg/Library/LockBoxNullLib/LockBoxNullLib.inf
FileExplorerLib|MdeModulePkg/Library/FileExplorerLib/FileExplorerLib.inf
AuthVariableLib|MdeModulePkg/Library/AuthVariableLibNull/AuthVariableLibNull.inf
!if $(VARIABLE_SUPPORT) == "EMU"
TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/TpmMeasurementLibNull.inf
!elseif $(VARIABLE_SUPPORT) == "SMMSTORE"
SmmStoreLib|UefiPayloadPkg/Library/SmmStoreLib/SmmStoreLib.inf
TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/TpmMeasurementLibNull.inf
!elseif $(VARIABLE_SUPPORT) == "SPI"
PlatformSecureLib|SecurityPkg/Library/PlatformSecureLibNull/PlatformSecureLibNull.inf
TpmMeasurementLib|SecurityPkg/Library/DxeTpmMeasurementLib/DxeTpmMeasurementLib.inf
@ -276,6 +299,9 @@
VmgExitLib|UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.inf
ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf
[LibraryClasses.common]
BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
[LibraryClasses.common.SEC]
HobLib|UefiPayloadPkg/Library/PayloadEntryHobLib/HobLib.inf
PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
@ -296,6 +322,18 @@
!if $(PERFORMANCE_MEASUREMENT_ENABLE)
PerformanceLib|MdeModulePkg/Library/DxeCorePerformanceLib/DxeCorePerformanceLib.inf
!endif
SmbusLib|MdePkg/Library/DxeSmbusLib/DxeSmbusLib.inf
OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLibCrypto.inf
IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf
RngLib|MdePkg/Library/BaseRngLibTimerLib/BaseRngLibTimerLib.inf
!if $(SECURE_BOOT_ENABLE) == TRUE
AuthVariableLib|SecurityPkg/Library/AuthVariableLib/AuthVariableLib.inf
# re-use the UserPhysicalPresent() dummy implementation from the ovmf tree
PlatformSecureLib|OvmfPkg/Library/PlatformSecureLib/PlatformSecureLib.inf
!else
AuthVariableLib|MdeModulePkg/Library/AuthVariableLibNull/AuthVariableLibNull.inf
!endif
[LibraryClasses.common.DXE_DRIVER]
PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
@ -310,6 +348,17 @@
!if $(PERFORMANCE_MEASUREMENT_ENABLE)
PerformanceLib|MdeModulePkg/Library/DxePerformanceLib/DxePerformanceLib.inf
!endif
OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLibCrypto.inf
IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf
RngLib|MdePkg/Library/BaseRngLibTimerLib/BaseRngLibTimerLib.inf
!if $(SECURE_BOOT_ENABLE) == TRUE
AuthVariableLib|SecurityPkg/Library/AuthVariableLib/AuthVariableLib.inf
# re-use the UserPhysicalPresent() dummy implementation from the ovmf tree
PlatformSecureLib|OvmfPkg/Library/PlatformSecureLib/PlatformSecureLib.inf
!else
AuthVariableLib|MdeModulePkg/Library/AuthVariableLibNull/AuthVariableLibNull.inf
!endif
[LibraryClasses.common.DXE_RUNTIME_DRIVER]
PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
@ -319,6 +368,19 @@
!if $(PERFORMANCE_MEASUREMENT_ENABLE)
PerformanceLib|MdeModulePkg/Library/DxePerformanceLib/DxePerformanceLib.inf
!endif
SmbusLib|MdePkg/Library/DxeSmbusLib/DxeSmbusLib.inf
BaseCryptLib|CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf
OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLibCrypto.inf
IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf
RngLib|MdePkg/Library/BaseRngLibTimerLib/BaseRngLibTimerLib.inf
!if $(SECURE_BOOT_ENABLE) == TRUE
AuthVariableLib|SecurityPkg/Library/AuthVariableLib/AuthVariableLib.inf
# re-use the UserPhysicalPresent() dummy implementation from the ovmf tree
PlatformSecureLib|OvmfPkg/Library/PlatformSecureLib/PlatformSecureLib.inf
!else
AuthVariableLib|MdeModulePkg/Library/AuthVariableLibNull/AuthVariableLibNull.inf
!endif
[LibraryClasses.common.UEFI_DRIVER,LibraryClasses.common.UEFI_APPLICATION]
PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
@ -383,18 +445,17 @@
[PcdsFixedAtBuild]
gEfiMdePkgTokenSpaceGuid.PcdHardwareErrorRecordLevel|1
gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize|0x10000
gEfiMdeModulePkgTokenSpaceGuid.PcdMaxHardwareErrorVariableSize|0x8000
gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize|0x10000
!if $(VARIABLE_SUPPORT) == "EMU"
gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvModeEnable |TRUE
!else
!elseif $(VARIABLE_SUPPORT) == "SPI" || $(VARIABLE_SUPPORT) == "SMMSTORE"
gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvModeEnable |FALSE
!endif
gEfiMdeModulePkgTokenSpaceGuid.PcdVpdBaseAddress|0x0
gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeUseMemory|FALSE
gEfiMdeModulePkgTokenSpaceGuid.PcdUse1GPageTable|TRUE
gEfiMdeModulePkgTokenSpaceGuid.PcdResetOnMemoryTypeInformationChange|FALSE
gUefiPayloadPkgTokenSpaceGuid.PcdPcdDriverFile|{ 0x57, 0x72, 0xcf, 0x80, 0xab, 0x87, 0xf9, 0x47, 0xa3, 0xfe, 0xD5, 0x0B, 0x76, 0xd8, 0x95, 0x41 }
@ -450,7 +511,6 @@
gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber|$(MAX_LOGICAL_PROCESSORS)
gUefiCpuPkgTokenSpaceGuid.PcdCpuNumberOfReservedVariableMtrrs|0
gUefiPayloadPkgTokenSpaceGuid.PcdBootloaderParameter|0
################################################################################
#
# Pcd DynamicEx Section - list of all EDK II PCD Entries defined by this Platform
@ -478,15 +538,19 @@
!endif
gEfiMdeModulePkgTokenSpaceGuid.PcdResetOnMemoryTypeInformationChange|FALSE
gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvStoreReserved|0
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase|0
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase64|0
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase|0
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase|0
gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut|$(PLATFORM_BOOT_TIMEOUT)
!if $(VARIABLE_SUPPORT) == "SPI"
!if $(VARIABLE_SUPPORT) == "SPI" || $(VARIABLE_SUPPORT) == "SMMSTORE"
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize |0
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize|0
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize |0
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase |0
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase64|0
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase64|0
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase64|0
!endif
# Disable SMM S3 script
gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiS3Enable|FALSE
@ -556,13 +620,25 @@
# Components that produce the architectural protocols
#
!if $(SECURITY_STUB_ENABLE) == TRUE
MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf
MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf {
<LibraryClasses>
!if $(SECURE_BOOT_ENABLE) == TRUE
NULL|SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.inf
!endif
}
!if $(SECURE_BOOT_ENABLE) == TRUE
SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf
SecurityPkg/VariableAuthenticated/SecureBootDefaultKeysDxe/SecureBootDefaultKeysDxe.inf
UefiPayloadPkg/SecureBootEnrollDefaultKeys/SecureBootSetup.inf
!endif
!endif
UefiCpuPkg/CpuDxe/CpuDxe.inf
MdeModulePkg/Universal/BdsDxe/BdsDxe.inf
MdeModulePkg/Logo/LogoDxe.inf
MdeModulePkg/Application/UiApp/UiApp.inf {
<LibraryClasses>
NULL|MdeModulePkg/Library/DeviceManagerUiLib/DeviceManagerUiLib.inf
NULL|MdeModulePkg/Library/BootManagerUiLib/BootManagerUiLib.inf
NULL|MdeModulePkg/Library/BootMaintenanceManagerUiLib/BootMaintenanceManagerUiLib.inf
}
@ -581,7 +657,10 @@
!endif
PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcatRealTimeClockRuntimeDxe.inf
!if $(EMU_VARIABLE_ENABLE) == TRUE
MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf
MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf {
<LibraryClasses>
NULL|MdeModulePkg/Library/VarCheckUefiLib/VarCheckUefiLib.inf
}
!endif
#
# Following are the DXE drivers
@ -701,9 +780,18 @@
MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableSmm/FirmwarePerformanceSmm.inf
!endif
!endif
UefiPayloadPkg/PciPlatformDxe/PciPlatformDxe.inf
!if $(VARIABLE_SUPPORT) == "EMU"
MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf
!elseif $(VARIABLE_SUPPORT) == "SMMSTORE"
UefiPayloadPkg/SmmStoreFvb/SmmStoreFvbRuntimeDxe.inf
MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf
MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf {
<LibraryClasses>
NULL|MdeModulePkg/Library/VarCheckUefiLib/VarCheckUefiLib.inf
NULL|EmbeddedPkg/Library/NvVarStoreFormattedLib/NvVarStoreFormattedLib.inf
}
!elseif $(VARIABLE_SUPPORT) == "SPI"
MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf {
<LibraryClasses>
@ -718,6 +806,14 @@
MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.inf
!endif
#
# Random Number Generator
#
SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf {
<LibraryClasses>
RngLib|SecurityPkg/Library/BaseRngLib/BaseRngLib.inf
}
#------------------------------
# Build the shell
#------------------------------

View File

@ -17,8 +17,8 @@ DEFINE FD_SIZE = 0x00850000
DEFINE NUM_BLOCKS = 0x850
!else
DEFINE FD_SIZE = 0x00590000
DEFINE NUM_BLOCKS = 0x590
DEFINE FD_SIZE = 0x00800000
DEFINE NUM_BLOCKS = 0x800
!endif
################################################################################
@ -61,7 +61,6 @@ FILE FV_IMAGE = 4E35FD93-9C72-4c15-8C4B-E77F1DB2D793 {
}
################################################################################
[FV.DXEFV]
FvNameGuid = 8063C21A-8E58-4576-95CE-089E87975D23
BlockSize = $(FD_BLOCK_SIZE)
@ -89,6 +88,11 @@ APRIORI DXE {
INF MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.inf
INF MdeModulePkg/Universal/StatusCodeHandler/RuntimeDxe/StatusCodeHandlerRuntimeDxe.inf
INF UefiPayloadPkg/BlSupportDxe/BlSupportDxe.inf
!if $(SECURE_BOOT_ENABLE) == TRUE
INF PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcatRealTimeClockRuntimeDxe.inf
INF SecurityPkg/VariableAuthenticated/SecureBootDefaultKeysDxe/SecureBootDefaultKeysDxe.inf # After SMBusConfigLoader and PcatRealTimeClockRuntimeDxe, before Tcg2Dxe
INF UefiPayloadPkg/SecureBootEnrollDefaultKeys/SecureBootSetup.inf
!endif
}
#
@ -140,6 +144,10 @@ INF PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcatRealTimeClockRuntimeDxe.inf
!if $(VARIABLE_SUPPORT) == "EMU"
INF MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf
!elseif $(VARIABLE_SUPPORT) == "SMMSTORE"
INF UefiPayloadPkg/SmmStoreFvb/SmmStoreFvbRuntimeDxe.inf
INF MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf
INF MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf
!elseif $(VARIABLE_SUPPORT) == "SPI"
INF UefiPayloadPkg/FvbRuntimeDxe/FvbSmm.inf
INF MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteSmm.inf
@ -153,11 +161,23 @@ INF MdeModulePkg/Universal/MemoryTest/NullMemoryTestDxe/NullMemoryTestDxe.inf
INF MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
INF MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf
INF MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf
!ifdef $(FIRMWARE_OPEN_FIRMWARE_SETUP)
!if $(ARCH) == IA32
!else
INF RuleOverride=BINARY USE = X64 $(FIRMWARE_OPEN_FIRMWARE_SETUP)
!endif
!endif
INF MdeModulePkg/Universal/PlatformDriOverrideDxe/PlatformDriOverrideDxe.inf
INF MdeModulePkg/Universal/EbcDxe/EbcDxe.inf
INF UefiPayloadPkg/BlSupportDxe/BlSupportDxe.inf
INF MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf
INF MdeModulePkg/Logo/LogoDxe.inf
FILE FREEFORM = PCD(gEfiMdeModulePkgTokenSpaceGuid.PcdLogoFile) {
SECTION RAW = MdeModulePkg/Logo/Logo.bmp
}
#
# PCI Support
#
@ -188,6 +208,7 @@ INF MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleDxe.inf
INF MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf
!endif
INF UefiPayloadPkg/GraphicsOutputDxe/GraphicsOutputDxe.inf
INF UefiPayloadPkg/PciPlatformDxe/PciPlatformDxe.inf
#
# SCSI/ATA/IDE/DISK Support
@ -206,6 +227,21 @@ INF MdeModulePkg/Universal/Disk/RamDiskDxe/RamDiskDxe.inf
!endif
INF FatPkg/EnhancedFatDxe/Fat.inf
#
# Filesystem drivers
#
!if $(ARCH) == IA32
INF RuleOverride=BINARY USE = IA32 FSDrivers/exfat.inf
INF RuleOverride=BINARY USE = IA32 FSDrivers/ext2.inf
INF RuleOverride=BINARY USE = IA32 FSDrivers/ntfs.inf
INF RuleOverride=BINARY USE = IA32 FSDrivers/ext4.inf
!else
INF RuleOverride=BINARY USE = X64 FSDrivers/exfat.inf
INF RuleOverride=BINARY USE = X64 FSDrivers/ext2.inf
INF RuleOverride=BINARY USE = X64 FSDrivers/ntfs.inf
INF RuleOverride=BINARY USE = X64 FSDrivers/ext4.inf
!endif
#
# SD/eMMC Support
#
@ -229,6 +265,10 @@ INF MdeModulePkg/Bus/Usb/UsbMouseDxe/UsbMouseDxe.inf
#
INF MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
# Random Number Generator
#
INF SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf
#
# UEFI network modules
#
@ -236,6 +276,19 @@ INF MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
!include NetworkPkg/Network.fdf.inc
!endif
#
# Security
#
!if $(SECURE_BOOT_ENABLE) == TRUE
INF SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf
INF SecurityPkg/VariableAuthenticated/SecureBootDefaultKeysDxe/SecureBootDefaultKeysDxe.inf
INF UefiPayloadPkg/SecureBootEnrollDefaultKeys/SecureBootSetup.inf
FILE FREEFORM = PCD(gUefiPayloadPkgTokenSpaceGuid.PcdNvsDataFile) {
SECTION RAW = UefiVariableBinary/SECUREBOOT.Fv
}
!endif
#
# Shell
#
@ -246,6 +299,21 @@ INF ShellPkg/Application/Shell/Shell.inf
!endif
!ifdef $(FIRMWARE_OPEN_GOP_POLICY)
# Add PlatformGopPolicy implementation
!if $(ARCH) == IA32
!else
INF RuleOverride=BINARY USE = X64 $(FIRMWARE_OPEN_GOP_POLICY)
!endif
!endif
!ifdef $(FIRMWARE_OPEN_GOP)
# Use IntelGopDriver binary
!if $(ARCH) == IA32
!else
INF RuleOverride=BINARY USE = X64 $(FIRMWARE_OPEN_GOP)
!endif
!endif
################################################################################
#
# Rules are use with the [FV] section's module INF type to define
@ -364,3 +432,17 @@ INF ShellPkg/Application/Shell/Shell.inf
UI STRING="Enter Setup"
VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
}
[RULE.COMMON.USER_DEFINED]
FILE FREEFORM = $(NAMED_GUID) {
RAW BIN |.crt
RAW BIN |.bin
}
[RULE.COMMON.USER_DEFINED.BINARY]
FILE FREEFORM = $(NAMED_GUID) {
RAW BIN |.crt
RAW BIN |.bin
UI STRING="$(MODULE_NAME)" Optional
}

View File

@ -0,0 +1,20 @@
## @file
# Secure Boot Variable File
#
# Builds a firmware volume to contain Secure Boot keys
#
# Copyright (c) 2021, Star Labs Online Limited. All rights reserved.<BR>
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
##
[Defines]
PLATFORM_NAME = SecureBoot
PLATFORM_GUID = 1035eeff-543e-4abb-ac7e-bcd68cb530f8
PLATFORM_VERSION = 0.1
OUTPUT_DIRECTORY = Build/UefiVariableBinary
SUPPORTED_ARCHITECTURES = IA32|X64
BUILD_TARGETS = DEBUG|RELEASE|NOOPT
SKUID_IDENTIFIER = DEFAULT
FLASH_DEFINITION = UefiVariableBinary/UefiVariableBinary.fdf

View File

@ -0,0 +1,31 @@
## @file
# FDF include file which allows to embed Secure Boot keys
#
# Copyright (c) 2021, Star Labs Online Limited. All rights reserved.
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
[Defines]
DEFINE FD_SIZE = 0x00850000
DEFINE NUM_BLOCKS = 0x850
[FV.SecureBoot]
FILE FREEFORM = 85254ea7-4759-4fc4-82d4-5eed5fb0a4a0 {
SECTION RAW = UefiVariableBinary/keys/pk.crt
SECTION UI = "PK Default"
}
FILE FREEFORM = 6f64916e-9f7a-4c35-b952-cd041efb05a3 {
SECTION RAW = UefiVariableBinary/keys/MicCorKEKCA2011_2011-06-24.crt
SECTION UI = "KEK Default"
}
FILE FREEFORM = c491d352-7623-4843-accc-2791a7574421 {
SECTION RAW = UefiVariableBinary/keys/MicWinProPCA2011_2011-10-19.crt
SECTION UI = "DB Default"
}
FILE FREEFORM = 5740766a-718e-4dc0-9935-c36f7d3f884f {
SECTION RAW = UefiVariableBinary/keys/dbxupdate_x64.bin
SECTION UI = "DBX Default"
}

Binary file not shown.

View File

@ -0,0 +1,8 @@
# PK certificate generation
* Do not save private key for re-usage.
* Generate a RSA 2048 / SHA256 x509 certificate
* Exponent should be 65537
* Microsoft certificates can be found here: https://docs.microsoft.com/en-us/windows-hardware/manufacture/desktop/windows-secure-boot-key-creation-and-management-guidance
openssl req -outform DER -newkey rsa:2048 -keyout /dev/null -passout file:<(head -c 40 /dev/urandom) -x509 -days 365 -out pk.crt

Binary file not shown.

Binary file not shown.