Compare commits

..

48 Commits

Author SHA1 Message Date
Jeremy Soller
8c80e407f5 Fix detection of framebuffer BAR 2022-07-09 15:23:29 -06:00
Sean Rhodes
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
Sean Rhodes
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
Matt DeVillier
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
Patrick Rudolph
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
Patrick Rudolph
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
Sean Rhodes
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
Patrick Rudolph
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
Patrick Rudolph
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
Patrick Rudolph
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
Patrick Rudolph
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
Jeremy Soller
626f1a3273 UefiPayloadPkg: Add System76 Setup menu 2022-06-03 09:03:42 -06:00
Jeremy Soller
0420529401 UefiPayloadPkg: Add Intel GOP driver 2022-06-03 09:03:42 -06:00
Tim Crawford
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
Tim Crawford
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
Tim Crawford
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
Tim Crawford
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
Jeremy Soller
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
Tim Crawford
f2e99ad7b6 MdeModulePkg/BMM: Unregister F9 and F10 hotkeys 2022-06-03 09:03:42 -06:00
Tim Crawford
ae93abfcbf MdeModulePkg/BMM: Remove Commit/Discard buttons 2022-06-03 09:03:42 -06:00
Tim Crawford
de3e52e5d3 MdeModulePkg/BMM: Save BootOrder on list update 2022-06-03 09:03:42 -06:00
Tim Crawford
260b22ed3e MdeModulePkg/BMM: Add some debug logging 2022-06-03 09:03:42 -06:00
Tim Crawford
b79d3f9599 MdeModulePkg/UiApp: Add warning if no bootable options found 2022-06-03 09:03:42 -06:00
Tim Crawford
49dad2f15d MdeModulePkg/BootMaintenanceManagerUiLib: Make it look like current BMM 2022-06-03 09:03:42 -06:00
Tim Crawford
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
Tim Crawford
52d9ce76db MdeModulePkg/BM: Make it look like current BootMngr 2022-06-03 09:03:42 -06:00
Tim Crawford
0d209e3a81 UefiPayloadPkg: Disable EFI shell 2022-06-03 09:03:42 -06:00
Jeremy Soller
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
Patrick Rudolph
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
Patrick Rudolph
6284b7fe6f UefiPayloadPkg: Use new filesystem drivers
Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com>
2022-06-03 09:03:42 -06:00
CoolStar
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
Tim Crawford
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
Tim Crawford
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
Matt DeVillier
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
Tim Crawford
1fd1cf3dfb UefiPayloadPkg: Clear screen on boot error 2022-06-03 09:03:42 -06:00
Tim Crawford
053e8aed4d UefiPayloadPkg: Copy PlatformBootManagerUnableToBoot() from OvmfPkg 2022-06-03 09:03:42 -06:00
Matt DeVillier
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
Matt DeVillier
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
Matt DeVillier
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
Matt DeVillier
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
Matt DeVillier
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
Tim Crawford
85f616be1b UefiPayloadPkg: Disable Device Manager 2022-06-03 09:03:41 -06:00
Matt DeVillier
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
Matt DeVillier
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
Tim Crawford
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
Tim Crawford
57ed7e7151 MdeModulePkg/Logo: Use System76 boot logo 2022-06-03 09:03:41 -06:00
Tim Crawford
a8285c29d8 UefiPayloadPkg: Enable boot logo
Signed-off-by: Tim Crawford <tcrawford@system76.com>
2022-06-03 09:03:41 -06:00
Tim Crawford
be10ebabba UefiPayloadPkg: Show boot message as progress text
Signed-off-by: Tim Crawford <tcrawford@system76.com>
2022-06-03 09:03:41 -06:00
1305 changed files with 20384 additions and 120062 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.10.6'
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.10.6"
default_linux_image: "ghcr.io/tianocore/containers/fedora-35-test:47addc9"

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'

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,7 +37,7 @@ 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'
@@ -52,9 +45,6 @@ jobs:
TARGET_CRYPTO:
Build.Pkgs: 'CryptoPkg'
Build.Targets: 'DEBUG,RELEASE,NO-TARGET,NOOPT'
TARGET_FSP:
Build.Pkgs: 'IntelFsp2Pkg,IntelFsp2WrapperPkg'
Build.Targets: 'DEBUG,RELEASE,NO-TARGET,NOOPT'
TARGET_SECURITY:
Build.Pkgs: 'SecurityPkg'
Build.Targets: 'DEBUG,RELEASE,NO-TARGET,NOOPT'
@@ -73,9 +63,6 @@ jobs:
pool:
vmImage: ${{ parameters.vm_image }}
${{ if not(eq(parameters.container, '')) }}:
container: ${{ parameters.container }}
steps:
- template: pr-gate-steps.yml
parameters:
@@ -83,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,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,29 +0,0 @@
## @file
# CodeQL configuration file for edk2.
#
# Copyright (c) Microsoft Corporation.
# SPDX-License-Identifier: BSD-2-Clause-Patent
##
name: "CodeQL config"
# The following line disables the default queries. This is used because we want to enable on query at a time by
# explicitly specifying each query in a "queries" array as they are enabled.
#
# See the following for more information about adding custom queries:
# https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-a-custom-configuration-file
#disable-default-queries: true
queries:
- name: EDK2 CodeQL Query List
uses: ./.github/codeql/edk2.qls
# We must specify a query for CodeQL to run. Until the first query is enabled, enable the security query suite but
# exclude all problem levels from impacting the results. After the first query is enabled, this filter can be relaxed
# to find the level of problems desired from the query.
query-filters:
- exclude:
problem.severity:
- warning
- recommendation

View File

@@ -1,14 +0,0 @@
---
- description: EDK2 (C++) queries
# Bring in all queries from the official cpp-queries suite so individual queries can be explicitly enabled.
- queries: '.'
from: codeql/cpp-queries
# Enable individual queries below.
- include:
id: cpp/infinite-loop-with-unsatisfiable-exit-condition
- include:
id: cpp/overflow-buffer

View File

@@ -1,34 +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"
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
day: "monday"
commit-message:
prefix: "GitHub Action"
reviewers:
- "makubacki"
- "mdkinney"
- "spbrogan"

View File

@@ -1,96 +0,0 @@
# @file
# GitHub Workflow for CodeQL Analysis
#
# Copyright (c) Microsoft Corporation.
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
##
name: "CodeQL"
on:
push:
branches:
- master
pull_request:
branches:
- master
paths-ignore:
- '**/*.bat'
- '**/*.md'
- '**/*.py'
- '**/*.rst'
- '**/*.sh'
- '**/*.txt'
schedule:
# https://crontab.guru/#20_23_*_*_4
- cron: '20 23 * * 4'
jobs:
analyze:
name: Analyze
runs-on: windows-2019
permissions:
actions: read
contents: read
security-events: write
strategy:
fail-fast: false
matrix:
package: [
"ArmPkg",
"CryptoPkg",
"DynamicTablesPkg",
"FatPkg",
"FmpDevicePkg",
"IntelFsp2Pkg",
"IntelFsp2WrapperPkg",
"MdeModulePkg",
"MdePkg",
"PcAtChipsetPkg",
"PrmPkg",
"SecurityPkg",
"ShellPkg",
"SourceLevelDebugPkg",
"StandaloneMmPkg",
"UefiCpuPkg",
"UnitTestFrameworkPkg"]
steps:
- name: Checkout repository
uses: actions/checkout@v3
- name: Install Python
uses: actions/setup-python@v4
with:
python-version: '3.10.6'
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
with:
languages: 'cpp'
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
# Learn more about CodeQL language support at https://codeql.github.com/docs/codeql-overview/supported-languages-and-frameworks/
config-file: ./.github/codeql/codeql-config.yml
# Note: Add new queries to codeql-config.yml file as they are enabled.
- name: Install/Upgrade pip Modules
run: pip install -r pip-requirements.txt --upgrade
- name: Setup
run: stuart_setup -c .pytool/CISettings.py -t DEBUG -a IA32,X64 TOOL_CHAIN_TAG=VS2019
- name: Update
run: stuart_update -c .pytool/CISettings.py -t DEBUG -a IA32,X64 TOOL_CHAIN_TAG=VS2019
- name: Build Tools From Source
run: python BaseTools/Edk2ToolsBuild.py -t VS2019
- name: CI Build
run: stuart_ci_build -c .pytool/CISettings.py -p ${{ matrix.package }} -t DEBUG -a IA32,X64 TOOL_CHAIN_TAG=VS2019
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2

3
.gitmodules vendored
View File

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

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

@@ -53,10 +53,7 @@ class Settings(CiBuildSettingsManager, UpdateSettingsManager, SetupSettingsManag
"ArmPlatformPkg",
"ArmVirtPkg",
"DynamicTablesPkg",
"EmbeddedPkg",
"EmulatorPkg",
"IntelFsp2Pkg",
"IntelFsp2WrapperPkg",
"MdePkg",
"MdeModulePkg",
"NetworkPkg",
@@ -65,7 +62,6 @@ class Settings(CiBuildSettingsManager, UpdateSettingsManager, SetupSettingsManag
"UefiCpuPkg",
"FmpDevicePkg",
"ShellPkg",
"SignedCapsulePkg",
"StandaloneMmPkg",
"FatPkg",
"CryptoPkg",
@@ -73,7 +69,6 @@ class Settings(CiBuildSettingsManager, UpdateSettingsManager, SetupSettingsManag
"UnitTestFrameworkPkg",
"OvmfPkg",
"RedfishPkg",
"SourceLevelDebugPkg",
"UefiPayloadPkg"
)
@@ -84,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 '''
@@ -169,6 +163,13 @@ class Settings(CiBuildSettingsManager, UpdateSettingsManager, SetupSettingsManag
else:
logging.warning("Falling back to using in-tree BaseTools")
if is_linux and self.ActualToolChainTag.upper().startswith("GCC"):
if "AARCH64" in self.ActualArchitectures:
scopes += ("gcc_aarch64_linux",)
if "ARM" in self.ActualArchitectures:
scopes += ("gcc_arm_linux",)
if "RISCV64" in self.ActualArchitectures:
scopes += ("gcc_riscv64_unknown",)
self.ActualScopes = scopes
return self.ActualScopes
@@ -183,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(

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

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

View File

@@ -290,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]:
""""

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 |
@@ -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

View File

@@ -2,7 +2,7 @@
# ARM processor package.
#
# Copyright (c) 2009 - 2010, Apple Inc. All rights reserved.<BR>
# Copyright (c) 2011 - 2022, 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
## Define the conduit to use for monitor calls.
# Default PcdMonitorConduitHvc = FALSE, conduit = SMC
# If PcdMonitorConduitHvc = TRUE, conduit = HVC
gArmTokenSpaceGuid.PcdMonitorConduitHvc|FALSE|BOOLEAN|0x00000047
[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

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
@@ -163,7 +161,6 @@
ArmPkg/Universal/Smbios/OemMiscLibNull/OemMiscLibNull.inf
[Components.AARCH64]
ArmPkg/Drivers/ArmPsciMpServicesDxe/ArmPsciMpServicesDxe.inf
ArmPkg/Drivers/MmCommunicationDxe/MmCommunication.inf
ArmPkg/Library/ArmMmuLib/ArmMmuPeiLib.inf

View File

@@ -366,9 +366,10 @@ ArmGicIsInterruptEnabled (
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,

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

@@ -256,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

@@ -104,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 (

View File

@@ -21,6 +21,7 @@
[Sources.Common]
CpuDxe.c
CpuDxe.h
CpuMpCore.c
CpuMmuCommon.c
Exception.c

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

@@ -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,102 +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)
#endif // ARM_STD_SMC_H_

View File

@@ -108,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.

View File

@@ -52,10 +52,9 @@ ArmClearMemoryRegionReadOnly (
VOID
EFIAPI
ArmReplaceLiveTranslationEntry (
IN UINT64 *Entry,
IN UINT64 Value,
IN UINT64 RegionStart,
IN BOOLEAN DisableMmu
IN UINT64 *Entry,
IN UINT64 Value,
IN UINT64 RegionStart
);
EFI_STATUS

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

@@ -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

@@ -10,7 +10,6 @@
**/
#include <Uefi.h>
#include <Pi/PiMultiPhase.h>
#include <Chipset/AArch64.h>
#include <Library/BaseMemoryLib.h>
#include <Library/CacheMaintenanceLib.h>
@@ -19,17 +18,6 @@
#include <Library/ArmMmuLib.h>
#include <Library/BaseLib.h>
#include <Library/DebugLib.h>
#include <Library/HobLib.h>
STATIC
VOID (
EFIAPI *mReplaceLiveEntryFunc
)(
IN UINT64 *Entry,
IN UINT64 Value,
IN UINT64 RegionStart,
IN BOOLEAN DisableMmu
) = ArmReplaceLiveTranslationEntry;
STATIC
UINT64
@@ -95,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", __FUNCTION__));
}
mReplaceLiveEntryFunc (Entry, Value, RegionStart, DisableMmu);
ArmReplaceLiveTranslationEntry (Entry, Value, RegionStart);
}
}
@@ -193,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;
@@ -209,7 +170,6 @@ UpdateRegionMappingRecursive (
UINT64 EntryValue;
VOID *TranslationTable;
EFI_STATUS Status;
BOOLEAN NextTableIsLive;
ASSERT (((RegionStart | RegionEnd) & EFI_PAGE_MASK) == 0);
@@ -237,16 +197,12 @@ 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);
@@ -281,8 +237,7 @@ UpdateRegionMappingRecursive (
*Entry & TT_ATTRIBUTES_MASK,
0,
TranslationTable,
Level + 1,
FALSE
Level + 1
);
if (EFI_ERROR (Status)) {
//
@@ -294,11 +249,8 @@ UpdateRegionMappingRecursive (
return Status;
}
}
NextTableIsLive = FALSE;
} else {
TranslationTable = (VOID *)(UINTN)(*Entry & TT_ADDRESS_MASK_BLOCK_ENTRY);
NextTableIsLive = TableIsLive;
}
//
@@ -310,8 +262,7 @@ UpdateRegionMappingRecursive (
AttributeSetMask,
AttributeClearMask,
TranslationTable,
Level + 1,
NextTableIsLive
Level + 1
);
if (EFI_ERROR (Status)) {
if (!IsTableEntry (*Entry, Level)) {
@@ -334,8 +285,7 @@ UpdateRegionMappingRecursive (
Entry,
EntryValue,
RegionStart,
BlockMask,
TableIsLive && IsBlockEntry (*Entry, Level)
IsBlockEntry (*Entry, Level)
);
}
} else {
@@ -344,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);
}
}
}
@@ -354,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;
@@ -375,9 +336,8 @@ UpdateRegionMapping (
RegionStart + RegionLength,
AttributeSetMask,
AttributeClearMask,
RootTable,
GetRootTableLevel (T0SZ),
TableIsLive
ArmGetTTBR0BaseAddress (),
GetRootTableLevel (T0SZ)
);
}
@@ -392,9 +352,7 @@ FillTranslationTable (
MemoryRegion->VirtualBase,
MemoryRegion->Length,
ArmMemoryAttributeToPageAttribute (MemoryRegion->Attributes) | TT_AF,
0,
RootTable,
FALSE
0
);
}
@@ -468,9 +426,7 @@ ArmSetMemoryAttributes (
BaseAddress,
Length,
PageAttributes,
PageAttributeMask,
ArmGetTTBR0BaseAddress (),
TRUE
PageAttributeMask
);
}
@@ -483,14 +439,7 @@ SetMemoryRegionAttribute (
IN UINT64 BlockEntryMask
)
{
return UpdateRegionMapping (
BaseAddress,
Length,
Attributes,
BlockEntryMask,
ArmGetTTBR0BaseAddress (),
TRUE
);
return UpdateRegionMapping (BaseAddress, Length, Attributes, BlockEntryMask);
}
EFI_STATUS
@@ -664,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 |
@@ -680,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;
}
@@ -688,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) {
@@ -723,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:
@@ -748,21 +697,15 @@ ArmMmuBaseLibConstructor (
)
{
extern UINT32 ArmReplaceLiveTranslationEntrySize;
VOID *Hob;
Hob = GetFirstGuidHob (&gArmMmuReplaceLiveTranslationEntryFuncGuid);
if (Hob != NULL) {
mReplaceLiveEntryFunc = *(VOID **)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,33 +38,8 @@
// 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
.L2_\@:
.endm
// Align this routine to a log2 upper bound of its size, so that it is
// guaranteed not to cross a page or block boundary.
.balign 0x200
//VOID
//ArmReplaceLiveTranslationEntry (
// IN UINT64 *Entry,
@@ -86,7 +53,12 @@ ASM_FUNC(ArmReplaceLiveTranslationEntry)
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,6 +72,3 @@ ASM_GLOBAL ASM_PFX(ArmReplaceLiveTranslationEntrySize)
ASM_PFX(ArmReplaceLiveTranslationEntrySize):
.long . - ArmReplaceLiveTranslationEntry
// Double check that we did not overrun the assumed maximum size
.org ArmReplaceLiveTranslationEntry + 0x200

View File

@@ -12,7 +12,6 @@
#include <Library/ArmMmuLib.h>
#include <Library/CacheMaintenanceLib.h>
#include <Library/DebugLib.h>
#include <Library/HobLib.h>
EFI_STATUS
EFIAPI
@@ -22,8 +21,6 @@ ArmMmuPeiLibConstructor (
)
{
extern UINT32 ArmReplaceLiveTranslationEntrySize;
VOID *ArmReplaceLiveTranslationEntryFunc;
VOID *Hob;
EFI_FV_FILE_INFO FileInfo;
EFI_STATUS Status;
@@ -45,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

@@ -36,11 +36,7 @@
[LibraryClasses]
ArmLib
CacheMaintenanceLib
HobLib
MemoryAllocationLib
[Guids]
gArmMmuReplaceLiveTranslationEntryFuncGuid
[Pcd.ARM]
gArmTokenSpaceGuid.PcdNormalMemoryNonshareableOverride

View File

@@ -29,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 (FeaturePcdGet (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

@@ -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

@@ -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

View File

@@ -77,8 +77,13 @@ PeCoffLoaderRelocateImageExtraAction (
if (ImageContext->PdbPointer) {
#ifdef __CC_ARM
#if (__ARMCC_VERSION < 500000)
// Print out the command for the RVD debugger to load symbols for this image
DEBUG ((DEBUG_LOAD | DEBUG_INFO, "load /a /ni /np %a &0x%p\n", DeCygwinPathIfNeeded (ImageContext->PdbPointer, Temp, sizeof (Temp)), (UINTN)(ImageContext->ImageAddress + ImageContext->SizeOfHeaders)));
#else
// Print out the command for the DS-5 to load symbols for this image
DEBUG ((DEBUG_LOAD | DEBUG_INFO, "add-symbol-file %a 0x%p\n", DeCygwinPathIfNeeded (ImageContext->PdbPointer, Temp, sizeof (Temp)), (UINTN)(ImageContext->ImageAddress + ImageContext->SizeOfHeaders)));
#endif
#elif __GNUC__
// This may not work correctly if you generate PE/COFF directly as then the Offset would not be required
DEBUG ((DEBUG_LOAD | DEBUG_INFO, "add-symbol-file %a 0x%p\n", DeCygwinPathIfNeeded (ImageContext->PdbPointer, Temp, sizeof (Temp)), (UINTN)(ImageContext->ImageAddress + ImageContext->SizeOfHeaders)));

View File

@@ -0,0 +1,147 @@
/**@file
Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR>
Portions copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
Portions copyright (c) 2011 - 2012, ARM Ltd. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include <PiDxe.h>
#include <Library/PeCoffLib.h>
#include <Library/BaseLib.h>
#include <Library/DebugLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/PeCoffExtraActionLib.h>
#include <Library/SemihostLib.h>
#include <Library/PrintLib.h>
/**
Append string to debugger script file, create file if needed.
This library can show up in multiple places so we need to append the file every time we write to it.
For example Sec can use this to load the DXE core, and the DXE core would use this to load all the
other modules. So we have two instances of the library in the system.
@param Buffer Buffer to write to file.
@param Length Length of Buffer in bytes.
**/
VOID
WriteStringToFile (
IN VOID *Buffer,
IN UINT32 Length
)
{
// Working around and issue with the code that is commented out. For now send it to the console.
// You can copy the console into a file and source the file as a script and you get symbols.
// This gets you all the symbols except for SEC. To get SEC symbols you need to copy the
// debug print in the SEC into the debugger manually
SemihostWriteString (Buffer);
/*
I'm currently having issues with this code crashing the debugger. Seems like it should work.
UINT32 SemihostHandle;
UINT32 SemihostMode = SEMIHOST_FILE_MODE_WRITE | SEMIHOST_FILE_MODE_BINARY | SEMIHOST_FILE_MODE_UPDATE;
SemihostFileOpen ("c:\rvi_symbols.inc", SemihostMode, &SemihostHandle);
SemihostFileWrite (SemihostHandle, &Length, Buffer);
SemihostFileClose (SemihostHandle);
*/
}
/**
If the build is done on cygwin the paths are cygpaths.
/cygdrive/c/tmp.txt vs c:\tmp.txt so we need to convert
them to work with RVD commands
@param Name Path to convert if needed
**/
CHAR8 *
DeCygwinPathIfNeeded (
IN CHAR8 *Name
)
{
CHAR8 *Ptr;
UINTN Index;
UINTN Len;
Ptr = AsciiStrStr (Name, "/cygdrive/");
if (Ptr == NULL) {
return Name;
}
Len = AsciiStrLen (Ptr);
// convert "/cygdrive" to spaces
for (Index = 0; Index < 9; Index++) {
Ptr[Index] = ' ';
}
// convert /c to c:
Ptr[9] = Ptr[10];
Ptr[10] = ':';
// switch path separators
for (Index = 11; Index < Len; Index++) {
if (Ptr[Index] == '/') {
Ptr[Index] = '\\';
}
}
return Name;
}
/**
Performs additional actions after a PE/COFF image has been loaded and relocated.
If ImageContext is NULL, then ASSERT().
@param ImageContext Pointer to the image context structure that describes the
PE/COFF image that has already been loaded and relocated.
**/
VOID
EFIAPI
PeCoffLoaderRelocateImageExtraAction (
IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext
)
{
CHAR8 Buffer[256];
#if (__ARMCC_VERSION < 500000)
AsciiSPrint (Buffer, sizeof (Buffer), "load /a /ni /np \"%a\" &0x%08x\n", ImageContext->PdbPointer, (UINTN)(ImageContext->ImageAddress + ImageContext->SizeOfHeaders));
#else
AsciiSPrint (Buffer, sizeof (Buffer), "add-symbol-file %a 0x%08x\n", ImageContext->PdbPointer, (UINTN)(ImageContext->ImageAddress + ImageContext->SizeOfHeaders));
#endif
DeCygwinPathIfNeeded (&Buffer[16]);
WriteStringToFile (Buffer, AsciiStrSize (Buffer));
}
/**
Performs additional actions just before a PE/COFF image is unloaded. Any resources
that were allocated by PeCoffLoaderRelocateImageExtraAction() must be freed.
If ImageContext is NULL, then ASSERT().
@param ImageContext Pointer to the image context structure that describes the
PE/COFF image that is being unloaded.
**/
VOID
EFIAPI
PeCoffLoaderUnloadImageExtraAction (
IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext
)
{
CHAR8 Buffer[256];
AsciiSPrint (Buffer, sizeof (Buffer), "unload symbols_only \"%a\"\n", ImageContext->PdbPointer);
DeCygwinPathIfNeeded (Buffer);
WriteStringToFile (Buffer, AsciiStrSize (Buffer));
}

View File

@@ -0,0 +1,35 @@
#/** @file
# PeCoff extra action library for DXE phase that run Unix emulator.
#
# Lib to provide memory journal status code reporting Routines
# Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>
# Portions copyright (c) 2010, Apple Inc. All rights reserved.<BR>
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
#
#**/
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = RvdUnixPeCoffExtraActionLib
FILE_GUID = 5EDEB7E7-EA55-4E92-8216-335AC98A3B11
MODULE_TYPE = BASE
VERSION_STRING = 1.0
LIBRARY_CLASS = PeCoffExtraActionLib
#
# The following information is for reference only and not required by the build tools.
#
# VALID_ARCHITECTURES = ARM
#
[Sources.common]
RvdPeCoffExtraActionLib.c
[Packages]
MdePkg/MdePkg.dec
ArmPkg/ArmPkg.dec
[LibraryClasses]
DebugLib
SemihostLib

View File

@@ -1,7 +1,6 @@
/** @file
* OemMiscLib.c
*
* Copyright (c) 2022, Ampere Computing LLC. All rights reserved.
* Copyright (c) 2021, NUVIA Inc. All rights reserved.
* Copyright (c) 2018, Hisilicon Limited. All rights reserved.
* Copyright (c) 2018, Linaro Limited. All rights reserved.
@@ -11,12 +10,10 @@
**/
#include <Uefi.h>
#include <Guid/ZeroGuid.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/HiiLib.h>
#include <Library/OemMiscLib.h>
#include <Library/PcdLib.h>
/** Gets the CPU frequency of the specified processor.
@@ -239,47 +236,3 @@ OemGetChassisNumPowerCords (
ASSERT (FALSE);
return 1;
}
/**
Fetches the system UUID.
@param[out] SystemUuid The pointer to the buffer to store the System UUID.
**/
VOID
EFIAPI
OemGetSystemUuid (
OUT GUID *SystemUuid
)
{
ASSERT (FALSE);
CopyGuid (SystemUuid, &gZeroGuid);
}
/** Fetches the BIOS release.
@return The BIOS release.
**/
UINT16
EFIAPI
OemGetBiosRelease (
VOID
)
{
ASSERT (FALSE);
return PcdGet16 (PcdSystemBiosRelease);
}
/** Fetches the embedded controller firmware release.
@return The embedded controller firmware release.
**/
UINT16
EFIAPI
OemGetEmbeddedControllerFirmwareRelease (
VOID
)
{
ASSERT (FALSE);
return PcdGet16 (PcdEmbeddedControllerFirmwareRelease);
}

View File

@@ -1,7 +1,6 @@
#/** @file
# OemMiscLib.inf
#
# Copyright (c) 2022, Ampere Computing LLC. All rights reserved.
# Copyright (c) 2021, NUVIA Inc. All rights reserved.
# Copyright (c) 2018, Hisilicon Limited. All rights reserved.
# Copyright (c) 2018, Linaro Limited. All rights reserved.
@@ -30,11 +29,3 @@
[LibraryClasses]
BaseMemoryLib
DebugLib
PcdLib
[Guids]
gZeroGuid
[Pcd]
gArmTokenSpaceGuid.PcdEmbeddedControllerFirmwareRelease
gArmTokenSpaceGuid.PcdSystemBiosRelease

View File

@@ -1,7 +1,6 @@
/** @file
ProcessorSubClass.c
Copyright (c) 2022, Ampere Computing LLC. All rights reserved.
Copyright (c) 2021, NUVIA Inc. All rights reserved.<BR>
Copyright (c) 2015, Hisilicon Limited. All rights reserved.
Copyright (c) 2015, Linaro Limited. All rights reserved.
@@ -513,6 +512,7 @@ AllocateType4AndSetProcessorInformationStrings (
PartNumber = STRING_TOKEN (STR_PROCESSOR_PART_NUMBER);
SET_HII_STRING_IF_PCD_NOT_EMPTY (PcdProcessorManufacturer, ProcessorManu);
SET_HII_STRING_IF_PCD_NOT_EMPTY (PcdProcessorVersion, ProcessorVersion);
SET_HII_STRING_IF_PCD_NOT_EMPTY (PcdProcessorAssetTag, AssetTag);
if (StrLen ((CHAR16 *)FixedPcdGetPtr (PcdProcessorSerialNumber)) > 0) {
@@ -527,12 +527,6 @@ AllocateType4AndSetProcessorInformationStrings (
OemUpdateSmbiosInfo (mHiiHandle, PartNumber, ProcessorPartNumType04);
}
if (StrLen ((CHAR16 *)FixedPcdGetPtr (PcdProcessorVersion)) > 0) {
HiiSetString (mHiiHandle, ProcessorVersion, (CHAR16 *)FixedPcdGetPtr (PcdProcessorVersion), NULL);
} else {
OemUpdateSmbiosInfo (mHiiHandle, ProcessorVersion, ProcessorVersionType04);
}
// Processor Designation
StringBufferSize = sizeof (CHAR16) * SMBIOS_STRING_MAX_LENGTH;
ProcessorStr = AllocateZeroPool (StringBufferSize);

View File

@@ -2,7 +2,7 @@
Functions for processor information common to ARM and AARCH64.
Copyright (c) 2021, NUVIA Inc. All rights reserved.<BR>
Copyright (c) 2021 - 2022, Ampere Computing LLC. All rights reserved.<BR>
Copyright (c) 2021, Ampere Computing LLC. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -131,7 +131,7 @@ SmbiosGetSmcArm64SocId (
SmcCallStatus = ArmCallSmc1 (SMCCC_ARCH_SOC_ID, &SmcParam, NULL, NULL);
if (SmcCallStatus >= 0) {
*Jep106Code = SmcCallStatus;
*Jep106Code = (INT32)SmcParam;
} else {
Status = EFI_UNSUPPORTED;
}
@@ -140,7 +140,7 @@ SmbiosGetSmcArm64SocId (
SmcCallStatus = ArmCallSmc1 (SMCCC_ARCH_SOC_ID, &SmcParam, NULL, NULL);
if (SmcCallStatus >= 0) {
*SocRevision = SmcCallStatus;
*SocRevision = (INT32)SmcParam;
} else {
Status = EFI_UNSUPPORTED;
}

View File

@@ -1,6 +1,5 @@
/** @file
Copyright (c) 2022, Ampere Computing LLC. All rights reserved.<BR>
Copyright (c) 2021, NUVIA Inc. All rights reserved.<BR>
Copyright (c) 2009, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2015, Hisilicon Limited. All rights reserved.<BR>
@@ -14,7 +13,6 @@
#include <Library/DebugLib.h>
#include <Library/HiiLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/OemMiscLib.h>
#include <Library/PrintLib.h>
#include <Library/UefiBootServicesTableLib.h>
@@ -193,11 +191,11 @@ SMBIOS_MISC_TABLE_FUNCTION (MiscBiosVendor) {
TokenToUpdate = STRING_TOKEN (STR_MISC_BIOS_VERSION);
HiiSetString (mSmbiosMiscHiiHandle, TokenToUpdate, Version, NULL);
} else {
OemUpdateSmbiosInfo (
mSmbiosMiscHiiHandle,
STRING_TOKEN (STR_MISC_BIOS_VERSION),
BiosVersionType00
);
Version = (CHAR16 *)PcdGetPtr (PcdFirmwareVersionString);
if (StrLen (Version) > 0) {
TokenToUpdate = STRING_TOKEN (STR_MISC_BIOS_VERSION);
HiiSetString (mSmbiosMiscHiiHandle, TokenToUpdate, Version, NULL);
}
}
Char16String = GetBiosReleaseDate ();
@@ -253,11 +251,13 @@ SMBIOS_MISC_TABLE_FUNCTION (MiscBiosVendor) {
}
}
SmbiosRecord->SystemBiosMajorRelease = (UINT8)(OemGetBiosRelease () >> 8);
SmbiosRecord->SystemBiosMinorRelease = (UINT8)(OemGetBiosRelease () & 0xFF);
SmbiosRecord->SystemBiosMajorRelease = (UINT8)(PcdGet16 (PcdSystemBiosRelease) >> 8);
SmbiosRecord->SystemBiosMinorRelease = (UINT8)(PcdGet16 (PcdSystemBiosRelease) & 0xFF);
SmbiosRecord->EmbeddedControllerFirmwareMajorRelease = (UINT16)(OemGetEmbeddedControllerFirmwareRelease () >> 8);
SmbiosRecord->EmbeddedControllerFirmwareMinorRelease = (UINT16)(OemGetEmbeddedControllerFirmwareRelease () & 0xFF);
SmbiosRecord->EmbeddedControllerFirmwareMajorRelease = (UINT16)
(PcdGet16 (PcdEmbeddedControllerFirmwareRelease) >> 8);
SmbiosRecord->EmbeddedControllerFirmwareMinorRelease = (UINT16)
(PcdGet16 (PcdEmbeddedControllerFirmwareRelease) & 0xFF);
OptionalStrStart = (CHAR8 *)(SmbiosRecord + 1);
UnicodeStrToAsciiStrS (Vendor, OptionalStrStart, VendorStrLen + 1);

View File

@@ -4,7 +4,6 @@
Based on files under Nt32Pkg/MiscSubClassPlatformDxe/
Copyright (c) 2022, Ampere Computing LLC. All rights reserved.<BR>
Copyright (c) 2021, NUVIA Inc. All rights reserved.<BR>
Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2015, Hisilicon Limited. All rights reserved.<BR>
@@ -161,7 +160,7 @@ SMBIOS_MISC_TABLE_FUNCTION (MiscSystemManufacturer) {
SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE1);
OemGetSystemUuid (&SmbiosRecord->Uuid);
CopyGuid (&SmbiosRecord->Uuid, &InputData->Uuid);
OptionalStrStart = (CHAR8 *)(SmbiosRecord + 1);
UnicodeStrToAsciiStrS (Manufacturer, OptionalStrStart, ManuStrLen + 1);

View File

@@ -4,7 +4,6 @@
Based on files under Nt32Pkg/MiscSubClassPlatformDxe/
Copyright (c) 2022, Ampere Computing LLC. All rights reserved.<BR>
Copyright (c) 2021, NUVIA Inc. All rights reserved.<BR>
Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2015, Hisilicon Limited. All rights reserved.<BR>
@@ -113,7 +112,17 @@ SMBIOS_MISC_TABLE_FUNCTION (MiscBaseBoardManufacturer) {
OemUpdateSmbiosInfo (
mSmbiosMiscHiiHandle,
STRING_TOKEN (STR_MISC_BASE_BOARD_ASSET_TAG),
AssetTagType02
AssertTagType02
);
OemUpdateSmbiosInfo (
mSmbiosMiscHiiHandle,
STRING_TOKEN (STR_MISC_BASE_BOARD_SERIAL_NUMBER),
SerialNumberType02
);
OemUpdateSmbiosInfo (
mSmbiosMiscHiiHandle,
STRING_TOKEN (STR_MISC_BASE_BOARD_MANUFACTURER),
BoardManufacturerType02
);
OemUpdateSmbiosInfo (
mSmbiosMiscHiiHandle,

View File

@@ -38,6 +38,10 @@
#
LcdPlatformLib|Include/Library/LcdPlatformLib.h
## @libraryclass Provides a Nor flash interface.
#
NorFlashPlatformLib|Include/Library/NorFlashPlatformLib.h
## @libraryclass Provides an interface to the clock of a PL011 device.
#
PL011UartClockLib|Include/Library/PL011UartClockLib.h
@@ -52,6 +56,8 @@
[PcdsFeatureFlag.common]
gArmPlatformTokenSpaceGuid.PcdSendSgiToBringUpSecondaryCores|FALSE|BOOLEAN|0x00000004
gArmPlatformTokenSpaceGuid.PcdNorFlashCheckBlockLocked|FALSE|BOOLEAN|0x0000003C
# Disable the GOP controller on ExitBootServices(). By default the value is FALSE,
# we assume the OS will handle the FrameBuffer from the UEFI GOP information.
gArmPlatformTokenSpaceGuid.PcdGopDisableOnExitBootServices|FALSE|BOOLEAN|0x0000003D
@@ -88,7 +94,6 @@
gArmPlatformTokenSpaceGuid.PcdSerialDbgRegisterBase|0x00000000|UINT64|0x00000030
gArmPlatformTokenSpaceGuid.PcdSerialDbgUartBaudRate|0x00000000|UINT64|0x00000031
gArmPlatformTokenSpaceGuid.PcdSerialDbgUartClkInHz|0x00000000|UINT32|0x00000032
gArmPlatformTokenSpaceGuid.PcdSerialDbgInterrupt|0x00000000|UINT32|0x00000041
## PL061 GPIO
gArmPlatformTokenSpaceGuid.PcdPL061GpioBase|0x0|UINT32|0x00000025

View File

@@ -55,6 +55,7 @@
LzmaDecompressLib|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf
MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
MemoryInitPeiLib|ArmPlatformPkg/MemoryInitPei/MemoryInitPeiLib.inf
NorFlashPlatformLib|ArmPlatformPkg/Library/NorFlashPlatformNullLib/NorFlashPlatformNullLib.inf
PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf
PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
@@ -99,6 +100,7 @@
[Components.common]
ArmPlatformPkg/Drivers/LcdGraphicsOutputDxe/LcdGraphicsOutputDxe.inf
ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.inf
ArmPlatformPkg/Drivers/PL061GpioDxe/PL061GpioDxe.inf
ArmPlatformPkg/Drivers/SP805WatchdogDxe/SP805WatchdogDxe.inf
@@ -107,6 +109,7 @@
ArmPlatformPkg/Library/HdLcd/HdLcd.inf
ArmPlatformPkg/Library/LcdHwNullLib/LcdHwNullLib.inf
ArmPlatformPkg/Library/LcdPlatformNullLib/LcdPlatformNullLib.inf
ArmPlatformPkg/Library/NorFlashPlatformNullLib/NorFlashPlatformNullLib.inf
ArmPlatformPkg/Library/PL011SerialPortLib/PL011SerialPortLib.inf
ArmPlatformPkg/Library/PL011UartClockLib/PL011UartClockLib.inf
ArmPlatformPkg/Library/PL011UartLib/PL011UartLib.inf
@@ -127,3 +130,6 @@
ArmPlatformPkg/PrePi/PeiUniCore.inf
ArmPlatformPkg/Library/ArmMaliDp/ArmMaliDp.inf
[Components.AARCH64]
ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashStandaloneMm.inf

View File

@@ -815,6 +815,18 @@ LcdGraphicsBlt (
HorizontalResolution = This->Mode->Info->HorizontalResolution;
VerticalResolution = This->Mode->Info->VerticalResolution;
DEBUG ((
DEBUG_INFO,
"LcdGraphicsBlt (BltOperation:%d,DestX:%d,DestY:%d,Width:%d,Height:%d) res(%d,%d)\n",
BltOperation,
DestinationX,
DestinationY,
Width,
Height,
HorizontalResolution,
VerticalResolution
));
// Check we have reasonable parameters
if ((Width == 0) || (Height == 0)) {
DEBUG ((DEBUG_ERROR, "LcdGraphicsBlt: ERROR - Invalid dimension: Zero size area.\n"));

View File

@@ -9,7 +9,7 @@
#include <Library/BaseMemoryLib.h>
#include "VirtNorFlash.h"
#include "NorFlash.h"
//
// Global variable declarations
@@ -65,16 +65,35 @@ NorFlashUnlockSingleBlock (
// Raise the Task Priority Level to TPL_NOTIFY to serialise all its operations
// and to protect shared data structures.
// Request a lock setup
SEND_NOR_COMMAND (BlockAddress, 0, P30_CMD_LOCK_BLOCK_SETUP);
if (FeaturePcdGet (PcdNorFlashCheckBlockLocked) == TRUE) {
do {
// Request a lock setup
SEND_NOR_COMMAND (BlockAddress, 0, P30_CMD_LOCK_BLOCK_SETUP);
// Request an unlock
SEND_NOR_COMMAND (BlockAddress, 0, P30_CMD_UNLOCK_BLOCK);
// Request an unlock
SEND_NOR_COMMAND (BlockAddress, 0, P30_CMD_UNLOCK_BLOCK);
// Wait until the status register gives us the all clear
do {
LockStatus = NorFlashReadStatusRegister (Instance, BlockAddress);
} while ((LockStatus & P30_SR_BIT_WRITE) != P30_SR_BIT_WRITE);
// Send command for reading device id
SEND_NOR_COMMAND (BlockAddress, 2, P30_CMD_READ_DEVICE_ID);
// Read block lock status
LockStatus = MmioRead32 (CREATE_NOR_ADDRESS (BlockAddress, 2));
// Decode block lock status
LockStatus = FOLD_32BIT_INTO_16BIT (LockStatus);
} while ((LockStatus & 0x1) == 1);
} else {
// Request a lock setup
SEND_NOR_COMMAND (BlockAddress, 0, P30_CMD_LOCK_BLOCK_SETUP);
// Request an unlock
SEND_NOR_COMMAND (BlockAddress, 0, P30_CMD_UNLOCK_BLOCK);
// Wait until the status register gives us the all clear
do {
LockStatus = NorFlashReadStatusRegister (Instance, BlockAddress);
} while ((LockStatus & P30_SR_BIT_WRITE) != P30_SR_BIT_WRITE);
}
// Put device back into Read Array mode
SEND_NOR_COMMAND (BlockAddress, 0, P30_CMD_READ_ARRAY);
@@ -205,6 +224,9 @@ NorFlashWriteSingleWord (
SEND_NOR_COMMAND (Instance->DeviceBaseAddress, 0, P30_CMD_CLEAR_STATUS_REGISTER);
}
// Put device back into Read Array mode
SEND_NOR_COMMAND (Instance->DeviceBaseAddress, 0, P30_CMD_READ_ARRAY);
return Status;
}
@@ -283,7 +305,8 @@ NorFlashWriteBuffer (
// The buffer was not available for writing
if (WaitForBuffer == 0) {
return EFI_DEVICE_ERROR;
Status = EFI_DEVICE_ERROR;
goto EXIT;
}
// From now on we work in 32-bit words
@@ -333,6 +356,10 @@ NorFlashWriteBuffer (
SEND_NOR_COMMAND (Instance->DeviceBaseAddress, 0, P30_CMD_CLEAR_STATUS_REGISTER);
}
EXIT:
// Put device back into Read Array mode
SEND_NOR_COMMAND (Instance->DeviceBaseAddress, 0, P30_CMD_READ_ARRAY);
return Status;
}
@@ -358,6 +385,10 @@ NorFlashWriteBlocks (
return EFI_INVALID_PARAMETER;
}
if (Instance->Media.ReadOnly == TRUE) {
return EFI_WRITE_PROTECTED;
}
// We must have some bytes to read
DEBUG ((DEBUG_BLKIO, "NorFlashWriteBlocks: BufferSizeInBytes=0x%x\n", BufferSizeInBytes));
if (BufferSizeInBytes == 0) {
@@ -365,22 +396,22 @@ NorFlashWriteBlocks (
}
// The size of the buffer must be a multiple of the block size
DEBUG ((DEBUG_BLKIO, "NorFlashWriteBlocks: BlockSize in bytes =0x%x\n", Instance->BlockSize));
if ((BufferSizeInBytes % Instance->BlockSize) != 0) {
DEBUG ((DEBUG_BLKIO, "NorFlashWriteBlocks: BlockSize in bytes =0x%x\n", Instance->Media.BlockSize));
if ((BufferSizeInBytes % Instance->Media.BlockSize) != 0) {
return EFI_BAD_BUFFER_SIZE;
}
// All blocks must be within the device
NumBlocks = ((UINT32)BufferSizeInBytes) / Instance->BlockSize;
NumBlocks = ((UINT32)BufferSizeInBytes) / Instance->Media.BlockSize;
DEBUG ((DEBUG_BLKIO, "NorFlashWriteBlocks: NumBlocks=%d, LastBlock=%ld, Lba=%ld.\n", NumBlocks, Instance->LastBlock, Lba));
DEBUG ((DEBUG_BLKIO, "NorFlashWriteBlocks: NumBlocks=%d, LastBlock=%ld, Lba=%ld.\n", NumBlocks, Instance->Media.LastBlock, Lba));
if ((Lba + NumBlocks) > (Instance->LastBlock + 1)) {
if ((Lba + NumBlocks) > (Instance->Media.LastBlock + 1)) {
DEBUG ((DEBUG_ERROR, "NorFlashWriteBlocks: ERROR - Write will exceed last block.\n"));
return EFI_INVALID_PARAMETER;
}
BlockSizeInWords = Instance->BlockSize / 4;
BlockSizeInWords = Instance->Media.BlockSize / 4;
// Because the target *Buffer is a pointer to VOID, we must put all the data into a pointer
// to a proper data type, so use *ReadBuffer
@@ -401,6 +432,67 @@ NorFlashWriteBlocks (
return Status;
}
#define BOTH_ALIGNED(a, b, align) ((((UINTN)(a) | (UINTN)(b)) & ((align) - 1)) == 0)
/**
Copy Length bytes from Source to Destination, using aligned accesses only.
Note that this implementation uses memcpy() semantics rather then memmove()
semantics, i.e., SourceBuffer and DestinationBuffer should not overlap.
@param DestinationBuffer The target of the copy request.
@param SourceBuffer The place to copy from.
@param Length The number of bytes to copy.
@return Destination
**/
STATIC
VOID *
AlignedCopyMem (
OUT VOID *DestinationBuffer,
IN CONST VOID *SourceBuffer,
IN UINTN Length
)
{
UINT8 *Destination8;
CONST UINT8 *Source8;
UINT32 *Destination32;
CONST UINT32 *Source32;
UINT64 *Destination64;
CONST UINT64 *Source64;
if (BOTH_ALIGNED (DestinationBuffer, SourceBuffer, 8) && (Length >= 8)) {
Destination64 = DestinationBuffer;
Source64 = SourceBuffer;
while (Length >= 8) {
*Destination64++ = *Source64++;
Length -= 8;
}
Destination8 = (UINT8 *)Destination64;
Source8 = (CONST UINT8 *)Source64;
} else if (BOTH_ALIGNED (DestinationBuffer, SourceBuffer, 4) && (Length >= 4)) {
Destination32 = DestinationBuffer;
Source32 = SourceBuffer;
while (Length >= 4) {
*Destination32++ = *Source32++;
Length -= 4;
}
Destination8 = (UINT8 *)Destination32;
Source8 = (CONST UINT8 *)Source32;
} else {
Destination8 = DestinationBuffer;
Source8 = SourceBuffer;
}
while (Length-- != 0) {
*Destination8++ = *Source8++;
}
return DestinationBuffer;
}
EFI_STATUS
NorFlashReadBlocks (
IN NOR_FLASH_INSTANCE *Instance,
@@ -416,8 +508,8 @@ NorFlashReadBlocks (
DEBUG_BLKIO,
"NorFlashReadBlocks: BufferSize=0x%xB BlockSize=0x%xB LastBlock=%ld, Lba=%ld.\n",
BufferSizeInBytes,
Instance->BlockSize,
Instance->LastBlock,
Instance->Media.BlockSize,
Instance->Media.LastBlock,
Lba
));
@@ -432,14 +524,14 @@ NorFlashReadBlocks (
}
// The size of the buffer must be a multiple of the block size
if ((BufferSizeInBytes % Instance->BlockSize) != 0) {
if ((BufferSizeInBytes % Instance->Media.BlockSize) != 0) {
return EFI_BAD_BUFFER_SIZE;
}
// All blocks must be within the device
NumBlocks = ((UINT32)BufferSizeInBytes) / Instance->BlockSize;
NumBlocks = ((UINT32)BufferSizeInBytes) / Instance->Media.BlockSize;
if ((Lba + NumBlocks) > (Instance->LastBlock + 1)) {
if ((Lba + NumBlocks) > (Instance->Media.LastBlock + 1)) {
DEBUG ((DEBUG_ERROR, "NorFlashReadBlocks: ERROR - Read will exceed last block\n"));
return EFI_INVALID_PARAMETER;
}
@@ -448,14 +540,14 @@ NorFlashReadBlocks (
StartAddress = GET_NOR_BLOCK_ADDRESS (
Instance->RegionBaseAddress,
Lba,
Instance->BlockSize
Instance->Media.BlockSize
);
// Put the device into Read Array mode
SEND_NOR_COMMAND (Instance->DeviceBaseAddress, 0, P30_CMD_READ_ARRAY);
// Readout the data
CopyMem (Buffer, (VOID *)StartAddress, BufferSizeInBytes);
AlignedCopyMem (Buffer, (VOID *)StartAddress, BufferSizeInBytes);
return EFI_SUCCESS;
}
@@ -481,7 +573,7 @@ NorFlashRead (
return EFI_SUCCESS;
}
if (((Lba * Instance->BlockSize) + Offset + BufferSizeInBytes) > Instance->Size) {
if (((Lba * Instance->Media.BlockSize) + Offset + BufferSizeInBytes) > Instance->Size) {
DEBUG ((DEBUG_ERROR, "NorFlashRead: ERROR - Read will exceed device size.\n"));
return EFI_INVALID_PARAMETER;
}
@@ -490,21 +582,21 @@ NorFlashRead (
StartAddress = GET_NOR_BLOCK_ADDRESS (
Instance->RegionBaseAddress,
Lba,
Instance->BlockSize
Instance->Media.BlockSize
);
// Put the device into Read Array mode
SEND_NOR_COMMAND (Instance->DeviceBaseAddress, 0, P30_CMD_READ_ARRAY);
// Readout the data
CopyMem (Buffer, (VOID *)(StartAddress + Offset), BufferSizeInBytes);
AlignedCopyMem (Buffer, (VOID *)(StartAddress + Offset), BufferSizeInBytes);
return EFI_SUCCESS;
}
/*
Write a full or portion of a block. It must not span block boundaries; that is,
Offset + *NumBytes <= Instance->BlockSize.
Offset + *NumBytes <= Instance->Media.BlockSize.
*/
EFI_STATUS
NorFlashWriteSingleBlock (
@@ -515,22 +607,32 @@ NorFlashWriteSingleBlock (
IN UINT8 *Buffer
)
{
EFI_STATUS Status;
EFI_STATUS TempStatus;
UINT32 Tmp;
UINT32 TmpBuf;
UINT32 WordToWrite;
UINT32 Mask;
BOOLEAN DoErase;
UINTN BytesToWrite;
UINTN CurOffset;
UINTN WordAddr;
UINTN BlockSize;
UINTN BlockAddress;
UINT8 *OrigData;
UINTN PrevBlockAddress;
PrevBlockAddress = 0;
DEBUG ((DEBUG_BLKIO, "NorFlashWriteSingleBlock(Parameters: Lba=%ld, Offset=0x%x, *NumBytes=0x%x, Buffer @ 0x%08x)\n", Lba, Offset, *NumBytes, Buffer));
// Check we did get some memory. Buffer is BlockSize.
if (Instance->ShadowBuffer == NULL) {
DEBUG ((DEBUG_ERROR, "FvbWrite: ERROR - Buffer not ready\n"));
return EFI_DEVICE_ERROR;
// Detect WriteDisabled state
if (Instance->Media.ReadOnly == TRUE) {
DEBUG ((DEBUG_ERROR, "NorFlashWriteSingleBlock: ERROR - Can not write: Device is in WriteDisabled state.\n"));
// It is in WriteDisabled state, return an error right away
return EFI_ACCESS_DENIED;
}
// Cache the block size to avoid de-referencing pointers all the time
BlockSize = Instance->BlockSize;
BlockSize = Instance->Media.BlockSize;
// The write must not span block boundaries.
// We need to check each variable individually because adding two large values together overflows.
@@ -548,89 +650,146 @@ NorFlashWriteSingleBlock (
return EFI_BAD_BUFFER_SIZE;
}
// Pick P30_MAX_BUFFER_SIZE_IN_BYTES (== 128 bytes) as a good start for word
// operations as opposed to erasing the block and writing the data regardless
// if an erase is really needed. It looks like most individual NV variable
// writes are smaller than 128 bytes.
// To avoid pathological cases were a 2 byte write is disregarded because it
// occurs right at a 128 byte buffered write alignment boundary, permit up to
// twice the max buffer size, and perform two writes if needed.
if ((*NumBytes + (Offset & BOUNDARY_OF_32_WORDS)) <= (2 * P30_MAX_BUFFER_SIZE_IN_BYTES)) {
// Pick 128bytes as a good start for word operations as opposed to erasing the
// block and writing the data regardless if an erase is really needed.
// It looks like most individual NV variable writes are smaller than 128bytes.
if (*NumBytes <= 128) {
// Check to see if we need to erase before programming the data into NOR.
// If the destination bits are only changing from 1s to 0s we can just write.
// After a block is erased all bits in the block is set to 1.
// If any byte requires us to erase we just give up and rewrite all of it.
DoErase = FALSE;
BytesToWrite = *NumBytes;
CurOffset = Offset;
// Read the old version of the data into the shadow buffer
Status = NorFlashRead (
Instance,
Lba,
Offset & ~BOUNDARY_OF_32_WORDS,
(*NumBytes | BOUNDARY_OF_32_WORDS) + 1,
Instance->ShadowBuffer
);
if (EFI_ERROR (Status)) {
return EFI_DEVICE_ERROR;
}
// Make OrigData point to the start of the old version of the data inside
// the word aligned buffer
OrigData = Instance->ShadowBuffer + (Offset & BOUNDARY_OF_32_WORDS);
// Update the buffer containing the old version of the data with the new
// contents, while checking whether the old version had any bits cleared
// that we want to set. In that case, we will need to erase the block first.
for (CurOffset = 0; CurOffset < *NumBytes; CurOffset++) {
if (~OrigData[CurOffset] & Buffer[CurOffset]) {
goto DoErase;
while (BytesToWrite > 0) {
// Read full word from NOR, splice as required. A word is the smallest
// unit we can write.
TempStatus = NorFlashRead (Instance, Lba, CurOffset & ~(0x3), sizeof (Tmp), &Tmp);
if (EFI_ERROR (TempStatus)) {
return EFI_DEVICE_ERROR;
}
OrigData[CurOffset] = Buffer[CurOffset];
// Physical address of word in NOR to write.
WordAddr = (CurOffset & ~(0x3)) + GET_NOR_BLOCK_ADDRESS (
Instance->RegionBaseAddress,
Lba,
BlockSize
);
// The word of data that is to be written.
TmpBuf = *((UINT32 *)(Buffer + (*NumBytes - BytesToWrite)));
// First do word aligned chunks.
if ((CurOffset & 0x3) == 0) {
if (BytesToWrite >= 4) {
// Is the destination still in 'erased' state?
if (~Tmp != 0) {
// Check to see if we are only changing bits to zero.
if ((Tmp ^ TmpBuf) & TmpBuf) {
DoErase = TRUE;
break;
}
}
// Write this word to NOR
WordToWrite = TmpBuf;
CurOffset += sizeof (TmpBuf);
BytesToWrite -= sizeof (TmpBuf);
} else {
// BytesToWrite < 4. Do small writes and left-overs
Mask = ~((~0) << (BytesToWrite * 8));
// Mask out the bytes we want.
TmpBuf &= Mask;
// Is the destination still in 'erased' state?
if ((Tmp & Mask) != Mask) {
// Check to see if we are only changing bits to zero.
if ((Tmp ^ TmpBuf) & TmpBuf) {
DoErase = TRUE;
break;
}
}
// Merge old and new data. Write merged word to NOR
WordToWrite = (Tmp & ~Mask) | TmpBuf;
CurOffset += BytesToWrite;
BytesToWrite = 0;
}
} else {
// Do multiple words, but starting unaligned.
if (BytesToWrite > (4 - (CurOffset & 0x3))) {
Mask = ((~0) << ((CurOffset & 0x3) * 8));
// Mask out the bytes we want.
TmpBuf &= Mask;
// Is the destination still in 'erased' state?
if ((Tmp & Mask) != Mask) {
// Check to see if we are only changing bits to zero.
if ((Tmp ^ TmpBuf) & TmpBuf) {
DoErase = TRUE;
break;
}
}
// Merge old and new data. Write merged word to NOR
WordToWrite = (Tmp & ~Mask) | TmpBuf;
BytesToWrite -= (4 - (CurOffset & 0x3));
CurOffset += (4 - (CurOffset & 0x3));
} else {
// Unaligned and fits in one word.
Mask = (~((~0) << (BytesToWrite * 8))) << ((CurOffset & 0x3) * 8);
// Mask out the bytes we want.
TmpBuf = (TmpBuf << ((CurOffset & 0x3) * 8)) & Mask;
// Is the destination still in 'erased' state?
if ((Tmp & Mask) != Mask) {
// Check to see if we are only changing bits to zero.
if ((Tmp ^ TmpBuf) & TmpBuf) {
DoErase = TRUE;
break;
}
}
// Merge old and new data. Write merged word to NOR
WordToWrite = (Tmp & ~Mask) | TmpBuf;
CurOffset += BytesToWrite;
BytesToWrite = 0;
}
}
//
// Write the word to NOR.
//
BlockAddress = GET_NOR_BLOCK_ADDRESS (Instance->RegionBaseAddress, Lba, BlockSize);
if (BlockAddress != PrevBlockAddress) {
TempStatus = NorFlashUnlockSingleBlockIfNecessary (Instance, BlockAddress);
if (EFI_ERROR (TempStatus)) {
return EFI_DEVICE_ERROR;
}
PrevBlockAddress = BlockAddress;
}
TempStatus = NorFlashWriteSingleWord (Instance, WordAddr, WordToWrite);
if (EFI_ERROR (TempStatus)) {
return EFI_DEVICE_ERROR;
}
}
//
// Write the updated buffer to NOR.
//
BlockAddress = GET_NOR_BLOCK_ADDRESS (Instance->RegionBaseAddress, Lba, BlockSize);
// Unlock the block if we have to
Status = NorFlashUnlockSingleBlockIfNecessary (Instance, BlockAddress);
if (EFI_ERROR (Status)) {
goto Exit;
// Exit if we got here and could write all the data. Otherwise do the
// Erase-Write cycle.
if (!DoErase) {
return EFI_SUCCESS;
}
Status = NorFlashWriteBuffer (
Instance,
BlockAddress + (Offset & ~BOUNDARY_OF_32_WORDS),
P30_MAX_BUFFER_SIZE_IN_BYTES,
Instance->ShadowBuffer
);
if (EFI_ERROR (Status)) {
goto Exit;
}
if ((*NumBytes + (Offset & BOUNDARY_OF_32_WORDS)) > P30_MAX_BUFFER_SIZE_IN_BYTES) {
BlockAddress += P30_MAX_BUFFER_SIZE_IN_BYTES;
Status = NorFlashWriteBuffer (
Instance,
BlockAddress + (Offset & ~BOUNDARY_OF_32_WORDS),
P30_MAX_BUFFER_SIZE_IN_BYTES,
Instance->ShadowBuffer + P30_MAX_BUFFER_SIZE_IN_BYTES
);
}
Exit:
// Put device back into Read Array mode
SEND_NOR_COMMAND (Instance->DeviceBaseAddress, 0, P30_CMD_READ_ARRAY);
return Status;
}
DoErase:
// Check we did get some memory. Buffer is BlockSize.
if (Instance->ShadowBuffer == NULL) {
DEBUG ((DEBUG_ERROR, "FvbWrite: ERROR - Buffer not ready\n"));
return EFI_DEVICE_ERROR;
}
// Read NOR Flash data into shadow buffer
Status = NorFlashReadBlocks (Instance, Lba, BlockSize, Instance->ShadowBuffer);
if (EFI_ERROR (Status)) {
TempStatus = NorFlashReadBlocks (Instance, Lba, BlockSize, Instance->ShadowBuffer);
if (EFI_ERROR (TempStatus)) {
// Return one of the pre-approved error statuses
return EFI_DEVICE_ERROR;
}
@@ -639,8 +798,8 @@ DoErase:
CopyMem ((VOID *)((UINTN)Instance->ShadowBuffer + Offset), Buffer, *NumBytes);
// Write the modified buffer back to the NorFlash
Status = NorFlashWriteBlocks (Instance, Lba, BlockSize, Instance->ShadowBuffer);
if (EFI_ERROR (Status)) {
TempStatus = NorFlashWriteBlocks (Instance, Lba, BlockSize, Instance->ShadowBuffer);
if (EFI_ERROR (TempStatus)) {
// Return one of the pre-approved error statuses
return EFI_DEVICE_ERROR;
}
@@ -648,6 +807,135 @@ DoErase:
return EFI_SUCCESS;
}
/*
Although DiskIoDxe will automatically install the DiskIO protocol whenever
we install the BlockIO protocol, its implementation is sub-optimal as it reads
and writes entire blocks using the BlockIO protocol. In fact we can access
NOR flash with a finer granularity than that, so we can improve performance
by directly producing the DiskIO protocol.
*/
/**
Read BufferSize bytes from Offset into Buffer.
@param This Protocol instance pointer.
@param MediaId Id of the media, changes every time the media is replaced.
@param Offset The starting byte offset to read from
@param BufferSize Size of Buffer
@param Buffer Buffer containing read data
@retval EFI_SUCCESS The data was read correctly from the device.
@retval EFI_DEVICE_ERROR The device reported an error while performing the read.
@retval EFI_NO_MEDIA There is no media in the device.
@retval EFI_MEDIA_CHANGED The MediaId does not match the current device.
@retval EFI_INVALID_PARAMETER The read request contains device addresses that are not
valid for the device.
**/
EFI_STATUS
EFIAPI
NorFlashDiskIoReadDisk (
IN EFI_DISK_IO_PROTOCOL *This,
IN UINT32 MediaId,
IN UINT64 DiskOffset,
IN UINTN BufferSize,
OUT VOID *Buffer
)
{
NOR_FLASH_INSTANCE *Instance;
UINT32 BlockSize;
UINT32 BlockOffset;
EFI_LBA Lba;
Instance = INSTANCE_FROM_DISKIO_THIS (This);
if (MediaId != Instance->Media.MediaId) {
return EFI_MEDIA_CHANGED;
}
BlockSize = Instance->Media.BlockSize;
Lba = (EFI_LBA)DivU64x32Remainder (DiskOffset, BlockSize, &BlockOffset);
return NorFlashRead (Instance, Lba, BlockOffset, BufferSize, Buffer);
}
/**
Writes a specified number of bytes to a device.
@param This Indicates a pointer to the calling context.
@param MediaId ID of the medium to be written.
@param Offset The starting byte offset on the logical block I/O device to write.
@param BufferSize The size in bytes of Buffer. The number of bytes to write to the device.
@param Buffer A pointer to the buffer containing the data to be written.
@retval EFI_SUCCESS The data was written correctly to the device.
@retval EFI_WRITE_PROTECTED The device can not be written to.
@retval EFI_DEVICE_ERROR The device reported an error while performing the write.
@retval EFI_NO_MEDIA There is no media in the device.
@retval EFI_MEDIA_CHANGED The MediaId does not match the current device.
@retval EFI_INVALID_PARAMETER The write request contains device addresses that are not
valid for the device.
**/
EFI_STATUS
EFIAPI
NorFlashDiskIoWriteDisk (
IN EFI_DISK_IO_PROTOCOL *This,
IN UINT32 MediaId,
IN UINT64 DiskOffset,
IN UINTN BufferSize,
IN VOID *Buffer
)
{
NOR_FLASH_INSTANCE *Instance;
UINT32 BlockSize;
UINT32 BlockOffset;
EFI_LBA Lba;
UINTN RemainingBytes;
UINTN WriteSize;
EFI_STATUS Status;
Instance = INSTANCE_FROM_DISKIO_THIS (This);
if (MediaId != Instance->Media.MediaId) {
return EFI_MEDIA_CHANGED;
}
BlockSize = Instance->Media.BlockSize;
Lba = (EFI_LBA)DivU64x32Remainder (DiskOffset, BlockSize, &BlockOffset);
RemainingBytes = BufferSize;
// Write either all the remaining bytes, or the number of bytes that bring
// us up to a block boundary, whichever is less.
// (DiskOffset | (BlockSize - 1)) + 1) rounds DiskOffset up to the next
// block boundary (even if it is already on one).
WriteSize = MIN (RemainingBytes, ((DiskOffset | (BlockSize - 1)) + 1) - DiskOffset);
do {
if (WriteSize == BlockSize) {
// Write a full block
Status = NorFlashWriteFullBlock (Instance, Lba, Buffer, BlockSize / sizeof (UINT32));
} else {
// Write a partial block
Status = NorFlashWriteSingleBlock (Instance, Lba, BlockOffset, &WriteSize, Buffer);
}
if (EFI_ERROR (Status)) {
return Status;
}
// Now continue writing either all the remaining bytes or single blocks.
RemainingBytes -= WriteSize;
Buffer = (UINT8 *)Buffer + WriteSize;
Lba++;
BlockOffset = 0;
WriteSize = MIN (RemainingBytes, BlockSize);
} while (RemainingBytes);
return Status;
}
EFI_STATUS
NorFlashReset (
IN NOR_FLASH_INSTANCE *Instance
@@ -679,6 +967,12 @@ NorFlashVirtualNotifyEvent (
EfiConvertPointer (0x0, (VOID **)&mNorFlashInstances[Index]->DeviceBaseAddress);
EfiConvertPointer (0x0, (VOID **)&mNorFlashInstances[Index]->RegionBaseAddress);
// Convert BlockIo protocol
EfiConvertPointer (0x0, (VOID **)&mNorFlashInstances[Index]->BlockIoProtocol.FlushBlocks);
EfiConvertPointer (0x0, (VOID **)&mNorFlashInstances[Index]->BlockIoProtocol.ReadBlocks);
EfiConvertPointer (0x0, (VOID **)&mNorFlashInstances[Index]->BlockIoProtocol.Reset);
EfiConvertPointer (0x0, (VOID **)&mNorFlashInstances[Index]->BlockIoProtocol.WriteBlocks);
// Convert Fvb
EfiConvertPointer (0x0, (VOID **)&mNorFlashInstances[Index]->FvbProtocol.EraseBlocks);
EfiConvertPointer (0x0, (VOID **)&mNorFlashInstances[Index]->FvbProtocol.GetAttributes);

View File

@@ -6,21 +6,23 @@
**/
#ifndef __VIRT_NOR_FLASH__
#define __VIRT_NOR_FLASH__
#ifndef __NOR_FLASH_H__
#define __NOR_FLASH_H__
#include <Base.h>
#include <PiDxe.h>
#include <Guid/EventGroup.h>
#include <Protocol/BlockIo.h>
#include <Protocol/DiskIo.h>
#include <Protocol/FirmwareVolumeBlock.h>
#include <Library/DebugLib.h>
#include <Library/IoLib.h>
#include <Library/NorFlashPlatformLib.h>
#include <Library/UefiLib.h>
#include <Library/UefiRuntimeLib.h>
#include <Library/VirtNorFlashPlatformLib.h>
#define NOR_FLASH_ERASE_RETRY 10
@@ -107,7 +109,9 @@
#define P30_CMD_READ_CONFIGURATION_REGISTER 0x0003
#define NOR_FLASH_SIGNATURE SIGNATURE_32('n', 'o', 'r', '0')
#define INSTANCE_FROM_FVB_THIS(a) CR(a, NOR_FLASH_INSTANCE, FvbProtocol, NOR_FLASH_SIGNATURE)
#define INSTANCE_FROM_FVB_THIS(a) CR(a, NOR_FLASH_INSTANCE, FvbProtocol, NOR_FLASH_SIGNATURE)
#define INSTANCE_FROM_BLKIO_THIS(a) CR(a, NOR_FLASH_INSTANCE, BlockIoProtocol, NOR_FLASH_SIGNATURE)
#define INSTANCE_FROM_DISKIO_THIS(a) CR(a, NOR_FLASH_INSTANCE, DiskIoProtocol, NOR_FLASH_SIGNATURE)
typedef struct _NOR_FLASH_INSTANCE NOR_FLASH_INSTANCE;
@@ -127,8 +131,10 @@ struct _NOR_FLASH_INSTANCE {
UINTN RegionBaseAddress;
UINTN Size;
EFI_LBA StartLba;
EFI_LBA LastBlock;
UINT32 BlockSize;
EFI_BLOCK_IO_PROTOCOL BlockIoProtocol;
EFI_BLOCK_IO_MEDIA Media;
EFI_DISK_IO_PROTOCOL DiskIoProtocol;
EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL FvbProtocol;
VOID *ShadowBuffer;
@@ -152,6 +158,77 @@ NorFlashWriteBuffer (
IN UINT32 *Buffer
);
//
// BlockIO Protocol function EFI_BLOCK_IO_PROTOCOL.Reset
//
EFI_STATUS
EFIAPI
NorFlashBlockIoReset (
IN EFI_BLOCK_IO_PROTOCOL *This,
IN BOOLEAN ExtendedVerification
);
//
// BlockIO Protocol function EFI_BLOCK_IO_PROTOCOL.ReadBlocks
//
EFI_STATUS
EFIAPI
NorFlashBlockIoReadBlocks (
IN EFI_BLOCK_IO_PROTOCOL *This,
IN UINT32 MediaId,
IN EFI_LBA Lba,
IN UINTN BufferSizeInBytes,
OUT VOID *Buffer
);
//
// BlockIO Protocol function EFI_BLOCK_IO_PROTOCOL.WriteBlocks
//
EFI_STATUS
EFIAPI
NorFlashBlockIoWriteBlocks (
IN EFI_BLOCK_IO_PROTOCOL *This,
IN UINT32 MediaId,
IN EFI_LBA Lba,
IN UINTN BufferSizeInBytes,
IN VOID *Buffer
);
//
// BlockIO Protocol function EFI_BLOCK_IO_PROTOCOL.FlushBlocks
//
EFI_STATUS
EFIAPI
NorFlashBlockIoFlushBlocks (
IN EFI_BLOCK_IO_PROTOCOL *This
);
//
// DiskIO Protocol function EFI_DISK_IO_PROTOCOL.ReadDisk
//
EFI_STATUS
EFIAPI
NorFlashDiskIoReadDisk (
IN EFI_DISK_IO_PROTOCOL *This,
IN UINT32 MediaId,
IN UINT64 Offset,
IN UINTN BufferSize,
OUT VOID *Buffer
);
//
// DiskIO Protocol function EFI_DISK_IO_PROTOCOL.WriteDisk
//
EFI_STATUS
EFIAPI
NorFlashDiskIoWriteDisk (
IN EFI_DISK_IO_PROTOCOL *This,
IN UINT32 MediaId,
IN UINT64 Offset,
IN UINTN BufferSize,
IN VOID *Buffer
);
//
// NorFlashFvbDxe.c
//
@@ -342,4 +419,4 @@ NorFlashVirtualNotifyEvent (
IN VOID *Context
);
#endif /* __VIRT_NOR_FLASH__ */
#endif /* __NOR_FLASH_H__ */

View File

@@ -0,0 +1,123 @@
/** @file NorFlashBlockIoDxe.c
Copyright (c) 2011-2013, ARM Ltd. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include <Library/BaseMemoryLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include "NorFlash.h"
//
// BlockIO Protocol function EFI_BLOCK_IO_PROTOCOL.Reset
//
EFI_STATUS
EFIAPI
NorFlashBlockIoReset (
IN EFI_BLOCK_IO_PROTOCOL *This,
IN BOOLEAN ExtendedVerification
)
{
NOR_FLASH_INSTANCE *Instance;
Instance = INSTANCE_FROM_BLKIO_THIS (This);
DEBUG ((DEBUG_BLKIO, "NorFlashBlockIoReset(MediaId=0x%x)\n", This->Media->MediaId));
return NorFlashReset (Instance);
}
//
// BlockIO Protocol function EFI_BLOCK_IO_PROTOCOL.ReadBlocks
//
EFI_STATUS
EFIAPI
NorFlashBlockIoReadBlocks (
IN EFI_BLOCK_IO_PROTOCOL *This,
IN UINT32 MediaId,
IN EFI_LBA Lba,
IN UINTN BufferSizeInBytes,
OUT VOID *Buffer
)
{
NOR_FLASH_INSTANCE *Instance;
EFI_STATUS Status;
EFI_BLOCK_IO_MEDIA *Media;
if (This == NULL) {
return EFI_INVALID_PARAMETER;
}
Instance = INSTANCE_FROM_BLKIO_THIS (This);
Media = This->Media;
DEBUG ((DEBUG_BLKIO, "NorFlashBlockIoReadBlocks(MediaId=0x%x, Lba=%ld, BufferSize=0x%x bytes (%d kB), BufferPtr @ 0x%08x)\n", MediaId, Lba, BufferSizeInBytes, Buffer));
if (!Media) {
Status = EFI_INVALID_PARAMETER;
} else if (!Media->MediaPresent) {
Status = EFI_NO_MEDIA;
} else if (Media->MediaId != MediaId) {
Status = EFI_MEDIA_CHANGED;
} else if ((Media->IoAlign > 2) && (((UINTN)Buffer & (Media->IoAlign - 1)) != 0)) {
Status = EFI_INVALID_PARAMETER;
} else {
Status = NorFlashReadBlocks (Instance, Lba, BufferSizeInBytes, Buffer);
}
return Status;
}
//
// BlockIO Protocol function EFI_BLOCK_IO_PROTOCOL.WriteBlocks
//
EFI_STATUS
EFIAPI
NorFlashBlockIoWriteBlocks (
IN EFI_BLOCK_IO_PROTOCOL *This,
IN UINT32 MediaId,
IN EFI_LBA Lba,
IN UINTN BufferSizeInBytes,
IN VOID *Buffer
)
{
NOR_FLASH_INSTANCE *Instance;
EFI_STATUS Status;
Instance = INSTANCE_FROM_BLKIO_THIS (This);
DEBUG ((DEBUG_BLKIO, "NorFlashBlockIoWriteBlocks(MediaId=0x%x, Lba=%ld, BufferSize=0x%x bytes (%d kB), BufferPtr @ 0x%08x)\n", MediaId, Lba, BufferSizeInBytes, Buffer));
if ( !This->Media->MediaPresent ) {
Status = EFI_NO_MEDIA;
} else if ( This->Media->MediaId != MediaId ) {
Status = EFI_MEDIA_CHANGED;
} else if ( This->Media->ReadOnly ) {
Status = EFI_WRITE_PROTECTED;
} else {
Status = NorFlashWriteBlocks (Instance, Lba, BufferSizeInBytes, Buffer);
}
return Status;
}
//
// BlockIO Protocol function EFI_BLOCK_IO_PROTOCOL.FlushBlocks
//
EFI_STATUS
EFIAPI
NorFlashBlockIoFlushBlocks (
IN EFI_BLOCK_IO_PROTOCOL *This
)
{
// No Flush required for the NOR Flash driver
// because cache operations are not permitted.
DEBUG ((DEBUG_BLKIO, "NorFlashBlockIoFlushBlocks: Function NOT IMPLEMENTED (not required).\n"));
// Nothing to do so just return without error
return EFI_SUCCESS;
}

View File

@@ -6,15 +6,15 @@
**/
#include <Library/BaseMemoryLib.h>
#include <Library/DxeServicesTableLib.h>
#include <Library/HobLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/PcdLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/PcdLib.h>
#include <Library/HobLib.h>
#include <Library/DxeServicesTableLib.h>
#include "VirtNorFlash.h"
#include "NorFlash.h"
STATIC EFI_EVENT mNorFlashVirtualAddrChangeEvent;
@@ -34,8 +34,35 @@ NOR_FLASH_INSTANCE mNorFlashInstanceTemplate = {
0, // RegionBaseAddress ... NEED TO BE FILLED
0, // Size ... NEED TO BE FILLED
0, // StartLba
0, // LastBlock
0, // BlockSize
{
EFI_BLOCK_IO_PROTOCOL_REVISION2, // Revision
NULL, // Media ... NEED TO BE FILLED
NorFlashBlockIoReset, // Reset;
NorFlashBlockIoReadBlocks, // ReadBlocks
NorFlashBlockIoWriteBlocks, // WriteBlocks
NorFlashBlockIoFlushBlocks // FlushBlocks
}, // BlockIoProtocol
{
0, // MediaId ... NEED TO BE FILLED
FALSE, // RemovableMedia
TRUE, // MediaPresent
FALSE, // LogicalPartition
FALSE, // ReadOnly
FALSE, // WriteCaching;
0, // BlockSize ... NEED TO BE FILLED
4, // IoAlign
0, // LastBlock ... NEED TO BE FILLED
0, // LowestAlignedLba
1, // LogicalBlocksPerPhysicalBlock
}, // Media;
{
EFI_DISK_IO_PROTOCOL_REVISION, // Revision
NorFlashDiskIoReadDisk, // ReadDisk
NorFlashDiskIoWriteDisk // WriteDisk
},
{
FvbGetAttributes, // GetAttributes
@@ -94,8 +121,11 @@ NorFlashCreateInstance (
Instance->DeviceBaseAddress = NorFlashDeviceBase;
Instance->RegionBaseAddress = NorFlashRegionBase;
Instance->Size = NorFlashSize;
Instance->BlockSize = BlockSize;
Instance->LastBlock = (NorFlashSize / BlockSize) - 1;
Instance->BlockIoProtocol.Media = &Instance->Media;
Instance->Media.MediaId = Index;
Instance->Media.BlockSize = BlockSize;
Instance->Media.LastBlock = (NorFlashSize / BlockSize)-1;
CopyGuid (&Instance->DevicePath.Vendor.Guid, &gEfiCallerIdGuid);
Instance->DevicePath.Index = (UINT8)Index;
@@ -112,6 +142,8 @@ NorFlashCreateInstance (
&Instance->Handle,
&gEfiDevicePathProtocolGuid,
&Instance->DevicePath,
&gEfiBlockIoProtocolGuid,
&Instance->BlockIoProtocol,
&gEfiFirmwareVolumeBlockProtocolGuid,
&Instance->FvbProtocol,
NULL
@@ -125,6 +157,10 @@ NorFlashCreateInstance (
&Instance->Handle,
&gEfiDevicePathProtocolGuid,
&Instance->DevicePath,
&gEfiBlockIoProtocolGuid,
&Instance->BlockIoProtocol,
&gEfiDiskIoProtocolGuid,
&Instance->DiskIoProtocol,
NULL
);
if (EFI_ERROR (Status)) {
@@ -280,9 +316,6 @@ NorFlashWriteFullBlock (
}
EXIT:
// Put device back into Read Array mode
SEND_NOR_COMMAND (Instance->DeviceBaseAddress, 0, P30_CMD_READ_ARRAY);
if (!EfiAtRuntime ()) {
// Interruptions can resume.
gBS->RestoreTPL (OriginalTPL);
@@ -302,18 +335,18 @@ NorFlashInitialise (
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EFI_STATUS Status;
UINT32 Index;
VIRT_NOR_FLASH_DESCRIPTION *NorFlashDevices;
BOOLEAN ContainVariableStorage;
EFI_STATUS Status;
UINT32 Index;
NOR_FLASH_DESCRIPTION *NorFlashDevices;
BOOLEAN ContainVariableStorage;
Status = VirtNorFlashPlatformInitialization ();
Status = NorFlashPlatformInitialization ();
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "NorFlashInitialise: Fail to initialize Nor Flash devices\n"));
return Status;
}
Status = VirtNorFlashPlatformGetDevices (&NorFlashDevices, &mNorFlashDeviceCount);
Status = NorFlashPlatformGetDevices (&NorFlashDevices, &mNorFlashDeviceCount);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "NorFlashInitialise: Fail to get Nor Flash devices\n"));
return Status;
@@ -409,7 +442,7 @@ NorFlashFvbInitialize (
PcdGet64 (PcdFlashNvStorageVariableBase64) : PcdGet32 (PcdFlashNvStorageVariableBase);
// Set the index of the first LBA for the FVB
Instance->StartLba = (mFlashNvStorageVariableBase - Instance->RegionBaseAddress) / Instance->BlockSize;
Instance->StartLba = (mFlashNvStorageVariableBase - Instance->RegionBaseAddress) / Instance->Media.BlockSize;
BootMode = GetBootModeHob ();
if (BootMode == BOOT_WITH_DEFAULT_SETTINGS) {
@@ -430,7 +463,7 @@ NorFlashFvbInitialize (
));
// Erase all the NorFlash that is reserved for variable storage
FvbNumLba = (PcdGet32 (PcdFlashNvStorageVariableSize) + PcdGet32 (PcdFlashNvStorageFtwWorkingSize) + PcdGet32 (PcdFlashNvStorageFtwSpareSize)) / Instance->BlockSize;
FvbNumLba = (PcdGet32 (PcdFlashNvStorageVariableSize) + PcdGet32 (PcdFlashNvStorageFtwWorkingSize) + PcdGet32 (PcdFlashNvStorageFtwSpareSize)) / Instance->Media.BlockSize;
Status = FvbEraseBlocks (&Instance->FvbProtocol, (EFI_LBA)0, FvbNumLba, EFI_LBA_LIST_TERMINATOR);
if (EFI_ERROR (Status)) {

View File

@@ -9,49 +9,50 @@
#**/
[Defines]
INF_VERSION = 1.29
BASE_NAME = VirtNorFlashDxe
FILE_GUID = e452cabd-5fe1-4d97-8161-e80ed6a409a8
INF_VERSION = 0x00010005
BASE_NAME = ArmVeNorFlashDxe
FILE_GUID = 93E34C7E-B50E-11DF-9223-2443DFD72085
MODULE_TYPE = DXE_RUNTIME_DRIVER
VERSION_STRING = 1.0
ENTRY_POINT = NorFlashInitialise
[Sources.common]
VirtNorFlash.c
VirtNorFlash.h
VirtNorFlashDxe.c
VirtNorFlashFvb.c
NorFlash.c
NorFlash.h
NorFlashDxe.c
NorFlashFvb.c
NorFlashBlockIoDxe.c
[Packages]
EmbeddedPkg/EmbeddedPkg.dec
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
OvmfPkg/OvmfPkg.dec
ArmPlatformPkg/ArmPlatformPkg.dec
EmbeddedPkg/EmbeddedPkg.dec
[LibraryClasses]
IoLib
BaseLib
DebugLib
DxeServicesTableLib
HobLib
IoLib
UefiBootServicesTableLib
UefiDriverEntryPoint
NorFlashPlatformLib
UefiLib
UefiDriverEntryPoint
UefiBootServicesTableLib
UefiRuntimeLib
VirtNorFlashPlatformLib
DxeServicesTableLib
[Guids]
gEdkiiNvVarStoreFormattedGuid ## PRODUCES ## PROTOCOL
gEfiAuthenticatedVariableGuid
gEfiEventVirtualAddressChangeGuid
gEfiSystemNvDataFvGuid
gEfiVariableGuid
gEfiAuthenticatedVariableGuid
gEfiEventVirtualAddressChangeGuid
gEdkiiNvVarStoreFormattedGuid ## PRODUCES ## PROTOCOL
[Protocols]
gEfiBlockIoProtocolGuid
gEfiDevicePathProtocolGuid
gEfiDiskIoProtocolGuid
gEfiFirmwareVolumeBlockProtocolGuid
gEfiDiskIoProtocolGuid
[Pcd.common]
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase64
@@ -64,5 +65,7 @@
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize
gArmPlatformTokenSpaceGuid.PcdNorFlashCheckBlockLocked
[Depex]
gEfiCpuArchProtocolGuid

View File

@@ -8,17 +8,17 @@
#include <PiDxe.h>
#include <Library/PcdLib.h>
#include <Library/BaseLib.h>
#include <Library/UefiLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/PcdLib.h>
#include <Library/UefiLib.h>
#include <Guid/NvVarStoreFormatted.h>
#include <Guid/SystemNvDataGuid.h>
#include <Guid/VariableFormat.h>
#include <Guid/SystemNvDataGuid.h>
#include <Guid/NvVarStoreFormatted.h>
#include "VirtNorFlash.h"
#include "NorFlash.h"
extern UINTN mFlashNvStorageVariableBase;
///
@@ -89,7 +89,7 @@ InitializeFvAndVariableStoreHeaders (
}
// Check if the size of the area is at least one block size
if ((NvStorageVariableSize <= 0) || (NvStorageVariableSize / Instance->BlockSize <= 0)) {
if ((NvStorageVariableSize <= 0) || (NvStorageVariableSize / Instance->Media.BlockSize <= 0)) {
DEBUG ((
DEBUG_ERROR,
"%a: NvStorageVariableSize is 0x%x, should be atleast one block size\n",
@@ -99,7 +99,7 @@ InitializeFvAndVariableStoreHeaders (
return EFI_INVALID_PARAMETER;
}
if ((NvStorageFtwWorkingSize <= 0) || (NvStorageFtwWorkingSize / Instance->BlockSize <= 0)) {
if ((NvStorageFtwWorkingSize <= 0) || (NvStorageFtwWorkingSize / Instance->Media.BlockSize <= 0)) {
DEBUG ((
DEBUG_ERROR,
"%a: NvStorageFtwWorkingSize is 0x%x, should be atleast one block size\n",
@@ -109,7 +109,7 @@ InitializeFvAndVariableStoreHeaders (
return EFI_INVALID_PARAMETER;
}
if ((NvStorageFtwSpareSize <= 0) || (NvStorageFtwSpareSize / Instance->BlockSize <= 0)) {
if ((NvStorageFtwSpareSize <= 0) || (NvStorageFtwSpareSize / Instance->Media.BlockSize <= 0)) {
DEBUG ((
DEBUG_ERROR,
"%a: NvStorageFtwSpareSize is 0x%x, should be atleast one block size\n",
@@ -120,9 +120,9 @@ InitializeFvAndVariableStoreHeaders (
}
// Ensure the Variable area Base Addresses are aligned on a block size boundaries
if ((NvStorageVariableBase % Instance->BlockSize != 0) ||
(NvStorageFtwWorkingBase % Instance->BlockSize != 0) ||
(NvStorageFtwSpareBase % Instance->BlockSize != 0))
if ((NvStorageVariableBase % Instance->Media.BlockSize != 0) ||
(NvStorageFtwWorkingBase % Instance->Media.BlockSize != 0) ||
(NvStorageFtwSpareBase % Instance->Media.BlockSize != 0))
{
DEBUG ((DEBUG_ERROR, "%a: NvStorage Base addresses must be aligned to block size boundaries", __FUNCTION__));
return EFI_INVALID_PARAMETER;
@@ -149,8 +149,8 @@ InitializeFvAndVariableStoreHeaders (
);
FirmwareVolumeHeader->HeaderLength = sizeof (EFI_FIRMWARE_VOLUME_HEADER) + sizeof (EFI_FV_BLOCK_MAP_ENTRY);
FirmwareVolumeHeader->Revision = EFI_FVH_REVISION;
FirmwareVolumeHeader->BlockMap[0].NumBlocks = Instance->LastBlock + 1;
FirmwareVolumeHeader->BlockMap[0].Length = Instance->BlockSize;
FirmwareVolumeHeader->BlockMap[0].NumBlocks = Instance->Media.LastBlock + 1;
FirmwareVolumeHeader->BlockMap[0].Length = Instance->Media.BlockSize;
FirmwareVolumeHeader->BlockMap[1].NumBlocks = 0;
FirmwareVolumeHeader->BlockMap[1].Length = 0;
FirmwareVolumeHeader->Checksum = CalculateCheckSum16 ((UINT16 *)FirmwareVolumeHeader, FirmwareVolumeHeader->HeaderLength);
@@ -284,6 +284,9 @@ FvbGetAttributes (
)
{
EFI_FVB_ATTRIBUTES_2 FlashFvbAttributes;
NOR_FLASH_INSTANCE *Instance;
Instance = INSTANCE_FROM_FVB_THIS (This);
FlashFvbAttributes = (EFI_FVB_ATTRIBUTES_2)(
@@ -291,12 +294,17 @@ FvbGetAttributes (
EFI_FVB2_READ_STATUS | // Reads are currently enabled
EFI_FVB2_STICKY_WRITE | // A block erase is required to flip bits into EFI_FVB2_ERASE_POLARITY
EFI_FVB2_MEMORY_MAPPED | // It is memory mapped
EFI_FVB2_ERASE_POLARITY | // After erasure all bits take this value (i.e. '1')
EFI_FVB2_WRITE_STATUS | // Writes are currently enabled
EFI_FVB2_WRITE_ENABLED_CAP // Writes may be enabled
EFI_FVB2_ERASE_POLARITY // After erasure all bits take this value (i.e. '1')
);
// Check if it is write protected
if (Instance->Media.ReadOnly != TRUE) {
FlashFvbAttributes = FlashFvbAttributes |
EFI_FVB2_WRITE_STATUS | // Writes are currently enabled
EFI_FVB2_WRITE_ENABLED_CAP; // Writes may be enabled
}
*Attributes = FlashFvbAttributes;
DEBUG ((DEBUG_BLKIO, "FvbGetAttributes(0x%X)\n", *Attributes));
@@ -410,15 +418,15 @@ FvbGetBlockSize (
Instance = INSTANCE_FROM_FVB_THIS (This);
DEBUG ((DEBUG_BLKIO, "FvbGetBlockSize(Lba=%ld, BlockSize=0x%x, LastBlock=%ld)\n", Lba, Instance->BlockSize, Instance->LastBlock));
DEBUG ((DEBUG_BLKIO, "FvbGetBlockSize(Lba=%ld, BlockSize=0x%x, LastBlock=%ld)\n", Lba, Instance->Media.BlockSize, Instance->Media.LastBlock));
if (Lba > Instance->LastBlock) {
DEBUG ((DEBUG_ERROR, "FvbGetBlockSize: ERROR - Parameter LBA %ld is beyond the last Lba (%ld).\n", Lba, Instance->LastBlock));
if (Lba > Instance->Media.LastBlock) {
DEBUG ((DEBUG_ERROR, "FvbGetBlockSize: ERROR - Parameter LBA %ld is beyond the last Lba (%ld).\n", Lba, Instance->Media.LastBlock));
Status = EFI_INVALID_PARAMETER;
} else {
// This is easy because in this platform each NorFlash device has equal sized blocks.
*BlockSize = (UINTN)Instance->BlockSize;
*NumberOfBlocks = (UINTN)(Instance->LastBlock - Lba + 1);
*BlockSize = (UINTN)Instance->Media.BlockSize;
*NumberOfBlocks = (UINTN)(Instance->Media.LastBlock - Lba + 1);
DEBUG ((DEBUG_BLKIO, "FvbGetBlockSize: *BlockSize=0x%x, *NumberOfBlocks=0x%x.\n", *BlockSize, *NumberOfBlocks));
@@ -490,7 +498,7 @@ FvbRead (
TempStatus = EFI_SUCCESS;
// Cache the block size to avoid de-referencing pointers all the time
BlockSize = Instance->BlockSize;
BlockSize = Instance->Media.BlockSize;
DEBUG ((DEBUG_BLKIO, "FvbRead: Check if (Offset=0x%x + NumBytes=0x%x) <= BlockSize=0x%x\n", Offset, *NumBytes, BlockSize));
@@ -661,6 +669,13 @@ FvbEraseBlocks (
Status = EFI_SUCCESS;
// Detect WriteDisabled state
if (Instance->Media.ReadOnly == TRUE) {
// Firmware volume is in WriteDisabled state
DEBUG ((DEBUG_ERROR, "FvbEraseBlocks: ERROR - Device is in WriteDisabled state.\n"));
return EFI_ACCESS_DENIED;
}
// Before erasing, check the entire list of parameters to ensure all specified blocks are valid
VA_START (Args, This);
@@ -683,9 +698,9 @@ FvbEraseBlocks (
"FvbEraseBlocks: Check if: ( StartingLba=%ld + NumOfLba=%Lu - 1 ) > LastBlock=%ld.\n",
Instance->StartLba + StartingLba,
(UINT64)NumOfLba,
Instance->LastBlock
Instance->Media.LastBlock
));
if ((NumOfLba == 0) || ((Instance->StartLba + StartingLba + NumOfLba - 1) > Instance->LastBlock)) {
if ((NumOfLba == 0) || ((Instance->StartLba + StartingLba + NumOfLba - 1) > Instance->Media.LastBlock)) {
VA_END (Args);
DEBUG ((DEBUG_ERROR, "FvbEraseBlocks: ERROR - Lba range goes past the last Lba.\n"));
Status = EFI_INVALID_PARAMETER;
@@ -718,7 +733,7 @@ FvbEraseBlocks (
BlockAddress = GET_NOR_BLOCK_ADDRESS (
Instance->RegionBaseAddress,
Instance->StartLba + StartingLba,
Instance->BlockSize
Instance->Media.BlockSize
);
// Erase it

View File

@@ -0,0 +1,383 @@
/** @file NorFlashStandaloneMm.c
Copyright (c) 2011 - 2021, Arm Limited. All rights reserved.<BR>
Copyright (c) 2020, Linaro, Ltd. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include <Library/BaseMemoryLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/MmServicesTableLib.h>
#include "NorFlash.h"
//
// Global variable declarations
//
NOR_FLASH_INSTANCE **mNorFlashInstances;
UINT32 mNorFlashDeviceCount;
UINTN mFlashNvStorageVariableBase;
NOR_FLASH_INSTANCE mNorFlashInstanceTemplate = {
NOR_FLASH_SIGNATURE, // Signature
NULL, // Handle ... NEED TO BE FILLED
0, // DeviceBaseAddress ... NEED TO BE FILLED
0, // RegionBaseAddress ... NEED TO BE FILLED
0, // Size ... NEED TO BE FILLED
0, // StartLba
{
EFI_BLOCK_IO_PROTOCOL_REVISION2, // Revision
NULL, // Media ... NEED TO BE FILLED
NULL, // Reset;
NULL, // ReadBlocks
NULL, // WriteBlocks
NULL // FlushBlocks
}, // BlockIoProtocol
{
0, // MediaId ... NEED TO BE FILLED
FALSE, // RemovableMedia
TRUE, // MediaPresent
FALSE, // LogicalPartition
FALSE, // ReadOnly
FALSE, // WriteCaching;
0, // BlockSize ... NEED TO BE FILLED
4, // IoAlign
0, // LastBlock ... NEED TO BE FILLED
0, // LowestAlignedLba
1, // LogicalBlocksPerPhysicalBlock
}, // Media;
{
EFI_DISK_IO_PROTOCOL_REVISION, // Revision
NULL, // ReadDisk
NULL // WriteDisk
},
{
FvbGetAttributes, // GetAttributes
FvbSetAttributes, // SetAttributes
FvbGetPhysicalAddress, // GetPhysicalAddress
FvbGetBlockSize, // GetBlockSize
FvbRead, // Read
FvbWrite, // Write
FvbEraseBlocks, // EraseBlocks
NULL, // ParentHandle
}, // FvbProtoccol;
NULL, // ShadowBuffer
{
{
{
HARDWARE_DEVICE_PATH,
HW_VENDOR_DP,
{
(UINT8)(OFFSET_OF (NOR_FLASH_DEVICE_PATH, End)),
(UINT8)(OFFSET_OF (NOR_FLASH_DEVICE_PATH, End) >> 8)
}
},
{ 0x0, 0x0, 0x0, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }
}, // GUID ... NEED TO BE FILLED
},
0, // Index
{
END_DEVICE_PATH_TYPE,
END_ENTIRE_DEVICE_PATH_SUBTYPE,
{ sizeof (EFI_DEVICE_PATH_PROTOCOL), 0 }
}
} // DevicePath
};
EFI_STATUS
NorFlashCreateInstance (
IN UINTN NorFlashDeviceBase,
IN UINTN NorFlashRegionBase,
IN UINTN NorFlashSize,
IN UINT32 Index,
IN UINT32 BlockSize,
IN BOOLEAN SupportFvb,
OUT NOR_FLASH_INSTANCE **NorFlashInstance
)
{
EFI_STATUS Status;
NOR_FLASH_INSTANCE *Instance;
ASSERT (NorFlashInstance != NULL);
Instance = AllocateRuntimeCopyPool (sizeof (NOR_FLASH_INSTANCE), &mNorFlashInstanceTemplate);
if (Instance == NULL) {
return EFI_OUT_OF_RESOURCES;
}
Instance->DeviceBaseAddress = NorFlashDeviceBase;
Instance->RegionBaseAddress = NorFlashRegionBase;
Instance->Size = NorFlashSize;
Instance->BlockIoProtocol.Media = &Instance->Media;
Instance->Media.MediaId = Index;
Instance->Media.BlockSize = BlockSize;
Instance->Media.LastBlock = (NorFlashSize / BlockSize)-1;
CopyGuid (&Instance->DevicePath.Vendor.Guid, &gEfiCallerIdGuid);
Instance->DevicePath.Index = (UINT8)Index;
Instance->ShadowBuffer = AllocateRuntimePool (BlockSize);
if (Instance->ShadowBuffer == NULL) {
return EFI_OUT_OF_RESOURCES;
}
if (SupportFvb) {
NorFlashFvbInitialize (Instance);
Status = gMmst->MmInstallProtocolInterface (
&Instance->Handle,
&gEfiSmmFirmwareVolumeBlockProtocolGuid,
EFI_NATIVE_INTERFACE,
&Instance->FvbProtocol
);
if (EFI_ERROR (Status)) {
FreePool (Instance);
return Status;
}
} else {
DEBUG ((DEBUG_ERROR, "standalone MM NOR Flash driver only support FVB.\n"));
FreePool (Instance);
return EFI_UNSUPPORTED;
}
*NorFlashInstance = Instance;
return Status;
}
/**
* This function unlock and erase an entire NOR Flash block.
**/
EFI_STATUS
NorFlashUnlockAndEraseSingleBlock (
IN NOR_FLASH_INSTANCE *Instance,
IN UINTN BlockAddress
)
{
EFI_STATUS Status;
UINTN Index;
Index = 0;
// The block erase might fail a first time (SW bug ?). Retry it ...
do {
// Unlock the block if we have to
Status = NorFlashUnlockSingleBlockIfNecessary (Instance, BlockAddress);
if (EFI_ERROR (Status)) {
break;
}
Status = NorFlashEraseSingleBlock (Instance, BlockAddress);
Index++;
} while ((Index < NOR_FLASH_ERASE_RETRY) && (Status == EFI_WRITE_PROTECTED));
if (Index == NOR_FLASH_ERASE_RETRY) {
DEBUG ((DEBUG_ERROR, "EraseSingleBlock(BlockAddress=0x%08x: Block Locked Error (try to erase %d times)\n", BlockAddress, Index));
}
return Status;
}
EFI_STATUS
NorFlashWriteFullBlock (
IN NOR_FLASH_INSTANCE *Instance,
IN EFI_LBA Lba,
IN UINT32 *DataBuffer,
IN UINT32 BlockSizeInWords
)
{
EFI_STATUS Status;
UINTN WordAddress;
UINT32 WordIndex;
UINTN BufferIndex;
UINTN BlockAddress;
UINTN BuffersInBlock;
UINTN RemainingWords;
UINTN Cnt;
Status = EFI_SUCCESS;
// Get the physical address of the block
BlockAddress = GET_NOR_BLOCK_ADDRESS (Instance->RegionBaseAddress, Lba, BlockSizeInWords * 4);
// Start writing from the first address at the start of the block
WordAddress = BlockAddress;
Status = NorFlashUnlockAndEraseSingleBlock (Instance, BlockAddress);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "WriteSingleBlock: ERROR - Failed to Unlock and Erase the single block at 0x%X\n", BlockAddress));
goto EXIT;
}
// To speed up the programming operation, NOR Flash is programmed using the Buffered Programming method.
// Check that the address starts at a 32-word boundary, i.e. last 7 bits must be zero
if ((WordAddress & BOUNDARY_OF_32_WORDS) == 0x00) {
// First, break the entire block into buffer-sized chunks.
BuffersInBlock = (UINTN)(BlockSizeInWords * 4) / P30_MAX_BUFFER_SIZE_IN_BYTES;
// Then feed each buffer chunk to the NOR Flash
// If a buffer does not contain any data, don't write it.
for (BufferIndex = 0;
BufferIndex < BuffersInBlock;
BufferIndex++, WordAddress += P30_MAX_BUFFER_SIZE_IN_BYTES, DataBuffer += P30_MAX_BUFFER_SIZE_IN_WORDS
)
{
// Check the buffer to see if it contains any data (not set all 1s).
for (Cnt = 0; Cnt < P30_MAX_BUFFER_SIZE_IN_WORDS; Cnt++) {
if (~DataBuffer[Cnt] != 0 ) {
// Some data found, write the buffer.
Status = NorFlashWriteBuffer (
Instance,
WordAddress,
P30_MAX_BUFFER_SIZE_IN_BYTES,
DataBuffer
);
if (EFI_ERROR (Status)) {
goto EXIT;
}
break;
}
}
}
// Finally, finish off any remaining words that are less than the maximum size of the buffer
RemainingWords = BlockSizeInWords % P30_MAX_BUFFER_SIZE_IN_WORDS;
if (RemainingWords != 0) {
Status = NorFlashWriteBuffer (Instance, WordAddress, (RemainingWords * 4), DataBuffer);
if (EFI_ERROR (Status)) {
goto EXIT;
}
}
} else {
// For now, use the single word programming algorithm
// It is unlikely that the NOR Flash will exist in an address which falls within a 32 word boundary range,
// i.e. which ends in the range 0x......01 - 0x......7F.
for (WordIndex = 0; WordIndex < BlockSizeInWords; WordIndex++, DataBuffer++, WordAddress = WordAddress + 4) {
Status = NorFlashWriteSingleWord (Instance, WordAddress, *DataBuffer);
if (EFI_ERROR (Status)) {
goto EXIT;
}
}
}
EXIT:
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "NOR FLASH Programming [WriteSingleBlock] failed at address 0x%08x. Exit Status = \"%r\".\n", WordAddress, Status));
}
return Status;
}
EFI_STATUS
EFIAPI
NorFlashInitialise (
IN EFI_HANDLE ImageHandle,
IN EFI_MM_SYSTEM_TABLE *MmSystemTable
)
{
EFI_STATUS Status;
UINT32 Index;
NOR_FLASH_DESCRIPTION *NorFlashDevices;
BOOLEAN ContainVariableStorage;
Status = NorFlashPlatformInitialization ();
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "NorFlashInitialise: Fail to initialize Nor Flash devices\n"));
return Status;
}
Status = NorFlashPlatformGetDevices (&NorFlashDevices, &mNorFlashDeviceCount);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "NorFlashInitialise: Fail to get Nor Flash devices\n"));
return Status;
}
mNorFlashInstances = AllocatePool (sizeof (NOR_FLASH_INSTANCE *) * mNorFlashDeviceCount);
for (Index = 0; Index < mNorFlashDeviceCount; Index++) {
// Check if this NOR Flash device contain the variable storage region
if (FixedPcdGet64 (PcdFlashNvStorageVariableBase64) != 0) {
ContainVariableStorage =
(NorFlashDevices[Index].RegionBaseAddress <= FixedPcdGet64 (PcdFlashNvStorageVariableBase64)) &&
(FixedPcdGet64 (PcdFlashNvStorageVariableBase64) + FixedPcdGet32 (PcdFlashNvStorageVariableSize) <=
NorFlashDevices[Index].RegionBaseAddress + NorFlashDevices[Index].Size);
} else {
ContainVariableStorage =
(NorFlashDevices[Index].RegionBaseAddress <= FixedPcdGet32 (PcdFlashNvStorageVariableBase)) &&
(FixedPcdGet32 (PcdFlashNvStorageVariableBase) + FixedPcdGet32 (PcdFlashNvStorageVariableSize) <=
NorFlashDevices[Index].RegionBaseAddress + NorFlashDevices[Index].Size);
}
Status = NorFlashCreateInstance (
NorFlashDevices[Index].DeviceBaseAddress,
NorFlashDevices[Index].RegionBaseAddress,
NorFlashDevices[Index].Size,
Index,
NorFlashDevices[Index].BlockSize,
ContainVariableStorage,
&mNorFlashInstances[Index]
);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "NorFlashInitialise: Fail to create instance for NorFlash[%d]\n", Index));
}
}
return Status;
}
EFI_STATUS
EFIAPI
NorFlashFvbInitialize (
IN NOR_FLASH_INSTANCE *Instance
)
{
EFI_STATUS Status;
UINT32 FvbNumLba;
ASSERT ((Instance != NULL));
mFlashNvStorageVariableBase = (FixedPcdGet64 (PcdFlashNvStorageVariableBase64) != 0) ?
FixedPcdGet64 (PcdFlashNvStorageVariableBase64) : FixedPcdGet32 (PcdFlashNvStorageVariableBase);
// Set the index of the first LBA for the FVB
Instance->StartLba = (mFlashNvStorageVariableBase - Instance->RegionBaseAddress) / Instance->Media.BlockSize;
// Determine if there is a valid header at the beginning of the NorFlash
Status = ValidateFvHeader (Instance);
// Install the Default FVB header if required
if (EFI_ERROR (Status)) {
// There is no valid header, so time to install one.
DEBUG ((DEBUG_INFO, "%a: The FVB Header is not valid.\n", __FUNCTION__));
DEBUG ((
DEBUG_INFO,
"%a: Installing a correct one for this volume.\n",
__FUNCTION__
));
// Erase all the NorFlash that is reserved for variable storage
FvbNumLba = (PcdGet32 (PcdFlashNvStorageVariableSize) + PcdGet32 (PcdFlashNvStorageFtwWorkingSize) + PcdGet32 (PcdFlashNvStorageFtwSpareSize)) / Instance->Media.BlockSize;
Status = FvbEraseBlocks (&Instance->FvbProtocol, (EFI_LBA)0, FvbNumLba, EFI_LBA_LIST_TERMINATOR);
if (EFI_ERROR (Status)) {
return Status;
}
// Install all appropriate headers
Status = InitializeFvAndVariableStoreHeaders (Instance);
if (EFI_ERROR (Status)) {
return Status;
}
}
return Status;
}

View File

@@ -0,0 +1,66 @@
#/** @file
#
# Component description file for NorFlashStandaloneMm module
#
# Copyright (c) 2011 - 2021, Arm Limited. All rights reserved.<BR>
# Copyright (c) 2020, Linaro, Ltd. All rights reserved.<BR>
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
#**/
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = ArmVeNorFlashStandaloneMm
FILE_GUID = e67d82ad-cd56-4071-9151-95ee44990bb0
MODULE_TYPE = MM_STANDALONE
VERSION_STRING = 1.0
PI_SPECIFICATION_VERSION = 0x00010032
ENTRY_POINT = NorFlashInitialise
[Sources.common]
NorFlash.h
NorFlash.c
NorFlashStandaloneMm.c
NorFlashFvb.c
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
ArmPlatformPkg/ArmPlatformPkg.dec
EmbeddedPkg/EmbeddedPkg.dec
[LibraryClasses]
BaseLib
BaseMemoryLib
DebugLib
IoLib
MemoryAllocationLib
MmServicesTableLib
NorFlashPlatformLib
StandaloneMmDriverEntryPoint
[Guids]
gEfiSystemNvDataFvGuid
gEfiVariableGuid
gEfiAuthenticatedVariableGuid
[Protocols]
gEfiSmmFirmwareVolumeBlockProtocolGuid
[FixedPcd]
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase64
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase64
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase64
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize
[FeaturePcd]
gArmPlatformTokenSpaceGuid.PcdNorFlashCheckBlockLocked
[Depex]
TRUE

View File

@@ -6,25 +6,25 @@
**/
#ifndef __VIRT_NOR_FLASH_PLATFORM_LIB__
#define __VIRT_NOR_FLASH_PLATFORM_LIB__
#ifndef _NORFLASHPLATFORMLIB_H_
#define _NORFLASHPLATFORMLIB_H_
typedef struct {
UINTN DeviceBaseAddress; // Start address of the Device Base Address (DBA)
UINTN RegionBaseAddress; // Start address of one single region
UINTN Size;
UINTN BlockSize;
} VIRT_NOR_FLASH_DESCRIPTION;
} NOR_FLASH_DESCRIPTION;
EFI_STATUS
VirtNorFlashPlatformInitialization (
NorFlashPlatformInitialization (
VOID
);
EFI_STATUS
VirtNorFlashPlatformGetDevices (
OUT VIRT_NOR_FLASH_DESCRIPTION **NorFlashDescriptions,
OUT UINT32 *Count
NorFlashPlatformGetDevices (
OUT NOR_FLASH_DESCRIPTION **NorFlashDescriptions,
OUT UINT32 *Count
);
#endif /* __VIRT_NOR_FLASH_PLATFORM_LIB__ */
#endif /* _NORFLASHPLATFORMLIB_H_ */

View File

@@ -0,0 +1,28 @@
/** @file
Copyright (c) 2014, Linaro Ltd. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include <Library/NorFlashPlatformLib.h>
EFI_STATUS
NorFlashPlatformInitialization (
VOID
)
{
return EFI_SUCCESS;
}
EFI_STATUS
NorFlashPlatformGetDevices (
OUT NOR_FLASH_DESCRIPTION **NorFlashDescriptions,
OUT UINT32 *Count
)
{
*NorFlashDescriptions = NULL;
*Count = 0;
return EFI_SUCCESS;
}

View File

@@ -0,0 +1,24 @@
#/** @file
#
# Component description file for NorFlashPlatformNullLib module
#
# Copyright (c) 2017, Linaro Ltd. All rights reserved.<BR>
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
#**/
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = NorFlashPlatformNullLib
FILE_GUID = 29b733ad-d066-4df6-8a89-b9df1beb818a
MODULE_TYPE = DXE_DRIVER
VERSION_STRING = 1.0
LIBRARY_CLASS = NorFlashPlatformLib
[Sources.common]
NorFlashPlatformNullLib.c
[Packages]
MdePkg/MdePkg.dec
ArmPlatformPkg/ArmPlatformPkg.dec

View File

@@ -173,7 +173,7 @@ LibGetTime (
@retval EFI_SUCCESS The operation completed successfully.
@retval EFI_INVALID_PARAMETER A time field is out of range.
@retval EFI_DEVICE_ERROR The time could not be set due to hardware error.
@retval EFI_DEVICE_ERROR The time could not be set due due to hardware error.
**/
EFI_STATUS

View File

@@ -1,7 +1,7 @@
/** @file
Main file supporting the transition to PEI Core in Normal World for Versatile Express
Copyright (c) 2011 - 2022, ARM Limited. All rights reserved.
Copyright (c) 2011-2014, ARM Limited. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -11,8 +11,6 @@
#include <Library/CacheMaintenanceLib.h>
#include <Library/DebugAgentLib.h>
#include <Library/ArmLib.h>
#include <Library/PrintLib.h>
#include <Library/SerialPortLib.h>
#include "PrePeiCore.h"
@@ -54,50 +52,23 @@ CreatePpiList (
*PpiListSize = sizeof (gCommonPpiTable) + PlatformPpiListSize;
}
/**
Prints firmware version and build time to serial console.
**/
STATIC
VOID
PrintFirmwareVersion (
VOID
)
{
CHAR8 Buffer[100];
UINTN CharCount;
CharCount = AsciiSPrint (
Buffer,
sizeof (Buffer),
"UEFI firmware (version %s built at %a on %a)\n\r",
(CHAR16 *)PcdGetPtr (PcdFirmwareVersionString),
__TIME__,
__DATE__
);
SerialPortWrite ((UINT8 *)Buffer, CharCount);
}
VOID
CEntryPoint (
IN UINTN MpId,
IN EFI_PEI_CORE_ENTRY_POINT PeiCoreEntryPoint
)
{
if (!ArmMmuEnabled ()) {
// Data Cache enabled on Primary core when MMU is enabled.
ArmDisableDataCache ();
// Invalidate instruction cache
ArmInvalidateInstructionCache ();
// Enable Instruction Caches on all cores.
ArmEnableInstructionCache ();
// Data Cache enabled on Primary core when MMU is enabled.
ArmDisableDataCache ();
// Invalidate instruction cache
ArmInvalidateInstructionCache ();
// Enable Instruction Caches on all cores.
ArmEnableInstructionCache ();
InvalidateDataCacheRange (
(VOID *)(UINTN)PcdGet64 (PcdCPUCoresStackBase),
PcdGet32 (PcdCPUCorePrimaryStackSize)
);
}
InvalidateDataCacheRange (
(VOID *)(UINTN)PcdGet64 (PcdCPUCoresStackBase),
PcdGet32 (PcdCPUCorePrimaryStackSize)
);
//
// Note: Doesn't have to Enable CPU interface in non-secure world,
@@ -119,12 +90,6 @@ CEntryPoint (
// If not primary Jump to Secondary Main
if (ArmPlatformIsPrimaryCore (MpId)) {
// Invoke "ProcessLibraryConstructorList" to have all library constructors
// called.
ProcessLibraryConstructorList ();
PrintFirmwareVersion ();
// Initialize the Debug Agent for Source Level Debugging
InitializeDebugAgent (DEBUG_AGENT_INIT_POSTMEM_SEC, NULL, NULL);
SaveAndSetDebugTimerInterrupt (TRUE);

View File

@@ -1,7 +1,7 @@
/** @file
Main file supporting the transition to PEI Core in Normal World for Versatile Express
Copyright (c) 2011 - 2022, ARM Limited. All rights reserved.
Copyright (c) 2011, ARM Limited. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -73,14 +73,4 @@ PeiCommonExceptionEntry (
IN UINTN LR
);
/*
* Autogenerated function that calls the library constructors for all of the
* module's dependent libraries.
*/
VOID
EFIAPI
ProcessLibraryConstructorList (
VOID
);
#endif

View File

@@ -54,9 +54,6 @@
gEfiTemporaryRamSupportPpiGuid
gArmMpCoreInfoPpiGuid
[Pcd]
gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVersionString
[FeaturePcd]
gArmPlatformTokenSpaceGuid.PcdSendSgiToBringUpSecondaryCores

View File

@@ -52,9 +52,6 @@
[Ppis]
gEfiTemporaryRamSupportPpiGuid
[Pcd]
gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVersionString
[FeaturePcd]
gArmPlatformTokenSpaceGuid.PcdSendSgiToBringUpSecondaryCores

View File

@@ -122,6 +122,13 @@
PL011UartLib|ArmPlatformPkg/Library/PL011UartLib/PL011UartLib.inf
SerialPortLib|ArmVirtPkg/Library/FdtPL011SerialPortLib/FdtPL011SerialPortLib.inf
#
# Uncomment (and comment out the next line) For RealView Debugger. The Standard IO window
# in the debugger will show load and unload commands for symbols. You can cut and paste this
# into the command window to load symbols. We should be able to use a script to do this, but
# the version of RVD I have does not support scripts accessing system memory.
#
#PeCoffExtraActionLib|ArmPkg/Library/RvdPeCoffExtraActionLib/RvdPeCoffExtraActionLib.inf
PeCoffExtraActionLib|ArmPkg/Library/DebugPeCoffExtraActionLib/DebugPeCoffExtraActionLib.inf
#PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf
@@ -137,7 +144,6 @@
PciCapLib|OvmfPkg/Library/BasePciCapLib/BasePciCapLib.inf
PciCapPciSegmentLib|OvmfPkg/Library/BasePciCapPciSegmentLib/BasePciCapPciSegmentLib.inf
PciCapPciIoLib|OvmfPkg/Library/UefiPciCapPciIoLib/UefiPciCapPciIoLib.inf
DxeHardwareInfoLib|OvmfPkg/Library/HardwareInfoLib/DxeHardwareInfoLib.inf
# USB Libraries
UefiUsbLib|MdePkg/Library/UefiUsbLib/UefiUsbLib.inf
@@ -163,7 +169,6 @@
AuthVariableLib|SecurityPkg/Library/AuthVariableLib/AuthVariableLib.inf
SecureBootVariableLib|SecurityPkg/Library/SecureBootVariableLib/SecureBootVariableLib.inf
SecureBootVariableProvisionLib|SecurityPkg/Library/SecureBootVariableProvisionLib/SecureBootVariableProvisionLib.inf
PlatformPKProtectionLib|SecurityPkg/Library/PlatformPKProtectionLibVarPolicy/PlatformPKProtectionLibVarPolicy.inf
# re-use the UserPhysicalPresent() dummy implementation from the ovmf tree
PlatformSecureLib|OvmfPkg/Library/PlatformSecureLib/PlatformSecureLib.inf
@@ -361,7 +366,7 @@
# reserved ones, with the exception of LoaderData regions, of which OS loaders
# (i.e., GRUB) may assume that its contents are executable.
#
gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy|0xC000000000007FD5
gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy|0xC000000000007FD1
[Components.common]
#
@@ -415,3 +420,8 @@
<LibraryClasses>
NULL|EmbeddedPkg/Library/PlatformHasAcpiLib/PlatformHasAcpiLib.inf
}
#
# EBC support
#
MdeModulePkg/Universal/EbcDxe/EbcDxe.inf

View File

@@ -60,7 +60,7 @@
!include MdePkg/MdeLibs.dsc.inc
[LibraryClasses.common.PEIM]
ArmVirtMemInfoLib|ArmVirtPkg/Library/CloudHvVirtMemInfoLib/CloudHvVirtMemInfoPeiLib.inf
ArmVirtMemInfoLib|ArmVirtPkg/Library/QemuVirtMemInfoLib/QemuVirtMemInfoPeiLib.inf
[LibraryClasses.common.DXE_DRIVER]
ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf
@@ -198,7 +198,7 @@
gEfiSecurityPkgTokenSpaceGuid.PcdTpmBaseAddress|0x0
[PcdsDynamicHii]
gUefiOvmfPkgTokenSpaceGuid.PcdForceNoAcpi|L"ForceNoAcpi"|gOvmfVariableGuid|0x0|FALSE|NV,BS
gArmVirtTokenSpaceGuid.PcdForceNoAcpi|L"ForceNoAcpi"|gArmVirtVariableGuid|0x0|FALSE|NV,BS
################################################################################
#

View File

@@ -195,6 +195,11 @@ READ_LOCK_STATUS = TRUE
INF MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
INF MdeModulePkg/Universal/Acpi/BootGraphicsResourceTableDxe/BootGraphicsResourceTableDxe.inf
INF ArmVirtPkg/CloudHvAcpiPlatformDxe/CloudHvAcpiPlatformDxe.inf
#
# EBC support
#
INF MdeModulePkg/Universal/EbcDxe/EbcDxe.inf
!endif
#

View File

@@ -50,7 +50,7 @@
ArmVirtMemInfoLib|ArmVirtPkg/Library/KvmtoolVirtMemInfoLib/KvmtoolVirtMemInfoLib.inf
TimerLib|ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.inf
VirtNorFlashPlatformLib|ArmVirtPkg/Library/NorFlashKvmtoolLib/NorFlashKvmtoolLib.inf
NorFlashPlatformLib|ArmVirtPkg/Library/NorFlashKvmtoolLib/NorFlashKvmtoolLib.inf
CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf
@@ -81,9 +81,6 @@
HwInfoParserLib|DynamicTablesPkg/Library/FdtHwInfoParserLib/FdtHwInfoParserLib.inf
DynamicPlatRepoLib|DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/DynamicPlatRepoLib.inf
ArmMonitorLib|ArmPkg/Library/ArmMonitorLib/ArmMonitorLib.inf
ArmTrngLib|ArmPkg/Library/ArmTrngLib/ArmTrngLib.inf
[LibraryClasses.common.SEC, LibraryClasses.common.PEI_CORE, LibraryClasses.common.PEIM]
PciExpressLib|MdePkg/Library/BasePciExpressLib/BasePciExpressLib.inf
PlatformHookLib|ArmVirtPkg/Library/Fdt16550SerialPortHookLib/EarlyFdt16550SerialPortHookLib.inf
@@ -115,8 +112,6 @@
# Use MMIO for accessing RTC controller registers.
gPcAtChipsetPkgTokenSpaceGuid.PcdRtcUseMmio|TRUE
gArmTokenSpaceGuid.PcdMonitorConduitHvc|TRUE
[PcdsFixedAtBuild.common]
gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x8000000F
@@ -296,11 +291,7 @@
NULL|ArmVirtPkg/Library/ArmVirtTimerFdtClientLib/ArmVirtTimerFdtClientLib.inf
}
OvmfPkg/VirtNorFlashDxe/VirtNorFlashDxe.inf {
<LibraryClasses>
# don't use unaligned CopyMem () on the UEFI varstore NOR flash region
BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
}
ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.inf
MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf
@@ -371,11 +362,6 @@
OvmfPkg/VirtioPciDeviceDxe/VirtioPciDeviceDxe.inf
OvmfPkg/Virtio10Dxe/Virtio10.inf
#
# Rng Support
#
SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf
!if $(ARCH) == AARCH64
#
# ACPI Support

View File

@@ -154,7 +154,7 @@ READ_LOCK_STATUS = TRUE
INF ArmPkg/Drivers/ArmGic/ArmGicDxe.inf
INF ArmPkg/Drivers/TimerDxe/TimerDxe.inf
INF MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf
INF OvmfPkg/VirtNorFlashDxe/VirtNorFlashDxe.inf
INF ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.inf
#
# FAT filesystem + GPT/MBR partitioning + UDF filesystem
@@ -224,11 +224,6 @@ READ_LOCK_STATUS = TRUE
#
INF MdeModulePkg/Universal/Disk/RamDiskDxe/RamDiskDxe.inf
#
# Rng Support
#
INF SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf
[FV.FVMAIN_COMPACT]
FvAlignment = 16
ERASE_POLARITY = 1

View File

@@ -96,7 +96,7 @@
## options defined .pytool/Plugin/SpellCheck
"SpellCheck": {
"AuditOnly": True,
"AuditOnly": False, # Fails right now with over 270 errors
"IgnoreFiles": [], # use gitignore syntax to ignore errors in matching files
"ExtendWords": [
"acpiview",

View File

@@ -32,7 +32,8 @@
gArmVirtTokenSpaceGuid = { 0x0B6F5CA7, 0x4F53, 0x445A, { 0xB7, 0x6E, 0x2E, 0x36, 0x5B, 0x80, 0x63, 0x66 } }
gEarlyPL011BaseAddressGuid = { 0xB199DEA9, 0xFD5C, 0x4A84, { 0x80, 0x82, 0x2F, 0x41, 0x70, 0x78, 0x03, 0x05 } }
gEarly16550UartBaseAddressGuid = { 0xea67ca3e, 0x1f54, 0x436b, { 0x97, 0x88, 0xd4, 0xeb, 0x29, 0xc3, 0x42, 0x67 } }
gArmVirtSystemMemorySizeGuid = { 0x504eccb9, 0x1bf0, 0x4420, { 0x86, 0x5d, 0xdc, 0x66, 0x06, 0xd4, 0x13, 0xbf } }
gArmVirtVariableGuid = { 0x50bea1e5, 0xa2c5, 0x46e9, { 0x9b, 0x3a, 0x59, 0x59, 0x65, 0x16, 0xb0, 0x0a } }
[PcdsFeatureFlag]
#
@@ -67,3 +68,10 @@
# Cloud Hypervisor has no other way to pass Rsdp address to the guest except use a PCD.
#
gArmVirtTokenSpaceGuid.PcdCloudHvAcpiRsdpBaseAddress|0x0|UINT64|0x00000005
[PcdsDynamic]
#
# Whether to force disable ACPI, regardless of the fw_cfg settings
# exposed by QEMU
#
gArmVirtTokenSpaceGuid.PcdForceNoAcpi|0x0|BOOLEAN|0x00000003

View File

@@ -31,7 +31,6 @@
DEFINE SECURE_BOOT_ENABLE = FALSE
DEFINE TPM2_ENABLE = FALSE
DEFINE TPM2_CONFIG_ENABLE = FALSE
DEFINE CAVIUM_ERRATUM_27456 = FALSE
#
# Network definition
@@ -41,7 +40,7 @@
DEFINE NETWORK_SNP_ENABLE = FALSE
DEFINE NETWORK_TLS_ENABLE = FALSE
DEFINE NETWORK_ALLOW_HTTP_CONNECTIONS = TRUE
DEFINE NETWORK_ISCSI_ENABLE = FALSE
DEFINE NETWORK_ISCSI_ENABLE = TRUE
!if $(NETWORK_SNP_ENABLE) == TRUE
!error "NETWORK_SNP_ENABLE is IA32/X64/EBC only"
@@ -65,8 +64,10 @@
QemuFwCfgSimpleParserLib|OvmfPkg/Library/QemuFwCfgSimpleParserLib/QemuFwCfgSimpleParserLib.inf
QemuLoadImageLib|OvmfPkg/Library/GenericQemuLoadImageLib/GenericQemuLoadImageLib.inf
ArmPlatformLib|ArmPlatformPkg/Library/ArmPlatformLibNull/ArmPlatformLibNull.inf
TimerLib|ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.inf
VirtNorFlashPlatformLib|ArmVirtPkg/Library/NorFlashQemuLib/NorFlashQemuLib.inf
NorFlashPlatformLib|ArmVirtPkg/Library/NorFlashQemuLib/NorFlashQemuLib.inf
CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf
BootLogoLib|MdeModulePkg/Library/BootLogoLib/BootLogoLib.inf
@@ -80,7 +81,6 @@
PciSegmentLib|MdePkg/Library/BasePciSegmentLibPci/BasePciSegmentLibPci.inf
PciHostBridgeLib|OvmfPkg/Fdt/FdtPciHostBridgeLib/FdtPciHostBridgeLib.inf
PciHostBridgeUtilityLib|OvmfPkg/Library/PciHostBridgeUtilityLib/PciHostBridgeUtilityLib.inf
PeiHardwareInfoLib|OvmfPkg/Library/HardwareInfoLib/PeiHardwareInfoLib.inf
!if $(TPM2_ENABLE) == TRUE
Tpm2CommandLib|SecurityPkg/Library/Tpm2CommandLib/Tpm2CommandLib.inf
@@ -92,12 +92,6 @@
TpmPlatformHierarchyLib|SecurityPkg/Library/PeiDxeTpmPlatformHierarchyLibNull/PeiDxeTpmPlatformHierarchyLib.inf
!endif
[LibraryClasses.AARCH64]
ArmPlatformLib|ArmVirtPkg/Library/ArmPlatformLibQemu/ArmPlatformLibQemu.inf
[LibraryClasses.ARM]
ArmPlatformLib|ArmPlatformPkg/Library/ArmPlatformLibNull/ArmPlatformLibNull.inf
[LibraryClasses.common.PEIM]
ArmVirtMemInfoLib|ArmVirtPkg/Library/QemuVirtMemInfoLib/QemuVirtMemInfoPeiLib.inf
@@ -118,12 +112,6 @@
UefiScsiLib|MdePkg/Library/UefiScsiLib/UefiScsiLib.inf
[BuildOptions]
!if $(CAVIUM_ERRATUM_27456) == TRUE
GCC:*_*_AARCH64_PP_FLAGS = -DCAVIUM_ERRATUM_27456
!else
GCC:*_*_AARCH64_CC_XIPFLAGS ==
!endif
!include NetworkPkg/NetworkBuildOptions.dsc.inc
################################################################################
@@ -223,12 +211,6 @@
gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|3
gEfiShellPkgTokenSpaceGuid.PcdShellFileOperationSize|0x20000
# Shadowing PEI modules is absolutely pointless when the NOR flash is emulated
gEfiMdeModulePkgTokenSpaceGuid.PcdShadowPeimOnBoot|FALSE
# System Memory Size -- 128 MB initially, actual size will be fetched from DT
gArmTokenSpaceGuid.PcdSystemMemorySize|0x8000000
[PcdsFixedAtBuild.AARCH64]
# Clearing BIT0 in this PCD prevents installing a 32-bit SMBIOS entry point,
# if the entry point version is >= 3.0. AARCH64 OSes cannot assume the
@@ -245,6 +227,9 @@
# enumeration to complete before installing ACPI tables.
gEfiMdeModulePkgTokenSpaceGuid.PcdPciDisableBusEnumeration|TRUE
# System Memory Size -- 1 MB initially, actual size will be fetched from DT
gArmTokenSpaceGuid.PcdSystemMemorySize|0x00100000
gArmTokenSpaceGuid.PcdArmArchTimerSecIntrNum|0x0
gArmTokenSpaceGuid.PcdArmArchTimerIntrNum|0x0
gArmTokenSpaceGuid.PcdArmArchTimerVirtIntrNum|0x0
@@ -293,34 +278,20 @@
#
# TPM2 support
#
!if $(TPM2_ENABLE) == TRUE
gEfiSecurityPkgTokenSpaceGuid.PcdTpmBaseAddress|0x0
!if $(TPM2_ENABLE) == TRUE
gEfiSecurityPkgTokenSpaceGuid.PcdTpmInstanceGuid|{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
gEfiSecurityPkgTokenSpaceGuid.PcdTpm2HashMask|0
!else
[PcdsPatchableInModule]
# make this PCD patchable instead of dynamic when TPM support is not enabled
# this permits setting the PCD in unreachable code without pulling in dynamic PCD support
gEfiSecurityPkgTokenSpaceGuid.PcdTpmBaseAddress|0x0
!endif
[PcdsDynamicHii]
gUefiOvmfPkgTokenSpaceGuid.PcdForceNoAcpi|L"ForceNoAcpi"|gOvmfVariableGuid|0x0|FALSE|NV,BS
gArmVirtTokenSpaceGuid.PcdForceNoAcpi|L"ForceNoAcpi"|gArmVirtVariableGuid|0x0|FALSE|NV,BS
!if $(TPM2_CONFIG_ENABLE) == TRUE
gEfiSecurityPkgTokenSpaceGuid.PcdTcgPhysicalPresenceInterfaceVer|L"TCG2_VERSION"|gTcg2ConfigFormSetGuid|0x0|"1.3"|NV,BS
gEfiSecurityPkgTokenSpaceGuid.PcdTpm2AcpiTableRev|L"TCG2_VERSION"|gTcg2ConfigFormSetGuid|0x8|3|NV,BS
!endif
gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut|L"Timeout"|gEfiGlobalVariableGuid|0x0|5
[LibraryClasses.common.PEI_CORE, LibraryClasses.common.PEIM]
!if $(TPM2_ENABLE) == TRUE
PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
!else
PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
!endif
################################################################################
#
# Components Section - list of all EDK II Modules needed by this Platform
@@ -332,20 +303,17 @@
#
ArmPlatformPkg/PrePeiCore/PrePeiCoreUniCore.inf
MdeModulePkg/Core/Pei/PeiMain.inf
ArmPlatformPkg/PlatformPei/PlatformPeim.inf
ArmVirtPkg/MemoryInitPei/MemoryInitPeim.inf {
<LibraryClasses>
!if $(ARCH) == AARCH64
ArmMmuLib|ArmPkg/Library/ArmMmuLib/ArmMmuPeiLib.inf
!endif
}
ArmPkg/Drivers/CpuPei/CpuPei.inf
!if $(TPM2_ENABLE) == TRUE
MdeModulePkg/Universal/PCD/Pei/Pcd.inf {
<LibraryClasses>
PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
}
ArmPlatformPkg/PlatformPei/PlatformPeim.inf
ArmPlatformPkg/MemoryInitPei/MemoryInitPeim.inf
ArmPkg/Drivers/CpuPei/CpuPei.inf
MdeModulePkg/Universal/Variable/Pei/VariablePei.inf
!if $(TPM2_ENABLE) == TRUE
MdeModulePkg/Universal/ResetSystemPei/ResetSystemPei.inf {
<LibraryClasses>
ResetSystemLib|ArmVirtPkg/Library/ArmVirtPsciResetSystemPeiLib/ArmVirtPsciResetSystemPeiLib.inf
@@ -428,11 +396,7 @@
<LibraryClasses>
NULL|ArmVirtPkg/Library/ArmVirtTimerFdtClientLib/ArmVirtTimerFdtClientLib.inf
}
OvmfPkg/VirtNorFlashDxe/VirtNorFlashDxe.inf {
<LibraryClasses>
# don't use unaligned CopyMem () on the UEFI varstore NOR flash region
BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
}
ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.inf
MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf
#
@@ -578,7 +542,7 @@
#
# ACPI Support
#
OvmfPkg/PlatformHasAcpiDtDxe/PlatformHasAcpiDtDxe.inf
ArmVirtPkg/PlatformHasAcpiDtDxe/PlatformHasAcpiDtDxe.inf
[Components.AARCH64]
MdeModulePkg/Universal/Acpi/BootGraphicsResourceTableDxe/BootGraphicsResourceTableDxe.inf
OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf {

View File

@@ -107,12 +107,13 @@ READ_LOCK_STATUS = TRUE
INF ArmPlatformPkg/PrePeiCore/PrePeiCoreUniCore.inf
INF MdeModulePkg/Core/Pei/PeiMain.inf
INF ArmPlatformPkg/PlatformPei/PlatformPeim.inf
INF ArmVirtPkg/MemoryInitPei/MemoryInitPeim.inf
INF ArmPlatformPkg/MemoryInitPei/MemoryInitPeim.inf
INF ArmPkg/Drivers/CpuPei/CpuPei.inf
INF MdeModulePkg/Universal/PCD/Pei/Pcd.inf
INF MdeModulePkg/Universal/Variable/Pei/VariablePei.inf
INF MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
!if $(TPM2_ENABLE) == TRUE
INF MdeModulePkg/Universal/PCD/Pei/Pcd.inf
INF MdeModulePkg/Universal/ResetSystemPei/ResetSystemPei.inf
INF OvmfPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf
INF SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.inf

View File

@@ -73,7 +73,7 @@ READ_LOCK_STATUS = TRUE
INF ArmPkg/Drivers/ArmGic/ArmGicDxe.inf
INF ArmPkg/Drivers/TimerDxe/TimerDxe.inf
INF OvmfPkg/VirtNorFlashDxe/VirtNorFlashDxe.inf
INF ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.inf
INF MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf
#
@@ -141,11 +141,16 @@ READ_LOCK_STATUS = TRUE
#
# ACPI Support
#
INF OvmfPkg/PlatformHasAcpiDtDxe/PlatformHasAcpiDtDxe.inf
INF ArmVirtPkg/PlatformHasAcpiDtDxe/PlatformHasAcpiDtDxe.inf
!if $(ARCH) == AARCH64
INF MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
INF MdeModulePkg/Universal/Acpi/BootGraphicsResourceTableDxe/BootGraphicsResourceTableDxe.inf
INF OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf
#
# EBC support
#
INF MdeModulePkg/Universal/EbcDxe/EbcDxe.inf
!endif
#

View File

@@ -38,7 +38,7 @@
DEFINE NETWORK_SNP_ENABLE = FALSE
DEFINE NETWORK_TLS_ENABLE = FALSE
DEFINE NETWORK_ALLOW_HTTP_CONNECTIONS = TRUE
DEFINE NETWORK_ISCSI_ENABLE = FALSE
DEFINE NETWORK_ISCSI_ENABLE = TRUE
!if $(NETWORK_SNP_ENABLE) == TRUE
!error "NETWORK_SNP_ENABLE is IA32/X64/EBC only"
@@ -65,7 +65,7 @@
ArmVirtMemInfoLib|ArmVirtPkg/Library/QemuVirtMemInfoLib/QemuVirtMemInfoLib.inf
TimerLib|ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.inf
VirtNorFlashPlatformLib|ArmVirtPkg/Library/NorFlashQemuLib/NorFlashQemuLib.inf
NorFlashPlatformLib|ArmVirtPkg/Library/NorFlashQemuLib/NorFlashQemuLib.inf
CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf
BootLogoLib|MdeModulePkg/Library/BootLogoLib/BootLogoLib.inf
@@ -331,11 +331,7 @@
<LibraryClasses>
NULL|ArmVirtPkg/Library/ArmVirtTimerFdtClientLib/ArmVirtTimerFdtClientLib.inf
}
OvmfPkg/VirtNorFlashDxe/VirtNorFlashDxe.inf {
<LibraryClasses>
# don't use unaligned CopyMem () on the UEFI varstore NOR flash region
BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
}
ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.inf
MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf
#
@@ -461,7 +457,7 @@
#
# ACPI Support
#
OvmfPkg/PlatformHasAcpiDtDxe/PlatformHasAcpiDtDxe.inf
ArmVirtPkg/PlatformHasAcpiDtDxe/PlatformHasAcpiDtDxe.inf
[Components.AARCH64]
MdeModulePkg/Universal/Acpi/BootGraphicsResourceTableDxe/BootGraphicsResourceTableDxe.inf
OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf {

View File

@@ -201,6 +201,11 @@ READ_LOCK_STATUS = TRUE
!if $(ARCH) == AARCH64
INF MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
INF ArmVirtPkg/XenAcpiPlatformDxe/XenAcpiPlatformDxe.inf
#
# EBC support
#
INF MdeModulePkg/Universal/EbcDxe/EbcDxe.inf
!endif
#

View File

@@ -36,7 +36,7 @@
gEdkiiPlatformHasDeviceTreeGuid ## SOMETIMES_PRODUCES ## PROTOCOL
[Pcd]
gUefiOvmfPkgTokenSpaceGuid.PcdForceNoAcpi
gArmVirtTokenSpaceGuid.PcdForceNoAcpi
[Depex]
gEfiVariableArchProtocolGuid

View File

@@ -128,7 +128,7 @@ EDKII_PLATFORM_REPOSITORY_INFO mKvmtoolPlatRepositoryInfo = {
//
{
EFI_ACPI_6_3_IO_REMAPPING_TABLE_SIGNATURE,
EFI_ACPI_IO_REMAPPING_TABLE_REVISION_00,
EFI_ACPI_IO_REMAPPING_TABLE_REVISION,
CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdIort),
NULL
},

View File

@@ -21,7 +21,7 @@
KvmtoolPlatformDxe.c
[Packages]
OvmfPkg/OvmfPkg.dec
ArmVirtPkg/ArmVirtPkg.dec
EmbeddedPkg/EmbeddedPkg.dec
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
@@ -37,7 +37,7 @@
gEdkiiPlatformHasDeviceTreeGuid ## SOMETIMES_PRODUCES ## PROTOCOL
[Pcd]
gUefiOvmfPkgTokenSpaceGuid.PcdForceNoAcpi
gArmVirtTokenSpaceGuid.PcdForceNoAcpi
[Depex]
TRUE

View File

@@ -1,128 +0,0 @@
//
// Copyright (c) 2022, Google LLC. All rights reserved.
//
// SPDX-License-Identifier: BSD-2-Clause-Patent
//
//
#include <AsmMacroIoLibV8.h>
.macro mov_i, reg:req, imm:req
movz \reg, :abs_g1:\imm
movk \reg, :abs_g0_nc:\imm
.endm
.set MAIR_DEV_nGnRnE, 0x00
.set MAIR_MEM_NC, 0x44
.set MAIR_MEM_WT, 0xbb
.set MAIR_MEM_WBWA, 0xff
.set mairval, MAIR_DEV_nGnRnE | (MAIR_MEM_NC << 8) | (MAIR_MEM_WT << 16) | (MAIR_MEM_WBWA << 24)
.set TCR_TG0_4KB, 0x0 << 14
.set TCR_TG1_4KB, 0x2 << 30
.set TCR_IPS_SHIFT, 32
.set TCR_EPD1, 0x1 << 23
.set TCR_SH_INNER, 0x3 << 12
.set TCR_RGN_OWB, 0x1 << 10
.set TCR_RGN_IWB, 0x1 << 8
.set tcrval, TCR_TG0_4KB | TCR_TG1_4KB | TCR_EPD1 | TCR_RGN_OWB
.set tcrval, tcrval | TCR_RGN_IWB | TCR_SH_INNER
.set SCTLR_ELx_I, 0x1 << 12
.set SCTLR_ELx_SA, 0x1 << 3
.set SCTLR_ELx_C, 0x1 << 2
.set SCTLR_ELx_M, 0x1 << 0
.set SCTLR_EL1_SPAN, 0x1 << 23
.set SCTLR_EL1_WXN, 0x1 << 19
.set SCTLR_EL1_SED, 0x1 << 8
.set SCTLR_EL1_ITD, 0x1 << 7
.set SCTLR_EL1_RES1, (0x1 << 11) | (0x1 << 20) | (0x1 << 22) | (0x1 << 28) | (0x1 << 29)
.set sctlrval, SCTLR_ELx_M | SCTLR_ELx_C | SCTLR_ELx_SA | SCTLR_EL1_ITD | SCTLR_EL1_SED
.set sctlrval, sctlrval | SCTLR_ELx_I | SCTLR_EL1_SPAN | SCTLR_EL1_RES1
ASM_FUNC(ArmPlatformPeiBootAction)
#ifdef CAVIUM_ERRATUM_27456
/*
* On Cavium ThunderX, using non-global mappings that are executable at EL1
* results in I-cache corruption. So just avoid the early ID mapping there.
*
* MIDR implementor 0x43
* MIDR part numbers 0xA1 0xA2 (but not 0xAF)
*/
mrs x0, midr_el1 // read the MIDR into X0
ubfx x1, x0, #24, #8 // grab implementor id
ubfx x0, x0, #7, #9 // grab part number bits [11:3]
cmp x1, #0x43 // compare implementor id
ccmp x0, #0xA0 >> 3, #0, eq // compare part# bits [11:3]
b.eq 0f
#endif
mrs x0, CurrentEL // check current exception level
tbnz x0, #3, 0f // omit early ID map if above EL1
mov_i x0, mairval
mov_i x1, tcrval
adrp x2, idmap
orr x2, x2, #0xff << 48 // set non-zero ASID
mov_i x3, sctlrval
mrs x6, id_aa64mmfr0_el1 // get the supported PA range
and x6, x6, #0xf // isolate PArange bits
cmp x6, #6 // 0b0110 == 52 bits
sub x6, x6, #1 // subtract 1
cinc x6, x6, ne // add back 1 unless PArange == 52 bits
bfi x1, x6, #32, #3 // copy updated PArange into TCR_EL1.IPS
cmp x6, #3 // 0b0011 == 42 bits
sub x6, x6, #1 // subtract 1
cinc x6, x6, lt // add back 1 unless VA range >= 42
mov x7, #32
sub x6, x7, x6, lsl #2 // T0SZ for PArange != 42
mov x7, #64 - 42 // T0SZ for PArange == 42
csel x6, x6, x7, ne
orr x1, x1, x6 // set T0SZ field in TCR
cmp x6, #64 - 40 // VA size < 40 bits?
add x4, x2, #0x1000 // advance to level 1 descriptor
csel x2, x4, x2, gt
msr mair_el1, x0 // set up the 1:1 mapping
msr tcr_el1, x1
msr ttbr0_el1, x2
isb
tlbi vmalle1 // invalidate any cached translations
ic iallu // invalidate the I-cache
dsb nsh
isb
msr sctlr_el1, x3 // enable MMU and caches
isb
0:b ArmEnableVFP // enable SIMD before entering C code
//UINTN
//ArmPlatformGetCorePosition (
// IN UINTN MpId
// );
// With this function: CorePos = (ClusterId * 4) + CoreId
ASM_FUNC(ArmPlatformGetCorePosition)
mov x0, xzr
ret
//UINTN
//ArmPlatformGetPrimaryCoreMpId (
// VOID
// );
ASM_FUNC(ArmPlatformGetPrimaryCoreMpId)
MOV32 (w0, FixedPcdGet32 (PcdArmPrimaryCore))
ret
//UINTN
//ArmPlatformIsPrimaryCore (
// IN UINTN MpId
// );
ASM_FUNC(ArmPlatformIsPrimaryCore)
mov x0, #1
ret

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