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
7284 changed files with 546375 additions and 1083022 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,25 +2,17 @@
# Azure Pipeline build file for a build using ubuntu and GCC5 # Azure Pipeline build file for a build using ubuntu and GCC5
# #
# Copyright (c) Microsoft Corporation. # Copyright (c) Microsoft Corporation.
# Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
# Copyright (c) 2022, Loongson Technology Corporation Limited. All rights reserved.<BR>
# SPDX-License-Identifier: BSD-2-Clause-Patent # SPDX-License-Identifier: BSD-2-Clause-Patent
## ##
trigger: trigger:
- master - master
- stable/*
pr: pr:
- master - master
- stable/*
variables:
- template: templates/defaults.yml
jobs: jobs:
- template: templates/pr-gate-build-job.yml - template: templates/pr-gate-build-job.yml
parameters: parameters:
tool_chain_tag: 'GCC5' tool_chain_tag: 'GCC5'
vm_image: 'ubuntu-22.04' vm_image: 'ubuntu-latest'
container: ${{ variables.default_linux_image }} arch_list: "IA32,X64,ARM,AARCH64"
arch_list: "IA32,X64,ARM,AARCH64,RISCV64,LOONGARCH64"
usePythonVersion: '' # use Python from the container image

View File

@@ -5,7 +5,7 @@
# NOTE: This example monitors pull requests against the edk2-ci branch. Most # NOTE: This example monitors pull requests against the edk2-ci branch. Most
# environments would replace 'edk2-ci' with 'master'. # 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 # SPDX-License-Identifier: BSD-2-Clause-Patent
# #
# https://github.com/tianocore # https://github.com/tianocore
@@ -16,7 +16,6 @@ trigger: none
pr: pr:
- master - master
- stable/*
pool: pool:
vmImage: 'ubuntu-latest' vmImage: 'ubuntu-latest'
@@ -27,7 +26,7 @@ steps:
- task: UsePythonVersion@0 - task: UsePythonVersion@0
inputs: inputs:
versionSpec: '3.12' versionSpec: '3.7.x'
architecture: 'x64' architecture: 'x64'
- script: | - script: |

View File

@@ -6,24 +6,13 @@
## ##
trigger: trigger:
- master - master
- stable/*
pr: pr:
- master - master
- stable/*
variables:
- template: templates/defaults.yml
jobs: jobs:
- template: templates/pr-gate-build-job.yml - template: templates/pr-gate-build-job.yml
parameters: parameters:
tool_chain_tag: 'VS2019' tool_chain_tag: 'VS2019'
vm_image: 'windows-2019' vm_image: 'windows-latest'
arch_list: "IA32,X64" arch_list: "IA32,X64"
usePythonVersion: ${{ variables.default_python_version }}
extra_install_step:
- powershell: choco install opencppcoverage; Write-Host "##vso[task.prependpath]C:\Program Files\OpenCppCoverage"
displayName: Install Code Coverage Tool
condition: and(gt(variables.pkg_count, 0), succeeded())

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

@@ -10,6 +10,15 @@ parameters:
tool_chain_tag: '' tool_chain_tag: ''
steps: steps:
- ${{ if contains(parameters.tool_chain_tag, 'GCC') }}:
- bash: sudo apt-get update
displayName: Update apt
condition: and(gt(variables.pkg_count, 0), succeeded())
- bash: sudo apt-get install gcc g++ make uuid-dev
displayName: Install required tools
condition: and(gt(variables.pkg_count, 0), succeeded())
- task: CmdLine@1 - task: CmdLine@1
displayName: Build Base Tools from source displayName: Build Base Tools from source
inputs: inputs:

View File

@@ -1,12 +0,0 @@
## @file
# File templates/default.yml
#
# template file containing common default values
#
# Copyright (c) Red Hat, Inc.
# SPDX-License-Identifier: BSD-2-Clause-Patent
##
variables:
default_python_version: "3.12"
default_linux_image: "ghcr.io/tianocore/containers/fedora-37-test:a0dd931"

View File

@@ -1,150 +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: []
- name: usePythonVersion
type: string
default: ''
steps:
- bash: |
echo "##vso[task.prependpath]${HOME}/.local/bin"
echo "new PATH=${PATH}"
displayName: Set PATH
condition: eq('${{ parameters.tool_chain_tag }}', 'GCC5')
- checkout: self
clean: true
fetchDepth: 1
- task: UsePythonVersion@0
inputs:
versionSpec: ${{ parameters.usePythonVersion }}
architecture: "x64"
condition: ne('${{ parameters.usePythonVersion }}', '')
- script: pip install -r pip-requirements.txt --upgrade
displayName: 'Install/Upgrade pip modules'
# Set default
- bash: echo "##vso[task.setvariable variable=pkg_count]${{ 1 }}"
# Fetch the target branch so that pr_eval can diff them.
# Seems like azure pipelines/github changed checkout process in nov 2020.
- script: git fetch origin $(System.PullRequest.targetBranch)
displayName: fetch target branch
condition: eq(variables['Build.Reason'], 'PullRequest')
# trim the package list if this is a PR
- task: CmdLine@1
displayName: Check if ${{ parameters.build_pkg }} need testing
inputs:
filename: stuart_pr_eval
arguments: -c ${{ parameters.build_file }} -t ${{ parameters.build_target}} -a ${{ parameters.build_arch}} --pr-target origin/$(System.PullRequest.targetBranch) --output-count-format-string "##vso[task.setvariable variable=pkg_count;isOutpout=true]{pkgcount}"
condition: eq(variables['Build.Reason'], 'PullRequest')
# Setup repo
- task: CmdLine@1
displayName: Setup
inputs:
filename: stuart_setup
arguments: -c ${{ parameters.build_file }} TOOL_CHAIN_TAG=${{ parameters.tool_chain_tag}} -t ${{ parameters.build_target}} -a ${{ parameters.build_arch}} ${{ parameters.build_flags}}
condition: and(gt(variables.pkg_count, 0), succeeded())
# Stuart Update
- task: CmdLine@1
displayName: Update
inputs:
filename: stuart_update
arguments: -c ${{ parameters.build_file }} TOOL_CHAIN_TAG=${{ parameters.tool_chain_tag}} -t ${{ parameters.build_target}} -a ${{ parameters.build_arch}} ${{ parameters.build_flags}}
condition: and(gt(variables.pkg_count, 0), succeeded())
# build basetools
# do this after setup and update so that code base dependencies
# are all resolved.
- template: basetools-build-steps.yml
parameters:
tool_chain_tag: ${{ parameters.tool_chain_tag }}
# Potential Extra steps
- ${{ parameters.extra_install_step }}
# Build
- task: CmdLine@1
displayName: Build
inputs:
filename: stuart_build
arguments: -c ${{ parameters.build_file }} TOOL_CHAIN_TAG=${{ parameters.tool_chain_tag}} TARGET=${{ parameters.build_target}} -a ${{ parameters.build_arch}} ${{ parameters.build_flags}}
condition: and(gt(variables.pkg_count, 0), succeeded())
# Run
- task: CmdLine@1
displayName: Run to shell
inputs:
filename: stuart_build
arguments: -c ${{ parameters.build_file }} TOOL_CHAIN_TAG=${{ parameters.tool_chain_tag}} TARGET=${{ parameters.build_target}} -a ${{ parameters.build_arch}} ${{ parameters.build_flags}} ${{ parameters.run_flags }} --FlashOnly
condition: and(and(gt(variables.pkg_count, 0), succeeded()), eq(variables['Run'], true))
timeoutInMinutes: 2
# 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. # template file used to build supported packages.
# #
# Copyright (c) Microsoft Corporation. # Copyright (c) Microsoft Corporation.
# Copyright (c) 2020 - 2021, ARM Limited. All rights reserved.<BR>
# SPDX-License-Identifier: BSD-2-Clause-Patent # SPDX-License-Identifier: BSD-2-Clause-Patent
## ##
@@ -12,25 +11,15 @@ parameters:
tool_chain_tag: '' tool_chain_tag: ''
vm_image: '' vm_image: ''
arch_list: '' arch_list: ''
extra_install_step: []
usePythonVersion: ''
container: ''
# Build step # Build step
jobs: jobs:
- job: Build_${{ parameters.tool_chain_tag }} - job: Build_${{ parameters.tool_chain_tag }}
timeoutInMinutes: 120
#Use matrix to speed up the build process #Use matrix to speed up the build process
strategy: strategy:
matrix: matrix:
${{ if eq(parameters.tool_chain_tag, 'GCC5') }}:
TARGET_GCC_ONLY:
Build.Pkgs: 'EmbeddedPkg'
Build.Targets: 'DEBUG,RELEASE,NO-TARGET,NOOPT'
TARGET_ARM_ARMPLATFORM:
Build.Pkgs: 'ArmPkg,ArmPlatformPkg'
Build.Targets: 'DEBUG,RELEASE,NO-TARGET,NOOPT'
TARGET_MDE_CPU: TARGET_MDE_CPU:
Build.Pkgs: 'MdePkg,UefiCpuPkg' Build.Pkgs: 'MdePkg,UefiCpuPkg'
Build.Targets: 'DEBUG,RELEASE,NO-TARGET,NOOPT' Build.Targets: 'DEBUG,RELEASE,NO-TARGET,NOOPT'
@@ -41,34 +30,20 @@ jobs:
Build.Pkgs: 'MdeModulePkg' Build.Pkgs: 'MdeModulePkg'
Build.Targets: 'RELEASE,NO-TARGET' Build.Targets: 'RELEASE,NO-TARGET'
TARGET_NETWORK: TARGET_NETWORK:
Build.Pkgs: 'NetworkPkg,RedfishPkg' Build.Pkgs: 'NetworkPkg'
Build.Targets: 'DEBUG,RELEASE,NO-TARGET,NOOPT' Build.Targets: 'DEBUG,RELEASE,NO-TARGET'
TARGET_OTHER: TARGET_OTHER:
Build.Pkgs: 'PcAtChipsetPkg,PrmPkg,ShellPkg,SourceLevelDebugPkg,StandaloneMmPkg,SignedCapsulePkg' Build.Pkgs: 'PcAtChipsetPkg,ShellPkg'
Build.Targets: 'DEBUG,RELEASE,NO-TARGET,NOOPT' Build.Targets: 'DEBUG,RELEASE,NO-TARGET'
TARGET_FMP_FAT_TEST: TARGET_FMP_FAT_TEST:
Build.Pkgs: 'FmpDevicePkg,FatPkg,UnitTestFrameworkPkg,DynamicTablesPkg' Build.Pkgs: 'FmpDevicePkg,FatPkg,UnitTestFrameworkPkg'
Build.Targets: 'DEBUG,RELEASE,NO-TARGET,NOOPT' Build.Targets: 'DEBUG,RELEASE,NO-TARGET,NOOPT'
TARGET_CRYPTO_DEBUG: TARGET_CRYPTO:
Build.Pkgs: 'CryptoPkg' Build.Pkgs: 'CryptoPkg'
Build.Targets: 'DEBUG,NOOPT' Build.Targets: 'DEBUG,RELEASE,NO-TARGET'
TARGET_CRYPTO_RELEASE:
Build.Pkgs: 'CryptoPkg'
Build.Targets: 'RELEASE,NO-TARGET'
TARGET_FSP:
Build.Pkgs: 'IntelFsp2Pkg,IntelFsp2WrapperPkg'
Build.Targets: 'DEBUG,RELEASE,NO-TARGET,NOOPT'
TARGET_SECURITY: TARGET_SECURITY:
Build.Pkgs: 'SecurityPkg' Build.Pkgs: 'SecurityPkg'
Build.Targets: 'DEBUG,RELEASE,NO-TARGET,NOOPT' Build.Targets: 'DEBUG,RELEASE,NO-TARGET'
TARGET_UEFIPAYLOAD:
Build.Pkgs: 'UefiPayloadPkg'
Build.Targets: 'DEBUG,RELEASE,NO-TARGET,NOOPT'
TARGET_PLATFORMS:
# For Platforms only check code. Leave it to Platform CI
# to build them.
Build.Pkgs: 'ArmVirtPkg,EmulatorPkg,OvmfPkg'
Build.Targets: 'NO-TARGET,NOOPT'
workspace: workspace:
clean: all clean: all
@@ -76,9 +51,6 @@ jobs:
pool: pool:
vmImage: ${{ parameters.vm_image }} vmImage: ${{ parameters.vm_image }}
${{ if not(eq(parameters.container, '')) }}:
container: ${{ parameters.container }}
steps: steps:
- template: pr-gate-steps.yml - template: pr-gate-steps.yml
parameters: parameters:
@@ -86,47 +58,23 @@ jobs:
build_pkgs: $(Build.Pkgs) build_pkgs: $(Build.Pkgs)
build_targets: $(Build.Targets) build_targets: $(Build.Targets)
build_archs: ${{ parameters.arch_list }} build_archs: ${{ parameters.arch_list }}
usePythonVersion: ${{ parameters.usePythonVersion }}
extra_install_step: ${{ parameters.extra_install_step }}
- job: Build_${{ parameters.tool_chain_tag }}_TARGET_CODE_COVERAGE - job: FINISHED
dependsOn: Build_${{ parameters.tool_chain_tag }} dependsOn: Build_${{ parameters.tool_chain_tag }}
workspace: condition: succeeded()
clean: all
pool:
vmImage: 'windows-2019'
steps: steps:
- checkout: self - checkout: none
clean: true - script: |
fetchDepth: 1 echo FINISHED
submodules: true sleep 10
displayName: FINISHED
- task: DownloadPipelineArtifact@2
displayName: 'Download Build Artifacts'
inputs:
buildType: 'current'
targetPath: '$(Build.ArtifactStagingDirectory)'
- powershell: Write-Host "##vso[task.setvariable variable=is_code_coverage]0"
displayName: Give default value for whether CodeCoverage or not
- powershell: if (Test-Path -Path $(Build.ArtifactStagingDirectory)/**/coverage.xml) {Write-Host "##vso[task.setvariable variable=is_code_coverage]1"}
displayName: Check coverage.xml exist or not
- task: CmdLine@2
displayName: Create code coverage report
inputs:
script: |
dotnet tool install -g dotnet-reportgenerator-globaltool
reportgenerator -reports:$(Build.ArtifactStagingDirectory)/**/coverage.xml -targetdir:$(Build.ArtifactStagingDirectory)/Coverage -reporttypes:Cobertura -filefilters:-*Build*;-*UnitTest*;-*Mock*;-*usr*
condition: eq(variables.is_code_coverage, 1)
- task: PublishCodeCoverageResults@1
displayName: 'Publish code coverage'
inputs:
codeCoverageTool: Cobertura
summaryFileLocation: '$(Build.ArtifactStagingDirectory)/Coverage/Cobertura.xml'
condition: eq(variables.is_code_coverage, 1)
- job: FAILED
dependsOn: Build_${{ parameters.tool_chain_tag }}
condition: failed()
steps:
- checkout: none
- script: |
echo FAILED
sleep 10
displayName: FAILED

View File

@@ -12,25 +12,16 @@ parameters:
build_pkgs: '' build_pkgs: ''
build_targets: '' build_targets: ''
build_archs: '' build_archs: ''
usePythonVersion: ''
extra_install_step: []
steps: steps:
- bash: |
echo "##vso[task.prependpath]${HOME}/.local/bin"
echo "new PATH=${PATH}"
displayName: Set PATH
condition: eq('${{ parameters.tool_chain_tag }}', 'GCC5')
- checkout: self - checkout: self
clean: true clean: true
fetchDepth: 1 fetchDepth: 1
- task: UsePythonVersion@0 - task: UsePythonVersion@0
inputs: inputs:
versionSpec: ${{ parameters.usePythonVersion }} versionSpec: '3.7.x'
architecture: "x64" architecture: 'x64'
condition: ne('${{ parameters.usePythonVersion }}', '')
- script: pip install -r pip-requirements.txt --upgrade - script: pip install -r pip-requirements.txt --upgrade
displayName: 'Install/Upgrade pip modules' displayName: 'Install/Upgrade pip modules'
@@ -40,14 +31,6 @@ steps:
echo "##vso[task.setvariable variable=pkgs_to_build]${{ parameters.build_pkgs }}" echo "##vso[task.setvariable variable=pkgs_to_build]${{ parameters.build_pkgs }}"
echo "##vso[task.setvariable variable=pkg_count]${{ 1 }}" echo "##vso[task.setvariable variable=pkg_count]${{ 1 }}"
# Fetch the target branch so that pr_eval can diff them.
# Seems like azure pipelines/github changed checkout process in nov 2020.
- script: git fetch origin $(System.PullRequest.targetBranch)
displayName: fetch target branch
condition: eq(variables['Build.Reason'], 'PullRequest')
- ${{ parameters.extra_install_step }}
# trim the package list if this is a PR # trim the package list if this is a PR
- task: CmdLine@1 - task: CmdLine@1
displayName: Check if ${{ parameters.build_pkgs }} need testing displayName: Check if ${{ parameters.build_pkgs }} need testing
@@ -56,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}" 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') 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 # install spell check prereqs
- template: spell-check-prereq-steps.yml - template: spell-check-prereq-steps.yml
@@ -74,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}} 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()) 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 - task: CmdLine@1
displayName: Build and Test ${{ parameters.build_pkgs }} ${{ parameters.build_archs}} displayName: Build and Test ${{ parameters.build_pkgs }} ${{ parameters.build_archs}}
inputs: inputs:
@@ -136,7 +117,6 @@ steps:
TestSuites.xml TestSuites.xml
**/BUILD_TOOLS_REPORT.html **/BUILD_TOOLS_REPORT.html
**/OVERRIDELOG.TXT **/OVERRIDELOG.TXT
coverage.xml
flattenFolders: true flattenFolders: true
condition: succeededOrFailed() condition: succeededOrFailed()

View File

@@ -13,10 +13,10 @@ parameters:
steps: steps:
- task: NodeTool@0 - task: NodeTool@0
inputs: inputs:
versionSpec: '14.x' versionSpec: '10.x'
#checkLatest: false # Optional #checkLatest: false # Optional
condition: and(gt(variables.pkg_count, 0), succeeded()) condition: and(gt(variables.pkg_count, 0), succeeded())
- script: npm install -g cspell@5.20.0 - script: npm install -g cspell
displayName: 'Install cspell npm' displayName: 'Install cspell npm'
condition: and(gt(variables.pkg_count, 0), succeeded()) condition: and(gt(variables.pkg_count, 0), succeeded())

View File

@@ -1,16 +0,0 @@
{
"image": "ghcr.io/tianocore/containers/fedora-35-dev:latest",
"postCreateCommand": "git config --global --add safe.directory * && pip install --upgrade -r pip-requirements.txt",
"customizations": {
"vscode": {
"extensions": [
"DavidAnson.vscode-markdownlint",
"ms-azuretools.vscode-docker",
"ms-vscode-remote.remote-containers",
"ms-vscode.cpptools",
"walonli.edk2-vscode",
"zachflower.uncrustify"
]
}
}
}

View File

@@ -1,31 +0,0 @@
# EditorConfig file: https://EditorConfig.org
root = true
[*]
charset = latin1
end_of_line = crlf
indent_style = space
indent_size = 2
insert_final_newline = true
trim_trailing_whitespace = true
[*.py]
charset = utf-8
indent_style = space
indent_size = 4
[*.sh]
end_of_line = lf
[.gitattributes]
end_of_line = lf
[.mailmap]
charset = utf-8
[Maintainers.txt]
charset = utf-8
[Makefile,GNUmakefile]
indent_style = tab

View File

@@ -1,56 +0,0 @@
# PrmPkg: Apply uncrustify changes
a298a84478053872ed9da660a75f182ce81b8ddc
# UnitTestFrameworkPkg: Apply uncrustify changes
7c0ad2c33810ead45b7919f8f8d0e282dae52e71
# UefiPayloadPkg: Apply uncrustify changes
e5efcf8be8a1bf59aa98875787475e3144ee4cef
# UefiCpuPkg: Apply uncrustify changes
053e878bfb5c9d5eca779789b62891add30b14ba
# StandaloneMmPkg: Apply uncrustify changes
91415a36ae7aaeabb2bbab3762f39544f9aed683
# SourceLevelDebugPkg: Apply uncrustify changes
c1e126b1196de75e0a4cda21e4551ea9bb05e059
# SignedCapsulePkg: Apply uncrustify changes
b87864896714cf3062a7bc6d577d8fbd62d105e5
# ShellPkg: Apply uncrustify changes
47d20b54f9a65b08aa602a1866c1b59a69088dfc
# SecurityPkg: Apply uncrustify changes
c411b485b63a671a1e276700cff025c73997233c
# RedfishPkg: Apply uncrustify changes
39de741e2dcb8f11e9b4438e37224797643d8451
# PcAtChipsetPkg: Apply uncrustify changes
5220bd211df890f2672c23c050082862cd1e82d6
# OvmfPkg: Apply uncrustify changes
ac0a286f4d747a4c6c603a7b225917293cbe1e9f
# NetworkPkg: Apply uncrustify changes
d1050b9dff1cace252aff86630bfdb59dff5f507
# MdePkg: Apply uncrustify changes
2f88bd3a1296c522317f1c21377876de63de5be7
# MdeModulePkg: Apply uncrustify changes
1436aea4d5707e672672a11bda72be2c63c936c3
# IntelFsp2WrapperPkg: Apply uncrustify changes
7c7184e201a90a1d2376e615e55e3f4074731468
# IntelFsp2Pkg: Apply uncrustify changes
111f2228ddf487b0ac3491e416bb3dcdcfa4f979
# FmpDevicePkg: Apply uncrustify changes
45ce0a67bb4ee80f27da93777c623f51f344f23b
# FatPkg: Apply uncrustify changes
bcdcc4160d7460c46c08c9395aae81be44ef23a9
# EmulatorPkg: Apply uncrustify changes
a550d468a6ca577d9e9c57a0eafcf2fc9fbb8c97
# EmbeddedPkg: Apply uncrustify changes
e7108d0e9655b1795c94ac372b0449f28dd907df
# DynamicTablesPkg: Apply uncrustify changes
731c67e1d77b7741a91762d17659fc9fbcb9e305
# CryptoPkg: Apply uncrustify changes
7c342378317039e632d9a1a5d4cf7c21aec8cb7a
# ArmVirtPkg: Apply uncrustify changes
2b16a4fb91b9b31c0d152588f5ac51080c6c0763
# ArmPlatformPkg: Apply uncrustify changes
40b0b23ed34f48c26d711d3e4613a4bb35eeadff
# ArmPkg: Apply uncrustify changes
429309e0c6b74792d679681a8edd0d5ae0ff850c
# EmulatorPkg: Format with Uncrustify 73.0.8
972e3b0b9d67ef2847c9c1c89e606e6074a7ddda
# OvmfPkg: Format with Uncrustify 73.0.8
0e9ce9146a6dc50a35488e3a4a7a2a4bbaf1eb1c

View File

@@ -1,24 +0,0 @@
## @file
# GitHub issue configuration file.
#
# This file is meant to direct contributors familiar with GitHub's issue tracker
# to the external resources used by TianoCore.
#
# Copyright (c) Microsoft Corporation.
# SPDX-License-Identifier: BSD-2-Clause-Patent
##
blank_issues_enabled: false
contact_links:
- name: Bugs and Feature Requests
url: https://bugzilla.tianocore.org/
about: Submit bug reports and feature requests here
- name: Reporting Security Issues
url: https://github.com/tianocore/tianocore.github.io/wiki/Reporting-Security-Issues
about: Read the wiki page that describes the process here
- name: EDK II Development Mailing List
url: https://edk2.groups.io/g/devel
about: Submit code patches and ask questions on the mailing list (devel@edk2.groups.io)
- name: EDK II Discussions
url: https://github.com/tianocore/edk2/discussions
about: You can also reach out on the Discussion section of this repository

View File

@@ -1,36 +0,0 @@
## @file
# Dependabot configuration file to enable GitHub services for managing and updating
# dependencies.
#
# Copyright (c) Microsoft Corporation.
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
# Please see the documentation for all configuration options:
# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
##
version: 2
updates:
- package-ecosystem: "pip"
directory: "/"
schedule:
interval: "daily"
commit-message:
prefix: "pip"
reviewers:
- "makubacki"
- "mdkinney"
- "spbrogan"
rebase-strategy: "disabled"
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
day: "monday"
commit-message:
prefix: "GitHub Action"
reviewers:
- "makubacki"
- "mdkinney"
- "spbrogan"
rebase-strategy: "disabled"

View File

@@ -1,361 +0,0 @@
# This workflow runs CodeQL against the repository.
#
# Results are uploaded to GitHub Code Scanning.
#
# Due to a known issue with the CodeQL extractor when building the edk2
# codebase on Linux systems, only Windows agents are used for build with
# the VS toolchain.
#
# Copyright (c) Microsoft Corporation.
# SPDX-License-Identifier: BSD-2-Clause-Patent
name: "CodeQL"
on:
push:
branches:
- master
pull_request:
branches:
- master
paths-ignore:
- '!**.c'
- '!**.h'
jobs:
analyze:
name: Analyze
runs-on: windows-2019
permissions:
actions: read
contents: read
security-events: write
strategy:
fail-fast: false
matrix:
include:
- Package: "ArmPkg"
ArchList: "IA32,X64"
- Package: "CryptoPkg"
ArchList: "IA32"
- Package: "CryptoPkg"
ArchList: "X64"
- Package: "DynamicTablesPkg"
ArchList: "IA32,X64"
- Package: "FatPkg"
ArchList: "IA32,X64"
- Package: "FmpDevicePkg"
ArchList: "IA32,X64"
- Package: "IntelFsp2Pkg"
ArchList: "IA32,X64"
- Package: "IntelFsp2WrapperPkg"
ArchList: "IA32,X64"
- Package: "MdeModulePkg"
ArchList: "IA32"
- Package: "MdeModulePkg"
ArchList: "X64"
- Package: "MdePkg"
ArchList: "IA32,X64"
- Package: "PcAtChipsetPkg"
ArchList: "IA32,X64"
- Package: "PrmPkg"
ArchList: "IA32,X64"
- Package: "SecurityPkg"
ArchList: "IA32,X64"
- Package: "ShellPkg"
ArchList: "IA32,X64"
- Package: "SourceLevelDebugPkg"
ArchList: "IA32,X64"
- Package: "StandaloneMmPkg"
ArchList: "IA32,X64"
- Package: "UefiCpuPkg"
ArchList: "IA32,X64"
- Package: "UnitTestFrameworkPkg"
ArchList: "IA32,X64"
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Install Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
cache: 'pip'
cache-dependency-path: 'pip-requirements.txt'
- name: Use Git Long Paths on Windows
if: runner.os == 'Windows'
shell: pwsh
run: |
git config --system core.longpaths true
- name: Install/Upgrade pip Modules
run: pip install -r pip-requirements.txt --upgrade requests sarif-tools
- name: Determine CI Settings File Supported Operations
id: get_ci_file_operations
shell: python
run: |
import importlib
import os
import sys
from pathlib import Path
from edk2toolext.invocables.edk2_ci_setup import CiSetupSettingsManager
from edk2toolext.invocables.edk2_setup import SetupSettingsManager
# Find the repo CI Settings file
ci_settings_file = list(Path(os.environ['GITHUB_WORKSPACE']).rglob('.pytool/CISettings.py'))
# Note: At this point, submodules have not been pulled, only one CI Settings file should exist
if len(ci_settings_file) != 1 or not ci_settings_file[0].is_file():
print("::error title=Workspace Error!::Failed to find CI Settings file!")
sys.exit(1)
ci_settings_file = ci_settings_file[0]
# Try Finding the Settings class in the file
module_name = 'ci_settings'
spec = importlib.util.spec_from_file_location(module_name, ci_settings_file)
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
try:
settings = getattr(module, 'Settings')
except AttributeError:
print("::error title=Workspace Error!::Failed to find Settings class in CI Settings file!")
sys.exit(1)
# Determine Which Operations Are Supported by the Settings Class
ci_setup_supported = issubclass(settings, CiSetupSettingsManager)
setup_supported = issubclass(settings, SetupSettingsManager)
with open(os.environ['GITHUB_OUTPUT'], 'a') as fh:
print(f'ci_setup_supported={str(ci_setup_supported).lower()}', file=fh)
print(f'setup_supported={str(setup_supported).lower()}', file=fh)
- name: Convert Arch to Log Format
id: convert_arch_hyphen
env:
ARCH_LIST: ${{ matrix.ArchList }}
shell: python
run: |
import os
with open(os.environ['GITHUB_OUTPUT'], 'a') as fh:
print(f'arch_list={os.environ["ARCH_LIST"].replace(",", "-")}', file=fh)
- name: Setup
if: steps.get_ci_file_operations.outputs.setup_supported == 'true'
run: stuart_setup -c .pytool/CISettings.py -t DEBUG -a ${{ matrix.ArchList }} TOOL_CHAIN_TAG=VS2019
- name: Upload Setup Log As An Artifact
uses: actions/upload-artifact@v4
if: (success() || failure()) && steps.get_ci_file_operations.outputs.setup_supported == 'true'
with:
name: ${{ matrix.Package }}-${{ steps.convert_arch_hyphen.outputs.arch_list }}-Setup-Log
path: |
**/SETUPLOG.txt
retention-days: 7
if-no-files-found: ignore
- name: CI Setup
if: steps.get_ci_file_operations.outputs.ci_setup_supported == 'true'
run: stuart_ci_setup -c .pytool/CISettings.py -t DEBUG -a ${{ matrix.ArchList }} TOOL_CHAIN_TAG=VS2019
- name: Upload CI Setup Log As An Artifact
uses: actions/upload-artifact@v4
if: (success() || failure()) && steps.get_ci_file_operations.outputs.ci_setup_supported == 'true'
with:
name: ${{ matrix.Package }}-${{ steps.convert_arch_hyphen.outputs.arch_list }}-CI-Setup-Log
path: |
**/CISETUP.txt
retention-days: 7
if-no-files-found: ignore
- name: Update
run: stuart_update -c .pytool/CISettings.py -t DEBUG -a ${{ matrix.ArchList }} TOOL_CHAIN_TAG=VS2019
- name: Upload Update Log As An Artifact
uses: actions/upload-artifact@v4
if: success() || failure()
with:
name: ${{ matrix.Package }}-${{ steps.convert_arch_hyphen.outputs.arch_list }}-Update-Log
path: |
**/UPDATE_LOG.txt
retention-days: 7
if-no-files-found: ignore
- name: Build Tools From Source
run: python BaseTools/Edk2ToolsBuild.py -t VS2019
- name: Find CodeQL Plugin Directory
id: find_dir
shell: python
run: |
import os
import sys
from pathlib import Path
# Find the plugin directory that contains the CodeQL plugin
plugin_dir = list(Path(os.environ['GITHUB_WORKSPACE']).rglob('BaseTools/Plugin/CodeQL'))
# This should only be found once
if len(plugin_dir) == 1:
plugin_dir = str(plugin_dir[0])
with open(os.environ['GITHUB_OUTPUT'], 'a') as fh:
print(f'codeql_plugin_dir={plugin_dir}', file=fh)
else:
print("::error title=Workspace Error!::Failed to find CodeQL plugin directory!")
sys.exit(1)
- name: Get CodeQL CLI Cache Data
id: cache_key_gen
env:
CODEQL_PLUGIN_DIR: ${{ steps.find_dir.outputs.codeql_plugin_dir }}
shell: python
run: |
import os
import yaml
codeql_cli_ext_dep_name = 'codeqlcli_windows_ext_dep'
codeql_plugin_file = os.path.join(os.environ['CODEQL_PLUGIN_DIR'], codeql_cli_ext_dep_name + '.yaml')
with open (codeql_plugin_file) as pf:
codeql_cli_ext_dep = yaml.safe_load(pf)
cache_key_name = codeql_cli_ext_dep['name']
cache_key_version = codeql_cli_ext_dep['version']
cache_key = f'{cache_key_name}-{cache_key_version}'
codeql_plugin_cli_ext_dep_dir = os.path.join(os.environ['CODEQL_PLUGIN_DIR'], codeql_cli_ext_dep['name'].strip() + '_extdep')
with open(os.environ['GITHUB_OUTPUT'], 'a') as fh:
print(f'codeql_cli_cache_key={cache_key}', file=fh)
print(f'codeql_cli_ext_dep_dir={codeql_plugin_cli_ext_dep_dir}', file=fh)
- name: Attempt to Load CodeQL CLI From Cache
id: codeqlcli_cache
uses: actions/cache@v4
with:
path: ${{ steps.cache_key_gen.outputs.codeql_cli_ext_dep_dir }}
key: ${{ steps.cache_key_gen.outputs.codeql_cli_cache_key }}
- name: Download CodeQL CLI
if: steps.codeqlcli_cache.outputs.cache-hit != 'true'
run: stuart_update -c .pytool/CISettings.py -t DEBUG -a ${{ matrix.ArchList }} TOOL_CHAIN_TAG=VS2019 --codeql
- name: Remove CI Plugins Irrelevant to CodeQL
shell: python
env:
CODEQL_PLUGIN_DIR: ${{ steps.find_dir.outputs.codeql_plugin_dir }}
run: |
import os
import shutil
from pathlib import Path
# Only these two plugins are needed for CodeQL
plugins_to_keep = ['CompilerPlugin']
plugin_dir = Path('.pytool/Plugin').absolute()
if plugin_dir.is_dir():
for dir in plugin_dir.iterdir():
if str(dir.stem) not in plugins_to_keep:
shutil.rmtree(str(dir.absolute()), ignore_errors=True)
- name: CI Build
env:
STUART_CODEQL_PATH: ${{ steps.cache_key_gen.outputs.codeql_cli_ext_dep_dir }}
run: stuart_ci_build -c .pytool/CISettings.py -t DEBUG -p ${{ matrix.Package }} -a ${{ matrix.ArchList }} TOOL_CHAIN_TAG=VS2019 --codeql
- name: Build Cleanup
id: build_cleanup
shell: python
run: |
import os
import shutil
from pathlib import Path
dirs_to_delete = ['ia32', 'x64', 'arm', 'aarch64']
def delete_dirs(path: Path):
if path.exists() and path.is_dir():
if path.name.lower() in dirs_to_delete:
print(f'Removed {str(path)}')
shutil.rmtree(path)
return
for child_dir in path.iterdir():
delete_dirs(child_dir)
build_path = Path(os.environ['GITHUB_WORKSPACE'], 'Build')
delete_dirs(build_path)
- name: Upload Build Logs As An Artifact
uses: actions/upload-artifact@v4
if: success() || failure()
with:
name: ${{ matrix.Package }}-${{ steps.convert_arch_hyphen.outputs.arch_list }}-Build-Logs
path: |
**/BUILD_REPORT.TXT
**/OVERRIDELOG.TXT
**/BUILDLOG_*.md
**/BUILDLOG_*.txt
**/CI_*.md
**/CI_*.txt
retention-days: 7
if-no-files-found: ignore
- name: Prepare Env Data for CodeQL Upload
id: env_data
env:
PACKAGE_NAME: ${{ matrix.Package }}
shell: python
run: |
import logging
import os
from edk2toollib.utility_functions import RunCmd
from io import StringIO
from pathlib import Path
package = os.environ['PACKAGE_NAME'].strip().lower()
directory_name = 'codeql-analysis-' + package + '-debug'
file_name = 'codeql-db-' + package + '-debug-0.sarif'
sarif_path = Path('Build', directory_name, file_name)
with open(os.environ['GITHUB_OUTPUT'], 'a') as fh:
if sarif_path.is_file():
emacs_file_path = sarif_path.with_name(sarif_path.stem + "-emacs.txt")
out_stream_buffer = StringIO()
exit_code = RunCmd("sarif", f"emacs {sarif_path} --output {emacs_file_path} --no-autotrim",
outstream=out_stream_buffer,
logging_level=logging.NOTSET)
print(f'upload_sarif_file=true', file=fh)
print(f'emacs_file_path={emacs_file_path}', file=fh)
print(f'sarif_file_path={sarif_path}', file=fh)
else:
print(f'upload_sarif_file=false', file=fh)
- name: Upload CodeQL Results (SARIF) As An Artifact
uses: actions/upload-artifact@v4
if: steps.env_data.outputs.upload_sarif_file == 'true'
with:
name: ${{ matrix.Package }}-${{ steps.convert_arch_hyphen.outputs.arch_list }}-CodeQL-SARIF
path: |
${{ steps.env_data.outputs.emacs_file_path }}
${{ steps.env_data.outputs.sarif_file_path }}
retention-days: 14
if-no-files-found: warn
- name: Upload CodeQL Results (SARIF) To GitHub Code Scanning
uses: github/codeql-action/upload-sarif@v3
if: steps.env_data.outputs.upload_sarif_file == 'true'
with:
# Path to SARIF file relative to the root of the repository.
sarif_file: ${{ steps.env_data.outputs.sarif_file_path }}
# Optional category for the results. Used to differentiate multiple results for one commit.
# Each package is a separate category.
category: ${{ matrix.Package }}

View File

@@ -1,44 +0,0 @@
# This workflow warns and then closes issues and PRs that have had no activity
# for a specified amount of time.
#
# For more information, see:
# https://github.com/actions/stale
#
# Copyright (c) Microsoft Corporation.
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
name: Stale Check
on:
schedule:
# At 23:35 on every day-of-week from Sunday through Saturday
# https://crontab.guru/#35_23_*_*_0-6
- cron: '35 23 * * 0-6'
workflow_dispatch:
jobs:
stale:
name: Stale
runs-on: ubuntu-latest
permissions:
issues: write
pull-requests: write
steps:
- name: Check for Stale Items
uses: actions/stale@v8
with:
days-before-issue-close: -1
days-before-issue-stale: -1
days-before-pr-stale: 60
days-before-pr-close: 7
stale-pr-message: >
This PR has been automatically marked as stale because it has not had
activity in 60 days. It will be closed if no further activity occurs within
7 days. Thank you for your contributions.
close-pr-message: >
This pull request has been automatically been closed because it did not have any
activity in 60 days and no follow up within 7 days after being marked stale.
Thank you for your contributions.
stale-pr-label: stale

33
.gitmodules vendored
View File

@@ -6,35 +6,4 @@
url = https://github.com/ucb-bar/berkeley-softfloat-3.git url = https://github.com/ucb-bar/berkeley-softfloat-3.git
[submodule "UnitTestFrameworkPkg/Library/CmockaLib/cmocka"] [submodule "UnitTestFrameworkPkg/Library/CmockaLib/cmocka"]
path = UnitTestFrameworkPkg/Library/CmockaLib/cmocka path = UnitTestFrameworkPkg/Library/CmockaLib/cmocka
url = https://github.com/tianocore/edk2-cmocka.git 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
[submodule "UnitTestFrameworkPkg/Library/GoogleTestLib/googletest"]
path = UnitTestFrameworkPkg/Library/GoogleTestLib/googletest
url = https://github.com/google/googletest.git
[submodule "UnitTestFrameworkPkg/Library/SubhookLib/subhook"]
path = UnitTestFrameworkPkg/Library/SubhookLib/subhook
url = https://github.com/Zeex/subhook.git
[submodule "MdePkg/Library/BaseFdtLib/libfdt"]
path = MdePkg/Library/BaseFdtLib/libfdt
url = https://github.com/devicetree-org/pylibfdt.git
[submodule "MdePkg/Library/MipiSysTLib/mipisyst"]
path = MdePkg/Library/MipiSysTLib/mipisyst
url = https://github.com/MIPI-Alliance/public-mipi-sys-t.git
[submodule "CryptoPkg/Library/MbedTlsLib/mbedtls"]
path = CryptoPkg/Library/MbedTlsLib/mbedtls
url = https://github.com/ARMmbed/mbedtls
[submodule "SecurityPkg/DeviceSecurity/SpdmLib/libspdm"]
path = SecurityPkg/DeviceSecurity/SpdmLib/libspdm
url = https://github.com/DMTF/libspdm.git

View File

@@ -1,7 +1,8 @@
# #
# This list is used by git-shortlog to update a few name translations # This list is used by git-shortlog to fix a few botched name translations
# in the git archive to adjust for job changes or incorrect/inconsistent # in the git archive, either because the author's full name was messed up
# name usage. # 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. # Please keep this file sorted alphabetically, and email in lowercase.
# The format used is: # 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@6f19259b-4bc3-4df7-8a09-765794883524>
Eric Dong <eric.dong@intel.com> <ydong10@Edk2> Eric Dong <eric.dong@intel.com> <ydong10@Edk2>
Erik Bjorge <erik.c.bjorge@intel.com> <geekboy15a@6f19259b-4bc3-4df7-8a09-765794883524> 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>
Hao A Wu <hao.a.wu@intel.com> <hwu1225@Edk2> Hao A Wu <hao.a.wu@intel.com> <hwu1225@Edk2>
Hot Tian <hot.tian@intel.com> 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> 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@6f19259b-4bc3-4df7-8a09-765794883524>
Laszlo Ersek <lersek@redhat.com> <lersek@Edk2> 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> <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@6f19259b-4bc3-4df7-8a09-765794883524>
Liming Gao <liming.gao@intel.com> <lgao4@Edk2> 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>
Marvin Häuser <Marvin.Haeuser@outlook.com> edk2-devel <edk2-devel-bounces@lists.01.org> Marvin Häuser <Marvin.Haeuser@outlook.com> edk2-devel <edk2-devel-bounces@lists.01.org>
Marvin Häuser <mhaeuser@outlook.de> Marvin Häuser <mhaeuser@outlook.de>
Matt DeVillier <matt.devillier@gmail.com>
Maurice Ma <maurice.ma@intel.com> Maurice Ma <maurice.ma@intel.com>
Michael Kubacki <michael.a.kubacki@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> 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> <Ruiyu.ni@Intel.com> Ray Ni <ray.ni@intel.com> <Ruiyu.ni@Intel.com>
Ray Ni <ray.ni@intel.com> <ruyu.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> <elhaj@hpe.com>
Samer El-Haj-Mahmoud <samer@elhajmahmoud.com> <Samer El-Haj-Mahmoud elhaj@hp.com> Samer El-Haj-Mahmoud <samer@elhajmahmoud.com> <Samer El-Haj-Mahmoud elhaj@hp.com>
Shenglei Zhang <shenglei.zhang@intel.com> Shenglei Zhang <shenglei.zhang@intel.com>
Star Zeng <star.zeng@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@6f19259b-4bc3-4df7-8a09-765794883524>
Star Zeng <star.zeng@intel.com> <lzeng14@Edk2> 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> 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> 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>
Yonghong Zhu <yonghong.zhu@intel.com> <yzhu52@Edk2> Yonghong Zhu <yonghong.zhu@intel.com> <yzhu52@Edk2>
Yu-Chen Lin <yuchenlin@synology.com> 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 # * 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. # of this file on other branches of a repo are ignored by Mergify.
# #
# Copyright (c) 2019 - 2021, Intel Corporation. All rights reserved.<BR> # Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
# SPDX-License-Identifier: BSD-2-Clause-Patent # SPDX-License-Identifier: BSD-2-Clause-Patent
# #
# https://github.com/apps/mergify # https://github.com/apps/mergify
@@ -24,26 +24,74 @@
# #
## ##
queue_rules:
- name: default
conditions:
- base~=(^main|^master|^stable/)
- label=push
pull_request_rules: pull_request_rules:
- name: Automatically merge a PR when all required checks pass and 'push' label is present - name: Automatically merge a PR when all required checks pass and 'push' label is present
conditions: conditions:
- base~=(^main|^master|^stable/) - base=master
- label=push - label=push
- author=@tianocore/edk-ii-maintainers
- status-success=tianocore.PatchCheck
- status-success=Ubuntu GCC5 PR
- status-success=Windows VS2019 PR
actions: actions:
queue: merge:
strict: true
method: rebase method: rebase
name: default
- name: Automatically close a PR when all required checks pass and 'push' label is not present
conditions:
- base=master
- -label=push
- -closed
- status-success=tianocore.PatchCheck
- status-success=Ubuntu GCC5 PR
- status-success=Windows VS2019 PR
- status-success=Ubuntu GCC5 PR (FINISHED)
- status-success=Windows VS2019 PR (FINISHED)
actions:
close:
message: All checks passed. Auto close personal build.
- name: Post a comment on a PR that can not be merged due to a merge conflict - name: Post a comment on a PR that can not be merged due to a merge conflict
conditions: conditions:
- base~=(^main|^master|^stable/) - base=master
- conflict - conflict
actions: actions:
comment: comment:
message: PR can not be merged due to conflict. Please rebase and resubmit message: PR can not be merged due to conflict. Please rebase and resubmit
- name: Automatically close a PR that fails the EDK II Maintainers membership check and 'push' label is present
conditions:
- base=master
- label=push
- -author=@tianocore/edk-ii-maintainers
actions:
close:
message: PR submitter is not a member of the Tianocore EDK II Maintainers team
- name: Post a comment on a PR if PatchCheck fails
conditions:
- base=master
- status-failure=tianocore.PatchCheck
actions:
comment:
message: PR can not be merged due to a PatchCheck failure. Please resolve and resubmit
- name: Post a comment on a PR if Ubuntu GCC5 fails
conditions:
- base=master
- status-failure=Ubuntu GCC5 PR
- status-success=Ubuntu GCC5 PR (FAILED)
actions:
comment:
message: PR can not be merged due to an Ubuntu GCC5 failure. Please resolve and resubmit
- name: Post a comment on a PR if Windows VS2019 fails
conditions:
- base=master
- status-failure=Windows VS2019 PR
- status-success=Windows VS2019 PR (FAILED)
actions:
comment:
message: PR can not be merged due to a Windows VS2019 failure. Please resolve and resubmit

View File

@@ -1,33 +1,16 @@
# @file # @file
# #
# Copyright (c) Microsoft Corporation. # 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 # SPDX-License-Identifier: BSD-2-Clause-Patent
## ##
import os import os
import logging import logging
import sys
from edk2toolext.environment import shell_environment from edk2toolext.environment import shell_environment
from edk2toolext.invocables.edk2_ci_build import CiBuildSettingsManager from edk2toolext.invocables.edk2_ci_build import CiBuildSettingsManager
from edk2toolext.invocables.edk2_setup import SetupSettingsManager, RequiredSubmodule from edk2toolext.invocables.edk2_setup import SetupSettingsManager, RequiredSubmodule
from edk2toolext.invocables.edk2_update import UpdateSettingsManager from edk2toolext.invocables.edk2_update import UpdateSettingsManager
from edk2toolext.invocables.edk2_pr_eval import PrEvalSettingsManager from edk2toolext.invocables.edk2_pr_eval import PrEvalSettingsManager
from edk2toollib.utility_functions import GetHostInfo from edk2toollib.utility_functions import GetHostInfo
from pathlib import Path
try:
# Temporarily needed until edk2 can update to the latest edk2-pytools
# that has the CodeQL helpers.
#
# May not be present until submodules are populated.
#
root = Path(__file__).parent.parent.resolve()
sys.path.append(str(root/'BaseTools'/'Plugin'/'CodeQL'/'integration'))
import stuart_codeql as codeql_helpers
except ImportError:
pass
class Settings(CiBuildSettingsManager, UpdateSettingsManager, SetupSettingsManager, PrEvalSettingsManager): class Settings(CiBuildSettingsManager, UpdateSettingsManager, SetupSettingsManager, PrEvalSettingsManager):
@@ -37,33 +20,15 @@ class Settings(CiBuildSettingsManager, UpdateSettingsManager, SetupSettingsManag
self.ActualTargets = [] self.ActualTargets = []
self.ActualArchitectures = [] self.ActualArchitectures = []
self.ActualToolChainTag = "" self.ActualToolChainTag = ""
self.UseBuiltInBaseTools = None
self.ActualScopes = None
# ####################################################################################### # # ####################################################################################### #
# Extra CmdLine configuration # # Extra CmdLine configuration #
# ####################################################################################### # # ####################################################################################### #
def AddCommandLineOptions(self, parserObj): 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")
try:
codeql_helpers.add_command_line_option(parserObj)
except NameError:
pass pass
def RetrieveCommandLineOptions(self, args): def RetrieveCommandLineOptions(self, args):
super().RetrieveCommandLineOptions(args)
if args.force_piptools:
self.UseBuiltInBaseTools = True
if args.no_piptools:
self.UseBuiltInBaseTools = False
try:
self.codeql = codeql_helpers.is_codeql_enabled_on_command_line(args)
except NameError:
pass pass
# ####################################################################################### # # ####################################################################################### #
@@ -74,15 +39,7 @@ class Settings(CiBuildSettingsManager, UpdateSettingsManager, SetupSettingsManag
''' return iterable of edk2 packages supported by this build. ''' return iterable of edk2 packages supported by this build.
These should be edk2 workspace relative paths ''' These should be edk2 workspace relative paths '''
return ("ArmPkg", return ("MdePkg",
"ArmPlatformPkg",
"ArmVirtPkg",
"DynamicTablesPkg",
"EmbeddedPkg",
"EmulatorPkg",
"IntelFsp2Pkg",
"IntelFsp2WrapperPkg",
"MdePkg",
"MdeModulePkg", "MdeModulePkg",
"NetworkPkg", "NetworkPkg",
"PcAtChipsetPkg", "PcAtChipsetPkg",
@@ -90,27 +47,17 @@ class Settings(CiBuildSettingsManager, UpdateSettingsManager, SetupSettingsManag
"UefiCpuPkg", "UefiCpuPkg",
"FmpDevicePkg", "FmpDevicePkg",
"ShellPkg", "ShellPkg",
"SignedCapsulePkg",
"StandaloneMmPkg",
"FatPkg", "FatPkg",
"CryptoPkg", "CryptoPkg",
"PrmPkg", "UnitTestFrameworkPkg"
"UnitTestFrameworkPkg",
"OvmfPkg",
"RedfishPkg",
"SourceLevelDebugPkg",
"UefiPayloadPkg"
) )
def GetArchitecturesSupported(self): def GetArchitecturesSupported(self):
''' return iterable of edk2 architectures supported by this build ''' ''' return iterable of edk2 architectures supported by this build '''
return ( return ("IA32",
"IA32",
"X64", "X64",
"ARM", "ARM",
"AARCH64", "AARCH64")
"RISCV64",
"LOONGARCH64")
def GetTargetsSupported(self): def GetTargetsSupported(self):
''' return iterable of edk2 target tags supported by this build ''' ''' return iterable of edk2 target tags supported by this build '''
@@ -171,42 +118,20 @@ class Settings(CiBuildSettingsManager, UpdateSettingsManager, SetupSettingsManag
def GetActiveScopes(self): def GetActiveScopes(self):
''' return tuple containing scopes that should be active for this process ''' ''' 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: if GetHostInfo().os.upper() == "LINUX" and self.ActualToolChainTag.upper().startswith("GCC"):
is_linux = GetHostInfo().os.upper() == "LINUX" if "AARCH64" in self.ActualArchitectures:
# try and import the pip module for basetools scopes += ("gcc_aarch64_linux",)
try: if "ARM" in self.ActualArchitectures:
import edk2basetools scopes += ("gcc_arm_linux",)
self.UseBuiltInBaseTools = True
except ImportError:
self.UseBuiltInBaseTools = False
pass
if self.UseBuiltInBaseTools == True: return scopes
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")
try:
scopes += codeql_helpers.get_scopes(self.codeql)
if self.codeql:
shell_environment.GetBuildVars().SetValue(
"STUART_CODEQL_AUDIT_ONLY",
"TRUE",
"Set in CISettings.py")
except NameError:
pass
self.ActualScopes = scopes
return self.ActualScopes
def GetRequiredSubmodules(self): def GetRequiredSubmodules(self):
''' return iterable containing RequiredSubmodule objects. ''' return iterable containing RequiredSubmodule objects.
@@ -219,26 +144,6 @@ class Settings(CiBuildSettingsManager, UpdateSettingsManager, SetupSettingsManag
"CryptoPkg/Library/OpensslLib/openssl", False)) "CryptoPkg/Library/OpensslLib/openssl", False))
rs.append(RequiredSubmodule( rs.append(RequiredSubmodule(
"UnitTestFrameworkPkg/Library/CmockaLib/cmocka", False)) "UnitTestFrameworkPkg/Library/CmockaLib/cmocka", False))
rs.append(RequiredSubmodule(
"UnitTestFrameworkPkg/Library/GoogleTestLib/googletest", 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))
rs.append(RequiredSubmodule(
"UnitTestFrameworkPkg/Library/SubhookLib/subhook", False))
rs.append(RequiredSubmodule(
"MdePkg/Library/BaseFdtLib/libfdt", False))
rs.append(RequiredSubmodule(
"MdePkg/Library/MipiSysTLib/mipisyst", False))
rs.append(RequiredSubmodule(
"CryptoPkg/Library/MbedTlsLib/mbedtls", False))
rs.append(RequiredSubmodule(
"SecurityPkg/DeviceSecurity/SpdmLib/libspdm", False))
return rs return rs
def GetName(self): def GetName(self):

View File

@@ -69,7 +69,7 @@ class CharEncodingCheck(ICiBuildPlugin):
overall_status = 0 overall_status = 0
files_tested = 0 files_tested = 0
abs_pkg_path = Edk2pathObj.GetAbsolutePathOnThisSystemFromEdk2RelativePath(packagename) abs_pkg_path = Edk2pathObj.GetAbsolutePathOnThisSytemFromEdk2RelativePath(packagename)
if abs_pkg_path is None: if abs_pkg_path is None:
tc.SetSkipped() tc.SetSkipped()
@@ -90,10 +90,12 @@ class CharEncodingCheck(ICiBuildPlugin):
tc.LogStdError("CharEncodingCheck.IgnoreInf -> {0} not found in filesystem. Invalid ignore file".format(a)) tc.LogStdError("CharEncodingCheck.IgnoreInf -> {0} not found in filesystem. Invalid ignore file".format(a))
logging.info("CharEncodingCheck.IgnoreInf -> {0} not found in filesystem. Invalid ignore file".format(a)) logging.info("CharEncodingCheck.IgnoreInf -> {0} not found in filesystem. Invalid ignore file".format(a))
files = [Edk2pathObj.GetAbsolutePathOnThisSystemFromEdk2RelativePath(x) for x in files] files = [Edk2pathObj.GetAbsolutePathOnThisSytemFromEdk2RelativePath(x) for x in files]
for a in files: for a in files:
files_tested += 1 files_tested += 1
if not self.TestEncodingOk(a, enc): if(self.TestEncodingOk(a, enc)):
logging.debug("File {0} Passed Encoding Check {1}".format(a, enc))
else:
tc.LogStdError("Encoding Failure in {0}. Not {1}".format(a, enc)) tc.LogStdError("Encoding Failure in {0}. Not {1}".format(a, enc))
overall_status += 1 overall_status += 1

View File

@@ -61,7 +61,7 @@ class CompilerPlugin(ICiBuildPlugin):
tc.LogStdError("DscPath not found in config file. Nothing to compile.") tc.LogStdError("DscPath not found in config file. Nothing to compile.")
return -1 return -1
AP = Edk2pathObj.GetAbsolutePathOnThisSystemFromEdk2RelativePath(packagename) AP = Edk2pathObj.GetAbsolutePathOnThisSytemFromEdk2RelativePath(packagename)
APDSC = os.path.join(AP, pkgconfig["DscPath"].strip()) APDSC = os.path.join(AP, pkgconfig["DscPath"].strip())
AP_Path = Edk2pathObj.GetEdk2RelativePathFromAbsolutePath(APDSC) AP_Path = Edk2pathObj.GetEdk2RelativePathFromAbsolutePath(APDSC)

View File

@@ -55,7 +55,7 @@ class DependencyCheck(ICiBuildPlugin):
overall_status = 0 overall_status = 0
# Get current platform # Get current platform
abs_pkg_path = Edk2pathObj.GetAbsolutePathOnThisSystemFromEdk2RelativePath(packagename) abs_pkg_path = Edk2pathObj.GetAbsolutePathOnThisSytemFromEdk2RelativePath(packagename)
# Get INF Files # Get INF Files
INFFiles = self.WalkDirectoryForExtension([".inf"], abs_pkg_path) INFFiles = self.WalkDirectoryForExtension([".inf"], abs_pkg_path)

View File

@@ -58,7 +58,7 @@ class DscCompleteCheck(ICiBuildPlugin):
"DscPath not found in config file. Nothing to check.") "DscPath not found in config file. Nothing to check.")
return -1 return -1
abs_pkg_path = Edk2pathObj.GetAbsolutePathOnThisSystemFromEdk2RelativePath( abs_pkg_path = Edk2pathObj.GetAbsolutePathOnThisSytemFromEdk2RelativePath(
packagename) packagename)
abs_dsc_path = os.path.join(abs_pkg_path, pkgconfig["DscPath"].strip()) abs_dsc_path = os.path.join(abs_pkg_path, pkgconfig["DscPath"].strip())
wsr_dsc_path = Edk2pathObj.GetEdk2RelativePathFromAbsolutePath( wsr_dsc_path = Edk2pathObj.GetEdk2RelativePathFromAbsolutePath(

View File

@@ -1,414 +0,0 @@
# @file EccCheck.py
#
# Copyright (c) 2021, Arm Limited. All rights reserved.<BR>
# 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": []
},
"""
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):
workspace_path = Edk2pathObj.WorkspacePath
basetools_path = environment.GetValue("EDK_TOOLS_PATH")
python_path = os.path.join(basetools_path, "Source", "Python")
env = shell_environment.GetEnvironment()
env.set_shell_var('PYTHONPATH', python_path)
env.set_shell_var('WORKSPACE', workspace_path)
env.set_shell_var('PACKAGES_PATH', os.pathsep.join(Edk2pathObj.PackagePathList))
self.ECC_PASS = True
abs_pkg_path = Edk2pathObj.GetAbsolutePathOnThisSystemFromEdk2RelativePath(packagename)
if abs_pkg_path is None:
tc.SetSkipped()
tc.LogStdError("No Package folder {0}".format(abs_pkg_path))
return 0
# Create temp directory
temp_path = os.path.join(workspace_path, 'Build', '.pytool', 'Plugin', 'EccCheck')
try:
# Delete temp directory
if os.path.exists(temp_path):
shutil.rmtree(temp_path)
# Copy package being scanned to temp_path
shutil.copytree (
abs_pkg_path,
os.path.join(temp_path, packagename),
symlinks=True
)
# Copy exception.xml to temp_path
shutil.copyfile (
os.path.join(basetools_path, "Source", "Python", "Ecc", "exception.xml"),
os.path.join(temp_path, "exception.xml")
)
# Output file to use for git diff operations
temp_diff_output = os.path.join (temp_path, 'diff.txt')
self.ApplyConfig(pkgconfig, temp_path, packagename)
modify_dir_list = self.GetModifyDir(packagename, temp_diff_output)
patch = self.GetDiff(packagename, temp_diff_output)
ecc_diff_range = self.GetDiffRange(patch, packagename, temp_path)
#
# Use temp_path as working directory when running ECC tool
#
self.GenerateEccReport(modify_dir_list, ecc_diff_range, temp_path, basetools_path)
ecc_log = os.path.join(temp_path, "Ecc.log")
if self.ECC_PASS:
# Delete temp directory
if os.path.exists(temp_path):
shutil.rmtree(temp_path)
tc.SetSuccess()
return 0
else:
with open(ecc_log, encoding='utf8') as output:
ecc_output = output.readlines()
for line in ecc_output:
logging.error(line.strip())
# Delete temp directory
if os.path.exists(temp_path):
shutil.rmtree(temp_path)
tc.SetFailed("EccCheck failed for {0}".format(packagename), "CHECK FAILED")
return 1
except KeyboardInterrupt:
# If EccCheck is interrupted by keybard interrupt, then return failure
# Delete temp directory
if os.path.exists(temp_path):
shutil.rmtree(temp_path)
tc.SetFailed("EccCheck interrupted for {0}".format(packagename), "CHECK FAILED")
return 1
else:
# If EccCheck fails for any other exception type, raise the exception
# Delete temp directory
if os.path.exists(temp_path):
shutil.rmtree(temp_path)
tc.SetFailed("EccCheck exception for {0}".format(packagename), "CHECK FAILED")
raise
return 1
def GetDiff(self, pkg: str, temp_diff_output: str) -> List[str]:
patch = []
#
# Generate unified diff between origin/master and HEAD.
#
params = "diff --output={} --unified=0 origin/master HEAD".format(temp_diff_output)
RunCmd("git", params)
with open(temp_diff_output) as file:
patch = file.read().strip().split('\n')
return patch
def GetModifyDir(self, pkg: str, temp_diff_output: str) -> List[str]:
#
# Generate diff between origin/master and HEAD using --diff-filter to
# exclude deleted and renamed files that do not need to be scanned by
# ECC. Also use --name-status to only generate the names of the files
# with differences. The output format of this git diff command is a
# list of files with the change status and the filename. The filename
# is always at the end of the line. Examples:
#
# M MdeModulePkg/Application/CapsuleApp/CapsuleApp.h
# M MdeModulePkg/Application/UiApp/FrontPage.h
#
params = "diff --output={} --diff-filter=dr --name-status origin/master HEAD".format(temp_diff_output)
RunCmd("git", params)
dir_list = []
with open(temp_diff_output) as file:
dir_list = file.read().strip().split('\n')
modify_dir_list = []
for modify_dir in dir_list:
#
# Parse file name from the end of the line
#
file_path = modify_dir.strip().split()
#
# Skip lines that do not have at least 2 elements (status and file name)
#
if len(file_path) < 2:
continue
#
# Parse the directory name from the file name
#
file_dir = os.path.dirname(file_path[-1])
#
# Skip directory names that do not start with the package being scanned.
#
if file_dir.split('/')[0] != pkg:
continue
#
# Skip directory names that are identical to the package being scanned.
# The assumption here is that there are no source files at the package
# root. Instead, the only expected files in the package root are
# EDK II meta data files (DEC, DSC, FDF).
#
if file_dir == pkg:
continue
#
# Skip directory names that are already in the modified dir list
#
if file_dir in modify_dir_list:
continue
#
# Add the candidate directory to scan to the modified dir list
#
modify_dir_list.append(file_dir)
#
# Remove duplicates from modify_dir_list
# Given a folder path, ECC performs a recursive scan of that folder.
# If a parent and child folder are both present in modify_dir_list,
# then ECC will perform redudanct scans of source files. In order
# to prevent redundant scans, if a parent and child folder are both
# present, then remove all the child folders.
#
# For example, if modified_dir_list contains the following elements:
# MdeModulePkg/Core/Dxe
# MdeModulePkg/Core/Dxe/Hand
# MdeModulePkg/Core/Dxe/Mem
#
# Then MdeModulePkg/Core/Dxe/Hand and MdeModulePkg/Core/Dxe/Mem should
# be removed because the files in those folders are covered by a scan
# of MdeModulePkg/Core/Dxe.
#
filtered_list = []
for dir1 in modify_dir_list:
Append = True
for dir2 in modify_dir_list:
if dir1 == dir2:
continue
common = os.path.commonpath([dir1, dir2])
if os.path.normpath(common) == os.path.normpath(dir2):
Append = False
break
if Append and dir1 not in filtered_list:
filtered_list.append(dir1)
return filtered_list
def GetDiffRange(self, patch_diff: List[str], pkg: str, temp_path: 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], temp_path)
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, temp_path: str) -> List[Tuple[int, int]]:
comment_range: List[Tuple[int, int]] = []
modify_file_path = os.path.join(temp_path, modify_file)
if not os.path.exists (modify_file_path):
return comment_range
with open(modify_file_path) as f:
line_no = 1
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]]],
temp_path: str, basetools_path: str) -> None:
ecc_need = False
ecc_run = True
config = os.path.normpath(os.path.join(basetools_path, "Source", "Python", "Ecc", "config.ini"))
exception = os.path.normpath(os.path.join(temp_path, "exception.xml"))
report = os.path.normpath(os.path.join(temp_path, "Ecc.csv"))
for modify_dir in modify_dir_list:
target = os.path.normpath(os.path.join(temp_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=temp_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, temp_path)
if not ecc_need:
logging.info("Doesn't need run ECC check")
return
def ParseEccReport(self, ecc_diff_range: Dict[str, List[Tuple[int, int]]], temp_path: str) -> None:
ecc_log = os.path.join(temp_path, "Ecc.log")
ecc_csv = os.path.join(temp_path, "Ecc.csv")
row_lines = []
ignore_error_code = self.GetIgnoreErrorCode()
if os.path.exists(ecc_csv):
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]], temp_path: str, pkg: str) -> None:
if "IgnoreFiles" in pkgconfig:
for a in pkgconfig["IgnoreFiles"]:
a = os.path.join(temp_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):
os.remove(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(temp_path, "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

@@ -116,7 +116,7 @@ class GuidCheck(ICiBuildPlugin):
def RunBuildPlugin(self, packagename, Edk2pathObj, pkgconfig, environment, PLM, PLMHelper, tc, output_stream=None): def RunBuildPlugin(self, packagename, Edk2pathObj, pkgconfig, environment, PLM, PLMHelper, tc, output_stream=None):
Errors = [] Errors = []
abs_pkg_path = Edk2pathObj.GetAbsolutePathOnThisSystemFromEdk2RelativePath( abs_pkg_path = Edk2pathObj.GetAbsolutePathOnThisSytemFromEdk2RelativePath(
packagename) packagename)
if abs_pkg_path is None: if abs_pkg_path is None:

View File

@@ -93,7 +93,7 @@ class HostUnitTestCompilerPlugin(ICiBuildPlugin):
tc.LogStdError("DscPath not found in config file. Nothing to compile for HostBasedUnitTests.") tc.LogStdError("DscPath not found in config file. Nothing to compile for HostBasedUnitTests.")
return -1 return -1
AP = Edk2pathObj.GetAbsolutePathOnThisSystemFromEdk2RelativePath(packagename) AP = Edk2pathObj.GetAbsolutePathOnThisSytemFromEdk2RelativePath(packagename)
APDSC = os.path.join(AP, pkgconfig["DscPath"].strip()) APDSC = os.path.join(AP, pkgconfig["DscPath"].strip())
AP_Path = Edk2pathObj.GetEdk2RelativePathFromAbsolutePath(APDSC) AP_Path = Edk2pathObj.GetEdk2RelativePathFromAbsolutePath(APDSC)

View File

@@ -10,7 +10,7 @@ import logging
import os import os
from edk2toolext.environment.plugintypes.ci_build_plugin import ICiBuildPlugin from edk2toolext.environment.plugintypes.ci_build_plugin import ICiBuildPlugin
from edk2toollib.uefi.edk2.parsers.dsc_parser import DscParser from edk2toollib.uefi.edk2.parsers.dsc_parser import DscParser
from edk2toollib.uefi.edk2.parsers.inf_parser import InfParser, AllPhases from edk2toollib.uefi.edk2.parsers.inf_parser import InfParser
from edk2toolext.environment.var_dict import VarDict from edk2toolext.environment.var_dict import VarDict
@@ -61,7 +61,7 @@ class HostUnitTestDscCompleteCheck(ICiBuildPlugin):
"DscPath not found in config file. Nothing to check.") "DscPath not found in config file. Nothing to check.")
return -1 return -1
abs_pkg_path = Edk2pathObj.GetAbsolutePathOnThisSystemFromEdk2RelativePath( abs_pkg_path = Edk2pathObj.GetAbsolutePathOnThisSytemFromEdk2RelativePath(
packagename) packagename)
abs_dsc_path = os.path.join(abs_pkg_path, pkgconfig["DscPath"].strip()) abs_dsc_path = os.path.join(abs_pkg_path, pkgconfig["DscPath"].strip())
wsr_dsc_path = Edk2pathObj.GetEdk2RelativePathFromAbsolutePath( wsr_dsc_path = Edk2pathObj.GetEdk2RelativePathFromAbsolutePath(
@@ -116,9 +116,8 @@ class HostUnitTestDscCompleteCheck(ICiBuildPlugin):
# should compile test a library that is declared type HOST_APPLICATION # should compile test a library that is declared type HOST_APPLICATION
pass pass
elif (len(infp.SupportedPhases) > 0 and elif len(infp.SupportedPhases) > 0 and \
"HOST_APPLICATION" in infp.SupportedPhases and "HOST_APPLICATION" in infp.SupportedPhases:
infp.SupportedPhases != AllPhases):
# should compile test a library that supports HOST_APPLICATION but # should compile test a library that supports HOST_APPLICATION but
# require it to be an explicit opt-in # require it to be an explicit opt-in
pass pass

View File

@@ -63,7 +63,7 @@ class LibraryClassCheck(ICiBuildPlugin):
overall_status = 0 overall_status = 0
LibraryClassIgnore = [] LibraryClassIgnore = []
abs_pkg_path = Edk2pathObj.GetAbsolutePathOnThisSystemFromEdk2RelativePath(packagename) abs_pkg_path = Edk2pathObj.GetAbsolutePathOnThisSytemFromEdk2RelativePath(packagename)
abs_dec_path = self.__GetPkgDec(abs_pkg_path) abs_dec_path = self.__GetPkgDec(abs_pkg_path)
wsr_dec_path = Edk2pathObj.GetEdk2RelativePathFromAbsolutePath(abs_dec_path) wsr_dec_path = Edk2pathObj.GetEdk2RelativePathFromAbsolutePath(abs_dec_path)

View File

@@ -1,123 +0,0 @@
# @file LicenseCheck.py
#
# Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
# SPDX-License-Identifier: BSD-2-Clause-Patent
##
import os
import shutil
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):
# Create temp directory
temp_path = os.path.join(Edk2pathObj.WorkspacePath, 'Build', '.pytool', 'Plugin', 'LicenseCheck')
if not os.path.exists(temp_path):
os.makedirs(temp_path)
# Output file to use for git diff operations
temp_diff_output = os.path.join (temp_path, 'diff.txt')
params = "diff --output={} --unified=0 origin/master HEAD".format(temp_diff_output)
RunCmd("git", params)
with open(temp_diff_output) as file:
patch = file.read().strip().split("\n")
# Delete temp directory
if os.path.exists(temp_path):
shutil.rmtree(temp_path)
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

@@ -37,12 +37,12 @@ class SpellCheck(ICiBuildPlugin):
# #
# A package can remove any of these using IgnoreStandardPaths # A package can remove any of these using IgnoreStandardPaths
# #
STANDARD_PLUGIN_DEFINED_PATHS = ("*.c", "*.h", STANDARD_PLUGIN_DEFINED_PATHS = ["*.c", "*.h",
"*.nasm", "*.asm", "*.masm", "*.s", "*.nasm", "*.asm", "*.masm", "*.s",
"*.asl", "*.asl",
"*.dsc", "*.dec", "*.fdf", "*.inf", "*.dsc", "*.dec", "*.fdf", "*.inf",
"*.md", "*.txt" "*.md", "*.txt"
) ]
def GetTestName(self, packagename: str, environment: VarDict) -> tuple: def GetTestName(self, packagename: str, environment: VarDict) -> tuple:
""" Provide the testcase name and classname for use in reporting """ Provide the testcase name and classname for use in reporting
@@ -73,7 +73,7 @@ class SpellCheck(ICiBuildPlugin):
def RunBuildPlugin(self, packagename, Edk2pathObj, pkgconfig, environment, PLM, PLMHelper, tc, output_stream=None): def RunBuildPlugin(self, packagename, Edk2pathObj, pkgconfig, environment, PLM, PLMHelper, tc, output_stream=None):
Errors = [] Errors = []
abs_pkg_path = Edk2pathObj.GetAbsolutePathOnThisSystemFromEdk2RelativePath( abs_pkg_path = Edk2pathObj.GetAbsolutePathOnThisSytemFromEdk2RelativePath(
packagename) packagename)
if abs_pkg_path is None: if abs_pkg_path is None:
@@ -107,8 +107,7 @@ class SpellCheck(ICiBuildPlugin):
version_aggregator.GetVersionAggregator().ReportVersion( version_aggregator.GetVersionAggregator().ReportVersion(
"CSpell", cspell_version, version_aggregator.VersionTypes.INFO) "CSpell", cspell_version, version_aggregator.VersionTypes.INFO)
# copy the default as a list package_relative_paths_to_spell_check = SpellCheck.STANDARD_PLUGIN_DEFINED_PATHS
package_relative_paths_to_spell_check = list(SpellCheck.STANDARD_PLUGIN_DEFINED_PATHS)
# #
# Allow the ci.yaml to remove any of the above standard paths # Allow the ci.yaml to remove any of the above standard paths
@@ -134,8 +133,7 @@ class SpellCheck(ICiBuildPlugin):
# #
relpath = os.path.relpath(abs_pkg_path) relpath = os.path.relpath(abs_pkg_path)
cpsell_paths = " ".join( cpsell_paths = " ".join(
# Double quote each path to defer expansion to cspell parameters [f"{relpath}/**/{x}" for x in package_relative_paths_to_spell_check])
[f'"{relpath}/**/{x}"' for x in package_relative_paths_to_spell_check])
# Make the config file # Make the config file
config_file_path = os.path.join( config_file_path = os.path.join(

View File

@@ -21,9 +21,7 @@
"*.jpg" "*.jpg"
], ],
"minWordLength": 5, "minWordLength": 5,
"allowCompoundWords": true, "allowCompoundWords": false,
"maxNumberOfProblems": 200,
"maxDuplicateProblems": 200,
"ignoreWords": [ "ignoreWords": [
"muchange" "muchange"
], ],
@@ -163,134 +161,5 @@
"bootability", "bootability",
"Sdhci", "Sdhci",
"inmodule", "inmodule",
"RISCV",
"edksetup",
"iscsi",
"nvdata",
"pytools",
"NTDDI",
"Wnonportable",
"CLANGPDB",
"nologo",
"lldmap",
"ASMLINK",
"NODEFAULTLIB",
"vcruntimed",
"ucrtd",
"msvcrtd",
"XIPFLAGS",
"bootflow",
"bootup",
"cacheability",
"cachetype",
"conout",
"deadloop",
"devicepath",
"hisilicon",
"littleendian",
"nonsecure",
"pagetable",
"postmem",
"premem",
"reglist",
"semihalf",
"subvendor",
"subhierarchy",
"targetlist",
"tmpname",
"watchdogtimer",
"writeback",
"langcode",
"langcodes",
"autoreload",
"bootable",
"endiannness",
"fvmain",
"prefetchable",
"multiboot",
"ramdisk",
"unbootable",
"setjump",
"bytecodes",
"bytelist",
"bytestream",
"countof",
"deregistering",
"devicetree",
"mainpage",
"mismanipulation",
"pytool",
"wbinvd",
"armltd",
"datacache",
"lastattemptstatus",
"lastattemptversion",
"lowestsupportedversion",
"updateable",
"pecoff",
"autodetect",
"harddisk",
"toctou",
"bugbug",
"depexes",
"fwvol",
"hoblist",
"imagehandle",
"schedulable",
"StandaloneMMCore",
"systemtable",
"uncacheable",
"devpath",
"testsuites",
"testcase",
"pxmldoc",
"pcxml",
"pclutf",
"pcunicode",
"ntxmltransformcharacter",
"ntxmlcomparestrings",
"pcxmldoc",
"ntxmlfetchcharacterdecoder",
"ntxml",
"ntxmlspecialstringcompare",
"rtlxmlcallback",
"xmlef",
"osruntime",
"readytoboot",
"hwerrrec",
"xformed",
"xform",
"undock",
"qrencoder",
"selawik",
"ntxmlrawnextcharacter",
"undocked",
"reprompt",
"yesno",
"okcancel",
"qrencoding",
"qrlevel",
"shiftn",
"unenroll",
"pcxmlstructure",
"pxmlstructure",
"pcencoder",
"pcvoid",
"nofailure",
"blockio",
"lockv",
"uefishelldebug",
"mtrrcap",
"drhds",
"rmrrs",
"creatorid",
"dxeipl",
"swmdialogs",
"unrecovered",
"cmocka",
"unenrolling",
"unconfigure",
"Loongson",
"LOONGARCH"
] ]
} }

View File

@@ -1,127 +0,0 @@
# UncrustifyCheck Plugin
This CiBuildPlugin scans all the files in a given package and checks for coding standard compliance issues.
This plugin is enabled by default. If a package would like to prevent the plugin from reporting errors, it can do
so by enabling [`AuditOnly`](#auditonly) mode.
This plugin requires the directory containing the Uncrustify executable that should be used for this plugin to
be specified in an environment variable named `UNCRUSTIFY_CI_PATH`. This unique variable name is used to avoid confusion
with other paths to Uncrustify which might not be the expected build for use by this plugin.
By default, an Uncrustify configuration file named "uncrustify.cfg" located in the same directory as the plugin is
used. The value can be overridden to a package-specific path with the `ConfigFilePath` configuration file option.
* Uncrustify source code and documentation: https://github.com/uncrustify/uncrustify
* Project Mu Uncrustify fork source code and documentation: https://dev.azure.com/projectmu/Uncrustify
## Files Checked in a Package
By default, this plugin will discover all files in the package with the following default paths:
```python
[
# C source
"*.c",
"*.h"
]
```
From this list of files, any files ignored by Git or residing in a Git submodule will be removed. If Git is not
found, submodules are not found, or ignored files are not found no changes are made to the list of discovered files.
To control the paths checked in a given package, review the configuration options described in this file.
## Configuration
The plugin can be configured with a few optional configuration options.
``` yaml
"UncrustifyCheck": {
"AdditionalIncludePaths": [], # Additional paths to check formatting (wildcards supported).
"AuditOnly": False, # Don't fail the build if there are errors. Just log them.
"ConfigFilePath": "", # Custom path to an Uncrustify config file.
"IgnoreFiles": [], # A list of file patterns to ignore.
"IgnoreStandardPaths": [], # Standard Plugin defined paths that should be ignored.
"OutputFileDiffs": True, # Output chunks of formatting diffs in the test case log.
# This can significantly slow down the plugin on very large packages.
"SkipGitExclusions": False # Don't exclude git ignored files and files in git submodules.
}
```
### `AdditionalIncludePaths`
A package configuration file can specify any additional paths to be included with this option.
At this time, it is recommended all files run against the plugin be written in the C or C++ language.
### `AuditOnly`
`Boolean` - Default is `False`.
If `True`, run the test in an "audit only mode" which will log all errors but instead of failing the build, it will set
the test as skipped. This allows visibility into the failures without breaking the build.
### `ConfigFilePath`
`String` - Default is `"uncrustify.cfg"`
When specified in the config file, this is a package relative path to the Uncrustify configuration file.
### `IgnoreFiles`
This option supports .gitignore file and folder matching strings including wildcards.
The files specified by this configuration option will not be processed by Uncrustify.
### `IgnoreStandardPaths`
This plugin by default will check the below standard paths. A package configuration file can specify any of these paths
to be ignored.
```python
[
# C source
"*.c",
"*.h"
]
```
### `OutputFileDiffs`
`Boolean` - Default is `True`.
If `True`, output diffs of formatting changes into the test case log. This is helpful to exactly understand what changes
need to be made to the source code in order to fix a coding standard compliance issue.
Note that calculating the file diffs on a very large set of of results (e.g. >100 files) can significantly slow down
plugin execution.
### `SkipGitExclusions`
`Boolean` - Default is `False`.
By default, files in paths matched in a .gitignore file or a recognized git submodule are excluded. If this option
is `True`, the plugin will not attempt to recognize these files and exclude them.
## High-Level Plugin Operation
This plugin generates two main sets of temporary files:
1. A working directory in the directory `Build/.pytool/Plugin/Uncrustify`
2. For each source file with formatting errors, a sibling file with the `.uncrustify_plugin` extension
The working directory contains temporary files unique to operation of the plugin. All of these files are removed on
exit of the plugin including successful or unsuccessful execution (such as a Python exception occurring). If for any
reason, any files in the package exist prior to running the plugin with the `.uncrustify_plugin` extension, the plugin
will inform the user to remove these files and exit before running Uncrustify. This is to ensure the accuracy of the
results reported from each execution instance of the plugin.
The plugin determines the list of relevant files to check with Uncrustify and then invokes Uncrustify with that file
list. For any files not compliant to the configuration file provided, Uncrustify will generate a corresponding file
with the `.uncrustify_plugin` extension. The plugin discovers all of these files. If any such files are present, this
indicates a formatting issue was found and the test is marked failed (unless `AuditOnly` mode is enabled).
The test case log will contain a report of which files failed to format properly, allowing the user to run Uncrustify
against the file locally to fix the issue. If the `OutputFileDiffs` configuration option is set to `True`, the plugin
will output diff chunks for all code formatting issues in the test case log.

View File

@@ -1,661 +0,0 @@
# @file UncrustifyCheck.py
#
# An edk2-pytool based plugin wrapper for Uncrustify
#
# Copyright (c) Microsoft Corporation.
# SPDX-License-Identifier: BSD-2-Clause-Patent
##
import configparser
import difflib
import errno
import logging
import os
import pathlib
import shutil
import stat
import timeit
from edk2toolext.environment import version_aggregator
from edk2toolext.environment.plugin_manager import PluginManager
from edk2toolext.environment.plugintypes.ci_build_plugin import ICiBuildPlugin
from edk2toolext.environment.plugintypes.uefi_helper_plugin import HelperFunctions
from edk2toolext.environment.var_dict import VarDict
from edk2toollib.gitignore_parser import parse_gitignore_lines
from edk2toollib.log.junit_report_format import JunitReportTestCase
from edk2toollib.uefi.edk2.path_utilities import Edk2Path
from edk2toollib.utility_functions import RunCmd
from io import StringIO
from typing import Any, Dict, List, Tuple
#
# Provide more user friendly messages for certain scenarios
#
class UncrustifyException(Exception):
def __init__(self, message, exit_code):
super().__init__(message)
self.exit_code = exit_code
class UncrustifyAppEnvVarNotFoundException(UncrustifyException):
def __init__(self, message):
super().__init__(message, -101)
class UncrustifyAppVersionErrorException(UncrustifyException):
def __init__(self, message):
super().__init__(message, -102)
class UncrustifyAppExecutionException(UncrustifyException):
def __init__(self, message):
super().__init__(message, -103)
class UncrustifyStalePluginFormattedFilesException(UncrustifyException):
def __init__(self, message):
super().__init__(message, -120)
class UncrustifyInputFileCreationErrorException(UncrustifyException):
def __init__(self, message):
super().__init__(message, -121)
class UncrustifyInvalidIgnoreStandardPathsException(UncrustifyException):
def __init__(self, message):
super().__init__(message, -122)
class UncrustifyGitIgnoreFileException(UncrustifyException):
def __init__(self, message):
super().__init__(message, -140)
class UncrustifyGitSubmoduleException(UncrustifyException):
def __init__(self, message):
super().__init__(message, -141)
class UncrustifyCheck(ICiBuildPlugin):
"""
A CiBuildPlugin that uses Uncrustify to check the source files in the
package being tested for coding standard issues.
By default, the plugin runs against standard C source file extensions but
its configuration can be modified through its configuration file.
Configuration options:
"UncrustifyCheck": {
"AdditionalIncludePaths": [], # Additional paths to check formatting (wildcards supported).
"AuditOnly": False, # Don't fail the build if there are errors. Just log them.
"ConfigFilePath": "", # Custom path to an Uncrustify config file.
"IgnoreStandardPaths": [], # Standard Plugin defined paths that should be ignored.
"OutputFileDiffs": False, # Output chunks of formatting diffs in the test case log.
# This can significantly slow down the plugin on very large packages.
"SkipGitExclusions": False # Don't exclude git ignored files and files in git submodules.
}
"""
#
# By default, use an "uncrustify.cfg" config file in the plugin directory
# A package can override this path via "ConfigFilePath"
#
# Note: Values specified via "ConfigFilePath" are relative to the package
#
DEFAULT_CONFIG_FILE_PATH = os.path.join(
pathlib.Path(__file__).parent.resolve(), "uncrustify.cfg")
#
# The extension used for formatted files produced by this plugin
#
FORMATTED_FILE_EXTENSION = ".uncrustify_plugin"
#
# A package can add any additional paths with "AdditionalIncludePaths"
# A package can remove any of these paths with "IgnoreStandardPaths"
#
STANDARD_PLUGIN_DEFINED_PATHS = ("*.c", "*.h", "*.cpp")
#
# The Uncrustify application path should set in this environment variable
#
UNCRUSTIFY_PATH_ENV_KEY = "UNCRUSTIFY_CI_PATH"
def GetTestName(self, packagename: str, environment: VarDict) -> Tuple:
""" Provide the testcase name and classname for use in reporting
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)
testclassname: a descriptive string for the testcase can include whitespace
classname: should be patterned <packagename>.<plugin>.<optionally any unique condition>
"""
return ("Check file coding standard compliance in " + packagename, packagename + ".UncrustifyCheck")
def RunBuildPlugin(self, package_rel_path: str, edk2_path: Edk2Path, package_config: Dict[str, List[str]], environment_config: Any, plugin_manager: PluginManager, plugin_manager_helper: HelperFunctions, tc: JunitReportTestCase, output_stream=None) -> int:
"""
External function of plugin. This function is used to perform the task of the CiBuild Plugin.
Args:
- package_rel_path: edk2 workspace relative path to the package
- edk2_path: Edk2Path object with workspace and packages paths
- package_config: Dictionary with the package configuration
- environment_config: Environment configuration
- plugin_manager: Plugin Manager Instance
- plugin_manager_helper: Plugin Manager Helper Instance
- tc: JUnit test case
- output_stream: The StringIO output stream from this plugin (logging)
Returns
>0 : Number of errors found
0 : Passed successfully
-1 : Skipped for missing prereq
"""
try:
# Initialize plugin and check pre-requisites.
self._initialize_environment_info(
package_rel_path, edk2_path, package_config, tc)
self._initialize_configuration()
self._check_for_preexisting_formatted_files()
# Log important context information.
self._log_uncrustify_app_info()
# Get template file contents if specified
self._get_template_file_contents()
# Create meta input files & directories
self._create_temp_working_directory()
self._create_uncrustify_file_list_file()
self._run_uncrustify()
# Post-execution actions.
self._process_uncrustify_results()
except UncrustifyException as e:
self._tc.LogStdError(
f"Uncrustify error {e.exit_code}. Details:\n\n{str(e)}")
logging.warning(
f"Uncrustify error {e.exit_code}. Details:\n\n{str(e)}")
return -1
else:
if self._formatted_file_error_count > 0:
if self._audit_only_mode:
logging.info(
"Setting test as skipped since AuditOnly is enabled")
self._tc.SetSkipped()
return -1
else:
self._tc.SetFailed(
f"{self._plugin_name} failed due to {self._formatted_file_error_count} incorrectly formatted files.", "CHECK_FAILED")
else:
self._tc.SetSuccess()
return self._formatted_file_error_count
finally:
self._cleanup_temporary_formatted_files()
self._cleanup_temporary_directory()
def _initialize_configuration(self) -> None:
"""
Initializes plugin configuration.
"""
self._initialize_app_info()
self._initialize_config_file_info()
self._initialize_file_to_format_info()
self._initialize_test_case_output_options()
def _check_for_preexisting_formatted_files(self) -> None:
"""
Checks if any formatted files from prior execution are present.
Existence of such files is an unexpected condition. This might result
from an error that occurred during a previous run or a premature exit from a debug scenario. In any case, the package should be clean before starting a new run.
"""
pre_existing_formatted_file_count = len(
[str(path.resolve()) for path in pathlib.Path(self._abs_package_path).rglob(f'*{UncrustifyCheck.FORMATTED_FILE_EXTENSION}')])
if pre_existing_formatted_file_count > 0:
raise UncrustifyStalePluginFormattedFilesException(
f"{pre_existing_formatted_file_count} formatted files already exist. To prevent overwriting these files, please remove them before running this plugin.")
def _cleanup_temporary_directory(self) -> None:
"""
Cleans up the temporary directory used for this execution instance.
This removes the directory and all files created during this instance.
"""
if hasattr(self, '_working_dir'):
self._remove_tree(self._working_dir)
def _cleanup_temporary_formatted_files(self) -> None:
"""
Cleans up the temporary formmatted files produced by Uncrustify.
This will recursively remove all formatted files generated by Uncrustify
during this execution instance.
"""
if hasattr(self, '_abs_package_path'):
formatted_files = [str(path.resolve()) for path in pathlib.Path(
self._abs_package_path).rglob(f'*{UncrustifyCheck.FORMATTED_FILE_EXTENSION}')]
for formatted_file in formatted_files:
os.remove(formatted_file)
def _create_temp_working_directory(self) -> None:
"""
Creates the temporary directory used for this execution instance.
"""
self._working_dir = os.path.join(
self._abs_workspace_path, "Build", ".pytool", "Plugin", f"{self._plugin_name}")
try:
pathlib.Path(self._working_dir).mkdir(parents=True, exist_ok=True)
except OSError as e:
raise UncrustifyInputFileCreationErrorException(
f"Error creating plugin directory {self._working_dir}.\n\n{repr(e)}.")
def _create_uncrustify_file_list_file(self) -> None:
"""
Creates the file with the list of source files for Uncrustify to process.
"""
self._app_input_file_path = os.path.join(
self._working_dir, "uncrustify_file_list.txt")
with open(self._app_input_file_path, 'w', encoding='utf8') as f:
f.writelines(f"\n".join(self._abs_file_paths_to_format))
def _execute_uncrustify(self) -> None:
"""
Executes Uncrustify with the initialized configuration.
"""
output = StringIO()
self._app_exit_code = RunCmd(
self._app_path,
f"-c {self._app_config_file} -F {self._app_input_file_path} --if-changed --suffix {UncrustifyCheck.FORMATTED_FILE_EXTENSION}", outstream=output)
self._app_output = output.getvalue().strip().splitlines()
def _get_files_ignored_in_config(self):
""""
Returns a function that returns true if a given file string path is ignored in the plugin configuration file and false otherwise.
"""
ignored_files = []
if "IgnoreFiles" in self._package_config:
ignored_files = self._package_config["IgnoreFiles"]
# Pass "Package configuration file" as the source file path since
# the actual configuration file name is unknown to this plugin and
# this provides a generic description of the file that provided
# the ignore file content.
#
# This information is only used for reporting (not used here) and
# the ignore lines are being passed directly as they are given to
# this plugin.
return parse_gitignore_lines(ignored_files, "Package configuration file", self._abs_package_path)
def _get_git_ignored_paths(self) -> List[str]:
""""
Returns a list of file absolute path strings to all files ignored in this git repository.
If git is not found, an empty list will be returned.
"""
if not shutil.which("git"):
logging.warning(
"Git is not found on this system. Git submodule paths will not be considered.")
return []
outstream_buffer = StringIO()
exit_code = RunCmd("git", "ls-files --other",
workingdir=self._abs_workspace_path, outstream=outstream_buffer, logging_level=logging.NOTSET)
if (exit_code != 0):
raise UncrustifyGitIgnoreFileException(
f"An error occurred reading git ignore settings. This will prevent Uncrustify from running against the expected set of files.")
# Note: This will potentially be a large list, but at least sorted
rel_paths = outstream_buffer.getvalue().strip().splitlines()
abs_paths = []
for path in rel_paths:
abs_paths.append(
os.path.normpath(os.path.join(self._abs_workspace_path, path)))
return abs_paths
def _get_git_submodule_paths(self) -> List[str]:
"""
Returns a list of directory absolute path strings to the root of each submodule in the workspace repository.
If git is not found, an empty list will be returned.
"""
if not shutil.which("git"):
logging.warning(
"Git is not found on this system. Git submodule paths will not be considered.")
return []
if os.path.isfile(os.path.join(self._abs_workspace_path, ".gitmodules")):
logging.info(
f".gitmodules file found. Excluding submodules in {self._package_name}.")
outstream_buffer = StringIO()
exit_code = RunCmd("git", "config --file .gitmodules --get-regexp path", workingdir=self._abs_workspace_path, outstream=outstream_buffer, logging_level=logging.NOTSET)
if (exit_code != 0):
raise UncrustifyGitSubmoduleException(
f".gitmodule file detected but an error occurred reading the file. Cannot proceed with unknown submodule paths.")
submodule_paths = []
for line in outstream_buffer.getvalue().strip().splitlines():
submodule_paths.append(
os.path.normpath(os.path.join(self._abs_workspace_path, line.split()[1])))
return submodule_paths
else:
return []
def _get_template_file_contents(self) -> None:
"""
Gets the contents of Uncrustify template files if they are specified
in the Uncrustify configuration file.
"""
self._file_template_contents = None
self._func_template_contents = None
# Allow no value to allow "set" statements in the config file which do
# not specify value assignment
parser = configparser.ConfigParser(allow_no_value=True)
with open(self._app_config_file, 'r') as cf:
parser.read_string("[dummy_section]\n" + cf.read())
try:
file_template_name = parser["dummy_section"]["cmt_insert_file_header"]
file_template_path = pathlib.Path(file_template_name)
if not file_template_path.is_file():
file_template_path = pathlib.Path(os.path.join(self._plugin_path, file_template_name))
self._file_template_contents = file_template_path.read_text()
except KeyError:
logging.warning("A file header template is not specified in the config file.")
except FileNotFoundError:
logging.warning("The specified file header template file was not found.")
try:
func_template_name = parser["dummy_section"]["cmt_insert_func_header"]
func_template_path = pathlib.Path(func_template_name)
if not func_template_path.is_file():
func_template_path = pathlib.Path(os.path.join(self._plugin_path, func_template_name))
self._func_template_contents = func_template_path.read_text()
except KeyError:
logging.warning("A function header template is not specified in the config file.")
except FileNotFoundError:
logging.warning("The specified function header template file was not found.")
def _initialize_app_info(self) -> None:
"""
Initialize Uncrustify application information.
This function will determine the application path and version.
"""
# Verify Uncrustify is specified in the environment.
if UncrustifyCheck.UNCRUSTIFY_PATH_ENV_KEY not in os.environ:
raise UncrustifyAppEnvVarNotFoundException(
f"Uncrustify environment variable {UncrustifyCheck.UNCRUSTIFY_PATH_ENV_KEY} is not present.")
self._app_path = shutil.which('uncrustify', path=os.environ[UncrustifyCheck.UNCRUSTIFY_PATH_ENV_KEY])
if self._app_path is None:
raise FileNotFoundError(
errno.ENOENT, os.strerror(errno.ENOENT), self._app_path)
self._app_path = os.path.normcase(os.path.normpath(self._app_path))
if not os.path.isfile(self._app_path):
raise FileNotFoundError(
errno.ENOENT, os.strerror(errno.ENOENT), self._app_path)
# Verify Uncrustify is present at the expected path.
return_buffer = StringIO()
ret = RunCmd(self._app_path, "--version", outstream=return_buffer)
if (ret != 0):
raise UncrustifyAppVersionErrorException(
f"Error occurred executing --version: {ret}.")
# Log Uncrustify version information.
self._app_version = return_buffer.getvalue().strip()
self._tc.LogStdOut(f"Uncrustify version: {self._app_version}")
version_aggregator.GetVersionAggregator().ReportVersion(
"Uncrustify", self._app_version, version_aggregator.VersionTypes.INFO)
def _initialize_config_file_info(self) -> None:
"""
Initialize Uncrustify configuration file info.
The config file path is relative to the package root.
"""
self._app_config_file = UncrustifyCheck.DEFAULT_CONFIG_FILE_PATH
if "ConfigFilePath" in self._package_config:
self._app_config_file = self._package_config["ConfigFilePath"].strip()
self._app_config_file = os.path.normpath(
os.path.join(self._abs_package_path, self._app_config_file))
if not os.path.isfile(self._app_config_file):
raise FileNotFoundError(
errno.ENOENT, os.strerror(errno.ENOENT), self._app_config_file)
def _initialize_environment_info(self, package_rel_path: str, edk2_path: Edk2Path, package_config: Dict[str, List[str]], tc: JunitReportTestCase) -> None:
"""
Initializes plugin environment information.
"""
self._abs_package_path = edk2_path.GetAbsolutePathOnThisSystemFromEdk2RelativePath(
package_rel_path)
self._abs_workspace_path = edk2_path.WorkspacePath
self._package_config = package_config
self._package_name = os.path.basename(
os.path.normpath(package_rel_path))
self._plugin_name = self.__class__.__name__
self._plugin_path = os.path.dirname(os.path.realpath(__file__))
self._rel_package_path = package_rel_path
self._tc = tc
def _initialize_file_to_format_info(self) -> None:
"""
Forms the list of source files for Uncrustify to process.
"""
# Create a list of all the package relative file paths in the package to run against Uncrustify.
rel_file_paths_to_format = list(
UncrustifyCheck.STANDARD_PLUGIN_DEFINED_PATHS)
# Allow the ci.yaml to remove any of the pre-defined standard paths
if "IgnoreStandardPaths" in self._package_config:
for a in self._package_config["IgnoreStandardPaths"]:
if a.strip() in rel_file_paths_to_format:
self._tc.LogStdOut(
f"Ignoring standard path due to ci.yaml ignore: {a}")
rel_file_paths_to_format.remove(a.strip())
else:
raise UncrustifyInvalidIgnoreStandardPathsException(f"Invalid IgnoreStandardPaths value: {a}")
# Allow the ci.yaml to specify additional include paths for this package
if "AdditionalIncludePaths" in self._package_config:
rel_file_paths_to_format.extend(
self._package_config["AdditionalIncludePaths"])
self._abs_file_paths_to_format = []
for path in rel_file_paths_to_format:
self._abs_file_paths_to_format.extend(
[str(path.resolve()) for path in pathlib.Path(self._abs_package_path).rglob(path)])
# Remove files ignore in the plugin configuration file
plugin_ignored_files = list(filter(self._get_files_ignored_in_config(), self._abs_file_paths_to_format))
if plugin_ignored_files:
logging.info(
f"{self._package_name} file count before plugin ignore file exclusion: {len(self._abs_file_paths_to_format)}")
for path in plugin_ignored_files:
if path in self._abs_file_paths_to_format:
logging.info(f" File ignored in plugin config file: {path}")
self._abs_file_paths_to_format.remove(path)
logging.info(
f"{self._package_name} file count after plugin ignore file exclusion: {len(self._abs_file_paths_to_format)}")
if not "SkipGitExclusions" in self._package_config or not self._package_config["SkipGitExclusions"]:
# Remove files ignored by git
logging.info(
f"{self._package_name} file count before git ignore file exclusion: {len(self._abs_file_paths_to_format)}")
ignored_paths = self._get_git_ignored_paths()
self._abs_file_paths_to_format = list(
set(self._abs_file_paths_to_format).difference(ignored_paths))
logging.info(
f"{self._package_name} file count after git ignore file exclusion: {len(self._abs_file_paths_to_format)}")
# Remove files in submodules
logging.info(
f"{self._package_name} file count before submodule exclusion: {len(self._abs_file_paths_to_format)}")
submodule_paths = tuple(self._get_git_submodule_paths())
for path in submodule_paths:
logging.info(f" submodule path: {path}")
self._abs_file_paths_to_format = [
f for f in self._abs_file_paths_to_format if not f.startswith(submodule_paths)]
logging.info(
f"{self._package_name} file count after submodule exclusion: {len(self._abs_file_paths_to_format)}")
# Sort the files for more consistent results
self._abs_file_paths_to_format.sort()
def _initialize_test_case_output_options(self) -> None:
"""
Initializes options that influence test case output.
"""
self._audit_only_mode = False
self._output_file_diffs = True
if "AuditOnly" in self._package_config and self._package_config["AuditOnly"]:
self._audit_only_mode = True
if "OutputFileDiffs" in self._package_config and not self._package_config["OutputFileDiffs"]:
self._output_file_diffs = False
def _log_uncrustify_app_info(self) -> None:
"""
Logs Uncrustify application information.
"""
self._tc.LogStdOut(f"Found Uncrustify at {self._app_path}")
self._tc.LogStdOut(f"Uncrustify version: {self._app_version}")
self._tc.LogStdOut('\n')
logging.info(f"Found Uncrustify at {self._app_path}")
logging.info(f"Uncrustify version: {self._app_version}")
logging.info('\n')
def _process_uncrustify_results(self) -> None:
"""
Process the results from Uncrustify.
Determines whether formatting errors are present and logs failures.
"""
formatted_files = [str(path.resolve()) for path in pathlib.Path(
self._abs_package_path).rglob(f'*{UncrustifyCheck.FORMATTED_FILE_EXTENSION}')]
self._formatted_file_error_count = len(formatted_files)
if self._formatted_file_error_count > 0:
logging.error(
"Visit the following instructions to learn "
"how to find the detailed formatting errors in Azure "
"DevOps CI: "
"https://github.com/tianocore/tianocore.github.io/wiki/EDK-II-Code-Formatting#how-to-find-uncrustify-formatting-errors-in-continuous-integration-ci")
self._tc.LogStdError("Files with formatting errors:\n")
if self._output_file_diffs:
logging.info("Calculating file diffs. This might take a while...")
for formatted_file in formatted_files:
pre_formatted_file = formatted_file[:-
len(UncrustifyCheck.FORMATTED_FILE_EXTENSION)]
logging.error(pre_formatted_file)
if (self._output_file_diffs or
self._file_template_contents is not None or
self._func_template_contents is not None):
self._tc.LogStdError(
f"Formatting errors in {os.path.relpath(pre_formatted_file, self._abs_package_path)}\n")
with open(formatted_file) as ff:
formatted_file_text = ff.read()
if (self._file_template_contents is not None and
self._file_template_contents in formatted_file_text):
self._tc.LogStdError(f"File header is missing in {os.path.relpath(pre_formatted_file, self._abs_package_path)}\n")
if (self._func_template_contents is not None and
self._func_template_contents in formatted_file_text):
self._tc.LogStdError(f"A function header is missing in {os.path.relpath(pre_formatted_file, self._abs_package_path)}\n")
if self._output_file_diffs:
with open(pre_formatted_file) as pf:
pre_formatted_file_text = pf.read()
for line in difflib.unified_diff(pre_formatted_file_text.split('\n'), formatted_file_text.split('\n'), fromfile=pre_formatted_file, tofile=formatted_file, n=3):
self._tc.LogStdError(line)
self._tc.LogStdError('\n')
else:
self._tc.LogStdError(pre_formatted_file)
def _remove_tree(self, dir_path: str, ignore_errors: bool = False) -> None:
"""
Helper for removing a directory. Over time there have been
many private implementations of this due to reliability issues in the
shutil implementations. To consolidate on a single function this helper is added.
On error try to change file attributes. Also add retry logic.
This function is temporarily borrowed from edk2toollib.utility_functions
since the version used in edk2 is not recent enough to include the
function.
This function should be replaced by "RemoveTree" when it is available.
Args:
- dir_path: Path to directory to remove.
- ignore_errors: Whether to ignore errors during removal
"""
def _remove_readonly(func, path, _):
"""
Private function to attempt to change permissions on file/folder being deleted.
"""
os.chmod(path, stat.S_IWRITE)
func(path)
for _ in range(3): # retry up to 3 times
try:
shutil.rmtree(dir_path, ignore_errors=ignore_errors, onerror=_remove_readonly)
except OSError as err:
logging.warning(f"Failed to fully remove {dir_path}: {err}")
else:
break
else:
raise RuntimeError(f"Failed to remove {dir_path}")
def _run_uncrustify(self) -> None:
"""
Runs Uncrustify for this instance of plugin execution.
"""
logging.info("Executing Uncrustify. This might take a while...")
start_time = timeit.default_timer()
self._execute_uncrustify()
end_time = timeit.default_timer() - start_time
execution_summary = f"Uncrustify executed against {len(self._abs_file_paths_to_format)} files in {self._package_name} in {end_time:.2f} seconds.\n"
self._tc.LogStdOut(execution_summary)
logging.info(execution_summary)
if self._app_exit_code != 0 and self._app_exit_code != 1:
raise UncrustifyAppExecutionException(
f"Error {str(self._app_exit_code)} returned from Uncrustify:\n\n{str(self._app_output)}")

View File

@@ -1,9 +0,0 @@
/** @file
Brief description of the file's purpose.
Detailed description of the file's contents and other useful
information for a person viewing the file for the first time.
<<Copyright>>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/

View File

@@ -1,15 +0,0 @@
/**
Brief description of this function's purpose.
Follow it immediately with the detailed description.
@param[in] Arg1 Description of Arg1.
@param[in] Arg2 Description of Arg2 This is complicated and requires
multiple lines to describe.
@param[out] Arg3 Description of Arg3.
@param[in, out] Arg4 Description of Arg4.
@retval VAL_ONE Description of what VAL_ONE signifies.
@retval OTHER This is the only other return value. If there were other
return values, they would be listed.
**/

View File

@@ -1,462 +0,0 @@
## @file
# Uncrustify Configuration File for EDK II C Code
#
# Coding Standard: https://edk2-docs.gitbook.io/edk-ii-c-coding-standards-specification/
#
# This configuration file is meant to be a "best attempt" to align with the
# definitions in the EDK II C Coding Standards Specification.
#
# Copyright (c) Microsoft Corporation.
# SPDX-License-Identifier: BSD-2-Clause-Patent
##
# Force UTF-8 encoding (no UTF-16)
enable_digraphs = false
utf8_byte = false
utf8_force = true
# Code width / line splitting
#code_width =120 # TODO: This causes non-deterministic behaviour in some cases when code wraps
ls_code_width =false
ls_for_split_full =true
ls_func_split_full =true
pos_comma =trail
# 5.1.7 All files must end with CRLF
newlines = crlf
# 5.1.2 Do not use tab characters
cmt_convert_tab_to_spaces = true # Whether to convert all tabs to spaces in comments. If false, tabs in
# comments are left alone, unless used for indenting.
indent_columns = 2 # Number of spaces for indentation
indent_with_tabs = 0 # Do not use TAB characters
string_replace_tab_chars = true # Replace TAB with SPACE
# Note: This will break .robot files but is needed for edk2 style
# 5.2.1.1 There shall be only one statement on a line (statement ends with ;)
nl_multi_line_cond = true # Add a newline between ')' and '{' if the ')' is on a different line than
# the if/for/etc.
nl_after_semicolon = true # Whether to add a newline after semicolons, except in 'for' statements.
# 5.2.1.3 An open brace '{' goes on the same line as the closing parenthesis ')' of simple predicate expressions
mod_full_brace_do = add # Add or remove braces on a single-line 'do' statement.
mod_full_brace_for = add
mod_full_brace_function = add # Add or remove braces on a single-line function definition.
mod_full_brace_if = add # Add or remove braces on a single-line 'if' statement. Braces will not be
# removed if the braced statement contains an 'else'.
mod_full_brace_if_chain = false
mod_full_brace_while = add
# 5.2.1.4 A close brace '}' always goes at the beginning of the last line of the body
eat_blanks_after_open_brace = true
eat_blanks_before_close_brace = true # Whether to remove blank lines before '}'.
# 5.2.2.2 Always put space before and after binary operators.
sp_assign = add # Add or remove space around assignment operator '=', '+=', etc.
sp_assign_default = add
sp_bool = add # Add or remove space around boolean operators '&&' and '||'.
sp_compare = add # Add or remove space around compare operator '<', '>', '==', etc.
# 5.2.2.3 Do not put space between unary operators and their object
sp_addr = remove # A or remove space after the '&' (address-of) unary operator.
sp_incdec = remove # Add or remove space between '++' and '--' the word to which it is being
# applied, as in '(--x)' or 'y++;'.
sp_inv = remove # Add or remove space after the '~' (invert) unary operator.
sp_not = remove # Add or remove space after the '!' (not) unary operator.
sp_sign = remove # Add or remove space after '+' or '-', as in 'x = -5' or 'y = +7'.
# 5.2.2.4 Subsequent lines of multi-line function calls should line up two spaces from the beginning of the function
# name
nl_func_call_args_multi_line = true # Whether to add a newline after each ',' in a function call if '(' and ')'
# are in different lines.
nl_func_call_args_multi_line_ignore_closures = false
# - Indent each argument 2 spaces from the start of the function name. If a
# function is called through a structure or union member, of type
# pointer-to-function, then indent each argument 2 spaces from the start of the
# member name.
indent_func_call_edk2_style = true # Use EDK2 indentation style for function calls (**CUSTOM SETTING**)
indent_paren_after_func_call = true # Whether to indent the open parenthesis of a function call, if the
# parenthesis is on its own line.
# - Align the close parenthesis with the start of the last argument
indent_paren_close = 0 # How to indent a close parenthesis after a newline.
# (0: Body, 1: Openparenthesis, 2: Brace level)
# 5.2.2.5 Always put space after commas or semicolons that separate items
sp_after_comma = force # Add or remove space after ',', i.e. 'a,b' vs. 'a, b'.
sp_before_comma = remove # Add or remove space before ','.
# 5.2.2.6 Always put space before an open parenthesis
sp_after_sparen = add # Add or remove space after ')' of control statements.
sp_attribute_paren = add # Add or remove space between '__attribute__' and '('.
sp_before_sparen = force # Add or remove space before '(' of control statements
# ('if', 'for', 'switch', 'while', etc.).
sp_defined_paren = force # Add or remove space between 'defined' and '(' in '#if defined (FOO)'.
sp_func_call_paren = force # Add or remove space between function name and '(' on function calls.
sp_func_call_paren_empty = force # Add or remove space between function name and '()' on function calls
# without parameters. If set to ignore (the default), sp_func_call_paren is
# used.
sp_func_def_paren = add # Add or remove space between alias name and '(' of a non-pointer function
# type typedef.
sp_func_proto_paren = add # Add or remove space between function name and '()' on function declaration
sp_sizeof_paren = force # Add or remove space between 'sizeof' and '('.
sp_type_func = add # Add or remove space between return type and function name. A minimum of 1
# is forced except for pointer return types.
# Not specified, but also good style to remove spaces inside parentheses (Optional)
sp_cparen_oparen = remove # Add or remove space between back-to-back parentheses, i.e. ')(' vs. ') ('.
sp_inside_fparen = remove # Add or remove space inside function '(' and ')'.
sp_inside_fparens = remove # Add or remove space inside empty function '()'.
sp_inside_paren = remove # Add or remove space inside '(' and ')'.
sp_inside_paren_cast = remove # Add or remove spaces inside cast parentheses. '(int)x'
sp_inside_square = remove # Add or remove space inside a non-empty '[' and ']'.
sp_paren_paren = remove # Add or remove space between nested parentheses, i.e. '((' vs. ') )'.
sp_square_fparen = remove # Add or remove space between ']' and '(' when part of a function call.
# 5.2.2.7 Put a space before an open brace if it is not on its own line
sp_do_brace_open = force # Add or remove space between 'do' and '{'.
sp_paren_brace = force # Add or remove space between ')' and '{'.
sp_sparen_brace = force # Add or remove space between ')' and '{' of of control statements.
# 5.2.2.8 Do not put spaces around structure member and pointer operators
sp_after_byref = remove # Add or remove space after reference sign '&', if followed by a word.
sp_before_byref = add # Add or remove space before a reference sign '&'.
sp_deref = remove # Add or remove space after the '*' (dereference) unary operator. This does
# not affect the spacing after a '*' that is part of a type.
sp_member = remove # Add or remove space around the '.' or '->' operators.
# 5.2.2.9 Do not put spaces before open brackets of array subscripts
sp_before_square = remove # Add or remove space before '[' (except '[]').
sp_before_squares = remove # Add or remove space before '[]'.
sp_before_vardef_square = remove # Add or remove space before '[' for a variable definition.
# 5.2.2.10 Use extra parentheses rather than depending on in-depth knowledge of the order of precedence of C
mod_full_paren_if_bool = true # Whether to fully parenthesize Boolean expressions in 'while' and 'if'
# statement, as in 'if (a && b > c)' => 'if (a && (b > c))'.
# 5.2.2.11 Align a continuation line with the part of the line that it continues.
use_indent_continue_only_once = true
# Additional '{}' bracing rules (Optional)
# NOTE - The style guide specifies two different styles for braces,
# so these are ignored for now to allow developers some flexibility.
nl_after_brace_close = true # Whether to add a newline after '}'. Does not apply if followed by a
# necessary ';'.
nl_brace_else = remove # Add or remove newline between '}' and 'else'.
nl_brace_while = remove # Add or remove newline between '}' and 'while' of 'do' statement.
nl_do_brace = remove # Add or remove newline between 'do' and '{'.
nl_else_brace = remove # Add or remove newline between 'else' and '{'.
nl_else_if = remove # Add or remove newline between 'else' and 'if'.
nl_elseif_brace = remove # Add or remove newline between 'else if' and '{'.
nl_enum_brace = remove # Add or remove newline between 'enum' and '{'.
nl_fcall_brace = remove # Add or remove newline between a function call's ')' and '{',
# as in 'list_for_each(item, &list) { }'.
nl_for_brace = remove # Add or remove newline between 'for' and '{'.
nl_if_brace = remove # Add or remove newline between 'if' and '{'.
nl_struct_brace = remove # Add or remove newline between 'struct and '{'.
nl_switch_brace = remove # Add or remove newline between 'switch' and '{'.
nl_union_brace = remove # Add or remove newline between 'union' and '{'.
nl_while_brace = remove # Add or remove newline between 'while' and '{'.
# Additional whitespace rules (Optional)
sp_after_ptr_star = remove # Add or remove space after pointer star '*', if followed by a word.
# Useful when paired with align_var_def_star_style==2
sp_after_ptr_star_func = remove # Add or remove space after a pointer star '*', if followed by a function
# prototype or function definition.
sp_after_semi = remove # Add or remove space after ';', except when followed by a comment.
sp_before_case_colon = remove # Add or remove space before case ':'.
sp_before_ptr_star = add # Add or remove space before pointer star '*'.
sp_before_ptr_star_func = add # Add or remove space before a pointer star '*', if followed by a function
# prototype or function definition.
sp_before_semi = remove # Add or remove space before ';'
sp_before_semi_for = remove # Add or remove space before ';' in non-empty 'for' statements.
sp_before_semi_for_empty = add # Add or remove space before a semicolon of an empty part of a for statement
sp_between_ptr_star = remove # Add or remove space between pointer stars '*'. (ie, 'VOID **')
sp_brace_close_while = force # Add or remove space between '}' and 'while'.
sp_after_cast = remove
sp_after_type = add
sp_balance_nested_parens = false
sp_before_nl_cont = add
sp_before_square_asm_block = ignore
sp_before_unnamed_byref = add
sp_brace_brace = ignore
sp_brace_else = force
sp_brace_typedef = add
sp_case_label = force
sp_cmt_cpp_doxygen = true
sp_cond_colon = add
sp_cond_question = add
sp_cpp_cast_paren = force
sp_else_brace = force
sp_endif_cmt = force
sp_enum_assign = add
sp_inside_braces = force
sp_inside_braces_empty = force
sp_inside_braces_enum = force
sp_inside_braces_struct = force
sp_pp_concat = add
sp_pp_stringify = add
sp_return_paren = add
sp_special_semi = force
sp_while_paren_open = force
# Additional Indentation Rules
indent_access_spec = 1
indent_access_spec_body = false
indent_align_assign = true
indent_align_string = true
indent_bool_paren = true
indent_brace_parent = false
indent_braces = false
indent_braces_no_class = false
indent_braces_no_func = true
indent_braces_no_struct = false
indent_class = true
indent_class_colon = false
indent_cmt_with_tabs = false # Whether to indent comments that are not at a brace level with tabs on
# a tabstop. Requires indent_with_tabs=2. If false, will use spaces.
indent_col1_comment = true
indent_col1_multi_string_literal= true
indent_comma_paren = true
indent_else_if = true
indent_extern = true
indent_first_bool_expr = true
indent_func_def_param_paren_pos_threshold = 0
indent_func_param_double = false
indent_func_proto_param = true
indent_ignore_asm_block = true
indent_label = 1
indent_member = 2
indent_namespace = false
indent_param = 2
indent_paren_nl = false
indent_paren_open_brace = false
indent_preserve_sql = false
indent_relative_single_line_comments = false
indent_sing_line_comments = 0
indent_single_newlines = false
indent_square_nl = false
indent_switch_case = 2
indent_template_param = true
indent_var_def_blk = 0
indent_var_def_cont = false
# Tidy-up rules (Optional)
mod_move_case_break = true # Whether to move a 'break' that appears after a fully braced 'case'
# before the close brace, as in 'case X: { ... } break;' =>
# 'case X: { ... break; }'.
mod_pawn_semicolon = false
mod_remove_empty_return = false # Whether to remove a void 'return;' that appears as the last statement
# in a function.
mod_remove_extra_semicolon = true
mod_sort_import = false
mod_sort_include = false
mod_sort_using = false
nl_after_case = false # Whether to add a newline after a 'case' statement.
nl_end_of_file = force # Add or remove newline at the end of the file.
nl_end_of_file_min = 1 # The minimum number of newlines at the end of the file
nl_max = 2 # The maximum number of consecutive newlines (3 = 2 blank lines).
nl_start_of_file = remove # Add or remove newlines at the start of the file.
# Code alignment rules (Optional)
align_asm_colon = false
align_assign_span = 1 # The span for aligning on '=' in assignments.
align_assign_thresh = 0
align_edk2_style = true # Whether to apply edk2-specific alignment formatting
align_enum_equ_span = 1 # The span for aligning on '=' in enums.
align_func_params = true # Whether to align variable definitions in prototypes and functions.
align_func_params_gap = 2
align_func_params_span = 2 # The span for aligning parameter definitions in function on parameter name.
align_func_params_thresh = 0
align_func_proto_span = 0
align_keep_tabs = false
align_left_shift = false
align_mix_var_proto = false
align_nl_cont = false
align_oc_decl_colon = false
align_on_operator = false
align_on_tabstop = false
align_pp_define_gap = 2
align_pp_define_span = 1
align_right_cmt_at_col = 0 # Align trailing comment at or beyond column N; 'pulls in' comments as
# a bonus side effect (0=ignore)
align_right_cmt_gap = 0 # If a trailing comment is more than this number of columns away from the
# text it follows,
# it will qualify for being aligned. This has to be > 0 to do anything.
align_right_cmt_mix = false # If aligning comments, mix with comments after '}' and #endif with less
# than 3 spaces before the comment
align_right_cmt_same_level = true # Whether to only align trailing comments that are at the same brace level.
align_right_cmt_span = 2 # The span for aligning comments that end lines.
align_same_func_call_params = false
align_single_line_brace = true
align_single_line_func = true
align_struct_init_span = 1 # The span for aligning struct initializer values.
align_typedef_amp_style = 1
align_typedef_func = 1 # How to align typedef'd functions with other typedefs.
# (0: No align, 1: Align open paranthesis, 2: Align function type name)
align_typedef_gap = 2
align_typedef_span = 1 # The span for aligning single-line typedefs.
align_typedef_star_style = 1
align_var_def_amp_style = 1
align_var_def_attribute = true
align_var_def_colon = true # Whether to align the colon in struct bit fields.
align_var_def_gap = 2 # The gap (minimum spacing for aligned items) for variable definitions.
align_var_def_inline = false
align_var_def_span = 1 # The span (lines needed to align) for aligning variable definitions.
align_var_def_star_style = 1 # How to consider (or treat) the '*' in the alignment of variable
# definitions.
# 0: Part of the type 'void * foo;' (default)
# 1: Part of the variable 'void *foo;'
# 2: Dangling 'void *foo;'
# (Note - should also set sp_after_ptr_star=remove)
align_var_struct_gap = 4
align_var_struct_span = 8 # The span for aligning struct/union member definitions.
align_var_struct_thresh = 0
align_with_tabs = false
# Comment formatting
cmt_align_doxygen_javadoc_tags = true # Whether to align doxygen javadoc-style tags ('@param', '@return', etc.)
# TODO: Eats '[' in '[in]'
cmt_c_group = false
cmt_c_nl_end = true # Whether to add a newline before the closing '*/' of the combined c-comment.
cmt_c_nl_start = true
cmt_cpp_group = false
cmt_cpp_nl_end = true
cmt_cpp_nl_start = true
cmt_cpp_to_c = false
cmt_indent_multi = false # Whether to apply changes to multi-line comments, including cmt_width,
# keyword substitution and leading chars.
cmt_insert_before_preproc = false
#cmt_insert_file_header = default_file_header.txt
#cmt_insert_func_header = default_function_header.txt
cmt_multi_check_last = false
cmt_multi_first_len_minimum = 2
cmt_reflow_mode = 1 # How to reflow comments.
# (0:No reflow, 1:No touching at all, 2: Full reflow)
cmt_sp_after_star_cont = 0 # The number of spaces to insert after the star on subsequent comment lines.
cmt_sp_before_star_cont = 0 # The number of spaces to insert at the start of subsequent comment lines.
cmt_star_cont = false # Whether to put a star on subsequent comment lines.
cmt_width = 120 # Try to wrap comments at N columns.
sp_cmt_cpp_start = add # Add or remove space after the opening of a C++ comment, as in
# '// <here> A'. NOTE: Breaks indentation within comments.
# Function definitions / declarations
indent_func_call_param = false # Whether to indent continued function call parameters one indent level,
# rather than aligning parameters under the open parenthesis.
indent_func_class_param = false # Whether to indent continued function call declaration one indent level,
# rather than aligning parameters under the open parenthesis.
indent_func_ctor_var_param = false # Whether to indent continued class variable constructors one indent level,
# rather than aligning parameters under the open parenthesis.
indent_func_def_param = true # Whether to indent continued function definition parameters one indent
# level, rather than aligning parameters under the open parenthesis.
nl_fdef_brace = add # Add or remove newline between function signature and '{'.
nl_func_call_end_multi_line = true # Whether to add a newline before ')' in a function call if '(' and ')' are
# in different lines.
nl_func_call_paren = remove # Add or remove newline between a function name and the opening '(' in the
# call.
nl_func_call_start_multi_line = true # Whether to add a newline after '(' in a function call if '(' and ')' are
# in different lines.
nl_func_decl_args = force # Add or remove newline after each ',' in a function declaration.
nl_func_decl_empty = add # Add or remove newline between '()' in a function declaration.
nl_func_def_args = force # Add or remove newline after each ',' in a function definition.
nl_func_def_empty = add # Add or remove newline between '()' in a function definition.
nl_func_def_paren = remove # Add or remove newline between a function name and the opening '('
# in the definition.
nl_func_paren = remove # Add or remove newline between a function name and the opening '(' in
# the declaration.
nl_func_type_name = add # Add or remove newline between return type and function name in a function
# definition.
sp_fparen_brace = force # Add or remove space between ')' and '{' of function.
use_indent_func_call_param = true # indent_func_call_param will be used
# Additional Newline Rules
nl_after_brace_open = true # Whether to add a newline after '{'. This also adds a newline
# before the matching '}'.
nl_after_brace_open_cmt = true # Whether to add a newline between the open brace and a
# trailing single-line comment.
# Requires nl_after_brace_open = true.
nl_after_do = add # Add or remove blank line after 'do/while' statement.
nl_after_for = add # Add or remove blank line after 'for' statement.
nl_after_func_body = 2 # The number of newlines after '}' of a multi-line function body
nl_after_func_body_one_liner = 2
nl_after_func_proto = 2
nl_after_func_proto_group = 2
nl_after_if = add
nl_after_multiline_comment = false
nl_after_return = false
nl_after_struct = 2
nl_after_switch = add
nl_after_vbrace_close = true
nl_after_vbrace_open = true
nl_after_vbrace_open_empty = true
nl_after_while = add
nl_assign_leave_one_liners = true
nl_before_block_comment = 2
nl_before_case = false
nl_before_do = ignore
nl_before_for = ignore
nl_before_if = ignore
nl_before_switch = ignore
nl_before_while = ignore
nl_before_whole_file_ifdef = 2
nl_brace_brace = force
nl_brace_struct_var = remove
nl_case_colon_brace = add
nl_class_leave_one_liners = false
nl_collapse_empty_body = false
nl_comment_func_def = 1
nl_create_for_one_liner = false
nl_create_if_one_liner = false
nl_create_while_one_liner = false
nl_define_macro = false
nl_ds_struct_enum_close_brace = true
nl_ds_struct_enum_cmt = false
nl_enum_leave_one_liners = false
nl_func_decl_end = add
nl_func_decl_start = add
nl_func_def_end = add
nl_func_def_start = add
nl_func_leave_one_liners = false
nl_func_proto_type_name = add
nl_func_var_def_blk = 1
nl_getset_leave_one_liners = false
nl_if_leave_one_liners = false
nl_multi_line_define = false
nl_squeeze_ifdef = false
nl_var_def_blk_end = 0
nl_var_def_blk_start = 0
# Preprocessor Rules
pp_define_at_level = true
pp_if_indent_code = false
pp_indent_func_def = false
pp_indent_extern = false
pp_ignore_define_body = true # Workaround: Turn off processing for #define body
# (current rules do not work for some defines)
pp_indent = add
pp_indent_at_level = true
pp_indent_count = 2
pp_indent_if = 2
pp_indent_region = 2
pp_region_indent_code = false
pp_space = remove
#
# The tokens below are assigned specific types so they are always recognized properly.
#
# Explicitly define EDK II qualifiers
set QUALIFIER CONST
set QUALIFIER EFIAPI
set QUALIFIER IN
set QUALIFIER OPTIONAL
set QUALIFIER OUT
# Explicitly define EDK II types
set TYPE EFI_STATUS
set TYPE VOID

View File

@@ -1,16 +0,0 @@
## @file
# Downloads the Uncrustify application from a Project Mu NuGet package.
#
# Copyright (c) Microsoft Corporation.
# SPDX-License-Identifier: BSD-2-Clause-Patent
##
{
"id": "uncrustify-ci-1",
"scope": "cibuild",
"type": "nuget",
"name": "mu-uncrustify-release",
"source": "https://pkgs.dev.azure.com/projectmu/Uncrustify/_packaging/mu_uncrustify/nuget/v3/index.json",
"version": "73.0.8",
"flags": ["set_shell_var", "host_specific"],
"var_name": "UNCRUSTIFY_CI_PATH"
}

View File

@@ -1,11 +0,0 @@
## @file
# CiBuildPlugin used to check coding standard compliance of EDK II style C source code
#
# Copyright (c) Microsoft Corporation.
# SPDX-License-Identifier: BSD-2-Clause-Patent
##
{
"scope": "cibuild",
"name": "Uncrustify Coding Standard Test",
"module": "UncrustifyCheck"
}

View File

@@ -1,23 +1,16 @@
# Edk2 Continuous Integration # Edk2 Continuous Integration
This file focuses on information for those working with the `.pytools` directory
directly or interested in lower-level details about how CI works.
If you just want to get started building code, visit
[Build Instructions](https://github.com/tianocore/tianocore.github.io/wiki/Build-Instruction)
on the TianoCore wiki.
## Basic Status ## Basic Status
| Package | Windows VS2019 (IA32/X64)| Ubuntu GCC (IA32/X64/ARM/AARCH64) | Known Issues | | Package | Windows VS2019 (IA32/X64)| Ubuntu GCC (IA32/X64/ARM/AARCH64) | Known Issues |
| :---- | :----- | :---- | :--- | | :---- | :----- | :---- | :--- |
| ArmPkg | | :heavy_check_mark: | | ArmPkg |
| ArmPlatformPkg | | :heavy_check_mark: | | ArmPlatformPkg |
| ArmVirtPkg | SEE PACKAGE README | SEE PACKAGE README | | ArmVirtPkg |
| CryptoPkg | :heavy_check_mark: | :heavy_check_mark: | Spell checking in audit mode | CryptoPkg | :heavy_check_mark: | :heavy_check_mark: | Spell checking in audit mode
| DynamicTablesPkg | :heavy_check_mark: | :heavy_check_mark: | | DynamicTablesPkg |
| EmbeddedPkg | | EmbeddedPkg |
| EmulatorPkg | SEE PACKAGE README | SEE PACKAGE README | Spell checking in audit mode | EmulatorPkg |
| FatPkg | :heavy_check_mark: | :heavy_check_mark: | | FatPkg | :heavy_check_mark: | :heavy_check_mark: |
| FmpDevicePkg | :heavy_check_mark: | :heavy_check_mark: | | FmpDevicePkg | :heavy_check_mark: | :heavy_check_mark: |
| IntelFsp2Pkg | | IntelFsp2Pkg |
@@ -25,16 +18,15 @@ on the TianoCore wiki.
| MdeModulePkg | :heavy_check_mark: | :heavy_check_mark: | DxeIpl dependency on ArmPkg, Depends on StandaloneMmPkg, Spell checking in audit mode | 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 | MdePkg | :heavy_check_mark: | :heavy_check_mark: | Spell checking in audit mode
| NetworkPkg | :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 | OvmfPkg |
| PcAtChipsetPkg | :heavy_check_mark: | :heavy_check_mark: | | PcAtChipsetPkg | :heavy_check_mark: | :heavy_check_mark: |
| SecurityPkg | :heavy_check_mark: | :heavy_check_mark: | Spell checking in audit mode | 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 | ShellPkg | :heavy_check_mark: | :heavy_check_mark: | Spell checking in audit mode, 3 modules are not being built by DSC
| SignedCapsulePkg | | SignedCapsulePkg |
| SourceLevelDebugPkg | | SourceLevelDebugPkg |
| StandaloneMmPkg | :heavy_check_mark: | :heavy_check_mark: | | StandaloneMmPkg |
| UefiCpuPkg | :heavy_check_mark: | :heavy_check_mark: | Spell checking in audit mode, 2 binary modules not being built by DSC | UefiCpuPkg | :heavy_check_mark: | :heavy_check_mark: | Spell checking in audit mode, 2 binary modules not being built by DSC
| UefiPayloadPkg | | UefiPayloadPkg |
| UnitTestFrameworkPkg | :heavy_check_mark: | :heavy_check_mark: |
For more detailed status look at the test results of the latest CI run on the For more detailed status look at the test results of the latest CI run on the
repo readme. repo readme.
@@ -85,22 +77,47 @@ per package configuration which comes from this file.
## Running CI locally ## Running CI locally
The EDKII Tools environment (and by extension the ci) is designed to support 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 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) [docs folder here](https://github.com/tianocore/edk2-pytool-extensions/tree/master/docs)
### Prerequisets
1. A supported toolchain (others might work but this is what is tested and validated)
* Windows 10:
* VS 2017 or VS 2019
* Windows SDK (for rc)
* Windows WDK (for capsules)
* Ubuntu 16.04
* GCC5
* Easy to add more but this is the current state
2. Python 3.7.x or newer on path
3. git on path
4. Recommended to setup and activate a python virtual environment
5. Install the requirements `pip install --upgrade pip-requirements.txt`
### Running CI ### Running CI
Quick notes: 1. clone your edk2 repo
2. Activate your python virtual environment in cmd window
* By default all CI plugins are opted in. 3. Get code dependencies (done only when submodules change)
* Setting the plugin to `skip` as an argument will skip running the plugin. * `stuart_setup -c .pytool/CISettings.py TOOL_CHAIN_TAG=<your tag here>`
Examples: 4. Update other dependencies (done more often)
* `stuart_update -c .pytool/CISettings.py TOOL_CHAIN_TAG=<your tag here>`
5. Run CI build (--help will give you options)
* `stuart_ci_build -c .pytool/CISettings.py TOOL_CHAIN_TAG=<your tag here>`
* -p <pkg1,pkg2,pkg3> : To build only certain packages use a CSV list
* -a <arch1,arch2,arch3>: To run only certain architectures use a CSV list
* -t <target1,target2>: To run only tests related to certain targets use a
CSV list
* By default all tests are opted in. Then given a package.ci.yaml file those
tests can be configured for a package. Finally setting the check to the
value `skip` will skip that plugin. Examples:
* `CompilerPlugin=skip` skip the build test * `CompilerPlugin=skip` skip the build test
* `GuidCheck=skip` skip the Guid check * `GuidCheck=skip` skip the Guid check
* `SpellCheck=skip` skip the spell checker * `SpellCheck=skip` skip the spell checker
* etc. * etc
* Detailed reports and logs per package are captured in the `Build` directory. 6. Detailed reports and logs per package are captured in the `Build` directory
## Current PyTool Test Capabilities ## Current PyTool Test Capabilities
@@ -120,31 +137,11 @@ location makes more sense for the community.
### Module Inclusion Test - DscCompleteCheck ### Module Inclusion Test - DscCompleteCheck
This scans all INF files from a package and confirms they are This test scans all available modules (via INF files) and compares them to the
listed in the package level DSC file. The test considers it an error if any INF package-level DSC file for the package each module is contained within. The test
does not appear in the `Components` section of the package-level DSC (indicating considers it an error if any module does not appear in the `Components` section
that it would not be built if the package were built). This is critical because of at least one package-level DSC (indicating that it would not be built if the
much of the CI infrastructure assumes that all modules will be listed in the DSC package were built).
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
### Code Compilation Test - CompilerPlugin ### Code Compilation Test - CompilerPlugin
@@ -153,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 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. 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 ### GUID Uniqueness Test - GuidCheck
This test works on the collection of all packages rather than an individual This test works on the collection of all packages rather than an individual
@@ -236,20 +193,6 @@ Install
More cspell info: https://github.com/streetsidesoftware/cspell More cspell info: https://github.com/streetsidesoftware/cspell
### License Checking - LicenseCheck
Scans all new added files in a package to make sure code is contributed under
BSD-2-Clause-Patent.
### Ecc tool - EccCheck
Run the Ecc tool on the package. The Ecc tool is available in the BaseTools
package. It checks that the code complies to the EDKII coding standard.
### Coding Standard Compliance - UncrustifyCheck
Runs the Uncrustify application to check for coding standard compliance issues.
## PyTool Scopes ## PyTool Scopes
Scopes are how the PyTool ext_dep, path_env, and plugins are activated. Meaning Scopes are how the PyTool ext_dep, path_env, and plugins are activated. Meaning
@@ -264,8 +207,6 @@ few standard scopes.
| global-nix | edk2_invocable++ | Running on Linux based OS | | global-nix | edk2_invocable++ | Running on Linux based OS |
| edk2-build | | This indicates that an invocable is building EDK2 based UEFI code | | 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 | | 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 ## Future investments
@@ -275,6 +216,8 @@ few standard scopes.
* Visual Studio AARCH64 and ARM support * Visual Studio AARCH64 and ARM support
* BaseTools C tools CI/PR and binary release process * BaseTools C tools CI/PR and binary release process
* BaseTools Python tools CI/PR process * BaseTools Python tools CI/PR process
* Host based unit testing
* Extensible private/closed source platform reporting * Extensible private/closed source platform reporting
* Platform builds, validation
* UEFI SCTs * UEFI SCTs
* Other automation * Other automation

View File

@@ -1,248 +0,0 @@
## @file
# CI configuration for ArmPkg
#
# Copyright (c) 2021, Arm Limited. All rights reserved.<BR>
# SPDX-License-Identifier: BSD-2-Clause-Patent
##
{
## options defined .pytool/Plugin/LicenseCheck
"LicenseCheck": {
"IgnoreFiles": []
},
"EccCheck": {
## Exception sample looks like below:
## "ExceptionList": [
## "<ErrorID>", "<KeyWord>"
## ]
"ExceptionList": [
],
## Both file path and directory path are accepted.
"IgnoreFiles": [
"Library/ArmSoftFloatLib/berkeley-softfloat-3",
"Library/ArmSoftFloatLib/ArmSoftFloatLib.c",
"Library/CompilerIntrinsicsLib",
"Universal/Smbios/SmbiosMiscDxe"
]
},
## options defined .pytool/Plugin/CompilerPlugin
"CompilerPlugin": {
"DscPath": "ArmPkg.dsc"
},
## options defined .pytool/Plugin/HostUnitTestCompilerPlugin
"HostUnitTestCompilerPlugin": {
"DscPath": "" # Don't support this test
},
## options defined .pytool/Plugin/CharEncodingCheck
"CharEncodingCheck": {
"IgnoreFiles": []
},
## options defined .pytool/Plugin/DependencyCheck
"DependencyCheck": {
"AcceptableDependencies": [
"ArmPlatformPkg/ArmPlatformPkg.dec",
"ArmPkg/ArmPkg.dec",
"EmbeddedPkg/EmbeddedPkg.dec",
"MdeModulePkg/MdeModulePkg.dec",
"MdePkg/MdePkg.dec",
"ShellPkg/ShellPkg.dec"
],
# For host based unit tests
"AcceptableDependencies-HOST_APPLICATION":[
"UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec"
],
# For UEFI shell based apps
"AcceptableDependencies-UEFI_APPLICATION":[],
"IgnoreInf": []
},
## options defined .pytool/Plugin/DscCompleteCheck
"DscCompleteCheck": {
"IgnoreInf": [],
"DscPath": "ArmPkg.dsc"
},
## options defined .pytool/Plugin/HostUnitTestDscCompleteCheck
"HostUnitTestDscCompleteCheck": {
"IgnoreInf": [""],
"DscPath": "" # Don't support this test
},
## options defined .pytool/Plugin/GuidCheck
"GuidCheck": {
"IgnoreGuidName": [],
"IgnoreGuidValue": [],
"IgnoreFoldersAndFiles": [],
"IgnoreDuplicates": [],
},
## options defined .pytool/Plugin/LibraryClassCheck
"LibraryClassCheck": {
"IgnoreHeaderFile": []
},
## options defined .pytool/Plugin/SpellCheck
"SpellCheck": {
"AuditOnly": True,
"IgnoreFiles": [
"Library/ArmSoftFloatLib/berkeley-softfloat-3/**"
], # use gitignore syntax to ignore errors
# in matching files
"ExtendWords": [
"api's",
"ackintid",
"actlr",
"aeabi",
"asedis",
"ashldi",
"ashrdi",
"baddr",
"ccidx",
"ccsidr",
"clidr",
"clrex",
"clzsi",
"cnthctl",
"cortexa",
"cpacr",
"cpuactlr",
"csselr",
"ctzsi",
"cygdrive",
"cygpaths",
"datas",
"dcmpeq",
"dcmpge",
"dcmpgt",
"dcmple",
"dcmplt",
"ddisable",
"divdi",
"divsi",
"dmdepkg",
"dpref",
"drsub",
"fcmpeq",
"fcmpge",
"fcmpgt",
"fcmple",
"fcmplt",
"ffreestanding",
"frsub",
"hisilicon",
"iccabpr",
"iccbpr",
"icciar",
"iccicr",
"icciidr",
"iccpir",
"iccpmr",
"iccrpr",
"icdabr",
"icdicer",
"icdicfr",
"icdicpr",
"icdictr",
"icdiidr",
"icdiser",
"icdisr",
"icdppisr",
"icdsgir",
"icdspr",
"icenabler",
"intid",
"ipriority",
"irouter",
"isenabler",
"istatus",
"itargets",
"lable",
"ldivmod",
"ldmdb",
"ldmia",
"ldrbt",
"ldrex",
"ldrexb",
"ldrexd",
"ldrexh",
"ldrhbt",
"ldrht",
"ldrsb",
"ldrsbt",
"ldrsh",
"lshrdi",
"moddi",
"modsi",
"mpcore",
"mpidr",
"muldi",
"mullu",
"nonshareable",
"nsacr",
"nsasedis",
"nuvia",
"oldit",
"pcten",
"plpis",
"procno",
"readc",
"revsh",
"rfedb",
"sctlr",
"smccc",
"smlabb",
"smlabt",
"smlad",
"smladx",
"smlatb",
"smlatt",
"smlawb",
"smlawt",
"smlsd",
"smlsdx",
"smmla",
"smmlar",
"smmls",
"smmlsr",
"sourcery",
"srsdb",
"ssacr",
"stmdb",
"stmia",
"strbt",
"strexb",
"strexd",
"strexh",
"strht",
"switchu",
"tpidrurw",
"ttbcr",
"typer",
"ucmpdi",
"udivdi",
"udivmoddi",
"udivsi",
"uefi's",
"uldiv",
"umoddi",
"umodsi",
"usada",
"vlpis",
"writec"
], # words to extend to the dictionary for this package
"IgnoreStandardPaths": [ # Standard Plugin defined paths that
"*.asm", "*.s" # should be ignore
],
"AdditionalIncludePaths": [] # Additional paths to spell check
# (wildcards supported)
},
# options defined in .pytool/Plugin/UncrustifyCheck
"UncrustifyCheck": {
"AuditOnly": True
}
}

View File

@@ -2,8 +2,7 @@
# ARM processor package. # ARM processor package.
# #
# Copyright (c) 2009 - 2010, Apple Inc. All rights reserved.<BR> # Copyright (c) 2009 - 2010, Apple Inc. All rights reserved.<BR>
# Copyright (c) 2011 - 2023, ARM Limited. All rights reserved. # Copyright (c) 2011 - 2018, ARM Limited. All rights reserved.
# Copyright (c) 2021, Ampere Computing LLC. All rights reserved.
# #
# SPDX-License-Identifier: BSD-2-Clause-Patent # SPDX-License-Identifier: BSD-2-Clause-Patent
# #
@@ -28,73 +27,15 @@
Include # Root include for the package Include # Root include for the package
[LibraryClasses.common] [LibraryClasses.common]
## @libraryclass Convert Arm instructions to a human readable format.
#
ArmDisassemblerLib|Include/Library/ArmDisassemblerLib.h
## @libraryclass Provides an interface to Arm generic counters.
#
ArmGenericTimerCounterLib|Include/Library/ArmGenericTimerCounterLib.h
## @libraryclass Provides an interface to initialize a
# Generic Interrupt Controller (GIC).
#
ArmGicArchLib|Include/Library/ArmGicArchLib.h
## @libraryclass Provides a Generic Interrupt Controller (GIC)
# configuration interface.
#
ArmGicLib|Include/Library/ArmGicLib.h
## @libraryclass Provides a HyperVisor Call (HVC) interface.
#
ArmHvcLib|Include/Library/ArmHvcLib.h
## @libraryclass Provides an interface to Arm registers.
#
ArmLib|Include/Library/ArmLib.h ArmLib|Include/Library/ArmLib.h
## @libraryclass Provides a Mmu interface.
#
ArmMmuLib|Include/Library/ArmMmuLib.h ArmMmuLib|Include/Library/ArmMmuLib.h
SemihostLib|Include/Library/Semihosting.h
## @libraryclass Provides a Mailbox Transport Layer (MTL) interface
# for the System Control and Management Interface (SCMI).
#
ArmMtlLib|Include/Library/ArmMtlLib.h
## @libraryclass Provides a System Monitor Call (SMC) interface.
#
ArmSmcLib|Include/Library/ArmSmcLib.h
## @libraryclass Provides a SuperVisor Call (SVC) interface.
#
ArmSvcLib|Include/Library/ArmSvcLib.h
## @libraryclass Provides a Monitor Call interface that will use the
# default conduit (HVC or SMC).
#
ArmMonitorLib|Include/Library/ArmMonitorLib.h
## @libraryclass Provides a default exception handler.
#
DefaultExceptionHandlerLib|Include/Library/DefaultExceptionHandlerLib.h DefaultExceptionHandlerLib|Include/Library/DefaultExceptionHandlerLib.h
ArmDisassemblerLib|Include/Library/ArmDisassemblerLib.h
## @libraryclass Provides an interface to query miscellaneous OEM ArmGicArchLib|Include/Library/ArmGicArchLib.h
# information. ArmMtlLib|ArmPlatformPkg/Include/Library/ArmMtlLib.h
# ArmSvcLib|Include/Library/ArmSvcLib.h
OemMiscLib|Include/Library/OemMiscLib.h
## @libraryclass Provides an OpTee interface.
#
OpteeLib|Include/Library/OpteeLib.h OpteeLib|Include/Library/OpteeLib.h
## @libraryclass Provides a semihosting interface.
#
SemihostLib|Include/Library/SemihostLib.h
## @libraryclass Provides an interface for a StandaloneMm Mmu.
#
StandaloneMmMmuLib|Include/Library/StandaloneMmMmuLib.h StandaloneMmMmuLib|Include/Library/StandaloneMmMmuLib.h
[Guids.common] [Guids.common]
@@ -104,8 +45,6 @@
# Include/Guid/ArmMpCoreInfo.h # Include/Guid/ArmMpCoreInfo.h
gArmMpCoreInfoGuid = { 0xa4ee0728, 0xe5d7, 0x4ac5, {0xb2, 0x1e, 0x65, 0x8e, 0xd8, 0x57, 0xe8, 0x34} } gArmMpCoreInfoGuid = { 0xa4ee0728, 0xe5d7, 0x4ac5, {0xb2, 0x1e, 0x65, 0x8e, 0xd8, 0x57, 0xe8, 0x34} }
gArmMmuReplaceLiveTranslationEntryFuncGuid = { 0xa8b50ff3, 0x08ec, 0x4dd3, {0xbf, 0x04, 0x28, 0xbf, 0x71, 0x75, 0xc7, 0x4a} }
[Protocols.common] [Protocols.common]
## Arm System Control and Management Interface(SCMI) Base protocol ## Arm System Control and Management Interface(SCMI) Base protocol
## ArmPkg/Include/Protocol/ArmScmiBaseProtocol.h ## ArmPkg/Include/Protocol/ArmScmiBaseProtocol.h
@@ -139,24 +78,12 @@
# Define if the GICv3 controller should use the GICv2 legacy # Define if the GICv3 controller should use the GICv2 legacy
gArmTokenSpaceGuid.PcdArmGicV3WithV2Legacy|FALSE|BOOLEAN|0x00000042 gArmTokenSpaceGuid.PcdArmGicV3WithV2Legacy|FALSE|BOOLEAN|0x00000042
# Whether to remap all unused memory NX before installing the CPU arch
# protocol driver. This is needed on platforms that map all DRAM with RWX
# attributes initially, and can be disabled otherwise.
gArmTokenSpaceGuid.PcdRemapUnusedMemoryNx|TRUE|BOOLEAN|0x00000048
[PcdsFeatureFlag.ARM] [PcdsFeatureFlag.ARM]
# Whether to map normal memory as non-shareable. FALSE is the safe choice, but # Whether to map normal memory as non-shareable. FALSE is the safe choice, but
# TRUE may be appropriate to fix performance problems if you don't care about # TRUE may be appropriate to fix performance problems if you don't care about
# hardware coherency (i.e., no virtualization or cache coherent DMA) # hardware coherency (i.e., no virtualization or cache coherent DMA)
gArmTokenSpaceGuid.PcdNormalMemoryNonshareableOverride|FALSE|BOOLEAN|0x00000043 gArmTokenSpaceGuid.PcdNormalMemoryNonshareableOverride|FALSE|BOOLEAN|0x00000043
[PcdsFeatureFlag.AARCH64, PcdsFeatureFlag.ARM]
## 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] [PcdsFixedAtBuild.common]
gArmTokenSpaceGuid.PcdTrustzoneSupport|FALSE|BOOLEAN|0x00000006 gArmTokenSpaceGuid.PcdTrustzoneSupport|FALSE|BOOLEAN|0x00000006
@@ -188,20 +115,6 @@
# The Primary Core is ClusterId[0] & CoreId[0] # The Primary Core is ClusterId[0] & CoreId[0]
gArmTokenSpaceGuid.PcdArmPrimaryCore|0|UINT32|0x00000037 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 # ARM L2x0 PCDs
# #
@@ -221,13 +134,6 @@
# #
gArmTokenSpaceGuid.PcdArmDmaDeviceOffset|0x0|UINT64|0x0000044 gArmTokenSpaceGuid.PcdArmDmaDeviceOffset|0x0|UINT64|0x0000044
#
# Boot the Uefi Shell instead of UiApp when no valid boot option is found.
# This is useful in CI environment so that startup.nsh can be launched.
# The default value is FALSE.
#
gArmTokenSpaceGuid.PcdUefiShellDefaultBootEnable|FALSE|BOOLEAN|0x0000052
[PcdsFixedAtBuild.common, PcdsPatchableInModule.common] [PcdsFixedAtBuild.common, PcdsPatchableInModule.common]
gArmTokenSpaceGuid.PcdFdBaseAddress|0|UINT64|0x0000002B gArmTokenSpaceGuid.PcdFdBaseAddress|0|UINT64|0x0000002B
gArmTokenSpaceGuid.PcdFvBaseAddress|0|UINT64|0x0000002D gArmTokenSpaceGuid.PcdFvBaseAddress|0|UINT64|0x0000002D
@@ -309,14 +215,6 @@
gArmTokenSpaceGuid.PcdMmBufferBase|0|UINT64|0x00000045 gArmTokenSpaceGuid.PcdMmBufferBase|0|UINT64|0x00000045
gArmTokenSpaceGuid.PcdMmBufferSize|0|UINT64|0x00000046 gArmTokenSpaceGuid.PcdMmBufferSize|0|UINT64|0x00000046
gArmTokenSpaceGuid.PcdSystemBiosRelease|0xFFFF|UINT16|0x30000058
gArmTokenSpaceGuid.PcdEmbeddedControllerFirmwareRelease|0xFFFF|UINT16|0x30000059
## Define the conduit to use for monitor calls.
# Default PcdMonitorConduitHvc = FALSE, conduit = SMC
# If PcdMonitorConduitHvc = TRUE, conduit = HVC
gArmTokenSpaceGuid.PcdMonitorConduitHvc|FALSE|BOOLEAN|0x00000047
[PcdsFixedAtBuild.common, PcdsDynamic.common] [PcdsFixedAtBuild.common, PcdsDynamic.common]
# #
# ARM Architectural Timer # ARM Architectural Timer
@@ -328,7 +226,6 @@
gArmTokenSpaceGuid.PcdArmArchTimerIntrNum|30|UINT32|0x00000036 gArmTokenSpaceGuid.PcdArmArchTimerIntrNum|30|UINT32|0x00000036
gArmTokenSpaceGuid.PcdArmArchTimerHypIntrNum|26|UINT32|0x00000040 gArmTokenSpaceGuid.PcdArmArchTimerHypIntrNum|26|UINT32|0x00000040
gArmTokenSpaceGuid.PcdArmArchTimerVirtIntrNum|27|UINT32|0x00000041 gArmTokenSpaceGuid.PcdArmArchTimerVirtIntrNum|27|UINT32|0x00000041
gArmTokenSpaceGuid.PcdArmArchTimerHypVirtIntrNum|28|UINT32|0x0000004A
# #
# ARM Generic Watchdog # ARM Generic Watchdog
@@ -363,9 +260,9 @@
# UINT64 Mmio32CpuBase; // mapping target in 64-bit cpu-physical space # UINT64 Mmio32CpuBase; // mapping target in 64-bit cpu-physical space
# UINT64 Mmio64CpuBase; // mapping target in 64-bit cpu-physical space # UINT64 Mmio64CpuBase; // mapping target in 64-bit cpu-physical space
# #
# gEfiMdePkgTokenSpaceGuid.PcdPciIoTranslation = IoCpuBase - PcdPciIoBase; # PcdPciIoTranslation = IoCpuBase - PcdPciIoBase;
# gEfiMdePkgTokenSpaceGuid.PcdPciMmio32Translation = Mmio32CpuBase - (UINT64)PcdPciMmio32Base; # PcdPciMmio32Translation = Mmio32CpuBase - (UINT64)PcdPciMmio32Base;
# gEfiMdePkgTokenSpaceGuid.PcdPciMmio64Translation = Mmio64CpuBase - PcdPciMmio64Base; # PcdPciMmio64Translation = Mmio64CpuBase - PcdPciMmio64Base;
# #
# because (a) the target address space (ie. the cpu-physical space) is # because (a) the target address space (ie. the cpu-physical space) is
# 64-bit, and (b) the translation values are meant as offsets for *modular* # 64-bit, and (b) the translation values are meant as offsets for *modular*
@@ -382,11 +279,11 @@
# UINT64 TranslatedMmio64Address; // output parameter # UINT64 TranslatedMmio64Address; // output parameter
# #
# TranslatedIoAddress = UntranslatedIoAddress + # TranslatedIoAddress = UntranslatedIoAddress +
# gEfiMdePkgTokenSpaceGuid.PcdPciIoTranslation; # PcdPciIoTranslation;
# TranslatedMmio32Address = (UINT64)UntranslatedMmio32Address + # TranslatedMmio32Address = (UINT64)UntranslatedMmio32Address +
# gEfiMdePkgTokenSpaceGuid.PcdPciMmio32Translation; # PcdPciMmio32Translation;
# TranslatedMmio64Address = UntranslatedMmio64Address + # TranslatedMmio64Address = UntranslatedMmio64Address +
# gEfiMdePkgTokenSpaceGuid.PcdPciMmio64Translation; # PcdPciMmio64Translation;
# #
# The modular arithmetic performed in UINT64 ensures that the translation # The modular arithmetic performed in UINT64 ensures that the translation
# works correctly regardless of the relation between IoCpuBase and # works correctly regardless of the relation between IoCpuBase and
@@ -395,20 +292,16 @@
# #
gArmTokenSpaceGuid.PcdPciIoBase|0x0|UINT64|0x00000050 gArmTokenSpaceGuid.PcdPciIoBase|0x0|UINT64|0x00000050
gArmTokenSpaceGuid.PcdPciIoSize|0x0|UINT64|0x00000051 gArmTokenSpaceGuid.PcdPciIoSize|0x0|UINT64|0x00000051
gArmTokenSpaceGuid.PcdPciIoTranslation|0x0|UINT64|0x00000052
gArmTokenSpaceGuid.PcdPciMmio32Base|0x0|UINT32|0x00000053 gArmTokenSpaceGuid.PcdPciMmio32Base|0x0|UINT32|0x00000053
gArmTokenSpaceGuid.PcdPciMmio32Size|0x0|UINT32|0x00000054 gArmTokenSpaceGuid.PcdPciMmio32Size|0x0|UINT32|0x00000054
gArmTokenSpaceGuid.PcdPciMmio32Translation|0x0|UINT64|0x00000055
gArmTokenSpaceGuid.PcdPciMmio64Base|0x0|UINT64|0x00000056 gArmTokenSpaceGuid.PcdPciMmio64Base|0x0|UINT64|0x00000056
gArmTokenSpaceGuid.PcdPciMmio64Size|0x0|UINT64|0x00000057 gArmTokenSpaceGuid.PcdPciMmio64Size|0x0|UINT64|0x00000057
gArmTokenSpaceGuid.PcdPciMmio64Translation|0x0|UINT64|0x00000058
# #
# Inclusive range of allowed PCI buses. # Inclusive range of allowed PCI buses.
# #
gArmTokenSpaceGuid.PcdPciBusMin|0x0|UINT32|0x00000059 gArmTokenSpaceGuid.PcdPciBusMin|0x0|UINT32|0x00000059
gArmTokenSpaceGuid.PcdPciBusMax|0x0|UINT32|0x0000005A gArmTokenSpaceGuid.PcdPciBusMax|0x0|UINT32|0x0000005A
[PcdsDynamicEx]
#
# This dynamic PCD hold the GUID of a firmware FFS which contains
# the LinuxBoot payload.
#
gArmTokenSpaceGuid.PcdLinuxBootFileGuid|{0x0}|VOID*|0x0000005C

View File

@@ -2,10 +2,8 @@
# ARM processor package. # ARM processor package.
# #
# Copyright (c) 2009 - 2010, Apple Inc. All rights reserved.<BR> # Copyright (c) 2009 - 2010, Apple Inc. All rights reserved.<BR>
# Copyright (c) 2011 - 2021, Arm Limited. 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) 2016, Linaro Ltd. All rights reserved.<BR>
# Copyright (c) Microsoft Corporation.<BR>
# Copyright (c) 2021, Ampere Computing LLC. All rights reserved.
# #
# SPDX-License-Identifier: BSD-2-Clause-Patent # SPDX-License-Identifier: BSD-2-Clause-Patent
# #
@@ -30,25 +28,17 @@
RELEASE_*_*_CC_FLAGS = -DMDEPKG_NDEBUG RELEASE_*_*_CC_FLAGS = -DMDEPKG_NDEBUG
*_*_*_CC_FLAGS = -DDISABLE_NEW_DEPRECATED_INTERFACES *_*_*_CC_FLAGS = -DDISABLE_NEW_DEPRECATED_INTERFACES
[PcdsFixedAtBuild]
gEfiMdePkgTokenSpaceGuid.PcdDefaultTerminalType|4
!include MdePkg/MdeLibs.dsc.inc
[LibraryClasses.common] [LibraryClasses.common]
BaseLib|MdePkg/Library/BaseLib/BaseLib.inf BaseLib|MdePkg/Library/BaseLib/BaseLib.inf
BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
BootLogoLib|MdeModulePkg/Library/BootLogoLib/BootLogoLib.inf
CacheMaintenanceLib|ArmPkg/Library/ArmCacheMaintenanceLib/ArmCacheMaintenanceLib.inf CacheMaintenanceLib|ArmPkg/Library/ArmCacheMaintenanceLib/ArmCacheMaintenanceLib.inf
CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf
DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf
HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
TimerLib|MdePkg/Library/BaseTimerLibNullTemplate/BaseTimerLibNullTemplate.inf TimerLib|MdePkg/Library/BaseTimerLibNullTemplate/BaseTimerLibNullTemplate.inf
UefiBootManagerLib|MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf
UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf
UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf
UefiLib|MdePkg/Library/UefiLib/UefiLib.inf UefiLib|MdePkg/Library/UefiLib/UefiLib.inf
@@ -56,7 +46,6 @@
UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf
PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf
PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf
UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf
HiiLib|MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf HiiLib|MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf
@@ -91,8 +80,6 @@
ArmMtlLib|ArmPkg/Library/ArmMtlNullLib/ArmMtlNullLib.inf ArmMtlLib|ArmPkg/Library/ArmMtlNullLib/ArmMtlNullLib.inf
OemMiscLib|ArmPkg/Universal/Smbios/OemMiscLibNull/OemMiscLibNull.inf
[LibraryClasses.common.PEIM] [LibraryClasses.common.PEIM]
HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf
@@ -113,6 +100,7 @@
ArmPkg/Library/DebugAgentSymbolsBaseLib/DebugAgentSymbolsBaseLib.inf ArmPkg/Library/DebugAgentSymbolsBaseLib/DebugAgentSymbolsBaseLib.inf
ArmPkg/Library/DebugPeCoffExtraActionLib/DebugPeCoffExtraActionLib.inf ArmPkg/Library/DebugPeCoffExtraActionLib/DebugPeCoffExtraActionLib.inf
ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandlerLib.inf ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandlerLib.inf
ArmPkg/Library/RvdPeCoffExtraActionLib/RvdPeCoffExtraActionLib.inf
ArmPkg/Library/SemiHostingDebugLib/SemiHostingDebugLib.inf ArmPkg/Library/SemiHostingDebugLib/SemiHostingDebugLib.inf
ArmPkg/Library/SemiHostingSerialPortLib/SemiHostingSerialPortLib.inf ArmPkg/Library/SemiHostingSerialPortLib/SemiHostingSerialPortLib.inf
ArmPkg/Library/SemihostLib/SemihostLib.inf ArmPkg/Library/SemihostLib/SemihostLib.inf
@@ -130,12 +118,9 @@
ArmPkg/Library/ArmGenericTimerPhyCounterLib/ArmGenericTimerPhyCounterLib.inf ArmPkg/Library/ArmGenericTimerPhyCounterLib/ArmGenericTimerPhyCounterLib.inf
ArmPkg/Library/ArmGenericTimerVirtCounterLib/ArmGenericTimerVirtCounterLib.inf ArmPkg/Library/ArmGenericTimerVirtCounterLib/ArmGenericTimerVirtCounterLib.inf
ArmPkg/Library/ArmTrngLib/ArmTrngLib.inf
ArmPkg/Library/ArmHvcLib/ArmHvcLib.inf
ArmPkg/Library/ArmHvcLibNull/ArmHvcLibNull.inf
ArmPkg/Library/ArmMonitorLib/ArmMonitorLib.inf
ArmPkg/Library/ArmSmcLib/ArmSmcLib.inf ArmPkg/Library/ArmSmcLib/ArmSmcLib.inf
ArmPkg/Library/ArmSmcLibNull/ArmSmcLibNull.inf ArmPkg/Library/ArmSmcLibNull/ArmSmcLibNull.inf
ArmPkg/Library/ArmHvcLib/ArmHvcLib.inf
ArmPkg/Library/ArmSvcLib/ArmSvcLib.inf ArmPkg/Library/ArmSvcLib/ArmSvcLib.inf
ArmPkg/Library/OpteeLib/OpteeLib.inf ArmPkg/Library/OpteeLib/OpteeLib.inf
@@ -148,26 +133,12 @@
ArmPkg/Library/ArmGicArchLib/ArmGicArchLib.inf ArmPkg/Library/ArmGicArchLib/ArmGicArchLib.inf
ArmPkg/Library/ArmGicArchSecLib/ArmGicArchSecLib.inf ArmPkg/Library/ArmGicArchSecLib/ArmGicArchSecLib.inf
ArmPkg/Library/ArmLib/ArmBaseLib.inf ArmPkg/Library/ArmLib/ArmBaseLib.inf
ArmPkg/Library/ArmMtlNullLib/ArmMtlNullLib.inf
ArmPkg/Library/ArmSoftFloatLib/ArmSoftFloatLib.inf ArmPkg/Library/ArmSoftFloatLib/ArmSoftFloatLib.inf
ArmPkg/Library/ArmSmcPsciResetSystemLib/ArmSmcPsciResetSystemLib.inf
ArmPkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointerLib.inf ArmPkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointerLib.inf
ArmPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf ArmPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
ArmPkg/Library/LinuxBootBootManagerLib/LinuxBootBootManagerLib.inf
ArmPkg/Drivers/ArmCrashDumpDxe/ArmCrashDumpDxe.inf
ArmPkg/Drivers/ArmScmiDxe/ArmScmiDxe.inf ArmPkg/Drivers/ArmScmiDxe/ArmScmiDxe.inf
ArmPkg/Universal/Smbios/ProcessorSubClassDxe/ProcessorSubClassDxe.inf
ArmPkg/Universal/Smbios/SmbiosMiscDxe/SmbiosMiscDxe.inf
ArmPkg/Universal/Smbios/OemMiscLibNull/OemMiscLibNull.inf
ArmPkg/Drivers/MmCommunicationPei/MmCommunicationPei.inf
[Components.AARCH64] [Components.AARCH64]
ArmPkg/Drivers/ArmPsciMpServicesDxe/ArmPsciMpServicesDxe.inf
ArmPkg/Drivers/MmCommunicationDxe/MmCommunication.inf
ArmPkg/Library/ArmMmuLib/ArmMmuPeiLib.inf ArmPkg/Library/ArmMmuLib/ArmMmuPeiLib.inf
[Components.AARCH64, Components.ARM]
ArmPkg/Library/StandaloneMmMmuLib/ArmMmuStandaloneMmLib.inf ArmPkg/Library/StandaloneMmMmuLib/ArmMmuStandaloneMmLib.inf

View File

@@ -24,11 +24,9 @@ ArmCrashDumpDxeInitialize (
EFI_STATUS Status; EFI_STATUS Status;
Status = gBS->LocateProtocol (&gEfiCpuArchProtocolGuid, NULL, (VOID **)&mCpu); Status = gBS->LocateProtocol (&gEfiCpuArchProtocolGuid, NULL, (VOID **)&mCpu);
ASSERT_EFI_ERROR (Status); ASSERT_EFI_ERROR(Status);
return mCpu->RegisterInterruptHandler ( return mCpu->RegisterInterruptHandler (mCpu,
mCpu,
EXCEPT_AARCH64_SYNCHRONOUS_EXCEPTIONS, EXCEPT_AARCH64_SYNCHRONOUS_EXCEPTIONS,
&DefaultExceptionHandler &DefaultExceptionHandler);
);
} }

View File

@@ -1,6 +1,6 @@
/*++ /*++
Copyright (c) 2013-2023, Arm Ltd. All rights reserved.<BR> Copyright (c) 2013-2017, ARM Ltd. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -8,6 +8,20 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include "ArmGicDxe.h" #include "ArmGicDxe.h"
VOID
EFIAPI
IrqInterruptHandler (
IN EFI_EXCEPTION_TYPE InterruptType,
IN EFI_SYSTEM_CONTEXT SystemContext
);
VOID
EFIAPI
ExitBootServicesEvent (
IN EFI_EVENT Event,
IN VOID *Context
);
// Making this global saves a few bytes in image size // Making this global saves a few bytes in image size
EFI_HANDLE gHardwareInterruptHandle = NULL; EFI_HANDLE gHardwareInterruptHandle = NULL;
@@ -19,6 +33,7 @@ UINTN mGicNumInterrupts = 0;
HARDWARE_INTERRUPT_HANDLER *gRegisteredInterruptHandlers = NULL; HARDWARE_INTERRUPT_HANDLER *gRegisteredInterruptHandlers = NULL;
/** /**
Calculate GICD_ICFGRn base address and corresponding bit Calculate GICD_ICFGRn base address and corresponding bit
field Int_config[1] of the GIC distributor register. field Int_config[1] of the GIC distributor register.
@@ -41,13 +56,13 @@ GicGetDistributorIcfgBaseAndBit (
UINTN Field; UINTN Field;
if (Source >= mGicNumInterrupts) { if (Source >= mGicNumInterrupts) {
ASSERT (Source < mGicNumInterrupts); ASSERT(Source < mGicNumInterrupts);
return EFI_UNSUPPORTED; return EFI_UNSUPPORTED;
} }
RegIndex = Source / ARM_GIC_ICDICFR_F_STRIDE; // NOTE: truncation is significant RegIndex = Source / ARM_GIC_ICDICFR_F_STRIDE; // NOTE: truncation is significant
Field = Source % ARM_GIC_ICDICFR_F_STRIDE; Field = Source % ARM_GIC_ICDICFR_F_STRIDE;
*RegAddress = (UINTN)PcdGet64 (PcdGicDistributorBase) *RegAddress = PcdGet64 (PcdGicDistributorBase)
+ ARM_GIC_ICDICFR + ARM_GIC_ICDICFR
+ (ARM_GIC_ICDICFR_BYTES * RegIndex); + (ARM_GIC_ICDICFR_BYTES * RegIndex);
*Config1Bit = ((Field * ARM_GIC_ICDICFR_F_WIDTH) *Config1Bit = ((Field * ARM_GIC_ICDICFR_F_WIDTH)
@@ -56,6 +71,8 @@ GicGetDistributorIcfgBaseAndBit (
return EFI_SUCCESS; return EFI_SUCCESS;
} }
/** /**
Register Handler for the specified interrupt source. Register Handler for the specified interrupt source.
@@ -76,7 +93,7 @@ RegisterInterruptSource (
) )
{ {
if (Source >= mGicNumInterrupts) { if (Source >= mGicNumInterrupts) {
ASSERT (FALSE); ASSERT(FALSE);
return EFI_UNSUPPORTED; return EFI_UNSUPPORTED;
} }
@@ -91,7 +108,7 @@ RegisterInterruptSource (
gRegisteredInterruptHandlers[Source] = Handler; gRegisteredInterruptHandlers[Source] = Handler;
// If the interrupt handler is unregistered then disable the interrupt // If the interrupt handler is unregistered then disable the interrupt
if (NULL == Handler) { if (NULL == Handler){
return This->DisableInterruptSource (This, Source); return This->DisableInterruptSource (This, Source);
} else { } else {
return This->EnableInterruptSource (This, Source); return This->EnableInterruptSource (This, Source);
@@ -120,28 +137,17 @@ CpuArchEventProtocolNotify (
// Unregister the default exception handler. // Unregister the default exception handler.
Status = Cpu->RegisterInterruptHandler (Cpu, ARM_ARCH_EXCEPTION_IRQ, NULL); Status = Cpu->RegisterInterruptHandler (Cpu, ARM_ARCH_EXCEPTION_IRQ, NULL);
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
DEBUG (( DEBUG ((DEBUG_ERROR, "%a: Cpu->RegisterInterruptHandler() - %r\n",
DEBUG_ERROR, __FUNCTION__, Status));
"%a: Cpu->RegisterInterruptHandler() - %r\n",
__func__,
Status
));
return; return;
} }
// Register to receive interrupts // Register to receive interrupts
Status = Cpu->RegisterInterruptHandler ( Status = Cpu->RegisterInterruptHandler (Cpu, ARM_ARCH_EXCEPTION_IRQ,
Cpu, Context);
ARM_ARCH_EXCEPTION_IRQ,
Context
);
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
DEBUG (( DEBUG ((DEBUG_ERROR, "%a: Cpu->RegisterInterruptHandler() - %r\n",
DEBUG_ERROR, __FUNCTION__, Status));
"%a: Cpu->RegisterInterruptHandler() - %r\n",
__func__,
Status
));
} }
gBS->CloseEvent (Event); gBS->CloseEvent (Event);
@@ -157,7 +163,7 @@ InstallAndRegisterInterruptService (
{ {
EFI_STATUS Status; EFI_STATUS Status;
CONST UINTN RihArraySize = CONST UINTN RihArraySize =
(sizeof (HARDWARE_INTERRUPT_HANDLER) * mGicNumInterrupts); (sizeof(HARDWARE_INTERRUPT_HANDLER) * mGicNumInterrupts);
// Initialize the array for the Interrupt Handlers // Initialize the array for the Interrupt Handlers
gRegisteredInterruptHandlers = AllocateZeroPool (RihArraySize); gRegisteredInterruptHandlers = AllocateZeroPool (RihArraySize);
@@ -185,8 +191,7 @@ InstallAndRegisterInterruptService (
TPL_CALLBACK, TPL_CALLBACK,
CpuArchEventProtocolNotify, CpuArchEventProtocolNotify,
InterruptHandler, InterruptHandler,
&mCpuArchProtocolNotifyEventRegistration &mCpuArchProtocolNotifyEventRegistration);
);
// Register for an ExitBootServicesEvent // Register for an ExitBootServicesEvent
Status = gBS->CreateEvent ( Status = gBS->CreateEvent (

View File

@@ -6,8 +6,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
--*/ --*/
#ifndef ARM_GIC_DXE_H_ #ifndef __ARM_GIC_DXE_H__
#define ARM_GIC_DXE_H_ #define __ARM_GIC_DXE_H__
#include <Library/ArmGicLib.h> #include <Library/ArmGicLib.h>
#include <Library/ArmLib.h> #include <Library/ArmLib.h>
@@ -55,6 +55,7 @@ GicV3DxeInitialize (
IN EFI_SYSTEM_TABLE *SystemTable IN EFI_SYSTEM_TABLE *SystemTable
); );
// Shared code // Shared code
/** /**
@@ -75,4 +76,4 @@ GicGetDistributorIcfgBaseAndBit (
OUT UINTN *Config1Bit OUT UINTN *Config1Bit
); );
#endif // ARM_GIC_DXE_H_ #endif

View File

@@ -1,6 +1,6 @@
/** @file /** @file
* *
* Copyright (c) 2011-2023, Arm Limited. All rights reserved. * Copyright (c) 2011-2018, ARM Limited. All rights reserved.
* *
* SPDX-License-Identifier: BSD-2-Clause-Patent * SPDX-License-Identifier: BSD-2-Clause-Patent
* *
@@ -24,14 +24,11 @@
+ ARM_GICR_SGI_VLPI_FRAME_SIZE \ + ARM_GICR_SGI_VLPI_FRAME_SIZE \
+ ARM_GICR_SGI_RESERVED_FRAME_SIZE) + ARM_GICR_SGI_RESERVED_FRAME_SIZE)
#define ISENABLER_ADDRESS(base, offset) ((base) +\ #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) +\ #define ICENABLER_ADDRESS(base,offset) ((base) + \
ARM_GICR_CTLR_FRAME_SIZE + ARM_GICR_ICENABLER + 4 * (offset)) 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))
/** /**
* *
@@ -104,17 +101,10 @@ GicGetCpuRedistributorBase (
return 0; return 0;
} }
/** UINTN
Return the GIC CPU Interrupt Interface ID.
@param GicInterruptInterfaceBase Base address of the GIC Interrupt Interface.
@retval CPU Interface Identification information.
**/
UINT32
EFIAPI EFIAPI
ArmGicGetInterfaceIdentification ( ArmGicGetInterfaceIdentification (
IN UINTN GicInterruptInterfaceBase IN INTN GicInterruptInterfaceBase
) )
{ {
// Read the GIC Identification Register // Read the GIC Identification Register
@@ -124,33 +114,24 @@ ArmGicGetInterfaceIdentification (
UINTN UINTN
EFIAPI EFIAPI
ArmGicGetMaxNumInterrupts ( ArmGicGetMaxNumInterrupts (
IN UINTN GicDistributorBase IN INTN GicDistributorBase
) )
{ {
UINTN ItLines; return 32 * ((MmioRead32 (GicDistributorBase + ARM_GIC_ICDICTR) & 0x1F) + 1);
ItLines = MmioRead32 (GicDistributorBase + ARM_GIC_ICDICTR) & 0x1F;
//
// Interrupt ID 1020-1023 are reserved.
//
return (ItLines == 0x1f) ? 1020 : 32 * (ItLines + 1);
} }
VOID VOID
EFIAPI EFIAPI
ArmGicSendSgiTo ( ArmGicSendSgiTo (
IN UINTN GicDistributorBase, IN INTN GicDistributorBase,
IN UINT8 TargetListFilter, IN INTN TargetListFilter,
IN UINT8 CPUTargetList, IN INTN CPUTargetList,
IN UINT8 SgiId IN INTN SgiId
) )
{ {
MmioWrite32 ( MmioWrite32 (
GicDistributorBase + ARM_GIC_ICDSGIR, GicDistributorBase + ARM_GIC_ICDSGIR,
((TargetListFilter & 0x3) << 24) | ((TargetListFilter & 0x3) << 24) | ((CPUTargetList & 0xFF) << 16) | SgiId
((CPUTargetList & 0xFF) << 16) |
(SgiId & 0xF)
); );
} }
@@ -176,17 +157,19 @@ ArmGicAcknowledgeInterrupt (
) )
{ {
UINTN Value; UINTN Value;
UINTN IntId;
ARM_GIC_ARCH_REVISION Revision; ARM_GIC_ARCH_REVISION Revision;
ASSERT (InterruptId != NULL);
Revision = ArmGicGetSupportedArchRevision (); Revision = ArmGicGetSupportedArchRevision ();
if (Revision == ARM_GIC_ARCH_REVISION_2) { if (Revision == ARM_GIC_ARCH_REVISION_2) {
Value = ArmGicV2AcknowledgeInterrupt (GicInterruptInterfaceBase); Value = ArmGicV2AcknowledgeInterrupt (GicInterruptInterfaceBase);
IntId = Value & ARM_GIC_ICCIAR_ACKINTID; // InterruptId is required for the caller to know if a valid or spurious
// interrupt has been read
ASSERT (InterruptId != NULL);
if (InterruptId != NULL) {
*InterruptId = Value & ARM_GIC_ICCIAR_ACKINTID;
}
} else if (Revision == ARM_GIC_ARCH_REVISION_3) { } else if (Revision == ARM_GIC_ARCH_REVISION_3) {
Value = ArmGicV3AcknowledgeInterrupt (); Value = ArmGicV3AcknowledgeInterrupt ();
IntId = Value;
} else { } else {
ASSERT_EFI_ERROR (EFI_UNSUPPORTED); ASSERT_EFI_ERROR (EFI_UNSUPPORTED);
// Report Spurious interrupt which is what the above controllers would // Report Spurious interrupt which is what the above controllers would
@@ -194,12 +177,6 @@ ArmGicAcknowledgeInterrupt (
Value = 1023; Value = 1023;
} }
if (InterruptId != NULL) {
// InterruptId is required for the caller to know if a valid or spurious
// interrupt has been read
*InterruptId = IntId;
}
return Value; return Value;
} }
@@ -222,51 +199,6 @@ ArmGicEndOfInterrupt (
} }
} }
VOID
EFIAPI
ArmGicSetInterruptPriority (
IN UINTN GicDistributorBase,
IN UINTN GicRedistributorBase,
IN UINTN Source,
IN UINTN Priority
)
{
UINT32 RegOffset;
UINT8 RegShift;
ARM_GIC_ARCH_REVISION Revision;
UINTN GicCpuRedistributorBase;
// Calculate register offset and bit position
RegOffset = (UINT32)(Source / 4);
RegShift = (UINT8)((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 VOID
EFIAPI EFIAPI
ArmGicEnableInterrupt ( ArmGicEnableInterrupt (
@@ -276,19 +208,18 @@ ArmGicEnableInterrupt (
) )
{ {
UINT32 RegOffset; UINT32 RegOffset;
UINT8 RegShift; UINTN RegShift;
ARM_GIC_ARCH_REVISION Revision; ARM_GIC_ARCH_REVISION Revision;
UINTN GicCpuRedistributorBase; UINTN GicCpuRedistributorBase;
// Calculate enable register offset and bit position // Calculate enable register offset and bit position
RegOffset = (UINT32)(Source / 32); RegOffset = Source / 32;
RegShift = (UINT8)(Source % 32); RegShift = Source % 32;
Revision = ArmGicGetSupportedArchRevision (); Revision = ArmGicGetSupportedArchRevision ();
if ((Revision == ARM_GIC_ARCH_REVISION_2) || if ((Revision == ARM_GIC_ARCH_REVISION_2) ||
FeaturePcdGet (PcdArmGicV3WithV2Legacy) || FeaturePcdGet (PcdArmGicV3WithV2Legacy) ||
SourceIsSpi (Source)) SourceIsSpi (Source)) {
{
// Write set-enable register // Write set-enable register
MmioWrite32 ( MmioWrite32 (
GicDistributorBase + ARM_GIC_ICDISER + (4 * RegOffset), GicDistributorBase + ARM_GIC_ICDISER + (4 * RegOffset),
@@ -306,7 +237,7 @@ ArmGicEnableInterrupt (
// Write set-enable register // Write set-enable register
MmioWrite32 ( MmioWrite32 (
ISENABLER_ADDRESS (GicCpuRedistributorBase, RegOffset), ISENABLER_ADDRESS(GicCpuRedistributorBase, RegOffset),
1 << RegShift 1 << RegShift
); );
} }
@@ -321,19 +252,18 @@ ArmGicDisableInterrupt (
) )
{ {
UINT32 RegOffset; UINT32 RegOffset;
UINT8 RegShift; UINTN RegShift;
ARM_GIC_ARCH_REVISION Revision; ARM_GIC_ARCH_REVISION Revision;
UINTN GicCpuRedistributorBase; UINTN GicCpuRedistributorBase;
// Calculate enable register offset and bit position // Calculate enable register offset and bit position
RegOffset = (UINT32)(Source / 32); RegOffset = Source / 32;
RegShift = (UINT8)(Source % 32); RegShift = Source % 32;
Revision = ArmGicGetSupportedArchRevision (); Revision = ArmGicGetSupportedArchRevision ();
if ((Revision == ARM_GIC_ARCH_REVISION_2) || if ((Revision == ARM_GIC_ARCH_REVISION_2) ||
FeaturePcdGet (PcdArmGicV3WithV2Legacy) || FeaturePcdGet (PcdArmGicV3WithV2Legacy) ||
SourceIsSpi (Source)) SourceIsSpi (Source)) {
{
// Write clear-enable register // Write clear-enable register
MmioWrite32 ( MmioWrite32 (
GicDistributorBase + ARM_GIC_ICDICER + (4 * RegOffset), GicDistributorBase + ARM_GIC_ICDICER + (4 * RegOffset),
@@ -350,7 +280,7 @@ ArmGicDisableInterrupt (
// Write clear-enable register // Write clear-enable register
MmioWrite32 ( MmioWrite32 (
ICENABLER_ADDRESS (GicCpuRedistributorBase, RegOffset), ICENABLER_ADDRESS(GicCpuRedistributorBase, RegOffset),
1 << RegShift 1 << RegShift
); );
} }
@@ -365,23 +295,23 @@ ArmGicIsInterruptEnabled (
) )
{ {
UINT32 RegOffset; UINT32 RegOffset;
UINT8 RegShift; UINTN RegShift;
ARM_GIC_ARCH_REVISION Revision; ARM_GIC_ARCH_REVISION Revision;
UINTN GicCpuRedistributorBase; UINTN GicCpuRedistributorBase;
UINT32 Interrupts; UINT32 Interrupts;
// Calculate enable register offset and bit position // Calculate enable register offset and bit position
RegOffset = (UINT32)(Source / 32); RegOffset = Source / 32;
RegShift = (UINT8)(Source % 32); RegShift = Source % 32;
Revision = ArmGicGetSupportedArchRevision (); Revision = ArmGicGetSupportedArchRevision ();
if ((Revision == ARM_GIC_ARCH_REVISION_2) || if ((Revision == ARM_GIC_ARCH_REVISION_2) ||
FeaturePcdGet (PcdArmGicV3WithV2Legacy) || FeaturePcdGet (PcdArmGicV3WithV2Legacy) ||
SourceIsSpi (Source)) SourceIsSpi (Source)) {
{ Interrupts = ((MmioRead32 (
Interrupts = MmioRead32 (
GicDistributorBase + ARM_GIC_ICDISER + (4 * RegOffset) GicDistributorBase + ARM_GIC_ICDISER + (4 * RegOffset)
); )
& (1 << RegShift)) != 0);
} else { } else {
GicCpuRedistributorBase = GicGetCpuRedistributorBase ( GicCpuRedistributorBase = GicGetCpuRedistributorBase (
GicRedistributorBase, GicRedistributorBase,
@@ -393,7 +323,7 @@ ArmGicIsInterruptEnabled (
// Read set-enable register // Read set-enable register
Interrupts = MmioRead32 ( Interrupts = MmioRead32 (
ISENABLER_ADDRESS (GicCpuRedistributorBase, RegOffset) ISENABLER_ADDRESS(GicCpuRedistributorBase, RegOffset)
); );
} }
@@ -403,7 +333,7 @@ ArmGicIsInterruptEnabled (
VOID VOID
EFIAPI EFIAPI
ArmGicDisableDistributor ( ArmGicDisableDistributor (
IN UINTN GicDistributorBase IN INTN GicDistributorBase
) )
{ {
// Disable Gic Distributor // Disable Gic Distributor
@@ -413,7 +343,7 @@ ArmGicDisableDistributor (
VOID VOID
EFIAPI EFIAPI
ArmGicEnableInterruptInterface ( ArmGicEnableInterruptInterface (
IN UINTN GicInterruptInterfaceBase IN INTN GicInterruptInterfaceBase
) )
{ {
ARM_GIC_ARCH_REVISION Revision; ARM_GIC_ARCH_REVISION Revision;
@@ -431,7 +361,7 @@ ArmGicEnableInterruptInterface (
VOID VOID
EFIAPI EFIAPI
ArmGicDisableInterruptInterface ( ArmGicDisableInterruptInterface (
IN UINTN GicInterruptInterfaceBase IN INTN GicInterruptInterfaceBase
) )
{ {
ARM_GIC_ARCH_REVISION Revision; ARM_GIC_ARCH_REVISION Revision;

View File

@@ -22,6 +22,7 @@
[Sources.ARM] [Sources.ARM]
GicV3/Arm/ArmGicV3.S | GCC GicV3/Arm/ArmGicV3.S | GCC
GicV3/Arm/ArmGicV3.asm | RVCT
[Sources.AARCH64] [Sources.AARCH64]
GicV3/AArch64/ArmGicV3.S GicV3/AArch64/ArmGicV3.S

View File

@@ -1,6 +1,6 @@
/** @file /** @file
* *
* Copyright (c) 2011-2023, Arm Limited. All rights reserved. * Copyright (c) 2011-2015, ARM Limited. All rights reserved.
* *
* SPDX-License-Identifier: BSD-2-Clause-Patent * SPDX-License-Identifier: BSD-2-Clause-Patent
* *
@@ -13,11 +13,10 @@
VOID VOID
EFIAPI EFIAPI
ArmGicEnableDistributor ( ArmGicEnableDistributor (
IN UINTN GicDistributorBase IN INTN GicDistributorBase
) )
{ {
ARM_GIC_ARCH_REVISION Revision; ARM_GIC_ARCH_REVISION Revision;
UINT32 GicDistributorCtl;
/* /*
* Enable GIC distributor in Non-Secure world. * Enable GIC distributor in Non-Secure world.
@@ -27,8 +26,7 @@ ArmGicEnableDistributor (
if (Revision == ARM_GIC_ARCH_REVISION_2) { if (Revision == ARM_GIC_ARCH_REVISION_2) {
MmioWrite32 (GicDistributorBase + ARM_GIC_ICDDCR, 0x1); MmioWrite32 (GicDistributorBase + ARM_GIC_ICDDCR, 0x1);
} else { } else {
GicDistributorCtl = MmioRead32 (GicDistributorBase + ARM_GIC_ICDDCR); if (MmioRead32 (GicDistributorBase + ARM_GIC_ICDDCR) & ARM_GIC_ICDDCR_ARE) {
if ((GicDistributorCtl & ARM_GIC_ICDDCR_ARE) != 0) {
MmioOr32 (GicDistributorBase + ARM_GIC_ICDDCR, 0x2); MmioOr32 (GicDistributorBase + ARM_GIC_ICDDCR, 0x2);
} else { } else {
MmioOr32 (GicDistributorBase + ARM_GIC_ICDDCR, 0x1); MmioOr32 (GicDistributorBase + ARM_GIC_ICDDCR, 0x1);

View File

@@ -0,0 +1,58 @@
/** @file
*
* Copyright (c) 2011-2014, ARM Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-2-Clause-Patent
*
**/
#include <Base.h>
#include <Library/DebugLib.h>
#include <Library/IoLib.h>
#include <Library/ArmGicLib.h>
/*
* This function configures the interrupts set by the mask to be secure.
*
*/
VOID
EFIAPI
ArmGicSetSecureInterrupts (
IN UINTN GicDistributorBase,
IN UINTN* GicSecureInterruptMask,
IN UINTN GicSecureInterruptMaskSize
)
{
UINTN Index;
UINT32 InterruptStatus;
// We must not have more interrupts defined by the mask than the number of available interrupts
ASSERT(GicSecureInterruptMaskSize <= (ArmGicGetMaxNumInterrupts (GicDistributorBase) / 32));
// Set all the interrupts defined by the mask as Secure
for (Index = 0; Index < GicSecureInterruptMaskSize; Index++) {
InterruptStatus = MmioRead32 (GicDistributorBase + ARM_GIC_ICDISR + (Index * 4));
MmioWrite32 (GicDistributorBase + ARM_GIC_ICDISR + (Index * 4), InterruptStatus & (~GicSecureInterruptMask[Index]));
}
}
VOID
EFIAPI
ArmGicEnableDistributor (
IN INTN GicDistributorBase
)
{
// Turn on the GIC distributor
MmioWrite32 (GicDistributorBase + ARM_GIC_ICDDCR, 1);
}
VOID
EFIAPI
ArmGicSetupNonSecure (
IN UINTN MpId,
IN INTN GicDistributorBase,
IN INTN GicInterruptInterfaceBase
)
{
ArmGicV2SetupNonSecure (MpId, GicDistributorBase, GicInterruptInterfaceBase);
}

View File

@@ -2,7 +2,7 @@
Copyright (c) 2009, Hewlett-Packard Company. All rights reserved.<BR> Copyright (c) 2009, Hewlett-Packard Company. All rights reserved.<BR>
Portions copyright (c) 2010, Apple Inc. All rights reserved.<BR> Portions copyright (c) 2010, Apple Inc. All rights reserved.<BR>
Portions copyright (c) 2011-2023, Arm Ltd. All rights reserved.<BR> Portions copyright (c) 2011-2017, ARM Ltd. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -25,8 +25,8 @@ Abstract:
extern EFI_HARDWARE_INTERRUPT_PROTOCOL gHardwareInterruptV2Protocol; extern EFI_HARDWARE_INTERRUPT_PROTOCOL gHardwareInterruptV2Protocol;
extern EFI_HARDWARE_INTERRUPT2_PROTOCOL gHardwareInterrupt2V2Protocol; extern EFI_HARDWARE_INTERRUPT2_PROTOCOL gHardwareInterrupt2V2Protocol;
STATIC UINTN mGicInterruptInterfaceBase; STATIC UINT32 mGicInterruptInterfaceBase;
STATIC UINTN mGicDistributorBase; STATIC UINT32 mGicDistributorBase;
/** /**
Enable interrupt source Source. Enable interrupt source Source.
@@ -47,7 +47,7 @@ GicV2EnableInterruptSource (
) )
{ {
if (Source >= mGicNumInterrupts) { if (Source >= mGicNumInterrupts) {
ASSERT (FALSE); ASSERT(FALSE);
return EFI_UNSUPPORTED; return EFI_UNSUPPORTED;
} }
@@ -75,7 +75,7 @@ GicV2DisableInterruptSource (
) )
{ {
if (Source >= mGicNumInterrupts) { if (Source >= mGicNumInterrupts) {
ASSERT (FALSE); ASSERT(FALSE);
return EFI_UNSUPPORTED; return EFI_UNSUPPORTED;
} }
@@ -105,7 +105,7 @@ GicV2GetInterruptSourceState (
) )
{ {
if (Source >= mGicNumInterrupts) { if (Source >= mGicNumInterrupts) {
ASSERT (FALSE); ASSERT(FALSE);
return EFI_UNSUPPORTED; return EFI_UNSUPPORTED;
} }
@@ -121,7 +121,7 @@ GicV2GetInterruptSourceState (
@param This Instance pointer for this protocol @param This Instance pointer for this protocol
@param Source Hardware source of the interrupt @param Source Hardware source of the interrupt
@retval EFI_SUCCESS Source interrupt ended successfully. @retval EFI_SUCCESS Source interrupt EOI'ed.
@retval EFI_UNSUPPORTED Source interrupt is not supported @retval EFI_UNSUPPORTED Source interrupt is not supported
**/ **/
@@ -134,7 +134,7 @@ GicV2EndOfInterrupt (
) )
{ {
if (Source >= mGicNumInterrupts) { if (Source >= mGicNumInterrupts) {
ASSERT (FALSE); ASSERT(FALSE);
return EFI_UNSUPPORTED; return EFI_UNSUPPORTED;
} }
@@ -162,7 +162,7 @@ GicV2IrqInterruptHandler (
IN EFI_SYSTEM_CONTEXT SystemContext IN EFI_SYSTEM_CONTEXT SystemContext
) )
{ {
UINTN GicInterrupt; UINT32 GicInterrupt;
HARDWARE_INTERRUPT_HANDLER InterruptHandler; HARDWARE_INTERRUPT_HANDLER InterruptHandler;
GicInterrupt = ArmGicV2AcknowledgeInterrupt (mGicInterruptInterfaceBase); GicInterrupt = ArmGicV2AcknowledgeInterrupt (mGicInterruptInterfaceBase);
@@ -179,7 +179,7 @@ GicV2IrqInterruptHandler (
// Call the registered interrupt handler. // Call the registered interrupt handler.
InterruptHandler (GicInterrupt, SystemContext); InterruptHandler (GicInterrupt, SystemContext);
} else { } else {
DEBUG ((DEBUG_ERROR, "Spurious GIC interrupt: 0x%x\n", (UINT32)GicInterrupt)); DEBUG ((DEBUG_ERROR, "Spurious GIC interrupt: 0x%x\n", GicInterrupt));
GicV2EndOfInterrupt (&gHardwareInterruptV2Protocol, GicInterrupt); GicV2EndOfInterrupt (&gHardwareInterruptV2Protocol, GicInterrupt);
} }
} }
@@ -261,13 +261,9 @@ GicV2SetTriggerType (
BOOLEAN SourceEnabled; BOOLEAN SourceEnabled;
if ( (TriggerType != EFI_HARDWARE_INTERRUPT2_TRIGGER_EDGE_RISING) if ( (TriggerType != EFI_HARDWARE_INTERRUPT2_TRIGGER_EDGE_RISING)
&& (TriggerType != EFI_HARDWARE_INTERRUPT2_TRIGGER_LEVEL_HIGH)) && (TriggerType != EFI_HARDWARE_INTERRUPT2_TRIGGER_LEVEL_HIGH)) {
{ DEBUG ((DEBUG_ERROR, "Invalid interrupt trigger type: %d\n", \
DEBUG (( TriggerType));
DEBUG_ERROR,
"Invalid interrupt trigger type: %d\n", \
TriggerType
));
ASSERT (FALSE); ASSERT (FALSE);
return EFI_UNSUPPORTED; return EFI_UNSUPPORTED;
} }
@@ -283,7 +279,7 @@ GicV2SetTriggerType (
} }
Status = GicV2GetInterruptSourceState ( Status = GicV2GetInterruptSourceState (
(EFI_HARDWARE_INTERRUPT_PROTOCOL *)This, (EFI_HARDWARE_INTERRUPT_PROTOCOL*)This,
Source, Source,
&SourceEnabled &SourceEnabled
); );
@@ -300,7 +296,7 @@ GicV2SetTriggerType (
// otherwise GIC behavior is UNPREDICTABLE. // otherwise GIC behavior is UNPREDICTABLE.
if (SourceEnabled) { if (SourceEnabled) {
GicV2DisableInterruptSource ( GicV2DisableInterruptSource (
(EFI_HARDWARE_INTERRUPT_PROTOCOL *)This, (EFI_HARDWARE_INTERRUPT_PROTOCOL*)This,
Source Source
); );
} }
@@ -314,7 +310,7 @@ GicV2SetTriggerType (
// Restore interrupt state // Restore interrupt state
if (SourceEnabled) { if (SourceEnabled) {
GicV2EnableInterruptSource ( GicV2EnableInterruptSource (
(EFI_HARDWARE_INTERRUPT_PROTOCOL *)This, (EFI_HARDWARE_INTERRUPT_PROTOCOL*)This,
Source Source
); );
} }
@@ -350,7 +346,7 @@ GicV2ExitBootServicesEvent (
) )
{ {
UINTN Index; UINTN Index;
UINTN GicInterrupt; UINT32 GicInterrupt;
// Disable all the interrupts // Disable all the interrupts
for (Index = 0; Index < mGicNumInterrupts; Index++) { for (Index = 0; Index < mGicNumInterrupts; Index++) {
@@ -393,26 +389,23 @@ GicV2DxeInitialize (
EFI_STATUS Status; EFI_STATUS Status;
UINTN Index; UINTN Index;
UINT32 RegOffset; UINT32 RegOffset;
UINT8 RegShift; UINTN RegShift;
UINT32 CpuTarget; UINT32 CpuTarget;
// Make sure the Interrupt Controller Protocol is not already installed in // Make sure the Interrupt Controller Protocol is not already installed in
// the system. // the system.
ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gHardwareInterruptProtocolGuid); ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gHardwareInterruptProtocolGuid);
ASSERT (PcdGet64 (PcdGicInterruptInterfaceBase) <= MAX_UINTN); mGicInterruptInterfaceBase = PcdGet64 (PcdGicInterruptInterfaceBase);
ASSERT (PcdGet64 (PcdGicDistributorBase) <= MAX_UINTN); mGicDistributorBase = PcdGet64 (PcdGicDistributorBase);
mGicInterruptInterfaceBase = (UINTN)PcdGet64 (PcdGicInterruptInterfaceBase);
mGicDistributorBase = (UINTN)PcdGet64 (PcdGicDistributorBase);
mGicNumInterrupts = ArmGicGetMaxNumInterrupts (mGicDistributorBase); mGicNumInterrupts = ArmGicGetMaxNumInterrupts (mGicDistributorBase);
for (Index = 0; Index < mGicNumInterrupts; Index++) { for (Index = 0; Index < mGicNumInterrupts; Index++) {
GicV2DisableInterruptSource (&gHardwareInterruptV2Protocol, Index); GicV2DisableInterruptSource (&gHardwareInterruptV2Protocol, Index);
// Set Priority // Set Priority
RegOffset = (UINT32)(Index / 4); RegOffset = Index / 4;
RegShift = (UINT8)((Index % 4) * 8); RegShift = (Index % 4) * 8;
MmioAndThenOr32 ( MmioAndThenOr32 (
mGicDistributorBase + ARM_GIC_ICDIPR + (4 * RegOffset), mGicDistributorBase + ARM_GIC_ICDIPR + (4 * RegOffset),
~(0xff << RegShift), ~(0xff << RegShift),

View File

@@ -1,13 +1,12 @@
/** @file /** @file
* *
* Copyright (c) 2013-2023, ARM Limited. All rights reserved. * Copyright (c) 2013-2014, ARM Limited. All rights reserved.
* *
* SPDX-License-Identifier: BSD-2-Clause-Patent * SPDX-License-Identifier: BSD-2-Clause-Patent
* *
**/ **/
#include <Library/ArmGicLib.h> #include <Library/ArmGicLib.h>
#include <Library/DebugLib.h>
#include <Library/IoLib.h> #include <Library/IoLib.h>
UINTN UINTN
@@ -27,6 +26,5 @@ ArmGicV2EndOfInterrupt (
IN UINTN Source IN UINTN Source
) )
{ {
ASSERT (Source <= MAX_UINT32); MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCEIOR, Source);
MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCEIOR, (UINT32)Source);
} }

View File

@@ -1,6 +1,6 @@
/** @file /** @file
* *
* Copyright (c) 2011-2023, Arm Limited. All rights reserved. * Copyright (c) 2011-2014, ARM Limited. All rights reserved.
* *
* SPDX-License-Identifier: BSD-2-Clause-Patent * SPDX-License-Identifier: BSD-2-Clause-Patent
* *
@@ -10,10 +10,11 @@
#include <Library/IoLib.h> #include <Library/IoLib.h>
#include <Library/ArmGicLib.h> #include <Library/ArmGicLib.h>
VOID VOID
EFIAPI EFIAPI
ArmGicV2EnableInterruptInterface ( ArmGicV2EnableInterruptInterface (
IN UINTN GicInterruptInterfaceBase IN INTN GicInterruptInterfaceBase
) )
{ {
/* /*
@@ -26,7 +27,7 @@ ArmGicV2EnableInterruptInterface (
VOID VOID
EFIAPI EFIAPI
ArmGicV2DisableInterruptInterface ( ArmGicV2DisableInterruptInterface (
IN UINTN GicInterruptInterfaceBase IN INTN GicInterruptInterfaceBase
) )
{ {
// Disable Gic Interface // Disable Gic Interface

View File

@@ -0,0 +1,82 @@
//
// Copyright (c) 2014, ARM Limited. All rights reserved.
//
// SPDX-License-Identifier: BSD-2-Clause-Patent
//
//
// For the moment we assume this will run in SVC mode on ARMv7
INCLUDE AsmMacroExport.inc
//UINT32
//EFIAPI
//ArmGicGetControlSystemRegisterEnable (
// VOID
// );
RVCT_ASM_EXPORT ArmGicV3GetControlSystemRegisterEnable
mrc p15, 0, r0, c12, c12, 5 // ICC_SRE
bx lr
//VOID
//EFIAPI
//ArmGicSetControlSystemRegisterEnable (
// IN UINT32 ControlSystemRegisterEnable
// );
RVCT_ASM_EXPORT ArmGicV3SetControlSystemRegisterEnable
mcr p15, 0, r0, c12, c12, 5 // ICC_SRE
isb
bx lr
//VOID
//ArmGicV3EnableInterruptInterface (
// VOID
// );
RVCT_ASM_EXPORT ArmGicV3EnableInterruptInterface
mov r0, #1
mcr p15, 0, r0, c12, c12, 7 // ICC_IGRPEN1
bx lr
//VOID
//ArmGicV3DisableInterruptInterface (
// VOID
// );
RVCT_ASM_EXPORT ArmGicV3DisableInterruptInterface
mov r0, #0
mcr p15, 0, r0, c12, c12, 7 // ICC_IGRPEN1
bx lr
//VOID
//ArmGicV3EndOfInterrupt (
// IN UINTN InterruptId
// );
RVCT_ASM_EXPORT ArmGicV3EndOfInterrupt
mcr p15, 0, r0, c12, c12, 1 //ICC_EOIR1
bx lr
//UINTN
//ArmGicV3AcknowledgeInterrupt (
// VOID
// );
RVCT_ASM_EXPORT ArmGicV3AcknowledgeInterrupt
mrc p15, 0, r0, c12, c12, 0 //ICC_IAR1
bx lr
//VOID
//ArmGicV3SetPriorityMask (
// IN UINTN Priority
// );
RVCT_ASM_EXPORT ArmGicV3SetPriorityMask
mcr p15, 0, r0, c4, c6, 0 //ICC_PMR
bx lr
//VOID
//ArmGicV3SetBinaryPointer (
// IN UINTN BinaryPoint
// );
RVCT_ASM_EXPORT ArmGicV3SetBinaryPointer
mcr p15, 0, r0, c12, c12, 3 //ICC_BPR1
bx lr
END

View File

@@ -1,6 +1,6 @@
/** @file /** @file
* *
* Copyright (c) 2011-2023, Arm Limited. All rights reserved. * Copyright (c) 2011-2018, ARM Limited. All rights reserved.
* *
* SPDX-License-Identifier: BSD-2-Clause-Patent * SPDX-License-Identifier: BSD-2-Clause-Patent
* *
@@ -37,7 +37,7 @@ GicV3EnableInterruptSource (
) )
{ {
if (Source >= mGicNumInterrupts) { if (Source >= mGicNumInterrupts) {
ASSERT (FALSE); ASSERT(FALSE);
return EFI_UNSUPPORTED; return EFI_UNSUPPORTED;
} }
@@ -65,7 +65,7 @@ GicV3DisableInterruptSource (
) )
{ {
if (Source >= mGicNumInterrupts) { if (Source >= mGicNumInterrupts) {
ASSERT (FALSE); ASSERT(FALSE);
return EFI_UNSUPPORTED; return EFI_UNSUPPORTED;
} }
@@ -95,7 +95,7 @@ GicV3GetInterruptSourceState (
) )
{ {
if (Source >= mGicNumInterrupts) { if (Source >= mGicNumInterrupts) {
ASSERT (FALSE); ASSERT(FALSE);
return EFI_UNSUPPORTED; return EFI_UNSUPPORTED;
} }
@@ -115,7 +115,7 @@ GicV3GetInterruptSourceState (
@param This Instance pointer for this protocol @param This Instance pointer for this protocol
@param Source Hardware source of the interrupt @param Source Hardware source of the interrupt
@retval EFI_SUCCESS Source interrupt ended successfully. @retval EFI_SUCCESS Source interrupt EOI'ed.
@retval EFI_DEVICE_ERROR Hardware could not be programmed. @retval EFI_DEVICE_ERROR Hardware could not be programmed.
**/ **/
@@ -128,7 +128,7 @@ GicV3EndOfInterrupt (
) )
{ {
if (Source >= mGicNumInterrupts) { if (Source >= mGicNumInterrupts) {
ASSERT (FALSE); ASSERT(FALSE);
return EFI_UNSUPPORTED; return EFI_UNSUPPORTED;
} }
@@ -156,7 +156,7 @@ GicV3IrqInterruptHandler (
IN EFI_SYSTEM_CONTEXT SystemContext IN EFI_SYSTEM_CONTEXT SystemContext
) )
{ {
UINTN GicInterrupt; UINT32 GicInterrupt;
HARDWARE_INTERRUPT_HANDLER InterruptHandler; HARDWARE_INTERRUPT_HANDLER InterruptHandler;
GicInterrupt = ArmGicV3AcknowledgeInterrupt (); GicInterrupt = ArmGicV3AcknowledgeInterrupt ();
@@ -173,7 +173,7 @@ GicV3IrqInterruptHandler (
// Call the registered interrupt handler. // Call the registered interrupt handler.
InterruptHandler (GicInterrupt, SystemContext); InterruptHandler (GicInterrupt, SystemContext);
} else { } else {
DEBUG ((DEBUG_ERROR, "Spurious GIC interrupt: 0x%x\n", (UINT32)GicInterrupt)); DEBUG ((DEBUG_ERROR, "Spurious GIC interrupt: 0x%x\n", GicInterrupt));
GicV3EndOfInterrupt (&gHardwareInterruptV3Protocol, GicInterrupt); GicV3EndOfInterrupt (&gHardwareInterruptV3Protocol, GicInterrupt);
} }
} }
@@ -255,13 +255,9 @@ GicV3SetTriggerType (
BOOLEAN SourceEnabled; BOOLEAN SourceEnabled;
if ( (TriggerType != EFI_HARDWARE_INTERRUPT2_TRIGGER_EDGE_RISING) if ( (TriggerType != EFI_HARDWARE_INTERRUPT2_TRIGGER_EDGE_RISING)
&& (TriggerType != EFI_HARDWARE_INTERRUPT2_TRIGGER_LEVEL_HIGH)) && (TriggerType != EFI_HARDWARE_INTERRUPT2_TRIGGER_LEVEL_HIGH)) {
{ DEBUG ((DEBUG_ERROR, "Invalid interrupt trigger type: %d\n", \
DEBUG (( TriggerType));
DEBUG_ERROR,
"Invalid interrupt trigger type: %d\n", \
TriggerType
));
ASSERT (FALSE); ASSERT (FALSE);
return EFI_UNSUPPORTED; return EFI_UNSUPPORTED;
} }
@@ -277,7 +273,7 @@ GicV3SetTriggerType (
} }
Status = GicV3GetInterruptSourceState ( Status = GicV3GetInterruptSourceState (
(EFI_HARDWARE_INTERRUPT_PROTOCOL *)This, (EFI_HARDWARE_INTERRUPT_PROTOCOL*)This,
Source, Source,
&SourceEnabled &SourceEnabled
); );
@@ -294,7 +290,7 @@ GicV3SetTriggerType (
// otherwise GIC behavior is UNPREDICTABLE. // otherwise GIC behavior is UNPREDICTABLE.
if (SourceEnabled) { if (SourceEnabled) {
GicV3DisableInterruptSource ( GicV3DisableInterruptSource (
(EFI_HARDWARE_INTERRUPT_PROTOCOL *)This, (EFI_HARDWARE_INTERRUPT_PROTOCOL*)This,
Source Source
); );
} }
@@ -307,7 +303,7 @@ GicV3SetTriggerType (
// Restore interrupt state // Restore interrupt state
if (SourceEnabled) { if (SourceEnabled) {
GicV3EnableInterruptSource ( GicV3EnableInterruptSource (
(EFI_HARDWARE_INTERRUPT_PROTOCOL *)This, (EFI_HARDWARE_INTERRUPT_PROTOCOL*)This,
Source Source
); );
} }
@@ -348,6 +344,10 @@ GicV3ExitBootServicesEvent (
GicV3DisableInterruptSource (&gHardwareInterruptV3Protocol, Index); GicV3DisableInterruptSource (&gHardwareInterruptV3Protocol, Index);
} }
for (Index = 0; Index < mGicNumInterrupts; Index++) {
GicV3EndOfInterrupt (&gHardwareInterruptV3Protocol, Index);
}
// Disable Gic Interface // Disable Gic Interface
ArmGicV3DisableInterruptInterface (); ArmGicV3DisableInterruptInterface ();
@@ -374,6 +374,8 @@ GicV3DxeInitialize (
{ {
EFI_STATUS Status; EFI_STATUS Status;
UINTN Index; UINTN Index;
UINT32 RegOffset;
UINTN RegShift;
UINT64 CpuTarget; UINT64 CpuTarget;
UINT64 MpId; UINT64 MpId;
@@ -381,7 +383,7 @@ GicV3DxeInitialize (
// the system. // the system.
ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gHardwareInterruptProtocolGuid); ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gHardwareInterruptProtocolGuid);
mGicDistributorBase = (UINTN)PcdGet64 (PcdGicDistributorBase); mGicDistributorBase = PcdGet64 (PcdGicDistributorBase);
mGicRedistributorsBase = PcdGet64 (PcdGicRedistributorsBase); mGicRedistributorsBase = PcdGet64 (PcdGicRedistributorsBase);
mGicNumInterrupts = ArmGicGetMaxNumInterrupts (mGicDistributorBase); mGicNumInterrupts = ArmGicGetMaxNumInterrupts (mGicDistributorBase);
@@ -395,11 +397,12 @@ GicV3DxeInitialize (
GicV3DisableInterruptSource (&gHardwareInterruptV3Protocol, Index); GicV3DisableInterruptSource (&gHardwareInterruptV3Protocol, Index);
// Set Priority // Set Priority
ArmGicSetInterruptPriority ( RegOffset = Index / 4;
mGicDistributorBase, RegShift = (Index % 4) * 8;
mGicRedistributorsBase, MmioAndThenOr32 (
Index, mGicDistributorBase + ARM_GIC_ICDIPR + (4 * RegOffset),
ARM_GIC_DEFAULT_PRIORITY ~(0xff << RegShift),
ARM_GIC_DEFAULT_PRIORITY << RegShift
); );
} }
@@ -434,8 +437,8 @@ GicV3DxeInitialize (
if ((MmioRead32 ( if ((MmioRead32 (
mGicDistributorBase + ARM_GIC_ICDDCR mGicDistributorBase + ARM_GIC_ICDDCR
) & ARM_GIC_ICDDCR_DS) != 0) ) & ARM_GIC_ICDDCR_DS) != 0) {
{
// If the Disable Security (DS) control bit is set, we are dealing with a // If the Disable Security (DS) control bit is set, we are dealing with a
// GIC that has only one security state. In this case, let's assume we are // GIC that has only one security state. In this case, let's assume we are
// executing in non-secure state (which is appropriate for DXE modules) // executing in non-secure state (which is appropriate for DXE modules)

View File

@@ -117,14 +117,14 @@ CpuIoCheckParameter (
// For FIFO type, the target address won't increase during the access, // For FIFO type, the target address won't increase during the access,
// so treat Count as 1 // so treat Count as 1
// //
if ((Width >= EfiCpuIoWidthFifoUint8) && (Width <= EfiCpuIoWidthFifoUint64)) { if (Width >= EfiCpuIoWidthFifoUint8 && Width <= EfiCpuIoWidthFifoUint64) {
Count = 1; Count = 1;
} }
// //
// Check to see if Width is in the valid range for I/O Port operations // Check to see if Width is in the valid range for I/O Port operations
// //
Width = (EFI_CPU_IO_PROTOCOL_WIDTH)(Width & 0x03); Width = (EFI_CPU_IO_PROTOCOL_WIDTH) (Width & 0x03);
if (!MmioOperation && (Width == EfiCpuIoWidthUint64)) { if (!MmioOperation && (Width == EfiCpuIoWidthUint64)) {
return EFI_INVALID_PARAMETER; return EFI_INVALID_PARAMETER;
} }
@@ -161,7 +161,6 @@ CpuIoCheckParameter (
if (MaxCount < (Count - 1)) { if (MaxCount < (Count - 1)) {
return EFI_UNSUPPORTED; return EFI_UNSUPPORTED;
} }
if (Address > LShiftU64 (MaxCount - Count + 1, Width)) { if (Address > LShiftU64 (MaxCount - Count + 1, Width)) {
return EFI_UNSUPPORTED; return EFI_UNSUPPORTED;
} }
@@ -243,7 +242,7 @@ CpuMemoryServiceRead (
// //
InStride = mInStride[Width]; InStride = mInStride[Width];
OutStride = mOutStride[Width]; OutStride = mOutStride[Width];
OperationWidth = (EFI_CPU_IO_PROTOCOL_WIDTH)(Width & 0x03); OperationWidth = (EFI_CPU_IO_PROTOCOL_WIDTH) (Width & 0x03);
for (Uint8Buffer = Buffer; Count > 0; Address += InStride, Uint8Buffer += OutStride, Count--) { for (Uint8Buffer = Buffer; Count > 0; Address += InStride, Uint8Buffer += OutStride, Count--) {
if (OperationWidth == EfiCpuIoWidthUint8) { if (OperationWidth == EfiCpuIoWidthUint8) {
*Uint8Buffer = MmioRead8 ((UINTN)Address); *Uint8Buffer = MmioRead8 ((UINTN)Address);
@@ -255,7 +254,6 @@ CpuMemoryServiceRead (
*((UINT64 *)Uint8Buffer) = MmioRead64 ((UINTN)Address); *((UINT64 *)Uint8Buffer) = MmioRead64 ((UINTN)Address);
} }
} }
return EFI_SUCCESS; return EFI_SUCCESS;
} }
@@ -325,7 +323,7 @@ CpuMemoryServiceWrite (
// //
InStride = mInStride[Width]; InStride = mInStride[Width];
OutStride = mOutStride[Width]; OutStride = mOutStride[Width];
OperationWidth = (EFI_CPU_IO_PROTOCOL_WIDTH)(Width & 0x03); OperationWidth = (EFI_CPU_IO_PROTOCOL_WIDTH) (Width & 0x03);
for (Uint8Buffer = Buffer; Count > 0; Address += InStride, Uint8Buffer += OutStride, Count--) { for (Uint8Buffer = Buffer; Count > 0; Address += InStride, Uint8Buffer += OutStride, Count--) {
if (OperationWidth == EfiCpuIoWidthUint8) { if (OperationWidth == EfiCpuIoWidthUint8) {
MmioWrite8 ((UINTN)Address, *Uint8Buffer); MmioWrite8 ((UINTN)Address, *Uint8Buffer);
@@ -337,7 +335,6 @@ CpuMemoryServiceWrite (
MmioWrite64 ((UINTN)Address, *((UINT64 *)Uint8Buffer)); MmioWrite64 ((UINTN)Address, *((UINT64 *)Uint8Buffer));
} }
} }
return EFI_SUCCESS; return EFI_SUCCESS;
} }
@@ -409,7 +406,7 @@ CpuIoServiceRead (
// //
InStride = mInStride[Width]; InStride = mInStride[Width];
OutStride = mOutStride[Width]; OutStride = mOutStride[Width];
OperationWidth = (EFI_CPU_IO_PROTOCOL_WIDTH)(Width & 0x03); OperationWidth = (EFI_CPU_IO_PROTOCOL_WIDTH) (Width & 0x03);
for (Uint8Buffer = Buffer; Count > 0; Address += InStride, Uint8Buffer += OutStride, Count--) { for (Uint8Buffer = Buffer; Count > 0; Address += InStride, Uint8Buffer += OutStride, Count--) {
if (OperationWidth == EfiCpuIoWidthUint8) { if (OperationWidth == EfiCpuIoWidthUint8) {
@@ -495,7 +492,7 @@ CpuIoServiceWrite (
// //
InStride = mInStride[Width]; InStride = mInStride[Width];
OutStride = mOutStride[Width]; OutStride = mOutStride[Width];
OperationWidth = (EFI_CPU_IO_PROTOCOL_WIDTH)(Width & 0x03); OperationWidth = (EFI_CPU_IO_PROTOCOL_WIDTH) (Width & 0x03);
for (Uint8Buffer = (UINT8 *)Buffer; Count > 0; Address += InStride, Uint8Buffer += OutStride, Count--) { for (Uint8Buffer = (UINT8 *)Buffer; Count > 0; Address += InStride, Uint8Buffer += OutStride, Count--) {
if (OperationWidth == EfiCpuIoWidthUint8) { if (OperationWidth == EfiCpuIoWidthUint8) {
@@ -524,6 +521,7 @@ STATIC EFI_CPU_IO2_PROTOCOL mCpuIo2 = {
} }
}; };
/** /**
The user Entry Point for module CpuIo2Dxe. The user code starts with this function. The user Entry Point for module CpuIo2Dxe. The user code starts with this function.
@@ -546,8 +544,7 @@ ArmPciCpuIo2Initialize (
ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiCpuIo2ProtocolGuid); ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiCpuIo2ProtocolGuid);
Status = gBS->InstallMultipleProtocolInterfaces ( Status = gBS->InstallMultipleProtocolInterfaces (
&mHandle, &mHandle,
&gEfiCpuIo2ProtocolGuid, &gEfiCpuIo2ProtocolGuid, &mCpuIo2,
&mCpuIo2,
NULL NULL
); );
ASSERT_EFI_ERROR (Status); ASSERT_EFI_ERROR (Status);

View File

@@ -38,7 +38,7 @@
UefiBootServicesTableLib UefiBootServicesTableLib
[Pcd] [Pcd]
gEfiMdePkgTokenSpaceGuid.PcdPciIoTranslation gArmTokenSpaceGuid.PcdPciIoTranslation
[Protocols] [Protocols]
gEfiCpuIo2ProtocolGuid ## PRODUCES gEfiCpuIo2ProtocolGuid ## PRODUCES

File diff suppressed because it is too large Load Diff

View File

@@ -1,56 +0,0 @@
## @file
# ARM MP services protocol driver
#
# Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved.<BR>
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
##
[Defines]
INF_VERSION = 1.27
BASE_NAME = ArmPsciMpServicesDxe
FILE_GUID = 007ab472-dc4a-4df8-a5c2-abb4a327278c
MODULE_TYPE = DXE_DRIVER
VERSION_STRING = 1.0
ENTRY_POINT = ArmPsciMpServicesDxeInitialize
[Sources.Common]
ArmPsciMpServicesDxe.c
MpFuncs.S
MpServicesInternal.h
[Packages]
ArmPkg/ArmPkg.dec
ArmPlatformPkg/ArmPlatformPkg.dec
EmbeddedPkg/EmbeddedPkg.dec
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
[LibraryClasses]
ArmLib
ArmMmuLib
ArmSmcLib
BaseMemoryLib
CacheMaintenanceLib
CpuExceptionHandlerLib
DebugLib
HobLib
MemoryAllocationLib
UefiBootServicesTableLib
UefiDriverEntryPoint
UefiLib
[Protocols]
gEfiMpServiceProtocolGuid ## PRODUCES
gEfiLoadedImageProtocolGuid ## CONSUMES
[Guids]
gArmMpCoreInfoGuid
[Depex]
TRUE
[BuildOptions]
GCC:*_*_*_CC_FLAGS = -mstrict-align

View File

@@ -1,74 +0,0 @@
#===============================================================================
# Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
#===============================================================================
.text
.align 3
#include <AsmMacroIoLibV8.h>
#include <IndustryStandard/ArmStdSmc.h>
#include <Library/ArmLib.h>
#include "MpServicesInternal.h"
GCC_ASM_IMPORT (gApStacksBase)
GCC_ASM_IMPORT (gProcessorIDs)
GCC_ASM_IMPORT (ApProcedure)
GCC_ASM_IMPORT (gApStackSize)
GCC_ASM_IMPORT (gTcr)
GCC_ASM_IMPORT (gTtbr0)
GCC_ASM_IMPORT (gMair)
GCC_ASM_EXPORT (ApEntryPoint)
// Entry-point for the AP
// VOID
// ApEntryPoint (
// VOID
// );
ASM_PFX(ApEntryPoint):
// Configure the MMU and caches
ldr x0, gTcr
bl ArmSetTCR
ldr x0, gTtbr0
bl ArmSetTTBR0
ldr x0, gMair
bl ArmSetMAIR
bl ArmDisableAlignmentCheck
bl ArmEnableStackAlignmentCheck
bl ArmEnableInstructionCache
bl ArmEnableDataCache
bl ArmEnableMmu
mrs x0, mpidr_el1
// Mask the non-affinity bits
bic x0, x0, 0x00ff000000
and x0, x0, 0xffffffffff
ldr x1, gProcessorIDs
mov x2, 0 // x2 = processor index
// Find index in gProcessorIDs for current processor
1:
ldr x3, [x1, x2, lsl #3] // x4 = gProcessorIDs + x2 * 8
cmp x3, #-1 // check if we've reached the end of gProcessorIDs
beq ProcessorNotFound
add x2, x2, 1 // x2++
cmp x0, x3 // if mpidr_el1 != gProcessorIDs[x] then loop
bne 1b
// Calculate stack address
// x2 contains the index for the current processor plus 1
ldr x0, gApStacksBase
ldr x1, gApStackSize
mul x3, x2, x1 // x3 = (ProcessorIndex + 1) * gApStackSize
add sp, x0, x3 // sp = gApStacksBase + x3
mov x29, xzr
bl ApProcedure // doesn't return
ProcessorNotFound:
// Turn off the processor
MOV32 (w0, ARM_SMC_ID_PSCI_CPU_OFF)
smc #0
b .

View File

@@ -1,345 +0,0 @@
/** @file
Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved.<BR>
Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
Portions copyright (c) 2011, Apple Inc. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#ifndef MP_SERVICES_INTERNAL_H_
#define MP_SERVICES_INTERNAL_H_
#include <Protocol/Cpu.h>
#include <Protocol/MpService.h>
#include <Library/BaseLib.h>
#include <Library/UefiLib.h>
#define AP_STACK_SIZE 0x1000
//
// Internal Data Structures
//
//
// AP state
//
// The state transitions for an AP when it processes a procedure are:
// Idle ----> Ready ----> Busy ----> Finished ----> Idle
// [BSP] [BSP] [AP] [BSP]
//
typedef enum {
CpuStateIdle,
CpuStateReady,
CpuStateBlocked,
CpuStateBusy,
CpuStateFinished,
CpuStateDisabled
} CPU_STATE;
//
// Define Individual Processor Data block.
//
typedef struct {
EFI_PROCESSOR_INFORMATION Info;
EFI_AP_PROCEDURE Procedure;
VOID *Parameter;
CPU_STATE State;
EFI_EVENT CheckThisAPEvent;
EFI_EVENT WaitEvent;
UINTN Timeout;
UINTN TimeTaken;
BOOLEAN TimeoutActive;
BOOLEAN *SingleApFinished;
} CPU_AP_DATA;
//
// Define MP data block which consumes individual processor block.
//
typedef struct {
UINTN NumberOfProcessors;
UINTN NumberOfEnabledProcessors;
EFI_EVENT CheckAllAPsEvent;
EFI_EVENT AllWaitEvent;
UINTN FinishCount;
UINTN StartCount;
EFI_AP_PROCEDURE Procedure;
VOID *ProcedureArgument;
BOOLEAN SingleThread;
UINTN StartedNumber;
CPU_AP_DATA *CpuData;
UINTN *FailedList;
UINTN FailedListIndex;
UINTN AllTimeout;
UINTN AllTimeTaken;
BOOLEAN AllTimeoutActive;
} CPU_MP_DATA;
/** Secondary core entry point.
**/
VOID
ApEntryPoint (
VOID
);
/** C entry-point for the AP.
This function gets called from the assembly function ApEntryPoint.
**/
VOID
ApProcedure (
VOID
);
/** Turns on the specified core using PSCI and executes the user-supplied
function that's been configured via a previous call to SetApProcedure.
@param ProcessorIndex The index of the core to turn on.
@retval EFI_SUCCESS The processor was successfully turned on.
@retval EFI_DEVICE_ERROR An error occurred turning the processor on.
**/
STATIC
EFI_STATUS
EFIAPI
DispatchCpu (
IN UINTN ProcessorIndex
);
/** Returns whether the specified processor is the BSP.
@param[in] ProcessorIndex The index the processor to check.
@return TRUE if the processor is the BSP, FALSE otherwise.
**/
STATIC
BOOLEAN
IsProcessorBSP (
UINTN ProcessorIndex
);
/** Returns whether the processor executing this function is the BSP.
@return Whether the current processor is the BSP.
**/
STATIC
BOOLEAN
IsCurrentProcessorBSP (
VOID
);
/** Returns whether the specified processor is enabled.
@param[in] ProcessorIndex The index of the processor to check.
@return TRUE if the processor is enabled, FALSE otherwise.
**/
STATIC
BOOLEAN
IsProcessorEnabled (
UINTN ProcessorIndex
);
/** Configures the processor context with the user-supplied procedure and
argument.
@param CpuData The processor context.
@param Procedure The user-supplied procedure.
@param ProcedureArgument The user-supplied procedure argument.
**/
STATIC
VOID
SetApProcedure (
IN CPU_AP_DATA *CpuData,
IN EFI_AP_PROCEDURE Procedure,
IN VOID *ProcedureArgument
);
/**
Get the Application Processors state.
@param[in] CpuData The pointer to CPU_AP_DATA of specified AP
@return The AP status
**/
CPU_STATE
GetApState (
IN CPU_AP_DATA *CpuData
);
/** Returns the index of the next processor that is blocked.
@param[out] NextNumber The index of the next blocked processor.
@retval EFI_SUCCESS Successfully found the next blocked processor.
@retval EFI_NOT_FOUND There are no blocked processors.
**/
STATIC
EFI_STATUS
GetNextBlockedNumber (
OUT UINTN *NextNumber
);
/** Stalls the BSP for the minimum of gPollInterval and Timeout.
@param[in] Timeout The time limit in microseconds remaining for
APs to return from Procedure.
@retval StallTime Time of execution stall.
**/
STATIC
UINTN
CalculateAndStallInterval (
IN UINTN Timeout
);
/** Sets up the state for the StartupAllAPs function.
@param SingleThread Whether the APs will execute sequentially.
**/
STATIC
VOID
StartupAllAPsPrepareState (
IN BOOLEAN SingleThread
);
/** Handles execution of StartupAllAPs when a WaitEvent has been specified.
@param Procedure The user-supplied procedure.
@param ProcedureArgument The user-supplied procedure argument.
@param WaitEvent The wait event to be signaled when the work is
complete or a timeout has occurred.
@param TimeoutInMicroseconds The timeout for the work to be completed. Zero
indicates an infinite timeout.
@param SingleThread Whether the APs will execute sequentially.
@param FailedCpuList User-supplied pointer for list of failed CPUs.
@return EFI_SUCCESS on success.
**/
STATIC
EFI_STATUS
StartupAllAPsWithWaitEvent (
IN EFI_AP_PROCEDURE Procedure,
IN VOID *ProcedureArgument,
IN EFI_EVENT WaitEvent,
IN UINTN TimeoutInMicroseconds,
IN BOOLEAN SingleThread,
IN UINTN **FailedCpuList
);
/** Handles execution of StartupAllAPs when no wait event has been specified.
@param Procedure The user-supplied procedure.
@param ProcedureArgument The user-supplied procedure argument.
@param TimeoutInMicroseconds The timeout for the work to be completed. Zero
indicates an infinite timeout.
@param SingleThread Whether the APs will execute sequentially.
@param FailedCpuList User-supplied pointer for list of failed CPUs.
@return EFI_SUCCESS on success.
**/
STATIC
EFI_STATUS
StartupAllAPsNoWaitEvent (
IN EFI_AP_PROCEDURE Procedure,
IN VOID *ProcedureArgument,
IN UINTN TimeoutInMicroseconds,
IN BOOLEAN SingleThread,
IN UINTN **FailedCpuList
);
/** Adds the specified processor the list of failed processors.
@param ProcessorIndex The processor index to add.
@param ApState Processor state.
**/
STATIC
VOID
AddProcessorToFailedList (
UINTN ProcessorIndex,
CPU_STATE ApState
);
/** Handles the StartupAllAPs case where the timeout has occurred.
**/
STATIC
VOID
ProcessStartupAllAPsTimeout (
VOID
);
/**
If a timeout is specified in StartupAllAps(), a timer is set, which invokes
this procedure periodically to check whether all APs have finished.
@param[in] Event The WaitEvent the user supplied.
@param[in] Context The event context.
**/
STATIC
VOID
EFIAPI
CheckAllAPsStatus (
IN EFI_EVENT Event,
IN VOID *Context
);
/** Invoked periodically via a timer to check the state of the processor.
@param Event The event supplied by the timer expiration.
@param Context The processor context.
**/
STATIC
VOID
EFIAPI
CheckThisAPStatus (
IN EFI_EVENT Event,
IN VOID *Context
);
/**
This function is called by all processors (both BSP and AP) once and collects
MP related data.
@param BSP TRUE if the processor is the BSP.
@param Mpidr The MPIDR for the specified processor. This should be
the full MPIDR and not only the affinity bits.
@param ProcessorIndex The index of the processor.
@return EFI_SUCCESS if the data for the processor collected and filled in.
**/
STATIC
EFI_STATUS
FillInProcessorInformation (
IN BOOLEAN BSP,
IN UINTN Mpidr,
IN UINTN ProcessorIndex
);
/**
Event notification function called when the EFI_EVENT_GROUP_READY_TO_BOOT is
signaled. After this point, non-blocking mode is no longer allowed.
@param Event Event whose notification function is being invoked.
@param Context The pointer to the notification function's context,
which is implementation-dependent.
**/
STATIC
VOID
EFIAPI
ReadyToBootSignaled (
IN EFI_EVENT Event,
IN VOID *Context
);
#endif /* MP_SERVICES_INTERNAL_H_ */

View File

@@ -34,7 +34,7 @@ typedef struct {
**/ **/
EFI_STATUS EFI_STATUS
ScmiBaseProtocolInit ( ScmiBaseProtocolInit (
IN OUT EFI_HANDLE *Handle IN OUT EFI_HANDLE* Handle
); );
#endif /* ARM_SCMI_BASE_PROTOCOL_PRIVATE_H_ */ #endif /* ARM_SCMI_BASE_PROTOCOL_PRIVATE_H_ */

View File

@@ -53,6 +53,7 @@ typedef struct {
CLOCK_RATE_DWORD Rate; CLOCK_RATE_DWORD Rate;
} CLOCK_RATE_SET_ATTRIBUTES; } CLOCK_RATE_SET_ATTRIBUTES;
// Message parameters for CLOCK_CONFIG_SET command. // Message parameters for CLOCK_CONFIG_SET command.
typedef struct { typedef struct {
UINT32 ClockId; UINT32 ClockId;

View File

@@ -1,6 +1,6 @@
#/** @file #/** @file
# #
# Copyright (c) 2017-2021, Arm Limited. All rights reserved.<BR> # Copyright (c) 2017-2018, Arm Limited. All rights reserved.
# #
# SPDX-License-Identifier: BSD-2-Clause-Patent # SPDX-License-Identifier: BSD-2-Clause-Patent
# #
@@ -18,16 +18,11 @@
ENTRY_POINT = ArmScmiDxeEntryPoint ENTRY_POINT = ArmScmiDxeEntryPoint
[Sources.common] [Sources.common]
ArmScmiBaseProtocolPrivate.h
ArmScmiClockProtocolPrivate.h
ArmScmiPerformanceProtocolPrivate.h
ScmiBaseProtocol.c
Scmi.c Scmi.c
ScmiBaseProtocol.c
ScmiClockProtocol.c ScmiClockProtocol.c
ScmiDxe.c ScmiDxe.c
ScmiDxe.h
ScmiPerformanceProtocol.c ScmiPerformanceProtocol.c
ScmiPrivate.h
[Packages] [Packages]
ArmPkg/ArmPkg.dec ArmPkg/ArmPkg.dec

View File

@@ -1,6 +1,6 @@
/** @file /** @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 SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -22,7 +22,7 @@
#define NUM_REMAIN_PERF_LEVELS_SHIFT 16 #define NUM_REMAIN_PERF_LEVELS_SHIFT 16
#define NUM_REMAIN_PERF_LEVELS(Lvls) (Lvls >> NUM_REMAIN_PERF_LEVELS_SHIFT) #define NUM_REMAIN_PERF_LEVELS(Lvls) (Lvls >> NUM_REMAIN_PERF_LEVELS_SHIFT)
/** Return values for ScmiMessageIdPerformanceDescribeLevels command. /** Return values for SCMI_MESSAGE_ID_PERFORMANCE_DESCRIBE_LEVELS command.
SCMI Spec section 4.5.2.5 SCMI Spec section 4.5.2.5
**/ **/
typedef struct { typedef struct {
@@ -43,7 +43,7 @@ typedef struct {
**/ **/
EFI_STATUS EFI_STATUS
ScmiPerformanceProtocolInit ( ScmiPerformanceProtocolInit (
IN EFI_HANDLE *Handle IN EFI_HANDLE* Handle
); );
#endif /* ARM_SCMI_PERFORMANCE_PROTOCOL_PRIVATE_H_ */ #endif /* ARM_SCMI_PERFORMANCE_PROTOCOL_PRIVATE_H_ */

View File

@@ -1,6 +1,6 @@
/** @file /** @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 SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -29,7 +29,7 @@
**/ **/
EFI_STATUS EFI_STATUS
ScmiCommandGetPayload ( ScmiCommandGetPayload (
OUT UINT32 **Payload OUT UINT32** Payload
) )
{ {
EFI_STATUS Status; EFI_STATUS Status;
@@ -95,7 +95,7 @@ ScmiCommandExecute (
// Fill in message header. // Fill in message header.
MessageHeader = SCMI_MESSAGE_HEADER ( MessageHeader = SCMI_MESSAGE_HEADER (
Command->MessageId, Command->MessageId,
ScmiMessageTypeCommand, SCMI_MESSAGE_TYPE_COMMAND,
Command->ProtocolId Command->ProtocolId
); );
@@ -121,12 +121,10 @@ ScmiCommandExecute (
return EFI_DEVICE_ERROR; return EFI_DEVICE_ERROR;
} }
Response = (SCMI_MESSAGE_RESPONSE *)MtlGetChannelPayload (Channel); Response = (SCMI_MESSAGE_RESPONSE*)MtlGetChannelPayload (Channel);
if (Response->Status != ScmiSuccess) { if (Response->Status != SCMI_SUCCESS) {
DEBUG (( DEBUG ((DEBUG_ERROR, "SCMI error: ProtocolId = 0x%x, MessageId = 0x%x, error = %d\n",
DEBUG_ERROR,
"SCMI error: ProtocolId = 0x%x, MessageId = 0x%x, error = %d\n",
Command->ProtocolId, Command->ProtocolId,
Command->MessageId, Command->MessageId,
Response->Status Response->Status
@@ -145,8 +143,8 @@ ScmiCommandExecute (
/** Internal common function useful for common protocol discovery messages. /** Internal common function useful for common protocol discovery messages.
@param[in] ProtocolId Protocol Id of the protocol. @param[in] ProtocolId Protocol Id of the the protocol.
@param[in] MessageId Message Id of the message. @param[in] MesaageId Message Id of the message.
@param[out] ReturnValues SCMI response return values. @param[out] ReturnValues SCMI response return values.
@@ -163,9 +161,8 @@ ScmiProtocolDiscoveryCommon (
) )
{ {
SCMI_COMMAND Command; SCMI_COMMAND Command;
UINT32 PayloadLength; UINT32 PayloadLength = 0;
PayloadLength = 0;
Command.ProtocolId = ProtocolId; Command.ProtocolId = ProtocolId;
Command.MessageId = MessageId; Command.MessageId = MessageId;
@@ -197,8 +194,8 @@ ScmiGetProtocolVersion (
Status = ScmiProtocolDiscoveryCommon ( Status = ScmiProtocolDiscoveryCommon (
ProtocolId, ProtocolId,
ScmiMessageIdProtocolVersion, SCMI_MESSAGE_ID_PROTOCOL_VERSION,
(UINT32 **)&ProtocolVersion (UINT32**)&ProtocolVersion
); );
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
return Status; return Status;
@@ -226,7 +223,7 @@ ScmiGetProtocolAttributes (
{ {
return ScmiProtocolDiscoveryCommon ( return ScmiProtocolDiscoveryCommon (
ProtocolId, ProtocolId,
ScmiMessageIdProtocolAttributes, SCMI_MESSAGE_ID_PROTOCOL_ATTRIBUTES,
ReturnValues ReturnValues
); );
} }
@@ -248,7 +245,7 @@ ScmiGetProtocolMessageAttributes (
{ {
return ScmiProtocolDiscoveryCommon ( return ScmiProtocolDiscoveryCommon (
ProtocolId, ProtocolId,
ScmiMessageIdProtocolMessageAttributes, SCMI_MESSAGE_ID_PROTOCOL_MESSAGE_ATTRIBUTES,
ReturnValues ReturnValues
); );
} }

View File

@@ -1,6 +1,6 @@
/** @file /** @file
Copyright (c) 2017-2021, Arm Limited. All rights reserved.<BR> Copyright (c) 2017-2018, Arm Limited. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -34,7 +34,7 @@ BaseGetVersion (
OUT UINT32 *Version OUT UINT32 *Version
) )
{ {
return ScmiGetProtocolVersion (ScmiProtocolIdBase, Version); return ScmiGetProtocolVersion (SCMI_PROTOCOL_ID_BASE, Version);
} }
/** Return total number of SCMI protocols supported by the SCP firmware. /** Return total number of SCMI protocols supported by the SCP firmware.
@@ -57,7 +57,7 @@ BaseGetTotalProtocols (
EFI_STATUS Status; EFI_STATUS Status;
UINT32 *ReturnValues; UINT32 *ReturnValues;
Status = ScmiGetProtocolAttributes (ScmiProtocolIdBase, &ReturnValues); Status = ScmiGetProtocolAttributes (SCMI_PROTOCOL_ID_BASE, &ReturnValues);
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
return Status; return Status;
} }
@@ -69,9 +69,9 @@ BaseGetTotalProtocols (
/** Common function which returns vendor details. /** Common function which returns vendor details.
@param[in] MessageId ScmiMessageIdBaseDiscoverVendor @param[in] MessageId SCMI_MESSAGE_ID_BASE_DISCOVER_VENDOR
OR OR
ScmiMessageIdBaseDiscoverSubVendor SCMI_MESSAGE_ID_BASE_DISCOVER_SUB_VENDOR
@param[out] VendorIdentifier ASCII name of the vendor/subvendor. @param[out] VendorIdentifier ASCII name of the vendor/subvendor.
@@ -91,7 +91,7 @@ BaseDiscoverVendorDetails (
SCMI_COMMAND Cmd; SCMI_COMMAND Cmd;
UINT32 PayloadLength; UINT32 PayloadLength;
Cmd.ProtocolId = ScmiProtocolIdBase; Cmd.ProtocolId = SCMI_PROTOCOL_ID_BASE;
Cmd.MessageId = MessageId; Cmd.MessageId = MessageId;
PayloadLength = 0; PayloadLength = 0;
@@ -106,9 +106,9 @@ BaseDiscoverVendorDetails (
} }
AsciiStrCpyS ( AsciiStrCpyS (
(CHAR8 *)VendorIdentifier, (CHAR8*)VendorIdentifier,
SCMI_MAX_STR_LEN, SCMI_MAX_STR_LEN,
(CONST CHAR8 *)ReturnValues (CONST CHAR8*)ReturnValues
); );
return EFI_SUCCESS; return EFI_SUCCESS;
@@ -133,7 +133,7 @@ BaseDiscoverVendor (
) )
{ {
return BaseDiscoverVendorDetails ( return BaseDiscoverVendorDetails (
ScmiMessageIdBaseDiscoverVendor, SCMI_MESSAGE_ID_BASE_DISCOVER_VENDOR,
VendorIdentifier VendorIdentifier
); );
} }
@@ -156,7 +156,7 @@ BaseDiscoverSubVendor (
) )
{ {
return BaseDiscoverVendorDetails ( return BaseDiscoverVendorDetails (
ScmiMessageIdBaseDiscoverSubVendor, SCMI_MESSAGE_ID_BASE_DISCOVER_SUB_VENDOR,
VendorIdentifier VendorIdentifier
); );
} }
@@ -183,8 +183,8 @@ BaseDiscoverImplVersion (
SCMI_COMMAND Cmd; SCMI_COMMAND Cmd;
UINT32 PayloadLength; UINT32 PayloadLength;
Cmd.ProtocolId = ScmiProtocolIdBase; Cmd.ProtocolId = SCMI_PROTOCOL_ID_BASE;
Cmd.MessageId = ScmiMessageIdBaseDiscoverImplementationVersion; Cmd.MessageId = SCMI_MESSAGE_ID_BASE_DISCOVER_IMPLEMENTATION_VERSION;
PayloadLength = 0; PayloadLength = 0;
@@ -250,12 +250,13 @@ BaseDiscoverListProtocols (
return EFI_BUFFER_TOO_SMALL; return EFI_BUFFER_TOO_SMALL;
} }
Cmd.ProtocolId = ScmiProtocolIdBase; Cmd.ProtocolId = SCMI_PROTOCOL_ID_BASE;
Cmd.MessageId = ScmiMessageIdBaseDiscoverListProtocols; Cmd.MessageId = SCMI_MESSAGE_ID_BASE_DISCOVER_LIST_PROTOCOLS;
Skip = 0; Skip = 0;
while (Skip < TotalProtocols) { while (Skip < TotalProtocols) {
*MessageParams = Skip; *MessageParams = Skip;
// Note PayloadLength is a IN/OUT parameter. // Note PayloadLength is a IN/OUT parameter.
@@ -264,7 +265,7 @@ BaseDiscoverListProtocols (
Status = ScmiCommandExecute ( Status = ScmiCommandExecute (
&Cmd, &Cmd,
&PayloadLength, &PayloadLength,
(UINT32 **)&DiscoverList (UINT32**)&DiscoverList
); );
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
return Status; return Status;
@@ -299,7 +300,7 @@ STATIC CONST SCMI_BASE_PROTOCOL BaseProtocol = {
**/ **/
EFI_STATUS EFI_STATUS
ScmiBaseProtocolInit ( ScmiBaseProtocolInit (
IN OUT EFI_HANDLE *Handle IN OUT EFI_HANDLE* Handle
) )
{ {
return gBS->InstallMultipleProtocolInterfaces ( return gBS->InstallMultipleProtocolInterfaces (

View File

@@ -1,6 +1,6 @@
/** @file /** @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 SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -52,7 +52,7 @@ ClockGetVersion (
OUT UINT32 *Version OUT UINT32 *Version
) )
{ {
return ScmiGetProtocolVersion (ScmiProtocolIdClock, Version); return ScmiGetProtocolVersion (SCMI_PROTOCOL_ID_CLOCK, Version);
} }
/** Return total number of clock devices supported by the clock management /** Return total number of clock devices supported by the clock management
@@ -76,7 +76,7 @@ ClockGetTotalClocks (
EFI_STATUS Status; EFI_STATUS Status;
UINT32 *ReturnValues; UINT32 *ReturnValues;
Status = ScmiGetProtocolAttributes (ScmiProtocolIdClock, &ReturnValues); Status = ScmiGetProtocolAttributes (SCMI_PROTOCOL_ID_CLOCK, &ReturnValues);
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
return Status; return Status;
} }
@@ -122,27 +122,26 @@ ClockGetClockAttributes (
*MessageParams = ClockId; *MessageParams = ClockId;
Cmd.ProtocolId = ScmiProtocolIdClock; Cmd.ProtocolId = SCMI_PROTOCOL_ID_CLOCK;
Cmd.MessageId = ScmiMessageIdClockAttributes; Cmd.MessageId = SCMI_MESSAGE_ID_CLOCK_ATTRIBUTES;
PayloadLength = sizeof (ClockId); PayloadLength = sizeof (ClockId);
Status = ScmiCommandExecute ( Status = ScmiCommandExecute (
&Cmd, &Cmd,
&PayloadLength, &PayloadLength,
(UINT32 **)&ClockAttributes (UINT32**)&ClockAttributes
); );
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
return Status; return Status;
} }
// TRUE if bit 0 of ClockAttributes->Attributes is set. // TRUE if bit 0 of ClockAttributes->Attributes is set.
*Enabled = CLOCK_ENABLED (ClockAttributes->Attributes); *Enabled = CLOCK_ENABLED (ClockAttributes->Attributes);
AsciiStrCpyS ( AsciiStrCpyS (
ClockAsciiName, ClockAsciiName,
SCMI_MAX_STR_LEN, SCMI_MAX_STR_LEN,
(CONST CHAR8 *)ClockAttributes->ClockName (CONST CHAR8*)ClockAttributes->ClockName
); );
return EFI_SUCCESS; return EFI_SUCCESS;
@@ -153,10 +152,10 @@ ClockGetClockAttributes (
@param[in] This A pointer to SCMI_CLOCK_PROTOCOL Instance. @param[in] This A pointer to SCMI_CLOCK_PROTOCOL Instance.
@param[in] ClockId Identifier for the clock device. @param[in] ClockId Identifier for the clock device.
@param[out] Format ScmiClockRateFormatDiscrete: Clock device @param[out] Format SCMI_CLOCK_RATE_FORMAT_DISCRETE: Clock device
supports range of clock rates which are non-linear. supports range of clock rates which are non-linear.
ScmiClockRateFormatLinear: Clock device supports SCMI_CLOCK_RATE_FORMAT_LINEAR: Clock device supports
range of linear clock rates from Min to Max in steps. range of linear clock rates from Min to Max in steps.
@param[out] TotalRates Total number of rates. @param[out] TotalRates Total number of rates.
@@ -190,26 +189,25 @@ ClockDescribeRates (
CLOCK_DESCRIBE_RATES *DescribeRates; CLOCK_DESCRIBE_RATES *DescribeRates;
CLOCK_RATE_DWORD *Rate; CLOCK_RATE_DWORD *Rate;
UINT32 RequiredArraySize; UINT32 RequiredArraySize = 0;
UINT32 RateIndex; UINT32 RateIndex = 0;
UINT32 RateNo; UINT32 RateNo;
UINT32 RateOffset; UINT32 RateOffset;
*TotalRates = 0; *TotalRates = 0;
RequiredArraySize = 0;
RateIndex = 0;
Status = ScmiCommandGetPayload (&MessageParams); Status = ScmiCommandGetPayload (&MessageParams);
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
return Status; return Status;
} }
Cmd.ProtocolId = ScmiProtocolIdClock; Cmd.ProtocolId = SCMI_PROTOCOL_ID_CLOCK;
Cmd.MessageId = ScmiMessageIdClockDescribeRates; Cmd.MessageId = SCMI_MESSAGE_ID_CLOCK_DESCRIBE_RATES;
*MessageParams++ = ClockId; *MessageParams++ = ClockId;
do { do {
*MessageParams = RateIndex; *MessageParams = RateIndex;
// Set Payload length, note PayloadLength is a IN/OUT parameter. // Set Payload length, note PayloadLength is a IN/OUT parameter.
@@ -219,7 +217,7 @@ ClockDescribeRates (
Status = ScmiCommandExecute ( Status = ScmiCommandExecute (
&Cmd, &Cmd,
&PayloadLength, &PayloadLength,
(UINT32 **)&DescribeRates (UINT32**)&DescribeRates
); );
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
return Status; return Status;
@@ -236,7 +234,12 @@ ClockDescribeRates (
*TotalRates = NUM_RATES (DescribeRates->NumRatesFlags) *TotalRates = NUM_RATES (DescribeRates->NumRatesFlags)
+ NUM_REMAIN_RATES (DescribeRates->NumRatesFlags); + NUM_REMAIN_RATES (DescribeRates->NumRatesFlags);
if (*Format == SCMI_CLOCK_RATE_FORMAT_DISCRETE) {
RequiredArraySize = (*TotalRates) * sizeof (UINT64); RequiredArraySize = (*TotalRates) * sizeof (UINT64);
} else {
// We need to return triplet of 64 bit value for each rate
RequiredArraySize = (*TotalRates) * 3 * sizeof (UINT64);
}
if (RequiredArraySize > (*RateArraySize)) { if (RequiredArraySize > (*RateArraySize)) {
*RateArraySize = RequiredArraySize; *RateArraySize = RequiredArraySize;
@@ -246,29 +249,27 @@ ClockDescribeRates (
RateOffset = 0; RateOffset = 0;
if (*Format == ScmiClockRateFormatDiscrete) { if (*Format == SCMI_CLOCK_RATE_FORMAT_DISCRETE) {
for (RateNo = 0; RateNo < NUM_RATES (DescribeRates->NumRatesFlags); RateNo++) { for (RateNo = 0; RateNo < NUM_RATES (DescribeRates->NumRatesFlags); RateNo++) {
Rate = &DescribeRates->Rates[RateOffset++]; Rate = &DescribeRates->Rates[RateOffset++];
// Non-linear discrete rates. // Non-linear discrete rates.
RateArray[RateIndex++].DiscreteRate.Rate = RateArray[RateIndex++].Rate = ConvertTo64Bit (Rate->Low, Rate->High);
ConvertTo64Bit (Rate->Low, Rate->High);
} }
} else { } else {
for (RateNo = 0; RateNo < NUM_RATES (DescribeRates->NumRatesFlags); RateNo++) {
// Linear clock rates from minimum to maximum in steps // Linear clock rates from minimum to maximum in steps
// Minimum clock rate. // Minimum clock rate.
Rate = &DescribeRates->Rates[RateOffset++]; Rate = &DescribeRates->Rates[RateOffset++];
RateArray[RateIndex].ContinuousRate.Min = RateArray[RateIndex].Min = ConvertTo64Bit (Rate->Low, Rate->High);
ConvertTo64Bit (Rate->Low, Rate->High);
Rate = &DescribeRates->Rates[RateOffset++]; Rate = &DescribeRates->Rates[RateOffset++];
// Maximum clock rate. // Maximum clock rate.
RateArray[RateIndex].ContinuousRate.Max = RateArray[RateIndex].Max = ConvertTo64Bit (Rate->Low, Rate->High);
ConvertTo64Bit (Rate->Low, Rate->High);
Rate = &DescribeRates->Rates[RateOffset++]; Rate = &DescribeRates->Rates[RateOffset++];
// Step. // Step.
RateArray[RateIndex++].ContinuousRate.Step = RateArray[RateIndex++].Step = ConvertTo64Bit (Rate->Low, Rate->High);
ConvertTo64Bit (Rate->Low, Rate->High); }
} }
} while (NUM_REMAIN_RATES (DescribeRates->NumRatesFlags) != 0); } while (NUM_REMAIN_RATES (DescribeRates->NumRatesFlags) != 0);
@@ -313,8 +314,8 @@ ClockRateGet (
// Fill arguments for clock protocol command. // Fill arguments for clock protocol command.
*MessageParams = ClockId; *MessageParams = ClockId;
Cmd.ProtocolId = ScmiProtocolIdClock; Cmd.ProtocolId = SCMI_PROTOCOL_ID_CLOCK;
Cmd.MessageId = ScmiMessageIdClockRateGet; Cmd.MessageId = SCMI_MESSAGE_ID_CLOCK_RATE_GET;
PayloadLength = sizeof (ClockId); PayloadLength = sizeof (ClockId);
@@ -322,7 +323,7 @@ ClockRateGet (
Status = ScmiCommandExecute ( Status = ScmiCommandExecute (
&Cmd, &Cmd,
&PayloadLength, &PayloadLength,
(UINT32 **)&ClockRate (UINT32**)&ClockRate
); );
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
return Status; return Status;
@@ -356,7 +357,7 @@ ClockRateSet (
SCMI_COMMAND Cmd; SCMI_COMMAND Cmd;
UINT32 PayloadLength; UINT32 PayloadLength;
Status = ScmiCommandGetPayload ((UINT32 **)&ClockRateSetAttributes); Status = ScmiCommandGetPayload ((UINT32**)&ClockRateSetAttributes);
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
return Status; return Status;
} }
@@ -367,8 +368,8 @@ ClockRateSet (
ClockRateSetAttributes->Rate.Low = (UINT32)Rate; ClockRateSetAttributes->Rate.Low = (UINT32)Rate;
ClockRateSetAttributes->Rate.High = (UINT32)(Rate >> 32); ClockRateSetAttributes->Rate.High = (UINT32)(Rate >> 32);
Cmd.ProtocolId = ScmiProtocolIdClock; Cmd.ProtocolId = SCMI_PROTOCOL_ID_CLOCK;
Cmd.MessageId = ScmiMessageIdClockRateSet; Cmd.MessageId = SCMI_MESSAGE_ID_CLOCK_RATE_SET;
PayloadLength = sizeof (CLOCK_RATE_SET_ATTRIBUTES); PayloadLength = sizeof (CLOCK_RATE_SET_ATTRIBUTES);
@@ -405,7 +406,7 @@ ClockEnable (
SCMI_COMMAND Cmd; SCMI_COMMAND Cmd;
UINT32 PayloadLength; UINT32 PayloadLength;
Status = ScmiCommandGetPayload ((UINT32 **)&ClockConfigSetAttributes); Status = ScmiCommandGetPayload ((UINT32**)&ClockConfigSetAttributes);
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
return Status; return Status;
} }
@@ -414,8 +415,8 @@ ClockEnable (
ClockConfigSetAttributes->ClockId = ClockId; ClockConfigSetAttributes->ClockId = ClockId;
ClockConfigSetAttributes->Attributes = Enable ? BIT0 : 0; ClockConfigSetAttributes->Attributes = Enable ? BIT0 : 0;
Cmd.ProtocolId = ScmiProtocolIdClock; Cmd.ProtocolId = SCMI_PROTOCOL_ID_CLOCK;
Cmd.MessageId = ScmiMessageIdClockConfigSet; Cmd.MessageId = SCMI_MESSAGE_ID_CLOCK_CONFIG_SET;
PayloadLength = sizeof (CLOCK_CONFIG_SET_ATTRIBUTES); PayloadLength = sizeof (CLOCK_CONFIG_SET_ATTRIBUTES);
@@ -437,7 +438,7 @@ STATIC CONST SCMI_CLOCK_PROTOCOL ScmiClockProtocol = {
ClockDescribeRates, ClockDescribeRates,
ClockRateGet, ClockRateGet,
ClockRateSet ClockRateSet
}; };
// Instance of the SCMI clock management protocol. // Instance of the SCMI clock management protocol.
STATIC CONST SCMI_CLOCK2_PROTOCOL ScmiClock2Protocol = { STATIC CONST SCMI_CLOCK2_PROTOCOL ScmiClock2Protocol = {
@@ -449,7 +450,7 @@ STATIC CONST SCMI_CLOCK2_PROTOCOL ScmiClock2Protocol = {
(SCMI_CLOCK2_RATE_SET)ClockRateSet, (SCMI_CLOCK2_RATE_SET)ClockRateSet,
SCMI_CLOCK2_PROTOCOL_VERSION, SCMI_CLOCK2_PROTOCOL_VERSION,
ClockEnable ClockEnable
}; };
/** Initialize clock management protocol and install protocol on a given handle. /** Initialize clock management protocol and install protocol on a given handle.
@@ -459,7 +460,7 @@ STATIC CONST SCMI_CLOCK2_PROTOCOL ScmiClock2Protocol = {
**/ **/
EFI_STATUS EFI_STATUS
ScmiClockProtocolInit ( ScmiClockProtocolInit (
IN EFI_HANDLE *Handle IN EFI_HANDLE* Handle
) )
{ {
return gBS->InstallMultipleProtocolInterfaces ( return gBS->InstallMultipleProtocolInterfaces (

View File

@@ -1,12 +1,12 @@
/** @file /** @file
Copyright (c) 2017-2021, Arm Limited. All rights reserved.<BR> Copyright (c) 2017-2018, Arm Limited. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent SPDX-License-Identifier: BSD-2-Clause-Patent
@par Specification Reference: System Control and Management Interface V1.0
- Arm System Control and Management Interface - Platform Design Document http://infocenter.arm.com/help/topic/com.arm.doc.den0056a/
(https://developer.arm.com/documentation/den0056/) DEN0056A_System_Control_and_Management_Interface.pdf
**/ **/
#include <Base.h> #include <Base.h>
@@ -24,9 +24,9 @@
#include "ScmiPrivate.h" #include "ScmiPrivate.h"
STATIC CONST SCMI_PROTOCOL_ENTRY Protocols[] = { STATIC CONST SCMI_PROTOCOL_ENTRY Protocols[] = {
{ ScmiProtocolIdBase, ScmiBaseProtocolInit }, { SCMI_PROTOCOL_ID_BASE, ScmiBaseProtocolInit },
{ ScmiProtocolIdPerformance, ScmiPerformanceProtocolInit }, { SCMI_PROTOCOL_ID_PERFORMANCE, ScmiPerformanceProtocolInit },
{ ScmiProtocolIdClock, ScmiClockProtocolInit } { SCMI_PROTOCOL_ID_CLOCK, ScmiClockProtocolInit }
}; };
/** ARM SCMI driver entry point function. /** ARM SCMI driver entry point function.
@@ -61,7 +61,7 @@ ArmScmiDxeEntryPoint (
UINT32 SupportedListSize; UINT32 SupportedListSize;
// Every SCMI implementation must implement the base protocol. // Every SCMI implementation must implement the base protocol.
ASSERT (Protocols[0].Id == ScmiProtocolIdBase); ASSERT (Protocols[0].Id == SCMI_PROTOCOL_ID_BASE);
Status = ScmiBaseProtocolInit (&ImageHandle); Status = ScmiBaseProtocolInit (&ImageHandle);
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
@@ -72,7 +72,7 @@ ArmScmiDxeEntryPoint (
Status = gBS->LocateProtocol ( Status = gBS->LocateProtocol (
&gArmScmiBaseProtocolGuid, &gArmScmiBaseProtocolGuid,
NULL, NULL,
(VOID **)&BaseProtocol (VOID**)&BaseProtocol
); );
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
ASSERT (FALSE); ASSERT (FALSE);
@@ -86,10 +86,7 @@ ArmScmiDxeEntryPoint (
return Status; return Status;
} }
// Accept any version between SCMI v1.0 and SCMI v2.0 if (Version != BASE_PROTOCOL_VERSION) {
if ((Version < BASE_PROTOCOL_VERSION_V1) ||
(Version > BASE_PROTOCOL_VERSION_V2))
{
ASSERT (FALSE); ASSERT (FALSE);
return EFI_UNSUPPORTED; return EFI_UNSUPPORTED;
} }
@@ -110,7 +107,7 @@ ArmScmiDxeEntryPoint (
Status = gBS->AllocatePool ( Status = gBS->AllocatePool (
EfiBootServicesData, EfiBootServicesData,
SupportedListSize, SupportedListSize,
(VOID **)&SupportedList (VOID**)&SupportedList
); );
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
ASSERT (FALSE); ASSERT (FALSE);
@@ -131,8 +128,7 @@ ArmScmiDxeEntryPoint (
// Install supported protocol on ImageHandle. // Install supported protocol on ImageHandle.
for (ProtocolIndex = 1; ProtocolIndex < ARRAY_SIZE (Protocols); for (ProtocolIndex = 1; ProtocolIndex < ARRAY_SIZE (Protocols);
ProtocolIndex++) ProtocolIndex++) {
{
for (Index = 0; Index < NumProtocols; Index++) { for (Index = 0; Index < NumProtocols; Index++) {
if (Protocols[ProtocolIndex].Id == SupportedList[Index]) { if (Protocols[ProtocolIndex].Id == SupportedList[Index]) {
Status = Protocols[ProtocolIndex].InitFn (&ImageHandle); Status = Protocols[ProtocolIndex].InitFn (&ImageHandle);
@@ -140,7 +136,6 @@ ArmScmiDxeEntryPoint (
ASSERT_EFI_ERROR (Status); ASSERT_EFI_ERROR (Status);
return Status; return Status;
} }
break; break;
} }
} }

View File

@@ -8,7 +8,6 @@
http://infocenter.arm.com/help/topic/com.arm.doc.den0056a/ http://infocenter.arm.com/help/topic/com.arm.doc.den0056a/
DEN0056A_System_Control_and_Management_Interface.pdf DEN0056A_System_Control_and_Management_Interface.pdf
**/ **/
#ifndef SCMI_DXE_H_ #ifndef SCMI_DXE_H_
#define SCMI_DXE_H_ #define SCMI_DXE_H_

View File

@@ -1,12 +1,12 @@
/** @file /** @file
Copyright (c) 2017-2023, Arm Limited. All rights reserved.<BR> Copyright (c) 2017-2018, Arm Limited. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent SPDX-License-Identifier: BSD-2-Clause-Patent
System Control and Management Interface V3.2, latest version at: System Control and Management Interface V1.0
- https://developer.arm.com/documentation/den0056/latest/ http://infocenter.arm.com/help/topic/com.arm.doc.den0056a/
DEN0056A_System_Control_and_Management_Interface.pdf
**/ **/
#include <Library/BaseMemoryLib.h> #include <Library/BaseMemoryLib.h>
@@ -35,7 +35,7 @@ PerformanceGetVersion (
OUT UINT32 *Version OUT UINT32 *Version
) )
{ {
return ScmiGetProtocolVersion (ScmiProtocolIdPerformance, Version); return ScmiGetProtocolVersion (SCMI_PROTOCOL_ID_PERFORMANCE, Version);
} }
/** Return protocol attributes of the performance management protocol. /** Return protocol attributes of the performance management protocol.
@@ -56,10 +56,10 @@ PerformanceGetAttributes (
) )
{ {
EFI_STATUS Status; EFI_STATUS Status;
UINT32 *ReturnValues; UINT32* ReturnValues;
Status = ScmiGetProtocolAttributes ( Status = ScmiGetProtocolAttributes (
ScmiProtocolIdPerformance, SCMI_PROTOCOL_ID_PERFORMANCE,
&ReturnValues &ReturnValues
); );
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
@@ -107,8 +107,8 @@ PerformanceDomainAttributes (
*MessageParams = DomainId; *MessageParams = DomainId;
Cmd.ProtocolId = ScmiProtocolIdPerformance; Cmd.ProtocolId = SCMI_PROTOCOL_ID_PERFORMANCE;
Cmd.MessageId = ScmiMessageIdPerformanceDomainAttributes; Cmd.MessageId = SCMI_MESSAGE_ID_PERFORMANCE_DOMAIN_ATTRIBUTES;
PayloadLength = sizeof (DomainId); PayloadLength = sizeof (DomainId);
@@ -160,7 +160,7 @@ PerformanceDescribeLevels (
EFI_STATUS Status; EFI_STATUS Status;
UINT32 PayloadLength; UINT32 PayloadLength;
SCMI_COMMAND Cmd; SCMI_COMMAND Cmd;
UINT32 *MessageParams; UINT32* MessageParams;
UINT32 LevelIndex; UINT32 LevelIndex;
UINT32 RequiredSize; UINT32 RequiredSize;
UINT32 LevelNo; UINT32 LevelNo;
@@ -179,10 +179,11 @@ PerformanceDescribeLevels (
*MessageParams++ = DomainId; *MessageParams++ = DomainId;
Cmd.ProtocolId = ScmiProtocolIdPerformance; Cmd.ProtocolId = SCMI_PROTOCOL_ID_PERFORMANCE;
Cmd.MessageId = ScmiMessageIdPerformanceDescribeLevels; Cmd.MessageId = SCMI_MESSAGE_ID_PERFORMANCE_DESCRIBE_LEVELS;
do { do {
*MessageParams = LevelIndex; *MessageParams = LevelIndex;
// Note, PayloadLength is an IN/OUT parameter. // Note, PayloadLength is an IN/OUT parameter.
@@ -191,7 +192,7 @@ PerformanceDescribeLevels (
Status = ScmiCommandExecute ( Status = ScmiCommandExecute (
&Cmd, &Cmd,
&PayloadLength, &PayloadLength,
(UINT32 **)&Levels (UINT32**)&Levels
); );
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
return Status; return Status;
@@ -218,6 +219,7 @@ PerformanceDescribeLevels (
sizeof (SCMI_PERFORMANCE_LEVEL) sizeof (SCMI_PERFORMANCE_LEVEL)
); );
} }
} while (ReturnRemainNumLevels != 0); } while (ReturnRemainNumLevels != 0);
*LevelArraySize = RequiredSize; *LevelArraySize = RequiredSize;
@@ -256,8 +258,8 @@ PerformanceLimitsSet (
*MessageParams++ = Limits->RangeMax; *MessageParams++ = Limits->RangeMax;
*MessageParams = Limits->RangeMin; *MessageParams = Limits->RangeMin;
Cmd.ProtocolId = ScmiProtocolIdPerformance; Cmd.ProtocolId = SCMI_PROTOCOL_ID_PERFORMANCE;
Cmd.MessageId = ScmiMessageIdPerformanceLimitsSet; Cmd.MessageId = SCMI_MESSAGE_ID_PERFORMANCE_LIMITS_SET;
PayloadLength = sizeof (DomainId) + sizeof (SCMI_PERFORMANCE_LIMITS); PayloadLength = sizeof (DomainId) + sizeof (SCMI_PERFORMANCE_LIMITS);
@@ -302,15 +304,15 @@ PerformanceLimitsGet (
*MessageParams = DomainId; *MessageParams = DomainId;
Cmd.ProtocolId = ScmiProtocolIdPerformance; Cmd.ProtocolId = SCMI_PROTOCOL_ID_PERFORMANCE;
Cmd.MessageId = ScmiMessageIdPerformanceLimitsGet; Cmd.MessageId = SCMI_MESSAGE_ID_PERFORMANCE_LIMITS_GET;
PayloadLength = sizeof (DomainId); PayloadLength = sizeof (DomainId);
Status = ScmiCommandExecute ( Status = ScmiCommandExecute (
&Cmd, &Cmd,
&PayloadLength, &PayloadLength,
(UINT32 **)&ReturnValues (UINT32**)&ReturnValues
); );
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
return Status; return Status;
@@ -352,8 +354,8 @@ PerformanceLevelSet (
*MessageParams++ = DomainId; *MessageParams++ = DomainId;
*MessageParams = Level; *MessageParams = Level;
Cmd.ProtocolId = ScmiProtocolIdPerformance; Cmd.ProtocolId = SCMI_PROTOCOL_ID_PERFORMANCE;
Cmd.MessageId = ScmiMessageIdPerformanceLevelSet; Cmd.MessageId = SCMI_MESSAGE_ID_PERFORMANCE_LEVEL_SET;
PayloadLength = sizeof (DomainId) + sizeof (Level); PayloadLength = sizeof (DomainId) + sizeof (Level);
@@ -397,8 +399,8 @@ PerformanceLevelGet (
*MessageParams = DomainId; *MessageParams = DomainId;
Cmd.ProtocolId = ScmiProtocolIdPerformance; Cmd.ProtocolId = SCMI_PROTOCOL_ID_PERFORMANCE;
Cmd.MessageId = ScmiMessageIdPerformanceLevelGet; Cmd.MessageId = SCMI_MESSAGE_ID_PERFORMANCE_LEVEL_GET;
PayloadLength = sizeof (DomainId); PayloadLength = sizeof (DomainId);
@@ -416,75 +418,6 @@ PerformanceLevelGet (
return EFI_SUCCESS; return EFI_SUCCESS;
} }
/** Discover the attributes of the FastChannel for the specified
performance domain and the specified message.
@param[in] This A Pointer to SCMI_PERFORMANCE_PROTOCOL Instance.
@param[in] DomainId Identifier for the performance domain.
@param[in] MessageId Message Id of the FastChannel to discover.
Must be one of:
- PERFORMANCE_LIMITS_SET
- PERFORMANCE_LIMITS_GET
- PERFORMANCE_LEVEL_SET
- PERFORMANCE_LEVEL_GET
@param[out] FastChannel If success, contains the FastChannel description.
@retval EFI_SUCCESS Performance level got successfully.
@retval EFI_DEVICE_ERROR SCP returns an SCMI error.
@retval EFI_INVALID_PARAMETER Invalid parameter.
@retval EFI_TIMEOUT Time out.
@retval EFI_UNSUPPORTED Unsupported.
**/
EFI_STATUS
DescribeFastchannel (
IN SCMI_PERFORMANCE_PROTOCOL *This,
IN UINT32 DomainId,
IN SCMI_MESSAGE_ID_PERFORMANCE MessageId,
OUT SCMI_PERFORMANCE_FASTCHANNEL *FastChannel
)
{
EFI_STATUS Status;
SCMI_COMMAND Cmd;
UINT32 PayloadLength;
UINT32 *ReturnValues;
UINT32 *MessageParams;
if ((This == NULL) ||
(FastChannel == NULL))
{
return EFI_INVALID_PARAMETER;
}
Status = ScmiCommandGetPayload (&MessageParams);
if (EFI_ERROR (Status)) {
return Status;
}
*MessageParams++ = DomainId;
*MessageParams = MessageId;
Cmd.ProtocolId = ScmiProtocolIdPerformance;
Cmd.MessageId = ScmiMessageIdPerformanceDescribeFastchannel;
PayloadLength = sizeof (DomainId) + sizeof (MessageId);
Status = ScmiCommandExecute (
&Cmd,
&PayloadLength,
&ReturnValues
);
if (EFI_ERROR (Status)) {
return Status;
}
CopyMem (
FastChannel,
ReturnValues,
sizeof (SCMI_PERFORMANCE_FASTCHANNEL)
);
return Status;
}
// Instance of the SCMI performance management protocol. // Instance of the SCMI performance management protocol.
STATIC CONST SCMI_PERFORMANCE_PROTOCOL PerformanceProtocol = { STATIC CONST SCMI_PERFORMANCE_PROTOCOL PerformanceProtocol = {
PerformanceGetVersion, PerformanceGetVersion,
@@ -494,8 +427,7 @@ STATIC CONST SCMI_PERFORMANCE_PROTOCOL PerformanceProtocol = {
PerformanceLimitsSet, PerformanceLimitsSet,
PerformanceLimitsGet, PerformanceLimitsGet,
PerformanceLevelSet, PerformanceLevelSet,
PerformanceLevelGet, PerformanceLevelGet
DescribeFastchannel,
}; };
/** Initialize performance management protocol and install on a given Handle. /** Initialize performance management protocol and install on a given Handle.
@@ -507,7 +439,7 @@ STATIC CONST SCMI_PERFORMANCE_PROTOCOL PerformanceProtocol = {
**/ **/
EFI_STATUS EFI_STATUS
ScmiPerformanceProtocolInit ( ScmiPerformanceProtocolInit (
IN EFI_HANDLE *Handle IN EFI_HANDLE* Handle
) )
{ {
return gBS->InstallMultipleProtocolInterfaces ( return gBS->InstallMultipleProtocolInterfaces (

View File

@@ -1,6 +1,6 @@
/** @file /** @file
Copyright (c) 2017-2021, Arm Limited. All rights reserved.<BR> Copyright (c) 2017-2018, Arm Limited. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -8,47 +8,46 @@
http://infocenter.arm.com/help/topic/com.arm.doc.den0056a/ http://infocenter.arm.com/help/topic/com.arm.doc.den0056a/
DEN0056A_System_Control_and_Management_Interface.pdf DEN0056A_System_Control_and_Management_Interface.pdf
**/ **/
#ifndef SCMI_PRIVATE_H_ #ifndef SCMI_PRIVATE_H_
#define SCMI_PRIVATE_H_ #define SCMI_PRIVATE_H_
// SCMI protocol IDs. // SCMI protocol IDs.
typedef enum { typedef enum {
ScmiProtocolIdBase = 0x10, SCMI_PROTOCOL_ID_BASE = 0x10,
ScmiProtocolIdPowerDomain = 0x11, SCMI_PROTOCOL_ID_POWER_DOMAIN = 0x11,
ScmiProtocolIdSystemPower = 0x12, SCMI_PROTOCOL_ID_SYSTEM_POWER = 0x12,
ScmiProtocolIdPerformance = 0x13, SCMI_PROTOCOL_ID_PERFORMANCE = 0x13,
ScmiProtocolIdClock = 0x14, SCMI_PROTOCOL_ID_CLOCK = 0x14,
ScmiProtocolIdSensor = 0x15 SCMI_PROTOCOL_ID_SENSOR = 0x15
} SCMI_PROTOCOL_ID; } SCMI_PROTOCOL_ID;
// SCMI message types. // SCMI message types.
typedef enum { typedef enum {
ScmiMessageTypeCommand = 0, SCMI_MESSAGE_TYPE_COMMAND = 0,
ScmiMessageTypeDelayedResponse = 2, // Skipping 1 is deliberate. SCMI_MESSAGE_TYPE_DELAYED_RESPONSE = 2, // Skipping 1 is deliberate.
ScmiMessageTypeNotification = 3 SCMI_MESSAGE_TYPE_NOTIFICATION = 3
} SCMI_MESSAGE_TYPE; } SCMI_MESSAGE_TYPE;
// SCMI response error codes. // SCMI response error codes.
typedef enum { typedef enum {
ScmiSuccess = 0, SCMI_SUCCESS = 0,
ScmiNotSupported = -1, SCMI_NOT_SUPPORTED = -1,
ScmiInvalidParameters = -2, SCMI_INVALID_PARAMETERS = -2,
ScmiDenied = -3, SCMI_DENIED = -3,
ScmiNotFound = -4, SCMI_NOT_FOUND = -4,
ScmiOutOfRange = -5, SCMI_OUT_OF_RANGE = -5,
ScmiBusy = -6, SCMI_BUSY = -6,
ScmiCommsError = -7, SCMI_COMMS_ERROR = -7,
ScmiGenericError = -8, SCMI_GENERIC_ERROR = -8,
ScmiHardwareError = -9, SCMI_HARDWARE_ERROR = -9,
ScmiProtocolError = -10 SCMI_PROTOCOL_ERROR = -10
} SCMI_STATUS; } SCMI_STATUS;
// SCMI message IDs common to all protocols. // SCMI message IDs common to all protocols.
typedef enum { typedef enum {
ScmiMessageIdProtocolVersion = 0x0, SCMI_MESSAGE_ID_PROTOCOL_VERSION = 0x0,
ScmiMessageIdProtocolAttributes = 0x1, SCMI_MESSAGE_ID_PROTOCOL_ATTRIBUTES = 0x1,
ScmiMessageIdProtocolMessageAttributes = 0x2 SCMI_MESSAGE_ID_PROTOCOL_MESSAGE_ATTRIBUTES = 0x2
} SCMI_MESSAGE_ID; } SCMI_MESSAGE_ID;
// Not defined in SCMI specification but will help to identify a message. // Not defined in SCMI specification but will help to identify a message.
@@ -90,7 +89,7 @@ typedef struct {
**/ **/
EFI_STATUS EFI_STATUS
ScmiCommandGetPayload ( ScmiCommandGetPayload (
OUT UINT32 **Payload OUT UINT32** Payload
); );
/** Execute a SCMI command and receive a response. /** Execute a SCMI command and receive a response.

View File

@@ -2,7 +2,7 @@
Copyright (c) 2009, Hewlett-Packard Company. All rights reserved.<BR> Copyright (c) 2009, Hewlett-Packard Company. All rights reserved.<BR>
Portions copyright (c) 2010, Apple Inc. 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> Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -13,116 +13,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include <Library/MemoryAllocationLib.h> #include <Library/MemoryAllocationLib.h>
#include "CpuDxe.h" #include "CpuDxe.h"
#define INVALID_ENTRY ((UINT64)~0) #define TT_ATTR_INDX_INVALID ((UINT32)~0)
#define MIN_T0SZ 16
#define BITS_PER_LEVEL 9
/**
Parses T0SZ to determine the level and number of entries at the root
of the translation table.
@param T0SZ The T0SZ value to be parsed.
@param RootTableLevel The level of the root table.
@param RootTableEntryCount The number of entries in the root table.
**/
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;
}
/**
Converts ARM translation table attributes to GCD attributes.
@param PageAttributes The translation table attributes to be converted.
@retval The analogous GCD attributes.
**/
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_AF) == 0) {
GcdAttributes |= EFI_MEMORY_RP;
}
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;
}
/**
Convert an arch specific set of page attributes into a mask
of EFI_MEMORY_xx constants.
@param PageAttributes The set of page attributes.
@retval The mask of EFI_MEMORY_xx constants.
**/
UINT64
RegionAttributeToGcdAttribute (
IN UINTN PageAttributes
)
{
return PageAttributeToGcdAttribute (PageAttributes);
}
/**
Retrieves the attribute of the first page entry in the translation table.
@param[in] FirstLevelTableAddress The base address of the translation table.
@param[in] TableLevel The current level being traversed.
@retval The attributes of the first page entry found, or INVALID_ENTRY.
**/
STATIC STATIC
UINT64 UINT64
GetFirstPageAttribute ( GetFirstPageAttribute (
@@ -135,33 +27,20 @@ GetFirstPageAttribute (
// Get the first entry of the table // Get the first entry of the table
FirstEntry = *FirstLevelTableAddress; FirstEntry = *FirstLevelTableAddress;
if ((TableLevel != 3) && ((FirstEntry & TT_TYPE_MASK) == TT_TYPE_TABLE_ENTRY)) { if ((TableLevel != 3) && (FirstEntry & TT_TYPE_MASK) == TT_TYPE_TABLE_ENTRY) {
// Only valid for Levels 0, 1 and 2 // Only valid for Levels 0, 1 and 2
// Get the attribute of the subsequent table // Get the attribute of the subsequent table
return GetFirstPageAttribute ((UINT64 *)(FirstEntry & TT_ADDRESS_MASK_DESCRIPTION_TABLE), TableLevel + 1); return GetFirstPageAttribute ((UINT64*)(FirstEntry & TT_ADDRESS_MASK_DESCRIPTION_TABLE), TableLevel + 1);
} else if (((FirstEntry & TT_TYPE_MASK) == TT_TYPE_BLOCK_ENTRY) || } else if (((FirstEntry & TT_TYPE_MASK) == TT_TYPE_BLOCK_ENTRY) ||
((TableLevel == 3) && ((FirstEntry & TT_TYPE_MASK) == TT_TYPE_BLOCK_ENTRY_LEVEL3))) ((TableLevel == 3) && ((FirstEntry & TT_TYPE_MASK) == TT_TYPE_BLOCK_ENTRY_LEVEL3)))
{ {
return FirstEntry & TT_ATTRIBUTES_MASK; return FirstEntry & TT_ATTR_INDX_MASK;
} else { } else {
return INVALID_ENTRY; return TT_ATTR_INDX_INVALID;
} }
} }
/**
This function recursively traverses the translation table heirarchy to
synchronise the GCD with the translation table.
@param[in] TableAddress The address of the table being processed.
@param[in] EntryCount The number of entries in the current level of the table.
@param[in] TableLevel The current level of the memory table being processed.
@param[in] BaseAddress The starting address of the region.
@param[in, out] PrevEntryAttribute The attributes of the previous region.
@param[in, out] StartGcdRegion The start of the GCD region.
@retval The address at the end of the last region processed.
**/
STATIC STATIC
UINT64 UINT64
GetNextEntryAttribute ( GetNextEntryAttribute (
@@ -169,14 +48,14 @@ GetNextEntryAttribute (
IN UINTN EntryCount, IN UINTN EntryCount,
IN UINTN TableLevel, IN UINTN TableLevel,
IN UINT64 BaseAddress, IN UINT64 BaseAddress,
IN OUT UINT64 *PrevEntryAttribute, IN OUT UINT32 *PrevEntryAttribute,
IN OUT UINT64 *StartGcdRegion IN OUT UINT64 *StartGcdRegion
) )
{ {
UINTN Index; UINTN Index;
UINT64 Entry; UINT64 Entry;
UINT64 EntryAttribute; UINT32 EntryAttribute;
UINT64 EntryType; UINT32 EntryType;
EFI_STATUS Status; EFI_STATUS Status;
UINTN NumberOfDescriptors; UINTN NumberOfDescriptors;
EFI_GCD_MEMORY_SPACE_DESCRIPTOR *MemorySpaceMap; EFI_GCD_MEMORY_SPACE_DESCRIPTOR *MemorySpaceMap;
@@ -184,38 +63,32 @@ GetNextEntryAttribute (
// Get the memory space map from GCD // Get the memory space map from GCD
MemorySpaceMap = NULL; MemorySpaceMap = NULL;
Status = gDS->GetMemorySpaceMap (&NumberOfDescriptors, &MemorySpaceMap); Status = gDS->GetMemorySpaceMap (&NumberOfDescriptors, &MemorySpaceMap);
if (EFI_ERROR (Status) || (TableLevel > 3)) {
ASSERT_EFI_ERROR (Status); ASSERT_EFI_ERROR (Status);
// We cannot get more than 3-level page table
ASSERT (TableLevel <= 3); ASSERT (TableLevel <= 3);
return 0;
}
// While the top level table might not contain TT_ENTRY_COUNT entries; // While the top level table might not contain TT_ENTRY_COUNT entries;
// the subsequent ones should be filled up // the subsequent ones should be filled up
for (Index = 0; Index < EntryCount; Index++) { for (Index = 0; Index < EntryCount; Index++) {
Entry = TableAddress[Index]; Entry = TableAddress[Index];
EntryType = Entry & TT_TYPE_MASK; EntryType = Entry & TT_TYPE_MASK;
EntryAttribute = Entry & TT_ATTRIBUTES_MASK; EntryAttribute = Entry & TT_ATTR_INDX_MASK;
// If Entry is a Table Descriptor type entry then go through the sub-level table // If Entry is a Table Descriptor type entry then go through the sub-level table
if ((EntryType == TT_TYPE_BLOCK_ENTRY) || if ((EntryType == TT_TYPE_BLOCK_ENTRY) ||
((TableLevel == 3) && (EntryType == TT_TYPE_BLOCK_ENTRY_LEVEL3))) ((TableLevel == 3) && (EntryType == TT_TYPE_BLOCK_ENTRY_LEVEL3))) {
{ if ((*PrevEntryAttribute == TT_ATTR_INDX_INVALID) || (EntryAttribute != *PrevEntryAttribute)) {
if ((*PrevEntryAttribute == INVALID_ENTRY) || (EntryAttribute != *PrevEntryAttribute)) { if (*PrevEntryAttribute != TT_ATTR_INDX_INVALID) {
if (*PrevEntryAttribute != INVALID_ENTRY) {
// Update GCD with the last region // Update GCD with the last region
SetGcdMemorySpaceAttributes ( SetGcdMemorySpaceAttributes (MemorySpaceMap, NumberOfDescriptors,
MemorySpaceMap,
NumberOfDescriptors,
*StartGcdRegion, *StartGcdRegion,
(BaseAddress + (Index * TT_ADDRESS_AT_LEVEL (TableLevel))) - *StartGcdRegion, (BaseAddress + (Index * TT_ADDRESS_AT_LEVEL(TableLevel))) - *StartGcdRegion,
PageAttributeToGcdAttribute (*PrevEntryAttribute) PageAttributeToGcdAttribute (*PrevEntryAttribute));
);
} }
// Start of the new region // Start of the new region
*StartGcdRegion = BaseAddress + (Index * TT_ADDRESS_AT_LEVEL (TableLevel)); *StartGcdRegion = BaseAddress + (Index * TT_ADDRESS_AT_LEVEL(TableLevel));
*PrevEntryAttribute = EntryAttribute; *PrevEntryAttribute = EntryAttribute;
} else { } else {
continue; continue;
@@ -225,53 +98,37 @@ GetNextEntryAttribute (
ASSERT (TableLevel < 3); ASSERT (TableLevel < 3);
// Increase the level number and scan the sub-level table // Increase the level number and scan the sub-level table
GetNextEntryAttribute ( GetNextEntryAttribute ((UINT64*)(Entry & TT_ADDRESS_MASK_DESCRIPTION_TABLE),
(UINT64 *)(Entry & TT_ADDRESS_MASK_DESCRIPTION_TABLE), TT_ENTRY_COUNT, TableLevel + 1,
TT_ENTRY_COUNT, (BaseAddress + (Index * TT_ADDRESS_AT_LEVEL(TableLevel))),
TableLevel + 1, PrevEntryAttribute, StartGcdRegion);
(BaseAddress + (Index * TT_ADDRESS_AT_LEVEL (TableLevel))),
PrevEntryAttribute,
StartGcdRegion
);
} else { } else {
if (*PrevEntryAttribute != INVALID_ENTRY) { if (*PrevEntryAttribute != TT_ATTR_INDX_INVALID) {
// Update GCD with the last region // Update GCD with the last region
SetGcdMemorySpaceAttributes ( SetGcdMemorySpaceAttributes (MemorySpaceMap, NumberOfDescriptors,
MemorySpaceMap,
NumberOfDescriptors,
*StartGcdRegion, *StartGcdRegion,
(BaseAddress + (Index * TT_ADDRESS_AT_LEVEL (TableLevel))) - *StartGcdRegion, (BaseAddress + (Index * TT_ADDRESS_AT_LEVEL(TableLevel))) - *StartGcdRegion,
PageAttributeToGcdAttribute (*PrevEntryAttribute) PageAttributeToGcdAttribute (*PrevEntryAttribute));
);
// Start of the new region // Start of the new region
*StartGcdRegion = BaseAddress + (Index * TT_ADDRESS_AT_LEVEL (TableLevel)); *StartGcdRegion = BaseAddress + (Index * TT_ADDRESS_AT_LEVEL(TableLevel));
*PrevEntryAttribute = INVALID_ENTRY; *PrevEntryAttribute = TT_ATTR_INDX_INVALID;
} }
} }
} }
FreePool (MemorySpaceMap); FreePool (MemorySpaceMap);
return BaseAddress + (EntryCount * TT_ADDRESS_AT_LEVEL (TableLevel)); return BaseAddress + (EntryCount * TT_ADDRESS_AT_LEVEL(TableLevel));
} }
/**
Sync the GCD memory space attributes with the translation table.
@param[in] CpuProtocol The CPU architectural protocol instance.
@retval EFI_SUCCESS The GCD memory space attributes are synced with
the MMU page table.
@retval Others The return value of GetMemorySpaceMap().
**/
EFI_STATUS EFI_STATUS
SyncCacheConfig ( SyncCacheConfig (
IN EFI_CPU_ARCH_PROTOCOL *CpuProtocol IN EFI_CPU_ARCH_PROTOCOL *CpuProtocol
) )
{ {
EFI_STATUS Status; EFI_STATUS Status;
UINT64 PageAttribute; UINT32 PageAttribute = 0;
UINT64 *FirstLevelTableAddress; UINT64 *FirstLevelTableAddress;
UINTN TableLevel; UINTN TableLevel;
UINTN TableCount; UINTN TableCount;
@@ -290,11 +147,7 @@ SyncCacheConfig (
// //
MemorySpaceMap = NULL; MemorySpaceMap = NULL;
Status = gDS->GetMemorySpaceMap (&NumberOfDescriptors, &MemorySpaceMap); Status = gDS->GetMemorySpaceMap (&NumberOfDescriptors, &MemorySpaceMap);
if (EFI_ERROR (Status)) {
ASSERT_EFI_ERROR (Status); ASSERT_EFI_ERROR (Status);
return Status;
}
// The GCD implementation maintains its own copy of the state of memory space attributes. GCD needs // The GCD implementation maintains its own copy of the state of memory space attributes. GCD needs
// to know what the initial memory space attributes are. The CPU Arch. Protocol does not provide a // to know what the initial memory space attributes are. The CPU Arch. Protocol does not provide a
@@ -303,7 +156,7 @@ SyncCacheConfig (
// with a way for GCD to query the CPU Arch. driver of the existing memory space attributes instead. // with a way for GCD to query the CPU Arch. driver of the existing memory space attributes instead.
// Obtain page table base // Obtain page table base
FirstLevelTableAddress = (UINT64 *)(ArmGetTTBR0BaseAddress ()); FirstLevelTableAddress = (UINT64*)(ArmGetTTBR0BaseAddress ());
// Get Translation Control Register value // Get Translation Control Register value
Tcr = ArmGetTCR (); Tcr = ArmGetTCR ();
@@ -318,24 +171,17 @@ SyncCacheConfig (
// We scan from the start of the memory map (ie: at the address 0x0) // We scan from the start of the memory map (ie: at the address 0x0)
BaseAddressGcdRegion = 0x0; BaseAddressGcdRegion = 0x0;
EndAddressGcdRegion = GetNextEntryAttribute ( EndAddressGcdRegion = GetNextEntryAttribute (FirstLevelTableAddress,
FirstLevelTableAddress, TableCount, TableLevel,
TableCount,
TableLevel,
BaseAddressGcdRegion, BaseAddressGcdRegion,
&PageAttribute, &PageAttribute, &BaseAddressGcdRegion);
&BaseAddressGcdRegion
);
// Update GCD with the last region if valid // Update GCD with the last region if valid
if ((PageAttribute != INVALID_ENTRY) && (EndAddressGcdRegion > BaseAddressGcdRegion)) { if (PageAttribute != TT_ATTR_INDX_INVALID) {
SetGcdMemorySpaceAttributes ( SetGcdMemorySpaceAttributes (MemorySpaceMap, NumberOfDescriptors,
MemorySpaceMap,
NumberOfDescriptors,
BaseAddressGcdRegion, BaseAddressGcdRegion,
EndAddressGcdRegion - BaseAddressGcdRegion, EndAddressGcdRegion - BaseAddressGcdRegion,
PageAttributeToGcdAttribute (PageAttribute) PageAttributeToGcdAttribute (PageAttribute));
);
} }
FreePool (MemorySpaceMap); FreePool (MemorySpaceMap);
@@ -343,13 +189,6 @@ SyncCacheConfig (
return EFI_SUCCESS; return EFI_SUCCESS;
} }
/**
Convert EFI memory attributes to ARM translation table attributes.
@param[in] EfiAttributes EFI memory attributes.
@retval The analogous translation table attributes.
**/
UINT64 UINT64
EfiAttributeToArmAttribute ( EfiAttributeToArmAttribute (
IN UINT64 EfiAttributes IN UINT64 EfiAttributes
@@ -364,7 +203,6 @@ EfiAttributeToArmAttribute (
} else { } else {
ArmAttributes = TT_ATTR_INDX_DEVICE_MEMORY | TT_UXN_MASK | TT_PXN_MASK; ArmAttributes = TT_ATTR_INDX_DEVICE_MEMORY | TT_UXN_MASK | TT_PXN_MASK;
} }
break; break;
case EFI_MEMORY_WC: case EFI_MEMORY_WC:
ArmAttributes = TT_ATTR_INDX_MEMORY_NON_CACHEABLE; ArmAttributes = TT_ATTR_INDX_MEMORY_NON_CACHEABLE;
@@ -380,42 +218,23 @@ EfiAttributeToArmAttribute (
} }
// Set the access flag to match the block attributes // Set the access flag to match the block attributes
if ((EfiAttributes & EFI_MEMORY_RP) == 0) {
ArmAttributes |= TT_AF; ArmAttributes |= TT_AF;
}
// Determine protection attributes // Determine protection attributes
if ((EfiAttributes & EFI_MEMORY_RO) != 0) { if (EfiAttributes & EFI_MEMORY_RO) {
ArmAttributes |= TT_AP_NO_RO; ArmAttributes |= TT_AP_RO_RO;
} }
// Process eXecute Never attribute // Process eXecute Never attribute
if ((EfiAttributes & EFI_MEMORY_XP) != 0) { if (EfiAttributes & EFI_MEMORY_XP) {
ArmAttributes |= TT_PXN_MASK; ArmAttributes |= TT_PXN_MASK;
} }
return ArmAttributes; return ArmAttributes;
} }
/** // This function will recursively go down the page table to find the first block address linked to 'BaseAddress'.
This function returns the attributes of the memory region containing the // And then the function will identify the size of the region that has the same page table attribute.
specified address.
RegionLength and RegionAttributes are only valid if the result is EFI_SUCCESS.
@param[in] TranslationTable The translation table base address.
@param[in] TableLevel The level of the translation table.
@param[in] LastBlockEntry The last block address of the table level.
@param[in, out] BaseAddress The base address of the memory region.
@param[out] RegionLength The length of the memory region.
@param[out] RegionAttributes The attributes of the memory region.
@retval EFI_SUCCESS The attributes of the memory region were
returned successfully.
@retval EFI_NOT_FOUND The memory region was not found.
@retval EFI_NO_MAPPING The translation table entry associated with
BaseAddress is invalid.
**/
EFI_STATUS EFI_STATUS
GetMemoryRegionRec ( GetMemoryRegionRec (
IN UINT64 *TranslationTable, IN UINT64 *TranslationTable,
@@ -439,26 +258,23 @@ GetMemoryRegionRec (
} }
// Find the block entry linked to the Base Address // Find the block entry linked to the Base Address
BlockEntry = (UINT64 *)TT_GET_ENTRY_FOR_ADDRESS (TranslationTable, TableLevel, *BaseAddress); BlockEntry = (UINT64*)TT_GET_ENTRY_FOR_ADDRESS (TranslationTable, TableLevel, *BaseAddress);
EntryType = *BlockEntry & TT_TYPE_MASK; EntryType = *BlockEntry & TT_TYPE_MASK;
if ((TableLevel < 3) && (EntryType == TT_TYPE_TABLE_ENTRY)) { if ((TableLevel < 3) && (EntryType == TT_TYPE_TABLE_ENTRY)) {
NextTranslationTable = (UINT64 *)(*BlockEntry & TT_ADDRESS_MASK_DESCRIPTION_TABLE); NextTranslationTable = (UINT64*)(*BlockEntry & TT_ADDRESS_MASK_DESCRIPTION_TABLE);
// The entry is a page table, so we go to the next level // The entry is a page table, so we go to the next level
Status = GetMemoryRegionRec ( Status = GetMemoryRegionRec (
NextTranslationTable, // Address of the next level page table NextTranslationTable, // Address of the next level page table
TableLevel + 1, // Next Page Table level TableLevel + 1, // Next Page Table level
(UINTN *)TT_LAST_BLOCK_ADDRESS (NextTranslationTable, TT_ENTRY_COUNT), (UINTN*)TT_LAST_BLOCK_ADDRESS(NextTranslationTable, TT_ENTRY_COUNT),
BaseAddress, BaseAddress, RegionLength, RegionAttributes);
RegionLength,
RegionAttributes
);
// EFI_SUCCESS: The end of the end of the region was found. // In case of 'Success', it means the end of the block region has been found into the upper
// EFI_NO_MAPPING: The translation entry associated with BaseAddress is invalid. // level translation table
if (Status != EFI_NOT_FOUND) { if (!EFI_ERROR(Status)) {
return Status; return EFI_SUCCESS;
} }
// Now we processed the table move to the next entry // Now we processed the table move to the next entry
@@ -466,51 +282,30 @@ GetMemoryRegionRec (
} else if (EntryType == BlockEntryType) { } else if (EntryType == BlockEntryType) {
// We have found the BlockEntry attached to the address. We save its start address (the start // We have found the BlockEntry attached to the address. We save its start address (the start
// address might be before the 'BaseAddress') and attributes // address might be before the 'BaseAddress') and attributes
*BaseAddress = *BaseAddress & ~(TT_ADDRESS_AT_LEVEL (TableLevel) - 1); *BaseAddress = *BaseAddress & ~(TT_ADDRESS_AT_LEVEL(TableLevel) - 1);
*RegionLength = 0; *RegionLength = 0;
*RegionAttributes = *BlockEntry & TT_ATTRIBUTES_MASK; *RegionAttributes = *BlockEntry & TT_ATTRIBUTES_MASK;
} else { } else {
return EFI_NO_MAPPING; // We have an 'Invalid' entry
return EFI_UNSUPPORTED;
} }
while (BlockEntry <= LastBlockEntry) { while (BlockEntry <= LastBlockEntry) {
if (((*BlockEntry & TT_TYPE_MASK) == BlockEntryType) && if ((*BlockEntry & TT_ATTRIBUTES_MASK) == *RegionAttributes) {
((*BlockEntry & TT_ATTRIBUTES_MASK) == *RegionAttributes)) *RegionLength = *RegionLength + TT_BLOCK_ENTRY_SIZE_AT_LEVEL(TableLevel);
{
*RegionLength = *RegionLength + TT_BLOCK_ENTRY_SIZE_AT_LEVEL (TableLevel);
} else { } else {
// In case we have found the end of the region we return success // In case we have found the end of the region we return success
return EFI_SUCCESS; return EFI_SUCCESS;
} }
BlockEntry++; BlockEntry++;
} }
// If we have reached the end of the TranslationTable and we have not found the end of the region then // If we have reached the end of the TranslationTable and we have not found the end of the region then
// we return EFI_NOT_FOUND. // we return EFI_NOT_FOUND.
// The caller will continue to look for the memory region at its level. // The caller will continue to look for the memory region at its level
return EFI_NOT_FOUND; return EFI_NOT_FOUND;
} }
/**
Retrieves a memory region from a given base address.
This function retrieves a memory region starting from a given base address.
@param[in, out] BaseAddress The base address from which to retrieve
the memory region. On successful return, this is
updated to the end address of the retrieved region.
@param[out] RegionLength The length of the retrieved memory region.
@param[out] RegionAttributes The attributes of the retrieved memory region.
@retval EFI_STATUS Returns EFI_SUCCESS if the memory region is
retrieved successfully, or the status of the
recursive call to GetMemoryRegionRec.
@retval EFI_NOT_FOUND The memory region was not found.
@retval EFI_NO_MAPPING The translation table entry associated with
BaseAddress is invalid.
@retval EFI_INVALID_PARAMETER One of the input parameters was NULL.
**/
EFI_STATUS EFI_STATUS
GetMemoryRegion ( GetMemoryRegion (
IN OUT UINTN *BaseAddress, IN OUT UINTN *BaseAddress,
@@ -524,36 +319,23 @@ GetMemoryRegion (
UINTN EntryCount; UINTN EntryCount;
UINTN T0SZ; UINTN T0SZ;
if ((BaseAddress == NULL) || (RegionLength == NULL) || (RegionAttributes == NULL)) {
ASSERT ((BaseAddress != NULL) && (RegionLength != NULL) && (RegionAttributes != NULL)); ASSERT ((BaseAddress != NULL) && (RegionLength != NULL) && (RegionAttributes != NULL));
return EFI_INVALID_PARAMETER;
}
TranslationTable = ArmGetTTBR0BaseAddress (); TranslationTable = ArmGetTTBR0BaseAddress ();
// Initialize the output parameters. These paramaters are only valid if the
// result is EFI_SUCCESS.
*RegionLength = 0;
*RegionAttributes = 0;
T0SZ = ArmGetTCR () & TCR_T0SZ_MASK; T0SZ = ArmGetTCR () & TCR_T0SZ_MASK;
// Get the Table info from T0SZ // Get the Table info from T0SZ
GetRootTranslationTableInfo (T0SZ, &TableLevel, &EntryCount); GetRootTranslationTableInfo (T0SZ, &TableLevel, &EntryCount);
Status = GetMemoryRegionRec ( Status = GetMemoryRegionRec (TranslationTable, TableLevel,
TranslationTable, (UINTN*)TT_LAST_BLOCK_ADDRESS(TranslationTable, EntryCount),
TableLevel, BaseAddress, RegionLength, RegionAttributes);
(UINTN *)TT_LAST_BLOCK_ADDRESS (TranslationTable, EntryCount),
BaseAddress,
RegionLength,
RegionAttributes
);
// If the region continues up to the end of the root table then GetMemoryRegionRec() // If the region continues up to the end of the root table then GetMemoryRegionRec()
// will return EFI_NOT_FOUND. Check if the region length was updated. // will return EFI_NOT_FOUND
if ((Status == EFI_NOT_FOUND) && (*RegionLength > 0)) { if (Status == EFI_NOT_FOUND) {
return EFI_SUCCESS; return EFI_SUCCESS;
} } else {
return Status; return Status;
}
} }

View File

@@ -2,7 +2,7 @@
Copyright (c) 2009, Hewlett-Packard Company. All rights reserved.<BR> Copyright (c) 2009, Hewlett-Packard Company. All rights reserved.<BR>
Portions copyright (c) 2010, Apple Inc. 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> Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -13,18 +13,6 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include <Library/MemoryAllocationLib.h> #include <Library/MemoryAllocationLib.h>
#include "CpuDxe.h" #include "CpuDxe.h"
/**
Convert a set of ARM short descriptor section attributes into a mask
of EFI_MEMORY_xx constants.
@param[in] SectionAttributes The set of page attributes.
@param[out] GcdAttributes Pointer to the return value.
@retval EFI_SUCCESS The attributes were converted successfully.
@retval EFI_UNSUPPORTED The section attributes did not have a
GCD transation.
**/
STATIC
EFI_STATUS EFI_STATUS
SectionToGcdAttributes ( SectionToGcdAttributes (
IN UINT32 SectionAttributes, IN UINT32 SectionAttributes,
@@ -34,7 +22,7 @@ SectionToGcdAttributes (
*GcdAttributes = 0; *GcdAttributes = 0;
// determine cacheability attributes // determine cacheability attributes
switch (SectionAttributes & TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK) { switch(SectionAttributes & TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK) {
case TT_DESCRIPTOR_SECTION_CACHE_POLICY_STRONGLY_ORDERED: case TT_DESCRIPTOR_SECTION_CACHE_POLICY_STRONGLY_ORDERED:
*GcdAttributes |= EFI_MEMORY_UC; *GcdAttributes |= EFI_MEMORY_UC;
break; break;
@@ -61,63 +49,34 @@ SectionToGcdAttributes (
} }
// determine protection attributes // determine protection attributes
switch (SectionAttributes & TT_DESCRIPTOR_SECTION_AP_MASK) { switch(SectionAttributes & TT_DESCRIPTOR_SECTION_AP_MASK) {
case TT_DESCRIPTOR_SECTION_AP_NO_RW: case TT_DESCRIPTOR_SECTION_AP_NO_NO: // no read, no write
//*GcdAttributes |= EFI_MEMORY_RO | EFI_MEMORY_RP;
break;
case TT_DESCRIPTOR_SECTION_AP_RW_NO:
case TT_DESCRIPTOR_SECTION_AP_RW_RW: case TT_DESCRIPTOR_SECTION_AP_RW_RW:
// normal read/write access, do not add additional attributes // normal read/write access, do not add additional attributes
break; break;
// read only cases map to write-protect // read only cases map to write-protect
case TT_DESCRIPTOR_SECTION_AP_NO_RO: case TT_DESCRIPTOR_SECTION_AP_RO_NO:
case TT_DESCRIPTOR_SECTION_AP_RO_RO: case TT_DESCRIPTOR_SECTION_AP_RO_RO:
*GcdAttributes |= EFI_MEMORY_RO; *GcdAttributes |= EFI_MEMORY_RO;
break; break;
default:
return EFI_UNSUPPORTED;
} }
// now process eXectue Never attribute // now process eXectue Never attribute
if ((SectionAttributes & TT_DESCRIPTOR_SECTION_XN_MASK) != 0) { if ((SectionAttributes & TT_DESCRIPTOR_SECTION_XN_MASK) != 0 ) {
*GcdAttributes |= EFI_MEMORY_XP; *GcdAttributes |= EFI_MEMORY_XP;
} }
if ((SectionAttributes & TT_DESCRIPTOR_SECTION_AF) == 0) {
*GcdAttributes |= EFI_MEMORY_RP;
}
return EFI_SUCCESS; return EFI_SUCCESS;
} }
/**
Convert an arch specific set of page attributes into a mask
of EFI_MEMORY_xx constants.
@param[in] PageAttributes The set of page attributes.
@retval EFI_SUCCESS The attributes were converted successfully.
@retval EFI_UNSUPPORTED The section attributes did not have a
GCD transation.
**/
UINT64
RegionAttributeToGcdAttribute (
IN UINTN PageAttributes
)
{
UINT64 Result;
SectionToGcdAttributes (PageAttributes, &Result);
return Result;
}
/**
Convert a set of ARM short descriptor page attributes into a mask
of EFI_MEMORY_xx constants.
@param[in] PageAttributes The set of page attributes.
@param[out] GcdAttributes Pointer to the return value.
@retval EFI_SUCCESS The attributes were converted successfully.
@retval EFI_UNSUPPORTED The page attributes did not have a GCD transation.
**/
STATIC
EFI_STATUS EFI_STATUS
PageToGcdAttributes ( PageToGcdAttributes (
IN UINT32 PageAttributes, IN UINT32 PageAttributes,
@@ -127,7 +86,7 @@ PageToGcdAttributes (
*GcdAttributes = 0; *GcdAttributes = 0;
// determine cacheability attributes // determine cacheability attributes
switch (PageAttributes & TT_DESCRIPTOR_PAGE_CACHE_POLICY_MASK) { switch(PageAttributes & TT_DESCRIPTOR_PAGE_CACHE_POLICY_MASK) {
case TT_DESCRIPTOR_PAGE_CACHE_POLICY_STRONGLY_ORDERED: case TT_DESCRIPTOR_PAGE_CACHE_POLICY_STRONGLY_ORDERED:
*GcdAttributes |= EFI_MEMORY_UC; *GcdAttributes |= EFI_MEMORY_UC;
break; break;
@@ -154,48 +113,34 @@ PageToGcdAttributes (
} }
// determine protection attributes // determine protection attributes
switch (PageAttributes & TT_DESCRIPTOR_PAGE_AP_MASK) { switch(PageAttributes & TT_DESCRIPTOR_PAGE_AP_MASK) {
case TT_DESCRIPTOR_PAGE_AP_NO_RW: case TT_DESCRIPTOR_PAGE_AP_NO_NO: // no read, no write
//*GcdAttributes |= EFI_MEMORY_RO | EFI_MEMORY_RP;
break;
case TT_DESCRIPTOR_PAGE_AP_RW_NO:
case TT_DESCRIPTOR_PAGE_AP_RW_RW: case TT_DESCRIPTOR_PAGE_AP_RW_RW:
// normal read/write access, do not add additional attributes // normal read/write access, do not add additional attributes
break; break;
// read only cases map to write-protect // read only cases map to write-protect
case TT_DESCRIPTOR_PAGE_AP_NO_RO: case TT_DESCRIPTOR_PAGE_AP_RO_NO:
case TT_DESCRIPTOR_PAGE_AP_RO_RO: case TT_DESCRIPTOR_PAGE_AP_RO_RO:
*GcdAttributes |= EFI_MEMORY_RO; *GcdAttributes |= EFI_MEMORY_RO;
break; break;
default:
return EFI_UNSUPPORTED;
} }
// now process eXectue Never attribute // now process eXectue Never attribute
if ((PageAttributes & TT_DESCRIPTOR_PAGE_XN_MASK) != 0) { if ((PageAttributes & TT_DESCRIPTOR_PAGE_XN_MASK) != 0 ) {
*GcdAttributes |= EFI_MEMORY_XP; *GcdAttributes |= EFI_MEMORY_XP;
} }
if ((PageAttributes & TT_DESCRIPTOR_PAGE_AF) == 0) {
*GcdAttributes |= EFI_MEMORY_RP;
}
return EFI_SUCCESS; return EFI_SUCCESS;
} }
/**
Synchronizes the GCD with the translation table for a specified page.
This function synchronizes cache configuration for a given page based on its section index
and the first level descriptor. It traverses the second level table entries of the page and
updates the GCD attributes accordingly for each entry.
@param[in] SectionIndex The index of the section where the page resides.
@param[in] FirstLevelDescriptor The first translation table level of the page.
@param[in] NumberOfDescriptors The number of descriptors in the GCD memory space map.
@param[in] MemorySpaceMap The GCD memory space descriptor.
@param[in, out] NextRegionBase The next region base address.
@param[in, out] NextRegionLength The next region length.
@param[in, out] NextSectionAttributes The next section attributes.
@retval EFI_STATUS Always return success
**/
EFI_STATUS EFI_STATUS
SyncCacheConfigPage ( SyncCacheConfigPage (
IN UINT32 SectionIndex, IN UINT32 SectionIndex,
@@ -210,27 +155,26 @@ SyncCacheConfigPage (
EFI_STATUS Status; EFI_STATUS Status;
UINT32 i; UINT32 i;
volatile ARM_PAGE_TABLE_ENTRY *SecondLevelTable; volatile ARM_PAGE_TABLE_ENTRY *SecondLevelTable;
UINT32 NextPageAttributes; UINT32 NextPageAttributes = 0;
UINT32 PageAttributes; UINT32 PageAttributes = 0;
UINT32 BaseAddress; UINT32 BaseAddress;
UINT64 GcdAttributes; UINT64 GcdAttributes;
// Get the Base Address from FirstLevelDescriptor; // Get the Base Address from FirstLevelDescriptor;
BaseAddress = TT_DESCRIPTOR_PAGE_BASE_ADDRESS (SectionIndex << TT_DESCRIPTOR_SECTION_BASE_SHIFT); BaseAddress = TT_DESCRIPTOR_PAGE_BASE_ADDRESS(SectionIndex << TT_DESCRIPTOR_SECTION_BASE_SHIFT);
// Convert SectionAttributes into PageAttributes // Convert SectionAttributes into PageAttributes
NextPageAttributes = NextPageAttributes =
TT_DESCRIPTOR_CONVERT_TO_PAGE_CACHE_POLICY (*NextSectionAttributes) | TT_DESCRIPTOR_CONVERT_TO_PAGE_CACHE_POLICY(*NextSectionAttributes,0) |
TT_DESCRIPTOR_CONVERT_TO_PAGE_AF (*NextSectionAttributes) | TT_DESCRIPTOR_CONVERT_TO_PAGE_AP(*NextSectionAttributes);
TT_DESCRIPTOR_CONVERT_TO_PAGE_AP (*NextSectionAttributes);
// obtain page table base // obtain page table base
SecondLevelTable = (ARM_PAGE_TABLE_ENTRY *)(FirstLevelDescriptor & TT_DESCRIPTOR_SECTION_PAGETABLE_ADDRESS_MASK); SecondLevelTable = (ARM_PAGE_TABLE_ENTRY *)(FirstLevelDescriptor & TT_DESCRIPTOR_SECTION_PAGETABLE_ADDRESS_MASK);
for (i = 0; i < TRANSLATION_TABLE_PAGE_COUNT; i++) { for (i=0; i < TRANSLATION_TABLE_PAGE_COUNT; i++) {
if ((SecondLevelTable[i] & TT_DESCRIPTOR_PAGE_TYPE_MASK) == TT_DESCRIPTOR_PAGE_TYPE_PAGE) { if ((SecondLevelTable[i] & TT_DESCRIPTOR_PAGE_TYPE_MASK) == TT_DESCRIPTOR_PAGE_TYPE_PAGE) {
// extract attributes (cacheability and permissions) // extract attributes (cacheability and permissions)
PageAttributes = SecondLevelTable[i] & (TT_DESCRIPTOR_PAGE_CACHE_POLICY_MASK | TT_DESCRIPTOR_PAGE_AP_MASK | TT_DESCRIPTOR_PAGE_AF); PageAttributes = SecondLevelTable[i] & (TT_DESCRIPTOR_PAGE_CACHE_POLICY_MASK | TT_DESCRIPTOR_PAGE_AP_MASK);
if (NextPageAttributes == 0) { if (NextPageAttributes == 0) {
// start on a new region // start on a new region
@@ -240,10 +184,7 @@ SyncCacheConfigPage (
} else if (PageAttributes != NextPageAttributes) { } else if (PageAttributes != NextPageAttributes) {
// Convert Section Attributes into GCD Attributes // Convert Section Attributes into GCD Attributes
Status = PageToGcdAttributes (NextPageAttributes, &GcdAttributes); Status = PageToGcdAttributes (NextPageAttributes, &GcdAttributes);
if (EFI_ERROR (Status)) {
ASSERT_EFI_ERROR (Status); ASSERT_EFI_ERROR (Status);
GcdAttributes = 0;
}
// update GCD with these changes (this will recurse into our own CpuSetMemoryAttributes below which is OK) // update GCD with these changes (this will recurse into our own CpuSetMemoryAttributes below which is OK)
SetGcdMemorySpaceAttributes (MemorySpaceMap, NumberOfDescriptors, *NextRegionBase, *NextRegionLength, GcdAttributes); SetGcdMemorySpaceAttributes (MemorySpaceMap, NumberOfDescriptors, *NextRegionBase, *NextRegionLength, GcdAttributes);
@@ -256,10 +197,7 @@ SyncCacheConfigPage (
} else if (NextPageAttributes != 0) { } else if (NextPageAttributes != 0) {
// Convert Page Attributes into GCD Attributes // Convert Page Attributes into GCD Attributes
Status = PageToGcdAttributes (NextPageAttributes, &GcdAttributes); Status = PageToGcdAttributes (NextPageAttributes, &GcdAttributes);
if (EFI_ERROR (Status)) {
ASSERT_EFI_ERROR (Status); ASSERT_EFI_ERROR (Status);
GcdAttributes = 0;
}
// update GCD with these changes (this will recurse into our own CpuSetMemoryAttributes below which is OK) // update GCD with these changes (this will recurse into our own CpuSetMemoryAttributes below which is OK)
SetGcdMemorySpaceAttributes (MemorySpaceMap, NumberOfDescriptors, *NextRegionBase, *NextRegionLength, GcdAttributes); SetGcdMemorySpaceAttributes (MemorySpaceMap, NumberOfDescriptors, *NextRegionBase, *NextRegionLength, GcdAttributes);
@@ -268,27 +206,17 @@ SyncCacheConfigPage (
*NextRegionBase = BaseAddress | (i << TT_DESCRIPTOR_PAGE_BASE_SHIFT); *NextRegionBase = BaseAddress | (i << TT_DESCRIPTOR_PAGE_BASE_SHIFT);
NextPageAttributes = 0; NextPageAttributes = 0;
} }
*NextRegionLength += TT_DESCRIPTOR_PAGE_SIZE; *NextRegionLength += TT_DESCRIPTOR_PAGE_SIZE;
} }
// Convert back PageAttributes into SectionAttributes // Convert back PageAttributes into SectionAttributes
*NextSectionAttributes = *NextSectionAttributes =
TT_DESCRIPTOR_CONVERT_TO_SECTION_CACHE_POLICY (NextPageAttributes) | TT_DESCRIPTOR_CONVERT_TO_SECTION_CACHE_POLICY(NextPageAttributes,0) |
TT_DESCRIPTOR_CONVERT_TO_SECTION_AF (NextPageAttributes) | TT_DESCRIPTOR_CONVERT_TO_SECTION_AP(NextPageAttributes);
TT_DESCRIPTOR_CONVERT_TO_SECTION_AP (NextPageAttributes);
return EFI_SUCCESS; return EFI_SUCCESS;
} }
/**
Sync the GCD memory space attributes with the translation table.
@param[in] CpuProtocol The CPU architectural protocol instance.
@retval EFI_SUCCESS The GCD memory space attributes are synced with the MMU page table.
@retval Others The return value of GetMemorySpaceMap().
**/
EFI_STATUS EFI_STATUS
SyncCacheConfig ( SyncCacheConfig (
IN EFI_CPU_ARCH_PROTOCOL *CpuProtocol IN EFI_CPU_ARCH_PROTOCOL *CpuProtocol
@@ -298,13 +226,14 @@ SyncCacheConfig (
UINT32 i; UINT32 i;
EFI_PHYSICAL_ADDRESS NextRegionBase; EFI_PHYSICAL_ADDRESS NextRegionBase;
UINT64 NextRegionLength; UINT64 NextRegionLength;
UINT32 NextSectionAttributes; UINT32 NextSectionAttributes = 0;
UINT32 SectionAttributes; UINT32 SectionAttributes = 0;
UINT64 GcdAttributes; UINT64 GcdAttributes;
volatile ARM_FIRST_LEVEL_DESCRIPTOR *FirstLevelTable; volatile ARM_FIRST_LEVEL_DESCRIPTOR *FirstLevelTable;
UINTN NumberOfDescriptors; UINTN NumberOfDescriptors;
EFI_GCD_MEMORY_SPACE_DESCRIPTOR *MemorySpaceMap; EFI_GCD_MEMORY_SPACE_DESCRIPTOR *MemorySpaceMap;
DEBUG ((DEBUG_PAGE, "SyncCacheConfig()\n")); DEBUG ((DEBUG_PAGE, "SyncCacheConfig()\n"));
// This code assumes MMU is enabled and filed with section translations // This code assumes MMU is enabled and filed with section translations
@@ -315,12 +244,8 @@ SyncCacheConfig (
// //
MemorySpaceMap = NULL; MemorySpaceMap = NULL;
Status = gDS->GetMemorySpaceMap (&NumberOfDescriptors, &MemorySpaceMap); Status = gDS->GetMemorySpaceMap (&NumberOfDescriptors, &MemorySpaceMap);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "SyncCacheConfig - GetMemorySpaceMap() failed! Status: %r\n", Status));
ASSERT_EFI_ERROR (Status); ASSERT_EFI_ERROR (Status);
return Status;
}
// The GCD implementation maintains its own copy of the state of memory space attributes. GCD needs // The GCD implementation maintains its own copy of the state of memory space attributes. GCD needs
// to know what the initial memory space attributes are. The CPU Arch. Protocol does not provide a // to know what the initial memory space attributes are. The CPU Arch. Protocol does not provide a
@@ -332,55 +257,44 @@ SyncCacheConfig (
FirstLevelTable = (ARM_FIRST_LEVEL_DESCRIPTOR *)(ArmGetTTBR0BaseAddress ()); FirstLevelTable = (ARM_FIRST_LEVEL_DESCRIPTOR *)(ArmGetTTBR0BaseAddress ());
// Get the first region // Get the first region
NextSectionAttributes = FirstLevelTable[0] & (TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK | TT_DESCRIPTOR_SECTION_AP_MASK | TT_DESCRIPTOR_SECTION_AF); NextSectionAttributes = FirstLevelTable[0] & (TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK | TT_DESCRIPTOR_SECTION_AP_MASK);
// iterate through each 1MB descriptor // iterate through each 1MB descriptor
NextRegionBase = NextRegionLength = 0; NextRegionBase = NextRegionLength = 0;
for (i = 0; i < TRANSLATION_TABLE_SECTION_COUNT; i++) { for (i=0; i < TRANSLATION_TABLE_SECTION_COUNT; i++) {
if ((FirstLevelTable[i] & TT_DESCRIPTOR_SECTION_TYPE_MASK) == TT_DESCRIPTOR_SECTION_TYPE_SECTION) { if ((FirstLevelTable[i] & TT_DESCRIPTOR_SECTION_TYPE_MASK) == TT_DESCRIPTOR_SECTION_TYPE_SECTION) {
// extract attributes (cacheability and permissions) // extract attributes (cacheability and permissions)
SectionAttributes = FirstLevelTable[i] & (TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK | TT_DESCRIPTOR_SECTION_AP_MASK | TT_DESCRIPTOR_SECTION_AF); SectionAttributes = FirstLevelTable[i] & (TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK | TT_DESCRIPTOR_SECTION_AP_MASK);
if (NextSectionAttributes == 0) { if (NextSectionAttributes == 0) {
// start on a new region // start on a new region
NextRegionLength = 0; NextRegionLength = 0;
NextRegionBase = TT_DESCRIPTOR_SECTION_BASE_ADDRESS (i << TT_DESCRIPTOR_SECTION_BASE_SHIFT); NextRegionBase = TT_DESCRIPTOR_SECTION_BASE_ADDRESS(i << TT_DESCRIPTOR_SECTION_BASE_SHIFT);
NextSectionAttributes = SectionAttributes; NextSectionAttributes = SectionAttributes;
} else if (SectionAttributes != NextSectionAttributes) { } else if (SectionAttributes != NextSectionAttributes) {
// Convert Section Attributes into GCD Attributes // Convert Section Attributes into GCD Attributes
Status = SectionToGcdAttributes (NextSectionAttributes, &GcdAttributes); Status = SectionToGcdAttributes (NextSectionAttributes, &GcdAttributes);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "SyncCacheConfig - SectionToGcdAttributes() failed! Status: %r\n", Status));
ASSERT_EFI_ERROR (Status); ASSERT_EFI_ERROR (Status);
GcdAttributes = 0;
}
// update GCD with these changes (this will recurse into our own CpuSetMemoryAttributes below which is OK) // update GCD with these changes (this will recurse into our own CpuSetMemoryAttributes below which is OK)
SetGcdMemorySpaceAttributes (MemorySpaceMap, NumberOfDescriptors, NextRegionBase, NextRegionLength, GcdAttributes); SetGcdMemorySpaceAttributes (MemorySpaceMap, NumberOfDescriptors, NextRegionBase, NextRegionLength, GcdAttributes);
// start on a new region // start on a new region
NextRegionLength = 0; NextRegionLength = 0;
NextRegionBase = TT_DESCRIPTOR_SECTION_BASE_ADDRESS (i << TT_DESCRIPTOR_SECTION_BASE_SHIFT); NextRegionBase = TT_DESCRIPTOR_SECTION_BASE_ADDRESS(i << TT_DESCRIPTOR_SECTION_BASE_SHIFT);
NextSectionAttributes = SectionAttributes; NextSectionAttributes = SectionAttributes;
} }
NextRegionLength += TT_DESCRIPTOR_SECTION_SIZE; NextRegionLength += TT_DESCRIPTOR_SECTION_SIZE;
} else if (TT_DESCRIPTOR_SECTION_TYPE_IS_PAGE_TABLE (FirstLevelTable[i])) { } else if (TT_DESCRIPTOR_SECTION_TYPE_IS_PAGE_TABLE(FirstLevelTable[i])) {
// In this case any bits set in the 'NextSectionAttributes' are garbage and were set from // In this case any bits set in the 'NextSectionAttributes' are garbage and were set from
// bits that are actually part of the pagetable address. We clear it out to zero so that // bits that are actually part of the pagetable address. We clear it out to zero so that
// the SyncCacheConfigPage will use the page attributes instead of trying to convert the // the SyncCacheConfigPage will use the page attributes instead of trying to convert the
// section attributes into page attributes // section attributes into page attributes
NextSectionAttributes = 0; NextSectionAttributes = 0;
Status = SyncCacheConfigPage ( Status = SyncCacheConfigPage (
i, i,FirstLevelTable[i],
FirstLevelTable[i], NumberOfDescriptors, MemorySpaceMap,
NumberOfDescriptors, &NextRegionBase,&NextRegionLength,&NextSectionAttributes);
MemorySpaceMap,
&NextRegionBase,
&NextRegionLength,
&NextSectionAttributes
);
ASSERT_EFI_ERROR (Status); ASSERT_EFI_ERROR (Status);
} else { } else {
// We do not support yet 16MB sections // We do not support yet 16MB sections
@@ -390,20 +304,15 @@ SyncCacheConfig (
if (NextSectionAttributes != 0) { if (NextSectionAttributes != 0) {
// Convert Section Attributes into GCD Attributes // Convert Section Attributes into GCD Attributes
Status = SectionToGcdAttributes (NextSectionAttributes, &GcdAttributes); Status = SectionToGcdAttributes (NextSectionAttributes, &GcdAttributes);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "SyncCacheConfig - SectionToGcdAttributes() failed! Status: %r\n", Status));
ASSERT_EFI_ERROR (Status); ASSERT_EFI_ERROR (Status);
GcdAttributes = 0;
}
// update GCD with these changes (this will recurse into our own CpuSetMemoryAttributes below which is OK) // update GCD with these changes (this will recurse into our own CpuSetMemoryAttributes below which is OK)
SetGcdMemorySpaceAttributes (MemorySpaceMap, NumberOfDescriptors, NextRegionBase, NextRegionLength, GcdAttributes); SetGcdMemorySpaceAttributes (MemorySpaceMap, NumberOfDescriptors, NextRegionBase, NextRegionLength, GcdAttributes);
NextRegionLength = 0; NextRegionLength = 0;
NextRegionBase = TT_DESCRIPTOR_SECTION_BASE_ADDRESS (i << TT_DESCRIPTOR_SECTION_BASE_SHIFT); NextRegionBase = TT_DESCRIPTOR_SECTION_BASE_ADDRESS(i << TT_DESCRIPTOR_SECTION_BASE_SHIFT);
NextSectionAttributes = 0; NextSectionAttributes = 0;
} }
NextRegionLength += TT_DESCRIPTOR_SECTION_SIZE; NextRegionLength += TT_DESCRIPTOR_SECTION_SIZE;
} }
} // section entry loop } // section entry loop
@@ -411,11 +320,7 @@ SyncCacheConfig (
if (NextSectionAttributes != 0) { if (NextSectionAttributes != 0) {
// Convert Section Attributes into GCD Attributes // Convert Section Attributes into GCD Attributes
Status = SectionToGcdAttributes (NextSectionAttributes, &GcdAttributes); Status = SectionToGcdAttributes (NextSectionAttributes, &GcdAttributes);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "SyncCacheConfig - SectionToGcdAttributes() failed! Status: %r\n", Status));
ASSERT_EFI_ERROR (Status); ASSERT_EFI_ERROR (Status);
GcdAttributes = 0;
}
// update GCD with these changes (this will recurse into our own CpuSetMemoryAttributes below which is OK) // update GCD with these changes (this will recurse into our own CpuSetMemoryAttributes below which is OK)
SetGcdMemorySpaceAttributes (MemorySpaceMap, NumberOfDescriptors, NextRegionBase, NextRegionLength, GcdAttributes); SetGcdMemorySpaceAttributes (MemorySpaceMap, NumberOfDescriptors, NextRegionBase, NextRegionLength, GcdAttributes);
@@ -426,13 +331,6 @@ SyncCacheConfig (
return EFI_SUCCESS; return EFI_SUCCESS;
} }
/**
Convert EFI memory attributes to ARM translation table attributes.
@param[in] EfiAttributes EFI memory attributes.
@retval The analogous translation table attributes.
**/
UINT64 UINT64
EfiAttributeToArmAttribute ( EfiAttributeToArmAttribute (
IN UINT64 EfiAttributes IN UINT64 EfiAttributes
@@ -447,7 +345,7 @@ EfiAttributeToArmAttribute (
break; break;
case EFI_MEMORY_WC: case EFI_MEMORY_WC:
// Map to normal non-cacheable // Map to normal non-cachable
ArmAttributes = TT_DESCRIPTOR_SECTION_CACHE_POLICY_NON_CACHEABLE; // TEX [2:0]= 001 = 0x2, B=0, C=0 ArmAttributes = TT_DESCRIPTOR_SECTION_CACHE_POLICY_NON_CACHEABLE; // TEX [2:0]= 001 = 0x2, B=0, C=0
break; break;
@@ -468,106 +366,64 @@ EfiAttributeToArmAttribute (
} }
// Determine protection attributes // Determine protection attributes
if ((EfiAttributes & EFI_MEMORY_RO) != 0) { if (EfiAttributes & EFI_MEMORY_RO) {
ArmAttributes |= TT_DESCRIPTOR_SECTION_AP_RO_RO; ArmAttributes |= TT_DESCRIPTOR_SECTION_AP_RO_RO;
} else { } else {
ArmAttributes |= TT_DESCRIPTOR_SECTION_AP_RW_RW; ArmAttributes |= TT_DESCRIPTOR_SECTION_AP_RW_RW;
} }
// Determine eXecute Never attribute // Determine eXecute Never attribute
if ((EfiAttributes & EFI_MEMORY_XP) != 0) { if (EfiAttributes & EFI_MEMORY_XP) {
ArmAttributes |= TT_DESCRIPTOR_SECTION_XN_MASK; ArmAttributes |= TT_DESCRIPTOR_SECTION_XN_MASK;
} }
if ((EfiAttributes & EFI_MEMORY_RP) == 0) {
ArmAttributes |= TT_DESCRIPTOR_SECTION_AF;
}
return ArmAttributes; return ArmAttributes;
} }
/**
This function finds the end of a memory region in a translation table. A
memory region is defined as a contiguous set of pages with the same attributes.
@param[in] PageTable The translation table to traverse.
@param[in] BaseAddress The address from which to start the search
@param[in] RegionAttributes The attributes of the start of the region.
@param[out] RegionLength The length of the region found.
@retval EFI_SUCCESS The region was found.
@retval EFI_NOT_FOUND The end of the region was not found.
@retval EFI_NO_MAPPING The region specified by BaseAddress is not mapped
in the input translation table.
@retval EFI_UNSUPPORTED Large pages are not supported.
**/
STATIC
EFI_STATUS EFI_STATUS
GetMemoryRegionPage ( GetMemoryRegionPage (
IN UINT32 *PageTable, IN UINT32 *PageTable,
IN UINTN *BaseAddress, IN OUT UINTN *BaseAddress,
IN UINTN *RegionAttributes, OUT UINTN *RegionLength,
OUT UINTN *RegionLength OUT UINTN *RegionAttributes
) )
{ {
UINT32 PageAttributes; UINT32 PageAttributes;
UINT32 TableIndex; UINT32 TableIndex;
UINT32 PageDescriptor; UINT32 PageDescriptor;
EFI_STATUS Status;
// Convert the section attributes into page attributes // Convert the section attributes into page attributes
PageAttributes = ConvertSectionAttributesToPageAttributes (*RegionAttributes); PageAttributes = ConvertSectionAttributesToPageAttributes (*RegionAttributes, 0);
Status = EFI_NOT_FOUND;
*RegionLength = 0;
// Calculate index into first level translation table for start of modification // Calculate index into first level translation table for start of modification
TableIndex = ((*BaseAddress) & TT_DESCRIPTOR_PAGE_INDEX_MASK) >> TT_DESCRIPTOR_PAGE_BASE_SHIFT; TableIndex = ((*BaseAddress) & TT_DESCRIPTOR_PAGE_INDEX_MASK) >> TT_DESCRIPTOR_PAGE_BASE_SHIFT;
ASSERT (TableIndex < TRANSLATION_TABLE_PAGE_COUNT); ASSERT (TableIndex < TRANSLATION_TABLE_PAGE_COUNT);
// Go through the page table to find the end of the section // Go through the page table to find the end of the section
for ( ; TableIndex < TRANSLATION_TABLE_PAGE_COUNT; TableIndex++) { for (; TableIndex < TRANSLATION_TABLE_PAGE_COUNT; TableIndex++) {
// Get the section at the given index // Get the section at the given index
PageDescriptor = PageTable[TableIndex]; PageDescriptor = PageTable[TableIndex];
if ((PageDescriptor & TT_DESCRIPTOR_PAGE_TYPE_MASK) == TT_DESCRIPTOR_PAGE_TYPE_FAULT) { if ((PageDescriptor & TT_DESCRIPTOR_PAGE_TYPE_MASK) == TT_DESCRIPTOR_PAGE_TYPE_FAULT) {
Status = (*RegionLength > 0) ? EFI_SUCCESS : EFI_NO_MAPPING; // Case: End of the boundary of the region
break; return EFI_SUCCESS;
} else if ((PageDescriptor & TT_DESCRIPTOR_PAGE_TYPE_PAGE) == TT_DESCRIPTOR_PAGE_TYPE_PAGE) { } else if ((PageDescriptor & TT_DESCRIPTOR_PAGE_TYPE_PAGE) == TT_DESCRIPTOR_PAGE_TYPE_PAGE) {
if ((PageDescriptor & TT_DESCRIPTOR_PAGE_ATTRIBUTE_MASK) != PageAttributes) { if ((PageDescriptor & TT_DESCRIPTOR_PAGE_ATTRIBUTE_MASK) == PageAttributes) {
Status = EFI_SUCCESS; *RegionLength = *RegionLength + TT_DESCRIPTOR_PAGE_SIZE;
break;
}
*RegionLength += TT_DESCRIPTOR_PAGE_SIZE;
} else { } else {
// Large pages are unsupported. // Case: End of the boundary of the region
Status = EFI_UNSUPPORTED; return EFI_SUCCESS;
ASSERT (0); }
break; } else {
// We do not support Large Page yet. We return EFI_SUCCESS that means end of the region.
ASSERT(0);
return EFI_SUCCESS;
} }
} }
return Status; return EFI_NOT_FOUND;
} }
/**
Get the memory region that contains the specified address. A memory region is defined
as a contiguous set of pages with the same attributes.
RegionLength and RegionAttributes are only valid if EFI_SUCCESS is returned.
@param[in, out] BaseAddress On input, the address to search for.
On output, the base address of the region found.
@param[out] RegionLength The length of the region found.
@param[out] RegionAttributes The attributes of the region found.
@retval EFI_SUCCESS Region found
@retval EFI_NOT_FOUND Region not found
@retval EFI_UNSUPPORTED Large pages are unsupported
@retval EFI_NO_MAPPING The page specified by BaseAddress is unmapped
@retval EFI_INVALID_PARAMETER The BaseAddress exceeds the addressable range of
the translation table.
**/
EFI_STATUS EFI_STATUS
GetMemoryRegion ( GetMemoryRegion (
IN OUT UINTN *BaseAddress, IN OUT UINTN *BaseAddress,
@@ -582,7 +438,6 @@ GetMemoryRegion (
UINT32 SectionDescriptor; UINT32 SectionDescriptor;
ARM_FIRST_LEVEL_DESCRIPTOR *FirstLevelTable; ARM_FIRST_LEVEL_DESCRIPTOR *FirstLevelTable;
UINT32 *PageTable; UINT32 *PageTable;
UINTN Length;
// Initialize the arguments // Initialize the arguments
*RegionLength = 0; *RegionLength = 0;
@@ -592,11 +447,7 @@ GetMemoryRegion (
// Calculate index into first level translation table for start of modification // Calculate index into first level translation table for start of modification
TableIndex = TT_DESCRIPTOR_SECTION_BASE_ADDRESS (*BaseAddress) >> TT_DESCRIPTOR_SECTION_BASE_SHIFT; TableIndex = TT_DESCRIPTOR_SECTION_BASE_ADDRESS (*BaseAddress) >> TT_DESCRIPTOR_SECTION_BASE_SHIFT;
if (TableIndex >= TRANSLATION_TABLE_SECTION_COUNT) {
ASSERT (TableIndex < TRANSLATION_TABLE_SECTION_COUNT); ASSERT (TableIndex < TRANSLATION_TABLE_SECTION_COUNT);
return EFI_INVALID_PARAMETER;
}
// Get the section at the given index // Get the section at the given index
SectionDescriptor = FirstLevelTable[TableIndex]; SectionDescriptor = FirstLevelTable[TableIndex];
@@ -615,45 +466,35 @@ GetMemoryRegion (
*BaseAddress = (*BaseAddress) & TT_DESCRIPTOR_PAGE_BASE_ADDRESS_MASK; *BaseAddress = (*BaseAddress) & TT_DESCRIPTOR_PAGE_BASE_ADDRESS_MASK;
// Get the attribute at the page table level (Level 2) // Get the attribute at the page table level (Level 2)
PageTable = (UINT32 *)(SectionDescriptor & TT_DESCRIPTOR_SECTION_PAGETABLE_ADDRESS_MASK); PageTable = (UINT32*)(SectionDescriptor & TT_DESCRIPTOR_SECTION_PAGETABLE_ADDRESS_MASK);
// Calculate index into first level translation table for start of modification // Calculate index into first level translation table for start of modification
PageTableIndex = ((*BaseAddress) & TT_DESCRIPTOR_PAGE_INDEX_MASK) >> TT_DESCRIPTOR_PAGE_BASE_SHIFT; PageTableIndex = ((*BaseAddress) & TT_DESCRIPTOR_PAGE_INDEX_MASK) >> TT_DESCRIPTOR_PAGE_BASE_SHIFT;
ASSERT (PageTableIndex < TRANSLATION_TABLE_PAGE_COUNT); ASSERT (PageTableIndex < TRANSLATION_TABLE_PAGE_COUNT);
PageAttributes = PageTable[PageTableIndex] & TT_DESCRIPTOR_PAGE_ATTRIBUTE_MASK; PageAttributes = PageTable[PageTableIndex] & TT_DESCRIPTOR_PAGE_ATTRIBUTE_MASK;
*RegionAttributes = TT_DESCRIPTOR_CONVERT_TO_SECTION_CACHE_POLICY (PageAttributes) | *RegionAttributes = TT_DESCRIPTOR_CONVERT_TO_SECTION_CACHE_POLICY (PageAttributes, 0) |
TT_DESCRIPTOR_CONVERT_TO_SECTION_S (PageAttributes) |
TT_DESCRIPTOR_CONVERT_TO_SECTION_XN (PageAttributes) |
TT_DESCRIPTOR_CONVERT_TO_SECTION_AF (PageAttributes) |
TT_DESCRIPTOR_CONVERT_TO_SECTION_AP (PageAttributes); TT_DESCRIPTOR_CONVERT_TO_SECTION_AP (PageAttributes);
} }
Status = EFI_NOT_FOUND; for (;TableIndex < TRANSLATION_TABLE_SECTION_COUNT; TableIndex++) {
for ( ; TableIndex < TRANSLATION_TABLE_SECTION_COUNT; TableIndex++) {
// Get the section at the given index // Get the section at the given index
SectionDescriptor = FirstLevelTable[TableIndex]; SectionDescriptor = FirstLevelTable[TableIndex];
// If the entry is a level-2 page table then we scan it to find the end of the region // If the entry is a level-2 page table then we scan it to find the end of the region
if (TT_DESCRIPTOR_SECTION_TYPE_IS_PAGE_TABLE (SectionDescriptor)) { if (TT_DESCRIPTOR_SECTION_TYPE_IS_PAGE_TABLE (SectionDescriptor)) {
// Extract the page table location from the descriptor // Extract the page table location from the descriptor
PageTable = (UINT32 *)(SectionDescriptor & TT_DESCRIPTOR_SECTION_PAGETABLE_ADDRESS_MASK); PageTable = (UINT32*)(SectionDescriptor & TT_DESCRIPTOR_SECTION_PAGETABLE_ADDRESS_MASK);
Length = 0;
// Scan the page table to find the end of the region. // Scan the page table to find the end of the region.
Status = GetMemoryRegionPage (PageTable, BaseAddress, RegionAttributes, &Length); Status = GetMemoryRegionPage (PageTable, BaseAddress, RegionLength, RegionAttributes);
*RegionLength += Length;
// Status == EFI_NOT_FOUND implies we have not reached the end of the region.
if ((Status == EFI_NOT_FOUND) && (Length > 0)) {
continue;
}
// If we have found the end of the region (Status == EFI_SUCCESS) then we exit the for-loop
if (Status == EFI_SUCCESS) {
break; break;
}
} else if (((SectionDescriptor & TT_DESCRIPTOR_SECTION_TYPE_MASK) == TT_DESCRIPTOR_SECTION_TYPE_SECTION) || } else if (((SectionDescriptor & TT_DESCRIPTOR_SECTION_TYPE_MASK) == TT_DESCRIPTOR_SECTION_TYPE_SECTION) ||
((SectionDescriptor & TT_DESCRIPTOR_SECTION_TYPE_MASK) == TT_DESCRIPTOR_SECTION_TYPE_SUPERSECTION)) ((SectionDescriptor & TT_DESCRIPTOR_SECTION_TYPE_MASK) == TT_DESCRIPTOR_SECTION_TYPE_SUPERSECTION)) {
{
if ((SectionDescriptor & TT_DESCRIPTOR_SECTION_ATTRIBUTE_MASK) != *RegionAttributes) { if ((SectionDescriptor & TT_DESCRIPTOR_SECTION_ATTRIBUTE_MASK) != *RegionAttributes) {
// If the attributes of the section differ from the one targeted then we exit the loop // If the attributes of the section differ from the one targeted then we exit the loop
break; break;
@@ -666,10 +507,5 @@ GetMemoryRegion (
} }
} }
// Check if the region length was updated. return EFI_SUCCESS;
if (*RegionLength > 0) {
Status = EFI_SUCCESS;
}
return Status;
} }

View File

@@ -11,8 +11,6 @@
#include <Guid/IdleLoopEvent.h> #include <Guid/IdleLoopEvent.h>
#include <Library/MemoryAllocationLib.h>
BOOLEAN mIsFlushingGCD; BOOLEAN mIsFlushingGCD;
/** /**
@@ -51,6 +49,7 @@ CpuFlushCpuDataCache (
IN EFI_CPU_FLUSH_TYPE FlushType IN EFI_CPU_FLUSH_TYPE FlushType
) )
{ {
switch (FlushType) { switch (FlushType) {
case EfiCpuFlushTypeWriteBack: case EfiCpuFlushTypeWriteBack:
WriteBackDataCacheRange ((VOID *)(UINTN)Start, (UINTN)Length); WriteBackDataCacheRange ((VOID *)(UINTN)Start, (UINTN)Length);
@@ -68,6 +67,7 @@ CpuFlushCpuDataCache (
return EFI_SUCCESS; return EFI_SUCCESS;
} }
/** /**
This function enables interrupt processing by the processor. This function enables interrupt processing by the processor.
@@ -88,6 +88,7 @@ CpuEnableInterrupt (
return EFI_SUCCESS; return EFI_SUCCESS;
} }
/** /**
This function disables interrupt processing by the processor. This function disables interrupt processing by the processor.
@@ -108,6 +109,7 @@ CpuDisableInterrupt (
return EFI_SUCCESS; return EFI_SUCCESS;
} }
/** /**
This function retrieves the processor's current interrupt state a returns it in This function retrieves the processor's current interrupt state a returns it in
State. If interrupts are currently enabled, then TRUE is returned. If interrupts State. If interrupts are currently enabled, then TRUE is returned. If interrupts
@@ -132,10 +134,11 @@ CpuGetInterruptState (
return EFI_INVALID_PARAMETER; return EFI_INVALID_PARAMETER;
} }
*State = ArmGetInterruptState (); *State = ArmGetInterruptState();
return EFI_SUCCESS; return EFI_SUCCESS;
} }
/** /**
This function generates an INIT on the processor. If this function succeeds, then the This function generates an INIT on the processor. If this function succeeds, then the
processor will be reset, and control will not be returned to the caller. If InitType is processor will be reset, and control will not be returned to the caller. If InitType is
@@ -229,77 +232,6 @@ InitializeDma (
CpuArchProtocol->DmaBufferAlignment = ArmCacheWritebackGranule (); CpuArchProtocol->DmaBufferAlignment = ArmCacheWritebackGranule ();
} }
/**
Map all EfiConventionalMemory regions in the memory map with NX
attributes so that allocating or freeing EfiBootServicesData regions
does not result in changes to memory permission attributes.
**/
STATIC
VOID
RemapUnusedMemoryNx (
VOID
)
{
UINT64 TestBit;
UINTN MemoryMapSize;
UINTN MapKey;
UINTN DescriptorSize;
UINT32 DescriptorVersion;
EFI_MEMORY_DESCRIPTOR *MemoryMap;
EFI_MEMORY_DESCRIPTOR *MemoryMapEntry;
EFI_MEMORY_DESCRIPTOR *MemoryMapEnd;
EFI_STATUS Status;
TestBit = LShiftU64 (1, EfiBootServicesData);
if ((PcdGet64 (PcdDxeNxMemoryProtectionPolicy) & TestBit) == 0) {
return;
}
MemoryMapSize = 0;
MemoryMap = NULL;
Status = gBS->GetMemoryMap (
&MemoryMapSize,
MemoryMap,
&MapKey,
&DescriptorSize,
&DescriptorVersion
);
ASSERT (Status == EFI_BUFFER_TOO_SMALL);
do {
MemoryMap = (EFI_MEMORY_DESCRIPTOR *)AllocatePool (MemoryMapSize);
ASSERT (MemoryMap != NULL);
Status = gBS->GetMemoryMap (
&MemoryMapSize,
MemoryMap,
&MapKey,
&DescriptorSize,
&DescriptorVersion
);
if (EFI_ERROR (Status)) {
FreePool (MemoryMap);
}
} while (Status == EFI_BUFFER_TOO_SMALL);
ASSERT_EFI_ERROR (Status);
MemoryMapEntry = MemoryMap;
MemoryMapEnd = (EFI_MEMORY_DESCRIPTOR *)((UINT8 *)MemoryMap + MemoryMapSize);
while ((UINTN)MemoryMapEntry < (UINTN)MemoryMapEnd) {
if (MemoryMapEntry->Type == EfiConventionalMemory) {
ArmSetMemoryAttributes (
MemoryMapEntry->PhysicalStart,
EFI_PAGES_TO_SIZE (MemoryMapEntry->NumberOfPages),
EFI_MEMORY_XP,
EFI_MEMORY_XP
);
}
MemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize);
}
}
EFI_STATUS EFI_STATUS
CpuDxeInitialize ( CpuDxeInitialize (
IN EFI_HANDLE ImageHandle, IN EFI_HANDLE ImageHandle,
@@ -313,26 +245,9 @@ CpuDxeInitialize (
InitializeDma (&mCpu); InitializeDma (&mCpu);
//
// Once we install the CPU arch protocol, the DXE core's memory
// protection routines will invoke them to manage the permissions of page
// allocations as they are created. Given that this includes pages
// allocated for page tables by this driver, we must ensure that unused
// memory is mapped with the same permissions as boot services data
// regions. Otherwise, we may end up with unbounded recursion, due to the
// fact that updating permissions on a newly allocated page table may trigger
// a block entry split, which triggers a page table allocation, etc etc
//
if (FeaturePcdGet (PcdRemapUnusedMemoryNx)) {
RemapUnusedMemoryNx ();
}
Status = gBS->InstallMultipleProtocolInterfaces ( Status = gBS->InstallMultipleProtocolInterfaces (
&mCpuHandle, &mCpuHandle,
&gEfiCpuArchProtocolGuid, &gEfiCpuArchProtocolGuid, &mCpu,
&mCpu,
&gEfiMemoryAttributeProtocolGuid,
&mMemoryAttribute,
NULL NULL
); );
@@ -345,6 +260,12 @@ CpuDxeInitialize (
SyncCacheConfig (&mCpu); SyncCacheConfig (&mCpu);
mIsFlushingGCD = FALSE; mIsFlushingGCD = FALSE;
// If the platform is a MPCore system then install the Configuration Table describing the
// secondary core states
if (ArmIsMpCore()) {
PublishArmProcessorTable();
}
// //
// Setup a callback for idle events // Setup a callback for idle events
// //

View File

@@ -7,8 +7,8 @@
**/ **/
#ifndef CPU_DXE_H_ #ifndef __CPU_DXE_ARM_EXCEPTION_H__
#define CPU_DXE_H_ #define __CPU_DXE_ARM_EXCEPTION_H__
#include <Uefi.h> #include <Uefi.h>
@@ -30,12 +30,9 @@
#include <Protocol/Cpu.h> #include <Protocol/Cpu.h>
#include <Protocol/DebugSupport.h> #include <Protocol/DebugSupport.h>
#include <Protocol/LoadedImage.h> #include <Protocol/LoadedImage.h>
#include <Protocol/MemoryAttribute.h>
extern BOOLEAN mIsFlushingGCD; extern BOOLEAN mIsFlushingGCD;
extern EFI_MEMORY_ATTRIBUTE_PROTOCOL mMemoryAttribute;
/** /**
This function registers and enables the handler specified by InterruptHandler for a processor This function registers and enables the handler specified by InterruptHandler for a processor
interrupt or exception type specified by InterruptType. If InterruptHandler is NULL, then the interrupt or exception type specified by InterruptType. If InterruptHandler is NULL, then the
@@ -62,6 +59,7 @@ RegisterInterruptHandler (
IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler
); );
/** /**
This function registers and enables the handler specified by InterruptHandler for a processor This function registers and enables the handler specified by InterruptHandler for a processor
interrupt or exception type specified by InterruptType. If InterruptHandler is NULL, then the interrupt or exception type specified by InterruptType. If InterruptHandler is NULL, then the
@@ -88,6 +86,7 @@ RegisterDebuggerInterruptHandler (
IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler
); );
EFI_STATUS EFI_STATUS
EFIAPI EFIAPI
CpuSetMemoryAttributes ( CpuSetMemoryAttributes (
@@ -107,6 +106,21 @@ SyncCacheConfig (
IN EFI_CPU_ARCH_PROTOCOL *CpuProtocol IN EFI_CPU_ARCH_PROTOCOL *CpuProtocol
); );
/**
* Publish ARM Processor Data table in UEFI SYSTEM Table.
* @param HobStart Pointer to the beginning of the HOB List from PEI.
*
* Description : This function iterates through HOB list and finds ARM processor Table Entry HOB.
* If the ARM processor Table Entry HOB is found, the HOB data is copied to run-time memory
* and a pointer is assigned to it in ARM processor table. Then the ARM processor table is
* installed in EFI configuration table.
**/
VOID
EFIAPI
PublishArmProcessorTable(
VOID
);
// The ARM Attributes might be defined on 64-bit (case of the long format description table) // The ARM Attributes might be defined on 64-bit (case of the long format description table)
UINT64 UINT64
EfiAttributeToArmAttribute ( EfiAttributeToArmAttribute (
@@ -120,6 +134,13 @@ GetMemoryRegion (
OUT UINTN *RegionAttributes OUT UINTN *RegionAttributes
); );
VOID
GetRootTranslationTableInfo (
IN UINTN T0SZ,
OUT UINTN *TableLevel,
OUT UINTN *TableEntryCount
);
EFI_STATUS EFI_STATUS
SetGcdMemorySpaceAttributes ( SetGcdMemorySpaceAttributes (
IN EFI_GCD_MEMORY_SPACE_DESCRIPTOR *MemorySpaceMap, IN EFI_GCD_MEMORY_SPACE_DESCRIPTOR *MemorySpaceMap,
@@ -129,18 +150,4 @@ SetGcdMemorySpaceAttributes (
IN UINT64 Attributes IN UINT64 Attributes
); );
/** #endif // __CPU_DXE_ARM_EXCEPTION_H__
Convert an arch specific set of page attributes into a mask
of EFI_MEMORY_xx constants.
@param PageAttributes The set of page attributes.
@retval The mask of EFI_MEMORY_xx constants.
**/
UINT64
RegionAttributeToGcdAttribute (
IN UINTN PageAttributes
);
#endif // CPU_DXE_H_

View File

@@ -21,9 +21,9 @@
[Sources.Common] [Sources.Common]
CpuDxe.c CpuDxe.c
CpuDxe.h CpuDxe.h
CpuMpCore.c
CpuMmuCommon.c CpuMmuCommon.c
Exception.c Exception.c
MemoryAttribute.c
[Sources.ARM] [Sources.ARM]
Arm/Mmu.c Arm/Mmu.c
@@ -48,14 +48,12 @@
DefaultExceptionHandlerLib DefaultExceptionHandlerLib
DxeServicesTableLib DxeServicesTableLib
HobLib HobLib
MemoryAllocationLib
PeCoffGetEntryPointLib PeCoffGetEntryPointLib
UefiDriverEntryPoint UefiDriverEntryPoint
UefiLib UefiLib
[Protocols] [Protocols]
gEfiCpuArchProtocolGuid gEfiCpuArchProtocolGuid
gEfiMemoryAttributeProtocolGuid
[Guids] [Guids]
gEfiDebugImageInfoTableGuid gEfiDebugImageInfoTableGuid
@@ -65,11 +63,9 @@
[Pcd.common] [Pcd.common]
gArmTokenSpaceGuid.PcdVFPEnabled gArmTokenSpaceGuid.PcdVFPEnabled
gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy
[FeaturePcd.common] [FeaturePcd.common]
gArmTokenSpaceGuid.PcdDebuggerExceptionSupport gArmTokenSpaceGuid.PcdDebuggerExceptionSupport
gArmTokenSpaceGuid.PcdRemapUnusedMemoryNx
[Depex] [Depex]
gHardwareInterruptProtocolGuid OR gHardwareInterrupt2ProtocolGuid gHardwareInterruptProtocolGuid OR gHardwareInterrupt2ProtocolGuid

View File

@@ -43,22 +43,19 @@ SearchGcdMemorySpaces (
*EndIndex = 0; *EndIndex = 0;
for (Index = 0; Index < NumberOfDescriptors; Index++) { for (Index = 0; Index < NumberOfDescriptors; Index++) {
if ((BaseAddress >= MemorySpaceMap[Index].BaseAddress) && if ((BaseAddress >= MemorySpaceMap[Index].BaseAddress) &&
(BaseAddress < (MemorySpaceMap[Index].BaseAddress + MemorySpaceMap[Index].Length))) (BaseAddress < (MemorySpaceMap[Index].BaseAddress + MemorySpaceMap[Index].Length))) {
{
*StartIndex = Index; *StartIndex = Index;
} }
if (((BaseAddress + Length - 1) >= MemorySpaceMap[Index].BaseAddress) && if (((BaseAddress + Length - 1) >= MemorySpaceMap[Index].BaseAddress) &&
((BaseAddress + Length - 1) < (MemorySpaceMap[Index].BaseAddress + MemorySpaceMap[Index].Length))) ((BaseAddress + Length - 1) < (MemorySpaceMap[Index].BaseAddress + MemorySpaceMap[Index].Length))) {
{
*EndIndex = Index; *EndIndex = Index;
return EFI_SUCCESS; return EFI_SUCCESS;
} }
} }
return EFI_NOT_FOUND; return EFI_NOT_FOUND;
} }
/** /**
Sets the attributes for a specified range in Gcd Memory Space Map. Sets the attributes for a specified range in Gcd Memory Space Map.
@@ -91,21 +88,14 @@ SetGcdMemorySpaceAttributes (
EFI_PHYSICAL_ADDRESS RegionStart; EFI_PHYSICAL_ADDRESS RegionStart;
UINT64 RegionLength; UINT64 RegionLength;
DEBUG (( DEBUG ((DEBUG_GCD, "SetGcdMemorySpaceAttributes[0x%lX; 0x%lX] = 0x%lX\n",
DEBUG_GCD, BaseAddress, BaseAddress + Length, Attributes));
"SetGcdMemorySpaceAttributes[0x%lX; 0x%lX] = 0x%lX\n",
BaseAddress,
BaseAddress + Length,
Attributes
));
// We do not support a smaller granularity than 4KB on ARM Architecture // We do not support a smaller granularity than 4KB on ARM Architecture
if ((Length & EFI_PAGE_MASK) != 0) { if ((Length & EFI_PAGE_MASK) != 0) {
DEBUG (( DEBUG ((DEBUG_WARN,
DEBUG_WARN,
"Warning: We do not support smaller granularity than 4KB on ARM Architecture (passed length: 0x%lX).\n", "Warning: We do not support smaller granularity than 4KB on ARM Architecture (passed length: 0x%lX).\n",
Length Length));
));
} }
// //
@@ -130,7 +120,6 @@ SetGcdMemorySpaceAttributes (
if (MemorySpaceMap[Index].GcdMemoryType == EfiGcdMemoryTypeNonExistent) { if (MemorySpaceMap[Index].GcdMemoryType == EfiGcdMemoryTypeNonExistent) {
continue; continue;
} }
// //
// Calculate the start and end address of the overlapping range // Calculate the start and end address of the overlapping range
// //
@@ -139,13 +128,11 @@ SetGcdMemorySpaceAttributes (
} else { } else {
RegionStart = MemorySpaceMap[Index].BaseAddress; RegionStart = MemorySpaceMap[Index].BaseAddress;
} }
if ((BaseAddress + Length - 1) < (MemorySpaceMap[Index].BaseAddress + MemorySpaceMap[Index].Length)) { if ((BaseAddress + Length - 1) < (MemorySpaceMap[Index].BaseAddress + MemorySpaceMap[Index].Length)) {
RegionLength = BaseAddress + Length - RegionStart; RegionLength = BaseAddress + Length - RegionStart;
} else { } else {
RegionLength = MemorySpaceMap[Index].BaseAddress + MemorySpaceMap[Index].Length - RegionStart; RegionLength = MemorySpaceMap[Index].BaseAddress + MemorySpaceMap[Index].Length - RegionStart;
} }
// //
// Set memory attributes according to MTRR attribute and the original attribute of descriptor // Set memory attributes according to MTRR attribute and the original attribute of descriptor
// //
@@ -217,7 +204,7 @@ CpuSetMemoryAttributes (
if (EFI_ERROR (Status) || (RegionArmAttributes != ArmAttributes) || if (EFI_ERROR (Status) || (RegionArmAttributes != ArmAttributes) ||
((BaseAddress + Length) > (RegionBaseAddress + RegionLength))) ((BaseAddress + Length) > (RegionBaseAddress + RegionLength)))
{ {
return ArmSetMemoryAttributes (BaseAddress, Length, EfiAttributes, 0); return ArmSetMemoryAttributes (BaseAddress, Length, EfiAttributes);
} else { } else {
return EFI_SUCCESS; return EFI_SUCCESS;
} }

View File

@@ -0,0 +1,97 @@
/** @file
*
* Copyright (c) 2011-2014, ARM Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-2-Clause-Patent
*
**/
#include <Library/UefiBootServicesTableLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/HobLib.h>
#include <Library/DebugLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Guid/ArmMpCoreInfo.h>
ARM_PROCESSOR_TABLE mArmProcessorTableTemplate = {
{
EFI_ARM_PROCESSOR_TABLE_SIGNATURE,
0,
EFI_ARM_PROCESSOR_TABLE_REVISION,
EFI_ARM_PROCESSOR_TABLE_OEM_ID,
EFI_ARM_PROCESSOR_TABLE_OEM_TABLE_ID,
EFI_ARM_PROCESSOR_TABLE_OEM_REVISION,
EFI_ARM_PROCESSOR_TABLE_CREATOR_ID,
EFI_ARM_PROCESSOR_TABLE_CREATOR_REVISION,
{ 0 },
0
}, //ARM Processor table header
0, // Number of entries in ARM processor Table
NULL // ARM Processor Table
};
/** Publish ARM Processor Data table in UEFI SYSTEM Table.
* @param: HobStart Pointer to the beginning of the HOB List from PEI.
*
* Description : This function iterates through HOB list and finds ARM processor Table Entry HOB.
* If the ARM processor Table Entry HOB is found, the HOB data is copied to run-time memory
* and a pointer is assigned to it in ARM processor table. Then the ARM processor table is
* installed in EFI configuration table.
**/
VOID
EFIAPI
PublishArmProcessorTable (
VOID
)
{
EFI_PEI_HOB_POINTERS Hob;
Hob.Raw = GetHobList ();
// Iterate through the HOBs and find if there is ARM PROCESSOR ENTRY HOB
for (; !END_OF_HOB_LIST(Hob); Hob.Raw = GET_NEXT_HOB(Hob)) {
// Check for Correct HOB type
if ((GET_HOB_TYPE (Hob)) == EFI_HOB_TYPE_GUID_EXTENSION) {
// Check for correct GUID type
if (CompareGuid(&(Hob.Guid->Name), &gArmMpCoreInfoGuid)) {
ARM_PROCESSOR_TABLE *ArmProcessorTable;
EFI_STATUS Status;
// Allocate Runtime memory for ARM processor table
ArmProcessorTable = (ARM_PROCESSOR_TABLE*)AllocateRuntimePool(sizeof(ARM_PROCESSOR_TABLE));
// Check if the memory allocation is successful or not
ASSERT(NULL != ArmProcessorTable);
// Set ARM processor table to default values
CopyMem(ArmProcessorTable,&mArmProcessorTableTemplate,sizeof(ARM_PROCESSOR_TABLE));
// Fill in Length fields of ARM processor table
ArmProcessorTable->Header.Length = sizeof(ARM_PROCESSOR_TABLE);
ArmProcessorTable->Header.DataLen = GET_GUID_HOB_DATA_SIZE(Hob);
// Fill in Identifier(ARM processor table GUID)
ArmProcessorTable->Header.Identifier = gArmMpCoreInfoGuid;
// Set Number of ARM core entries in the Table
ArmProcessorTable->NumberOfEntries = GET_GUID_HOB_DATA_SIZE(Hob)/sizeof(ARM_CORE_INFO);
// Allocate runtime memory for ARM processor Table entries
ArmProcessorTable->ArmCpus = (ARM_CORE_INFO*)AllocateRuntimePool (
ArmProcessorTable->NumberOfEntries * sizeof(ARM_CORE_INFO));
// Check if the memory allocation is successful or not
ASSERT(NULL != ArmProcessorTable->ArmCpus);
// Copy ARM Processor Table data from HOB list to newly allocated memory
CopyMem(ArmProcessorTable->ArmCpus,GET_GUID_HOB_DATA(Hob), ArmProcessorTable->Header.DataLen);
// Install the ARM Processor table into EFI system configuration table
Status = gBS->InstallConfigurationTable (&gArmMpCoreInfoGuid, ArmProcessorTable);
ASSERT_EFI_ERROR (Status);
}
}
}
}

View File

@@ -1,7 +1,7 @@
/** @file /** @file
Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR> 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 SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -14,8 +14,7 @@
EFI_STATUS EFI_STATUS
InitializeExceptions ( InitializeExceptions (
IN EFI_CPU_ARCH_PROTOCOL *Cpu IN EFI_CPU_ARCH_PROTOCOL *Cpu
) ) {
{
EFI_STATUS Status; EFI_STATUS Status;
EFI_VECTOR_HANDOFF_INFO *VectorInfoList; EFI_VECTOR_HANDOFF_INFO *VectorInfoList;
EFI_VECTOR_HANDOFF_INFO *VectorInfo; EFI_VECTOR_HANDOFF_INFO *VectorInfo;
@@ -23,13 +22,13 @@ InitializeExceptions (
BOOLEAN FiqEnabled; BOOLEAN FiqEnabled;
VectorInfo = (EFI_VECTOR_HANDOFF_INFO *)NULL; VectorInfo = (EFI_VECTOR_HANDOFF_INFO *)NULL;
Status = EfiGetSystemConfigurationTable (&gEfiVectorHandoffTableGuid, (VOID **)&VectorInfoList); Status = EfiGetSystemConfigurationTable(&gEfiVectorHandoffTableGuid, (VOID **)&VectorInfoList);
if ((Status == EFI_SUCCESS) && (VectorInfoList != NULL)) { if (Status == EFI_SUCCESS && VectorInfoList != NULL) {
VectorInfo = VectorInfoList; VectorInfo = VectorInfoList;
} }
// initialize the CpuExceptionHandlerLib so we take over the exception vector table from the DXE Core // initialize the CpuExceptionHandlerLib so we take over the exception vector table from the DXE Core
InitializeCpuExceptionHandlers (VectorInfo); InitializeCpuExceptionHandlers(VectorInfo);
Status = EFI_SUCCESS; Status = EFI_SUCCESS;
@@ -90,11 +89,10 @@ previously installed.
**/ **/
EFI_STATUS EFI_STATUS
RegisterInterruptHandler ( RegisterInterruptHandler(
IN EFI_EXCEPTION_TYPE InterruptType, IN EFI_EXCEPTION_TYPE InterruptType,
IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler
) ) {
{
// pass down to CpuExceptionHandlerLib // pass down to CpuExceptionHandlerLib
return (EFI_STATUS)RegisterCpuInterruptHandler (InterruptType, InterruptHandler); return (EFI_STATUS)RegisterCpuInterruptHandler(InterruptType, InterruptHandler);
} }

View File

@@ -1,273 +0,0 @@
/** @file
Copyright (c) 2023, Google LLC. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include "CpuDxe.h"
/**
Check whether the provided memory range is covered by a single entry of type
EfiGcdSystemMemory in the GCD memory map.
@param BaseAddress The physical address that is the start address of
a memory region.
@param Length The size in bytes of the memory region.
@return Whether the region is system memory or not.
**/
STATIC
BOOLEAN
RegionIsSystemMemory (
IN EFI_PHYSICAL_ADDRESS BaseAddress,
IN UINT64 Length
)
{
EFI_GCD_MEMORY_SPACE_DESCRIPTOR GcdDescriptor;
EFI_PHYSICAL_ADDRESS GcdEndAddress;
EFI_STATUS Status;
Status = gDS->GetMemorySpaceDescriptor (BaseAddress, &GcdDescriptor);
if (EFI_ERROR (Status) ||
(GcdDescriptor.GcdMemoryType != EfiGcdMemoryTypeSystemMemory))
{
return FALSE;
}
GcdEndAddress = GcdDescriptor.BaseAddress + GcdDescriptor.Length;
//
// Return TRUE if the GCD descriptor covers the range entirely
//
return GcdEndAddress >= (BaseAddress + Length);
}
/**
This function retrieves the attributes of the memory region specified by
BaseAddress and Length. If different attributes are obtained from different
parts of the memory region, EFI_NO_MAPPING will be returned.
@param This The EFI_MEMORY_ATTRIBUTE_PROTOCOL instance.
@param BaseAddress The physical address that is the start address of
a memory region.
@param Length The size in bytes of the memory region.
@param Attributes Pointer to attributes returned.
@retval EFI_SUCCESS The attributes got for the memory region.
@retval EFI_INVALID_PARAMETER Length is zero.
Attributes is NULL.
@retval EFI_NO_MAPPING Attributes are not consistent cross the memory
region.
@retval EFI_UNSUPPORTED The processor does not support one or more
bytes of the memory resource range specified
by BaseAddress and Length.
**/
STATIC
EFI_STATUS
GetMemoryAttributes (
IN EFI_MEMORY_ATTRIBUTE_PROTOCOL *This,
IN EFI_PHYSICAL_ADDRESS BaseAddress,
IN UINT64 Length,
OUT UINT64 *Attributes
)
{
UINTN RegionAddress;
UINTN RegionLength;
UINTN RegionAttributes;
UINTN Union;
UINTN Intersection;
EFI_STATUS Status;
if ((Length == 0) || (Attributes == NULL)) {
return EFI_INVALID_PARAMETER;
}
if (!RegionIsSystemMemory (BaseAddress, Length)) {
return EFI_UNSUPPORTED;
}
DEBUG ((
DEBUG_VERBOSE,
"%a: BaseAddress == 0x%lx, Length == 0x%lx\n",
__func__,
BaseAddress,
Length
));
Union = 0;
Intersection = MAX_UINTN;
for (RegionAddress = (UINTN)BaseAddress;
RegionAddress < (UINTN)(BaseAddress + Length);
RegionAddress += RegionLength)
{
Status = GetMemoryRegion (
&RegionAddress,
&RegionLength,
&RegionAttributes
);
DEBUG ((
DEBUG_VERBOSE,
"%a: RegionAddress == 0x%lx, RegionLength == 0x%lx, RegionAttributes == 0x%lx\n",
__func__,
(UINT64)RegionAddress,
(UINT64)RegionLength,
(UINT64)RegionAttributes
));
if (EFI_ERROR (Status)) {
return EFI_NO_MAPPING;
}
Union |= RegionAttributes;
Intersection &= RegionAttributes;
}
DEBUG ((
DEBUG_VERBOSE,
"%a: Union == %lx, Intersection == %lx\n",
__func__,
(UINT64)Union,
(UINT64)Intersection
));
if (Union != Intersection) {
return EFI_NO_MAPPING;
}
*Attributes = RegionAttributeToGcdAttribute (Union);
*Attributes &= EFI_MEMORY_RP | EFI_MEMORY_RO | EFI_MEMORY_XP;
return EFI_SUCCESS;
}
/**
This function set given attributes of the memory region specified by
BaseAddress and Length.
The valid Attributes is EFI_MEMORY_RP, EFI_MEMORY_XP, and EFI_MEMORY_RO.
@param This The EFI_MEMORY_ATTRIBUTE_PROTOCOL instance.
@param BaseAddress The physical address that is the start address of
a memory region.
@param Length The size in bytes of the memory region.
@param Attributes The bit mask of attributes to set for the memory
region.
@retval EFI_SUCCESS The attributes were set for the memory region.
@retval EFI_INVALID_PARAMETER Length is zero.
Attributes specified an illegal combination of
attributes that cannot be set together.
@retval EFI_UNSUPPORTED The processor does not support one or more
bytes of the memory resource range specified
by BaseAddress and Length.
The bit mask of attributes is not supported for
the memory resource range specified by
BaseAddress and Length.
@retval EFI_OUT_OF_RESOURCES Requested attributes cannot be applied due to
lack of system resources.
@retval EFI_ACCESS_DENIED Attributes for the requested memory region are
controlled by system firmware and cannot be
updated via the protocol.
**/
STATIC
EFI_STATUS
SetMemoryAttributes (
IN EFI_MEMORY_ATTRIBUTE_PROTOCOL *This,
IN EFI_PHYSICAL_ADDRESS BaseAddress,
IN UINT64 Length,
IN UINT64 Attributes
)
{
DEBUG ((
DEBUG_INFO,
"%a: BaseAddress == 0x%lx, Length == 0x%lx, Attributes == 0x%lx\n",
__func__,
(UINTN)BaseAddress,
(UINTN)Length,
(UINTN)Attributes
));
if ((Length == 0) ||
((Attributes & ~(EFI_MEMORY_RO | EFI_MEMORY_RP | EFI_MEMORY_XP)) != 0))
{
return EFI_INVALID_PARAMETER;
}
if (!RegionIsSystemMemory (BaseAddress, Length)) {
return EFI_UNSUPPORTED;
}
return ArmSetMemoryAttributes (BaseAddress, Length, Attributes, Attributes);
}
/**
This function clears given attributes of the memory region specified by
BaseAddress and Length.
The valid Attributes is EFI_MEMORY_RP, EFI_MEMORY_XP, and EFI_MEMORY_RO.
@param This The EFI_MEMORY_ATTRIBUTE_PROTOCOL instance.
@param BaseAddress The physical address that is the start address of
a memory region.
@param Length The size in bytes of the memory region.
@param Attributes The bit mask of attributes to clear for the memory
region.
@retval EFI_SUCCESS The attributes were cleared for the memory region.
@retval EFI_INVALID_PARAMETER Length is zero.
Attributes specified an illegal combination of
attributes that cannot be cleared together.
@retval EFI_UNSUPPORTED The processor does not support one or more
bytes of the memory resource range specified
by BaseAddress and Length.
The bit mask of attributes is not supported for
the memory resource range specified by
BaseAddress and Length.
@retval EFI_OUT_OF_RESOURCES Requested attributes cannot be applied due to
lack of system resources.
@retval EFI_ACCESS_DENIED Attributes for the requested memory region are
controlled by system firmware and cannot be
updated via the protocol.
**/
STATIC
EFI_STATUS
ClearMemoryAttributes (
IN EFI_MEMORY_ATTRIBUTE_PROTOCOL *This,
IN EFI_PHYSICAL_ADDRESS BaseAddress,
IN UINT64 Length,
IN UINT64 Attributes
)
{
DEBUG ((
DEBUG_INFO,
"%a: BaseAddress == 0x%lx, Length == 0x%lx, Attributes == 0x%lx\n",
__func__,
(UINTN)BaseAddress,
(UINTN)Length,
(UINTN)Attributes
));
if ((Length == 0) ||
((Attributes & ~(EFI_MEMORY_RO | EFI_MEMORY_RP | EFI_MEMORY_XP)) != 0))
{
return EFI_INVALID_PARAMETER;
}
if (!RegionIsSystemMemory (BaseAddress, Length)) {
return EFI_UNSUPPORTED;
}
return ArmSetMemoryAttributes (BaseAddress, Length, 0, Attributes);
}
EFI_MEMORY_ATTRIBUTE_PROTOCOL mMemoryAttribute = {
GetMemoryAttributes,
SetMemoryAttributes,
ClearMemoryAttributes
};

View File

@@ -3,7 +3,6 @@
Copyright (c) 2006, Intel Corporation. All rights reserved.<BR> Copyright (c) 2006, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2011 Hewlett Packard Corporation. All rights reserved.<BR> Copyright (c) 2011 Hewlett Packard Corporation. All rights reserved.<BR>
Copyright (c) 2011-2013, ARM Limited. All rights reserved.<BR> Copyright (c) 2011-2013, ARM Limited. All rights reserved.<BR>
Copyright (c) 2023, Google, LLC. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -17,6 +16,8 @@ Abstract:
**/ **/
// //
// The package level header files this module uses // The package level header files this module uses
// //
@@ -25,7 +26,6 @@ Abstract:
// The protocols, PPI and GUID definitions for this module // The protocols, PPI and GUID definitions for this module
// //
#include <Ppi/ArmMpCoreInfo.h> #include <Ppi/ArmMpCoreInfo.h>
#include <Ppi/MemoryAttribute.h>
// //
// The Library classes this module consumes // The Library classes this module consumes
@@ -36,77 +36,6 @@ Abstract:
#include <Library/PcdLib.h> #include <Library/PcdLib.h>
#include <Library/HobLib.h> #include <Library/HobLib.h>
#include <Library/ArmLib.h> #include <Library/ArmLib.h>
#include <Library/ArmMmuLib.h>
/**
Set the requested memory permission attributes on a region of memory.
BaseAddress and Length must be aligned to EFI_PAGE_SIZE.
Attributes must contain a combination of EFI_MEMORY_RP, EFI_MEMORY_RO and
EFI_MEMORY_XP, and specifies the attributes that must be set for the
region in question. Attributes that are omitted will be cleared from the
region only if they are set in AttributeMask.
AttributeMask must contain a combination of EFI_MEMORY_RP, EFI_MEMORY_RO and
EFI_MEMORY_XP, and specifies the attributes that the call will operate on.
AttributeMask must not be 0x0, and must contain at least the bits set in
Attributes.
@param[in] This The protocol instance pointer.
@param[in] BaseAddress The physical address that is the start address
of a memory region.
@param[in] Length The size in bytes of the memory region.
@param[in] Attributes Memory attributes to set or clear.
@param[in] AttributeMask Mask of memory attributes to operate on.
@retval EFI_SUCCESS The attributes were set for the memory region.
@retval EFI_INVALID_PARAMETER Length is zero.
AttributeMask is zero.
AttributeMask lacks bits set in Attributes.
BaseAddress or Length is not suitably aligned.
@retval EFI_UNSUPPORTED The processor does not support one or more
bytes of the memory resource range specified
by BaseAddress and Length.
The bit mask of attributes is not supported for
the memory resource range specified by
BaseAddress and Length.
@retval EFI_OUT_OF_RESOURCES Requested attributes cannot be applied due to
lack of system resources.
**/
STATIC
EFI_STATUS
EFIAPI
SetMemoryPermissions (
IN EDKII_MEMORY_ATTRIBUTE_PPI *This,
IN EFI_PHYSICAL_ADDRESS BaseAddress,
IN UINT64 Length,
IN UINT64 Attributes,
IN UINT64 AttributeMask
)
{
if ((Length == 0) ||
(AttributeMask == 0) ||
((AttributeMask & (EFI_MEMORY_RP | EFI_MEMORY_RO | EFI_MEMORY_XP)) == 0) ||
((Attributes & ~AttributeMask) != 0) ||
(((BaseAddress | Length) & EFI_PAGE_MASK) != 0))
{
return EFI_INVALID_PARAMETER;
}
return ArmSetMemoryAttributes (BaseAddress, Length, Attributes, AttributeMask);
}
STATIC CONST EDKII_MEMORY_ATTRIBUTE_PPI mMemoryAttributePpi = {
SetMemoryPermissions
};
STATIC CONST EFI_PEI_PPI_DESCRIPTOR mMemoryAttributePpiDesc = {
(EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
&gEdkiiMemoryAttributePpiGuid,
(VOID *)&mMemoryAttributePpi
};
/*++ /*++
@@ -141,19 +70,16 @@ InitializeCpuPeim (
BuildCpuHob (ArmGetPhysicalAddressBits (), PcdGet8 (PcdPrePiCpuIoSize)); BuildCpuHob (ArmGetPhysicalAddressBits (), PcdGet8 (PcdPrePiCpuIoSize));
// Only MP Core platform need to produce gArmMpCoreInfoPpiGuid // Only MP Core platform need to produce gArmMpCoreInfoPpiGuid
Status = PeiServicesLocatePpi (&gArmMpCoreInfoPpiGuid, 0, NULL, (VOID **)&ArmMpCoreInfoPpi); Status = PeiServicesLocatePpi (&gArmMpCoreInfoPpiGuid, 0, NULL, (VOID**)&ArmMpCoreInfoPpi);
if (!EFI_ERROR (Status)) { if (!EFI_ERROR(Status)) {
// Build the MP Core Info Table // Build the MP Core Info Table
ArmCoreCount = 0; ArmCoreCount = 0;
Status = ArmMpCoreInfoPpi->GetMpCoreInfo (&ArmCoreCount, &ArmCoreInfoTable); Status = ArmMpCoreInfoPpi->GetMpCoreInfo (&ArmCoreCount, &ArmCoreInfoTable);
if (!EFI_ERROR (Status) && (ArmCoreCount > 0)) { if (!EFI_ERROR(Status) && (ArmCoreCount > 0)) {
// Build MPCore Info HOB // Build MPCore Info HOB
BuildGuidDataHob (&gArmMpCoreInfoGuid, ArmCoreInfoTable, sizeof (ARM_CORE_INFO) * ArmCoreCount); BuildGuidDataHob (&gArmMpCoreInfoGuid, ArmCoreInfoTable, sizeof (ARM_CORE_INFO) * ArmCoreCount);
} }
} }
Status = PeiServicesInstallPpi (&mMemoryAttributePpiDesc);
ASSERT_EFI_ERROR (Status);
return EFI_SUCCESS; return EFI_SUCCESS;
} }

View File

@@ -3,7 +3,6 @@
# #
# This module provides platform specific function to detect boot mode. # This module provides platform specific function to detect boot mode.
# Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR> # Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
# Copyright (c) 2023, Google, LLC. All rights reserved.<BR>
# #
# SPDX-License-Identifier: BSD-2-Clause-Patent # SPDX-License-Identifier: BSD-2-Clause-Patent
# #
@@ -29,7 +28,6 @@
CpuPei.c CpuPei.c
[Packages] [Packages]
MdeModulePkg/MdeModulePkg.dec
MdePkg/MdePkg.dec MdePkg/MdePkg.dec
EmbeddedPkg/EmbeddedPkg.dec EmbeddedPkg/EmbeddedPkg.dec
ArmPkg/ArmPkg.dec ArmPkg/ArmPkg.dec
@@ -39,11 +37,9 @@
DebugLib DebugLib
HobLib HobLib
ArmLib ArmLib
ArmMmuLib
[Ppis] [Ppis]
gArmMpCoreInfoPpiGuid gArmMpCoreInfoPpiGuid
gEdkiiMemoryAttributePpiGuid
[Guids] [Guids]
gArmMpCoreInfoGuid gArmMpCoreInfoGuid

View File

@@ -1,34 +1,24 @@
/** @file /** @file
* *
* Copyright (c) 2023, Ampere Computing LLC. All rights reserved.<BR>
* Copyright (c) 2013-2017, ARM Limited. All rights reserved. * Copyright (c) 2013-2017, ARM Limited. All rights reserved.
* *
* SPDX-License-Identifier: BSD-2-Clause-Patent * SPDX-License-Identifier: BSD-2-Clause-Patent
* *
* @par Reference(s):
* - Generic Watchdog specification in Arm Base System Architecture 1.0C:
* https://developer.arm.com/documentation/den0094/c/
**/ **/
#ifndef __GENERIC_WATCHDOG_H__
#ifndef GENERIC_WATCHDOG_H_ #define __GENERIC_WATCHDOG_H__
#define GENERIC_WATCHDOG_H_
// Refresh Frame: // Refresh Frame:
#define GENERIC_WDOG_REFRESH_REG ((UINTN)FixedPcdGet64 (PcdGenericWatchdogRefreshBase) + 0x000) #define GENERIC_WDOG_REFRESH_REG ((UINTN)FixedPcdGet64 (PcdGenericWatchdogRefreshBase) + 0x000)
// Control Frame: // Control Frame:
#define GENERIC_WDOG_CONTROL_STATUS_REG ((UINTN)FixedPcdGet64 (PcdGenericWatchdogControlBase) + 0x000) #define GENERIC_WDOG_CONTROL_STATUS_REG ((UINTN)FixedPcdGet64 (PcdGenericWatchdogControlBase) + 0x000)
#define GENERIC_WDOG_OFFSET_REG_LOW ((UINTN)FixedPcdGet64 (PcdGenericWatchdogControlBase) + 0x008) #define GENERIC_WDOG_OFFSET_REG ((UINTN)FixedPcdGet64 (PcdGenericWatchdogControlBase) + 0x008)
#define GENERIC_WDOG_OFFSET_REG_HIGH ((UINTN)FixedPcdGet64 (PcdGenericWatchdogControlBase) + 0x00C)
#define GENERIC_WDOG_COMPARE_VALUE_REG_LOW ((UINTN)FixedPcdGet64 (PcdGenericWatchdogControlBase) + 0x010) #define GENERIC_WDOG_COMPARE_VALUE_REG_LOW ((UINTN)FixedPcdGet64 (PcdGenericWatchdogControlBase) + 0x010)
#define GENERIC_WDOG_COMPARE_VALUE_REG_HIGH ((UINTN)FixedPcdGet64 (PcdGenericWatchdogControlBase) + 0x014) #define GENERIC_WDOG_COMPARE_VALUE_REG_HIGH ((UINTN)FixedPcdGet64 (PcdGenericWatchdogControlBase) + 0x014)
#define GENERIC_WDOG_IID_REG ((UINTN)FixedPcdGet64 (PcdGenericWatchdogControlBase) + 0xFCC)
// Values of bit 0 of the Control/Status Register // Values of bit 0 of the Control/Status Register
#define GENERIC_WDOG_ENABLED 1 #define GENERIC_WDOG_ENABLED 1
#define GENERIC_WDOG_DISABLED 0 #define GENERIC_WDOG_DISABLED 0
#define GENERIC_WDOG_IID_ARCH_REV_SHIFT 16 #endif // __GENERIC_WATCHDOG_H__
#define GENERIC_WDOG_IID_ARCH_REV_MASK 0xF
#endif // GENERIC_WATCHDOG_H_

View File

@@ -1,6 +1,5 @@
/** @file /** @file
* *
* Copyright (c) 2023, Ampere Computing LLC. All rights reserved.<BR>
* Copyright (c) 2013-2018, ARM Limited. All rights reserved. * Copyright (c) 2013-2018, ARM Limited. All rights reserved.
* *
* SPDX-License-Identifier: BSD-2-Clause-Patent * SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -28,58 +27,24 @@
in a second */ in a second */
#define TIME_UNITS_PER_SECOND 10000000 #define TIME_UNITS_PER_SECOND 10000000
// Tick frequency of the generic timer basis of the generic watchdog.
STATIC UINTN mTimerFrequencyHz = 0;
/* In cases where the compare register was set manually, information about /* In cases where the compare register was set manually, information about
how long the watchdog was asked to wait cannot be retrieved from hardware. how long the watchdog was asked to wait cannot be retrieved from hardware.
It is therefore stored here. 0 means the timer is not running. */ It is therefore stored here. 0 means the timer is not running. */
STATIC UINT64 mTimerPeriod = 0; STATIC UINT64 mNumTimerTicks = 0;
/* disables watchdog interaction after Exit Boot Services */
STATIC BOOLEAN mExitedBootServices = FALSE;
#define MAX_UINT48 0xFFFFFFFFFFFFULL
STATIC EFI_HARDWARE_INTERRUPT2_PROTOCOL *mInterruptProtocol; STATIC EFI_HARDWARE_INTERRUPT2_PROTOCOL *mInterruptProtocol;
STATIC EFI_WATCHDOG_TIMER_NOTIFY mWatchdogNotify; STATIC EFI_WATCHDOG_TIMER_NOTIFY mWatchdogNotify;
STATIC EFI_EVENT mEfiExitBootServicesEvent;
/**
This function returns the maximum watchdog offset register value.
@retval MAX_UINT32 The watchdog offset register holds a 32-bit value.
@retval MAX_UINT48 The watchdog offset register holds a 48-bit value.
**/
STATIC
UINT64
GetMaxWatchdogOffsetRegisterValue (
VOID
)
{
UINT64 MaxWatchdogOffsetValue;
UINT32 WatchdogIId;
UINT8 WatchdogArchRevision;
WatchdogIId = MmioRead32 (GENERIC_WDOG_IID_REG);
WatchdogArchRevision = (WatchdogIId >> GENERIC_WDOG_IID_ARCH_REV_SHIFT) & GENERIC_WDOG_IID_ARCH_REV_MASK;
if (WatchdogArchRevision == 0) {
MaxWatchdogOffsetValue = MAX_UINT32;
} else {
MaxWatchdogOffsetValue = MAX_UINT48;
}
return MaxWatchdogOffsetValue;
}
STATIC STATIC
VOID VOID
WatchdogWriteOffsetRegister ( WatchdogWriteOffsetRegister (
UINT64 Value UINT32 Value
) )
{ {
MmioWrite32 (GENERIC_WDOG_OFFSET_REG_LOW, Value & MAX_UINT32); MmioWrite32 (GENERIC_WDOG_OFFSET_REG, Value);
if (GetMaxWatchdogOffsetRegisterValue () == MAX_UINT48) {
MmioWrite32 (GENERIC_WDOG_OFFSET_REG_HIGH, (Value >> 32) & MAX_UINT16);
}
} }
STATIC STATIC
@@ -122,8 +87,7 @@ WatchdogExitBootServicesEvent (
) )
{ {
WatchdogDisable (); WatchdogDisable ();
mTimerPeriod = 0; mNumTimerTicks = 0;
mExitedBootServices = TRUE;
} }
/* This function is called when the watchdog's first signal (WS0) goes high. /* This function is called when the watchdog's first signal (WS0) goes high.
@@ -137,7 +101,8 @@ WatchdogInterruptHandler (
IN EFI_SYSTEM_CONTEXT SystemContext IN EFI_SYSTEM_CONTEXT SystemContext
) )
{ {
STATIC CONST CHAR16 ResetString[] = L"The generic watchdog timer ran out."; STATIC CONST CHAR16 ResetString[]= L"The generic watchdog timer ran out.";
UINT64 TimerPeriod;
WatchdogDisable (); WatchdogDisable ();
@@ -150,15 +115,12 @@ WatchdogInterruptHandler (
// the timer period plus 1. // the timer period plus 1.
// //
if (mWatchdogNotify != NULL) { if (mWatchdogNotify != NULL) {
mWatchdogNotify (mTimerPeriod + 1); TimerPeriod = ((TIME_UNITS_PER_SECOND / mTimerFrequencyHz) * mNumTimerTicks);
mWatchdogNotify (TimerPeriod + 1);
} }
gRT->ResetSystem ( gRT->ResetSystem (EfiResetCold, EFI_TIMEOUT, StrSize (ResetString),
EfiResetCold, (CHAR16 *)ResetString);
EFI_TIMEOUT,
StrSize (ResetString),
(CHAR16 *)ResetString
);
// If we got here then the reset didn't work // If we got here then the reset didn't work
ASSERT (FALSE); ASSERT (FALSE);
@@ -196,11 +158,11 @@ WatchdogRegisterHandler (
IN EFI_WATCHDOG_TIMER_NOTIFY NotifyFunction IN EFI_WATCHDOG_TIMER_NOTIFY NotifyFunction
) )
{ {
if ((mWatchdogNotify == NULL) && (NotifyFunction == NULL)) { if (mWatchdogNotify == NULL && NotifyFunction == NULL) {
return EFI_INVALID_PARAMETER; return EFI_INVALID_PARAMETER;
} }
if ((mWatchdogNotify != NULL) && (NotifyFunction != NULL)) { if (mWatchdogNotify != NULL && NotifyFunction != NULL) {
return EFI_ALREADY_STARTED; return EFI_ALREADY_STARTED;
} }
@@ -220,8 +182,6 @@ WatchdogRegisterHandler (
@retval EFI_SUCCESS The watchdog timer has been programmed to fire @retval EFI_SUCCESS The watchdog timer has been programmed to fire
in TimerPeriod 100ns units. in TimerPeriod 100ns units.
@retval EFI_DEVICE_ERROR Boot Services has been exited but TimerPeriod
is not zero.
**/ **/
STATIC STATIC
@@ -233,46 +193,31 @@ WatchdogSetTimerPeriod (
) )
{ {
UINTN SystemCount; UINTN SystemCount;
UINT64 MaxWatchdogOffsetValue;
UINT64 TimerFrequencyHz;
UINT64 NumTimerTicks;
// If we've exited Boot Services but TimerPeriod isn't zero, this // if TimerPeriod is 0, this is a request to stop the watchdog.
// indicates that the caller is doing something wrong.
if (mExitedBootServices && (TimerPeriod != 0)) {
mTimerPeriod = 0;
WatchdogDisable ();
return EFI_DEVICE_ERROR;
}
// If TimerPeriod is 0 this is a request to stop the watchdog.
if (TimerPeriod == 0) { if (TimerPeriod == 0) {
mTimerPeriod = 0; mNumTimerTicks = 0;
WatchdogDisable (); WatchdogDisable ();
return EFI_SUCCESS; return EFI_SUCCESS;
} }
// Work out how many timer ticks will equate to TimerPeriod // Work out how many timer ticks will equate to TimerPeriod
TimerFrequencyHz = ArmGenericTimerGetTimerFreq (); mNumTimerTicks = (mTimerFrequencyHz * TimerPeriod) / TIME_UNITS_PER_SECOND;
ASSERT (TimerFrequencyHz != 0);
mTimerPeriod = TimerPeriod;
NumTimerTicks = (TimerFrequencyHz * TimerPeriod) / TIME_UNITS_PER_SECOND;
/* If the number of required ticks is greater than the max the watchdog's /* If the number of required ticks is greater than the max the watchdog's
offset register (WOR) can hold, we need to manually compute and set offset register (WOR) can hold, we need to manually compute and set
the compare register (WCV) */ the compare register (WCV) */
MaxWatchdogOffsetValue = GetMaxWatchdogOffsetRegisterValue (); if (mNumTimerTicks > MAX_UINT32) {
if (NumTimerTicks > MaxWatchdogOffsetValue) {
/* We need to enable the watchdog *before* writing to the compare register, /* We need to enable the watchdog *before* writing to the compare register,
because enabling the watchdog causes an "explicit refresh", which because enabling the watchdog causes an "explicit refresh", which
clobbers the compare register (WCV). In order to make sure this doesn't clobbers the compare register (WCV). In order to make sure this doesn't
trigger an interrupt, set the offset to max. */ trigger an interrupt, set the offset to max. */
WatchdogWriteOffsetRegister (MaxWatchdogOffsetValue); WatchdogWriteOffsetRegister (MAX_UINT32);
WatchdogEnable (); WatchdogEnable ();
SystemCount = ArmGenericTimerGetSystemCount (); SystemCount = ArmGenericTimerGetSystemCount ();
WatchdogWriteCompareRegister (SystemCount + NumTimerTicks); WatchdogWriteCompareRegister (SystemCount + mNumTimerTicks);
} else { } else {
WatchdogWriteOffsetRegister (NumTimerTicks); WatchdogWriteOffsetRegister ((UINT32)mNumTimerTicks);
WatchdogEnable (); WatchdogEnable ();
} }
@@ -307,7 +252,7 @@ WatchdogGetTimerPeriod (
return EFI_INVALID_PARAMETER; return EFI_INVALID_PARAMETER;
} }
*TimerPeriod = mTimerPeriod; *TimerPeriod = ((TIME_UNITS_PER_SECOND / mTimerFrequencyHz) * mNumTimerTicks);
return EFI_SUCCESS; return EFI_SUCCESS;
} }
@@ -350,6 +295,8 @@ STATIC EFI_WATCHDOG_TIMER_ARCH_PROTOCOL mWatchdogTimer = {
WatchdogGetTimerPeriod WatchdogGetTimerPeriod
}; };
STATIC EFI_EVENT mEfiExitBootServicesEvent;
EFI_STATUS EFI_STATUS
EFIAPI EFIAPI
GenericWatchdogEntry ( GenericWatchdogEntry (
@@ -360,11 +307,8 @@ GenericWatchdogEntry (
EFI_STATUS Status; EFI_STATUS Status;
EFI_HANDLE Handle; EFI_HANDLE Handle;
Status = gBS->LocateProtocol ( Status = gBS->LocateProtocol (&gHardwareInterrupt2ProtocolGuid, NULL,
&gHardwareInterrupt2ProtocolGuid, (VOID **)&mInterruptProtocol);
NULL,
(VOID **)&mInterruptProtocol
);
ASSERT_EFI_ERROR (Status); ASSERT_EFI_ERROR (Status);
/* Make sure the Watchdog Timer Architectural Protocol has not been installed /* Make sure the Watchdog Timer Architectural Protocol has not been installed
@@ -372,57 +316,48 @@ GenericWatchdogEntry (
This will avoid conflicts with the universal watchdog */ This will avoid conflicts with the universal watchdog */
ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiWatchdogTimerArchProtocolGuid); ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiWatchdogTimerArchProtocolGuid);
mTimerFrequencyHz = ArmGenericTimerGetTimerFreq ();
ASSERT (mTimerFrequencyHz != 0);
// Install interrupt handler // Install interrupt handler
Status = mInterruptProtocol->RegisterInterruptSource ( Status = mInterruptProtocol->RegisterInterruptSource (mInterruptProtocol,
mInterruptProtocol,
FixedPcdGet32 (PcdGenericWatchdogEl2IntrNum), FixedPcdGet32 (PcdGenericWatchdogEl2IntrNum),
WatchdogInterruptHandler WatchdogInterruptHandler);
);
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
return Status; return Status;
} }
Status = mInterruptProtocol->SetTriggerType ( Status = mInterruptProtocol->SetTriggerType (mInterruptProtocol,
mInterruptProtocol,
FixedPcdGet32 (PcdGenericWatchdogEl2IntrNum), FixedPcdGet32 (PcdGenericWatchdogEl2IntrNum),
EFI_HARDWARE_INTERRUPT2_TRIGGER_EDGE_RISING EFI_HARDWARE_INTERRUPT2_TRIGGER_EDGE_RISING);
);
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
goto UnregisterHandler; goto UnregisterHandler;
} }
// Install the Timer Architectural Protocol onto a new handle // Install the Timer Architectural Protocol onto a new handle
Handle = NULL; Handle = NULL;
Status = gBS->InstallMultipleProtocolInterfaces ( Status = gBS->InstallMultipleProtocolInterfaces (&Handle,
&Handle, &gEfiWatchdogTimerArchProtocolGuid, &mWatchdogTimer,
&gEfiWatchdogTimerArchProtocolGuid, NULL);
&mWatchdogTimer,
NULL
);
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
goto UnregisterHandler; goto UnregisterHandler;
} }
// Register for an ExitBootServicesEvent // Register for an ExitBootServicesEvent
Status = gBS->CreateEvent ( Status = gBS->CreateEvent (EVT_SIGNAL_EXIT_BOOT_SERVICES, TPL_NOTIFY,
EVT_SIGNAL_EXIT_BOOT_SERVICES, WatchdogExitBootServicesEvent, NULL,
TPL_NOTIFY, &mEfiExitBootServicesEvent);
WatchdogExitBootServicesEvent,
NULL,
&mEfiExitBootServicesEvent
);
ASSERT_EFI_ERROR (Status); ASSERT_EFI_ERROR (Status);
mNumTimerTicks = 0;
WatchdogDisable (); WatchdogDisable ();
return EFI_SUCCESS; return EFI_SUCCESS;
UnregisterHandler: UnregisterHandler:
// Unregister the handler // Unregister the handler
mInterruptProtocol->RegisterInterruptSource ( mInterruptProtocol->RegisterInterruptSource (mInterruptProtocol,
mInterruptProtocol,
FixedPcdGet32 (PcdGenericWatchdogEl2IntrNum), FixedPcdGet32 (PcdGenericWatchdogEl2IntrNum),
NULL NULL);
);
return Status; return Status;
} }

View File

@@ -1,5 +1,5 @@
# #
# Copyright (c) 2013-2021, Arm Limited. All rights reserved.<BR> # Copyright (c) 2013-2017, ARM Limited. All rights reserved.
# #
# SPDX-License-Identifier: BSD-2-Clause-Patent # SPDX-License-Identifier: BSD-2-Clause-Patent
# #
@@ -13,7 +13,6 @@
ENTRY_POINT = GenericWatchdogEntry ENTRY_POINT = GenericWatchdogEntry
[Sources.common] [Sources.common]
GenericWatchdog.h
GenericWatchdogDxe.c GenericWatchdogDxe.c
[Packages] [Packages]

View File

@@ -1,13 +1,13 @@
/** @file /** @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 SPDX-License-Identifier: BSD-2-Clause-Patent
**/ **/
#ifndef MM_COMMUNICATE_H_ #if !defined _MM_COMMUNICATE_H_
#define MM_COMMUNICATE_H_ #define _MM_COMMUNICATE_H_
#define MM_MAJOR_VER_MASK 0xEFFF0000 #define MM_MAJOR_VER_MASK 0xEFFF0000
#define MM_MINOR_VER_MASK 0x0000FFFF #define MM_MINOR_VER_MASK 0x0000FFFF
@@ -19,4 +19,4 @@
#define MM_CALLER_MAJOR_VER 0x1UL #define MM_CALLER_MAJOR_VER 0x1UL
#define MM_CALLER_MINOR_VER 0x0 #define MM_CALLER_MINOR_VER 0x0
#endif /* MM_COMMUNICATE_H_ */ #endif /* _MM_COMMUNICATE_H_ */

View File

@@ -1,6 +1,6 @@
/** @file /** @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 SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -16,7 +16,7 @@
#include <Library/UefiBootServicesTableLib.h> #include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiRuntimeServicesTableLib.h> #include <Library/UefiRuntimeServicesTableLib.h>
#include <Protocol/MmCommunication2.h> #include <Protocol/MmCommunication.h>
#include <IndustryStandard/ArmStdSmc.h> #include <IndustryStandard/ArmStdSmc.h>
@@ -39,39 +39,38 @@ STATIC EFI_HANDLE mMmCommunicateHandle;
/** /**
Communicates with a registered handler. 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] This The EFI_MM_COMMUNICATION_PROTOCOL
@param[in, out] CommBufferPhysical Physical address of the MM communication buffer instance.
@param[in, out] CommBufferVirtual Virtual address of the MM communication buffer @param[in, out] CommBuffer A pointer to the buffer to convey
@param[in, out] CommSize The size of the data buffer being passed in. On input, into MMRAM.
when not omitted, the buffer should cover EFI_MM_COMMUNICATE_HEADER @param[in, out] CommSize The size of the data buffer being
and the value of MessageLength field. On exit, the size passed in. This is optional.
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_SUCCESS The message was successfully posted.
@retval EFI_INVALID_PARAMETER CommBufferPhysical or CommBufferVirtual was NULL, or @retval EFI_INVALID_PARAMETER The CommBuffer was NULL.
integer value pointed by CommSize does not cover @retval EFI_BAD_BUFFER_SIZE The buffer size is incorrect for the MM
EFI_MM_COMMUNICATE_HEADER and the value of MessageLength implementation. If this error is
field. returned, the MessageLength field in
@retval EFI_BAD_BUFFER_SIZE The buffer is too large for the MM implementation. the CommBuffer header or the integer
If this error is returned, the MessageLength field pointed by CommSize are updated to reflect
in the CommBuffer header or the integer pointed by the maximum payload size the
CommSize, are updated to reflect the maximum payload implementation can accommodate.
size the implementation can accommodate. @retval EFI_ACCESS_DENIED The CommunicateBuffer parameter
@retval EFI_ACCESS_DENIED The CommunicateBuffer parameter or CommSize parameter, or CommSize parameter, if not omitted,
if not omitted, are in address range that cannot be are in address range that cannot be
accessed by the MM environment. accessed by the MM environment
**/ **/
STATIC
EFI_STATUS EFI_STATUS
EFIAPI EFIAPI
MmCommunication2Communicate ( MmCommunicationCommunicate (
IN CONST EFI_MM_COMMUNICATION2_PROTOCOL *This, IN CONST EFI_MM_COMMUNICATION_PROTOCOL *This,
IN OUT VOID *CommBufferPhysical, IN OUT VOID *CommBuffer,
IN OUT VOID *CommBufferVirtual,
IN OUT UINTN *CommSize OPTIONAL IN OUT UINTN *CommSize OPTIONAL
) )
{ {
@@ -88,12 +87,11 @@ MmCommunication2Communicate (
// //
// Check parameters // Check parameters
// //
if ((CommBufferVirtual == NULL) || (CommBufferPhysical == NULL)) { if (CommBuffer == NULL) {
return EFI_INVALID_PARAMETER; return EFI_INVALID_PARAMETER;
} }
Status = EFI_SUCCESS; CommunicateHeader = CommBuffer;
CommunicateHeader = CommBufferVirtual;
// CommBuffer is a mandatory parameter. Hence, Rely on // CommBuffer is a mandatory parameter. Hence, Rely on
// MessageLength + Header to ascertain the // MessageLength + Header to ascertain the
// total size of the communication payload rather than // total size of the communication payload rather than
@@ -102,41 +100,33 @@ MmCommunication2Communicate (
sizeof (CommunicateHeader->HeaderGuid) + sizeof (CommunicateHeader->HeaderGuid) +
sizeof (CommunicateHeader->MessageLength); sizeof (CommunicateHeader->MessageLength);
// If CommSize is not omitted, perform size inspection before proceeding. // If the length of the CommBuffer is 0 then return the expected length.
if (CommSize != NULL) { if (CommSize) {
// This case can be used by the consumer of this driver to find out the // This case can be used by the consumer of this driver to find out the
// max size that can be used for allocating CommBuffer. // max size that can be used for allocating CommBuffer.
if ((*CommSize == 0) || if ((*CommSize == 0) ||
(*CommSize > mNsCommBuffMemRegion.Length)) (*CommSize > mNsCommBuffMemRegion.Length)) {
{
*CommSize = mNsCommBuffMemRegion.Length; *CommSize = mNsCommBuffMemRegion.Length;
Status = EFI_BAD_BUFFER_SIZE; return EFI_BAD_BUFFER_SIZE;
} }
// //
// CommSize should cover at least MessageLength + sizeof (EFI_MM_COMMUNICATE_HEADER); // CommSize must match MessageLength + sizeof (EFI_MM_COMMUNICATE_HEADER);
// //
if (*CommSize < BufferSize) { if (*CommSize != BufferSize) {
Status = EFI_INVALID_PARAMETER; return EFI_INVALID_PARAMETER;
} }
} }
// //
// If the message length is 0 or greater than what can be tolerated by the MM // If the buffer size is 0 or greater than what can be tolerated by the MM
// environment then return the expected size. // environment then return the expected size.
// //
if ((CommunicateHeader->MessageLength == 0) || if ((BufferSize == 0) ||
(BufferSize > mNsCommBuffMemRegion.Length)) (BufferSize > mNsCommBuffMemRegion.Length)) {
{
CommunicateHeader->MessageLength = mNsCommBuffMemRegion.Length - CommunicateHeader->MessageLength = mNsCommBuffMemRegion.Length -
sizeof (CommunicateHeader->HeaderGuid) - sizeof (CommunicateHeader->HeaderGuid) -
sizeof (CommunicateHeader->MessageLength); sizeof (CommunicateHeader->MessageLength);
Status = EFI_BAD_BUFFER_SIZE; return EFI_BAD_BUFFER_SIZE;
}
// MessageLength or CommSize check has failed, return here.
if (EFI_ERROR (Status)) {
return Status;
} }
// SMC Function ID // SMC Function ID
@@ -146,7 +136,7 @@ MmCommunication2Communicate (
CommunicateSmcArgs.Arg1 = 0; CommunicateSmcArgs.Arg1 = 0;
// Copy Communication Payload // Copy Communication Payload
CopyMem ((VOID *)mNsCommBuffMemRegion.VirtualBase, CommBufferVirtual, BufferSize); CopyMem ((VOID *)mNsCommBuffMemRegion.VirtualBase, CommBuffer, BufferSize);
// comm_buffer_address (64-bit physical address) // comm_buffer_address (64-bit physical address)
CommunicateSmcArgs.Arg2 = (UINTN)mNsCommBuffMemRegion.PhysicalBase; CommunicateSmcArgs.Arg2 = (UINTN)mNsCommBuffMemRegion.PhysicalBase;
@@ -159,7 +149,7 @@ MmCommunication2Communicate (
switch (CommunicateSmcArgs.Arg0) { switch (CommunicateSmcArgs.Arg0) {
case ARM_SMC_MM_RET_SUCCESS: case ARM_SMC_MM_RET_SUCCESS:
ZeroMem (CommBufferVirtual, BufferSize); ZeroMem (CommBuffer, BufferSize);
// On successful return, the size of data being returned is inferred from // On successful return, the size of data being returned is inferred from
// MessageLength + Header. // MessageLength + Header.
CommunicateHeader = (EFI_MM_COMMUNICATE_HEADER *)mNsCommBuffMemRegion.VirtualBase; CommunicateHeader = (EFI_MM_COMMUNICATE_HEADER *)mNsCommBuffMemRegion.VirtualBase;
@@ -168,7 +158,7 @@ MmCommunication2Communicate (
sizeof (CommunicateHeader->MessageLength); sizeof (CommunicateHeader->MessageLength);
CopyMem ( CopyMem (
CommBufferVirtual, CommBuffer,
(VOID *)mNsCommBuffMemRegion.VirtualBase, (VOID *)mNsCommBuffMemRegion.VirtualBase,
BufferSize BufferSize
); );
@@ -201,8 +191,8 @@ MmCommunication2Communicate (
// //
// MM Communication Protocol instance // MM Communication Protocol instance
// //
STATIC EFI_MM_COMMUNICATION2_PROTOCOL mMmCommunication2 = { EFI_MM_COMMUNICATION_PROTOCOL mMmCommunication = {
MmCommunication2Communicate MmCommunicationCommunicate
}; };
/** /**
@@ -234,19 +224,15 @@ NotifySetVirtualAddressMap (
(VOID **)&mNsCommBuffMemRegion.VirtualBase (VOID **)&mNsCommBuffMemRegion.VirtualBase
); );
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
DEBUG (( DEBUG ((DEBUG_ERROR, "NotifySetVirtualAddressMap():"
DEBUG_ERROR, " Unable to convert MM runtime pointer. Status:0x%r\n", Status));
"NotifySetVirtualAddressMap():"
" Unable to convert MM runtime pointer. Status:0x%r\n",
Status
));
} }
} }
STATIC STATIC
EFI_STATUS EFI_STATUS
GetMmCompatibility ( GetMmCompatibility ()
)
{ {
EFI_STATUS Status; EFI_STATUS Status;
UINT32 MmVersion; UINT32 MmVersion;
@@ -259,32 +245,21 @@ GetMmCompatibility (
MmVersion = MmVersionArgs.Arg0; MmVersion = MmVersionArgs.Arg0;
if ((MM_MAJOR_VER (MmVersion) == MM_CALLER_MAJOR_VER) && if ((MM_MAJOR_VER(MmVersion) == MM_CALLER_MAJOR_VER) &&
(MM_MINOR_VER (MmVersion) >= MM_CALLER_MINOR_VER)) (MM_MINOR_VER(MmVersion) >= MM_CALLER_MINOR_VER)) {
{ DEBUG ((DEBUG_INFO, "MM Version: Major=0x%x, Minor=0x%x\n",
DEBUG (( MM_MAJOR_VER(MmVersion), MM_MINOR_VER(MmVersion)));
DEBUG_INFO,
"MM Version: Major=0x%x, Minor=0x%x\n",
MM_MAJOR_VER (MmVersion),
MM_MINOR_VER (MmVersion)
));
Status = EFI_SUCCESS; Status = EFI_SUCCESS;
} else { } else {
DEBUG (( DEBUG ((DEBUG_ERROR, "Incompatible MM Versions.\n Current Version: Major=0x%x, Minor=0x%x.\n Expected: Major=0x%x, Minor>=0x%x.\n",
DEBUG_ERROR, MM_MAJOR_VER(MmVersion), MM_MINOR_VER(MmVersion), MM_CALLER_MAJOR_VER, MM_CALLER_MINOR_VER));
"Incompatible MM Versions.\n Current Version: Major=0x%x, Minor=0x%x.\n Expected: Major=0x%x, Minor>=0x%x.\n",
MM_MAJOR_VER (MmVersion),
MM_MINOR_VER (MmVersion),
MM_CALLER_MAJOR_VER,
MM_CALLER_MINOR_VER
));
Status = EFI_UNSUPPORTED; Status = EFI_UNSUPPORTED;
} }
return Status; return Status;
} }
STATIC EFI_GUID *CONST mGuidedEventGuid[] = { STATIC EFI_GUID* CONST mGuidedEventGuid[] = {
&gEfiEndOfDxeEventGroupGuid, &gEfiEndOfDxeEventGroupGuid,
&gEfiEventExitBootServicesGuid, &gEfiEventExitBootServicesGuid,
&gEfiEventReadyToBootGuid, &gEfiEventReadyToBootGuid,
@@ -318,7 +293,7 @@ MmGuidedEventNotify (
Header.Data[0] = 0; Header.Data[0] = 0;
Size = sizeof (Header); Size = sizeof (Header);
MmCommunication2Communicate (&mMmCommunication2, &Header, &Header, &Size); MmCommunicationCommunicate (&mMmCommunication, &Header, &Size);
} }
/** /**
@@ -337,7 +312,7 @@ MmGuidedEventNotify (
**/ **/
EFI_STATUS EFI_STATUS
EFIAPI EFIAPI
MmCommunication2Initialize ( MmCommunicationInitialize (
IN EFI_HANDLE ImageHandle, IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable IN EFI_SYSTEM_TABLE *SystemTable
) )
@@ -347,7 +322,7 @@ MmCommunication2Initialize (
// Check if we can make the MM call // Check if we can make the MM call
Status = GetMmCompatibility (); Status = GetMmCompatibility ();
if (EFI_ERROR (Status)) { if (EFI_ERROR(Status)) {
goto ReturnErrorStatus; goto ReturnErrorStatus;
} }
@@ -369,11 +344,8 @@ MmCommunication2Initialize (
EFI_MEMORY_RUNTIME EFI_MEMORY_RUNTIME
); );
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
DEBUG (( DEBUG ((DEBUG_ERROR, "MmCommunicateInitialize: "
DEBUG_ERROR, "Failed to add MM-NS Buffer Memory Space\n"));
"MmCommunicateInitialize: "
"Failed to add MM-NS Buffer Memory Space\n"
));
goto ReturnErrorStatus; goto ReturnErrorStatus;
} }
@@ -383,27 +355,21 @@ MmCommunication2Initialize (
EFI_MEMORY_WB | EFI_MEMORY_XP | EFI_MEMORY_RUNTIME EFI_MEMORY_WB | EFI_MEMORY_XP | EFI_MEMORY_RUNTIME
); );
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
DEBUG (( DEBUG ((DEBUG_ERROR, "MmCommunicateInitialize: "
DEBUG_ERROR, "Failed to set MM-NS Buffer Memory attributes\n"));
"MmCommunicateInitialize: "
"Failed to set MM-NS Buffer Memory attributes\n"
));
goto CleanAddedMemorySpace; goto CleanAddedMemorySpace;
} }
// Install the communication protocol // Install the communication protocol
Status = gBS->InstallProtocolInterface ( Status = gBS->InstallProtocolInterface (
&mMmCommunicateHandle, &mMmCommunicateHandle,
&gEfiMmCommunication2ProtocolGuid, &gEfiMmCommunicationProtocolGuid,
EFI_NATIVE_INTERFACE, EFI_NATIVE_INTERFACE,
&mMmCommunication2 &mMmCommunication
); );
if (EFI_ERROR (Status)) { if (EFI_ERROR(Status)) {
DEBUG (( DEBUG ((DEBUG_ERROR, "MmCommunicationInitialize: "
DEBUG_ERROR, "Failed to install MM communication protocol\n"));
"MmCommunicationInitialize: "
"Failed to install MM communication protocol\n"
));
goto CleanAddedMemorySpace; goto CleanAddedMemorySpace;
} }
@@ -420,31 +386,16 @@ MmCommunication2Initialize (
ASSERT_EFI_ERROR (Status); ASSERT_EFI_ERROR (Status);
for (Index = 0; Index < ARRAY_SIZE (mGuidedEventGuid); Index++) { for (Index = 0; Index < ARRAY_SIZE (mGuidedEventGuid); Index++) {
Status = gBS->CreateEventEx ( Status = gBS->CreateEventEx (EVT_NOTIFY_SIGNAL, TPL_CALLBACK,
EVT_NOTIFY_SIGNAL, MmGuidedEventNotify, mGuidedEventGuid[Index],
TPL_CALLBACK, mGuidedEventGuid[Index], &mGuidedEvent[Index]);
MmGuidedEventNotify,
mGuidedEventGuid[Index],
mGuidedEventGuid[Index],
&mGuidedEvent[Index]
);
ASSERT_EFI_ERROR (Status); ASSERT_EFI_ERROR (Status);
if (EFI_ERROR (Status)) {
while (Index-- > 0) {
gBS->CloseEvent (mGuidedEvent[Index]);
} }
goto UninstallProtocol;
}
}
return EFI_SUCCESS;
UninstallProtocol:
gBS->UninstallProtocolInterface ( gBS->UninstallProtocolInterface (
mMmCommunicateHandle, mMmCommunicateHandle,
&gEfiMmCommunication2ProtocolGuid, &gEfiMmCommunicationProtocolGuid,
&mMmCommunication2 &mMmCommunication
); );
CleanAddedMemorySpace: CleanAddedMemorySpace:

View File

@@ -2,7 +2,7 @@
# #
# DXE MM Communicate driver # DXE MM Communicate driver
# #
# 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 # SPDX-License-Identifier: BSD-2-Clause-Patent
# #
@@ -14,7 +14,7 @@
FILE_GUID = 09EE81D3-F15E-43F4-85B4-CB9873DA5D6B FILE_GUID = 09EE81D3-F15E-43F4-85B4-CB9873DA5D6B
MODULE_TYPE = DXE_RUNTIME_DRIVER MODULE_TYPE = DXE_RUNTIME_DRIVER
VERSION_STRING = 1.0 VERSION_STRING = 1.0
ENTRY_POINT = MmCommunication2Initialize ENTRY_POINT = MmCommunicationInitialize
# #
# The following is for reference only and not required by # The following is for reference only and not required by
@@ -24,7 +24,6 @@
# #
[Sources.AARCH64] [Sources.AARCH64]
MmCommunicate.h
MmCommunication.c MmCommunication.c
[Packages] [Packages]
@@ -41,7 +40,7 @@
UefiDriverEntryPoint UefiDriverEntryPoint
[Protocols] [Protocols]
gEfiMmCommunication2ProtocolGuid ## PRODUCES gEfiMmCommunicationProtocolGuid ## PRODUCES
[Guids] [Guids]
gEfiEndOfDxeEventGroupGuid gEfiEndOfDxeEventGroupGuid

View File

@@ -1,221 +0,0 @@
/** @file -- MmCommunicationPei.c
Provides an interface to send MM request in PEI
Copyright (c) 2016-2021, Arm Limited. All rights reserved.<BR>
Copyright (c) Microsoft Corporation.
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include <PiPei.h>
#include <IndustryStandard/ArmStdSmc.h>
#include <Protocol/MmCommunication.h>
#include <Ppi/MmCommunication.h>
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/ArmSmcLib.h>
#include <Library/DebugLib.h>
#include <Library/PcdLib.h>
#include <Library/PeimEntryPoint.h>
#include <Library/PeiServicesLib.h>
/**
MmCommunicationPeim
Communicates with a registered handler.
This function provides a service to send and receive messages from a registered UEFI service during PEI.
@param[in] This The EFI_PEI_MM_COMMUNICATION_PPI instance.
@param[in, out] CommBuffer Pointer to the data buffer
@param[in, out] 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.
@retval EFI_SUCCESS The message was successfully posted.
@retval EFI_INVALID_PARAMETER CommBuffer or CommSize was NULL, or *CommSize does not
match MessageLength + sizeof (EFI_MM_COMMUNICATE_HEADER).
@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.
**/
STATIC
EFI_STATUS
EFIAPI
MmCommunicationPeim (
IN CONST EFI_PEI_MM_COMMUNICATION_PPI *This,
IN OUT VOID *CommBuffer,
IN OUT UINTN *CommSize
)
{
EFI_MM_COMMUNICATE_HEADER *CommunicateHeader;
EFI_MM_COMMUNICATE_HEADER *TempCommHeader;
ARM_SMC_ARGS CommunicateSmcArgs;
EFI_STATUS Status;
UINTN BufferSize;
ZeroMem (&CommunicateSmcArgs, sizeof (ARM_SMC_ARGS));
// Check that our static buffer is looking good.
// We are using PcdMmBufferBase to transfer variable data.
// We are not using the full size of the buffer since there is a cost
// of copying data between Normal and Secure World.
if ((PcdGet64 (PcdMmBufferBase) == 0) || (PcdGet64 (PcdMmBufferSize) == 0)) {
ASSERT (PcdGet64 (PcdMmBufferSize) > 0);
ASSERT (PcdGet64 (PcdMmBufferBase) != 0);
return EFI_UNSUPPORTED;
}
//
// Check parameters
//
if ((CommBuffer == NULL) || (CommSize == NULL)) {
ASSERT (CommBuffer != NULL);
ASSERT (CommSize != NULL);
return EFI_INVALID_PARAMETER;
}
// If the length of the CommBuffer is 0 then return the expected length.
// 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) || (*CommSize > (UINTN)PcdGet64 (PcdMmBufferSize))) {
DEBUG ((
DEBUG_ERROR,
"%a Invalid CommSize value 0x%llx!\n",
__func__,
*CommSize
));
*CommSize = (UINTN)PcdGet64 (PcdMmBufferSize);
return EFI_BAD_BUFFER_SIZE;
}
// Given CommBuffer is not NULL here, we use it to test the legitimacy of CommSize.
TempCommHeader = (EFI_MM_COMMUNICATE_HEADER *)(UINTN)CommBuffer;
// CommBuffer is a mandatory parameter. Hence, Rely on
// MessageLength + Header to ascertain the
// total size of the communication payload rather than
// rely on optional CommSize parameter
BufferSize = TempCommHeader->MessageLength +
sizeof (TempCommHeader->HeaderGuid) +
sizeof (TempCommHeader->MessageLength);
//
// If CommSize is supplied it must match MessageLength + sizeof (EFI_MM_COMMUNICATE_HEADER);
//
if (*CommSize != BufferSize) {
DEBUG ((
DEBUG_ERROR,
"%a Unexpected CommSize value, has: 0x%llx vs. expected: 0x%llx!\n",
__func__,
*CommSize,
BufferSize
));
return EFI_INVALID_PARAMETER;
}
// Now we know that the size is something we can handle, copy it over to the designated comm buffer.
CommunicateHeader = (EFI_MM_COMMUNICATE_HEADER *)(UINTN)(PcdGet64 (PcdMmBufferBase));
CopyMem (CommunicateHeader, CommBuffer, *CommSize);
// SMC Function ID
CommunicateSmcArgs.Arg0 = ARM_SMC_ID_MM_COMMUNICATE_AARCH64;
// Cookie
CommunicateSmcArgs.Arg1 = 0;
// comm_buffer_address (64-bit physical address)
CommunicateSmcArgs.Arg2 = (UINTN)CommunicateHeader;
// comm_size_address (not used, indicated by setting to zero)
CommunicateSmcArgs.Arg3 = 0;
// Call the Standalone MM environment.
ArmCallSmc (&CommunicateSmcArgs);
switch (CommunicateSmcArgs.Arg0) {
case ARM_SMC_MM_RET_SUCCESS:
// On successful return, the size of data being returned is inferred from
// MessageLength + Header.
BufferSize = CommunicateHeader->MessageLength +
sizeof (CommunicateHeader->HeaderGuid) +
sizeof (CommunicateHeader->MessageLength);
if (BufferSize > (UINTN)PcdGet64 (PcdMmBufferSize)) {
// Something bad has happened, we should have landed in ARM_SMC_MM_RET_NO_MEMORY
DEBUG ((
DEBUG_ERROR,
"%a Returned buffer exceeds communication buffer limit. Has: 0x%llx vs. max: 0x%llx!\n",
__func__,
BufferSize,
(UINTN)PcdGet64 (PcdMmBufferSize)
));
Status = EFI_BAD_BUFFER_SIZE;
break;
}
CopyMem (CommBuffer, CommunicateHeader, BufferSize);
*CommSize = BufferSize;
Status = EFI_SUCCESS;
break;
case ARM_SMC_MM_RET_INVALID_PARAMS:
Status = EFI_INVALID_PARAMETER;
break;
case ARM_SMC_MM_RET_DENIED:
Status = EFI_ACCESS_DENIED;
break;
case ARM_SMC_MM_RET_NO_MEMORY:
// Unexpected error since the CommSize was checked for zero length
// prior to issuing the SMC
Status = EFI_OUT_OF_RESOURCES;
ASSERT (0);
break;
default:
Status = EFI_ACCESS_DENIED;
ASSERT (0);
break;
}
return Status;
}
//
// Module globals for the MM Communication PPI
//
STATIC CONST EFI_PEI_MM_COMMUNICATION_PPI mPeiMmCommunication = {
MmCommunicationPeim
};
STATIC CONST EFI_PEI_PPI_DESCRIPTOR mPeiMmCommunicationPpi = {
(EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
&gEfiPeiMmCommunicationPpiGuid,
(VOID *)&mPeiMmCommunication
};
/**
Entry point of PEI MM Communication driver
@param FileHandle Handle of the file being invoked.
Type EFI_PEI_FILE_HANDLE is defined in FfsFindNextFile().
@param PeiServices General purpose services available to every PEIM.
@retval EFI_SUCCESS If the interface could be successfully installed
@retval Others Returned from PeiServicesInstallPpi()
**/
EFI_STATUS
EFIAPI
MmCommunicationPeiInitialize (
IN EFI_PEI_FILE_HANDLE FileHandle,
IN CONST EFI_PEI_SERVICES **PeiServices
)
{
return PeiServicesInstallPpi (&mPeiMmCommunicationPpi);
}

View File

@@ -1,40 +0,0 @@
## @file -- MmCommunicationPei.inf
# PEI MM Communicate driver
#
# Copyright (c) 2016 - 2021, Arm Limited. All rights reserved.<BR>
# Copyright (c) Microsoft Corporation.
# SPDX-License-Identifier: BSD-2-Clause-Patent
##
[Defines]
INF_VERSION = 0x0001001B
BASE_NAME = MmCommunicationPei
FILE_GUID = 58FFB346-1B75-42C7-AD69-37C652423C1A
MODULE_TYPE = PEIM
VERSION_STRING = 1.0
ENTRY_POINT = MmCommunicationPeiInitialize
[Sources]
MmCommunicationPei.c
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
ArmPkg/ArmPkg.dec
[LibraryClasses]
DebugLib
ArmSmcLib
PeimEntryPoint
PeiServicesLib
HobLib
[Pcd]
gArmTokenSpaceGuid.PcdMmBufferBase
gArmTokenSpaceGuid.PcdMmBufferSize
[Ppis]
gEfiPeiMmCommunicationPpiGuid ## PRODUCES
[Depex]
TRUE

View File

@@ -1,12 +1,13 @@
/** @file /** @file
Timer Architecture Protocol driver of the ARM flavor 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 SPDX-License-Identifier: BSD-2-Clause-Patent
**/ **/
#include <PiDxe.h> #include <PiDxe.h>
#include <Library/ArmLib.h> #include <Library/ArmLib.h>
@@ -304,8 +305,9 @@ TimerInterruptHandler (
gInterrupt->EndOfInterrupt (gInterrupt, Source); gInterrupt->EndOfInterrupt (gInterrupt, Source);
// Check if the timer interrupt is active // Check if the timer interrupt is active
if ((ArmGenericTimerGetTimerCtrlReg ()) & ARM_ARCH_TIMER_ISTATUS) { if ((ArmGenericTimerGetTimerCtrlReg () ) & ARM_ARCH_TIMER_ISTATUS) {
if (mTimerNotifyFunction != 0) {
if (mTimerNotifyFunction) {
mTimerNotifyFunction (mTimerPeriod * mElapsedPeriod); mTimerNotifyFunction (mTimerPeriod * mElapsedPeriod);
} }
@@ -336,6 +338,7 @@ TimerInterruptHandler (
gBS->RestoreTPL (OriginalTPL); gBS->RestoreTPL (OriginalTPL);
} }
/** /**
Initialize the state information for the Timer Architectural Protocol and Initialize the state information for the Timer Architectural Protocol and
the Timer Debug support protocol that allows the debugger to break into a the Timer Debug support protocol that allows the debugger to break into a
@@ -356,7 +359,7 @@ TimerInitialize (
IN EFI_SYSTEM_TABLE *SystemTable IN EFI_SYSTEM_TABLE *SystemTable
) )
{ {
EFI_HANDLE Handle; EFI_HANDLE Handle = NULL;
EFI_STATUS Status; EFI_STATUS Status;
UINTN TimerCtrlReg; UINTN TimerCtrlReg;
UINT32 TimerHypIntrNum; UINT32 TimerHypIntrNum;
@@ -402,18 +405,16 @@ TimerInitialize (
ASSERT_EFI_ERROR (Status); ASSERT_EFI_ERROR (Status);
// Set up default timer // Set up default timer
Status = TimerDriverSetTimerPeriod (&gTimer, FixedPcdGet32 (PcdTimerPeriod)); // TIMER_DEFAULT_PERIOD Status = TimerDriverSetTimerPeriod (&gTimer, FixedPcdGet32(PcdTimerPeriod)); // TIMER_DEFAULT_PERIOD
ASSERT_EFI_ERROR (Status); ASSERT_EFI_ERROR (Status);
Handle = NULL;
// Install the Timer Architectural Protocol onto a new handle // Install the Timer Architectural Protocol onto a new handle
Status = gBS->InstallMultipleProtocolInterfaces ( Status = gBS->InstallMultipleProtocolInterfaces(
&Handle, &Handle,
&gEfiTimerArchProtocolGuid, &gEfiTimerArchProtocolGuid, &gTimer,
&gTimer,
NULL NULL
); );
ASSERT_EFI_ERROR (Status); ASSERT_EFI_ERROR(Status);
// Everything is ready, unmask and enable timer interrupts // Everything is ready, unmask and enable timer interrupts
TimerCtrlReg = ARM_ARCH_TIMER_ENABLE; TimerCtrlReg = ARM_ARCH_TIMER_ENABLE;

View File

@@ -2,7 +2,7 @@
Support a Semi Host file system over a debuggers JTAG Support a Semi Host file system over a debuggers JTAG
Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR> 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 SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -51,7 +51,7 @@ EFI_FILE gSemihostFsFile = {
}; };
// //
// Device path for semi-hosting. It contains our auto-generated Caller ID GUID. // Device path for semi-hosting. It contains our autogened Caller ID GUID.
// //
typedef struct { typedef struct {
VENDOR_DEVICE_PATH Guid; VENDOR_DEVICE_PATH Guid;
@@ -60,12 +60,10 @@ typedef struct {
SEMIHOST_DEVICE_PATH gDevicePath = { SEMIHOST_DEVICE_PATH gDevicePath = {
{ {
{ HARDWARE_DEVICE_PATH, HW_VENDOR_DP, { sizeof (VENDOR_DEVICE_PATH), 0 } { HARDWARE_DEVICE_PATH, HW_VENDOR_DP, { sizeof (VENDOR_DEVICE_PATH), 0 } },
},
EFI_CALLER_ID_GUID EFI_CALLER_ID_GUID
}, },
{ END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE, { sizeof (EFI_DEVICE_PATH_PROTOCOL), 0 } { END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE, { sizeof (EFI_DEVICE_PATH_PROTOCOL), 0 } }
}
}; };
typedef struct { typedef struct {
@@ -92,9 +90,8 @@ AllocateFCB (
VOID VOID
) )
{ {
SEMIHOST_FCB *Fcb; SEMIHOST_FCB *Fcb = AllocateZeroPool (sizeof (SEMIHOST_FCB));
Fcb = AllocateZeroPool (sizeof (SEMIHOST_FCB));
if (Fcb != NULL) { if (Fcb != NULL) {
CopyMem (&Fcb->File, &gSemihostFsFile, sizeof (gSemihostFsFile)); CopyMem (&Fcb->File, &gSemihostFsFile, sizeof (gSemihostFsFile));
Fcb->Signature = SEMIHOST_FCB_SIGNATURE; Fcb->Signature = SEMIHOST_FCB_SIGNATURE;
@@ -117,13 +114,15 @@ FreeFCB (
FreePool (Fcb); FreePool (Fcb);
} }
EFI_STATUS EFI_STATUS
VolumeOpen ( VolumeOpen (
IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *This, IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *This,
OUT EFI_FILE **Root OUT EFI_FILE **Root
) )
{ {
SEMIHOST_FCB *RootFcb; SEMIHOST_FCB *RootFcb = NULL;
if (Root == NULL) { if (Root == NULL) {
return EFI_INVALID_PARAMETER; return EFI_INVALID_PARAMETER;
@@ -191,16 +190,14 @@ FileOpen (
return EFI_INVALID_PARAMETER; return EFI_INVALID_PARAMETER;
} }
if ((OpenMode != EFI_FILE_MODE_READ) && if ( (OpenMode != EFI_FILE_MODE_READ) &&
(OpenMode != (EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE)) && (OpenMode != (EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE)) &&
(OpenMode != (EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE))) (OpenMode != (EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE)) ) {
{
return EFI_INVALID_PARAMETER; return EFI_INVALID_PARAMETER;
} }
if (((OpenMode & EFI_FILE_MODE_CREATE) != 0) && if ((OpenMode & EFI_FILE_MODE_CREATE) &&
((Attributes & EFI_FILE_DIRECTORY) != 0)) (Attributes & EFI_FILE_DIRECTORY) ) {
{
return EFI_WRITE_PROTECTED; return EFI_WRITE_PROTECTED;
} }
@@ -209,15 +206,13 @@ FileOpen (
if (AsciiFileName == NULL) { if (AsciiFileName == NULL) {
return EFI_OUT_OF_RESOURCES; return EFI_OUT_OF_RESOURCES;
} }
UnicodeStrToAsciiStrS (FileName, AsciiFileName, Length); UnicodeStrToAsciiStrS (FileName, AsciiFileName, Length);
// Opening '/', '\', '.', or the NULL pathname is trying to open the root directory // Opening '/', '\', '.', or the NULL pathname is trying to open the root directory
if ((AsciiStrCmp (AsciiFileName, "\\") == 0) || if ((AsciiStrCmp (AsciiFileName, "\\") == 0) ||
(AsciiStrCmp (AsciiFileName, "/") == 0) || (AsciiStrCmp (AsciiFileName, "/") == 0) ||
(AsciiStrCmp (AsciiFileName, "") == 0) || (AsciiStrCmp (AsciiFileName, "") == 0) ||
(AsciiStrCmp (AsciiFileName, ".") == 0)) (AsciiStrCmp (AsciiFileName, ".") == 0) ) {
{
FreePool (AsciiFileName); FreePool (AsciiFileName);
return (VolumeOpen (&gSemihostFs, NewHandle)); return (VolumeOpen (&gSemihostFs, NewHandle));
} }
@@ -236,11 +231,10 @@ FileOpen (
} else { } else {
SemihostMode = SEMIHOST_FILE_MODE_READ | SEMIHOST_FILE_MODE_BINARY | SEMIHOST_FILE_MODE_UPDATE; SemihostMode = SEMIHOST_FILE_MODE_READ | SEMIHOST_FILE_MODE_BINARY | SEMIHOST_FILE_MODE_UPDATE;
} }
Return = SemihostFileOpen (AsciiFileName, SemihostMode, &SemihostHandle); Return = SemihostFileOpen (AsciiFileName, SemihostMode, &SemihostHandle);
if (RETURN_ERROR (Return)) { 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 // 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 // mode failed, create it and open it in update mode. The update
@@ -283,8 +277,7 @@ FileOpen (
FileFcb->Info.FileSize = Length; FileFcb->Info.FileSize = Length;
FileFcb->Info.PhysicalSize = Length; FileFcb->Info.PhysicalSize = Length;
FileFcb->Info.Attribute = ((OpenMode & EFI_FILE_MODE_CREATE) != 0) ? FileFcb->Info.Attribute = (OpenMode & EFI_FILE_MODE_CREATE) ? Attributes : 0;
Attributes : 0;
InsertTailList (&gFileList, &FileFcb->Link); InsertTailList (&gFileList, &FileFcb->Link);
@@ -351,7 +344,6 @@ TruncateFile (
if (RETURN_ERROR (Return)) { if (RETURN_ERROR (Return)) {
goto Error; goto Error;
} }
Remaining -= ToRead; Remaining -= ToRead;
Read += ToRead; Read += ToRead;
} }
@@ -385,12 +377,12 @@ Error:
if (FileHandle != 0) { if (FileHandle != 0) {
SemihostFileClose (FileHandle); SemihostFileClose (FileHandle);
} }
if (Buffer != NULL) { if (Buffer != NULL) {
FreePool (Buffer); FreePool (Buffer);
} }
return (Status); return (Status);
} }
/** /**
@@ -414,7 +406,7 @@ FileClose (
return EFI_INVALID_PARAMETER; return EFI_INVALID_PARAMETER;
} }
Fcb = SEMIHOST_FCB_FROM_THIS (This); Fcb = SEMIHOST_FCB_FROM_THIS(This);
if (!Fcb->IsRoot) { if (!Fcb->IsRoot) {
SemihostFileClose (Fcb->SemihostHandle); SemihostFileClose (Fcb->SemihostHandle);
@@ -426,7 +418,6 @@ FileClose (
if (Fcb->Info.FileSize < Fcb->Info.PhysicalSize) { if (Fcb->Info.FileSize < Fcb->Info.PhysicalSize) {
TruncateFile (Fcb->FileName, Fcb->Info.FileSize); TruncateFile (Fcb->FileName, Fcb->Info.FileSize);
} }
FreePool (Fcb->FileName); FreePool (Fcb->FileName);
} }
@@ -478,7 +469,6 @@ FileDelete (
if (RETURN_ERROR (Return)) { if (RETURN_ERROR (Return)) {
return EFI_WARN_DELETE_FAILURE; return EFI_WARN_DELETE_FAILURE;
} }
return EFI_SUCCESS; return EFI_SUCCESS;
} else { } else {
return EFI_WARN_DELETE_FAILURE; return EFI_WARN_DELETE_FAILURE;
@@ -574,15 +564,14 @@ ExtendFile (
} }
Remaining = Size; Remaining = Size;
ZeroMem (WriteBuffer, sizeof (WriteBuffer)); SetMem (WriteBuffer, 0, sizeof(WriteBuffer));
while (Remaining > 0) { while (Remaining > 0) {
WriteNb = MIN (Remaining, sizeof (WriteBuffer)); WriteNb = MIN (Remaining, sizeof(WriteBuffer));
WriteSize = WriteNb; WriteSize = WriteNb;
Return = SemihostFileWrite (Fcb->SemihostHandle, &WriteSize, WriteBuffer); Return = SemihostFileWrite (Fcb->SemihostHandle, &WriteSize, WriteBuffer);
if (RETURN_ERROR (Return)) { if (RETURN_ERROR (Return)) {
return EFI_DEVICE_ERROR; return EFI_DEVICE_ERROR;
} }
Remaining -= WriteNb; Remaining -= WriteNb;
} }
@@ -626,9 +615,8 @@ FileWrite (
Fcb = SEMIHOST_FCB_FROM_THIS (This); Fcb = SEMIHOST_FCB_FROM_THIS (This);
// We cannot write a read-only file // We cannot write a read-only file
if ( (Fcb->Info.Attribute & EFI_FILE_READ_ONLY) if ((Fcb->Info.Attribute & EFI_FILE_READ_ONLY)
|| !(Fcb->OpenMode & EFI_FILE_MODE_WRITE)) || !(Fcb->OpenMode & EFI_FILE_MODE_WRITE)) {
{
return EFI_ACCESS_DENIED; return EFI_ACCESS_DENIED;
} }
@@ -642,7 +630,6 @@ FileWrite (
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
return Status; return Status;
} }
Fcb->Info.FileSize = Fcb->Position; Fcb->Info.FileSize = Fcb->Position;
} }
@@ -661,7 +648,6 @@ FileWrite (
if (RETURN_ERROR (Return)) { if (RETURN_ERROR (Return)) {
return EFI_DEVICE_ERROR; return EFI_DEVICE_ERROR;
} }
Fcb->Info.PhysicalSize = Length; Fcb->Info.PhysicalSize = Length;
return EFI_SUCCESS; return EFI_SUCCESS;
@@ -690,7 +676,7 @@ FileGetPosition (
return EFI_INVALID_PARAMETER; return EFI_INVALID_PARAMETER;
} }
Fcb = SEMIHOST_FCB_FROM_THIS (This); Fcb = SEMIHOST_FCB_FROM_THIS(This);
*Position = Fcb->Position; *Position = Fcb->Position;
@@ -730,7 +716,8 @@ FileSetPosition (
if (Position != 0) { if (Position != 0) {
return EFI_UNSUPPORTED; return EFI_UNSUPPORTED;
} }
} else { }
else {
// //
// UEFI Spec section 12.5: // UEFI Spec section 12.5:
// "Seeking to position 0xFFFFFFFFFFFFFFFF causes the current position to // "Seeking to position 0xFFFFFFFFFFFFFFFF causes the current position to
@@ -739,7 +726,6 @@ FileSetPosition (
if (Position == 0xFFFFFFFFFFFFFFFF) { if (Position == 0xFFFFFFFFFFFFFFFF) {
Position = Fcb->Info.FileSize; Position = Fcb->Info.FileSize;
} }
Return = SemihostFileSeek (Fcb->SemihostHandle, MIN (Position, Fcb->Info.FileSize)); Return = SemihostFileSeek (Fcb->SemihostHandle, MIN (Position, Fcb->Info.FileSize));
if (RETURN_ERROR (Return)) { if (RETURN_ERROR (Return)) {
return EFI_DEVICE_ERROR; return EFI_DEVICE_ERROR;
@@ -772,14 +758,13 @@ GetFileInfo (
OUT VOID *Buffer OUT VOID *Buffer
) )
{ {
EFI_FILE_INFO *Info; EFI_FILE_INFO *Info = NULL;
UINTN NameSize; UINTN NameSize = 0;
UINTN ResultSize; UINTN ResultSize;
UINTN Index; UINTN Index;
if (Fcb->IsRoot) { if (Fcb->IsRoot == TRUE) {
NameSize = 0; ResultSize = SIZE_OF_EFI_FILE_INFO + sizeof(CHAR16);
ResultSize = SIZE_OF_EFI_FILE_INFO + sizeof (CHAR16);
} else { } else {
NameSize = AsciiStrLen (Fcb->FileName) + 1; NameSize = AsciiStrLen (Fcb->FileName) + 1;
ResultSize = SIZE_OF_EFI_FILE_INFO + NameSize * sizeof (CHAR16); ResultSize = SIZE_OF_EFI_FILE_INFO + NameSize * sizeof (CHAR16);
@@ -798,7 +783,7 @@ GetFileInfo (
// Fill in the structure // Fill in the structure
Info->Size = ResultSize; Info->Size = ResultSize;
if (Fcb->IsRoot) { if (Fcb->IsRoot == TRUE) {
Info->FileName[0] = L'\0'; Info->FileName[0] = L'\0';
} else { } else {
for (Index = 0; Index < NameSize; Index++) { for (Index = 0; Index < NameSize; Index++) {
@@ -901,12 +886,11 @@ FileGetInfo (
if ((This == NULL) || if ((This == NULL) ||
(InformationType == NULL) || (InformationType == NULL) ||
(BufferSize == NULL) || (BufferSize == NULL) ||
((Buffer == NULL) && (*BufferSize > 0))) ((Buffer == NULL) && (*BufferSize > 0)) ) {
{
return EFI_INVALID_PARAMETER; return EFI_INVALID_PARAMETER;
} }
Fcb = SEMIHOST_FCB_FROM_THIS (This); Fcb = SEMIHOST_FCB_FROM_THIS(This);
if (CompareGuid (InformationType, &gEfiFileSystemInfoGuid)) { if (CompareGuid (InformationType, &gEfiFileSystemInfoGuid)) {
Status = GetFilesystemInfo (Fcb, BufferSize, Buffer); Status = GetFilesystemInfo (Fcb, BufferSize, Buffer);
@@ -981,7 +965,6 @@ SetFileInfo (
if (AsciiFileName == NULL) { if (AsciiFileName == NULL) {
return EFI_OUT_OF_RESOURCES; return EFI_OUT_OF_RESOURCES;
} }
UnicodeStrToAsciiStrS (Info->FileName, AsciiFileName, Length); UnicodeStrToAsciiStrS (Info->FileName, AsciiFileName, Length);
FileSizeIsDifferent = (Info->FileSize != Fcb->Info.FileSize); FileSizeIsDifferent = (Info->FileSize != Fcb->Info.FileSize);
@@ -999,8 +982,7 @@ SetFileInfo (
// description. // description.
// //
if ((Fcb->OpenMode == EFI_FILE_MODE_READ) || if ((Fcb->OpenMode == EFI_FILE_MODE_READ) ||
(Fcb->Info.Attribute & EFI_FILE_READ_ONLY)) (Fcb->Info.Attribute & EFI_FILE_READ_ONLY) ) {
{
if (FileSizeIsDifferent || FileNameIsDifferent || ReadOnlyIsDifferent) { if (FileSizeIsDifferent || FileNameIsDifferent || ReadOnlyIsDifferent) {
Status = EFI_ACCESS_DENIED; Status = EFI_ACCESS_DENIED;
goto Error; goto Error;
@@ -1021,7 +1003,6 @@ SetFileInfo (
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
goto Error; goto Error;
} }
// //
// The read/write position from the host file system point of view // The read/write position from the host file system point of view
// is at the end of the file. If the position from this module // is at the end of the file. If the position from this module
@@ -1032,14 +1013,12 @@ SetFileInfo (
FileSetPosition (&Fcb->File, Fcb->Position); FileSetPosition (&Fcb->File, Fcb->Position);
} }
} }
Fcb->Info.FileSize = FileSize; Fcb->Info.FileSize = FileSize;
Return = SemihostFileLength (Fcb->SemihostHandle, &Length); Return = SemihostFileLength (Fcb->SemihostHandle, &Length);
if (RETURN_ERROR (Return)) { if (RETURN_ERROR (Return)) {
goto Error; goto Error;
} }
Fcb->Info.PhysicalSize = Length; Fcb->Info.PhysicalSize = Length;
} }
@@ -1066,7 +1045,6 @@ SetFileInfo (
if (RETURN_ERROR (Return)) { if (RETURN_ERROR (Return)) {
goto Error; goto Error;
} }
FreePool (Fcb->FileName); FreePool (Fcb->FileName);
Fcb->FileName = AsciiFileName; Fcb->FileName = AsciiFileName;
AsciiFileName = NULL; AsciiFileName = NULL;
@@ -1138,24 +1116,19 @@ FileSetInfo (
if (Info->Size < (SIZE_OF_EFI_FILE_INFO + StrSize (Info->FileName))) { if (Info->Size < (SIZE_OF_EFI_FILE_INFO + StrSize (Info->FileName))) {
return EFI_INVALID_PARAMETER; return EFI_INVALID_PARAMETER;
} }
if (BufferSize < Info->Size) { if (BufferSize < Info->Size) {
return EFI_BAD_BUFFER_SIZE; return EFI_BAD_BUFFER_SIZE;
} }
return SetFileInfo (Fcb, Info); return SetFileInfo (Fcb, Info);
} else if (CompareGuid (InformationType, &gEfiFileSystemInfoGuid)) { } else if (CompareGuid (InformationType, &gEfiFileSystemInfoGuid)) {
SystemInfo = Buffer; SystemInfo = Buffer;
if (SystemInfo->Size < if (SystemInfo->Size <
(SIZE_OF_EFI_FILE_SYSTEM_INFO + StrSize (SystemInfo->VolumeLabel))) (SIZE_OF_EFI_FILE_SYSTEM_INFO + StrSize (SystemInfo->VolumeLabel))) {
{
return EFI_INVALID_PARAMETER; return EFI_INVALID_PARAMETER;
} }
if (BufferSize < SystemInfo->Size) { if (BufferSize < SystemInfo->Size) {
return EFI_BAD_BUFFER_SIZE; return EFI_BAD_BUFFER_SIZE;
} }
Buffer = SystemInfo->VolumeLabel; Buffer = SystemInfo->VolumeLabel;
if (StrSize (Buffer) > 0) { if (StrSize (Buffer) > 0) {
@@ -1184,14 +1157,13 @@ FileFlush (
{ {
SEMIHOST_FCB *Fcb; SEMIHOST_FCB *Fcb;
Fcb = SEMIHOST_FCB_FROM_THIS (File); Fcb = SEMIHOST_FCB_FROM_THIS(File);
if (Fcb->IsRoot) { if (Fcb->IsRoot) {
return EFI_SUCCESS; return EFI_SUCCESS;
} else { } else {
if ( (Fcb->Info.Attribute & EFI_FILE_READ_ONLY) if ((Fcb->Info.Attribute & EFI_FILE_READ_ONLY)
|| !(Fcb->OpenMode & EFI_FILE_MODE_WRITE)) || !(Fcb->OpenMode & EFI_FILE_MODE_WRITE)) {
{
return EFI_ACCESS_DENIED; return EFI_ACCESS_DENIED;
} else { } else {
return EFI_SUCCESS; return EFI_SUCCESS;
@@ -1217,14 +1189,12 @@ SemihostFsEntryPoint (
Status = gBS->InstallMultipleProtocolInterfaces ( Status = gBS->InstallMultipleProtocolInterfaces (
&gInstallHandle, &gInstallHandle,
&gEfiSimpleFileSystemProtocolGuid, &gEfiSimpleFileSystemProtocolGuid, &gSemihostFs,
&gSemihostFs, &gEfiDevicePathProtocolGuid, &gDevicePath,
&gEfiDevicePathProtocolGuid,
&gDevicePath,
NULL NULL
); );
if (EFI_ERROR (Status)) { if (EFI_ERROR(Status)) {
FreePool (mSemihostFsLabel); FreePool (mSemihostFsLabel);
} }
} }

View File

@@ -7,8 +7,8 @@
**/ **/
#ifndef SEMIHOST_FS_H_ #ifndef __SEMIHOST_FS_H__
#define SEMIHOST_FS_H_ #define __SEMIHOST_FS_H__
EFI_STATUS EFI_STATUS
VolumeOpen ( VolumeOpen (
@@ -242,4 +242,5 @@ FileFlush (
IN EFI_FILE *File IN EFI_FILE *File
); );
#endif // SEMIHOST_FS_H_ #endif // __SEMIHOST_FS_H__

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