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
2118 changed files with 184993 additions and 167356 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,20 +2,17 @@
# 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:
- master
- stable/*
pr:
- master
- stable/*
jobs:
- template: templates/pr-gate-build-job.yml
parameters:
tool_chain_tag: 'GCC5'
vm_image: 'ubuntu-latest'
arch_list: "IA32,X64,ARM,AARCH64,RISCV64"
arch_list: "IA32,X64,ARM,AARCH64"

View File

@@ -5,7 +5,7 @@
# NOTE: This example monitors pull requests against the edk2-ci branch. Most
# environments would replace 'edk2-ci' with 'master'.
#
# Copyright (c) 2019 - 2020, Intel Corporation. All rights reserved.<BR>
# Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
# https://github.com/tianocore
@@ -16,7 +16,6 @@ trigger: none
pr:
- master
- stable/*
pool:
vmImage: 'ubuntu-latest'

View File

@@ -6,11 +6,9 @@
##
trigger:
- master
- stable/*
pr:
- master
- stable/*
jobs:
- template: templates/pr-gate-build-job.yml

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,143 +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 }}"
# Use altername cmocka repo
- bash: git config --global url.https://github.com/neverware-mirrors/cmocka.git.insteadOf https://git.cryptomilk.org/projects/cmocka.git
# 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 - 2021, 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,StandaloneMmPkg'
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,15 +31,6 @@ steps:
echo "##vso[task.setvariable variable=pkgs_to_build]${{ parameters.build_pkgs }}"
echo "##vso[task.setvariable variable=pkg_count]${{ 1 }}"
# Use altername cmocka repo
- bash: git config --global url.https://github.com/neverware-mirrors/cmocka.git.insteadOf https://git.cryptomilk.org/projects/cmocka.git
# 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
@@ -48,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
@@ -66,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:

13
.gitmodules vendored
View File

@@ -7,16 +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
[submodule "RedfishPkg/Library/JsonLib/jansson"]
path = RedfishPkg/Library/JsonLib/jansson
url = https://github.com/akheron/jansson

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

@@ -16,7 +16,7 @@
# * This file must be checked into the 'default' branch of a repo. Copies
# of this file on other branches of a repo are ignored by Mergify.
#
# Copyright (c) 2019 - 2020, Intel Corporation. All rights reserved.<BR>
# Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
# https://github.com/apps/mergify
@@ -28,7 +28,7 @@ pull_request_rules:
- name: Automatically merge a PR when all required checks pass and 'push' label is present
conditions:
- base~=(^master|^stable/)
- base=master
- label=push
- author=@tianocore/edk-ii-maintainers
- status-success=tianocore.PatchCheck
@@ -41,7 +41,7 @@ pull_request_rules:
- name: Automatically close a PR when all required checks pass and 'push' label is not present
conditions:
- base~=(^master|^stable/)
- base=master
- -label=push
- -closed
- status-success=tianocore.PatchCheck
@@ -55,7 +55,7 @@ pull_request_rules:
- name: Post a comment on a PR that can not be merged due to a merge conflict
conditions:
- base~=(^master|^stable/)
- base=master
- conflict
actions:
comment:
@@ -63,7 +63,7 @@ pull_request_rules:
- name: Automatically close a PR that fails the EDK II Maintainers membership check and 'push' label is present
conditions:
- base~=(^master|^stable/)
- base=master
- label=push
- -author=@tianocore/edk-ii-maintainers
actions:
@@ -72,7 +72,7 @@ pull_request_rules:
- name: Post a comment on a PR if PatchCheck fails
conditions:
- base~=(^master|^stable/)
- base=master
- status-failure=tianocore.PatchCheck
actions:
comment:
@@ -80,7 +80,7 @@ pull_request_rules:
- name: Post a comment on a PR if Ubuntu GCC5 fails
conditions:
- base~=(^master|^stable/)
- base=master
- status-failure=Ubuntu GCC5 PR
- status-success=Ubuntu GCC5 PR (FAILED)
actions:
@@ -89,7 +89,7 @@ pull_request_rules:
- name: Post a comment on a PR if Windows VS2019 fails
conditions:
- base~=(^master|^stable/)
- base=master
- status-failure=Windows VS2019 PR
- status-success=Windows VS2019 PR (FAILED)
actions:

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 - 2021, ARM Limited. All rights reserved.<BR>
# SPDX-License-Identifier: BSD-2-Clause-Patent
##
import os
@@ -22,24 +20,16 @@ class Settings(CiBuildSettingsManager, UpdateSettingsManager, SetupSettingsManag
self.ActualTargets = []
self.ActualArchitectures = []
self.ActualToolChainTag = ""
self.UseBuiltInBaseTools = None
self.ActualScopes = None
# ####################################################################################### #
# Extra CmdLine configuration #
# ####################################################################################### #
def AddCommandLineOptions(self, parserObj):
group = parserObj.add_mutually_exclusive_group()
group.add_argument("-force_piptools", "--fpt", dest="force_piptools", action="store_true", default=False, help="Force the system to use pip tools")
group.add_argument("-no_piptools", "--npt", dest="no_piptools", action="store_true", default=False, help="Force the system to not use pip tools")
pass
def RetrieveCommandLineOptions(self, args):
super().RetrieveCommandLineOptions(args)
if args.force_piptools:
self.UseBuiltInBaseTools = True
if args.no_piptools:
self.UseBuiltInBaseTools = False
pass
# ####################################################################################### #
# Default Support for this Ci Build #
@@ -49,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",
@@ -60,22 +47,17 @@ class Settings(CiBuildSettingsManager, UpdateSettingsManager, SetupSettingsManag
"UefiCpuPkg",
"FmpDevicePkg",
"ShellPkg",
"StandaloneMmPkg",
"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 '''
@@ -136,38 +118,20 @@ class Settings(CiBuildSettingsManager, UpdateSettingsManager, SetupSettingsManag
def GetActiveScopes(self):
''' return tuple containing scopes that should be active for this process '''
if self.ActualScopes is None:
scopes = ("cibuild", "edk2-build", "host-based-test")
scopes = ("cibuild", "edk2-build", "host-based-test")
self.ActualToolChainTag = shell_environment.GetBuildVars().GetValue("TOOL_CHAIN_TAG", "")
self.ActualToolChainTag = shell_environment.GetBuildVars().GetValue("TOOL_CHAIN_TAG", "")
is_linux = GetHostInfo().os.upper() == "LINUX"
if GetHostInfo().os.upper() == "WINDOWS":
scopes += ('host-test-win',)
if self.UseBuiltInBaseTools is None:
is_linux = GetHostInfo().os.upper() == "LINUX"
# try and import the pip module for basetools
try:
import edk2basetools
self.UseBuiltInBaseTools = True
except ImportError:
self.UseBuiltInBaseTools = False
pass
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 self.UseBuiltInBaseTools == True:
scopes += ('pipbuild-unix',) if is_linux else ('pipbuild-win',)
logging.warning("Using Pip Tools based BaseTools")
else:
logging.warning("Falling back to using in-tree BaseTools")
if is_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",)
self.ActualScopes = scopes
return self.ActualScopes
return scopes
def GetRequiredSubmodules(self):
''' return iterable containing RequiredSubmodule objects.
@@ -180,14 +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))
rs.append(RequiredSubmodule(
"RedfishPkg/Library/JsonLib/jansson", 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 | :heavy_check_mark: | :heavy_check_mark: |
| 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

@@ -84,13 +84,6 @@
# hardware coherency (i.e., no virtualization or cache coherent DMA)
gArmTokenSpaceGuid.PcdNormalMemoryNonshareableOverride|FALSE|BOOLEAN|0x00000043
[PcdsFeatureFlag.AARCH64]
## Used to select method for requesting services from S-EL1.<BR><BR>
# TRUE - Selects FF-A calls for communication between S-EL0 and SPMC.<BR>
# FALSE - Selects SVC calls for communication between S-EL0 and SPMC.<BR>
# @Prompt Enable FF-A support.
gArmTokenSpaceGuid.PcdFfaEnable|FALSE|BOOLEAN|0x0000005B
[PcdsFixedAtBuild.common]
gArmTokenSpaceGuid.PcdTrustzoneSupport|FALSE|BOOLEAN|0x00000006
@@ -122,20 +115,6 @@
# The Primary Core is ClusterId[0] & CoreId[0]
gArmTokenSpaceGuid.PcdArmPrimaryCore|0|UINT32|0x00000037
#
# SMBIOS PCDs
#
gArmTokenSpaceGuid.PcdSystemProductName|L""|VOID*|0x30000053
gArmTokenSpaceGuid.PcdSystemVersion|L""|VOID*|0x30000054
gArmTokenSpaceGuid.PcdBaseBoardManufacturer|L""|VOID*|0x30000055
gArmTokenSpaceGuid.PcdBaseBoardProductName|L""|VOID*|0x30000056
gArmTokenSpaceGuid.PcdBaseBoardVersion|L""|VOID*|0x30000057
gArmTokenSpaceGuid.PcdProcessorManufacturer|L""|VOID*|0x30000071
gArmTokenSpaceGuid.PcdProcessorVersion|L""|VOID*|0x30000072
gArmTokenSpaceGuid.PcdProcessorSerialNumber|L""|VOID*|0x30000073
gArmTokenSpaceGuid.PcdProcessorAssetTag|L""|VOID*|0x30000074
gArmTokenSpaceGuid.PcdProcessorPartNumber|L""|VOID*|0x30000075
#
# ARM L2x0 PCDs
#
@@ -236,9 +215,6 @@
gArmTokenSpaceGuid.PcdMmBufferBase|0|UINT64|0x00000045
gArmTokenSpaceGuid.PcdMmBufferSize|0|UINT64|0x00000046
gArmTokenSpaceGuid.PcdSystemBiosRelease|0xFFFF|UINT16|0x30000058
gArmTokenSpaceGuid.PcdEmbeddedControllerFirmwareRelease|0xFFFF|UINT16|0x30000059
[PcdsFixedAtBuild.common, PcdsDynamic.common]
#
# ARM Architectural Timer

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
@@ -84,8 +80,6 @@
ArmMtlLib|ArmPkg/Library/ArmMtlNullLib/ArmMtlNullLib.inf
OemMiscLib|ArmPkg/Universal/Smbios/OemMiscLibNull/OemMiscLibNull.inf
[LibraryClasses.common.PEIM]
HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf
@@ -139,19 +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
ArmPkg/Universal/Smbios/ProcessorSubClassDxe/ProcessorSubClassDxe.inf
ArmPkg/Universal/Smbios/SmbiosMiscDxe/SmbiosMiscDxe.inf
[Components.AARCH64]
ArmPkg/Drivers/MmCommunicationDxe/MmCommunication.inf
ArmPkg/Library/ArmMmuLib/ArmMmuPeiLib.inf
ArmPkg/Library/StandaloneMmMmuLib/ArmMmuStandaloneMmLib.inf

View File

@@ -25,13 +25,10 @@
+ ARM_GICR_SGI_RESERVED_FRAME_SIZE)
#define ISENABLER_ADDRESS(base,offset) ((base) + \
ARM_GICR_CTLR_FRAME_SIZE + ARM_GICR_ISENABLER + 4 * (offset))
ARM_GICR_CTLR_FRAME_SIZE + ARM_GICR_ISENABLER + (4 * offset))
#define ICENABLER_ADDRESS(base,offset) ((base) + \
ARM_GICR_CTLR_FRAME_SIZE + ARM_GICR_ICENABLER + 4 * (offset))
#define IPRIORITY_ADDRESS(base,offset) ((base) + \
ARM_GICR_CTLR_FRAME_SIZE + ARM_GIC_ICDIPR + 4 * (offset))
ARM_GICR_CTLR_FRAME_SIZE + ARM_GICR_ICENABLER + (4 * offset))
/**
*
@@ -202,50 +199,6 @@ ArmGicEndOfInterrupt (
}
}
VOID
EFIAPI
ArmGicSetInterruptPriority (
IN UINTN GicDistributorBase,
IN UINTN GicRedistributorBase,
IN UINTN Source,
IN UINTN Priority
)
{
UINT32 RegOffset;
UINTN RegShift;
ARM_GIC_ARCH_REVISION Revision;
UINTN GicCpuRedistributorBase;
// Calculate register offset and bit position
RegOffset = Source / 4;
RegShift = (Source % 4) * 8;
Revision = ArmGicGetSupportedArchRevision ();
if ((Revision == ARM_GIC_ARCH_REVISION_2) ||
FeaturePcdGet (PcdArmGicV3WithV2Legacy) ||
SourceIsSpi (Source)) {
MmioAndThenOr32 (
GicDistributorBase + ARM_GIC_ICDIPR + (4 * RegOffset),
~(0xff << RegShift),
Priority << RegShift
);
} else {
GicCpuRedistributorBase = GicGetCpuRedistributorBase (
GicRedistributorBase,
Revision
);
if (GicCpuRedistributorBase == 0) {
return;
}
MmioAndThenOr32 (
IPRIORITY_ADDRESS (GicCpuRedistributorBase, RegOffset),
~(0xff << RegShift),
Priority << RegShift
);
}
}
VOID
EFIAPI
ArmGicEnableInterrupt (

View File

@@ -374,6 +374,8 @@ GicV3DxeInitialize (
{
EFI_STATUS Status;
UINTN Index;
UINT32 RegOffset;
UINTN RegShift;
UINT64 CpuTarget;
UINT64 MpId;
@@ -395,11 +397,12 @@ GicV3DxeInitialize (
GicV3DisableInterruptSource (&gHardwareInterruptV3Protocol, Index);
// Set Priority
ArmGicSetInterruptPriority (
mGicDistributorBase,
mGicRedistributorsBase,
Index,
ARM_GIC_DEFAULT_PRIORITY
RegOffset = Index / 4;
RegShift = (Index % 4) * 8;
MmioAndThenOr32 (
mGicDistributorBase + ARM_GIC_ICDIPR + (4 * RegOffset),
~(0xff << RegShift),
ARM_GIC_DEFAULT_PRIORITY << RegShift
);
}

View File

@@ -1,6 +1,6 @@
/** @file
Copyright (c) 2017-2021, Arm Limited. All rights reserved.
Copyright (c) 2017-2018, Arm Limited. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -161,9 +161,8 @@ ScmiProtocolDiscoveryCommon (
)
{
SCMI_COMMAND Command;
UINT32 PayloadLength;
UINT32 PayloadLength = 0;
PayloadLength = 0;
Command.ProtocolId = ProtocolId;
Command.MessageId = MessageId;

View File

@@ -1,6 +1,6 @@
/** @file
Copyright (c) 2017-2021, Arm Limited. All rights reserved.
Copyright (c) 2017-2018, Arm Limited. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -189,14 +189,12 @@ ClockDescribeRates (
CLOCK_DESCRIBE_RATES *DescribeRates;
CLOCK_RATE_DWORD *Rate;
UINT32 RequiredArraySize;
UINT32 RateIndex;
UINT32 RequiredArraySize = 0;
UINT32 RateIndex = 0;
UINT32 RateNo;
UINT32 RateOffset;
*TotalRates = 0;
RequiredArraySize = 0;
RateIndex = 0;
Status = ScmiCommandGetPayload (&MessageParams);
if (EFI_ERROR (Status)) {

View File

@@ -2,7 +2,7 @@
Copyright (c) 2009, Hewlett-Packard Company. All rights reserved.<BR>
Portions copyright (c) 2010, Apple Inc. All rights reserved.<BR>
Portions copyright (c) 2011-2021, Arm Limited. All rights reserved.<BR>
Portions copyright (c) 2011-2013, ARM Ltd. All rights reserved.<BR>
Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -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;
}
}
}
@@ -189,7 +128,7 @@ SyncCacheConfig (
)
{
EFI_STATUS Status;
UINT32 PageAttribute;
UINT32 PageAttribute = 0;
UINT64 *FirstLevelTableAddress;
UINTN TableLevel;
UINTN TableCount;
@@ -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,
@@ -282,12 +221,12 @@ EfiAttributeToArmAttribute (
ArmAttributes |= TT_AF;
// Determine protection attributes
if ((EfiAttributes & EFI_MEMORY_RO) != 0) {
if (EfiAttributes & EFI_MEMORY_RO) {
ArmAttributes |= TT_AP_RO_RO;
}
// Process eXecute Never attribute
if ((EfiAttributes & EFI_MEMORY_XP) != 0) {
if (EfiAttributes & EFI_MEMORY_XP) {
ArmAttributes |= TT_PXN_MASK;
}

View File

@@ -2,7 +2,7 @@
Copyright (c) 2009, Hewlett-Packard Company. All rights reserved.<BR>
Portions copyright (c) 2010, Apple Inc. All rights reserved.<BR>
Portions copyright (c) 2013-2021, Arm Limited. All rights reserved.<BR>
Portions copyright (c) 2013, ARM Ltd. All rights reserved.<BR>
Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -155,8 +155,8 @@ SyncCacheConfigPage (
EFI_STATUS Status;
UINT32 i;
volatile ARM_PAGE_TABLE_ENTRY *SecondLevelTable;
UINT32 NextPageAttributes;
UINT32 PageAttributes;
UINT32 NextPageAttributes = 0;
UINT32 PageAttributes = 0;
UINT32 BaseAddress;
UINT64 GcdAttributes;
@@ -226,8 +226,8 @@ SyncCacheConfig (
UINT32 i;
EFI_PHYSICAL_ADDRESS NextRegionBase;
UINT64 NextRegionLength;
UINT32 NextSectionAttributes;
UINT32 SectionAttributes;
UINT32 NextSectionAttributes = 0;
UINT32 SectionAttributes = 0;
UINT64 GcdAttributes;
volatile ARM_FIRST_LEVEL_DESCRIPTOR *FirstLevelTable;
UINTN NumberOfDescriptors;
@@ -366,14 +366,14 @@ EfiAttributeToArmAttribute (
}
// Determine protection attributes
if ((EfiAttributes & EFI_MEMORY_RO) != 0) {
if (EfiAttributes & EFI_MEMORY_RO) {
ArmAttributes |= TT_DESCRIPTOR_SECTION_AP_RO_RO;
} else {
ArmAttributes |= TT_DESCRIPTOR_SECTION_AP_RW_RW;
}
// Determine eXecute Never attribute
if ((EfiAttributes & EFI_MEMORY_XP) != 0) {
if (EfiAttributes & EFI_MEMORY_XP) {
ArmAttributes |= TT_DESCRIPTOR_SECTION_XN_MASK;
}

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,7 +1,7 @@
/** @file
Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
Portions Copyright (c) 2011 - 2021, Arm Limited. All rights reserved.<BR>
Portions Copyright (c) 2011 - 2014, ARM Ltd. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -14,8 +14,7 @@
EFI_STATUS
InitializeExceptions (
IN EFI_CPU_ARCH_PROTOCOL *Cpu
)
{
) {
EFI_STATUS Status;
EFI_VECTOR_HANDOFF_INFO *VectorInfoList;
EFI_VECTOR_HANDOFF_INFO *VectorInfo;
@@ -93,8 +92,7 @@ EFI_STATUS
RegisterInterruptHandler(
IN EFI_EXCEPTION_TYPE InterruptType,
IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler
)
{
) {
// pass down to CpuExceptionHandlerLib
return (EFI_STATUS)RegisterCpuInterruptHandler(InterruptType, InterruptHandler);
}

View File

@@ -1,6 +1,6 @@
/** @file
Copyright (c) 2016-2021, Arm Limited. All rights reserved.<BR>
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
@@ -96,7 +101,7 @@ MmCommunication2Communicate (
sizeof (CommunicateHeader->MessageLength);
// If the length of the CommBuffer is 0 then return the expected length.
if (CommSize != 0) {
if (CommSize) {
// This case can be used by the consumer of this driver to find out the
// max size that can be used for allocating CommBuffer.
if ((*CommSize == 0) ||
@@ -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

@@ -1,7 +1,7 @@
/** @file
Timer Architecture Protocol driver of the ARM flavor
Copyright (c) 2011-2021, Arm Limited. All rights reserved.<BR>
Copyright (c) 2011-2013 ARM Ltd. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -307,7 +307,7 @@ TimerInterruptHandler (
// Check if the timer interrupt is active
if ((ArmGenericTimerGetTimerCtrlReg () ) & ARM_ARCH_TIMER_ISTATUS) {
if (mTimerNotifyFunction != 0) {
if (mTimerNotifyFunction) {
mTimerNotifyFunction (mTimerPeriod * mElapsedPeriod);
}
@@ -359,7 +359,7 @@ TimerInitialize (
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EFI_HANDLE Handle;
EFI_HANDLE Handle = NULL;
EFI_STATUS Status;
UINTN TimerCtrlReg;
UINT32 TimerHypIntrNum;
@@ -408,7 +408,6 @@ TimerInitialize (
Status = TimerDriverSetTimerPeriod (&gTimer, FixedPcdGet32(PcdTimerPeriod)); // TIMER_DEFAULT_PERIOD
ASSERT_EFI_ERROR (Status);
Handle = NULL;
// Install the Timer Architectural Protocol onto a new handle
Status = gBS->InstallMultipleProtocolInterfaces(
&Handle,

View File

@@ -2,7 +2,7 @@
Support a Semi Host file system over a debuggers JTAG
Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
Portions copyright (c) 2011 - 2021, Arm Limited. All rights reserved.<BR>
Portions copyright (c) 2011 - 2014, ARM Ltd. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -90,9 +90,8 @@ AllocateFCB (
VOID
)
{
SEMIHOST_FCB *Fcb;
SEMIHOST_FCB *Fcb = AllocateZeroPool (sizeof (SEMIHOST_FCB));
Fcb = AllocateZeroPool (sizeof (SEMIHOST_FCB));
if (Fcb != NULL) {
CopyMem (&Fcb->File, &gSemihostFsFile, sizeof (gSemihostFsFile));
Fcb->Signature = SEMIHOST_FCB_SIGNATURE;
@@ -123,7 +122,7 @@ VolumeOpen (
OUT EFI_FILE **Root
)
{
SEMIHOST_FCB *RootFcb;
SEMIHOST_FCB *RootFcb = NULL;
if (Root == NULL) {
return EFI_INVALID_PARAMETER;
@@ -197,8 +196,8 @@ FileOpen (
return EFI_INVALID_PARAMETER;
}
if (((OpenMode & EFI_FILE_MODE_CREATE) != 0) &&
((Attributes & EFI_FILE_DIRECTORY) != 0)) {
if ((OpenMode & EFI_FILE_MODE_CREATE) &&
(Attributes & EFI_FILE_DIRECTORY) ) {
return EFI_WRITE_PROTECTED;
}
@@ -235,7 +234,7 @@ FileOpen (
Return = SemihostFileOpen (AsciiFileName, SemihostMode, &SemihostHandle);
if (RETURN_ERROR (Return)) {
if ((OpenMode & EFI_FILE_MODE_CREATE) != 0) {
if (OpenMode & EFI_FILE_MODE_CREATE) {
//
// In the create if does not exist case, if the opening in update
// mode failed, create it and open it in update mode. The update
@@ -278,8 +277,7 @@ FileOpen (
FileFcb->Info.FileSize = Length;
FileFcb->Info.PhysicalSize = Length;
FileFcb->Info.Attribute = ((OpenMode & EFI_FILE_MODE_CREATE) != 0) ?
Attributes : 0;
FileFcb->Info.Attribute = (OpenMode & EFI_FILE_MODE_CREATE) ? Attributes : 0;
InsertTailList (&gFileList, &FileFcb->Link);
@@ -760,13 +758,12 @@ GetFileInfo (
OUT VOID *Buffer
)
{
EFI_FILE_INFO *Info;
UINTN NameSize;
EFI_FILE_INFO *Info = NULL;
UINTN NameSize = 0;
UINTN ResultSize;
UINTN Index;
if (Fcb->IsRoot) {
NameSize = 0;
if (Fcb->IsRoot == TRUE) {
ResultSize = SIZE_OF_EFI_FILE_INFO + sizeof(CHAR16);
} else {
NameSize = AsciiStrLen (Fcb->FileName) + 1;
@@ -786,7 +783,7 @@ GetFileInfo (
// Fill in the structure
Info->Size = ResultSize;
if (Fcb->IsRoot) {
if (Fcb->IsRoot == TRUE) {
Info->FileName[0] = L'\0';
} else {
for (Index = 0; Index < NameSize; Index++) {

View File

@@ -112,10 +112,6 @@
#define ARM_VECTOR_LOW_A32_FIQ 0x700
#define ARM_VECTOR_LOW_A32_SERR 0x780
// The ID_AA64MMFR2_EL1 register was added in ARMv8.2. Since we
// build for ARMv8.0, we need to define the register here.
#define ID_AA64MMFR2_EL1 S3_0_C0_C7_2
#define VECTOR_BASE(tbl) \
.section .text.##tbl##,"ax"; \
.align 11; \
@@ -223,6 +219,11 @@ ArmReadCurrentEL (
VOID
);
UINT64
PageAttributeToGcdAttribute (
IN UINT64 PageAttributes
);
UINTN
ArmWriteCptr (
IN UINT64 Cptr

View File

@@ -1,44 +0,0 @@
/** @file
Header file for FF-A ABI's that will be used for
communication between S-EL0 and the Secure Partition
Manager(SPM)
Copyright (c) 2020, ARM Limited. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
@par Revision Reference:
- FF-A Version 1.0
**/
#ifndef ARM_FFA_SVC_H_
#define ARM_FFA_SVC_H_
#define ARM_SVC_ID_FFA_VERSION_AARCH32 0x84000063
#define ARM_SVC_ID_FFA_MSG_SEND_DIRECT_REQ_AARCH64 0xC400006F
#define ARM_SVC_ID_FFA_MSG_SEND_DIRECT_RESP_AARCH64 0xC4000070
#define SPM_MAJOR_VERSION_FFA 1
#define SPM_MINOR_VERSION_FFA 0
#define ARM_FFA_SPM_RET_SUCCESS 0
#define ARM_FFA_SPM_RET_NOT_SUPPORTED -1
#define ARM_FFA_SPM_RET_INVALID_PARAMETERS -2
#define ARM_FFA_SPM_RET_NO_MEMORY -3
#define ARM_FFA_SPM_RET_BUSY -4
#define ARM_FFA_SPM_RET_INTERRUPTED -5
#define ARM_FFA_SPM_RET_DENIED -6
#define ARM_FFA_SPM_RET_RETRY -7
#define ARM_FFA_SPM_RET_ABORTED -8
// For now, the destination id to be used in the FF-A calls
// is being hard-coded. Subsequently, support will be added
// to get the endpoint id's dynamically
// This is the endpoint id used by the optee os's implementation
// of the spmc.
// https://github.com/OP-TEE/optee_os/blob/master/core/arch/arm/kernel/stmm_sp.c#L66
#define ARM_FFA_DESTINATION_ENDPOINT_ID 3
#endif // ARM_FFA_SVC_H_

View File

@@ -41,7 +41,4 @@
#define ARM_SVC_SPM_RET_DENIED -3
#define ARM_SVC_SPM_RET_NO_MEMORY -5
#define SPM_MAJOR_VERSION 0
#define SPM_MINOR_VERSION 1
#endif

View File

@@ -1,13 +1,9 @@
/** @file
*
* Copyright (c) 2020, NUVIA Inc. All rights reserved.<BR>
* Copyright (c) 2012-2017, ARM Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-2-Clause-Patent
*
* @par Revision Reference:
* - SMC Calling Convention version 1.2
* (https://developer.arm.com/documentation/den0028/c/?lang=en)
**/
#ifndef __ARM_STD_SMC_H__
@@ -56,18 +52,6 @@
#define ARM_SMC_MM_RET_DENIED -3
#define ARM_SMC_MM_RET_NO_MEMORY -4
// ARM Architecture Calls
#define SMCCC_VERSION 0x80000000
#define SMCCC_ARCH_FEATURES 0x80000001
#define SMCCC_ARCH_SOC_ID 0x80000002
#define SMCCC_ARCH_WORKAROUND_1 0x80008000
#define SMCCC_ARCH_WORKAROUND_2 0x80007FFF
#define SMC_ARCH_CALL_SUCCESS 0
#define SMC_ARCH_CALL_NOT_SUPPORTED -1
#define SMC_ARCH_CALL_NOT_REQUIRED -2
#define SMC_ARCH_CALL_INVALID_PARAMETER -3
/*
* Power State Coordination Interface (PSCI) calls cover a subset of the
* Standard Service Call range.

View File

@@ -208,15 +208,6 @@ ArmGicSetPriorityMask (
IN INTN PriorityMask
);
VOID
EFIAPI
ArmGicSetInterruptPriority (
IN UINTN GicDistributorBase,
IN UINTN GicRedistributorBase,
IN UINTN Source,
IN UINTN Priority
);
VOID
EFIAPI
ArmGicEnableInterrupt (

View File

@@ -2,7 +2,6 @@
Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
Copyright (c) 2011 - 2016, ARM Ltd. All rights reserved.<BR>
Copyright (c) 2020, NUVIA Inc. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -109,10 +108,6 @@ typedef enum {
#define GET_MPID(ClusterId, CoreId) (((ClusterId) << 8) | (CoreId))
#define PRIMARY_CORE_ID (PcdGet32(PcdArmPrimaryCore) & ARM_CORE_MASK)
// The ARM Architecture Reference Manual for ARMv8-A defines up
// to 7 levels of cache, L1 through L7.
#define MAX_ARM_CACHE_LEVEL 7
UINTN
EFIAPI
ArmDataCacheLineLength (
@@ -137,6 +132,18 @@ ArmIsArchTimerImplemented (
VOID
);
UINTN
EFIAPI
ArmReadIdPfr0 (
VOID
);
UINTN
EFIAPI
ArmReadIdPfr1 (
VOID
);
UINTN
EFIAPI
ArmCacheInfo (
@@ -204,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 (
@@ -708,49 +733,4 @@ ArmGetPhysicalAddressBits (
VOID
);
///
/// ID Register Helper functions
///
/**
Check whether the CPU supports the GIC system register interface (any version)
@return Whether GIC System Register Interface is supported
**/
BOOLEAN
EFIAPI
ArmHasGicSystemRegisters (
VOID
);
/** Checks if CCIDX is implemented.
@retval TRUE CCIDX is implemented.
@retval FALSE CCIDX is not implemented.
**/
BOOLEAN
EFIAPI
ArmHasCcidx (
VOID
);
#ifdef MDE_CPU_ARM
///
/// AArch32-only ID Register Helper functions
///
/**
Check whether the CPU supports the Security extensions
@return Whether the Security extensions are implemented
**/
BOOLEAN
EFIAPI
ArmHasSecurityExtensions (
VOID
);
#endif // MDE_CPU_ARM
#endif // __ARM_LIB__

View File

@@ -27,16 +27,10 @@ typedef struct {
/**
Trigger an SVC call
SVC calls can take up to 8 arguments and return up to 8 return values.
Therefore, the 8 first fields in the ARM_SVC_ARGS structure are used
SVC calls can take up to 7 arguments and return up to 4 return values.
Therefore, the 4 first fields in the ARM_SVC_ARGS structure are used
for both input and output values.
@param[in, out] Args Arguments to be passed as part of the SVC call
The return values of the SVC call are also placed
in the same structure
@retval None
**/
VOID
ArmCallSvc (

View File

@@ -1,165 +0,0 @@
/** @file
*
* Copyright (c) 2021, NUVIA Inc. All rights reserved.
* Copyright (c) 2015, Hisilicon Limited. All rights reserved.
* Copyright (c) 2015, Linaro Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-2-Clause-Patent
*
**/
#ifndef OEM_MISC_LIB_H_
#define OEM_MISC_LIB_H_
#include <Uefi.h>
#include <IndustryStandard/SmBios.h>
typedef enum
{
CpuCacheL1 = 1,
CpuCacheL2,
CpuCacheL3,
CpuCacheL4,
CpuCacheL5,
CpuCacheL6,
CpuCacheL7,
CpuCacheLevelMax
} OEM_MISC_CPU_CACHE_LEVEL;
typedef struct
{
UINT8 Voltage; ///< Processor voltage
UINT16 CurrentSpeed; ///< Current clock speed in MHz
UINT16 MaxSpeed; ///< Maximum clock speed in MHz
UINT16 ExternalClock; ///< External clock speed in MHz
UINT16 CoreCount; ///< Number of cores available
UINT16 CoresEnabled; ///< Number of cores enabled
UINT16 ThreadCount; ///< Number of threads per processor
} OEM_MISC_PROCESSOR_DATA;
typedef enum
{
ProductNameType01,
SerialNumType01,
UuidType01,
SystemManufacturerType01,
SkuNumberType01,
FamilyType01,
AssertTagType02,
SerialNumberType02,
BoardManufacturerType02,
SkuNumberType02,
ChassisLocationType02,
AssetTagType03,
SerialNumberType03,
VersionType03,
ChassisTypeType03,
ManufacturerType03,
SkuNumberType03,
SmbiosHiiStringFieldMax
} OEM_MISC_SMBIOS_HII_STRING_FIELD;
/*
* The following are functions that the each platform needs to
* implement in its OemMiscLib library.
*/
/** Gets the CPU frequency of the specified processor.
@param ProcessorIndex Index of the processor to get the frequency for.
@return CPU frequency in Hz
**/
UINTN
EFIAPI
OemGetCpuFreq (
IN UINT8 ProcessorIndex
);
/** Gets information about the specified processor and stores it in
the structures provided.
@param ProcessorIndex Index of the processor to get the information for.
@param ProcessorStatus Processor status.
@param ProcessorCharacteristics Processor characteritics.
@param MiscProcessorData Miscellaneous processor information.
@return TRUE on success, FALSE on failure.
**/
BOOLEAN
EFIAPI
OemGetProcessorInformation (
IN UINTN ProcessorIndex,
IN OUT PROCESSOR_STATUS_DATA *ProcessorStatus,
IN OUT PROCESSOR_CHARACTERISTIC_FLAGS *ProcessorCharacteristics,
IN OUT OEM_MISC_PROCESSOR_DATA *MiscProcessorData
);
/** Gets information about the cache at the specified cache level.
@param ProcessorIndex The processor to get information for.
@param CacheLevel The cache level to get information for.
@param DataCache Whether the cache is a data cache.
@param UnifiedCache Whether the cache is a unified cache.
@param SmbiosCacheTable The SMBIOS Type7 cache information structure.
@return TRUE on success, FALSE on failure.
**/
BOOLEAN
EFIAPI
OemGetCacheInformation (
IN UINT8 ProcessorIndex,
IN UINT8 CacheLevel,
IN BOOLEAN DataCache,
IN BOOLEAN UnifiedCache,
IN OUT SMBIOS_TABLE_TYPE7 *SmbiosCacheTable
);
/** Gets the maximum number of processors supported by the platform.
@return The maximum number of processors.
**/
UINT8
EFIAPI
OemGetMaxProcessors (
VOID
);
/** Gets the type of chassis for the system.
@retval The type of the chassis.
**/
MISC_CHASSIS_TYPE
EFIAPI
OemGetChassisType (
VOID
);
/** Returns whether the specified processor is present or not.
@param ProcessIndex The processor index to check.
@return TRUE is the processor is present, FALSE otherwise.
**/
BOOLEAN
EFIAPI
OemIsProcessorPresent (
IN UINTN ProcessorIndex
);
/** Updates the HII string for the specified field.
@param HiiHandle The HII handle.
@param TokenToUpdate The string to update.
@param Field The field to get information about.
**/
VOID
EFIAPI
OemUpdateSmbiosInfo (
IN EFI_HII_HANDLE HiiHandle,
IN EFI_STRING_ID TokenToUpdate,
IN OEM_MISC_SMBIOS_HII_STRING_FIELD Field
);
#endif // OEM_MISC_LIB_H_

View File

@@ -56,7 +56,7 @@ TimerConstructor (
// If the security extension is not implemented, set Timer Frequency
// here.
//
if (ArmHasSecurityExtensions ()) {
if ((ArmReadIdPfr1 () & ARM_PFR1_SEC) == 0x0) {
ArmGenericTimerSetTimerFreq (PcdGet32 (PcdArmArchTimerFreqInHz));
}
#endif

View File

@@ -1,7 +1,7 @@
/** @file
Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
Copyright (c) 2011 - 2021, ARM Limited. All rights reserved.
Copyright (c) 2011 - 2014, ARM Limited. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -20,14 +20,11 @@ CacheRangeOperation (
IN UINTN LineLength
)
{
UINTN ArmCacheLineAlignmentMask;
// Align address (rounding down)
UINTN AlignedAddress;
UINTN EndAddress;
UINTN ArmCacheLineAlignmentMask = LineLength - 1;
ArmCacheLineAlignmentMask = LineLength - 1;
AlignedAddress = (UINTN)Start - ((UINTN)Start & ArmCacheLineAlignmentMask);
EndAddress = (UINTN)Start + Length;
// Align address (rounding down)
UINTN AlignedAddress = (UINTN)Start - ((UINTN)Start & ArmCacheLineAlignmentMask);
UINTN EndAddress = (UINTN)Start + Length;
// Perform the line operation on an address in each cache line
while (AlignedAddress < EndAddress) {

View File

@@ -2,7 +2,6 @@
Default exception handler
Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
Copyright (c) 2021, Arm Limited. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -158,7 +157,7 @@ DisassembleArmInstruction (
IN BOOLEAN Extended
)
{
UINT32 OpCode;
UINT32 OpCode = **OpCodePtr;
CHAR8 *Type, *Root;
BOOLEAN I, P, U, B, W, L, S, H;
UINT32 Rn, Rd, Rm;
@@ -166,8 +165,6 @@ DisassembleArmInstruction (
UINT32 Index;
UINT32 shift_imm, shift;
OpCode = **OpCodePtr;
I = (OpCode & BIT25) == BIT25;
P = (OpCode & BIT24) == BIT24;
U = (OpCode & BIT23) == BIT23;
@@ -243,7 +240,7 @@ DisassembleArmInstruction (
if (shift_imm == 0) {
shift_imm = 32;
}
} else if (shift == 0x2) {
} else if (shift == 0x12) {
Type = "ASR";
} else if (shift_imm == 0) {
AsciiSPrint (&Buf[Index], Size - Index, "[%a, #%a%a, %a, RRX]%a", gReg[Rn], SIGN (U), gReg[Rm], WRITE (W));
@@ -273,7 +270,7 @@ DisassembleArmInstruction (
if (shift_imm == 0) {
shift_imm = 32;
}
} else if (shift == 0x2) {
} else if (shift == 0x12) {
Type = "ASR";
} else if (shift_imm == 0) {
AsciiSPrint (&Buf[Index], Size - Index, "[%a], #%a%a, %a, RRX", gReg[Rn], SIGN (U), gReg[Rm]);
@@ -370,11 +367,7 @@ DisassembleArmInstruction (
AsciiSPrint (Buf, Size, "CPS #0x%x", (OpCode & 0x2f));
} else {
imode = (OpCode >> 18) & 0x3;
Index = AsciiSPrint (Buf, Size, "CPS%a %a%a%a",
(imode == 3) ? "ID":"IE",
((OpCode & BIT8) != 0) ? "A":"",
((OpCode & BIT7) != 0) ? "I":"",
((OpCode & BIT6) != 0) ? "F":"");
Index = AsciiSPrint (Buf, Size, "CPS%a %a%a%a", (imode == 3) ? "ID":"IE", (OpCode & BIT8) ? "A":"", (OpCode & BIT7) ? "I":"", (OpCode & BIT6) ? "F":"");
if ((OpCode & BIT17) != 0) {
AsciiSPrint (&Buf[Index], Size - Index, ", #0x%x", OpCode & 0x1f);
}

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

@@ -2,7 +2,7 @@
* Main file supporting the SEC Phase for Versatile Express
*
* Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
* Copyright (c) 2011-2021, Arm Limited. All rights reserved.<BR>
* Copyright (c) 2011-2014, ARM Limited. All rights reserved.
* Copyright (c) 2016 HP Development Company, L.P.
*
* SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -253,8 +253,7 @@ RETURN_STATUS
RegisterCpuInterruptHandler(
IN EFI_EXCEPTION_TYPE ExceptionType,
IN EFI_CPU_INTERRUPT_HANDLER ExceptionHandler
)
{
) {
if (ExceptionType > gMaxExceptionNumber) {
return RETURN_UNSUPPORTED;
}

View File

@@ -25,7 +25,7 @@ ArmGicArchLibInitialize (
// feature is implemented on the CPU. This is also convenient as our GICv3
// driver requires SRE. If only Memory mapped access is available we try to
// drive the GIC as a v2.
if (ArmHasGicSystemRegisters ()) {
if (ArmReadIdPfr0 () & AARCH64_PFR0_GIC) {
// Make sure System Register access is enabled (SRE). This depends on the
// higher privilege level giving us permission, otherwise we will either
// cause an exception here, or the write doesn't stick in which case we need

View File

@@ -0,0 +1,60 @@
/** @file
*
* Copyright (c) 2014, ARM Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-2-Clause-Patent
*
**/
#include <Library/ArmLib.h>
#include <Library/ArmGicLib.h>
STATIC ARM_GIC_ARCH_REVISION mGicArchRevision;
RETURN_STATUS
EFIAPI
ArmGicArchLibInitialize (
VOID
)
{
UINT32 IccSre;
// Ideally we would like to use the GICC IIDR Architecture version here, but
// this does not seem to be very reliable as the implementation could easily
// get it wrong. It is more reliable to check if the GICv3 System Register
// feature is implemented on the CPU. This is also convenient as our GICv3
// driver requires SRE. If only Memory mapped access is available we try to
// drive the GIC as a v2.
if (ArmReadIdPfr1 () & ARM_PFR1_GIC) {
// Make sure System Register access is enabled (SRE). This depends on the
// higher privilege level giving us permission, otherwise we will either
// cause an exception here, or the write doesn't stick in which case we need
// to fall back to the GICv2 MMIO interface.
// Note: We do not need to set ICC_SRE_EL2.Enable because the OS is started
// at the same exception level.
// It is the OS responsibility to set this bit.
IccSre = ArmGicV3GetControlSystemRegisterEnable ();
if (!(IccSre & ICC_SRE_EL2_SRE)) {
ArmGicV3SetControlSystemRegisterEnable (IccSre| ICC_SRE_EL2_SRE);
IccSre = ArmGicV3GetControlSystemRegisterEnable ();
}
if (IccSre & ICC_SRE_EL2_SRE) {
mGicArchRevision = ARM_GIC_ARCH_REVISION_3;
goto Done;
}
}
mGicArchRevision = ARM_GIC_ARCH_REVISION_2;
Done:
return RETURN_SUCCESS;
}
ARM_GIC_ARCH_REVISION
EFIAPI
ArmGicGetSupportedArchRevision (
VOID
)
{
return mGicArchRevision;
}

View File

@@ -14,8 +14,11 @@
LIBRARY_CLASS = ArmGicArchLib|DXE_DRIVER UEFI_DRIVER UEFI_APPLICATION
CONSTRUCTOR = ArmGicArchLibInitialize
[Sources]
ArmGicArchLib.c
[Sources.ARM]
Arm/ArmGicArchLib.c
[Sources.AARCH64]
AArch64/ArmGicArchLib.c
[Packages]
MdePkg/MdePkg.dec

View File

@@ -23,7 +23,7 @@ ArmGicGetSupportedArchRevision (
// feature is implemented on the CPU. This is also convenient as our GICv3
// driver requires SRE. If only Memory mapped access is available we try to
// drive the GIC as a v2.
if (ArmHasGicSystemRegisters ()) {
if (ArmReadIdPfr0 () & AARCH64_PFR0_GIC) {
// Make sure System Register access is enabled (SRE). This depends on the
// higher privilege level giving us permission, otherwise we will either
// cause an exception here, or the write doesn't stick in which case we need

View File

@@ -0,0 +1,45 @@
/** @file
*
* Copyright (c) 2014, ARM Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-2-Clause-Patent
*
**/
#include <Library/ArmLib.h>
#include <Library/ArmGicLib.h>
ARM_GIC_ARCH_REVISION
EFIAPI
ArmGicGetSupportedArchRevision (
VOID
)
{
UINT32 IccSre;
// Ideally we would like to use the GICC IIDR Architecture version here, but
// this does not seem to be very reliable as the implementation could easily
// get it wrong. It is more reliable to check if the GICv3 System Register
// feature is implemented on the CPU. This is also convenient as our GICv3
// driver requires SRE. If only Memory mapped access is available we try to
// drive the GIC as a v2.
if (ArmReadIdPfr1 () & ARM_PFR1_GIC) {
// Make sure System Register access is enabled (SRE). This depends on the
// higher privilege level giving us permission, otherwise we will either
// cause an exception here, or the write doesn't stick in which case we need
// to fall back to the GICv2 MMIO interface.
// Note: We do not need to set ICC_SRE_EL2.Enable because the OS is started
// at the same exception level.
// It is the OS responsibility to set this bit.
IccSre = ArmGicV3GetControlSystemRegisterEnable ();
if (!(IccSre & ICC_SRE_EL2_SRE)) {
ArmGicV3SetControlSystemRegisterEnable (IccSre| ICC_SRE_EL2_SRE);
IccSre = ArmGicV3GetControlSystemRegisterEnable ();
}
if (IccSre & ICC_SRE_EL2_SRE) {
return ARM_GIC_ARCH_REVISION_3;
}
}
return ARM_GIC_ARCH_REVISION_2;
}

View File

@@ -13,8 +13,11 @@
VERSION_STRING = 1.0
LIBRARY_CLASS = ArmGicArchLib|SEC
[Sources]
ArmGicArchLib.c
[Sources.ARM]
Arm/ArmGicArchLib.c
[Sources.AARCH64]
AArch64/ArmGicArchLib.c
[Packages]
MdePkg/MdePkg.dec

View File

@@ -2,19 +2,16 @@
Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
Portions copyright (c) 2011 - 2014, ARM Ltd. All rights reserved.<BR>
Copyright (c) 2021, NUVIA Inc. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#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"
@@ -43,8 +40,6 @@ ArmInvalidateDataCache (
VOID
)
{
ASSERT (!ArmMmuEnabled ());
ArmDataSynchronizationBarrier ();
AArch64DataCacheOperation (ArmInvalidateDataCacheEntryBySetWay);
}
@@ -55,8 +50,6 @@ ArmCleanInvalidateDataCache (
VOID
)
{
ASSERT (!ArmMmuEnabled ());
ArmDataSynchronizationBarrier ();
AArch64DataCacheOperation (ArmCleanInvalidateDataCacheEntryBySetWay);
}
@@ -67,40 +60,6 @@ ArmCleanDataCache (
VOID
)
{
ASSERT (!ArmMmuEnabled ());
ArmDataSynchronizationBarrier ();
AArch64DataCacheOperation (ArmCleanDataCacheEntryBySetWay);
}
/**
Check whether the CPU supports the GIC system register interface (any version)
@return Whether GIC System Register Interface is supported
**/
BOOLEAN
EFIAPI
ArmHasGicSystemRegisters (
VOID
)
{
return ((ArmReadIdAA64Pfr0 () & AARCH64_PFR0_GIC) != 0);
}
/** Checks if CCIDX is implemented.
@retval TRUE CCIDX is implemented.
@retval FALSE CCIDX is not implemented.
**/
BOOLEAN
EFIAPI
ArmHasCcidx (
VOID
)
{
UINTN Mmfr2;
Mmfr2 = ArmReadIdAA64Mmfr2 ();
return (((Mmfr2 >> 20) & 0xF) == 1) ? TRUE : FALSE;
}

View File

@@ -2,7 +2,6 @@
Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
Portions Copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.<BR>
Copyright (c) 2020, NUVIA Inc. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -18,39 +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
);
UINTN
EFIAPI
ArmReadIdAA64Pfr0 (
VOID
);
/** Reads the ID_AA64MMFR2_EL1 register.
@return The contents of the ID_AA64MMFR2_EL1 register.
**/
UINTN
EFIAPI
ArmReadIdAA64Mmfr2 (
VOID
);
#endif // __AARCH64_LIB_H__

View File

@@ -3,7 +3,6 @@
# Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
# Copyright (c) 2011 - 2017, ARM Limited. All rights reserved.
# Copyright (c) 2016, Linaro Limited. All rights reserved.
# Copyright (c) 2020, NUVIA Inc. All rights reserved.
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
@@ -396,7 +395,7 @@ ASM_FUNC(ArmReadVBar)
ASM_FUNC(ArmEnableVFP)
// Check whether floating-point is implemented in the processor.
mov x1, x30 // Save LR
bl ArmReadIdAA64Pfr0 // Read EL1 Processor Feature Register (PFR0)
bl ArmReadIdPfr0 // Read EL1 Processor Feature Register (PFR0)
mov x30, x1 // Restore LR
ubfx x0, x0, #16, #4 // Extract the FP bits 16:19
cmp x0, #0xF // Check if FP bits are '1111b',
@@ -425,9 +424,6 @@ ASM_FUNC(ArmCallWFI)
wfi
ret
ASM_FUNC(ArmReadIdAA64Mmfr2)
mrs x0, ID_AA64MMFR2_EL1 // read EL1 MMFR2
ret
ASM_FUNC(ArmReadMpidr)
mrs x0, mpidr_el1 // read EL1 MPIDR
@@ -452,11 +448,19 @@ ASM_FUNC(ArmIsArchTimerImplemented)
ret
ASM_FUNC(ArmReadIdAA64Pfr0)
ASM_FUNC(ArmReadIdPfr0)
mrs x0, id_aa64pfr0_el1 // Read ID_AA64PFR0 Register
ret
// Q: id_aa64pfr1_el1 not defined yet. What does this function want to access?
// A: used to setup arch timer. Check if we have security extensions, permissions to set stuff.
// See: ArmPkg/Library/ArmArchTimerLib/AArch64/ArmArchTimerLib.c
// Not defined yet, but stick in here for now, should read all zeros.
ASM_FUNC(ArmReadIdPfr1)
mrs x0, id_aa64pfr1_el1 // Read ID_PFR1 Register
ret
// VOID ArmWriteHcr(UINTN Hcr)
ASM_FUNC(ArmWriteHcr)
msr hcr_el2, x0 // Write the passed HCR value

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

@@ -84,7 +84,7 @@ ASM_FUNC(ArmDisableAllExceptions)
ret
// UINTN
// UINT32
// ReadCCSIDR (
// IN UINT32 CSSELR
// )

View File

@@ -60,11 +60,7 @@ ASM_FUNC(ArmDisableInterrupts)
isb
bx LR
ASM_FUNC(ArmReadIdMmfr4)
mrc p15,0,r0,c0,c2,6 @ Read ID_MMFR4 Register
bx lr
// UINTN
// UINT32
// ReadCCSIDR (
// IN UINT32 CSSELR
// )
@@ -74,16 +70,6 @@ ASM_FUNC(ReadCCSIDR)
mrc p15,1,r0,c0,c0,0 @ Read current CP15 Cache Size ID Register (CCSIDR)
bx lr
// UINT32
// ReadCCSIDR2 (
// IN UINT32 CSSELR
// )
ASM_FUNC(ReadCCSIDR2)
mcr p15,2,r0,c0,c0,0 @ Write Cache Size Selection Register (CSSELR)
isb
mrc p15,1,r0,c0,c0,2 @ Read current CP15 Cache Size ID Register (CCSIDR2)
bx lr
// UINT32
// ReadCLIDR (
// IN UINT32 CSSELR

View File

@@ -64,11 +64,7 @@
isb
bx LR
RVCT_ASM_EXPORT ArmReadIdMmfr4
mrc p15,0,r0,c0,c2,6 ; Read ID_MMFR4 Register
bx LR
// UINTN
// UINT32
// ReadCCSIDR (
// IN UINT32 CSSELR
// )
@@ -78,16 +74,6 @@
mrc p15,1,r0,c0,c0,0 ; Read current CP15 Cache Size ID Register (CCSIDR)
bx lr
// UINT32
// ReadCCSIDR2 (
// IN UINT32 CSSELR
// )
RVCT_ASM_EXPORT ReadCCSIDR2
mcr p15,2,r0,c0,c0,0 ; Write Cache Size Selection Register (CSSELR)
isb
mrc p15,1,r0,c0,c0,2 ; Read current CP15 Cache Size ID Register (CCSIDR2)
bx lr
// UINT32
// ReadCLIDR (
// IN UINT32 CSSELR

View File

@@ -2,19 +2,15 @@
Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
Copyright (c) 2011 - 2014, ARM Limited. All rights reserved.
Copyright (c) 2021, NUVIA Inc. All rights reserved.<BR>
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"
@@ -43,8 +39,6 @@ ArmInvalidateDataCache (
VOID
)
{
ASSERT (!ArmMmuEnabled ());
ArmDataSynchronizationBarrier ();
ArmV7DataCacheOperation (ArmInvalidateDataCacheEntryBySetWay);
}
@@ -55,8 +49,6 @@ ArmCleanInvalidateDataCache (
VOID
)
{
ASSERT (!ArmMmuEnabled ());
ArmDataSynchronizationBarrier ();
ArmV7DataCacheOperation (ArmCleanInvalidateDataCacheEntryBySetWay);
}
@@ -67,55 +59,6 @@ ArmCleanDataCache (
VOID
)
{
ASSERT (!ArmMmuEnabled ());
ArmDataSynchronizationBarrier ();
ArmV7DataCacheOperation (ArmCleanDataCacheEntryBySetWay);
}
/**
Check whether the CPU supports the GIC system register interface (any version)
@return Whether GIC System Register Interface is supported
**/
BOOLEAN
EFIAPI
ArmHasGicSystemRegisters (
VOID
)
{
return ((ArmReadIdPfr1 () & ARM_PFR1_GIC) != 0);
}
/**
Check whether the CPU supports the Security extensions
@return Whether the Security extensions are implemented
**/
BOOLEAN
EFIAPI
ArmHasSecurityExtensions (
VOID
)
{
return ((ArmReadIdPfr1 () & ARM_PFR1_SEC) != 0);
}
/** Checks if CCIDX is implemented.
@retval TRUE CCIDX is implemented.
@retval FALSE CCIDX is not implemented.
**/
BOOLEAN
EFIAPI
ArmHasCcidx (
VOID
)
{
UINTN Mmfr4;
Mmfr4 = ArmReadIdMmfr4 ();
return (((Mmfr4 >> 24) & 0xF) == 1) ? TRUE : FALSE;
}

View File

@@ -30,39 +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
);
/** Reads the ID_MMFR4 register.
@return The contents of the ID_MMFR4 register.
**/
UINT32
EFIAPI
ArmReadIdMmfr4 (
VOID
);
UINTN
EFIAPI
ArmReadIdPfr1 (
VOID
);
#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

@@ -1,7 +1,7 @@
/** @file
Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
Copyright (c) 2011 - 2021, ARM Ltd. All rights reserved.<BR>
Copyright (c) 2011 - 2014, ARM Ltd. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -10,6 +10,8 @@
#include <Base.h>
#include <Library/ArmLib.h>
#include <Library/DebugLib.h>
#include <Library/PcdLib.h>
#include "ArmLibPrivate.h"
@@ -19,7 +21,9 @@ ArmSetAuxCrBit (
IN UINT32 Bits
)
{
ArmWriteAuxCr(ArmReadAuxCr() | Bits);
UINT32 val = ArmReadAuxCr();
val |= Bits;
ArmWriteAuxCr(val);
}
VOID
@@ -28,7 +32,9 @@ ArmUnsetAuxCrBit (
IN UINT32 Bits
)
{
ArmWriteAuxCr(ArmReadAuxCr() & ~Bits);
UINT32 val = ArmReadAuxCr();
val &= ~Bits;
ArmWriteAuxCr(val);
}
//
@@ -41,7 +47,10 @@ ArmSetCpuActlrBit (
IN UINTN Bits
)
{
ArmWriteCpuActlr (ArmReadCpuActlr () | Bits);
UINTN Value;
Value = ArmReadCpuActlr ();
Value |= Bits;
ArmWriteCpuActlr (Value);
}
VOID
@@ -50,7 +59,10 @@ ArmUnsetCpuActlrBit (
IN UINTN Bits
)
{
ArmWriteCpuActlr (ArmReadCpuActlr () & ~Bits);
UINTN Value;
Value = ArmReadCpuActlr ();
Value &= ~Bits;
ArmWriteCpuActlr (Value);
}
UINTN

View File

@@ -1,7 +1,5 @@
/** @file
ArmLibPrivate.h
Copyright (c) 2020, NUVIA Inc. All rights reserved.<BR>
Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -52,101 +50,6 @@
#define CACHE_ARCHITECTURE_UNIFIED (0UL)
#define CACHE_ARCHITECTURE_SEPARATE (1UL)
/// Defines the structure of the CSSELR (Cache Size Selection) register
typedef union {
struct {
UINT32 InD :1; ///< Instruction not Data bit
UINT32 Level :3; ///< Cache level (zero based)
UINT32 TnD :1; ///< Allocation not Data bit
UINT32 Reserved :27; ///< Reserved, RES0
} Bits; ///< Bitfield definition of the register
UINT32 Data; ///< The entire 32-bit value
} CSSELR_DATA;
/// The cache type values for the InD field of the CSSELR register
typedef enum
{
/// Select the data or unified cache
CsselrCacheTypeDataOrUnified = 0,
/// Select the instruction cache
CsselrCacheTypeInstruction,
CsselrCacheTypeMax
} CSSELR_CACHE_TYPE;
/// Defines the structure of the CCSIDR (Current Cache Size ID) register
typedef union {
struct {
UINT64 LineSize :3; ///< Line size (Log2(Num bytes in cache) - 4)
UINT64 Associativity :10; ///< Associativity - 1
UINT64 NumSets :15; ///< Number of sets in the cache -1
UINT64 Unknown :4; ///< Reserved, UNKNOWN
UINT64 Reserved :32; ///< Reserved, RES0
} BitsNonCcidx; ///< Bitfield definition of the register when FEAT_CCIDX is not supported.
struct {
UINT64 LineSize :3; ///< Line size (Log2(Num bytes in cache) - 4)
UINT64 Associativity :21; ///< Associativity - 1
UINT64 Reserved1 :8; ///< Reserved, RES0
UINT64 NumSets :24; ///< Number of sets in the cache -1
UINT64 Reserved2 :8; ///< Reserved, RES0
} BitsCcidxAA64; ///< Bitfield definition of the register when FEAT_IDX is supported.
struct {
UINT64 LineSize : 3;
UINT64 Associativity : 21;
UINT64 Reserved : 8;
UINT64 Unallocated : 32;
} BitsCcidxAA32;
UINT64 Data; ///< The entire 64-bit value
} CCSIDR_DATA;
/// Defines the structure of the AARCH32 CCSIDR2 register.
typedef union {
struct {
UINT32 NumSets :24; ///< Number of sets in the cache - 1
UINT32 Reserved :8; ///< Reserved, RES0
} Bits; ///< Bitfield definition of the register
UINT32 Data; ///< The entire 32-bit value
} CCSIDR2_DATA;
/** Defines the structure of the CLIDR (Cache Level ID) register.
*
* The lower 32 bits are the same for both AARCH32 and AARCH64
* so we can use the same structure for both.
**/
typedef union {
struct {
UINT32 Ctype1 : 3; ///< Level 1 cache type
UINT32 Ctype2 : 3; ///< Level 2 cache type
UINT32 Ctype3 : 3; ///< Level 3 cache type
UINT32 Ctype4 : 3; ///< Level 4 cache type
UINT32 Ctype5 : 3; ///< Level 5 cache type
UINT32 Ctype6 : 3; ///< Level 6 cache type
UINT32 Ctype7 : 3; ///< Level 7 cache type
UINT32 LoUIS : 3; ///< Level of Unification Inner Shareable
UINT32 LoC : 3; ///< Level of Coherency
UINT32 LoUU : 3; ///< Level of Unification Uniprocessor
UINT32 Icb : 3; ///< Inner Cache Boundary
} Bits; ///< Bitfield definition of the register
UINT32 Data; ///< The entire 32-bit value
} CLIDR_DATA;
/// The cache types reported in the CLIDR register.
typedef enum {
/// No cache is present
ClidrCacheTypeNone = 0,
/// There is only an instruction cache
ClidrCacheTypeInstructionOnly,
/// There is only a data cache
ClidrCacheTypeDataOnly,
/// There are separate data and instruction caches
ClidrCacheTypeSeparate,
/// There is a unified cache
ClidrCacheTypeUnified,
ClidrCacheTypeMax
} CLIDR_CACHE_TYPE;
#define CLIDR_GET_CACHE_TYPE(x, level) ((x >> (3 * (level))) & 0b111)
VOID
CPSRMaskInsert (
IN UINT32 Mask,
@@ -158,26 +61,8 @@ CPSRRead (
VOID
);
/** Reads the CCSIDR register for the specified cache.
@param CSSELR The CSSELR cache selection register value.
@return The contents of the CCSIDR_EL1 register for the specified cache, when in AARCH64 mode.
Returns the contents of the CCSIDR register in AARCH32 mode.
**/
UINTN
ReadCCSIDR (
IN UINT32 CSSELR
);
/** Reads the CCSIDR2 for the specified cache.
@param CSSELR The CSSELR cache selection register value
@return The contents of the CCSIDR2 register for the specified cache.
**/
UINT32
ReadCCSIDR2 (
ReadCCSIDR (
IN UINT32 CSSELR
);

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) != 0) {
// 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

@@ -1,10 +1,10 @@
/** @file
Copyright (c) 2016, Linaro Limited. All rights reserved.
Copyright (c) 2021, Arm Limited. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
*/
#/* @file
#
# Copyright (c) 2016, Linaro Limited. All rights reserved.
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
#*/
#include <Base.h>
@@ -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,437 +0,0 @@
/** @file
* File managing the MMU for ARMv7 architecture
*
* Copyright (c) 2011-2021, Arm Limited. All rights reserved.<BR>
*
* 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) != 0) {
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) != 0) {
// 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) != 0) {
// 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) != 0) {
// 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) != 0) {
// 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) != 0) {
// catch unsupported memory type attributes
ASSERT (FALSE);
return EFI_UNSUPPORTED;
}
if ((Attributes & EFI_MEMORY_RO) != 0) {
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;
UINT32 EntryMask;
UINT32 EntryValue;
UINT32 FirstLevelIdx;
UINT32 NumSections;
UINT32 i;
UINT32 CurrentDescriptor;
UINT32 Descriptor;
VOID *Mva;
volatile ARM_FIRST_LEVEL_DESCRIPTOR *FirstLevelTable;
Status = EFI_SUCCESS;
// 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) != 0) {
// 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) != 0) {
// 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) != 0) {
// 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) != 0) {
// 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) != 0) {
// catch unsupported memory type attributes
ASSERT (FALSE);
return EFI_UNSUPPORTED;
}
if ((Attributes & EFI_MEMORY_RO) != 0) {
EntryValue |= TT_DESCRIPTOR_SECTION_AP_RO_RO;
} else {
EntryValue |= TT_DESCRIPTOR_SECTION_AP_RW_RW;
}
if ((Attributes & EFI_MEMORY_XP) != 0) {
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,19 +25,14 @@ 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]
// Store the SVC returned values into the ARM_SVC_ARGS structure.
// A SVC call can return up to 8 values
// A SVC call can return up to 4 values - we do not need to store back x4-x7.
stp x0, x1, [x9, #0]
stp x2, x3, [x9, #16]
stp x4, x5, [x9, #32]
stp x6, x7, [x9, #48]
mov x0, x9

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,7 +1,6 @@
//------------------------------------------------------------------------------
//
// Copyright (c) 2019, Pete Batard. All rights reserved.
// Copyright (c) 2021, Arm Limited. All rights reserved.<BR>
//
// SPDX-License-Identifier: BSD-2-Clause-Patent
//
@@ -18,13 +17,10 @@ int memcmp(void *, void *, size_t);
#pragma function(memcmp)
int memcmp(const void *s1, const void *s2, size_t n)
{
unsigned char const *t1;
unsigned char const *t2;
unsigned char const *t1 = s1;
unsigned char const *t2 = s2;
t1 = s1;
t2 = s2;
while (n-- != 0) {
while (n--) {
if (*t1 != *t2)
return (int)*t1 - (int)*t2;
t1++;

View File

@@ -1,7 +1,6 @@
//------------------------------------------------------------------------------
//
// Copyright (c) 2016, Linaro Ltd. All rights reserved.<BR>
// Copyright (c) 2021, Arm Limited. All rights reserved.<BR>
//
// SPDX-License-Identifier: BSD-2-Clause-Patent
//
@@ -11,15 +10,11 @@ typedef __SIZE_TYPE__ size_t;
static void __memcpy(void *dest, const void *src, size_t n)
{
unsigned char *d;
unsigned char const *s;
unsigned char *d = dest;
unsigned char const *s = src;
d = dest;
s = src;
while (n-- != 0) {
while (n--)
*d++ = *s++;
}
}
void *memcpy(void *dest, const void *src, size_t n)

View File

@@ -1,7 +1,6 @@
//------------------------------------------------------------------------------
//
// Copyright (c) 2017, Pete Batard. All rights reserved.<BR>
// Copyright (c) 2021, Arm Limited. All rights reserved.<BR>
//
// SPDX-License-Identifier: BSD-2-Clause-Patent
//
@@ -18,15 +17,11 @@ void* memcpy(void *, const void *, size_t);
#pragma function(memcpy)
void* memcpy(void *dest, const void *src, size_t n)
{
unsigned char *d;
unsigned char const *s;
unsigned char *d = dest;
unsigned char const *s = src;
d = dest;
s = src;
while (n-- != 0) {
while (n--)
*d++ = *s++;
}
return dest;
}

View File

@@ -1,7 +1,6 @@
//------------------------------------------------------------------------------
//
// Copyright (c) 2019, Pete Batard. All rights reserved.
// Copyright (c) 2021, Arm Limited. All rights reserved.<BR>
//
// SPDX-License-Identifier: BSD-2-Clause-Patent
//
@@ -18,22 +17,17 @@ void* memmove(void *, const void *, size_t);
#pragma function(memmove)
void* memmove(void *dest, const void *src, size_t n)
{
unsigned char *d;
unsigned char const *s;
d = dest;
s = src;
unsigned char *d = dest;
unsigned char const *s = src;
if (d < s) {
while (n-- != 0) {
while (n--)
*d++ = *s++;
}
} else {
d += n;
s += n;
while (n-- != 0) {
while (n--)
*--d = *--s;
}
}
return dest;

View File

@@ -1,59 +1,55 @@
//------------------------------------------------------------------------------
//
// Copyright (c) 2016, Linaro Ltd. All rights reserved.<BR>
// Copyright (c) 2021, Arm Limited. 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;
d = s;
while (n-- != 0) {
*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,7 +1,6 @@
//------------------------------------------------------------------------------
//
// Copyright (c) 2017, Pete Batard. All rights reserved.<BR>
// Copyright (c) 2021, Arm Limited. All rights reserved.<BR>
//
// SPDX-License-Identifier: BSD-2-Clause-Patent
//
@@ -18,13 +17,10 @@ void* memset(void *, int, size_t);
#pragma function(memset)
void *memset(void *s, int c, size_t n)
{
unsigned char *d;
unsigned char *d = s;
d = s;
while (n-- != 0) {
while (n--)
*d++ = (unsigned char)c;
}
return s;
}

View File

@@ -2,7 +2,7 @@
Default exception handler
Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
Copyright (c) 2012 - 2021, Arm Ltd. All rights reserved.<BR>
Copyright (c) 2012, ARM Ltd. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -34,20 +34,6 @@ typedef struct {
CHAR8 Char;
} CPSR_CHAR;
STATIC CONST CPSR_CHAR mCpsrChar[] = {
{ 31, 'n' },
{ 30, 'z' },
{ 29, 'c' },
{ 28, 'v' },
{ 9, 'e' },
{ 8, 'a' },
{ 7, 'i' },
{ 6, 'f' },
{ 5, 't' },
{ 0, '?' }
};
CHAR8 *
GetImageName (
IN UINTN FaultAddress,
@@ -59,7 +45,7 @@ GetImageName (
Convert the Current Program Status Register (CPSR) to a string. The string is
a defacto standard in the ARM world.
It is possible to add extra bits by adding them to mCpsrChar array.
It is possible to add extra bits by adding them to CpsrChar array.
@param Cpsr ARM CPSR register value
@param ReturnStr CPSR_STRING_SIZE byte string that contains string
@@ -75,12 +61,25 @@ CpsrString (
UINTN Index;
CHAR8* Str;
CHAR8* ModeStr;
CPSR_CHAR CpsrChar[] = {
{ 31, 'n' },
{ 30, 'z' },
{ 29, 'c' },
{ 28, 'v' },
{ 9, 'e' },
{ 8, 'a' },
{ 7, 'i' },
{ 6, 'f' },
{ 5, 't' },
{ 0, '?' }
};
Str = ReturnStr;
for (Index = 0; mCpsrChar[Index].BIT != 0; Index++, Str++) {
*Str = mCpsrChar[Index].Char;
if ((Cpsr & (1 << mCpsrChar[Index].BIT)) != 0) {
for (Index = 0; CpsrChar[Index].BIT != 0; Index++, Str++) {
*Str = CpsrChar[Index].Char;
if ((Cpsr & (1 << CpsrChar[Index].BIT)) != 0) {
// Concert to upper case if bit is set
*Str &= ~0x20;
}
@@ -187,9 +186,7 @@ DefaultExceptionHandler (
UINT32 DfsrStatus;
UINT32 IfsrStatus;
BOOLEAN DfsrWrite;
UINT32 PcAdjust;
PcAdjust = 0;
UINT32 PcAdjust = 0;
CharCount = AsciiSPrint (Buffer,sizeof (Buffer),"\n%a Exception PC at 0x%08x CPSR 0x%08x ",
gExceptionTypeString[ExceptionType], SystemContext.SystemContextArm->PC, SystemContext.SystemContextArm->CPSR);

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

@@ -3,7 +3,6 @@
secure monitor calls.
Copyright (c) 2018, Linaro Ltd. All rights reserved.<BR>
Copyright (c) 2021, Arm Limited. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -228,7 +227,7 @@ OpteeOpenSession (
MessageArg->NumParams = 2;
if (OpteeCallWithArg ((UINTN)MessageArg) != 0) {
if (OpteeCallWithArg ((UINTN)MessageArg)) {
MessageArg->Return = OPTEE_ERROR_COMMUNICATION;
MessageArg->ReturnOrigin = OPTEE_ORIGIN_COMMUNICATION;
}
@@ -432,7 +431,7 @@ OpteeInvokeFunction (
MessageArg->NumParams = OPTEE_MAX_CALL_PARAMS;
if (OpteeCallWithArg ((UINTN)MessageArg) != 0) {
if (OpteeCallWithArg ((UINTN)MessageArg)) {
MessageArg->Return = OPTEE_ERROR_COMMUNICATION;
MessageArg->ReturnOrigin = OPTEE_ORIGIN_COMMUNICATION;
}
@@ -441,7 +440,7 @@ OpteeInvokeFunction (
InvokeFunctionArg->Params,
OPTEE_MAX_CALL_PARAMS,
MessageArg->Params
) != 0) {
)) {
MessageArg->Return = OPTEE_ERROR_COMMUNICATION;
MessageArg->ReturnOrigin = OPTEE_ORIGIN_COMMUNICATION;
}

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,53 +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.
// *Unless* persistent varstore is being emulated, since we would
// then end up in an endless reboot loop.
//
if (!PcdGetBool (PcdEmuVariableNvModeEnable)) {
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

@@ -55,7 +55,6 @@
gEfiMdePkgTokenSpaceGuid.PcdUgaConsumeSupport
[FixedPcd]
gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvModeEnable
gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVersionString
gEfiMdePkgTokenSpaceGuid.PcdUartDefaultBaudRate
gEfiMdePkgTokenSpaceGuid.PcdUartDefaultDataBits
@@ -67,9 +66,6 @@
gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut
[Guids]
gEdkiiNonDiscoverableEhciDeviceGuid
gEdkiiNonDiscoverableUhciDeviceGuid
gEdkiiNonDiscoverableXhciDeviceGuid
gEfiFileInfoGuid
gEfiFileSystemInfoGuid
gEfiFileSystemVolumeLabelInfoIdGuid
@@ -78,7 +74,6 @@
gUefiShellFileGuid
[Protocols]
gEdkiiNonDiscoverableDeviceProtocolGuid
gEfiDevicePathProtocolGuid
gEfiGraphicsOutputProtocolGuid
gEfiLoadedImageProtocolGuid

View File

@@ -2,7 +2,6 @@
Serial I/O Port library functions with no library constructor/destructor
Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
Copyright (c) 2021, Arm Limited. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -56,13 +55,10 @@ SerialPortWrite (
)
{
UINT8 PrintBuffer[PRINT_BUFFER_SIZE];
UINTN SourceIndex;
UINTN DestinationIndex;
UINTN SourceIndex = 0;
UINTN DestinationIndex = 0;
UINT8 CurrentCharacter;
SourceIndex = 0;
DestinationIndex = 0;
while (SourceIndex < NumberOfBytes)
{
CurrentCharacter = Buffer[SourceIndex++];

View File

@@ -1,7 +1,7 @@
/** @file
Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
Copyright (c) 2013 - 2021, Arm Limited. All rights reserved.<BR>
Copyright (c) 2013 - 2014, ARM Ltd. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -135,7 +135,9 @@ SemihostFileClose (
IN UINTN FileHandle
)
{
if (Semihost_SYS_CLOSE (&FileHandle) == -1) {
INT32 Result = Semihost_SYS_CLOSE(&FileHandle);
if (Result == -1) {
return RETURN_INVALID_PARAMETER;
} else {
return RETURN_SUCCESS;

View File

@@ -1,149 +1,21 @@
/** @file
File managing the MMU for ARMv8 architecture in S-EL0
Copyright (c) 2017 - 2021, Arm Limited. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
@par Reference(s):
- [1] SPM based on the MM interface.
(https://trustedfirmware-a.readthedocs.io/en/latest/components/
secure-partition-manager-mm.html)
- [2] Arm Firmware Framework for Armv8-A, DEN0077A, version 1.0
(https://developer.arm.com/documentation/den0077/a)
* File managing the MMU for ARMv8 architecture in S-EL0
*
* Copyright (c) 2017 - 2018, ARM Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-2-Clause-Patent
*
**/
#include <Uefi.h>
#include <IndustryStandard/ArmMmSvc.h>
#include <IndustryStandard/ArmFfaSvc.h>
#include <Library/ArmLib.h>
#include <Library/ArmMmuLib.h>
#include <Library/ArmSvcLib.h>
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/PcdLib.h>
/** Send memory permission request to target.
@param [in, out] SvcArgs Pointer to SVC arguments to send. On
return it contains the response parameters.
@param [out] RetVal Pointer to return the response value.
@retval EFI_SUCCESS Request successfull.
@retval EFI_INVALID_PARAMETER A parameter is invalid.
@retval EFI_NOT_READY Callee is busy or not in a state to handle
this request.
@retval EFI_UNSUPPORTED This function is not implemented by the
callee.
@retval EFI_ABORTED Message target ran into an unexpected error
and has aborted.
@retval EFI_ACCESS_DENIED Access denied.
@retval EFI_OUT_OF_RESOURCES Out of memory to perform operation.
**/
STATIC
EFI_STATUS
SendMemoryPermissionRequest (
IN OUT ARM_SVC_ARGS *SvcArgs,
OUT INT32 *RetVal
)
{
if ((SvcArgs == NULL) || (RetVal == NULL)) {
return EFI_INVALID_PARAMETER;
}
ArmCallSvc (SvcArgs);
if (FeaturePcdGet (PcdFfaEnable)) {
// Get/Set memory attributes is an atomic call, with
// StandaloneMm at S-EL0 being the caller and the SPM
// core being the callee. Thus there won't be a
// FFA_INTERRUPT or FFA_SUCCESS response to the Direct
// Request sent above. This will have to be considered
// for other Direct Request calls which are not atomic
// We therefore check only for Direct Response by the
// callee.
if (SvcArgs->Arg0 == ARM_SVC_ID_FFA_MSG_SEND_DIRECT_RESP_AARCH64) {
// A Direct Response means FF-A success
// Now check the payload for errors
// The callee sends back the return value
// in Arg3
*RetVal = SvcArgs->Arg3;
} else {
// If Arg0 is not a Direct Response, that means we
// have an FF-A error. We need to check Arg2 for the
// FF-A error code.
// See [2], Table 10.8: FFA_ERROR encoding.
*RetVal = SvcArgs->Arg2;
switch (*RetVal) {
case ARM_FFA_SPM_RET_INVALID_PARAMETERS:
return EFI_INVALID_PARAMETER;
case ARM_FFA_SPM_RET_DENIED:
return EFI_ACCESS_DENIED;
case ARM_FFA_SPM_RET_NOT_SUPPORTED:
return EFI_UNSUPPORTED;
case ARM_FFA_SPM_RET_BUSY:
return EFI_NOT_READY;
case ARM_FFA_SPM_RET_ABORTED:
return EFI_ABORTED;
default:
// Undefined error code received.
ASSERT (0);
return EFI_INVALID_PARAMETER;
}
}
} else {
*RetVal = SvcArgs->Arg0;
}
// Check error response from Callee.
if (*RetVal & BIT31) {
// Bit 31 set means there is an error retured
// See [1], Section 13.5.5.1 MM_SP_MEMORY_ATTRIBUTES_GET_AARCH64 and
// Section 13.5.5.2 MM_SP_MEMORY_ATTRIBUTES_SET_AARCH64.
switch (*RetVal) {
case ARM_SVC_SPM_RET_NOT_SUPPORTED:
return EFI_UNSUPPORTED;
case ARM_SVC_SPM_RET_INVALID_PARAMS:
return EFI_INVALID_PARAMETER;
case ARM_SVC_SPM_RET_DENIED:
return EFI_ACCESS_DENIED;
case ARM_SVC_SPM_RET_NO_MEMORY:
return EFI_OUT_OF_RESOURCES;
default:
// Undefined error code received.
ASSERT (0);
return EFI_INVALID_PARAMETER;
}
}
return EFI_SUCCESS;
}
/** Request the permission attributes of a memory region from S-EL0.
@param [in] BaseAddress Base address for the memory region.
@param [out] MemoryAttributes Pointer to return the memory attributes.
@retval EFI_SUCCESS Request successfull.
@retval EFI_INVALID_PARAMETER A parameter is invalid.
@retval EFI_NOT_READY Callee is busy or not in a state to handle
this request.
@retval EFI_UNSUPPORTED This function is not implemented by the
callee.
@retval EFI_ABORTED Message target ran into an unexpected error
and has aborted.
@retval EFI_ACCESS_DENIED Access denied.
@retval EFI_OUT_OF_RESOURCES Out of memory to perform operation.
**/
STATIC
EFI_STATUS
GetMemoryPermissions (
@@ -151,89 +23,70 @@ GetMemoryPermissions (
OUT UINT32 *MemoryAttributes
)
{
EFI_STATUS Status;
INT32 Ret;
ARM_SVC_ARGS SvcArgs;
ARM_SVC_ARGS GetMemoryPermissionsSvcArgs = {0};
if (MemoryAttributes == NULL) {
GetMemoryPermissionsSvcArgs.Arg0 = ARM_SVC_ID_SP_GET_MEM_ATTRIBUTES_AARCH64;
GetMemoryPermissionsSvcArgs.Arg1 = BaseAddress;
GetMemoryPermissionsSvcArgs.Arg2 = 0;
GetMemoryPermissionsSvcArgs.Arg3 = 0;
ArmCallSvc (&GetMemoryPermissionsSvcArgs);
if (GetMemoryPermissionsSvcArgs.Arg0 == ARM_SVC_SPM_RET_INVALID_PARAMS) {
*MemoryAttributes = 0;
return EFI_INVALID_PARAMETER;
}
// Prepare the message parameters.
// See [1], Section 13.5.5.1 MM_SP_MEMORY_ATTRIBUTES_GET_AARCH64.
ZeroMem (&SvcArgs, sizeof (ARM_SVC_ARGS));
if (FeaturePcdGet (PcdFfaEnable)) {
// See [2], Section 10.2 FFA_MSG_SEND_DIRECT_REQ.
SvcArgs.Arg0 = ARM_SVC_ID_FFA_MSG_SEND_DIRECT_REQ_AARCH64;
SvcArgs.Arg1 = ARM_FFA_DESTINATION_ENDPOINT_ID;
SvcArgs.Arg2 = 0;
SvcArgs.Arg3 = ARM_SVC_ID_SP_GET_MEM_ATTRIBUTES_AARCH64;
SvcArgs.Arg4 = BaseAddress;
} else {
SvcArgs.Arg0 = ARM_SVC_ID_SP_GET_MEM_ATTRIBUTES_AARCH64;
SvcArgs.Arg1 = BaseAddress;
SvcArgs.Arg2 = 0;
SvcArgs.Arg3 = 0;
}
Status = SendMemoryPermissionRequest (&SvcArgs, &Ret);
if (EFI_ERROR (Status)) {
*MemoryAttributes = 0;
return Status;
}
*MemoryAttributes = Ret;
return Status;
*MemoryAttributes = GetMemoryPermissionsSvcArgs.Arg0;
return EFI_SUCCESS;
}
/** Set the permission attributes of a memory region from S-EL0.
@param [in] BaseAddress Base address for the memory region.
@param [in] Length Length of the memory region.
@param [in] Permissions Memory access controls attributes.
@retval EFI_SUCCESS Request successfull.
@retval EFI_INVALID_PARAMETER A parameter is invalid.
@retval EFI_NOT_READY Callee is busy or not in a state to handle
this request.
@retval EFI_UNSUPPORTED This function is not implemented by the
callee.
@retval EFI_ABORTED Message target ran into an unexpected error
and has aborted.
@retval EFI_ACCESS_DENIED Access denied.
@retval EFI_OUT_OF_RESOURCES Out of memory to perform operation.
**/
STATIC
EFI_STATUS
RequestMemoryPermissionChange (
IN EFI_PHYSICAL_ADDRESS BaseAddress,
IN UINT64 Length,
IN UINT32 Permissions
IN UINTN Permissions
)
{
INT32 Ret;
ARM_SVC_ARGS SvcArgs;
EFI_STATUS Status;
ARM_SVC_ARGS ChangeMemoryPermissionsSvcArgs = {0};
// Prepare the message parameters.
// See [1], Section 13.5.5.2 MM_SP_MEMORY_ATTRIBUTES_SET_AARCH64.
ZeroMem (&SvcArgs, sizeof (ARM_SVC_ARGS));
if (FeaturePcdGet (PcdFfaEnable)) {
// See [2], Section 10.2 FFA_MSG_SEND_DIRECT_REQ.
SvcArgs.Arg0 = ARM_SVC_ID_FFA_MSG_SEND_DIRECT_REQ_AARCH64;
SvcArgs.Arg1 = ARM_FFA_DESTINATION_ENDPOINT_ID;
SvcArgs.Arg2 = 0;
SvcArgs.Arg3 = ARM_SVC_ID_SP_SET_MEM_ATTRIBUTES_AARCH64;
SvcArgs.Arg4 = BaseAddress;
SvcArgs.Arg5 = EFI_SIZE_TO_PAGES (Length);
SvcArgs.Arg6 = Permissions;
} else {
SvcArgs.Arg0 = ARM_SVC_ID_SP_SET_MEM_ATTRIBUTES_AARCH64;
SvcArgs.Arg1 = BaseAddress;
SvcArgs.Arg2 = EFI_SIZE_TO_PAGES (Length);
SvcArgs.Arg3 = Permissions;
ChangeMemoryPermissionsSvcArgs.Arg0 = ARM_SVC_ID_SP_SET_MEM_ATTRIBUTES_AARCH64;
ChangeMemoryPermissionsSvcArgs.Arg1 = BaseAddress;
ChangeMemoryPermissionsSvcArgs.Arg2 = EFI_SIZE_TO_PAGES(Length);
ChangeMemoryPermissionsSvcArgs.Arg3 = Permissions;
ArmCallSvc (&ChangeMemoryPermissionsSvcArgs);
Status = ChangeMemoryPermissionsSvcArgs.Arg0;
switch (Status) {
case ARM_SVC_SPM_RET_SUCCESS:
Status = EFI_SUCCESS;
break;
case ARM_SVC_SPM_RET_NOT_SUPPORTED:
Status = EFI_UNSUPPORTED;
break;
case ARM_SVC_SPM_RET_INVALID_PARAMS:
Status = EFI_INVALID_PARAMETER;
break;
case ARM_SVC_SPM_RET_DENIED:
Status = EFI_ACCESS_DENIED;
break;
case ARM_SVC_SPM_RET_NO_MEMORY:
Status = EFI_BAD_BUFFER_SIZE;
break;
default:
Status = EFI_ACCESS_DENIED;
ASSERT (0);
}
return SendMemoryPermissionRequest (&SvcArgs, &Ret);
return Status;
}
EFI_STATUS
@@ -247,7 +100,7 @@ ArmSetMemoryRegionNoExec (
UINT32 CodePermission;
Status = GetMemoryPermissions (BaseAddress, &MemoryAttributes);
if (!EFI_ERROR (Status)) {
if (Status != EFI_INVALID_PARAMETER) {
CodePermission = SET_MEM_ATTR_CODE_PERM_XN << SET_MEM_ATTR_CODE_PERM_SHIFT;
return RequestMemoryPermissionChange (
BaseAddress,
@@ -255,7 +108,7 @@ ArmSetMemoryRegionNoExec (
MemoryAttributes | CodePermission
);
}
return Status;
return EFI_INVALID_PARAMETER;
}
EFI_STATUS
@@ -269,7 +122,7 @@ ArmClearMemoryRegionNoExec (
UINT32 CodePermission;
Status = GetMemoryPermissions (BaseAddress, &MemoryAttributes);
if (!EFI_ERROR (Status)) {
if (Status != EFI_INVALID_PARAMETER) {
CodePermission = SET_MEM_ATTR_CODE_PERM_XN << SET_MEM_ATTR_CODE_PERM_SHIFT;
return RequestMemoryPermissionChange (
BaseAddress,
@@ -277,7 +130,7 @@ ArmClearMemoryRegionNoExec (
MemoryAttributes & ~CodePermission
);
}
return Status;
return EFI_INVALID_PARAMETER;
}
EFI_STATUS
@@ -291,7 +144,7 @@ ArmSetMemoryRegionReadOnly (
UINT32 DataPermission;
Status = GetMemoryPermissions (BaseAddress, &MemoryAttributes);
if (!EFI_ERROR (Status)) {
if (Status != EFI_INVALID_PARAMETER) {
DataPermission = SET_MEM_ATTR_DATA_PERM_RO << SET_MEM_ATTR_DATA_PERM_SHIFT;
return RequestMemoryPermissionChange (
BaseAddress,
@@ -299,7 +152,7 @@ ArmSetMemoryRegionReadOnly (
MemoryAttributes | DataPermission
);
}
return Status;
return EFI_INVALID_PARAMETER;
}
EFI_STATUS
@@ -313,7 +166,7 @@ ArmClearMemoryRegionReadOnly (
UINT32 PermissionRequest;
Status = GetMemoryPermissions (BaseAddress, &MemoryAttributes);
if (!EFI_ERROR (Status)) {
if (Status != EFI_INVALID_PARAMETER) {
PermissionRequest = SET_MEM_ATTR_MAKE_PERM_REQUEST (SET_MEM_ATTR_DATA_PERM_RW,
MemoryAttributes);
return RequestMemoryPermissionChange (
@@ -322,5 +175,5 @@ ArmClearMemoryRegionReadOnly (
PermissionRequest
);
}
return Status;
return EFI_INVALID_PARAMETER;
}

View File

@@ -23,9 +23,6 @@
ArmPkg/ArmPkg.dec
MdePkg/MdePkg.dec
[FeaturePcd.AARCH64]
gArmTokenSpaceGuid.PcdFfaEnable
[LibraryClasses]
ArmLib
CacheMaintenanceLib

View File

@@ -1,141 +0,0 @@
/** @file
* OemMiscLib.c
*
* Copyright (c) 2021, NUVIA Inc. All rights reserved.
* Copyright (c) 2018, Hisilicon Limited. All rights reserved.
* Copyright (c) 2018, Linaro Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-2-Clause-Patent
*
**/
#include <Uefi.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/HiiLib.h>
#include <Library/OemMiscLib.h>
/** Gets the CPU frequency of the specified processor.
@param ProcessorIndex Index of the processor to get the frequency for.
@return CPU frequency in Hz
**/
UINTN
EFIAPI
OemGetCpuFreq (
IN UINT8 ProcessorIndex
)
{
ASSERT (FALSE);
return 0;
}
/** Gets information about the specified processor and stores it in
the structures provided.
@param ProcessorIndex Index of the processor to get the information for.
@param ProcessorStatus Processor status.
@param ProcessorCharacteristics Processor characteritics.
@param MiscProcessorData Miscellaneous processor information.
@return TRUE on success, FALSE on failure.
**/
BOOLEAN
EFIAPI
OemGetProcessorInformation (
IN UINTN ProcessorIndex,
IN OUT PROCESSOR_STATUS_DATA *ProcessorStatus,
IN OUT PROCESSOR_CHARACTERISTIC_FLAGS *ProcessorCharacteristics,
IN OUT OEM_MISC_PROCESSOR_DATA *MiscProcessorData
)
{
ASSERT (FALSE);
return TRUE;
}
/** Gets information about the cache at the specified cache level.
@param ProcessorIndex The processor to get information for.
@param CacheLevel The cache level to get information for.
@param DataCache Whether the cache is a data cache.
@param UnifiedCache Whether the cache is a unified cache.
@param SmbiosCacheTable The SMBIOS Type7 cache information structure.
@return TRUE on success, FALSE on failure.
**/
BOOLEAN
EFIAPI
OemGetCacheInformation (
IN UINT8 ProcessorIndex,
IN UINT8 CacheLevel,
IN BOOLEAN DataCache,
IN BOOLEAN UnifiedCache,
IN OUT SMBIOS_TABLE_TYPE7 *SmbiosCacheTable
)
{
ASSERT (FALSE);
return TRUE;
}
/** Gets the maximum number of processors supported by the platform.
@return The maximum number of processors.
**/
UINT8
EFIAPI
OemGetMaxProcessors (
VOID
)
{
ASSERT (FALSE);
return 1;
}
/** Gets the type of chassis for the system.
@retval The type of the chassis.
**/
MISC_CHASSIS_TYPE
EFIAPI
OemGetChassisType (
VOID
)
{
ASSERT (FALSE);
return MiscChassisTypeUnknown;
}
/** Returns whether the specified processor is present or not.
@param ProcessIndex The processor index to check.
@return TRUE is the processor is present, FALSE otherwise.
**/
BOOLEAN
EFIAPI
OemIsProcessorPresent (
IN UINTN ProcessorIndex
)
{
ASSERT (FALSE);
return FALSE;
}
/** Updates the HII string for the specified field.
@param HiiHandle The HII handle.
@param TokenToUpdate The string to update.
@param Field The field to get information about.
**/
VOID
EFIAPI
OemUpdateSmbiosInfo (
IN EFI_HII_HANDLE HiiHandle,
IN EFI_STRING_ID TokenToUpdate,
IN OEM_MISC_SMBIOS_HII_STRING_FIELD Field
)
{
ASSERT (FALSE);
}

View File

@@ -1,31 +0,0 @@
#/** @file
# OemMiscLib.inf
#
# Copyright (c) 2021, NUVIA Inc. All rights reserved.
# Copyright (c) 2018, Hisilicon Limited. All rights reserved.
# Copyright (c) 2018, Linaro Limited. All rights reserved.
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
#**/
[Defines]
INF_VERSION = 1.29
BASE_NAME = OemMiscLibNull
FILE_GUID = e80b8e6b-fffb-4c39-b433-41de67c9d7b8
MODULE_TYPE = BASE
VERSION_STRING = 1.0
LIBRARY_CLASS = OemMiscLib
[Sources.common]
OemMiscLib.c
[Packages]
ArmPkg/ArmPkg.dec
EmbeddedPkg/EmbeddedPkg.dec
MdeModulePkg/MdeModulePkg.dec
MdePkg/MdePkg.dec
[LibraryClasses]
BaseMemoryLib
DebugLib

View File

@@ -1,752 +0,0 @@
/** @file
ProcessorSubClass.c
Copyright (c) 2021, NUVIA Inc. All rights reserved.<BR>
Copyright (c) 2015, Hisilicon Limited. All rights reserved.
Copyright (c) 2015, Linaro Limited. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include <Uefi.h>
#include <Protocol/Smbios.h>
#include <IndustryStandard/ArmStdSmc.h>
#include <IndustryStandard/SmBios.h>
#include <Library/ArmLib.h>
#include <Library/ArmSmcLib.h>
#include <Library/ArmLib/ArmLibPrivate.h>
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/HiiLib.h>
#include <Library/IoLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/OemMiscLib.h>
#include <Library/PcdLib.h>
#include <Library/PrintLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiLib.h>
#include "SmbiosProcessor.h"
extern UINT8 ProcessorSubClassStrings[];
#define CACHE_SOCKETED_SHIFT 3
#define CACHE_LOCATION_SHIFT 5
#define CACHE_ENABLED_SHIFT 7
#define CACHE_OPERATION_MODE_SHIFT 8
typedef enum {
CacheModeWriteThrough = 0, ///< Cache is write-through
CacheModeWriteBack, ///< Cache is write-back
CacheModeVariesWithAddress, ///< Cache mode varies by address
CacheModeUnknown, ///< Cache mode is unknown
CacheModeMax
} CACHE_OPERATION_MODE;
typedef enum {
CacheLocationInternal = 0, ///< Cache is internal to the processor
CacheLocationExternal, ///< Cache is external to the processor
CacheLocationReserved, ///< Reserved
CacheLocationUnknown, ///< Cache location is unknown
CacheLocationMax
} CACHE_LOCATION;
EFI_HII_HANDLE mHiiHandle;
EFI_SMBIOS_PROTOCOL *mSmbios;
SMBIOS_TABLE_TYPE4 mSmbiosProcessorTableTemplate = {
{ // Hdr
EFI_SMBIOS_TYPE_PROCESSOR_INFORMATION, // Type
sizeof (SMBIOS_TABLE_TYPE4), // Length
0 // Handle
},
1, // Socket
CentralProcessor, // ProcessorType
ProcessorFamilyIndicatorFamily2, // ProcessorFamily
2, // ProcessorManufacture
{ // ProcessorId
{ // Signature
0
},
{ // FeatureFlags
0
}
},
3, // ProcessorVersion
{ // Voltage
0
},
0, // ExternalClock
0, // MaxSpeed
0, // CurrentSpeed
0, // Status
ProcessorUpgradeUnknown, // ProcessorUpgrade
0xFFFF, // L1CacheHandle
0xFFFF, // L2CacheHandle
0xFFFF, // L3CacheHandle
4, // SerialNumber
5, // AssetTag
6, // PartNumber
0, // CoreCount
0, //EnabledCoreCount
0, // ThreadCount
0, // ProcessorCharacteristics
ProcessorFamilyARM, // ProcessorFamily2
0, // CoreCount2
0, // EnabledCoreCount2
0 // ThreadCount2
};
/** Sets the HII variable `StringId` is `Pcd` isn't empty.
@param Pcd The FixedAtBuild PCD that contains the string to fetch.
@param StringId The string identifier to set.
**/
#define SET_HII_STRING_IF_PCD_NOT_EMPTY(Pcd, StringId) \
do { \
CHAR16 *Str; \
Str = (CHAR16*)PcdGetPtr (Pcd); \
if (StrLen (Str) > 0) { \
HiiSetString (mHiiHandle, StringId, Str, NULL); \
} \
} while (0)
/** Fetches the specified processor's frequency in Hz.
@param ProcessorNumber The processor number
@return The clock frequency in MHz
**/
UINT16
GetCpuFrequency (
IN UINT8 ProcessorNumber
)
{
return (UINT16)(OemGetCpuFreq (ProcessorNumber) / 1000 / 1000);
}
/** Gets a description of the specified cache.
@param[in] CacheLevel Zero-based cache level (e.g. L1 cache is 0).
@param[in] DataCache Cache is a data cache.
@param[in] UnifiedCache Cache is a unified cache.
@param[out] CacheSocketStr The description of the specified cache
@return The number of Unicode characters in CacheSocketStr not including the
terminating NUL.
**/
UINTN
GetCacheSocketStr (
IN UINT8 CacheLevel,
IN BOOLEAN DataCache,
IN BOOLEAN UnifiedCache,
OUT CHAR16 *CacheSocketStr
)
{
UINTN CacheSocketStrLen;
if (CacheLevel == CpuCacheL1 && !DataCache && !UnifiedCache) {
CacheSocketStrLen = UnicodeSPrint (
CacheSocketStr,
SMBIOS_STRING_MAX_LENGTH - 1,
L"L%x Instruction Cache",
CacheLevel);
} else if (CacheLevel == CpuCacheL1 && DataCache) {
CacheSocketStrLen = UnicodeSPrint (CacheSocketStr,
SMBIOS_STRING_MAX_LENGTH - 1,
L"L%x Data Cache",
CacheLevel);
} else {
CacheSocketStrLen = UnicodeSPrint (CacheSocketStr,
SMBIOS_STRING_MAX_LENGTH - 1,
L"L%x Cache",
CacheLevel);
}
return CacheSocketStrLen;
}
/** Fills in the Type 7 record with the cache architecture information
read from the CPU registers.
@param[in] CacheLevel Cache level (e.g. L1, L2).
@param[in] DataCache Cache is a data cache.
@param[in] UnifiedCache Cache is a unified cache.
@param[out] Type7Record The Type 7 record to fill in.
**/
VOID
ConfigureCacheArchitectureInformation (
IN UINT8 CacheLevel,
IN BOOLEAN DataCache,
IN BOOLEAN UnifiedCache,
OUT SMBIOS_TABLE_TYPE7 *Type7Record
)
{
UINT8 Associativity;
UINT32 CacheSize32;
UINT16 CacheSize16;
UINT64 CacheSize64;
if (!DataCache && !UnifiedCache) {
Type7Record->SystemCacheType = CacheTypeInstruction;
} else if (DataCache) {
Type7Record->SystemCacheType = CacheTypeData;
} else if (UnifiedCache) {
Type7Record->SystemCacheType = CacheTypeUnified;
} else {
ASSERT(FALSE);
}
CacheSize64 = SmbiosProcessorGetCacheSize (CacheLevel,
DataCache,
UnifiedCache
);
Associativity = SmbiosProcessorGetCacheAssociativity (CacheLevel,
DataCache,
UnifiedCache
);
CacheSize64 /= 1024; // Minimum granularity is 1K
// Encode the cache size into the format SMBIOS wants
if (CacheSize64 < MAX_INT16) {
CacheSize16 = CacheSize64;
CacheSize32 = CacheSize16;
} else if ((CacheSize64 / 64) < MAX_INT16) {
CacheSize16 = (1 << 15) | (CacheSize64 / 64);
CacheSize32 = CacheSize16;
} else {
if ((CacheSize64 / 1024) <= 2047) {
CacheSize32 = CacheSize64;
} else {
CacheSize32 = (1 << 31) | (CacheSize64 / 64);
}
CacheSize16 = -1;
}
Type7Record->MaximumCacheSize = CacheSize16;
Type7Record->InstalledSize = CacheSize16;
Type7Record->MaximumCacheSize2 = CacheSize32;
Type7Record->InstalledSize2 = CacheSize32;
switch (Associativity) {
case 2:
Type7Record->Associativity = CacheAssociativity2Way;
break;
case 4:
Type7Record->Associativity = CacheAssociativity4Way;
break;
case 8:
Type7Record->Associativity = CacheAssociativity8Way;
break;
case 12:
Type7Record->Associativity = CacheAssociativity12Way;
break;
case 16:
Type7Record->Associativity = CacheAssociativity16Way;
break;
case 20:
Type7Record->Associativity = CacheAssociativity20Way;
break;
case 24:
Type7Record->Associativity = CacheAssociativity24Way;
break;
case 32:
Type7Record->Associativity = CacheAssociativity32Way;
break;
case 48:
Type7Record->Associativity = CacheAssociativity48Way;
break;
case 64:
Type7Record->Associativity = CacheAssociativity64Way;
break;
default:
Type7Record->Associativity = CacheAssociativityOther;
break;
}
Type7Record->CacheConfiguration = (CacheModeUnknown << CACHE_OPERATION_MODE_SHIFT) |
(1 << CACHE_ENABLED_SHIFT) |
(CacheLocationUnknown << CACHE_LOCATION_SHIFT) |
(0 << CACHE_SOCKETED_SHIFT) |
(CacheLevel - 1);
}
/** Allocates and initializes an SMBIOS_TABLE_TYPE7 structure.
@param[in] CacheLevel The cache level (L1-L7).
@param[in] DataCache Cache is a data cache.
@param[in] UnifiedCache Cache is a unified cache.
@return A pointer to the Type 7 structure. Returns NULL on failure.
**/
SMBIOS_TABLE_TYPE7 *
AllocateAndInitCacheInformation (
IN UINT8 CacheLevel,
IN BOOLEAN DataCache,
IN BOOLEAN UnifiedCache
)
{
SMBIOS_TABLE_TYPE7 *Type7Record;
EFI_STRING CacheSocketStr;
UINTN CacheSocketStrLen;
UINTN StringBufferSize;
CHAR8 *OptionalStrStart;
UINTN TableSize;
// Allocate and fetch the cache description
StringBufferSize = sizeof (CHAR16) * SMBIOS_STRING_MAX_LENGTH;
CacheSocketStr = AllocateZeroPool (StringBufferSize);
if (CacheSocketStr == NULL) {
return NULL;
}
CacheSocketStrLen = GetCacheSocketStr (CacheLevel,
DataCache,
UnifiedCache,
CacheSocketStr);
TableSize = sizeof (SMBIOS_TABLE_TYPE7) + CacheSocketStrLen + 1 + 1;
Type7Record = AllocateZeroPool (TableSize);
if (Type7Record == NULL) {
FreePool(CacheSocketStr);
return NULL;
}
Type7Record->Hdr.Type = EFI_SMBIOS_TYPE_CACHE_INFORMATION;
Type7Record->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE7);
Type7Record->Hdr.Handle = SMBIOS_HANDLE_PI_RESERVED;
Type7Record->SocketDesignation = 1;
Type7Record->SupportedSRAMType.Unknown = 1;
Type7Record->CurrentSRAMType.Unknown = 1;
Type7Record->CacheSpeed = 0;
Type7Record->ErrorCorrectionType = CacheErrorUnknown;
OptionalStrStart = (CHAR8 *)(Type7Record + 1);
UnicodeStrToAsciiStrS (CacheSocketStr, OptionalStrStart, CacheSocketStrLen + 1);
FreePool (CacheSocketStr);
return Type7Record;
}
/**
Add Type 7 SMBIOS Record for Cache Information.
@param[in] ProcessorIndex Processor number of specified processor.
@param[out] L1CacheHandle Pointer to the handle of the L1 Cache SMBIOS record.
@param[out] L2CacheHandle Pointer to the handle of the L2 Cache SMBIOS record.
@param[out] L3CacheHandle Pointer to the handle of the L3 Cache SMBIOS record.
**/
VOID
AddSmbiosCacheTypeTable (
IN UINTN ProcessorIndex,
OUT EFI_SMBIOS_HANDLE *L1CacheHandle,
OUT EFI_SMBIOS_HANDLE *L2CacheHandle,
OUT EFI_SMBIOS_HANDLE *L3CacheHandle
)
{
EFI_STATUS Status;
SMBIOS_TABLE_TYPE7 *Type7Record;
EFI_SMBIOS_HANDLE SmbiosHandle;
UINT8 CacheLevel;
UINT8 MaxCacheLevel;
BOOLEAN DataCacheType;
BOOLEAN SeparateCaches;
Status = EFI_SUCCESS;
MaxCacheLevel = 0;
// See if there's an L1 cache present.
MaxCacheLevel = SmbiosProcessorGetMaxCacheLevel ();
if (MaxCacheLevel < 1) {
return;
}
for (CacheLevel = 1; CacheLevel <= MaxCacheLevel; CacheLevel++) {
Type7Record = NULL;
SeparateCaches = SmbiosProcessorHasSeparateCaches (CacheLevel);
// At each level of cache, we can have a single type (unified, instruction or data),
// or two types - separate data and instruction caches. If we have separate
// instruction and data caches, then on the first iteration (CacheSubLevel = 0)
// process the instruction cache.
for (DataCacheType = 0; DataCacheType <= 1; DataCacheType++) {
// If there's no separate data/instruction cache, skip the second iteration
if (DataCacheType == 1 && !SeparateCaches) {
continue;
}
Type7Record = AllocateAndInitCacheInformation (CacheLevel,
DataCacheType,
!SeparateCaches
);
if (Type7Record == NULL) {
continue;
}
ConfigureCacheArchitectureInformation(CacheLevel,
DataCacheType,
!SeparateCaches,
Type7Record
);
// Allow the platform to fill in other information such as speed, SRAM type etc.
if (!OemGetCacheInformation (ProcessorIndex, CacheLevel,
DataCacheType, !SeparateCaches, Type7Record)) {
continue;
}
SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
// Finally, install the table
Status = mSmbios->Add (mSmbios, NULL, &SmbiosHandle,
(EFI_SMBIOS_TABLE_HEADER *)Type7Record);
if (EFI_ERROR (Status)) {
continue;
}
// Config L1/L2/L3 Cache Handle
switch (CacheLevel) {
case CpuCacheL1:
*L1CacheHandle = SmbiosHandle;
break;
case CpuCacheL2:
*L2CacheHandle = SmbiosHandle;
break;
case CpuCacheL3:
*L3CacheHandle = SmbiosHandle;
break;
default:
break;
}
}
}
}
/** Allocates a Type 4 Processor Information structure and sets the
strings following the data fields.
@param[out] Type4Record The Type 4 structure to allocate and initialize
@param[in] ProcessorIndex The index of the processor
@param[in] Populated Whether the specified processor is
populated.
@retval EFI_SUCCESS The Type 4 structure was successfully
allocated and the strings initialized.
@retval EFI_OUT_OF_RESOURCES Could not allocate memory needed.
**/
EFI_STATUS
AllocateType4AndSetProcessorInformationStrings (
SMBIOS_TABLE_TYPE4 **Type4Record,
UINT8 ProcessorIndex,
BOOLEAN Populated
)
{
EFI_STATUS Status;
EFI_STRING_ID ProcessorManu;
EFI_STRING_ID ProcessorVersion;
EFI_STRING_ID SerialNumber;
EFI_STRING_ID AssetTag;
EFI_STRING_ID PartNumber;
EFI_STRING ProcessorStr;
EFI_STRING ProcessorManuStr;
EFI_STRING ProcessorVersionStr;
EFI_STRING SerialNumberStr;
EFI_STRING AssetTagStr;
EFI_STRING PartNumberStr;
CHAR8 *OptionalStrStart;
CHAR8 *StrStart;
UINTN ProcessorStrLen;
UINTN ProcessorManuStrLen;
UINTN ProcessorVersionStrLen;
UINTN SerialNumberStrLen;
UINTN AssetTagStrLen;
UINTN PartNumberStrLen;
UINTN TotalSize;
UINTN StringBufferSize;
Status = EFI_SUCCESS;
ProcessorManuStr = NULL;
ProcessorVersionStr = NULL;
SerialNumberStr = NULL;
AssetTagStr = NULL;
PartNumberStr = NULL;
ProcessorManu = STRING_TOKEN (STR_PROCESSOR_MANUFACTURE);
ProcessorVersion = STRING_TOKEN (STR_PROCESSOR_VERSION);
SerialNumber = STRING_TOKEN (STR_PROCESSOR_SERIAL_NUMBER);
AssetTag = STRING_TOKEN (STR_PROCESSOR_ASSET_TAG);
PartNumber = STRING_TOKEN (STR_PROCESSOR_PART_NUMBER);
SET_HII_STRING_IF_PCD_NOT_EMPTY (PcdProcessorManufacturer, ProcessorManu);
SET_HII_STRING_IF_PCD_NOT_EMPTY (PcdProcessorVersion, ProcessorVersion);
SET_HII_STRING_IF_PCD_NOT_EMPTY (PcdProcessorSerialNumber, SerialNumber);
SET_HII_STRING_IF_PCD_NOT_EMPTY (PcdProcessorAssetTag, AssetTag);
SET_HII_STRING_IF_PCD_NOT_EMPTY (PcdProcessorPartNumber, PartNumber);
// Processor Designation
StringBufferSize = sizeof (CHAR16) * SMBIOS_STRING_MAX_LENGTH;
ProcessorStr = AllocateZeroPool (StringBufferSize);
if (ProcessorStr == NULL) {
return EFI_OUT_OF_RESOURCES;
}
ProcessorStrLen = UnicodeSPrint (ProcessorStr, StringBufferSize,
L"CPU%02d", ProcessorIndex + 1);
// Processor Manufacture
ProcessorManuStr = HiiGetPackageString (&gEfiCallerIdGuid, ProcessorManu, NULL);
ProcessorManuStrLen = StrLen (ProcessorManuStr);
// Processor Version
ProcessorVersionStr = HiiGetPackageString (&gEfiCallerIdGuid, ProcessorVersion, NULL);
ProcessorVersionStrLen = StrLen (ProcessorVersionStr);
// Serial Number
SerialNumberStr = HiiGetPackageString (&gEfiCallerIdGuid, SerialNumber, NULL);
SerialNumberStrLen = StrLen (SerialNumberStr);
// Asset Tag
AssetTagStr = HiiGetPackageString (&gEfiCallerIdGuid, AssetTag, NULL);
AssetTagStrLen = StrLen (AssetTagStr);
// Part Number
PartNumberStr = HiiGetPackageString (&gEfiCallerIdGuid, PartNumber, NULL);
PartNumberStrLen = StrLen (PartNumberStr);
TotalSize = sizeof (SMBIOS_TABLE_TYPE4) +
ProcessorStrLen + 1 +
ProcessorManuStrLen + 1 +
ProcessorVersionStrLen + 1 +
SerialNumberStrLen + 1 +
AssetTagStrLen + 1 +
PartNumberStrLen + 1 + 1;
*Type4Record = AllocateZeroPool (TotalSize);
if (*Type4Record == NULL) {
Status = EFI_OUT_OF_RESOURCES;
goto Exit;
}
CopyMem (*Type4Record, &mSmbiosProcessorTableTemplate, sizeof (SMBIOS_TABLE_TYPE4));
OptionalStrStart = (CHAR8 *)(*Type4Record + 1);
UnicodeStrToAsciiStrS (
ProcessorStr,
OptionalStrStart,
ProcessorStrLen + 1
);
StrStart = OptionalStrStart + ProcessorStrLen + 1;
UnicodeStrToAsciiStrS (
ProcessorManuStr,
StrStart,
ProcessorManuStrLen + 1
);
StrStart += ProcessorManuStrLen + 1;
UnicodeStrToAsciiStrS (
ProcessorVersionStr,
StrStart,
ProcessorVersionStrLen + 1
);
StrStart += ProcessorVersionStrLen + 1;
UnicodeStrToAsciiStrS (
SerialNumberStr,
StrStart,
SerialNumberStrLen + 1
);
StrStart += SerialNumberStrLen + 1;
UnicodeStrToAsciiStrS (
AssetTagStr,
StrStart,
AssetTagStrLen + 1
);
StrStart += AssetTagStrLen + 1;
UnicodeStrToAsciiStrS (
PartNumberStr,
StrStart,
PartNumberStrLen + 1
);
Exit:
FreePool (ProcessorStr);
FreePool (ProcessorManuStr);
FreePool (ProcessorVersionStr);
FreePool (SerialNumberStr);
FreePool (AssetTagStr);
FreePool (PartNumberStr);
return Status;
}
/**
Add Type 4 SMBIOS Record for Processor Information.
@param[in] ProcessorIndex Processor index of specified processor.
**/
EFI_STATUS
AddSmbiosProcessorTypeTable (
IN UINTN ProcessorIndex
)
{
EFI_STATUS Status;
SMBIOS_TABLE_TYPE4 *Type4Record;
EFI_SMBIOS_HANDLE SmbiosHandle;
EFI_SMBIOS_HANDLE L1CacheHandle;
EFI_SMBIOS_HANDLE L2CacheHandle;
EFI_SMBIOS_HANDLE L3CacheHandle;
UINT8 *LegacyVoltage;
PROCESSOR_STATUS_DATA ProcessorStatus;
UINT64 *ProcessorId;
PROCESSOR_CHARACTERISTIC_FLAGS ProcessorCharacteristics;
OEM_MISC_PROCESSOR_DATA MiscProcessorData;
BOOLEAN ProcessorPopulated;
Type4Record = NULL;
MiscProcessorData.Voltage = 0;
MiscProcessorData.CurrentSpeed = 0;
MiscProcessorData.CoreCount = 0;
MiscProcessorData.CoresEnabled = 0;
MiscProcessorData.ThreadCount = 0;
MiscProcessorData.MaxSpeed = 0;
L1CacheHandle = 0xFFFF;
L2CacheHandle = 0xFFFF;
L3CacheHandle = 0xFFFF;
ProcessorPopulated = OemIsProcessorPresent (ProcessorIndex);
Status = AllocateType4AndSetProcessorInformationStrings (
&Type4Record,
ProcessorIndex,
ProcessorPopulated
);
if (EFI_ERROR (Status)) {
return Status;
}
OemGetProcessorInformation (ProcessorIndex,
&ProcessorStatus,
(PROCESSOR_CHARACTERISTIC_FLAGS*)
&Type4Record->ProcessorCharacteristics,
&MiscProcessorData);
if (ProcessorPopulated) {
AddSmbiosCacheTypeTable (ProcessorIndex, &L1CacheHandle,
&L2CacheHandle, &L3CacheHandle);
}
LegacyVoltage = (UINT8*)&Type4Record->Voltage;
*LegacyVoltage = MiscProcessorData.Voltage;
Type4Record->CurrentSpeed = MiscProcessorData.CurrentSpeed;
Type4Record->MaxSpeed = MiscProcessorData.MaxSpeed;
Type4Record->Status = ProcessorStatus.Data;
Type4Record->L1CacheHandle = L1CacheHandle;
Type4Record->L2CacheHandle = L2CacheHandle;
Type4Record->L3CacheHandle = L3CacheHandle;
Type4Record->CoreCount = MiscProcessorData.CoreCount;
Type4Record->CoreCount2 = MiscProcessorData.CoreCount;
Type4Record->EnabledCoreCount = MiscProcessorData.CoresEnabled;
Type4Record->EnabledCoreCount2 = MiscProcessorData.CoresEnabled;
Type4Record->ThreadCount = MiscProcessorData.ThreadCount;
Type4Record->ThreadCount2 = MiscProcessorData.ThreadCount;
Type4Record->CurrentSpeed = GetCpuFrequency (ProcessorIndex);
Type4Record->ExternalClock =
(UINT16)(SmbiosGetExternalClockFrequency () / 1000 / 1000);
ProcessorId = (UINT64*)&Type4Record->ProcessorId;
*ProcessorId = SmbiosGetProcessorId ();
ProcessorCharacteristics = SmbiosGetProcessorCharacteristics ();
Type4Record->ProcessorCharacteristics |= *((UINT64*)&ProcessorCharacteristics);
Type4Record->ProcessorFamily = SmbiosGetProcessorFamily ();
Type4Record->ProcessorFamily2 = SmbiosGetProcessorFamily2 ();
SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
Status = mSmbios->Add (mSmbios, NULL, &SmbiosHandle,
(EFI_SMBIOS_TABLE_HEADER *)Type4Record);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "[%a]:[%dL] Smbios Type04 Table Log Failed! %r \n",
__FUNCTION__, __LINE__, Status));
}
FreePool (Type4Record);
return Status;
}
/**
Standard EFI driver point.
@param ImageHandle Handle for the image of this driver
@param SystemTable Pointer to the EFI System Table
@retval EFI_SUCCESS The data was successfully stored.
**/
EFI_STATUS
EFIAPI
ProcessorSubClassEntryPoint(
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EFI_STATUS Status;
UINT32 ProcessorIndex;
//
// Locate dependent protocols
//
Status = gBS->LocateProtocol (&gEfiSmbiosProtocolGuid, NULL, (VOID**)&mSmbios);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "Could not locate SMBIOS protocol. %r\n", Status));
return Status;
}
//
// Add our default strings to the HII database. They will be modified later.
//
mHiiHandle = HiiAddPackages (&gEfiCallerIdGuid,
NULL,
ProcessorSubClassStrings,
NULL,
NULL
);
if (mHiiHandle == NULL) {
return EFI_OUT_OF_RESOURCES;
}
//
// Add SMBIOS tables for populated sockets.
//
for (ProcessorIndex = 0; ProcessorIndex < OemGetMaxProcessors (); ProcessorIndex++) {
Status = AddSmbiosProcessorTypeTable (ProcessorIndex);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "Add Processor Type Table Failed! %r.\n", Status));
return Status;
}
}
return Status;
}

View File

@@ -1,66 +0,0 @@
#/** @file
# ProcessorSubClassDxe.inf
#
# Copyright (c) 2021, NUVIA Inc. All rights reserved.
# Copyright (c) 2015, Hisilicon Limited. All rights reserved.
# Copyright (c) 2015, Linaro Limited. All rights reserved.
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
#**/
[Defines]
INF_VERSION = 1.29
BASE_NAME = ProcessorSubClass
FILE_GUID = f3fe0e33-ea38-4069-9fb5-be23407207c7
MODULE_TYPE = DXE_DRIVER
VERSION_STRING = 1.0
ENTRY_POINT = ProcessorSubClassEntryPoint
[Sources]
SmbiosProcessorArmCommon.c
ProcessorSubClass.c
ProcessorSubClassStrings.uni
SmbiosProcessor.h
[Sources.AARCH64]
SmbiosProcessorAArch64.c
[Sources.ARM]
SmbiosProcessorArm.c
[Packages]
ArmPkg/ArmPkg.dec
MdeModulePkg/MdeModulePkg.dec
MdePkg/MdePkg.dec
[LibraryClasses]
ArmLib
ArmSmcLib
BaseLib
BaseMemoryLib
DebugLib
HiiLib
IoLib
MemoryAllocationLib
OemMiscLib
PcdLib
PrintLib
UefiDriverEntryPoint
[Protocols]
gEfiSmbiosProtocolGuid # PROTOCOL ALWAYS_CONSUMED
[Pcd]
gArmTokenSpaceGuid.PcdProcessorManufacturer
gArmTokenSpaceGuid.PcdProcessorVersion
gArmTokenSpaceGuid.PcdProcessorSerialNumber
gArmTokenSpaceGuid.PcdProcessorAssetTag
gArmTokenSpaceGuid.PcdProcessorPartNumber
[Guids]
[Depex]
gEfiSmbiosProtocolGuid

View File

@@ -1,24 +0,0 @@
/** @file
SMBIOS Type 4 strings
Copyright (c) 2021, NUVIA Inc. All rights reserved.
Copyright (c) 2015, Hisilicon Limited. All rights reserved.
Copyright (c) 2015, Linaro Limited. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
/=#
#langdef en-US "English"
//
// Processor Information
//
#string STR_PROCESSOR_SOCKET_DESIGNATION #language en-US "Not Specified"
#string STR_PROCESSOR_MANUFACTURE #language en-US "Not Specified"
#string STR_PROCESSOR_VERSION #language en-US "Not Specified"
#string STR_PROCESSOR_SERIAL_NUMBER #language en-US "Not Specified"
#string STR_PROCESSOR_ASSET_TAG #language en-US "Not Specified"
#string STR_PROCESSOR_PART_NUMBER #language en-US "Not Specified"
#string STR_PROCESSOR_UNKNOWN #language en-US "Unknown"

View File

@@ -1,102 +0,0 @@
/** @file
SMBIOS Processor Related Functions.
Copyright (c) 2021, NUVIA Inc. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#ifndef SMBIOS_PROCESSOR_H_
#define SMBIOS_PROCESSOR_H_
#include <Uefi.h>
#include <IndustryStandard/SmBios.h>
/** Returns the maximum cache level implemented by the current CPU.
@return The maximum cache level implemented.
**/
UINT8
SmbiosProcessorGetMaxCacheLevel (
VOID
);
/** Returns whether or not the specified cache level has separate I/D caches.
@param CacheLevel The cache level (L1, L2 etc.).
@return TRUE if the cache level has separate I/D caches, FALSE otherwise.
**/
BOOLEAN
SmbiosProcessorHasSeparateCaches (
UINT8 CacheLevel
);
/** Gets the size of the specified cache.
@param CacheLevel The cache level (L1, L2 etc.).
@param DataCache Whether the cache is a dedicated data cache.
@param UnifiedCache Whether the cache is a unified cache.
@return The cache size.
**/
UINT64
SmbiosProcessorGetCacheSize (
IN UINT8 CacheLevel,
IN BOOLEAN DataCache,
IN BOOLEAN UnifiedCache
);
/** Gets the associativity of the specified cache.
@param CacheLevel The cache level (L1, L2 etc.).
@param DataCache Whether the cache is a dedicated data cache.
@param UnifiedCache Whether the cache is a unified cache.
@return The cache associativity.
**/
UINT32
SmbiosProcessorGetCacheAssociativity (
IN UINT8 CacheLevel,
IN BOOLEAN DataCache,
IN BOOLEAN UnifiedCache
);
/** Returns a value for the Processor ID field that conforms to SMBIOS
requirements.
@return Processor ID.
**/
UINT64
SmbiosGetProcessorId (VOID);
/** Returns the external clock frequency.
@return The external CPU clock frequency.
**/
UINTN
SmbiosGetExternalClockFrequency (VOID);
/** Returns the SMBIOS ProcessorFamily field value.
@return The value for the ProcessorFamily field.
**/
UINT8
SmbiosGetProcessorFamily (VOID);
/** Returns the ProcessorFamily2 field value.
@return The value for the ProcessorFamily2 field.
**/
UINT16
SmbiosGetProcessorFamily2 (VOID);
/** Returns the SMBIOS Processor Characteristics.
@return Processor Characteristics bitfield.
**/
PROCESSOR_CHARACTERISTIC_FLAGS
SmbiosGetProcessorCharacteristics (VOID);
#endif // SMBIOS_PROCESSOR_H_

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