Compare commits

..

82 Commits

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

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

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

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

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

This fixes this build error on python3.9:

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

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

  https://bugs.python.org/issue37751

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

This fixes test failures on python3.9, example:

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

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

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

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

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

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

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

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

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

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

Tested using a ST33TPHF TPM 2.0.

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

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

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

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

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

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

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

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

Enabling them and leaving them enabled will do no harm.

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

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

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

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

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

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

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

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

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

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

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

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

View File

@@ -1,50 +0,0 @@
# Azure DevOps Pipelines
These yml files are used to provide CI builds using the Azure DevOps Pipeline Service.
Most of the CI leverages edk2-pytools to support cross platform building and execution.
## Core CI
Focused on building and testing all packages in Edk2 without an actual target platform.
See `.pytools/ReadMe.py` for more details
## Platform CI
Focused on building a single target platform and confirming functionality on that platform.
## Conventions
* Files extension should be *.yml. *.yaml is also supported but in Edk2 we use those for our package configuration.
* Platform CI files should be in the `<PlatformPkg>/.azurepipelines` folder.
* Core CI files are in the root folder.
* Shared templates are in the `templates` folder.
* Top level CI files should be named `<host os>-<tool_chain_tag>.yml`
## Links
* Basic Azure Landing Site - https://docs.microsoft.com/en-us/azure/devops/pipelines/?view=azure-devops
* Pipeline jobs - https://docs.microsoft.com/en-us/azure/devops/pipelines/process/phases?view=azure-devops&tabs=yaml
* Pipeline yml scheme - https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=azure-devops&tabs=schema%2Cparameter-schema
* Pipeline expression - https://docs.microsoft.com/en-us/azure/devops/pipelines/process/expressions?view=azure-devops
* PyTools - https://github.com/tianocore/edk2-pytool-extensions and https://github.com/tianocore/edk2-pytool-library
## Lessons Learned
### Templates and parameters
They are great but evil. If they are used as part of determining the steps of a build they must resolve before the build starts. They can not use variables set in a yml or determined as part of a matrix. If they are used in a step then they can be bound late.
### File matching patterns
On Linux this can hang if there are too many files in the search list.
### Templates and file splitting
Suggestion is to do one big yaml file that does what you want for one of your targets. Then do the second one and find the deltas. From that you can start to figure out the right split of files, steps, jobs.
### Conditional steps
If you want the step to show up in the log but not run, use a step conditional. This is great when a platform doesn't currently support a feature but you want the builders to know that the features exists and maybe someday it will.
If you want the step to not show up use a template step conditional wrapper. Beware this will be evaluated early (at build start). This can hide things not needed on a given OS for example.

View File

@@ -2,7 +2,6 @@
# Azure Pipeline build file for a build using ubuntu and GCC5
#
# Copyright (c) Microsoft Corporation.
# Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
# SPDX-License-Identifier: BSD-2-Clause-Patent
##
trigger:
@@ -15,5 +14,5 @@ jobs:
parameters:
tool_chain_tag: 'GCC5'
vm_image: 'ubuntu-latest'
arch_list: "IA32,X64,ARM,AARCH64,RISCV64"
arch_list: "IA32,X64,ARM,AARCH64"

View File

@@ -1,59 +0,0 @@
# CI Templates
This folder contains azure pipeline yml templates for "Core" and "Platform" Continuous Integration and PR validation.
## Common CI templates
### basetools-build-steps.yml
This template compiles the Edk2 basetools from source. The steps in this template are
conditional and will only run if variable `pkg_count` is greater than 0.
It also has two conditional steps only used when the toolchain contains GCC. These two steps
use `apt` to update the system packages and add those necessary for Edk2 builds.
## Core CI templates
### pr-gate-build-job.yml
This templates contains the jobs and most importantly the matrix of which packages and
targets to run for Core CI.
### pr-gate-steps.yml
This template is the main Core CI template. It controls all the steps run and is responsible for most functionality of the Core CI process. This template sets
the `pkg_count` variable using the `stuart_pr_eval` tool when the
build type is "pull request"
### spell-check-prereq-steps.yml
This template installs the node based tools used by the spell checker plugin. The steps
in this template are conditional and will only run if variable `pkg_count` is greater than 0.
## Platform CI templates
### platform-build-run-steps.yml
This template makes heavy use of pytools to build and run a platform in the Edk2 repo
Also uses basetools-build-steps.yml to compile basetools
#### Special Notes
* For a build type of pull request it will conditionally build if the patches change files that impact the platform.
* uses `stuart_pr_eval` to determine impact
* For manual builds or CI builds it will always build the platform
* It compiles basetools from source
* Will use `stuart_build --FlashOnly` to attempt to run the built image if the `Run` parameter is set.
* See the parameters block for expected configuration options
* Parameter `extra_install_step` allows the caller to insert extra steps. This is useful if additional dependencies, tools, or other things need to be installed. Here is an example of installing qemu on Windows.
``` yaml
steps:
- template: ../../.azurepipelines/templates/build-run-steps.yml
parameters:
extra_install_step:
- powershell: choco install qemu; Write-Host "##vso[task.prependpath]c:\Program Files\qemu"
displayName: Install QEMU and Set QEMU on path # friendly name displayed in the UI
condition: and(gt(variables.pkg_count, 0), succeeded())
```

View File

@@ -1,140 +0,0 @@
## @file
# File steps.yml
#
# template file containing the steps to build
#
# Copyright (c) Microsoft Corporation.
# SPDX-License-Identifier: BSD-2-Clause-Patent
##
parameters:
- name: tool_chain_tag
type: string
default: ''
- name: build_pkg
type: string
default: ''
- name: build_target
type: string
default: ''
- name: build_arch
type: string
default: ''
- name: build_file
type: string
default: ''
- name: build_flags
type: string
default: ''
- name: run_flags
type: string
default: ''
- name: extra_install_step
type: stepList
default: []
steps:
- checkout: self
clean: true
fetchDepth: 1
- task: UsePythonVersion@0
inputs:
versionSpec: "3.8.x"
architecture: "x64"
- script: pip install -r pip-requirements.txt --upgrade
displayName: 'Install/Upgrade pip modules'
# Set default
- bash: echo "##vso[task.setvariable variable=pkg_count]${{ 1 }}"
# Fetch the target branch so that pr_eval can diff them.
# Seems like azure pipelines/github changed checkout process in nov 2020.
- script: git fetch origin $(System.PullRequest.targetBranch)
displayName: fetch target branch
condition: eq(variables['Build.Reason'], 'PullRequest')
# trim the package list if this is a PR
- task: CmdLine@1
displayName: Check if ${{ parameters.build_pkg }} need testing
inputs:
filename: stuart_pr_eval
arguments: -c ${{ parameters.build_file }} -t ${{ parameters.build_target}} -a ${{ parameters.build_arch}} --pr-target origin/$(System.PullRequest.targetBranch) --output-count-format-string "##vso[task.setvariable variable=pkg_count;isOutpout=true]{pkgcount}"
condition: eq(variables['Build.Reason'], 'PullRequest')
# Setup repo
- task: CmdLine@1
displayName: Setup
inputs:
filename: stuart_setup
arguments: -c ${{ parameters.build_file }} TOOL_CHAIN_TAG=${{ parameters.tool_chain_tag}} -t ${{ parameters.build_target}} -a ${{ parameters.build_arch}} ${{ parameters.build_flags}}
condition: and(gt(variables.pkg_count, 0), succeeded())
# Stuart Update
- task: CmdLine@1
displayName: Update
inputs:
filename: stuart_update
arguments: -c ${{ parameters.build_file }} TOOL_CHAIN_TAG=${{ parameters.tool_chain_tag}} -t ${{ parameters.build_target}} -a ${{ parameters.build_arch}} ${{ parameters.build_flags}}
condition: and(gt(variables.pkg_count, 0), succeeded())
# build basetools
# do this after setup and update so that code base dependencies
# are all resolved.
- template: basetools-build-steps.yml
parameters:
tool_chain_tag: ${{ parameters.tool_chain_tag }}
# Potential Extra steps
- ${{ parameters.extra_install_step }}
# Build
- task: CmdLine@1
displayName: Build
inputs:
filename: stuart_build
arguments: -c ${{ parameters.build_file }} TOOL_CHAIN_TAG=${{ parameters.tool_chain_tag}} TARGET=${{ parameters.build_target}} -a ${{ parameters.build_arch}} ${{ parameters.build_flags}}
condition: and(gt(variables.pkg_count, 0), succeeded())
# Run
- task: CmdLine@1
displayName: Run to shell
inputs:
filename: stuart_build
arguments: -c ${{ parameters.build_file }} TOOL_CHAIN_TAG=${{ parameters.tool_chain_tag}} TARGET=${{ parameters.build_target}} -a ${{ parameters.build_arch}} ${{ parameters.build_flags}} ${{ parameters.run_flags }} --FlashOnly
condition: and(and(gt(variables.pkg_count, 0), succeeded()), eq(variables['Run'], true))
timeoutInMinutes: 1
# Copy the build logs to the artifact staging directory
- task: CopyFiles@2
displayName: "Copy build logs"
inputs:
targetFolder: "$(Build.ArtifactStagingDirectory)"
SourceFolder: "Build"
contents: |
BUILDLOG_*.txt
BUILDLOG_*.md
CI_*.txt
CI_*.md
CISETUP.txt
SETUPLOG.txt
UPDATE_LOG.txt
PREVALLOG.txt
TestSuites.xml
**/BUILD_TOOLS_REPORT.html
**/OVERRIDELOG.TXT
BASETOOLS_BUILD*.*
flattenFolders: true
condition: succeededOrFailed()
# Publish build artifacts to Azure Artifacts/TFS or a file share
- task: PublishBuildArtifacts@1
continueOnError: true
displayName: "Publish build logs"
inputs:
pathtoPublish: "$(Build.ArtifactStagingDirectory)"
artifactName: "Build Logs $(System.JobName)"
condition: succeededOrFailed()

View File

@@ -4,7 +4,6 @@
# template file used to build supported packages.
#
# Copyright (c) Microsoft Corporation.
# Copyright (c) 2020, ARM Limited. All rights reserved.<BR>
# SPDX-License-Identifier: BSD-2-Clause-Patent
##
@@ -31,25 +30,20 @@ jobs:
Build.Pkgs: 'MdeModulePkg'
Build.Targets: 'RELEASE,NO-TARGET'
TARGET_NETWORK:
Build.Pkgs: 'NetworkPkg,RedfishPkg'
Build.Pkgs: 'NetworkPkg'
Build.Targets: 'DEBUG,RELEASE,NO-TARGET'
TARGET_OTHER:
Build.Pkgs: 'PcAtChipsetPkg,ShellPkg'
Build.Targets: 'DEBUG,RELEASE,NO-TARGET'
TARGET_FMP_FAT_TEST:
Build.Pkgs: 'FmpDevicePkg,FatPkg,UnitTestFrameworkPkg,DynamicTablesPkg'
Build.Pkgs: 'FmpDevicePkg,FatPkg,UnitTestFrameworkPkg'
Build.Targets: 'DEBUG,RELEASE,NO-TARGET,NOOPT'
TARGET_CRYPTO:
Build.Pkgs: 'CryptoPkg'
Build.Targets: 'DEBUG,RELEASE,NO-TARGET,NOOPT'
Build.Targets: 'DEBUG,RELEASE,NO-TARGET'
TARGET_SECURITY:
Build.Pkgs: 'SecurityPkg'
Build.Targets: 'DEBUG,RELEASE,NO-TARGET'
TARGET_PLATFORMS:
# For Platforms only check code. Leave it to Platform CI
# to build them.
Build.Pkgs: 'ArmVirtPkg,EmulatorPkg,OvmfPkg'
Build.Targets: 'NO-TARGET'
workspace:
clean: all

View File

@@ -20,7 +20,7 @@ steps:
- task: UsePythonVersion@0
inputs:
versionSpec: '3.8.x'
versionSpec: '3.7.x'
architecture: 'x64'
- script: pip install -r pip-requirements.txt --upgrade
@@ -31,12 +31,6 @@ steps:
echo "##vso[task.setvariable variable=pkgs_to_build]${{ parameters.build_pkgs }}"
echo "##vso[task.setvariable variable=pkg_count]${{ 1 }}"
# Fetch the target branch so that pr_eval can diff them.
# Seems like azure pipelines/github changed checkout process in nov 2020.
- script: git fetch origin $(System.PullRequest.targetBranch)
displayName: fetch target branch
condition: eq(variables['Build.Reason'], 'PullRequest')
# trim the package list if this is a PR
- task: CmdLine@1
displayName: Check if ${{ parameters.build_pkgs }} need testing
@@ -45,6 +39,11 @@ steps:
arguments: -c .pytool/CISettings.py -p ${{ parameters.build_pkgs }} --pr-target origin/$(System.PullRequest.targetBranch) --output-csv-format-string "##vso[task.setvariable variable=pkgs_to_build;isOutpout=true]{pkgcsv}" --output-count-format-string "##vso[task.setvariable variable=pkg_count;isOutpout=true]{pkgcount}"
condition: eq(variables['Build.Reason'], 'PullRequest')
# build basetools
- template: basetools-build-steps.yml
parameters:
tool_chain_tag: ${{ parameters.tool_chain_tag }}
# install spell check prereqs
- template: spell-check-prereq-steps.yml
@@ -63,13 +62,6 @@ steps:
arguments: -c .pytool/CISettings.py -p $(pkgs_to_build) -t ${{ parameters.build_targets}} -a ${{ parameters.build_archs}} TOOL_CHAIN_TAG=${{ parameters.tool_chain_tag}}
condition: and(gt(variables.pkg_count, 0), succeeded())
# build basetools
# do this after setup and update so that code base dependencies
# are all resolved.
- template: basetools-build-steps.yml
parameters:
tool_chain_tag: ${{ parameters.tool_chain_tag }}
- task: CmdLine@1
displayName: Build and Test ${{ parameters.build_pkgs }} ${{ parameters.build_archs}}
inputs:

10
.gitmodules vendored
View File

@@ -7,13 +7,3 @@
[submodule "UnitTestFrameworkPkg/Library/CmockaLib/cmocka"]
path = UnitTestFrameworkPkg/Library/CmockaLib/cmocka
url = https://git.cryptomilk.org/projects/cmocka.git
[submodule "MdeModulePkg/Universal/RegularExpressionDxe/oniguruma"]
path = MdeModulePkg/Universal/RegularExpressionDxe/oniguruma
url = https://github.com/kkos/oniguruma
[submodule "MdeModulePkg/Library/BrotliCustomDecompressLib/brotli"]
path = MdeModulePkg/Library/BrotliCustomDecompressLib/brotli
url = https://github.com/google/brotli
[submodule "BaseTools/Source/C/BrotliCompress/brotli"]
path = BaseTools/Source/C/BrotliCompress/brotli
url = https://github.com/google/brotli
ignore = untracked

View File

@@ -1,7 +1,8 @@
#
# This list is used by git-shortlog to update a few name translations
# in the git archive to adjust for job changes or incorrect/inconsistent
# name usage.
# This list is used by git-shortlog to fix a few botched name translations
# in the git archive, either because the author's full name was messed up
# and/or not always written the same way, making contributions from the
# same person appearing not to be so or badly displayed.
#
# Please keep this file sorted alphabetically, and email in lowercase.
# The format used is:
@@ -22,8 +23,6 @@ Eric Dong <eric.dong@intel.com> Eric Dong <eirc.dong@intel.com>
Eric Dong <eric.dong@intel.com> <ydong10@6f19259b-4bc3-4df7-8a09-765794883524>
Eric Dong <eric.dong@intel.com> <ydong10@Edk2>
Erik Bjorge <erik.c.bjorge@intel.com> <geekboy15a@6f19259b-4bc3-4df7-8a09-765794883524>
Eugene Cohen <eugene@nuviainc.com>
Eugene Cohen <eugene@nuviainc.com> <eugene@hp.com>
Hao A Wu <hao.a.wu@intel.com>
Hao A Wu <hao.a.wu@intel.com> <hwu1225@Edk2>
Hot Tian <hot.tian@intel.com>
@@ -38,7 +37,6 @@ Jim Dailey <Jim.Dailey@Dell.com>
Jim Dailey <Jim.Dailey@Dell.com> <Jim_Dailey@Dell.com>
Laszlo Ersek <lersek@redhat.com> <lersek@6f19259b-4bc3-4df7-8a09-765794883524>
Laszlo Ersek <lersek@redhat.com> <lersek@Edk2>
Liming Gao <gaoliming@byosoft.com.cn>
Liming Gao <liming.gao@intel.com> <Gao, Liming liming.gao@intel.com>
Liming Gao <liming.gao@intel.com> <lgao4@6f19259b-4bc3-4df7-8a09-765794883524>
Liming Gao <liming.gao@intel.com> <lgao4@Edk2>
@@ -48,7 +46,6 @@ Marc-André Lureau <marcandre.lureau@redhat.com> <marcandre.lureau@redhat.com>
Marvin Häuser <Marvin.Haeuser@outlook.com>
Marvin Häuser <Marvin.Haeuser@outlook.com> edk2-devel <edk2-devel-bounces@lists.01.org>
Marvin Häuser <mhaeuser@outlook.de>
Matt DeVillier <matt.devillier@gmail.com>
Maurice Ma <maurice.ma@intel.com>
Michael Kubacki <michael.a.kubacki@intel.com>
Michael Kubacki <michael.a.kubacki@intel.com> </o=Intel/ou=External (FYDIBOHF25SPDLT)/cn=Recipients/cn=3c8b0226e75f4ab08d20c151cb7a8a72>
@@ -62,20 +59,14 @@ Ray Ni <ray.ni@intel.com> <niruiyu@Edk2>
Ray Ni <ray.ni@intel.com> <ruiyu.ni@intel.com>
Ray Ni <ray.ni@intel.com> <Ruiyu.ni@Intel.com>
Ray Ni <ray.ni@intel.com> <ruyu.ni@intel.com>
Rebecca Cran <rebecca@bluestop.org>
Rebecca Cran <rebecca@bsdio.com>
Samer El-Haj-Mahmoud <samer@elhajmahmoud.com> <elhaj@hpe.com>
Samer El-Haj-Mahmoud <samer@elhajmahmoud.com> <Samer El-Haj-Mahmoud elhaj@hp.com>
Shenglei Zhang <shenglei.zhang@intel.com>
Star Zeng <star.zeng@intel.com>
Star Zeng <star.zeng@intel.com> <lzeng14@6f19259b-4bc3-4df7-8a09-765794883524>
Star Zeng <star.zeng@intel.com> <lzeng14@Edk2>
Tom Lendacky <thomas.lendacky@amd.com>
Vitaly Cheptsov <vit9696@protonmail.com> Vitaly Cheptsov via Groups.Io <vit9696=protonmail.com@groups.io>
Vladimir Olovyannikov <vladimir.olovyannikov@broadcom.com> Vladimir Olovyannikov via edk2-devel <edk2-devel@lists.01.org>
Wei6 Xu <wei6.xu@intel.com>
Yonghong Zhu <yonghong.zhu@intel.com>
Yonghong Zhu <yonghong.zhu@intel.com> <yzhu52@Edk2>
Yu-Chen Lin <yuchenlin@synology.com>
Zhichao Gao <zhichao.gao@intel.com>
Zhiguang Liu <zhiguang.liu@intel.com>

View File

@@ -1,8 +1,6 @@
# @file
#
# Copyright (c) Microsoft Corporation.
# Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
# Copyright (c) 2020, ARM Limited. All rights reserved.<BR>
# SPDX-License-Identifier: BSD-2-Clause-Patent
##
import os
@@ -41,10 +39,7 @@ class Settings(CiBuildSettingsManager, UpdateSettingsManager, SetupSettingsManag
''' return iterable of edk2 packages supported by this build.
These should be edk2 workspace relative paths '''
return ("ArmVirtPkg",
"DynamicTablesPkg",
"EmulatorPkg",
"MdePkg",
return ("MdePkg",
"MdeModulePkg",
"NetworkPkg",
"PcAtChipsetPkg",
@@ -54,19 +49,15 @@ class Settings(CiBuildSettingsManager, UpdateSettingsManager, SetupSettingsManag
"ShellPkg",
"FatPkg",
"CryptoPkg",
"UnitTestFrameworkPkg",
"OvmfPkg",
"RedfishPkg"
"UnitTestFrameworkPkg"
)
def GetArchitecturesSupported(self):
''' return iterable of edk2 architectures supported by this build '''
return (
"IA32",
return ("IA32",
"X64",
"ARM",
"AARCH64",
"RISCV64")
"AARCH64")
def GetTargetsSupported(self):
''' return iterable of edk2 target tags supported by this build '''
@@ -131,13 +122,14 @@ class Settings(CiBuildSettingsManager, UpdateSettingsManager, SetupSettingsManag
self.ActualToolChainTag = shell_environment.GetBuildVars().GetValue("TOOL_CHAIN_TAG", "")
if GetHostInfo().os.upper() == "WINDOWS":
scopes += ('host-test-win',)
if GetHostInfo().os.upper() == "LINUX" and self.ActualToolChainTag.upper().startswith("GCC"):
if "AARCH64" in self.ActualArchitectures:
scopes += ("gcc_aarch64_linux",)
if "ARM" in self.ActualArchitectures:
scopes += ("gcc_arm_linux",)
if "RISCV64" in self.ActualArchitectures:
scopes += ("gcc_riscv64_unknown",)
return scopes
@@ -152,12 +144,6 @@ class Settings(CiBuildSettingsManager, UpdateSettingsManager, SetupSettingsManag
"CryptoPkg/Library/OpensslLib/openssl", False))
rs.append(RequiredSubmodule(
"UnitTestFrameworkPkg/Library/CmockaLib/cmocka", False))
rs.append(RequiredSubmodule(
"MdeModulePkg/Universal/RegularExpressionDxe/oniguruma", False))
rs.append(RequiredSubmodule(
"MdeModulePkg/Library/BrotliCustomDecompressLib/brotli", False))
rs.append(RequiredSubmodule(
"BaseTools/Source/C/BrotliCompress/brotli", False))
return rs
def GetName(self):

View File

@@ -1,309 +0,0 @@
# @file EccCheck.py
#
# Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
# SPDX-License-Identifier: BSD-2-Clause-Patent
##
import os
import shutil
import re
import csv
import xml.dom.minidom
from typing import List, Dict, Tuple
import logging
from io import StringIO
from edk2toolext.environment import shell_environment
from edk2toolext.environment.plugintypes.ci_build_plugin import ICiBuildPlugin
from edk2toolext.environment.var_dict import VarDict
from edk2toollib.utility_functions import RunCmd
class EccCheck(ICiBuildPlugin):
"""
A CiBuildPlugin that finds the Ecc issues of newly added code in pull request.
Configuration options:
"EccCheck": {
"ExceptionList": [],
"IgnoreFiles": []
},
"""
ReModifyFile = re.compile(r'[B-Q,S-Z]+[\d]*\t(.*)')
FindModifyFile = re.compile(r'\+\+\+ b\/(.*)')
LineScopePattern = (r'@@ -\d*\,*\d* \+\d*\,*\d* @@.*')
LineNumRange = re.compile(r'@@ -\d*\,*\d* \+(\d*)\,*(\d*) @@.*')
def GetTestName(self, packagename: str, environment: VarDict) -> tuple:
""" Provide the testcase name and classname for use in reporting
testclassname: a descriptive string for the testcase can include whitespace
classname: should be patterned <packagename>.<plugin>.<optionally any unique condition>
Args:
packagename: string containing name of package to build
environment: The VarDict for the test to run in
Returns:
a tuple containing the testcase name and the classname
(testcasename, classname)
"""
return ("Check for efi coding style for " + packagename, packagename + ".EccCheck")
##
# External function of plugin. This function is used to perform the task of the ci_build_plugin Plugin
#
# - package is the edk2 path to package. This means workspace/packagepath relative.
# - edk2path object configured with workspace and packages path
# - PkgConfig Object (dict) for the pkg
# - EnvConfig Object
# - Plugin Manager Instance
# - Plugin Helper Obj Instance
# - Junit Logger
# - output_stream the StringIO output stream from this plugin via logging
def RunBuildPlugin(self, packagename, Edk2pathObj, pkgconfig, environment, PLM, PLMHelper, tc, output_stream=None):
edk2_path = Edk2pathObj.WorkspacePath
python_path = os.path.join(edk2_path, "BaseTools", "Source", "Python")
env = shell_environment.GetEnvironment()
env.set_shell_var('PYTHONPATH', python_path)
env.set_shell_var('WORKSPACE', edk2_path)
self.ECC_PASS = True
self.ApplyConfig(pkgconfig, edk2_path, packagename)
modify_dir_list = self.GetModifyDir(packagename)
patch = self.GetDiff(packagename)
ecc_diff_range = self.GetDiffRange(patch, packagename, edk2_path)
self.GenerateEccReport(modify_dir_list, ecc_diff_range, edk2_path)
ecc_log = os.path.join(edk2_path, "Ecc.log")
self.RevertCode()
if self.ECC_PASS:
tc.SetSuccess()
self.RemoveFile(ecc_log)
return 0
else:
with open(ecc_log, encoding='utf8') as output:
ecc_output = output.readlines()
for line in ecc_output:
logging.error(line.strip())
self.RemoveFile(ecc_log)
tc.SetFailed("EccCheck failed for {0}".format(packagename), "Ecc detected issues")
return 1
def RevertCode(self) -> None:
submoudle_params = "submodule update --init"
RunCmd("git", submoudle_params)
reset_params = "reset HEAD --hard"
RunCmd("git", reset_params)
def GetDiff(self, pkg: str) -> List[str]:
return_buffer = StringIO()
params = "diff --unified=0 origin/master HEAD"
RunCmd("git", params, outstream=return_buffer)
p = return_buffer.getvalue().strip()
patch = p.split("\n")
return_buffer.close()
return patch
def RemoveFile(self, file: str) -> None:
if os.path.exists(file):
os.remove(file)
return
def GetModifyDir(self, pkg: str) -> List[str]:
return_buffer = StringIO()
params = "diff --name-status" + ' HEAD' + ' origin/master'
RunCmd("git", params, outstream=return_buffer)
p1 = return_buffer.getvalue().strip()
dir_list = p1.split("\n")
return_buffer.close()
modify_dir_list = []
for modify_dir in dir_list:
file_path = self.ReModifyFile.findall(modify_dir)
if file_path:
file_dir = os.path.dirname(file_path[0])
else:
continue
if pkg in file_dir and file_dir != pkg:
modify_dir_list.append('%s' % file_dir)
else:
continue
modify_dir_list = list(set(modify_dir_list))
return modify_dir_list
def GetDiffRange(self, patch_diff: List[str], pkg: str, workingdir: str) -> Dict[str, List[Tuple[int, int]]]:
IsDelete = True
StartCheck = False
range_directory: Dict[str, List[Tuple[int, int]]] = {}
for line in patch_diff:
modify_file = self.FindModifyFile.findall(line)
if modify_file and pkg in modify_file[0] and not StartCheck and os.path.isfile(modify_file[0]):
modify_file_comment_dic = self.GetCommentRange(modify_file[0], workingdir)
IsDelete = False
StartCheck = True
modify_file_dic = modify_file[0]
modify_file_dic = modify_file_dic.replace("/", os.sep)
range_directory[modify_file_dic] = []
elif line.startswith('--- '):
StartCheck = False
elif re.match(self.LineScopePattern, line, re.I) and not IsDelete and StartCheck:
start_line = self.LineNumRange.search(line).group(1)
line_range = self.LineNumRange.search(line).group(2)
if not line_range:
line_range = '1'
range_directory[modify_file_dic].append((int(start_line), int(start_line) + int(line_range) - 1))
for i in modify_file_comment_dic:
if int(i[0]) <= int(start_line) <= int(i[1]):
range_directory[modify_file_dic].append(i)
return range_directory
def GetCommentRange(self, modify_file: str, workingdir: str) -> List[Tuple[int, int]]:
modify_file_path = os.path.join(workingdir, modify_file)
with open(modify_file_path) as f:
line_no = 1
comment_range: List[Tuple[int, int]] = []
Start = False
for line in f:
if line.startswith('/**'):
start_no = line_no
Start = True
if line.startswith('**/') and Start:
end_no = line_no
Start = False
comment_range.append((int(start_no), int(end_no)))
line_no += 1
if comment_range and comment_range[0][0] == 1:
del comment_range[0]
return comment_range
def GenerateEccReport(self, modify_dir_list: List[str], ecc_diff_range: Dict[str, List[Tuple[int, int]]],
edk2_path: str) -> None:
ecc_need = False
ecc_run = True
config = os.path.join(edk2_path, "BaseTools", "Source", "Python", "Ecc", "config.ini")
exception = os.path.join(edk2_path, "BaseTools", "Source", "Python", "Ecc", "exception.xml")
report = os.path.join(edk2_path, "Ecc.csv")
for modify_dir in modify_dir_list:
target = os.path.join(edk2_path, modify_dir)
logging.info('Run ECC tool for the commit in %s' % modify_dir)
ecc_need = True
ecc_params = "-c {0} -e {1} -t {2} -r {3}".format(config, exception, target, report)
return_code = RunCmd("Ecc", ecc_params, workingdir=edk2_path)
if return_code != 0:
ecc_run = False
break
if not ecc_run:
logging.error('Fail to run ECC tool')
self.ParseEccReport(ecc_diff_range, edk2_path)
if not ecc_need:
logging.info("Doesn't need run ECC check")
revert_params = "checkout -- {}".format(exception)
RunCmd("git", revert_params)
return
def ParseEccReport(self, ecc_diff_range: Dict[str, List[Tuple[int, int]]], edk2_path: str) -> None:
ecc_log = os.path.join(edk2_path, "Ecc.log")
ecc_csv = "Ecc.csv"
file = os.listdir(edk2_path)
row_lines = []
ignore_error_code = self.GetIgnoreErrorCode()
if ecc_csv in file:
with open(ecc_csv) as csv_file:
reader = csv.reader(csv_file)
for row in reader:
for modify_file in ecc_diff_range:
if modify_file in row[3]:
for i in ecc_diff_range[modify_file]:
line_no = int(row[4])
if i[0] <= line_no <= i[1] and row[1] not in ignore_error_code:
row[0] = '\nEFI coding style error'
row[1] = 'Error code: ' + row[1]
row[3] = 'file: ' + row[3]
row[4] = 'Line number: ' + row[4]
row_line = '\n *'.join(row)
row_lines.append(row_line)
break
break
if row_lines:
self.ECC_PASS = False
with open(ecc_log, 'a') as log:
all_line = '\n'.join(row_lines)
all_line = all_line + '\n'
log.writelines(all_line)
return
def ApplyConfig(self, pkgconfig: Dict[str, List[str]], edk2_path: str, pkg: str) -> None:
if "IgnoreFiles" in pkgconfig:
for a in pkgconfig["IgnoreFiles"]:
a = os.path.join(edk2_path, pkg, a)
a = a.replace(os.sep, "/")
logging.info("Ignoring Files {0}".format(a))
if os.path.exists(a):
if os.path.isfile(a):
self.RemoveFile(a)
elif os.path.isdir(a):
shutil.rmtree(a)
else:
logging.error("EccCheck.IgnoreInf -> {0} not found in filesystem. Invalid ignore files".format(a))
if "ExceptionList" in pkgconfig:
exception_list = pkgconfig["ExceptionList"]
exception_xml = os.path.join(edk2_path, "BaseTools", "Source", "Python", "Ecc", "exception.xml")
try:
logging.info("Appending exceptions")
self.AppendException(exception_list, exception_xml)
except Exception as e:
logging.error("Fail to apply exceptions")
raise e
return
def AppendException(self, exception_list: List[str], exception_xml: str) -> None:
error_code_list = exception_list[::2]
keyword_list = exception_list[1::2]
dom_tree = xml.dom.minidom.parse(exception_xml)
root_node = dom_tree.documentElement
for error_code, keyword in zip(error_code_list, keyword_list):
customer_node = dom_tree.createElement("Exception")
keyword_node = dom_tree.createElement("KeyWord")
keyword_node_text_value = dom_tree.createTextNode(keyword)
keyword_node.appendChild(keyword_node_text_value)
customer_node.appendChild(keyword_node)
error_code_node = dom_tree.createElement("ErrorID")
error_code_text_value = dom_tree.createTextNode(error_code)
error_code_node.appendChild(error_code_text_value)
customer_node.appendChild(error_code_node)
root_node.appendChild(customer_node)
with open(exception_xml, 'w') as f:
dom_tree.writexml(f, indent='', addindent='', newl='\n', encoding='UTF-8')
return
def GetIgnoreErrorCode(self) -> set:
"""
Below are kinds of error code that are accurate in ecc scanning of edk2 level.
But EccCheck plugin is partial scanning so they are always false positive issues.
The mapping relationship of error code and error message is listed BaseTools/Sourc/Python/Ecc/EccToolError.py
"""
ignore_error_code = {
"10000",
"10001",
"10002",
"10003",
"10004",
"10005",
"10006",
"10007",
"10008",
"10009",
"10010",
"10011",
"10012",
"10013",
"10015",
"10016",
"10017",
"10022",
}
return ignore_error_code

View File

@@ -1,11 +0,0 @@
## @file
# CiBuildPlugin used to check Ecc issues
#
# Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
# SPDX-License-Identifier: BSD-2-Clause-Patent
##
{
"scope": "cibuild",
"name": "EccCheck Test",
"module": "EccCheck"
}

View File

@@ -1,15 +0,0 @@
# EFI Coding style Check Plugin
This CiBuildPlugin finds the Ecc issues of newly added code in pull request.
## Configuration
The plugin can be configured to ignore certain files and issues.
"EccCheck": {
"ExceptionList": [],
"IgnoreFiles": []
},
"""
OPTIONAL List of file to ignore.

View File

@@ -1,115 +0,0 @@
# @file LicenseCheck.py
#
# Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
# SPDX-License-Identifier: BSD-2-Clause-Patent
##
import os
import logging
import re
from io import StringIO
from typing import List, Tuple
from edk2toolext.environment.plugintypes.ci_build_plugin import ICiBuildPlugin
from edk2toolext.environment.var_dict import VarDict
from edk2toollib.utility_functions import RunCmd
class LicenseCheck(ICiBuildPlugin):
"""
A CiBuildPlugin to check the license for new added files.
Configuration options:
"LicenseCheck": {
"IgnoreFiles": []
},
"""
license_format_preflix = 'SPDX-License-Identifier'
bsd2_patent = 'BSD-2-Clause-Patent'
Readdedfileformat = re.compile(r'\+\+\+ b\/(.*)')
file_extension_list = [".c", ".h", ".inf", ".dsc", ".dec", ".py", ".bat", ".sh", ".uni", ".yaml",
".fdf", ".inc", "yml", ".asm", ".asm16", ".asl", ".vfr", ".s", ".S", ".aslc",
".nasm", ".nasmb", ".idf", ".Vfr", ".H"]
def GetTestName(self, packagename: str, environment: VarDict) -> tuple:
""" Provide the testcase name and classname for use in reporting
testclassname: a descriptive string for the testcase can include whitespace
classname: should be patterned <packagename>.<plugin>.<optionally any unique condition>
Args:
packagename: string containing name of package to build
environment: The VarDict for the test to run in
Returns:
a tuple containing the testcase name and the classname
(testcasename, classname)
"""
return ("Check for license for " + packagename, packagename + ".LicenseCheck")
##
# External function of plugin. This function is used to perform the task of the ci_build_plugin Plugin
#
# - package is the edk2 path to package. This means workspace/packagepath relative.
# - edk2path object configured with workspace and packages path
# - PkgConfig Object (dict) for the pkg
# - EnvConfig Object
# - Plugin Manager Instance
# - Plugin Helper Obj Instance
# - Junit Logger
# - output_stream the StringIO output stream from this plugin via logging
def RunBuildPlugin(self, packagename, Edk2pathObj, pkgconfig, environment, PLM, PLMHelper, tc, output_stream=None):
return_buffer = StringIO()
params = "diff --unified=0 origin/master HEAD"
RunCmd("git", params, outstream=return_buffer)
p = return_buffer.getvalue().strip()
patch = p.split("\n")
return_buffer.close()
ignore_files = []
if "IgnoreFiles" in pkgconfig:
ignore_files = pkgconfig["IgnoreFiles"]
self.ok = True
self.startcheck = False
self.license = True
self.all_file_pass = True
count = len(patch)
line_index = 0
for line in patch:
if line.startswith('--- /dev/null'):
nextline = patch[line_index + 1]
added_file = self.Readdedfileformat.search(nextline).group(1)
added_file_extension = os.path.splitext(added_file)[1]
if added_file_extension in self.file_extension_list and packagename in added_file:
if (self.IsIgnoreFile(added_file, ignore_files)):
line_index = line_index + 1
continue
self.startcheck = True
self.license = False
if self.startcheck and self.license_format_preflix in line:
if self.bsd2_patent in line:
self.license = True
if line_index + 1 == count or patch[line_index + 1].startswith('diff --') and self.startcheck:
if not self.license:
self.all_file_pass = False
error_message = "Invalid license in: " + added_file + " Hint: Only BSD-2-Clause-Patent is accepted."
logging.error(error_message)
self.startcheck = False
self.license = True
line_index = line_index + 1
if self.all_file_pass:
tc.SetSuccess()
return 0
else:
tc.SetFailed("License Check {0} Failed. ".format(packagename), "LICENSE_CHECK_FAILED")
return 1
def IsIgnoreFile(self, file: str, ignore_files: List[str]) -> bool:
for f in ignore_files:
if f in file:
return True
return False

View File

@@ -1,11 +0,0 @@
## @file
# CiBuildPlugin used to check license issues for new added files
#
# Copyright (c) 2020, Intel Corporation. All rights reserved.
# SPDX-License-Identifier: BSD-2-Clause-Patent
##
{
"scope": "cibuild",
"name": "License Check Test",
"module": "LicenseCheck"
}

View File

@@ -1,17 +0,0 @@
# License Check Plugin
This CiBuildPlugin scans all new added files in a package to make sure code
is contributed under BSD-2-Clause-Patent.
## Configuration
The plugin can be configured to ignore certain files.
``` yaml
"LicenseCheck": {
"IgnoreFiles": []
}
```
### IgnoreFiles
OPTIONAL List of file to ignore.

View File

@@ -22,8 +22,6 @@
],
"minWordLength": 5,
"allowCompoundWords": false,
"maxNumberOfProblems": 200,
"maxDuplicateProblems": 200,
"ignoreWords": [
"muchange"
],
@@ -163,21 +161,5 @@
"bootability",
"Sdhci",
"inmodule",
"RISCV",
"edksetup",
"iscsi",
"nvdata",
"pytools",
"NTDDI",
"Wnonportable",
"CLANGPDB",
"nologo",
"lldmap",
"ASMLINK",
"NODEFAULTLIB",
"vcruntimed",
"ucrtd",
"msvcrtd",
"XIPFLAGS"
]
}

View File

@@ -2,32 +2,31 @@
## Basic Status
| Package | Windows VS2019 (IA32/X64)| Ubuntu GCC (IA32/X64/ARM/AARCH64) | Known Issues |
| :---- | :----- | :---- | :--- |
| ArmPkg |
| ArmPlatformPkg |
| ArmVirtPkg | SEE PACKAGE README | SEE PACKAGE README |
| CryptoPkg | :heavy_check_mark: | :heavy_check_mark: | Spell checking in audit mode
| DynamicTablesPkg | | :heavy_check_mark: |
| EmbeddedPkg |
| EmulatorPkg | SEE PACKAGE README | SEE PACKAGE README | Spell checking in audit mode
| FatPkg | :heavy_check_mark: | :heavy_check_mark: |
| FmpDevicePkg | :heavy_check_mark: | :heavy_check_mark: |
| IntelFsp2Pkg |
| IntelFsp2WrapperPkg |
| MdeModulePkg | :heavy_check_mark: | :heavy_check_mark: | DxeIpl dependency on ArmPkg, Depends on StandaloneMmPkg, Spell checking in audit mode
| MdePkg | :heavy_check_mark: | :heavy_check_mark: | Spell checking in audit mode
| NetworkPkg | :heavy_check_mark: | :heavy_check_mark: | Spell checking in audit mode
| OvmfPkg | SEE PACKAGE README | SEE PACKAGE README | Spell checking in audit mode
| PcAtChipsetPkg | :heavy_check_mark: | :heavy_check_mark: |
| SecurityPkg | :heavy_check_mark: | :heavy_check_mark: | Spell checking in audit mode
| ShellPkg | :heavy_check_mark: | :heavy_check_mark: | Spell checking in audit mode, 3 modules are not being built by DSC
| SignedCapsulePkg |
| SourceLevelDebugPkg |
| StandaloneMmPkg |
| UefiCpuPkg | :heavy_check_mark: | :heavy_check_mark: | Spell checking in audit mode, 2 binary modules not being built by DSC
| UefiPayloadPkg |
| UnitTestFrameworkPkg | :heavy_check_mark: | :heavy_check_mark: |
| Package | Windows VS2019 (IA32/X64)| Ubuntu GCC (IA32/X64/ARM/AARCH64) | Known Issues |
| :---- | :----- | :---- | :--- |
| ArmPkg |
| ArmPlatformPkg |
| ArmVirtPkg |
| CryptoPkg | :heavy_check_mark: | :heavy_check_mark: | Spell checking in audit mode
| DynamicTablesPkg |
| EmbeddedPkg |
| EmulatorPkg |
| FatPkg | :heavy_check_mark: | :heavy_check_mark: |
| FmpDevicePkg | :heavy_check_mark: | :heavy_check_mark: |
| IntelFsp2Pkg |
| IntelFsp2WrapperPkg |
| MdeModulePkg | :heavy_check_mark: | :heavy_check_mark: | DxeIpl dependency on ArmPkg, Depends on StandaloneMmPkg, Spell checking in audit mode
| MdePkg | :heavy_check_mark: | :heavy_check_mark: | Spell checking in audit mode
| NetworkPkg | :heavy_check_mark: | :heavy_check_mark: | Spell checking in audit mode
| OvmfPkg |
| PcAtChipsetPkg | :heavy_check_mark: | :heavy_check_mark: |
| SecurityPkg | :heavy_check_mark: | :heavy_check_mark: | Spell checking in audit mode
| ShellPkg | :heavy_check_mark: | :heavy_check_mark: | Spell checking in audit mode, 3 modules are not being built by DSC
| SignedCapsulePkg |
| SourceLevelDebugPkg |
| StandaloneMmPkg |
| UefiCpuPkg | :heavy_check_mark: | :heavy_check_mark: | Spell checking in audit mode, 2 binary modules not being built by DSC
| UefiPayloadPkg |
For more detailed status look at the test results of the latest CI run on the
repo readme.
@@ -78,7 +77,7 @@ per package configuration which comes from this file.
## Running CI locally
The EDKII Tools environment (and by extension the ci) is designed to support
easily and consistently running locally and in a cloud ci environment. To do
easily and consistantly running locally and in a cloud ci environment. To do
that a few steps should be followed. Details of EDKII Tools can be found in the
[docs folder here](https://github.com/tianocore/edk2-pytool-extensions/tree/master/docs)
@@ -89,7 +88,7 @@ that a few steps should be followed. Details of EDKII Tools can be found in the
* VS 2017 or VS 2019
* Windows SDK (for rc)
* Windows WDK (for capsules)
* Ubuntu 18.04 or Fedora
* Ubuntu 16.04
* GCC5
* Easy to add more but this is the current state
2. Python 3.7.x or newer on path
@@ -138,31 +137,11 @@ location makes more sense for the community.
### Module Inclusion Test - DscCompleteCheck
This scans all INF files from a package and confirms they are
listed in the package level DSC file. The test considers it an error if any INF
does not appear in the `Components` section of the package-level DSC (indicating
that it would not be built if the package were built). This is critical because
much of the CI infrastructure assumes that all modules will be listed in the DSC
and compiled.
This test will ignore INFs in the following cases:
1. When `MODULE_TYPE` = `HOST_APPLICATION`
2. When a Library instance **only** supports the `HOST_APPLICATION` environment
### Host Module Inclusion Test - HostUnitTestDscCompleteCheck
This test scans all INF files from a package for those related to host
based unit tests and confirms they are listed in the unit test DSC file for the package.
The test considers it an error if any INF meeting the requirements does not appear
in the `Components` section of the unit test DSC. This is critical because
much of the CI infrastructure assumes that modules will be listed in the DSC
and compiled.
This test will only require INFs in the following cases:
1. When `MODULE_TYPE` = `HOST_APPLICATION`
2. When a Library instance explicitly supports the `HOST_APPLICATION` environment
This test scans all available modules (via INF files) and compares them to the
package-level DSC file for the package each module is contained within. The test
considers it an error if any module does not appear in the `Components` section
of at least one package-level DSC (indicating that it would not be built if the
package were built).
### Code Compilation Test - CompilerPlugin
@@ -171,46 +150,6 @@ all package-level DSCs were built, the Code Compilation Test simply runs through
and builds every package-level DSC on every toolchain and for every architecture
that is supported. Any module that fails to build is considered an error.
### Host Unit Test Compilation and Run Test - HostUnitTestCompilerPlugin
A test that compiles the dsc for host based unit test apps.
On Windows this will also enable a build plugin to execute that will run the unit tests and verify the results.
These tools will be invoked on any CI
pass that includes the NOOPT target. In order for these tools to do their job,
the package and tests must be configured in a particular way...
#### Including Host-Based Tests in the Package YAML
For example, looking at the `MdeModulePkg.ci.yaml` config file, there are two
config options that control HostBased test behavior:
```json
## options defined .pytool/Plugin/HostUnitTestCompilerPlugin
"HostUnitTestCompilerPlugin": {
"DscPath": "Test/MdeModulePkgHostTest.dsc"
},
```
This option tell the test builder to run. The test builder needs to know which
modules in this package are host-based tests, so that DSC path is provided.
#### Configuring the HostBased DSC
The HostBased DSC for `MdeModulePkg` is located at
`MdeModulePkg/Test/MdeModulePkgHostTest.dsc`.
To add automated host-based unit test building to a new package, create a
similar DSC. The new DSC should make sure to have the `NOOPT` BUILD_TARGET
and should include the line:
```
!include UnitTestFrameworkPkg/UnitTestFrameworkPkgHost.dsc.inc
```
All of the modules that are included in the `Components` section of this
DSC should be of type HOST_APPLICATION.
### GUID Uniqueness Test - GuidCheck
This test works on the collection of all packages rather than an individual
@@ -268,8 +207,6 @@ few standard scopes.
| global-nix | edk2_invocable++ | Running on Linux based OS |
| edk2-build | | This indicates that an invocable is building EDK2 based UEFI code |
| cibuild | set in .pytool/CISettings.py | Suggested target for edk2 continuous integration builds. Tools used for CiBuilds can use this scope. Example: asl compiler |
| host-based-test | set in .pytool/CISettings.py | Turns on the host based tests and plugin |
| host-test-win | set in .pytool/CISettings.py | Enables the host based test runner for Windows |
## Future investments
@@ -279,6 +216,8 @@ few standard scopes.
* Visual Studio AARCH64 and ARM support
* BaseTools C tools CI/PR and binary release process
* BaseTools Python tools CI/PR process
* Host based unit testing
* Extensible private/closed source platform reporting
* Platform builds, validation
* UEFI SCTs
* Other automation

View File

@@ -4,7 +4,6 @@
# Copyright (c) 2009 - 2010, Apple Inc. All rights reserved.<BR>
# Copyright (c) 2011 - 2018, ARM Ltd. All rights reserved.<BR>
# Copyright (c) 2016, Linaro Ltd. All rights reserved.<BR>
# Copyright (c) Microsoft Corporation.<BR>
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
@@ -29,9 +28,6 @@
RELEASE_*_*_CC_FLAGS = -DMDEPKG_NDEBUG
*_*_*_CC_FLAGS = -DDISABLE_NEW_DEPRECATED_INTERFACES
[PcdsFixedAtBuild]
gEfiMdePkgTokenSpaceGuid.PcdDefaultTerminalType|4
[LibraryClasses.common]
BaseLib|MdePkg/Library/BaseLib/BaseLib.inf
BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
@@ -137,16 +133,12 @@
ArmPkg/Library/ArmGicArchLib/ArmGicArchLib.inf
ArmPkg/Library/ArmGicArchSecLib/ArmGicArchSecLib.inf
ArmPkg/Library/ArmLib/ArmBaseLib.inf
ArmPkg/Library/ArmMtlNullLib/ArmMtlNullLib.inf
ArmPkg/Library/ArmSoftFloatLib/ArmSoftFloatLib.inf
ArmPkg/Library/ArmSmcPsciResetSystemLib/ArmSmcPsciResetSystemLib.inf
ArmPkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointerLib.inf
ArmPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
ArmPkg/Drivers/ArmCrashDumpDxe/ArmCrashDumpDxe.inf
ArmPkg/Drivers/ArmScmiDxe/ArmScmiDxe.inf
[Components.AARCH64]
ArmPkg/Drivers/MmCommunicationDxe/MmCommunication.inf
ArmPkg/Library/ArmMmuLib/ArmMmuPeiLib.inf
ArmPkg/Library/StandaloneMmMmuLib/ArmMmuStandaloneMmLib.inf

View File

@@ -13,68 +13,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include <Library/MemoryAllocationLib.h>
#include "CpuDxe.h"
#define INVALID_ENTRY ((UINT32)~0)
#define MIN_T0SZ 16
#define BITS_PER_LEVEL 9
STATIC
VOID
GetRootTranslationTableInfo (
IN UINTN T0SZ,
OUT UINTN *RootTableLevel,
OUT UINTN *RootTableEntryCount
)
{
*RootTableLevel = (T0SZ - MIN_T0SZ) / BITS_PER_LEVEL;
*RootTableEntryCount = TT_ENTRY_COUNT >> (T0SZ - MIN_T0SZ) % BITS_PER_LEVEL;
}
STATIC
UINT64
PageAttributeToGcdAttribute (
IN UINT64 PageAttributes
)
{
UINT64 GcdAttributes;
switch (PageAttributes & TT_ATTR_INDX_MASK) {
case TT_ATTR_INDX_DEVICE_MEMORY:
GcdAttributes = EFI_MEMORY_UC;
break;
case TT_ATTR_INDX_MEMORY_NON_CACHEABLE:
GcdAttributes = EFI_MEMORY_WC;
break;
case TT_ATTR_INDX_MEMORY_WRITE_THROUGH:
GcdAttributes = EFI_MEMORY_WT;
break;
case TT_ATTR_INDX_MEMORY_WRITE_BACK:
GcdAttributes = EFI_MEMORY_WB;
break;
default:
DEBUG ((DEBUG_ERROR,
"PageAttributeToGcdAttribute: PageAttributes:0x%lX not supported.\n",
PageAttributes));
ASSERT (0);
// The Global Coherency Domain (GCD) value is defined as a bit set.
// Returning 0 means no attribute has been set.
GcdAttributes = 0;
}
// Determine protection attributes
if (((PageAttributes & TT_AP_MASK) == TT_AP_NO_RO) ||
((PageAttributes & TT_AP_MASK) == TT_AP_RO_RO)) {
// Read only cases map to write-protect
GcdAttributes |= EFI_MEMORY_RO;
}
// Process eXecute Never attribute
if ((PageAttributes & (TT_PXN_MASK | TT_UXN_MASK)) != 0) {
GcdAttributes |= EFI_MEMORY_XP;
}
return GcdAttributes;
}
#define TT_ATTR_INDX_INVALID ((UINT32)~0)
STATIC
UINT64
@@ -98,7 +37,7 @@ GetFirstPageAttribute (
{
return FirstEntry & TT_ATTR_INDX_MASK;
} else {
return INVALID_ENTRY;
return TT_ATTR_INDX_INVALID;
}
}
@@ -139,8 +78,8 @@ GetNextEntryAttribute (
// If Entry is a Table Descriptor type entry then go through the sub-level table
if ((EntryType == TT_TYPE_BLOCK_ENTRY) ||
((TableLevel == 3) && (EntryType == TT_TYPE_BLOCK_ENTRY_LEVEL3))) {
if ((*PrevEntryAttribute == INVALID_ENTRY) || (EntryAttribute != *PrevEntryAttribute)) {
if (*PrevEntryAttribute != INVALID_ENTRY) {
if ((*PrevEntryAttribute == TT_ATTR_INDX_INVALID) || (EntryAttribute != *PrevEntryAttribute)) {
if (*PrevEntryAttribute != TT_ATTR_INDX_INVALID) {
// Update GCD with the last region
SetGcdMemorySpaceAttributes (MemorySpaceMap, NumberOfDescriptors,
*StartGcdRegion,
@@ -164,7 +103,7 @@ GetNextEntryAttribute (
(BaseAddress + (Index * TT_ADDRESS_AT_LEVEL(TableLevel))),
PrevEntryAttribute, StartGcdRegion);
} else {
if (*PrevEntryAttribute != INVALID_ENTRY) {
if (*PrevEntryAttribute != TT_ATTR_INDX_INVALID) {
// Update GCD with the last region
SetGcdMemorySpaceAttributes (MemorySpaceMap, NumberOfDescriptors,
*StartGcdRegion,
@@ -173,7 +112,7 @@ GetNextEntryAttribute (
// Start of the new region
*StartGcdRegion = BaseAddress + (Index * TT_ADDRESS_AT_LEVEL(TableLevel));
*PrevEntryAttribute = INVALID_ENTRY;
*PrevEntryAttribute = TT_ATTR_INDX_INVALID;
}
}
}
@@ -238,7 +177,7 @@ SyncCacheConfig (
&PageAttribute, &BaseAddressGcdRegion);
// Update GCD with the last region if valid
if (PageAttribute != INVALID_ENTRY) {
if (PageAttribute != TT_ATTR_INDX_INVALID) {
SetGcdMemorySpaceAttributes (MemorySpaceMap, NumberOfDescriptors,
BaseAddressGcdRegion,
EndAddressGcdRegion - BaseAddressGcdRegion,

View File

@@ -134,6 +134,13 @@ GetMemoryRegion (
OUT UINTN *RegionAttributes
);
VOID
GetRootTranslationTableInfo (
IN UINTN T0SZ,
OUT UINTN *TableLevel,
OUT UINTN *TableEntryCount
);
EFI_STATUS
SetGcdMemorySpaceAttributes (
IN EFI_GCD_MEMORY_SPACE_DESCRIPTOR *MemorySpaceMap,

View File

@@ -1,6 +1,6 @@
/** @file
Copyright (c) 2016-2019, ARM Limited. All rights reserved.
Copyright (c) 2016-2018, ARM Limited. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -16,7 +16,7 @@
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiRuntimeServicesTableLib.h>
#include <Protocol/MmCommunication2.h>
#include <Protocol/MmCommunication.h>
#include <IndustryStandard/ArmStdSmc.h>
@@ -39,34 +39,39 @@ STATIC EFI_HANDLE mMmCommunicateHandle;
/**
Communicates with a registered handler.
This function provides a service to send and receive messages from a registered UEFI service.
This function provides an interface to send and receive messages to the
Standalone MM environment on behalf of UEFI services. This function is part
of the MM Communication Protocol that may be called in physical mode prior to
SetVirtualAddressMap() and in virtual mode after SetVirtualAddressMap().
@param[in] This The EFI_MM_COMMUNICATION_PROTOCOL instance.
@param[in] CommBufferPhysical Physical address of the MM communication buffer
@param[in] CommBufferVirtual Virtual address of the MM communication buffer
@param[in] CommSize The size of the data buffer being passed in. On exit, the size of data
being returned. Zero if the handler does not wish to reply with any data.
This parameter is optional and may be NULL.
@retval EFI_SUCCESS The message was successfully posted.
@retval EFI_INVALID_PARAMETER CommBufferPhysical was NULL or CommBufferVirtual was NULL.
@retval EFI_BAD_BUFFER_SIZE The buffer is too large for the MM implementation.
If this error is returned, the MessageLength field
in the CommBuffer header or the integer pointed by
CommSize, are updated to reflect the maximum payload
size the implementation can accommodate.
@retval EFI_ACCESS_DENIED The CommunicateBuffer parameter or CommSize parameter,
if not omitted, are in address range that cannot be
accessed by the MM environment.
@param[in] This The EFI_MM_COMMUNICATION_PROTOCOL
instance.
@param[in, out] CommBuffer A pointer to the buffer to convey
into MMRAM.
@param[in, out] CommSize The size of the data buffer being
passed in. This is optional.
@retval EFI_SUCCESS The message was successfully posted.
@retval EFI_INVALID_PARAMETER The CommBuffer was NULL.
@retval EFI_BAD_BUFFER_SIZE The buffer size is incorrect for the MM
implementation. If this error is
returned, the MessageLength field in
the CommBuffer header or the integer
pointed by CommSize are updated to reflect
the maximum payload size the
implementation can accommodate.
@retval EFI_ACCESS_DENIED The CommunicateBuffer parameter
or CommSize parameter, if not omitted,
are in address range that cannot be
accessed by the MM environment
**/
STATIC
EFI_STATUS
EFIAPI
MmCommunication2Communicate (
IN CONST EFI_MM_COMMUNICATION2_PROTOCOL *This,
IN OUT VOID *CommBufferPhysical,
IN OUT VOID *CommBufferVirtual,
IN OUT UINTN *CommSize OPTIONAL
MmCommunicationCommunicate (
IN CONST EFI_MM_COMMUNICATION_PROTOCOL *This,
IN OUT VOID *CommBuffer,
IN OUT UINTN *CommSize OPTIONAL
)
{
EFI_MM_COMMUNICATE_HEADER *CommunicateHeader;
@@ -82,11 +87,11 @@ MmCommunication2Communicate (
//
// Check parameters
//
if (CommBufferVirtual == NULL) {
if (CommBuffer == NULL) {
return EFI_INVALID_PARAMETER;
}
CommunicateHeader = CommBufferVirtual;
CommunicateHeader = CommBuffer;
// CommBuffer is a mandatory parameter. Hence, Rely on
// MessageLength + Header to ascertain the
// total size of the communication payload rather than
@@ -131,7 +136,7 @@ MmCommunication2Communicate (
CommunicateSmcArgs.Arg1 = 0;
// Copy Communication Payload
CopyMem ((VOID *)mNsCommBuffMemRegion.VirtualBase, CommBufferVirtual, BufferSize);
CopyMem ((VOID *)mNsCommBuffMemRegion.VirtualBase, CommBuffer, BufferSize);
// comm_buffer_address (64-bit physical address)
CommunicateSmcArgs.Arg2 = (UINTN)mNsCommBuffMemRegion.PhysicalBase;
@@ -144,7 +149,7 @@ MmCommunication2Communicate (
switch (CommunicateSmcArgs.Arg0) {
case ARM_SMC_MM_RET_SUCCESS:
ZeroMem (CommBufferVirtual, BufferSize);
ZeroMem (CommBuffer, BufferSize);
// On successful return, the size of data being returned is inferred from
// MessageLength + Header.
CommunicateHeader = (EFI_MM_COMMUNICATE_HEADER *)mNsCommBuffMemRegion.VirtualBase;
@@ -153,7 +158,7 @@ MmCommunication2Communicate (
sizeof (CommunicateHeader->MessageLength);
CopyMem (
CommBufferVirtual,
CommBuffer,
(VOID *)mNsCommBuffMemRegion.VirtualBase,
BufferSize
);
@@ -186,8 +191,8 @@ MmCommunication2Communicate (
//
// MM Communication Protocol instance
//
STATIC EFI_MM_COMMUNICATION2_PROTOCOL mMmCommunication2 = {
MmCommunication2Communicate
EFI_MM_COMMUNICATION_PROTOCOL mMmCommunication = {
MmCommunicationCommunicate
};
/**
@@ -288,7 +293,7 @@ MmGuidedEventNotify (
Header.Data[0] = 0;
Size = sizeof (Header);
MmCommunication2Communicate (&mMmCommunication2, &Header, &Header, &Size);
MmCommunicationCommunicate (&mMmCommunication, &Header, &Size);
}
/**
@@ -307,7 +312,7 @@ MmGuidedEventNotify (
**/
EFI_STATUS
EFIAPI
MmCommunication2Initialize (
MmCommunicationInitialize (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
@@ -358,9 +363,9 @@ MmCommunication2Initialize (
// Install the communication protocol
Status = gBS->InstallProtocolInterface (
&mMmCommunicateHandle,
&gEfiMmCommunication2ProtocolGuid,
&gEfiMmCommunicationProtocolGuid,
EFI_NATIVE_INTERFACE,
&mMmCommunication2
&mMmCommunication
);
if (EFI_ERROR(Status)) {
DEBUG ((DEBUG_ERROR, "MmCommunicationInitialize: "
@@ -385,20 +390,12 @@ MmCommunication2Initialize (
MmGuidedEventNotify, mGuidedEventGuid[Index],
mGuidedEventGuid[Index], &mGuidedEvent[Index]);
ASSERT_EFI_ERROR (Status);
if (EFI_ERROR (Status)) {
while (Index-- > 0) {
gBS->CloseEvent (mGuidedEvent[Index]);
}
goto UninstallProtocol;
}
}
return EFI_SUCCESS;
UninstallProtocol:
gBS->UninstallProtocolInterface (
mMmCommunicateHandle,
&gEfiMmCommunication2ProtocolGuid,
&mMmCommunication2
&gEfiMmCommunicationProtocolGuid,
&mMmCommunication
);
CleanAddedMemorySpace:

View File

@@ -2,7 +2,7 @@
#
# DXE MM Communicate driver
#
# Copyright (c) 2016 - 2019, ARM Limited. All rights reserved.
# Copyright (c) 2016 - 2018, ARM Limited. All rights reserved.
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
@@ -14,7 +14,7 @@
FILE_GUID = 09EE81D3-F15E-43F4-85B4-CB9873DA5D6B
MODULE_TYPE = DXE_RUNTIME_DRIVER
VERSION_STRING = 1.0
ENTRY_POINT = MmCommunication2Initialize
ENTRY_POINT = MmCommunicationInitialize
#
# The following is for reference only and not required by
@@ -40,7 +40,7 @@
UefiDriverEntryPoint
[Protocols]
gEfiMmCommunication2ProtocolGuid ## PRODUCES
gEfiMmCommunicationProtocolGuid ## PRODUCES
[Guids]
gEfiEndOfDxeEventGroupGuid

View File

@@ -219,6 +219,11 @@ ArmReadCurrentEL (
VOID
);
UINT64
PageAttributeToGcdAttribute (
IN UINT64 PageAttributes
);
UINTN
ArmWriteCptr (
IN UINT64 Cptr

View File

@@ -211,6 +211,24 @@ ArmCleanInvalidateDataCacheEntryByMVA (
IN UINTN Address
);
VOID
EFIAPI
ArmInvalidateDataCacheEntryBySetWay (
IN UINTN SetWayFormat
);
VOID
EFIAPI
ArmCleanDataCacheEntryBySetWay (
IN UINTN SetWayFormat
);
VOID
EFIAPI
ArmCleanInvalidateDataCacheEntryBySetWay (
IN UINTN SetWayFormat
);
VOID
EFIAPI
ArmEnableDataCache (

View File

@@ -19,8 +19,7 @@ EFI_EXCEPTION_CALLBACK gDebuggerExceptionHandlers[MAX_AARCH64_EXCEPTION + 1] =
PHYSICAL_ADDRESS gExceptionVectorAlignmentMask = ARM_VECTOR_TABLE_ALIGNMENT;
UINTN gDebuggerNoHandlerValue = 0; // todo: define for AArch64
#define EL0_STACK_SIZE EFI_PAGES_TO_SIZE(2)
STATIC UINTN mNewStackBase[EL0_STACK_SIZE / sizeof (UINTN)];
#define EL0_STACK_PAGES 2
VOID
RegisterEl0Stack (
@@ -32,11 +31,14 @@ RETURN_STATUS ArchVectorConfig(
)
{
UINTN HcrReg;
UINT8 *Stack;
// Round down sp by 16 bytes alignment
RegisterEl0Stack (
(VOID *)(((UINTN)mNewStackBase + EL0_STACK_SIZE) & ~0xFUL)
);
Stack = AllocatePages (EL0_STACK_PAGES);
if (Stack == NULL) {
return RETURN_OUT_OF_RESOURCES;
}
RegisterEl0Stack ((UINT8 *)Stack + EFI_PAGES_TO_SIZE (EL0_STACK_PAGES));
if (ArmReadCurrentEL() == AARCH64_EL2) {
HcrReg = ArmReadHcr();

View File

@@ -7,13 +7,11 @@
**/
#include <Base.h>
#include <Library/ArmLib.h>
#include <Library/DebugLib.h>
#include <Uefi.h>
#include <Chipset/AArch64.h>
#include <Library/ArmLib.h>
#include <Library/BaseLib.h>
#include <Library/IoLib.h>
#include "AArch64Lib.h"
#include "ArmLibPrivate.h"
@@ -42,8 +40,6 @@ ArmInvalidateDataCache (
VOID
)
{
ASSERT (!ArmMmuEnabled ());
ArmDataSynchronizationBarrier ();
AArch64DataCacheOperation (ArmInvalidateDataCacheEntryBySetWay);
}
@@ -54,8 +50,6 @@ ArmCleanInvalidateDataCache (
VOID
)
{
ASSERT (!ArmMmuEnabled ());
ArmDataSynchronizationBarrier ();
AArch64DataCacheOperation (ArmCleanInvalidateDataCacheEntryBySetWay);
}
@@ -66,8 +60,6 @@ ArmCleanDataCache (
VOID
)
{
ASSERT (!ArmMmuEnabled ());
ArmDataSynchronizationBarrier ();
AArch64DataCacheOperation (ArmCleanDataCacheEntryBySetWay);
}

View File

@@ -17,23 +17,5 @@ AArch64AllDataCachesOperation (
IN AARCH64_CACHE_OPERATION DataCacheOperation
);
VOID
EFIAPI
ArmInvalidateDataCacheEntryBySetWay (
IN UINTN SetWayFormat
);
VOID
EFIAPI
ArmCleanDataCacheEntryBySetWay (
IN UINTN SetWayFormat
);
VOID
EFIAPI
ArmCleanInvalidateDataCacheEntryBySetWay (
IN UINTN SetWayFormat
);
#endif // __AARCH64_LIB_H__

View File

@@ -13,8 +13,6 @@
.set DAIF_RD_FIQ_BIT, (1 << 6)
.set DAIF_RD_IRQ_BIT, (1 << 7)
.set SCTLR_ELx_M_BIT_POS, (0)
ASM_FUNC(ArmReadMidr)
mrs x0, midr_el1 // Read from Main ID Register (MIDR)
ret
@@ -122,18 +120,13 @@ ASM_FUNC(ArmSetMAIR)
ASM_FUNC(ArmUpdateTranslationTableEntry)
dsb nshst
lsr x1, x1, #12
EL1_OR_EL2_OR_EL3(x2)
EL1_OR_EL2_OR_EL3(x0)
1: tlbi vaae1, x1 // TLB Invalidate VA , EL1
mrs x2, sctlr_el1
b 4f
2: tlbi vae2, x1 // TLB Invalidate VA , EL2
mrs x2, sctlr_el2
b 4f
3: tlbi vae3, x1 // TLB Invalidate VA , EL3
mrs x2, sctlr_el3
4: tbnz x2, SCTLR_ELx_M_BIT_POS, 5f
dc ivac, x0 // invalidate in Dcache if MMU is still off
5: dsb nsh
4: dsb nsh
isb
ret

View File

@@ -6,14 +6,11 @@
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include <Base.h>
#include <Library/ArmLib.h>
#include <Library/DebugLib.h>
#include <Uefi.h>
#include <Chipset/ArmV7.h>
#include <Library/ArmLib.h>
#include <Library/BaseLib.h>
#include <Library/IoLib.h>
#include "ArmV7Lib.h"
#include "ArmLibPrivate.h"
@@ -42,8 +39,6 @@ ArmInvalidateDataCache (
VOID
)
{
ASSERT (!ArmMmuEnabled ());
ArmDataSynchronizationBarrier ();
ArmV7DataCacheOperation (ArmInvalidateDataCacheEntryBySetWay);
}
@@ -54,8 +49,6 @@ ArmCleanInvalidateDataCache (
VOID
)
{
ASSERT (!ArmMmuEnabled ());
ArmDataSynchronizationBarrier ();
ArmV7DataCacheOperation (ArmCleanInvalidateDataCacheEntryBySetWay);
}
@@ -66,8 +59,6 @@ ArmCleanDataCache (
VOID
)
{
ASSERT (!ArmMmuEnabled ());
ArmDataSynchronizationBarrier ();
ArmV7DataCacheOperation (ArmCleanDataCacheEntryBySetWay);
}

View File

@@ -30,23 +30,5 @@ ArmV7AllDataCachesOperation (
IN ARM_V7_CACHE_OPERATION DataCacheOperation
);
VOID
EFIAPI
ArmInvalidateDataCacheEntryBySetWay (
IN UINTN SetWayFormat
);
VOID
EFIAPI
ArmCleanDataCacheEntryBySetWay (
IN UINTN SetWayFormat
);
VOID
EFIAPI
ArmCleanInvalidateDataCacheEntryBySetWay (
IN UINTN SetWayFormat
);
#endif // __ARM_V7_LIB_H__

View File

@@ -44,12 +44,12 @@
AArch64/AArch64Support.S
AArch64/AArch64ArchTimerSupport.S
[LibraryClasses]
DebugLib
[Packages]
ArmPkg/ArmPkg.dec
MdePkg/MdePkg.dec
[Protocols]
gEfiCpuArchProtocolGuid
[FeaturePcd.ARM]
gArmTokenSpaceGuid.PcdNormalMemoryNonshareableOverride

View File

@@ -10,6 +10,8 @@
#include <Base.h>
#include <Library/ArmLib.h>
#include <Library/DebugLib.h>
#include <Library/PcdLib.h>
#include "ArmLibPrivate.h"

View File

@@ -1,7 +1,7 @@
/** @file
* File managing the MMU for ARMv8 architecture
*
* Copyright (c) 2011-2020, ARM Limited. All rights reserved.
* Copyright (c) 2011-2014, ARM Limited. All rights reserved.
* Copyright (c) 2016, Linaro Limited. All rights reserved.
* Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
*
@@ -19,6 +19,9 @@
#include <Library/BaseLib.h>
#include <Library/DebugLib.h>
// We use this index definition to define an invalid block entry
#define TT_ATTR_INDX_INVALID ((UINT32)~0)
STATIC
UINT64
ArmMemoryAttributeToPageAttribute (
@@ -44,7 +47,7 @@ ArmMemoryAttributeToPageAttribute (
return TT_ATTR_INDX_MEMORY_NON_CACHEABLE;
default:
ASSERT (0);
ASSERT(0);
case ARM_MEMORY_REGION_ATTRIBUTE_DEVICE:
case ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_DEVICE:
if (ArmReadCurrentEL () == AARCH64_EL2)
@@ -54,40 +57,78 @@ ArmMemoryAttributeToPageAttribute (
}
}
#define MIN_T0SZ 16
#define BITS_PER_LEVEL 9
#define MAX_VA_BITS 48
STATIC
UINTN
GetRootTableEntryCount (
IN UINTN T0SZ
UINT64
PageAttributeToGcdAttribute (
IN UINT64 PageAttributes
)
{
return TT_ENTRY_COUNT >> (T0SZ - MIN_T0SZ) % BITS_PER_LEVEL;
UINT64 GcdAttributes;
switch (PageAttributes & TT_ATTR_INDX_MASK) {
case TT_ATTR_INDX_DEVICE_MEMORY:
GcdAttributes = EFI_MEMORY_UC;
break;
case TT_ATTR_INDX_MEMORY_NON_CACHEABLE:
GcdAttributes = EFI_MEMORY_WC;
break;
case TT_ATTR_INDX_MEMORY_WRITE_THROUGH:
GcdAttributes = EFI_MEMORY_WT;
break;
case TT_ATTR_INDX_MEMORY_WRITE_BACK:
GcdAttributes = EFI_MEMORY_WB;
break;
default:
DEBUG ((EFI_D_ERROR, "PageAttributeToGcdAttribute: PageAttributes:0x%lX not supported.\n", PageAttributes));
ASSERT (0);
// The Global Coherency Domain (GCD) value is defined as a bit set.
// Returning 0 means no attribute has been set.
GcdAttributes = 0;
}
// Determine protection attributes
if (((PageAttributes & TT_AP_MASK) == TT_AP_NO_RO) || ((PageAttributes & TT_AP_MASK) == TT_AP_RO_RO)) {
// Read only cases map to write-protect
GcdAttributes |= EFI_MEMORY_RO;
}
// Process eXecute Never attribute
if ((PageAttributes & (TT_PXN_MASK | TT_UXN_MASK)) != 0 ) {
GcdAttributes |= EFI_MEMORY_XP;
}
return GcdAttributes;
}
STATIC
UINTN
GetRootTableLevel (
IN UINTN T0SZ
#define MIN_T0SZ 16
#define BITS_PER_LEVEL 9
VOID
GetRootTranslationTableInfo (
IN UINTN T0SZ,
OUT UINTN *TableLevel,
OUT UINTN *TableEntryCount
)
{
return (T0SZ - MIN_T0SZ) / BITS_PER_LEVEL;
// Get the level of the root table
if (TableLevel) {
*TableLevel = (T0SZ - MIN_T0SZ) / BITS_PER_LEVEL;
}
if (TableEntryCount) {
*TableEntryCount = 1UL << (BITS_PER_LEVEL - (T0SZ - MIN_T0SZ) % BITS_PER_LEVEL);
}
}
STATIC
VOID
ReplaceTableEntry (
ReplaceLiveEntry (
IN UINT64 *Entry,
IN UINT64 Value,
IN UINT64 RegionStart,
IN BOOLEAN IsLiveBlockMapping
IN UINT64 RegionStart
)
{
if (!ArmMmuEnabled () || !IsLiveBlockMapping) {
if (!ArmMmuEnabled ()) {
*Entry = Value;
ArmUpdateTranslationTableEntry (Entry, (VOID *)(UINTN)RegionStart);
} else {
ArmReplaceLiveTranslationEntry (Entry, Value, RegionStart);
}
@@ -95,214 +136,258 @@ ReplaceTableEntry (
STATIC
VOID
FreePageTablesRecursive (
IN UINT64 *TranslationTable,
IN UINTN Level
LookupAddresstoRootTable (
IN UINT64 MaxAddress,
OUT UINTN *T0SZ,
OUT UINTN *TableEntryCount
)
{
UINTN Index;
UINTN TopBit;
ASSERT (Level <= 3);
// Check the parameters are not NULL
ASSERT ((T0SZ != NULL) && (TableEntryCount != NULL));
if (Level < 3) {
for (Index = 0; Index < TT_ENTRY_COUNT; Index++) {
if ((TranslationTable[Index] & TT_TYPE_MASK) == TT_TYPE_TABLE_ENTRY) {
FreePageTablesRecursive ((VOID *)(UINTN)(TranslationTable[Index] &
TT_ADDRESS_MASK_BLOCK_ENTRY),
Level + 1);
}
// Look for the highest bit set in MaxAddress
for (TopBit = 63; TopBit != 0; TopBit--) {
if ((1ULL << TopBit) & MaxAddress) {
// MaxAddress top bit is found
TopBit = TopBit + 1;
break;
}
}
FreePages (TranslationTable, 1);
ASSERT (TopBit != 0);
// Calculate T0SZ from the top bit of the MaxAddress
*T0SZ = 64 - TopBit;
// Get the Table info from T0SZ
GetRootTranslationTableInfo (*T0SZ, NULL, TableEntryCount);
}
STATIC
BOOLEAN
IsBlockEntry (
IN UINT64 Entry,
IN UINTN Level
UINT64*
GetBlockEntryListFromAddress (
IN UINT64 *RootTable,
IN UINT64 RegionStart,
OUT UINTN *TableLevel,
IN OUT UINT64 *BlockEntrySize,
OUT UINT64 **LastBlockEntry
)
{
if (Level == 3) {
return (Entry & TT_TYPE_MASK) == TT_TYPE_BLOCK_ENTRY_LEVEL3;
UINTN RootTableLevel;
UINTN RootTableEntryCount;
UINT64 *TranslationTable;
UINT64 *BlockEntry;
UINT64 *SubTableBlockEntry;
UINT64 BlockEntryAddress;
UINTN BaseAddressAlignment;
UINTN PageLevel;
UINTN Index;
UINTN IndexLevel;
UINTN T0SZ;
UINT64 Attributes;
UINT64 TableAttributes;
// Initialize variable
BlockEntry = NULL;
// Ensure the parameters are valid
if (!(TableLevel && BlockEntrySize && LastBlockEntry)) {
ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
return NULL;
}
return (Entry & TT_TYPE_MASK) == TT_TYPE_BLOCK_ENTRY;
}
STATIC
BOOLEAN
IsTableEntry (
IN UINT64 Entry,
IN UINTN Level
)
{
if (Level == 3) {
//
// TT_TYPE_TABLE_ENTRY aliases TT_TYPE_BLOCK_ENTRY_LEVEL3
// so we need to take the level into account as well.
//
return FALSE;
// Ensure the Region is aligned on 4KB boundary
if ((RegionStart & (SIZE_4KB - 1)) != 0) {
ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
return NULL;
}
return (Entry & TT_TYPE_MASK) == TT_TYPE_TABLE_ENTRY;
}
STATIC
EFI_STATUS
UpdateRegionMappingRecursive (
IN UINT64 RegionStart,
IN UINT64 RegionEnd,
IN UINT64 AttributeSetMask,
IN UINT64 AttributeClearMask,
IN UINT64 *PageTable,
IN UINTN Level
)
{
UINTN BlockShift;
UINT64 BlockMask;
UINT64 BlockEnd;
UINT64 *Entry;
UINT64 EntryValue;
VOID *TranslationTable;
EFI_STATUS Status;
// Ensure the required size is aligned on 4KB boundary and not 0
if ((*BlockEntrySize & (SIZE_4KB - 1)) != 0 || *BlockEntrySize == 0) {
ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
return NULL;
}
ASSERT (((RegionStart | RegionEnd) & EFI_PAGE_MASK) == 0);
T0SZ = ArmGetTCR () & TCR_T0SZ_MASK;
// Get the Table info from T0SZ
GetRootTranslationTableInfo (T0SZ, &RootTableLevel, &RootTableEntryCount);
BlockShift = (Level + 1) * BITS_PER_LEVEL + MIN_T0SZ;
BlockMask = MAX_UINT64 >> BlockShift;
// If the start address is 0x0 then we use the size of the region to identify the alignment
if (RegionStart == 0) {
// Identify the highest possible alignment for the Region Size
BaseAddressAlignment = LowBitSet64 (*BlockEntrySize);
} else {
// Identify the highest possible alignment for the Base Address
BaseAddressAlignment = LowBitSet64 (RegionStart);
}
DEBUG ((DEBUG_VERBOSE, "%a(%d): %llx - %llx set %lx clr %lx\n", __FUNCTION__,
Level, RegionStart, RegionEnd, AttributeSetMask, AttributeClearMask));
// Identify the Page Level the RegionStart must belong to. Note that PageLevel
// should be at least 1 since block translations are not supported at level 0
PageLevel = MAX (3 - ((BaseAddressAlignment - 12) / 9), 1);
for (; RegionStart < RegionEnd; RegionStart = BlockEnd) {
BlockEnd = MIN (RegionEnd, (RegionStart | BlockMask) + 1);
Entry = &PageTable[(RegionStart >> (64 - BlockShift)) & (TT_ENTRY_COUNT - 1)];
// If the required size is smaller than the current block size then we need to go to the page below.
// The PageLevel was calculated on the Base Address alignment but did not take in account the alignment
// of the allocation size
while (*BlockEntrySize < TT_BLOCK_ENTRY_SIZE_AT_LEVEL (PageLevel)) {
// It does not fit so we need to go a page level above
PageLevel++;
}
//
// If RegionStart or BlockEnd is not aligned to the block size at this
// level, we will have to create a table mapping in order to map less
// than a block, and recurse to create the block or page entries at
// the next level. No block mappings are allowed at all at level 0,
// so in that case, we have to recurse unconditionally.
// If we are changing a table entry and the AttributeClearMask is non-zero,
// we cannot replace it with a block entry without potentially losing
// attribute information, so keep the table entry in that case.
//
if (Level == 0 || ((RegionStart | BlockEnd) & BlockMask) != 0 ||
(IsTableEntry (*Entry, Level) && AttributeClearMask != 0)) {
ASSERT (Level < 3);
//
// Get the Table Descriptor for the corresponding PageLevel. We need to decompose RegionStart to get appropriate entries
//
if (!IsTableEntry (*Entry, Level)) {
//
// No table entry exists yet, so we need to allocate a page table
// for the next level.
//
TranslationTable = RootTable;
for (IndexLevel = RootTableLevel; IndexLevel <= PageLevel; IndexLevel++) {
BlockEntry = (UINT64*)TT_GET_ENTRY_FOR_ADDRESS (TranslationTable, IndexLevel, RegionStart);
if ((IndexLevel != 3) && ((*BlockEntry & TT_TYPE_MASK) == TT_TYPE_TABLE_ENTRY)) {
// Go to the next table
TranslationTable = (UINT64*)(*BlockEntry & TT_ADDRESS_MASK_DESCRIPTION_TABLE);
// If we are at the last level then update the last level to next level
if (IndexLevel == PageLevel) {
// Enter the next level
PageLevel++;
}
} else if ((*BlockEntry & TT_TYPE_MASK) == TT_TYPE_BLOCK_ENTRY) {
// If we are not at the last level then we need to split this BlockEntry
if (IndexLevel != PageLevel) {
// Retrieve the attributes from the block entry
Attributes = *BlockEntry & TT_ATTRIBUTES_MASK;
// Convert the block entry attributes into Table descriptor attributes
TableAttributes = TT_TABLE_AP_NO_PERMISSION;
if (Attributes & TT_NS) {
TableAttributes = TT_TABLE_NS;
}
// Get the address corresponding at this entry
BlockEntryAddress = RegionStart;
BlockEntryAddress = BlockEntryAddress >> TT_ADDRESS_OFFSET_AT_LEVEL(IndexLevel);
// Shift back to right to set zero before the effective address
BlockEntryAddress = BlockEntryAddress << TT_ADDRESS_OFFSET_AT_LEVEL(IndexLevel);
// Set the correct entry type for the next page level
if ((IndexLevel + 1) == 3) {
Attributes |= TT_TYPE_BLOCK_ENTRY_LEVEL3;
} else {
Attributes |= TT_TYPE_BLOCK_ENTRY;
}
// Create a new translation table
TranslationTable = AllocatePages (1);
if (TranslationTable == NULL) {
return EFI_OUT_OF_RESOURCES;
return NULL;
}
if (!ArmMmuEnabled ()) {
//
// Make sure we are not inadvertently hitting in the caches
// when populating the page tables.
//
InvalidateDataCacheRange (TranslationTable, EFI_PAGE_SIZE);
// Populate the newly created lower level table
SubTableBlockEntry = TranslationTable;
for (Index = 0; Index < TT_ENTRY_COUNT; Index++) {
*SubTableBlockEntry = Attributes | (BlockEntryAddress + (Index << TT_ADDRESS_OFFSET_AT_LEVEL(IndexLevel + 1)));
SubTableBlockEntry++;
}
ZeroMem (TranslationTable, EFI_PAGE_SIZE);
if (IsBlockEntry (*Entry, Level)) {
//
// We are splitting an existing block entry, so we have to populate
// the new table with the attributes of the block entry it replaces.
//
Status = UpdateRegionMappingRecursive (RegionStart & ~BlockMask,
(RegionStart | BlockMask) + 1, *Entry & TT_ATTRIBUTES_MASK,
0, TranslationTable, Level + 1);
if (EFI_ERROR (Status)) {
//
// The range we passed to UpdateRegionMappingRecursive () is block
// aligned, so it is guaranteed that no further pages were allocated
// by it, and so we only have to free the page we allocated here.
//
FreePages (TranslationTable, 1);
return Status;
}
}
} else {
TranslationTable = (VOID *)(UINTN)(*Entry & TT_ADDRESS_MASK_BLOCK_ENTRY);
}
//
// Recurse to the next level
//
Status = UpdateRegionMappingRecursive (RegionStart, BlockEnd,
AttributeSetMask, AttributeClearMask, TranslationTable,
Level + 1);
if (EFI_ERROR (Status)) {
if (!IsTableEntry (*Entry, Level)) {
//
// We are creating a new table entry, so on failure, we can free all
// allocations we made recursively, given that the whole subhierarchy
// has not been wired into the live page tables yet. (This is not
// possible for existing table entries, since we cannot revert the
// modifications we made to the subhierarchy it represents.)
//
FreePageTablesRecursive (TranslationTable, Level + 1);
}
return Status;
}
if (!IsTableEntry (*Entry, Level)) {
EntryValue = (UINTN)TranslationTable | TT_TYPE_TABLE_ENTRY;
ReplaceTableEntry (Entry, EntryValue, RegionStart,
IsBlockEntry (*Entry, Level));
// Fill the BlockEntry with the new TranslationTable
ReplaceLiveEntry (BlockEntry,
(UINTN)TranslationTable | TableAttributes | TT_TYPE_TABLE_ENTRY,
RegionStart);
}
} else {
EntryValue = (*Entry & AttributeClearMask) | AttributeSetMask;
EntryValue |= RegionStart;
EntryValue |= (Level == 3) ? TT_TYPE_BLOCK_ENTRY_LEVEL3
: TT_TYPE_BLOCK_ENTRY;
if (IndexLevel != PageLevel) {
//
// Case when we have an Invalid Entry and we are at a page level above of the one targetted.
//
if (IsTableEntry (*Entry, Level)) {
//
// We are replacing a table entry with a block entry. This is only
// possible if we are keeping none of the original attributes.
// We can free the table entry's page table, and all the ones below
// it, since we are dropping the only possible reference to it.
//
ASSERT (AttributeClearMask == 0);
TranslationTable = (VOID *)(UINTN)(*Entry & TT_ADDRESS_MASK_BLOCK_ENTRY);
ReplaceTableEntry (Entry, EntryValue, RegionStart, TRUE);
FreePageTablesRecursive (TranslationTable, Level + 1);
} else {
ReplaceTableEntry (Entry, EntryValue, RegionStart, FALSE);
// Create a new translation table
TranslationTable = AllocatePages (1);
if (TranslationTable == NULL) {
return NULL;
}
ZeroMem (TranslationTable, TT_ENTRY_COUNT * sizeof(UINT64));
// Fill the new BlockEntry with the TranslationTable
*BlockEntry = ((UINTN)TranslationTable & TT_ADDRESS_MASK_DESCRIPTION_TABLE) | TT_TYPE_TABLE_ENTRY;
}
}
}
return EFI_SUCCESS;
// Expose the found PageLevel to the caller
*TableLevel = PageLevel;
// Now, we have the Table Level we can get the Block Size associated to this table
*BlockEntrySize = TT_BLOCK_ENTRY_SIZE_AT_LEVEL (PageLevel);
// The last block of the root table depends on the number of entry in this table,
// otherwise it is always the (TT_ENTRY_COUNT - 1)th entry in the table.
*LastBlockEntry = TT_LAST_BLOCK_ADDRESS(TranslationTable,
(PageLevel == RootTableLevel) ? RootTableEntryCount : TT_ENTRY_COUNT);
return BlockEntry;
}
STATIC
EFI_STATUS
UpdateRegionMapping (
IN UINT64 *RootTable,
IN UINT64 RegionStart,
IN UINT64 RegionLength,
IN UINT64 AttributeSetMask,
IN UINT64 AttributeClearMask
IN UINT64 Attributes,
IN UINT64 BlockEntryMask
)
{
UINTN T0SZ;
UINT32 Type;
UINT64 *BlockEntry;
UINT64 *LastBlockEntry;
UINT64 BlockEntrySize;
UINTN TableLevel;
if (((RegionStart | RegionLength) & EFI_PAGE_MASK)) {
// Ensure the Length is aligned on 4KB boundary
if ((RegionLength == 0) || ((RegionLength & (SIZE_4KB - 1)) != 0)) {
ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
return EFI_INVALID_PARAMETER;
}
T0SZ = ArmGetTCR () & TCR_T0SZ_MASK;
do {
// Get the first Block Entry that matches the Virtual Address and also the information on the Table Descriptor
// such as the size of the Block Entry and the address of the last BlockEntry of the Table Descriptor
BlockEntrySize = RegionLength;
BlockEntry = GetBlockEntryListFromAddress (RootTable, RegionStart, &TableLevel, &BlockEntrySize, &LastBlockEntry);
if (BlockEntry == NULL) {
// GetBlockEntryListFromAddress() return NULL when it fails to allocate new pages from the Translation Tables
return EFI_OUT_OF_RESOURCES;
}
return UpdateRegionMappingRecursive (RegionStart, RegionStart + RegionLength,
AttributeSetMask, AttributeClearMask, ArmGetTTBR0BaseAddress (),
GetRootTableLevel (T0SZ));
if (TableLevel != 3) {
Type = TT_TYPE_BLOCK_ENTRY;
} else {
Type = TT_TYPE_BLOCK_ENTRY_LEVEL3;
}
do {
// Fill the Block Entry with attribute and output block address
*BlockEntry &= BlockEntryMask;
*BlockEntry |= (RegionStart & TT_ADDRESS_MASK_BLOCK_ENTRY) | Attributes | Type;
ArmUpdateTranslationTableEntry (BlockEntry, (VOID *)RegionStart);
// Go to the next BlockEntry
RegionStart += BlockEntrySize;
RegionLength -= BlockEntrySize;
BlockEntry++;
// Break the inner loop when next block is a table
// Rerun GetBlockEntryListFromAddress to avoid page table memory leak
if (TableLevel != 3 && BlockEntry <= LastBlockEntry &&
(*BlockEntry & TT_TYPE_MASK) == TT_TYPE_TABLE_ENTRY) {
break;
}
} while ((RegionLength >= BlockEntrySize) && (BlockEntry <= LastBlockEntry));
} while (RegionLength != 0);
return EFI_SUCCESS;
}
STATIC
@@ -313,6 +398,7 @@ FillTranslationTable (
)
{
return UpdateRegionMapping (
RootTable,
MemoryRegion->VirtualBase,
MemoryRegion->Length,
ArmMemoryAttributeToPageAttribute (MemoryRegion->Attributes) | TT_AF,
@@ -369,6 +455,8 @@ ArmSetMemoryAttributes (
IN UINT64 Attributes
)
{
EFI_STATUS Status;
UINT64 *TranslationTable;
UINT64 PageAttributes;
UINT64 PageAttributeMask;
@@ -385,8 +473,19 @@ ArmSetMemoryAttributes (
TT_PXN_MASK | TT_XN_MASK);
}
return UpdateRegionMapping (BaseAddress, Length, PageAttributes,
PageAttributeMask);
TranslationTable = ArmGetTTBR0BaseAddress ();
Status = UpdateRegionMapping (
TranslationTable,
BaseAddress,
Length,
PageAttributes,
PageAttributeMask);
if (EFI_ERROR (Status)) {
return Status;
}
return EFI_SUCCESS;
}
STATIC
@@ -398,7 +497,17 @@ SetMemoryRegionAttribute (
IN UINT64 BlockEntryMask
)
{
return UpdateRegionMapping (BaseAddress, Length, Attributes, BlockEntryMask);
EFI_STATUS Status;
UINT64 *RootTable;
RootTable = ArmGetTTBR0BaseAddress ();
Status = UpdateRegionMapping (RootTable, BaseAddress, Length, Attributes, BlockEntryMask);
if (EFI_ERROR (Status)) {
return Status;
}
return EFI_SUCCESS;
}
EFI_STATUS
@@ -475,14 +584,14 @@ ArmConfigureMmu (
)
{
VOID* TranslationTable;
UINTN MaxAddressBits;
UINT32 TranslationTableAttribute;
UINT64 MaxAddress;
UINTN T0SZ;
UINTN RootTableEntryCount;
UINT64 TCR;
EFI_STATUS Status;
if (MemoryTable == NULL) {
if(MemoryTable == NULL) {
ASSERT (MemoryTable != NULL);
return EFI_INVALID_PARAMETER;
}
@@ -494,11 +603,11 @@ ArmConfigureMmu (
// into account the architectural limitations that result from UEFI's
// use of 4 KB pages.
//
MaxAddressBits = MIN (ArmGetPhysicalAddressBits (), MAX_VA_BITS);
MaxAddress = LShiftU64 (1ULL, MaxAddressBits) - 1;
MaxAddress = MIN (LShiftU64 (1ULL, ArmGetPhysicalAddressBits ()) - 1,
MAX_ALLOC_ADDRESS);
T0SZ = 64 - MaxAddressBits;
RootTableEntryCount = GetRootTableEntryCount (T0SZ);
// Lookup the Table Level to get the information
LookupAddresstoRootTable (MaxAddress, &T0SZ, &RootTableEntryCount);
//
// Set TCR that allows us to retrieve T0SZ in the subsequent functions
@@ -523,9 +632,7 @@ ArmConfigureMmu (
} else if (MaxAddress < SIZE_256TB) {
TCR |= TCR_PS_256TB;
} else {
DEBUG ((DEBUG_ERROR,
"ArmConfigureMmu: The MaxAddress 0x%lX is not supported by this MMU configuration.\n",
MaxAddress));
DEBUG ((EFI_D_ERROR, "ArmConfigureMmu: The MaxAddress 0x%lX is not supported by this MMU configuration.\n", MaxAddress));
ASSERT (0); // Bigger than 48-bit memory space are not supported
return EFI_UNSUPPORTED;
}
@@ -547,9 +654,7 @@ ArmConfigureMmu (
} else if (MaxAddress < SIZE_256TB) {
TCR |= TCR_IPS_256TB;
} else {
DEBUG ((DEBUG_ERROR,
"ArmConfigureMmu: The MaxAddress 0x%lX is not supported by this MMU configuration.\n",
MaxAddress));
DEBUG ((EFI_D_ERROR, "ArmConfigureMmu: The MaxAddress 0x%lX is not supported by this MMU configuration.\n", MaxAddress));
ASSERT (0); // Bigger than 48-bit memory space are not supported
return EFI_UNSUPPORTED;
}
@@ -579,12 +684,9 @@ ArmConfigureMmu (
if (TranslationTable == NULL) {
return EFI_OUT_OF_RESOURCES;
}
//
// We set TTBR0 just after allocating the table to retrieve its location from
// the subsequent functions without needing to pass this value across the
// functions. The MMU is only enabled after the translation tables are
// populated.
//
// We set TTBR0 just after allocating the table to retrieve its location from the subsequent
// functions without needing to pass this value across the functions. The MMU is only enabled
// after the translation tables are populated.
ArmSetTTBR0 (TranslationTable);
if (TranslationTableBase != NULL) {
@@ -592,37 +694,46 @@ ArmConfigureMmu (
}
if (TranslationTableSize != NULL) {
*TranslationTableSize = RootTableEntryCount * sizeof (UINT64);
*TranslationTableSize = RootTableEntryCount * sizeof(UINT64);
}
//
// Make sure we are not inadvertently hitting in the caches
// when populating the page tables.
//
InvalidateDataCacheRange (TranslationTable,
RootTableEntryCount * sizeof (UINT64));
ZeroMem (TranslationTable, RootTableEntryCount * sizeof (UINT64));
ZeroMem (TranslationTable, RootTableEntryCount * sizeof(UINT64));
// Disable MMU and caches. ArmDisableMmu() also invalidates the TLBs
ArmDisableMmu ();
ArmDisableDataCache ();
ArmDisableInstructionCache ();
// Make sure nothing sneaked into the cache
ArmCleanInvalidateDataCache ();
ArmInvalidateInstructionCache ();
TranslationTableAttribute = TT_ATTR_INDX_INVALID;
while (MemoryTable->Length != 0) {
DEBUG_CODE_BEGIN ();
// Find the memory attribute for the Translation Table
if ((UINTN)TranslationTable >= MemoryTable->PhysicalBase &&
(UINTN)TranslationTable + EFI_PAGE_SIZE <= MemoryTable->PhysicalBase +
MemoryTable->Length) {
TranslationTableAttribute = MemoryTable->Attributes;
}
DEBUG_CODE_END ();
Status = FillTranslationTable (TranslationTable, MemoryTable);
if (EFI_ERROR (Status)) {
goto FreeTranslationTable;
goto FREE_TRANSLATION_TABLE;
}
MemoryTable++;
}
//
// EFI_MEMORY_UC ==> MAIR_ATTR_DEVICE_MEMORY
// EFI_MEMORY_WC ==> MAIR_ATTR_NORMAL_MEMORY_NON_CACHEABLE
// EFI_MEMORY_WT ==> MAIR_ATTR_NORMAL_MEMORY_WRITE_THROUGH
// EFI_MEMORY_WB ==> MAIR_ATTR_NORMAL_MEMORY_WRITE_BACK
//
ArmSetMAIR (
MAIR_ATTR (TT_ATTR_INDX_DEVICE_MEMORY, MAIR_ATTR_DEVICE_MEMORY) |
MAIR_ATTR (TT_ATTR_INDX_MEMORY_NON_CACHEABLE, MAIR_ATTR_NORMAL_MEMORY_NON_CACHEABLE) |
MAIR_ATTR (TT_ATTR_INDX_MEMORY_WRITE_THROUGH, MAIR_ATTR_NORMAL_MEMORY_WRITE_THROUGH) |
MAIR_ATTR (TT_ATTR_INDX_MEMORY_WRITE_BACK, MAIR_ATTR_NORMAL_MEMORY_WRITE_BACK)
);
ASSERT (TranslationTableAttribute == ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK ||
TranslationTableAttribute == ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_WRITE_BACK);
ArmSetMAIR (MAIR_ATTR(TT_ATTR_INDX_DEVICE_MEMORY, MAIR_ATTR_DEVICE_MEMORY) | // mapped to EFI_MEMORY_UC
MAIR_ATTR(TT_ATTR_INDX_MEMORY_NON_CACHEABLE, MAIR_ATTR_NORMAL_MEMORY_NON_CACHEABLE) | // mapped to EFI_MEMORY_WC
MAIR_ATTR(TT_ATTR_INDX_MEMORY_WRITE_THROUGH, MAIR_ATTR_NORMAL_MEMORY_WRITE_THROUGH) | // mapped to EFI_MEMORY_WT
MAIR_ATTR(TT_ATTR_INDX_MEMORY_WRITE_BACK, MAIR_ATTR_NORMAL_MEMORY_WRITE_BACK)); // mapped to EFI_MEMORY_WB
ArmDisableAlignmentCheck ();
ArmEnableStackAlignmentCheck ();
@@ -632,7 +743,7 @@ ArmConfigureMmu (
ArmEnableMmu ();
return EFI_SUCCESS;
FreeTranslationTable:
FREE_TRANSLATION_TABLE:
FreePages (TranslationTable, 1);
return Status;
}
@@ -649,7 +760,7 @@ ArmMmuBaseLibConstructor (
// The ArmReplaceLiveTranslationEntry () helper function may be invoked
// with the MMU off so we have to ensure that it gets cleaned to the PoC
//
WriteBackDataCacheRange ((VOID *)(UINTN)ArmReplaceLiveTranslationEntry,
WriteBackDataCacheRange (ArmReplaceLiveTranslationEntry,
ArmReplaceLiveTranslationEntrySize);
return RETURN_SUCCESS;

View File

@@ -47,7 +47,7 @@ ArmMmuPeiLibConstructor (
// The ArmReplaceLiveTranslationEntry () helper function may be invoked
// with the MMU off so we have to ensure that it gets cleaned to the PoC
//
WriteBackDataCacheRange ((VOID *)(UINTN)ArmReplaceLiveTranslationEntry,
WriteBackDataCacheRange (ArmReplaceLiveTranslationEntry,
ArmReplaceLiveTranslationEntrySize);
}

View File

@@ -1,32 +0,0 @@
/** @file
* File managing the MMU for ARMv7 architecture
*
* Copyright (c) 2011-2016, ARM Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-2-Clause-Patent
*
**/
#include <Uefi.h>
#include <Library/ArmLib.h>
#include <Chipset/ArmV7.h>
UINT32
ConvertSectionAttributesToPageAttributes (
IN UINT32 SectionAttributes,
IN BOOLEAN IsLargePage
)
{
UINT32 PageAttributes;
PageAttributes = 0;
PageAttributes |= TT_DESCRIPTOR_CONVERT_TO_PAGE_CACHE_POLICY (SectionAttributes, IsLargePage);
PageAttributes |= TT_DESCRIPTOR_CONVERT_TO_PAGE_AP (SectionAttributes);
PageAttributes |= TT_DESCRIPTOR_CONVERT_TO_PAGE_XN (SectionAttributes, IsLargePage);
PageAttributes |= TT_DESCRIPTOR_CONVERT_TO_PAGE_NG (SectionAttributes);
PageAttributes |= TT_DESCRIPTOR_CONVERT_TO_PAGE_S (SectionAttributes);
return PageAttributes;
}

View File

@@ -31,6 +31,15 @@
#define ID_MMFR0_SHR_IMP_HW_COHERENT 1
#define ID_MMFR0_SHR_IGNORED 0xf
#define __EFI_MEMORY_RWX 0 // no restrictions
#define CACHE_ATTRIBUTE_MASK (EFI_MEMORY_UC | \
EFI_MEMORY_WC | \
EFI_MEMORY_WT | \
EFI_MEMORY_WB | \
EFI_MEMORY_UCE | \
EFI_MEMORY_WP)
UINTN
EFIAPI
ArmReadIdMmfr0 (
@@ -43,6 +52,24 @@ ArmHasMpExtensions (
VOID
);
UINT32
ConvertSectionAttributesToPageAttributes (
IN UINT32 SectionAttributes,
IN BOOLEAN IsLargePage
)
{
UINT32 PageAttributes;
PageAttributes = 0;
PageAttributes |= TT_DESCRIPTOR_CONVERT_TO_PAGE_CACHE_POLICY (SectionAttributes, IsLargePage);
PageAttributes |= TT_DESCRIPTOR_CONVERT_TO_PAGE_AP (SectionAttributes);
PageAttributes |= TT_DESCRIPTOR_CONVERT_TO_PAGE_XN (SectionAttributes, IsLargePage);
PageAttributes |= TT_DESCRIPTOR_CONVERT_TO_PAGE_NG (SectionAttributes);
PageAttributes |= TT_DESCRIPTOR_CONVERT_TO_PAGE_S (SectionAttributes);
return PageAttributes;
}
STATIC
BOOLEAN
PreferNonshareableMemory (
@@ -138,22 +165,14 @@ PopulateLevel2PageTable (
// Case where a virtual memory map descriptor overlapped a section entry
// Allocate a Level2 Page Table for this Section
TranslationTable = (UINTN)AllocateAlignedPages (
EFI_SIZE_TO_PAGES (TRANSLATION_TABLE_PAGE_SIZE),
TRANSLATION_TABLE_PAGE_ALIGNMENT);
TranslationTable = (UINTN)AllocatePages(EFI_SIZE_TO_PAGES(TRANSLATION_TABLE_PAGE_SIZE + TRANSLATION_TABLE_PAGE_ALIGNMENT));
TranslationTable = ((UINTN)TranslationTable + TRANSLATION_TABLE_PAGE_ALIGNMENT_MASK) & ~TRANSLATION_TABLE_PAGE_ALIGNMENT_MASK;
// Translate the Section Descriptor into Page Descriptor
SectionDescriptor = TT_DESCRIPTOR_PAGE_TYPE_PAGE | ConvertSectionAttributesToPageAttributes (*SectionEntry, FALSE);
BaseSectionAddress = TT_DESCRIPTOR_SECTION_BASE_ADDRESS(*SectionEntry);
//
// Make sure we are not inadvertently hitting in the caches
// when populating the page tables
//
InvalidateDataCacheRange ((VOID *)TranslationTable,
TRANSLATION_TABLE_PAGE_SIZE);
// Populate the new Level2 Page Table for the section
PageEntry = (UINT32*)TranslationTable;
for (Index = 0; Index < TRANSLATION_TABLE_PAGE_COUNT; Index++) {
@@ -170,15 +189,9 @@ PopulateLevel2PageTable (
return;
}
} else {
TranslationTable = (UINTN)AllocateAlignedPages (
EFI_SIZE_TO_PAGES (TRANSLATION_TABLE_PAGE_SIZE),
TRANSLATION_TABLE_PAGE_ALIGNMENT);
//
// Make sure we are not inadvertently hitting in the caches
// when populating the page tables
//
InvalidateDataCacheRange ((VOID *)TranslationTable,
TRANSLATION_TABLE_PAGE_SIZE);
TranslationTable = (UINTN)AllocatePages(EFI_SIZE_TO_PAGES(TRANSLATION_TABLE_PAGE_SIZE + TRANSLATION_TABLE_PAGE_ALIGNMENT));
TranslationTable = ((UINTN)TranslationTable + TRANSLATION_TABLE_PAGE_ALIGNMENT_MASK) & ~TRANSLATION_TABLE_PAGE_ALIGNMENT_MASK;
ZeroMem ((VOID *)TranslationTable, TRANSLATION_TABLE_PAGE_SIZE);
*SectionEntry = (TranslationTable & TT_DESCRIPTOR_SECTION_PAGETABLE_ADDRESS_MASK) |
@@ -197,13 +210,6 @@ PopulateLevel2PageTable (
PhysicalBase += TT_DESCRIPTOR_PAGE_SIZE;
}
//
// Invalidate again to ensure that any line fetches that may have occurred
// [speculatively] since the previous invalidate are evicted again.
//
ArmDataMemoryBarrier ();
InvalidateDataCacheRange ((UINT32 *)TranslationTable + FirstPageOffset,
RemainLength / TT_DESCRIPTOR_PAGE_SIZE * sizeof (*PageEntry));
}
STATIC
@@ -225,7 +231,7 @@ FillTranslationTable (
return;
}
PhysicalBase = (UINT32)MemoryRegion->PhysicalBase;
PhysicalBase = MemoryRegion->PhysicalBase;
RemainLength = MIN(MemoryRegion->Length, SIZE_4GB - PhysicalBase);
switch (MemoryRegion->Attributes) {
@@ -278,36 +284,19 @@ FillTranslationTable (
RemainLength >= TT_DESCRIPTOR_SECTION_SIZE) {
// Case: Physical address aligned on the Section Size (1MB) && the length
// is greater than the Section Size
*SectionEntry = TT_DESCRIPTOR_SECTION_BASE_ADDRESS(PhysicalBase) | Attributes;
//
// Issue a DMB to ensure that the page table entry update made it to
// memory before we issue the invalidate, otherwise, a subsequent
// speculative fetch could observe the old value.
//
ArmDataMemoryBarrier ();
ArmInvalidateDataCacheEntryByMVA ((UINTN)SectionEntry++);
*SectionEntry++ = TT_DESCRIPTOR_SECTION_BASE_ADDRESS(PhysicalBase) | Attributes;
PhysicalBase += TT_DESCRIPTOR_SECTION_SIZE;
RemainLength -= TT_DESCRIPTOR_SECTION_SIZE;
} else {
PageMapLength = MIN ((UINT32)RemainLength, TT_DESCRIPTOR_SECTION_SIZE -
PageMapLength = MIN (RemainLength, TT_DESCRIPTOR_SECTION_SIZE -
(PhysicalBase % TT_DESCRIPTOR_SECTION_SIZE));
// Case: Physical address aligned on the Section Size (1MB) && the length
// does not fill a section
// Case: Physical address NOT aligned on the Section Size (1MB)
PopulateLevel2PageTable (SectionEntry, PhysicalBase, PageMapLength,
PopulateLevel2PageTable (SectionEntry++, PhysicalBase, PageMapLength,
MemoryRegion->Attributes);
//
// Issue a DMB to ensure that the page table entry update made it to
// memory before we issue the invalidate, otherwise, a subsequent
// speculative fetch could observe the old value.
//
ArmDataMemoryBarrier ();
ArmInvalidateDataCacheEntryByMVA ((UINTN)SectionEntry++);
// If it is the last entry
if (RemainLength < TT_DESCRIPTOR_SECTION_SIZE) {
break;
@@ -327,15 +316,16 @@ ArmConfigureMmu (
OUT UINTN *TranslationTableSize OPTIONAL
)
{
VOID *TranslationTable;
VOID* TranslationTable;
ARM_MEMORY_REGION_ATTRIBUTES TranslationTableAttribute;
UINT32 TTBRAttributes;
TranslationTable = AllocateAlignedPages (
EFI_SIZE_TO_PAGES (TRANSLATION_TABLE_SECTION_SIZE),
TRANSLATION_TABLE_SECTION_ALIGNMENT);
// Allocate pages for translation table.
TranslationTable = AllocatePages (EFI_SIZE_TO_PAGES (TRANSLATION_TABLE_SECTION_SIZE + TRANSLATION_TABLE_SECTION_ALIGNMENT));
if (TranslationTable == NULL) {
return RETURN_OUT_OF_RESOURCES;
}
TranslationTable = (VOID*)(((UINTN)TranslationTable + TRANSLATION_TABLE_SECTION_ALIGNMENT_MASK) & ~TRANSLATION_TABLE_SECTION_ALIGNMENT_MASK);
if (TranslationTableBase != NULL) {
*TranslationTableBase = TranslationTable;
@@ -345,20 +335,30 @@ ArmConfigureMmu (
*TranslationTableSize = TRANSLATION_TABLE_SECTION_SIZE;
}
//
// Make sure we are not inadvertently hitting in the caches
// when populating the page tables
//
InvalidateDataCacheRange (TranslationTable, TRANSLATION_TABLE_SECTION_SIZE);
ZeroMem (TranslationTable, TRANSLATION_TABLE_SECTION_SIZE);
// By default, mark the translation table as belonging to a uncached region
TranslationTableAttribute = ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED;
while (MemoryTable->Length != 0) {
// Find the memory attribute for the Translation Table
if (((UINTN)TranslationTable >= MemoryTable->PhysicalBase) && ((UINTN)TranslationTable <= MemoryTable->PhysicalBase - 1 + MemoryTable->Length)) {
TranslationTableAttribute = MemoryTable->Attributes;
}
FillTranslationTable (TranslationTable, MemoryTable);
MemoryTable++;
}
TTBRAttributes = ArmHasMpExtensions () ? TTBR_MP_WRITE_BACK_ALLOC
: TTBR_WRITE_BACK_ALLOC;
// Translate the Memory Attributes into Translation Table Register Attributes
if ((TranslationTableAttribute == ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK) ||
(TranslationTableAttribute == ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_WRITE_BACK)) {
TTBRAttributes = ArmHasMpExtensions () ? TTBR_MP_WRITE_BACK_ALLOC : TTBR_WRITE_BACK_ALLOC;
} else {
// Page tables must reside in memory mapped as write-back cacheable
ASSERT (0);
return RETURN_UNSUPPORTED;
}
if (TTBRAttributes & TTBR_SHAREABLE) {
if (PreferNonshareableMemory ()) {
TTBRAttributes ^= TTBR_SHAREABLE;
@@ -376,7 +376,19 @@ ArmConfigureMmu (
}
}
ArmSetTTBR0 ((VOID *)((UINTN)TranslationTable | TTBRAttributes));
ArmCleanInvalidateDataCache ();
ArmInvalidateInstructionCache ();
ArmDisableDataCache ();
ArmDisableInstructionCache();
// TLBs are also invalidated when calling ArmDisableMmu()
ArmDisableMmu ();
// Make sure nothing sneaked into the cache
ArmCleanInvalidateDataCache ();
ArmInvalidateInstructionCache ();
ArmSetTTBR0 ((VOID *)(UINTN)(((UINTN)TranslationTable & ~TRANSLATION_TABLE_SECTION_ALIGNMENT_MASK) | (TTBRAttributes & 0x7F)));
//
// The TTBCR register value is undefined at reset in the Non-Secure world.
@@ -411,3 +423,419 @@ ArmConfigureMmu (
ArmEnableMmu();
return RETURN_SUCCESS;
}
STATIC
EFI_STATUS
ConvertSectionToPages (
IN EFI_PHYSICAL_ADDRESS BaseAddress
)
{
UINT32 FirstLevelIdx;
UINT32 SectionDescriptor;
UINT32 PageTableDescriptor;
UINT32 PageDescriptor;
UINT32 Index;
volatile ARM_FIRST_LEVEL_DESCRIPTOR *FirstLevelTable;
volatile ARM_PAGE_TABLE_ENTRY *PageTable;
DEBUG ((EFI_D_PAGE, "Converting section at 0x%x to pages\n", (UINTN)BaseAddress));
// Obtain page table base
FirstLevelTable = (ARM_FIRST_LEVEL_DESCRIPTOR *)ArmGetTTBR0BaseAddress ();
// Calculate index into first level translation table for start of modification
FirstLevelIdx = TT_DESCRIPTOR_SECTION_BASE_ADDRESS(BaseAddress) >> TT_DESCRIPTOR_SECTION_BASE_SHIFT;
ASSERT (FirstLevelIdx < TRANSLATION_TABLE_SECTION_COUNT);
// Get section attributes and convert to page attributes
SectionDescriptor = FirstLevelTable[FirstLevelIdx];
PageDescriptor = TT_DESCRIPTOR_PAGE_TYPE_PAGE | ConvertSectionAttributesToPageAttributes (SectionDescriptor, FALSE);
// Allocate a page table for the 4KB entries (we use up a full page even though we only need 1KB)
PageTable = (volatile ARM_PAGE_TABLE_ENTRY *)AllocatePages (1);
if (PageTable == NULL) {
return EFI_OUT_OF_RESOURCES;
}
// Write the page table entries out
for (Index = 0; Index < TRANSLATION_TABLE_PAGE_COUNT; Index++) {
PageTable[Index] = TT_DESCRIPTOR_PAGE_BASE_ADDRESS(BaseAddress + (Index << 12)) | PageDescriptor;
}
// Formulate page table entry, Domain=0, NS=0
PageTableDescriptor = (((UINTN)PageTable) & TT_DESCRIPTOR_SECTION_PAGETABLE_ADDRESS_MASK) | TT_DESCRIPTOR_SECTION_TYPE_PAGE_TABLE;
// Write the page table entry out, replacing section entry
FirstLevelTable[FirstLevelIdx] = PageTableDescriptor;
return EFI_SUCCESS;
}
STATIC
EFI_STATUS
UpdatePageEntries (
IN EFI_PHYSICAL_ADDRESS BaseAddress,
IN UINT64 Length,
IN UINT64 Attributes,
OUT BOOLEAN *FlushTlbs OPTIONAL
)
{
EFI_STATUS Status;
UINT32 EntryValue;
UINT32 EntryMask;
UINT32 FirstLevelIdx;
UINT32 Offset;
UINT32 NumPageEntries;
UINT32 Descriptor;
UINT32 p;
UINT32 PageTableIndex;
UINT32 PageTableEntry;
UINT32 CurrentPageTableEntry;
VOID *Mva;
volatile ARM_FIRST_LEVEL_DESCRIPTOR *FirstLevelTable;
volatile ARM_PAGE_TABLE_ENTRY *PageTable;
Status = EFI_SUCCESS;
// EntryMask: bitmask of values to change (1 = change this value, 0 = leave alone)
// EntryValue: values at bit positions specified by EntryMask
EntryMask = TT_DESCRIPTOR_PAGE_TYPE_MASK | TT_DESCRIPTOR_PAGE_AP_MASK;
if (Attributes & EFI_MEMORY_XP) {
EntryValue = TT_DESCRIPTOR_PAGE_TYPE_PAGE_XN;
} else {
EntryValue = TT_DESCRIPTOR_PAGE_TYPE_PAGE;
}
// Although the PI spec is unclear on this, the GCD guarantees that only
// one Attribute bit is set at a time, so the order of the conditionals below
// is irrelevant. If no memory attribute is specified, we preserve whatever
// memory type is set in the page tables, and update the permission attributes
// only.
if (Attributes & EFI_MEMORY_UC) {
// modify cacheability attributes
EntryMask |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_MASK;
// map to strongly ordered
EntryValue |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_STRONGLY_ORDERED; // TEX[2:0] = 0, C=0, B=0
} else if (Attributes & EFI_MEMORY_WC) {
// modify cacheability attributes
EntryMask |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_MASK;
// map to normal non-cachable
EntryValue |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_NON_CACHEABLE; // TEX [2:0]= 001 = 0x2, B=0, C=0
} else if (Attributes & EFI_MEMORY_WT) {
// modify cacheability attributes
EntryMask |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_MASK;
// write through with no-allocate
EntryValue |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_WRITE_THROUGH_NO_ALLOC; // TEX [2:0] = 0, C=1, B=0
} else if (Attributes & EFI_MEMORY_WB) {
// modify cacheability attributes
EntryMask |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_MASK;
// write back (with allocate)
EntryValue |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_WRITE_BACK_ALLOC; // TEX [2:0] = 001, C=1, B=1
} else if (Attributes & CACHE_ATTRIBUTE_MASK) {
// catch unsupported memory type attributes
ASSERT (FALSE);
return EFI_UNSUPPORTED;
}
if (Attributes & EFI_MEMORY_RO) {
EntryValue |= TT_DESCRIPTOR_PAGE_AP_RO_RO;
} else {
EntryValue |= TT_DESCRIPTOR_PAGE_AP_RW_RW;
}
// Obtain page table base
FirstLevelTable = (ARM_FIRST_LEVEL_DESCRIPTOR *)ArmGetTTBR0BaseAddress ();
// Calculate number of 4KB page table entries to change
NumPageEntries = Length / TT_DESCRIPTOR_PAGE_SIZE;
// Iterate for the number of 4KB pages to change
Offset = 0;
for(p = 0; p < NumPageEntries; p++) {
// Calculate index into first level translation table for page table value
FirstLevelIdx = TT_DESCRIPTOR_SECTION_BASE_ADDRESS(BaseAddress + Offset) >> TT_DESCRIPTOR_SECTION_BASE_SHIFT;
ASSERT (FirstLevelIdx < TRANSLATION_TABLE_SECTION_COUNT);
// Read the descriptor from the first level page table
Descriptor = FirstLevelTable[FirstLevelIdx];
// Does this descriptor need to be converted from section entry to 4K pages?
if (!TT_DESCRIPTOR_SECTION_TYPE_IS_PAGE_TABLE(Descriptor)) {
Status = ConvertSectionToPages (FirstLevelIdx << TT_DESCRIPTOR_SECTION_BASE_SHIFT);
if (EFI_ERROR(Status)) {
// Exit for loop
break;
}
// Re-read descriptor
Descriptor = FirstLevelTable[FirstLevelIdx];
if (FlushTlbs != NULL) {
*FlushTlbs = TRUE;
}
}
// Obtain page table base address
PageTable = (ARM_PAGE_TABLE_ENTRY *)TT_DESCRIPTOR_PAGE_BASE_ADDRESS(Descriptor);
// Calculate index into the page table
PageTableIndex = ((BaseAddress + Offset) & TT_DESCRIPTOR_PAGE_INDEX_MASK) >> TT_DESCRIPTOR_PAGE_BASE_SHIFT;
ASSERT (PageTableIndex < TRANSLATION_TABLE_PAGE_COUNT);
// Get the entry
CurrentPageTableEntry = PageTable[PageTableIndex];
// Mask off appropriate fields
PageTableEntry = CurrentPageTableEntry & ~EntryMask;
// Mask in new attributes and/or permissions
PageTableEntry |= EntryValue;
if (CurrentPageTableEntry != PageTableEntry) {
Mva = (VOID *)(UINTN)((((UINTN)FirstLevelIdx) << TT_DESCRIPTOR_SECTION_BASE_SHIFT) + (PageTableIndex << TT_DESCRIPTOR_PAGE_BASE_SHIFT));
// Only need to update if we are changing the entry
PageTable[PageTableIndex] = PageTableEntry;
ArmUpdateTranslationTableEntry ((VOID *)&PageTable[PageTableIndex], Mva);
}
Status = EFI_SUCCESS;
Offset += TT_DESCRIPTOR_PAGE_SIZE;
} // End first level translation table loop
return Status;
}
STATIC
EFI_STATUS
UpdateSectionEntries (
IN EFI_PHYSICAL_ADDRESS BaseAddress,
IN UINT64 Length,
IN UINT64 Attributes
)
{
EFI_STATUS Status = EFI_SUCCESS;
UINT32 EntryMask;
UINT32 EntryValue;
UINT32 FirstLevelIdx;
UINT32 NumSections;
UINT32 i;
UINT32 CurrentDescriptor;
UINT32 Descriptor;
VOID *Mva;
volatile ARM_FIRST_LEVEL_DESCRIPTOR *FirstLevelTable;
// EntryMask: bitmask of values to change (1 = change this value, 0 = leave alone)
// EntryValue: values at bit positions specified by EntryMask
// Make sure we handle a section range that is unmapped
EntryMask = TT_DESCRIPTOR_SECTION_TYPE_MASK | TT_DESCRIPTOR_SECTION_XN_MASK |
TT_DESCRIPTOR_SECTION_AP_MASK;
EntryValue = TT_DESCRIPTOR_SECTION_TYPE_SECTION;
// Although the PI spec is unclear on this, the GCD guarantees that only
// one Attribute bit is set at a time, so the order of the conditionals below
// is irrelevant. If no memory attribute is specified, we preserve whatever
// memory type is set in the page tables, and update the permission attributes
// only.
if (Attributes & EFI_MEMORY_UC) {
// modify cacheability attributes
EntryMask |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK;
// map to strongly ordered
EntryValue |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_STRONGLY_ORDERED; // TEX[2:0] = 0, C=0, B=0
} else if (Attributes & EFI_MEMORY_WC) {
// modify cacheability attributes
EntryMask |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK;
// map to normal non-cachable
EntryValue |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_NON_CACHEABLE; // TEX [2:0]= 001 = 0x2, B=0, C=0
} else if (Attributes & EFI_MEMORY_WT) {
// modify cacheability attributes
EntryMask |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK;
// write through with no-allocate
EntryValue |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_THROUGH_NO_ALLOC; // TEX [2:0] = 0, C=1, B=0
} else if (Attributes & EFI_MEMORY_WB) {
// modify cacheability attributes
EntryMask |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK;
// write back (with allocate)
EntryValue |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_BACK_ALLOC; // TEX [2:0] = 001, C=1, B=1
} else if (Attributes & CACHE_ATTRIBUTE_MASK) {
// catch unsupported memory type attributes
ASSERT (FALSE);
return EFI_UNSUPPORTED;
}
if (Attributes & EFI_MEMORY_RO) {
EntryValue |= TT_DESCRIPTOR_SECTION_AP_RO_RO;
} else {
EntryValue |= TT_DESCRIPTOR_SECTION_AP_RW_RW;
}
if (Attributes & EFI_MEMORY_XP) {
EntryValue |= TT_DESCRIPTOR_SECTION_XN_MASK;
}
// obtain page table base
FirstLevelTable = (ARM_FIRST_LEVEL_DESCRIPTOR *)ArmGetTTBR0BaseAddress ();
// calculate index into first level translation table for start of modification
FirstLevelIdx = TT_DESCRIPTOR_SECTION_BASE_ADDRESS(BaseAddress) >> TT_DESCRIPTOR_SECTION_BASE_SHIFT;
ASSERT (FirstLevelIdx < TRANSLATION_TABLE_SECTION_COUNT);
// calculate number of 1MB first level entries this applies to
NumSections = Length / TT_DESCRIPTOR_SECTION_SIZE;
// iterate through each descriptor
for(i=0; i<NumSections; i++) {
CurrentDescriptor = FirstLevelTable[FirstLevelIdx + i];
// has this descriptor already been converted to pages?
if (TT_DESCRIPTOR_SECTION_TYPE_IS_PAGE_TABLE(CurrentDescriptor)) {
// forward this 1MB range to page table function instead
Status = UpdatePageEntries (
(FirstLevelIdx + i) << TT_DESCRIPTOR_SECTION_BASE_SHIFT,
TT_DESCRIPTOR_SECTION_SIZE,
Attributes,
NULL);
} else {
// still a section entry
if (CurrentDescriptor != 0) {
// mask off appropriate fields
Descriptor = CurrentDescriptor & ~EntryMask;
} else {
Descriptor = ((UINTN)FirstLevelIdx + i) << TT_DESCRIPTOR_SECTION_BASE_SHIFT;
}
// mask in new attributes and/or permissions
Descriptor |= EntryValue;
if (CurrentDescriptor != Descriptor) {
Mva = (VOID *)(UINTN)(((UINTN)FirstLevelIdx + i) << TT_DESCRIPTOR_SECTION_BASE_SHIFT);
// Only need to update if we are changing the descriptor
FirstLevelTable[FirstLevelIdx + i] = Descriptor;
ArmUpdateTranslationTableEntry ((VOID *)&FirstLevelTable[FirstLevelIdx + i], Mva);
}
Status = EFI_SUCCESS;
}
}
return Status;
}
EFI_STATUS
ArmSetMemoryAttributes (
IN EFI_PHYSICAL_ADDRESS BaseAddress,
IN UINT64 Length,
IN UINT64 Attributes
)
{
EFI_STATUS Status;
UINT64 ChunkLength;
BOOLEAN FlushTlbs;
if (BaseAddress > (UINT64)MAX_ADDRESS) {
return EFI_UNSUPPORTED;
}
Length = MIN (Length, (UINT64)MAX_ADDRESS - BaseAddress + 1);
if (Length == 0) {
return EFI_SUCCESS;
}
FlushTlbs = FALSE;
while (Length > 0) {
if ((BaseAddress % TT_DESCRIPTOR_SECTION_SIZE == 0) &&
Length >= TT_DESCRIPTOR_SECTION_SIZE) {
ChunkLength = Length - Length % TT_DESCRIPTOR_SECTION_SIZE;
DEBUG ((DEBUG_PAGE,
"SetMemoryAttributes(): MMU section 0x%lx length 0x%lx to %lx\n",
BaseAddress, ChunkLength, Attributes));
Status = UpdateSectionEntries (BaseAddress, ChunkLength, Attributes);
FlushTlbs = TRUE;
} else {
//
// Process page by page until the next section boundary, but only if
// we have more than a section's worth of area to deal with after that.
//
ChunkLength = TT_DESCRIPTOR_SECTION_SIZE -
(BaseAddress % TT_DESCRIPTOR_SECTION_SIZE);
if (ChunkLength + TT_DESCRIPTOR_SECTION_SIZE > Length) {
ChunkLength = Length;
}
DEBUG ((DEBUG_PAGE,
"SetMemoryAttributes(): MMU page 0x%lx length 0x%lx to %lx\n",
BaseAddress, ChunkLength, Attributes));
Status = UpdatePageEntries (BaseAddress, ChunkLength, Attributes,
&FlushTlbs);
}
if (EFI_ERROR (Status)) {
break;
}
BaseAddress += ChunkLength;
Length -= ChunkLength;
}
if (FlushTlbs) {
ArmInvalidateTlb ();
}
return Status;
}
EFI_STATUS
ArmSetMemoryRegionNoExec (
IN EFI_PHYSICAL_ADDRESS BaseAddress,
IN UINT64 Length
)
{
return ArmSetMemoryAttributes (BaseAddress, Length, EFI_MEMORY_XP);
}
EFI_STATUS
ArmClearMemoryRegionNoExec (
IN EFI_PHYSICAL_ADDRESS BaseAddress,
IN UINT64 Length
)
{
return ArmSetMemoryAttributes (BaseAddress, Length, __EFI_MEMORY_RWX);
}
EFI_STATUS
ArmSetMemoryRegionReadOnly (
IN EFI_PHYSICAL_ADDRESS BaseAddress,
IN UINT64 Length
)
{
return ArmSetMemoryAttributes (BaseAddress, Length, EFI_MEMORY_RO);
}
EFI_STATUS
ArmClearMemoryRegionReadOnly (
IN EFI_PHYSICAL_ADDRESS BaseAddress,
IN UINT64 Length
)
{
return ArmSetMemoryAttributes (BaseAddress, Length, __EFI_MEMORY_RWX);
}
RETURN_STATUS
EFIAPI
ArmMmuBaseLibConstructor (
VOID
)
{
return RETURN_SUCCESS;
}

View File

@@ -1,435 +0,0 @@
/** @file
* File managing the MMU for ARMv7 architecture
*
* Copyright (c) 2011-2016, ARM Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-2-Clause-Patent
*
**/
#include <Uefi.h>
#include <Library/ArmLib.h>
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/CacheMaintenanceLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Chipset/ArmV7.h>
#define __EFI_MEMORY_RWX 0 // no restrictions
#define CACHE_ATTRIBUTE_MASK (EFI_MEMORY_UC | \
EFI_MEMORY_WC | \
EFI_MEMORY_WT | \
EFI_MEMORY_WB | \
EFI_MEMORY_UCE | \
EFI_MEMORY_WP)
STATIC
EFI_STATUS
ConvertSectionToPages (
IN EFI_PHYSICAL_ADDRESS BaseAddress
)
{
UINT32 FirstLevelIdx;
UINT32 SectionDescriptor;
UINT32 PageTableDescriptor;
UINT32 PageDescriptor;
UINT32 Index;
volatile ARM_FIRST_LEVEL_DESCRIPTOR *FirstLevelTable;
volatile ARM_PAGE_TABLE_ENTRY *PageTable;
DEBUG ((DEBUG_PAGE, "Converting section at 0x%x to pages\n", (UINTN)BaseAddress));
// Obtain page table base
FirstLevelTable = (ARM_FIRST_LEVEL_DESCRIPTOR *)ArmGetTTBR0BaseAddress ();
// Calculate index into first level translation table for start of modification
FirstLevelIdx = TT_DESCRIPTOR_SECTION_BASE_ADDRESS(BaseAddress) >> TT_DESCRIPTOR_SECTION_BASE_SHIFT;
ASSERT (FirstLevelIdx < TRANSLATION_TABLE_SECTION_COUNT);
// Get section attributes and convert to page attributes
SectionDescriptor = FirstLevelTable[FirstLevelIdx];
PageDescriptor = TT_DESCRIPTOR_PAGE_TYPE_PAGE | ConvertSectionAttributesToPageAttributes (SectionDescriptor, FALSE);
// Allocate a page table for the 4KB entries (we use up a full page even though we only need 1KB)
PageTable = (volatile ARM_PAGE_TABLE_ENTRY *)AllocatePages (1);
if (PageTable == NULL) {
return EFI_OUT_OF_RESOURCES;
}
// Write the page table entries out
for (Index = 0; Index < TRANSLATION_TABLE_PAGE_COUNT; Index++) {
PageTable[Index] = TT_DESCRIPTOR_PAGE_BASE_ADDRESS(BaseAddress + (Index << 12)) | PageDescriptor;
}
// Formulate page table entry, Domain=0, NS=0
PageTableDescriptor = (((UINTN)PageTable) & TT_DESCRIPTOR_SECTION_PAGETABLE_ADDRESS_MASK) | TT_DESCRIPTOR_SECTION_TYPE_PAGE_TABLE;
// Write the page table entry out, replacing section entry
FirstLevelTable[FirstLevelIdx] = PageTableDescriptor;
return EFI_SUCCESS;
}
STATIC
EFI_STATUS
UpdatePageEntries (
IN EFI_PHYSICAL_ADDRESS BaseAddress,
IN UINT64 Length,
IN UINT64 Attributes,
OUT BOOLEAN *FlushTlbs OPTIONAL
)
{
EFI_STATUS Status;
UINT32 EntryValue;
UINT32 EntryMask;
UINT32 FirstLevelIdx;
UINT32 Offset;
UINT32 NumPageEntries;
UINT32 Descriptor;
UINT32 p;
UINT32 PageTableIndex;
UINT32 PageTableEntry;
UINT32 CurrentPageTableEntry;
VOID *Mva;
volatile ARM_FIRST_LEVEL_DESCRIPTOR *FirstLevelTable;
volatile ARM_PAGE_TABLE_ENTRY *PageTable;
Status = EFI_SUCCESS;
// EntryMask: bitmask of values to change (1 = change this value, 0 = leave alone)
// EntryValue: values at bit positions specified by EntryMask
EntryMask = TT_DESCRIPTOR_PAGE_TYPE_MASK | TT_DESCRIPTOR_PAGE_AP_MASK;
if (Attributes & EFI_MEMORY_XP) {
EntryValue = TT_DESCRIPTOR_PAGE_TYPE_PAGE_XN;
} else {
EntryValue = TT_DESCRIPTOR_PAGE_TYPE_PAGE;
}
// Although the PI spec is unclear on this, the GCD guarantees that only
// one Attribute bit is set at a time, so the order of the conditionals below
// is irrelevant. If no memory attribute is specified, we preserve whatever
// memory type is set in the page tables, and update the permission attributes
// only.
if (Attributes & EFI_MEMORY_UC) {
// modify cacheability attributes
EntryMask |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_MASK;
// map to strongly ordered
EntryValue |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_STRONGLY_ORDERED; // TEX[2:0] = 0, C=0, B=0
} else if (Attributes & EFI_MEMORY_WC) {
// modify cacheability attributes
EntryMask |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_MASK;
// map to normal non-cachable
EntryValue |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_NON_CACHEABLE; // TEX [2:0]= 001 = 0x2, B=0, C=0
} else if (Attributes & EFI_MEMORY_WT) {
// modify cacheability attributes
EntryMask |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_MASK;
// write through with no-allocate
EntryValue |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_WRITE_THROUGH_NO_ALLOC; // TEX [2:0] = 0, C=1, B=0
} else if (Attributes & EFI_MEMORY_WB) {
// modify cacheability attributes
EntryMask |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_MASK;
// write back (with allocate)
EntryValue |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_WRITE_BACK_ALLOC; // TEX [2:0] = 001, C=1, B=1
} else if (Attributes & CACHE_ATTRIBUTE_MASK) {
// catch unsupported memory type attributes
ASSERT (FALSE);
return EFI_UNSUPPORTED;
}
if (Attributes & EFI_MEMORY_RO) {
EntryValue |= TT_DESCRIPTOR_PAGE_AP_RO_RO;
} else {
EntryValue |= TT_DESCRIPTOR_PAGE_AP_RW_RW;
}
// Obtain page table base
FirstLevelTable = (ARM_FIRST_LEVEL_DESCRIPTOR *)ArmGetTTBR0BaseAddress ();
// Calculate number of 4KB page table entries to change
NumPageEntries = (UINT32)(Length / TT_DESCRIPTOR_PAGE_SIZE);
// Iterate for the number of 4KB pages to change
Offset = 0;
for(p = 0; p < NumPageEntries; p++) {
// Calculate index into first level translation table for page table value
FirstLevelIdx = TT_DESCRIPTOR_SECTION_BASE_ADDRESS(BaseAddress + Offset) >> TT_DESCRIPTOR_SECTION_BASE_SHIFT;
ASSERT (FirstLevelIdx < TRANSLATION_TABLE_SECTION_COUNT);
// Read the descriptor from the first level page table
Descriptor = FirstLevelTable[FirstLevelIdx];
// Does this descriptor need to be converted from section entry to 4K pages?
if (!TT_DESCRIPTOR_SECTION_TYPE_IS_PAGE_TABLE(Descriptor)) {
Status = ConvertSectionToPages (FirstLevelIdx << TT_DESCRIPTOR_SECTION_BASE_SHIFT);
if (EFI_ERROR(Status)) {
// Exit for loop
break;
}
// Re-read descriptor
Descriptor = FirstLevelTable[FirstLevelIdx];
if (FlushTlbs != NULL) {
*FlushTlbs = TRUE;
}
}
// Obtain page table base address
PageTable = (ARM_PAGE_TABLE_ENTRY *)TT_DESCRIPTOR_PAGE_BASE_ADDRESS(Descriptor);
// Calculate index into the page table
PageTableIndex = ((BaseAddress + Offset) & TT_DESCRIPTOR_PAGE_INDEX_MASK) >> TT_DESCRIPTOR_PAGE_BASE_SHIFT;
ASSERT (PageTableIndex < TRANSLATION_TABLE_PAGE_COUNT);
// Get the entry
CurrentPageTableEntry = PageTable[PageTableIndex];
// Mask off appropriate fields
PageTableEntry = CurrentPageTableEntry & ~EntryMask;
// Mask in new attributes and/or permissions
PageTableEntry |= EntryValue;
if (CurrentPageTableEntry != PageTableEntry) {
Mva = (VOID *)(UINTN)((((UINTN)FirstLevelIdx) << TT_DESCRIPTOR_SECTION_BASE_SHIFT) + (PageTableIndex << TT_DESCRIPTOR_PAGE_BASE_SHIFT));
// Only need to update if we are changing the entry
PageTable[PageTableIndex] = PageTableEntry;
ArmUpdateTranslationTableEntry ((VOID *)&PageTable[PageTableIndex], Mva);
}
Status = EFI_SUCCESS;
Offset += TT_DESCRIPTOR_PAGE_SIZE;
} // End first level translation table loop
return Status;
}
STATIC
EFI_STATUS
UpdateSectionEntries (
IN EFI_PHYSICAL_ADDRESS BaseAddress,
IN UINT64 Length,
IN UINT64 Attributes
)
{
EFI_STATUS Status = EFI_SUCCESS;
UINT32 EntryMask;
UINT32 EntryValue;
UINT32 FirstLevelIdx;
UINT32 NumSections;
UINT32 i;
UINT32 CurrentDescriptor;
UINT32 Descriptor;
VOID *Mva;
volatile ARM_FIRST_LEVEL_DESCRIPTOR *FirstLevelTable;
// EntryMask: bitmask of values to change (1 = change this value, 0 = leave alone)
// EntryValue: values at bit positions specified by EntryMask
// Make sure we handle a section range that is unmapped
EntryMask = TT_DESCRIPTOR_SECTION_TYPE_MASK | TT_DESCRIPTOR_SECTION_XN_MASK |
TT_DESCRIPTOR_SECTION_AP_MASK;
EntryValue = TT_DESCRIPTOR_SECTION_TYPE_SECTION;
// Although the PI spec is unclear on this, the GCD guarantees that only
// one Attribute bit is set at a time, so the order of the conditionals below
// is irrelevant. If no memory attribute is specified, we preserve whatever
// memory type is set in the page tables, and update the permission attributes
// only.
if (Attributes & EFI_MEMORY_UC) {
// modify cacheability attributes
EntryMask |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK;
// map to strongly ordered
EntryValue |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_STRONGLY_ORDERED; // TEX[2:0] = 0, C=0, B=0
} else if (Attributes & EFI_MEMORY_WC) {
// modify cacheability attributes
EntryMask |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK;
// map to normal non-cachable
EntryValue |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_NON_CACHEABLE; // TEX [2:0]= 001 = 0x2, B=0, C=0
} else if (Attributes & EFI_MEMORY_WT) {
// modify cacheability attributes
EntryMask |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK;
// write through with no-allocate
EntryValue |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_THROUGH_NO_ALLOC; // TEX [2:0] = 0, C=1, B=0
} else if (Attributes & EFI_MEMORY_WB) {
// modify cacheability attributes
EntryMask |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK;
// write back (with allocate)
EntryValue |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_BACK_ALLOC; // TEX [2:0] = 001, C=1, B=1
} else if (Attributes & CACHE_ATTRIBUTE_MASK) {
// catch unsupported memory type attributes
ASSERT (FALSE);
return EFI_UNSUPPORTED;
}
if (Attributes & EFI_MEMORY_RO) {
EntryValue |= TT_DESCRIPTOR_SECTION_AP_RO_RO;
} else {
EntryValue |= TT_DESCRIPTOR_SECTION_AP_RW_RW;
}
if (Attributes & EFI_MEMORY_XP) {
EntryValue |= TT_DESCRIPTOR_SECTION_XN_MASK;
}
// obtain page table base
FirstLevelTable = (ARM_FIRST_LEVEL_DESCRIPTOR *)ArmGetTTBR0BaseAddress ();
// calculate index into first level translation table for start of modification
FirstLevelIdx = TT_DESCRIPTOR_SECTION_BASE_ADDRESS(BaseAddress) >> TT_DESCRIPTOR_SECTION_BASE_SHIFT;
ASSERT (FirstLevelIdx < TRANSLATION_TABLE_SECTION_COUNT);
// calculate number of 1MB first level entries this applies to
NumSections = (UINT32)(Length / TT_DESCRIPTOR_SECTION_SIZE);
// iterate through each descriptor
for(i=0; i<NumSections; i++) {
CurrentDescriptor = FirstLevelTable[FirstLevelIdx + i];
// has this descriptor already been converted to pages?
if (TT_DESCRIPTOR_SECTION_TYPE_IS_PAGE_TABLE(CurrentDescriptor)) {
// forward this 1MB range to page table function instead
Status = UpdatePageEntries (
(FirstLevelIdx + i) << TT_DESCRIPTOR_SECTION_BASE_SHIFT,
TT_DESCRIPTOR_SECTION_SIZE,
Attributes,
NULL);
} else {
// still a section entry
if (CurrentDescriptor != 0) {
// mask off appropriate fields
Descriptor = CurrentDescriptor & ~EntryMask;
} else {
Descriptor = ((UINTN)FirstLevelIdx + i) << TT_DESCRIPTOR_SECTION_BASE_SHIFT;
}
// mask in new attributes and/or permissions
Descriptor |= EntryValue;
if (CurrentDescriptor != Descriptor) {
Mva = (VOID *)(UINTN)(((UINTN)FirstLevelIdx + i) << TT_DESCRIPTOR_SECTION_BASE_SHIFT);
// Only need to update if we are changing the descriptor
FirstLevelTable[FirstLevelIdx + i] = Descriptor;
ArmUpdateTranslationTableEntry ((VOID *)&FirstLevelTable[FirstLevelIdx + i], Mva);
}
Status = EFI_SUCCESS;
}
}
return Status;
}
EFI_STATUS
ArmSetMemoryAttributes (
IN EFI_PHYSICAL_ADDRESS BaseAddress,
IN UINT64 Length,
IN UINT64 Attributes
)
{
EFI_STATUS Status;
UINT64 ChunkLength;
BOOLEAN FlushTlbs;
if (BaseAddress > (UINT64)MAX_ADDRESS) {
return EFI_UNSUPPORTED;
}
Length = MIN (Length, (UINT64)MAX_ADDRESS - BaseAddress + 1);
if (Length == 0) {
return EFI_SUCCESS;
}
FlushTlbs = FALSE;
while (Length > 0) {
if ((BaseAddress % TT_DESCRIPTOR_SECTION_SIZE == 0) &&
Length >= TT_DESCRIPTOR_SECTION_SIZE) {
ChunkLength = Length - Length % TT_DESCRIPTOR_SECTION_SIZE;
DEBUG ((DEBUG_PAGE,
"SetMemoryAttributes(): MMU section 0x%lx length 0x%lx to %lx\n",
BaseAddress, ChunkLength, Attributes));
Status = UpdateSectionEntries (BaseAddress, ChunkLength, Attributes);
FlushTlbs = TRUE;
} else {
//
// Process page by page until the next section boundary, but only if
// we have more than a section's worth of area to deal with after that.
//
ChunkLength = TT_DESCRIPTOR_SECTION_SIZE -
(BaseAddress % TT_DESCRIPTOR_SECTION_SIZE);
if (ChunkLength + TT_DESCRIPTOR_SECTION_SIZE > Length) {
ChunkLength = Length;
}
DEBUG ((DEBUG_PAGE,
"SetMemoryAttributes(): MMU page 0x%lx length 0x%lx to %lx\n",
BaseAddress, ChunkLength, Attributes));
Status = UpdatePageEntries (BaseAddress, ChunkLength, Attributes,
&FlushTlbs);
}
if (EFI_ERROR (Status)) {
break;
}
BaseAddress += ChunkLength;
Length -= ChunkLength;
}
if (FlushTlbs) {
ArmInvalidateTlb ();
}
return Status;
}
EFI_STATUS
ArmSetMemoryRegionNoExec (
IN EFI_PHYSICAL_ADDRESS BaseAddress,
IN UINT64 Length
)
{
return ArmSetMemoryAttributes (BaseAddress, Length, EFI_MEMORY_XP);
}
EFI_STATUS
ArmClearMemoryRegionNoExec (
IN EFI_PHYSICAL_ADDRESS BaseAddress,
IN UINT64 Length
)
{
return ArmSetMemoryAttributes (BaseAddress, Length, __EFI_MEMORY_RWX);
}
EFI_STATUS
ArmSetMemoryRegionReadOnly (
IN EFI_PHYSICAL_ADDRESS BaseAddress,
IN UINT64 Length
)
{
return ArmSetMemoryAttributes (BaseAddress, Length, EFI_MEMORY_RO);
}
EFI_STATUS
ArmClearMemoryRegionReadOnly (
IN EFI_PHYSICAL_ADDRESS BaseAddress,
IN UINT64 Length
)
{
return ArmSetMemoryAttributes (BaseAddress, Length, __EFI_MEMORY_RWX);
}

View File

@@ -14,8 +14,6 @@
MODULE_TYPE = BASE
VERSION_STRING = 1.0
LIBRARY_CLASS = ArmMmuLib
[Defines.AARCH64]
CONSTRUCTOR = ArmMmuBaseLibConstructor
[Sources.AARCH64]
@@ -23,9 +21,7 @@
AArch64/ArmMmuLibReplaceEntry.S
[Sources.ARM]
Arm/ArmMmuLibConvert.c
Arm/ArmMmuLibCore.c
Arm/ArmMmuLibUpdate.c
Arm/ArmMmuLibV7Support.S |GCC
Arm/ArmMmuLibV7Support.asm |RVCT

View File

@@ -1,16 +1,16 @@
//
// Copyright (c) 2016, Linaro Limited. All rights reserved.
//
// SPDX-License-Identifier: BSD-2-Clause-Patent
//
//
#include <Base.h>
#include <Library/ArmSmcLib.h>
VOID
ArmCallSmc (
IN OUT ARM_SMC_ARGS *Args
)
{
}
//
// Copyright (c) 2016, Linaro Limited. All rights reserved.
//
// SPDX-License-Identifier: BSD-2-Clause-Patent
//
//
#include <Base.h>
#include <Library/ArmSmcLib.h>
VOID
ArmCallSmc (
IN OUT ARM_SMC_ARGS *Args
)
{
}

View File

@@ -1,283 +1,283 @@
/*
* Copyright (c) 2015 - 2019, Linaro Limited
*
* SPDX-License-Identifier: BSD-2-Clause-Patent
*/
#include "platform.h"
#include <softfloat.h>
/*
* On ARM32 EABI defines both a soft-float ABI and a hard-float ABI,
* hard-float is basically a super set of soft-float. Hard-float requires
* all the support routines provided for soft-float, but the compiler may
* choose to optimize to not use some of them.
*
* The AEABI functions uses soft-float calling convention even if the
* functions are compiled for hard-float. So where float and double would
* have been expected we use aeabi_float_t and aeabi_double_t respectively
* instead.
*/
typedef uint32_t aeabi_float_t;
typedef uint64_t aeabi_double_t;
/*
* Helpers to convert between float32 and aeabi_float_t, and float64 and
* aeabi_double_t used by the AEABI functions below.
*/
static aeabi_float_t f32_to_f(float32_t val)
{
return val.v;
}
static float32_t f32_from_f(aeabi_float_t val)
{
float32_t res;
res.v = val;
return res;
}
static aeabi_double_t f64_to_d(float64_t val)
{
return val.v;
}
static float64_t f64_from_d(aeabi_double_t val)
{
float64_t res;
res.v = val;
return res;
}
/*
* From ARM Run-time ABI for ARM Architecture
* ARM IHI 0043D, current through ABI release 2.09
*
* 4.1.2 The floating-point helper functions
*/
/*
* Table 2, Standard aeabi_double_t precision floating-point arithmetic helper
* functions
*/
aeabi_double_t __aeabi_dadd(aeabi_double_t a, aeabi_double_t b)
{
return f64_to_d(f64_add(f64_from_d(a), f64_from_d(b)));
}
aeabi_double_t __aeabi_ddiv(aeabi_double_t a, aeabi_double_t b)
{
return f64_to_d(f64_div(f64_from_d(a), f64_from_d(b)));
}
aeabi_double_t __aeabi_dmul(aeabi_double_t a, aeabi_double_t b)
{
return f64_to_d(f64_mul(f64_from_d(a), f64_from_d(b)));
}
aeabi_double_t __aeabi_drsub(aeabi_double_t a, aeabi_double_t b)
{
return f64_to_d(f64_sub(f64_from_d(b), f64_from_d(a)));
}
aeabi_double_t __aeabi_dsub(aeabi_double_t a, aeabi_double_t b)
{
return f64_to_d(f64_sub(f64_from_d(a), f64_from_d(b)));
}
/*
* Table 3, double precision floating-point comparison helper functions
*/
int __aeabi_dcmpeq(aeabi_double_t a, aeabi_double_t b)
{
return f64_eq(f64_from_d(a), f64_from_d(b));
}
int __aeabi_dcmplt(aeabi_double_t a, aeabi_double_t b)
{
return f64_lt(f64_from_d(a), f64_from_d(b));
}
int __aeabi_dcmple(aeabi_double_t a, aeabi_double_t b)
{
return f64_le(f64_from_d(a), f64_from_d(b));
}
int __aeabi_dcmpge(aeabi_double_t a, aeabi_double_t b)
{
return f64_le(f64_from_d(b), f64_from_d(a));
}
int __aeabi_dcmpgt(aeabi_double_t a, aeabi_double_t b)
{
return f64_lt(f64_from_d(b), f64_from_d(a));
}
/*
* Table 4, Standard single precision floating-point arithmetic helper
* functions
*/
aeabi_float_t __aeabi_fadd(aeabi_float_t a, aeabi_float_t b)
{
return f32_to_f(f32_add(f32_from_f(a), f32_from_f(b)));
}
aeabi_float_t __aeabi_fdiv(aeabi_float_t a, aeabi_float_t b)
{
return f32_to_f(f32_div(f32_from_f(a), f32_from_f(b)));
}
aeabi_float_t __aeabi_fmul(aeabi_float_t a, aeabi_float_t b)
{
return f32_to_f(f32_mul(f32_from_f(a), f32_from_f(b)));
}
aeabi_float_t __aeabi_frsub(aeabi_float_t a, aeabi_float_t b)
{
return f32_to_f(f32_sub(f32_from_f(b), f32_from_f(a)));
}
aeabi_float_t __aeabi_fsub(aeabi_float_t a, aeabi_float_t b)
{
return f32_to_f(f32_sub(f32_from_f(a), f32_from_f(b)));
}
/*
* Table 5, Standard single precision floating-point comparison helper
* functions
*/
int __aeabi_fcmpeq(aeabi_float_t a, aeabi_float_t b)
{
return f32_eq(f32_from_f(a), f32_from_f(b));
}
int __aeabi_fcmplt(aeabi_float_t a, aeabi_float_t b)
{
return f32_lt(f32_from_f(a), f32_from_f(b));
}
int __aeabi_fcmple(aeabi_float_t a, aeabi_float_t b)
{
return f32_le(f32_from_f(a), f32_from_f(b));
}
int __aeabi_fcmpge(aeabi_float_t a, aeabi_float_t b)
{
return f32_le(f32_from_f(b), f32_from_f(a));
}
int __aeabi_fcmpgt(aeabi_float_t a, aeabi_float_t b)
{
return f32_lt(f32_from_f(b), f32_from_f(a));
}
/*
* Table 6, Standard floating-point to integer conversions
*/
int __aeabi_d2iz(aeabi_double_t a)
{
return f64_to_i32_r_minMag(f64_from_d(a), false);
}
unsigned __aeabi_d2uiz(aeabi_double_t a)
{
return f64_to_ui32_r_minMag(f64_from_d(a), false);
}
long long __aeabi_d2lz(aeabi_double_t a)
{
return f64_to_i64_r_minMag(f64_from_d(a), false);
}
unsigned long long __aeabi_d2ulz(aeabi_double_t a)
{
return f64_to_ui64_r_minMag(f64_from_d(a), false);
}
int __aeabi_f2iz(aeabi_float_t a)
{
return f32_to_i32_r_minMag(f32_from_f(a), false);
}
unsigned __aeabi_f2uiz(aeabi_float_t a)
{
return f32_to_ui32_r_minMag(f32_from_f(a), false);
}
long long __aeabi_f2lz(aeabi_float_t a)
{
return f32_to_i64_r_minMag(f32_from_f(a), false);
}
unsigned long long __aeabi_f2ulz(aeabi_float_t a)
{
return f32_to_ui64_r_minMag(f32_from_f(a), false);
}
/*
* Table 7, Standard conversions between floating types
*/
aeabi_float_t __aeabi_d2f(aeabi_double_t a)
{
return f32_to_f(f64_to_f32(f64_from_d(a)));
}
aeabi_double_t __aeabi_f2d(aeabi_float_t a)
{
return f64_to_d(f32_to_f64(f32_from_f(a)));
}
/*
* Table 8, Standard integer to floating-point conversions
*/
aeabi_double_t __aeabi_i2d(int a)
{
return f64_to_d(i32_to_f64(a));
}
aeabi_double_t __aeabi_ui2d(unsigned a)
{
return f64_to_d(ui32_to_f64(a));
}
aeabi_double_t __aeabi_l2d(long long a)
{
return f64_to_d(i64_to_f64(a));
}
aeabi_double_t __aeabi_ul2d(unsigned long long a)
{
return f64_to_d(ui64_to_f64(a));
}
aeabi_float_t __aeabi_i2f(int a)
{
return f32_to_f(i32_to_f32(a));
}
aeabi_float_t __aeabi_ui2f(unsigned a)
{
return f32_to_f(ui32_to_f32(a));
}
aeabi_float_t __aeabi_l2f(long long a)
{
return f32_to_f(i64_to_f32(a));
}
aeabi_float_t __aeabi_ul2f(unsigned long long a)
{
return f32_to_f(ui64_to_f32(a));
}
/*
* Copyright (c) 2015 - 2019, Linaro Limited
*
* SPDX-License-Identifier: BSD-2-Clause-Patent
*/
#include "platform.h"
#include <softfloat.h>
/*
* On ARM32 EABI defines both a soft-float ABI and a hard-float ABI,
* hard-float is basically a super set of soft-float. Hard-float requires
* all the support routines provided for soft-float, but the compiler may
* choose to optimize to not use some of them.
*
* The AEABI functions uses soft-float calling convention even if the
* functions are compiled for hard-float. So where float and double would
* have been expected we use aeabi_float_t and aeabi_double_t respectively
* instead.
*/
typedef uint32_t aeabi_float_t;
typedef uint64_t aeabi_double_t;
/*
* Helpers to convert between float32 and aeabi_float_t, and float64 and
* aeabi_double_t used by the AEABI functions below.
*/
static aeabi_float_t f32_to_f(float32_t val)
{
return val.v;
}
static float32_t f32_from_f(aeabi_float_t val)
{
float32_t res;
res.v = val;
return res;
}
static aeabi_double_t f64_to_d(float64_t val)
{
return val.v;
}
static float64_t f64_from_d(aeabi_double_t val)
{
float64_t res;
res.v = val;
return res;
}
/*
* From ARM Run-time ABI for ARM Architecture
* ARM IHI 0043D, current through ABI release 2.09
*
* 4.1.2 The floating-point helper functions
*/
/*
* Table 2, Standard aeabi_double_t precision floating-point arithmetic helper
* functions
*/
aeabi_double_t __aeabi_dadd(aeabi_double_t a, aeabi_double_t b)
{
return f64_to_d(f64_add(f64_from_d(a), f64_from_d(b)));
}
aeabi_double_t __aeabi_ddiv(aeabi_double_t a, aeabi_double_t b)
{
return f64_to_d(f64_div(f64_from_d(a), f64_from_d(b)));
}
aeabi_double_t __aeabi_dmul(aeabi_double_t a, aeabi_double_t b)
{
return f64_to_d(f64_mul(f64_from_d(a), f64_from_d(b)));
}
aeabi_double_t __aeabi_drsub(aeabi_double_t a, aeabi_double_t b)
{
return f64_to_d(f64_sub(f64_from_d(b), f64_from_d(a)));
}
aeabi_double_t __aeabi_dsub(aeabi_double_t a, aeabi_double_t b)
{
return f64_to_d(f64_sub(f64_from_d(a), f64_from_d(b)));
}
/*
* Table 3, double precision floating-point comparison helper functions
*/
int __aeabi_dcmpeq(aeabi_double_t a, aeabi_double_t b)
{
return f64_eq(f64_from_d(a), f64_from_d(b));
}
int __aeabi_dcmplt(aeabi_double_t a, aeabi_double_t b)
{
return f64_lt(f64_from_d(a), f64_from_d(b));
}
int __aeabi_dcmple(aeabi_double_t a, aeabi_double_t b)
{
return f64_le(f64_from_d(a), f64_from_d(b));
}
int __aeabi_dcmpge(aeabi_double_t a, aeabi_double_t b)
{
return f64_le(f64_from_d(b), f64_from_d(a));
}
int __aeabi_dcmpgt(aeabi_double_t a, aeabi_double_t b)
{
return f64_lt(f64_from_d(b), f64_from_d(a));
}
/*
* Table 4, Standard single precision floating-point arithmetic helper
* functions
*/
aeabi_float_t __aeabi_fadd(aeabi_float_t a, aeabi_float_t b)
{
return f32_to_f(f32_add(f32_from_f(a), f32_from_f(b)));
}
aeabi_float_t __aeabi_fdiv(aeabi_float_t a, aeabi_float_t b)
{
return f32_to_f(f32_div(f32_from_f(a), f32_from_f(b)));
}
aeabi_float_t __aeabi_fmul(aeabi_float_t a, aeabi_float_t b)
{
return f32_to_f(f32_mul(f32_from_f(a), f32_from_f(b)));
}
aeabi_float_t __aeabi_frsub(aeabi_float_t a, aeabi_float_t b)
{
return f32_to_f(f32_sub(f32_from_f(b), f32_from_f(a)));
}
aeabi_float_t __aeabi_fsub(aeabi_float_t a, aeabi_float_t b)
{
return f32_to_f(f32_sub(f32_from_f(a), f32_from_f(b)));
}
/*
* Table 5, Standard single precision floating-point comparison helper
* functions
*/
int __aeabi_fcmpeq(aeabi_float_t a, aeabi_float_t b)
{
return f32_eq(f32_from_f(a), f32_from_f(b));
}
int __aeabi_fcmplt(aeabi_float_t a, aeabi_float_t b)
{
return f32_lt(f32_from_f(a), f32_from_f(b));
}
int __aeabi_fcmple(aeabi_float_t a, aeabi_float_t b)
{
return f32_le(f32_from_f(a), f32_from_f(b));
}
int __aeabi_fcmpge(aeabi_float_t a, aeabi_float_t b)
{
return f32_le(f32_from_f(b), f32_from_f(a));
}
int __aeabi_fcmpgt(aeabi_float_t a, aeabi_float_t b)
{
return f32_lt(f32_from_f(b), f32_from_f(a));
}
/*
* Table 6, Standard floating-point to integer conversions
*/
int __aeabi_d2iz(aeabi_double_t a)
{
return f64_to_i32_r_minMag(f64_from_d(a), false);
}
unsigned __aeabi_d2uiz(aeabi_double_t a)
{
return f64_to_ui32_r_minMag(f64_from_d(a), false);
}
long long __aeabi_d2lz(aeabi_double_t a)
{
return f64_to_i64_r_minMag(f64_from_d(a), false);
}
unsigned long long __aeabi_d2ulz(aeabi_double_t a)
{
return f64_to_ui64_r_minMag(f64_from_d(a), false);
}
int __aeabi_f2iz(aeabi_float_t a)
{
return f32_to_i32_r_minMag(f32_from_f(a), false);
}
unsigned __aeabi_f2uiz(aeabi_float_t a)
{
return f32_to_ui32_r_minMag(f32_from_f(a), false);
}
long long __aeabi_f2lz(aeabi_float_t a)
{
return f32_to_i64_r_minMag(f32_from_f(a), false);
}
unsigned long long __aeabi_f2ulz(aeabi_float_t a)
{
return f32_to_ui64_r_minMag(f32_from_f(a), false);
}
/*
* Table 7, Standard conversions between floating types
*/
aeabi_float_t __aeabi_d2f(aeabi_double_t a)
{
return f32_to_f(f64_to_f32(f64_from_d(a)));
}
aeabi_double_t __aeabi_f2d(aeabi_float_t a)
{
return f64_to_d(f32_to_f64(f32_from_f(a)));
}
/*
* Table 8, Standard integer to floating-point conversions
*/
aeabi_double_t __aeabi_i2d(int a)
{
return f64_to_d(i32_to_f64(a));
}
aeabi_double_t __aeabi_ui2d(unsigned a)
{
return f64_to_d(ui32_to_f64(a));
}
aeabi_double_t __aeabi_l2d(long long a)
{
return f64_to_d(i64_to_f64(a));
}
aeabi_double_t __aeabi_ul2d(unsigned long long a)
{
return f64_to_d(ui64_to_f64(a));
}
aeabi_float_t __aeabi_i2f(int a)
{
return f32_to_f(i32_to_f32(a));
}
aeabi_float_t __aeabi_ui2f(unsigned a)
{
return f32_to_f(ui32_to_f32(a));
}
aeabi_float_t __aeabi_l2f(long long a)
{
return f32_to_f(i64_to_f32(a));
}
aeabi_float_t __aeabi_ul2f(unsigned long long a)
{
return f32_to_f(ui64_to_f32(a));
}

View File

@@ -1,5 +1,5 @@
//
// Copyright (c) 2012 - 2020, ARM Limited. All rights reserved.
// Copyright (c) 2012 - 2017, ARM Limited. All rights reserved.
//
// SPDX-License-Identifier: BSD-2-Clause-Patent
//
@@ -25,9 +25,6 @@ ASM_PFX(ArmCallSvc):
ldp x0, x1, [x0, #0]
svc #0
// Prevent speculative execution beyond svc instruction
dsb nsh
isb
// Pop the ARM_SVC_ARGS structure address from the stack into x9
ldr x9, [sp, #16]

View File

@@ -1,5 +1,5 @@
//
// Copyright (c) 2016 - 2020, ARM Limited. All rights reserved.
// Copyright (c) 2016 - 2017, ARM Limited. All rights reserved.
//
// SPDX-License-Identifier: BSD-2-Clause-Patent
//
@@ -18,9 +18,6 @@ ASM_PFX(ArmCallSvc):
ldm r0, {r0-r7}
svc #0
// Prevent speculative execution beyond svc instruction
dsb nsh
isb
// Load the ARM_SVC_ARGS structure address from the stack into r8
ldr r8, [sp]

View File

@@ -1,5 +1,5 @@
//
// Copyright (c) 2016 - 2020, ARM Limited. All rights reserved.
// Copyright (c) 2016 - 2017, ARM Limited. All rights reserved.
//
// SPDX-License-Identifier: BSD-2-Clause-Patent
//
@@ -16,9 +16,6 @@
ldm r0, {r0-r7}
svc #0
// Prevent speculative execution beyond svc instruction
dsb nsh
isb
// Load the ARM_SVC_ARGS structure address from the stack into r8
ldr r8, [sp]

View File

@@ -1,142 +0,0 @@
#------------------------------------------------------------------------------
#
# Copyright (c) 2020, Arm, Limited. All rights reserved.<BR>
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
#------------------------------------------------------------------------------
/*
* Provide the GCC intrinsics that are required when using GCC 9 or
* later with the -moutline-atomics options (which became the default
* in GCC 10)
*/
.arch armv8-a
.macro reg_alias, pfx, sz
r0_\sz .req \pfx\()0
r1_\sz .req \pfx\()1
tmp0_\sz .req \pfx\()16
tmp1_\sz .req \pfx\()17
.endm
/*
* Define register aliases of the right type for each size
* (xN for 8 bytes, wN for everything smaller)
*/
reg_alias w, 1
reg_alias w, 2
reg_alias w, 4
reg_alias x, 8
.macro fn_start, name:req
.section .text.\name
.globl \name
.type \name, %function
\name\():
.endm
.macro fn_end, name:req
.size \name, . - \name
.endm
/*
* Emit an atomic helper for \model with operands of size \sz, using
* the operation specified by \insn (which is the LSE name), and which
* can be implemented using the generic load-locked/store-conditional
* (LL/SC) sequence below, using the arithmetic operation given by
* \opc.
*/
.macro emit_ld_sz, sz:req, insn:req, opc:req, model:req, s, a, l
fn_start __aarch64_\insn\()\sz\()\model
mov tmp0_\sz, r0_\sz
0: ld\a\()xr\s r0_\sz, [x1]
.ifnc \insn, swp
\opc tmp1_\sz, r0_\sz, tmp0_\sz
st\l\()xr\s w15, tmp1_\sz, [x1]
.else
st\l\()xr\s w15, tmp0_\sz, [x1]
.endif
cbnz w15, 0b
ret
fn_end __aarch64_\insn\()\sz\()\model
.endm
/*
* Emit atomic helpers for \model for operand sizes in the
* set {1, 2, 4, 8}, for the instruction pattern given by
* \insn. (This is the LSE name, but this implementation uses
* the generic LL/SC sequence using \opc as the arithmetic
* operation on the target.)
*/
.macro emit_ld, insn:req, opc:req, model:req, a, l
emit_ld_sz 1, \insn, \opc, \model, b, \a, \l
emit_ld_sz 2, \insn, \opc, \model, h, \a, \l
emit_ld_sz 4, \insn, \opc, \model, , \a, \l
emit_ld_sz 8, \insn, \opc, \model, , \a, \l
.endm
/*
* Emit the compare and swap helper for \model and size \sz
* using LL/SC instructions.
*/
.macro emit_cas_sz, sz:req, model:req, uxt:req, s, a, l
fn_start __aarch64_cas\sz\()\model
\uxt tmp0_\sz, r0_\sz
0: ld\a\()xr\s r0_\sz, [x2]
cmp r0_\sz, tmp0_\sz
bne 1f
st\l\()xr\s w15, r1_\sz, [x2]
cbnz w15, 0b
1: ret
fn_end __aarch64_cas\sz\()\model
.endm
/*
* Emit compare-and-swap helpers for \model for operand sizes in the
* set {1, 2, 4, 8, 16}.
*/
.macro emit_cas, model:req, a, l
emit_cas_sz 1, \model, uxtb, b, \a, \l
emit_cas_sz 2, \model, uxth, h, \a, \l
emit_cas_sz 4, \model, mov , , \a, \l
emit_cas_sz 8, \model, mov , , \a, \l
/*
* We cannot use the parameterized sequence for 16 byte CAS, so we
* need to define it explicitly.
*/
fn_start __aarch64_cas16\model
mov x16, x0
mov x17, x1
0: ld\a\()xp x0, x1, [x4]
cmp x0, x16
ccmp x1, x17, #0, eq
bne 1f
st\l\()xp w15, x16, x17, [x4]
cbnz w15, 0b
1: ret
fn_end __aarch64_cas16\model
.endm
/*
* Emit the set of GCC outline atomic helper functions for
* the memory ordering model given by \model:
* - relax unordered loads and stores
* - acq load-acquire, unordered store
* - rel unordered load, store-release
* - acq_rel load-acquire, store-release
*/
.macro emit_model, model:req, a, l
emit_ld ldadd, add, \model, \a, \l
emit_ld ldclr, bic, \model, \a, \l
emit_ld ldeor, eor, \model, \a, \l
emit_ld ldset, orr, \model, \a, \l
emit_ld swp, mov, \model, \a, \l
emit_cas \model, \a, \l
.endm
emit_model _relax
emit_model _acq, a
emit_model _rel,, l
emit_model _acq_rel, a, l

View File

@@ -79,9 +79,6 @@
Arm/ldivmod.asm | MSFT
Arm/llsr.asm | MSFT
[Sources.AARCH64]
AArch64/Atomics.S | GCC
[Packages]
MdePkg/MdePkg.dec
ArmPkg/ArmPkg.dec

View File

@@ -1,55 +1,55 @@
//------------------------------------------------------------------------------
//
// Copyright (c) 2016, Linaro Ltd. All rights reserved.<BR>
//
// SPDX-License-Identifier: BSD-2-Clause-Patent
//
//------------------------------------------------------------------------------
typedef __SIZE_TYPE__ size_t;
static __attribute__((__used__))
void *__memset(void *s, int c, size_t n)
{
unsigned char *d = s;
while (n--)
*d++ = c;
return s;
}
//
// Other modules (such as CryptoPkg/IntrinsicLib) may provide another
// implementation of memset(), which may conflict with this one if this
// object was pulled into the link due to the definitions below. So make
// our memset() 'weak' to let the other implementation take precedence.
//
__attribute__((__weak__, __alias__("__memset")))
void *memset(void *dest, int c, size_t n);
#ifdef __arm__
void __aeabi_memset(void *dest, size_t n, int c)
{
__memset(dest, c, n);
}
__attribute__((__alias__("__aeabi_memset")))
void __aeabi_memset4(void *dest, size_t n, int c);
__attribute__((__alias__("__aeabi_memset")))
void __aeabi_memset8(void *dest, size_t n, int c);
void __aeabi_memclr(void *dest, size_t n)
{
__memset(dest, 0, n);
}
__attribute__((__alias__("__aeabi_memclr")))
void __aeabi_memclr4(void *dest, size_t n);
__attribute__((__alias__("__aeabi_memclr")))
void __aeabi_memclr8(void *dest, size_t n);
#endif
//------------------------------------------------------------------------------
//
// Copyright (c) 2016, Linaro Ltd. All rights reserved.<BR>
//
// SPDX-License-Identifier: BSD-2-Clause-Patent
//
//------------------------------------------------------------------------------
typedef __SIZE_TYPE__ size_t;
static __attribute__((__used__))
void *__memset(void *s, int c, size_t n)
{
unsigned char *d = s;
while (n--)
*d++ = c;
return s;
}
//
// Other modules (such as CryptoPkg/IntrinsicLib) may provide another
// implementation of memset(), which may conflict with this one if this
// object was pulled into the link due to the definitions below. So make
// our memset() 'weak' to let the other implementation take precedence.
//
__attribute__((__weak__, __alias__("__memset")))
void *memset(void *dest, int c, size_t n);
#ifdef __arm__
void __aeabi_memset(void *dest, size_t n, int c)
{
__memset(dest, c, n);
}
__attribute__((__alias__("__aeabi_memset")))
void __aeabi_memset4(void *dest, size_t n, int c);
__attribute__((__alias__("__aeabi_memset")))
void __aeabi_memset8(void *dest, size_t n, int c);
void __aeabi_memclr(void *dest, size_t n)
{
__memset(dest, 0, n);
}
__attribute__((__alias__("__aeabi_memclr")))
void __aeabi_memclr4(void *dest, size_t n);
__attribute__((__alias__("__aeabi_memclr")))
void __aeabi_memclr8(void *dest, size_t n);
#endif

View File

@@ -1,21 +1,21 @@
//
// Copyright (c) 2016, Linaro Ltd. All rights reserved.<BR>
//
// SPDX-License-Identifier: BSD-2-Clause-Patent
//
//
// GCC in LTO mode interoperates poorly with non-standard libraries that
// provide implementations of compiler intrinsics such as memcpy/memset
// or the stack protector entry points.
//
// By referencing these functions from a non-LTO object that can be passed
// to the linker via the -plugin-opt=-pass-through=-lxxx options, the
// intrinsics are included in the link in a way that allows them to be
// pruned again if no other references to them exist.
//
.long memcpy - .
.long memset - .
.long __stack_chk_fail - .
.long __stack_chk_guard - .
//
// Copyright (c) 2016, Linaro Ltd. All rights reserved.<BR>
//
// SPDX-License-Identifier: BSD-2-Clause-Patent
//
//
// GCC in LTO mode interoperates poorly with non-standard libraries that
// provide implementations of compiler intrinsics such as memcpy/memset
// or the stack protector entry points.
//
// By referencing these functions from a non-LTO object that can be passed
// to the linker via the -plugin-opt=-pass-through=-lxxx options, the
// intrinsics are included in the link in a way that allows them to be
// pruned again if no other references to them exist.
//
.long memcpy - .
.long memset - .
.long __stack_chk_fail - .
.long __stack_chk_guard - .

View File

@@ -1,55 +1,55 @@
//
// Copyright (c) 2016, Linaro Ltd. All rights reserved.<BR>
//
// SPDX-License-Identifier: BSD-2-Clause-Patent
//
//
// GCC in LTO mode interoperates poorly with non-standard libraries that
// provide implementations of compiler intrinsics such as memcpy/memset
// or the stack protector entry points.
//
// By referencing these functions from a non-LTO object that can be passed
// to the linker via the -plugin-opt=-pass-through=-lxxx options, the
// intrinsics are included in the link in a way that allows them to be
// pruned again if no other references to them exist.
//
.long memcpy - .
.long memset - .
.long __stack_chk_fail - .
.long __stack_chk_guard - .
.long __ashrdi3 - .
.long __ashldi3 - .
.long __aeabi_idiv - .
.long __aeabi_idivmod - .
.long __aeabi_uidiv - .
.long __aeabi_uidivmod - .
.long __divdi3 - .
.long __divsi3 - .
.long __lshrdi3 - .
.long __aeabi_memcpy - .
.long __aeabi_memset - .
.long memmove - .
.long __modsi3 - .
.long __moddi3 - .
.long __muldi3 - .
.long __aeabi_lmul - .
.long __ARM_ll_mullu - .
.long __udivsi3 - .
.long __umodsi3 - .
.long __udivdi3 - .
.long __umoddi3 - .
.long __udivmoddi4 - .
.long __clzsi2 - .
.long __ctzsi2 - .
.long __ucmpdi2 - .
.long __switch8 - .
.long __switchu8 - .
.long __switch16 - .
.long __switch32 - .
.long __aeabi_ulcmp - .
.long __aeabi_uldivmod - .
.long __aeabi_ldivmod - .
.long __aeabi_llsr - .
.long __aeabi_llsl - .
//
// Copyright (c) 2016, Linaro Ltd. All rights reserved.<BR>
//
// SPDX-License-Identifier: BSD-2-Clause-Patent
//
//
// GCC in LTO mode interoperates poorly with non-standard libraries that
// provide implementations of compiler intrinsics such as memcpy/memset
// or the stack protector entry points.
//
// By referencing these functions from a non-LTO object that can be passed
// to the linker via the -plugin-opt=-pass-through=-lxxx options, the
// intrinsics are included in the link in a way that allows them to be
// pruned again if no other references to them exist.
//
.long memcpy - .
.long memset - .
.long __stack_chk_fail - .
.long __stack_chk_guard - .
.long __ashrdi3 - .
.long __ashldi3 - .
.long __aeabi_idiv - .
.long __aeabi_idivmod - .
.long __aeabi_uidiv - .
.long __aeabi_uidivmod - .
.long __divdi3 - .
.long __divsi3 - .
.long __lshrdi3 - .
.long __aeabi_memcpy - .
.long __aeabi_memset - .
.long memmove - .
.long __modsi3 - .
.long __moddi3 - .
.long __muldi3 - .
.long __aeabi_lmul - .
.long __ARM_ll_mullu - .
.long __udivsi3 - .
.long __umodsi3 - .
.long __udivdi3 - .
.long __umoddi3 - .
.long __udivmoddi4 - .
.long __clzsi2 - .
.long __ctzsi2 - .
.long __ucmpdi2 - .
.long __switch8 - .
.long __switchu8 - .
.long __switch16 - .
.long __switch32 - .
.long __aeabi_ulcmp - .
.long __aeabi_uldivmod - .
.long __aeabi_ldivmod - .
.long __aeabi_llsr - .
.long __aeabi_llsl - .

View File

@@ -23,12 +23,10 @@
#include <Protocol/EsrtManagement.h>
#include <Protocol/GraphicsOutput.h>
#include <Protocol/LoadedImage.h>
#include <Protocol/NonDiscoverableDevice.h>
#include <Protocol/PciIo.h>
#include <Protocol/PciRootBridgeIo.h>
#include <Protocol/PlatformBootManager.h>
#include <Guid/EventGroup.h>
#include <Guid/NonDiscoverableDevice.h>
#include <Guid/TtyTerm.h>
#include <Guid/SerialPortLibVendor.h>
@@ -256,37 +254,6 @@ IsPciDisplay (
}
/**
This FILTER_FUNCTION checks if a handle corresponds to a non-discoverable
USB host controller.
**/
STATIC
BOOLEAN
EFIAPI
IsUsbHost (
IN EFI_HANDLE Handle,
IN CONST CHAR16 *ReportText
)
{
NON_DISCOVERABLE_DEVICE *Device;
EFI_STATUS Status;
Status = gBS->HandleProtocol (Handle,
&gEdkiiNonDiscoverableDeviceProtocolGuid,
(VOID **)&Device);
if (EFI_ERROR (Status)) {
return FALSE;
}
if (CompareGuid (Device->Type, &gEdkiiNonDiscoverableUhciDeviceGuid) ||
CompareGuid (Device->Type, &gEdkiiNonDiscoverableEhciDeviceGuid) ||
CompareGuid (Device->Type, &gEdkiiNonDiscoverableXhciDeviceGuid)) {
return TRUE;
}
return FALSE;
}
/**
This CALLBACK_FUNCTION attempts to connect a handle non-recursively, asking
the matching driver to produce all first-level child handles.
@@ -357,8 +324,7 @@ VOID
PlatformRegisterFvBootOption (
CONST EFI_GUID *FileGuid,
CHAR16 *Description,
UINT32 Attributes,
EFI_INPUT_KEY *Key
UINT32 Attributes
)
{
EFI_STATUS Status;
@@ -410,9 +376,6 @@ PlatformRegisterFvBootOption (
if (OptionIndex == -1) {
Status = EfiBootManagerAddLoadOptionVariable (&NewOption, MAX_UINTN);
ASSERT_EFI_ERROR (Status);
Status = EfiBootManagerAddKeyOptionVariable (NULL,
(UINT16)NewOption.OptionNumber, 0, Key, NULL);
ASSERT (Status == EFI_SUCCESS || Status == EFI_ALREADY_STARTED);
}
EfiBootManagerFreeLoadOption (&NewOption);
EfiBootManagerFreeLoadOptions (BootOptions, BootOptionCount);
@@ -611,15 +574,6 @@ PlatformBootManagerBeforeConsole (
//
FilterAndProcess (&gEfiGraphicsOutputProtocolGuid, NULL, AddOutput);
//
// The core BDS code connects short-form USB device paths by explicitly
// looking for handles with PCI I/O installed, and checking the PCI class
// code whether it matches the one for a USB host controller. This means
// non-discoverable USB host controllers need to have the non-discoverable
// PCI driver attached first.
//
FilterAndProcess (&gEdkiiNonDiscoverableDeviceProtocolGuid, IsUsbHost, Connect);
//
// Add the hardcoded short-form USB keyboard device path to ConIn.
//
@@ -629,13 +583,7 @@ PlatformBootManagerBeforeConsole (
//
// Add the hardcoded serial console device path to ConIn, ConOut, ErrOut.
//
STATIC_ASSERT (FixedPcdGet8 (PcdDefaultTerminalType) == 4,
"PcdDefaultTerminalType must be TTYTERM");
STATIC_ASSERT (FixedPcdGet8 (PcdUartDefaultParity) != 0,
"PcdUartDefaultParity must be set to an actual value, not 'default'");
STATIC_ASSERT (FixedPcdGet8 (PcdUartDefaultStopBits) != 0,
"PcdUartDefaultStopBits must be set to an actual value, not 'default'");
ASSERT (FixedPcdGet8 (PcdDefaultTerminalType) == 4);
CopyGuid (&mSerialConsole.TermType.Guid, &gEfiTtyTermGuid);
EfiBootManagerUpdateConsoleVariable (ConIn,
@@ -725,7 +673,6 @@ PlatformBootManagerAfterConsole (
UINTN FirmwareVerLength;
UINTN PosX;
UINTN PosY;
EFI_INPUT_KEY Key;
FirmwareVerLength = StrLen (PcdGetPtr (PcdFirmwareVersionString));
@@ -753,6 +700,11 @@ PlatformBootManagerAfterConsole (
}
}
//
// Connect the rest of the devices.
//
EfiBootManagerConnectAll ();
//
// On ARM, there is currently no reason to use the phased capsule
// update approach where some capsules are dispatched before EndOfDxe
@@ -762,12 +714,17 @@ PlatformBootManagerAfterConsole (
//
HandleCapsules ();
//
// Enumerate all possible boot options.
//
EfiBootManagerRefreshAllBootOption ();
//
// Register UEFI Shell
//
Key.ScanCode = SCAN_NULL;
Key.UnicodeChar = L's';
PlatformRegisterFvBootOption (&gUefiShellFileGuid, L"UEFI Shell", 0, &Key);
PlatformRegisterFvBootOption (
&gUefiShellFileGuid, L"UEFI Shell", LOAD_OPTION_ACTIVE
);
}
/**
@@ -818,49 +775,5 @@ PlatformBootManagerUnableToBoot (
VOID
)
{
EFI_STATUS Status;
EFI_BOOT_MANAGER_LOAD_OPTION BootManagerMenu;
EFI_BOOT_MANAGER_LOAD_OPTION *BootOptions;
UINTN OldBootOptionCount;
UINTN NewBootOptionCount;
//
// Record the total number of boot configured boot options
//
BootOptions = EfiBootManagerGetLoadOptions (&OldBootOptionCount,
LoadOptionTypeBoot);
EfiBootManagerFreeLoadOptions (BootOptions, OldBootOptionCount);
//
// Connect all devices, and regenerate all boot options
//
EfiBootManagerConnectAll ();
EfiBootManagerRefreshAllBootOption ();
//
// Record the updated number of boot configured boot options
//
BootOptions = EfiBootManagerGetLoadOptions (&NewBootOptionCount,
LoadOptionTypeBoot);
EfiBootManagerFreeLoadOptions (BootOptions, NewBootOptionCount);
//
// If the number of configured boot options has changed, reboot
// the system so the new boot options will be taken into account
// while executing the ordinary BDS bootflow sequence.
//
if (NewBootOptionCount != OldBootOptionCount) {
DEBUG ((DEBUG_WARN, "%a: rebooting after refreshing all boot options\n",
__FUNCTION__));
gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL);
}
Status = EfiBootManagerGetBootManagerMenu (&BootManagerMenu);
if (EFI_ERROR (Status)) {
return;
}
for (;;) {
EfiBootManagerBoot (&BootManagerMenu);
}
return;
}

View File

@@ -66,9 +66,6 @@
gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut
[Guids]
gEdkiiNonDiscoverableEhciDeviceGuid
gEdkiiNonDiscoverableUhciDeviceGuid
gEdkiiNonDiscoverableXhciDeviceGuid
gEfiFileInfoGuid
gEfiFileSystemInfoGuid
gEfiFileSystemVolumeLabelInfoIdGuid
@@ -77,7 +74,6 @@
gUefiShellFileGuid
[Protocols]
gEdkiiNonDiscoverableDeviceProtocolGuid
gEfiDevicePathProtocolGuid
gEfiGraphicsOutputProtocolGuid
gEfiLoadedImageProtocolGuid

View File

@@ -94,6 +94,10 @@
gArmPlatformTokenSpaceGuid.PcdArmMaliDpBase|0x0|UINT64|0x00000050
gArmPlatformTokenSpaceGuid.PcdArmMaliDpMemoryRegionLength|0x0|UINT32|0x00000051
## PL180 MCI
gArmPlatformTokenSpaceGuid.PcdPL180SysMciRegAddress|0x00000000|UINT32|0x00000028
gArmPlatformTokenSpaceGuid.PcdPL180MciBaseAddress|0x00000000|UINT32|0x00000029
# Graphics Output Pixel format
# 0 : PixelRedGreenBlueReserved8BitPerColor
# 1 : PixelBlueGreenRedReserved8BitPerColor

View File

@@ -4,7 +4,6 @@
# Copyright (c) 2009 - 2010, Apple Inc. All rights reserved.<BR>
# Copyright (c) 2011 - 2018, ARM Ltd. All rights reserved.<BR>
# Copyright (c) 2016 - 2017, Linaro Ltd. All rights reserved.<BR>
# Copyright (c) Microsoft Corporation.<BR>
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
@@ -91,11 +90,11 @@
ArmPlatformPkg/Drivers/LcdGraphicsOutputDxe/LcdGraphicsOutputDxe.inf
ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.inf
ArmPlatformPkg/Drivers/PL061GpioDxe/PL061GpioDxe.inf
ArmPlatformPkg/Drivers/PL180MciDxe/PL180MciDxe.inf
ArmPlatformPkg/Drivers/SP805WatchdogDxe/SP805WatchdogDxe.inf
ArmPlatformPkg/Library/ArmPlatformLibNull/ArmPlatformLibNull.inf
ArmPlatformPkg/Library/ArmPlatformStackLib/ArmPlatformStackLib.inf
ArmPlatformPkg/Library/HdLcd/HdLcd.inf
ArmPlatformPkg/Library/LcdHwNullLib/LcdHwNullLib.inf
ArmPlatformPkg/Library/LcdPlatformNullLib/LcdPlatformNullLib.inf
ArmPlatformPkg/Library/NorFlashPlatformNullLib/NorFlashPlatformNullLib.inf
@@ -103,7 +102,6 @@
ArmPlatformPkg/Library/PL011UartClockLib/PL011UartClockLib.inf
ArmPlatformPkg/Library/PL011UartLib/PL011UartLib.inf
ArmPlatformPkg/Library/PL031RealTimeClockLib/PL031RealTimeClockLib.inf
ArmPlatformPkg/Library/PL111Lcd/PL111Lcd.inf
ArmPlatformPkg/Library/PrePiHobListPointerLib/PrePiHobListPointerLib.inf
ArmPlatformPkg/MemoryInitPei/MemoryInitPeiLib.inf

View File

@@ -38,7 +38,6 @@
UefiLib
[Protocols]
gEfiCpuArchProtocolGuid
gEfiDevicePathProtocolGuid
gEfiGraphicsOutputProtocolGuid

View File

@@ -1,6 +1,6 @@
/*++ @file NorFlashFvbDxe.c
Copyright (c) 2011 - 2020, ARM Ltd. All rights reserved.<BR>
Copyright (c) 2011 - 2014, ARM Ltd. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -736,7 +736,7 @@ NorFlashFvbInitialize (
EFI_MEMORY_UC | EFI_MEMORY_RUNTIME);
ASSERT_EFI_ERROR (Status);
mFlashNvStorageVariableBase = PcdGet32 (PcdFlashNvStorageVariableBase);
mFlashNvStorageVariableBase = FixedPcdGet32 (PcdFlashNvStorageVariableBase);
// Set the index of the first LBA for the FVB
Instance->StartLba = (PcdGet32 (PcdFlashNvStorageVariableBase) - Instance->RegionBaseAddress) / Instance->Media.BlockSize;

View File

@@ -0,0 +1,563 @@
/** @file
This file implement the MMC Host Protocol for the ARM PrimeCell PL180.
Copyright (c) 2011-2012, ARM Limited. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include "PL180Mci.h"
#include <Library/DevicePathLib.h>
#include <Library/BaseMemoryLib.h>
EFI_MMC_HOST_PROTOCOL *gpMmcHost;
// Untested ...
//#define USE_STREAM
#define MMCI0_BLOCKLEN 512
#define MMCI0_POW2_BLOCKLEN 9
#define MMCI0_TIMEOUT 1000
#define SYS_MCI_CARDIN BIT0
#define SYS_MCI_WPROT BIT1
BOOLEAN
MciIsPowerOn (
VOID
)
{
return ((MmioRead32 (MCI_POWER_CONTROL_REG) & MCI_POWER_ON) == MCI_POWER_ON);
}
EFI_STATUS
MciInitialize (
VOID
)
{
MCI_TRACE ("MciInitialize()");
return EFI_SUCCESS;
}
BOOLEAN
MciIsCardPresent (
IN EFI_MMC_HOST_PROTOCOL *This
)
{
return (MmioRead32 (FixedPcdGet32 (PcdPL180SysMciRegAddress)) & SYS_MCI_CARDIN);
}
BOOLEAN
MciIsReadOnly (
IN EFI_MMC_HOST_PROTOCOL *This
)
{
return (MmioRead32 (FixedPcdGet32 (PcdPL180SysMciRegAddress)) & SYS_MCI_WPROT);
}
// Convert block size to 2^n
STATIC
UINT32
GetPow2BlockLen (
IN UINT32 BlockLen
)
{
UINTN Loop;
UINTN Pow2BlockLen;
Loop = 0x8000;
Pow2BlockLen = 15;
do {
Loop = (Loop >> 1) & 0xFFFF;
Pow2BlockLen--;
} while (Pow2BlockLen && (!(Loop & BlockLen)));
return Pow2BlockLen;
}
VOID
MciPrepareDataPath (
IN UINTN TransferDirection
)
{
// Set Data Length & Data Timer
MmioWrite32 (MCI_DATA_TIMER_REG, 0xFFFFFFF);
MmioWrite32 (MCI_DATA_LENGTH_REG, MMCI0_BLOCKLEN);
#ifndef USE_STREAM
//Note: we are using a hardcoded BlockLen (==512). If we decide to use a variable size, we could
// compute the pow2 of BlockLen with the above function GetPow2BlockLen ()
MmioWrite32 (MCI_DATA_CTL_REG, MCI_DATACTL_ENABLE | MCI_DATACTL_DMA_ENABLE | TransferDirection | (MMCI0_POW2_BLOCKLEN << 4));
#else
MmioWrite32 (MCI_DATA_CTL_REG, MCI_DATACTL_ENABLE | MCI_DATACTL_DMA_ENABLE | TransferDirection | MCI_DATACTL_STREAM_TRANS);
#endif
}
EFI_STATUS
MciSendCommand (
IN EFI_MMC_HOST_PROTOCOL *This,
IN MMC_CMD MmcCmd,
IN UINT32 Argument
)
{
UINT32 Status;
UINT32 Cmd;
UINTN RetVal;
UINTN CmdCtrlReg;
UINT32 DoneMask;
RetVal = EFI_SUCCESS;
if ((MmcCmd == MMC_CMD17) || (MmcCmd == MMC_CMD11)) {
MciPrepareDataPath (MCI_DATACTL_CARD_TO_CONT);
} else if ((MmcCmd == MMC_CMD24) || (MmcCmd == MMC_CMD20)) {
MciPrepareDataPath (MCI_DATACTL_CONT_TO_CARD);
} else if (MmcCmd == MMC_CMD6) {
MmioWrite32 (MCI_DATA_TIMER_REG, 0xFFFFFFF);
MmioWrite32 (MCI_DATA_LENGTH_REG, 64);
#ifndef USE_STREAM
MmioWrite32 (MCI_DATA_CTL_REG, MCI_DATACTL_ENABLE | MCI_DATACTL_CARD_TO_CONT | GetPow2BlockLen (64));
#else
MmioWrite32 (MCI_DATA_CTL_REG, MCI_DATACTL_ENABLE | MCI_DATACTL_CARD_TO_CONT | MCI_DATACTL_STREAM_TRANS);
#endif
} else if (MmcCmd == MMC_ACMD51) {
MmioWrite32 (MCI_DATA_TIMER_REG, 0xFFFFFFF);
/* SCR register is 8 bytes long. */
MmioWrite32 (MCI_DATA_LENGTH_REG, 8);
#ifndef USE_STREAM
MmioWrite32 (MCI_DATA_CTL_REG, MCI_DATACTL_ENABLE | MCI_DATACTL_CARD_TO_CONT | GetPow2BlockLen (8));
#else
MmioWrite32 (MCI_DATA_CTL_REG, MCI_DATACTL_ENABLE | MCI_DATACTL_CARD_TO_CONT | MCI_DATACTL_STREAM_TRANS);
#endif
}
// Create Command for PL180
Cmd = (MMC_GET_INDX (MmcCmd) & INDX_MASK) | MCI_CPSM_ENABLE;
if (MmcCmd & MMC_CMD_WAIT_RESPONSE) {
Cmd |= MCI_CPSM_WAIT_RESPONSE;
}
if (MmcCmd & MMC_CMD_LONG_RESPONSE) {
Cmd |= MCI_CPSM_LONG_RESPONSE;
}
// Clear Status register static flags
MmioWrite32 (MCI_CLEAR_STATUS_REG, MCI_CLR_ALL_STATUS);
// Write to command argument register
MmioWrite32 (MCI_ARGUMENT_REG, Argument);
// Write to command register
MmioWrite32 (MCI_COMMAND_REG, Cmd);
DoneMask = (Cmd & MCI_CPSM_WAIT_RESPONSE)
? (MCI_STATUS_CMD_RESPEND | MCI_STATUS_CMD_ERROR)
: (MCI_STATUS_CMD_SENT | MCI_STATUS_CMD_ERROR);
do {
Status = MmioRead32 (MCI_STATUS_REG);
} while (! (Status & DoneMask));
if ((Status & MCI_STATUS_CMD_ERROR)) {
// Clear Status register error flags
MmioWrite32 (MCI_CLEAR_STATUS_REG, MCI_STATUS_CMD_ERROR);
if ((Status & MCI_STATUS_CMD_START_BIT_ERROR)) {
DEBUG ((EFI_D_ERROR, "MciSendCommand(CmdIndex:%d) Start bit Error! Response:0x%X Status:0x%x\n", (Cmd & 0x3F), MmioRead32 (MCI_RESPONSE0_REG), Status));
RetVal = EFI_NO_RESPONSE;
} else if ((Status & MCI_STATUS_CMD_CMDTIMEOUT)) {
//DEBUG ((EFI_D_ERROR, "MciSendCommand(CmdIndex:%d) TIMEOUT! Response:0x%X Status:0x%x\n", (Cmd & 0x3F), MmioRead32 (MCI_RESPONSE0_REG), Status));
RetVal = EFI_TIMEOUT;
} else if ((!(MmcCmd & MMC_CMD_NO_CRC_RESPONSE)) && (Status & MCI_STATUS_CMD_CMDCRCFAIL)) {
// The CMD1 and response type R3 do not contain CRC. We should ignore the CRC failed Status.
RetVal = EFI_CRC_ERROR;
}
}
// Disable Command Path
CmdCtrlReg = MmioRead32 (MCI_COMMAND_REG);
MmioWrite32 (MCI_COMMAND_REG, (CmdCtrlReg & ~MCI_CPSM_ENABLE));
return RetVal;
}
EFI_STATUS
MciReceiveResponse (
IN EFI_MMC_HOST_PROTOCOL *This,
IN MMC_RESPONSE_TYPE Type,
IN UINT32* Buffer
)
{
if (Buffer == NULL) {
return EFI_INVALID_PARAMETER;
}
if ( (Type == MMC_RESPONSE_TYPE_R1)
|| (Type == MMC_RESPONSE_TYPE_R1b)
|| (Type == MMC_RESPONSE_TYPE_R3)
|| (Type == MMC_RESPONSE_TYPE_R6)
|| (Type == MMC_RESPONSE_TYPE_R7))
{
Buffer[0] = MmioRead32 (MCI_RESPONSE3_REG);
} else if (Type == MMC_RESPONSE_TYPE_R2) {
Buffer[0] = MmioRead32 (MCI_RESPONSE0_REG);
Buffer[1] = MmioRead32 (MCI_RESPONSE1_REG);
Buffer[2] = MmioRead32 (MCI_RESPONSE2_REG);
Buffer[3] = MmioRead32 (MCI_RESPONSE3_REG);
}
return EFI_SUCCESS;
}
EFI_STATUS
MciReadBlockData (
IN EFI_MMC_HOST_PROTOCOL *This,
IN EFI_LBA Lba,
IN UINTN Length,
IN UINT32* Buffer
)
{
UINTN Loop;
UINTN Finish;
UINTN Status;
EFI_STATUS RetVal;
UINTN DataCtrlReg;
EFI_TPL Tpl;
RetVal = EFI_SUCCESS;
// Read data from the RX FIFO
Loop = 0;
if (Length < MMCI0_BLOCKLEN) {
Finish = Length / 4;
} else {
Finish = MMCI0_BLOCKLEN / 4;
}
// Raise the TPL at the highest level to disable Interrupts.
Tpl = gBS->RaiseTPL (TPL_HIGH_LEVEL);
do {
// Read the Status flags
Status = MmioRead32 (MCI_STATUS_REG);
// Do eight reads if possible else a single read
if (Status & MCI_STATUS_CMD_RXFIFOHALFFULL) {
Buffer[Loop] = MmioRead32(MCI_FIFO_REG);
Loop++;
Buffer[Loop] = MmioRead32(MCI_FIFO_REG);
Loop++;
Buffer[Loop] = MmioRead32(MCI_FIFO_REG);
Loop++;
Buffer[Loop] = MmioRead32(MCI_FIFO_REG);
Loop++;
Buffer[Loop] = MmioRead32(MCI_FIFO_REG);
Loop++;
Buffer[Loop] = MmioRead32(MCI_FIFO_REG);
Loop++;
Buffer[Loop] = MmioRead32(MCI_FIFO_REG);
Loop++;
Buffer[Loop] = MmioRead32(MCI_FIFO_REG);
Loop++;
} else if (Status & MCI_STATUS_CMD_RXDATAAVAILBL) {
Buffer[Loop] = MmioRead32(MCI_FIFO_REG);
Loop++;
} else {
//Check for error conditions and timeouts
if (Status & MCI_STATUS_CMD_DATATIMEOUT) {
DEBUG ((EFI_D_ERROR, "MciReadBlockData(): TIMEOUT! Response:0x%X Status:0x%x\n", MmioRead32 (MCI_RESPONSE0_REG), Status));
RetVal = EFI_TIMEOUT;
break;
} else if (Status & MCI_STATUS_CMD_DATACRCFAIL) {
DEBUG ((EFI_D_ERROR, "MciReadBlockData(): CRC Error! Response:0x%X Status:0x%x\n", MmioRead32 (MCI_RESPONSE0_REG), Status));
RetVal = EFI_CRC_ERROR;
break;
} else if (Status & MCI_STATUS_CMD_START_BIT_ERROR) {
DEBUG ((EFI_D_ERROR, "MciReadBlockData(): Start-bit Error! Response:0x%X Status:0x%x\n", MmioRead32 (MCI_RESPONSE0_REG), Status));
RetVal = EFI_NO_RESPONSE;
break;
}
}
//clear RX over run flag
if(Status & MCI_STATUS_CMD_RXOVERRUN) {
MmioWrite32(MCI_CLEAR_STATUS_REG, MCI_STATUS_CMD_RXOVERRUN);
}
} while ((Loop < Finish));
// Restore Tpl
gBS->RestoreTPL (Tpl);
// Clear Status flags
MmioWrite32 (MCI_CLEAR_STATUS_REG, MCI_CLR_ALL_STATUS);
//Disable Data path
DataCtrlReg = MmioRead32 (MCI_DATA_CTL_REG);
MmioWrite32 (MCI_DATA_CTL_REG, (DataCtrlReg & MCI_DATACTL_DISABLE_MASK));
return RetVal;
}
EFI_STATUS
MciWriteBlockData (
IN EFI_MMC_HOST_PROTOCOL *This,
IN EFI_LBA Lba,
IN UINTN Length,
IN UINT32* Buffer
)
{
UINTN Loop;
UINTN Finish;
UINTN Timer;
UINTN Status;
EFI_STATUS RetVal;
UINTN DataCtrlReg;
EFI_TPL Tpl;
RetVal = EFI_SUCCESS;
// Write the data to the TX FIFO
Loop = 0;
Finish = MMCI0_BLOCKLEN / 4;
Timer = MMCI0_TIMEOUT * 100;
// Raise the TPL at the highest level to disable Interrupts.
Tpl = gBS->RaiseTPL (TPL_HIGH_LEVEL);
do {
// Read the Status flags
Status = MmioRead32 (MCI_STATUS_REG);
// Do eight writes if possible else a single write
if (Status & MCI_STATUS_CMD_TXFIFOHALFEMPTY) {
MmioWrite32(MCI_FIFO_REG, Buffer[Loop]);
Loop++;
MmioWrite32(MCI_FIFO_REG, Buffer[Loop]);
Loop++;
MmioWrite32(MCI_FIFO_REG, Buffer[Loop]);
Loop++;
MmioWrite32(MCI_FIFO_REG, Buffer[Loop]);
Loop++;
MmioWrite32(MCI_FIFO_REG, Buffer[Loop]);
Loop++;
MmioWrite32(MCI_FIFO_REG, Buffer[Loop]);
Loop++;
MmioWrite32(MCI_FIFO_REG, Buffer[Loop]);
Loop++;
MmioWrite32(MCI_FIFO_REG, Buffer[Loop]);
Loop++;
} else if (!(Status & MCI_STATUS_CMD_TXFIFOFULL)) {
MmioWrite32(MCI_FIFO_REG, Buffer[Loop]);
Loop++;
} else {
// Check for error conditions and timeouts
if (Status & MCI_STATUS_CMD_DATATIMEOUT) {
DEBUG ((EFI_D_ERROR, "MciWriteBlockData(): TIMEOUT! Response:0x%X Status:0x%x\n", MmioRead32 (MCI_RESPONSE0_REG), Status));
RetVal = EFI_TIMEOUT;
goto Exit;
} else if (Status & MCI_STATUS_CMD_DATACRCFAIL) {
DEBUG ((EFI_D_ERROR, "MciWriteBlockData(): CRC Error! Response:0x%X Status:0x%x\n", MmioRead32 (MCI_RESPONSE0_REG), Status));
RetVal = EFI_CRC_ERROR;
goto Exit;
} else if (Status & MCI_STATUS_CMD_TX_UNDERRUN) {
DEBUG ((EFI_D_ERROR, "MciWriteBlockData(): TX buffer Underrun! Response:0x%X Status:0x%x, Number of bytes written 0x%x\n",MmioRead32(MCI_RESPONSE0_REG),Status, Loop));
RetVal = EFI_BUFFER_TOO_SMALL;
ASSERT(0);
goto Exit;
}
}
} while (Loop < Finish);
// Restore Tpl
gBS->RestoreTPL (Tpl);
// Wait for FIFO to drain
Timer = MMCI0_TIMEOUT * 60;
Status = MmioRead32 (MCI_STATUS_REG);
#ifndef USE_STREAM
// Single block
while (((Status & MCI_STATUS_TXDONE) != MCI_STATUS_TXDONE) && Timer) {
#else
// Stream
while (((Status & MCI_STATUS_CMD_DATAEND) != MCI_STATUS_CMD_DATAEND) && Timer) {
#endif
NanoSecondDelay(10);
Status = MmioRead32 (MCI_STATUS_REG);
Timer--;
}
// Clear Status flags
MmioWrite32 (MCI_CLEAR_STATUS_REG, MCI_CLR_ALL_STATUS);
if (Timer == 0) {
DEBUG ((EFI_D_ERROR, "MciWriteBlockData(): Data End timeout Number of words written 0x%x\n", Loop));
RetVal = EFI_TIMEOUT;
}
Exit:
// Disable Data path
DataCtrlReg = MmioRead32 (MCI_DATA_CTL_REG);
MmioWrite32 (MCI_DATA_CTL_REG, (DataCtrlReg & MCI_DATACTL_DISABLE_MASK));
return RetVal;
}
EFI_STATUS
MciNotifyState (
IN EFI_MMC_HOST_PROTOCOL *This,
IN MMC_STATE State
)
{
UINT32 Data32;
switch (State) {
case MmcInvalidState:
ASSERT (0);
break;
case MmcHwInitializationState:
// If device already turn on then restart it
Data32 = MmioRead32 (MCI_POWER_CONTROL_REG);
if ((Data32 & 0x2) == MCI_POWER_UP) {
MCI_TRACE ("MciNotifyState(MmcHwInitializationState): TurnOff MCI");
// Turn off
MmioWrite32 (MCI_CLOCK_CONTROL_REG, 0);
MmioWrite32 (MCI_POWER_CONTROL_REG, 0);
MicroSecondDelay (100);
}
MCI_TRACE ("MciNotifyState(MmcHwInitializationState): TurnOn MCI");
// Setup clock
// - 0x1D = 29 => should be the clock divider to be less than 400kHz at MCLK = 24Mhz
MmioWrite32 (MCI_CLOCK_CONTROL_REG, 0x1D | MCI_CLOCK_ENABLE | MCI_CLOCK_POWERSAVE);
// Set the voltage
MmioWrite32 (MCI_POWER_CONTROL_REG, MCI_POWER_OPENDRAIN | (15<<2));
MmioWrite32 (MCI_POWER_CONTROL_REG, MCI_POWER_ROD | MCI_POWER_OPENDRAIN | (15<<2) | MCI_POWER_UP);
MicroSecondDelay (10);
MmioWrite32 (MCI_POWER_CONTROL_REG, MCI_POWER_ROD | MCI_POWER_OPENDRAIN | (15<<2) | MCI_POWER_ON);
MicroSecondDelay (100);
// Set Data Length & Data Timer
MmioWrite32 (MCI_DATA_TIMER_REG, 0xFFFFF);
MmioWrite32 (MCI_DATA_LENGTH_REG, 8);
ASSERT ((MmioRead32 (MCI_POWER_CONTROL_REG) & 0x3) == MCI_POWER_ON);
break;
case MmcIdleState:
MCI_TRACE ("MciNotifyState(MmcIdleState)");
break;
case MmcReadyState:
MCI_TRACE ("MciNotifyState(MmcReadyState)");
break;
case MmcIdentificationState:
MCI_TRACE ("MciNotifyState (MmcIdentificationState)");
break;
case MmcStandByState:{
volatile UINT32 PwrCtrlReg;
MCI_TRACE ("MciNotifyState (MmcStandByState)");
// Enable MCICMD push-pull drive
PwrCtrlReg = MmioRead32 (MCI_POWER_CONTROL_REG);
//Disable Open Drain output
PwrCtrlReg &= ~ (MCI_POWER_OPENDRAIN);
MmioWrite32 (MCI_POWER_CONTROL_REG, PwrCtrlReg);
// Set MMCI0 clock to 4MHz (24MHz may be possible with cache enabled)
//
// Note: Increasing clock speed causes TX FIFO under-run errors.
// So careful when optimising this driver for higher performance.
//
MmioWrite32(MCI_CLOCK_CONTROL_REG,0x02 | MCI_CLOCK_ENABLE | MCI_CLOCK_POWERSAVE);
// Set MMCI0 clock to 24MHz (by bypassing the divider)
//MmioWrite32(MCI_CLOCK_CONTROL_REG,MCI_CLOCK_BYPASS | MCI_CLOCK_ENABLE);
break;
}
case MmcTransferState:
//MCI_TRACE ("MciNotifyState(MmcTransferState)");
break;
case MmcSendingDataState:
MCI_TRACE ("MciNotifyState(MmcSendingDataState)");
break;
case MmcReceiveDataState:
MCI_TRACE ("MciNotifyState(MmcReceiveDataState)");
break;
case MmcProgrammingState:
MCI_TRACE ("MciNotifyState(MmcProgrammingState)");
break;
case MmcDisconnectState:
MCI_TRACE ("MciNotifyState(MmcDisconnectState)");
break;
default:
ASSERT (0);
}
return EFI_SUCCESS;
}
EFI_GUID mPL180MciDevicePathGuid = EFI_CALLER_ID_GUID;
EFI_STATUS
MciBuildDevicePath (
IN EFI_MMC_HOST_PROTOCOL *This,
IN EFI_DEVICE_PATH_PROTOCOL **DevicePath
)
{
EFI_DEVICE_PATH_PROTOCOL *NewDevicePathNode;
NewDevicePathNode = CreateDeviceNode (HARDWARE_DEVICE_PATH, HW_VENDOR_DP, sizeof (VENDOR_DEVICE_PATH));
CopyGuid (& ((VENDOR_DEVICE_PATH*)NewDevicePathNode)->Guid, &mPL180MciDevicePathGuid);
*DevicePath = NewDevicePathNode;
return EFI_SUCCESS;
}
EFI_MMC_HOST_PROTOCOL gMciHost = {
MMC_HOST_PROTOCOL_REVISION,
MciIsCardPresent,
MciIsReadOnly,
MciBuildDevicePath,
MciNotifyState,
MciSendCommand,
MciReceiveResponse,
MciReadBlockData,
MciWriteBlockData
};
EFI_STATUS
PL180MciDxeInitialize (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EFI_STATUS Status;
EFI_HANDLE Handle;
DEBUG ((EFI_D_WARN, "Probing ID registers at 0x%lx for a PL180\n",
MCI_PERIPH_ID_REG0));
// Check if this is a PL180
if (MmioRead8 (MCI_PERIPH_ID_REG0) != MCI_PERIPH_ID0 ||
MmioRead8 (MCI_PERIPH_ID_REG1) != MCI_PERIPH_ID1 ||
MmioRead8 (MCI_PERIPH_ID_REG2) != MCI_PERIPH_ID2 ||
MmioRead8 (MCI_PCELL_ID_REG0) != MCI_PCELL_ID0 ||
MmioRead8 (MCI_PCELL_ID_REG1) != MCI_PCELL_ID1 ||
MmioRead8 (MCI_PCELL_ID_REG2) != MCI_PCELL_ID2 ||
MmioRead8 (MCI_PCELL_ID_REG3) != MCI_PCELL_ID3) {
DEBUG ((EFI_D_WARN, "Probing ID registers at 0x%lx for a PL180"
" failed\n", MCI_PERIPH_ID_REG0));
return EFI_NOT_FOUND;
}
Handle = NULL;
MCI_TRACE ("PL180MciDxeInitialize()");
//Publish Component Name, BlockIO protocol interfaces
Status = gBS->InstallMultipleProtocolInterfaces (
&Handle,
&gEfiMmcHostProtocolGuid, &gMciHost,
NULL
);
ASSERT_EFI_ERROR (Status);
return EFI_SUCCESS;
}

View File

@@ -0,0 +1,162 @@
/** @file
Header for the MMC Host Protocol implementation for the ARM PrimeCell PL180.
Copyright (c) 2011-2012, ARM Limited. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#ifndef __PL180_MCI_H
#define __PL180_MCI_H
#include <Uefi.h>
#include <Protocol/MmcHost.h>
#include <Library/UefiLib.h>
#include <Library/DebugLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/IoLib.h>
#include <Library/TimerLib.h>
#include <Library/PcdLib.h>
#define PL180_MCI_DXE_VERSION 0x10
#define MCI_SYSCTL FixedPcdGet32 (PcdPL180MciBaseAddress)
#define MCI_POWER_CONTROL_REG (MCI_SYSCTL + 0x000)
#define MCI_CLOCK_CONTROL_REG (MCI_SYSCTL + 0x004)
#define MCI_ARGUMENT_REG (MCI_SYSCTL + 0x008)
#define MCI_COMMAND_REG (MCI_SYSCTL + 0x00C)
#define MCI_RESPCMD_REG (MCI_SYSCTL + 0x010)
#define MCI_RESPONSE3_REG (MCI_SYSCTL + 0x014)
#define MCI_RESPONSE2_REG (MCI_SYSCTL + 0x018)
#define MCI_RESPONSE1_REG (MCI_SYSCTL + 0x01C)
#define MCI_RESPONSE0_REG (MCI_SYSCTL + 0x020)
#define MCI_DATA_TIMER_REG (MCI_SYSCTL + 0x024)
#define MCI_DATA_LENGTH_REG (MCI_SYSCTL + 0x028)
#define MCI_DATA_CTL_REG (MCI_SYSCTL + 0x02C)
#define MCI_DATA_COUNTER (MCI_SYSCTL + 0x030)
#define MCI_STATUS_REG (MCI_SYSCTL + 0x034)
#define MCI_CLEAR_STATUS_REG (MCI_SYSCTL + 0x038)
#define MCI_INT0_MASK_REG (MCI_SYSCTL + 0x03C)
#define MCI_INT1_MASK_REG (MCI_SYSCTL + 0x040)
#define MCI_SELECT_REG (MCI_SYSCTL + 0x044)
#define MCI_FIFOCOUNT_REG (MCI_SYSCTL + 0x048)
#define MCI_FIFO_REG (MCI_SYSCTL + 0x080)
#define MCI_PERIPH_ID_REG0 (MCI_SYSCTL + 0xFE0)
#define MCI_PERIPH_ID_REG1 (MCI_SYSCTL + 0xFE4)
#define MCI_PERIPH_ID_REG2 (MCI_SYSCTL + 0xFE8)
#define MCI_PERIPH_ID_REG3 (MCI_SYSCTL + 0xFEC)
#define MCI_PCELL_ID_REG0 (MCI_SYSCTL + 0xFF0)
#define MCI_PCELL_ID_REG1 (MCI_SYSCTL + 0xFF4)
#define MCI_PCELL_ID_REG2 (MCI_SYSCTL + 0xFF8)
#define MCI_PCELL_ID_REG3 (MCI_SYSCTL + 0xFFC)
#define MCI_PERIPH_ID0 0x80
#define MCI_PERIPH_ID1 0x11
#define MCI_PERIPH_ID2 0x04
#define MCI_PERIPH_ID3 0x00
#define MCI_PCELL_ID0 0x0D
#define MCI_PCELL_ID1 0xF0
#define MCI_PCELL_ID2 0x05
#define MCI_PCELL_ID3 0xB1
#define MCI_POWER_OFF 0
#define MCI_POWER_UP BIT1
#define MCI_POWER_ON (BIT1 | BIT0)
#define MCI_POWER_OPENDRAIN BIT6
#define MCI_POWER_ROD BIT7
#define MCI_CLOCK_ENABLE BIT8
#define MCI_CLOCK_POWERSAVE BIT9
#define MCI_CLOCK_BYPASS BIT10
#define MCI_CLOCK_WIDEBUS BIT11
#define MCI_STATUS_CMD_CMDCRCFAIL BIT0
#define MCI_STATUS_CMD_DATACRCFAIL BIT1
#define MCI_STATUS_CMD_CMDTIMEOUT BIT2
#define MCI_STATUS_CMD_DATATIMEOUT BIT3
#define MCI_STATUS_CMD_TX_UNDERRUN BIT4
#define MCI_STATUS_CMD_RXOVERRUN BIT5
#define MCI_STATUS_CMD_RESPEND BIT6
#define MCI_STATUS_CMD_SENT BIT7
#define MCI_STATUS_CMD_DATAEND BIT8
#define MCI_STATUS_CMD_START_BIT_ERROR BIT9
#define MCI_STATUS_CMD_DATABLOCKEND BIT10
#define MCI_STATUS_CMD_ACTIVE BIT11
#define MCI_STATUS_CMD_TXACTIVE BIT12
#define MCI_STATUS_CMD_RXACTIVE BIT13
#define MCI_STATUS_CMD_TXFIFOHALFEMPTY BIT14
#define MCI_STATUS_CMD_RXFIFOHALFFULL BIT15
#define MCI_STATUS_CMD_TXFIFOFULL BIT16
#define MCI_STATUS_CMD_RXFIFOFULL BIT17
#define MCI_STATUS_CMD_TXFIFOEMPTY BIT18
#define MCI_STATUS_CMD_RXFIFOEMPTY BIT19
#define MCI_STATUS_CMD_TXDATAAVAILBL BIT20
#define MCI_STATUS_CMD_RXDATAAVAILBL BIT21
#define MCI_STATUS_TXDONE (MCI_STATUS_CMD_DATAEND | MCI_STATUS_CMD_DATABLOCKEND)
#define MCI_STATUS_RXDONE (MCI_STATUS_CMD_DATAEND | MCI_STATUS_CMD_DATABLOCKEND)
#define MCI_STATUS_READ_ERROR ( MCI_STATUS_CMD_DATACRCFAIL \
| MCI_STATUS_CMD_DATATIMEOUT \
| MCI_STATUS_CMD_RXOVERRUN \
| MCI_STATUS_CMD_START_BIT_ERROR )
#define MCI_STATUS_WRITE_ERROR ( MCI_STATUS_CMD_DATACRCFAIL \
| MCI_STATUS_CMD_DATATIMEOUT \
| MCI_STATUS_CMD_TX_UNDERRUN )
#define MCI_STATUS_CMD_ERROR ( MCI_STATUS_CMD_CMDCRCFAIL \
| MCI_STATUS_CMD_CMDTIMEOUT \
| MCI_STATUS_CMD_START_BIT_ERROR )
#define MCI_CLR_CMD_STATUS ( MCI_STATUS_CMD_RESPEND \
| MCI_STATUS_CMD_SENT \
| MCI_STATUS_CMD_ERROR )
#define MCI_CLR_READ_STATUS ( MCI_STATUS_RXDONE \
| MCI_STATUS_READ_ERROR )
#define MCI_CLR_WRITE_STATUS ( MCI_STATUS_TXDONE \
| MCI_STATUS_WRITE_ERROR )
#define MCI_CLR_ALL_STATUS (BIT11 - 1)
#define MCI_DATACTL_DISABLE_MASK 0xFE
#define MCI_DATACTL_ENABLE BIT0
#define MCI_DATACTL_CONT_TO_CARD 0
#define MCI_DATACTL_CARD_TO_CONT BIT1
#define MCI_DATACTL_BLOCK_TRANS 0
#define MCI_DATACTL_STREAM_TRANS BIT2
#define MCI_DATACTL_DMA_DISABLED 0
#define MCI_DATACTL_DMA_ENABLE BIT3
#define INDX_MASK 0x3F
#define MCI_CPSM_WAIT_RESPONSE BIT6
#define MCI_CPSM_LONG_RESPONSE BIT7
#define MCI_CPSM_LONG_INTERRUPT BIT8
#define MCI_CPSM_LONG_PENDING BIT9
#define MCI_CPSM_ENABLE BIT10
#define MCI_TRACE(txt) DEBUG ((EFI_D_BLKIO, "ARM_MCI: " txt "\n"))
EFI_STATUS
EFIAPI
MciGetDriverName (
IN EFI_COMPONENT_NAME_PROTOCOL *This,
IN CHAR8 *Language,
OUT CHAR16 **DriverName
);
EFI_STATUS
EFIAPI
MciGetControllerName (
IN EFI_COMPONENT_NAME_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN EFI_HANDLE ChildHandle OPTIONAL,
IN CHAR8 *Language,
OUT CHAR16 **ControllerName
);
#endif

View File

@@ -0,0 +1,46 @@
#/** @file
# INF file for the MMC Host Protocol implementation for the ARM PrimeCell PL180.
#
# Copyright (c) 2011, ARM Limited. All rights reserved.
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
#**/
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = PL180MciDxe
FILE_GUID = 09831032-6fa3-4484-af4f-0a000a8d3a82
MODULE_TYPE = DXE_DRIVER
VERSION_STRING = 1.0
ENTRY_POINT = PL180MciDxeInitialize
[Sources.common]
PL180Mci.c
[Packages]
ArmPlatformPkg/ArmPlatformPkg.dec
EmbeddedPkg/EmbeddedPkg.dec
MdePkg/MdePkg.dec
[LibraryClasses]
BaseLib
UefiLib
UefiDriverEntryPoint
BaseMemoryLib
ArmLib
IoLib
TimerLib
[Protocols]
gEfiCpuArchProtocolGuid
gEfiDevicePathProtocolGuid
gEfiMmcHostProtocolGuid
[Pcd]
gArmPlatformTokenSpaceGuid.PcdPL180SysMciRegAddress
gArmPlatformTokenSpaceGuid.PcdPL180MciBaseAddress
[Depex]
gEfiCpuArchProtocolGuid

View File

@@ -78,14 +78,10 @@ PL011UartInitializePort (
UINT32 Integer;
UINT32 Fractional;
UINT32 HardwareFifoDepth;
UINT32 UartPid2;
HardwareFifoDepth = FixedPcdGet16 (PcdUartDefaultReceiveFifoDepth);
if (HardwareFifoDepth == 0) {
UartPid2 = MmioRead32 (UartBase + UARTPID2);
HardwareFifoDepth = (PL011_UARTPID2_VER (UartPid2) > PL011_VER_R1P4) ? 32 : 16;
}
HardwareFifoDepth = (PL011_UARTPID2_VER (MmioRead32 (UartBase + UARTPID2)) \
> PL011_VER_R1P4) \
? 32 : 16 ;
// The PL011 supports a buffer of 1, 16 or 32 chars. Therefore we can accept
// 1 char buffer as the minimum FIFO size. Because everything can be rounded
// down, there is no maximum FIFO size.

View File

@@ -30,7 +30,6 @@
ArmPlatformPkg/ArmPlatformPkg.dec
[FixedPcd]
gEfiMdePkgTokenSpaceGuid.PcdUartDefaultReceiveFifoDepth
gEfiMdeModulePkgTokenSpaceGuid.PcdSerialBaudRate
gArmPlatformTokenSpaceGuid.PL011UartInteger

View File

@@ -8,7 +8,6 @@
**/
#include <Library/BaseLib.h>
#include <Library/CacheMaintenanceLib.h>
#include <Library/DebugAgentLib.h>
#include <Library/ArmLib.h>
@@ -60,14 +59,13 @@ CEntryPoint (
{
// Data Cache enabled on Primary core when MMU is enabled.
ArmDisableDataCache ();
// Invalidate Data cache
ArmInvalidateDataCache ();
// Invalidate instruction cache
ArmInvalidateInstructionCache ();
// Enable Instruction Caches on all cores.
ArmEnableInstructionCache ();
InvalidateDataCacheRange ((VOID *)(UINTN)PcdGet64 (PcdCPUCoresStackBase),
PcdGet32 (PcdCPUCorePrimaryStackSize));
//
// Note: Doesn't have to Enable CPU interface in non-secure world,
// as Non-secure interface is already enabled in Secure world.

View File

@@ -44,7 +44,6 @@
[LibraryClasses]
ArmLib
ArmPlatformLib
CacheMaintenanceLib
BaseLib
DebugLib
DebugAgentLib

View File

@@ -44,7 +44,6 @@
[LibraryClasses]
ArmLib
ArmPlatformLib
CacheMaintenanceLib
BaseLib
DebugLib
DebugAgentLib

View File

@@ -37,7 +37,6 @@
[LibraryClasses]
BaseLib
CacheMaintenanceLib
DebugLib
DebugAgentLib
ArmLib

View File

@@ -37,7 +37,6 @@
[LibraryClasses]
BaseLib
CacheMaintenanceLib
DebugLib
DebugAgentLib
ArmLib

View File

@@ -8,7 +8,6 @@
#include <PiPei.h>
#include <Library/CacheMaintenanceLib.h>
#include <Library/DebugAgentLib.h>
#include <Library/PrePiLib.h>
#include <Library/PrintLib.h>
@@ -23,7 +22,7 @@
#include "PrePi.h"
#define IS_XIP() (((UINT64)FixedPcdGet64 (PcdFdBaseAddress) > mSystemMemoryEnd) || \
((FixedPcdGet64 (PcdFdBaseAddress) + FixedPcdGet32 (PcdFdSize)) <= FixedPcdGet64 (PcdSystemMemoryBase)))
((FixedPcdGet64 (PcdFdBaseAddress) + FixedPcdGet32 (PcdFdSize)) < FixedPcdGet64 (PcdSystemMemoryBase)))
UINT64 mSystemMemoryEnd = FixedPcdGet64(PcdSystemMemoryBase) +
FixedPcdGet64(PcdSystemMemorySize) - 1;
@@ -179,6 +178,8 @@ CEntryPoint (
// Data Cache enabled on Primary core when MMU is enabled.
ArmDisableDataCache ();
// Invalidate Data cache
ArmInvalidateDataCache ();
// Invalidate instruction cache
ArmInvalidateInstructionCache ();
// Enable Instruction Caches on all cores.
@@ -199,10 +200,6 @@ CEntryPoint (
// If not primary Jump to Secondary Main
if (ArmPlatformIsPrimaryCore (MpId)) {
InvalidateDataCacheRange ((VOID *)UefiMemoryBase,
FixedPcdGet32 (PcdSystemMemoryUefiRegionSize));
// Goto primary Main.
PrimaryMain (UefiMemoryBase, StacksBase, StartTimeStamp);
} else {
@@ -212,3 +209,4 @@ CEntryPoint (
// DXE Core should always load and never return
ASSERT (FALSE);
}

View File

@@ -1,328 +1,328 @@
#!/usr/bin/python
#
# Copyright (c) 2014, ARM Limited. All rights reserved.
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
import getopt
import operator
import os
import pickle
import sys
from sys import argv
from cStringIO import StringIO
modules = {}
functions = {}
functions_addr = {}
def usage():
print "-t,--trace: Location of the Trace file"
print "-s,--symbols: Location of the symbols and modules"
def get_address_from_string(address):
return int(address.strip("S:").strip("N:").strip("EL2:").strip("EL1:"), 16)
def get_module_from_addr(modules, addr):
for key,value in modules.items():
if (value['start'] <= addr) and (addr <= value['end']):
return key
return None
def add_cycles_to_function(functions, func_name, addr, cycles):
if func_name != "<Unknown>":
# Check if we are still in the previous function
if add_cycles_to_function.prev_func_name == func_name:
add_cycles_to_function.prev_entry['cycles'] += cycles
return (add_cycles_to_function.prev_func_name, add_cycles_to_function.prev_module_name)
if func_name in functions.keys():
for module_name, module_value in functions[func_name].iteritems():
if (module_value['start'] <= addr) and (addr < module_value['end']):
module_value['cycles'] += cycles
add_cycles_to_function.prev_func_name = func_name
add_cycles_to_function.prev_module_name = module_name
add_cycles_to_function.prev_entry = module_value
return (func_name, module_name)
elif (module_value['end'] == 0):
module_value['cycles'] += cycles
add_cycles_to_function.prev_func_name = func_name
add_cycles_to_function.prev_module_name = module_name
add_cycles_to_function.prev_entry = module_value
return (func_name, module_name)
# Workaround to fix the 'info func' limitation that does not expose the 'static' function
module_name = get_module_from_addr(modules, addr)
functions[func_name] = {}
functions[func_name][module_name] = {}
functions[func_name][module_name]['start'] = 0
functions[func_name][module_name]['end'] = 0
functions[func_name][module_name]['cycles'] = cycles
functions[func_name][module_name]['count'] = 0
add_cycles_to_function.prev_func_name = func_name
add_cycles_to_function.prev_module_name = module_name
add_cycles_to_function.prev_entry = functions[func_name][module_name]
return (func_name, module_name)
else:
# Check if we are still in the previous function
if (add_cycles_to_function.prev_entry is not None) and (add_cycles_to_function.prev_entry['start'] <= addr) and (addr < add_cycles_to_function.prev_entry['end']):
add_cycles_to_function.prev_entry['cycles'] += cycles
return (add_cycles_to_function.prev_func_name, add_cycles_to_function.prev_module_name)
# Generate the key for the given address
key = addr & ~0x0FFF
if key not in functions_addr.keys():
if 'Unknown' not in functions.keys():
functions['Unknown'] = {}
if 'Unknown' not in functions['Unknown'].keys():
functions['Unknown']['Unknown'] = {}
functions['Unknown']['Unknown']['cycles'] = 0
functions['Unknown']['Unknown']['count'] = 0
functions['Unknown']['Unknown']['cycles'] += cycles
add_cycles_to_function.prev_func_name = None
return None
for func_key, module in functions_addr[key].iteritems():
for module_key, module_value in module.iteritems():
if (module_value['start'] <= addr) and (addr < module_value['end']):
module_value['cycles'] += cycles
# In case o <Unknown> we prefer to fallback on the direct search
add_cycles_to_function.prev_func_name = func_key
add_cycles_to_function.prev_module_name = module_key
add_cycles_to_function.prev_entry = module_value
return (func_key, module_key)
print "Warning: Function %s @ 0x%x not found" % (func_name, addr)
add_cycles_to_function.prev_func_name = None
return None
# Static variables for the previous function
add_cycles_to_function.prev_func_name = None
add_cycles_to_function.prev_entry = None
def trace_read():
global trace_process
line = trace.readline()
trace_process += len(line)
return line
#
# Parse arguments
#
trace_name = None
symbols_file = None
opts,args = getopt.getopt(sys.argv[1:], "ht:vs:v", ["help","trace=","symbols="])
if (opts is None) or (not opts):
usage()
sys.exit()
for o,a in opts:
if o in ("-h","--help"):
usage()
sys.exit()
elif o in ("-t","--trace"):
trace_name = a
elif o in ("-s","--symbols"):
symbols_file = a
else:
assert False, "Unhandled option (%s)" % o
#
# We try first to see if we run the script from DS-5
#
try:
from arm_ds.debugger_v1 import Debugger
from arm_ds.debugger_v1 import DebugException
# Debugger object for accessing the debugger
debugger = Debugger()
# Initialisation commands
ec = debugger.getExecutionContext(0)
ec.getExecutionService().stop()
ec.getExecutionService().waitForStop()
# in case the execution context reference is out of date
ec = debugger.getExecutionContext(0)
#
# Get the module name and their memory range
#
info_file = ec.executeDSCommand("info file")
info_file_str = StringIO(info_file)
line = info_file_str.readline().strip('\n')
while line != '':
if ("Symbols from" in line):
# Get the module name from the line 'Symbols from "/home/...."'
module_name = line.split("\"")[1].split("/")[-1]
modules[module_name] = {}
# Look for the text section
line = info_file_str.readline().strip('\n')
while (line != '') and ("Symbols from" not in line):
if ("ER_RO" in line):
modules[module_name]['start'] = get_address_from_string(line.split()[0])
modules[module_name]['end'] = get_address_from_string(line.split()[2])
line = info_file_str.readline().strip('\n')
break;
if (".text" in line):
modules[module_name]['start'] = get_address_from_string(line.split()[0])
modules[module_name]['end'] = get_address_from_string(line.split()[2])
line = info_file_str.readline().strip('\n')
break;
line = info_file_str.readline().strip('\n')
line = info_file_str.readline().strip('\n')
#
# Get the function name and their memory range
#
info_func = ec.executeDSCommand("info func")
info_func_str = StringIO(info_func)
# Skip the first line 'Low-level symbols ...'
line = info_func_str.readline().strip('\n')
func_prev = None
while line != '':
# We ignore all the functions after 'Functions in'
if ("Functions in " in line):
line = info_func_str.readline().strip('\n')
while line != '':
line = info_func_str.readline().strip('\n')
line = info_func_str.readline().strip('\n')
continue
if ("Low-level symbols" in line):
# We need to fixup the last function of the module
if func_prev is not None:
func_prev['end'] = modules[module_name]['end']
func_prev = None
line = info_func_str.readline().strip('\n')
continue
func_name = line.split()[1]
func_start = get_address_from_string(line.split()[0])
module_name = get_module_from_addr(modules, func_start)
if func_name not in functions.keys():
functions[func_name] = {}
functions[func_name][module_name] = {}
functions[func_name][module_name]['start'] = func_start
functions[func_name][module_name]['cycles'] = 0
functions[func_name][module_name]['count'] = 0
# Set the end address of the previous function
if func_prev is not None:
func_prev['end'] = func_start
func_prev = functions[func_name][module_name]
line = info_func_str.readline().strip('\n')
# Fixup the last function
func_prev['end'] = modules[module_name]['end']
if symbols_file is not None:
pickle.dump((modules, functions), open(symbols_file, "w"))
except:
if symbols_file is None:
print "Error: Symbols file is required when run out of ARM DS-5"
sys.exit()
(modules, functions) = pickle.load(open(symbols_file, "r"))
#
# Build optimized table for the <Unknown> functions
#
functions_addr = {}
for func_key, module in functions.iteritems():
for module_key, module_value in module.iteritems():
key = module_value['start'] & ~0x0FFF
if key not in functions_addr.keys():
functions_addr[key] = {}
if func_key not in functions_addr[key].keys():
functions_addr[key][func_key] = {}
functions_addr[key][func_key][module_key] = module_value
#
# Process the trace file
#
if trace_name is None:
sys.exit()
trace = open(trace_name, "r")
trace_size = os.path.getsize(trace_name)
trace_process = 0
# Get the column names from the first line
columns = trace_read().split()
column_addr = columns.index('Address')
column_cycles = columns.index('Cycles')
column_function = columns.index('Function')
line = trace_read()
i = 0
prev_callee = None
while line:
try:
func_name = line.split('\t')[column_function].strip()
address = get_address_from_string(line.split('\t')[column_addr])
cycles = int(line.split('\t')[column_cycles])
callee = add_cycles_to_function(functions, func_name, address, cycles)
if (prev_callee != None) and (prev_callee != callee):
functions[prev_callee[0]][prev_callee[1]]['count'] += 1
prev_callee = callee
except ValueError:
pass
line = trace_read()
if ((i % 1000000) == 0) and (i != 0):
percent = (trace_process * 100.00) / trace_size
print "Processing file ... (%.2f %%)" % (percent)
i = i + 1
# Fixup the last callee
functions[prev_callee[0]][prev_callee[1]]['count'] += 1
#
# Process results
#
functions_cycles = {}
all_functions_cycles = {}
total_cycles = 0
for func_key, module in functions.iteritems():
for module_key, module_value in module.iteritems():
key = "%s/%s" % (module_key, func_key)
functions_cycles[key] = (module_value['cycles'], module_value['count'])
total_cycles += module_value['cycles']
if func_key not in all_functions_cycles.keys():
all_functions_cycles[func_key] = (module_value['cycles'], module_value['count'])
else:
all_functions_cycles[func_key] = tuple(map(sum, zip(all_functions_cycles[func_key], (module_value['cycles'], module_value['count']))))
sorted_functions_cycles = sorted(functions_cycles.iteritems(), key=operator.itemgetter(1), reverse = True)
sorted_all_functions_cycles = sorted(all_functions_cycles.items(), key=operator.itemgetter(1), reverse = True)
print
print "----"
for (key,value) in sorted_functions_cycles[:20]:
if value[0] != 0:
print "%s (cycles: %d - %d%%, count: %d)" % (key, value[0], (value[0] * 100) / total_cycles, value[1])
else:
break;
print "----"
for (key,value) in sorted_all_functions_cycles[:20]:
if value[0] != 0:
print "%s (cycles: %d - %d%%, count: %d)" % (key, value[0], (value[0] * 100) / total_cycles, value[1])
else:
break;
#!/usr/bin/python
#
# Copyright (c) 2014, ARM Limited. All rights reserved.
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
import getopt
import operator
import os
import pickle
import sys
from sys import argv
from cStringIO import StringIO
modules = {}
functions = {}
functions_addr = {}
def usage():
print "-t,--trace: Location of the Trace file"
print "-s,--symbols: Location of the symbols and modules"
def get_address_from_string(address):
return int(address.strip("S:").strip("N:").strip("EL2:").strip("EL1:"), 16)
def get_module_from_addr(modules, addr):
for key,value in modules.items():
if (value['start'] <= addr) and (addr <= value['end']):
return key
return None
def add_cycles_to_function(functions, func_name, addr, cycles):
if func_name != "<Unknown>":
# Check if we are still in the previous function
if add_cycles_to_function.prev_func_name == func_name:
add_cycles_to_function.prev_entry['cycles'] += cycles
return (add_cycles_to_function.prev_func_name, add_cycles_to_function.prev_module_name)
if func_name in functions.keys():
for module_name, module_value in functions[func_name].iteritems():
if (module_value['start'] <= addr) and (addr < module_value['end']):
module_value['cycles'] += cycles
add_cycles_to_function.prev_func_name = func_name
add_cycles_to_function.prev_module_name = module_name
add_cycles_to_function.prev_entry = module_value
return (func_name, module_name)
elif (module_value['end'] == 0):
module_value['cycles'] += cycles
add_cycles_to_function.prev_func_name = func_name
add_cycles_to_function.prev_module_name = module_name
add_cycles_to_function.prev_entry = module_value
return (func_name, module_name)
# Workaround to fix the 'info func' limitation that does not expose the 'static' function
module_name = get_module_from_addr(modules, addr)
functions[func_name] = {}
functions[func_name][module_name] = {}
functions[func_name][module_name]['start'] = 0
functions[func_name][module_name]['end'] = 0
functions[func_name][module_name]['cycles'] = cycles
functions[func_name][module_name]['count'] = 0
add_cycles_to_function.prev_func_name = func_name
add_cycles_to_function.prev_module_name = module_name
add_cycles_to_function.prev_entry = functions[func_name][module_name]
return (func_name, module_name)
else:
# Check if we are still in the previous function
if (add_cycles_to_function.prev_entry is not None) and (add_cycles_to_function.prev_entry['start'] <= addr) and (addr < add_cycles_to_function.prev_entry['end']):
add_cycles_to_function.prev_entry['cycles'] += cycles
return (add_cycles_to_function.prev_func_name, add_cycles_to_function.prev_module_name)
# Generate the key for the given address
key = addr & ~0x0FFF
if key not in functions_addr.keys():
if 'Unknown' not in functions.keys():
functions['Unknown'] = {}
if 'Unknown' not in functions['Unknown'].keys():
functions['Unknown']['Unknown'] = {}
functions['Unknown']['Unknown']['cycles'] = 0
functions['Unknown']['Unknown']['count'] = 0
functions['Unknown']['Unknown']['cycles'] += cycles
add_cycles_to_function.prev_func_name = None
return None
for func_key, module in functions_addr[key].iteritems():
for module_key, module_value in module.iteritems():
if (module_value['start'] <= addr) and (addr < module_value['end']):
module_value['cycles'] += cycles
# In case o <Unknown> we prefer to fallback on the direct search
add_cycles_to_function.prev_func_name = func_key
add_cycles_to_function.prev_module_name = module_key
add_cycles_to_function.prev_entry = module_value
return (func_key, module_key)
print "Warning: Function %s @ 0x%x not found" % (func_name, addr)
add_cycles_to_function.prev_func_name = None
return None
# Static variables for the previous function
add_cycles_to_function.prev_func_name = None
add_cycles_to_function.prev_entry = None
def trace_read():
global trace_process
line = trace.readline()
trace_process += len(line)
return line
#
# Parse arguments
#
trace_name = None
symbols_file = None
opts,args = getopt.getopt(sys.argv[1:], "ht:vs:v", ["help","trace=","symbols="])
if (opts is None) or (not opts):
usage()
sys.exit()
for o,a in opts:
if o in ("-h","--help"):
usage()
sys.exit()
elif o in ("-t","--trace"):
trace_name = a
elif o in ("-s","--symbols"):
symbols_file = a
else:
assert False, "Unhandled option (%s)" % o
#
# We try first to see if we run the script from DS-5
#
try:
from arm_ds.debugger_v1 import Debugger
from arm_ds.debugger_v1 import DebugException
# Debugger object for accessing the debugger
debugger = Debugger()
# Initialisation commands
ec = debugger.getExecutionContext(0)
ec.getExecutionService().stop()
ec.getExecutionService().waitForStop()
# in case the execution context reference is out of date
ec = debugger.getExecutionContext(0)
#
# Get the module name and their memory range
#
info_file = ec.executeDSCommand("info file")
info_file_str = StringIO(info_file)
line = info_file_str.readline().strip('\n')
while line != '':
if ("Symbols from" in line):
# Get the module name from the line 'Symbols from "/home/...."'
module_name = line.split("\"")[1].split("/")[-1]
modules[module_name] = {}
# Look for the text section
line = info_file_str.readline().strip('\n')
while (line != '') and ("Symbols from" not in line):
if ("ER_RO" in line):
modules[module_name]['start'] = get_address_from_string(line.split()[0])
modules[module_name]['end'] = get_address_from_string(line.split()[2])
line = info_file_str.readline().strip('\n')
break;
if (".text" in line):
modules[module_name]['start'] = get_address_from_string(line.split()[0])
modules[module_name]['end'] = get_address_from_string(line.split()[2])
line = info_file_str.readline().strip('\n')
break;
line = info_file_str.readline().strip('\n')
line = info_file_str.readline().strip('\n')
#
# Get the function name and their memory range
#
info_func = ec.executeDSCommand("info func")
info_func_str = StringIO(info_func)
# Skip the first line 'Low-level symbols ...'
line = info_func_str.readline().strip('\n')
func_prev = None
while line != '':
# We ignore all the functions after 'Functions in'
if ("Functions in " in line):
line = info_func_str.readline().strip('\n')
while line != '':
line = info_func_str.readline().strip('\n')
line = info_func_str.readline().strip('\n')
continue
if ("Low-level symbols" in line):
# We need to fixup the last function of the module
if func_prev is not None:
func_prev['end'] = modules[module_name]['end']
func_prev = None
line = info_func_str.readline().strip('\n')
continue
func_name = line.split()[1]
func_start = get_address_from_string(line.split()[0])
module_name = get_module_from_addr(modules, func_start)
if func_name not in functions.keys():
functions[func_name] = {}
functions[func_name][module_name] = {}
functions[func_name][module_name]['start'] = func_start
functions[func_name][module_name]['cycles'] = 0
functions[func_name][module_name]['count'] = 0
# Set the end address of the previous function
if func_prev is not None:
func_prev['end'] = func_start
func_prev = functions[func_name][module_name]
line = info_func_str.readline().strip('\n')
# Fixup the last function
func_prev['end'] = modules[module_name]['end']
if symbols_file is not None:
pickle.dump((modules, functions), open(symbols_file, "w"))
except:
if symbols_file is None:
print "Error: Symbols file is required when run out of ARM DS-5"
sys.exit()
(modules, functions) = pickle.load(open(symbols_file, "r"))
#
# Build optimized table for the <Unknown> functions
#
functions_addr = {}
for func_key, module in functions.iteritems():
for module_key, module_value in module.iteritems():
key = module_value['start'] & ~0x0FFF
if key not in functions_addr.keys():
functions_addr[key] = {}
if func_key not in functions_addr[key].keys():
functions_addr[key][func_key] = {}
functions_addr[key][func_key][module_key] = module_value
#
# Process the trace file
#
if trace_name is None:
sys.exit()
trace = open(trace_name, "r")
trace_size = os.path.getsize(trace_name)
trace_process = 0
# Get the column names from the first line
columns = trace_read().split()
column_addr = columns.index('Address')
column_cycles = columns.index('Cycles')
column_function = columns.index('Function')
line = trace_read()
i = 0
prev_callee = None
while line:
try:
func_name = line.split('\t')[column_function].strip()
address = get_address_from_string(line.split('\t')[column_addr])
cycles = int(line.split('\t')[column_cycles])
callee = add_cycles_to_function(functions, func_name, address, cycles)
if (prev_callee != None) and (prev_callee != callee):
functions[prev_callee[0]][prev_callee[1]]['count'] += 1
prev_callee = callee
except ValueError:
pass
line = trace_read()
if ((i % 1000000) == 0) and (i != 0):
percent = (trace_process * 100.00) / trace_size
print "Processing file ... (%.2f %%)" % (percent)
i = i + 1
# Fixup the last callee
functions[prev_callee[0]][prev_callee[1]]['count'] += 1
#
# Process results
#
functions_cycles = {}
all_functions_cycles = {}
total_cycles = 0
for func_key, module in functions.iteritems():
for module_key, module_value in module.iteritems():
key = "%s/%s" % (module_key, func_key)
functions_cycles[key] = (module_value['cycles'], module_value['count'])
total_cycles += module_value['cycles']
if func_key not in all_functions_cycles.keys():
all_functions_cycles[func_key] = (module_value['cycles'], module_value['count'])
else:
all_functions_cycles[func_key] = tuple(map(sum, zip(all_functions_cycles[func_key], (module_value['cycles'], module_value['count']))))
sorted_functions_cycles = sorted(functions_cycles.iteritems(), key=operator.itemgetter(1), reverse = True)
sorted_all_functions_cycles = sorted(all_functions_cycles.items(), key=operator.itemgetter(1), reverse = True)
print
print "----"
for (key,value) in sorted_functions_cycles[:20]:
if value[0] != 0:
print "%s (cycles: %d - %d%%, count: %d)" % (key, value[0], (value[0] * 100) / total_cycles, value[1])
else:
break;
print "----"
for (key,value) in sorted_all_functions_cycles[:20]:
if value[0] != 0:
print "%s (cycles: %d - %d%%, count: %d)" % (key, value[0], (value[0] * 100) / total_cycles, value[1])
else:
break;

View File

@@ -2,7 +2,6 @@
# Copyright (c) 2011-2015, ARM Limited. All rights reserved.
# Copyright (c) 2014, Linaro Limited. All rights reserved.
# Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.
# Copyright (c) Microsoft Corporation.
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
@@ -161,22 +160,21 @@
OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLibCrypto.inf
!endif
BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
RngLib|MdePkg/Library/BaseRngLibTimerLib/BaseRngLibTimerLib.inf
#
# Secure Boot dependencies
#
!if $(SECURE_BOOT_ENABLE) == TRUE
TpmMeasurementLib|SecurityPkg/Library/DxeTpmMeasurementLib/DxeTpmMeasurementLib.inf
AuthVariableLib|SecurityPkg/Library/AuthVariableLib/AuthVariableLib.inf
# re-use the UserPhysicalPresent() dummy implementation from the ovmf tree
PlatformSecureLib|OvmfPkg/Library/PlatformSecureLib/PlatformSecureLib.inf
!else
TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/TpmMeasurementLibNull.inf
AuthVariableLib|MdeModulePkg/Library/AuthVariableLibNull/AuthVariableLibNull.inf
!endif
VarCheckLib|MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf
VariablePolicyLib|MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.inf
VariablePolicyHelperLib|MdeModulePkg/Library/VariablePolicyHelperLib/VariablePolicyHelperLib.inf
UefiBootManagerLib|MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf
ReportStatusCodeLib|MdePkg/Library/BaseReportStatusCodeLibNull/BaseReportStatusCodeLibNull.inf
@@ -250,7 +248,6 @@
!if $(TARGET) != RELEASE
DebugLib|MdePkg/Library/DxeRuntimeDebugLibSerialPort/DxeRuntimeDebugLibSerialPort.inf
!endif
VariablePolicyLib|MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLibRuntimeDxe.inf
!if $(SECURE_BOOT_ENABLE) == TRUE
BaseCryptLib|CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf
@@ -382,14 +379,6 @@
<PcdsFixedAtBuild>
gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
}
ShellPkg/DynamicCommand/HttpDynamicCommand/HttpDynamicCommand.inf {
<PcdsFixedAtBuild>
gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
}
OvmfPkg/LinuxInitrdDynamicShellCommand/LinuxInitrdDynamicShellCommand.inf {
<PcdsFixedAtBuild>
gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
}
ShellPkg/Application/Shell/Shell.inf {
<LibraryClasses>
ShellCommandLib|ShellPkg/Library/UefiShellCommandLib/UefiShellCommandLib.inf

View File

@@ -1,321 +0,0 @@
# @file
# Workspace file for KVMTool virtual platform.
#
# Copyright (c) 2018 - 2020, ARM Limited. All rights reserved.
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
#
################################################################################
#
# Defines Section - statements that will be processed to create a Makefile.
#
################################################################################
[Defines]
PLATFORM_NAME = ArmVirtKvmTool
PLATFORM_GUID = 4CB2C61E-FA32-4130-8E37-54ABC71A1A43
PLATFORM_VERSION = 0.1
DSC_SPECIFICATION = 0x0001001B
!ifdef $(EDK2_OUT_DIR)
OUTPUT_DIRECTORY = $(EDK2_OUT_DIR)
!else
OUTPUT_DIRECTORY = Build/ArmVirtKvmTool-$(ARCH)
!endif
SUPPORTED_ARCHITECTURES = AARCH64|ARM
BUILD_TARGETS = DEBUG|RELEASE
SKUID_IDENTIFIER = DEFAULT
FLASH_DEFINITION = ArmVirtPkg/ArmVirtKvmTool.fdf
!include ArmVirtPkg/ArmVirt.dsc.inc
[LibraryClasses.common]
ArmLib|ArmPkg/Library/ArmLib/ArmBaseLib.inf
ArmMmuLib|ArmPkg/Library/ArmMmuLib/ArmMmuBaseLib.inf
# Virtio Support
VirtioLib|OvmfPkg/Library/VirtioLib/VirtioLib.inf
VirtioMmioDeviceLib|OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDeviceLib.inf
ArmPlatformLib|ArmPlatformPkg/Library/ArmPlatformLibNull/ArmPlatformLibNull.inf
ArmVirtMemInfoLib|ArmVirtPkg/Library/KvmtoolVirtMemInfoLib/KvmtoolVirtMemInfoLib.inf
TimerLib|ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.inf
NorFlashPlatformLib|ArmVirtPkg/Library/NorFlashKvmtoolLib/NorFlashKvmtoolLib.inf
CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf
# BDS Libraries
UefiBootManagerLib|MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf
PlatformBootManagerLib|ArmPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
BootLogoLib|MdeModulePkg/Library/BootLogoLib/BootLogoLib.inf
CustomizedDisplayLib|MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.inf
FrameBufferBltLib|MdeModulePkg/Library/FrameBufferBltLib/FrameBufferBltLib.inf
FileExplorerLib|MdeModulePkg/Library/FileExplorerLib/FileExplorerLib.inf
PciPcdProducerLib|ArmVirtPkg/Library/FdtPciPcdProducerLib/FdtPciPcdProducerLib.inf
PciSegmentLib|MdePkg/Library/BasePciSegmentLibPci/BasePciSegmentLibPci.inf
PciHostBridgeLib|ArmVirtPkg/Library/FdtPciHostBridgeLib/FdtPciHostBridgeLib.inf
TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/TpmMeasurementLibNull.inf
AuthVariableLib|MdeModulePkg/Library/AuthVariableLibNull/AuthVariableLibNull.inf
PlatformPeiLib|ArmVirtPkg/Library/KvmtoolPlatformPeiLib/KvmtoolPlatformPeiLib.inf
PciExpressLib|MdePkg/Library/BasePciExpressLib/BasePciExpressLib.inf
PlatformHookLib|ArmVirtPkg/Library/Fdt16550SerialPortHookLib/Fdt16550SerialPortHookLib.inf
SerialPortLib|MdeModulePkg/Library/BaseSerialPortLib16550/BaseSerialPortLib16550.inf
[LibraryClasses.common.SEC, LibraryClasses.common.PEI_CORE, LibraryClasses.common.PEIM]
PciExpressLib|MdePkg/Library/BasePciExpressLib/BasePciExpressLib.inf
PlatformHookLib|ArmVirtPkg/Library/Fdt16550SerialPortHookLib/EarlyFdt16550SerialPortHookLib.inf
SerialPortLib|MdeModulePkg/Library/BaseSerialPortLib16550/BaseSerialPortLib16550.inf
[LibraryClasses.common.UEFI_DRIVER]
UefiScsiLib|MdePkg/Library/UefiScsiLib/UefiScsiLib.inf
[BuildOptions]
*_*_*_CC_FLAGS = -D DISABLE_NEW_DEPRECATED_INTERFACES
#
# We need to avoid jump tables in SEC and BASE modules, so that the PE/COFF
# self-relocation code itself is guaranteed to be position independent.
#
GCC:*_*_*_CC_XIPFLAGS = -fno-jump-tables
################################################################################
#
# Pcd Section - list of all EDK II PCD Entries defined by this Platform
#
################################################################################
[PcdsFeatureFlag.common]
## If TRUE, Graphics Output Protocol will be installed on virtual handle created by ConsplitterDxe.
# It could be set FALSE to save size.
gEfiMdeModulePkgTokenSpaceGuid.PcdConOutGopSupport|TRUE
gEfiMdeModulePkgTokenSpaceGuid.PcdConOutUgaSupport|FALSE
# Use MMIO for accessing RTC controller registers.
gPcAtChipsetPkgTokenSpaceGuid.PcdRtcUseMmio|TRUE
[PcdsFixedAtBuild.common]
gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x8000000F
gArmPlatformTokenSpaceGuid.PcdCoreCount|1
!if $(ARCH) == AARCH64
gArmTokenSpaceGuid.PcdVFPEnabled|1
!endif
gArmPlatformTokenSpaceGuid.PcdCPUCorePrimaryStackSize|0x4000
gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize|0x2000
gEfiMdeModulePkgTokenSpaceGuid.PcdMaxAuthVariableSize|0x2800
# Size of the region used by UEFI in permanent memory (Reserved 64MB)
gArmPlatformTokenSpaceGuid.PcdSystemMemoryUefiRegionSize|0x04000000
#
# TTY Terminal Type
# 0-PCANSI, 1-VT100, 2-VT00+, 3-UTF8, 4-TTYTERM
gEfiMdePkgTokenSpaceGuid.PcdDefaultTerminalType|4
#
# ARM Virtual Architectural Timer -- fetch frequency from KVM
#
gArmTokenSpaceGuid.PcdArmArchTimerFreqInHz|0
# Use MMIO for accessing Serial port registers.
gEfiMdeModulePkgTokenSpaceGuid.PcdSerialUseMmio|TRUE
gEfiMdeModulePkgTokenSpaceGuid.PcdSerialPciDeviceInfo|{0xFF}
gEfiMdeModulePkgTokenSpaceGuid.PcdResetOnMemoryTypeInformationChange|FALSE
gEfiMdeModulePkgTokenSpaceGuid.PcdBootManagerMenuFile|{ 0x21, 0xaa, 0x2c, 0x46, 0x14, 0x76, 0x03, 0x45, 0x83, 0x6e, 0x8a, 0xb6, 0xf4, 0x66, 0x23, 0x31 }
#
# The maximum physical I/O addressability of the processor, set with
# BuildCpuHob().
#
gEmbeddedTokenSpaceGuid.PcdPrePiCpuIoSize|16
[PcdsPatchableInModule.common]
#
# This will be overridden in the code
#
gArmTokenSpaceGuid.PcdSystemMemoryBase|0x0
gArmTokenSpaceGuid.PcdSystemMemorySize|0x0
#
# The device tree base address is handed off by kvmtool.
# We are booting from RAM using the Linux kernel boot protocol,
# x0 will point to the DTB image in memory.
#
gArmVirtTokenSpaceGuid.PcdDeviceTreeInitialBaseAddress|0x0
gArmTokenSpaceGuid.PcdFdBaseAddress|0x0
gArmTokenSpaceGuid.PcdFvBaseAddress|0x0
gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterBase|0x0
[PcdsDynamicDefault.common]
gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut|3
gArmTokenSpaceGuid.PcdArmArchTimerSecIntrNum|0x0
gArmTokenSpaceGuid.PcdArmArchTimerIntrNum|0x0
gArmTokenSpaceGuid.PcdArmArchTimerVirtIntrNum|0x0
gArmTokenSpaceGuid.PcdArmArchTimerHypIntrNum|0x0
#
# ARM General Interrupt Controller
#
gArmTokenSpaceGuid.PcdGicDistributorBase|0x0
gArmTokenSpaceGuid.PcdGicRedistributorsBase|0x0
gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase|0x0
#
# Set video resolution for boot options and for text setup.
# PlatformDxe can set the former at runtime.
#
gEfiMdeModulePkgTokenSpaceGuid.PcdVideoHorizontalResolution|800
gEfiMdeModulePkgTokenSpaceGuid.PcdVideoVerticalResolution|600
gEfiMdeModulePkgTokenSpaceGuid.PcdSetupVideoHorizontalResolution|640
gEfiMdeModulePkgTokenSpaceGuid.PcdSetupVideoVerticalResolution|480
## Force DTB
gArmVirtTokenSpaceGuid.PcdForceNoAcpi|TRUE
# Setup Flash storage variables
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase|0
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize|0x40000
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase|0
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize|0x40000
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase|0
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize|0x40000
## RTC Register address in MMIO space.
gPcAtChipsetPkgTokenSpaceGuid.PcdRtcIndexRegister64|0x0
gPcAtChipsetPkgTokenSpaceGuid.PcdRtcTargetRegister64|0x0
################################################################################
#
# Components Section - list of all EDK II Modules needed by this Platform
#
################################################################################
[Components.common]
#
# PEI Phase modules
#
ArmVirtPkg/PrePi/ArmVirtPrePiUniCoreRelocatable.inf {
<LibraryClasses>
ExtractGuidedSectionLib|EmbeddedPkg/Library/PrePiExtractGuidedSectionLib/PrePiExtractGuidedSectionLib.inf
LzmaDecompressLib|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf
PrePiLib|EmbeddedPkg/Library/PrePiLib/PrePiLib.inf
HobLib|EmbeddedPkg/Library/PrePiHobLib/PrePiHobLib.inf
PrePiHobListPointerLib|ArmPlatformPkg/Library/PrePiHobListPointerLib/PrePiHobListPointerLib.inf
MemoryAllocationLib|EmbeddedPkg/Library/PrePiMemoryAllocationLib/PrePiMemoryAllocationLib.inf
}
#
# DXE
#
MdeModulePkg/Core/Dxe/DxeMain.inf {
<LibraryClasses>
NULL|MdeModulePkg/Library/DxeCrc32GuidedSectionExtractLib/DxeCrc32GuidedSectionExtractLib.inf
DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
}
MdeModulePkg/Universal/PCD/Dxe/Pcd.inf {
<LibraryClasses>
PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
}
#
# Architectural Protocols
#
ArmPkg/Drivers/CpuDxe/CpuDxe.inf
MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf
MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf {
<LibraryClasses>
NULL|MdeModulePkg/Library/VarCheckUefiLib/VarCheckUefiLib.inf
NULL|EmbeddedPkg/Library/NvVarStoreFormattedLib/NvVarStoreFormattedLib.inf
BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
}
MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf
MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf
MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf {
<LibraryClasses>
NULL|ArmVirtPkg/Library/NorFlashKvmtoolLib/NorFlashKvmtoolLib.inf
}
MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf
MdeModulePkg/Universal/ResetSystemRuntimeDxe/ResetSystemRuntimeDxe.inf
MdeModulePkg/Universal/Metronome/Metronome.inf
PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcatRealTimeClockRuntimeDxe.inf {
<LibraryClasses>
NULL|ArmVirtPkg/Library/KvmtoolRtcFdtClientLib/KvmtoolRtcFdtClientLib.inf
}
MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf
MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf
MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleDxe.inf
MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf
MdeModulePkg/Universal/SerialDxe/SerialDxe.inf
MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
ArmPkg/Drivers/ArmGic/ArmGicDxe.inf
ArmPkg/Drivers/TimerDxe/TimerDxe.inf {
<LibraryClasses>
NULL|ArmVirtPkg/Library/ArmVirtTimerFdtClientLib/ArmVirtTimerFdtClientLib.inf
}
ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.inf
MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf
#
# Platform Driver
#
ArmVirtPkg/KvmtoolPlatformDxe/KvmtoolPlatformDxe.inf
ArmVirtPkg/VirtioFdtDxe/VirtioFdtDxe.inf
ArmVirtPkg/FdtClientDxe/FdtClientDxe.inf
ArmVirtPkg/HighMemDxe/HighMemDxe.inf
OvmfPkg/VirtioBlkDxe/VirtioBlk.inf
OvmfPkg/VirtioScsiDxe/VirtioScsi.inf
OvmfPkg/VirtioNetDxe/VirtioNet.inf
OvmfPkg/VirtioRngDxe/VirtioRng.inf
#
# FAT filesystem + GPT/MBR partitioning + UDF filesystem
#
MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf
MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf
MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf
FatPkg/EnhancedFatDxe/Fat.inf
MdeModulePkg/Universal/Disk/UdfDxe/UdfDxe.inf
#
# Bds
#
MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf {
<LibraryClasses>
DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
}
MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf
MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf
MdeModulePkg/Universal/DriverHealthManagerDxe/DriverHealthManagerDxe.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
}
#
# SCSI Bus and Disk Driver
#
MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBusDxe.inf
MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf

View File

@@ -1,234 +0,0 @@
#
# Copyright (c) 2018 - 2020, ARM Limited. All rights reserved.
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
#
################################################################################
#
# FD Section
# The [FD] Section is made up of the definition statements and a
# description of what goes into the Flash Device Image. Each FD section
# defines one flash "device" image. A flash device image may be one of
# the following: Removable media bootable image (like a boot floppy
# image,) an Option ROM image (that would be "flashed" into an add-in
# card,) a System "Flash" image (that would be burned into a system's
# flash) or an Update ("Capsule") image that will be used to update and
# existing system flash.
#
################################################################################
[FD.KVMTOOL_EFI]
BaseAddress = 0x00000000|gArmTokenSpaceGuid.PcdFdBaseAddress
# The size in bytes of the FLASH Device
Size = 0x00200000|gArmTokenSpaceGuid.PcdFdSize
ErasePolarity = 1
# This one is tricky, it must be: BlockSize * NumBlocks = Size
BlockSize = 0x00001000
NumBlocks = 0x200
################################################################################
#
# Following are lists of FD Region layout which correspond to the locations of different
# images within the flash device.
#
# Regions must be defined in ascending order and may not overlap.
#
# A Layout Region start with a eight digit hex offset (leading "0x" required) followed by
# the pipe "|" character, followed by the size of the region, also in hex with the leading
# "0x" characters. Like:
# Offset|Size
# PcdOffsetCName|PcdSizeCName
# RegionType <FV, DATA, or FILE>
#
################################################################################
#
# Implement the Linux kernel header layout so that the loader will identify
# it as something bootable, and execute it with a FDT pointer in x0 or r2.
# This area will be reused to store a copy of the FDT so round it up to 32 KB.
#
0x00000000|0x00008000
DATA = {
!if $(ARCH) == AARCH64
0x01, 0x00, 0x00, 0x10, # code0: adr x1, .
0xff, 0x1f, 0x00, 0x14, # code1: b 0x8000
0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, # text_offset: 512 KB
0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, # image_size: 2 MB
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, # flags
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, # res2
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, # res3
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, # res4
0x41, 0x52, 0x4d, 0x64, # magic: "ARM\x64"
0x00, 0x00, 0x00, 0x00 # res5
!else
0x08, 0x10, 0x4f, 0xe2, # adr r1, .
0x02, 0x00, 0xa0, 0xe1, # mov r0, r2 (DTB)
0x00, 0x00, 0xa0, 0xe1, # nop
0x00, 0x00, 0xa0, 0xe1, # nop
0x00, 0x00, 0xa0, 0xe1, # nop
0x00, 0x00, 0xa0, 0xe1, # nop
0x00, 0x00, 0xa0, 0xe1, # nop
0x00, 0x00, 0xa0, 0xe1, # nop
0xf6, 0x1f, 0x00, 0xea, # b 0x8000
0x18, 0x28, 0x6f, 0x01, # magic
0x00, 0x00, 0x00, 0x00, # start
0x00, 0x00, 0x20, 0x00, # image size: 2 MB
0x01, 0x02, 0x03, 0x04 # endiannness flag
!endif
}
0x00008000|0x001f8000
gArmTokenSpaceGuid.PcdFvBaseAddress|gArmTokenSpaceGuid.PcdFvSize
FV = FVMAIN_COMPACT
################################################################################
#
# FV Section
#
# [FV] section is used to define what components or modules are placed within a flash
# device file. This section also defines order the components and modules are positioned
# within the image. The [FV] section consists of define statements, set statements and
# module statements.
#
################################################################################
[FV.FvMain]
FvNameGuid = 8A91C08E-7D9D-4933-84D6-901D26D0766E
BlockSize = 0x40
NumBlocks = 0 # This FV gets compressed so make it just big enough
FvAlignment = 16 # FV alignment and FV attributes setting.
ERASE_POLARITY = 1
MEMORY_MAPPED = TRUE
STICKY_WRITE = TRUE
LOCK_CAP = TRUE
LOCK_STATUS = TRUE
WRITE_DISABLED_CAP = TRUE
WRITE_ENABLED_CAP = TRUE
WRITE_STATUS = TRUE
WRITE_LOCK_CAP = TRUE
WRITE_LOCK_STATUS = TRUE
READ_DISABLED_CAP = TRUE
READ_ENABLED_CAP = TRUE
READ_STATUS = TRUE
READ_LOCK_CAP = TRUE
READ_LOCK_STATUS = TRUE
INF MdeModulePkg/Core/Dxe/DxeMain.inf
INF MdeModulePkg/Universal/PCD/Dxe/Pcd.inf
INF ArmVirtPkg/VirtioFdtDxe/VirtioFdtDxe.inf
INF ArmVirtPkg/FdtClientDxe/FdtClientDxe.inf
INF ArmVirtPkg/KvmtoolPlatformDxe/KvmtoolPlatformDxe.inf
INF ArmVirtPkg/HighMemDxe/HighMemDxe.inf
#
# PI DXE Drivers producing Architectural Protocols (EFI Services)
#
INF ArmPkg/Drivers/CpuDxe/CpuDxe.inf
INF MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf
INF MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf
INF MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf
INF MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf
INF MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf
INF MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf
INF MdeModulePkg/Universal/ResetSystemRuntimeDxe/ResetSystemRuntimeDxe.inf
INF MdeModulePkg/Universal/Metronome/Metronome.inf
INF PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcatRealTimeClockRuntimeDxe.inf
INF MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
#
# Multiple Console IO support
#
INF MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf
INF MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf
INF MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleDxe.inf
INF MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf
INF MdeModulePkg/Universal/SerialDxe/SerialDxe.inf
INF ArmPkg/Drivers/ArmGic/ArmGicDxe.inf
INF ArmPkg/Drivers/TimerDxe/TimerDxe.inf
INF MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf
INF ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.inf
#
# FAT filesystem + GPT/MBR partitioning + UDF filesystem
#
INF MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf
INF MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf
INF FatPkg/EnhancedFatDxe/Fat.inf
INF MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf
INF MdeModulePkg/Universal/Disk/UdfDxe/UdfDxe.inf
#
# Platform Driver
#
INF OvmfPkg/VirtioBlkDxe/VirtioBlk.inf
INF OvmfPkg/VirtioNetDxe/VirtioNet.inf
INF OvmfPkg/VirtioScsiDxe/VirtioScsi.inf
INF OvmfPkg/VirtioRngDxe/VirtioRng.inf
#
# UEFI application (Shell Embedded Boot Loader)
#
INF ShellPkg/Application/Shell/Shell.inf
INF ShellPkg/DynamicCommand/TftpDynamicCommand/TftpDynamicCommand.inf
#
# Bds
#
INF MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf
INF MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf
INF MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf
INF MdeModulePkg/Universal/DriverHealthManagerDxe/DriverHealthManagerDxe.inf
INF MdeModulePkg/Universal/BdsDxe/BdsDxe.inf
INF MdeModulePkg/Application/UiApp/UiApp.inf
#
# SCSI Bus and Disk Driver
#
INF MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBusDxe.inf
INF MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf
#
# TianoCore logo (splash screen)
#
INF MdeModulePkg/Logo/LogoDxe.inf
#
# Ramdisk support
#
INF MdeModulePkg/Universal/Disk/RamDiskDxe/RamDiskDxe.inf
[FV.FVMAIN_COMPACT]
FvAlignment = 16
ERASE_POLARITY = 1
MEMORY_MAPPED = TRUE
STICKY_WRITE = TRUE
LOCK_CAP = TRUE
LOCK_STATUS = TRUE
WRITE_DISABLED_CAP = TRUE
WRITE_ENABLED_CAP = TRUE
WRITE_STATUS = TRUE
WRITE_LOCK_CAP = TRUE
WRITE_LOCK_STATUS = TRUE
READ_DISABLED_CAP = TRUE
READ_ENABLED_CAP = TRUE
READ_STATUS = TRUE
READ_LOCK_CAP = TRUE
READ_LOCK_STATUS = TRUE
INF RuleOverride = SELF_RELOC ArmVirtPkg/PrePi/ArmVirtPrePiUniCoreRelocatable.inf
FILE FV_IMAGE = 9E21FD93-9C72-4c15-8C4B-E77F1DB2D792 {
SECTION GUIDED EE4E5898-3914-4259-9D6E-DC7BD79403CF PROCESSING_REQUIRED = TRUE {
SECTION FV_IMAGE = FVMAIN
}
}
!include ArmVirtRules.fdf.inc

View File

@@ -1,123 +0,0 @@
## @file
# Core CI configuration for ArmVirtPkg
#
# ArmVirtPkg is part of Platform Ci for builds so this is only
# used for code analysis.
#
# Copyright (c) Microsoft Corporation
# Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
# Copyright (c) 2020, ARM Limited. All rights reserved.
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
##
{
## options defined .pytool/Plugin/LicenseCheck
"LicenseCheck": {
"IgnoreFiles": []
},
"EccCheck": {
## Exception sample looks like below:
## "ExceptionList": [
## "<ErrorID>", "<KeyWord>"
## ]
"ExceptionList": [
],
## Both file path and directory path are accepted.
"IgnoreFiles": [
]
},
## options defined .pytool/Plugin/CompilerPlugin
"CompilerPlugin": {
"DscPath": "" # Don't support this test
},
## options defined .pytool/Plugin/HostUnitTestCompilerPlugin
"HostUnitTestCompilerPlugin": {
"DscPath": "" # Don't support this test
},
## options defined .pytool/Plugin/CharEncodingCheck
"CharEncodingCheck": {
"IgnoreFiles": []
},
## options defined .pytool/Plugin/DependencyCheck
"DependencyCheck": {
"AcceptableDependencies": [
"MdePkg/MdePkg.dec",
"MdeModulePkg/MdeModulePkg.dec",
"ArmVirtPkg/ArmVirtPkg.dec",
"NetworkPkg/NetworkPkg.dec",
"ArmPkg/ArmPkg.dec",
"OvmfPkg/OvmfPkg.dec",
"EmbeddedPkg/EmbeddedPkg.dec",
"ArmPlatformPkg/ArmPlatformPkg.dec",
"PcAtChipsetPkg/PcAtChipsetPkg.dec",
"SecurityPkg/SecurityPkg.dec",
"ShellPkg/ShellPkg.dec" #Is this ok?
],
# For host based unit tests
"AcceptableDependencies-HOST_APPLICATION":[
"UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec"
],
# For UEFI shell based apps
"AcceptableDependencies-UEFI_APPLICATION":[
],
"IgnoreInf": []
},
## options defined .pytool/Plugin/DscCompleteCheck
"DscCompleteCheck": {
"IgnoreInf": [""],
"DscPath": "" # Don't support this test
},
## options defined .pytool/Plugin/HostUnitTestDscCompleteCheck
"HostUnitTestDscCompleteCheck": {
"IgnoreInf": [""],
"DscPath": "" # Don't support this test
},
## options defined .pytool/Plugin/GuidCheck
"GuidCheck": {
"IgnoreGuidName": [],
"IgnoreGuidValue": [],
"IgnoreFoldersAndFiles": [],
"IgnoreDuplicates": [],
},
## options defined .pytool/Plugin/LibraryClassCheck
"LibraryClassCheck": {
"IgnoreHeaderFile": []
},
## options defined .pytool/Plugin/SpellCheck
"SpellCheck": {
"AuditOnly": False, # Fails right now with over 270 errors
"IgnoreFiles": [], # use gitignore syntax to ignore errors in matching files
"ExtendWords": [
"setjump",
"plong",
"lparam",
"lpdword",
"lpthread",
"lresult",
"bootable",
"bsymbolic",
"endiannness",
"fvmain",
"multiboot",
"qemu's",
"ramdisk",
"ramfb",
"unbootable",
"virt's",
"werror",
"xenio",
"kvmtool"
], # words to extend to the dictionary for this package
"IgnoreStandardPaths": [], # Standard Plugin defined paths that should be ignore
"AdditionalIncludePaths": [] # Additional paths to spell check (wildcards supported)
}
}

View File

@@ -1,7 +1,6 @@
#/** @file
#
# Copyright (c) 2014, Linaro Limited. All rights reserved.
# Copyright (c) 2020, ARM Limited. All rights reserved.
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
@@ -31,19 +30,12 @@
[Guids.common]
gArmVirtTokenSpaceGuid = { 0x0B6F5CA7, 0x4F53, 0x445A, { 0xB7, 0x6E, 0x2E, 0x36, 0x5B, 0x80, 0x63, 0x66 } }
gEarlyPL011BaseAddressGuid = { 0xB199DEA9, 0xFD5C, 0x4A84, { 0x80, 0x82, 0x2F, 0x41, 0x70, 0x78, 0x03, 0x05 } }
gEarly16550UartBaseAddressGuid = { 0xea67ca3e, 0x1f54, 0x436b, { 0x97, 0x88, 0xd4, 0xeb, 0x29, 0xc3, 0x42, 0x67 } }
gArmVirtVariableGuid = { 0x50bea1e5, 0xa2c5, 0x46e9, { 0x9b, 0x3a, 0x59, 0x59, 0x65, 0x16, 0xb0, 0x0a } }
[Protocols]
gFdtClientProtocolGuid = { 0xE11FACA0, 0x4710, 0x4C8E, { 0xA7, 0xA2, 0x01, 0xBA, 0xA2, 0x59, 0x1B, 0x4C } }
[PcdsFeatureFlag]
#
# Feature Flag PCD that defines whether TPM2 support is enabled
#
gArmVirtTokenSpaceGuid.PcdTpm2SupportEnabled|FALSE|BOOLEAN|0x00000004
[PcdsFixedAtBuild, PcdsPatchableInModule]
#
# This is the physical address where the device tree is expected to be stored

View File

@@ -1,7 +1,7 @@
#
# Copyright (c) 2011-2015, ARM Limited. All rights reserved.
# Copyright (c) 2014, Linaro Limited. All rights reserved.
# Copyright (c) 2015 - 2020, Intel Corporation. All rights reserved.
# Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
@@ -29,8 +29,6 @@
#
DEFINE TTY_TERMINAL = FALSE
DEFINE SECURE_BOOT_ENABLE = FALSE
DEFINE TPM2_ENABLE = FALSE
DEFINE TPM2_CONFIG_ENABLE = FALSE
#
# Network definition
@@ -40,7 +38,6 @@
DEFINE NETWORK_SNP_ENABLE = FALSE
DEFINE NETWORK_TLS_ENABLE = FALSE
DEFINE NETWORK_ALLOW_HTTP_CONNECTIONS = TRUE
DEFINE NETWORK_ISCSI_ENABLE = TRUE
!if $(NETWORK_SNP_ENABLE) == TRUE
!error "NETWORK_SNP_ENABLE is IA32/X64/EBC only"
@@ -59,8 +56,6 @@
VirtioMmioDeviceLib|OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDeviceLib.inf
QemuFwCfgLib|ArmVirtPkg/Library/QemuFwCfgLib/QemuFwCfgLib.inf
QemuFwCfgS3Lib|OvmfPkg/Library/QemuFwCfgS3Lib/BaseQemuFwCfgS3LibNull.inf
QemuFwCfgSimpleParserLib|OvmfPkg/Library/QemuFwCfgSimpleParserLib/QemuFwCfgSimpleParserLib.inf
QemuLoadImageLib|OvmfPkg/Library/GenericQemuLoadImageLib/GenericQemuLoadImageLib.inf
ArmPlatformLib|ArmPlatformPkg/Library/ArmPlatformLibNull/ArmPlatformLibNull.inf
@@ -79,36 +74,15 @@
PciSegmentLib|MdePkg/Library/BasePciSegmentLibPci/BasePciSegmentLibPci.inf
PciHostBridgeLib|ArmVirtPkg/Library/FdtPciHostBridgeLib/FdtPciHostBridgeLib.inf
!if $(TPM2_ENABLE) == TRUE
Tpm2CommandLib|SecurityPkg/Library/Tpm2CommandLib/Tpm2CommandLib.inf
Tcg2PhysicalPresenceLib|OvmfPkg/Library/Tcg2PhysicalPresenceLibQemu/DxeTcg2PhysicalPresenceLib.inf
TpmMeasurementLib|SecurityPkg/Library/DxeTpmMeasurementLib/DxeTpmMeasurementLib.inf
!else
TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/TpmMeasurementLibNull.inf
!endif
[LibraryClasses.common.PEIM]
ArmVirtMemInfoLib|ArmVirtPkg/Library/QemuVirtMemInfoLib/QemuVirtMemInfoPeiLib.inf
!if $(TPM2_ENABLE) == TRUE
BaseCryptLib|CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf
ResetSystemLib|MdeModulePkg/Library/PeiResetSystemLib/PeiResetSystemLib.inf
Tpm2DeviceLib|SecurityPkg/Library/Tpm2DeviceLibDTpm/Tpm2DeviceLibDTpm.inf
!endif
[LibraryClasses.common.DXE_DRIVER]
ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf
!if $(TPM2_ENABLE) == TRUE
Tpm2DeviceLib|SecurityPkg/Library/Tpm2DeviceLibTcg2/Tpm2DeviceLibTcg2.inf
!endif
[LibraryClasses.common.UEFI_DRIVER]
UefiScsiLib|MdePkg/Library/UefiScsiLib/UefiScsiLib.inf
[BuildOptions]
!include NetworkPkg/NetworkBuildOptions.dsc.inc
################################################################################
#
# Pcd Section - list of all EDK II PCD Entries defined by this Platform
@@ -126,8 +100,6 @@
gEfiMdeModulePkgTokenSpaceGuid.PcdTurnOffUsbLegacySupport|TRUE
gArmVirtTokenSpaceGuid.PcdTpm2SupportEnabled|$(TPM2_ENABLE)
[PcdsFixedAtBuild.common]
!if $(ARCH) == AARCH64
gArmTokenSpaceGuid.PcdVFPEnabled|1
@@ -214,6 +186,10 @@
# point only, for entry point versions >= 3.0.
gEfiMdeModulePkgTokenSpaceGuid.PcdSmbiosEntryPointProvideMethod|0x2
# ACPI predates the AARCH64 architecture by 5 versions, so
# we only target OSes that support ACPI v5.0 or later
gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiExposedTableVersions|0x20
[PcdsDynamicDefault.common]
gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut|3
@@ -261,29 +237,9 @@
gEfiMdeModulePkgTokenSpaceGuid.PcdSmbiosDocRev|0x0
gUefiOvmfPkgTokenSpaceGuid.PcdQemuSmbiosValidated|FALSE
#
# IPv4 and IPv6 PXE Boot support.
#
gEfiNetworkPkgTokenSpaceGuid.PcdIPv4PXESupport|0x01
gEfiNetworkPkgTokenSpaceGuid.PcdIPv6PXESupport|0x01
#
# TPM2 support
#
gEfiSecurityPkgTokenSpaceGuid.PcdTpmBaseAddress|0x0
!if $(TPM2_ENABLE) == TRUE
gEfiSecurityPkgTokenSpaceGuid.PcdTpmInstanceGuid|{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
gEfiSecurityPkgTokenSpaceGuid.PcdTpm2HashMask|0
!endif
[PcdsDynamicHii]
gArmVirtTokenSpaceGuid.PcdForceNoAcpi|L"ForceNoAcpi"|gArmVirtVariableGuid|0x0|FALSE|NV,BS
!if $(TPM2_CONFIG_ENABLE) == TRUE
gEfiSecurityPkgTokenSpaceGuid.PcdTcgPhysicalPresenceInterfaceVer|L"TCG2_VERSION"|gTcg2ConfigFormSetGuid|0x0|"1.3"|NV,BS
gEfiSecurityPkgTokenSpaceGuid.PcdTpm2AcpiTableRev|L"TCG2_VERSION"|gTcg2ConfigFormSetGuid|0x8|3|NV,BS
!endif
################################################################################
#
# Components Section - list of all EDK II Modules needed by this Platform
@@ -305,23 +261,6 @@
MdeModulePkg/Universal/Variable/Pei/VariablePei.inf
!if $(TPM2_ENABLE) == TRUE
MdeModulePkg/Universal/ResetSystemPei/ResetSystemPei.inf {
<LibraryClasses>
ResetSystemLib|ArmVirtPkg/Library/ArmVirtPsciResetSystemPeiLib/ArmVirtPsciResetSystemPeiLib.inf
}
OvmfPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf
SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.inf {
<LibraryClasses>
HashLib|SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterPei.inf
NULL|SecurityPkg/Library/HashInstanceLibSha1/HashInstanceLibSha1.inf
NULL|SecurityPkg/Library/HashInstanceLibSha256/HashInstanceLibSha256.inf
NULL|SecurityPkg/Library/HashInstanceLibSha384/HashInstanceLibSha384.inf
NULL|SecurityPkg/Library/HashInstanceLibSha512/HashInstanceLibSha512.inf
NULL|SecurityPkg/Library/HashInstanceLibSm3/HashInstanceLibSm3.inf
}
!endif
MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf {
<LibraryClasses>
NULL|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf
@@ -356,9 +295,6 @@
MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf {
<LibraryClasses>
NULL|SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.inf
!if $(TPM2_ENABLE) == TRUE
NULL|SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.inf
!endif
}
SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf
OvmfPkg/EnrollDefaultKeys/EnrollDefaultKeys.inf
@@ -435,18 +371,11 @@
NULL|MdeModulePkg/Library/BootManagerUiLib/BootManagerUiLib.inf
NULL|MdeModulePkg/Library/BootMaintenanceManagerUiLib/BootMaintenanceManagerUiLib.inf
}
OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.inf
#
# Networking stack
#
!include NetworkPkg/NetworkComponents.dsc.inc
NetworkPkg/UefiPxeBcDxe/UefiPxeBcDxe.inf {
<LibraryClasses>
NULL|OvmfPkg/Library/PxeBcPcdProducerLib/PxeBcPcdProducerLib.inf
}
!if $(NETWORK_TLS_ENABLE) == TRUE
NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.inf {
<LibraryClasses>
@@ -460,11 +389,6 @@
MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBusDxe.inf
MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf
#
# NVME Driver
#
MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxe.inf
#
# SMBIOS Support
#
@@ -506,26 +430,6 @@
MdeModulePkg/Bus/Usb/UsbKbDxe/UsbKbDxe.inf
MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf
#
# TPM2 support
#
!if $(TPM2_ENABLE) == TRUE
SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.inf {
<LibraryClasses>
HashLib|SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterDxe.inf
Tpm2DeviceLib|SecurityPkg/Library/Tpm2DeviceLibRouter/Tpm2DeviceLibRouterDxe.inf
NULL|SecurityPkg/Library/Tpm2DeviceLibDTpm/Tpm2InstanceLibDTpm.inf
NULL|SecurityPkg/Library/HashInstanceLibSha1/HashInstanceLibSha1.inf
NULL|SecurityPkg/Library/HashInstanceLibSha256/HashInstanceLibSha256.inf
NULL|SecurityPkg/Library/HashInstanceLibSha384/HashInstanceLibSha384.inf
NULL|SecurityPkg/Library/HashInstanceLibSha512/HashInstanceLibSha512.inf
NULL|SecurityPkg/Library/HashInstanceLibSm3/HashInstanceLibSm3.inf
}
!if $(TPM2_CONFIG_ENABLE) == TRUE
SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigDxe.inf
!endif
!endif
#
# ACPI Support
#

View File

@@ -113,12 +113,6 @@ READ_LOCK_STATUS = TRUE
INF MdeModulePkg/Universal/Variable/Pei/VariablePei.inf
INF MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
!if $(TPM2_ENABLE) == TRUE
INF MdeModulePkg/Universal/ResetSystemPei/ResetSystemPei.inf
INF OvmfPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf
INF SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.inf
!endif
FILE FV_IMAGE = 9E21FD93-9C72-4c15-8C4B-E77F1DB2D792 {
SECTION GUIDED EE4E5898-3914-4259-9D6E-DC7BD79403CF PROCESSING_REQUIRED = TRUE {
SECTION FV_IMAGE = FVMAIN

View File

@@ -103,8 +103,6 @@ READ_LOCK_STATUS = TRUE
#
INF ShellPkg/Application/Shell/Shell.inf
INF ShellPkg/DynamicCommand/TftpDynamicCommand/TftpDynamicCommand.inf
INF ShellPkg/DynamicCommand/HttpDynamicCommand/HttpDynamicCommand.inf
INF OvmfPkg/LinuxInitrdDynamicShellCommand/LinuxInitrdDynamicShellCommand.inf
#
# Bds
@@ -115,7 +113,6 @@ READ_LOCK_STATUS = TRUE
INF MdeModulePkg/Universal/DriverHealthManagerDxe/DriverHealthManagerDxe.inf
INF MdeModulePkg/Universal/BdsDxe/BdsDxe.inf
INF MdeModulePkg/Application/UiApp/UiApp.inf
INF OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.inf
#
# Networking stack
@@ -129,11 +126,6 @@ READ_LOCK_STATUS = TRUE
INF MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBusDxe.inf
INF MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf
#
# NVME Driver
#
INF MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxe.inf
#
# SMBIOS Support
#
@@ -181,16 +173,6 @@ READ_LOCK_STATUS = TRUE
INF MdeModulePkg/Bus/Usb/UsbKbDxe/UsbKbDxe.inf
INF MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf
#
# TPM2 support
#
!if $(TPM2_ENABLE) == TRUE
INF SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.inf
!if $(TPM2_CONFIG_ENABLE) == TRUE
INF SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigDxe.inf
!endif
!endif
#
# TianoCore logo (splash screen)
#

View File

@@ -1,7 +1,7 @@
#
# Copyright (c) 2011-2015, ARM Limited. All rights reserved.
# Copyright (c) 2014, Linaro Limited. All rights reserved.
# Copyright (c) 2015 - 2020, Intel Corporation. All rights reserved.
# Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
@@ -38,7 +38,6 @@
DEFINE NETWORK_SNP_ENABLE = FALSE
DEFINE NETWORK_TLS_ENABLE = FALSE
DEFINE NETWORK_ALLOW_HTTP_CONNECTIONS = TRUE
DEFINE NETWORK_ISCSI_ENABLE = TRUE
!if $(NETWORK_SNP_ENABLE) == TRUE
!error "NETWORK_SNP_ENABLE is IA32/X64/EBC only"
@@ -57,8 +56,6 @@
VirtioMmioDeviceLib|OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDeviceLib.inf
QemuFwCfgLib|ArmVirtPkg/Library/QemuFwCfgLib/QemuFwCfgLib.inf
QemuFwCfgS3Lib|OvmfPkg/Library/QemuFwCfgS3Lib/BaseQemuFwCfgS3LibNull.inf
QemuFwCfgSimpleParserLib|OvmfPkg/Library/QemuFwCfgSimpleParserLib/QemuFwCfgSimpleParserLib.inf
QemuLoadImageLib|OvmfPkg/Library/GenericQemuLoadImageLib/GenericQemuLoadImageLib.inf
ArmVirtMemInfoLib|ArmVirtPkg/Library/QemuVirtMemInfoLib/QemuVirtMemInfoLib.inf
@@ -76,7 +73,6 @@
PciPcdProducerLib|ArmVirtPkg/Library/FdtPciPcdProducerLib/FdtPciPcdProducerLib.inf
PciSegmentLib|MdePkg/Library/BasePciSegmentLibPci/BasePciSegmentLibPci.inf
PciHostBridgeLib|ArmVirtPkg/Library/FdtPciHostBridgeLib/FdtPciHostBridgeLib.inf
TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/TpmMeasurementLibNull.inf
[LibraryClasses.common.DXE_DRIVER]
ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf
@@ -84,14 +80,14 @@
[LibraryClasses.common.UEFI_DRIVER]
UefiScsiLib|MdePkg/Library/UefiScsiLib/UefiScsiLib.inf
[BuildOptions]
!include NetworkPkg/NetworkBuildOptions.dsc.inc
[BuildOptions.common.EDKII.SEC, BuildOptions.common.EDKII.BASE]
#
# We need to avoid jump tables in SEC modules, so that the PE/COFF
# self-relocation code itself is guaranteed to be position independent.
# CLANG38 with LTO support enabled uses the GNU GOLD linker, which insists
# on emitting GOT based symbol references when running in shared mode, unless
# we override visibility to 'hidden' in all modules that make up the PrePi
# build.
#
GCC:*_*_*_CC_FLAGS = -fno-jump-tables
GCC:*_CLANG38_*_CC_FLAGS = -include $(WORKSPACE)/ArmVirtPkg/Include/Platform/Hidden.h
################################################################################
#
@@ -176,12 +172,6 @@
gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|3
[PcdsPatchableInModule.common]
# we need to provide a resolution for this PCD that supports PcdSet64()
# being called from ArmVirtPkg/Library/PlatformPeiLib/PlatformPeiLib.c,
# even though that call will be compiled out on this platform as it does
# not (and cannot) support the TPM2 driver stack
gEfiSecurityPkgTokenSpaceGuid.PcdTpmBaseAddress|0x0
#
# This will be overridden in the code
#
@@ -241,12 +231,6 @@
gEfiMdeModulePkgTokenSpaceGuid.PcdSmbiosDocRev|0x0
gUefiOvmfPkgTokenSpaceGuid.PcdQemuSmbiosValidated|FALSE
#
# IPv4 and IPv6 PXE Boot support.
#
gEfiNetworkPkgTokenSpaceGuid.PcdIPv4PXESupport|0x01
gEfiNetworkPkgTokenSpaceGuid.PcdIPv6PXESupport|0x01
################################################################################
#
# Components Section - list of all EDK II Modules needed by this Platform
@@ -371,18 +355,11 @@
NULL|MdeModulePkg/Library/BootManagerUiLib/BootManagerUiLib.inf
NULL|MdeModulePkg/Library/BootMaintenanceManagerUiLib/BootMaintenanceManagerUiLib.inf
}
OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.inf
#
# Networking stack
#
!include NetworkPkg/NetworkComponents.dsc.inc
NetworkPkg/UefiPxeBcDxe/UefiPxeBcDxe.inf {
<LibraryClasses>
NULL|OvmfPkg/Library/PxeBcPcdProducerLib/PxeBcPcdProducerLib.inf
}
!if $(NETWORK_TLS_ENABLE) == TRUE
NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.inf {
<LibraryClasses>
@@ -396,11 +373,6 @@
MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBusDxe.inf
MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf
#
# NVME Driver
#
MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxe.inf
#
# SMBIOS Support
#

View File

@@ -136,7 +136,7 @@ READ_STATUS = TRUE
READ_LOCK_CAP = TRUE
READ_LOCK_STATUS = TRUE
INF RuleOverride = SELF_RELOC ArmVirtPkg/PrePi/ArmVirtPrePiUniCoreRelocatable.inf
INF ArmVirtPkg/PrePi/ArmVirtPrePiUniCoreRelocatable.inf
FILE FV_IMAGE = 9E21FD93-9C72-4c15-8C4B-E77F1DB2D792 {
SECTION GUIDED EE4E5898-3914-4259-9D6E-DC7BD79403CF PROCESSING_REQUIRED = TRUE {

View File

@@ -39,11 +39,6 @@
TE TE Align = Auto $(INF_OUTPUT)/$(MODULE_NAME).efi
}
[Rule.Common.SEC.SELF_RELOC]
FILE SEC = $(NAMED_GUID) {
TE TE Align = Auto $(INF_OUTPUT)/$(MODULE_NAME).efi
}
[Rule.Common.PEI_CORE]
FILE PEI_CORE = $(NAMED_GUID) FIXED {
TE TE Align = Auto $(INF_OUTPUT)/$(MODULE_NAME).efi

View File

@@ -47,17 +47,18 @@
BootLogoLib|MdeModulePkg/Library/BootLogoLib/BootLogoLib.inf
PlatformBootManagerLib|ArmPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
CustomizedDisplayLib|MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.inf
TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/TpmMeasurementLibNull.inf
[LibraryClasses.common.UEFI_DRIVER]
UefiScsiLib|MdePkg/Library/UefiScsiLib/UefiScsiLib.inf
[BuildOptions]
[BuildOptions.common.EDKII.SEC, BuildOptions.common.EDKII.BASE]
#
# We need to avoid jump tables in SEC modules, so that the PE/COFF
# self-relocation code itself is guaranteed to be position independent.
# CLANG38 with LTO support enabled uses the GNU GOLD linker, which insists
# on emitting GOT based symbol references when running in shared mode, unless
# we override visibility to 'hidden' in all modules that make up the PrePi
# build.
#
GCC:*_*_*_CC_FLAGS = -fno-jump-tables
GCC:*_CLANG38_*_CC_FLAGS = -include $(WORKSPACE)/ArmVirtPkg/Include/Platform/Hidden.h
################################################################################
#
@@ -94,12 +95,6 @@
gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvModeEnable|TRUE
[PcdsPatchableInModule.common]
# we need to provide a resolution for this PCD that supports PcdSet64()
# being called from ArmVirtPkg/Library/PlatformPeiLib/PlatformPeiLib.c,
# even though that call will be compiled out on this platform as it does
# not (and cannot) support the TPM2 driver stack
gEfiSecurityPkgTokenSpaceGuid.PcdTpmBaseAddress|0x0
#
# This will be overridden in the code
#

View File

@@ -182,8 +182,6 @@ READ_LOCK_STATUS = TRUE
#
INF ShellPkg/Application/Shell/Shell.inf
INF ShellPkg/DynamicCommand/TftpDynamicCommand/TftpDynamicCommand.inf
INF ShellPkg/DynamicCommand/HttpDynamicCommand/HttpDynamicCommand.inf
INF OvmfPkg/LinuxInitrdDynamicShellCommand/LinuxInitrdDynamicShellCommand.inf
#
# Bds
@@ -234,7 +232,7 @@ READ_STATUS = TRUE
READ_LOCK_CAP = TRUE
READ_LOCK_STATUS = TRUE
INF RuleOverride = SELF_RELOC ArmVirtPkg/PrePi/ArmVirtPrePiUniCoreRelocatable.inf
INF ArmVirtPkg/PrePi/ArmVirtPrePiUniCoreRelocatable.inf
FILE FV_IMAGE = 9E21FD93-9C72-4c15-8C4B-E77F1DB2D792 {
SECTION GUIDED EE4E5898-3914-4259-9D6E-DC7BD79403CF PROCESSING_REQUIRED = TRUE {

View File

@@ -1,22 +0,0 @@
/** @file
GUID for the HOB that caches the base address of the 16550 serial port, for
when PCD access is not available.
Copyright (c) 2020, ARM Limited. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#ifndef EARLY_16550_UART_BASE_ADDRESS_H__
#define EARLY_16550_UART_BASE_ADDRESS_H__
#define EARLY_16550_UART_BASE_ADDRESS_GUID { \
0xea67ca3e, 0x1f54, 0x436b, { \
0x97, 0x88, 0xd4, 0xeb, 0x29, 0xc3, 0x42, 0x67 \
} \
}
extern EFI_GUID gEarly16550UartBaseAddressGuid;
#endif // EARLY_16550_UART_BASE_ADDRESS_H__

View File

@@ -0,0 +1,22 @@
/** @file
Copyright (c) 2018, Linaro Limited. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#ifndef __PLATFORM_HIDDEN_H
#define __PLATFORM_HIDDEN_H
//
// Setting the GCC -fvisibility=hidden command line option is not quite the same
// as setting the pragma below: the former only affects definitions, whereas the
// pragma affects extern declarations as well. So if we want to ensure that no
// GOT indirected symbol references are emitted, we need to use the pragma, or
// GOT based cross object references could be emitted, e.g., in libraries, and
// these cannot be relaxed to ordinary symbol references at link time.
//
#pragma GCC visibility push (hidden)
#endif

View File

@@ -1,82 +0,0 @@
/** @file
The KvmtoolPlatformDxe performs the platform specific initialization like:
- It decides if the firmware should expose ACPI or Device Tree-based
hardware description to the operating system.
Copyright (c) 2018 - 2020, ARM Limited. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include <Guid/VariableFormat.h>
#include <Library/BaseLib.h>
#include <Library/DebugLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Protocol/FdtClient.h>
/** Decide if the firmware should expose ACPI tables or Device Tree and
install the appropriate protocol interface.
Note: This function is derived from "ArmVirtPkg/PlatformHasAcpiDtDxe",
by dropping the word size check, and the fw_cfg check.
@param [in] ImageHandle Handle for this image.
@retval EFI_SUCCESS Success.
@retval EFI_OUT_OF_RESOURCES There was not enough memory to install the
protocols.
@retval EFI_INVALID_PARAMETER A parameter is invalid.
**/
STATIC
EFI_STATUS
PlatformHasAcpiDt (
IN EFI_HANDLE ImageHandle
)
{
if (!PcdGetBool (PcdForceNoAcpi)) {
// Expose ACPI tables
return gBS->InstallProtocolInterface (
&ImageHandle,
&gEdkiiPlatformHasAcpiGuid,
EFI_NATIVE_INTERFACE,
NULL
);
}
// Expose the Device Tree.
return gBS->InstallProtocolInterface (
&ImageHandle,
&gEdkiiPlatformHasDeviceTreeGuid,
EFI_NATIVE_INTERFACE,
NULL
);
}
/** Entry point for Kvmtool Platform Dxe
@param [in] ImageHandle Handle for this image.
@param [in] SystemTable Pointer to the EFI system table.
@retval EFI_SUCCESS Success.
@retval EFI_OUT_OF_RESOURCES There was not enough memory to install the
protocols.
@retval EFI_INVALID_PARAMETER A parameter is invalid.
**/
EFI_STATUS
EFIAPI
KvmtoolPlatformDxeEntryPoint (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EFI_STATUS Status;
Status = PlatformHasAcpiDt (ImageHandle);
ASSERT_EFI_ERROR (Status);
return Status;
}

View File

@@ -1,43 +0,0 @@
## @file
# The KvmtoolPlatformDxe performs the platform specific initialization like:
# - It decides if the firmware should expose ACPI or Device Tree-based
# hardware description to the operating system.
#
# Copyright (c) 2018 - 2020, ARM Limited. All rights reserved.
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
##
[Defines]
INF_VERSION = 0x0001001B
BASE_NAME = KvmtoolPlatformDxe
FILE_GUID = 7479CCCD-D721-442A-8C73-A72DBB886669
MODULE_TYPE = DXE_DRIVER
VERSION_STRING = 1.0
ENTRY_POINT = KvmtoolPlatformDxeEntryPoint
[Sources]
KvmtoolPlatformDxe.c
[Packages]
ArmVirtPkg/ArmVirtPkg.dec
EmbeddedPkg/EmbeddedPkg.dec
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
[LibraryClasses]
BaseLib
DebugLib
UefiBootServicesTableLib
UefiDriverEntryPoint
[Guids]
gEdkiiPlatformHasAcpiGuid ## SOMETIMES_PRODUCES ## PROTOCOL
gEdkiiPlatformHasDeviceTreeGuid ## SOMETIMES_PRODUCES ## PROTOCOL
[Pcd]
gArmVirtTokenSpaceGuid.PcdForceNoAcpi
[Depex]
TRUE

View File

@@ -110,12 +110,7 @@ ArmVirtGicArchLibConstructor (
break;
case 2:
//
// When the GICv2 is emulated with virtualization=on, it adds a virtual
// set of control registers. This means the register property can be
// either 32 or 64 bytes in size.
//
ASSERT ((RegSize == 32) || (RegSize == 64));
ASSERT (RegSize == 32);
DistBase = SwapBytes64 (Reg[0]);
CpuBase = SwapBytes64 (Reg[2]);

View File

@@ -1,232 +0,0 @@
/** @file
Reset System lib using PSCI hypervisor or secure monitor calls
Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
Copyright (c) 2013, ARM Ltd. All rights reserved.<BR>
Copyright (c) 2014-2020, Linaro Ltd. All rights reserved.<BR>
Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include <PiPei.h>
#include <libfdt.h>
#include <Library/ArmHvcLib.h>
#include <Library/ArmSmcLib.h>
#include <Library/BaseLib.h>
#include <Library/DebugLib.h>
#include <Library/HobLib.h>
#include <Library/ResetSystemLib.h>
#include <IndustryStandard/ArmStdSmc.h>
typedef enum {
PsciMethodUnknown,
PsciMethodSmc,
PsciMethodHvc,
} PSCI_METHOD;
STATIC
PSCI_METHOD
DiscoverPsciMethod (
VOID
)
{
VOID *DeviceTreeBase;
INT32 Node, Prev;
INT32 Len;
CONST CHAR8 *Compatible;
CONST CHAR8 *CompatibleItem;
CONST VOID *Prop;
DeviceTreeBase = (VOID*)(UINTN)PcdGet64 (PcdDeviceTreeInitialBaseAddress);
ASSERT (fdt_check_header (DeviceTreeBase) == 0);
//
// Enumerate all FDT nodes looking for the PSCI node and capture the method
//
for (Prev = 0;; Prev = Node) {
Node = fdt_next_node (DeviceTreeBase, Prev, NULL);
if (Node < 0) {
break;
}
Compatible = fdt_getprop (DeviceTreeBase, Node, "compatible", &Len);
if (Compatible == NULL) {
continue;
}
//
// Iterate over the NULL-separated items in the compatible string
//
for (CompatibleItem = Compatible; CompatibleItem < Compatible + Len;
CompatibleItem += 1 + AsciiStrLen (CompatibleItem)) {
if (AsciiStrCmp (CompatibleItem, "arm,psci-0.2") != 0) {
continue;
}
Prop = fdt_getprop (DeviceTreeBase, Node, "method", NULL);
if (!Prop) {
DEBUG ((DEBUG_ERROR, "%a: Missing PSCI method property\n",
__FUNCTION__));
return PsciMethodUnknown;
}
if (AsciiStrnCmp (Prop, "hvc", 3) == 0) {
return PsciMethodHvc;
} else if (AsciiStrnCmp (Prop, "smc", 3) == 0) {
return PsciMethodSmc;
} else {
DEBUG ((DEBUG_ERROR, "%a: Unknown PSCI method \"%a\"\n", __FUNCTION__,
Prop));
return PsciMethodUnknown;
}
}
}
return PsciMethodUnknown;
}
STATIC
VOID
PerformPsciAction (
IN UINTN Arg0
)
{
ARM_SMC_ARGS ArmSmcArgs;
ARM_HVC_ARGS ArmHvcArgs;
ArmSmcArgs.Arg0 = Arg0;
ArmHvcArgs.Arg0 = Arg0;
switch (DiscoverPsciMethod ()) {
case PsciMethodHvc:
ArmCallHvc (&ArmHvcArgs);
break;
case PsciMethodSmc:
ArmCallSmc (&ArmSmcArgs);
break;
default:
DEBUG ((DEBUG_ERROR, "%a: no PSCI method defined\n", __FUNCTION__));
ASSERT (FALSE);
}
}
/**
This function causes a system-wide reset (cold reset), in which
all circuitry within the system returns to its initial state. This type of reset
is asynchronous to system operation and operates without regard to
cycle boundaries.
If this function returns, it means that the system does not support cold reset.
**/
VOID
EFIAPI
ResetCold (
VOID
)
{
// Send a PSCI 0.2 SYSTEM_RESET command
PerformPsciAction (ARM_SMC_ID_PSCI_SYSTEM_RESET);
}
/**
This function causes a system-wide initialization (warm reset), in which all processors
are set to their initial state. Pending cycles are not corrupted.
If this function returns, it means that the system does not support warm reset.
**/
VOID
EFIAPI
ResetWarm (
VOID
)
{
// Map a warm reset into a cold reset
ResetCold ();
}
/**
This function causes the system to enter a power state equivalent
to the ACPI G2/S5 or G3 states.
If this function returns, it means that the system does not support shutdown reset.
**/
VOID
EFIAPI
ResetShutdown (
VOID
)
{
// Send a PSCI 0.2 SYSTEM_OFF command
PerformPsciAction (ARM_SMC_ID_PSCI_SYSTEM_OFF);
}
/**
This function causes a systemwide reset. The exact type of the reset is
defined by the EFI_GUID that follows the Null-terminated Unicode string passed
into ResetData. If the platform does not recognize the EFI_GUID in ResetData
the platform must pick a supported reset type to perform.The platform may
optionally log the parameters from any non-normal reset that occurs.
@param[in] DataSize The size, in bytes, of ResetData.
@param[in] ResetData The data buffer starts with a Null-terminated string,
followed by the EFI_GUID.
**/
VOID
EFIAPI
ResetPlatformSpecific (
IN UINTN DataSize,
IN VOID *ResetData
)
{
// Map the platform specific reset as reboot
ResetCold ();
}
/**
The ResetSystem function resets the entire platform.
@param[in] ResetType The type of reset to perform.
@param[in] ResetStatus The status code for the reset.
@param[in] DataSize The size, in bytes, of ResetData.
@param[in] ResetData For a ResetType of EfiResetCold, EfiResetWarm, or EfiResetShutdown
the data buffer starts with a Null-terminated string, optionally
followed by additional binary data. The string is a description
that the caller may use to further indicate the reason for the
system reset.
**/
VOID
EFIAPI
ResetSystem (
IN EFI_RESET_TYPE ResetType,
IN EFI_STATUS ResetStatus,
IN UINTN DataSize,
IN VOID *ResetData OPTIONAL
)
{
switch (ResetType) {
case EfiResetWarm:
ResetWarm ();
break;
case EfiResetCold:
ResetCold ();
break;
case EfiResetShutdown:
ResetShutdown ();
return;
case EfiResetPlatformSpecific:
ResetPlatformSpecific (DataSize, ResetData);
return;
default:
return;
}
}

View File

@@ -1,39 +0,0 @@
#/** @file
# Reset System lib using PSCI hypervisor or secure monitor calls
#
# Copyright (c) 2008, Apple Inc. All rights reserved.<BR>
# Copyright (c) 2014-2020, Linaro Ltd. All rights reserved.<BR>
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
#
#**/
[Defines]
INF_VERSION = 1.27
BASE_NAME = ArmVirtPsciResetSystemPeiLib
FILE_GUID = 551cfb98-c185-41a3-86bf-8cdb7e2a530c
MODULE_TYPE = BASE
VERSION_STRING = 1.0
LIBRARY_CLASS = ResetSystemLib|PEIM
[Sources]
ArmVirtPsciResetSystemPeiLib.c
[Packages]
ArmPkg/ArmPkg.dec
ArmVirtPkg/ArmVirtPkg.dec
EmbeddedPkg/EmbeddedPkg.dec
MdeModulePkg/MdeModulePkg.dec
MdePkg/MdePkg.dec
[LibraryClasses]
ArmSmcLib
ArmHvcLib
BaseLib
DebugLib
FdtLib
HobLib
[Pcd]
gArmVirtTokenSpaceGuid.PcdDeviceTreeInitialBaseAddress

View File

@@ -1,137 +0,0 @@
/** @file
Early Platform Hook Library instance for 16550 Uart.
Copyright (c) 2020, ARM Ltd. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include <Base.h>
#include <Uefi.h>
#include <Pi/PiBootMode.h>
#include <Pi/PiHob.h>
#include <Library/BaseLib.h>
#include <Library/DebugLib.h>
#include <Library/HobLib.h>
#include <Library/PcdLib.h>
#include <Library/PlatformHookLib.h>
#include <libfdt.h>
/** Get the UART base address of the console serial-port from the DT.
This function fetches the node referenced in the "stdout-path"
property of the "chosen" node and returns the base address of
the console UART.
@param [in] Fdt Pointer to a Flattened Device Tree (Fdt).
@param [out] SerialConsoleAddress If success, contains the base address
of the console serial-port.
@retval EFI_SUCCESS The function completed successfully.
@retval EFI_NOT_FOUND Console serial-port info not found in DT.
@retval EFI_INVALID_PARAMETER Invalid parameter.
**/
STATIC
EFI_STATUS
EFIAPI
GetSerialConsolePortAddress (
IN CONST VOID *Fdt,
OUT UINT64 *SerialConsoleAddress
)
{
CONST CHAR8 *Prop;
INT32 PropSize;
CONST CHAR8 *Path;
INT32 PathLen;
INT32 ChosenNode;
INT32 SerialConsoleNode;
INT32 Len;
CONST CHAR8 *NodeStatus;
CONST UINT64 *RegProperty;
if ((Fdt == NULL) || (fdt_check_header (Fdt) != 0)) {
return EFI_INVALID_PARAMETER;
}
// The "chosen" node resides at the the root of the DT. Fetch it.
ChosenNode = fdt_path_offset (Fdt, "/chosen");
if (ChosenNode < 0) {
return EFI_NOT_FOUND;
}
Prop = fdt_getprop (Fdt, ChosenNode, "stdout-path", &PropSize);
if (PropSize < 0) {
return EFI_NOT_FOUND;
}
// Determine the actual path length, as a colon terminates the path.
Path = ScanMem8 (Prop, ':', PropSize);
if (Path == NULL) {
PathLen = AsciiStrLen (Prop);
} else {
PathLen = Path - Prop;
}
// Aliases cannot start with a '/', so it must be the actual path.
if (Prop[0] == '/') {
SerialConsoleNode = fdt_path_offset_namelen (Fdt, Prop, PathLen);
} else {
// Lookup the alias, as this contains the actual path.
Path = fdt_get_alias_namelen (Fdt, Prop, PathLen);
if (Path == NULL) {
return EFI_NOT_FOUND;
}
SerialConsoleNode = fdt_path_offset (Fdt, Path);
}
NodeStatus = fdt_getprop (Fdt, SerialConsoleNode, "status", &Len);
if ((NodeStatus != NULL) && (AsciiStrCmp (NodeStatus, "okay") != 0)) {
return EFI_NOT_FOUND;
}
RegProperty = fdt_getprop (Fdt, SerialConsoleNode, "reg", &Len);
if (Len != 16) {
return EFI_INVALID_PARAMETER;
}
*SerialConsoleAddress = fdt64_to_cpu (ReadUnaligned64 (RegProperty));
return EFI_SUCCESS;
}
/** Platform hook to retrieve the 16550 UART base address from the platform
Device tree and store it in PcdSerialRegisterBase.
@retval RETURN_SUCCESS Success.
@retval RETURN_INVALID_PARAMETER A parameter was invalid.
@retval RETURN_NOT_FOUND Serial port information not found.
**/
RETURN_STATUS
EFIAPI
PlatformHookSerialPortInitialize (
VOID
)
{
RETURN_STATUS Status;
VOID *DeviceTreeBase;
UINT64 SerialConsoleAddress;
if (PcdGet64 (PcdSerialRegisterBase) != 0) {
return RETURN_SUCCESS;
}
DeviceTreeBase = (VOID *)(UINTN)PcdGet64 (PcdDeviceTreeInitialBaseAddress);
if (DeviceTreeBase == NULL) {
return RETURN_NOT_FOUND;
}
Status = GetSerialConsolePortAddress (DeviceTreeBase, &SerialConsoleAddress);
if (RETURN_ERROR (Status)) {
return Status;
}
return (EFI_STATUS)PcdSet64S (PcdSerialRegisterBase, SerialConsoleAddress);
}

View File

@@ -1,36 +0,0 @@
## @file
# Early Platform Hook Library instance for 16550 Uart.
#
# Copyright (c) 2020, ARM Ltd. All rights reserved.<BR>
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
##
[Defines]
INF_VERSION = 0x0001001B
BASE_NAME = EarlyFdt16550SerialPortHookLib
MODULE_UNI_FILE = Fdt16550SerialPortHookLib.uni
FILE_GUID = FFB19961-79CC-4684-84A8-C31B0A2BBE82
MODULE_TYPE = BASE
VERSION_STRING = 1.0
LIBRARY_CLASS = PlatformHookLib|SEC PEI_CORE PEIM
[Sources]
EarlyFdt16550SerialPortHookLib.c
[LibraryClasses]
BaseLib
PcdLib
FdtLib
HobLib
[Packages]
ArmVirtPkg/ArmVirtPkg.dec
EmbeddedPkg/EmbeddedPkg.dec
MdeModulePkg/MdeModulePkg.dec
MdePkg/MdePkg.dec
[Pcd]
gArmVirtTokenSpaceGuid.PcdDeviceTreeInitialBaseAddress
gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterBase

View File

@@ -1,56 +0,0 @@
/** @file
Platform Hook Library instance for 16550 Uart.
Copyright (c) 2020, ARM Ltd. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include <Base.h>
#include <Uefi.h>
#include <Pi/PiBootMode.h>
#include <Pi/PiHob.h>
#include <Guid/Early16550UartBaseAddress.h>
#include <Guid/Fdt.h>
#include <Guid/FdtHob.h>
#include <Library/BaseLib.h>
#include <Library/HobLib.h>
#include <Library/PcdLib.h>
#include <Library/PlatformHookLib.h>
/** Platform hook to retrieve the 16550 UART base address from the GUID Hob
that caches the UART base address from early boot stage and store it in
PcdSerialRegisterBase.
@retval RETURN_SUCCESS Success.
@retval RETURN_NOT_FOUND Serial Port information not found.
**/
RETURN_STATUS
EFIAPI
PlatformHookSerialPortInitialize (
VOID
)
{
VOID *Hob;
UINT64 *UartBase;
if (PcdGet64 (PcdSerialRegisterBase) != 0) {
return RETURN_SUCCESS;
}
Hob = GetFirstGuidHob (&gEarly16550UartBaseAddressGuid);
if ((Hob == NULL) || (GET_GUID_HOB_DATA_SIZE (Hob) != sizeof (*UartBase))) {
return RETURN_NOT_FOUND;
}
UartBase = GET_GUID_HOB_DATA (Hob);
if ((UINTN)*UartBase == 0) {
return RETURN_NOT_FOUND;
}
return (RETURN_STATUS)PcdSet64S (PcdSerialRegisterBase, (UINTN)*UartBase);
}

View File

@@ -1,38 +0,0 @@
## @file
# Platform Hook Library instance for 16550 Uart.
#
# Copyright (c) 2020, ARM Ltd. All rights reserved.<BR>
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
##
[Defines]
INF_VERSION = 0x0001001B
BASE_NAME = Fdt16550SerialPortHookLib
MODULE_UNI_FILE = Fdt16550SerialPortHookLib.uni
FILE_GUID = C6DFD3F0-179D-4376-89A5-F641A2E7EFB5
MODULE_TYPE = BASE
VERSION_STRING = 1.0
LIBRARY_CLASS = PlatformHookLib|DXE_CORE DXE_DRIVER UEFI_DRIVER DXE_RUNTIME_DRIVER UEFI_APPLICATION
CONSTRUCTOR = PlatformHookSerialPortInitialize
[Sources]
Fdt16550SerialPortHookLib.c
[LibraryClasses]
BaseLib
PcdLib
HobLib
[Packages]
ArmVirtPkg/ArmVirtPkg.dec
EmbeddedPkg/EmbeddedPkg.dec
MdeModulePkg/MdeModulePkg.dec
MdePkg/MdePkg.dec
[Pcd]
gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterBase
[Guids]
gEarly16550UartBaseAddressGuid

View File

@@ -1,13 +0,0 @@
// /** @file
// Platform Hook Library instance for 16550 Uart.
//
//
// Copyright (c) 2020, ARM Ltd. All rights reserved.<BR>
//
// SPDX-License-Identifier: BSD-2-Clause-Patent
//
// **/
#string STR_MODULE_ABSTRACT #language en-US "Platform Hook Library instance for 16550 Uart."
#string STR_MODULE_DESCRIPTION #language en-US "Platform Hook Library instance for 16550 Uart."

View File

@@ -1,79 +0,0 @@
/** @file
Kvmtool platform PEI library.
Copyright (c) 2020, ARM Limited. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include <PiPei.h>
#include <Guid/Early16550UartBaseAddress.h>
#include <Guid/FdtHob.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/DebugLib.h>
#include <Library/HobLib.h>
#include <Library/PcdLib.h>
#include <Library/PeiServicesLib.h>
#include <libfdt.h>
/** Initialise Platform HOBs
@retval EFI_SUCCESS Success.
@retval EFI_INVALID_PARAMETER A parameter is invalid.
@retval EFI_OUT_OF_RESOURCES Out of resources.
**/
EFI_STATUS
EFIAPI
PlatformPeim (
VOID
)
{
VOID *Base;
VOID *NewBase;
UINTN FdtSize;
UINTN FdtPages;
UINT64 *FdtHobData;
UINT64 *UartHobData;
Base = (VOID*)(UINTN)PcdGet64 (PcdDeviceTreeInitialBaseAddress);
if ((Base == NULL) || (fdt_check_header (Base) != 0)) {
ASSERT (0);
return EFI_INVALID_PARAMETER;
}
FdtSize = fdt_totalsize (Base) + PcdGet32 (PcdDeviceTreeAllocationPadding);
FdtPages = EFI_SIZE_TO_PAGES (FdtSize);
NewBase = AllocatePages (FdtPages);
if (NewBase == NULL) {
ASSERT (0);
return EFI_OUT_OF_RESOURCES;
}
fdt_open_into (Base, NewBase, EFI_PAGES_TO_SIZE (FdtPages));
FdtHobData = BuildGuidHob (&gFdtHobGuid, sizeof (*FdtHobData));
if (FdtHobData == NULL) {
ASSERT (0);
return EFI_OUT_OF_RESOURCES;
}
*FdtHobData = (UINTN)NewBase;
UartHobData = BuildGuidHob (
&gEarly16550UartBaseAddressGuid,
sizeof (*UartHobData)
);
if (UartHobData == NULL) {
ASSERT (0);
return EFI_OUT_OF_RESOURCES;
}
*UartHobData = PcdGet64 (PcdSerialRegisterBase);
BuildFvHob (PcdGet64 (PcdFvBaseAddress), PcdGet32 (PcdFvSize));
return EFI_SUCCESS;
}

View File

@@ -1,49 +0,0 @@
## @file
# Kvmtool platform PEI library.
#
# Copyright (c) 2020, ARM Limited. All rights reserved.
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
##
[Defines]
INF_VERSION = 0x0001001B
BASE_NAME = PlatformPeiLib
FILE_GUID = 21073FB3-BA6F-43EB-83F0-4A840C648165
MODULE_TYPE = BASE
VERSION_STRING = 1.0
LIBRARY_CLASS = KvmtoolPlatformPeiLib
[Sources]
KvmtoolPlatformPeiLib.c
[Packages]
ArmPkg/ArmPkg.dec
ArmVirtPkg/ArmVirtPkg.dec
EmbeddedPkg/EmbeddedPkg.dec
MdeModulePkg/MdeModulePkg.dec
MdePkg/MdePkg.dec
[LibraryClasses]
DebugLib
HobLib
FdtLib
PcdLib
PeiServicesLib
[FixedPcd]
gArmTokenSpaceGuid.PcdFvSize
gArmVirtTokenSpaceGuid.PcdDeviceTreeAllocationPadding
[Pcd]
gArmTokenSpaceGuid.PcdFvBaseAddress
gArmVirtTokenSpaceGuid.PcdDeviceTreeInitialBaseAddress
gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterBase
[Guids]
gFdtHobGuid
gEarly16550UartBaseAddressGuid
[Depex]
gEfiPeiMemoryDiscoveredPpiGuid

View File

@@ -1,230 +0,0 @@
/** @file
FDT client library for motorola,mc146818 RTC driver
Copyright (c) 2020, ARM Limited. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include <Library/BaseLib.h>
#include <Library/DebugLib.h>
#include <Library/DxeServicesTableLib.h>
#include <Library/PcdLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Protocol/FdtClient.h>
/** RTC Index register is at offset 0x0
*/
#define RTC_INDEX_REG_OFFSET 0x0ULL
/** RTC Target register is at offset 0x1
*/
#define RTC_TARGET_REG_OFFSET 0x1ULL
/** Add the RTC controller address range to the memory map.
@param [in] ImageHandle The handle to the image.
@param [in] RtcPageBase Base address of the RTC controller.
@retval EFI_SUCCESS Success.
@retval EFI_INVALID_PARAMETER A parameter is invalid.
@retval EFI_NOT_FOUND Flash device not found.
**/
STATIC
EFI_STATUS
KvmtoolRtcMapMemory (
IN EFI_HANDLE ImageHandle,
IN EFI_PHYSICAL_ADDRESS RtcPageBase
)
{
EFI_STATUS Status;
Status = gDS->AddMemorySpace (
EfiGcdMemoryTypeMemoryMappedIo,
RtcPageBase,
EFI_PAGE_SIZE,
EFI_MEMORY_UC | EFI_MEMORY_RUNTIME
);
if (EFI_ERROR (Status)) {
DEBUG ((
DEBUG_ERROR, "Failed to add memory space. Status = %r\n",
Status
));
return Status;
}
Status = gDS->AllocateMemorySpace (
EfiGcdAllocateAddress,
EfiGcdMemoryTypeMemoryMappedIo,
0,
EFI_PAGE_SIZE,
&RtcPageBase,
ImageHandle,
NULL
);
if (EFI_ERROR (Status)) {
DEBUG ((
DEBUG_ERROR,
"Failed to allocate memory space. Status = %r\n",
Status
));
gDS->RemoveMemorySpace (
RtcPageBase,
EFI_PAGE_SIZE
);
return Status;
}
Status = gDS->SetMemorySpaceAttributes (
RtcPageBase,
EFI_PAGE_SIZE,
EFI_MEMORY_UC | EFI_MEMORY_RUNTIME
);
if (EFI_ERROR (Status)) {
DEBUG ((
DEBUG_ERROR,
"Failed to set memory attributes. Status = %r\n",
Status
));
gDS->FreeMemorySpace (
RtcPageBase,
EFI_PAGE_SIZE
);
gDS->RemoveMemorySpace (
RtcPageBase,
EFI_PAGE_SIZE
);
}
return Status;
}
/** Entrypoint for KvmtoolRtcFdtClientLib.
Locate the RTC node in the DT and update the Index and
Target register base addresses in the respective PCDs.
Add the RTC memory region to the memory map.
Disable the RTC node as the RTC is owned by UEFI.
@param [in] ImageHandle The handle to the image.
@param [in] SystemTable Pointer to the System Table.
@retval EFI_SUCCESS Success.
@retval EFI_INVALID_PARAMETER A parameter is invalid.
@retval EFI_NOT_FOUND Flash device not found.
**/
EFI_STATUS
EFIAPI
KvmtoolRtcFdtClientLibConstructor (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EFI_STATUS Status;
FDT_CLIENT_PROTOCOL *FdtClient;
INT32 Node;
CONST UINT32 *Reg;
UINT32 RegSize;
UINT64 RegBase;
UINT64 Range;
RETURN_STATUS PcdStatus;
Status = gBS->LocateProtocol (
&gFdtClientProtocolGuid,
NULL,
(VOID **)&FdtClient
);
ASSERT_EFI_ERROR (Status);
Status = FdtClient->FindCompatibleNode (
FdtClient,
"motorola,mc146818",
&Node
);
if (EFI_ERROR (Status)) {
DEBUG ((
DEBUG_ERROR,
"%a: No 'motorola,mc146818' compatible DT node found\n",
__FUNCTION__
));
return Status;
}
Status = FdtClient->GetNodeProperty (
FdtClient,
Node,
"reg",
(CONST VOID **)&Reg,
&RegSize
);
if (EFI_ERROR (Status)) {
DEBUG ((
DEBUG_ERROR,
"%a: No 'reg' property found in 'motorola,mc146818' compatible DT node\n",
__FUNCTION__
));
return Status;
}
ASSERT (RegSize == 16);
RegBase = SwapBytes64 (ReadUnaligned64 ((VOID *)&Reg[0]));
Range = SwapBytes64 (ReadUnaligned64 ((VOID *)&Reg[2]));
DEBUG ((
DEBUG_INFO,
"Found motorola,mc146818 RTC @ 0x%Lx Range = 0x%x\n",
RegBase,
Range
));
// The address range must cover the RTC Index and the Target registers.
ASSERT (Range >= 0x2);
// RTC Index register is at offset 0x0
PcdStatus = PcdSet64S (
PcdRtcIndexRegister64,
(RegBase + RTC_INDEX_REG_OFFSET)
);
ASSERT_RETURN_ERROR (PcdStatus);
// RTC Target register is at offset 0x1
PcdStatus = PcdSet64S (
PcdRtcTargetRegister64,
(RegBase + RTC_TARGET_REG_OFFSET)
);
ASSERT_RETURN_ERROR (PcdStatus);
Status = KvmtoolRtcMapMemory (ImageHandle, (RegBase & ~EFI_PAGE_MASK));
if (EFI_ERROR (Status)) {
DEBUG ((
DEBUG_ERROR,
"Failed to map memory for motorola,mc146818. Status = %r\n",
Status
));
return Status;
}
//
// UEFI takes ownership of the RTC hardware, and exposes its functionality
// through the UEFI Runtime Services GetTime, SetTime, etc. This means we
// need to disable it in the device tree to prevent the OS from attaching
// its device driver as well.
//
Status = FdtClient->SetNodeProperty (
FdtClient,
Node,
"status",
"disabled",
sizeof ("disabled")
);
if (EFI_ERROR (Status)) {
DEBUG ((
DEBUG_WARN,
"Failed to set motorola,mc146818 status to 'disabled', Status = %r\n",
Status
));
}
return EFI_SUCCESS;
}

View File

@@ -1,42 +0,0 @@
## @file
# FDT client library for motorola,mc146818 RTC driver
#
# Copyright (c) 2020, ARM Limited. All rights reserved.<BR>
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
##
[Defines]
INF_VERSION = 0x0001001B
BASE_NAME = KvmtoolRtcFdtClientLib
FILE_GUID = 3254B4F7-30B5-48C6-B06A-D8FF97F3EF95
MODULE_TYPE = DXE_DRIVER
VERSION_STRING = 1.0
LIBRARY_CLASS = KvmtoolRtcFdtClientLib|DXE_DRIVER DXE_RUNTIME_DRIVER
CONSTRUCTOR = KvmtoolRtcFdtClientLibConstructor
[Sources]
KvmtoolRtcFdtClientLib.c
[Packages]
ArmVirtPkg/ArmVirtPkg.dec
MdePkg/MdePkg.dec
PcAtChipsetPkg/PcAtChipsetPkg.dec
[LibraryClasses]
BaseLib
DebugLib
PcdLib
UefiBootServicesTableLib
DxeServicesTableLib
[Protocols]
gFdtClientProtocolGuid ## CONSUMES
[Pcd]
gPcAtChipsetPkgTokenSpaceGuid.PcdRtcIndexRegister64
gPcAtChipsetPkgTokenSpaceGuid.PcdRtcTargetRegister64
[Depex]
gFdtClientProtocolGuid

View File

@@ -1,98 +0,0 @@
/** @file
Kvmtool virtual memory map library.
Copyright (c) 2018 - 2020, ARM Limited. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include <Base.h>
#include <Library/ArmLib.h>
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/MemoryAllocationLib.h>
// Number of Virtual Memory Map Descriptors
#define MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS 5
/**
Return the Virtual Memory Map of your platform
This Virtual Memory Map is used by MemoryInitPei Module to initialize the MMU
on your platform.
@param[out] VirtualMemoryMap Array of ARM_MEMORY_REGION_DESCRIPTOR
describing a Physical-to-Virtual Memory
mapping. This array must be ended by a
zero-filled entry. The allocated memory
will not be freed.
**/
VOID
ArmVirtGetMemoryMap (
OUT ARM_MEMORY_REGION_DESCRIPTOR **VirtualMemoryMap
)
{
ARM_MEMORY_REGION_DESCRIPTOR *VirtualMemoryTable;
UINTN Idx;
EFI_PHYSICAL_ADDRESS TopOfAddressSpace;
ASSERT (VirtualMemoryMap != NULL);
TopOfAddressSpace = LShiftU64 (1ULL, ArmGetPhysicalAddressBits ());
VirtualMemoryTable = (ARM_MEMORY_REGION_DESCRIPTOR*)
AllocatePages (
EFI_SIZE_TO_PAGES (
sizeof (ARM_MEMORY_REGION_DESCRIPTOR) *
MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS
)
);
if (VirtualMemoryTable == NULL) {
DEBUG ((
DEBUG_ERROR,
"%a: Error: Failed to Allocate Pages\n",
__FUNCTION__
));
return;
}
Idx = 0;
// System DRAM
VirtualMemoryTable[Idx].PhysicalBase = PcdGet64 (PcdSystemMemoryBase);
VirtualMemoryTable[Idx].VirtualBase = VirtualMemoryTable[Idx].PhysicalBase;
VirtualMemoryTable[Idx].Length = PcdGet64 (PcdSystemMemorySize);
VirtualMemoryTable[Idx].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK;
// Peripheral space before DRAM
VirtualMemoryTable[++Idx].PhysicalBase = 0x0;
VirtualMemoryTable[Idx].VirtualBase = 0x0;
VirtualMemoryTable[Idx].Length = PcdGet64 (PcdSystemMemoryBase);
VirtualMemoryTable[Idx].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
// Peripheral space after DRAM
VirtualMemoryTable[++Idx].PhysicalBase = PcdGet64 (PcdSystemMemoryBase) +
PcdGet64 (PcdSystemMemorySize);
VirtualMemoryTable[Idx].VirtualBase = VirtualMemoryTable[Idx].PhysicalBase;
VirtualMemoryTable[Idx].Length = TopOfAddressSpace -
VirtualMemoryTable[Idx].PhysicalBase;
VirtualMemoryTable[Idx].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
// Map the FV region as normal executable memory
VirtualMemoryTable[++Idx].PhysicalBase = PcdGet64 (PcdFvBaseAddress);
VirtualMemoryTable[Idx].VirtualBase = VirtualMemoryTable[Idx].PhysicalBase;
VirtualMemoryTable[Idx].Length = FixedPcdGet32 (PcdFvSize);
VirtualMemoryTable[Idx].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK;
// End of Table
VirtualMemoryTable[++Idx].PhysicalBase = 0;
VirtualMemoryTable[Idx].VirtualBase = 0;
VirtualMemoryTable[Idx].Length = 0;
VirtualMemoryTable[Idx].Attributes = (ARM_MEMORY_REGION_ATTRIBUTES)0;
ASSERT((Idx + 1) <= MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS);
*VirtualMemoryMap = VirtualMemoryTable;
}

View File

@@ -1,42 +0,0 @@
## @file
# Kvmtool virtual memory map library.
#
# Copyright (c) 2018, ARM Limited. All rights reserved.
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
##
[Defines]
INF_VERSION = 0x0001001B
BASE_NAME = KvmtoolVirtMemInfoLib
FILE_GUID = B752E953-394F-462C-811C-F8BE35C8C071
MODULE_TYPE = BASE
VERSION_STRING = 1.0
LIBRARY_CLASS = ArmVirtMemInfoLib
[Sources]
KvmtoolVirtMemInfoLib.c
[Packages]
ArmPkg/ArmPkg.dec
ArmVirtPkg/ArmVirtPkg.dec
EmbeddedPkg/EmbeddedPkg.dec
MdeModulePkg/MdeModulePkg.dec
MdePkg/MdePkg.dec
[LibraryClasses]
ArmLib
BaseLib
BaseMemoryLib
DebugLib
MemoryAllocationLib
PcdLib
[Pcd]
gArmTokenSpaceGuid.PcdFvBaseAddress
gArmTokenSpaceGuid.PcdSystemMemoryBase
gArmTokenSpaceGuid.PcdSystemMemorySize
[FixedPcd]
gArmTokenSpaceGuid.PcdFvSize

View File

@@ -1,335 +0,0 @@
/** @file
An instance of the NorFlashPlatformLib for Kvmtool platform.
Copyright (c) 2020, ARM Ltd. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include <Library/BaseLib.h>
#include <Library/DebugLib.h>
#include <Library/NorFlashPlatformLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Protocol/FdtClient.h>
/** Macro defining the NOR block size configured in Kvmtool.
*/
#define KVMTOOL_NOR_BLOCK_SIZE SIZE_64KB
/** Macro defining the maximum number of Flash devices.
*/
#define MAX_FLASH_DEVICES 4
/** Macro defining the cfi-flash label describing the UEFI variable store.
*/
#define LABEL_UEFI_VAR_STORE "System-firmware"
STATIC NOR_FLASH_DESCRIPTION mNorFlashDevices[MAX_FLASH_DEVICES];
STATIC UINTN mNorFlashDeviceCount = 0;
STATIC INT32 mUefiVarStoreNode = MAX_INT32;
STATIC FDT_CLIENT_PROTOCOL *mFdtClient;
/** This function performs platform specific actions to initialise
the NOR flash, if required.
@retval EFI_SUCCESS Success.
**/
EFI_STATUS
NorFlashPlatformInitialization (
VOID
)
{
EFI_STATUS Status;
DEBUG ((DEBUG_INFO, "NorFlashPlatformInitialization\n"));
if ((mNorFlashDeviceCount > 0) && (mUefiVarStoreNode != MAX_INT32)) {
//
// UEFI takes ownership of the cfi-flash hardware, and exposes its
// functionality through the UEFI Runtime Variable Service. This means we
// need to disable it in the device tree to prevent the OS from attaching
// its device driver as well.
// Note: This library is loaded twice. First by FaultTolerantWriteDxe to
// setup the PcdFlashNvStorageFtw* and later by NorFlashDxe to provide the
// NorFlashPlatformLib interfaces. If the node is disabled when the library
// is first loaded, then during the subsequent loading of the library the
// call to FindNextCompatibleNode() from the library constructor skips the
// FDT node used for UEFI storage variable. Due to this we cannot setup the
// NOR flash device description i.e. mNorFlashDevices[].
// Since NorFlashPlatformInitialization() is called only by NorFlashDxe,
// we know it is safe to disable the node here.
//
Status = mFdtClient->SetNodeProperty (
mFdtClient,
mUefiVarStoreNode,
"status",
"disabled",
sizeof ("disabled")
);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_WARN, "Failed to set cfi-flash status to 'disabled'\n"));
}
} else {
Status = EFI_NOT_FOUND;
DEBUG ((DEBUG_ERROR, "Flash device for UEFI variable storage not found\n"));
}
return Status;
}
/** Initialise Non volatile Flash storage variables.
@param [in] FlashDevice Pointer to the NOR Flash device.
@retval EFI_SUCCESS Success.
@retval EFI_INVALID_PARAMETER A parameter is invalid.
@retval EFI_OUT_OF_RESOURCES Insufficient flash storage space.
**/
STATIC
EFI_STATUS
SetupVariableStore (
IN NOR_FLASH_DESCRIPTION * FlashDevice
)
{
UINTN FlashRegion;
UINTN FlashNvStorageVariableBase;
UINTN FlashNvStorageFtwWorkingBase;
UINTN FlashNvStorageFtwSpareBase;
UINTN FlashNvStorageVariableSize;
UINTN FlashNvStorageFtwWorkingSize;
UINTN FlashNvStorageFtwSpareSize;
FlashNvStorageVariableSize = PcdGet32 (PcdFlashNvStorageVariableSize);
FlashNvStorageFtwWorkingSize = PcdGet32 (PcdFlashNvStorageFtwWorkingSize);
FlashNvStorageFtwSpareSize = PcdGet32 (PcdFlashNvStorageFtwSpareSize);
if ((FlashNvStorageVariableSize == 0) ||
(FlashNvStorageFtwWorkingSize == 0) ||
(FlashNvStorageFtwSpareSize == 0)) {
DEBUG ((DEBUG_ERROR, "FlashNvStorage size not defined\n"));
return EFI_INVALID_PARAMETER;
}
// Setup the variable store
FlashRegion = FlashDevice->DeviceBaseAddress;
FlashNvStorageVariableBase = FlashRegion;
FlashRegion += PcdGet32 (PcdFlashNvStorageVariableSize);
FlashNvStorageFtwWorkingBase = FlashRegion;
FlashRegion += PcdGet32 (PcdFlashNvStorageFtwWorkingSize);
FlashNvStorageFtwSpareBase = FlashRegion;
FlashRegion += PcdGet32 (PcdFlashNvStorageFtwSpareSize);
if (FlashRegion > (FlashDevice->DeviceBaseAddress + FlashDevice->Size)) {
DEBUG ((DEBUG_ERROR, "Insufficient flash storage size\n"));
return EFI_OUT_OF_RESOURCES;
}
PcdSet32S (
PcdFlashNvStorageVariableBase,
FlashNvStorageVariableBase
);
PcdSet32S (
PcdFlashNvStorageFtwWorkingBase,
FlashNvStorageFtwWorkingBase
);
PcdSet32S (
PcdFlashNvStorageFtwSpareBase,
FlashNvStorageFtwSpareBase
);
DEBUG ((
DEBUG_INFO,
"PcdFlashNvStorageVariableBase = 0x%x\n",
FlashNvStorageVariableBase
));
DEBUG ((
DEBUG_INFO,
"PcdFlashNvStorageVariableSize = 0x%x\n",
FlashNvStorageVariableSize
));
DEBUG ((
DEBUG_INFO,
"PcdFlashNvStorageFtwWorkingBase = 0x%x\n",
FlashNvStorageFtwWorkingBase
));
DEBUG ((
DEBUG_INFO,
"PcdFlashNvStorageFtwWorkingSize = 0x%x\n",
FlashNvStorageFtwWorkingSize
));
DEBUG ((
DEBUG_INFO,
"PcdFlashNvStorageFtwSpareBase = 0x%x\n",
FlashNvStorageFtwSpareBase
));
DEBUG ((
DEBUG_INFO,
"PcdFlashNvStorageFtwSpareSize = 0x%x\n",
FlashNvStorageFtwSpareSize
));
return EFI_SUCCESS;
}
/** Return the Flash devices on the platform.
@param [out] NorFlashDescriptions Pointer to the Flash device description.
@param [out] Count Number of Flash devices.
@retval EFI_SUCCESS Success.
@retval EFI_NOT_FOUND Flash device not found.
**/
EFI_STATUS
NorFlashPlatformGetDevices (
OUT NOR_FLASH_DESCRIPTION **NorFlashDescriptions,
OUT UINT32 *Count
)
{
if (mNorFlashDeviceCount > 0) {
*NorFlashDescriptions = mNorFlashDevices;
*Count = mNorFlashDeviceCount;
return EFI_SUCCESS;
}
return EFI_NOT_FOUND;
}
/** Entrypoint for NorFlashPlatformLib.
@param [in] ImageHandle The handle to the image.
@param [in] SystemTable Pointer to the System Table.
@retval EFI_SUCCESS Success.
@retval EFI_INVALID_PARAMETER A parameter is invalid.
@retval EFI_NOT_FOUND Flash device not found.
**/
EFI_STATUS
EFIAPI
NorFlashPlatformLibConstructor (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE * SystemTable
)
{
INT32 Node;
EFI_STATUS Status;
EFI_STATUS FindNodeStatus;
CONST UINT32 *Reg;
UINT32 PropSize;
UINT64 Base;
UINT64 Size;
UINTN UefiVarStoreIndex;
CONST CHAR8 *Label;
UINT32 LabelLen;
if (mNorFlashDeviceCount != 0) {
return EFI_SUCCESS;
}
Status = gBS->LocateProtocol (
&gFdtClientProtocolGuid,
NULL,
(VOID **)&mFdtClient
);
ASSERT_EFI_ERROR (Status);
UefiVarStoreIndex = MAX_UINTN;
for (FindNodeStatus = mFdtClient->FindCompatibleNode (
mFdtClient,
"cfi-flash",
&Node
);
!EFI_ERROR (FindNodeStatus) &&
(mNorFlashDeviceCount < MAX_FLASH_DEVICES);
FindNodeStatus = mFdtClient->FindNextCompatibleNode (
mFdtClient,
"cfi-flash",
Node,
&Node
)) {
Status = mFdtClient->GetNodeProperty (
mFdtClient,
Node,
"label",
(CONST VOID **)&Label,
&LabelLen
);
if (EFI_ERROR (Status)) {
DEBUG ((
DEBUG_ERROR,
"%a: GetNodeProperty ('label') failed (Status == %r)\n",
__FUNCTION__,
Status
));
} else if (AsciiStrCmp (Label, LABEL_UEFI_VAR_STORE) == 0) {
UefiVarStoreIndex = mNorFlashDeviceCount;
mUefiVarStoreNode = Node;
}
Status = mFdtClient->GetNodeProperty (
mFdtClient,
Node,
"reg",
(CONST VOID **)&Reg,
&PropSize
);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "%a: GetNodeProperty () failed (Status == %r)\n",
__FUNCTION__, Status));
continue;
}
ASSERT ((PropSize % (4 * sizeof (UINT32))) == 0);
while ((PropSize >= (4 * sizeof (UINT32))) &&
(mNorFlashDeviceCount < MAX_FLASH_DEVICES)) {
Base = SwapBytes64 (ReadUnaligned64 ((VOID *)&Reg[0]));
Size = SwapBytes64 (ReadUnaligned64 ((VOID *)&Reg[2]));
Reg += 4;
PropSize -= 4 * sizeof (UINT32);
//
// Disregard any flash devices that overlap with the primary FV.
// The firmware is not updatable from inside the guest anyway.
//
if ((PcdGet64 (PcdFvBaseAddress) + PcdGet32 (PcdFvSize) > Base) &&
(Base + Size) > PcdGet64 (PcdFvBaseAddress)) {
continue;
}
DEBUG ((
DEBUG_INFO,
"NOR%d : Base = 0x%lx, Size = 0x%lx\n",
mNorFlashDeviceCount,
Base,
Size
));
mNorFlashDevices[mNorFlashDeviceCount].DeviceBaseAddress = (UINTN)Base;
mNorFlashDevices[mNorFlashDeviceCount].RegionBaseAddress = (UINTN)Base;
mNorFlashDevices[mNorFlashDeviceCount].Size = (UINTN)Size;
mNorFlashDevices[mNorFlashDeviceCount].BlockSize = KVMTOOL_NOR_BLOCK_SIZE;
mNorFlashDeviceCount++;
}
} // for
// Setup the variable store in the last device
if (mNorFlashDeviceCount > 0) {
if (UefiVarStoreIndex == MAX_UINTN) {
// We did not find a label matching the UEFI Variable store. Default to
// using the last cfi-flash device as the variable store.
UefiVarStoreIndex = mNorFlashDeviceCount - 1;
mUefiVarStoreNode = Node;
}
if (mNorFlashDevices[UefiVarStoreIndex].DeviceBaseAddress != 0) {
return SetupVariableStore (&mNorFlashDevices[UefiVarStoreIndex]);
}
}
return EFI_NOT_FOUND;
}

View File

@@ -1,49 +0,0 @@
## @file
# Nor Flash library for Kvmtool.
#
# Copyright (c) 2020, ARM Ltd. All rights reserved.<BR>
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
##
[Defines]
INF_VERSION = 0x0001001B
BASE_NAME = NorFlashKvmtoolLib
FILE_GUID = E75F07A1-B160-4893-BDD4-09E32FF847DC
MODULE_TYPE = DXE_DRIVER
VERSION_STRING = 1.0
LIBRARY_CLASS = NorFlashPlatformLib
CONSTRUCTOR = NorFlashPlatformLibConstructor
[Sources.common]
NorFlashKvmtool.c
[Packages]
ArmPkg/ArmPkg.dec
ArmPlatformPkg/ArmPlatformPkg.dec
ArmVirtPkg/ArmVirtPkg.dec
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
[LibraryClasses]
BaseLib
DebugLib
PcdLib
UefiBootServicesTableLib
[Protocols]
gFdtClientProtocolGuid ## CONSUMES
[Pcd]
gArmTokenSpaceGuid.PcdFvBaseAddress
gArmTokenSpaceGuid.PcdFvSize
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize
[Depex]
gFdtClientProtocolGuid

View File

@@ -86,22 +86,6 @@ NorFlashPlatformGetDevices (
mNorFlashDevices[Num].BlockSize = QEMU_NOR_BLOCK_SIZE;
Num++;
}
//
// UEFI takes ownership of the NOR flash, and exposes its functionality
// through the UEFI Runtime Services GetVariable, SetVariable, etc. This
// means we need to disable it in the device tree to prevent the OS from
// attaching its device driver as well.
// Note that this also hides other flash banks, but the only other flash
// bank we expect to encounter is the one that carries the UEFI executable
// code, which is not intended to be guest updatable, and is usually backed
// in a readonly manner by QEMU anyway.
//
Status = FdtClient->SetNodeProperty (FdtClient, Node, "status",
"disabled", sizeof ("disabled"));
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_WARN, "Failed to set NOR flash status to 'disabled'\n"));
}
}
*NorFlashDescriptions = mNorFlashDevices;

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