Compare commits

..

47 Commits

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

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

Tested on google/dracia and purism/librem_14

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Add the tag and headers to parse the table.

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

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

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

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2022-06-03 09:03:42 -06:00
601bcb9ce2 MdeModulePkg/BM: Update boot options on device change
Register an event to trigger when a block device is added or removed
that will update the list of boot options. Use a refreshguid to force
the form to display the changes if it already open.
2022-06-03 09:03:42 -06:00
6468032370 MdeModulePkg/Core: Signal notify events on protocol removal
In order for BootManager to maintain a valid list of boot options, it
must know when the BlockIo protocol is also removed, not just added.
2022-06-03 09:03:42 -06:00
7b3153b1cb UiApp: Dynamically generated firmware configuration information page
Signed-off-by: Jeremy Soller <jeremy@system76.com>
Signed-off-by: Tim Crawford <tcrawford@system76.com>
2022-06-03 09:03:42 -06:00
f2e99ad7b6 MdeModulePkg/BMM: Unregister F9 and F10 hotkeys 2022-06-03 09:03:42 -06:00
ae93abfcbf MdeModulePkg/BMM: Remove Commit/Discard buttons 2022-06-03 09:03:42 -06:00
de3e52e5d3 MdeModulePkg/BMM: Save BootOrder on list update 2022-06-03 09:03:42 -06:00
260b22ed3e MdeModulePkg/BMM: Add some debug logging 2022-06-03 09:03:42 -06:00
b79d3f9599 MdeModulePkg/UiApp: Add warning if no bootable options found 2022-06-03 09:03:42 -06:00
49dad2f15d MdeModulePkg/BootMaintenanceManagerUiLib: Make it look like current BMM 2022-06-03 09:03:42 -06:00
21bbc9ae0e MdeModulePkg/UiApp: Make it look like current FrontPage
Signed-off-by: Jeremy Soller <jeremy@system76.com>
Signed-off-by: Tim Crawford <tcrawford@system76.com>
2022-06-03 09:03:42 -06:00
52d9ce76db MdeModulePkg/BM: Make it look like current BootMngr 2022-06-03 09:03:42 -06:00
0d209e3a81 UefiPayloadPkg: Disable EFI shell 2022-06-03 09:03:42 -06:00
c418d4eb9e UefiPayloadPkg: Add library for logging to EC
Make use of the SMFI command interface to forward logs from edk2 to
System76 EC.

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

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

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

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

Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com>
2022-06-03 09:03:42 -06:00
6284b7fe6f UefiPayloadPkg: Use new filesystem drivers
Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com>
2022-06-03 09:03:42 -06:00
e3ac04f774 Add filesystem drivers
Add EXT2/EXT4, exFAT, NTFS filesystem drivers.
Do not add ISO9115 drivers as it breaks El Torito boot.
2022-06-03 09:03:42 -06:00
5f7a6fe58b UefiPayloadPkg: Stall before connecting devices
USB devices are not being detected when booting. Pause a bit for them to
be initialized and detected by EfiBootManagerConnectAll().
2022-06-03 09:03:42 -06:00
4f9743107d MdeModulePkg/BdsDxe: Forward any key for booting
Pressing escape will bring a user to the boot manager. Pressing any
other key will continue booting, forwarding the key to systemd-boot.
2022-06-03 09:03:42 -06:00
f300ed8297 MdeModulePkg: Wait for input after boot failure
Signed-off-by: Matt DeVillier <matt.devillier@gmail.com>
2022-06-03 09:03:42 -06:00
1fd1cf3dfb UefiPayloadPkg: Clear screen on boot error 2022-06-03 09:03:42 -06:00
053e8aed4d UefiPayloadPkg: Copy PlatformBootManagerUnableToBoot() from OvmfPkg 2022-06-03 09:03:42 -06:00
b219d5c94f UefiPayloadPkg: Set ResetOnMemoryTypeInformationChange to FALSE
the default value, TRUE, causes reboots if a device boots to the
shell, exits, and then attempts to boot from another source.

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

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

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

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

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

Test: use BMP created by/saved by Photoshop

Signed-off-by: Matt DeVillier <matt.devillier@gmail.com>
2022-06-03 09:03:41 -06:00
f8d5dcd99b MdeModulePkg: load boot logo into BGRT table
This is a shoehorned-in implementation of an ACPI BGRT
table, ported pretty much directly from the version used
under CorebootPayloadPkg.

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

Signed-off-by: Matt DeVillier <matt.devillier@gmail.com>
2022-06-03 09:03:41 -06:00
2046be8d5e MdeModulePkg/BootLogoLib: Center logo 38.2% from top of screen
Use Microsoft's recommended positioning [1] for the boot logo.

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

[1]: https://docs.microsoft.com/en-us/windows-hardware/drivers/bringup/boot-screen-components#position-the-logo-during-post
2022-06-03 09:03:41 -06:00
57ed7e7151 MdeModulePkg/Logo: Use System76 boot logo 2022-06-03 09:03:41 -06:00
a8285c29d8 UefiPayloadPkg: Enable boot logo
Signed-off-by: Tim Crawford <tcrawford@system76.com>
2022-06-03 09:03:41 -06:00
be10ebabba UefiPayloadPkg: Show boot message as progress text
Signed-off-by: Tim Crawford <tcrawford@system76.com>
2022-06-03 09:03:41 -06:00
3018 changed files with 110605 additions and 485985 deletions

View File

@ -3,7 +3,6 @@
#
# 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
##
trigger:
@ -13,14 +12,10 @@ pr:
- master
- stable/*
variables:
- template: templates/defaults.yml
jobs:
- template: templates/pr-gate-build-job.yml
parameters:
tool_chain_tag: 'GCC5'
vm_image: 'ubuntu-22.04'
container: ${{ variables.default_linux_image }}
arch_list: "IA32,X64,ARM,AARCH64,RISCV64,LOONGARCH64"
usePythonVersion: '' # use Python from the container image
vm_image: 'ubuntu-latest'
arch_list: "IA32,X64,ARM,AARCH64,RISCV64"

View File

@ -27,7 +27,7 @@ steps:
- task: UsePythonVersion@0
inputs:
versionSpec: '3.12'
versionSpec: '3.8.x'
architecture: 'x64'
- script: |

View File

@ -12,18 +12,9 @@ pr:
- master
- stable/*
variables:
- template: templates/defaults.yml
jobs:
- template: templates/pr-gate-build-job.yml
parameters:
tool_chain_tag: 'VS2019'
vm_image: 'windows-2019'
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

@ -10,6 +10,15 @@ parameters:
tool_chain_tag: ''
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
displayName: Build Base Tools from source
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

@ -34,26 +34,16 @@ parameters:
- 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 }}
versionSpec: "3.8.x"
architecture: "x64"
condition: ne('${{ parameters.usePythonVersion }}', '')
- script: pip install -r pip-requirements.txt --upgrade
displayName: 'Install/Upgrade pip modules'
@ -116,7 +106,7 @@ steps:
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
timeoutInMinutes: 1
# Copy the build logs to the artifact staging directory
- task: CopyFiles@2

View File

@ -12,9 +12,6 @@ parameters:
tool_chain_tag: ''
vm_image: ''
arch_list: ''
extra_install_step: []
usePythonVersion: ''
container: ''
# Build step
jobs:
@ -24,10 +21,6 @@ jobs:
#Use matrix to speed up the build process
strategy:
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'
@ -44,19 +37,13 @@ jobs:
Build.Pkgs: 'NetworkPkg,RedfishPkg'
Build.Targets: 'DEBUG,RELEASE,NO-TARGET,NOOPT'
TARGET_OTHER:
Build.Pkgs: 'PcAtChipsetPkg,PrmPkg,ShellPkg,SourceLevelDebugPkg,StandaloneMmPkg,SignedCapsulePkg'
Build.Pkgs: 'PcAtChipsetPkg,PrmPkg,ShellPkg,StandaloneMmPkg'
Build.Targets: 'DEBUG,RELEASE,NO-TARGET,NOOPT'
TARGET_FMP_FAT_TEST:
Build.Pkgs: 'FmpDevicePkg,FatPkg,UnitTestFrameworkPkg,DynamicTablesPkg'
Build.Targets: 'DEBUG,RELEASE,NO-TARGET,NOOPT'
TARGET_CRYPTO_DEBUG:
TARGET_CRYPTO:
Build.Pkgs: 'CryptoPkg'
Build.Targets: 'DEBUG,NOOPT'
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:
Build.Pkgs: 'SecurityPkg'
@ -76,9 +63,6 @@ jobs:
pool:
vmImage: ${{ parameters.vm_image }}
${{ if not(eq(parameters.container, '')) }}:
container: ${{ parameters.container }}
steps:
- template: pr-gate-steps.yml
parameters:
@ -86,47 +70,3 @@ jobs:
build_pkgs: $(Build.Pkgs)
build_targets: $(Build.Targets)
build_archs: ${{ parameters.arch_list }}
usePythonVersion: ${{ parameters.usePythonVersion }}
extra_install_step: ${{ parameters.extra_install_step }}
- job: Build_${{ parameters.tool_chain_tag }}_TARGET_CODE_COVERAGE
dependsOn: Build_${{ parameters.tool_chain_tag }}
workspace:
clean: all
pool:
vmImage: 'windows-2019'
steps:
- checkout: self
clean: true
fetchDepth: 1
submodules: true
- 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)

View File

@ -12,25 +12,16 @@ parameters:
build_pkgs: ''
build_targets: ''
build_archs: ''
usePythonVersion: ''
extra_install_step: []
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 }}', '')
versionSpec: '3.8.x'
architecture: 'x64'
- script: pip install -r pip-requirements.txt --upgrade
displayName: 'Install/Upgrade pip modules'
@ -46,8 +37,6 @@ steps:
displayName: fetch target branch
condition: eq(variables['Build.Reason'], 'PullRequest')
- ${{ parameters.extra_install_step }}
# trim the package list if this is a PR
- task: CmdLine@1
displayName: Check if ${{ parameters.build_pkgs }} need testing
@ -136,7 +125,6 @@ steps:
TestSuites.xml
**/BUILD_TOOLS_REPORT.html
**/OVERRIDELOG.TXT
coverage.xml
flattenFolders: true
condition: succeededOrFailed()

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,27 +0,0 @@
# Description
<_Include a description of the change and why this change was made._>
<_For each item, place an "x" in between `[` and `]` if true. Example: `[x]` (you can also check items in GitHub UI)_>
<_Create the PR as a Draft PR if it is only created to run CI checks._>
<_Delete lines in \<\> tags before creating the PR._>
- [ ] Breaking change?
- **Breaking change** - Will this cause a break in build or boot behavior?
- Examples: Add a new library class or move a module to a different repo.
- [ ] Impacts security?
- **Security** - Does the change have a direct security impact?
- Examples: Crypto algorithm change or buffer overflow fix.
- [ ] Includes tests?
- **Tests** - Does the change include any explicit test code?
- Examples: Unit tests or integration tests.
## How This Was Tested
<_Describe the test(s) that were run to verify the changes._>
## Integration Instructions
<_Describe how these changes should be integrated. Use N/A if nothing is required._>

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,36 +0,0 @@
# This workflow automatically applies labels to pull requests based on regular expression matches against the content
# in the pull request.
#
# Copyright (c) Microsoft Corporation.
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
# For more information, see:
# https://github.com/github/issue-labeler
name: Apply Labels Based on Message Content
on:
pull_request_target:
types:
- edited
- opened
- reopened
- synchronize
workflow_dispatch:
jobs:
sync:
name: Label PR from Description
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write
steps:
- name: Apply Labels Based on PR Description
uses: github/issue-labeler@v3.1
with:
configuration-path: .github/workflows/pr-labeler/regex.yml
enable-versioned-regex: 0
repo-token: ${{ secrets.GITHUB_TOKEN }}

View File

@ -1,16 +0,0 @@
# Specifies labels to apply to pull requests based on regular expressions.
#
# Copyright (c) Microsoft Corporation.
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
# For more information, see:
# https://github.com/github/issue-labeler
impact:breaking-change:
- '\s*-\s*\[\s*[x|X]\s*\] Breaking change\?'
impact:security:
- '\s*-\s*\[\s*[x|X]\s*\] Impacts security\?'
impact:testing:
- '\s*-\s*\[\s*[x|X]\s*\] Includes tests\?'

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

18
.gitmodules vendored
View File

@ -20,21 +20,3 @@
[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

@ -38,6 +38,7 @@ pull_request_rules:
actions:
queue:
method: rebase
rebase_fallback: none
name: default
- name: Post a comment on a PR that can not be merged due to a merge conflict

View File

@ -7,27 +7,12 @@
##
import os
import logging
import sys
from edk2toolext.environment import shell_environment
from edk2toolext.invocables.edk2_ci_build import CiBuildSettingsManager
from edk2toolext.invocables.edk2_setup import SetupSettingsManager, RequiredSubmodule
from edk2toolext.invocables.edk2_update import UpdateSettingsManager
from edk2toolext.invocables.edk2_pr_eval import PrEvalSettingsManager
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):
@ -49,11 +34,6 @@ class Settings(CiBuildSettingsManager, UpdateSettingsManager, SetupSettingsManag
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
def RetrieveCommandLineOptions(self, args):
super().RetrieveCommandLineOptions(args)
if args.force_piptools:
@ -61,11 +41,6 @@ class Settings(CiBuildSettingsManager, UpdateSettingsManager, SetupSettingsManag
if args.no_piptools:
self.UseBuiltInBaseTools = False
try:
self.codeql = codeql_helpers.is_codeql_enabled_on_command_line(args)
except NameError:
pass
# ####################################################################################### #
# Default Support for this Ci Build #
# ####################################################################################### #
@ -78,10 +53,7 @@ class Settings(CiBuildSettingsManager, UpdateSettingsManager, SetupSettingsManag
"ArmPlatformPkg",
"ArmVirtPkg",
"DynamicTablesPkg",
"EmbeddedPkg",
"EmulatorPkg",
"IntelFsp2Pkg",
"IntelFsp2WrapperPkg",
"MdePkg",
"MdeModulePkg",
"NetworkPkg",
@ -90,7 +62,6 @@ class Settings(CiBuildSettingsManager, UpdateSettingsManager, SetupSettingsManag
"UefiCpuPkg",
"FmpDevicePkg",
"ShellPkg",
"SignedCapsulePkg",
"StandaloneMmPkg",
"FatPkg",
"CryptoPkg",
@ -98,7 +69,6 @@ class Settings(CiBuildSettingsManager, UpdateSettingsManager, SetupSettingsManag
"UnitTestFrameworkPkg",
"OvmfPkg",
"RedfishPkg",
"SourceLevelDebugPkg",
"UefiPayloadPkg"
)
@ -109,8 +79,7 @@ class Settings(CiBuildSettingsManager, UpdateSettingsManager, SetupSettingsManag
"X64",
"ARM",
"AARCH64",
"RISCV64",
"LOONGARCH64")
"RISCV64")
def GetTargetsSupported(self):
''' return iterable of edk2 target tags supported by this build '''
@ -194,17 +163,13 @@ class Settings(CiBuildSettingsManager, UpdateSettingsManager, SetupSettingsManag
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
if is_linux and self.ActualToolChainTag.upper().startswith("GCC"):
if "AARCH64" in self.ActualArchitectures:
scopes += ("gcc_aarch64_linux",)
if "ARM" in self.ActualArchitectures:
scopes += ("gcc_arm_linux",)
if "RISCV64" in self.ActualArchitectures:
scopes += ("gcc_riscv64_unknown",)
self.ActualScopes = scopes
return self.ActualScopes
@ -219,8 +184,6 @@ class Settings(CiBuildSettingsManager, UpdateSettingsManager, SetupSettingsManag
"CryptoPkg/Library/OpensslLib/openssl", False))
rs.append(RequiredSubmodule(
"UnitTestFrameworkPkg/Library/CmockaLib/cmocka", False))
rs.append(RequiredSubmodule(
"UnitTestFrameworkPkg/Library/GoogleTestLib/googletest", False))
rs.append(RequiredSubmodule(
"MdeModulePkg/Universal/RegularExpressionDxe/oniguruma", False))
rs.append(RequiredSubmodule(
@ -229,16 +192,6 @@ class Settings(CiBuildSettingsManager, UpdateSettingsManager, SetupSettingsManag
"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
def GetName(self):

View File

@ -93,7 +93,9 @@ class CharEncodingCheck(ICiBuildPlugin):
files = [Edk2pathObj.GetAbsolutePathOnThisSystemFromEdk2RelativePath(x) for x in files]
for a in files:
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))
overall_status += 1

View File

@ -69,13 +69,6 @@ class EccCheck(ICiBuildPlugin):
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:
@ -84,7 +77,7 @@ class EccCheck(ICiBuildPlugin):
shutil.rmtree(temp_path)
# Copy package being scanned to temp_path
shutil.copytree (
abs_pkg_path,
os.path.join(workspace_path, packagename),
os.path.join(temp_path, packagename),
symlinks=True
)

View File

@ -10,7 +10,7 @@ import logging
import os
from edk2toolext.environment.plugintypes.ci_build_plugin import ICiBuildPlugin
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
@ -116,9 +116,8 @@ class HostUnitTestDscCompleteCheck(ICiBuildPlugin):
# should compile test a library that is declared type HOST_APPLICATION
pass
elif (len(infp.SupportedPhases) > 0 and
"HOST_APPLICATION" in infp.SupportedPhases and
infp.SupportedPhases != AllPhases):
elif len(infp.SupportedPhases) > 0 and \
"HOST_APPLICATION" in infp.SupportedPhases:
# should compile test a library that supports HOST_APPLICATION but
# require it to be an explicit opt-in
pass

View File

@ -289,8 +289,6 @@
"unrecovered",
"cmocka",
"unenrolling",
"unconfigure",
"Loongson",
"LOONGARCH"
"unconfigure"
]
}

View File

@ -12,7 +12,6 @@ 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
@ -111,7 +110,7 @@ class UncrustifyCheck(ICiBuildPlugin):
# 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")
STANDARD_PLUGIN_DEFINED_PATHS = ("*.c", "*.h")
#
# The Uncrustify application path should set in this environment variable
@ -291,7 +290,7 @@ class UncrustifyCheck(ICiBuildPlugin):
# 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)
return parse_gitignore_lines(ignored_files, "Package configuration file", self._abs_workspace_path)
def _get_git_ignored_paths(self) -> List[str]:
""""
@ -300,7 +299,7 @@ class UncrustifyCheck(ICiBuildPlugin):
If git is not found, an empty list will be returned.
"""
if not shutil.which("git"):
logging.warning(
logging.warn(
"Git is not found on this system. Git submodule paths will not be considered.")
return []
@ -326,7 +325,7 @@ class UncrustifyCheck(ICiBuildPlugin):
If git is not found, an empty list will be returned.
"""
if not shutil.which("git"):
logging.warning(
logging.warn(
"Git is not found on this system. Git submodule paths will not be considered.")
return []
@ -373,9 +372,9 @@ class UncrustifyCheck(ICiBuildPlugin):
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.")
logging.warn("A file header template is not specified in the config file.")
except FileNotFoundError:
logging.warning("The specified file header template file was not found.")
logging.warn("The specified file header template file was not found.")
try:
func_template_name = parser["dummy_section"]["cmt_insert_func_header"]
@ -385,9 +384,9 @@ class UncrustifyCheck(ICiBuildPlugin):
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.")
logging.warn("A function header template is not specified in the config file.")
except FileNotFoundError:
logging.warning("The specified function header template file was not found.")
logging.warn("The specified function header template file was not found.")
def _initialize_app_info(self) -> None:
"""
@ -629,7 +628,7 @@ class UncrustifyCheck(ICiBuildPlugin):
"""
Private function to attempt to change permissions on file/folder being deleted.
"""
os.chmod(path, stat.S_IWRITE)
os.chmod(path, os.stat.S_IWRITE)
func(path)
for _ in range(3): # retry up to 3 times

View File

@ -215,7 +215,7 @@ indent_braces = false
indent_braces_no_class = false
indent_braces_no_func = true
indent_braces_no_struct = false
indent_class = true
indent_class = false
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.
@ -223,7 +223,7 @@ indent_col1_comment = true
indent_col1_multi_string_literal= true
indent_comma_paren = true
indent_else_if = true
indent_extern = true
indent_extern = false
indent_first_bool_expr = true
indent_func_def_param_paren_pos_threshold = 0

View File

@ -10,7 +10,7 @@
"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",
"version": "73.0.3",
"flags": ["set_shell_var", "host_specific"],
"var_name": "UNCRUSTIFY_CI_PATH"
}

View File

@ -1,12 +1,5 @@
# 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
| Package | Windows VS2019 (IA32/X64)| Ubuntu GCC (IA32/X64/ARM/AARCH64) | Known Issues |
@ -15,7 +8,7 @@ on the TianoCore wiki.
| ArmPlatformPkg | | :heavy_check_mark: |
| ArmVirtPkg | SEE PACKAGE README | SEE PACKAGE README |
| CryptoPkg | :heavy_check_mark: | :heavy_check_mark: | Spell checking in audit mode
| DynamicTablesPkg | :heavy_check_mark: | :heavy_check_mark: |
| DynamicTablesPkg | | :heavy_check_mark: |
| EmbeddedPkg |
| EmulatorPkg | SEE PACKAGE README | SEE PACKAGE README | Spell checking in audit mode
| FatPkg | :heavy_check_mark: | :heavy_check_mark: |
@ -89,18 +82,43 @@ easily and consistently running locally and in a cloud ci environment. To do
that a few steps should be followed. Details of EDKII Tools can be found in the
[docs folder here](https://github.com/tianocore/edk2-pytool-extensions/tree/master/docs)
### Prerequisites
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 18.04 or Fedora
* 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 -r pip-requirements.txt`
### Running CI
Quick notes:
* By default all CI plugins are opted in.
* Setting the plugin to `skip` as an argument will skip running the plugin.
Examples:
* `CompilerPlugin=skip` skip the build test
* `GuidCheck=skip` skip the Guid check
* `SpellCheck=skip` skip the spell checker
* etc.
* Detailed reports and logs per package are captured in the `Build` directory.
1. clone your edk2 repo
2. Activate your python virtual environment in cmd window
3. Get code dependencies (done only when submodules change)
* `stuart_setup -c .pytool/CISettings.py TOOL_CHAIN_TAG=<your tag here>`
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
* `GuidCheck=skip` skip the Guid check
* `SpellCheck=skip` skip the spell checker
* etc
6. Detailed reports and logs per package are captured in the `Build` directory
## Current PyTool Test Capabilities

View File

@ -87,7 +87,7 @@
## options defined .pytool/Plugin/SpellCheck
"SpellCheck": {
"AuditOnly": True,
"AuditOnly": False,
"IgnoreFiles": [
"Library/ArmSoftFloatLib/berkeley-softfloat-3/**"
], # use gitignore syntax to ignore errors
@ -239,10 +239,5 @@
],
"AdditionalIncludePaths": [] # Additional paths to spell check
# (wildcards supported)
},
# options defined in .pytool/Plugin/UncrustifyCheck
"UncrustifyCheck": {
"AuditOnly": True
}
}

View File

@ -2,7 +2,7 @@
# ARM processor package.
#
# Copyright (c) 2009 - 2010, Apple Inc. All rights reserved.<BR>
# Copyright (c) 2011 - 2023, ARM Limited. All rights reserved.
# Copyright (c) 2011 - 2021, ARM Limited. All rights reserved.
# Copyright (c) 2021, Ampere Computing LLC. All rights reserved.
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
@ -71,11 +71,6 @@
#
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
@ -104,8 +99,6 @@
# Include/Guid/ArmMpCoreInfo.h
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]
## Arm System Control and Management Interface(SCMI) Base protocol
## ArmPkg/Include/Protocol/ArmScmiBaseProtocol.h
@ -139,11 +132,6 @@
# Define if the GICv3 controller should use the GICv2 legacy
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]
# 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
@ -221,13 +209,6 @@
#
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]
gArmTokenSpaceGuid.PcdFdBaseAddress|0|UINT64|0x0000002B
gArmTokenSpaceGuid.PcdFvBaseAddress|0|UINT64|0x0000002D
@ -312,11 +293,6 @@
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]
#
# ARM Architectural Timer
@ -328,7 +304,6 @@
gArmTokenSpaceGuid.PcdArmArchTimerIntrNum|30|UINT32|0x00000036
gArmTokenSpaceGuid.PcdArmArchTimerHypIntrNum|26|UINT32|0x00000040
gArmTokenSpaceGuid.PcdArmArchTimerVirtIntrNum|27|UINT32|0x00000041
gArmTokenSpaceGuid.PcdArmArchTimerHypVirtIntrNum|28|UINT32|0x0000004A
#
# ARM Generic Watchdog

View File

@ -113,6 +113,7 @@
ArmPkg/Library/DebugAgentSymbolsBaseLib/DebugAgentSymbolsBaseLib.inf
ArmPkg/Library/DebugPeCoffExtraActionLib/DebugPeCoffExtraActionLib.inf
ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandlerLib.inf
ArmPkg/Library/RvdPeCoffExtraActionLib/RvdPeCoffExtraActionLib.inf
ArmPkg/Library/SemiHostingDebugLib/SemiHostingDebugLib.inf
ArmPkg/Library/SemiHostingSerialPortLib/SemiHostingSerialPortLib.inf
ArmPkg/Library/SemihostLib/SemihostLib.inf
@ -130,12 +131,9 @@
ArmPkg/Library/ArmGenericTimerPhyCounterLib/ArmGenericTimerPhyCounterLib.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/ArmSmcLibNull/ArmSmcLibNull.inf
ArmPkg/Library/ArmHvcLib/ArmHvcLib.inf
ArmPkg/Library/ArmSvcLib/ArmSvcLib.inf
ArmPkg/Library/OpteeLib/OpteeLib.inf
@ -162,10 +160,7 @@
ArmPkg/Universal/Smbios/SmbiosMiscDxe/SmbiosMiscDxe.inf
ArmPkg/Universal/Smbios/OemMiscLibNull/OemMiscLibNull.inf
ArmPkg/Drivers/MmCommunicationPei/MmCommunicationPei.inf
[Components.AARCH64]
ArmPkg/Drivers/ArmPsciMpServicesDxe/ArmPsciMpServicesDxe.inf
ArmPkg/Drivers/MmCommunicationDxe/MmCommunication.inf
ArmPkg/Library/ArmMmuLib/ArmMmuPeiLib.inf

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
@ -8,6 +8,20 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#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
EFI_HANDLE gHardwareInterruptHandle = NULL;
@ -47,7 +61,7 @@ GicGetDistributorIcfgBaseAndBit (
RegIndex = Source / ARM_GIC_ICDICFR_F_STRIDE; // NOTE: truncation is significant
Field = Source % ARM_GIC_ICDICFR_F_STRIDE;
*RegAddress = (UINTN)PcdGet64 (PcdGicDistributorBase)
*RegAddress = PcdGet64 (PcdGicDistributorBase)
+ ARM_GIC_ICDICFR
+ (ARM_GIC_ICDICFR_BYTES * RegIndex);
*Config1Bit = ((Field * ARM_GIC_ICDICFR_F_WIDTH)
@ -123,7 +137,7 @@ CpuArchEventProtocolNotify (
DEBUG ((
DEBUG_ERROR,
"%a: Cpu->RegisterInterruptHandler() - %r\n",
__func__,
__FUNCTION__,
Status
));
return;
@ -139,7 +153,7 @@ CpuArchEventProtocolNotify (
DEBUG ((
DEBUG_ERROR,
"%a: Cpu->RegisterInterruptHandler() - %r\n",
__func__,
__FUNCTION__,
Status
));
}

View File

@ -1,6 +1,6 @@
/** @file
*
* Copyright (c) 2011-2023, Arm Limited. All rights reserved.
* Copyright (c) 2011-2021, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-2-Clause-Patent
*
@ -104,17 +104,10 @@ GicGetCpuRedistributorBase (
return 0;
}
/**
Return the GIC CPU Interrupt Interface ID.
@param GicInterruptInterfaceBase Base address of the GIC Interrupt Interface.
@retval CPU Interface Identification information.
**/
UINT32
UINTN
EFIAPI
ArmGicGetInterfaceIdentification (
IN UINTN GicInterruptInterfaceBase
IN INTN GicInterruptInterfaceBase
)
{
// Read the GIC Identification Register
@ -124,7 +117,7 @@ ArmGicGetInterfaceIdentification (
UINTN
EFIAPI
ArmGicGetMaxNumInterrupts (
IN UINTN GicDistributorBase
IN INTN GicDistributorBase
)
{
UINTN ItLines;
@ -140,17 +133,15 @@ ArmGicGetMaxNumInterrupts (
VOID
EFIAPI
ArmGicSendSgiTo (
IN UINTN GicDistributorBase,
IN UINT8 TargetListFilter,
IN UINT8 CPUTargetList,
IN UINT8 SgiId
IN INTN GicDistributorBase,
IN INTN TargetListFilter,
IN INTN CPUTargetList,
IN INTN SgiId
)
{
MmioWrite32 (
GicDistributorBase + ARM_GIC_ICDSGIR,
((TargetListFilter & 0x3) << 24) |
((CPUTargetList & 0xFF) << 16) |
(SgiId & 0xF)
((TargetListFilter & 0x3) << 24) | ((CPUTargetList & 0xFF) << 16) | SgiId
);
}
@ -176,17 +167,19 @@ ArmGicAcknowledgeInterrupt (
)
{
UINTN Value;
UINTN IntId;
ARM_GIC_ARCH_REVISION Revision;
ASSERT (InterruptId != NULL);
Revision = ArmGicGetSupportedArchRevision ();
if (Revision == ARM_GIC_ARCH_REVISION_2) {
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) {
Value = ArmGicV3AcknowledgeInterrupt ();
IntId = Value;
} else {
ASSERT_EFI_ERROR (EFI_UNSUPPORTED);
// Report Spurious interrupt which is what the above controllers would
@ -194,12 +187,6 @@ ArmGicAcknowledgeInterrupt (
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;
}
@ -232,13 +219,13 @@ ArmGicSetInterruptPriority (
)
{
UINT32 RegOffset;
UINT8 RegShift;
UINTN RegShift;
ARM_GIC_ARCH_REVISION Revision;
UINTN GicCpuRedistributorBase;
// Calculate register offset and bit position
RegOffset = (UINT32)(Source / 4);
RegShift = (UINT8)((Source % 4) * 8);
RegOffset = Source / 4;
RegShift = (Source % 4) * 8;
Revision = ArmGicGetSupportedArchRevision ();
if ((Revision == ARM_GIC_ARCH_REVISION_2) ||
@ -276,13 +263,13 @@ ArmGicEnableInterrupt (
)
{
UINT32 RegOffset;
UINT8 RegShift;
UINTN RegShift;
ARM_GIC_ARCH_REVISION Revision;
UINTN GicCpuRedistributorBase;
// Calculate enable register offset and bit position
RegOffset = (UINT32)(Source / 32);
RegShift = (UINT8)(Source % 32);
RegOffset = Source / 32;
RegShift = Source % 32;
Revision = ArmGicGetSupportedArchRevision ();
if ((Revision == ARM_GIC_ARCH_REVISION_2) ||
@ -321,13 +308,13 @@ ArmGicDisableInterrupt (
)
{
UINT32 RegOffset;
UINT8 RegShift;
UINTN RegShift;
ARM_GIC_ARCH_REVISION Revision;
UINTN GicCpuRedistributorBase;
// Calculate enable register offset and bit position
RegOffset = (UINT32)(Source / 32);
RegShift = (UINT8)(Source % 32);
RegOffset = Source / 32;
RegShift = Source % 32;
Revision = ArmGicGetSupportedArchRevision ();
if ((Revision == ARM_GIC_ARCH_REVISION_2) ||
@ -365,23 +352,24 @@ ArmGicIsInterruptEnabled (
)
{
UINT32 RegOffset;
UINT8 RegShift;
UINTN RegShift;
ARM_GIC_ARCH_REVISION Revision;
UINTN GicCpuRedistributorBase;
UINT32 Interrupts;
// Calculate enable register offset and bit position
RegOffset = (UINT32)(Source / 32);
RegShift = (UINT8)(Source % 32);
RegOffset = Source / 32;
RegShift = Source % 32;
Revision = ArmGicGetSupportedArchRevision ();
if ((Revision == ARM_GIC_ARCH_REVISION_2) ||
FeaturePcdGet (PcdArmGicV3WithV2Legacy) ||
SourceIsSpi (Source))
{
Interrupts = MmioRead32 (
GicDistributorBase + ARM_GIC_ICDISER + (4 * RegOffset)
);
Interrupts = ((MmioRead32 (
GicDistributorBase + ARM_GIC_ICDISER + (4 * RegOffset)
)
& (1 << RegShift)) != 0);
} else {
GicCpuRedistributorBase = GicGetCpuRedistributorBase (
GicRedistributorBase,
@ -403,7 +391,7 @@ ArmGicIsInterruptEnabled (
VOID
EFIAPI
ArmGicDisableDistributor (
IN UINTN GicDistributorBase
IN INTN GicDistributorBase
)
{
// Disable Gic Distributor
@ -413,7 +401,7 @@ ArmGicDisableDistributor (
VOID
EFIAPI
ArmGicEnableInterruptInterface (
IN UINTN GicInterruptInterfaceBase
IN INTN GicInterruptInterfaceBase
)
{
ARM_GIC_ARCH_REVISION Revision;
@ -431,7 +419,7 @@ ArmGicEnableInterruptInterface (
VOID
EFIAPI
ArmGicDisableInterruptInterface (
IN UINTN GicInterruptInterfaceBase
IN INTN GicInterruptInterfaceBase
)
{
ARM_GIC_ARCH_REVISION Revision;

View File

@ -1,6 +1,6 @@
/** @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
*
@ -13,11 +13,10 @@
VOID
EFIAPI
ArmGicEnableDistributor (
IN UINTN GicDistributorBase
IN INTN GicDistributorBase
)
{
ARM_GIC_ARCH_REVISION Revision;
UINT32 GicDistributorCtl;
/*
* Enable GIC distributor in Non-Secure world.
@ -27,8 +26,7 @@ ArmGicEnableDistributor (
if (Revision == ARM_GIC_ARCH_REVISION_2) {
MmioWrite32 (GicDistributorBase + ARM_GIC_ICDDCR, 0x1);
} else {
GicDistributorCtl = MmioRead32 (GicDistributorBase + ARM_GIC_ICDDCR);
if ((GicDistributorCtl & ARM_GIC_ICDDCR_ARE) != 0) {
if (MmioRead32 (GicDistributorBase + ARM_GIC_ICDDCR) & ARM_GIC_ICDDCR_ARE) {
MmioOr32 (GicDistributorBase + ARM_GIC_ICDDCR, 0x2);
} else {
MmioOr32 (GicDistributorBase + ARM_GIC_ICDDCR, 0x1);

View File

@ -2,7 +2,7 @@
Copyright (c) 2009, Hewlett-Packard Company. All rights reserved.<BR>
Portions copyright (c) 2010, Apple Inc. All rights reserved.<BR>
Portions copyright (c) 2011-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
@ -25,8 +25,8 @@ Abstract:
extern EFI_HARDWARE_INTERRUPT_PROTOCOL gHardwareInterruptV2Protocol;
extern EFI_HARDWARE_INTERRUPT2_PROTOCOL gHardwareInterrupt2V2Protocol;
STATIC UINTN mGicInterruptInterfaceBase;
STATIC UINTN mGicDistributorBase;
STATIC UINT32 mGicInterruptInterfaceBase;
STATIC UINT32 mGicDistributorBase;
/**
Enable interrupt source Source.
@ -162,7 +162,7 @@ GicV2IrqInterruptHandler (
IN EFI_SYSTEM_CONTEXT SystemContext
)
{
UINTN GicInterrupt;
UINT32 GicInterrupt;
HARDWARE_INTERRUPT_HANDLER InterruptHandler;
GicInterrupt = ArmGicV2AcknowledgeInterrupt (mGicInterruptInterfaceBase);
@ -179,7 +179,7 @@ GicV2IrqInterruptHandler (
// Call the registered interrupt handler.
InterruptHandler (GicInterrupt, SystemContext);
} 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);
}
}
@ -349,8 +349,8 @@ GicV2ExitBootServicesEvent (
IN VOID *Context
)
{
UINTN Index;
UINTN GicInterrupt;
UINTN Index;
UINT32 GicInterrupt;
// Disable all the interrupts
for (Index = 0; Index < mGicNumInterrupts; Index++) {
@ -393,26 +393,23 @@ GicV2DxeInitialize (
EFI_STATUS Status;
UINTN Index;
UINT32 RegOffset;
UINT8 RegShift;
UINTN RegShift;
UINT32 CpuTarget;
// Make sure the Interrupt Controller Protocol is not already installed in
// the system.
ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gHardwareInterruptProtocolGuid);
ASSERT (PcdGet64 (PcdGicInterruptInterfaceBase) <= MAX_UINTN);
ASSERT (PcdGet64 (PcdGicDistributorBase) <= MAX_UINTN);
mGicInterruptInterfaceBase = (UINTN)PcdGet64 (PcdGicInterruptInterfaceBase);
mGicDistributorBase = (UINTN)PcdGet64 (PcdGicDistributorBase);
mGicInterruptInterfaceBase = PcdGet64 (PcdGicInterruptInterfaceBase);
mGicDistributorBase = PcdGet64 (PcdGicDistributorBase);
mGicNumInterrupts = ArmGicGetMaxNumInterrupts (mGicDistributorBase);
for (Index = 0; Index < mGicNumInterrupts; Index++) {
GicV2DisableInterruptSource (&gHardwareInterruptV2Protocol, Index);
// Set Priority
RegOffset = (UINT32)(Index / 4);
RegShift = (UINT8)((Index % 4) * 8);
RegOffset = Index / 4;
RegShift = (Index % 4) * 8;
MmioAndThenOr32 (
mGicDistributorBase + ARM_GIC_ICDIPR + (4 * RegOffset),
~(0xff << RegShift),

View File

@ -1,13 +1,12 @@
/** @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
*
**/
#include <Library/ArmGicLib.h>
#include <Library/DebugLib.h>
#include <Library/IoLib.h>
UINTN
@ -27,6 +26,5 @@ ArmGicV2EndOfInterrupt (
IN UINTN Source
)
{
ASSERT (Source <= MAX_UINT32);
MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCEIOR, (UINT32)Source);
MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCEIOR, Source);
}

View File

@ -1,6 +1,6 @@
/** @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
*
@ -13,7 +13,7 @@
VOID
EFIAPI
ArmGicV2EnableInterruptInterface (
IN UINTN GicInterruptInterfaceBase
IN INTN GicInterruptInterfaceBase
)
{
/*
@ -26,7 +26,7 @@ ArmGicV2EnableInterruptInterface (
VOID
EFIAPI
ArmGicV2DisableInterruptInterface (
IN UINTN GicInterruptInterfaceBase
IN INTN GicInterruptInterfaceBase
)
{
// Disable Gic Interface

View File

@ -1,6 +1,6 @@
/** @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
*
@ -156,7 +156,7 @@ GicV3IrqInterruptHandler (
IN EFI_SYSTEM_CONTEXT SystemContext
)
{
UINTN GicInterrupt;
UINT32 GicInterrupt;
HARDWARE_INTERRUPT_HANDLER InterruptHandler;
GicInterrupt = ArmGicV3AcknowledgeInterrupt ();
@ -173,7 +173,7 @@ GicV3IrqInterruptHandler (
// Call the registered interrupt handler.
InterruptHandler (GicInterrupt, SystemContext);
} 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);
}
}
@ -381,7 +381,7 @@ GicV3DxeInitialize (
// the system.
ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gHardwareInterruptProtocolGuid);
mGicDistributorBase = (UINTN)PcdGet64 (PcdGicDistributorBase);
mGicDistributorBase = PcdGet64 (PcdGicDistributorBase);
mGicRedistributorsBase = PcdGet64 (PcdGicRedistributorsBase);
mGicNumInterrupts = ArmGicGetMaxNumInterrupts (mGicDistributorBase);

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

@ -145,8 +145,8 @@ ScmiCommandExecute (
/** Internal common function useful for common protocol discovery messages.
@param[in] ProtocolId Protocol Id of the protocol.
@param[in] MessageId Message Id of the message.
@param[in] ProtocolId Protocol Id of the the protocol.
@param[in] MesaageId Message Id of the message.
@param[out] ReturnValues SCMI response return values.

View File

@ -236,7 +236,12 @@ ClockDescribeRates (
*TotalRates = NUM_RATES (DescribeRates->NumRatesFlags)
+ NUM_REMAIN_RATES (DescribeRates->NumRatesFlags);
RequiredArraySize = (*TotalRates) * sizeof (UINT64);
if (*Format == ScmiClockRateFormatDiscrete) {
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)) {
*RateArraySize = RequiredArraySize;
@ -254,21 +259,23 @@ ClockDescribeRates (
ConvertTo64Bit (Rate->Low, Rate->High);
}
} else {
// Linear clock rates from minimum to maximum in steps
// Minimum clock rate.
Rate = &DescribeRates->Rates[RateOffset++];
RateArray[RateIndex].ContinuousRate.Min =
ConvertTo64Bit (Rate->Low, Rate->High);
for (RateNo = 0; RateNo < NUM_RATES (DescribeRates->NumRatesFlags); RateNo++) {
// Linear clock rates from minimum to maximum in steps
// Minimum clock rate.
Rate = &DescribeRates->Rates[RateOffset++];
RateArray[RateIndex].ContinuousRate.Min =
ConvertTo64Bit (Rate->Low, Rate->High);
Rate = &DescribeRates->Rates[RateOffset++];
// Maximum clock rate.
RateArray[RateIndex].ContinuousRate.Max =
ConvertTo64Bit (Rate->Low, Rate->High);
Rate = &DescribeRates->Rates[RateOffset++];
// Maximum clock rate.
RateArray[RateIndex].ContinuousRate.Max =
ConvertTo64Bit (Rate->Low, Rate->High);
Rate = &DescribeRates->Rates[RateOffset++];
// Step.
RateArray[RateIndex++].ContinuousRate.Step =
ConvertTo64Bit (Rate->Low, Rate->High);
Rate = &DescribeRates->Rates[RateOffset++];
// Step.
RateArray[RateIndex++].ContinuousRate.Step =
ConvertTo64Bit (Rate->Low, Rate->High);
}
}
} while (NUM_REMAIN_RATES (DescribeRates->NumRatesFlags) != 0);

View File

@ -1,12 +1,12 @@
/** @file
Copyright (c) 2017-2023, Arm Limited. All rights reserved.<BR>
Copyright (c) 2017-2021, Arm Limited. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
System Control and Management Interface V3.2, latest version at:
- https://developer.arm.com/documentation/den0056/latest/
System Control and Management Interface V1.0
http://infocenter.arm.com/help/topic/com.arm.doc.den0056a/
DEN0056A_System_Control_and_Management_Interface.pdf
**/
#include <Library/BaseMemoryLib.h>
@ -416,75 +416,6 @@ PerformanceLevelGet (
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.
STATIC CONST SCMI_PERFORMANCE_PROTOCOL PerformanceProtocol = {
PerformanceGetVersion,
@ -494,8 +425,7 @@ STATIC CONST SCMI_PERFORMANCE_PROTOCOL PerformanceProtocol = {
PerformanceLimitsSet,
PerformanceLimitsGet,
PerformanceLevelSet,
PerformanceLevelGet,
DescribeFastchannel,
PerformanceLevelGet
};
/** Initialize performance management protocol and install on a given Handle.

View File

@ -13,19 +13,11 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include <Library/MemoryAllocationLib.h>
#include "CpuDxe.h"
#define INVALID_ENTRY ((UINT64)~0)
#define INVALID_ENTRY ((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 (
@ -38,13 +30,6 @@ GetRootTranslationTableInfo (
*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 (
@ -79,10 +64,6 @@ PageAttributeToGcdAttribute (
}
// 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))
{
@ -98,31 +79,6 @@ PageAttributeToGcdAttribute (
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
UINT64
GetFirstPageAttribute (
@ -143,25 +99,12 @@ GetFirstPageAttribute (
} else if (((FirstEntry & TT_TYPE_MASK) == TT_TYPE_BLOCK_ENTRY) ||
((TableLevel == 3) && ((FirstEntry & TT_TYPE_MASK) == TT_TYPE_BLOCK_ENTRY_LEVEL3)))
{
return FirstEntry & TT_ATTRIBUTES_MASK;
return FirstEntry & TT_ATTR_INDX_MASK;
} else {
return INVALID_ENTRY;
}
}
/**
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
UINT64
GetNextEntryAttribute (
@ -169,14 +112,14 @@ GetNextEntryAttribute (
IN UINTN EntryCount,
IN UINTN TableLevel,
IN UINT64 BaseAddress,
IN OUT UINT64 *PrevEntryAttribute,
IN OUT UINT32 *PrevEntryAttribute,
IN OUT UINT64 *StartGcdRegion
)
{
UINTN Index;
UINT64 Entry;
UINT64 EntryAttribute;
UINT64 EntryType;
UINT32 EntryAttribute;
UINT32 EntryType;
EFI_STATUS Status;
UINTN NumberOfDescriptors;
EFI_GCD_MEMORY_SPACE_DESCRIPTOR *MemorySpaceMap;
@ -184,19 +127,17 @@ GetNextEntryAttribute (
// Get the memory space map from GCD
MemorySpaceMap = NULL;
Status = gDS->GetMemorySpaceMap (&NumberOfDescriptors, &MemorySpaceMap);
ASSERT_EFI_ERROR (Status);
if (EFI_ERROR (Status) || (TableLevel > 3)) {
ASSERT_EFI_ERROR (Status);
ASSERT (TableLevel <= 3);
return 0;
}
// We cannot get more than 3-level page table
ASSERT (TableLevel <= 3);
// While the top level table might not contain TT_ENTRY_COUNT entries;
// the subsequent ones should be filled up
for (Index = 0; Index < EntryCount; Index++) {
Entry = TableAddress[Index];
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 ((EntryType == TT_TYPE_BLOCK_ENTRY) ||
@ -256,22 +197,13 @@ GetNextEntryAttribute (
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
SyncCacheConfig (
IN EFI_CPU_ARCH_PROTOCOL *CpuProtocol
)
{
EFI_STATUS Status;
UINT64 PageAttribute;
UINT32 PageAttribute;
UINT64 *FirstLevelTableAddress;
UINTN TableLevel;
UINTN TableCount;
@ -290,11 +222,7 @@ SyncCacheConfig (
//
MemorySpaceMap = NULL;
Status = gDS->GetMemorySpaceMap (&NumberOfDescriptors, &MemorySpaceMap);
if (EFI_ERROR (Status)) {
ASSERT_EFI_ERROR (Status);
return Status;
}
ASSERT_EFI_ERROR (Status);
// 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
@ -328,7 +256,7 @@ SyncCacheConfig (
);
// Update GCD with the last region if valid
if ((PageAttribute != INVALID_ENTRY) && (EndAddressGcdRegion > BaseAddressGcdRegion)) {
if (PageAttribute != INVALID_ENTRY) {
SetGcdMemorySpaceAttributes (
MemorySpaceMap,
NumberOfDescriptors,
@ -343,13 +271,6 @@ SyncCacheConfig (
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
EfiAttributeToArmAttribute (
IN UINT64 EfiAttributes
@ -380,9 +301,7 @@ EfiAttributeToArmAttribute (
}
// Set the access flag to match the block attributes
if ((EfiAttributes & EFI_MEMORY_RP) == 0) {
ArmAttributes |= TT_AF;
}
ArmAttributes |= TT_AF;
// Determine protection attributes
if ((EfiAttributes & EFI_MEMORY_RO) != 0) {
@ -397,25 +316,8 @@ EfiAttributeToArmAttribute (
return ArmAttributes;
}
/**
This function returns the attributes of the memory region containing the
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.
**/
// This function will recursively go down the page table to find the first block address linked to 'BaseAddress'.
// And then the function will identify the size of the region that has the same page table attribute.
EFI_STATUS
GetMemoryRegionRec (
IN UINT64 *TranslationTable,
@ -455,10 +357,10 @@ GetMemoryRegionRec (
RegionAttributes
);
// EFI_SUCCESS: The end of the end of the region was found.
// EFI_NO_MAPPING: The translation entry associated with BaseAddress is invalid.
if (Status != EFI_NOT_FOUND) {
return Status;
// In case of 'Success', it means the end of the block region has been found into the upper
// level translation table
if (!EFI_ERROR (Status)) {
return EFI_SUCCESS;
}
// Now we processed the table move to the next entry
@ -470,13 +372,12 @@ GetMemoryRegionRec (
*RegionLength = 0;
*RegionAttributes = *BlockEntry & TT_ATTRIBUTES_MASK;
} else {
return EFI_NO_MAPPING;
// We have an 'Invalid' entry
return EFI_UNSUPPORTED;
}
while (BlockEntry <= LastBlockEntry) {
if (((*BlockEntry & TT_TYPE_MASK) == BlockEntryType) &&
((*BlockEntry & TT_ATTRIBUTES_MASK) == *RegionAttributes))
{
if ((*BlockEntry & TT_ATTRIBUTES_MASK) == *RegionAttributes) {
*RegionLength = *RegionLength + TT_BLOCK_ENTRY_SIZE_AT_LEVEL (TableLevel);
} else {
// In case we have found the end of the region we return success
@ -488,29 +389,10 @@ GetMemoryRegionRec (
// 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.
// 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;
}
/**
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
GetMemoryRegion (
IN OUT UINTN *BaseAddress,
@ -524,18 +406,10 @@ GetMemoryRegion (
UINTN EntryCount;
UINTN T0SZ;
if ((BaseAddress == NULL) || (RegionLength == NULL) || (RegionAttributes == NULL)) {
ASSERT ((BaseAddress != NULL) && (RegionLength != NULL) && (RegionAttributes != NULL));
return EFI_INVALID_PARAMETER;
}
ASSERT ((BaseAddress != NULL) && (RegionLength != NULL) && (RegionAttributes != NULL));
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;
// Get the Table info from T0SZ
GetRootTranslationTableInfo (T0SZ, &TableLevel, &EntryCount);
@ -550,10 +424,10 @@ GetMemoryRegion (
);
// 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.
if ((Status == EFI_NOT_FOUND) && (*RegionLength > 0)) {
// will return EFI_NOT_FOUND
if (Status == EFI_NOT_FOUND) {
return EFI_SUCCESS;
} else {
return Status;
}
return Status;
}

View File

@ -13,18 +13,6 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include <Library/MemoryAllocationLib.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
SectionToGcdAttributes (
IN UINT32 SectionAttributes,
@ -62,62 +50,33 @@ SectionToGcdAttributes (
// determine protection attributes
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:
// normal read/write access, do not add additional attributes
break;
// 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:
*GcdAttributes |= EFI_MEMORY_RO;
break;
default:
return EFI_UNSUPPORTED;
}
// 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;
}
if ((SectionAttributes & TT_DESCRIPTOR_SECTION_AF) == 0) {
*GcdAttributes |= EFI_MEMORY_RP;
}
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
PageToGcdAttributes (
IN UINT32 PageAttributes,
@ -155,47 +114,33 @@ PageToGcdAttributes (
// determine protection attributes
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:
// normal read/write access, do not add additional attributes
break;
// 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:
*GcdAttributes |= EFI_MEMORY_RO;
break;
default:
return EFI_UNSUPPORTED;
}
// 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;
}
if ((PageAttributes & TT_DESCRIPTOR_PAGE_AF) == 0) {
*GcdAttributes |= EFI_MEMORY_RP;
}
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
SyncCacheConfigPage (
IN UINT32 SectionIndex,
@ -220,8 +165,7 @@ SyncCacheConfigPage (
// Convert SectionAttributes into PageAttributes
NextPageAttributes =
TT_DESCRIPTOR_CONVERT_TO_PAGE_CACHE_POLICY (*NextSectionAttributes) |
TT_DESCRIPTOR_CONVERT_TO_PAGE_AF (*NextSectionAttributes) |
TT_DESCRIPTOR_CONVERT_TO_PAGE_CACHE_POLICY (*NextSectionAttributes, 0) |
TT_DESCRIPTOR_CONVERT_TO_PAGE_AP (*NextSectionAttributes);
// obtain page table base
@ -230,7 +174,7 @@ SyncCacheConfigPage (
for (i = 0; i < TRANSLATION_TABLE_PAGE_COUNT; i++) {
if ((SecondLevelTable[i] & TT_DESCRIPTOR_PAGE_TYPE_MASK) == TT_DESCRIPTOR_PAGE_TYPE_PAGE) {
// 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) {
// start on a new region
@ -240,10 +184,7 @@ SyncCacheConfigPage (
} else if (PageAttributes != NextPageAttributes) {
// Convert Section Attributes into GCD Attributes
Status = PageToGcdAttributes (NextPageAttributes, &GcdAttributes);
if (EFI_ERROR (Status)) {
ASSERT_EFI_ERROR (Status);
GcdAttributes = 0;
}
ASSERT_EFI_ERROR (Status);
// update GCD with these changes (this will recurse into our own CpuSetMemoryAttributes below which is OK)
SetGcdMemorySpaceAttributes (MemorySpaceMap, NumberOfDescriptors, *NextRegionBase, *NextRegionLength, GcdAttributes);
@ -256,10 +197,7 @@ SyncCacheConfigPage (
} else if (NextPageAttributes != 0) {
// Convert Page Attributes into GCD Attributes
Status = PageToGcdAttributes (NextPageAttributes, &GcdAttributes);
if (EFI_ERROR (Status)) {
ASSERT_EFI_ERROR (Status);
GcdAttributes = 0;
}
ASSERT_EFI_ERROR (Status);
// update GCD with these changes (this will recurse into our own CpuSetMemoryAttributes below which is OK)
SetGcdMemorySpaceAttributes (MemorySpaceMap, NumberOfDescriptors, *NextRegionBase, *NextRegionLength, GcdAttributes);
@ -274,21 +212,12 @@ SyncCacheConfigPage (
// Convert back PageAttributes into SectionAttributes
*NextSectionAttributes =
TT_DESCRIPTOR_CONVERT_TO_SECTION_CACHE_POLICY (NextPageAttributes) |
TT_DESCRIPTOR_CONVERT_TO_SECTION_AF (NextPageAttributes) |
TT_DESCRIPTOR_CONVERT_TO_SECTION_CACHE_POLICY (NextPageAttributes, 0) |
TT_DESCRIPTOR_CONVERT_TO_SECTION_AP (NextPageAttributes);
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
SyncCacheConfig (
IN EFI_CPU_ARCH_PROTOCOL *CpuProtocol
@ -315,12 +244,7 @@ SyncCacheConfig (
//
MemorySpaceMap = NULL;
Status = gDS->GetMemorySpaceMap (&NumberOfDescriptors, &MemorySpaceMap);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "SyncCacheConfig - GetMemorySpaceMap() failed! Status: %r\n", Status));
ASSERT_EFI_ERROR (Status);
return Status;
}
ASSERT_EFI_ERROR (Status);
// 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
@ -332,14 +256,14 @@ SyncCacheConfig (
FirstLevelTable = (ARM_FIRST_LEVEL_DESCRIPTOR *)(ArmGetTTBR0BaseAddress ());
// 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
NextRegionBase = NextRegionLength = 0;
for (i = 0; i < TRANSLATION_TABLE_SECTION_COUNT; i++) {
if ((FirstLevelTable[i] & TT_DESCRIPTOR_SECTION_TYPE_MASK) == TT_DESCRIPTOR_SECTION_TYPE_SECTION) {
// 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) {
// start on a new region
@ -349,12 +273,7 @@ SyncCacheConfig (
} else if (SectionAttributes != NextSectionAttributes) {
// Convert Section Attributes into GCD Attributes
Status = SectionToGcdAttributes (NextSectionAttributes, &GcdAttributes);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "SyncCacheConfig - SectionToGcdAttributes() failed! Status: %r\n", Status));
ASSERT_EFI_ERROR (Status);
GcdAttributes = 0;
}
ASSERT_EFI_ERROR (Status);
// update GCD with these changes (this will recurse into our own CpuSetMemoryAttributes below which is OK)
SetGcdMemorySpaceAttributes (MemorySpaceMap, NumberOfDescriptors, NextRegionBase, NextRegionLength, GcdAttributes);
@ -390,11 +309,7 @@ SyncCacheConfig (
if (NextSectionAttributes != 0) {
// Convert Section Attributes into GCD Attributes
Status = SectionToGcdAttributes (NextSectionAttributes, &GcdAttributes);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "SyncCacheConfig - SectionToGcdAttributes() failed! Status: %r\n", Status));
ASSERT_EFI_ERROR (Status);
GcdAttributes = 0;
}
ASSERT_EFI_ERROR (Status);
// update GCD with these changes (this will recurse into our own CpuSetMemoryAttributes below which is OK)
SetGcdMemorySpaceAttributes (MemorySpaceMap, NumberOfDescriptors, NextRegionBase, NextRegionLength, GcdAttributes);
@ -411,11 +326,7 @@ SyncCacheConfig (
if (NextSectionAttributes != 0) {
// Convert Section Attributes into GCD Attributes
Status = SectionToGcdAttributes (NextSectionAttributes, &GcdAttributes);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "SyncCacheConfig - SectionToGcdAttributes() failed! Status: %r\n", Status));
ASSERT_EFI_ERROR (Status);
GcdAttributes = 0;
}
ASSERT_EFI_ERROR (Status);
// update GCD with these changes (this will recurse into our own CpuSetMemoryAttributes below which is OK)
SetGcdMemorySpaceAttributes (MemorySpaceMap, NumberOfDescriptors, NextRegionBase, NextRegionLength, GcdAttributes);
@ -426,13 +337,6 @@ SyncCacheConfig (
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
EfiAttributeToArmAttribute (
IN UINT64 EfiAttributes
@ -479,46 +383,23 @@ EfiAttributeToArmAttribute (
ArmAttributes |= TT_DESCRIPTOR_SECTION_XN_MASK;
}
if ((EfiAttributes & EFI_MEMORY_RP) == 0) {
ArmAttributes |= TT_DESCRIPTOR_SECTION_AF;
}
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
GetMemoryRegionPage (
IN UINT32 *PageTable,
IN UINTN *BaseAddress,
IN UINTN *RegionAttributes,
OUT UINTN *RegionLength
IN OUT UINTN *BaseAddress,
OUT UINTN *RegionLength,
OUT UINTN *RegionAttributes
)
{
UINT32 PageAttributes;
UINT32 TableIndex;
UINT32 PageDescriptor;
EFI_STATUS Status;
UINT32 PageAttributes;
UINT32 TableIndex;
UINT32 PageDescriptor;
// Convert the section attributes into page attributes
PageAttributes = ConvertSectionAttributesToPageAttributes (*RegionAttributes);
Status = EFI_NOT_FOUND;
*RegionLength = 0;
PageAttributes = ConvertSectionAttributesToPageAttributes (*RegionAttributes, 0);
// Calculate index into first level translation table for start of modification
TableIndex = ((*BaseAddress) & TT_DESCRIPTOR_PAGE_INDEX_MASK) >> TT_DESCRIPTOR_PAGE_BASE_SHIFT;
@ -530,44 +411,25 @@ GetMemoryRegionPage (
PageDescriptor = PageTable[TableIndex];
if ((PageDescriptor & TT_DESCRIPTOR_PAGE_TYPE_MASK) == TT_DESCRIPTOR_PAGE_TYPE_FAULT) {
Status = (*RegionLength > 0) ? EFI_SUCCESS : EFI_NO_MAPPING;
break;
// Case: End of the boundary of the region
return EFI_SUCCESS;
} else if ((PageDescriptor & TT_DESCRIPTOR_PAGE_TYPE_PAGE) == TT_DESCRIPTOR_PAGE_TYPE_PAGE) {
if ((PageDescriptor & TT_DESCRIPTOR_PAGE_ATTRIBUTE_MASK) != PageAttributes) {
Status = EFI_SUCCESS;
break;
if ((PageDescriptor & TT_DESCRIPTOR_PAGE_ATTRIBUTE_MASK) == PageAttributes) {
*RegionLength = *RegionLength + TT_DESCRIPTOR_PAGE_SIZE;
} else {
// Case: End of the boundary of the region
return EFI_SUCCESS;
}
*RegionLength += TT_DESCRIPTOR_PAGE_SIZE;
} else {
// Large pages are unsupported.
Status = EFI_UNSUPPORTED;
// We do not support Large Page yet. We return EFI_SUCCESS that means end of the region.
ASSERT (0);
break;
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
GetMemoryRegion (
IN OUT UINTN *BaseAddress,
@ -582,7 +444,6 @@ GetMemoryRegion (
UINT32 SectionDescriptor;
ARM_FIRST_LEVEL_DESCRIPTOR *FirstLevelTable;
UINT32 *PageTable;
UINTN Length;
// Initialize the arguments
*RegionLength = 0;
@ -592,11 +453,7 @@ GetMemoryRegion (
// Calculate index into first level translation table for start of modification
TableIndex = TT_DESCRIPTOR_SECTION_BASE_ADDRESS (*BaseAddress) >> TT_DESCRIPTOR_SECTION_BASE_SHIFT;
if (TableIndex >= TRANSLATION_TABLE_SECTION_COUNT) {
ASSERT (TableIndex < TRANSLATION_TABLE_SECTION_COUNT);
return EFI_INVALID_PARAMETER;
}
ASSERT (TableIndex < TRANSLATION_TABLE_SECTION_COUNT);
// Get the section at the given index
SectionDescriptor = FirstLevelTable[TableIndex];
@ -622,15 +479,10 @@ GetMemoryRegion (
ASSERT (PageTableIndex < TRANSLATION_TABLE_PAGE_COUNT);
PageAttributes = PageTable[PageTableIndex] & TT_DESCRIPTOR_PAGE_ATTRIBUTE_MASK;
*RegionAttributes = TT_DESCRIPTOR_CONVERT_TO_SECTION_CACHE_POLICY (PageAttributes) |
TT_DESCRIPTOR_CONVERT_TO_SECTION_S (PageAttributes) |
TT_DESCRIPTOR_CONVERT_TO_SECTION_XN (PageAttributes) |
TT_DESCRIPTOR_CONVERT_TO_SECTION_AF (PageAttributes) |
*RegionAttributes = TT_DESCRIPTOR_CONVERT_TO_SECTION_CACHE_POLICY (PageAttributes, 0) |
TT_DESCRIPTOR_CONVERT_TO_SECTION_AP (PageAttributes);
}
Status = EFI_NOT_FOUND;
for ( ; TableIndex < TRANSLATION_TABLE_SECTION_COUNT; TableIndex++) {
// Get the section at the given index
SectionDescriptor = FirstLevelTable[TableIndex];
@ -639,18 +491,14 @@ GetMemoryRegion (
if (TT_DESCRIPTOR_SECTION_TYPE_IS_PAGE_TABLE (SectionDescriptor)) {
// Extract the page table location from the descriptor
PageTable = (UINT32 *)(SectionDescriptor & TT_DESCRIPTOR_SECTION_PAGETABLE_ADDRESS_MASK);
Length = 0;
// Scan the page table to find the end of the region.
Status = GetMemoryRegionPage (PageTable, BaseAddress, RegionAttributes, &Length);
*RegionLength += Length;
Status = GetMemoryRegionPage (PageTable, BaseAddress, RegionLength, RegionAttributes);
// 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) ||
((SectionDescriptor & TT_DESCRIPTOR_SECTION_TYPE_MASK) == TT_DESCRIPTOR_SECTION_TYPE_SUPERSECTION))
{
@ -666,10 +514,5 @@ GetMemoryRegion (
}
}
// Check if the region length was updated.
if (*RegionLength > 0) {
Status = EFI_SUCCESS;
}
return Status;
return EFI_SUCCESS;
}

View File

@ -11,8 +11,6 @@
#include <Guid/IdleLoopEvent.h>
#include <Library/MemoryAllocationLib.h>
BOOLEAN mIsFlushingGCD;
/**
@ -229,77 +227,6 @@ InitializeDma (
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
CpuDxeInitialize (
IN EFI_HANDLE ImageHandle,
@ -313,26 +240,10 @@ CpuDxeInitialize (
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 (
&mCpuHandle,
&gEfiCpuArchProtocolGuid,
&mCpu,
&gEfiMemoryAttributeProtocolGuid,
&mMemoryAttribute,
NULL
);
@ -345,6 +256,12 @@ CpuDxeInitialize (
SyncCacheConfig (&mCpu);
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
//

View File

@ -30,12 +30,9 @@
#include <Protocol/Cpu.h>
#include <Protocol/DebugSupport.h>
#include <Protocol/LoadedImage.h>
#include <Protocol/MemoryAttribute.h>
extern BOOLEAN mIsFlushingGCD;
extern EFI_MEMORY_ATTRIBUTE_PROTOCOL mMemoryAttribute;
/**
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
@ -107,6 +104,21 @@ SyncCacheConfig (
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)
UINT64
EfiAttributeToArmAttribute (
@ -129,18 +141,4 @@ SetGcdMemorySpaceAttributes (
IN UINT64 Attributes
);
/**
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]
CpuDxe.c
CpuDxe.h
CpuMpCore.c
CpuMmuCommon.c
Exception.c
MemoryAttribute.c
[Sources.ARM]
Arm/Mmu.c
@ -48,14 +48,12 @@
DefaultExceptionHandlerLib
DxeServicesTableLib
HobLib
MemoryAllocationLib
PeCoffGetEntryPointLib
UefiDriverEntryPoint
UefiLib
[Protocols]
gEfiCpuArchProtocolGuid
gEfiMemoryAttributeProtocolGuid
[Guids]
gEfiDebugImageInfoTableGuid
@ -65,11 +63,9 @@
[Pcd.common]
gArmTokenSpaceGuid.PcdVFPEnabled
gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy
[FeaturePcd.common]
gArmTokenSpaceGuid.PcdDebuggerExceptionSupport
gArmTokenSpaceGuid.PcdRemapUnusedMemoryNx
[Depex]
gHardwareInterruptProtocolGuid OR gHardwareInterrupt2ProtocolGuid

View File

@ -217,7 +217,7 @@ CpuSetMemoryAttributes (
if (EFI_ERROR (Status) || (RegionArmAttributes != ArmAttributes) ||
((BaseAddress + Length) > (RegionBaseAddress + RegionLength)))
{
return ArmSetMemoryAttributes (BaseAddress, Length, EfiAttributes, 0);
return ArmSetMemoryAttributes (BaseAddress, Length, EfiAttributes);
} else {
return EFI_SUCCESS;
}

View File

@ -0,0 +1,98 @@
/** @file
*
* Copyright (c) 2011-2021, Arm Limited. All rights reserved.<BR>
*
* 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,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) 2011 Hewlett Packard Corporation. 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
@ -25,7 +24,6 @@ Abstract:
// The protocols, PPI and GUID definitions for this module
//
#include <Ppi/ArmMpCoreInfo.h>
#include <Ppi/MemoryAttribute.h>
//
// The Library classes this module consumes
@ -36,77 +34,6 @@ Abstract:
#include <Library/PcdLib.h>
#include <Library/HobLib.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
};
/*++
@ -152,8 +79,5 @@ InitializeCpuPeim (
}
}
Status = PeiServicesInstallPpi (&mMemoryAttributePpiDesc);
ASSERT_EFI_ERROR (Status);
return EFI_SUCCESS;
}

View File

@ -3,7 +3,6 @@
#
# This module provides platform specific function to detect boot mode.
# 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
#
@ -29,7 +28,6 @@
CpuPei.c
[Packages]
MdeModulePkg/MdeModulePkg.dec
MdePkg/MdePkg.dec
EmbeddedPkg/EmbeddedPkg.dec
ArmPkg/ArmPkg.dec
@ -39,11 +37,9 @@
DebugLib
HobLib
ArmLib
ArmMmuLib
[Ppis]
gArmMpCoreInfoPpiGuid
gEdkiiMemoryAttributePpiGuid
[Guids]
gArmMpCoreInfoGuid

View File

@ -1,13 +1,9 @@
/** @file
*
* Copyright (c) 2023, Ampere Computing LLC. All rights reserved.<BR>
* Copyright (c) 2013-2017, ARM Limited. All rights reserved.
*
* 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_
@ -18,17 +14,12 @@
// Control Frame:
#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_HIGH ((UINTN)FixedPcdGet64 (PcdGenericWatchdogControlBase) + 0x00C)
#define GENERIC_WDOG_OFFSET_REG ((UINTN)FixedPcdGet64 (PcdGenericWatchdogControlBase) + 0x008)
#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_IID_REG ((UINTN)FixedPcdGet64 (PcdGenericWatchdogControlBase) + 0xFCC)
// Values of bit 0 of the Control/Status Register
#define GENERIC_WDOG_ENABLED 1
#define GENERIC_WDOG_DISABLED 0
#define GENERIC_WDOG_IID_ARCH_REV_SHIFT 16
#define GENERIC_WDOG_IID_ARCH_REV_MASK 0xF
#endif // GENERIC_WATCHDOG_H_

View File

@ -1,6 +1,5 @@
/** @file
*
* Copyright (c) 2023, Ampere Computing LLC. All rights reserved.<BR>
* Copyright (c) 2013-2018, ARM Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-2-Clause-Patent
@ -28,58 +27,24 @@
in a second */
#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
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. */
STATIC UINT64 mTimerPeriod = 0;
/* disables watchdog interaction after Exit Boot Services */
STATIC BOOLEAN mExitedBootServices = FALSE;
#define MAX_UINT48 0xFFFFFFFFFFFFULL
STATIC UINT64 mNumTimerTicks = 0;
STATIC EFI_HARDWARE_INTERRUPT2_PROTOCOL *mInterruptProtocol;
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
VOID
WatchdogWriteOffsetRegister (
UINT64 Value
UINT32 Value
)
{
MmioWrite32 (GENERIC_WDOG_OFFSET_REG_LOW, Value & MAX_UINT32);
if (GetMaxWatchdogOffsetRegisterValue () == MAX_UINT48) {
MmioWrite32 (GENERIC_WDOG_OFFSET_REG_HIGH, (Value >> 32) & MAX_UINT16);
}
MmioWrite32 (GENERIC_WDOG_OFFSET_REG, Value);
}
STATIC
@ -122,8 +87,7 @@ WatchdogExitBootServicesEvent (
)
{
WatchdogDisable ();
mTimerPeriod = 0;
mExitedBootServices = TRUE;
mNumTimerTicks = 0;
}
/* This function is called when the watchdog's first signal (WS0) goes high.
@ -138,6 +102,7 @@ WatchdogInterruptHandler (
)
{
STATIC CONST CHAR16 ResetString[] = L"The generic watchdog timer ran out.";
UINT64 TimerPeriod;
WatchdogDisable ();
@ -150,7 +115,8 @@ WatchdogInterruptHandler (
// the timer period plus 1.
//
if (mWatchdogNotify != NULL) {
mWatchdogNotify (mTimerPeriod + 1);
TimerPeriod = ((TIME_UNITS_PER_SECOND / mTimerFrequencyHz) * mNumTimerTicks);
mWatchdogNotify (TimerPeriod + 1);
}
gRT->ResetSystem (
@ -220,8 +186,6 @@ WatchdogRegisterHandler (
@retval EFI_SUCCESS The watchdog timer has been programmed to fire
in TimerPeriod 100ns units.
@retval EFI_DEVICE_ERROR Boot Services has been exited but TimerPeriod
is not zero.
**/
STATIC
@ -232,47 +196,32 @@ WatchdogSetTimerPeriod (
IN UINT64 TimerPeriod // In 100ns units
)
{
UINTN SystemCount;
UINT64 MaxWatchdogOffsetValue;
UINT64 TimerFrequencyHz;
UINT64 NumTimerTicks;
UINTN SystemCount;
// If we've exited Boot Services but TimerPeriod isn't zero, this
// 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 is 0, this is a request to stop the watchdog.
if (TimerPeriod == 0) {
mTimerPeriod = 0;
mNumTimerTicks = 0;
WatchdogDisable ();
return EFI_SUCCESS;
}
// Work out how many timer ticks will equate to TimerPeriod
TimerFrequencyHz = ArmGenericTimerGetTimerFreq ();
ASSERT (TimerFrequencyHz != 0);
mTimerPeriod = TimerPeriod;
NumTimerTicks = (TimerFrequencyHz * TimerPeriod) / TIME_UNITS_PER_SECOND;
mNumTimerTicks = (mTimerFrequencyHz * TimerPeriod) / TIME_UNITS_PER_SECOND;
/* 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
the compare register (WCV) */
MaxWatchdogOffsetValue = GetMaxWatchdogOffsetRegisterValue ();
if (NumTimerTicks > MaxWatchdogOffsetValue) {
if (mNumTimerTicks > MAX_UINT32) {
/* We need to enable the watchdog *before* writing to the compare register,
because enabling the watchdog causes an "explicit refresh", which
clobbers the compare register (WCV). In order to make sure this doesn't
trigger an interrupt, set the offset to max. */
WatchdogWriteOffsetRegister (MaxWatchdogOffsetValue);
WatchdogWriteOffsetRegister (MAX_UINT32);
WatchdogEnable ();
SystemCount = ArmGenericTimerGetSystemCount ();
WatchdogWriteCompareRegister (SystemCount + NumTimerTicks);
WatchdogWriteCompareRegister (SystemCount + mNumTimerTicks);
} else {
WatchdogWriteOffsetRegister (NumTimerTicks);
WatchdogWriteOffsetRegister ((UINT32)mNumTimerTicks);
WatchdogEnable ();
}
@ -307,7 +256,7 @@ WatchdogGetTimerPeriod (
return EFI_INVALID_PARAMETER;
}
*TimerPeriod = mTimerPeriod;
*TimerPeriod = ((TIME_UNITS_PER_SECOND / mTimerFrequencyHz) * mNumTimerTicks);
return EFI_SUCCESS;
}
@ -350,6 +299,8 @@ STATIC EFI_WATCHDOG_TIMER_ARCH_PROTOCOL mWatchdogTimer = {
WatchdogGetTimerPeriod
};
STATIC EFI_EVENT mEfiExitBootServicesEvent;
EFI_STATUS
EFIAPI
GenericWatchdogEntry (
@ -372,6 +323,9 @@ GenericWatchdogEntry (
This will avoid conflicts with the universal watchdog */
ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiWatchdogTimerArchProtocolGuid);
mTimerFrequencyHz = ArmGenericTimerGetTimerFreq ();
ASSERT (mTimerFrequencyHz != 0);
// Install interrupt handler
Status = mInterruptProtocol->RegisterInterruptSource (
mInterruptProtocol,
@ -413,6 +367,7 @@ GenericWatchdogEntry (
);
ASSERT_EFI_ERROR (Status);
mNumTimerTicks = 0;
WatchdogDisable ();
return EFI_SUCCESS;

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

@ -574,7 +574,7 @@ ExtendFile (
}
Remaining = Size;
ZeroMem (WriteBuffer, sizeof (WriteBuffer));
SetMem (WriteBuffer, 0, sizeof (WriteBuffer));
while (Remaining > 0) {
WriteNb = MIN (Remaining, sizeof (WriteBuffer));
WriteSize = WriteNb;

View File

@ -38,22 +38,10 @@
.global Name ; \
.section #Section, "ax" ; \
.type Name, %function ; \
Name: ; \
AARCH64_BTI(c)
#define _ASM_FUNC_ALIGN(Name, Section, Align) \
.global Name ; \
.section #Section, "ax" ; \
.type Name, %function ; \
.balign Align ; \
Name: ; \
AARCH64_BTI(c)
Name:
#define ASM_FUNC(Name) _ASM_FUNC(ASM_PFX(Name), .text. ## Name)
#define ASM_FUNC_ALIGN(Name, Align) \
_ASM_FUNC_ALIGN(ASM_PFX(Name), .text. ## Name, Align)
#define MOV32(Reg, Val) \
movz Reg, (Val) >> 16, lsl #16 ; \
movk Reg, (Val) & 0xffff

View File

@ -24,17 +24,10 @@
// Coprocessor Trap Register (CPTR)
#define AARCH64_CPTR_TFP (1 << 10)
// ID_AA64MMFR1 - AArch64 Memory Model Feature Register 0 definitions
#define AARCH64_MMFR1_VH (0xF << 8)
// ID_AA64PFR0 - AArch64 Processor Feature Register 0 definitions
#define AARCH64_PFR0_FP (0xF << 16)
#define AARCH64_PFR0_GIC (0xF << 24)
// ID_AA64DFR0 - AArch64 Debug Feature Register 0 definitions
#define AARCH64_DFR0_TRACEVER (0xFULL << 4)
#define AARCH64_DFR0_TRBE (0xFULL << 44)
// SCR - Secure Configuration Register definitions
#define SCR_NS (1 << 0)
#define SCR_IRQ (1 << 1)
@ -119,10 +112,6 @@
#define ARM_VECTOR_LOW_A32_FIQ 0x700
#define ARM_VECTOR_LOW_A32_SERR 0x780
// The ID_AA64ISAR2_EL1 register is not recognized by older
// assemblers, we need to define it here.
#define ID_AA64ISAR2_EL1 S3_0_C0_C6_2
// The ID_AA64MMFR2_EL1 register was added in ARMv8.2. Since we
// build for ARMv8.0, we need to define the register here.
#define ID_AA64MMFR2_EL1 S3_0_C0_C7_2

View File

@ -0,0 +1,44 @@
/** @file
Copyright (c) 2012 - 2021, Arm Limited. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#ifndef ARM_CORTEX_A5X_H_
#define ARM_CORTEX_A5X_H_
//
// Cortex A5x feature bit definitions
//
#define A5X_FEATURE_SMP (1 << 6)
//
// Helper functions to access CPU Extended Control Register
//
UINT64
EFIAPI
ArmReadCpuExCr (
VOID
);
VOID
EFIAPI
ArmWriteCpuExCr (
IN UINT64 Val
);
VOID
EFIAPI
ArmSetCpuExCrBit (
IN UINT64 Bits
);
VOID
EFIAPI
ArmUnsetCpuExCrBit (
IN UINT64 Bits
);
#endif // ARM_CORTEX_A5X_H_

View File

@ -0,0 +1,57 @@
/** @file
Copyright (c) 2011, ARM Limited. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#ifndef ARM_CORTEX_A9_H_
#define ARM_CORTEX_A9_H_
#include <Chipset/ArmV7.h>
//
// Cortex A9 feature bit definitions
//
#define A9_FEATURE_PARITY (1<<9)
#define A9_FEATURE_AOW (1<<8)
#define A9_FEATURE_EXCL (1<<7)
#define A9_FEATURE_SMP (1<<6)
#define A9_FEATURE_FOZ (1<<3)
#define A9_FEATURE_DPREF (1<<2)
#define A9_FEATURE_HINT (1<<1)
#define A9_FEATURE_FWD (1<<0)
//
// Cortex A9 Watchdog
//
#define ARM_A9_WATCHDOG_REGION 0x600
#define ARM_A9_WATCHDOG_LOAD_REGISTER 0x20
#define ARM_A9_WATCHDOG_CONTROL_REGISTER 0x28
#define ARM_A9_WATCHDOG_WATCHDOG_MODE (1 << 3)
#define ARM_A9_WATCHDOG_TIMER_MODE (0 << 3)
#define ARM_A9_WATCHDOG_SINGLE_SHOT (0 << 1)
#define ARM_A9_WATCHDOG_AUTORELOAD (1 << 1)
#define ARM_A9_WATCHDOG_ENABLE 1
//
// SCU register offsets & masks
//
#define A9_SCU_CONTROL_OFFSET 0x0
#define A9_SCU_CONFIG_OFFSET 0x4
#define A9_SCU_INVALL_OFFSET 0xC
#define A9_SCU_FILT_START_OFFSET 0x40
#define A9_SCU_FILT_END_OFFSET 0x44
#define A9_SCU_SACR_OFFSET 0x50
#define A9_SCU_SSACR_OFFSET 0x54
UINTN
EFIAPI
ArmGetScuBaseAddress (
VOID
);
#endif // ARM_CORTEX_A9_H_

View File

@ -54,9 +54,11 @@
#define TT_DESCRIPTOR_SECTION_TYPE_IS_PAGE_TABLE(Desc) (((Desc) & 3UL) == TT_DESCRIPTOR_SECTION_TYPE_PAGE_TABLE)
// Translation table descriptor types
#define TT_DESCRIPTOR_PAGE_TYPE_MASK (1UL << 1)
#define TT_DESCRIPTOR_PAGE_TYPE_FAULT (0UL << 1)
#define TT_DESCRIPTOR_PAGE_TYPE_PAGE (1UL << 1)
#define TT_DESCRIPTOR_PAGE_TYPE_MASK (3UL << 0)
#define TT_DESCRIPTOR_PAGE_TYPE_FAULT (0UL << 0)
#define TT_DESCRIPTOR_PAGE_TYPE_PAGE (2UL << 0)
#define TT_DESCRIPTOR_PAGE_TYPE_PAGE_XN (3UL << 0)
#define TT_DESCRIPTOR_PAGE_TYPE_LARGEPAGE (1UL << 0)
// Section descriptor definitions
#define TT_DESCRIPTOR_SECTION_SIZE (0x00100000)
@ -80,24 +82,25 @@
#define TT_DESCRIPTOR_PAGE_S_NOT_SHARED (0UL << 10)
#define TT_DESCRIPTOR_PAGE_S_SHARED (1UL << 10)
#define TT_DESCRIPTOR_SECTION_AP_MASK ((1UL << 15) | (1UL << 11))
#define TT_DESCRIPTOR_SECTION_AP_NO_RW ((0UL << 15) | (0UL << 11))
#define TT_DESCRIPTOR_SECTION_AP_RW_RW ((0UL << 15) | (1UL << 11))
#define TT_DESCRIPTOR_SECTION_AP_NO_RO ((1UL << 15) | (0UL << 11))
#define TT_DESCRIPTOR_SECTION_AP_RO_RO ((1UL << 15) | (1UL << 11))
#define TT_DESCRIPTOR_SECTION_AP_MASK ((1UL << 15) | (3UL << 10))
#define TT_DESCRIPTOR_SECTION_AP_NO_NO ((0UL << 15) | (0UL << 10))
#define TT_DESCRIPTOR_SECTION_AP_RW_NO ((0UL << 15) | (1UL << 10))
#define TT_DESCRIPTOR_SECTION_AP_RW_RO ((0UL << 15) | (2UL << 10))
#define TT_DESCRIPTOR_SECTION_AP_RW_RW ((0UL << 15) | (3UL << 10))
#define TT_DESCRIPTOR_SECTION_AP_RO_NO ((1UL << 15) | (1UL << 10))
#define TT_DESCRIPTOR_SECTION_AP_RO_RO ((1UL << 15) | (3UL << 10))
#define TT_DESCRIPTOR_SECTION_AF (1UL << 10)
#define TT_DESCRIPTOR_PAGE_AP_MASK ((1UL << 9) | (3UL << 4))
#define TT_DESCRIPTOR_PAGE_AP_NO_NO ((0UL << 9) | (0UL << 4))
#define TT_DESCRIPTOR_PAGE_AP_RW_NO ((0UL << 9) | (1UL << 4))
#define TT_DESCRIPTOR_PAGE_AP_RW_RO ((0UL << 9) | (2UL << 4))
#define TT_DESCRIPTOR_PAGE_AP_RW_RW ((0UL << 9) | (3UL << 4))
#define TT_DESCRIPTOR_PAGE_AP_RO_NO ((1UL << 9) | (1UL << 4))
#define TT_DESCRIPTOR_PAGE_AP_RO_RO ((1UL << 9) | (3UL << 4))
#define TT_DESCRIPTOR_PAGE_AP_MASK ((1UL << 9) | (1UL << 5))
#define TT_DESCRIPTOR_PAGE_AP_NO_RW ((0UL << 9) | (0UL << 5))
#define TT_DESCRIPTOR_PAGE_AP_RW_RW ((0UL << 9) | (1UL << 5))
#define TT_DESCRIPTOR_PAGE_AP_NO_RO ((1UL << 9) | (0UL << 5))
#define TT_DESCRIPTOR_PAGE_AP_RO_RO ((1UL << 9) | (1UL << 5))
#define TT_DESCRIPTOR_PAGE_AF (1UL << 4)
#define TT_DESCRIPTOR_SECTION_XN_MASK (0x1UL << 4)
#define TT_DESCRIPTOR_PAGE_XN_MASK (0x1UL << 0)
#define TT_DESCRIPTOR_SECTION_XN_MASK (0x1UL << 4)
#define TT_DESCRIPTOR_PAGE_XN_MASK (0x1UL << 0)
#define TT_DESCRIPTOR_LARGEPAGE_XN_MASK (0x1UL << 15)
#define TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK ((3UL << 12) | (1UL << 3) | (1UL << 2))
#define TT_DESCRIPTOR_SECTION_CACHEABLE_MASK (1UL << 3)
@ -121,27 +124,37 @@
#define TT_DESCRIPTOR_PAGE_CACHE_POLICY_WRITE_BACK_ALLOC ((1UL << 6) | (1UL << 3) | (1UL << 2))
#define TT_DESCRIPTOR_PAGE_CACHE_POLICY_NON_SHAREABLE_DEVICE ((2UL << 6) | (0UL << 3) | (0UL << 2))
#define TT_DESCRIPTOR_CONVERT_TO_PAGE_AP(Desc) ((((Desc) & TT_DESCRIPTOR_SECTION_AP_MASK) >> 6) & TT_DESCRIPTOR_PAGE_AP_MASK)
#define TT_DESCRIPTOR_CONVERT_TO_PAGE_NG(Desc) ((((Desc) & TT_DESCRIPTOR_SECTION_NG_MASK) >> 6) & TT_DESCRIPTOR_PAGE_NG_MASK)
#define TT_DESCRIPTOR_CONVERT_TO_PAGE_S(Desc) ((((Desc) & TT_DESCRIPTOR_SECTION_S_MASK) >> 6) & TT_DESCRIPTOR_PAGE_S_MASK)
#define TT_DESCRIPTOR_CONVERT_TO_PAGE_AF(Desc) ((((Desc) & TT_DESCRIPTOR_SECTION_AF) >> 6) & TT_DESCRIPTOR_PAGE_AF)
#define TT_DESCRIPTOR_CONVERT_TO_PAGE_XN(Desc) ((((Desc) & TT_DESCRIPTOR_SECTION_XN_MASK) >> 4) & TT_DESCRIPTOR_PAGE_XN_MASK)
#define TT_DESCRIPTOR_CONVERT_TO_PAGE_CACHE_POLICY(Desc) ((((Desc) & (0x3 << 12)) >> 6) | (Desc & (0x3 << 2)))
#define TT_DESCRIPTOR_LARGEPAGE_CACHE_POLICY_MASK ((3UL << 12) | (1UL << 3) | (1UL << 2))
#define TT_DESCRIPTOR_LARGEPAGE_CACHE_POLICY_STRONGLY_ORDERED ((0UL << 12) | (0UL << 3) | (0UL << 2))
#define TT_DESCRIPTOR_LARGEPAGE_CACHE_POLICY_SHAREABLE_DEVICE ((0UL << 12) | (0UL << 3) | (1UL << 2))
#define TT_DESCRIPTOR_LARGEPAGE_CACHE_POLICY_WRITE_THROUGH_NO_ALLOC ((0UL << 12) | (1UL << 3) | (0UL << 2))
#define TT_DESCRIPTOR_LARGEPAGE_CACHE_POLICY_WRITE_BACK_NO_ALLOC ((0UL << 12) | (1UL << 3) | (1UL << 2))
#define TT_DESCRIPTOR_LARGEPAGE_CACHE_POLICY_NON_CACHEABLE ((1UL << 12) | (0UL << 3) | (0UL << 2))
#define TT_DESCRIPTOR_LARGEPAGE_CACHE_POLICY_WRITE_BACK_ALLOC ((1UL << 12) | (1UL << 3) | (1UL << 2))
#define TT_DESCRIPTOR_LARGEPAGE_CACHE_POLICY_NON_SHAREABLE_DEVICE ((2UL << 12) | (0UL << 3) | (0UL << 2))
#define TT_DESCRIPTOR_CONVERT_TO_SECTION_AP(Desc) ((((Desc) & TT_DESCRIPTOR_PAGE_AP_MASK) << 6) & TT_DESCRIPTOR_SECTION_AP_MASK)
#define TT_DESCRIPTOR_CONVERT_TO_SECTION_S(Desc) ((((Desc) & TT_DESCRIPTOR_PAGE_S_MASK) << 6) & TT_DESCRIPTOR_SECTION_S_MASK)
#define TT_DESCRIPTOR_CONVERT_TO_SECTION_AF(Desc) ((((Desc) & TT_DESCRIPTOR_PAGE_AF) << 6) & TT_DESCRIPTOR_SECTION_AF)
#define TT_DESCRIPTOR_CONVERT_TO_SECTION_XN(Desc) ((((Desc) & TT_DESCRIPTOR_PAGE_XN_MASK) << 4) & TT_DESCRIPTOR_SECTION_XN_MASK)
#define TT_DESCRIPTOR_CONVERT_TO_SECTION_CACHE_POLICY(Desc) ((((Desc) & (0x3 << 6)) << 6) | (Desc & (0x3 << 2)))
#define TT_DESCRIPTOR_CONVERT_TO_PAGE_AP(Desc) ((((Desc) & TT_DESCRIPTOR_SECTION_AP_MASK) >> 6) & TT_DESCRIPTOR_PAGE_AP_MASK)
#define TT_DESCRIPTOR_CONVERT_TO_PAGE_NG(Desc) ((((Desc) & TT_DESCRIPTOR_SECTION_NG_MASK) >> 6) & TT_DESCRIPTOR_PAGE_NG_MASK)
#define TT_DESCRIPTOR_CONVERT_TO_PAGE_S(Desc) ((((Desc) & TT_DESCRIPTOR_SECTION_S_MASK) >> 6) & TT_DESCRIPTOR_PAGE_S_MASK)
#define TT_DESCRIPTOR_CONVERT_TO_PAGE_XN(Desc, IsLargePage) ((IsLargePage)?\
((((Desc) & TT_DESCRIPTOR_SECTION_XN_MASK) << 11) & TT_DESCRIPTOR_LARGEPAGE_XN_MASK): \
((((Desc) & TT_DESCRIPTOR_SECTION_XN_MASK) >> 4) & TT_DESCRIPTOR_PAGE_XN_MASK))
#define TT_DESCRIPTOR_CONVERT_TO_PAGE_CACHE_POLICY(Desc, IsLargePage) (IsLargePage? \
(((Desc) & TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK) & TT_DESCRIPTOR_LARGEPAGE_CACHE_POLICY_MASK): \
(((((Desc) & (0x3 << 12)) >> 6) | (Desc & (0x3 << 2)))))
#define TT_DESCRIPTOR_CONVERT_TO_SECTION_AP(Desc) ((((Desc) & TT_DESCRIPTOR_PAGE_AP_MASK) << 6) & TT_DESCRIPTOR_SECTION_AP_MASK)
#define TT_DESCRIPTOR_CONVERT_TO_SECTION_CACHE_POLICY(Desc, IsLargePage) (IsLargePage? \
(((Desc) & TT_DESCRIPTOR_LARGEPAGE_CACHE_POLICY_MASK) & TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK): \
(((((Desc) & (0x3 << 6)) << 6) | (Desc & (0x3 << 2)))))
#define TT_DESCRIPTOR_SECTION_ATTRIBUTE_MASK (TT_DESCRIPTOR_SECTION_NS_MASK | TT_DESCRIPTOR_SECTION_NG_MASK | \
TT_DESCRIPTOR_SECTION_S_MASK | TT_DESCRIPTOR_SECTION_AP_MASK | \
TT_DESCRIPTOR_SECTION_AF | \
TT_DESCRIPTOR_SECTION_XN_MASK | TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK)
#define TT_DESCRIPTOR_PAGE_ATTRIBUTE_MASK (TT_DESCRIPTOR_PAGE_NG_MASK | TT_DESCRIPTOR_PAGE_S_MASK | \
TT_DESCRIPTOR_PAGE_AP_MASK | TT_DESCRIPTOR_PAGE_XN_MASK | \
TT_DESCRIPTOR_PAGE_AF | \
TT_DESCRIPTOR_PAGE_CACHE_POLICY_MASK)
#define TT_DESCRIPTOR_SECTION_DOMAIN_MASK (0x0FUL << 5)
@ -157,49 +170,56 @@
#define TT_DESCRIPTOR_PAGE_BASE_ADDRESS(a) ((a) & TT_DESCRIPTOR_PAGE_BASE_ADDRESS_MASK)
#define TT_DESCRIPTOR_PAGE_BASE_SHIFT 12
#define TT_DESCRIPTOR_SECTION_DEFAULT (TT_DESCRIPTOR_SECTION_TYPE_SECTION | \
TT_DESCRIPTOR_SECTION_NG_GLOBAL | \
TT_DESCRIPTOR_SECTION_S_SHARED | \
TT_DESCRIPTOR_SECTION_DOMAIN(0) | \
TT_DESCRIPTOR_SECTION_AP_RW_RW | \
TT_DESCRIPTOR_SECTION_AF)
#define TT_DESCRIPTOR_SECTION_WRITE_BACK (TT_DESCRIPTOR_SECTION_DEFAULT | \
TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_BACK_ALLOC)
#define TT_DESCRIPTOR_SECTION_WRITE_THROUGH (TT_DESCRIPTOR_SECTION_DEFAULT | \
TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_THROUGH_NO_ALLOC)
#define TT_DESCRIPTOR_SECTION_DEVICE (TT_DESCRIPTOR_SECTION_DEFAULT | \
TT_DESCRIPTOR_SECTION_CACHE_POLICY_SHAREABLE_DEVICE)
#define TT_DESCRIPTOR_SECTION_UNCACHED (TT_DESCRIPTOR_SECTION_DEFAULT | \
TT_DESCRIPTOR_SECTION_CACHE_POLICY_NON_CACHEABLE)
#define TT_DESCRIPTOR_SECTION_WRITE_BACK(NonSecure) (TT_DESCRIPTOR_SECTION_TYPE_SECTION | \
((NonSecure) ? TT_DESCRIPTOR_SECTION_NS : 0) | \
TT_DESCRIPTOR_SECTION_NG_GLOBAL | \
TT_DESCRIPTOR_SECTION_S_SHARED | \
TT_DESCRIPTOR_SECTION_DOMAIN(0) | \
TT_DESCRIPTOR_SECTION_AP_RW_RW | \
TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_BACK_ALLOC)
#define TT_DESCRIPTOR_SECTION_WRITE_THROUGH(NonSecure) (TT_DESCRIPTOR_SECTION_TYPE_SECTION | \
((NonSecure) ? TT_DESCRIPTOR_SECTION_NS : 0) | \
TT_DESCRIPTOR_SECTION_NG_GLOBAL | \
TT_DESCRIPTOR_SECTION_S_SHARED | \
TT_DESCRIPTOR_SECTION_DOMAIN(0) | \
TT_DESCRIPTOR_SECTION_AP_RW_RW | \
TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_THROUGH_NO_ALLOC)
#define TT_DESCRIPTOR_SECTION_DEVICE(NonSecure) (TT_DESCRIPTOR_SECTION_TYPE_SECTION | \
((NonSecure) ? TT_DESCRIPTOR_SECTION_NS : 0) | \
TT_DESCRIPTOR_SECTION_NG_GLOBAL | \
TT_DESCRIPTOR_SECTION_S_NOT_SHARED | \
TT_DESCRIPTOR_SECTION_DOMAIN(0) | \
TT_DESCRIPTOR_SECTION_AP_RW_RW | \
TT_DESCRIPTOR_SECTION_XN_MASK | \
TT_DESCRIPTOR_SECTION_CACHE_POLICY_SHAREABLE_DEVICE)
#define TT_DESCRIPTOR_SECTION_UNCACHED(NonSecure) (TT_DESCRIPTOR_SECTION_TYPE_SECTION | \
((NonSecure) ? TT_DESCRIPTOR_SECTION_NS : 0) | \
TT_DESCRIPTOR_SECTION_NG_GLOBAL | \
TT_DESCRIPTOR_SECTION_S_NOT_SHARED | \
TT_DESCRIPTOR_SECTION_DOMAIN(0) | \
TT_DESCRIPTOR_SECTION_AP_RW_RW | \
TT_DESCRIPTOR_SECTION_CACHE_POLICY_NON_CACHEABLE)
#define TT_DESCRIPTOR_PAGE_WRITE_BACK (TT_DESCRIPTOR_PAGE_TYPE_PAGE | \
TT_DESCRIPTOR_PAGE_NG_GLOBAL | \
TT_DESCRIPTOR_PAGE_S_SHARED | \
TT_DESCRIPTOR_PAGE_AP_RW_RW | \
TT_DESCRIPTOR_PAGE_AF | \
TT_DESCRIPTOR_PAGE_CACHE_POLICY_WRITE_BACK_ALLOC)
#define TT_DESCRIPTOR_PAGE_WRITE_THROUGH (TT_DESCRIPTOR_PAGE_TYPE_PAGE | \
TT_DESCRIPTOR_PAGE_NG_GLOBAL | \
TT_DESCRIPTOR_PAGE_S_SHARED | \
TT_DESCRIPTOR_PAGE_AP_RW_RW | \
TT_DESCRIPTOR_PAGE_AF | \
TT_DESCRIPTOR_PAGE_CACHE_POLICY_WRITE_THROUGH_NO_ALLOC)
#define TT_DESCRIPTOR_PAGE_DEVICE (TT_DESCRIPTOR_PAGE_TYPE_PAGE | \
TT_DESCRIPTOR_PAGE_NG_GLOBAL | \
TT_DESCRIPTOR_PAGE_S_NOT_SHARED | \
TT_DESCRIPTOR_PAGE_AP_RW_RW | \
TT_DESCRIPTOR_PAGE_AF | \
TT_DESCRIPTOR_PAGE_XN_MASK | \
TT_DESCRIPTOR_PAGE_CACHE_POLICY_SHAREABLE_DEVICE)
#define TT_DESCRIPTOR_PAGE_UNCACHED (TT_DESCRIPTOR_PAGE_TYPE_PAGE | \
TT_DESCRIPTOR_PAGE_NG_GLOBAL | \
TT_DESCRIPTOR_PAGE_S_NOT_SHARED | \
TT_DESCRIPTOR_PAGE_AP_RW_RW | \
TT_DESCRIPTOR_PAGE_AF | \
TT_DESCRIPTOR_PAGE_CACHE_POLICY_NON_CACHEABLE)
// First Level Descriptors
@ -210,7 +230,8 @@ typedef UINT32 ARM_PAGE_TABLE_ENTRY;
UINT32
ConvertSectionAttributesToPageAttributes (
IN UINT32 SectionAttributes
IN UINT32 SectionAttributes,
IN BOOLEAN IsLargePage
);
#endif // ARMV7_MMU_H_

View File

@ -23,9 +23,36 @@ typedef struct {
UINT64 MailboxClearValue;
} ARM_CORE_INFO;
typedef struct {
UINT64 Signature;
UINT32 Length;
UINT32 Revision;
UINT64 OemId;
UINT64 OemTableId;
UINTN OemRevision;
UINTN CreatorId;
UINTN CreatorRevision;
EFI_GUID Identifier;
UINTN DataLen;
} ARM_PROCESSOR_TABLE_HEADER;
typedef struct {
ARM_PROCESSOR_TABLE_HEADER Header;
UINTN NumberOfEntries;
ARM_CORE_INFO *ArmCpus;
} ARM_PROCESSOR_TABLE;
#define ARM_MP_CORE_INFO_GUID \
{ 0xa4ee0728, 0xe5d7, 0x4ac5, {0xb2, 0x1e, 0x65, 0x8e, 0xd8, 0x57, 0xe8, 0x34} }
#define EFI_ARM_PROCESSOR_TABLE_SIGNATURE SIGNATURE_64 ('C', 'P', 'U', 'T', 'A', 'B', 'L', 'E')
#define EFI_ARM_PROCESSOR_TABLE_REVISION 0x00010000// 1.0
#define EFI_ARM_PROCESSOR_TABLE_OEM_ID SIGNATURE_64('A','R','M',' ', 'L', 't', 'd', ' ')
#define EFI_ARM_PROCESSOR_TABLE_OEM_TABLE_ID SIGNATURE_64('V', 'E', 'R', 'S', 'A', 'T', 'I', 'L')
#define EFI_ARM_PROCESSOR_TABLE_OEM_REVISION 0x00000001
#define EFI_ARM_PROCESSOR_TABLE_CREATOR_ID 0xA5A5A5A5
#define EFI_ARM_PROCESSOR_TABLE_CREATOR_REVISION 0x01000001
extern EFI_GUID gArmMpCoreInfoGuid;
#endif /* ARM_MP_CORE_INFO_GUID_H_ */

View File

@ -1,20 +1,13 @@
/** @file
*
* Copyright (c) 2020, NUVIA Inc. All rights reserved.<BR>
* Copyright (c) 2012 - 2022, Arm Limited. All rights reserved.
* Copyright (c) 2012-2017, ARM Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-2-Clause-Patent
*
* @par Revision Reference:
* - [1] SMC Calling Convention version 1.2
* - SMC Calling Convention version 1.2
* (https://developer.arm.com/documentation/den0028/c/?lang=en)
* - [2] Arm True Random Number Generator Firmware, Interface 1.0,
* Platform Design Document.
* (https://developer.arm.com/documentation/den0098/latest/)
*
* @par Glossary:
* - TRNG - True Random Number Generator
*
**/
#ifndef ARM_STD_SMC_H_
@ -100,8 +93,6 @@
#define ARM_SMC_ID_PSCI_MIGRATE_AARCH32 0x84000005
#define ARM_SMC_ID_PSCI_SYSTEM_OFF 0x84000008
#define ARM_SMC_ID_PSCI_SYSTEM_RESET 0x84000009
#define ARM_SMC_ID_PSCI_FEATURES 0x8400000A
#define ARM_SMC_ID_PSCI_SYSTEM_RESET2_AARCH64 0xC4000012
/* The current PSCI version is: 0.2 */
#define ARM_SMC_PSCI_VERSION_MAJOR 0
@ -146,111 +137,4 @@
/* 0xbf00ff02 is reserved */
#define ARM_SMC_ID_TOS_REVISION 0xbf00ff03
// Firmware TRNG interface Function IDs
/*
SMC/HVC call to get the version of the TRNG backend,
Cf. [2], 2.1 TRNG_VERSION
Input values:
W0 0x8400_0050
W1-W7 Reserved (MBZ)
Return values:
Success (W0 > 0) W0[31] MBZ
W0[30:16] Major revision
W0[15:0] Minor revision
W1 - W3 Reserved (MBZ)
Error (W0 < 0)
NOT_SUPPORTED Function not implemented
*/
#define ARM_SMC_ID_TRNG_VERSION 0x84000050
/*
SMC/HVC call to check if a TRNG function ID is implemented by the backend,
Cf. [2], Section 2.2 TRNG_FEATURES
Input Values
W0 0x8400_0051
W1 trng_func_id
W2-W7 Reserved (MBZ)
Return values:
Success (W0 >= 0):
SUCCESS Function is implemented.
> 0 Function is implemented and
has specific capabilities,
see function definition.
Error (W0 < 0)
NOT_SUPPORTED Function with FID=trng_func_id
is not implemented
*/
#define ARM_SMC_ID_TRNG_FEATURES 0x84000051
/*
SMC/HVC call to get the UUID of the TRNG backend,
Cf. [2], Section 2.3 TRNG_GET_UUID
Input Values:
W0 0x8400_0052
W1-W7 Reserved (MBZ)
Return Values:
Success (W0 != -1)
W0 UUID[31:0]
W1 UUID[63:32]
W2 UUID[95:64]
W3 UUID[127:96]
Error (W0 = -1)
W0 NOT_SUPPORTED
*/
#define ARM_SMC_ID_TRNG_GET_UUID 0x84000052
/*
AARCH32 SMC/HVC call to get entropy bits, Cf. [2], Section 2.4 TRNG_RND.
Input values:
W0 0x8400_0053
W2-W7 Reserved (MBZ)
Return values:
Success (W0 = 0):
W0 MBZ
W1 Entropy[95:64]
W2 Entropy[63:32]
W3 Entropy[31:0]
Error (W0 < 0)
W0 NOT_SUPPORTED
NO_ENTROPY
INVALID_PARAMETERS
W1 - W3 Reserved (MBZ)
*/
#define ARM_SMC_ID_TRNG_RND_AARCH32 0x84000053
/*
AARCH64 SMC/HVC call to get entropy bits, Cf. [2], Section 2.4 TRNG_RND.
Input values:
X0 0xC400_0053
X2-X7 Reserved (MBZ)
Return values:
Success (X0 = 0):
X0 MBZ
X1 Entropy[191:128]
X2 Entropy[127:64]
X3 Entropy[63:0]
Error (X0 < 0)
X0 NOT_SUPPORTED
NO_ENTROPY
INVALID_PARAMETERS
X1 - X3 Reserved (MBZ)
*/
#define ARM_SMC_ID_TRNG_RND_AARCH64 0xC4000053
// Firmware TRNG status codes
#define TRNG_STATUS_SUCCESS (INT32)(0)
#define TRNG_STATUS_NOT_SUPPORTED (INT32)(-1)
#define TRNG_STATUS_INVALID_PARAMETER (INT32)(-2)
#define TRNG_STATUS_NO_ENTROPY (INT32)(-3)
/*
* SMC64 SiP Service Calls
*/
#define SMC_FASTCALL 0x80000000
#define SMC64_FUNCTION (SMC_FASTCALL | 0x40000000)
#define SMC_SIP_FUNCTION (SMC64_FUNCTION | 0x02000000)
#define SMC_SIP_FUNCTION_ID(n) (SMC_SIP_FUNCTION | (n))
#endif // ARM_STD_SMC_H_

View File

@ -1,15 +1,9 @@
/** @file
*
* Copyright (c) 2015, Linaro Ltd. All rights reserved.
* Copyright (c) 2024, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-2-Clause-Patent
*
* @par Reference(s):
* - Arm Generic Interrupt Controller Architecture Specification,
* Issue H, January 2022.
* (https://developer.arm.com/documentation/ihi0069/)
*
**/
#ifndef ARM_GIC_ARCH_LIB_H_
@ -29,12 +23,4 @@ ArmGicGetSupportedArchRevision (
VOID
);
//
// GIC SPI and extended SPI ranges
//
#define ARM_GIC_ARCH_SPI_MIN 32
#define ARM_GIC_ARCH_SPI_MAX 1019
#define ARM_GIC_ARCH_EXT_SPI_MIN 4096
#define ARM_GIC_ARCH_EXT_SPI_MAX 5119
#endif // ARM_GIC_ARCH_LIB_H_

View File

@ -1,6 +1,6 @@
/** @file
*
* Copyright (c) 2011-2023, Arm Limited. All rights reserved.<BR>
* Copyright (c) 2011-2021, Arm Limited. All rights reserved.<BR>
*
* SPDX-License-Identifier: BSD-2-Clause-Patent
*
@ -110,10 +110,10 @@
// Bit Mask for
#define ARM_GIC_ICCIAR_ACKINTID 0x3FF
UINT32
UINTN
EFIAPI
ArmGicGetInterfaceIdentification (
IN UINTN GicInterruptInterfaceBase
IN INTN GicInterruptInterfaceBase
);
// GIC Secure interfaces
@ -121,8 +121,8 @@ VOID
EFIAPI
ArmGicSetupNonSecure (
IN UINTN MpId,
IN UINTN GicDistributorBase,
IN UINTN GicInterruptInterfaceBase
IN INTN GicDistributorBase,
IN INTN GicInterruptInterfaceBase
);
VOID
@ -136,40 +136,40 @@ ArmGicSetSecureInterrupts (
VOID
EFIAPI
ArmGicEnableInterruptInterface (
IN UINTN GicInterruptInterfaceBase
IN INTN GicInterruptInterfaceBase
);
VOID
EFIAPI
ArmGicDisableInterruptInterface (
IN UINTN GicInterruptInterfaceBase
IN INTN GicInterruptInterfaceBase
);
VOID
EFIAPI
ArmGicEnableDistributor (
IN UINTN GicDistributorBase
IN INTN GicDistributorBase
);
VOID
EFIAPI
ArmGicDisableDistributor (
IN UINTN GicDistributorBase
IN INTN GicDistributorBase
);
UINTN
EFIAPI
ArmGicGetMaxNumInterrupts (
IN UINTN GicDistributorBase
IN INTN GicDistributorBase
);
VOID
EFIAPI
ArmGicSendSgiTo (
IN UINTN GicDistributorBase,
IN UINT8 TargetListFilter,
IN UINT8 CPUTargetList,
IN UINT8 SgiId
IN INTN GicDistributorBase,
IN INTN TargetListFilter,
IN INTN CPUTargetList,
IN INTN SgiId
);
/*
@ -203,8 +203,8 @@ ArmGicEndOfInterrupt (
UINTN
EFIAPI
ArmGicSetPriorityMask (
IN UINTN GicInterruptInterfaceBase,
IN INTN PriorityMask
IN INTN GicInterruptInterfaceBase,
IN INTN PriorityMask
);
VOID
@ -251,20 +251,20 @@ VOID
EFIAPI
ArmGicV2SetupNonSecure (
IN UINTN MpId,
IN UINTN GicDistributorBase,
IN UINTN GicInterruptInterfaceBase
IN INTN GicDistributorBase,
IN INTN GicInterruptInterfaceBase
);
VOID
EFIAPI
ArmGicV2EnableInterruptInterface (
IN UINTN GicInterruptInterfaceBase
IN INTN GicInterruptInterfaceBase
);
VOID
EFIAPI
ArmGicV2DisableInterruptInterface (
IN UINTN GicInterruptInterfaceBase
IN INTN GicInterruptInterfaceBase
);
UINTN

View File

@ -25,26 +25,33 @@
EFI_MEMORY_WT | EFI_MEMORY_WB | \
EFI_MEMORY_UCE)
/**
* The UEFI firmware must not use the ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_* attributes.
*
* The Non Secure memory attribute (ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_*) should only
* be used in Secure World to distinguished Secure to Non-Secure memory.
*/
typedef enum {
ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED = 0,
ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_UNCACHED_UNBUFFERED,
ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK,
ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_WRITE_BACK,
// On some platforms, memory mapped flash region is designed as not supporting
// shareable attribute, so WRITE_BACK_NONSHAREABLE is added for such special
// need.
// Do NOT use below two attributes if you are not sure.
ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK_NONSHAREABLE,
// Special region types for memory that must be mapped with read-only or
// non-execute permissions from the very start, e.g., to support the use
// of the WXN virtual memory control.
ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK_RO,
ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK_XP,
ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_WRITE_BACK_NONSHAREABLE,
ARM_MEMORY_REGION_ATTRIBUTE_WRITE_THROUGH,
ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_WRITE_THROUGH,
ARM_MEMORY_REGION_ATTRIBUTE_DEVICE,
ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_DEVICE
} ARM_MEMORY_REGION_ATTRIBUTES;
#define IS_ARM_MEMORY_REGION_ATTRIBUTES_SECURE(attr) ((UINT32)(attr) & 1)
typedef struct {
EFI_PHYSICAL_ADDRESS PhysicalBase;
EFI_VIRTUAL_ADDRESS VirtualBase;
@ -101,16 +108,14 @@ typedef enum {
#define ARM_CORE_MASK ARM_CORE_AFF0
#define ARM_CLUSTER_MASK ARM_CORE_AFF1
#define GET_CORE_ID(MpId) ((MpId) & ARM_CORE_MASK)
#define GET_CLUSTER_ID(MpId) (((MpId) & ARM_CLUSTER_MASK) >> 8)
#define GET_MPID(ClusterId, CoreId) (((ClusterId) << 8) | (CoreId))
#define GET_MPIDR_AFF0(MpId) ((MpId) & ARM_CORE_AFF0)
#define GET_MPIDR_AFF1(MpId) (((MpId) & ARM_CORE_AFF1) >> 8)
#define GET_MPIDR_AFF2(MpId) (((MpId) & ARM_CORE_AFF2) >> 16)
#define GET_MPIDR_AFF3(MpId) (((MpId) & ARM_CORE_AFF3) >> 32)
#define GET_MPIDR_AFFINITY_BITS(MpId) ((MpId) & 0xFF00FFFFFF)
#define GET_CORE_ID(MpId) ((MpId) & ARM_CORE_MASK)
#define GET_CLUSTER_ID(MpId) (((MpId) & ARM_CLUSTER_MASK) >> 8)
#define GET_MPID(ClusterId, CoreId) (((ClusterId) << 8) | (CoreId))
#define GET_MPIDR_AFF0(MpId) ((MpId) & ARM_CORE_AFF0)
#define GET_MPIDR_AFF1(MpId) (((MpId) & ARM_CORE_AFF1) >> 8)
#define GET_MPIDR_AFF2(MpId) (((MpId) & ARM_CORE_AFF2) >> 16)
#define GET_MPIDR_AFF3(MpId) (((MpId) & ARM_CORE_AFF3) >> 32)
#define PRIMARY_CORE_ID (PcdGet32(PcdArmPrimaryCore) & ARM_CORE_MASK)
#define MPIDR_MT_BIT BIT24
/** Reads the CCSIDR register for the specified cache.
@ -764,49 +769,6 @@ ArmHasCcidx (
VOID
);
#ifdef MDE_CPU_AARCH64
///
/// AArch64-only ID Register Helper functions
///
/**
Checks whether the CPU implements the Virtualization Host Extensions.
@retval TRUE FEAT_VHE is implemented.
@retval FALSE FEAT_VHE is not mplemented.
**/
BOOLEAN
EFIAPI
ArmHasVhe (
VOID
);
/**
Checks whether the CPU implements the Trace Buffer Extension.
@retval TRUE FEAT_TRBE is implemented.
@retval FALSE FEAT_TRBE is not mplemented.
**/
BOOLEAN
EFIAPI
ArmHasTrbe (
VOID
);
/**
Checks whether the CPU implements the Embedded Trace Extension.
@retval TRUE FEAT_ETE is implemented.
@retval FALSE FEAT_ETE is not mplemented.
**/
BOOLEAN
EFIAPI
ArmHasEte (
VOID
);
#endif // MDE_CPU_AARCH64
#ifdef MDE_CPU_ARM
///
/// AArch32-only ID Register Helper functions

View File

@ -21,54 +21,47 @@ ArmConfigureMmu (
OUT UINTN *TranslationTableSize OPTIONAL
);
EFI_STATUS
EFIAPI
ArmSetMemoryRegionNoExec (
IN EFI_PHYSICAL_ADDRESS BaseAddress,
IN UINT64 Length
);
EFI_STATUS
EFIAPI
ArmClearMemoryRegionNoExec (
IN EFI_PHYSICAL_ADDRESS BaseAddress,
IN UINT64 Length
);
EFI_STATUS
EFIAPI
ArmSetMemoryRegionReadOnly (
IN EFI_PHYSICAL_ADDRESS BaseAddress,
IN UINT64 Length
);
EFI_STATUS
EFIAPI
ArmClearMemoryRegionReadOnly (
IN EFI_PHYSICAL_ADDRESS BaseAddress,
IN UINT64 Length
);
VOID
EFIAPI
ArmReplaceLiveTranslationEntry (
IN UINT64 *Entry,
IN UINT64 Value,
IN UINT64 RegionStart,
IN BOOLEAN DisableMmu
IN UINT64 *Entry,
IN UINT64 Value,
IN UINT64 RegionStart
);
/**
Set the requested memory permission attributes on a region of memory.
BaseAddress and Length must be aligned to EFI_PAGE_SIZE.
If Attributes contains a memory type attribute (EFI_MEMORY_UC/WC/WT/WB), the
region is mapped according to this memory type, and additional memory
permission attributes (EFI_MEMORY_RP/RO/XP) are taken into account as well,
discarding any permission attributes that are currently set for the region.
AttributeMask is ignored in this case, and must be set to 0x0.
If Attributes contains only a combination of memory permission attributes
(EFI_MEMORY_RP/RO/XP), each page in the region will retain its existing
memory type, even if it is not uniformly set across the region. In this case,
AttributesMask may be set to a mask of permission attributes, and memory
permissions omitted from this mask will not be updated for any page in the
region. All attributes appearing in Attributes must appear in AttributeMask
as well. (Attributes & ~AttributeMask must produce 0x0)
@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 Mask of memory attributes to set.
@param[in] AttributeMask Mask of memory attributes to take into account.
@retval EFI_SUCCESS The attributes were set for the memory region.
@retval EFI_INVALID_PARAMETER BaseAddress or Length is not suitably aligned.
Invalid combination of Attributes and
AttributeMask.
@retval EFI_OUT_OF_RESOURCES Requested attributes cannot be applied due to
lack of system resources.
**/
EFI_STATUS
ArmSetMemoryAttributes (
IN EFI_PHYSICAL_ADDRESS BaseAddress,
IN UINT64 Length,
IN UINT64 Attributes,
IN UINT64 AttributeMask
IN UINT64 Attributes
);
#endif // ARM_MMU_LIB_H_

View File

@ -1,42 +0,0 @@
/** @file
Copyright (c) 2022, Arm Limited. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#ifndef ARM_MONITOR_LIB_H_
#define ARM_MONITOR_LIB_H_
/** The size of the SMC arguments is different between AArch64 and AArch32.
The native size is used for the arguments.
It will be casted to either HVC or SMC args.
*/
typedef struct {
UINTN Arg0;
UINTN Arg1;
UINTN Arg2;
UINTN Arg3;
UINTN Arg4;
UINTN Arg5;
UINTN Arg6;
UINTN Arg7;
} ARM_MONITOR_ARGS;
/** Monitor call.
An HyperVisor Call (HVC) or System Monitor Call (SMC) will be issued
depending on the default conduit. PcdMonitorConduitHvc determines the type
of the call: if true, do an HVC.
@param [in,out] Args Arguments for the HVC/SMC.
**/
VOID
EFIAPI
ArmMonitorCall (
IN OUT ARM_MONITOR_ARGS *Args
);
#endif // ARM_MONITOR_LIB_H_

View File

@ -1,6 +1,5 @@
/** @file
*
* Copyright (c) 2022, Ampere Computing LLC. All rights reserved.
* Copyright (c) 2021, NUVIA Inc. All rights reserved.
* Copyright (c) 2015, Hisilicon Limited. All rights reserved.
* Copyright (c) 2015, Linaro Limited. All rights reserved.
@ -37,7 +36,6 @@ typedef struct {
} OEM_MISC_PROCESSOR_DATA;
typedef enum {
BiosVersionType00,
ProductNameType01,
SerialNumType01,
UuidType01,
@ -45,7 +43,7 @@ typedef enum {
VersionType01,
SkuNumberType01,
FamilyType01,
AssetTagType02,
AssertTagType02,
SerialNumberType02,
BoardManufacturerType02,
ProductNameType02,
@ -60,7 +58,6 @@ typedef enum {
SkuNumberType03,
ProcessorPartNumType04,
ProcessorSerialNumType04,
ProcessorVersionType04,
SmbiosHiiStringFieldMax
} OEM_MISC_SMBIOS_HII_STRING_FIELD;
@ -236,36 +233,4 @@ OemGetChassisNumPowerCords (
VOID
);
/**
Fetches the system UUID.
@param[out] SystemUuid The pointer to the buffer to store the System UUID.
**/
VOID
EFIAPI
OemGetSystemUuid (
OUT GUID *SystemUuid
);
/** Fetches the BIOS release.
@return The BIOS release.
**/
UINT16
EFIAPI
OemGetBiosRelease (
VOID
);
/** Fetches the embedded controller firmware release.
@return The embedded controller firmware release.
**/
UINT16
EFIAPI
OemGetEmbeddedControllerFirmwareRelease (
VOID
);
#endif // OEM_MISC_LIB_H_

View File

@ -1,12 +1,12 @@
/** @file
Copyright (c) 2017-2023, Arm Limited. All rights reserved.
Copyright (c) 2017-2021, Arm Limited. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
System Control and Management Interface V3.2, latest version at:
- https://developer.arm.com/documentation/den0056/latest/
System Control and Management Interface V1.0
http://infocenter.arm.com/help/topic/com.arm.doc.den0056a/
DEN0056A_System_Control_and_Management_Interface.pdf
**/
#ifndef ARM_SCMI_PERFORMANCE_PROTOCOL_H_
@ -14,10 +14,7 @@
#include <Protocol/ArmScmi.h>
/// Arm Scmi performance protocol versions.
#define PERFORMANCE_PROTOCOL_VERSION_V1 0x10000
#define PERFORMANCE_PROTOCOL_VERSION_V2 0x20000
#define PERFORMANCE_PROTOCOL_VERSION_V3 0x30000
#define PERFORMANCE_PROTOCOL_VERSION 0x10000
#define ARM_SCMI_PERFORMANCE_PROTOCOL_GUID { \
0x9b8ba84, 0x3dd3, 0x49a6, {0xa0, 0x5a, 0x31, 0x34, 0xa5, 0xf0, 0x7b, 0xad} \
@ -79,58 +76,8 @@ typedef struct {
UINT32 RangeMin;
} SCMI_PERFORMANCE_LIMITS;
/// Doorbell Support bit.
#define SCMI_PERF_FC_ATTRIB_HAS_DOORBELL BIT0
/// Performance protocol describe fastchannel
typedef struct {
/// Attributes.
UINT32 Attributes;
/// Rate limit.
UINT32 RateLimit;
/// Lower 32 bits of the FastChannel address.
UINT32 ChanAddrLow;
/// Higher 32 bits of the FastChannel address.
UINT32 ChanAddrHigh;
/// Size of the FastChannel in bytes.
UINT32 ChanSize;
/// Lower 32 bits of the doorbell address.
UINT32 DoorbellAddrLow;
/// Higher 32 bits of the doorbell address.
UINT32 DoorbellAddrHigh;
/// Mask of lower 32 bits to set when writing to the doorbell register.
UINT32 DoorbellSetMaskLow;
/// Mask of higher 32 bits to set when writing to the doorbell register.
UINT32 DoorbellSetMaskHigh;
/// Mask of lower 32 bits to preserve when writing to the doorbell register.
UINT32 DoorbellPreserveMaskLow;
/// Mask of higher 32 bits to preserve when writing to the doorbell register.
UINT32 DoorbellPreserveMaskHigh;
} SCMI_PERFORMANCE_FASTCHANNEL;
#pragma pack()
/// SCMI Message Ids for the Performance Protocol.
typedef enum {
ScmiMessageIdPerformanceDomainAttributes = 0x3,
ScmiMessageIdPerformanceDescribeLevels = 0x4,
ScmiMessageIdPerformanceLimitsSet = 0x5,
ScmiMessageIdPerformanceLimitsGet = 0x6,
ScmiMessageIdPerformanceLevelSet = 0x7,
ScmiMessageIdPerformanceLevelGet = 0x8,
ScmiMessageIdPerformanceDescribeFastchannel = 0xB,
} SCMI_MESSAGE_ID_PERFORMANCE;
/** Return version of the performance management protocol supported by SCP.
firmware.
@ -288,34 +235,6 @@ EFI_STATUS
OUT UINT32 *Level
);
/** 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.
**/
typedef
EFI_STATUS
(EFIAPI *SCMI_PERFORMANCE_DESCRIBE_FASTCHANNEL)(
IN SCMI_PERFORMANCE_PROTOCOL *This,
IN UINT32 DomainId,
IN SCMI_MESSAGE_ID_PERFORMANCE MessageId,
OUT SCMI_PERFORMANCE_FASTCHANNEL *FastChannel
);
typedef struct _SCMI_PERFORMANCE_PROTOCOL {
SCMI_PERFORMANCE_GET_VERSION GetVersion;
SCMI_PERFORMANCE_GET_ATTRIBUTES GetProtocolAttributes;
@ -325,7 +244,15 @@ typedef struct _SCMI_PERFORMANCE_PROTOCOL {
SCMI_PERFORMANCE_LIMITS_GET LimitsGet;
SCMI_PERFORMANCE_LEVEL_SET LevelSet;
SCMI_PERFORMANCE_LEVEL_GET LevelGet;
SCMI_PERFORMANCE_DESCRIBE_FASTCHANNEL DescribeFastchannel;
} SCMI_PERFORMANCE_PROTOCOL;
typedef enum {
ScmiMessageIdPerformanceDomainAttributes = 0x3,
ScmiMessageIdPerformanceDescribeLevels = 0x4,
ScmiMessageIdPerformanceLimitsSet = 0x5,
ScmiMessageIdPerformanceLimitsGet = 0x6,
ScmiMessageIdPerformanceLevelSet = 0x7,
ScmiMessageIdPerformanceLevelGet = 0x8,
} SCMI_MESSAGE_ID_PERFORMANCE;
#endif /* ARM_SCMI_PERFORMANCE_PROTOCOL_H_ */

View File

@ -94,6 +94,7 @@
GCC_ASM_EXPORT(ExceptionHandlersEnd)
GCC_ASM_EXPORT(CommonCExceptionHandler)
GCC_ASM_EXPORT(RegisterEl0Stack)
.text
@ -386,6 +387,6 @@ ASM_PFX(CommonExceptionEntry):
eret
ASM_FUNC(RegisterEl0Stack)
ASM_PFX(RegisterEl0Stack):
msr sp_el0, x0
ret

View File

@ -4,7 +4,6 @@
* Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
* Copyright (c) 2011-2021, Arm Limited. All rights reserved.<BR>
* Copyright (c) 2016 HP Development Company, L.P.
* Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
*
* SPDX-License-Identifier: BSD-2-Clause-Patent
*
@ -195,6 +194,32 @@ CopyExceptionHandlers (
return RETURN_SUCCESS;
}
/**
Initializes all CPU interrupt/exceptions entries and provides the default interrupt/exception handlers.
Caller should try to get an array of interrupt and/or exception vectors that are in use and need to
persist by EFI_VECTOR_HANDOFF_INFO defined in PI 1.3 specification.
If caller cannot get reserved vector list or it does not exists, set VectorInfo to NULL.
If VectorInfo is not NULL, the exception vectors will be initialized per vector attribute accordingly.
@param[in] VectorInfo Pointer to reserved vector list.
@retval EFI_SUCCESS All CPU interrupt/exception entries have been successfully initialized
with default interrupt/exception handlers.
@retval EFI_INVALID_PARAMETER VectorInfo includes the invalid content if VectorInfo is not NULL.
@retval EFI_UNSUPPORTED This function is not supported.
**/
EFI_STATUS
EFIAPI
InitializeCpuInterruptHandlers (
IN EFI_VECTOR_HANDOFF_INFO *VectorInfo OPTIONAL
)
{
// not needed, this is what the CPU driver is for
return EFI_UNSUPPORTED;
}
/**
Registers a function to be called from the processor exception handler. (On ARM/AArch64 this only
provides exception handlers, not interrupt handling which is provided through the Hardware Interrupt
@ -204,8 +229,8 @@ This function registers and enables the handler specified by ExceptionHandler fo
interrupt or exception type specified by ExceptionType. If ExceptionHandler is NULL, then the
handler for the processor interrupt or exception type specified by ExceptionType is uninstalled.
The installed handler is called once for each processor interrupt or exception.
NOTE: This function should be invoked after InitializeCpuExceptionHandlers() is invoked,
otherwise EFI_UNSUPPORTED returned.
NOTE: This function should be invoked after InitializeCpuExceptionHandlers() or
InitializeCpuInterruptHandlers() invoked, otherwise EFI_UNSUPPORTED returned.
@param[in] ExceptionType Defines which interrupt or exception to hook.
@param[in] ExceptionHandler A pointer to a function of type EFI_CPU_INTERRUPT_HANDLER that is called
@ -287,25 +312,33 @@ CommonCExceptionHandler (
}
/**
Setup separate stacks for certain exception handlers.
If the input Buffer and BufferSize are both NULL, use global variable if possible.
Initializes all CPU exceptions entries with optional extra initializations.
@param[in] Buffer Point to buffer used to separate exception stack.
@param[in, out] BufferSize On input, it indicates the byte size of Buffer.
If the size is not enough, the return status will
be EFI_BUFFER_TOO_SMALL, and output BufferSize
will be the size it needs.
By default, this method should include all functionalities implemented by
InitializeCpuExceptionHandlers(), plus extra initialization works, if any.
This could be done by calling InitializeCpuExceptionHandlers() directly
in this method besides the extra works.
InitData is optional and its use and content are processor arch dependent.
The typical usage of it is to convey resources which have to be reserved
elsewhere and are necessary for the extra initializations of exception.
@param[in] VectorInfo Pointer to reserved vector list.
@param[in] InitData Pointer to data optional for extra initializations
of exception.
@retval EFI_SUCCESS The exceptions have been successfully
initialized.
@retval EFI_INVALID_PARAMETER VectorInfo or InitData contains invalid
content.
@retval EFI_SUCCESS The stacks are assigned successfully.
@retval EFI_UNSUPPORTED This function is not supported.
@retval EFI_BUFFER_TOO_SMALL This BufferSize is too small.
**/
EFI_STATUS
EFIAPI
InitializeSeparateExceptionStacks (
IN VOID *Buffer,
IN OUT UINTN *BufferSize
InitializeCpuExceptionHandlersEx (
IN EFI_VECTOR_HANDOFF_INFO *VectorInfo OPTIONAL,
IN CPU_EXCEPTION_INIT_DATA *InitData OPTIONAL
)
{
return EFI_SUCCESS;
return InitializeCpuExceptionHandlers (VectorInfo);
}

View File

@ -1,29 +0,0 @@
/** @file
Arm HyperVisor Call (HVC) Null Library.
Copyright (c) 2022, Arm Limited. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include <Library/ArmHvcLib.h>
#include <Library/DebugLib.h>
/**
Trigger an HVC call
HVC calls can take up to 8 arguments and return up to 4 return values.
Therefore, the 4 first fields in the ARM_HVC_ARGS structure are used
for both input and output values.
@param [in,out] Args Arguments for the HVC call.
**/
VOID
ArmCallHvc (
IN OUT ARM_HVC_ARGS *Args
)
{
ASSERT (FALSE);
return;
}

View File

@ -1,22 +0,0 @@
## @file
# Arm Hvc Null Library
#
# Copyright (c) 2022, Arm Limited. All rights reserved.<BR>
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
##
[Defines]
INF_VERSION = 1.29
BASE_NAME = ArmHvcLibNull
FILE_GUID = 02076A46-D6DB-48DD-8E5F-153172DD73A1
MODULE_TYPE = BASE
VERSION_STRING = 1.0
LIBRARY_CLASS = ArmHvcLib
[Sources]
ArmHvcLibNull.c
[Packages]
ArmPkg/ArmPkg.dec
MdePkg/MdePkg.dec

View File

@ -104,49 +104,3 @@ ArmHasCcidx (
Mmfr2 = ArmReadIdAA64Mmfr2 ();
return (((Mmfr2 >> 20) & 0xF) == 1) ? TRUE : FALSE;
}
/**
Checks whether the CPU implements the Virtualization Host Extensions.
@retval TRUE FEAT_VHE is implemented.
@retval FALSE FEAT_VHE is not mplemented.
**/
BOOLEAN
EFIAPI
ArmHasVhe (
VOID
)
{
return ((ArmReadIdAA64Mmfr1 () & AARCH64_MMFR1_VH) != 0);
}
/**
Checks whether the CPU implements the Trace Buffer Extension.
@retval TRUE FEAT_TRBE is implemented.
@retval FALSE FEAT_TRBE is not mplemented.
**/
BOOLEAN
EFIAPI
ArmHasTrbe (
VOID
)
{
return ((ArmReadIdAA64Dfr0 () & AARCH64_DFR0_TRBE) != 0);
}
/**
Checks whether the CPU implements the Embedded Trace Extension.
@retval TRUE FEAT_ETE is implemented.
@retval FALSE FEAT_ETE is not mplemented.
**/
BOOLEAN
EFIAPI
ArmHasEte (
VOID
)
{
// The ID_AA64DFR0_EL1.TraceVer field identifies the presence of FEAT_ETE.
return ((ArmReadIdAA64Dfr0 () & AARCH64_DFR0_TRACEVER) != 0);
}

View File

@ -40,43 +40,7 @@ ArmCleanInvalidateDataCacheEntryBySetWay (
UINTN
EFIAPI
ArmReadIdAA64Dfr0 (
VOID
);
UINTN
EFIAPI
ArmReadIdAA64Dfr1 (
VOID
);
UINTN
EFIAPI
ArmReadIdAA64Isar0 (
VOID
);
UINTN
EFIAPI
ArmReadIdAA64Isar1 (
VOID
);
UINTN
EFIAPI
ArmReadIdAA64Isar2 (
VOID
);
UINTN
EFIAPI
ArmReadIdAA64Mmfr0 (
VOID
);
UINTN
EFIAPI
ArmReadIdAA64Mmfr1 (
ArmReadIdAA64Pfr0 (
VOID
);
@ -90,16 +54,4 @@ ArmReadIdAA64Mmfr2 (
VOID
);
UINTN
EFIAPI
ArmReadIdAA64Pfr0 (
VOID
);
UINTN
EFIAPI
ArmReadIdAA64Pfr1 (
VOID
);
#endif // AARCH64_LIB_H_

View File

@ -425,6 +425,10 @@ ASM_FUNC(ArmCallWFI)
wfi
ret
ASM_FUNC(ArmReadIdAA64Mmfr2)
mrs x0, ID_AA64MMFR2_EL1 // read EL1 MMFR2
ret
ASM_FUNC(ArmReadMpidr)
mrs x0, mpidr_el1 // read EL1 MPIDR
ret
@ -448,6 +452,10 @@ ASM_FUNC(ArmIsArchTimerImplemented)
ret
ASM_FUNC(ArmReadIdAA64Pfr0)
mrs x0, id_aa64pfr0_el1 // Read ID_AA64PFR0 Register
ret
// VOID ArmWriteHcr(UINTN Hcr)
ASM_FUNC(ArmWriteHcr)
@ -474,54 +482,4 @@ ASM_FUNC(ArmWriteCntHctl)
msr cnthctl_el2, x0
ret
ASM_FUNC(ArmReadIdAA64Dfr0)
mrs x0, ID_AA64DFR0_EL1
ret
ASM_FUNC(ArmReadIdAA64Dfr1)
mrs x0, ID_AA64DFR1_EL1
ret
ASM_FUNC(ArmReadIdAA64Isar0)
mrs x0, ID_AA64ISAR0_EL1
ret
ASM_FUNC(ArmReadIdAA64Isar1)
mrs x0, ID_AA64ISAR1_EL1
ret
ASM_FUNC(ArmReadIdAA64Isar2)
mrs x0, ID_AA64ISAR2_EL1
ret
ASM_FUNC(ArmReadIdAA64Mmfr0)
mrs x0, ID_AA64MMFR0_EL1
ret
ASM_FUNC(ArmReadIdAA64Mmfr1)
mrs x0, ID_AA64MMFR1_EL1
ret
ASM_FUNC(ArmReadIdAA64Mmfr2)
mrs x0, ID_AA64MMFR2_EL1
ret
ASM_FUNC(ArmReadIdAA64Pfr0)
mrs x0, ID_AA64PFR0_EL1
ret
ASM_FUNC(ArmReadIdAA64Pfr1)
mrs x0, ID_AA64PFR1_EL1
ret
ASM_FUNCTION_REMOVE_IF_UNREFERENCED

View File

@ -16,7 +16,6 @@
.set CTRL_C_BIT, (1 << 2)
.set CTRL_B_BIT, (1 << 7)
.set CTRL_I_BIT, (1 << 12)
.set CTRL_AFE_BIT,(1 << 29)
ASM_FUNC(ArmInvalidateDataCacheEntryByMVA)
@ -65,7 +64,6 @@ ASM_FUNC(ArmInvalidateInstructionCache)
ASM_FUNC(ArmEnableMmu)
mrc p15,0,R0,c1,c0,0
orr R0,R0,#1
orr R0,R0,#CTRL_AFE_BIT
mcr p15,0,R0,c1,c0,0
dsb
isb

View File

@ -10,7 +10,6 @@
**/
#include <Uefi.h>
#include <Pi/PiMultiPhase.h>
#include <Chipset/AArch64.h>
#include <Library/BaseMemoryLib.h>
#include <Library/CacheMaintenanceLib.h>
@ -19,10 +18,6 @@
#include <Library/ArmMmuLib.h>
#include <Library/BaseLib.h>
#include <Library/DebugLib.h>
#include <Library/HobLib.h>
#include "ArmMmuLibInternal.h"
STATIC ARM_REPLACE_LIVE_TRANSLATION_ENTRY mReplaceLiveEntryFunc = ArmReplaceLiveTranslationEntry;
STATIC
UINT64
@ -30,47 +25,33 @@ ArmMemoryAttributeToPageAttribute (
IN ARM_MEMORY_REGION_ATTRIBUTES Attributes
)
{
UINT64 Permissions;
switch (Attributes) {
case ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK_RO:
Permissions = TT_AP_NO_RO;
break;
case ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK_XP:
case ARM_MEMORY_REGION_ATTRIBUTE_DEVICE:
if (ArmReadCurrentEL () == AARCH64_EL2) {
Permissions = TT_XN_MASK;
} else {
Permissions = TT_UXN_MASK | TT_PXN_MASK;
}
break;
default:
Permissions = 0;
break;
}
switch (Attributes) {
case ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK_NONSHAREABLE:
case ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_WRITE_BACK_NONSHAREABLE:
return TT_ATTR_INDX_MEMORY_WRITE_BACK;
case ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK:
case ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK_RO:
case ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK_XP:
return TT_ATTR_INDX_MEMORY_WRITE_BACK | TT_SH_INNER_SHAREABLE | Permissions;
case ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_WRITE_BACK:
return TT_ATTR_INDX_MEMORY_WRITE_BACK | TT_SH_INNER_SHAREABLE;
case ARM_MEMORY_REGION_ATTRIBUTE_WRITE_THROUGH:
case ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_WRITE_THROUGH:
return TT_ATTR_INDX_MEMORY_WRITE_THROUGH | TT_SH_INNER_SHAREABLE;
// Uncached and device mappings are treated as outer shareable by default,
case ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED:
case ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_UNCACHED_UNBUFFERED:
return TT_ATTR_INDX_MEMORY_NON_CACHEABLE;
default:
ASSERT (0);
case ARM_MEMORY_REGION_ATTRIBUTE_DEVICE:
return TT_ATTR_INDX_DEVICE_MEMORY | Permissions;
case ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_DEVICE:
if (ArmReadCurrentEL () == AARCH64_EL2) {
return TT_ATTR_INDX_DEVICE_MEMORY | TT_XN_MASK;
} else {
return TT_ATTR_INDX_DEVICE_MEMORY | TT_UXN_MASK | TT_PXN_MASK;
}
}
}
@ -102,40 +83,14 @@ ReplaceTableEntry (
IN UINT64 *Entry,
IN UINT64 Value,
IN UINT64 RegionStart,
IN UINT64 BlockMask,
IN BOOLEAN IsLiveBlockMapping
)
{
BOOLEAN DisableMmu;
//
// Replacing a live block entry with a table entry (or vice versa) requires a
// break-before-make sequence as per the architecture. This means the mapping
// must be made invalid and cleaned from the TLBs first, and this is a bit of
// a hassle if the mapping in question covers the code that is actually doing
// the mapping and the unmapping, and so we only bother with this if actually
// necessary.
//
if (!IsLiveBlockMapping || !ArmMmuEnabled ()) {
// If the mapping is not a live block mapping, or the MMU is not on yet, we
// can simply overwrite the entry.
if (!ArmMmuEnabled () || !IsLiveBlockMapping) {
*Entry = Value;
ArmUpdateTranslationTableEntry (Entry, (VOID *)(UINTN)RegionStart);
} else {
// If the mapping in question does not cover the code that updates the
// entry in memory, or the entry that we are intending to update, we can
// use an ordinary break before make. Otherwise, we will need to
// temporarily disable the MMU.
DisableMmu = FALSE;
if ((((RegionStart ^ (UINTN)mReplaceLiveEntryFunc) & ~BlockMask) == 0) ||
(((RegionStart ^ (UINTN)Entry) & ~BlockMask) == 0))
{
DisableMmu = TRUE;
DEBUG ((DEBUG_WARN, "%a: splitting block entry with MMU disabled\n", __func__));
}
mReplaceLiveEntryFunc (Entry, Value, RegionStart, DisableMmu);
ArmReplaceLiveTranslationEntry (Entry, Value, RegionStart);
}
}
@ -200,13 +155,12 @@ IsTableEntry (
STATIC
EFI_STATUS
UpdateRegionMappingRecursive (
IN UINT64 RegionStart,
IN UINT64 RegionEnd,
IN UINT64 AttributeSetMask,
IN UINT64 AttributeClearMask,
IN UINT64 *PageTable,
IN UINTN Level,
IN BOOLEAN TableIsLive
IN UINT64 RegionStart,
IN UINT64 RegionEnd,
IN UINT64 AttributeSetMask,
IN UINT64 AttributeClearMask,
IN UINT64 *PageTable,
IN UINTN Level
)
{
UINTN BlockShift;
@ -216,7 +170,6 @@ UpdateRegionMappingRecursive (
UINT64 EntryValue;
VOID *TranslationTable;
EFI_STATUS Status;
BOOLEAN NextTableIsLive;
ASSERT (((RegionStart | RegionEnd) & EFI_PAGE_MASK) == 0);
@ -226,7 +179,7 @@ UpdateRegionMappingRecursive (
DEBUG ((
DEBUG_VERBOSE,
"%a(%d): %llx - %llx set %lx clr %lx\n",
__func__,
__FUNCTION__,
Level,
RegionStart,
RegionEnd,
@ -244,30 +197,16 @@ UpdateRegionMappingRecursive (
// than a block, and recurse to create the block or page entries at
// the next level. No block mappings are allowed at all at level 0,
// so in that case, we have to recurse unconditionally.
//
// One special case to take into account is any region that covers the page
// table itself: if we'd cover such a region with block mappings, we are
// more likely to end up in the situation later where we need to disable
// the MMU in order to update page table entries safely, so prefer page
// mappings in that particular case.
// If we are changing a table entry and the AttributeClearMask is non-zero,
// we cannot replace it with a block entry without potentially losing
// attribute information, so keep the table entry in that case.
//
if ((Level == 0) || (((RegionStart | BlockEnd) & BlockMask) != 0) ||
((Level < 3) && (((UINT64)PageTable & ~BlockMask) == RegionStart)) ||
IsTableEntry (*Entry, Level))
(IsTableEntry (*Entry, Level) && (AttributeClearMask != 0)))
{
ASSERT (Level < 3);
if (!IsTableEntry (*Entry, Level)) {
//
// If the region we are trying to map is already covered by a block
// entry with the right attributes, don't bother splitting it up.
//
if (IsBlockEntry (*Entry, Level) &&
((*Entry & TT_ATTRIBUTES_MASK & ~AttributeClearMask) == AttributeSetMask))
{
continue;
}
//
// No table entry exists yet, so we need to allocate a page table
// for the next level.
@ -298,8 +237,7 @@ UpdateRegionMappingRecursive (
*Entry & TT_ATTRIBUTES_MASK,
0,
TranslationTable,
Level + 1,
FALSE
Level + 1
);
if (EFI_ERROR (Status)) {
//
@ -311,11 +249,8 @@ UpdateRegionMappingRecursive (
return Status;
}
}
NextTableIsLive = FALSE;
} else {
TranslationTable = (VOID *)(UINTN)(*Entry & TT_ADDRESS_MASK_BLOCK_ENTRY);
NextTableIsLive = TableIsLive;
}
//
@ -327,8 +262,7 @@ UpdateRegionMappingRecursive (
AttributeSetMask,
AttributeClearMask,
TranslationTable,
Level + 1,
NextTableIsLive
Level + 1
);
if (EFI_ERROR (Status)) {
if (!IsTableEntry (*Entry, Level)) {
@ -351,8 +285,7 @@ UpdateRegionMappingRecursive (
Entry,
EntryValue,
RegionStart,
BlockMask,
TableIsLive && IsBlockEntry (*Entry, Level)
IsBlockEntry (*Entry, Level)
);
}
} else {
@ -361,7 +294,20 @@ UpdateRegionMappingRecursive (
EntryValue |= (Level == 3) ? TT_TYPE_BLOCK_ENTRY_LEVEL3
: TT_TYPE_BLOCK_ENTRY;
ReplaceTableEntry (Entry, EntryValue, RegionStart, BlockMask, FALSE);
if (IsTableEntry (*Entry, Level)) {
//
// We are replacing a table entry with a block entry. This is only
// possible if we are keeping none of the original attributes.
// We can free the table entry's page table, and all the ones below
// it, since we are dropping the only possible reference to it.
//
ASSERT (AttributeClearMask == 0);
TranslationTable = (VOID *)(UINTN)(*Entry & TT_ADDRESS_MASK_BLOCK_ENTRY);
ReplaceTableEntry (Entry, EntryValue, RegionStart, TRUE);
FreePageTablesRecursive (TranslationTable, Level + 1);
} else {
ReplaceTableEntry (Entry, EntryValue, RegionStart, FALSE);
}
}
}
@ -371,12 +317,10 @@ UpdateRegionMappingRecursive (
STATIC
EFI_STATUS
UpdateRegionMapping (
IN UINT64 RegionStart,
IN UINT64 RegionLength,
IN UINT64 AttributeSetMask,
IN UINT64 AttributeClearMask,
IN UINT64 *RootTable,
IN BOOLEAN TableIsLive
IN UINT64 RegionStart,
IN UINT64 RegionLength,
IN UINT64 AttributeSetMask,
IN UINT64 AttributeClearMask
)
{
UINTN T0SZ;
@ -392,9 +336,8 @@ UpdateRegionMapping (
RegionStart + RegionLength,
AttributeSetMask,
AttributeClearMask,
RootTable,
GetRootTableLevel (T0SZ),
TableIsLive
ArmGetTTBR0BaseAddress (),
GetRootTableLevel (T0SZ)
);
}
@ -409,9 +352,7 @@ FillTranslationTable (
MemoryRegion->VirtualBase,
MemoryRegion->Length,
ArmMemoryAttributeToPageAttribute (MemoryRegion->Attributes) | TT_AF,
0,
RootTable,
FALSE
0
);
}
@ -455,52 +396,14 @@ GcdAttributeToPageAttribute (
PageAttributes |= TT_AP_NO_RO;
}
if ((GcdAttributes & EFI_MEMORY_RP) == 0) {
PageAttributes |= TT_AF;
}
return PageAttributes;
return PageAttributes | TT_AF;
}
/**
Set the requested memory permission attributes on a region of memory.
BaseAddress and Length must be aligned to EFI_PAGE_SIZE.
If Attributes contains a memory type attribute (EFI_MEMORY_UC/WC/WT/WB), the
region is mapped according to this memory type, and additional memory
permission attributes (EFI_MEMORY_RP/RO/XP) are taken into account as well,
discarding any permission attributes that are currently set for the region.
AttributeMask is ignored in this case, and must be set to 0x0.
If Attributes contains only a combination of memory permission attributes
(EFI_MEMORY_RP/RO/XP), each page in the region will retain its existing
memory type, even if it is not uniformly set across the region. In this case,
AttributesMask may be set to a mask of permission attributes, and memory
permissions omitted from this mask will not be updated for any page in the
region. All attributes appearing in Attributes must appear in AttributeMask
as well. (Attributes & ~AttributeMask must produce 0x0)
@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 Mask of memory attributes to set.
@param[in] AttributeMask Mask of memory attributes to take into account.
@retval EFI_SUCCESS The attributes were set for the memory region.
@retval EFI_INVALID_PARAMETER BaseAddress or Length is not suitably aligned.
Invalid combination of Attributes and
AttributeMask.
@retval EFI_OUT_OF_RESOURCES Requested attributes cannot be applied due to
lack of system resources.
**/
EFI_STATUS
ArmSetMemoryAttributes (
IN EFI_PHYSICAL_ADDRESS BaseAddress,
IN UINT64 Length,
IN UINT64 Attributes,
IN UINT64 AttributeMask
IN UINT64 Attributes
)
{
UINT64 PageAttributes;
@ -514,34 +417,97 @@ ArmSetMemoryAttributes (
// No memory type was set in Attributes, so we are going to update the
// permissions only.
//
PageAttributes &= TT_AP_MASK | TT_UXN_MASK | TT_PXN_MASK | TT_AF;
PageAttributes &= TT_AP_MASK | TT_UXN_MASK | TT_PXN_MASK;
PageAttributeMask = ~(TT_ADDRESS_MASK_BLOCK_ENTRY | TT_AP_MASK |
TT_PXN_MASK | TT_XN_MASK | TT_AF);
if (AttributeMask != 0) {
if (((AttributeMask & ~(UINT64)(EFI_MEMORY_RP|EFI_MEMORY_RO|EFI_MEMORY_XP)) != 0) ||
((Attributes & ~AttributeMask) != 0))
{
return EFI_INVALID_PARAMETER;
}
// Add attributes omitted from AttributeMask to the set of attributes to preserve
PageAttributeMask |= GcdAttributeToPageAttribute (~AttributeMask) &
(TT_AP_MASK | TT_UXN_MASK | TT_PXN_MASK | TT_AF);
}
} else {
ASSERT (AttributeMask == 0);
if (AttributeMask != 0) {
return EFI_INVALID_PARAMETER;
}
TT_PXN_MASK | TT_XN_MASK);
}
return UpdateRegionMapping (
BaseAddress,
Length,
PageAttributes,
PageAttributeMask,
ArmGetTTBR0BaseAddress (),
TRUE
PageAttributeMask
);
}
STATIC
EFI_STATUS
SetMemoryRegionAttribute (
IN EFI_PHYSICAL_ADDRESS BaseAddress,
IN UINT64 Length,
IN UINT64 Attributes,
IN UINT64 BlockEntryMask
)
{
return UpdateRegionMapping (BaseAddress, Length, Attributes, BlockEntryMask);
}
EFI_STATUS
ArmSetMemoryRegionNoExec (
IN EFI_PHYSICAL_ADDRESS BaseAddress,
IN UINT64 Length
)
{
UINT64 Val;
if (ArmReadCurrentEL () == AARCH64_EL1) {
Val = TT_PXN_MASK | TT_UXN_MASK;
} else {
Val = TT_XN_MASK;
}
return SetMemoryRegionAttribute (
BaseAddress,
Length,
Val,
~TT_ADDRESS_MASK_BLOCK_ENTRY
);
}
EFI_STATUS
ArmClearMemoryRegionNoExec (
IN EFI_PHYSICAL_ADDRESS BaseAddress,
IN UINT64 Length
)
{
UINT64 Mask;
// XN maps to UXN in the EL1&0 translation regime
Mask = ~(TT_ADDRESS_MASK_BLOCK_ENTRY | TT_PXN_MASK | TT_XN_MASK);
return SetMemoryRegionAttribute (
BaseAddress,
Length,
0,
Mask
);
}
EFI_STATUS
ArmSetMemoryRegionReadOnly (
IN EFI_PHYSICAL_ADDRESS BaseAddress,
IN UINT64 Length
)
{
return SetMemoryRegionAttribute (
BaseAddress,
Length,
TT_AP_NO_RO,
~TT_ADDRESS_MASK_BLOCK_ENTRY
);
}
EFI_STATUS
ArmClearMemoryRegionReadOnly (
IN EFI_PHYSICAL_ADDRESS BaseAddress,
IN UINT64 Length
)
{
return SetMemoryRegionAttribute (
BaseAddress,
Length,
TT_AP_NO_RW,
~(TT_ADDRESS_MASK_BLOCK_ENTRY | TT_AP_MASK)
);
}
@ -647,7 +613,7 @@ ArmConfigureMmu (
// loss of coherency when using mismatched attributes, and given that memory
// is mapped cacheable except for extraordinary cases (such as non-coherent
// DMA), have the page table walker perform cached accesses as well, and
// assert below that matches the attributes we use for CPU accesses to
// assert below that that matches the attributes we use for CPU accesses to
// the region.
//
TCR |= TCR_SH_INNER_SHAREABLE |
@ -663,6 +629,14 @@ ArmConfigureMmu (
return EFI_OUT_OF_RESOURCES;
}
//
// We set TTBR0 just after allocating the table to retrieve its location from
// the subsequent functions without needing to pass this value across the
// functions. The MMU is only enabled after the translation tables are
// populated.
//
ArmSetTTBR0 (TranslationTable);
if (TranslationTableBase != NULL) {
*TranslationTableBase = TranslationTable;
}
@ -671,17 +645,14 @@ ArmConfigureMmu (
*TranslationTableSize = RootTableEntryCount * sizeof (UINT64);
}
if (!ArmMmuEnabled ()) {
//
// Make sure we are not inadvertently hitting in the caches
// when populating the page tables.
//
InvalidateDataCacheRange (
TranslationTable,
RootTableEntryCount * sizeof (UINT64)
);
}
//
// Make sure we are not inadvertently hitting in the caches
// when populating the page tables.
//
InvalidateDataCacheRange (
TranslationTable,
RootTableEntryCount * sizeof (UINT64)
);
ZeroMem (TranslationTable, RootTableEntryCount * sizeof (UINT64));
while (MemoryTable->Length != 0) {
@ -706,17 +677,12 @@ ArmConfigureMmu (
MAIR_ATTR (TT_ATTR_INDX_MEMORY_WRITE_BACK, MAIR_ATTR_NORMAL_MEMORY_WRITE_BACK)
);
ArmSetTTBR0 (TranslationTable);
if (!ArmMmuEnabled ()) {
ArmDisableAlignmentCheck ();
ArmEnableStackAlignmentCheck ();
ArmEnableInstructionCache ();
ArmEnableDataCache ();
ArmEnableMmu ();
}
ArmDisableAlignmentCheck ();
ArmEnableStackAlignmentCheck ();
ArmEnableInstructionCache ();
ArmEnableDataCache ();
ArmEnableMmu ();
return EFI_SUCCESS;
FreeTranslationTable:
@ -731,21 +697,15 @@ ArmMmuBaseLibConstructor (
)
{
extern UINT32 ArmReplaceLiveTranslationEntrySize;
VOID *Hob;
Hob = GetFirstGuidHob (&gArmMmuReplaceLiveTranslationEntryFuncGuid);
if (Hob != NULL) {
mReplaceLiveEntryFunc = *(ARM_REPLACE_LIVE_TRANSLATION_ENTRY *)GET_GUID_HOB_DATA (Hob);
} else {
//
// The ArmReplaceLiveTranslationEntry () helper function may be invoked
// with the MMU off so we have to ensure that it gets cleaned to the PoC
//
WriteBackDataCacheRange (
(VOID *)(UINTN)ArmReplaceLiveTranslationEntry,
ArmReplaceLiveTranslationEntrySize
);
}
//
// The ArmReplaceLiveTranslationEntry () helper function may be invoked
// with the MMU off so we have to ensure that it gets cleaned to the PoC
//
WriteBackDataCacheRange (
(VOID *)(UINTN)ArmReplaceLiveTranslationEntry,
ArmReplaceLiveTranslationEntrySize
);
return RETURN_SUCCESS;
}

View File

@ -12,14 +12,6 @@
.macro __replace_entry, el
// check whether we should disable the MMU
cbz x3, .L1_\@
// clean and invalidate first so that we don't clobber
// adjacent entries that are dirty in the caches
dc civac, x0
dsb nsh
// disable the MMU
mrs x8, sctlr_el\el
bic x9, x8, #CTRL_M_BIT
@ -46,28 +38,6 @@
// re-enable the MMU
msr sctlr_el\el, x8
isb
b .L2_\@
.L1_\@:
// write invalid entry
str xzr, [x0]
dsb nshst
// flush translations for the target address from the TLBs
lsr x2, x2, #12
.if \el == 1
tlbi vaae1, x2
.else
tlbi vae\el, x2
.endif
dsb nsh
// write updated entry
str x1, [x0]
dsb nshst
isb
.L2_\@:
.endm
//VOID
@ -76,17 +46,19 @@
// IN UINT64 Value,
// IN UINT64 Address
// )
//
// Align this routine to a log2 upper bound of its size, so that it is
// guaranteed not to cross a page or block boundary.
ASM_FUNC_ALIGN(ArmReplaceLiveTranslationEntry, 0x200)
ASM_FUNC(ArmReplaceLiveTranslationEntry)
// disable interrupts
mrs x4, daif
msr daifset, #0xf
isb
EL1_OR_EL2_OR_EL3(x5)
// clean and invalidate first so that we don't clobber
// adjacent entries that are dirty in the caches
dc civac, x0
dsb nsh
EL1_OR_EL2_OR_EL3(x3)
1:__replace_entry 1
b 4f
2:__replace_entry 2
@ -100,9 +72,3 @@ ASM_GLOBAL ASM_PFX(ArmReplaceLiveTranslationEntrySize)
ASM_PFX(ArmReplaceLiveTranslationEntrySize):
.long . - ArmReplaceLiveTranslationEntry
// Double check that we did not overrun the assumed maximum size or cross a
// 0x200 boundary (and thus implicitly not any larger power of two, including
// the page size).
.balign 0x200
.org ArmReplaceLiveTranslationEntry + 0x200

View File

@ -12,8 +12,6 @@
#include <Library/ArmMmuLib.h>
#include <Library/CacheMaintenanceLib.h>
#include <Library/DebugLib.h>
#include <Library/HobLib.h>
#include "ArmMmuLibInternal.h"
EFI_STATUS
EFIAPI
@ -22,9 +20,7 @@ ArmMmuPeiLibConstructor (
IN CONST EFI_PEI_SERVICES **PeiServices
)
{
extern UINT32 ArmReplaceLiveTranslationEntrySize;
ARM_REPLACE_LIVE_TRANSLATION_ENTRY ArmReplaceLiveTranslationEntryFunc;
VOID *Hob;
extern UINT32 ArmReplaceLiveTranslationEntrySize;
EFI_FV_FILE_INFO FileInfo;
EFI_STATUS Status;
@ -46,20 +42,6 @@ ArmMmuPeiLibConstructor (
(UINTN)ArmReplaceLiveTranslationEntry + ArmReplaceLiveTranslationEntrySize))
{
DEBUG ((DEBUG_INFO, "ArmMmuLib: skipping cache maintenance on XIP PEIM\n"));
//
// Expose the XIP version of the ArmReplaceLiveTranslationEntry() routine
// via a HOB so we can fall back to it later when we need to split block
// mappings in a way that adheres to break-before-make requirements.
//
ArmReplaceLiveTranslationEntryFunc = ArmReplaceLiveTranslationEntry;
Hob = BuildGuidDataHob (
&gArmMmuReplaceLiveTranslationEntryFuncGuid,
&ArmReplaceLiveTranslationEntryFunc,
sizeof ArmReplaceLiveTranslationEntryFunc
);
ASSERT (Hob != NULL);
} else {
DEBUG ((DEBUG_INFO, "ArmMmuLib: performing cache maintenance on shadowed PEIM\n"));
//

View File

@ -15,16 +15,16 @@
UINT32
ConvertSectionAttributesToPageAttributes (
IN UINT32 SectionAttributes
IN UINT32 SectionAttributes,
IN BOOLEAN IsLargePage
)
{
UINT32 PageAttributes;
PageAttributes = 0;
PageAttributes |= TT_DESCRIPTOR_CONVERT_TO_PAGE_CACHE_POLICY (SectionAttributes);
PageAttributes |= TT_DESCRIPTOR_CONVERT_TO_PAGE_CACHE_POLICY (SectionAttributes, IsLargePage);
PageAttributes |= TT_DESCRIPTOR_CONVERT_TO_PAGE_AP (SectionAttributes);
PageAttributes |= TT_DESCRIPTOR_CONVERT_TO_PAGE_AF (SectionAttributes);
PageAttributes |= TT_DESCRIPTOR_CONVERT_TO_PAGE_XN (SectionAttributes);
PageAttributes |= TT_DESCRIPTOR_CONVERT_TO_PAGE_XN (SectionAttributes, IsLargePage);
PageAttributes |= TT_DESCRIPTOR_CONVERT_TO_PAGE_NG (SectionAttributes);
PageAttributes |= TT_DESCRIPTOR_CONVERT_TO_PAGE_S (SectionAttributes);

View File

@ -100,27 +100,24 @@ PopulateLevel2PageTable (
switch (Attributes) {
case ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK:
case ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_WRITE_BACK:
PageAttributes = TT_DESCRIPTOR_PAGE_WRITE_BACK;
break;
case ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK_NONSHAREABLE:
case ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_WRITE_BACK_NONSHAREABLE:
PageAttributes = TT_DESCRIPTOR_PAGE_WRITE_BACK;
PageAttributes &= ~TT_DESCRIPTOR_PAGE_S_SHARED;
break;
case ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK_RO:
PageAttributes = TT_DESCRIPTOR_PAGE_WRITE_BACK;
PageAttributes |= TT_DESCRIPTOR_PAGE_AP_NO_RO;
break;
case ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK_XP:
PageAttributes = TT_DESCRIPTOR_PAGE_WRITE_BACK;
PageAttributes |= TT_DESCRIPTOR_PAGE_XN_MASK;
break;
case ARM_MEMORY_REGION_ATTRIBUTE_WRITE_THROUGH:
case ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_WRITE_THROUGH:
PageAttributes = TT_DESCRIPTOR_PAGE_WRITE_THROUGH;
break;
case ARM_MEMORY_REGION_ATTRIBUTE_DEVICE:
case ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_DEVICE:
PageAttributes = TT_DESCRIPTOR_PAGE_DEVICE;
break;
case ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED:
case ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_UNCACHED_UNBUFFERED:
PageAttributes = TT_DESCRIPTOR_PAGE_UNCACHED;
break;
default:
@ -148,7 +145,7 @@ PopulateLevel2PageTable (
);
// Translate the Section Descriptor into Page Descriptor
SectionDescriptor = TT_DESCRIPTOR_PAGE_TYPE_PAGE | ConvertSectionAttributesToPageAttributes (*SectionEntry);
SectionDescriptor = TT_DESCRIPTOR_PAGE_TYPE_PAGE | ConvertSectionAttributesToPageAttributes (*SectionEntry, FALSE);
BaseSectionAddress = TT_DESCRIPTOR_SECTION_BASE_ADDRESS (*SectionEntry);
@ -169,6 +166,7 @@ PopulateLevel2PageTable (
// Overwrite the section entry to point to the new Level2 Translation Table
*SectionEntry = (TranslationTable & TT_DESCRIPTOR_SECTION_PAGETABLE_ADDRESS_MASK) |
(IS_ARM_MEMORY_REGION_ATTRIBUTES_SECURE (Attributes) ? (1 << 3) : 0) |
TT_DESCRIPTOR_SECTION_TYPE_PAGE_TABLE;
} else {
// We do not support the other section type (16MB Section)
@ -191,6 +189,7 @@ PopulateLevel2PageTable (
ZeroMem ((VOID *)TranslationTable, TRANSLATION_TABLE_PAGE_SIZE);
*SectionEntry = (TranslationTable & TT_DESCRIPTOR_SECTION_PAGETABLE_ADDRESS_MASK) |
(IS_ARM_MEMORY_REGION_ATTRIBUTES_SECURE (Attributes) ? (1 << 3) : 0) |
TT_DESCRIPTOR_SECTION_TYPE_PAGE_TABLE;
}
@ -240,31 +239,39 @@ FillTranslationTable (
switch (MemoryRegion->Attributes) {
case ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK:
Attributes = TT_DESCRIPTOR_SECTION_WRITE_BACK;
Attributes = TT_DESCRIPTOR_SECTION_WRITE_BACK (0);
break;
case ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK_NONSHAREABLE:
Attributes = TT_DESCRIPTOR_SECTION_WRITE_BACK;
Attributes = TT_DESCRIPTOR_SECTION_WRITE_BACK (0);
Attributes &= ~TT_DESCRIPTOR_SECTION_S_SHARED;
break;
case ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK_RO:
Attributes = TT_DESCRIPTOR_SECTION_WRITE_BACK;
Attributes |= TT_DESCRIPTOR_SECTION_AP_NO_RO;
break;
case ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK_XP:
Attributes = TT_DESCRIPTOR_SECTION_WRITE_BACK;
Attributes |= TT_DESCRIPTOR_SECTION_XN_MASK;
break;
case ARM_MEMORY_REGION_ATTRIBUTE_WRITE_THROUGH:
Attributes = TT_DESCRIPTOR_SECTION_WRITE_THROUGH;
Attributes = TT_DESCRIPTOR_SECTION_WRITE_THROUGH (0);
break;
case ARM_MEMORY_REGION_ATTRIBUTE_DEVICE:
Attributes = TT_DESCRIPTOR_SECTION_DEVICE;
Attributes = TT_DESCRIPTOR_SECTION_DEVICE (0);
break;
case ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED:
Attributes = TT_DESCRIPTOR_SECTION_UNCACHED;
Attributes = TT_DESCRIPTOR_SECTION_UNCACHED (0);
break;
case ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_WRITE_BACK:
Attributes = TT_DESCRIPTOR_SECTION_WRITE_BACK (1);
break;
case ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_WRITE_BACK_NONSHAREABLE:
Attributes = TT_DESCRIPTOR_SECTION_WRITE_BACK (1);
Attributes &= ~TT_DESCRIPTOR_SECTION_S_SHARED;
break;
case ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_WRITE_THROUGH:
Attributes = TT_DESCRIPTOR_SECTION_WRITE_THROUGH (1);
break;
case ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_DEVICE:
Attributes = TT_DESCRIPTOR_SECTION_DEVICE (1);
break;
case ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_UNCACHED_UNBUFFERED:
Attributes = TT_DESCRIPTOR_SECTION_UNCACHED (1);
break;
default:
Attributes = TT_DESCRIPTOR_SECTION_UNCACHED;
Attributes = TT_DESCRIPTOR_SECTION_UNCACHED (0);
break;
}

View File

@ -10,7 +10,6 @@
#include <Uefi.h>
#include <Library/ArmLib.h>
#include <Library/ArmMmuLib.h>
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
@ -54,7 +53,7 @@ ConvertSectionToPages (
// Get section attributes and convert to page attributes
SectionDescriptor = FirstLevelTable[FirstLevelIdx];
PageDescriptor = TT_DESCRIPTOR_PAGE_TYPE_PAGE | ConvertSectionAttributesToPageAttributes (SectionDescriptor);
PageDescriptor = TT_DESCRIPTOR_PAGE_TYPE_PAGE | ConvertSectionAttributesToPageAttributes (SectionDescriptor, FALSE);
// Allocate a page table for the 4KB entries (we use up a full page even though we only need 1KB)
PageTable = (volatile ARM_PAGE_TABLE_ENTRY *)AllocatePages (1);
@ -82,12 +81,12 @@ UpdatePageEntries (
IN EFI_PHYSICAL_ADDRESS BaseAddress,
IN UINT64 Length,
IN UINT64 Attributes,
IN UINT32 EntryMask,
OUT BOOLEAN *FlushTlbs OPTIONAL
)
{
EFI_STATUS Status;
UINT32 EntryValue;
UINT32 EntryMask;
UINT32 FirstLevelIdx;
UINT32 Offset;
UINT32 NumPageEntries;
@ -105,7 +104,12 @@ UpdatePageEntries (
// EntryMask: bitmask of values to change (1 = change this value, 0 = leave alone)
// EntryValue: values at bit positions specified by EntryMask
EntryValue = TT_DESCRIPTOR_PAGE_TYPE_PAGE;
EntryMask = TT_DESCRIPTOR_PAGE_TYPE_MASK | TT_DESCRIPTOR_PAGE_AP_MASK;
if ((Attributes & EFI_MEMORY_XP) != 0) {
EntryValue = TT_DESCRIPTOR_PAGE_TYPE_PAGE_XN;
} else {
EntryValue = TT_DESCRIPTOR_PAGE_TYPE_PAGE;
}
// Although the PI spec is unclear on this, the GCD guarantees that only
// one Attribute bit is set at a time, so the order of the conditionals below
@ -138,20 +142,12 @@ UpdatePageEntries (
return EFI_UNSUPPORTED;
}
if ((Attributes & EFI_MEMORY_RP) == 0) {
EntryValue |= TT_DESCRIPTOR_PAGE_AF;
}
if ((Attributes & EFI_MEMORY_RO) != 0) {
EntryValue |= TT_DESCRIPTOR_PAGE_AP_RO_RO;
} else {
EntryValue |= TT_DESCRIPTOR_PAGE_AP_RW_RW;
}
if ((Attributes & EFI_MEMORY_XP) != 0) {
EntryValue |= TT_DESCRIPTOR_PAGE_XN_MASK;
}
// Obtain page table base
FirstLevelTable = (ARM_FIRST_LEVEL_DESCRIPTOR *)ArmGetTTBR0BaseAddress ();
@ -171,17 +167,6 @@ UpdatePageEntries (
// Does this descriptor need to be converted from section entry to 4K pages?
if (!TT_DESCRIPTOR_SECTION_TYPE_IS_PAGE_TABLE (Descriptor)) {
//
// If the section mapping covers the requested region with the expected
// attributes, splitting it is unnecessary, and should be avoided as it
// may result in unbounded recursion when using a strict NX policy.
//
if ((EntryValue & ~TT_DESCRIPTOR_PAGE_TYPE_MASK & EntryMask) ==
(ConvertSectionAttributesToPageAttributes (Descriptor) & EntryMask))
{
continue;
}
Status = ConvertSectionToPages (FirstLevelIdx << TT_DESCRIPTOR_SECTION_BASE_SHIFT);
if (EFI_ERROR (Status)) {
// Exit for loop
@ -231,11 +216,11 @@ EFI_STATUS
UpdateSectionEntries (
IN EFI_PHYSICAL_ADDRESS BaseAddress,
IN UINT64 Length,
IN UINT64 Attributes,
IN UINT32 EntryMask
IN UINT64 Attributes
)
{
EFI_STATUS Status;
UINT32 EntryMask;
UINT32 EntryValue;
UINT32 FirstLevelIdx;
UINT32 NumSections;
@ -251,6 +236,8 @@ UpdateSectionEntries (
// EntryValue: values at bit positions specified by EntryMask
// Make sure we handle a section range that is unmapped
EntryMask = TT_DESCRIPTOR_SECTION_TYPE_MASK | TT_DESCRIPTOR_SECTION_XN_MASK |
TT_DESCRIPTOR_SECTION_AP_MASK;
EntryValue = TT_DESCRIPTOR_SECTION_TYPE_SECTION;
// Although the PI spec is unclear on this, the GCD guarantees that only
@ -294,10 +281,6 @@ UpdateSectionEntries (
EntryValue |= TT_DESCRIPTOR_SECTION_XN_MASK;
}
if ((Attributes & EFI_MEMORY_RP) == 0) {
EntryValue |= TT_DESCRIPTOR_SECTION_AF;
}
// obtain page table base
FirstLevelTable = (ARM_FIRST_LEVEL_DESCRIPTOR *)ArmGetTTBR0BaseAddress ();
@ -319,7 +302,6 @@ UpdateSectionEntries (
(FirstLevelIdx + i) << TT_DESCRIPTOR_SECTION_BASE_SHIFT,
TT_DESCRIPTOR_SECTION_SIZE,
Attributes,
ConvertSectionAttributesToPageAttributes (EntryMask),
NULL
);
} else {
@ -350,26 +332,11 @@ UpdateSectionEntries (
return Status;
}
/**
Update the permission or memory type attributes on a range of memory.
@param BaseAddress The start of the region.
@param Length The size of the region.
@param Attributes A mask of EFI_MEMORY_xx constants.
@param SectionMask A mask of short descriptor section attributes
describing which descriptor bits to update.
@retval EFI_SUCCESS The attributes were set successfully.
@retval EFI_OUT_OF_RESOURCES The operation failed due to insufficient memory.
**/
STATIC
EFI_STATUS
SetMemoryAttributes (
ArmSetMemoryAttributes (
IN EFI_PHYSICAL_ADDRESS BaseAddress,
IN UINT64 Length,
IN UINT64 Attributes,
IN UINT32 SectionMask
IN UINT64 Attributes
)
{
EFI_STATUS Status;
@ -400,12 +367,7 @@ SetMemoryAttributes (
Attributes
));
Status = UpdateSectionEntries (
BaseAddress,
ChunkLength,
Attributes,
SectionMask
);
Status = UpdateSectionEntries (BaseAddress, ChunkLength, Attributes);
FlushTlbs = TRUE;
} else {
@ -431,7 +393,6 @@ SetMemoryAttributes (
BaseAddress,
ChunkLength,
Attributes,
ConvertSectionAttributesToPageAttributes (SectionMask),
&FlushTlbs
);
}
@ -451,96 +412,38 @@ SetMemoryAttributes (
return Status;
}
/**
Set the requested memory permission attributes on a region of memory.
BaseAddress and Length must be aligned to EFI_PAGE_SIZE.
If Attributes contains a memory type attribute (EFI_MEMORY_UC/WC/WT/WB), the
region is mapped according to this memory type, and additional memory
permission attributes (EFI_MEMORY_RP/RO/XP) are taken into account as well,
discarding any permission attributes that are currently set for the region.
AttributeMask is ignored in this case, and must be set to 0x0.
If Attributes contains only a combination of memory permission attributes
(EFI_MEMORY_RP/RO/XP), each page in the region will retain its existing
memory type, even if it is not uniformly set across the region. In this case,
AttributesMask may be set to a mask of permission attributes, and memory
permissions omitted from this mask will not be updated for any page in the
region. All attributes appearing in Attributes must appear in AttributeMask
as well. (Attributes & ~AttributeMask must produce 0x0)
@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 Mask of memory attributes to set.
@param[in] AttributeMask Mask of memory attributes to take into account.
@retval EFI_SUCCESS The attributes were set for the memory region.
@retval EFI_INVALID_PARAMETER BaseAddress or Length is not suitably aligned.
Invalid combination of Attributes and
AttributeMask.
@retval EFI_OUT_OF_RESOURCES Requested attributes cannot be applied due to
lack of system resources.
**/
EFI_STATUS
ArmSetMemoryAttributes (
IN EFI_PHYSICAL_ADDRESS BaseAddress,
IN UINT64 Length,
IN UINT64 Attributes,
IN UINT64 AttributeMask
ArmSetMemoryRegionNoExec (
IN EFI_PHYSICAL_ADDRESS BaseAddress,
IN UINT64 Length
)
{
UINT32 TtEntryMask;
if (((BaseAddress | Length) & EFI_PAGE_MASK) != 0) {
return EFI_INVALID_PARAMETER;
}
if ((Attributes & EFI_MEMORY_CACHETYPE_MASK) == 0) {
//
// No memory type was set in Attributes, so we are going to update the
// permissions only.
//
if (AttributeMask != 0) {
if (((AttributeMask & ~(UINT64)(EFI_MEMORY_RP|EFI_MEMORY_RO|EFI_MEMORY_XP)) != 0) ||
((Attributes & ~AttributeMask) != 0))
{
return EFI_INVALID_PARAMETER;
}
} else {
AttributeMask = EFI_MEMORY_RP | EFI_MEMORY_RO | EFI_MEMORY_XP;
}
TtEntryMask = 0;
if ((AttributeMask & EFI_MEMORY_RP) != 0) {
TtEntryMask |= TT_DESCRIPTOR_SECTION_AF;
}
if ((AttributeMask & EFI_MEMORY_RO) != 0) {
TtEntryMask |= TT_DESCRIPTOR_SECTION_AP_MASK;
}
if ((AttributeMask & EFI_MEMORY_XP) != 0) {
TtEntryMask |= TT_DESCRIPTOR_SECTION_XN_MASK;
}
} else {
ASSERT (AttributeMask == 0);
if (AttributeMask != 0) {
return EFI_INVALID_PARAMETER;
}
TtEntryMask = TT_DESCRIPTOR_SECTION_TYPE_MASK |
TT_DESCRIPTOR_SECTION_XN_MASK |
TT_DESCRIPTOR_SECTION_AP_MASK |
TT_DESCRIPTOR_SECTION_AF;
}
return SetMemoryAttributes (
BaseAddress,
Length,
Attributes,
TtEntryMask
);
return ArmSetMemoryAttributes (BaseAddress, Length, EFI_MEMORY_XP);
}
EFI_STATUS
ArmClearMemoryRegionNoExec (
IN EFI_PHYSICAL_ADDRESS BaseAddress,
IN UINT64 Length
)
{
return ArmSetMemoryAttributes (BaseAddress, Length, __EFI_MEMORY_RWX);
}
EFI_STATUS
ArmSetMemoryRegionReadOnly (
IN EFI_PHYSICAL_ADDRESS BaseAddress,
IN UINT64 Length
)
{
return ArmSetMemoryAttributes (BaseAddress, Length, EFI_MEMORY_RO);
}
EFI_STATUS
ArmClearMemoryRegionReadOnly (
IN EFI_PHYSICAL_ADDRESS BaseAddress,
IN UINT64 Length
)
{
return ArmSetMemoryAttributes (BaseAddress, Length, __EFI_MEMORY_RWX);
}

View File

@ -19,12 +19,10 @@
CONSTRUCTOR = ArmMmuBaseLibConstructor
[Sources.AARCH64]
ArmMmuLibInternal.h
AArch64/ArmMmuLibCore.c
AArch64/ArmMmuLibReplaceEntry.S
[Sources.ARM]
ArmMmuLibInternal.h
Arm/ArmMmuLibConvert.c
Arm/ArmMmuLibCore.c
Arm/ArmMmuLibUpdate.c
@ -38,11 +36,7 @@
[LibraryClasses]
ArmLib
CacheMaintenanceLib
HobLib
MemoryAllocationLib
[Guids]
gArmMmuReplaceLiveTranslationEntryFuncGuid
[Pcd.ARM]
gArmTokenSpaceGuid.PcdNormalMemoryNonshareableOverride

View File

@ -1,23 +0,0 @@
/** @file
Arm MMU library instance internal header file.
Copyright (C) Microsoft Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#ifndef ARM_MMU_LIB_INTERNAL_H_
#define ARM_MMU_LIB_INTERNAL_H_
typedef
VOID(
EFIAPI *ARM_REPLACE_LIVE_TRANSLATION_ENTRY
)(
IN UINT64 *Entry,
IN UINT64 Value,
IN UINT64 RegionStart,
IN BOOLEAN DisableMmu
);
#endif

View File

@ -17,7 +17,6 @@
CONSTRUCTOR = ArmMmuPeiLibConstructor
[Sources.AARCH64]
ArmMmuLibInternal.h
AArch64/ArmMmuLibCore.c
AArch64/ArmMmuPeiLibConstructor.c
AArch64/ArmMmuLibReplaceEntry.S
@ -30,8 +29,4 @@
[LibraryClasses]
ArmLib
CacheMaintenanceLib
HobLib
MemoryAllocationLib
[Guids]
gArmMmuReplaceLiveTranslationEntryFuncGuid

View File

@ -1,34 +0,0 @@
/** @file
Arm Monitor Library.
Copyright (c) 2022, Arm Limited. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include <Library/ArmHvcLib.h>
#include <Library/ArmMonitorLib.h>
#include <Library/ArmSmcLib.h>
#include <Library/PcdLib.h>
/** Monitor call.
An HyperVisor Call (HVC) or System Monitor Call (SMC) will be issued
depending on the default conduit. PcdMonitorConduitHvc determines the type
of the call: if true, do an HVC.
@param [in,out] Args Arguments for the HVC/SMC.
**/
VOID
EFIAPI
ArmMonitorCall (
IN OUT ARM_MONITOR_ARGS *Args
)
{
if (PcdGetBool (PcdMonitorConduitHvc)) {
ArmCallHvc ((ARM_HVC_ARGS *)Args);
} else {
ArmCallSmc ((ARM_SMC_ARGS *)Args);
}
}

View File

@ -1,29 +0,0 @@
## @file
# Arm Monitor Library
#
# Copyright (c) 2022, Arm Limited. All rights reserved.<BR>
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
##
[Defines]
INF_VERSION = 1.29
BASE_NAME = ArmMonitorLib
FILE_GUID = F918DACB-FBB8-4CB6-A61D-08E75AF0E7CD
MODULE_TYPE = BASE
VERSION_STRING = 1.0
LIBRARY_CLASS = ArmMonitorLib
[Sources]
ArmMonitorLib.c
[Packages]
ArmPkg/ArmPkg.dec
MdePkg/MdePkg.dec
[LibraryClasses]
ArmHvcLib
ArmSmcLib
[Pcd]
gArmTokenSpaceGuid.PcdMonitorConduitHvc

View File

@ -65,7 +65,7 @@ LibResetSystem (
ArmCallSmc (&ArmSmcArgs);
// We should never be here
DEBUG ((DEBUG_ERROR, "%a: PSCI Reset failed\n", __func__));
DEBUG ((DEBUG_ERROR, "%a: PSCI Reset failed\n", __FUNCTION__));
CpuDeadLoop ();
return EFI_UNSUPPORTED;
}

View File

@ -3,7 +3,6 @@
Copyright (c) 2017 - 2018, Linaro Ltd. All rights reserved.<BR>
Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2022, Arm Limited. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
@ -48,24 +47,8 @@ ResetWarm (
VOID
)
{
UINTN Arg1;
UINTN Ret;
Arg1 = ARM_SMC_ID_PSCI_SYSTEM_RESET2_AARCH64;
// Is SYSTEM_RESET2 supported?
Ret = ArmCallSmc0 (ARM_SMC_ID_PSCI_FEATURES, &Arg1, NULL, NULL);
if (Ret == ARM_SMC_PSCI_RET_SUCCESS) {
// Send PSCI SYSTEM_RESET2 command
ArmCallSmc0 (Arg1, NULL, NULL, NULL);
} else {
// Map a warm reset into a cold reset
DEBUG ((
DEBUG_INFO,
"Warm reboot not supported by platform, issuing cold reboot\n"
));
ResetCold ();
}
// Map a warm reset into a cold reset
ResetCold ();
}
/**

View File

@ -5,12 +5,12 @@
//
//
#include <AsmMacroIoLibV8.h>
.text
.align 3
ASM_FUNC(ArmCallSvc)
GCC_ASM_EXPORT(ArmCallSvc)
ASM_PFX(ArmCallSvc):
// Push frame pointer and return address on the stack
stp x29, x30, [sp, #-32]!
mov x29, sp

View File

@ -1,50 +0,0 @@
/** @file
Arm Firmware TRNG definitions.
Copyright (c) 2021 - 2022, Arm Limited. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
@par Reference(s):
- [1] Arm True Random Number Generator Firmware, Interface 1.0,
Platform Design Document.
(https://developer.arm.com/documentation/den0098/latest/)
@par Glossary:
- TRNG - True Random Number Generator
- FID - Function ID
**/
#ifndef ARM_FW_TRNG_DEFS_H_
#define ARM_FW_TRNG_DEFS_H_
#include <IndustryStandard/ArmStdSmc.h>
// Firmware TRNG revision mask and shift
#define TRNG_REV_MAJOR_MASK 0x7FFF
#define TRNG_REV_MINOR_MASK 0xFFFF
#define TRNG_REV_MAJOR_SHIFT 16
#if defined (MDE_CPU_ARM)
/** FID to use on AArch32 platform to request entropy.
*/
#define ARM_SMC_ID_TRNG_RND ARM_SMC_ID_TRNG_RND_AARCH32
/** Maximum bits of entropy supported on AArch32.
*/
#define MAX_ENTROPY_BITS 96
#elif defined (MDE_CPU_AARCH64)
/** FID to use on AArch64 platform to request entropy.
*/
#define ARM_SMC_ID_TRNG_RND ARM_SMC_ID_TRNG_RND_AARCH64
/** Maximum bits of entropy supported on AArch64.
*/
#define MAX_ENTROPY_BITS 192
#else
#error "Firmware TRNG not supported. Unknown chipset."
#endif
#endif // ARM_FW_TRNG_DEFS_H_

View File

@ -1,382 +0,0 @@
/** @file
Arm Firmware TRNG interface library.
Copyright (c) 2021 - 2022, Arm Limited. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
@par Reference(s):
- [1] Arm True Random Number Generator Firmware, Interface 1.0,
Platform Design Document.
(https://developer.arm.com/documentation/den0098/latest/)
- [2] NIST Special Publication 800-90B, Recommendation for the Entropy
Sources Used for Random Bit Generation.
(https://csrc.nist.gov/publications/detail/sp/800-90b/final)
@par Glossary:
- TRNG - True Random Number Generator
- FID - Function ID
**/
#include <Base.h>
#include <Library/ArmLib.h>
#include <Library/ArmMonitorLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include "ArmTrngDefs.h"
/** Convert TRNG status codes to RETURN status codes.
@param [in] TrngStatus TRNG status code.
@retval RETURN_SUCCESS Success.
@retval RETURN_UNSUPPORTED Function not implemented or
negative return code.
@retval RETURN_INVALID_PARAMETER A parameter is invalid.
@retval RETURN_NOT_READY No Entropy available.
**/
STATIC
RETURN_STATUS
TrngStatusToReturnStatus (
IN INT32 TrngStatus
)
{
switch (TrngStatus) {
case TRNG_STATUS_NOT_SUPPORTED:
return RETURN_UNSUPPORTED;
case TRNG_STATUS_INVALID_PARAMETER:
return RETURN_INVALID_PARAMETER;
case TRNG_STATUS_NO_ENTROPY:
return RETURN_NOT_READY;
case TRNG_STATUS_SUCCESS:
return RETURN_SUCCESS;
default:
if (TrngStatus < 0) {
return RETURN_UNSUPPORTED;
}
return RETURN_SUCCESS;
}
}
/** Get the version of the Arm TRNG backend.
A TRNG may be implemented by the system firmware, in which case this
function shall return the version of the Arm TRNG backend.
The implementation must return NOT_SUPPORTED if a Back end is not present.
@param [out] MajorRevision Major revision.
@param [out] MinorRevision Minor revision.
@retval RETURN_SUCCESS The function completed successfully.
@retval RETURN_INVALID_PARAMETER Invalid parameter.
@retval RETURN_UNSUPPORTED Backend not present.
**/
RETURN_STATUS
EFIAPI
GetArmTrngVersion (
OUT UINT16 *MajorRevision,
OUT UINT16 *MinorRevision
)
{
RETURN_STATUS Status;
ARM_MONITOR_ARGS Parameters;
INT32 Revision;
if ((MajorRevision == NULL) || (MinorRevision == NULL)) {
return RETURN_INVALID_PARAMETER;
}
ZeroMem (&Parameters, sizeof (Parameters));
Parameters.Arg0 = ARM_SMC_ID_TRNG_VERSION;
ArmMonitorCall (&Parameters);
Revision = (INT32)Parameters.Arg0;
Status = TrngStatusToReturnStatus (Revision);
if (RETURN_ERROR (Status)) {
return Status;
}
*MinorRevision = (Revision & TRNG_REV_MINOR_MASK);
*MajorRevision = ((Revision >> TRNG_REV_MAJOR_SHIFT) & TRNG_REV_MAJOR_MASK);
return RETURN_SUCCESS;
}
/** Get the features supported by the Arm TRNG backend.
The caller can determine if functions defined in the Arm TRNG ABI are
present in the ABI implementation.
@param [in] FunctionId Function Id.
@param [out] Capability Function specific capability if present.
@retval RETURN_SUCCESS The function completed successfully.
@retval RETURN_INVALID_PARAMETER Invalid parameter.
@retval RETURN_UNSUPPORTED Function not implemented.
**/
STATIC
RETURN_STATUS
EFIAPI
GetArmTrngFeatures (
IN CONST UINT32 FunctionId,
OUT UINT32 *Capability OPTIONAL
)
{
ARM_MONITOR_ARGS Parameters;
RETURN_STATUS Status;
ZeroMem (&Parameters, sizeof (Parameters));
Parameters.Arg0 = ARM_SMC_ID_TRNG_FEATURES;
Parameters.Arg1 = FunctionId;
ArmMonitorCall (&Parameters);
Status = TrngStatusToReturnStatus (Parameters.Arg0);
if (RETURN_ERROR (Status)) {
return Status;
}
if (Capability != NULL) {
*Capability = (UINT32)Parameters.Arg0;
}
return RETURN_SUCCESS;
}
/** Get the UUID of the Arm TRNG backend.
A TRNG may be implemented by the system firmware, in which case this
function shall return the UUID of the TRNG backend.
Returning the Arm TRNG UUID is optional and if not implemented,
RETURN_UNSUPPORTED shall be returned.
Note: The caller must not rely on the returned UUID as a trustworthy Arm TRNG
Back end identity
@param [out] Guid UUID of the Arm TRNG backend.
@retval RETURN_SUCCESS The function completed successfully.
@retval RETURN_INVALID_PARAMETER Invalid parameter.
@retval RETURN_UNSUPPORTED Function not implemented.
**/
RETURN_STATUS
EFIAPI
GetArmTrngUuid (
OUT GUID *Guid
)
{
ARM_MONITOR_ARGS Parameters;
if (Guid == NULL) {
return RETURN_INVALID_PARAMETER;
}
ZeroMem (&Parameters, sizeof (Parameters));
Parameters.Arg0 = ARM_SMC_ID_TRNG_GET_UUID;
ArmMonitorCall (&Parameters);
// Only invalid value is TRNG_STATUS_NOT_SUPPORTED (-1).
if ((INT32)Parameters.Arg0 == TRNG_STATUS_NOT_SUPPORTED) {
return TrngStatusToReturnStatus ((INT32)Parameters.Arg0);
}
Guid->Data1 = (Parameters.Arg0 & MAX_UINT32);
Guid->Data2 = (Parameters.Arg1 & MAX_UINT16);
Guid->Data3 = ((Parameters.Arg1 >> 16) & MAX_UINT16);
Guid->Data4[0] = (Parameters.Arg2 & MAX_UINT8);
Guid->Data4[1] = ((Parameters.Arg2 >> 8) & MAX_UINT8);
Guid->Data4[2] = ((Parameters.Arg2 >> 16) & MAX_UINT8);
Guid->Data4[3] = ((Parameters.Arg2 >> 24) & MAX_UINT8);
Guid->Data4[4] = (Parameters.Arg3 & MAX_UINT8);
Guid->Data4[5] = ((Parameters.Arg3 >> 8) & MAX_UINT8);
Guid->Data4[6] = ((Parameters.Arg3 >> 16) & MAX_UINT8);
Guid->Data4[7] = ((Parameters.Arg3 >> 24) & MAX_UINT8);
DEBUG ((DEBUG_INFO, "FW-TRNG: UUID %g\n", Guid));
return RETURN_SUCCESS;
}
/** Returns maximum number of entropy bits that can be returned in a single
call.
@return Returns the maximum number of Entropy bits that can be returned
in a single call to GetArmTrngEntropy().
**/
UINTN
EFIAPI
GetArmTrngMaxSupportedEntropyBits (
VOID
)
{
return MAX_ENTROPY_BITS;
}
/** Returns N bits of conditioned entropy.
See [2] Section 2.3.1 GetEntropy: An Interface to the Entropy Source
GetEntropy
Input:
bits_of_entropy: the requested amount of entropy
Output:
entropy_bitstring: The string that provides the requested entropy.
status: A Boolean value that is TRUE if the request has been satisfied,
and is FALSE otherwise.
@param [in] EntropyBits Number of entropy bits requested.
@param [in] BufferSize Size of the Buffer in bytes.
@param [out] Buffer Buffer to return the entropy bits.
@retval RETURN_SUCCESS The function completed successfully.
@retval RETURN_INVALID_PARAMETER Invalid parameter.
@retval RETURN_UNSUPPORTED Function not implemented.
@retval RETURN_BAD_BUFFER_SIZE Buffer size is too small.
@retval RETURN_NOT_READY No Entropy available.
**/
RETURN_STATUS
EFIAPI
GetArmTrngEntropy (
IN UINTN EntropyBits,
IN UINTN BufferSize,
OUT UINT8 *Buffer
)
{
RETURN_STATUS Status;
ARM_MONITOR_ARGS Parameters;
UINTN EntropyBytes;
UINTN LastValidBits;
UINTN BytesToClear;
UINTN EntropyData[3];
if ((EntropyBits == 0) ||
(EntropyBits > MAX_ENTROPY_BITS) ||
(Buffer == NULL))
{
return RETURN_INVALID_PARAMETER;
}
EntropyBytes = (EntropyBits + 7) >> 3;
if (EntropyBytes > BufferSize) {
return RETURN_BAD_BUFFER_SIZE;
}
ZeroMem (Buffer, BufferSize);
ZeroMem (&Parameters, sizeof (Parameters));
Parameters.Arg0 = ARM_SMC_ID_TRNG_RND;
Parameters.Arg1 = EntropyBits;
ArmMonitorCall (&Parameters);
Status = TrngStatusToReturnStatus ((INT32)Parameters.Arg0);
if (RETURN_ERROR (Status)) {
return Status;
}
// The entropy data is returned in the Parameters.Arg<3..1>
// With the lower order bytes in Parameters.Arg3 and the higher
// order bytes being stored in Parameters.Arg1.
EntropyData[0] = Parameters.Arg3;
EntropyData[1] = Parameters.Arg2;
EntropyData[2] = Parameters.Arg1;
CopyMem (Buffer, EntropyData, EntropyBytes);
// Mask off any unused top bytes, in accordance with specification.
BytesToClear = BufferSize - EntropyBytes;
if (BytesToClear != 0) {
ZeroMem (&Buffer[EntropyBytes], BytesToClear);
}
// Clear the unused MSB bits of the last byte.
LastValidBits = EntropyBits & 0x7;
if (LastValidBits != 0) {
Buffer[EntropyBytes - 1] &= (0xFF >> (8 - LastValidBits));
}
return Status;
}
/** The constructor checks that the FW-TRNG interface is supported
by the host firmware.
It will ASSERT() if FW-TRNG is not supported.
It will always return RETURN_SUCCESS.
@retval RETURN_SUCCESS The constructor always returns RETURN_SUCCESS.
**/
RETURN_STATUS
EFIAPI
ArmTrngLibConstructor (
VOID
)
{
ARM_MONITOR_ARGS Parameters;
RETURN_STATUS Status;
UINT16 MajorRev;
UINT16 MinorRev;
GUID Guid;
ZeroMem (&Parameters, sizeof (Parameters));
Parameters.Arg0 = SMCCC_VERSION;
ArmMonitorCall (&Parameters);
Status = TrngStatusToReturnStatus ((INT32)Parameters.Arg0);
if (RETURN_ERROR (Status)) {
goto ErrorHandler;
}
// Cf [1] s2.1.3 'Caller responsibilities',
// SMCCC version must be greater or equal than 1.1
if ((INT32)Parameters.Arg0 < 0x10001) {
goto ErrorHandler;
}
Status = GetArmTrngVersion (&MajorRev, &MinorRev);
if (RETURN_ERROR (Status)) {
goto ErrorHandler;
}
// Check that the required features are present.
Status = GetArmTrngFeatures (ARM_SMC_ID_TRNG_RND, NULL);
if (RETURN_ERROR (Status)) {
goto ErrorHandler;
}
// Check if TRNG UUID is supported and if so trace the GUID.
Status = GetArmTrngFeatures (ARM_SMC_ID_TRNG_GET_UUID, NULL);
if (RETURN_ERROR (Status)) {
goto ErrorHandler;
}
DEBUG_CODE_BEGIN ();
Status = GetArmTrngUuid (&Guid);
if (RETURN_ERROR (Status)) {
goto ErrorHandler;
}
DEBUG ((
DEBUG_INFO,
"FW-TRNG: Version %d.%d, GUID {%g}\n",
MajorRev,
MinorRev,
&Guid
));
DEBUG_CODE_END ();
return RETURN_SUCCESS;
ErrorHandler:
DEBUG ((DEBUG_ERROR, "ArmTrngLib could not be correctly initialized.\n"));
return RETURN_SUCCESS;
}

View File

@ -1,29 +0,0 @@
## @file
# Arm Firmware TRNG interface library.
#
# Copyright (c) 2021 - 2022, Arm Limited. All rights reserved.<BR>
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
##
[Defines]
INF_VERSION = 1.29
BASE_NAME = ArmTrngLib
FILE_GUID = 10DE97C9-28E4-4C9B-A53E-8D7D1B0DD4E0
VERSION_STRING = 1.0
MODULE_TYPE = BASE
LIBRARY_CLASS = ArmTrngLib
CONSTRUCTOR = ArmTrngLibConstructor
[Sources]
ArmTrngDefs.h
ArmTrngLib.c
[Packages]
ArmPkg/ArmPkg.dec
MdePkg/MdePkg.dec
[LibraryClasses]
ArmMonitorLib
BaseLib
BaseMemoryLib

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