Compare commits
97 Commits
Author | SHA1 | Date | |
---|---|---|---|
2b549700ac | |||
88f5720e16 | |||
27585e73da | |||
42a443d5cd | |||
c466cc2ca5 | |||
5c49aca613 | |||
99891bd41e | |||
3485d55709 | |||
c1a7127e01 | |||
2f21eddfb8 | |||
860c29c923 | |||
8cfead2839 | |||
30f6b2f3c7 | |||
4de32568fa | |||
ff91020528 | |||
943773983d | |||
e91ea5561d | |||
5e86b202de | |||
b764882195 | |||
a2abc5e15f | |||
a618e43977 | |||
bbc04972bc | |||
61a7f360d9 | |||
fc1c47ccad | |||
fec64b04eb | |||
05aa27ef23 | |||
06cc698885 | |||
cb870a1ce9 | |||
90e04a7e31 | |||
1d01d2a9a7 | |||
70e9b22f5c | |||
e9d6369050 | |||
58d6aae969 | |||
4e0fcaba18 | |||
2d04a62512 | |||
8a0955dfa8 | |||
06f4583ea5 | |||
9daa69a59e | |||
9030464a1b | |||
bcfe7a54aa | |||
600c565eb2 | |||
aae506ce44 | |||
bf2ca74bb6 | |||
654e5958cd | |||
9657bbe08f | |||
10cbbe06d3 | |||
802391f1fe | |||
db04386fd9 | |||
7d5abcd016 | |||
d296a36cc4 | |||
bdb15bf9ba | |||
25af751320 | |||
7f99fae217 | |||
c134065066 | |||
eec38fd383 | |||
b9564773f1 | |||
8c767bb014 | |||
7386ad5ae3 | |||
e727453a97 | |||
553bda4d8e | |||
3e7febc83c | |||
b664a5352c | |||
b376a7d60f | |||
3fb944f925 | |||
1d70aa7a9b | |||
0bef9ccd43 | |||
d3b38ea28a | |||
69ae47ba5d | |||
95c492569f | |||
d996a4bc9f | |||
9f528fb4c0 | |||
bbab5b95b4 | |||
5e84cc0714 | |||
2af54dd5bd | |||
00283317d8 | |||
232f661f99 | |||
552ca5cc88 | |||
94e7cfc7e7 | |||
de7030ed26 | |||
587653cd8b | |||
e167ed1a3d | |||
003534f8f0 | |||
a363907bc9 | |||
530cc53f96 | |||
112268c70d | |||
726280b214 | |||
b1ab82d4c8 | |||
2e16857f3d | |||
308f9a49b0 | |||
7ab09015b1 | |||
d1c0828262 | |||
b4dd94c217 | |||
f428f538b6 | |||
75b91c0b9f | |||
9f1dd0acb1 | |||
6db1a5555a | |||
72f8b9d80b |
@ -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"
|
||||
|
||||
|
@ -27,7 +27,7 @@ steps:
|
||||
|
||||
- task: UsePythonVersion@0
|
||||
inputs:
|
||||
versionSpec: '3.12'
|
||||
versionSpec: '3.7.x'
|
||||
architecture: 'x64'
|
||||
|
||||
- script: |
|
||||
|
@ -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'
|
||||
vm_image: 'windows-latest'
|
||||
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())
|
||||
|
||||
|
@ -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:
|
||||
|
@ -1,12 +0,0 @@
|
||||
## @file
|
||||
# File templates/default.yml
|
||||
#
|
||||
# template file containing common default values
|
||||
#
|
||||
# Copyright (c) Red Hat, Inc.
|
||||
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
##
|
||||
|
||||
variables:
|
||||
default_python_version: "3.12"
|
||||
default_linux_image: "ghcr.io/tianocore/containers/fedora-37-test:a0dd931"
|
@ -34,26 +34,16 @@ parameters:
|
||||
- name: extra_install_step
|
||||
type: stepList
|
||||
default: []
|
||||
- name: usePythonVersion
|
||||
type: string
|
||||
default: ''
|
||||
|
||||
steps:
|
||||
- bash: |
|
||||
echo "##vso[task.prependpath]${HOME}/.local/bin"
|
||||
echo "new PATH=${PATH}"
|
||||
displayName: Set PATH
|
||||
condition: eq('${{ parameters.tool_chain_tag }}', 'GCC5')
|
||||
|
||||
- checkout: self
|
||||
clean: true
|
||||
fetchDepth: 1
|
||||
|
||||
- task: UsePythonVersion@0
|
||||
inputs:
|
||||
versionSpec: ${{ parameters.usePythonVersion }}
|
||||
versionSpec: "3.8.x"
|
||||
architecture: "x64"
|
||||
condition: ne('${{ parameters.usePythonVersion }}', '')
|
||||
|
||||
- script: pip install -r pip-requirements.txt --upgrade
|
||||
displayName: 'Install/Upgrade pip modules'
|
||||
@ -116,7 +106,7 @@ steps:
|
||||
filename: stuart_build
|
||||
arguments: -c ${{ parameters.build_file }} TOOL_CHAIN_TAG=${{ parameters.tool_chain_tag}} TARGET=${{ parameters.build_target}} -a ${{ parameters.build_arch}} ${{ parameters.build_flags}} ${{ parameters.run_flags }} --FlashOnly
|
||||
condition: and(and(gt(variables.pkg_count, 0), succeeded()), eq(variables['Run'], true))
|
||||
timeoutInMinutes: 2
|
||||
timeoutInMinutes: 1
|
||||
|
||||
# Copy the build logs to the artifact staging directory
|
||||
- task: CopyFiles@2
|
||||
|
@ -12,22 +12,15 @@ parameters:
|
||||
tool_chain_tag: ''
|
||||
vm_image: ''
|
||||
arch_list: ''
|
||||
extra_install_step: []
|
||||
usePythonVersion: ''
|
||||
container: ''
|
||||
|
||||
# Build step
|
||||
jobs:
|
||||
|
||||
- job: Build_${{ parameters.tool_chain_tag }}
|
||||
timeoutInMinutes: 120
|
||||
|
||||
#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'
|
||||
@ -42,33 +35,24 @@ jobs:
|
||||
Build.Targets: 'RELEASE,NO-TARGET'
|
||||
TARGET_NETWORK:
|
||||
Build.Pkgs: 'NetworkPkg,RedfishPkg'
|
||||
Build.Targets: 'DEBUG,RELEASE,NO-TARGET,NOOPT'
|
||||
Build.Targets: 'DEBUG,RELEASE,NO-TARGET'
|
||||
TARGET_OTHER:
|
||||
Build.Pkgs: 'PcAtChipsetPkg,PrmPkg,ShellPkg,SourceLevelDebugPkg,StandaloneMmPkg,SignedCapsulePkg'
|
||||
Build.Targets: 'DEBUG,RELEASE,NO-TARGET,NOOPT'
|
||||
Build.Pkgs: 'PcAtChipsetPkg,ShellPkg,StandaloneMmPkg'
|
||||
Build.Targets: 'DEBUG,RELEASE,NO-TARGET'
|
||||
TARGET_FMP_FAT_TEST:
|
||||
Build.Pkgs: 'FmpDevicePkg,FatPkg,UnitTestFrameworkPkg,DynamicTablesPkg'
|
||||
Build.Targets: 'DEBUG,RELEASE,NO-TARGET,NOOPT'
|
||||
TARGET_CRYPTO_DEBUG:
|
||||
TARGET_CRYPTO:
|
||||
Build.Pkgs: 'CryptoPkg'
|
||||
Build.Targets: 'DEBUG,NOOPT'
|
||||
TARGET_CRYPTO_RELEASE:
|
||||
Build.Pkgs: 'CryptoPkg'
|
||||
Build.Targets: 'RELEASE,NO-TARGET'
|
||||
TARGET_FSP:
|
||||
Build.Pkgs: 'IntelFsp2Pkg,IntelFsp2WrapperPkg'
|
||||
Build.Targets: 'DEBUG,RELEASE,NO-TARGET,NOOPT'
|
||||
TARGET_SECURITY:
|
||||
Build.Pkgs: 'SecurityPkg'
|
||||
Build.Targets: 'DEBUG,RELEASE,NO-TARGET,NOOPT'
|
||||
TARGET_UEFIPAYLOAD:
|
||||
Build.Pkgs: 'UefiPayloadPkg'
|
||||
Build.Targets: 'DEBUG,RELEASE,NO-TARGET,NOOPT'
|
||||
Build.Targets: 'DEBUG,RELEASE,NO-TARGET'
|
||||
TARGET_PLATFORMS:
|
||||
# For Platforms only check code. Leave it to Platform CI
|
||||
# to build them.
|
||||
Build.Pkgs: 'ArmVirtPkg,EmulatorPkg,OvmfPkg'
|
||||
Build.Targets: 'NO-TARGET,NOOPT'
|
||||
Build.Targets: 'NO-TARGET'
|
||||
|
||||
workspace:
|
||||
clean: all
|
||||
@ -76,9 +60,6 @@ jobs:
|
||||
pool:
|
||||
vmImage: ${{ parameters.vm_image }}
|
||||
|
||||
${{ if not(eq(parameters.container, '')) }}:
|
||||
container: ${{ parameters.container }}
|
||||
|
||||
steps:
|
||||
- template: pr-gate-steps.yml
|
||||
parameters:
|
||||
@ -86,47 +67,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)
|
||||
|
||||
|
@ -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()
|
||||
|
||||
|
@ -17,6 +17,6 @@ steps:
|
||||
#checkLatest: false # Optional
|
||||
condition: and(gt(variables.pkg_count, 0), succeeded())
|
||||
|
||||
- script: npm install -g cspell@5.20.0
|
||||
- script: npm install -g cspell
|
||||
displayName: 'Install cspell npm'
|
||||
condition: and(gt(variables.pkg_count, 0), succeeded())
|
||||
|
@ -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"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
@ -1,31 +0,0 @@
|
||||
# EditorConfig file: https://EditorConfig.org
|
||||
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = latin1
|
||||
end_of_line = crlf
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[*.py]
|
||||
charset = utf-8
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
|
||||
[*.sh]
|
||||
end_of_line = lf
|
||||
|
||||
[.gitattributes]
|
||||
end_of_line = lf
|
||||
|
||||
[.mailmap]
|
||||
charset = utf-8
|
||||
|
||||
[Maintainers.txt]
|
||||
charset = utf-8
|
||||
|
||||
[Makefile,GNUmakefile]
|
||||
indent_style = tab
|
@ -1,56 +0,0 @@
|
||||
# PrmPkg: Apply uncrustify changes
|
||||
a298a84478053872ed9da660a75f182ce81b8ddc
|
||||
# UnitTestFrameworkPkg: Apply uncrustify changes
|
||||
7c0ad2c33810ead45b7919f8f8d0e282dae52e71
|
||||
# UefiPayloadPkg: Apply uncrustify changes
|
||||
e5efcf8be8a1bf59aa98875787475e3144ee4cef
|
||||
# UefiCpuPkg: Apply uncrustify changes
|
||||
053e878bfb5c9d5eca779789b62891add30b14ba
|
||||
# StandaloneMmPkg: Apply uncrustify changes
|
||||
91415a36ae7aaeabb2bbab3762f39544f9aed683
|
||||
# SourceLevelDebugPkg: Apply uncrustify changes
|
||||
c1e126b1196de75e0a4cda21e4551ea9bb05e059
|
||||
# SignedCapsulePkg: Apply uncrustify changes
|
||||
b87864896714cf3062a7bc6d577d8fbd62d105e5
|
||||
# ShellPkg: Apply uncrustify changes
|
||||
47d20b54f9a65b08aa602a1866c1b59a69088dfc
|
||||
# SecurityPkg: Apply uncrustify changes
|
||||
c411b485b63a671a1e276700cff025c73997233c
|
||||
# RedfishPkg: Apply uncrustify changes
|
||||
39de741e2dcb8f11e9b4438e37224797643d8451
|
||||
# PcAtChipsetPkg: Apply uncrustify changes
|
||||
5220bd211df890f2672c23c050082862cd1e82d6
|
||||
# OvmfPkg: Apply uncrustify changes
|
||||
ac0a286f4d747a4c6c603a7b225917293cbe1e9f
|
||||
# NetworkPkg: Apply uncrustify changes
|
||||
d1050b9dff1cace252aff86630bfdb59dff5f507
|
||||
# MdePkg: Apply uncrustify changes
|
||||
2f88bd3a1296c522317f1c21377876de63de5be7
|
||||
# MdeModulePkg: Apply uncrustify changes
|
||||
1436aea4d5707e672672a11bda72be2c63c936c3
|
||||
# IntelFsp2WrapperPkg: Apply uncrustify changes
|
||||
7c7184e201a90a1d2376e615e55e3f4074731468
|
||||
# IntelFsp2Pkg: Apply uncrustify changes
|
||||
111f2228ddf487b0ac3491e416bb3dcdcfa4f979
|
||||
# FmpDevicePkg: Apply uncrustify changes
|
||||
45ce0a67bb4ee80f27da93777c623f51f344f23b
|
||||
# FatPkg: Apply uncrustify changes
|
||||
bcdcc4160d7460c46c08c9395aae81be44ef23a9
|
||||
# EmulatorPkg: Apply uncrustify changes
|
||||
a550d468a6ca577d9e9c57a0eafcf2fc9fbb8c97
|
||||
# EmbeddedPkg: Apply uncrustify changes
|
||||
e7108d0e9655b1795c94ac372b0449f28dd907df
|
||||
# DynamicTablesPkg: Apply uncrustify changes
|
||||
731c67e1d77b7741a91762d17659fc9fbcb9e305
|
||||
# CryptoPkg: Apply uncrustify changes
|
||||
7c342378317039e632d9a1a5d4cf7c21aec8cb7a
|
||||
# ArmVirtPkg: Apply uncrustify changes
|
||||
2b16a4fb91b9b31c0d152588f5ac51080c6c0763
|
||||
# ArmPlatformPkg: Apply uncrustify changes
|
||||
40b0b23ed34f48c26d711d3e4613a4bb35eeadff
|
||||
# ArmPkg: Apply uncrustify changes
|
||||
429309e0c6b74792d679681a8edd0d5ae0ff850c
|
||||
# EmulatorPkg: Format with Uncrustify 73.0.8
|
||||
972e3b0b9d67ef2847c9c1c89e606e6074a7ddda
|
||||
# OvmfPkg: Format with Uncrustify 73.0.8
|
||||
0e9ce9146a6dc50a35488e3a4a7a2a4bbaf1eb1c
|
24
.github/ISSUE_TEMPLATE/config.yml
vendored
24
.github/ISSUE_TEMPLATE/config.yml
vendored
@ -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
|
36
.github/dependabot.yml
vendored
36
.github/dependabot.yml
vendored
@ -1,36 +0,0 @@
|
||||
## @file
|
||||
# Dependabot configuration file to enable GitHub services for managing and updating
|
||||
# dependencies.
|
||||
#
|
||||
# Copyright (c) Microsoft Corporation.
|
||||
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
#
|
||||
# Please see the documentation for all configuration options:
|
||||
# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
|
||||
##
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: "pip"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "daily"
|
||||
commit-message:
|
||||
prefix: "pip"
|
||||
reviewers:
|
||||
- "makubacki"
|
||||
- "mdkinney"
|
||||
- "spbrogan"
|
||||
rebase-strategy: "disabled"
|
||||
|
||||
- package-ecosystem: "github-actions"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
day: "monday"
|
||||
commit-message:
|
||||
prefix: "GitHub Action"
|
||||
reviewers:
|
||||
- "makubacki"
|
||||
- "mdkinney"
|
||||
- "spbrogan"
|
||||
rebase-strategy: "disabled"
|
27
.github/pull_request_template.md
vendored
27
.github/pull_request_template.md
vendored
@ -1,27 +0,0 @@
|
||||
# Description
|
||||
|
||||
<_Include a description of the change and why this change was made._>
|
||||
|
||||
<_For each item, place an "x" in between `[` and `]` if true. Example: `[x]` (you can also check items in GitHub UI)_>
|
||||
|
||||
<_Create the PR as a Draft PR if it is only created to run CI checks._>
|
||||
|
||||
<_Delete lines in \<\> tags before creating the PR._>
|
||||
|
||||
- [ ] Breaking change?
|
||||
- **Breaking change** - Will this cause a break in build or boot behavior?
|
||||
- Examples: Add a new library class or move a module to a different repo.
|
||||
- [ ] Impacts security?
|
||||
- **Security** - Does the change have a direct security impact?
|
||||
- Examples: Crypto algorithm change or buffer overflow fix.
|
||||
- [ ] Includes tests?
|
||||
- **Tests** - Does the change include any explicit test code?
|
||||
- Examples: Unit tests or integration tests.
|
||||
|
||||
## How This Was Tested
|
||||
|
||||
<_Describe the test(s) that were run to verify the changes._>
|
||||
|
||||
## Integration Instructions
|
||||
|
||||
<_Describe how these changes should be integrated. Use N/A if nothing is required._>
|
361
.github/workflows/codeql.yml
vendored
361
.github/workflows/codeql.yml
vendored
@ -1,361 +0,0 @@
|
||||
# This workflow runs CodeQL against the repository.
|
||||
#
|
||||
# Results are uploaded to GitHub Code Scanning.
|
||||
#
|
||||
# Due to a known issue with the CodeQL extractor when building the edk2
|
||||
# codebase on Linux systems, only Windows agents are used for build with
|
||||
# the VS toolchain.
|
||||
#
|
||||
# Copyright (c) Microsoft Corporation.
|
||||
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
name: "CodeQL"
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
paths-ignore:
|
||||
- '!**.c'
|
||||
- '!**.h'
|
||||
|
||||
jobs:
|
||||
analyze:
|
||||
name: Analyze
|
||||
runs-on: windows-2019
|
||||
permissions:
|
||||
actions: read
|
||||
contents: read
|
||||
security-events: write
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- Package: "ArmPkg"
|
||||
ArchList: "IA32,X64"
|
||||
- Package: "CryptoPkg"
|
||||
ArchList: "IA32"
|
||||
- Package: "CryptoPkg"
|
||||
ArchList: "X64"
|
||||
- Package: "DynamicTablesPkg"
|
||||
ArchList: "IA32,X64"
|
||||
- Package: "FatPkg"
|
||||
ArchList: "IA32,X64"
|
||||
- Package: "FmpDevicePkg"
|
||||
ArchList: "IA32,X64"
|
||||
- Package: "IntelFsp2Pkg"
|
||||
ArchList: "IA32,X64"
|
||||
- Package: "IntelFsp2WrapperPkg"
|
||||
ArchList: "IA32,X64"
|
||||
- Package: "MdeModulePkg"
|
||||
ArchList: "IA32"
|
||||
- Package: "MdeModulePkg"
|
||||
ArchList: "X64"
|
||||
- Package: "MdePkg"
|
||||
ArchList: "IA32,X64"
|
||||
- Package: "PcAtChipsetPkg"
|
||||
ArchList: "IA32,X64"
|
||||
- Package: "PrmPkg"
|
||||
ArchList: "IA32,X64"
|
||||
- Package: "SecurityPkg"
|
||||
ArchList: "IA32,X64"
|
||||
- Package: "ShellPkg"
|
||||
ArchList: "IA32,X64"
|
||||
- Package: "SourceLevelDebugPkg"
|
||||
ArchList: "IA32,X64"
|
||||
- Package: "StandaloneMmPkg"
|
||||
ArchList: "IA32,X64"
|
||||
- Package: "UefiCpuPkg"
|
||||
ArchList: "IA32,X64"
|
||||
- Package: "UnitTestFrameworkPkg"
|
||||
ArchList: "IA32,X64"
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install Python
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.11'
|
||||
cache: 'pip'
|
||||
cache-dependency-path: 'pip-requirements.txt'
|
||||
|
||||
- name: Use Git Long Paths on Windows
|
||||
if: runner.os == 'Windows'
|
||||
shell: pwsh
|
||||
run: |
|
||||
git config --system core.longpaths true
|
||||
|
||||
- name: Install/Upgrade pip Modules
|
||||
run: pip install -r pip-requirements.txt --upgrade requests sarif-tools
|
||||
|
||||
- name: Determine CI Settings File Supported Operations
|
||||
id: get_ci_file_operations
|
||||
shell: python
|
||||
run: |
|
||||
import importlib
|
||||
import os
|
||||
import sys
|
||||
from pathlib import Path
|
||||
from edk2toolext.invocables.edk2_ci_setup import CiSetupSettingsManager
|
||||
from edk2toolext.invocables.edk2_setup import SetupSettingsManager
|
||||
|
||||
# Find the repo CI Settings file
|
||||
ci_settings_file = list(Path(os.environ['GITHUB_WORKSPACE']).rglob('.pytool/CISettings.py'))
|
||||
|
||||
# Note: At this point, submodules have not been pulled, only one CI Settings file should exist
|
||||
if len(ci_settings_file) != 1 or not ci_settings_file[0].is_file():
|
||||
print("::error title=Workspace Error!::Failed to find CI Settings file!")
|
||||
sys.exit(1)
|
||||
|
||||
ci_settings_file = ci_settings_file[0]
|
||||
|
||||
# Try Finding the Settings class in the file
|
||||
module_name = 'ci_settings'
|
||||
|
||||
spec = importlib.util.spec_from_file_location(module_name, ci_settings_file)
|
||||
module = importlib.util.module_from_spec(spec)
|
||||
spec.loader.exec_module(module)
|
||||
|
||||
try:
|
||||
settings = getattr(module, 'Settings')
|
||||
except AttributeError:
|
||||
print("::error title=Workspace Error!::Failed to find Settings class in CI Settings file!")
|
||||
sys.exit(1)
|
||||
|
||||
# Determine Which Operations Are Supported by the Settings Class
|
||||
ci_setup_supported = issubclass(settings, CiSetupSettingsManager)
|
||||
setup_supported = issubclass(settings, SetupSettingsManager)
|
||||
|
||||
with open(os.environ['GITHUB_OUTPUT'], 'a') as fh:
|
||||
print(f'ci_setup_supported={str(ci_setup_supported).lower()}', file=fh)
|
||||
print(f'setup_supported={str(setup_supported).lower()}', file=fh)
|
||||
|
||||
- name: Convert Arch to Log Format
|
||||
id: convert_arch_hyphen
|
||||
env:
|
||||
ARCH_LIST: ${{ matrix.ArchList }}
|
||||
shell: python
|
||||
run: |
|
||||
import os
|
||||
|
||||
with open(os.environ['GITHUB_OUTPUT'], 'a') as fh:
|
||||
print(f'arch_list={os.environ["ARCH_LIST"].replace(",", "-")}', file=fh)
|
||||
|
||||
- name: Setup
|
||||
if: steps.get_ci_file_operations.outputs.setup_supported == 'true'
|
||||
run: stuart_setup -c .pytool/CISettings.py -t DEBUG -a ${{ matrix.ArchList }} TOOL_CHAIN_TAG=VS2019
|
||||
|
||||
- name: Upload Setup Log As An Artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
if: (success() || failure()) && steps.get_ci_file_operations.outputs.setup_supported == 'true'
|
||||
with:
|
||||
name: ${{ matrix.Package }}-${{ steps.convert_arch_hyphen.outputs.arch_list }}-Setup-Log
|
||||
path: |
|
||||
**/SETUPLOG.txt
|
||||
retention-days: 7
|
||||
if-no-files-found: ignore
|
||||
|
||||
- name: CI Setup
|
||||
if: steps.get_ci_file_operations.outputs.ci_setup_supported == 'true'
|
||||
run: stuart_ci_setup -c .pytool/CISettings.py -t DEBUG -a ${{ matrix.ArchList }} TOOL_CHAIN_TAG=VS2019
|
||||
|
||||
- name: Upload CI Setup Log As An Artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
if: (success() || failure()) && steps.get_ci_file_operations.outputs.ci_setup_supported == 'true'
|
||||
with:
|
||||
name: ${{ matrix.Package }}-${{ steps.convert_arch_hyphen.outputs.arch_list }}-CI-Setup-Log
|
||||
path: |
|
||||
**/CISETUP.txt
|
||||
retention-days: 7
|
||||
if-no-files-found: ignore
|
||||
|
||||
- name: Update
|
||||
run: stuart_update -c .pytool/CISettings.py -t DEBUG -a ${{ matrix.ArchList }} TOOL_CHAIN_TAG=VS2019
|
||||
|
||||
- name: Upload Update Log As An Artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
if: success() || failure()
|
||||
with:
|
||||
name: ${{ matrix.Package }}-${{ steps.convert_arch_hyphen.outputs.arch_list }}-Update-Log
|
||||
path: |
|
||||
**/UPDATE_LOG.txt
|
||||
retention-days: 7
|
||||
if-no-files-found: ignore
|
||||
|
||||
- name: Build Tools From Source
|
||||
run: python BaseTools/Edk2ToolsBuild.py -t VS2019
|
||||
|
||||
- name: Find CodeQL Plugin Directory
|
||||
id: find_dir
|
||||
shell: python
|
||||
run: |
|
||||
import os
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
# Find the plugin directory that contains the CodeQL plugin
|
||||
plugin_dir = list(Path(os.environ['GITHUB_WORKSPACE']).rglob('BaseTools/Plugin/CodeQL'))
|
||||
|
||||
# This should only be found once
|
||||
if len(plugin_dir) == 1:
|
||||
plugin_dir = str(plugin_dir[0])
|
||||
|
||||
with open(os.environ['GITHUB_OUTPUT'], 'a') as fh:
|
||||
print(f'codeql_plugin_dir={plugin_dir}', file=fh)
|
||||
else:
|
||||
print("::error title=Workspace Error!::Failed to find CodeQL plugin directory!")
|
||||
sys.exit(1)
|
||||
|
||||
- name: Get CodeQL CLI Cache Data
|
||||
id: cache_key_gen
|
||||
env:
|
||||
CODEQL_PLUGIN_DIR: ${{ steps.find_dir.outputs.codeql_plugin_dir }}
|
||||
shell: python
|
||||
run: |
|
||||
import os
|
||||
import yaml
|
||||
|
||||
codeql_cli_ext_dep_name = 'codeqlcli_windows_ext_dep'
|
||||
codeql_plugin_file = os.path.join(os.environ['CODEQL_PLUGIN_DIR'], codeql_cli_ext_dep_name + '.yaml')
|
||||
|
||||
with open (codeql_plugin_file) as pf:
|
||||
codeql_cli_ext_dep = yaml.safe_load(pf)
|
||||
|
||||
cache_key_name = codeql_cli_ext_dep['name']
|
||||
cache_key_version = codeql_cli_ext_dep['version']
|
||||
cache_key = f'{cache_key_name}-{cache_key_version}'
|
||||
|
||||
codeql_plugin_cli_ext_dep_dir = os.path.join(os.environ['CODEQL_PLUGIN_DIR'], codeql_cli_ext_dep['name'].strip() + '_extdep')
|
||||
|
||||
with open(os.environ['GITHUB_OUTPUT'], 'a') as fh:
|
||||
print(f'codeql_cli_cache_key={cache_key}', file=fh)
|
||||
print(f'codeql_cli_ext_dep_dir={codeql_plugin_cli_ext_dep_dir}', file=fh)
|
||||
|
||||
- name: Attempt to Load CodeQL CLI From Cache
|
||||
id: codeqlcli_cache
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ${{ steps.cache_key_gen.outputs.codeql_cli_ext_dep_dir }}
|
||||
key: ${{ steps.cache_key_gen.outputs.codeql_cli_cache_key }}
|
||||
|
||||
- name: Download CodeQL CLI
|
||||
if: steps.codeqlcli_cache.outputs.cache-hit != 'true'
|
||||
run: stuart_update -c .pytool/CISettings.py -t DEBUG -a ${{ matrix.ArchList }} TOOL_CHAIN_TAG=VS2019 --codeql
|
||||
|
||||
- name: Remove CI Plugins Irrelevant to CodeQL
|
||||
shell: python
|
||||
env:
|
||||
CODEQL_PLUGIN_DIR: ${{ steps.find_dir.outputs.codeql_plugin_dir }}
|
||||
run: |
|
||||
import os
|
||||
import shutil
|
||||
from pathlib import Path
|
||||
|
||||
# Only these two plugins are needed for CodeQL
|
||||
plugins_to_keep = ['CompilerPlugin']
|
||||
|
||||
plugin_dir = Path('.pytool/Plugin').absolute()
|
||||
if plugin_dir.is_dir():
|
||||
for dir in plugin_dir.iterdir():
|
||||
if str(dir.stem) not in plugins_to_keep:
|
||||
shutil.rmtree(str(dir.absolute()), ignore_errors=True)
|
||||
|
||||
- name: CI Build
|
||||
env:
|
||||
STUART_CODEQL_PATH: ${{ steps.cache_key_gen.outputs.codeql_cli_ext_dep_dir }}
|
||||
run: stuart_ci_build -c .pytool/CISettings.py -t DEBUG -p ${{ matrix.Package }} -a ${{ matrix.ArchList }} TOOL_CHAIN_TAG=VS2019 --codeql
|
||||
|
||||
- name: Build Cleanup
|
||||
id: build_cleanup
|
||||
shell: python
|
||||
run: |
|
||||
import os
|
||||
import shutil
|
||||
from pathlib import Path
|
||||
|
||||
dirs_to_delete = ['ia32', 'x64', 'arm', 'aarch64']
|
||||
|
||||
def delete_dirs(path: Path):
|
||||
if path.exists() and path.is_dir():
|
||||
if path.name.lower() in dirs_to_delete:
|
||||
print(f'Removed {str(path)}')
|
||||
shutil.rmtree(path)
|
||||
return
|
||||
|
||||
for child_dir in path.iterdir():
|
||||
delete_dirs(child_dir)
|
||||
|
||||
build_path = Path(os.environ['GITHUB_WORKSPACE'], 'Build')
|
||||
delete_dirs(build_path)
|
||||
|
||||
- name: Upload Build Logs As An Artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
if: success() || failure()
|
||||
with:
|
||||
name: ${{ matrix.Package }}-${{ steps.convert_arch_hyphen.outputs.arch_list }}-Build-Logs
|
||||
path: |
|
||||
**/BUILD_REPORT.TXT
|
||||
**/OVERRIDELOG.TXT
|
||||
**/BUILDLOG_*.md
|
||||
**/BUILDLOG_*.txt
|
||||
**/CI_*.md
|
||||
**/CI_*.txt
|
||||
retention-days: 7
|
||||
if-no-files-found: ignore
|
||||
|
||||
- name: Prepare Env Data for CodeQL Upload
|
||||
id: env_data
|
||||
env:
|
||||
PACKAGE_NAME: ${{ matrix.Package }}
|
||||
shell: python
|
||||
run: |
|
||||
import logging
|
||||
import os
|
||||
from edk2toollib.utility_functions import RunCmd
|
||||
from io import StringIO
|
||||
from pathlib import Path
|
||||
|
||||
package = os.environ['PACKAGE_NAME'].strip().lower()
|
||||
directory_name = 'codeql-analysis-' + package + '-debug'
|
||||
file_name = 'codeql-db-' + package + '-debug-0.sarif'
|
||||
sarif_path = Path('Build', directory_name, file_name)
|
||||
|
||||
with open(os.environ['GITHUB_OUTPUT'], 'a') as fh:
|
||||
if sarif_path.is_file():
|
||||
emacs_file_path = sarif_path.with_name(sarif_path.stem + "-emacs.txt")
|
||||
out_stream_buffer = StringIO()
|
||||
exit_code = RunCmd("sarif", f"emacs {sarif_path} --output {emacs_file_path} --no-autotrim",
|
||||
outstream=out_stream_buffer,
|
||||
logging_level=logging.NOTSET)
|
||||
print(f'upload_sarif_file=true', file=fh)
|
||||
print(f'emacs_file_path={emacs_file_path}', file=fh)
|
||||
print(f'sarif_file_path={sarif_path}', file=fh)
|
||||
else:
|
||||
print(f'upload_sarif_file=false', file=fh)
|
||||
|
||||
- name: Upload CodeQL Results (SARIF) As An Artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
if: steps.env_data.outputs.upload_sarif_file == 'true'
|
||||
with:
|
||||
name: ${{ matrix.Package }}-${{ steps.convert_arch_hyphen.outputs.arch_list }}-CodeQL-SARIF
|
||||
path: |
|
||||
${{ steps.env_data.outputs.emacs_file_path }}
|
||||
${{ steps.env_data.outputs.sarif_file_path }}
|
||||
retention-days: 14
|
||||
if-no-files-found: warn
|
||||
|
||||
- name: Upload CodeQL Results (SARIF) To GitHub Code Scanning
|
||||
uses: github/codeql-action/upload-sarif@v3
|
||||
if: steps.env_data.outputs.upload_sarif_file == 'true'
|
||||
with:
|
||||
# Path to SARIF file relative to the root of the repository.
|
||||
sarif_file: ${{ steps.env_data.outputs.sarif_file_path }}
|
||||
# Optional category for the results. Used to differentiate multiple results for one commit.
|
||||
# Each package is a separate category.
|
||||
category: ${{ matrix.Package }}
|
36
.github/workflows/pr-labeler.yml
vendored
36
.github/workflows/pr-labeler.yml
vendored
@ -1,36 +0,0 @@
|
||||
# This workflow automatically applies labels to pull requests based on regular expression matches against the content
|
||||
# in the pull request.
|
||||
#
|
||||
# Copyright (c) Microsoft Corporation.
|
||||
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
#
|
||||
# For more information, see:
|
||||
# https://github.com/github/issue-labeler
|
||||
|
||||
name: Apply Labels Based on Message Content
|
||||
|
||||
on:
|
||||
pull_request_target:
|
||||
types:
|
||||
- edited
|
||||
- opened
|
||||
- reopened
|
||||
- synchronize
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
sync:
|
||||
name: Label PR from Description
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: write
|
||||
|
||||
steps:
|
||||
- name: Apply Labels Based on PR Description
|
||||
uses: github/issue-labeler@v3.1
|
||||
with:
|
||||
configuration-path: .github/workflows/pr-labeler/regex.yml
|
||||
enable-versioned-regex: 0
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
16
.github/workflows/pr-labeler/regex.yml
vendored
16
.github/workflows/pr-labeler/regex.yml
vendored
@ -1,16 +0,0 @@
|
||||
# Specifies labels to apply to pull requests based on regular expressions.
|
||||
#
|
||||
# Copyright (c) Microsoft Corporation.
|
||||
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
#
|
||||
# For more information, see:
|
||||
# https://github.com/github/issue-labeler
|
||||
|
||||
impact:breaking-change:
|
||||
- '\s*-\s*\[\s*[x|X]\s*\] Breaking change\?'
|
||||
|
||||
impact:security:
|
||||
- '\s*-\s*\[\s*[x|X]\s*\] Impacts security\?'
|
||||
|
||||
impact:testing:
|
||||
- '\s*-\s*\[\s*[x|X]\s*\] Includes tests\?'
|
44
.github/workflows/stale.yml
vendored
44
.github/workflows/stale.yml
vendored
@ -1,44 +0,0 @@
|
||||
# This workflow warns and then closes issues and PRs that have had no activity
|
||||
# for a specified amount of time.
|
||||
#
|
||||
# For more information, see:
|
||||
# https://github.com/actions/stale
|
||||
#
|
||||
# Copyright (c) Microsoft Corporation.
|
||||
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
#
|
||||
|
||||
name: Stale Check
|
||||
|
||||
on:
|
||||
schedule:
|
||||
# At 23:35 on every day-of-week from Sunday through Saturday
|
||||
# https://crontab.guru/#35_23_*_*_0-6
|
||||
- cron: '35 23 * * 0-6'
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
stale:
|
||||
name: Stale
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
issues: write
|
||||
pull-requests: write
|
||||
|
||||
steps:
|
||||
- name: Check for Stale Items
|
||||
uses: actions/stale@v8
|
||||
with:
|
||||
days-before-issue-close: -1
|
||||
days-before-issue-stale: -1
|
||||
days-before-pr-stale: 60
|
||||
days-before-pr-close: 7
|
||||
stale-pr-message: >
|
||||
This PR has been automatically marked as stale because it has not had
|
||||
activity in 60 days. It will be closed if no further activity occurs within
|
||||
7 days. Thank you for your contributions.
|
||||
close-pr-message: >
|
||||
This pull request has been automatically been closed because it did not have any
|
||||
activity in 60 days and no follow up within 7 days after being marked stale.
|
||||
Thank you for your contributions.
|
||||
stale-pr-label: stale
|
18
.gitmodules
vendored
18
.gitmodules
vendored
@ -20,21 +20,3 @@
|
||||
[submodule "RedfishPkg/Library/JsonLib/jansson"]
|
||||
path = RedfishPkg/Library/JsonLib/jansson
|
||||
url = https://github.com/akheron/jansson
|
||||
[submodule "UnitTestFrameworkPkg/Library/GoogleTestLib/googletest"]
|
||||
path = UnitTestFrameworkPkg/Library/GoogleTestLib/googletest
|
||||
url = https://github.com/google/googletest.git
|
||||
[submodule "UnitTestFrameworkPkg/Library/SubhookLib/subhook"]
|
||||
path = UnitTestFrameworkPkg/Library/SubhookLib/subhook
|
||||
url = https://github.com/Zeex/subhook.git
|
||||
[submodule "MdePkg/Library/BaseFdtLib/libfdt"]
|
||||
path = MdePkg/Library/BaseFdtLib/libfdt
|
||||
url = https://github.com/devicetree-org/pylibfdt.git
|
||||
[submodule "MdePkg/Library/MipiSysTLib/mipisyst"]
|
||||
path = MdePkg/Library/MipiSysTLib/mipisyst
|
||||
url = https://github.com/MIPI-Alliance/public-mipi-sys-t.git
|
||||
[submodule "CryptoPkg/Library/MbedTlsLib/mbedtls"]
|
||||
path = CryptoPkg/Library/MbedTlsLib/mbedtls
|
||||
url = https://github.com/ARMmbed/mbedtls
|
||||
[submodule "SecurityPkg/DeviceSecurity/SpdmLib/libspdm"]
|
||||
path = SecurityPkg/DeviceSecurity/SpdmLib/libspdm
|
||||
url = https://github.com/DMTF/libspdm.git
|
||||
|
@ -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
|
||||
|
@ -7,27 +7,12 @@
|
||||
##
|
||||
import os
|
||||
import logging
|
||||
import sys
|
||||
from edk2toolext.environment import shell_environment
|
||||
from edk2toolext.invocables.edk2_ci_build import CiBuildSettingsManager
|
||||
from edk2toolext.invocables.edk2_setup import SetupSettingsManager, RequiredSubmodule
|
||||
from edk2toolext.invocables.edk2_update import UpdateSettingsManager
|
||||
from edk2toolext.invocables.edk2_pr_eval import PrEvalSettingsManager
|
||||
from edk2toollib.utility_functions import GetHostInfo
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
try:
|
||||
# Temporarily needed until edk2 can update to the latest edk2-pytools
|
||||
# that has the CodeQL helpers.
|
||||
#
|
||||
# May not be present until submodules are populated.
|
||||
#
|
||||
root = Path(__file__).parent.parent.resolve()
|
||||
sys.path.append(str(root/'BaseTools'/'Plugin'/'CodeQL'/'integration'))
|
||||
import stuart_codeql as codeql_helpers
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
|
||||
class Settings(CiBuildSettingsManager, UpdateSettingsManager, SetupSettingsManager, PrEvalSettingsManager):
|
||||
@ -49,11 +34,6 @@ class Settings(CiBuildSettingsManager, UpdateSettingsManager, SetupSettingsManag
|
||||
group.add_argument("-force_piptools", "--fpt", dest="force_piptools", action="store_true", default=False, help="Force the system to use pip tools")
|
||||
group.add_argument("-no_piptools", "--npt", dest="no_piptools", action="store_true", default=False, help="Force the system to not use pip tools")
|
||||
|
||||
try:
|
||||
codeql_helpers.add_command_line_option(parserObj)
|
||||
except NameError:
|
||||
pass
|
||||
|
||||
def RetrieveCommandLineOptions(self, args):
|
||||
super().RetrieveCommandLineOptions(args)
|
||||
if args.force_piptools:
|
||||
@ -61,11 +41,6 @@ class Settings(CiBuildSettingsManager, UpdateSettingsManager, SetupSettingsManag
|
||||
if args.no_piptools:
|
||||
self.UseBuiltInBaseTools = False
|
||||
|
||||
try:
|
||||
self.codeql = codeql_helpers.is_codeql_enabled_on_command_line(args)
|
||||
except NameError:
|
||||
pass
|
||||
|
||||
# ####################################################################################### #
|
||||
# Default Support for this Ci Build #
|
||||
# ####################################################################################### #
|
||||
@ -78,10 +53,7 @@ class Settings(CiBuildSettingsManager, UpdateSettingsManager, SetupSettingsManag
|
||||
"ArmPlatformPkg",
|
||||
"ArmVirtPkg",
|
||||
"DynamicTablesPkg",
|
||||
"EmbeddedPkg",
|
||||
"EmulatorPkg",
|
||||
"IntelFsp2Pkg",
|
||||
"IntelFsp2WrapperPkg",
|
||||
"MdePkg",
|
||||
"MdeModulePkg",
|
||||
"NetworkPkg",
|
||||
@ -90,16 +62,12 @@ class Settings(CiBuildSettingsManager, UpdateSettingsManager, SetupSettingsManag
|
||||
"UefiCpuPkg",
|
||||
"FmpDevicePkg",
|
||||
"ShellPkg",
|
||||
"SignedCapsulePkg",
|
||||
"StandaloneMmPkg",
|
||||
"FatPkg",
|
||||
"CryptoPkg",
|
||||
"PrmPkg",
|
||||
"UnitTestFrameworkPkg",
|
||||
"OvmfPkg",
|
||||
"RedfishPkg",
|
||||
"SourceLevelDebugPkg",
|
||||
"UefiPayloadPkg"
|
||||
"RedfishPkg"
|
||||
)
|
||||
|
||||
def GetArchitecturesSupported(self):
|
||||
@ -109,8 +77,7 @@ class Settings(CiBuildSettingsManager, UpdateSettingsManager, SetupSettingsManag
|
||||
"X64",
|
||||
"ARM",
|
||||
"AARCH64",
|
||||
"RISCV64",
|
||||
"LOONGARCH64")
|
||||
"RISCV64")
|
||||
|
||||
def GetTargetsSupported(self):
|
||||
''' return iterable of edk2 target tags supported by this build '''
|
||||
@ -194,17 +161,13 @@ class Settings(CiBuildSettingsManager, UpdateSettingsManager, SetupSettingsManag
|
||||
else:
|
||||
logging.warning("Falling back to using in-tree BaseTools")
|
||||
|
||||
try:
|
||||
scopes += codeql_helpers.get_scopes(self.codeql)
|
||||
|
||||
if self.codeql:
|
||||
shell_environment.GetBuildVars().SetValue(
|
||||
"STUART_CODEQL_AUDIT_ONLY",
|
||||
"TRUE",
|
||||
"Set in CISettings.py")
|
||||
except NameError:
|
||||
pass
|
||||
|
||||
if is_linux and self.ActualToolChainTag.upper().startswith("GCC"):
|
||||
if "AARCH64" in self.ActualArchitectures:
|
||||
scopes += ("gcc_aarch64_linux",)
|
||||
if "ARM" in self.ActualArchitectures:
|
||||
scopes += ("gcc_arm_linux",)
|
||||
if "RISCV64" in self.ActualArchitectures:
|
||||
scopes += ("gcc_riscv64_unknown",)
|
||||
self.ActualScopes = scopes
|
||||
return self.ActualScopes
|
||||
|
||||
@ -219,8 +182,6 @@ class Settings(CiBuildSettingsManager, UpdateSettingsManager, SetupSettingsManag
|
||||
"CryptoPkg/Library/OpensslLib/openssl", False))
|
||||
rs.append(RequiredSubmodule(
|
||||
"UnitTestFrameworkPkg/Library/CmockaLib/cmocka", False))
|
||||
rs.append(RequiredSubmodule(
|
||||
"UnitTestFrameworkPkg/Library/GoogleTestLib/googletest", False))
|
||||
rs.append(RequiredSubmodule(
|
||||
"MdeModulePkg/Universal/RegularExpressionDxe/oniguruma", False))
|
||||
rs.append(RequiredSubmodule(
|
||||
@ -229,16 +190,6 @@ class Settings(CiBuildSettingsManager, UpdateSettingsManager, SetupSettingsManag
|
||||
"BaseTools/Source/C/BrotliCompress/brotli", False))
|
||||
rs.append(RequiredSubmodule(
|
||||
"RedfishPkg/Library/JsonLib/jansson", False))
|
||||
rs.append(RequiredSubmodule(
|
||||
"UnitTestFrameworkPkg/Library/SubhookLib/subhook", False))
|
||||
rs.append(RequiredSubmodule(
|
||||
"MdePkg/Library/BaseFdtLib/libfdt", False))
|
||||
rs.append(RequiredSubmodule(
|
||||
"MdePkg/Library/MipiSysTLib/mipisyst", False))
|
||||
rs.append(RequiredSubmodule(
|
||||
"CryptoPkg/Library/MbedTlsLib/mbedtls", False))
|
||||
rs.append(RequiredSubmodule(
|
||||
"SecurityPkg/DeviceSecurity/SpdmLib/libspdm", False))
|
||||
return rs
|
||||
|
||||
def GetName(self):
|
||||
|
@ -69,7 +69,7 @@ class CharEncodingCheck(ICiBuildPlugin):
|
||||
overall_status = 0
|
||||
files_tested = 0
|
||||
|
||||
abs_pkg_path = Edk2pathObj.GetAbsolutePathOnThisSystemFromEdk2RelativePath(packagename)
|
||||
abs_pkg_path = Edk2pathObj.GetAbsolutePathOnThisSytemFromEdk2RelativePath(packagename)
|
||||
|
||||
if abs_pkg_path is None:
|
||||
tc.SetSkipped()
|
||||
@ -90,10 +90,12 @@ class CharEncodingCheck(ICiBuildPlugin):
|
||||
tc.LogStdError("CharEncodingCheck.IgnoreInf -> {0} not found in filesystem. Invalid ignore file".format(a))
|
||||
logging.info("CharEncodingCheck.IgnoreInf -> {0} not found in filesystem. Invalid ignore file".format(a))
|
||||
|
||||
files = [Edk2pathObj.GetAbsolutePathOnThisSystemFromEdk2RelativePath(x) for x in files]
|
||||
files = [Edk2pathObj.GetAbsolutePathOnThisSytemFromEdk2RelativePath(x) for x in files]
|
||||
for a in files:
|
||||
files_tested += 1
|
||||
if not self.TestEncodingOk(a, enc):
|
||||
if(self.TestEncodingOk(a, enc)):
|
||||
logging.debug("File {0} Passed Encoding Check {1}".format(a, enc))
|
||||
else:
|
||||
tc.LogStdError("Encoding Failure in {0}. Not {1}".format(a, enc))
|
||||
overall_status += 1
|
||||
|
||||
|
@ -61,7 +61,7 @@ class CompilerPlugin(ICiBuildPlugin):
|
||||
tc.LogStdError("DscPath not found in config file. Nothing to compile.")
|
||||
return -1
|
||||
|
||||
AP = Edk2pathObj.GetAbsolutePathOnThisSystemFromEdk2RelativePath(packagename)
|
||||
AP = Edk2pathObj.GetAbsolutePathOnThisSytemFromEdk2RelativePath(packagename)
|
||||
|
||||
APDSC = os.path.join(AP, pkgconfig["DscPath"].strip())
|
||||
AP_Path = Edk2pathObj.GetEdk2RelativePathFromAbsolutePath(APDSC)
|
||||
|
@ -55,7 +55,7 @@ class DependencyCheck(ICiBuildPlugin):
|
||||
overall_status = 0
|
||||
|
||||
# Get current platform
|
||||
abs_pkg_path = Edk2pathObj.GetAbsolutePathOnThisSystemFromEdk2RelativePath(packagename)
|
||||
abs_pkg_path = Edk2pathObj.GetAbsolutePathOnThisSytemFromEdk2RelativePath(packagename)
|
||||
|
||||
# Get INF Files
|
||||
INFFiles = self.WalkDirectoryForExtension([".inf"], abs_pkg_path)
|
||||
|
@ -58,7 +58,7 @@ class DscCompleteCheck(ICiBuildPlugin):
|
||||
"DscPath not found in config file. Nothing to check.")
|
||||
return -1
|
||||
|
||||
abs_pkg_path = Edk2pathObj.GetAbsolutePathOnThisSystemFromEdk2RelativePath(
|
||||
abs_pkg_path = Edk2pathObj.GetAbsolutePathOnThisSytemFromEdk2RelativePath(
|
||||
packagename)
|
||||
abs_dsc_path = os.path.join(abs_pkg_path, pkgconfig["DscPath"].strip())
|
||||
wsr_dsc_path = Edk2pathObj.GetEdk2RelativePathFromAbsolutePath(
|
||||
|
@ -30,6 +30,7 @@ class EccCheck(ICiBuildPlugin):
|
||||
},
|
||||
"""
|
||||
|
||||
ReModifyFile = re.compile(r'[B-Q,S-Z]+[\d]*\t(.*)')
|
||||
FindModifyFile = re.compile(r'\+\+\+ b\/(.*)')
|
||||
LineScopePattern = (r'@@ -\d*\,*\d* \+\d*\,*\d* @@.*')
|
||||
LineNumRange = re.compile(r'@@ -\d*\,*\d* \+(\d*)\,*(\d*) @@.*')
|
||||
@ -68,181 +69,77 @@ class EccCheck(ICiBuildPlugin):
|
||||
env.set_shell_var('WORKSPACE', workspace_path)
|
||||
env.set_shell_var('PACKAGES_PATH', os.pathsep.join(Edk2pathObj.PackagePathList))
|
||||
self.ECC_PASS = True
|
||||
|
||||
abs_pkg_path = Edk2pathObj.GetAbsolutePathOnThisSystemFromEdk2RelativePath(packagename)
|
||||
|
||||
if abs_pkg_path is None:
|
||||
tc.SetSkipped()
|
||||
tc.LogStdError("No Package folder {0}".format(abs_pkg_path))
|
||||
self.ApplyConfig(pkgconfig, workspace_path, basetools_path, packagename)
|
||||
modify_dir_list = self.GetModifyDir(packagename)
|
||||
patch = self.GetDiff(packagename)
|
||||
ecc_diff_range = self.GetDiffRange(patch, packagename, workspace_path)
|
||||
self.GenerateEccReport(modify_dir_list, ecc_diff_range, workspace_path, basetools_path)
|
||||
ecc_log = os.path.join(workspace_path, "Ecc.log")
|
||||
self.RevertCode()
|
||||
if self.ECC_PASS:
|
||||
tc.SetSuccess()
|
||||
self.RemoveFile(ecc_log)
|
||||
return 0
|
||||
|
||||
# Create temp directory
|
||||
temp_path = os.path.join(workspace_path, 'Build', '.pytool', 'Plugin', 'EccCheck')
|
||||
try:
|
||||
# Delete temp directory
|
||||
if os.path.exists(temp_path):
|
||||
shutil.rmtree(temp_path)
|
||||
# Copy package being scanned to temp_path
|
||||
shutil.copytree (
|
||||
abs_pkg_path,
|
||||
os.path.join(temp_path, packagename),
|
||||
symlinks=True
|
||||
)
|
||||
# Copy exception.xml to temp_path
|
||||
shutil.copyfile (
|
||||
os.path.join(basetools_path, "Source", "Python", "Ecc", "exception.xml"),
|
||||
os.path.join(temp_path, "exception.xml")
|
||||
)
|
||||
# Output file to use for git diff operations
|
||||
temp_diff_output = os.path.join (temp_path, 'diff.txt')
|
||||
|
||||
self.ApplyConfig(pkgconfig, temp_path, packagename)
|
||||
modify_dir_list = self.GetModifyDir(packagename, temp_diff_output)
|
||||
patch = self.GetDiff(packagename, temp_diff_output)
|
||||
ecc_diff_range = self.GetDiffRange(patch, packagename, temp_path)
|
||||
#
|
||||
# Use temp_path as working directory when running ECC tool
|
||||
#
|
||||
self.GenerateEccReport(modify_dir_list, ecc_diff_range, temp_path, basetools_path)
|
||||
ecc_log = os.path.join(temp_path, "Ecc.log")
|
||||
if self.ECC_PASS:
|
||||
# Delete temp directory
|
||||
if os.path.exists(temp_path):
|
||||
shutil.rmtree(temp_path)
|
||||
tc.SetSuccess()
|
||||
return 0
|
||||
else:
|
||||
with open(ecc_log, encoding='utf8') as output:
|
||||
ecc_output = output.readlines()
|
||||
for line in ecc_output:
|
||||
logging.error(line.strip())
|
||||
# Delete temp directory
|
||||
if os.path.exists(temp_path):
|
||||
shutil.rmtree(temp_path)
|
||||
tc.SetFailed("EccCheck failed for {0}".format(packagename), "CHECK FAILED")
|
||||
return 1
|
||||
except KeyboardInterrupt:
|
||||
# If EccCheck is interrupted by keybard interrupt, then return failure
|
||||
# Delete temp directory
|
||||
if os.path.exists(temp_path):
|
||||
shutil.rmtree(temp_path)
|
||||
tc.SetFailed("EccCheck interrupted for {0}".format(packagename), "CHECK FAILED")
|
||||
return 1
|
||||
else:
|
||||
# If EccCheck fails for any other exception type, raise the exception
|
||||
# Delete temp directory
|
||||
if os.path.exists(temp_path):
|
||||
shutil.rmtree(temp_path)
|
||||
tc.SetFailed("EccCheck exception for {0}".format(packagename), "CHECK FAILED")
|
||||
raise
|
||||
with open(ecc_log, encoding='utf8') as output:
|
||||
ecc_output = output.readlines()
|
||||
for line in ecc_output:
|
||||
logging.error(line.strip())
|
||||
self.RemoveFile(ecc_log)
|
||||
tc.SetFailed("EccCheck failed for {0}".format(packagename), "Ecc detected issues")
|
||||
return 1
|
||||
|
||||
def GetDiff(self, pkg: str, temp_diff_output: str) -> List[str]:
|
||||
patch = []
|
||||
#
|
||||
# Generate unified diff between origin/master and HEAD.
|
||||
#
|
||||
params = "diff --output={} --unified=0 origin/master HEAD".format(temp_diff_output)
|
||||
RunCmd("git", params)
|
||||
with open(temp_diff_output) as file:
|
||||
patch = file.read().strip().split('\n')
|
||||
def RevertCode(self) -> None:
|
||||
submoudle_params = "submodule update --init"
|
||||
RunCmd("git", submoudle_params)
|
||||
reset_params = "reset HEAD --hard"
|
||||
RunCmd("git", reset_params)
|
||||
|
||||
def GetDiff(self, pkg: str) -> List[str]:
|
||||
return_buffer = StringIO()
|
||||
params = "diff --unified=0 origin/master HEAD"
|
||||
RunCmd("git", params, outstream=return_buffer)
|
||||
p = return_buffer.getvalue().strip()
|
||||
patch = p.split("\n")
|
||||
return_buffer.close()
|
||||
|
||||
return patch
|
||||
|
||||
def GetModifyDir(self, pkg: str, temp_diff_output: str) -> List[str]:
|
||||
#
|
||||
# Generate diff between origin/master and HEAD using --diff-filter to
|
||||
# exclude deleted and renamed files that do not need to be scanned by
|
||||
# ECC. Also use --name-status to only generate the names of the files
|
||||
# with differences. The output format of this git diff command is a
|
||||
# list of files with the change status and the filename. The filename
|
||||
# is always at the end of the line. Examples:
|
||||
#
|
||||
# M MdeModulePkg/Application/CapsuleApp/CapsuleApp.h
|
||||
# M MdeModulePkg/Application/UiApp/FrontPage.h
|
||||
#
|
||||
params = "diff --output={} --diff-filter=dr --name-status origin/master HEAD".format(temp_diff_output)
|
||||
RunCmd("git", params)
|
||||
dir_list = []
|
||||
with open(temp_diff_output) as file:
|
||||
dir_list = file.read().strip().split('\n')
|
||||
def RemoveFile(self, file: str) -> None:
|
||||
if os.path.exists(file):
|
||||
os.remove(file)
|
||||
return
|
||||
|
||||
def GetModifyDir(self, pkg: str) -> List[str]:
|
||||
return_buffer = StringIO()
|
||||
params = "diff --name-status" + ' HEAD' + ' origin/master'
|
||||
RunCmd("git", params, outstream=return_buffer)
|
||||
p1 = return_buffer.getvalue().strip()
|
||||
dir_list = p1.split("\n")
|
||||
return_buffer.close()
|
||||
modify_dir_list = []
|
||||
for modify_dir in dir_list:
|
||||
#
|
||||
# Parse file name from the end of the line
|
||||
#
|
||||
file_path = modify_dir.strip().split()
|
||||
#
|
||||
# Skip lines that do not have at least 2 elements (status and file name)
|
||||
#
|
||||
if len(file_path) < 2:
|
||||
file_path = self.ReModifyFile.findall(modify_dir)
|
||||
if file_path:
|
||||
file_dir = os.path.dirname(file_path[0])
|
||||
else:
|
||||
continue
|
||||
#
|
||||
# Parse the directory name from the file name
|
||||
#
|
||||
file_dir = os.path.dirname(file_path[-1])
|
||||
#
|
||||
# Skip directory names that do not start with the package being scanned.
|
||||
#
|
||||
if file_dir.split('/')[0] != pkg:
|
||||
if pkg in file_dir and file_dir != pkg:
|
||||
modify_dir_list.append('%s' % file_dir)
|
||||
else:
|
||||
continue
|
||||
#
|
||||
# Skip directory names that are identical to the package being scanned.
|
||||
# The assumption here is that there are no source files at the package
|
||||
# root. Instead, the only expected files in the package root are
|
||||
# EDK II meta data files (DEC, DSC, FDF).
|
||||
#
|
||||
if file_dir == pkg:
|
||||
continue
|
||||
#
|
||||
# Skip directory names that are already in the modified dir list
|
||||
#
|
||||
if file_dir in modify_dir_list:
|
||||
continue
|
||||
#
|
||||
# Add the candidate directory to scan to the modified dir list
|
||||
#
|
||||
modify_dir_list.append(file_dir)
|
||||
|
||||
#
|
||||
# Remove duplicates from modify_dir_list
|
||||
# Given a folder path, ECC performs a recursive scan of that folder.
|
||||
# If a parent and child folder are both present in modify_dir_list,
|
||||
# then ECC will perform redudanct scans of source files. In order
|
||||
# to prevent redundant scans, if a parent and child folder are both
|
||||
# present, then remove all the child folders.
|
||||
#
|
||||
# For example, if modified_dir_list contains the following elements:
|
||||
# MdeModulePkg/Core/Dxe
|
||||
# MdeModulePkg/Core/Dxe/Hand
|
||||
# MdeModulePkg/Core/Dxe/Mem
|
||||
#
|
||||
# Then MdeModulePkg/Core/Dxe/Hand and MdeModulePkg/Core/Dxe/Mem should
|
||||
# be removed because the files in those folders are covered by a scan
|
||||
# of MdeModulePkg/Core/Dxe.
|
||||
#
|
||||
filtered_list = []
|
||||
for dir1 in modify_dir_list:
|
||||
Append = True
|
||||
for dir2 in modify_dir_list:
|
||||
if dir1 == dir2:
|
||||
continue
|
||||
common = os.path.commonpath([dir1, dir2])
|
||||
if os.path.normpath(common) == os.path.normpath(dir2):
|
||||
Append = False
|
||||
break
|
||||
if Append and dir1 not in filtered_list:
|
||||
filtered_list.append(dir1)
|
||||
return filtered_list
|
||||
modify_dir_list = list(set(modify_dir_list))
|
||||
return modify_dir_list
|
||||
|
||||
def GetDiffRange(self, patch_diff: List[str], pkg: str, temp_path: str) -> Dict[str, List[Tuple[int, int]]]:
|
||||
def GetDiffRange(self, patch_diff: List[str], pkg: str, workingdir: str) -> Dict[str, List[Tuple[int, int]]]:
|
||||
IsDelete = True
|
||||
StartCheck = False
|
||||
range_directory: Dict[str, List[Tuple[int, int]]] = {}
|
||||
for line in patch_diff:
|
||||
modify_file = self.FindModifyFile.findall(line)
|
||||
if modify_file and pkg in modify_file[0] and not StartCheck and os.path.isfile(modify_file[0]):
|
||||
modify_file_comment_dic = self.GetCommentRange(modify_file[0], temp_path)
|
||||
modify_file_comment_dic = self.GetCommentRange(modify_file[0], workingdir)
|
||||
IsDelete = False
|
||||
StartCheck = True
|
||||
modify_file_dic = modify_file[0]
|
||||
@ -261,13 +158,11 @@ class EccCheck(ICiBuildPlugin):
|
||||
range_directory[modify_file_dic].append(i)
|
||||
return range_directory
|
||||
|
||||
def GetCommentRange(self, modify_file: str, temp_path: str) -> List[Tuple[int, int]]:
|
||||
comment_range: List[Tuple[int, int]] = []
|
||||
modify_file_path = os.path.join(temp_path, modify_file)
|
||||
if not os.path.exists (modify_file_path):
|
||||
return comment_range
|
||||
def GetCommentRange(self, modify_file: str, workingdir: str) -> List[Tuple[int, int]]:
|
||||
modify_file_path = os.path.join(workingdir, modify_file)
|
||||
with open(modify_file_path) as f:
|
||||
line_no = 1
|
||||
comment_range: List[Tuple[int, int]] = []
|
||||
Start = False
|
||||
for line in f:
|
||||
if line.startswith('/**'):
|
||||
@ -284,33 +179,35 @@ class EccCheck(ICiBuildPlugin):
|
||||
return comment_range
|
||||
|
||||
def GenerateEccReport(self, modify_dir_list: List[str], ecc_diff_range: Dict[str, List[Tuple[int, int]]],
|
||||
temp_path: str, basetools_path: str) -> None:
|
||||
workspace_path: str, basetools_path: str) -> None:
|
||||
ecc_need = False
|
||||
ecc_run = True
|
||||
config = os.path.normpath(os.path.join(basetools_path, "Source", "Python", "Ecc", "config.ini"))
|
||||
exception = os.path.normpath(os.path.join(temp_path, "exception.xml"))
|
||||
report = os.path.normpath(os.path.join(temp_path, "Ecc.csv"))
|
||||
config = os.path.join(basetools_path, "Source", "Python", "Ecc", "config.ini")
|
||||
exception = os.path.join(basetools_path, "Source", "Python", "Ecc", "exception.xml")
|
||||
report = os.path.join(workspace_path, "Ecc.csv")
|
||||
for modify_dir in modify_dir_list:
|
||||
target = os.path.normpath(os.path.join(temp_path, modify_dir))
|
||||
target = os.path.join(workspace_path, modify_dir)
|
||||
logging.info('Run ECC tool for the commit in %s' % modify_dir)
|
||||
ecc_need = True
|
||||
ecc_params = "-c {0} -e {1} -t {2} -r {3}".format(config, exception, target, report)
|
||||
return_code = RunCmd("Ecc", ecc_params, workingdir=temp_path)
|
||||
return_code = RunCmd("Ecc", ecc_params, workingdir=workspace_path)
|
||||
if return_code != 0:
|
||||
ecc_run = False
|
||||
break
|
||||
if not ecc_run:
|
||||
logging.error('Fail to run ECC tool')
|
||||
self.ParseEccReport(ecc_diff_range, temp_path)
|
||||
self.ParseEccReport(ecc_diff_range, workspace_path)
|
||||
|
||||
if not ecc_need:
|
||||
logging.info("Doesn't need run ECC check")
|
||||
|
||||
revert_params = "checkout -- {}".format(exception)
|
||||
RunCmd("git", revert_params)
|
||||
return
|
||||
|
||||
def ParseEccReport(self, ecc_diff_range: Dict[str, List[Tuple[int, int]]], temp_path: str) -> None:
|
||||
ecc_log = os.path.join(temp_path, "Ecc.log")
|
||||
ecc_csv = os.path.join(temp_path, "Ecc.csv")
|
||||
def ParseEccReport(self, ecc_diff_range: Dict[str, List[Tuple[int, int]]], workspace_path: str) -> None:
|
||||
ecc_log = os.path.join(workspace_path, "Ecc.log")
|
||||
ecc_csv = os.path.join(workspace_path, "Ecc.csv")
|
||||
row_lines = []
|
||||
ignore_error_code = self.GetIgnoreErrorCode()
|
||||
if os.path.exists(ecc_csv):
|
||||
@ -339,16 +236,16 @@ class EccCheck(ICiBuildPlugin):
|
||||
log.writelines(all_line)
|
||||
return
|
||||
|
||||
def ApplyConfig(self, pkgconfig: Dict[str, List[str]], temp_path: str, pkg: str) -> None:
|
||||
def ApplyConfig(self, pkgconfig: Dict[str, List[str]], workspace_path: str, basetools_path: str, pkg: str) -> None:
|
||||
if "IgnoreFiles" in pkgconfig:
|
||||
for a in pkgconfig["IgnoreFiles"]:
|
||||
a = os.path.join(temp_path, pkg, a)
|
||||
a = os.path.join(workspace_path, pkg, a)
|
||||
a = a.replace(os.sep, "/")
|
||||
|
||||
logging.info("Ignoring Files {0}".format(a))
|
||||
if os.path.exists(a):
|
||||
if os.path.isfile(a):
|
||||
os.remove(a)
|
||||
self.RemoveFile(a)
|
||||
elif os.path.isdir(a):
|
||||
shutil.rmtree(a)
|
||||
else:
|
||||
@ -356,7 +253,7 @@ class EccCheck(ICiBuildPlugin):
|
||||
|
||||
if "ExceptionList" in pkgconfig:
|
||||
exception_list = pkgconfig["ExceptionList"]
|
||||
exception_xml = os.path.join(temp_path, "exception.xml")
|
||||
exception_xml = os.path.join(basetools_path, "Source", "Python", "Ecc", "exception.xml")
|
||||
try:
|
||||
logging.info("Appending exceptions")
|
||||
self.AppendException(exception_list, exception_xml)
|
||||
|
@ -116,7 +116,7 @@ class GuidCheck(ICiBuildPlugin):
|
||||
def RunBuildPlugin(self, packagename, Edk2pathObj, pkgconfig, environment, PLM, PLMHelper, tc, output_stream=None):
|
||||
Errors = []
|
||||
|
||||
abs_pkg_path = Edk2pathObj.GetAbsolutePathOnThisSystemFromEdk2RelativePath(
|
||||
abs_pkg_path = Edk2pathObj.GetAbsolutePathOnThisSytemFromEdk2RelativePath(
|
||||
packagename)
|
||||
|
||||
if abs_pkg_path is None:
|
||||
|
@ -93,7 +93,7 @@ class HostUnitTestCompilerPlugin(ICiBuildPlugin):
|
||||
tc.LogStdError("DscPath not found in config file. Nothing to compile for HostBasedUnitTests.")
|
||||
return -1
|
||||
|
||||
AP = Edk2pathObj.GetAbsolutePathOnThisSystemFromEdk2RelativePath(packagename)
|
||||
AP = Edk2pathObj.GetAbsolutePathOnThisSytemFromEdk2RelativePath(packagename)
|
||||
|
||||
APDSC = os.path.join(AP, pkgconfig["DscPath"].strip())
|
||||
AP_Path = Edk2pathObj.GetEdk2RelativePathFromAbsolutePath(APDSC)
|
||||
|
@ -10,7 +10,7 @@ import logging
|
||||
import os
|
||||
from edk2toolext.environment.plugintypes.ci_build_plugin import ICiBuildPlugin
|
||||
from edk2toollib.uefi.edk2.parsers.dsc_parser import DscParser
|
||||
from edk2toollib.uefi.edk2.parsers.inf_parser import InfParser, AllPhases
|
||||
from edk2toollib.uefi.edk2.parsers.inf_parser import InfParser
|
||||
from edk2toolext.environment.var_dict import VarDict
|
||||
|
||||
|
||||
@ -61,7 +61,7 @@ class HostUnitTestDscCompleteCheck(ICiBuildPlugin):
|
||||
"DscPath not found in config file. Nothing to check.")
|
||||
return -1
|
||||
|
||||
abs_pkg_path = Edk2pathObj.GetAbsolutePathOnThisSystemFromEdk2RelativePath(
|
||||
abs_pkg_path = Edk2pathObj.GetAbsolutePathOnThisSytemFromEdk2RelativePath(
|
||||
packagename)
|
||||
abs_dsc_path = os.path.join(abs_pkg_path, pkgconfig["DscPath"].strip())
|
||||
wsr_dsc_path = Edk2pathObj.GetEdk2RelativePathFromAbsolutePath(
|
||||
@ -116,9 +116,8 @@ class HostUnitTestDscCompleteCheck(ICiBuildPlugin):
|
||||
# should compile test a library that is declared type HOST_APPLICATION
|
||||
pass
|
||||
|
||||
elif (len(infp.SupportedPhases) > 0 and
|
||||
"HOST_APPLICATION" in infp.SupportedPhases and
|
||||
infp.SupportedPhases != AllPhases):
|
||||
elif len(infp.SupportedPhases) > 0 and \
|
||||
"HOST_APPLICATION" in infp.SupportedPhases:
|
||||
# should compile test a library that supports HOST_APPLICATION but
|
||||
# require it to be an explicit opt-in
|
||||
pass
|
||||
|
@ -63,7 +63,7 @@ class LibraryClassCheck(ICiBuildPlugin):
|
||||
overall_status = 0
|
||||
LibraryClassIgnore = []
|
||||
|
||||
abs_pkg_path = Edk2pathObj.GetAbsolutePathOnThisSystemFromEdk2RelativePath(packagename)
|
||||
abs_pkg_path = Edk2pathObj.GetAbsolutePathOnThisSytemFromEdk2RelativePath(packagename)
|
||||
abs_dec_path = self.__GetPkgDec(abs_pkg_path)
|
||||
wsr_dec_path = Edk2pathObj.GetEdk2RelativePathFromAbsolutePath(abs_dec_path)
|
||||
|
||||
|
@ -5,7 +5,6 @@
|
||||
##
|
||||
|
||||
import os
|
||||
import shutil
|
||||
import logging
|
||||
import re
|
||||
from io import StringIO
|
||||
@ -62,19 +61,12 @@ class LicenseCheck(ICiBuildPlugin):
|
||||
# - Junit Logger
|
||||
# - output_stream the StringIO output stream from this plugin via logging
|
||||
def RunBuildPlugin(self, packagename, Edk2pathObj, pkgconfig, environment, PLM, PLMHelper, tc, output_stream=None):
|
||||
# Create temp directory
|
||||
temp_path = os.path.join(Edk2pathObj.WorkspacePath, 'Build', '.pytool', 'Plugin', 'LicenseCheck')
|
||||
if not os.path.exists(temp_path):
|
||||
os.makedirs(temp_path)
|
||||
# Output file to use for git diff operations
|
||||
temp_diff_output = os.path.join (temp_path, 'diff.txt')
|
||||
params = "diff --output={} --unified=0 origin/master HEAD".format(temp_diff_output)
|
||||
RunCmd("git", params)
|
||||
with open(temp_diff_output) as file:
|
||||
patch = file.read().strip().split("\n")
|
||||
# Delete temp directory
|
||||
if os.path.exists(temp_path):
|
||||
shutil.rmtree(temp_path)
|
||||
return_buffer = StringIO()
|
||||
params = "diff --unified=0 origin/master HEAD"
|
||||
RunCmd("git", params, outstream=return_buffer)
|
||||
p = return_buffer.getvalue().strip()
|
||||
patch = p.split("\n")
|
||||
return_buffer.close()
|
||||
|
||||
ignore_files = []
|
||||
if "IgnoreFiles" in pkgconfig:
|
||||
|
@ -73,7 +73,7 @@ class SpellCheck(ICiBuildPlugin):
|
||||
def RunBuildPlugin(self, packagename, Edk2pathObj, pkgconfig, environment, PLM, PLMHelper, tc, output_stream=None):
|
||||
Errors = []
|
||||
|
||||
abs_pkg_path = Edk2pathObj.GetAbsolutePathOnThisSystemFromEdk2RelativePath(
|
||||
abs_pkg_path = Edk2pathObj.GetAbsolutePathOnThisSytemFromEdk2RelativePath(
|
||||
packagename)
|
||||
|
||||
if abs_pkg_path is None:
|
||||
|
@ -21,7 +21,7 @@
|
||||
"*.jpg"
|
||||
],
|
||||
"minWordLength": 5,
|
||||
"allowCompoundWords": true,
|
||||
"allowCompoundWords": false,
|
||||
"maxNumberOfProblems": 200,
|
||||
"maxDuplicateProblems": 200,
|
||||
"ignoreWords": [
|
||||
@ -178,119 +178,6 @@
|
||||
"vcruntimed",
|
||||
"ucrtd",
|
||||
"msvcrtd",
|
||||
"XIPFLAGS",
|
||||
"bootflow",
|
||||
"bootup",
|
||||
"cacheability",
|
||||
"cachetype",
|
||||
"conout",
|
||||
"deadloop",
|
||||
"devicepath",
|
||||
"hisilicon",
|
||||
"littleendian",
|
||||
"nonsecure",
|
||||
"pagetable",
|
||||
"postmem",
|
||||
"premem",
|
||||
"reglist",
|
||||
"semihalf",
|
||||
"subvendor",
|
||||
"subhierarchy",
|
||||
"targetlist",
|
||||
"tmpname",
|
||||
"watchdogtimer",
|
||||
"writeback",
|
||||
"langcode",
|
||||
"langcodes",
|
||||
"autoreload",
|
||||
"bootable",
|
||||
"endiannness",
|
||||
"fvmain",
|
||||
"prefetchable",
|
||||
"multiboot",
|
||||
"ramdisk",
|
||||
"unbootable",
|
||||
"setjump",
|
||||
"bytecodes",
|
||||
"bytelist",
|
||||
"bytestream",
|
||||
"countof",
|
||||
"deregistering",
|
||||
"devicetree",
|
||||
"mainpage",
|
||||
"mismanipulation",
|
||||
"pytool",
|
||||
"wbinvd",
|
||||
"armltd",
|
||||
"datacache",
|
||||
"lastattemptstatus",
|
||||
"lastattemptversion",
|
||||
"lowestsupportedversion",
|
||||
"updateable",
|
||||
"pecoff",
|
||||
"autodetect",
|
||||
"harddisk",
|
||||
"toctou",
|
||||
"bugbug",
|
||||
"depexes",
|
||||
"fwvol",
|
||||
"hoblist",
|
||||
"imagehandle",
|
||||
"schedulable",
|
||||
"StandaloneMMCore",
|
||||
"systemtable",
|
||||
"uncacheable",
|
||||
"devpath",
|
||||
"testsuites",
|
||||
"testcase",
|
||||
"pxmldoc",
|
||||
"pcxml",
|
||||
"pclutf",
|
||||
"pcunicode",
|
||||
"ntxmltransformcharacter",
|
||||
"ntxmlcomparestrings",
|
||||
"pcxmldoc",
|
||||
"ntxmlfetchcharacterdecoder",
|
||||
"ntxml",
|
||||
"ntxmlspecialstringcompare",
|
||||
"rtlxmlcallback",
|
||||
"xmlef",
|
||||
"osruntime",
|
||||
"readytoboot",
|
||||
"hwerrrec",
|
||||
"xformed",
|
||||
"xform",
|
||||
"undock",
|
||||
"qrencoder",
|
||||
"selawik",
|
||||
"ntxmlrawnextcharacter",
|
||||
"undocked",
|
||||
"reprompt",
|
||||
"yesno",
|
||||
"okcancel",
|
||||
"qrencoding",
|
||||
"qrlevel",
|
||||
"shiftn",
|
||||
"unenroll",
|
||||
"pcxmlstructure",
|
||||
"pxmlstructure",
|
||||
"pcencoder",
|
||||
"pcvoid",
|
||||
"nofailure",
|
||||
"blockio",
|
||||
"lockv",
|
||||
"uefishelldebug",
|
||||
"mtrrcap",
|
||||
"drhds",
|
||||
"rmrrs",
|
||||
"creatorid",
|
||||
"dxeipl",
|
||||
"swmdialogs",
|
||||
"unrecovered",
|
||||
"cmocka",
|
||||
"unenrolling",
|
||||
"unconfigure",
|
||||
"Loongson",
|
||||
"LOONGARCH"
|
||||
"XIPFLAGS"
|
||||
]
|
||||
}
|
||||
|
@ -1,127 +0,0 @@
|
||||
# UncrustifyCheck Plugin
|
||||
|
||||
This CiBuildPlugin scans all the files in a given package and checks for coding standard compliance issues.
|
||||
|
||||
This plugin is enabled by default. If a package would like to prevent the plugin from reporting errors, it can do
|
||||
so by enabling [`AuditOnly`](#auditonly) mode.
|
||||
|
||||
This plugin requires the directory containing the Uncrustify executable that should be used for this plugin to
|
||||
be specified in an environment variable named `UNCRUSTIFY_CI_PATH`. This unique variable name is used to avoid confusion
|
||||
with other paths to Uncrustify which might not be the expected build for use by this plugin.
|
||||
|
||||
By default, an Uncrustify configuration file named "uncrustify.cfg" located in the same directory as the plugin is
|
||||
used. The value can be overridden to a package-specific path with the `ConfigFilePath` configuration file option.
|
||||
|
||||
* Uncrustify source code and documentation: https://github.com/uncrustify/uncrustify
|
||||
* Project Mu Uncrustify fork source code and documentation: https://dev.azure.com/projectmu/Uncrustify
|
||||
|
||||
## Files Checked in a Package
|
||||
|
||||
By default, this plugin will discover all files in the package with the following default paths:
|
||||
|
||||
```python
|
||||
[
|
||||
# C source
|
||||
"*.c",
|
||||
"*.h"
|
||||
]
|
||||
```
|
||||
|
||||
From this list of files, any files ignored by Git or residing in a Git submodule will be removed. If Git is not
|
||||
found, submodules are not found, or ignored files are not found no changes are made to the list of discovered files.
|
||||
|
||||
To control the paths checked in a given package, review the configuration options described in this file.
|
||||
|
||||
## Configuration
|
||||
|
||||
The plugin can be configured with a few optional configuration options.
|
||||
|
||||
``` yaml
|
||||
"UncrustifyCheck": {
|
||||
"AdditionalIncludePaths": [], # Additional paths to check formatting (wildcards supported).
|
||||
"AuditOnly": False, # Don't fail the build if there are errors. Just log them.
|
||||
"ConfigFilePath": "", # Custom path to an Uncrustify config file.
|
||||
"IgnoreFiles": [], # A list of file patterns to ignore.
|
||||
"IgnoreStandardPaths": [], # Standard Plugin defined paths that should be ignored.
|
||||
"OutputFileDiffs": True, # Output chunks of formatting diffs in the test case log.
|
||||
# This can significantly slow down the plugin on very large packages.
|
||||
"SkipGitExclusions": False # Don't exclude git ignored files and files in git submodules.
|
||||
}
|
||||
```
|
||||
|
||||
### `AdditionalIncludePaths`
|
||||
|
||||
A package configuration file can specify any additional paths to be included with this option.
|
||||
|
||||
At this time, it is recommended all files run against the plugin be written in the C or C++ language.
|
||||
|
||||
### `AuditOnly`
|
||||
|
||||
`Boolean` - Default is `False`.
|
||||
|
||||
If `True`, run the test in an "audit only mode" which will log all errors but instead of failing the build, it will set
|
||||
the test as skipped. This allows visibility into the failures without breaking the build.
|
||||
|
||||
### `ConfigFilePath`
|
||||
|
||||
`String` - Default is `"uncrustify.cfg"`
|
||||
|
||||
When specified in the config file, this is a package relative path to the Uncrustify configuration file.
|
||||
|
||||
### `IgnoreFiles`
|
||||
|
||||
This option supports .gitignore file and folder matching strings including wildcards.
|
||||
|
||||
The files specified by this configuration option will not be processed by Uncrustify.
|
||||
|
||||
### `IgnoreStandardPaths`
|
||||
|
||||
This plugin by default will check the below standard paths. A package configuration file can specify any of these paths
|
||||
to be ignored.
|
||||
|
||||
```python
|
||||
[
|
||||
# C source
|
||||
"*.c",
|
||||
"*.h"
|
||||
]
|
||||
```
|
||||
|
||||
### `OutputFileDiffs`
|
||||
|
||||
`Boolean` - Default is `True`.
|
||||
|
||||
If `True`, output diffs of formatting changes into the test case log. This is helpful to exactly understand what changes
|
||||
need to be made to the source code in order to fix a coding standard compliance issue.
|
||||
|
||||
Note that calculating the file diffs on a very large set of of results (e.g. >100 files) can significantly slow down
|
||||
plugin execution.
|
||||
|
||||
### `SkipGitExclusions`
|
||||
|
||||
`Boolean` - Default is `False`.
|
||||
|
||||
By default, files in paths matched in a .gitignore file or a recognized git submodule are excluded. If this option
|
||||
is `True`, the plugin will not attempt to recognize these files and exclude them.
|
||||
|
||||
## High-Level Plugin Operation
|
||||
|
||||
This plugin generates two main sets of temporary files:
|
||||
|
||||
1. A working directory in the directory `Build/.pytool/Plugin/Uncrustify`
|
||||
2. For each source file with formatting errors, a sibling file with the `.uncrustify_plugin` extension
|
||||
|
||||
The working directory contains temporary files unique to operation of the plugin. All of these files are removed on
|
||||
exit of the plugin including successful or unsuccessful execution (such as a Python exception occurring). If for any
|
||||
reason, any files in the package exist prior to running the plugin with the `.uncrustify_plugin` extension, the plugin
|
||||
will inform the user to remove these files and exit before running Uncrustify. This is to ensure the accuracy of the
|
||||
results reported from each execution instance of the plugin.
|
||||
|
||||
The plugin determines the list of relevant files to check with Uncrustify and then invokes Uncrustify with that file
|
||||
list. For any files not compliant to the configuration file provided, Uncrustify will generate a corresponding file
|
||||
with the `.uncrustify_plugin` extension. The plugin discovers all of these files. If any such files are present, this
|
||||
indicates a formatting issue was found and the test is marked failed (unless `AuditOnly` mode is enabled).
|
||||
|
||||
The test case log will contain a report of which files failed to format properly, allowing the user to run Uncrustify
|
||||
against the file locally to fix the issue. If the `OutputFileDiffs` configuration option is set to `True`, the plugin
|
||||
will output diff chunks for all code formatting issues in the test case log.
|
@ -1,661 +0,0 @@
|
||||
# @file UncrustifyCheck.py
|
||||
#
|
||||
# An edk2-pytool based plugin wrapper for Uncrustify
|
||||
#
|
||||
# Copyright (c) Microsoft Corporation.
|
||||
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
##
|
||||
import configparser
|
||||
import difflib
|
||||
import errno
|
||||
import logging
|
||||
import os
|
||||
import pathlib
|
||||
import shutil
|
||||
import stat
|
||||
import timeit
|
||||
from edk2toolext.environment import version_aggregator
|
||||
from edk2toolext.environment.plugin_manager import PluginManager
|
||||
from edk2toolext.environment.plugintypes.ci_build_plugin import ICiBuildPlugin
|
||||
from edk2toolext.environment.plugintypes.uefi_helper_plugin import HelperFunctions
|
||||
from edk2toolext.environment.var_dict import VarDict
|
||||
from edk2toollib.gitignore_parser import parse_gitignore_lines
|
||||
from edk2toollib.log.junit_report_format import JunitReportTestCase
|
||||
from edk2toollib.uefi.edk2.path_utilities import Edk2Path
|
||||
from edk2toollib.utility_functions import RunCmd
|
||||
from io import StringIO
|
||||
from typing import Any, Dict, List, Tuple
|
||||
|
||||
#
|
||||
# Provide more user friendly messages for certain scenarios
|
||||
#
|
||||
class UncrustifyException(Exception):
|
||||
def __init__(self, message, exit_code):
|
||||
super().__init__(message)
|
||||
self.exit_code = exit_code
|
||||
|
||||
|
||||
class UncrustifyAppEnvVarNotFoundException(UncrustifyException):
|
||||
def __init__(self, message):
|
||||
super().__init__(message, -101)
|
||||
|
||||
|
||||
class UncrustifyAppVersionErrorException(UncrustifyException):
|
||||
def __init__(self, message):
|
||||
super().__init__(message, -102)
|
||||
|
||||
|
||||
class UncrustifyAppExecutionException(UncrustifyException):
|
||||
def __init__(self, message):
|
||||
super().__init__(message, -103)
|
||||
|
||||
|
||||
class UncrustifyStalePluginFormattedFilesException(UncrustifyException):
|
||||
def __init__(self, message):
|
||||
super().__init__(message, -120)
|
||||
|
||||
|
||||
class UncrustifyInputFileCreationErrorException(UncrustifyException):
|
||||
def __init__(self, message):
|
||||
super().__init__(message, -121)
|
||||
|
||||
class UncrustifyInvalidIgnoreStandardPathsException(UncrustifyException):
|
||||
def __init__(self, message):
|
||||
super().__init__(message, -122)
|
||||
|
||||
class UncrustifyGitIgnoreFileException(UncrustifyException):
|
||||
def __init__(self, message):
|
||||
super().__init__(message, -140)
|
||||
|
||||
|
||||
class UncrustifyGitSubmoduleException(UncrustifyException):
|
||||
def __init__(self, message):
|
||||
super().__init__(message, -141)
|
||||
|
||||
|
||||
class UncrustifyCheck(ICiBuildPlugin):
|
||||
"""
|
||||
A CiBuildPlugin that uses Uncrustify to check the source files in the
|
||||
package being tested for coding standard issues.
|
||||
|
||||
By default, the plugin runs against standard C source file extensions but
|
||||
its configuration can be modified through its configuration file.
|
||||
|
||||
Configuration options:
|
||||
"UncrustifyCheck": {
|
||||
"AdditionalIncludePaths": [], # Additional paths to check formatting (wildcards supported).
|
||||
"AuditOnly": False, # Don't fail the build if there are errors. Just log them.
|
||||
"ConfigFilePath": "", # Custom path to an Uncrustify config file.
|
||||
"IgnoreStandardPaths": [], # Standard Plugin defined paths that should be ignored.
|
||||
"OutputFileDiffs": False, # Output chunks of formatting diffs in the test case log.
|
||||
# This can significantly slow down the plugin on very large packages.
|
||||
"SkipGitExclusions": False # Don't exclude git ignored files and files in git submodules.
|
||||
}
|
||||
"""
|
||||
|
||||
#
|
||||
# By default, use an "uncrustify.cfg" config file in the plugin directory
|
||||
# A package can override this path via "ConfigFilePath"
|
||||
#
|
||||
# Note: Values specified via "ConfigFilePath" are relative to the package
|
||||
#
|
||||
DEFAULT_CONFIG_FILE_PATH = os.path.join(
|
||||
pathlib.Path(__file__).parent.resolve(), "uncrustify.cfg")
|
||||
|
||||
#
|
||||
# The extension used for formatted files produced by this plugin
|
||||
#
|
||||
FORMATTED_FILE_EXTENSION = ".uncrustify_plugin"
|
||||
|
||||
#
|
||||
# A package can add any additional paths with "AdditionalIncludePaths"
|
||||
# A package can remove any of these paths with "IgnoreStandardPaths"
|
||||
#
|
||||
STANDARD_PLUGIN_DEFINED_PATHS = ("*.c", "*.h", "*.cpp")
|
||||
|
||||
#
|
||||
# The Uncrustify application path should set in this environment variable
|
||||
#
|
||||
UNCRUSTIFY_PATH_ENV_KEY = "UNCRUSTIFY_CI_PATH"
|
||||
|
||||
def GetTestName(self, packagename: str, environment: VarDict) -> Tuple:
|
||||
""" Provide the testcase name and classname for use in reporting
|
||||
|
||||
Args:
|
||||
packagename: string containing name of package to build
|
||||
environment: The VarDict for the test to run in
|
||||
Returns:
|
||||
A tuple containing the testcase name and the classname
|
||||
(testcasename, classname)
|
||||
testclassname: a descriptive string for the testcase can include whitespace
|
||||
classname: should be patterned <packagename>.<plugin>.<optionally any unique condition>
|
||||
"""
|
||||
return ("Check file coding standard compliance in " + packagename, packagename + ".UncrustifyCheck")
|
||||
|
||||
def RunBuildPlugin(self, package_rel_path: str, edk2_path: Edk2Path, package_config: Dict[str, List[str]], environment_config: Any, plugin_manager: PluginManager, plugin_manager_helper: HelperFunctions, tc: JunitReportTestCase, output_stream=None) -> int:
|
||||
"""
|
||||
External function of plugin. This function is used to perform the task of the CiBuild Plugin.
|
||||
|
||||
Args:
|
||||
- package_rel_path: edk2 workspace relative path to the package
|
||||
- edk2_path: Edk2Path object with workspace and packages paths
|
||||
- package_config: Dictionary with the package configuration
|
||||
- environment_config: Environment configuration
|
||||
- plugin_manager: Plugin Manager Instance
|
||||
- plugin_manager_helper: Plugin Manager Helper Instance
|
||||
- tc: JUnit test case
|
||||
- output_stream: The StringIO output stream from this plugin (logging)
|
||||
|
||||
Returns
|
||||
>0 : Number of errors found
|
||||
0 : Passed successfully
|
||||
-1 : Skipped for missing prereq
|
||||
"""
|
||||
try:
|
||||
# Initialize plugin and check pre-requisites.
|
||||
self._initialize_environment_info(
|
||||
package_rel_path, edk2_path, package_config, tc)
|
||||
self._initialize_configuration()
|
||||
self._check_for_preexisting_formatted_files()
|
||||
|
||||
# Log important context information.
|
||||
self._log_uncrustify_app_info()
|
||||
|
||||
# Get template file contents if specified
|
||||
self._get_template_file_contents()
|
||||
|
||||
# Create meta input files & directories
|
||||
self._create_temp_working_directory()
|
||||
self._create_uncrustify_file_list_file()
|
||||
|
||||
self._run_uncrustify()
|
||||
|
||||
# Post-execution actions.
|
||||
self._process_uncrustify_results()
|
||||
|
||||
except UncrustifyException as e:
|
||||
self._tc.LogStdError(
|
||||
f"Uncrustify error {e.exit_code}. Details:\n\n{str(e)}")
|
||||
logging.warning(
|
||||
f"Uncrustify error {e.exit_code}. Details:\n\n{str(e)}")
|
||||
return -1
|
||||
else:
|
||||
if self._formatted_file_error_count > 0:
|
||||
if self._audit_only_mode:
|
||||
logging.info(
|
||||
"Setting test as skipped since AuditOnly is enabled")
|
||||
self._tc.SetSkipped()
|
||||
return -1
|
||||
else:
|
||||
self._tc.SetFailed(
|
||||
f"{self._plugin_name} failed due to {self._formatted_file_error_count} incorrectly formatted files.", "CHECK_FAILED")
|
||||
else:
|
||||
self._tc.SetSuccess()
|
||||
return self._formatted_file_error_count
|
||||
finally:
|
||||
self._cleanup_temporary_formatted_files()
|
||||
self._cleanup_temporary_directory()
|
||||
|
||||
def _initialize_configuration(self) -> None:
|
||||
"""
|
||||
Initializes plugin configuration.
|
||||
"""
|
||||
self._initialize_app_info()
|
||||
self._initialize_config_file_info()
|
||||
self._initialize_file_to_format_info()
|
||||
self._initialize_test_case_output_options()
|
||||
|
||||
def _check_for_preexisting_formatted_files(self) -> None:
|
||||
"""
|
||||
Checks if any formatted files from prior execution are present.
|
||||
|
||||
Existence of such files is an unexpected condition. This might result
|
||||
from an error that occurred during a previous run or a premature exit from a debug scenario. In any case, the package should be clean before starting a new run.
|
||||
"""
|
||||
pre_existing_formatted_file_count = len(
|
||||
[str(path.resolve()) for path in pathlib.Path(self._abs_package_path).rglob(f'*{UncrustifyCheck.FORMATTED_FILE_EXTENSION}')])
|
||||
|
||||
if pre_existing_formatted_file_count > 0:
|
||||
raise UncrustifyStalePluginFormattedFilesException(
|
||||
f"{pre_existing_formatted_file_count} formatted files already exist. To prevent overwriting these files, please remove them before running this plugin.")
|
||||
|
||||
def _cleanup_temporary_directory(self) -> None:
|
||||
"""
|
||||
Cleans up the temporary directory used for this execution instance.
|
||||
|
||||
This removes the directory and all files created during this instance.
|
||||
"""
|
||||
if hasattr(self, '_working_dir'):
|
||||
self._remove_tree(self._working_dir)
|
||||
|
||||
def _cleanup_temporary_formatted_files(self) -> None:
|
||||
"""
|
||||
Cleans up the temporary formmatted files produced by Uncrustify.
|
||||
|
||||
This will recursively remove all formatted files generated by Uncrustify
|
||||
during this execution instance.
|
||||
"""
|
||||
if hasattr(self, '_abs_package_path'):
|
||||
formatted_files = [str(path.resolve()) for path in pathlib.Path(
|
||||
self._abs_package_path).rglob(f'*{UncrustifyCheck.FORMATTED_FILE_EXTENSION}')]
|
||||
|
||||
for formatted_file in formatted_files:
|
||||
os.remove(formatted_file)
|
||||
|
||||
def _create_temp_working_directory(self) -> None:
|
||||
"""
|
||||
Creates the temporary directory used for this execution instance.
|
||||
"""
|
||||
self._working_dir = os.path.join(
|
||||
self._abs_workspace_path, "Build", ".pytool", "Plugin", f"{self._plugin_name}")
|
||||
|
||||
try:
|
||||
pathlib.Path(self._working_dir).mkdir(parents=True, exist_ok=True)
|
||||
except OSError as e:
|
||||
raise UncrustifyInputFileCreationErrorException(
|
||||
f"Error creating plugin directory {self._working_dir}.\n\n{repr(e)}.")
|
||||
|
||||
def _create_uncrustify_file_list_file(self) -> None:
|
||||
"""
|
||||
Creates the file with the list of source files for Uncrustify to process.
|
||||
"""
|
||||
self._app_input_file_path = os.path.join(
|
||||
self._working_dir, "uncrustify_file_list.txt")
|
||||
|
||||
with open(self._app_input_file_path, 'w', encoding='utf8') as f:
|
||||
f.writelines(f"\n".join(self._abs_file_paths_to_format))
|
||||
|
||||
def _execute_uncrustify(self) -> None:
|
||||
"""
|
||||
Executes Uncrustify with the initialized configuration.
|
||||
"""
|
||||
output = StringIO()
|
||||
self._app_exit_code = RunCmd(
|
||||
self._app_path,
|
||||
f"-c {self._app_config_file} -F {self._app_input_file_path} --if-changed --suffix {UncrustifyCheck.FORMATTED_FILE_EXTENSION}", outstream=output)
|
||||
self._app_output = output.getvalue().strip().splitlines()
|
||||
|
||||
def _get_files_ignored_in_config(self):
|
||||
""""
|
||||
Returns a function that returns true if a given file string path is ignored in the plugin configuration file and false otherwise.
|
||||
"""
|
||||
ignored_files = []
|
||||
if "IgnoreFiles" in self._package_config:
|
||||
ignored_files = self._package_config["IgnoreFiles"]
|
||||
|
||||
# Pass "Package configuration file" as the source file path since
|
||||
# the actual configuration file name is unknown to this plugin and
|
||||
# this provides a generic description of the file that provided
|
||||
# the ignore file content.
|
||||
#
|
||||
# This information is only used for reporting (not used here) and
|
||||
# the ignore lines are being passed directly as they are given to
|
||||
# this plugin.
|
||||
return parse_gitignore_lines(ignored_files, "Package configuration file", self._abs_package_path)
|
||||
|
||||
def _get_git_ignored_paths(self) -> List[str]:
|
||||
""""
|
||||
Returns a list of file absolute path strings to all files ignored in this git repository.
|
||||
|
||||
If git is not found, an empty list will be returned.
|
||||
"""
|
||||
if not shutil.which("git"):
|
||||
logging.warning(
|
||||
"Git is not found on this system. Git submodule paths will not be considered.")
|
||||
return []
|
||||
|
||||
outstream_buffer = StringIO()
|
||||
exit_code = RunCmd("git", "ls-files --other",
|
||||
workingdir=self._abs_workspace_path, outstream=outstream_buffer, logging_level=logging.NOTSET)
|
||||
if (exit_code != 0):
|
||||
raise UncrustifyGitIgnoreFileException(
|
||||
f"An error occurred reading git ignore settings. This will prevent Uncrustify from running against the expected set of files.")
|
||||
|
||||
# Note: This will potentially be a large list, but at least sorted
|
||||
rel_paths = outstream_buffer.getvalue().strip().splitlines()
|
||||
abs_paths = []
|
||||
for path in rel_paths:
|
||||
abs_paths.append(
|
||||
os.path.normpath(os.path.join(self._abs_workspace_path, path)))
|
||||
return abs_paths
|
||||
|
||||
def _get_git_submodule_paths(self) -> List[str]:
|
||||
"""
|
||||
Returns a list of directory absolute path strings to the root of each submodule in the workspace repository.
|
||||
|
||||
If git is not found, an empty list will be returned.
|
||||
"""
|
||||
if not shutil.which("git"):
|
||||
logging.warning(
|
||||
"Git is not found on this system. Git submodule paths will not be considered.")
|
||||
return []
|
||||
|
||||
if os.path.isfile(os.path.join(self._abs_workspace_path, ".gitmodules")):
|
||||
logging.info(
|
||||
f".gitmodules file found. Excluding submodules in {self._package_name}.")
|
||||
|
||||
outstream_buffer = StringIO()
|
||||
exit_code = RunCmd("git", "config --file .gitmodules --get-regexp path", workingdir=self._abs_workspace_path, outstream=outstream_buffer, logging_level=logging.NOTSET)
|
||||
if (exit_code != 0):
|
||||
raise UncrustifyGitSubmoduleException(
|
||||
f".gitmodule file detected but an error occurred reading the file. Cannot proceed with unknown submodule paths.")
|
||||
|
||||
submodule_paths = []
|
||||
for line in outstream_buffer.getvalue().strip().splitlines():
|
||||
submodule_paths.append(
|
||||
os.path.normpath(os.path.join(self._abs_workspace_path, line.split()[1])))
|
||||
|
||||
return submodule_paths
|
||||
else:
|
||||
return []
|
||||
|
||||
def _get_template_file_contents(self) -> None:
|
||||
"""
|
||||
Gets the contents of Uncrustify template files if they are specified
|
||||
in the Uncrustify configuration file.
|
||||
"""
|
||||
|
||||
self._file_template_contents = None
|
||||
self._func_template_contents = None
|
||||
|
||||
# Allow no value to allow "set" statements in the config file which do
|
||||
# not specify value assignment
|
||||
parser = configparser.ConfigParser(allow_no_value=True)
|
||||
with open(self._app_config_file, 'r') as cf:
|
||||
parser.read_string("[dummy_section]\n" + cf.read())
|
||||
|
||||
try:
|
||||
file_template_name = parser["dummy_section"]["cmt_insert_file_header"]
|
||||
|
||||
file_template_path = pathlib.Path(file_template_name)
|
||||
|
||||
if not file_template_path.is_file():
|
||||
file_template_path = pathlib.Path(os.path.join(self._plugin_path, file_template_name))
|
||||
self._file_template_contents = file_template_path.read_text()
|
||||
except KeyError:
|
||||
logging.warning("A file header template is not specified in the config file.")
|
||||
except FileNotFoundError:
|
||||
logging.warning("The specified file header template file was not found.")
|
||||
try:
|
||||
func_template_name = parser["dummy_section"]["cmt_insert_func_header"]
|
||||
|
||||
func_template_path = pathlib.Path(func_template_name)
|
||||
|
||||
if not func_template_path.is_file():
|
||||
func_template_path = pathlib.Path(os.path.join(self._plugin_path, func_template_name))
|
||||
self._func_template_contents = func_template_path.read_text()
|
||||
except KeyError:
|
||||
logging.warning("A function header template is not specified in the config file.")
|
||||
except FileNotFoundError:
|
||||
logging.warning("The specified function header template file was not found.")
|
||||
|
||||
def _initialize_app_info(self) -> None:
|
||||
"""
|
||||
Initialize Uncrustify application information.
|
||||
|
||||
This function will determine the application path and version.
|
||||
"""
|
||||
# Verify Uncrustify is specified in the environment.
|
||||
if UncrustifyCheck.UNCRUSTIFY_PATH_ENV_KEY not in os.environ:
|
||||
raise UncrustifyAppEnvVarNotFoundException(
|
||||
f"Uncrustify environment variable {UncrustifyCheck.UNCRUSTIFY_PATH_ENV_KEY} is not present.")
|
||||
|
||||
self._app_path = shutil.which('uncrustify', path=os.environ[UncrustifyCheck.UNCRUSTIFY_PATH_ENV_KEY])
|
||||
|
||||
if self._app_path is None:
|
||||
raise FileNotFoundError(
|
||||
errno.ENOENT, os.strerror(errno.ENOENT), self._app_path)
|
||||
|
||||
self._app_path = os.path.normcase(os.path.normpath(self._app_path))
|
||||
|
||||
if not os.path.isfile(self._app_path):
|
||||
raise FileNotFoundError(
|
||||
errno.ENOENT, os.strerror(errno.ENOENT), self._app_path)
|
||||
|
||||
# Verify Uncrustify is present at the expected path.
|
||||
return_buffer = StringIO()
|
||||
ret = RunCmd(self._app_path, "--version", outstream=return_buffer)
|
||||
if (ret != 0):
|
||||
raise UncrustifyAppVersionErrorException(
|
||||
f"Error occurred executing --version: {ret}.")
|
||||
|
||||
# Log Uncrustify version information.
|
||||
self._app_version = return_buffer.getvalue().strip()
|
||||
self._tc.LogStdOut(f"Uncrustify version: {self._app_version}")
|
||||
version_aggregator.GetVersionAggregator().ReportVersion(
|
||||
"Uncrustify", self._app_version, version_aggregator.VersionTypes.INFO)
|
||||
|
||||
def _initialize_config_file_info(self) -> None:
|
||||
"""
|
||||
Initialize Uncrustify configuration file info.
|
||||
|
||||
The config file path is relative to the package root.
|
||||
"""
|
||||
self._app_config_file = UncrustifyCheck.DEFAULT_CONFIG_FILE_PATH
|
||||
if "ConfigFilePath" in self._package_config:
|
||||
self._app_config_file = self._package_config["ConfigFilePath"].strip()
|
||||
|
||||
self._app_config_file = os.path.normpath(
|
||||
os.path.join(self._abs_package_path, self._app_config_file))
|
||||
|
||||
if not os.path.isfile(self._app_config_file):
|
||||
raise FileNotFoundError(
|
||||
errno.ENOENT, os.strerror(errno.ENOENT), self._app_config_file)
|
||||
|
||||
def _initialize_environment_info(self, package_rel_path: str, edk2_path: Edk2Path, package_config: Dict[str, List[str]], tc: JunitReportTestCase) -> None:
|
||||
"""
|
||||
Initializes plugin environment information.
|
||||
"""
|
||||
self._abs_package_path = edk2_path.GetAbsolutePathOnThisSystemFromEdk2RelativePath(
|
||||
package_rel_path)
|
||||
self._abs_workspace_path = edk2_path.WorkspacePath
|
||||
self._package_config = package_config
|
||||
self._package_name = os.path.basename(
|
||||
os.path.normpath(package_rel_path))
|
||||
self._plugin_name = self.__class__.__name__
|
||||
self._plugin_path = os.path.dirname(os.path.realpath(__file__))
|
||||
self._rel_package_path = package_rel_path
|
||||
self._tc = tc
|
||||
|
||||
def _initialize_file_to_format_info(self) -> None:
|
||||
"""
|
||||
Forms the list of source files for Uncrustify to process.
|
||||
"""
|
||||
# Create a list of all the package relative file paths in the package to run against Uncrustify.
|
||||
rel_file_paths_to_format = list(
|
||||
UncrustifyCheck.STANDARD_PLUGIN_DEFINED_PATHS)
|
||||
|
||||
# Allow the ci.yaml to remove any of the pre-defined standard paths
|
||||
if "IgnoreStandardPaths" in self._package_config:
|
||||
for a in self._package_config["IgnoreStandardPaths"]:
|
||||
if a.strip() in rel_file_paths_to_format:
|
||||
self._tc.LogStdOut(
|
||||
f"Ignoring standard path due to ci.yaml ignore: {a}")
|
||||
rel_file_paths_to_format.remove(a.strip())
|
||||
else:
|
||||
raise UncrustifyInvalidIgnoreStandardPathsException(f"Invalid IgnoreStandardPaths value: {a}")
|
||||
|
||||
# Allow the ci.yaml to specify additional include paths for this package
|
||||
if "AdditionalIncludePaths" in self._package_config:
|
||||
rel_file_paths_to_format.extend(
|
||||
self._package_config["AdditionalIncludePaths"])
|
||||
|
||||
self._abs_file_paths_to_format = []
|
||||
for path in rel_file_paths_to_format:
|
||||
self._abs_file_paths_to_format.extend(
|
||||
[str(path.resolve()) for path in pathlib.Path(self._abs_package_path).rglob(path)])
|
||||
|
||||
# Remove files ignore in the plugin configuration file
|
||||
plugin_ignored_files = list(filter(self._get_files_ignored_in_config(), self._abs_file_paths_to_format))
|
||||
|
||||
if plugin_ignored_files:
|
||||
logging.info(
|
||||
f"{self._package_name} file count before plugin ignore file exclusion: {len(self._abs_file_paths_to_format)}")
|
||||
for path in plugin_ignored_files:
|
||||
if path in self._abs_file_paths_to_format:
|
||||
logging.info(f" File ignored in plugin config file: {path}")
|
||||
self._abs_file_paths_to_format.remove(path)
|
||||
logging.info(
|
||||
f"{self._package_name} file count after plugin ignore file exclusion: {len(self._abs_file_paths_to_format)}")
|
||||
|
||||
if not "SkipGitExclusions" in self._package_config or not self._package_config["SkipGitExclusions"]:
|
||||
# Remove files ignored by git
|
||||
logging.info(
|
||||
f"{self._package_name} file count before git ignore file exclusion: {len(self._abs_file_paths_to_format)}")
|
||||
|
||||
ignored_paths = self._get_git_ignored_paths()
|
||||
self._abs_file_paths_to_format = list(
|
||||
set(self._abs_file_paths_to_format).difference(ignored_paths))
|
||||
|
||||
logging.info(
|
||||
f"{self._package_name} file count after git ignore file exclusion: {len(self._abs_file_paths_to_format)}")
|
||||
|
||||
# Remove files in submodules
|
||||
logging.info(
|
||||
f"{self._package_name} file count before submodule exclusion: {len(self._abs_file_paths_to_format)}")
|
||||
|
||||
submodule_paths = tuple(self._get_git_submodule_paths())
|
||||
for path in submodule_paths:
|
||||
logging.info(f" submodule path: {path}")
|
||||
|
||||
self._abs_file_paths_to_format = [
|
||||
f for f in self._abs_file_paths_to_format if not f.startswith(submodule_paths)]
|
||||
|
||||
logging.info(
|
||||
f"{self._package_name} file count after submodule exclusion: {len(self._abs_file_paths_to_format)}")
|
||||
|
||||
# Sort the files for more consistent results
|
||||
self._abs_file_paths_to_format.sort()
|
||||
|
||||
def _initialize_test_case_output_options(self) -> None:
|
||||
"""
|
||||
Initializes options that influence test case output.
|
||||
"""
|
||||
self._audit_only_mode = False
|
||||
self._output_file_diffs = True
|
||||
|
||||
if "AuditOnly" in self._package_config and self._package_config["AuditOnly"]:
|
||||
self._audit_only_mode = True
|
||||
|
||||
if "OutputFileDiffs" in self._package_config and not self._package_config["OutputFileDiffs"]:
|
||||
self._output_file_diffs = False
|
||||
|
||||
def _log_uncrustify_app_info(self) -> None:
|
||||
"""
|
||||
Logs Uncrustify application information.
|
||||
"""
|
||||
self._tc.LogStdOut(f"Found Uncrustify at {self._app_path}")
|
||||
self._tc.LogStdOut(f"Uncrustify version: {self._app_version}")
|
||||
self._tc.LogStdOut('\n')
|
||||
logging.info(f"Found Uncrustify at {self._app_path}")
|
||||
logging.info(f"Uncrustify version: {self._app_version}")
|
||||
logging.info('\n')
|
||||
|
||||
def _process_uncrustify_results(self) -> None:
|
||||
"""
|
||||
Process the results from Uncrustify.
|
||||
|
||||
Determines whether formatting errors are present and logs failures.
|
||||
"""
|
||||
formatted_files = [str(path.resolve()) for path in pathlib.Path(
|
||||
self._abs_package_path).rglob(f'*{UncrustifyCheck.FORMATTED_FILE_EXTENSION}')]
|
||||
|
||||
self._formatted_file_error_count = len(formatted_files)
|
||||
|
||||
if self._formatted_file_error_count > 0:
|
||||
logging.error(
|
||||
"Visit the following instructions to learn "
|
||||
"how to find the detailed formatting errors in Azure "
|
||||
"DevOps CI: "
|
||||
"https://github.com/tianocore/tianocore.github.io/wiki/EDK-II-Code-Formatting#how-to-find-uncrustify-formatting-errors-in-continuous-integration-ci")
|
||||
self._tc.LogStdError("Files with formatting errors:\n")
|
||||
|
||||
if self._output_file_diffs:
|
||||
logging.info("Calculating file diffs. This might take a while...")
|
||||
|
||||
for formatted_file in formatted_files:
|
||||
pre_formatted_file = formatted_file[:-
|
||||
len(UncrustifyCheck.FORMATTED_FILE_EXTENSION)]
|
||||
logging.error(pre_formatted_file)
|
||||
|
||||
if (self._output_file_diffs or
|
||||
self._file_template_contents is not None or
|
||||
self._func_template_contents is not None):
|
||||
self._tc.LogStdError(
|
||||
f"Formatting errors in {os.path.relpath(pre_formatted_file, self._abs_package_path)}\n")
|
||||
|
||||
with open(formatted_file) as ff:
|
||||
formatted_file_text = ff.read()
|
||||
|
||||
if (self._file_template_contents is not None and
|
||||
self._file_template_contents in formatted_file_text):
|
||||
self._tc.LogStdError(f"File header is missing in {os.path.relpath(pre_formatted_file, self._abs_package_path)}\n")
|
||||
|
||||
if (self._func_template_contents is not None and
|
||||
self._func_template_contents in formatted_file_text):
|
||||
self._tc.LogStdError(f"A function header is missing in {os.path.relpath(pre_formatted_file, self._abs_package_path)}\n")
|
||||
|
||||
if self._output_file_diffs:
|
||||
with open(pre_formatted_file) as pf:
|
||||
pre_formatted_file_text = pf.read()
|
||||
|
||||
for line in difflib.unified_diff(pre_formatted_file_text.split('\n'), formatted_file_text.split('\n'), fromfile=pre_formatted_file, tofile=formatted_file, n=3):
|
||||
self._tc.LogStdError(line)
|
||||
|
||||
self._tc.LogStdError('\n')
|
||||
else:
|
||||
self._tc.LogStdError(pre_formatted_file)
|
||||
|
||||
def _remove_tree(self, dir_path: str, ignore_errors: bool = False) -> None:
|
||||
"""
|
||||
Helper for removing a directory. Over time there have been
|
||||
many private implementations of this due to reliability issues in the
|
||||
shutil implementations. To consolidate on a single function this helper is added.
|
||||
|
||||
On error try to change file attributes. Also add retry logic.
|
||||
|
||||
This function is temporarily borrowed from edk2toollib.utility_functions
|
||||
since the version used in edk2 is not recent enough to include the
|
||||
function.
|
||||
|
||||
This function should be replaced by "RemoveTree" when it is available.
|
||||
|
||||
Args:
|
||||
- dir_path: Path to directory to remove.
|
||||
- ignore_errors: Whether to ignore errors during removal
|
||||
"""
|
||||
|
||||
def _remove_readonly(func, path, _):
|
||||
"""
|
||||
Private function to attempt to change permissions on file/folder being deleted.
|
||||
"""
|
||||
os.chmod(path, stat.S_IWRITE)
|
||||
func(path)
|
||||
|
||||
for _ in range(3): # retry up to 3 times
|
||||
try:
|
||||
shutil.rmtree(dir_path, ignore_errors=ignore_errors, onerror=_remove_readonly)
|
||||
except OSError as err:
|
||||
logging.warning(f"Failed to fully remove {dir_path}: {err}")
|
||||
else:
|
||||
break
|
||||
else:
|
||||
raise RuntimeError(f"Failed to remove {dir_path}")
|
||||
|
||||
def _run_uncrustify(self) -> None:
|
||||
"""
|
||||
Runs Uncrustify for this instance of plugin execution.
|
||||
"""
|
||||
logging.info("Executing Uncrustify. This might take a while...")
|
||||
start_time = timeit.default_timer()
|
||||
self._execute_uncrustify()
|
||||
end_time = timeit.default_timer() - start_time
|
||||
|
||||
execution_summary = f"Uncrustify executed against {len(self._abs_file_paths_to_format)} files in {self._package_name} in {end_time:.2f} seconds.\n"
|
||||
|
||||
self._tc.LogStdOut(execution_summary)
|
||||
logging.info(execution_summary)
|
||||
|
||||
if self._app_exit_code != 0 and self._app_exit_code != 1:
|
||||
raise UncrustifyAppExecutionException(
|
||||
f"Error {str(self._app_exit_code)} returned from Uncrustify:\n\n{str(self._app_output)}")
|
@ -1,9 +0,0 @@
|
||||
/** @file
|
||||
Brief description of the file's purpose.
|
||||
|
||||
Detailed description of the file's contents and other useful
|
||||
information for a person viewing the file for the first time.
|
||||
|
||||
<<Copyright>>
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
**/
|
@ -1,15 +0,0 @@
|
||||
/**
|
||||
Brief description of this function's purpose.
|
||||
|
||||
Follow it immediately with the detailed description.
|
||||
|
||||
@param[in] Arg1 Description of Arg1.
|
||||
@param[in] Arg2 Description of Arg2 This is complicated and requires
|
||||
multiple lines to describe.
|
||||
@param[out] Arg3 Description of Arg3.
|
||||
@param[in, out] Arg4 Description of Arg4.
|
||||
|
||||
@retval VAL_ONE Description of what VAL_ONE signifies.
|
||||
@retval OTHER This is the only other return value. If there were other
|
||||
return values, they would be listed.
|
||||
**/
|
@ -1,462 +0,0 @@
|
||||
## @file
|
||||
# Uncrustify Configuration File for EDK II C Code
|
||||
#
|
||||
# Coding Standard: https://edk2-docs.gitbook.io/edk-ii-c-coding-standards-specification/
|
||||
#
|
||||
# This configuration file is meant to be a "best attempt" to align with the
|
||||
# definitions in the EDK II C Coding Standards Specification.
|
||||
#
|
||||
# Copyright (c) Microsoft Corporation.
|
||||
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
##
|
||||
|
||||
# Force UTF-8 encoding (no UTF-16)
|
||||
enable_digraphs = false
|
||||
utf8_byte = false
|
||||
utf8_force = true
|
||||
|
||||
# Code width / line splitting
|
||||
#code_width =120 # TODO: This causes non-deterministic behaviour in some cases when code wraps
|
||||
ls_code_width =false
|
||||
ls_for_split_full =true
|
||||
ls_func_split_full =true
|
||||
pos_comma =trail
|
||||
|
||||
# 5.1.7 All files must end with CRLF
|
||||
newlines = crlf
|
||||
|
||||
# 5.1.2 Do not use tab characters
|
||||
|
||||
cmt_convert_tab_to_spaces = true # Whether to convert all tabs to spaces in comments. If false, tabs in
|
||||
# comments are left alone, unless used for indenting.
|
||||
indent_columns = 2 # Number of spaces for indentation
|
||||
indent_with_tabs = 0 # Do not use TAB characters
|
||||
string_replace_tab_chars = true # Replace TAB with SPACE
|
||||
# Note: This will break .robot files but is needed for edk2 style
|
||||
|
||||
# 5.2.1.1 There shall be only one statement on a line (statement ends with ;)
|
||||
nl_multi_line_cond = true # Add a newline between ')' and '{' if the ')' is on a different line than
|
||||
# the if/for/etc.
|
||||
nl_after_semicolon = true # Whether to add a newline after semicolons, except in 'for' statements.
|
||||
|
||||
# 5.2.1.3 An open brace '{' goes on the same line as the closing parenthesis ')' of simple predicate expressions
|
||||
mod_full_brace_do = add # Add or remove braces on a single-line 'do' statement.
|
||||
mod_full_brace_for = add
|
||||
mod_full_brace_function = add # Add or remove braces on a single-line function definition.
|
||||
mod_full_brace_if = add # Add or remove braces on a single-line 'if' statement. Braces will not be
|
||||
# removed if the braced statement contains an 'else'.
|
||||
mod_full_brace_if_chain = false
|
||||
mod_full_brace_while = add
|
||||
|
||||
# 5.2.1.4 A close brace '}' always goes at the beginning of the last line of the body
|
||||
eat_blanks_after_open_brace = true
|
||||
eat_blanks_before_close_brace = true # Whether to remove blank lines before '}'.
|
||||
|
||||
# 5.2.2.2 Always put space before and after binary operators.
|
||||
sp_assign = add # Add or remove space around assignment operator '=', '+=', etc.
|
||||
sp_assign_default = add
|
||||
sp_bool = add # Add or remove space around boolean operators '&&' and '||'.
|
||||
sp_compare = add # Add or remove space around compare operator '<', '>', '==', etc.
|
||||
|
||||
# 5.2.2.3 Do not put space between unary operators and their object
|
||||
sp_addr = remove # A or remove space after the '&' (address-of) unary operator.
|
||||
sp_incdec = remove # Add or remove space between '++' and '--' the word to which it is being
|
||||
# applied, as in '(--x)' or 'y++;'.
|
||||
sp_inv = remove # Add or remove space after the '~' (invert) unary operator.
|
||||
sp_not = remove # Add or remove space after the '!' (not) unary operator.
|
||||
sp_sign = remove # Add or remove space after '+' or '-', as in 'x = -5' or 'y = +7'.
|
||||
|
||||
# 5.2.2.4 Subsequent lines of multi-line function calls should line up two spaces from the beginning of the function
|
||||
# name
|
||||
nl_func_call_args_multi_line = true # Whether to add a newline after each ',' in a function call if '(' and ')'
|
||||
# are in different lines.
|
||||
nl_func_call_args_multi_line_ignore_closures = false
|
||||
|
||||
# - Indent each argument 2 spaces from the start of the function name. If a
|
||||
# function is called through a structure or union member, of type
|
||||
# pointer-to-function, then indent each argument 2 spaces from the start of the
|
||||
# member name.
|
||||
indent_func_call_edk2_style = true # Use EDK2 indentation style for function calls (**CUSTOM SETTING**)
|
||||
indent_paren_after_func_call = true # Whether to indent the open parenthesis of a function call, if the
|
||||
# parenthesis is on its own line.
|
||||
|
||||
# - Align the close parenthesis with the start of the last argument
|
||||
indent_paren_close = 0 # How to indent a close parenthesis after a newline.
|
||||
# (0: Body, 1: Openparenthesis, 2: Brace level)
|
||||
|
||||
|
||||
# 5.2.2.5 Always put space after commas or semicolons that separate items
|
||||
sp_after_comma = force # Add or remove space after ',', i.e. 'a,b' vs. 'a, b'.
|
||||
sp_before_comma = remove # Add or remove space before ','.
|
||||
|
||||
# 5.2.2.6 Always put space before an open parenthesis
|
||||
sp_after_sparen = add # Add or remove space after ')' of control statements.
|
||||
sp_attribute_paren = add # Add or remove space between '__attribute__' and '('.
|
||||
sp_before_sparen = force # Add or remove space before '(' of control statements
|
||||
# ('if', 'for', 'switch', 'while', etc.).
|
||||
sp_defined_paren = force # Add or remove space between 'defined' and '(' in '#if defined (FOO)'.
|
||||
sp_func_call_paren = force # Add or remove space between function name and '(' on function calls.
|
||||
sp_func_call_paren_empty = force # Add or remove space between function name and '()' on function calls
|
||||
# without parameters. If set to ignore (the default), sp_func_call_paren is
|
||||
# used.
|
||||
sp_func_def_paren = add # Add or remove space between alias name and '(' of a non-pointer function
|
||||
# type typedef.
|
||||
sp_func_proto_paren = add # Add or remove space between function name and '()' on function declaration
|
||||
sp_sizeof_paren = force # Add or remove space between 'sizeof' and '('.
|
||||
sp_type_func = add # Add or remove space between return type and function name. A minimum of 1
|
||||
# is forced except for pointer return types.
|
||||
|
||||
# Not specified, but also good style to remove spaces inside parentheses (Optional)
|
||||
sp_cparen_oparen = remove # Add or remove space between back-to-back parentheses, i.e. ')(' vs. ') ('.
|
||||
sp_inside_fparen = remove # Add or remove space inside function '(' and ')'.
|
||||
sp_inside_fparens = remove # Add or remove space inside empty function '()'.
|
||||
sp_inside_paren = remove # Add or remove space inside '(' and ')'.
|
||||
sp_inside_paren_cast = remove # Add or remove spaces inside cast parentheses. '(int)x'
|
||||
sp_inside_square = remove # Add or remove space inside a non-empty '[' and ']'.
|
||||
sp_paren_paren = remove # Add or remove space between nested parentheses, i.e. '((' vs. ') )'.
|
||||
sp_square_fparen = remove # Add or remove space between ']' and '(' when part of a function call.
|
||||
|
||||
# 5.2.2.7 Put a space before an open brace if it is not on its own line
|
||||
sp_do_brace_open = force # Add or remove space between 'do' and '{'.
|
||||
sp_paren_brace = force # Add or remove space between ')' and '{'.
|
||||
sp_sparen_brace = force # Add or remove space between ')' and '{' of of control statements.
|
||||
|
||||
# 5.2.2.8 Do not put spaces around structure member and pointer operators
|
||||
sp_after_byref = remove # Add or remove space after reference sign '&', if followed by a word.
|
||||
sp_before_byref = add # Add or remove space before a reference sign '&'.
|
||||
sp_deref = remove # Add or remove space after the '*' (dereference) unary operator. This does
|
||||
# not affect the spacing after a '*' that is part of a type.
|
||||
sp_member = remove # Add or remove space around the '.' or '->' operators.
|
||||
|
||||
# 5.2.2.9 Do not put spaces before open brackets of array subscripts
|
||||
sp_before_square = remove # Add or remove space before '[' (except '[]').
|
||||
sp_before_squares = remove # Add or remove space before '[]'.
|
||||
sp_before_vardef_square = remove # Add or remove space before '[' for a variable definition.
|
||||
|
||||
# 5.2.2.10 Use extra parentheses rather than depending on in-depth knowledge of the order of precedence of C
|
||||
mod_full_paren_if_bool = true # Whether to fully parenthesize Boolean expressions in 'while' and 'if'
|
||||
# statement, as in 'if (a && b > c)' => 'if (a && (b > c))'.
|
||||
|
||||
# 5.2.2.11 Align a continuation line with the part of the line that it continues.
|
||||
use_indent_continue_only_once = true
|
||||
|
||||
# Additional '{}' bracing rules (Optional)
|
||||
# NOTE - The style guide specifies two different styles for braces,
|
||||
# so these are ignored for now to allow developers some flexibility.
|
||||
nl_after_brace_close = true # Whether to add a newline after '}'. Does not apply if followed by a
|
||||
# necessary ';'.
|
||||
nl_brace_else = remove # Add or remove newline between '}' and 'else'.
|
||||
nl_brace_while = remove # Add or remove newline between '}' and 'while' of 'do' statement.
|
||||
nl_do_brace = remove # Add or remove newline between 'do' and '{'.
|
||||
nl_else_brace = remove # Add or remove newline between 'else' and '{'.
|
||||
nl_else_if = remove # Add or remove newline between 'else' and 'if'.
|
||||
nl_elseif_brace = remove # Add or remove newline between 'else if' and '{'.
|
||||
nl_enum_brace = remove # Add or remove newline between 'enum' and '{'.
|
||||
nl_fcall_brace = remove # Add or remove newline between a function call's ')' and '{',
|
||||
# as in 'list_for_each(item, &list) { }'.
|
||||
nl_for_brace = remove # Add or remove newline between 'for' and '{'.
|
||||
nl_if_brace = remove # Add or remove newline between 'if' and '{'.
|
||||
nl_struct_brace = remove # Add or remove newline between 'struct and '{'.
|
||||
nl_switch_brace = remove # Add or remove newline between 'switch' and '{'.
|
||||
nl_union_brace = remove # Add or remove newline between 'union' and '{'.
|
||||
nl_while_brace = remove # Add or remove newline between 'while' and '{'.
|
||||
|
||||
# Additional whitespace rules (Optional)
|
||||
sp_after_ptr_star = remove # Add or remove space after pointer star '*', if followed by a word.
|
||||
# Useful when paired with align_var_def_star_style==2
|
||||
sp_after_ptr_star_func = remove # Add or remove space after a pointer star '*', if followed by a function
|
||||
# prototype or function definition.
|
||||
sp_after_semi = remove # Add or remove space after ';', except when followed by a comment.
|
||||
sp_before_case_colon = remove # Add or remove space before case ':'.
|
||||
sp_before_ptr_star = add # Add or remove space before pointer star '*'.
|
||||
sp_before_ptr_star_func = add # Add or remove space before a pointer star '*', if followed by a function
|
||||
# prototype or function definition.
|
||||
sp_before_semi = remove # Add or remove space before ';'
|
||||
sp_before_semi_for = remove # Add or remove space before ';' in non-empty 'for' statements.
|
||||
sp_before_semi_for_empty = add # Add or remove space before a semicolon of an empty part of a for statement
|
||||
sp_between_ptr_star = remove # Add or remove space between pointer stars '*'. (ie, 'VOID **')
|
||||
sp_brace_close_while = force # Add or remove space between '}' and 'while'.
|
||||
|
||||
sp_after_cast = remove
|
||||
sp_after_type = add
|
||||
sp_balance_nested_parens = false
|
||||
sp_before_nl_cont = add
|
||||
sp_before_square_asm_block = ignore
|
||||
sp_before_unnamed_byref = add
|
||||
sp_brace_brace = ignore
|
||||
sp_brace_else = force
|
||||
sp_brace_typedef = add
|
||||
sp_case_label = force
|
||||
sp_cmt_cpp_doxygen = true
|
||||
sp_cond_colon = add
|
||||
sp_cond_question = add
|
||||
sp_cpp_cast_paren = force
|
||||
sp_else_brace = force
|
||||
sp_endif_cmt = force
|
||||
sp_enum_assign = add
|
||||
sp_inside_braces = force
|
||||
sp_inside_braces_empty = force
|
||||
sp_inside_braces_enum = force
|
||||
sp_inside_braces_struct = force
|
||||
sp_pp_concat = add
|
||||
sp_pp_stringify = add
|
||||
sp_return_paren = add
|
||||
sp_special_semi = force
|
||||
sp_while_paren_open = force
|
||||
|
||||
# Additional Indentation Rules
|
||||
indent_access_spec = 1
|
||||
indent_access_spec_body = false
|
||||
indent_align_assign = true
|
||||
indent_align_string = true
|
||||
indent_bool_paren = true
|
||||
indent_brace_parent = false
|
||||
indent_braces = false
|
||||
indent_braces_no_class = false
|
||||
indent_braces_no_func = true
|
||||
indent_braces_no_struct = false
|
||||
indent_class = true
|
||||
indent_class_colon = false
|
||||
indent_cmt_with_tabs = false # Whether to indent comments that are not at a brace level with tabs on
|
||||
# a tabstop. Requires indent_with_tabs=2. If false, will use spaces.
|
||||
indent_col1_comment = true
|
||||
indent_col1_multi_string_literal= true
|
||||
indent_comma_paren = true
|
||||
indent_else_if = true
|
||||
indent_extern = true
|
||||
indent_first_bool_expr = true
|
||||
|
||||
indent_func_def_param_paren_pos_threshold = 0
|
||||
indent_func_param_double = false
|
||||
indent_func_proto_param = true
|
||||
indent_ignore_asm_block = true
|
||||
indent_label = 1
|
||||
indent_member = 2
|
||||
indent_namespace = false
|
||||
indent_param = 2
|
||||
indent_paren_nl = false
|
||||
indent_paren_open_brace = false
|
||||
indent_preserve_sql = false
|
||||
indent_relative_single_line_comments = false
|
||||
indent_sing_line_comments = 0
|
||||
indent_single_newlines = false
|
||||
indent_square_nl = false
|
||||
indent_switch_case = 2
|
||||
indent_template_param = true
|
||||
indent_var_def_blk = 0
|
||||
indent_var_def_cont = false
|
||||
|
||||
# Tidy-up rules (Optional)
|
||||
mod_move_case_break = true # Whether to move a 'break' that appears after a fully braced 'case'
|
||||
# before the close brace, as in 'case X: { ... } break;' =>
|
||||
# 'case X: { ... break; }'.
|
||||
mod_pawn_semicolon = false
|
||||
mod_remove_empty_return = false # Whether to remove a void 'return;' that appears as the last statement
|
||||
# in a function.
|
||||
mod_remove_extra_semicolon = true
|
||||
mod_sort_import = false
|
||||
mod_sort_include = false
|
||||
mod_sort_using = false
|
||||
nl_after_case = false # Whether to add a newline after a 'case' statement.
|
||||
nl_end_of_file = force # Add or remove newline at the end of the file.
|
||||
nl_end_of_file_min = 1 # The minimum number of newlines at the end of the file
|
||||
nl_max = 2 # The maximum number of consecutive newlines (3 = 2 blank lines).
|
||||
nl_start_of_file = remove # Add or remove newlines at the start of the file.
|
||||
|
||||
# Code alignment rules (Optional)
|
||||
align_asm_colon = false
|
||||
align_assign_span = 1 # The span for aligning on '=' in assignments.
|
||||
align_assign_thresh = 0
|
||||
align_edk2_style = true # Whether to apply edk2-specific alignment formatting
|
||||
align_enum_equ_span = 1 # The span for aligning on '=' in enums.
|
||||
align_func_params = true # Whether to align variable definitions in prototypes and functions.
|
||||
align_func_params_gap = 2
|
||||
align_func_params_span = 2 # The span for aligning parameter definitions in function on parameter name.
|
||||
align_func_params_thresh = 0
|
||||
align_func_proto_span = 0
|
||||
align_keep_tabs = false
|
||||
align_left_shift = false
|
||||
align_mix_var_proto = false
|
||||
align_nl_cont = false
|
||||
align_oc_decl_colon = false
|
||||
align_on_operator = false
|
||||
align_on_tabstop = false
|
||||
align_pp_define_gap = 2
|
||||
align_pp_define_span = 1
|
||||
align_right_cmt_at_col = 0 # Align trailing comment at or beyond column N; 'pulls in' comments as
|
||||
# a bonus side effect (0=ignore)
|
||||
align_right_cmt_gap = 0 # If a trailing comment is more than this number of columns away from the
|
||||
# text it follows,
|
||||
# it will qualify for being aligned. This has to be > 0 to do anything.
|
||||
align_right_cmt_mix = false # If aligning comments, mix with comments after '}' and #endif with less
|
||||
# than 3 spaces before the comment
|
||||
align_right_cmt_same_level = true # Whether to only align trailing comments that are at the same brace level.
|
||||
align_right_cmt_span = 2 # The span for aligning comments that end lines.
|
||||
align_same_func_call_params = false
|
||||
align_single_line_brace = true
|
||||
align_single_line_func = true
|
||||
align_struct_init_span = 1 # The span for aligning struct initializer values.
|
||||
align_typedef_amp_style = 1
|
||||
align_typedef_func = 1 # How to align typedef'd functions with other typedefs.
|
||||
# (0: No align, 1: Align open paranthesis, 2: Align function type name)
|
||||
align_typedef_gap = 2
|
||||
align_typedef_span = 1 # The span for aligning single-line typedefs.
|
||||
align_typedef_star_style = 1
|
||||
align_var_def_amp_style = 1
|
||||
align_var_def_attribute = true
|
||||
align_var_def_colon = true # Whether to align the colon in struct bit fields.
|
||||
align_var_def_gap = 2 # The gap (minimum spacing for aligned items) for variable definitions.
|
||||
align_var_def_inline = false
|
||||
align_var_def_span = 1 # The span (lines needed to align) for aligning variable definitions.
|
||||
align_var_def_star_style = 1 # How to consider (or treat) the '*' in the alignment of variable
|
||||
# definitions.
|
||||
# 0: Part of the type 'void * foo;' (default)
|
||||
# 1: Part of the variable 'void *foo;'
|
||||
# 2: Dangling 'void *foo;'
|
||||
# (Note - should also set sp_after_ptr_star=remove)
|
||||
align_var_struct_gap = 4
|
||||
align_var_struct_span = 8 # The span for aligning struct/union member definitions.
|
||||
align_var_struct_thresh = 0
|
||||
align_with_tabs = false
|
||||
|
||||
# Comment formatting
|
||||
cmt_align_doxygen_javadoc_tags = true # Whether to align doxygen javadoc-style tags ('@param', '@return', etc.)
|
||||
# TODO: Eats '[' in '[in]'
|
||||
cmt_c_group = false
|
||||
cmt_c_nl_end = true # Whether to add a newline before the closing '*/' of the combined c-comment.
|
||||
cmt_c_nl_start = true
|
||||
cmt_cpp_group = false
|
||||
cmt_cpp_nl_end = true
|
||||
cmt_cpp_nl_start = true
|
||||
cmt_cpp_to_c = false
|
||||
cmt_indent_multi = false # Whether to apply changes to multi-line comments, including cmt_width,
|
||||
# keyword substitution and leading chars.
|
||||
cmt_insert_before_preproc = false
|
||||
#cmt_insert_file_header = default_file_header.txt
|
||||
#cmt_insert_func_header = default_function_header.txt
|
||||
cmt_multi_check_last = false
|
||||
cmt_multi_first_len_minimum = 2
|
||||
cmt_reflow_mode = 1 # How to reflow comments.
|
||||
# (0:No reflow, 1:No touching at all, 2: Full reflow)
|
||||
cmt_sp_after_star_cont = 0 # The number of spaces to insert after the star on subsequent comment lines.
|
||||
cmt_sp_before_star_cont = 0 # The number of spaces to insert at the start of subsequent comment lines.
|
||||
cmt_star_cont = false # Whether to put a star on subsequent comment lines.
|
||||
cmt_width = 120 # Try to wrap comments at N columns.
|
||||
sp_cmt_cpp_start = add # Add or remove space after the opening of a C++ comment, as in
|
||||
# '// <here> A'. NOTE: Breaks indentation within comments.
|
||||
|
||||
# Function definitions / declarations
|
||||
indent_func_call_param = false # Whether to indent continued function call parameters one indent level,
|
||||
# rather than aligning parameters under the open parenthesis.
|
||||
indent_func_class_param = false # Whether to indent continued function call declaration one indent level,
|
||||
# rather than aligning parameters under the open parenthesis.
|
||||
indent_func_ctor_var_param = false # Whether to indent continued class variable constructors one indent level,
|
||||
# rather than aligning parameters under the open parenthesis.
|
||||
indent_func_def_param = true # Whether to indent continued function definition parameters one indent
|
||||
# level, rather than aligning parameters under the open parenthesis.
|
||||
nl_fdef_brace = add # Add or remove newline between function signature and '{'.
|
||||
nl_func_call_end_multi_line = true # Whether to add a newline before ')' in a function call if '(' and ')' are
|
||||
# in different lines.
|
||||
nl_func_call_paren = remove # Add or remove newline between a function name and the opening '(' in the
|
||||
# call.
|
||||
nl_func_call_start_multi_line = true # Whether to add a newline after '(' in a function call if '(' and ')' are
|
||||
# in different lines.
|
||||
nl_func_decl_args = force # Add or remove newline after each ',' in a function declaration.
|
||||
nl_func_decl_empty = add # Add or remove newline between '()' in a function declaration.
|
||||
nl_func_def_args = force # Add or remove newline after each ',' in a function definition.
|
||||
nl_func_def_empty = add # Add or remove newline between '()' in a function definition.
|
||||
nl_func_def_paren = remove # Add or remove newline between a function name and the opening '('
|
||||
# in the definition.
|
||||
nl_func_paren = remove # Add or remove newline between a function name and the opening '(' in
|
||||
# the declaration.
|
||||
nl_func_type_name = add # Add or remove newline between return type and function name in a function
|
||||
# definition.
|
||||
sp_fparen_brace = force # Add or remove space between ')' and '{' of function.
|
||||
use_indent_func_call_param = true # indent_func_call_param will be used
|
||||
|
||||
# Additional Newline Rules
|
||||
nl_after_brace_open = true # Whether to add a newline after '{'. This also adds a newline
|
||||
# before the matching '}'.
|
||||
nl_after_brace_open_cmt = true # Whether to add a newline between the open brace and a
|
||||
# trailing single-line comment.
|
||||
# Requires nl_after_brace_open = true.
|
||||
nl_after_do = add # Add or remove blank line after 'do/while' statement.
|
||||
nl_after_for = add # Add or remove blank line after 'for' statement.
|
||||
nl_after_func_body = 2 # The number of newlines after '}' of a multi-line function body
|
||||
nl_after_func_body_one_liner = 2
|
||||
nl_after_func_proto = 2
|
||||
nl_after_func_proto_group = 2
|
||||
nl_after_if = add
|
||||
nl_after_multiline_comment = false
|
||||
nl_after_return = false
|
||||
nl_after_struct = 2
|
||||
nl_after_switch = add
|
||||
nl_after_vbrace_close = true
|
||||
nl_after_vbrace_open = true
|
||||
nl_after_vbrace_open_empty = true
|
||||
nl_after_while = add
|
||||
nl_assign_leave_one_liners = true
|
||||
nl_before_block_comment = 2
|
||||
nl_before_case = false
|
||||
nl_before_do = ignore
|
||||
nl_before_for = ignore
|
||||
nl_before_if = ignore
|
||||
nl_before_switch = ignore
|
||||
nl_before_while = ignore
|
||||
nl_before_whole_file_ifdef = 2
|
||||
nl_brace_brace = force
|
||||
nl_brace_struct_var = remove
|
||||
nl_case_colon_brace = add
|
||||
nl_class_leave_one_liners = false
|
||||
nl_collapse_empty_body = false
|
||||
nl_comment_func_def = 1
|
||||
nl_create_for_one_liner = false
|
||||
nl_create_if_one_liner = false
|
||||
nl_create_while_one_liner = false
|
||||
nl_define_macro = false
|
||||
nl_ds_struct_enum_close_brace = true
|
||||
nl_ds_struct_enum_cmt = false
|
||||
nl_enum_leave_one_liners = false
|
||||
nl_func_decl_end = add
|
||||
nl_func_decl_start = add
|
||||
nl_func_def_end = add
|
||||
nl_func_def_start = add
|
||||
nl_func_leave_one_liners = false
|
||||
nl_func_proto_type_name = add
|
||||
nl_func_var_def_blk = 1
|
||||
nl_getset_leave_one_liners = false
|
||||
nl_if_leave_one_liners = false
|
||||
nl_multi_line_define = false
|
||||
nl_squeeze_ifdef = false
|
||||
nl_var_def_blk_end = 0
|
||||
nl_var_def_blk_start = 0
|
||||
|
||||
# Preprocessor Rules
|
||||
pp_define_at_level = true
|
||||
pp_if_indent_code = false
|
||||
pp_indent_func_def = false
|
||||
pp_indent_extern = false
|
||||
pp_ignore_define_body = true # Workaround: Turn off processing for #define body
|
||||
# (current rules do not work for some defines)
|
||||
pp_indent = add
|
||||
pp_indent_at_level = true
|
||||
pp_indent_count = 2
|
||||
pp_indent_if = 2
|
||||
pp_indent_region = 2
|
||||
pp_region_indent_code = false
|
||||
pp_space = remove
|
||||
|
||||
#
|
||||
# The tokens below are assigned specific types so they are always recognized properly.
|
||||
#
|
||||
|
||||
# Explicitly define EDK II qualifiers
|
||||
set QUALIFIER CONST
|
||||
set QUALIFIER EFIAPI
|
||||
set QUALIFIER IN
|
||||
set QUALIFIER OPTIONAL
|
||||
set QUALIFIER OUT
|
||||
|
||||
# Explicitly define EDK II types
|
||||
set TYPE EFI_STATUS
|
||||
set TYPE VOID
|
@ -1,16 +0,0 @@
|
||||
## @file
|
||||
# Downloads the Uncrustify application from a Project Mu NuGet package.
|
||||
#
|
||||
# Copyright (c) Microsoft Corporation.
|
||||
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
##
|
||||
{
|
||||
"id": "uncrustify-ci-1",
|
||||
"scope": "cibuild",
|
||||
"type": "nuget",
|
||||
"name": "mu-uncrustify-release",
|
||||
"source": "https://pkgs.dev.azure.com/projectmu/Uncrustify/_packaging/mu_uncrustify/nuget/v3/index.json",
|
||||
"version": "73.0.8",
|
||||
"flags": ["set_shell_var", "host_specific"],
|
||||
"var_name": "UNCRUSTIFY_CI_PATH"
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
## @file
|
||||
# CiBuildPlugin used to check coding standard compliance of EDK II style C source code
|
||||
#
|
||||
# Copyright (c) Microsoft Corporation.
|
||||
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
##
|
||||
{
|
||||
"scope": "cibuild",
|
||||
"name": "Uncrustify Coding Standard Test",
|
||||
"module": "UncrustifyCheck"
|
||||
}
|
@ -1,12 +1,5 @@
|
||||
# Edk2 Continuous Integration
|
||||
|
||||
This file focuses on information for those working with the `.pytools` directory
|
||||
directly or interested in lower-level details about how CI works.
|
||||
|
||||
If you just want to get started building code, visit
|
||||
[Build Instructions](https://github.com/tianocore/tianocore.github.io/wiki/Build-Instruction)
|
||||
on the TianoCore wiki.
|
||||
|
||||
## Basic Status
|
||||
|
||||
| Package | Windows VS2019 (IA32/X64)| Ubuntu GCC (IA32/X64/ARM/AARCH64) | Known Issues |
|
||||
@ -15,7 +8,7 @@ on the TianoCore wiki.
|
||||
| ArmPlatformPkg | | :heavy_check_mark: |
|
||||
| ArmVirtPkg | SEE PACKAGE README | SEE PACKAGE README |
|
||||
| CryptoPkg | :heavy_check_mark: | :heavy_check_mark: | Spell checking in audit mode
|
||||
| DynamicTablesPkg | :heavy_check_mark: | :heavy_check_mark: |
|
||||
| DynamicTablesPkg | | :heavy_check_mark: |
|
||||
| EmbeddedPkg |
|
||||
| EmulatorPkg | SEE PACKAGE README | SEE PACKAGE README | Spell checking in audit mode
|
||||
| FatPkg | :heavy_check_mark: | :heavy_check_mark: |
|
||||
@ -89,18 +82,43 @@ easily and consistently running locally and in a cloud ci environment. To do
|
||||
that a few steps should be followed. Details of EDKII Tools can be found in the
|
||||
[docs folder here](https://github.com/tianocore/edk2-pytool-extensions/tree/master/docs)
|
||||
|
||||
### Prerequisets
|
||||
|
||||
1. A supported toolchain (others might work but this is what is tested and validated)
|
||||
* Windows 10:
|
||||
* VS 2017 or VS 2019
|
||||
* Windows SDK (for rc)
|
||||
* Windows WDK (for capsules)
|
||||
* Ubuntu 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 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
|
||||
|
||||
@ -246,10 +264,6 @@ BSD-2-Clause-Patent.
|
||||
Run the Ecc tool on the package. The Ecc tool is available in the BaseTools
|
||||
package. It checks that the code complies to the EDKII coding standard.
|
||||
|
||||
### Coding Standard Compliance - UncrustifyCheck
|
||||
|
||||
Runs the Uncrustify application to check for coding standard compliance issues.
|
||||
|
||||
## PyTool Scopes
|
||||
|
||||
Scopes are how the PyTool ext_dep, path_env, and plugins are activated. Meaning
|
||||
|
@ -19,10 +19,7 @@
|
||||
],
|
||||
## Both file path and directory path are accepted.
|
||||
"IgnoreFiles": [
|
||||
"Library/ArmSoftFloatLib/berkeley-softfloat-3",
|
||||
"Library/ArmSoftFloatLib/ArmSoftFloatLib.c",
|
||||
"Library/CompilerIntrinsicsLib",
|
||||
"Universal/Smbios/SmbiosMiscDxe"
|
||||
"Library/ArmSoftFloatLib/berkeley-softfloat-3"
|
||||
]
|
||||
},
|
||||
|
||||
@ -87,7 +84,7 @@
|
||||
|
||||
## options defined .pytool/Plugin/SpellCheck
|
||||
"SpellCheck": {
|
||||
"AuditOnly": True,
|
||||
"AuditOnly": False,
|
||||
"IgnoreFiles": [
|
||||
"Library/ArmSoftFloatLib/berkeley-softfloat-3/**"
|
||||
], # use gitignore syntax to ignore errors
|
||||
@ -239,10 +236,5 @@
|
||||
],
|
||||
"AdditionalIncludePaths": [] # Additional paths to spell check
|
||||
# (wildcards supported)
|
||||
},
|
||||
|
||||
# options defined in .pytool/Plugin/UncrustifyCheck
|
||||
"UncrustifyCheck": {
|
||||
"AuditOnly": True
|
||||
}
|
||||
}
|
||||
|
@ -2,8 +2,7 @@
|
||||
# ARM processor package.
|
||||
#
|
||||
# Copyright (c) 2009 - 2010, Apple Inc. All rights reserved.<BR>
|
||||
# Copyright (c) 2011 - 2023, ARM Limited. All rights reserved.
|
||||
# Copyright (c) 2021, Ampere Computing LLC. All rights reserved.
|
||||
# Copyright (c) 2011 - 2021, ARM Limited. All rights reserved.
|
||||
#
|
||||
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
#
|
||||
@ -71,11 +70,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 +98,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 +131,6 @@
|
||||
# Define if the GICv3 controller should use the GICv2 legacy
|
||||
gArmTokenSpaceGuid.PcdArmGicV3WithV2Legacy|FALSE|BOOLEAN|0x00000042
|
||||
|
||||
# Whether to remap all unused memory NX before installing the CPU arch
|
||||
# protocol driver. This is needed on platforms that map all DRAM with RWX
|
||||
# attributes initially, and can be disabled otherwise.
|
||||
gArmTokenSpaceGuid.PcdRemapUnusedMemoryNx|TRUE|BOOLEAN|0x00000048
|
||||
|
||||
[PcdsFeatureFlag.ARM]
|
||||
# Whether to map normal memory as non-shareable. FALSE is the safe choice, but
|
||||
# TRUE may be appropriate to fix performance problems if you don't care about
|
||||
@ -221,13 +208,6 @@
|
||||
#
|
||||
gArmTokenSpaceGuid.PcdArmDmaDeviceOffset|0x0|UINT64|0x0000044
|
||||
|
||||
#
|
||||
# Boot the Uefi Shell instead of UiApp when no valid boot option is found.
|
||||
# This is useful in CI environment so that startup.nsh can be launched.
|
||||
# The default value is FALSE.
|
||||
#
|
||||
gArmTokenSpaceGuid.PcdUefiShellDefaultBootEnable|FALSE|BOOLEAN|0x0000052
|
||||
|
||||
[PcdsFixedAtBuild.common, PcdsPatchableInModule.common]
|
||||
gArmTokenSpaceGuid.PcdFdBaseAddress|0|UINT64|0x0000002B
|
||||
gArmTokenSpaceGuid.PcdFvBaseAddress|0|UINT64|0x0000002D
|
||||
@ -312,11 +292,6 @@
|
||||
gArmTokenSpaceGuid.PcdSystemBiosRelease|0xFFFF|UINT16|0x30000058
|
||||
gArmTokenSpaceGuid.PcdEmbeddedControllerFirmwareRelease|0xFFFF|UINT16|0x30000059
|
||||
|
||||
## Define the conduit to use for monitor calls.
|
||||
# Default PcdMonitorConduitHvc = FALSE, conduit = SMC
|
||||
# If PcdMonitorConduitHvc = TRUE, conduit = HVC
|
||||
gArmTokenSpaceGuid.PcdMonitorConduitHvc|FALSE|BOOLEAN|0x00000047
|
||||
|
||||
[PcdsFixedAtBuild.common, PcdsDynamic.common]
|
||||
#
|
||||
# ARM Architectural Timer
|
||||
@ -328,7 +303,6 @@
|
||||
gArmTokenSpaceGuid.PcdArmArchTimerIntrNum|30|UINT32|0x00000036
|
||||
gArmTokenSpaceGuid.PcdArmArchTimerHypIntrNum|26|UINT32|0x00000040
|
||||
gArmTokenSpaceGuid.PcdArmArchTimerVirtIntrNum|27|UINT32|0x00000041
|
||||
gArmTokenSpaceGuid.PcdArmArchTimerHypVirtIntrNum|28|UINT32|0x0000004A
|
||||
|
||||
#
|
||||
# ARM Generic Watchdog
|
||||
@ -363,9 +337,9 @@
|
||||
# UINT64 Mmio32CpuBase; // mapping target in 64-bit cpu-physical space
|
||||
# UINT64 Mmio64CpuBase; // mapping target in 64-bit cpu-physical space
|
||||
#
|
||||
# gEfiMdePkgTokenSpaceGuid.PcdPciIoTranslation = IoCpuBase - PcdPciIoBase;
|
||||
# gEfiMdePkgTokenSpaceGuid.PcdPciMmio32Translation = Mmio32CpuBase - (UINT64)PcdPciMmio32Base;
|
||||
# gEfiMdePkgTokenSpaceGuid.PcdPciMmio64Translation = Mmio64CpuBase - PcdPciMmio64Base;
|
||||
# PcdPciIoTranslation = IoCpuBase - PcdPciIoBase;
|
||||
# PcdPciMmio32Translation = Mmio32CpuBase - (UINT64)PcdPciMmio32Base;
|
||||
# PcdPciMmio64Translation = Mmio64CpuBase - PcdPciMmio64Base;
|
||||
#
|
||||
# because (a) the target address space (ie. the cpu-physical space) is
|
||||
# 64-bit, and (b) the translation values are meant as offsets for *modular*
|
||||
@ -382,11 +356,11 @@
|
||||
# UINT64 TranslatedMmio64Address; // output parameter
|
||||
#
|
||||
# TranslatedIoAddress = UntranslatedIoAddress +
|
||||
# gEfiMdePkgTokenSpaceGuid.PcdPciIoTranslation;
|
||||
# PcdPciIoTranslation;
|
||||
# TranslatedMmio32Address = (UINT64)UntranslatedMmio32Address +
|
||||
# gEfiMdePkgTokenSpaceGuid.PcdPciMmio32Translation;
|
||||
# PcdPciMmio32Translation;
|
||||
# TranslatedMmio64Address = UntranslatedMmio64Address +
|
||||
# gEfiMdePkgTokenSpaceGuid.PcdPciMmio64Translation;
|
||||
# PcdPciMmio64Translation;
|
||||
#
|
||||
# The modular arithmetic performed in UINT64 ensures that the translation
|
||||
# works correctly regardless of the relation between IoCpuBase and
|
||||
@ -395,20 +369,16 @@
|
||||
#
|
||||
gArmTokenSpaceGuid.PcdPciIoBase|0x0|UINT64|0x00000050
|
||||
gArmTokenSpaceGuid.PcdPciIoSize|0x0|UINT64|0x00000051
|
||||
gArmTokenSpaceGuid.PcdPciIoTranslation|0x0|UINT64|0x00000052
|
||||
gArmTokenSpaceGuid.PcdPciMmio32Base|0x0|UINT32|0x00000053
|
||||
gArmTokenSpaceGuid.PcdPciMmio32Size|0x0|UINT32|0x00000054
|
||||
gArmTokenSpaceGuid.PcdPciMmio32Translation|0x0|UINT64|0x00000055
|
||||
gArmTokenSpaceGuid.PcdPciMmio64Base|0x0|UINT64|0x00000056
|
||||
gArmTokenSpaceGuid.PcdPciMmio64Size|0x0|UINT64|0x00000057
|
||||
gArmTokenSpaceGuid.PcdPciMmio64Translation|0x0|UINT64|0x00000058
|
||||
|
||||
#
|
||||
# Inclusive range of allowed PCI buses.
|
||||
#
|
||||
gArmTokenSpaceGuid.PcdPciBusMin|0x0|UINT32|0x00000059
|
||||
gArmTokenSpaceGuid.PcdPciBusMax|0x0|UINT32|0x0000005A
|
||||
|
||||
[PcdsDynamicEx]
|
||||
#
|
||||
# This dynamic PCD hold the GUID of a firmware FFS which contains
|
||||
# the LinuxBoot payload.
|
||||
#
|
||||
gArmTokenSpaceGuid.PcdLinuxBootFileGuid|{0x0}|VOID*|0x0000005C
|
||||
|
@ -5,7 +5,6 @@
|
||||
# Copyright (c) 2011 - 2021, Arm Limited. All rights reserved.<BR>
|
||||
# Copyright (c) 2016, Linaro Ltd. All rights reserved.<BR>
|
||||
# Copyright (c) Microsoft Corporation.<BR>
|
||||
# Copyright (c) 2021, Ampere Computing LLC. All rights reserved.
|
||||
#
|
||||
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
#
|
||||
@ -113,6 +112,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 +130,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
|
||||
|
||||
@ -153,7 +150,6 @@
|
||||
ArmPkg/Library/ArmSmcPsciResetSystemLib/ArmSmcPsciResetSystemLib.inf
|
||||
ArmPkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointerLib.inf
|
||||
ArmPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
|
||||
ArmPkg/Library/LinuxBootBootManagerLib/LinuxBootBootManagerLib.inf
|
||||
|
||||
ArmPkg/Drivers/ArmCrashDumpDxe/ArmCrashDumpDxe.inf
|
||||
ArmPkg/Drivers/ArmScmiDxe/ArmScmiDxe.inf
|
||||
@ -162,10 +158,7 @@
|
||||
ArmPkg/Universal/Smbios/SmbiosMiscDxe/SmbiosMiscDxe.inf
|
||||
ArmPkg/Universal/Smbios/OemMiscLibNull/OemMiscLibNull.inf
|
||||
|
||||
ArmPkg/Drivers/MmCommunicationPei/MmCommunicationPei.inf
|
||||
|
||||
[Components.AARCH64]
|
||||
ArmPkg/Drivers/ArmPsciMpServicesDxe/ArmPsciMpServicesDxe.inf
|
||||
ArmPkg/Drivers/MmCommunicationDxe/MmCommunication.inf
|
||||
ArmPkg/Library/ArmMmuLib/ArmMmuPeiLib.inf
|
||||
|
||||
|
@ -12,23 +12,21 @@
|
||||
#include <Library/UefiBootServicesTableLib.h>
|
||||
#include <Protocol/Cpu.h>
|
||||
|
||||
STATIC EFI_CPU_ARCH_PROTOCOL *mCpu;
|
||||
STATIC EFI_CPU_ARCH_PROTOCOL *mCpu;
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
ArmCrashDumpDxeInitialize (
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
IN EFI_SYSTEM_TABLE *SystemTable
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
IN EFI_SYSTEM_TABLE *SystemTable
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_STATUS Status;
|
||||
|
||||
Status = gBS->LocateProtocol (&gEfiCpuArchProtocolGuid, NULL, (VOID **)&mCpu);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
ASSERT_EFI_ERROR(Status);
|
||||
|
||||
return mCpu->RegisterInterruptHandler (
|
||||
mCpu,
|
||||
EXCEPT_AARCH64_SYNCHRONOUS_EXCEPTIONS,
|
||||
&DefaultExceptionHandler
|
||||
);
|
||||
return mCpu->RegisterInterruptHandler (mCpu,
|
||||
EXCEPT_AARCH64_SYNCHRONOUS_EXCEPTIONS,
|
||||
&DefaultExceptionHandler);
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 2013-2023, Arm Ltd. All rights reserved.<BR>
|
||||
Copyright (c) 2013-2017, ARM Ltd. All rights reserved.<BR>
|
||||
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
@ -8,17 +8,32 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
#include "ArmGicDxe.h"
|
||||
|
||||
VOID
|
||||
EFIAPI
|
||||
IrqInterruptHandler (
|
||||
IN EFI_EXCEPTION_TYPE InterruptType,
|
||||
IN EFI_SYSTEM_CONTEXT SystemContext
|
||||
);
|
||||
|
||||
VOID
|
||||
EFIAPI
|
||||
ExitBootServicesEvent (
|
||||
IN EFI_EVENT Event,
|
||||
IN VOID *Context
|
||||
);
|
||||
|
||||
// Making this global saves a few bytes in image size
|
||||
EFI_HANDLE gHardwareInterruptHandle = NULL;
|
||||
|
||||
// Notifications
|
||||
EFI_EVENT EfiExitBootServicesEvent = (EFI_EVENT)NULL;
|
||||
EFI_EVENT EfiExitBootServicesEvent = (EFI_EVENT)NULL;
|
||||
|
||||
// Maximum Number of Interrupts
|
||||
UINTN mGicNumInterrupts = 0;
|
||||
UINTN mGicNumInterrupts = 0;
|
||||
|
||||
HARDWARE_INTERRUPT_HANDLER *gRegisteredInterruptHandlers = NULL;
|
||||
|
||||
|
||||
/**
|
||||
Calculate GICD_ICFGRn base address and corresponding bit
|
||||
field Int_config[1] of the GIC distributor register.
|
||||
@ -32,22 +47,22 @@ HARDWARE_INTERRUPT_HANDLER *gRegisteredInterruptHandlers = NULL;
|
||||
**/
|
||||
EFI_STATUS
|
||||
GicGetDistributorIcfgBaseAndBit (
|
||||
IN HARDWARE_INTERRUPT_SOURCE Source,
|
||||
OUT UINTN *RegAddress,
|
||||
OUT UINTN *Config1Bit
|
||||
IN HARDWARE_INTERRUPT_SOURCE Source,
|
||||
OUT UINTN *RegAddress,
|
||||
OUT UINTN *Config1Bit
|
||||
)
|
||||
{
|
||||
UINTN RegIndex;
|
||||
UINTN Field;
|
||||
UINTN RegIndex;
|
||||
UINTN Field;
|
||||
|
||||
if (Source >= mGicNumInterrupts) {
|
||||
ASSERT (Source < mGicNumInterrupts);
|
||||
ASSERT(Source < mGicNumInterrupts);
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
RegIndex = Source / ARM_GIC_ICDICFR_F_STRIDE; // NOTE: truncation is significant
|
||||
Field = Source % ARM_GIC_ICDICFR_F_STRIDE;
|
||||
*RegAddress = (UINTN)PcdGet64 (PcdGicDistributorBase)
|
||||
RegIndex = Source / ARM_GIC_ICDICFR_F_STRIDE; // NOTE: truncation is significant
|
||||
Field = Source % ARM_GIC_ICDICFR_F_STRIDE;
|
||||
*RegAddress = PcdGet64 (PcdGicDistributorBase)
|
||||
+ ARM_GIC_ICDICFR
|
||||
+ (ARM_GIC_ICDICFR_BYTES * RegIndex);
|
||||
*Config1Bit = ((Field * ARM_GIC_ICDICFR_F_WIDTH)
|
||||
@ -56,6 +71,8 @@ GicGetDistributorIcfgBaseAndBit (
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
Register Handler for the specified interrupt source.
|
||||
|
||||
@ -70,13 +87,13 @@ GicGetDistributorIcfgBaseAndBit (
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
RegisterInterruptSource (
|
||||
IN EFI_HARDWARE_INTERRUPT_PROTOCOL *This,
|
||||
IN HARDWARE_INTERRUPT_SOURCE Source,
|
||||
IN HARDWARE_INTERRUPT_HANDLER Handler
|
||||
IN EFI_HARDWARE_INTERRUPT_PROTOCOL *This,
|
||||
IN HARDWARE_INTERRUPT_SOURCE Source,
|
||||
IN HARDWARE_INTERRUPT_HANDLER Handler
|
||||
)
|
||||
{
|
||||
if (Source >= mGicNumInterrupts) {
|
||||
ASSERT (FALSE);
|
||||
ASSERT(FALSE);
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
@ -91,25 +108,25 @@ RegisterInterruptSource (
|
||||
gRegisteredInterruptHandlers[Source] = Handler;
|
||||
|
||||
// If the interrupt handler is unregistered then disable the interrupt
|
||||
if (NULL == Handler) {
|
||||
if (NULL == Handler){
|
||||
return This->DisableInterruptSource (This, Source);
|
||||
} else {
|
||||
return This->EnableInterruptSource (This, Source);
|
||||
}
|
||||
}
|
||||
|
||||
STATIC VOID *mCpuArchProtocolNotifyEventRegistration;
|
||||
STATIC VOID *mCpuArchProtocolNotifyEventRegistration;
|
||||
|
||||
STATIC
|
||||
VOID
|
||||
EFIAPI
|
||||
CpuArchEventProtocolNotify (
|
||||
IN EFI_EVENT Event,
|
||||
IN VOID *Context
|
||||
IN EFI_EVENT Event,
|
||||
IN VOID *Context
|
||||
)
|
||||
{
|
||||
EFI_CPU_ARCH_PROTOCOL *Cpu;
|
||||
EFI_STATUS Status;
|
||||
EFI_CPU_ARCH_PROTOCOL *Cpu;
|
||||
EFI_STATUS Status;
|
||||
|
||||
// Get the CPU protocol that this driver requires.
|
||||
Status = gBS->LocateProtocol (&gEfiCpuArchProtocolGuid, NULL, (VOID **)&Cpu);
|
||||
@ -120,28 +137,17 @@ CpuArchEventProtocolNotify (
|
||||
// Unregister the default exception handler.
|
||||
Status = Cpu->RegisterInterruptHandler (Cpu, ARM_ARCH_EXCEPTION_IRQ, NULL);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((
|
||||
DEBUG_ERROR,
|
||||
"%a: Cpu->RegisterInterruptHandler() - %r\n",
|
||||
__func__,
|
||||
Status
|
||||
));
|
||||
DEBUG ((DEBUG_ERROR, "%a: Cpu->RegisterInterruptHandler() - %r\n",
|
||||
__FUNCTION__, Status));
|
||||
return;
|
||||
}
|
||||
|
||||
// Register to receive interrupts
|
||||
Status = Cpu->RegisterInterruptHandler (
|
||||
Cpu,
|
||||
ARM_ARCH_EXCEPTION_IRQ,
|
||||
Context
|
||||
);
|
||||
Status = Cpu->RegisterInterruptHandler (Cpu, ARM_ARCH_EXCEPTION_IRQ,
|
||||
Context);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((
|
||||
DEBUG_ERROR,
|
||||
"%a: Cpu->RegisterInterruptHandler() - %r\n",
|
||||
__func__,
|
||||
Status
|
||||
));
|
||||
DEBUG ((DEBUG_ERROR, "%a: Cpu->RegisterInterruptHandler() - %r\n",
|
||||
__FUNCTION__, Status));
|
||||
}
|
||||
|
||||
gBS->CloseEvent (Event);
|
||||
@ -151,13 +157,13 @@ EFI_STATUS
|
||||
InstallAndRegisterInterruptService (
|
||||
IN EFI_HARDWARE_INTERRUPT_PROTOCOL *InterruptProtocol,
|
||||
IN EFI_HARDWARE_INTERRUPT2_PROTOCOL *Interrupt2Protocol,
|
||||
IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler,
|
||||
IN EFI_EVENT_NOTIFY ExitBootServicesEvent
|
||||
IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler,
|
||||
IN EFI_EVENT_NOTIFY ExitBootServicesEvent
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
CONST UINTN RihArraySize =
|
||||
(sizeof (HARDWARE_INTERRUPT_HANDLER) * mGicNumInterrupts);
|
||||
EFI_STATUS Status;
|
||||
CONST UINTN RihArraySize =
|
||||
(sizeof(HARDWARE_INTERRUPT_HANDLER) * mGicNumInterrupts);
|
||||
|
||||
// Initialize the array for the Interrupt Handlers
|
||||
gRegisteredInterruptHandlers = AllocateZeroPool (RihArraySize);
|
||||
@ -185,8 +191,7 @@ InstallAndRegisterInterruptService (
|
||||
TPL_CALLBACK,
|
||||
CpuArchEventProtocolNotify,
|
||||
InterruptHandler,
|
||||
&mCpuArchProtocolNotifyEventRegistration
|
||||
);
|
||||
&mCpuArchProtocolNotifyEventRegistration);
|
||||
|
||||
// Register for an ExitBootServicesEvent
|
||||
Status = gBS->CreateEvent (
|
||||
|
@ -32,12 +32,12 @@ Abstract:
|
||||
**/
|
||||
EFI_STATUS
|
||||
InterruptDxeInitialize (
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
IN EFI_SYSTEM_TABLE *SystemTable
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
IN EFI_SYSTEM_TABLE *SystemTable
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
ARM_GIC_ARCH_REVISION Revision;
|
||||
EFI_STATUS Status;
|
||||
ARM_GIC_ARCH_REVISION Revision;
|
||||
|
||||
Revision = ArmGicGetSupportedArchRevision ();
|
||||
|
||||
|
@ -21,7 +21,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
#include <Protocol/HardwareInterrupt.h>
|
||||
#include <Protocol/HardwareInterrupt2.h>
|
||||
|
||||
extern UINTN mGicNumInterrupts;
|
||||
extern UINTN mGicNumInterrupts;
|
||||
extern HARDWARE_INTERRUPT_HANDLER *gRegisteredInterruptHandlers;
|
||||
|
||||
// Common API
|
||||
@ -29,32 +29,33 @@ EFI_STATUS
|
||||
InstallAndRegisterInterruptService (
|
||||
IN EFI_HARDWARE_INTERRUPT_PROTOCOL *InterruptProtocol,
|
||||
IN EFI_HARDWARE_INTERRUPT2_PROTOCOL *Interrupt2Protocol,
|
||||
IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler,
|
||||
IN EFI_EVENT_NOTIFY ExitBootServicesEvent
|
||||
IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler,
|
||||
IN EFI_EVENT_NOTIFY ExitBootServicesEvent
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
RegisterInterruptSource (
|
||||
IN EFI_HARDWARE_INTERRUPT_PROTOCOL *This,
|
||||
IN HARDWARE_INTERRUPT_SOURCE Source,
|
||||
IN HARDWARE_INTERRUPT_HANDLER Handler
|
||||
IN EFI_HARDWARE_INTERRUPT_PROTOCOL *This,
|
||||
IN HARDWARE_INTERRUPT_SOURCE Source,
|
||||
IN HARDWARE_INTERRUPT_HANDLER Handler
|
||||
);
|
||||
|
||||
// GicV2 API
|
||||
EFI_STATUS
|
||||
GicV2DxeInitialize (
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
IN EFI_SYSTEM_TABLE *SystemTable
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
IN EFI_SYSTEM_TABLE *SystemTable
|
||||
);
|
||||
|
||||
// GicV3 API
|
||||
EFI_STATUS
|
||||
GicV3DxeInitialize (
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
IN EFI_SYSTEM_TABLE *SystemTable
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
IN EFI_SYSTEM_TABLE *SystemTable
|
||||
);
|
||||
|
||||
|
||||
// Shared code
|
||||
|
||||
/**
|
||||
@ -70,9 +71,9 @@ GicV3DxeInitialize (
|
||||
**/
|
||||
EFI_STATUS
|
||||
GicGetDistributorIcfgBaseAndBit (
|
||||
IN HARDWARE_INTERRUPT_SOURCE Source,
|
||||
OUT UINTN *RegAddress,
|
||||
OUT UINTN *Config1Bit
|
||||
IN HARDWARE_INTERRUPT_SOURCE Source,
|
||||
OUT UINTN *RegAddress,
|
||||
OUT UINTN *Config1Bit
|
||||
);
|
||||
|
||||
#endif // ARM_GIC_DXE_H_
|
||||
|
@ -1,6 +1,6 @@
|
||||
/** @file
|
||||
*
|
||||
* Copyright (c) 2011-2023, Arm Limited. All rights reserved.
|
||||
* Copyright (c) 2011-2021, Arm Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
*
|
||||
@ -24,13 +24,13 @@
|
||||
+ ARM_GICR_SGI_VLPI_FRAME_SIZE \
|
||||
+ ARM_GICR_SGI_RESERVED_FRAME_SIZE)
|
||||
|
||||
#define ISENABLER_ADDRESS(base, offset) ((base) +\
|
||||
#define ISENABLER_ADDRESS(base,offset) ((base) + \
|
||||
ARM_GICR_CTLR_FRAME_SIZE + ARM_GICR_ISENABLER + 4 * (offset))
|
||||
|
||||
#define ICENABLER_ADDRESS(base, offset) ((base) +\
|
||||
#define ICENABLER_ADDRESS(base,offset) ((base) + \
|
||||
ARM_GICR_CTLR_FRAME_SIZE + ARM_GICR_ICENABLER + 4 * (offset))
|
||||
|
||||
#define IPRIORITY_ADDRESS(base, offset) ((base) +\
|
||||
#define IPRIORITY_ADDRESS(base,offset) ((base) + \
|
||||
ARM_GICR_CTLR_FRAME_SIZE + ARM_GIC_ICDIPR + 4 * (offset))
|
||||
|
||||
/**
|
||||
@ -57,15 +57,15 @@ SourceIsSpi (
|
||||
STATIC
|
||||
UINTN
|
||||
GicGetCpuRedistributorBase (
|
||||
IN UINTN GicRedistributorBase,
|
||||
IN ARM_GIC_ARCH_REVISION Revision
|
||||
IN UINTN GicRedistributorBase,
|
||||
IN ARM_GIC_ARCH_REVISION Revision
|
||||
)
|
||||
{
|
||||
UINTN MpId;
|
||||
UINTN CpuAffinity;
|
||||
UINTN Affinity;
|
||||
UINTN GicCpuRedistributorBase;
|
||||
UINT64 TypeRegister;
|
||||
UINTN MpId;
|
||||
UINTN CpuAffinity;
|
||||
UINTN Affinity;
|
||||
UINTN GicCpuRedistributorBase;
|
||||
UINT64 TypeRegister;
|
||||
|
||||
MpId = ArmReadMpidr ();
|
||||
// Define CPU affinity as:
|
||||
@ -83,7 +83,7 @@ GicGetCpuRedistributorBase (
|
||||
|
||||
do {
|
||||
TypeRegister = MmioRead64 (GicCpuRedistributorBase + ARM_GICR_TYPER);
|
||||
Affinity = ARM_GICR_TYPER_GET_AFFINITY (TypeRegister);
|
||||
Affinity = ARM_GICR_TYPER_GET_AFFINITY (TypeRegister);
|
||||
if (Affinity == CpuAffinity) {
|
||||
return GicCpuRedistributorBase;
|
||||
}
|
||||
@ -104,17 +104,10 @@ GicGetCpuRedistributorBase (
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
Return the GIC CPU Interrupt Interface ID.
|
||||
|
||||
@param GicInterruptInterfaceBase Base address of the GIC Interrupt Interface.
|
||||
|
||||
@retval CPU Interface Identification information.
|
||||
**/
|
||||
UINT32
|
||||
UINTN
|
||||
EFIAPI
|
||||
ArmGicGetInterfaceIdentification (
|
||||
IN UINTN GicInterruptInterfaceBase
|
||||
IN INTN GicInterruptInterfaceBase
|
||||
)
|
||||
{
|
||||
// Read the GIC Identification Register
|
||||
@ -124,10 +117,10 @@ ArmGicGetInterfaceIdentification (
|
||||
UINTN
|
||||
EFIAPI
|
||||
ArmGicGetMaxNumInterrupts (
|
||||
IN UINTN GicDistributorBase
|
||||
IN INTN GicDistributorBase
|
||||
)
|
||||
{
|
||||
UINTN ItLines;
|
||||
UINTN ItLines;
|
||||
|
||||
ItLines = MmioRead32 (GicDistributorBase + ARM_GIC_ICDICTR) & 0x1F;
|
||||
|
||||
@ -140,17 +133,15 @@ ArmGicGetMaxNumInterrupts (
|
||||
VOID
|
||||
EFIAPI
|
||||
ArmGicSendSgiTo (
|
||||
IN UINTN GicDistributorBase,
|
||||
IN UINT8 TargetListFilter,
|
||||
IN UINT8 CPUTargetList,
|
||||
IN UINT8 SgiId
|
||||
IN INTN GicDistributorBase,
|
||||
IN INTN TargetListFilter,
|
||||
IN INTN CPUTargetList,
|
||||
IN INTN SgiId
|
||||
)
|
||||
{
|
||||
MmioWrite32 (
|
||||
GicDistributorBase + ARM_GIC_ICDSGIR,
|
||||
((TargetListFilter & 0x3) << 24) |
|
||||
((CPUTargetList & 0xFF) << 16) |
|
||||
(SgiId & 0xF)
|
||||
((TargetListFilter & 0x3) << 24) | ((CPUTargetList & 0xFF) << 16) | SgiId
|
||||
);
|
||||
}
|
||||
|
||||
@ -171,22 +162,24 @@ ArmGicSendSgiTo (
|
||||
UINTN
|
||||
EFIAPI
|
||||
ArmGicAcknowledgeInterrupt (
|
||||
IN UINTN GicInterruptInterfaceBase,
|
||||
OUT UINTN *InterruptId
|
||||
IN UINTN GicInterruptInterfaceBase,
|
||||
OUT UINTN *InterruptId
|
||||
)
|
||||
{
|
||||
UINTN Value;
|
||||
UINTN IntId;
|
||||
ARM_GIC_ARCH_REVISION Revision;
|
||||
UINTN Value;
|
||||
ARM_GIC_ARCH_REVISION Revision;
|
||||
|
||||
ASSERT (InterruptId != NULL);
|
||||
Revision = ArmGicGetSupportedArchRevision ();
|
||||
if (Revision == ARM_GIC_ARCH_REVISION_2) {
|
||||
Value = ArmGicV2AcknowledgeInterrupt (GicInterruptInterfaceBase);
|
||||
IntId = Value & ARM_GIC_ICCIAR_ACKINTID;
|
||||
// InterruptId is required for the caller to know if a valid or spurious
|
||||
// interrupt has been read
|
||||
ASSERT (InterruptId != NULL);
|
||||
if (InterruptId != NULL) {
|
||||
*InterruptId = Value & ARM_GIC_ICCIAR_ACKINTID;
|
||||
}
|
||||
} else if (Revision == ARM_GIC_ARCH_REVISION_3) {
|
||||
Value = ArmGicV3AcknowledgeInterrupt ();
|
||||
IntId = Value;
|
||||
} else {
|
||||
ASSERT_EFI_ERROR (EFI_UNSUPPORTED);
|
||||
// Report Spurious interrupt which is what the above controllers would
|
||||
@ -194,23 +187,17 @@ ArmGicAcknowledgeInterrupt (
|
||||
Value = 1023;
|
||||
}
|
||||
|
||||
if (InterruptId != NULL) {
|
||||
// InterruptId is required for the caller to know if a valid or spurious
|
||||
// interrupt has been read
|
||||
*InterruptId = IntId;
|
||||
}
|
||||
|
||||
return Value;
|
||||
}
|
||||
|
||||
VOID
|
||||
EFIAPI
|
||||
ArmGicEndOfInterrupt (
|
||||
IN UINTN GicInterruptInterfaceBase,
|
||||
IN UINTN Source
|
||||
IN UINTN GicInterruptInterfaceBase,
|
||||
IN UINTN Source
|
||||
)
|
||||
{
|
||||
ARM_GIC_ARCH_REVISION Revision;
|
||||
ARM_GIC_ARCH_REVISION Revision;
|
||||
|
||||
Revision = ArmGicGetSupportedArchRevision ();
|
||||
if (Revision == ARM_GIC_ARCH_REVISION_2) {
|
||||
@ -225,26 +212,25 @@ ArmGicEndOfInterrupt (
|
||||
VOID
|
||||
EFIAPI
|
||||
ArmGicSetInterruptPriority (
|
||||
IN UINTN GicDistributorBase,
|
||||
IN UINTN GicRedistributorBase,
|
||||
IN UINTN Source,
|
||||
IN UINTN Priority
|
||||
IN UINTN GicDistributorBase,
|
||||
IN UINTN GicRedistributorBase,
|
||||
IN UINTN Source,
|
||||
IN UINTN Priority
|
||||
)
|
||||
{
|
||||
UINT32 RegOffset;
|
||||
UINT8 RegShift;
|
||||
ARM_GIC_ARCH_REVISION Revision;
|
||||
UINTN GicCpuRedistributorBase;
|
||||
UINT32 RegOffset;
|
||||
UINTN RegShift;
|
||||
ARM_GIC_ARCH_REVISION Revision;
|
||||
UINTN GicCpuRedistributorBase;
|
||||
|
||||
// Calculate register offset and bit position
|
||||
RegOffset = (UINT32)(Source / 4);
|
||||
RegShift = (UINT8)((Source % 4) * 8);
|
||||
RegOffset = Source / 4;
|
||||
RegShift = (Source % 4) * 8;
|
||||
|
||||
Revision = ArmGicGetSupportedArchRevision ();
|
||||
if ((Revision == ARM_GIC_ARCH_REVISION_2) ||
|
||||
FeaturePcdGet (PcdArmGicV3WithV2Legacy) ||
|
||||
SourceIsSpi (Source))
|
||||
{
|
||||
SourceIsSpi (Source)) {
|
||||
MmioAndThenOr32 (
|
||||
GicDistributorBase + ARM_GIC_ICDIPR + (4 * RegOffset),
|
||||
~(0xff << RegShift),
|
||||
@ -270,25 +256,24 @@ ArmGicSetInterruptPriority (
|
||||
VOID
|
||||
EFIAPI
|
||||
ArmGicEnableInterrupt (
|
||||
IN UINTN GicDistributorBase,
|
||||
IN UINTN GicRedistributorBase,
|
||||
IN UINTN Source
|
||||
IN UINTN GicDistributorBase,
|
||||
IN UINTN GicRedistributorBase,
|
||||
IN UINTN Source
|
||||
)
|
||||
{
|
||||
UINT32 RegOffset;
|
||||
UINT8 RegShift;
|
||||
ARM_GIC_ARCH_REVISION Revision;
|
||||
UINTN GicCpuRedistributorBase;
|
||||
UINT32 RegOffset;
|
||||
UINTN RegShift;
|
||||
ARM_GIC_ARCH_REVISION Revision;
|
||||
UINTN GicCpuRedistributorBase;
|
||||
|
||||
// Calculate enable register offset and bit position
|
||||
RegOffset = (UINT32)(Source / 32);
|
||||
RegShift = (UINT8)(Source % 32);
|
||||
RegOffset = Source / 32;
|
||||
RegShift = Source % 32;
|
||||
|
||||
Revision = ArmGicGetSupportedArchRevision ();
|
||||
if ((Revision == ARM_GIC_ARCH_REVISION_2) ||
|
||||
FeaturePcdGet (PcdArmGicV3WithV2Legacy) ||
|
||||
SourceIsSpi (Source))
|
||||
{
|
||||
SourceIsSpi (Source)) {
|
||||
// Write set-enable register
|
||||
MmioWrite32 (
|
||||
GicDistributorBase + ARM_GIC_ICDISER + (4 * RegOffset),
|
||||
@ -306,7 +291,7 @@ ArmGicEnableInterrupt (
|
||||
|
||||
// Write set-enable register
|
||||
MmioWrite32 (
|
||||
ISENABLER_ADDRESS (GicCpuRedistributorBase, RegOffset),
|
||||
ISENABLER_ADDRESS(GicCpuRedistributorBase, RegOffset),
|
||||
1 << RegShift
|
||||
);
|
||||
}
|
||||
@ -315,25 +300,24 @@ ArmGicEnableInterrupt (
|
||||
VOID
|
||||
EFIAPI
|
||||
ArmGicDisableInterrupt (
|
||||
IN UINTN GicDistributorBase,
|
||||
IN UINTN GicRedistributorBase,
|
||||
IN UINTN Source
|
||||
IN UINTN GicDistributorBase,
|
||||
IN UINTN GicRedistributorBase,
|
||||
IN UINTN Source
|
||||
)
|
||||
{
|
||||
UINT32 RegOffset;
|
||||
UINT8 RegShift;
|
||||
ARM_GIC_ARCH_REVISION Revision;
|
||||
UINTN GicCpuRedistributorBase;
|
||||
UINT32 RegOffset;
|
||||
UINTN RegShift;
|
||||
ARM_GIC_ARCH_REVISION Revision;
|
||||
UINTN GicCpuRedistributorBase;
|
||||
|
||||
// Calculate enable register offset and bit position
|
||||
RegOffset = (UINT32)(Source / 32);
|
||||
RegShift = (UINT8)(Source % 32);
|
||||
RegOffset = Source / 32;
|
||||
RegShift = Source % 32;
|
||||
|
||||
Revision = ArmGicGetSupportedArchRevision ();
|
||||
if ((Revision == ARM_GIC_ARCH_REVISION_2) ||
|
||||
FeaturePcdGet (PcdArmGicV3WithV2Legacy) ||
|
||||
SourceIsSpi (Source))
|
||||
{
|
||||
SourceIsSpi (Source)) {
|
||||
// Write clear-enable register
|
||||
MmioWrite32 (
|
||||
GicDistributorBase + ARM_GIC_ICDICER + (4 * RegOffset),
|
||||
@ -341,16 +325,16 @@ ArmGicDisableInterrupt (
|
||||
);
|
||||
} else {
|
||||
GicCpuRedistributorBase = GicGetCpuRedistributorBase (
|
||||
GicRedistributorBase,
|
||||
Revision
|
||||
);
|
||||
GicRedistributorBase,
|
||||
Revision
|
||||
);
|
||||
if (GicCpuRedistributorBase == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Write clear-enable register
|
||||
MmioWrite32 (
|
||||
ICENABLER_ADDRESS (GicCpuRedistributorBase, RegOffset),
|
||||
ICENABLER_ADDRESS(GicCpuRedistributorBase, RegOffset),
|
||||
1 << RegShift
|
||||
);
|
||||
}
|
||||
@ -359,29 +343,29 @@ ArmGicDisableInterrupt (
|
||||
BOOLEAN
|
||||
EFIAPI
|
||||
ArmGicIsInterruptEnabled (
|
||||
IN UINTN GicDistributorBase,
|
||||
IN UINTN GicRedistributorBase,
|
||||
IN UINTN Source
|
||||
IN UINTN GicDistributorBase,
|
||||
IN UINTN GicRedistributorBase,
|
||||
IN UINTN Source
|
||||
)
|
||||
{
|
||||
UINT32 RegOffset;
|
||||
UINT8 RegShift;
|
||||
ARM_GIC_ARCH_REVISION Revision;
|
||||
UINTN GicCpuRedistributorBase;
|
||||
UINT32 Interrupts;
|
||||
UINT32 RegOffset;
|
||||
UINTN RegShift;
|
||||
ARM_GIC_ARCH_REVISION Revision;
|
||||
UINTN GicCpuRedistributorBase;
|
||||
UINT32 Interrupts;
|
||||
|
||||
// Calculate enable register offset and bit position
|
||||
RegOffset = (UINT32)(Source / 32);
|
||||
RegShift = (UINT8)(Source % 32);
|
||||
RegOffset = Source / 32;
|
||||
RegShift = Source % 32;
|
||||
|
||||
Revision = ArmGicGetSupportedArchRevision ();
|
||||
if ((Revision == ARM_GIC_ARCH_REVISION_2) ||
|
||||
FeaturePcdGet (PcdArmGicV3WithV2Legacy) ||
|
||||
SourceIsSpi (Source))
|
||||
{
|
||||
Interrupts = MmioRead32 (
|
||||
GicDistributorBase + ARM_GIC_ICDISER + (4 * RegOffset)
|
||||
);
|
||||
SourceIsSpi (Source)) {
|
||||
Interrupts = ((MmioRead32 (
|
||||
GicDistributorBase + ARM_GIC_ICDISER + (4 * RegOffset)
|
||||
)
|
||||
& (1 << RegShift)) != 0);
|
||||
} else {
|
||||
GicCpuRedistributorBase = GicGetCpuRedistributorBase (
|
||||
GicRedistributorBase,
|
||||
@ -393,7 +377,7 @@ ArmGicIsInterruptEnabled (
|
||||
|
||||
// Read set-enable register
|
||||
Interrupts = MmioRead32 (
|
||||
ISENABLER_ADDRESS (GicCpuRedistributorBase, RegOffset)
|
||||
ISENABLER_ADDRESS(GicCpuRedistributorBase, RegOffset)
|
||||
);
|
||||
}
|
||||
|
||||
@ -403,7 +387,7 @@ ArmGicIsInterruptEnabled (
|
||||
VOID
|
||||
EFIAPI
|
||||
ArmGicDisableDistributor (
|
||||
IN UINTN GicDistributorBase
|
||||
IN INTN GicDistributorBase
|
||||
)
|
||||
{
|
||||
// Disable Gic Distributor
|
||||
@ -413,10 +397,10 @@ ArmGicDisableDistributor (
|
||||
VOID
|
||||
EFIAPI
|
||||
ArmGicEnableInterruptInterface (
|
||||
IN UINTN GicInterruptInterfaceBase
|
||||
IN INTN GicInterruptInterfaceBase
|
||||
)
|
||||
{
|
||||
ARM_GIC_ARCH_REVISION Revision;
|
||||
ARM_GIC_ARCH_REVISION Revision;
|
||||
|
||||
Revision = ArmGicGetSupportedArchRevision ();
|
||||
if (Revision == ARM_GIC_ARCH_REVISION_2) {
|
||||
@ -431,10 +415,10 @@ ArmGicEnableInterruptInterface (
|
||||
VOID
|
||||
EFIAPI
|
||||
ArmGicDisableInterruptInterface (
|
||||
IN UINTN GicInterruptInterfaceBase
|
||||
IN INTN GicInterruptInterfaceBase
|
||||
)
|
||||
{
|
||||
ARM_GIC_ARCH_REVISION Revision;
|
||||
ARM_GIC_ARCH_REVISION Revision;
|
||||
|
||||
Revision = ArmGicGetSupportedArchRevision ();
|
||||
if (Revision == ARM_GIC_ARCH_REVISION_2) {
|
||||
|
@ -22,6 +22,7 @@
|
||||
|
||||
[Sources.ARM]
|
||||
GicV3/Arm/ArmGicV3.S | GCC
|
||||
GicV3/Arm/ArmGicV3.asm | RVCT
|
||||
|
||||
[Sources.AARCH64]
|
||||
GicV3/AArch64/ArmGicV3.S
|
||||
|
@ -1,6 +1,6 @@
|
||||
/** @file
|
||||
*
|
||||
* Copyright (c) 2011-2023, Arm Limited. All rights reserved.
|
||||
* Copyright (c) 2011-2015, ARM Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
*
|
||||
@ -13,11 +13,10 @@
|
||||
VOID
|
||||
EFIAPI
|
||||
ArmGicEnableDistributor (
|
||||
IN UINTN GicDistributorBase
|
||||
IN INTN GicDistributorBase
|
||||
)
|
||||
{
|
||||
ARM_GIC_ARCH_REVISION Revision;
|
||||
UINT32 GicDistributorCtl;
|
||||
ARM_GIC_ARCH_REVISION Revision;
|
||||
|
||||
/*
|
||||
* Enable GIC distributor in Non-Secure world.
|
||||
@ -27,8 +26,7 @@ ArmGicEnableDistributor (
|
||||
if (Revision == ARM_GIC_ARCH_REVISION_2) {
|
||||
MmioWrite32 (GicDistributorBase + ARM_GIC_ICDDCR, 0x1);
|
||||
} else {
|
||||
GicDistributorCtl = MmioRead32 (GicDistributorBase + ARM_GIC_ICDDCR);
|
||||
if ((GicDistributorCtl & ARM_GIC_ICDDCR_ARE) != 0) {
|
||||
if (MmioRead32 (GicDistributorBase + ARM_GIC_ICDDCR) & ARM_GIC_ICDDCR_ARE) {
|
||||
MmioOr32 (GicDistributorBase + ARM_GIC_ICDDCR, 0x2);
|
||||
} else {
|
||||
MmioOr32 (GicDistributorBase + ARM_GIC_ICDDCR, 0x1);
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
Copyright (c) 2009, Hewlett-Packard Company. All rights reserved.<BR>
|
||||
Portions copyright (c) 2010, Apple Inc. All rights reserved.<BR>
|
||||
Portions copyright (c) 2011-2023, Arm Ltd. All rights reserved.<BR>
|
||||
Portions copyright (c) 2011-2017, ARM Ltd. All rights reserved.<BR>
|
||||
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
@ -22,11 +22,11 @@ Abstract:
|
||||
|
||||
#define ARM_GIC_DEFAULT_PRIORITY 0x80
|
||||
|
||||
extern EFI_HARDWARE_INTERRUPT_PROTOCOL gHardwareInterruptV2Protocol;
|
||||
extern EFI_HARDWARE_INTERRUPT2_PROTOCOL gHardwareInterrupt2V2Protocol;
|
||||
extern EFI_HARDWARE_INTERRUPT_PROTOCOL gHardwareInterruptV2Protocol;
|
||||
extern EFI_HARDWARE_INTERRUPT2_PROTOCOL gHardwareInterrupt2V2Protocol;
|
||||
|
||||
STATIC UINTN mGicInterruptInterfaceBase;
|
||||
STATIC UINTN mGicDistributorBase;
|
||||
STATIC UINT32 mGicInterruptInterfaceBase;
|
||||
STATIC UINT32 mGicDistributorBase;
|
||||
|
||||
/**
|
||||
Enable interrupt source Source.
|
||||
@ -42,12 +42,12 @@ STATIC
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
GicV2EnableInterruptSource (
|
||||
IN EFI_HARDWARE_INTERRUPT_PROTOCOL *This,
|
||||
IN HARDWARE_INTERRUPT_SOURCE Source
|
||||
IN EFI_HARDWARE_INTERRUPT_PROTOCOL *This,
|
||||
IN HARDWARE_INTERRUPT_SOURCE Source
|
||||
)
|
||||
{
|
||||
if (Source >= mGicNumInterrupts) {
|
||||
ASSERT (FALSE);
|
||||
ASSERT(FALSE);
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
@ -70,12 +70,12 @@ STATIC
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
GicV2DisableInterruptSource (
|
||||
IN EFI_HARDWARE_INTERRUPT_PROTOCOL *This,
|
||||
IN HARDWARE_INTERRUPT_SOURCE Source
|
||||
IN EFI_HARDWARE_INTERRUPT_PROTOCOL *This,
|
||||
IN HARDWARE_INTERRUPT_SOURCE Source
|
||||
)
|
||||
{
|
||||
if (Source >= mGicNumInterrupts) {
|
||||
ASSERT (FALSE);
|
||||
ASSERT(FALSE);
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
@ -99,13 +99,13 @@ STATIC
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
GicV2GetInterruptSourceState (
|
||||
IN EFI_HARDWARE_INTERRUPT_PROTOCOL *This,
|
||||
IN HARDWARE_INTERRUPT_SOURCE Source,
|
||||
IN BOOLEAN *InterruptState
|
||||
IN EFI_HARDWARE_INTERRUPT_PROTOCOL *This,
|
||||
IN HARDWARE_INTERRUPT_SOURCE Source,
|
||||
IN BOOLEAN *InterruptState
|
||||
)
|
||||
{
|
||||
if (Source >= mGicNumInterrupts) {
|
||||
ASSERT (FALSE);
|
||||
ASSERT(FALSE);
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
@ -129,12 +129,12 @@ STATIC
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
GicV2EndOfInterrupt (
|
||||
IN EFI_HARDWARE_INTERRUPT_PROTOCOL *This,
|
||||
IN HARDWARE_INTERRUPT_SOURCE Source
|
||||
IN EFI_HARDWARE_INTERRUPT_PROTOCOL *This,
|
||||
IN HARDWARE_INTERRUPT_SOURCE Source
|
||||
)
|
||||
{
|
||||
if (Source >= mGicNumInterrupts) {
|
||||
ASSERT (FALSE);
|
||||
ASSERT(FALSE);
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
@ -158,11 +158,11 @@ STATIC
|
||||
VOID
|
||||
EFIAPI
|
||||
GicV2IrqInterruptHandler (
|
||||
IN EFI_EXCEPTION_TYPE InterruptType,
|
||||
IN EFI_SYSTEM_CONTEXT SystemContext
|
||||
IN EFI_EXCEPTION_TYPE InterruptType,
|
||||
IN EFI_SYSTEM_CONTEXT SystemContext
|
||||
)
|
||||
{
|
||||
UINTN GicInterrupt;
|
||||
UINT32 GicInterrupt;
|
||||
HARDWARE_INTERRUPT_HANDLER InterruptHandler;
|
||||
|
||||
GicInterrupt = ArmGicV2AcknowledgeInterrupt (mGicInterruptInterfaceBase);
|
||||
@ -179,13 +179,13 @@ GicV2IrqInterruptHandler (
|
||||
// Call the registered interrupt handler.
|
||||
InterruptHandler (GicInterrupt, SystemContext);
|
||||
} else {
|
||||
DEBUG ((DEBUG_ERROR, "Spurious GIC interrupt: 0x%x\n", (UINT32)GicInterrupt));
|
||||
DEBUG ((DEBUG_ERROR, "Spurious GIC interrupt: 0x%x\n", GicInterrupt));
|
||||
GicV2EndOfInterrupt (&gHardwareInterruptV2Protocol, GicInterrupt);
|
||||
}
|
||||
}
|
||||
|
||||
// The protocol instance produced by this driver
|
||||
EFI_HARDWARE_INTERRUPT_PROTOCOL gHardwareInterruptV2Protocol = {
|
||||
EFI_HARDWARE_INTERRUPT_PROTOCOL gHardwareInterruptV2Protocol = {
|
||||
RegisterInterruptSource,
|
||||
GicV2EnableInterruptSource,
|
||||
GicV2DisableInterruptSource,
|
||||
@ -208,28 +208,28 @@ EFI_STATUS
|
||||
EFIAPI
|
||||
GicV2GetTriggerType (
|
||||
IN EFI_HARDWARE_INTERRUPT2_PROTOCOL *This,
|
||||
IN HARDWARE_INTERRUPT_SOURCE Source,
|
||||
IN HARDWARE_INTERRUPT_SOURCE Source,
|
||||
OUT EFI_HARDWARE_INTERRUPT2_TRIGGER_TYPE *TriggerType
|
||||
)
|
||||
{
|
||||
UINTN RegAddress;
|
||||
UINTN Config1Bit;
|
||||
EFI_STATUS Status;
|
||||
UINTN RegAddress;
|
||||
UINTN Config1Bit;
|
||||
EFI_STATUS Status;
|
||||
|
||||
Status = GicGetDistributorIcfgBaseAndBit (
|
||||
Source,
|
||||
&RegAddress,
|
||||
&Config1Bit
|
||||
);
|
||||
Source,
|
||||
&RegAddress,
|
||||
&Config1Bit
|
||||
);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
if ((MmioRead32 (RegAddress) & (1 << Config1Bit)) == 0) {
|
||||
*TriggerType = EFI_HARDWARE_INTERRUPT2_TRIGGER_LEVEL_HIGH;
|
||||
*TriggerType = EFI_HARDWARE_INTERRUPT2_TRIGGER_LEVEL_HIGH;
|
||||
} else {
|
||||
*TriggerType = EFI_HARDWARE_INTERRUPT2_TRIGGER_EDGE_RISING;
|
||||
*TriggerType = EFI_HARDWARE_INTERRUPT2_TRIGGER_EDGE_RISING;
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
@ -254,22 +254,18 @@ GicV2SetTriggerType (
|
||||
IN EFI_HARDWARE_INTERRUPT2_TRIGGER_TYPE TriggerType
|
||||
)
|
||||
{
|
||||
UINTN RegAddress;
|
||||
UINTN Config1Bit;
|
||||
UINT32 Value;
|
||||
EFI_STATUS Status;
|
||||
BOOLEAN SourceEnabled;
|
||||
UINTN RegAddress;
|
||||
UINTN Config1Bit;
|
||||
UINT32 Value;
|
||||
EFI_STATUS Status;
|
||||
BOOLEAN SourceEnabled;
|
||||
|
||||
if ( (TriggerType != EFI_HARDWARE_INTERRUPT2_TRIGGER_EDGE_RISING)
|
||||
&& (TriggerType != EFI_HARDWARE_INTERRUPT2_TRIGGER_LEVEL_HIGH))
|
||||
{
|
||||
DEBUG ((
|
||||
DEBUG_ERROR,
|
||||
"Invalid interrupt trigger type: %d\n", \
|
||||
TriggerType
|
||||
));
|
||||
ASSERT (FALSE);
|
||||
return EFI_UNSUPPORTED;
|
||||
if ( (TriggerType != EFI_HARDWARE_INTERRUPT2_TRIGGER_EDGE_RISING)
|
||||
&& (TriggerType != EFI_HARDWARE_INTERRUPT2_TRIGGER_LEVEL_HIGH)) {
|
||||
DEBUG ((DEBUG_ERROR, "Invalid interrupt trigger type: %d\n", \
|
||||
TriggerType));
|
||||
ASSERT (FALSE);
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
Status = GicGetDistributorIcfgBaseAndBit (
|
||||
@ -283,7 +279,7 @@ GicV2SetTriggerType (
|
||||
}
|
||||
|
||||
Status = GicV2GetInterruptSourceState (
|
||||
(EFI_HARDWARE_INTERRUPT_PROTOCOL *)This,
|
||||
(EFI_HARDWARE_INTERRUPT_PROTOCOL*)This,
|
||||
Source,
|
||||
&SourceEnabled
|
||||
);
|
||||
@ -300,7 +296,7 @@ GicV2SetTriggerType (
|
||||
// otherwise GIC behavior is UNPREDICTABLE.
|
||||
if (SourceEnabled) {
|
||||
GicV2DisableInterruptSource (
|
||||
(EFI_HARDWARE_INTERRUPT_PROTOCOL *)This,
|
||||
(EFI_HARDWARE_INTERRUPT_PROTOCOL*)This,
|
||||
Source
|
||||
);
|
||||
}
|
||||
@ -314,7 +310,7 @@ GicV2SetTriggerType (
|
||||
// Restore interrupt state
|
||||
if (SourceEnabled) {
|
||||
GicV2EnableInterruptSource (
|
||||
(EFI_HARDWARE_INTERRUPT_PROTOCOL *)This,
|
||||
(EFI_HARDWARE_INTERRUPT_PROTOCOL*)This,
|
||||
Source
|
||||
);
|
||||
}
|
||||
@ -322,7 +318,7 @@ GicV2SetTriggerType (
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_HARDWARE_INTERRUPT2_PROTOCOL gHardwareInterrupt2V2Protocol = {
|
||||
EFI_HARDWARE_INTERRUPT2_PROTOCOL gHardwareInterrupt2V2Protocol = {
|
||||
(HARDWARE_INTERRUPT2_REGISTER)RegisterInterruptSource,
|
||||
(HARDWARE_INTERRUPT2_ENABLE)GicV2EnableInterruptSource,
|
||||
(HARDWARE_INTERRUPT2_DISABLE)GicV2DisableInterruptSource,
|
||||
@ -349,8 +345,8 @@ GicV2ExitBootServicesEvent (
|
||||
IN VOID *Context
|
||||
)
|
||||
{
|
||||
UINTN Index;
|
||||
UINTN GicInterrupt;
|
||||
UINTN Index;
|
||||
UINT32 GicInterrupt;
|
||||
|
||||
// Disable all the interrupts
|
||||
for (Index = 0; Index < mGicNumInterrupts; Index++) {
|
||||
@ -386,33 +382,30 @@ GicV2ExitBootServicesEvent (
|
||||
**/
|
||||
EFI_STATUS
|
||||
GicV2DxeInitialize (
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
IN EFI_SYSTEM_TABLE *SystemTable
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
IN EFI_SYSTEM_TABLE *SystemTable
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINTN Index;
|
||||
UINT32 RegOffset;
|
||||
UINT8 RegShift;
|
||||
UINT32 CpuTarget;
|
||||
EFI_STATUS Status;
|
||||
UINTN Index;
|
||||
UINT32 RegOffset;
|
||||
UINTN RegShift;
|
||||
UINT32 CpuTarget;
|
||||
|
||||
// Make sure the Interrupt Controller Protocol is not already installed in
|
||||
// the system.
|
||||
ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gHardwareInterruptProtocolGuid);
|
||||
|
||||
ASSERT (PcdGet64 (PcdGicInterruptInterfaceBase) <= MAX_UINTN);
|
||||
ASSERT (PcdGet64 (PcdGicDistributorBase) <= MAX_UINTN);
|
||||
|
||||
mGicInterruptInterfaceBase = (UINTN)PcdGet64 (PcdGicInterruptInterfaceBase);
|
||||
mGicDistributorBase = (UINTN)PcdGet64 (PcdGicDistributorBase);
|
||||
mGicNumInterrupts = ArmGicGetMaxNumInterrupts (mGicDistributorBase);
|
||||
mGicInterruptInterfaceBase = PcdGet64 (PcdGicInterruptInterfaceBase);
|
||||
mGicDistributorBase = PcdGet64 (PcdGicDistributorBase);
|
||||
mGicNumInterrupts = ArmGicGetMaxNumInterrupts (mGicDistributorBase);
|
||||
|
||||
for (Index = 0; Index < mGicNumInterrupts; Index++) {
|
||||
GicV2DisableInterruptSource (&gHardwareInterruptV2Protocol, Index);
|
||||
|
||||
// Set Priority
|
||||
RegOffset = (UINT32)(Index / 4);
|
||||
RegShift = (UINT8)((Index % 4) * 8);
|
||||
RegOffset = Index / 4;
|
||||
RegShift = (Index % 4) * 8;
|
||||
MmioAndThenOr32 (
|
||||
mGicDistributorBase + ARM_GIC_ICDIPR + (4 * RegOffset),
|
||||
~(0xff << RegShift),
|
||||
|
@ -1,19 +1,18 @@
|
||||
/** @file
|
||||
*
|
||||
* Copyright (c) 2013-2023, ARM Limited. All rights reserved.
|
||||
* Copyright (c) 2013-2014, ARM Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
*
|
||||
**/
|
||||
|
||||
#include <Library/ArmGicLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/IoLib.h>
|
||||
|
||||
UINTN
|
||||
EFIAPI
|
||||
ArmGicV2AcknowledgeInterrupt (
|
||||
IN UINTN GicInterruptInterfaceBase
|
||||
IN UINTN GicInterruptInterfaceBase
|
||||
)
|
||||
{
|
||||
// Read the Interrupt Acknowledge Register
|
||||
@ -23,10 +22,9 @@ ArmGicV2AcknowledgeInterrupt (
|
||||
VOID
|
||||
EFIAPI
|
||||
ArmGicV2EndOfInterrupt (
|
||||
IN UINTN GicInterruptInterfaceBase,
|
||||
IN UINTN Source
|
||||
IN UINTN GicInterruptInterfaceBase,
|
||||
IN UINTN Source
|
||||
)
|
||||
{
|
||||
ASSERT (Source <= MAX_UINT32);
|
||||
MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCEIOR, (UINT32)Source);
|
||||
MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCEIOR, Source);
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/** @file
|
||||
*
|
||||
* Copyright (c) 2011-2023, Arm Limited. All rights reserved.
|
||||
* Copyright (c) 2011-2014, ARM Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
*
|
||||
@ -10,10 +10,11 @@
|
||||
#include <Library/IoLib.h>
|
||||
#include <Library/ArmGicLib.h>
|
||||
|
||||
|
||||
VOID
|
||||
EFIAPI
|
||||
ArmGicV2EnableInterruptInterface (
|
||||
IN UINTN GicInterruptInterfaceBase
|
||||
IN INTN GicInterruptInterfaceBase
|
||||
)
|
||||
{
|
||||
/*
|
||||
@ -26,7 +27,7 @@ ArmGicV2EnableInterruptInterface (
|
||||
VOID
|
||||
EFIAPI
|
||||
ArmGicV2DisableInterruptInterface (
|
||||
IN UINTN GicInterruptInterfaceBase
|
||||
IN INTN GicInterruptInterfaceBase
|
||||
)
|
||||
{
|
||||
// Disable Gic Interface
|
||||
|
82
ArmPkg/Drivers/ArmGic/GicV3/Arm/ArmGicV3.asm
Normal file
82
ArmPkg/Drivers/ArmGic/GicV3/Arm/ArmGicV3.asm
Normal file
@ -0,0 +1,82 @@
|
||||
//
|
||||
// Copyright (c) 2014, ARM Limited. All rights reserved.
|
||||
//
|
||||
// SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
//
|
||||
//
|
||||
|
||||
// For the moment we assume this will run in SVC mode on ARMv7
|
||||
|
||||
|
||||
INCLUDE AsmMacroExport.inc
|
||||
|
||||
//UINT32
|
||||
//EFIAPI
|
||||
//ArmGicGetControlSystemRegisterEnable (
|
||||
// VOID
|
||||
// );
|
||||
RVCT_ASM_EXPORT ArmGicV3GetControlSystemRegisterEnable
|
||||
mrc p15, 0, r0, c12, c12, 5 // ICC_SRE
|
||||
bx lr
|
||||
|
||||
//VOID
|
||||
//EFIAPI
|
||||
//ArmGicSetControlSystemRegisterEnable (
|
||||
// IN UINT32 ControlSystemRegisterEnable
|
||||
// );
|
||||
RVCT_ASM_EXPORT ArmGicV3SetControlSystemRegisterEnable
|
||||
mcr p15, 0, r0, c12, c12, 5 // ICC_SRE
|
||||
isb
|
||||
bx lr
|
||||
|
||||
//VOID
|
||||
//ArmGicV3EnableInterruptInterface (
|
||||
// VOID
|
||||
// );
|
||||
RVCT_ASM_EXPORT ArmGicV3EnableInterruptInterface
|
||||
mov r0, #1
|
||||
mcr p15, 0, r0, c12, c12, 7 // ICC_IGRPEN1
|
||||
bx lr
|
||||
|
||||
//VOID
|
||||
//ArmGicV3DisableInterruptInterface (
|
||||
// VOID
|
||||
// );
|
||||
RVCT_ASM_EXPORT ArmGicV3DisableInterruptInterface
|
||||
mov r0, #0
|
||||
mcr p15, 0, r0, c12, c12, 7 // ICC_IGRPEN1
|
||||
bx lr
|
||||
|
||||
//VOID
|
||||
//ArmGicV3EndOfInterrupt (
|
||||
// IN UINTN InterruptId
|
||||
// );
|
||||
RVCT_ASM_EXPORT ArmGicV3EndOfInterrupt
|
||||
mcr p15, 0, r0, c12, c12, 1 //ICC_EOIR1
|
||||
bx lr
|
||||
|
||||
//UINTN
|
||||
//ArmGicV3AcknowledgeInterrupt (
|
||||
// VOID
|
||||
// );
|
||||
RVCT_ASM_EXPORT ArmGicV3AcknowledgeInterrupt
|
||||
mrc p15, 0, r0, c12, c12, 0 //ICC_IAR1
|
||||
bx lr
|
||||
|
||||
//VOID
|
||||
//ArmGicV3SetPriorityMask (
|
||||
// IN UINTN Priority
|
||||
// );
|
||||
RVCT_ASM_EXPORT ArmGicV3SetPriorityMask
|
||||
mcr p15, 0, r0, c4, c6, 0 //ICC_PMR
|
||||
bx lr
|
||||
|
||||
//VOID
|
||||
//ArmGicV3SetBinaryPointer (
|
||||
// IN UINTN BinaryPoint
|
||||
// );
|
||||
RVCT_ASM_EXPORT ArmGicV3SetBinaryPointer
|
||||
mcr p15, 0, r0, c12, c12, 3 //ICC_BPR1
|
||||
bx lr
|
||||
|
||||
END
|
@ -1,6 +1,6 @@
|
||||
/** @file
|
||||
*
|
||||
* Copyright (c) 2011-2023, Arm Limited. All rights reserved.
|
||||
* Copyright (c) 2011-2018, ARM Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
*
|
||||
@ -12,11 +12,11 @@
|
||||
|
||||
#define ARM_GIC_DEFAULT_PRIORITY 0x80
|
||||
|
||||
extern EFI_HARDWARE_INTERRUPT_PROTOCOL gHardwareInterruptV3Protocol;
|
||||
extern EFI_HARDWARE_INTERRUPT2_PROTOCOL gHardwareInterrupt2V3Protocol;
|
||||
extern EFI_HARDWARE_INTERRUPT_PROTOCOL gHardwareInterruptV3Protocol;
|
||||
extern EFI_HARDWARE_INTERRUPT2_PROTOCOL gHardwareInterrupt2V3Protocol;
|
||||
|
||||
STATIC UINTN mGicDistributorBase;
|
||||
STATIC UINTN mGicRedistributorsBase;
|
||||
STATIC UINTN mGicDistributorBase;
|
||||
STATIC UINTN mGicRedistributorsBase;
|
||||
|
||||
/**
|
||||
Enable interrupt source Source.
|
||||
@ -32,12 +32,12 @@ STATIC
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
GicV3EnableInterruptSource (
|
||||
IN EFI_HARDWARE_INTERRUPT_PROTOCOL *This,
|
||||
IN HARDWARE_INTERRUPT_SOURCE Source
|
||||
IN EFI_HARDWARE_INTERRUPT_PROTOCOL *This,
|
||||
IN HARDWARE_INTERRUPT_SOURCE Source
|
||||
)
|
||||
{
|
||||
if (Source >= mGicNumInterrupts) {
|
||||
ASSERT (FALSE);
|
||||
ASSERT(FALSE);
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
@ -60,12 +60,12 @@ STATIC
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
GicV3DisableInterruptSource (
|
||||
IN EFI_HARDWARE_INTERRUPT_PROTOCOL *This,
|
||||
IN HARDWARE_INTERRUPT_SOURCE Source
|
||||
IN EFI_HARDWARE_INTERRUPT_PROTOCOL *This,
|
||||
IN HARDWARE_INTERRUPT_SOURCE Source
|
||||
)
|
||||
{
|
||||
if (Source >= mGicNumInterrupts) {
|
||||
ASSERT (FALSE);
|
||||
ASSERT(FALSE);
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
@ -89,13 +89,13 @@ STATIC
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
GicV3GetInterruptSourceState (
|
||||
IN EFI_HARDWARE_INTERRUPT_PROTOCOL *This,
|
||||
IN HARDWARE_INTERRUPT_SOURCE Source,
|
||||
IN BOOLEAN *InterruptState
|
||||
IN EFI_HARDWARE_INTERRUPT_PROTOCOL *This,
|
||||
IN HARDWARE_INTERRUPT_SOURCE Source,
|
||||
IN BOOLEAN *InterruptState
|
||||
)
|
||||
{
|
||||
if (Source >= mGicNumInterrupts) {
|
||||
ASSERT (FALSE);
|
||||
ASSERT(FALSE);
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
@ -123,12 +123,12 @@ STATIC
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
GicV3EndOfInterrupt (
|
||||
IN EFI_HARDWARE_INTERRUPT_PROTOCOL *This,
|
||||
IN HARDWARE_INTERRUPT_SOURCE Source
|
||||
IN EFI_HARDWARE_INTERRUPT_PROTOCOL *This,
|
||||
IN HARDWARE_INTERRUPT_SOURCE Source
|
||||
)
|
||||
{
|
||||
if (Source >= mGicNumInterrupts) {
|
||||
ASSERT (FALSE);
|
||||
ASSERT(FALSE);
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
@ -152,11 +152,11 @@ STATIC
|
||||
VOID
|
||||
EFIAPI
|
||||
GicV3IrqInterruptHandler (
|
||||
IN EFI_EXCEPTION_TYPE InterruptType,
|
||||
IN EFI_SYSTEM_CONTEXT SystemContext
|
||||
IN EFI_EXCEPTION_TYPE InterruptType,
|
||||
IN EFI_SYSTEM_CONTEXT SystemContext
|
||||
)
|
||||
{
|
||||
UINTN GicInterrupt;
|
||||
UINT32 GicInterrupt;
|
||||
HARDWARE_INTERRUPT_HANDLER InterruptHandler;
|
||||
|
||||
GicInterrupt = ArmGicV3AcknowledgeInterrupt ();
|
||||
@ -173,13 +173,13 @@ GicV3IrqInterruptHandler (
|
||||
// Call the registered interrupt handler.
|
||||
InterruptHandler (GicInterrupt, SystemContext);
|
||||
} else {
|
||||
DEBUG ((DEBUG_ERROR, "Spurious GIC interrupt: 0x%x\n", (UINT32)GicInterrupt));
|
||||
DEBUG ((DEBUG_ERROR, "Spurious GIC interrupt: 0x%x\n", GicInterrupt));
|
||||
GicV3EndOfInterrupt (&gHardwareInterruptV3Protocol, GicInterrupt);
|
||||
}
|
||||
}
|
||||
|
||||
// The protocol instance produced by this driver
|
||||
EFI_HARDWARE_INTERRUPT_PROTOCOL gHardwareInterruptV3Protocol = {
|
||||
EFI_HARDWARE_INTERRUPT_PROTOCOL gHardwareInterruptV3Protocol = {
|
||||
RegisterInterruptSource,
|
||||
GicV3EnableInterruptSource,
|
||||
GicV3DisableInterruptSource,
|
||||
@ -206,9 +206,9 @@ GicV3GetTriggerType (
|
||||
OUT EFI_HARDWARE_INTERRUPT2_TRIGGER_TYPE *TriggerType
|
||||
)
|
||||
{
|
||||
UINTN RegAddress;
|
||||
UINTN Config1Bit;
|
||||
EFI_STATUS Status;
|
||||
UINTN RegAddress;
|
||||
UINTN Config1Bit;
|
||||
EFI_STATUS Status;
|
||||
|
||||
Status = GicGetDistributorIcfgBaseAndBit (
|
||||
Source,
|
||||
@ -221,9 +221,9 @@ GicV3GetTriggerType (
|
||||
}
|
||||
|
||||
if ((MmioRead32 (RegAddress) & (1 << Config1Bit)) == 0) {
|
||||
*TriggerType = EFI_HARDWARE_INTERRUPT2_TRIGGER_LEVEL_HIGH;
|
||||
*TriggerType = EFI_HARDWARE_INTERRUPT2_TRIGGER_LEVEL_HIGH;
|
||||
} else {
|
||||
*TriggerType = EFI_HARDWARE_INTERRUPT2_TRIGGER_EDGE_RISING;
|
||||
*TriggerType = EFI_HARDWARE_INTERRUPT2_TRIGGER_EDGE_RISING;
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
@ -248,22 +248,18 @@ GicV3SetTriggerType (
|
||||
IN EFI_HARDWARE_INTERRUPT2_TRIGGER_TYPE TriggerType
|
||||
)
|
||||
{
|
||||
UINTN RegAddress;
|
||||
UINTN Config1Bit;
|
||||
UINT32 Value;
|
||||
EFI_STATUS Status;
|
||||
BOOLEAN SourceEnabled;
|
||||
UINTN RegAddress;
|
||||
UINTN Config1Bit;
|
||||
UINT32 Value;
|
||||
EFI_STATUS Status;
|
||||
BOOLEAN SourceEnabled;
|
||||
|
||||
if ( (TriggerType != EFI_HARDWARE_INTERRUPT2_TRIGGER_EDGE_RISING)
|
||||
&& (TriggerType != EFI_HARDWARE_INTERRUPT2_TRIGGER_LEVEL_HIGH))
|
||||
{
|
||||
DEBUG ((
|
||||
DEBUG_ERROR,
|
||||
"Invalid interrupt trigger type: %d\n", \
|
||||
TriggerType
|
||||
));
|
||||
ASSERT (FALSE);
|
||||
return EFI_UNSUPPORTED;
|
||||
if ( (TriggerType != EFI_HARDWARE_INTERRUPT2_TRIGGER_EDGE_RISING)
|
||||
&& (TriggerType != EFI_HARDWARE_INTERRUPT2_TRIGGER_LEVEL_HIGH)) {
|
||||
DEBUG ((DEBUG_ERROR, "Invalid interrupt trigger type: %d\n", \
|
||||
TriggerType));
|
||||
ASSERT (FALSE);
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
Status = GicGetDistributorIcfgBaseAndBit (
|
||||
@ -277,7 +273,7 @@ GicV3SetTriggerType (
|
||||
}
|
||||
|
||||
Status = GicV3GetInterruptSourceState (
|
||||
(EFI_HARDWARE_INTERRUPT_PROTOCOL *)This,
|
||||
(EFI_HARDWARE_INTERRUPT_PROTOCOL*)This,
|
||||
Source,
|
||||
&SourceEnabled
|
||||
);
|
||||
@ -294,7 +290,7 @@ GicV3SetTriggerType (
|
||||
// otherwise GIC behavior is UNPREDICTABLE.
|
||||
if (SourceEnabled) {
|
||||
GicV3DisableInterruptSource (
|
||||
(EFI_HARDWARE_INTERRUPT_PROTOCOL *)This,
|
||||
(EFI_HARDWARE_INTERRUPT_PROTOCOL*)This,
|
||||
Source
|
||||
);
|
||||
}
|
||||
@ -307,7 +303,7 @@ GicV3SetTriggerType (
|
||||
// Restore interrupt state
|
||||
if (SourceEnabled) {
|
||||
GicV3EnableInterruptSource (
|
||||
(EFI_HARDWARE_INTERRUPT_PROTOCOL *)This,
|
||||
(EFI_HARDWARE_INTERRUPT_PROTOCOL*)This,
|
||||
Source
|
||||
);
|
||||
}
|
||||
@ -315,7 +311,7 @@ GicV3SetTriggerType (
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_HARDWARE_INTERRUPT2_PROTOCOL gHardwareInterrupt2V3Protocol = {
|
||||
EFI_HARDWARE_INTERRUPT2_PROTOCOL gHardwareInterrupt2V3Protocol = {
|
||||
(HARDWARE_INTERRUPT2_REGISTER)RegisterInterruptSource,
|
||||
(HARDWARE_INTERRUPT2_ENABLE)GicV3EnableInterruptSource,
|
||||
(HARDWARE_INTERRUPT2_DISABLE)GicV3DisableInterruptSource,
|
||||
@ -341,13 +337,17 @@ GicV3ExitBootServicesEvent (
|
||||
IN VOID *Context
|
||||
)
|
||||
{
|
||||
UINTN Index;
|
||||
UINTN Index;
|
||||
|
||||
// Acknowledge all pending interrupts
|
||||
for (Index = 0; Index < mGicNumInterrupts; Index++) {
|
||||
GicV3DisableInterruptSource (&gHardwareInterruptV3Protocol, Index);
|
||||
}
|
||||
|
||||
for (Index = 0; Index < mGicNumInterrupts; Index++) {
|
||||
GicV3EndOfInterrupt (&gHardwareInterruptV3Protocol, Index);
|
||||
}
|
||||
|
||||
// Disable Gic Interface
|
||||
ArmGicV3DisableInterruptInterface ();
|
||||
|
||||
@ -368,20 +368,20 @@ GicV3ExitBootServicesEvent (
|
||||
**/
|
||||
EFI_STATUS
|
||||
GicV3DxeInitialize (
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
IN EFI_SYSTEM_TABLE *SystemTable
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
IN EFI_SYSTEM_TABLE *SystemTable
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINTN Index;
|
||||
UINT64 CpuTarget;
|
||||
UINT64 MpId;
|
||||
EFI_STATUS Status;
|
||||
UINTN Index;
|
||||
UINT64 CpuTarget;
|
||||
UINT64 MpId;
|
||||
|
||||
// Make sure the Interrupt Controller Protocol is not already installed in
|
||||
// the system.
|
||||
ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gHardwareInterruptProtocolGuid);
|
||||
|
||||
mGicDistributorBase = (UINTN)PcdGet64 (PcdGicDistributorBase);
|
||||
mGicDistributorBase = PcdGet64 (PcdGicDistributorBase);
|
||||
mGicRedistributorsBase = PcdGet64 (PcdGicRedistributorsBase);
|
||||
mGicNumInterrupts = ArmGicGetMaxNumInterrupts (mGicDistributorBase);
|
||||
|
||||
@ -428,14 +428,14 @@ GicV3DxeInitialize (
|
||||
}
|
||||
}
|
||||
} else {
|
||||
MpId = ArmReadMpidr ();
|
||||
MpId = ArmReadMpidr ();
|
||||
CpuTarget = MpId &
|
||||
(ARM_CORE_AFF0 | ARM_CORE_AFF1 | ARM_CORE_AFF2 | ARM_CORE_AFF3);
|
||||
(ARM_CORE_AFF0 | ARM_CORE_AFF1 | ARM_CORE_AFF2 | ARM_CORE_AFF3);
|
||||
|
||||
if ((MmioRead32 (
|
||||
mGicDistributorBase + ARM_GIC_ICDDCR
|
||||
) & ARM_GIC_ICDDCR_DS) != 0)
|
||||
{
|
||||
) & ARM_GIC_ICDDCR_DS) != 0) {
|
||||
|
||||
// If the Disable Security (DS) control bit is set, we are dealing with a
|
||||
// GIC that has only one security state. In this case, let's assume we are
|
||||
// executing in non-secure state (which is appropriate for DXE modules)
|
||||
|
@ -18,7 +18,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
#include <Library/PcdLib.h>
|
||||
#include <Library/UefiBootServicesTableLib.h>
|
||||
|
||||
#define MAX_IO_PORT_ADDRESS 0xFFFF
|
||||
#define MAX_IO_PORT_ADDRESS 0xFFFF
|
||||
|
||||
//
|
||||
// Handle for the CPU I/O 2 Protocol
|
||||
@ -28,7 +28,7 @@ STATIC EFI_HANDLE mHandle = NULL;
|
||||
//
|
||||
// Lookup table for increment values based on transfer widths
|
||||
//
|
||||
STATIC CONST UINT8 mInStride[] = {
|
||||
STATIC CONST UINT8 mInStride[] = {
|
||||
1, // EfiCpuIoWidthUint8
|
||||
2, // EfiCpuIoWidthUint16
|
||||
4, // EfiCpuIoWidthUint32
|
||||
@ -46,7 +46,7 @@ STATIC CONST UINT8 mInStride[] = {
|
||||
//
|
||||
// Lookup table for increment values based on transfer widths
|
||||
//
|
||||
STATIC CONST UINT8 mOutStride[] = {
|
||||
STATIC CONST UINT8 mOutStride[] = {
|
||||
1, // EfiCpuIoWidthUint8
|
||||
2, // EfiCpuIoWidthUint16
|
||||
4, // EfiCpuIoWidthUint32
|
||||
@ -117,14 +117,14 @@ CpuIoCheckParameter (
|
||||
// For FIFO type, the target address won't increase during the access,
|
||||
// so treat Count as 1
|
||||
//
|
||||
if ((Width >= EfiCpuIoWidthFifoUint8) && (Width <= EfiCpuIoWidthFifoUint64)) {
|
||||
if (Width >= EfiCpuIoWidthFifoUint8 && Width <= EfiCpuIoWidthFifoUint64) {
|
||||
Count = 1;
|
||||
}
|
||||
|
||||
//
|
||||
// Check to see if Width is in the valid range for I/O Port operations
|
||||
//
|
||||
Width = (EFI_CPU_IO_PROTOCOL_WIDTH)(Width & 0x03);
|
||||
Width = (EFI_CPU_IO_PROTOCOL_WIDTH) (Width & 0x03);
|
||||
if (!MmioOperation && (Width == EfiCpuIoWidthUint64)) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
@ -161,7 +161,6 @@ CpuIoCheckParameter (
|
||||
if (MaxCount < (Count - 1)) {
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
if (Address > LShiftU64 (MaxCount - Count + 1, Width)) {
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
@ -241,9 +240,9 @@ CpuMemoryServiceRead (
|
||||
//
|
||||
// Select loop based on the width of the transfer
|
||||
//
|
||||
InStride = mInStride[Width];
|
||||
OutStride = mOutStride[Width];
|
||||
OperationWidth = (EFI_CPU_IO_PROTOCOL_WIDTH)(Width & 0x03);
|
||||
InStride = mInStride[Width];
|
||||
OutStride = mOutStride[Width];
|
||||
OperationWidth = (EFI_CPU_IO_PROTOCOL_WIDTH) (Width & 0x03);
|
||||
for (Uint8Buffer = Buffer; Count > 0; Address += InStride, Uint8Buffer += OutStride, Count--) {
|
||||
if (OperationWidth == EfiCpuIoWidthUint8) {
|
||||
*Uint8Buffer = MmioRead8 ((UINTN)Address);
|
||||
@ -255,7 +254,6 @@ CpuMemoryServiceRead (
|
||||
*((UINT64 *)Uint8Buffer) = MmioRead64 ((UINTN)Address);
|
||||
}
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
@ -323,9 +321,9 @@ CpuMemoryServiceWrite (
|
||||
//
|
||||
// Select loop based on the width of the transfer
|
||||
//
|
||||
InStride = mInStride[Width];
|
||||
OutStride = mOutStride[Width];
|
||||
OperationWidth = (EFI_CPU_IO_PROTOCOL_WIDTH)(Width & 0x03);
|
||||
InStride = mInStride[Width];
|
||||
OutStride = mOutStride[Width];
|
||||
OperationWidth = (EFI_CPU_IO_PROTOCOL_WIDTH) (Width & 0x03);
|
||||
for (Uint8Buffer = Buffer; Count > 0; Address += InStride, Uint8Buffer += OutStride, Count--) {
|
||||
if (OperationWidth == EfiCpuIoWidthUint8) {
|
||||
MmioWrite8 ((UINTN)Address, *Uint8Buffer);
|
||||
@ -337,7 +335,6 @@ CpuMemoryServiceWrite (
|
||||
MmioWrite64 ((UINTN)Address, *((UINT64 *)Uint8Buffer));
|
||||
}
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
@ -407,9 +404,9 @@ CpuIoServiceRead (
|
||||
//
|
||||
// Select loop based on the width of the transfer
|
||||
//
|
||||
InStride = mInStride[Width];
|
||||
OutStride = mOutStride[Width];
|
||||
OperationWidth = (EFI_CPU_IO_PROTOCOL_WIDTH)(Width & 0x03);
|
||||
InStride = mInStride[Width];
|
||||
OutStride = mOutStride[Width];
|
||||
OperationWidth = (EFI_CPU_IO_PROTOCOL_WIDTH) (Width & 0x03);
|
||||
|
||||
for (Uint8Buffer = Buffer; Count > 0; Address += InStride, Uint8Buffer += OutStride, Count--) {
|
||||
if (OperationWidth == EfiCpuIoWidthUint8) {
|
||||
@ -493,9 +490,9 @@ CpuIoServiceWrite (
|
||||
//
|
||||
// Select loop based on the width of the transfer
|
||||
//
|
||||
InStride = mInStride[Width];
|
||||
OutStride = mOutStride[Width];
|
||||
OperationWidth = (EFI_CPU_IO_PROTOCOL_WIDTH)(Width & 0x03);
|
||||
InStride = mInStride[Width];
|
||||
OutStride = mOutStride[Width];
|
||||
OperationWidth = (EFI_CPU_IO_PROTOCOL_WIDTH) (Width & 0x03);
|
||||
|
||||
for (Uint8Buffer = (UINT8 *)Buffer; Count > 0; Address += InStride, Uint8Buffer += OutStride, Count--) {
|
||||
if (OperationWidth == EfiCpuIoWidthUint8) {
|
||||
@ -513,7 +510,7 @@ CpuIoServiceWrite (
|
||||
//
|
||||
// CPU I/O 2 Protocol instance
|
||||
//
|
||||
STATIC EFI_CPU_IO2_PROTOCOL mCpuIo2 = {
|
||||
STATIC EFI_CPU_IO2_PROTOCOL mCpuIo2 = {
|
||||
{
|
||||
CpuMemoryServiceRead,
|
||||
CpuMemoryServiceWrite
|
||||
@ -524,6 +521,7 @@ STATIC EFI_CPU_IO2_PROTOCOL mCpuIo2 = {
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
The user Entry Point for module CpuIo2Dxe. The user code starts with this function.
|
||||
|
||||
@ -541,13 +539,12 @@ ArmPciCpuIo2Initialize (
|
||||
IN EFI_SYSTEM_TABLE *SystemTable
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_STATUS Status;
|
||||
|
||||
ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiCpuIo2ProtocolGuid);
|
||||
Status = gBS->InstallMultipleProtocolInterfaces (
|
||||
&mHandle,
|
||||
&gEfiCpuIo2ProtocolGuid,
|
||||
&mCpuIo2,
|
||||
&gEfiCpuIo2ProtocolGuid, &mCpuIo2,
|
||||
NULL
|
||||
);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
@ -38,7 +38,7 @@
|
||||
UefiBootServicesTableLib
|
||||
|
||||
[Pcd]
|
||||
gEfiMdePkgTokenSpaceGuid.PcdPciIoTranslation
|
||||
gArmTokenSpaceGuid.PcdPciIoTranslation
|
||||
|
||||
[Protocols]
|
||||
gEfiCpuIo2ProtocolGuid ## PRODUCES
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -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
|
@ -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 .
|
@ -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_ */
|
@ -14,7 +14,7 @@
|
||||
|
||||
// Return values of BASE_DISCOVER_LIST_PROTOCOLS command.
|
||||
typedef struct {
|
||||
UINT32 NumProtocols;
|
||||
UINT32 NumProtocols;
|
||||
|
||||
// Array of four protocols in each element
|
||||
// Total elements = 1 + (NumProtocols-1)/4
|
||||
@ -22,7 +22,7 @@ typedef struct {
|
||||
// NOTE: Since EDK2 does not allow flexible array member [] we declare
|
||||
// here array of 1 element length. However below is used as a variable
|
||||
// length array.
|
||||
UINT8 Protocols[1];
|
||||
UINT8 Protocols[1];
|
||||
} BASE_DISCOVER_LIST;
|
||||
|
||||
/** Initialize Base protocol and install protocol on a given handle.
|
||||
@ -34,7 +34,7 @@ typedef struct {
|
||||
**/
|
||||
EFI_STATUS
|
||||
ScmiBaseProtocolInit (
|
||||
IN OUT EFI_HANDLE *Handle
|
||||
IN OUT EFI_HANDLE* Handle
|
||||
);
|
||||
|
||||
#endif /* ARM_SCMI_BASE_PROTOCOL_PRIVATE_H_ */
|
||||
|
@ -16,56 +16,57 @@
|
||||
|
||||
// Clock rate in two 32bit words.
|
||||
typedef struct {
|
||||
UINT32 Low;
|
||||
UINT32 High;
|
||||
UINT32 Low;
|
||||
UINT32 High;
|
||||
} CLOCK_RATE_DWORD;
|
||||
|
||||
// Format of the returned rate array. Linear or Non-linear,.RatesFlag Bit[12]
|
||||
#define RATE_FORMAT_SHIFT 12
|
||||
#define RATE_FORMAT_MASK 0x0001
|
||||
#define RATE_FORMAT(RatesFlags) ((RatesFlags >> RATE_FORMAT_SHIFT) \
|
||||
#define RATE_FORMAT_SHIFT 12
|
||||
#define RATE_FORMAT_MASK 0x0001
|
||||
#define RATE_FORMAT(RatesFlags) ((RatesFlags >> RATE_FORMAT_SHIFT) \
|
||||
& RATE_FORMAT_MASK)
|
||||
|
||||
// Number of remaining rates after a call to the SCP, RatesFlag Bits[31:16]
|
||||
#define NUM_REMAIN_RATES_SHIFT 16
|
||||
#define NUM_REMAIN_RATES_SHIFT 16
|
||||
#define NUM_REMAIN_RATES(RatesFlags) ((RatesFlags >> NUM_REMAIN_RATES_SHIFT))
|
||||
|
||||
// Number of rates that are returned by a call.to the SCP, RatesFlag Bits[11:0]
|
||||
#define NUM_RATES_MASK 0x0FFF
|
||||
#define NUM_RATES(RatesFlags) (RatesFlags & NUM_RATES_MASK)
|
||||
#define NUM_RATES_MASK 0x0FFF
|
||||
#define NUM_RATES(RatesFlags) (RatesFlags & NUM_RATES_MASK)
|
||||
|
||||
// Return values for the CLOCK_DESCRIBER_RATE command.
|
||||
typedef struct {
|
||||
UINT32 NumRatesFlags;
|
||||
UINT32 NumRatesFlags;
|
||||
|
||||
// NOTE: Since EDK2 does not allow flexible array member [] we declare
|
||||
// here array of 1 element length. However below is used as a variable
|
||||
// length array.
|
||||
CLOCK_RATE_DWORD Rates[1];
|
||||
CLOCK_RATE_DWORD Rates[1];
|
||||
} CLOCK_DESCRIBE_RATES;
|
||||
|
||||
#define CLOCK_SET_DEFAULT_FLAGS 0
|
||||
#define CLOCK_SET_DEFAULT_FLAGS 0
|
||||
|
||||
// Message parameters for CLOCK_RATE_SET command.
|
||||
typedef struct {
|
||||
UINT32 Flags;
|
||||
UINT32 ClockId;
|
||||
CLOCK_RATE_DWORD Rate;
|
||||
UINT32 Flags;
|
||||
UINT32 ClockId;
|
||||
CLOCK_RATE_DWORD Rate;
|
||||
} CLOCK_RATE_SET_ATTRIBUTES;
|
||||
|
||||
|
||||
// Message parameters for CLOCK_CONFIG_SET command.
|
||||
typedef struct {
|
||||
UINT32 ClockId;
|
||||
UINT32 Attributes;
|
||||
UINT32 ClockId;
|
||||
UINT32 Attributes;
|
||||
} CLOCK_CONFIG_SET_ATTRIBUTES;
|
||||
|
||||
// if ClockAttr Bit[0] is set then clock device is enabled.
|
||||
#define CLOCK_ENABLE_MASK 0x1
|
||||
#define CLOCK_ENABLE_MASK 0x1
|
||||
#define CLOCK_ENABLED(ClockAttr) ((ClockAttr & CLOCK_ENABLE_MASK) == 1)
|
||||
|
||||
typedef struct {
|
||||
UINT32 Attributes;
|
||||
UINT8 ClockName[SCMI_MAX_STR_LEN];
|
||||
UINT32 Attributes;
|
||||
UINT8 ClockName[SCMI_MAX_STR_LEN];
|
||||
} CLOCK_ATTRIBUTES;
|
||||
|
||||
#pragma pack()
|
||||
@ -78,7 +79,7 @@ typedef struct {
|
||||
**/
|
||||
EFI_STATUS
|
||||
ScmiClockProtocolInit (
|
||||
IN EFI_HANDLE *Handle
|
||||
IN EFI_HANDLE *Handle
|
||||
);
|
||||
|
||||
#endif /* ARM_SCMI_CLOCK_PROTOCOL_PRIVATE_H_ */
|
||||
|
@ -15,23 +15,23 @@
|
||||
#include <Protocol/ArmScmiPerformanceProtocol.h>
|
||||
|
||||
// Number of performance levels returned by a call to the SCP, Lvls Bits[11:0]
|
||||
#define NUM_PERF_LEVELS_MASK 0x0FFF
|
||||
#define NUM_PERF_LEVELS(Lvls) (Lvls & NUM_PERF_LEVELS_MASK)
|
||||
#define NUM_PERF_LEVELS_MASK 0x0FFF
|
||||
#define NUM_PERF_LEVELS(Lvls) (Lvls & NUM_PERF_LEVELS_MASK)
|
||||
|
||||
// Number of performance levels remaining after a call to the SCP, Lvls Bits[31:16]
|
||||
#define NUM_REMAIN_PERF_LEVELS_SHIFT 16
|
||||
#define NUM_REMAIN_PERF_LEVELS(Lvls) (Lvls >> NUM_REMAIN_PERF_LEVELS_SHIFT)
|
||||
#define NUM_REMAIN_PERF_LEVELS(Lvls) (Lvls >> NUM_REMAIN_PERF_LEVELS_SHIFT)
|
||||
|
||||
/** Return values for ScmiMessageIdPerformanceDescribeLevels command.
|
||||
SCMI Spec section 4.5.2.5
|
||||
**/
|
||||
typedef struct {
|
||||
UINT32 NumLevels;
|
||||
UINT32 NumLevels;
|
||||
|
||||
// NOTE: Since EDK2 does not allow flexible array member [] we declare
|
||||
// here array of 1 element length. However below is used as a variable
|
||||
// length array.
|
||||
SCMI_PERFORMANCE_LEVEL PerfLevel[1]; // Offset to array of performance levels
|
||||
SCMI_PERFORMANCE_LEVEL PerfLevel[1]; // Offset to array of performance levels
|
||||
} PERF_DESCRIBE_LEVELS;
|
||||
|
||||
/** Initialize performance management protocol and install on a given Handle.
|
||||
@ -43,7 +43,7 @@ typedef struct {
|
||||
**/
|
||||
EFI_STATUS
|
||||
ScmiPerformanceProtocolInit (
|
||||
IN EFI_HANDLE *Handle
|
||||
IN EFI_HANDLE* Handle
|
||||
);
|
||||
|
||||
#endif /* ARM_SCMI_PERFORMANCE_PROTOCOL_PRIVATE_H_ */
|
||||
|
@ -29,7 +29,7 @@
|
||||
**/
|
||||
EFI_STATUS
|
||||
ScmiCommandGetPayload (
|
||||
OUT UINT32 **Payload
|
||||
OUT UINT32** Payload
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
@ -76,7 +76,7 @@ EFI_STATUS
|
||||
ScmiCommandExecute (
|
||||
IN SCMI_COMMAND *Command,
|
||||
IN OUT UINT32 *PayloadLength,
|
||||
OUT UINT32 **ReturnValues OPTIONAL
|
||||
OUT UINT32 **ReturnValues OPTIONAL
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
@ -121,12 +121,10 @@ ScmiCommandExecute (
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
Response = (SCMI_MESSAGE_RESPONSE *)MtlGetChannelPayload (Channel);
|
||||
Response = (SCMI_MESSAGE_RESPONSE*)MtlGetChannelPayload (Channel);
|
||||
|
||||
if (Response->Status != ScmiSuccess) {
|
||||
DEBUG ((
|
||||
DEBUG_ERROR,
|
||||
"SCMI error: ProtocolId = 0x%x, MessageId = 0x%x, error = %d\n",
|
||||
DEBUG ((DEBUG_ERROR, "SCMI error: ProtocolId = 0x%x, MessageId = 0x%x, error = %d\n",
|
||||
Command->ProtocolId,
|
||||
Command->MessageId,
|
||||
Response->Status
|
||||
@ -145,8 +143,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.
|
||||
|
||||
@ -165,7 +163,7 @@ ScmiProtocolDiscoveryCommon (
|
||||
SCMI_COMMAND Command;
|
||||
UINT32 PayloadLength;
|
||||
|
||||
PayloadLength = 0;
|
||||
PayloadLength = 0;
|
||||
Command.ProtocolId = ProtocolId;
|
||||
Command.MessageId = MessageId;
|
||||
|
||||
@ -192,13 +190,13 @@ ScmiGetProtocolVersion (
|
||||
OUT UINT32 *Version
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINT32 *ProtocolVersion;
|
||||
EFI_STATUS Status;
|
||||
UINT32 *ProtocolVersion;
|
||||
|
||||
Status = ScmiProtocolDiscoveryCommon (
|
||||
ProtocolId,
|
||||
ScmiMessageIdProtocolVersion,
|
||||
(UINT32 **)&ProtocolVersion
|
||||
(UINT32**)&ProtocolVersion
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
|
@ -106,9 +106,9 @@ BaseDiscoverVendorDetails (
|
||||
}
|
||||
|
||||
AsciiStrCpyS (
|
||||
(CHAR8 *)VendorIdentifier,
|
||||
(CHAR8*)VendorIdentifier,
|
||||
SCMI_MAX_STR_LEN,
|
||||
(CONST CHAR8 *)ReturnValues
|
||||
(CONST CHAR8*)ReturnValues
|
||||
);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
@ -256,6 +256,7 @@ BaseDiscoverListProtocols (
|
||||
Skip = 0;
|
||||
|
||||
while (Skip < TotalProtocols) {
|
||||
|
||||
*MessageParams = Skip;
|
||||
|
||||
// Note PayloadLength is a IN/OUT parameter.
|
||||
@ -264,7 +265,7 @@ BaseDiscoverListProtocols (
|
||||
Status = ScmiCommandExecute (
|
||||
&Cmd,
|
||||
&PayloadLength,
|
||||
(UINT32 **)&DiscoverList
|
||||
(UINT32**)&DiscoverList
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
@ -281,7 +282,7 @@ BaseDiscoverListProtocols (
|
||||
}
|
||||
|
||||
// Instance of the SCMI Base protocol.
|
||||
STATIC CONST SCMI_BASE_PROTOCOL BaseProtocol = {
|
||||
STATIC CONST SCMI_BASE_PROTOCOL BaseProtocol = {
|
||||
BaseGetVersion,
|
||||
BaseGetTotalProtocols,
|
||||
BaseDiscoverVendor,
|
||||
@ -299,7 +300,7 @@ STATIC CONST SCMI_BASE_PROTOCOL BaseProtocol = {
|
||||
**/
|
||||
EFI_STATUS
|
||||
ScmiBaseProtocolInit (
|
||||
IN OUT EFI_HANDLE *Handle
|
||||
IN OUT EFI_HANDLE* Handle
|
||||
)
|
||||
{
|
||||
return gBS->InstallMultipleProtocolInterfaces (
|
||||
|
@ -28,11 +28,11 @@
|
||||
STATIC
|
||||
UINT64
|
||||
ConvertTo64Bit (
|
||||
IN UINT32 Low,
|
||||
IN UINT32 High
|
||||
IN UINT32 Low,
|
||||
IN UINT32 High
|
||||
)
|
||||
{
|
||||
return (Low | ((UINT64)High << 32));
|
||||
return (Low | ((UINT64)High << 32));
|
||||
}
|
||||
|
||||
/** Return version of the clock management protocol supported by SCP firmware.
|
||||
@ -74,7 +74,7 @@ ClockGetTotalClocks (
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINT32 *ReturnValues;
|
||||
UINT32 *ReturnValues;
|
||||
|
||||
Status = ScmiGetProtocolAttributes (ScmiProtocolIdClock, &ReturnValues);
|
||||
if (EFI_ERROR (Status)) {
|
||||
@ -108,12 +108,12 @@ ClockGetClockAttributes (
|
||||
OUT CHAR8 *ClockAsciiName
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_STATUS Status;
|
||||
|
||||
UINT32 *MessageParams;
|
||||
CLOCK_ATTRIBUTES *ClockAttributes;
|
||||
SCMI_COMMAND Cmd;
|
||||
UINT32 PayloadLength;
|
||||
UINT32 *MessageParams;
|
||||
CLOCK_ATTRIBUTES *ClockAttributes;
|
||||
SCMI_COMMAND Cmd;
|
||||
UINT32 PayloadLength;
|
||||
|
||||
Status = ScmiCommandGetPayload (&MessageParams);
|
||||
if (EFI_ERROR (Status)) {
|
||||
@ -130,19 +130,18 @@ ClockGetClockAttributes (
|
||||
Status = ScmiCommandExecute (
|
||||
&Cmd,
|
||||
&PayloadLength,
|
||||
(UINT32 **)&ClockAttributes
|
||||
(UINT32**)&ClockAttributes
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
// TRUE if bit 0 of ClockAttributes->Attributes is set.
|
||||
// TRUE if bit 0 of ClockAttributes->Attributes is set.
|
||||
*Enabled = CLOCK_ENABLED (ClockAttributes->Attributes);
|
||||
|
||||
AsciiStrCpyS (
|
||||
ClockAsciiName,
|
||||
SCMI_MAX_STR_LEN,
|
||||
(CONST CHAR8 *)ClockAttributes->ClockName
|
||||
(CONST CHAR8*)ClockAttributes->ClockName
|
||||
);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
@ -175,29 +174,29 @@ STATIC
|
||||
EFI_STATUS
|
||||
ClockDescribeRates (
|
||||
IN SCMI_CLOCK_PROTOCOL *This,
|
||||
IN UINT32 ClockId,
|
||||
IN UINT32 ClockId,
|
||||
OUT SCMI_CLOCK_RATE_FORMAT *Format,
|
||||
OUT UINT32 *TotalRates,
|
||||
IN OUT UINT32 *RateArraySize,
|
||||
OUT SCMI_CLOCK_RATE *RateArray
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_STATUS Status;
|
||||
|
||||
UINT32 PayloadLength;
|
||||
SCMI_COMMAND Cmd;
|
||||
UINT32 *MessageParams;
|
||||
CLOCK_DESCRIBE_RATES *DescribeRates;
|
||||
CLOCK_RATE_DWORD *Rate;
|
||||
UINT32 PayloadLength;
|
||||
SCMI_COMMAND Cmd;
|
||||
UINT32 *MessageParams;
|
||||
CLOCK_DESCRIBE_RATES *DescribeRates;
|
||||
CLOCK_RATE_DWORD *Rate;
|
||||
|
||||
UINT32 RequiredArraySize;
|
||||
UINT32 RateIndex;
|
||||
UINT32 RateNo;
|
||||
UINT32 RateOffset;
|
||||
UINT32 RequiredArraySize;
|
||||
UINT32 RateIndex;
|
||||
UINT32 RateNo;
|
||||
UINT32 RateOffset;
|
||||
|
||||
*TotalRates = 0;
|
||||
*TotalRates = 0;
|
||||
RequiredArraySize = 0;
|
||||
RateIndex = 0;
|
||||
RateIndex = 0;
|
||||
|
||||
Status = ScmiCommandGetPayload (&MessageParams);
|
||||
if (EFI_ERROR (Status)) {
|
||||
@ -207,19 +206,20 @@ ClockDescribeRates (
|
||||
Cmd.ProtocolId = ScmiProtocolIdClock;
|
||||
Cmd.MessageId = ScmiMessageIdClockDescribeRates;
|
||||
|
||||
*MessageParams++ = ClockId;
|
||||
*MessageParams++ = ClockId;
|
||||
|
||||
do {
|
||||
|
||||
*MessageParams = RateIndex;
|
||||
|
||||
// Set Payload length, note PayloadLength is a IN/OUT parameter.
|
||||
PayloadLength = sizeof (ClockId) + sizeof (RateIndex);
|
||||
PayloadLength = sizeof (ClockId) + sizeof (RateIndex);
|
||||
|
||||
// Execute and wait for response on a SCMI channel.
|
||||
Status = ScmiCommandExecute (
|
||||
&Cmd,
|
||||
&PayloadLength,
|
||||
(UINT32 **)&DescribeRates
|
||||
(UINT32**)&DescribeRates
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
@ -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);
|
||||
|
||||
@ -297,13 +304,13 @@ ClockRateGet (
|
||||
OUT UINT64 *Rate
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_STATUS Status;
|
||||
|
||||
UINT32 *MessageParams;
|
||||
CLOCK_RATE_DWORD *ClockRate;
|
||||
SCMI_COMMAND Cmd;
|
||||
|
||||
UINT32 PayloadLength;
|
||||
UINT32 PayloadLength;
|
||||
|
||||
Status = ScmiCommandGetPayload (&MessageParams);
|
||||
if (EFI_ERROR (Status)) {
|
||||
@ -311,10 +318,10 @@ ClockRateGet (
|
||||
}
|
||||
|
||||
// Fill arguments for clock protocol command.
|
||||
*MessageParams = ClockId;
|
||||
*MessageParams = ClockId;
|
||||
|
||||
Cmd.ProtocolId = ScmiProtocolIdClock;
|
||||
Cmd.MessageId = ScmiMessageIdClockRateGet;
|
||||
Cmd.ProtocolId = ScmiProtocolIdClock;
|
||||
Cmd.MessageId = ScmiMessageIdClockRateGet;
|
||||
|
||||
PayloadLength = sizeof (ClockId);
|
||||
|
||||
@ -322,7 +329,7 @@ ClockRateGet (
|
||||
Status = ScmiCommandExecute (
|
||||
&Cmd,
|
||||
&PayloadLength,
|
||||
(UINT32 **)&ClockRate
|
||||
(UINT32**)&ClockRate
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
@ -351,21 +358,21 @@ ClockRateSet (
|
||||
IN UINT64 Rate
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
CLOCK_RATE_SET_ATTRIBUTES *ClockRateSetAttributes;
|
||||
SCMI_COMMAND Cmd;
|
||||
UINT32 PayloadLength;
|
||||
EFI_STATUS Status;
|
||||
CLOCK_RATE_SET_ATTRIBUTES *ClockRateSetAttributes;
|
||||
SCMI_COMMAND Cmd;
|
||||
UINT32 PayloadLength;
|
||||
|
||||
Status = ScmiCommandGetPayload ((UINT32 **)&ClockRateSetAttributes);
|
||||
Status = ScmiCommandGetPayload ((UINT32**)&ClockRateSetAttributes);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
// Fill arguments for clock protocol command.
|
||||
ClockRateSetAttributes->ClockId = ClockId;
|
||||
ClockRateSetAttributes->Flags = CLOCK_SET_DEFAULT_FLAGS;
|
||||
ClockRateSetAttributes->Rate.Low = (UINT32)Rate;
|
||||
ClockRateSetAttributes->Rate.High = (UINT32)(Rate >> 32);
|
||||
ClockRateSetAttributes->ClockId = ClockId;
|
||||
ClockRateSetAttributes->Flags = CLOCK_SET_DEFAULT_FLAGS;
|
||||
ClockRateSetAttributes->Rate.Low = (UINT32)Rate;
|
||||
ClockRateSetAttributes->Rate.High = (UINT32)(Rate >> 32);
|
||||
|
||||
Cmd.ProtocolId = ScmiProtocolIdClock;
|
||||
Cmd.MessageId = ScmiMessageIdClockRateSet;
|
||||
@ -395,17 +402,17 @@ ClockRateSet (
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
ClockEnable (
|
||||
IN SCMI_CLOCK2_PROTOCOL *This,
|
||||
IN UINT32 ClockId,
|
||||
IN BOOLEAN Enable
|
||||
IN SCMI_CLOCK2_PROTOCOL *This,
|
||||
IN UINT32 ClockId,
|
||||
IN BOOLEAN Enable
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
CLOCK_CONFIG_SET_ATTRIBUTES *ClockConfigSetAttributes;
|
||||
SCMI_COMMAND Cmd;
|
||||
UINT32 PayloadLength;
|
||||
EFI_STATUS Status;
|
||||
CLOCK_CONFIG_SET_ATTRIBUTES *ClockConfigSetAttributes;
|
||||
SCMI_COMMAND Cmd;
|
||||
UINT32 PayloadLength;
|
||||
|
||||
Status = ScmiCommandGetPayload ((UINT32 **)&ClockConfigSetAttributes);
|
||||
Status = ScmiCommandGetPayload ((UINT32**)&ClockConfigSetAttributes);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
@ -430,17 +437,17 @@ ClockEnable (
|
||||
}
|
||||
|
||||
// Instance of the SCMI clock management protocol.
|
||||
STATIC CONST SCMI_CLOCK_PROTOCOL ScmiClockProtocol = {
|
||||
STATIC CONST SCMI_CLOCK_PROTOCOL ScmiClockProtocol = {
|
||||
ClockGetVersion,
|
||||
ClockGetTotalClocks,
|
||||
ClockGetClockAttributes,
|
||||
ClockDescribeRates,
|
||||
ClockRateGet,
|
||||
ClockRateSet
|
||||
};
|
||||
};
|
||||
|
||||
// Instance of the SCMI clock management protocol.
|
||||
STATIC CONST SCMI_CLOCK2_PROTOCOL ScmiClock2Protocol = {
|
||||
STATIC CONST SCMI_CLOCK2_PROTOCOL ScmiClock2Protocol = {
|
||||
(SCMI_CLOCK2_GET_VERSION)ClockGetVersion,
|
||||
(SCMI_CLOCK2_GET_TOTAL_CLOCKS)ClockGetTotalClocks,
|
||||
(SCMI_CLOCK2_GET_CLOCK_ATTRIBUTES)ClockGetClockAttributes,
|
||||
@ -449,7 +456,7 @@ STATIC CONST SCMI_CLOCK2_PROTOCOL ScmiClock2Protocol = {
|
||||
(SCMI_CLOCK2_RATE_SET)ClockRateSet,
|
||||
SCMI_CLOCK2_PROTOCOL_VERSION,
|
||||
ClockEnable
|
||||
};
|
||||
};
|
||||
|
||||
/** Initialize clock management protocol and install protocol on a given handle.
|
||||
|
||||
@ -459,7 +466,7 @@ STATIC CONST SCMI_CLOCK2_PROTOCOL ScmiClock2Protocol = {
|
||||
**/
|
||||
EFI_STATUS
|
||||
ScmiClockProtocolInit (
|
||||
IN EFI_HANDLE *Handle
|
||||
IN EFI_HANDLE* Handle
|
||||
)
|
||||
{
|
||||
return gBS->InstallMultipleProtocolInterfaces (
|
||||
|
@ -23,10 +23,10 @@
|
||||
#include "ScmiDxe.h"
|
||||
#include "ScmiPrivate.h"
|
||||
|
||||
STATIC CONST SCMI_PROTOCOL_ENTRY Protocols[] = {
|
||||
{ ScmiProtocolIdBase, ScmiBaseProtocolInit },
|
||||
STATIC CONST SCMI_PROTOCOL_ENTRY Protocols[] = {
|
||||
{ ScmiProtocolIdBase, ScmiBaseProtocolInit },
|
||||
{ ScmiProtocolIdPerformance, ScmiPerformanceProtocolInit },
|
||||
{ ScmiProtocolIdClock, ScmiClockProtocolInit }
|
||||
{ ScmiProtocolIdClock, ScmiClockProtocolInit }
|
||||
};
|
||||
|
||||
/** ARM SCMI driver entry point function.
|
||||
@ -47,8 +47,8 @@ STATIC CONST SCMI_PROTOCOL_ENTRY Protocols[] = {
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
ArmScmiDxeEntryPoint (
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
IN EFI_SYSTEM_TABLE *SystemTable
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
IN EFI_SYSTEM_TABLE *SystemTable
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
@ -72,7 +72,7 @@ ArmScmiDxeEntryPoint (
|
||||
Status = gBS->LocateProtocol (
|
||||
&gArmScmiBaseProtocolGuid,
|
||||
NULL,
|
||||
(VOID **)&BaseProtocol
|
||||
(VOID**)&BaseProtocol
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
ASSERT (FALSE);
|
||||
@ -88,8 +88,7 @@ ArmScmiDxeEntryPoint (
|
||||
|
||||
// Accept any version between SCMI v1.0 and SCMI v2.0
|
||||
if ((Version < BASE_PROTOCOL_VERSION_V1) ||
|
||||
(Version > BASE_PROTOCOL_VERSION_V2))
|
||||
{
|
||||
(Version > BASE_PROTOCOL_VERSION_V2)) {
|
||||
ASSERT (FALSE);
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
@ -97,7 +96,7 @@ ArmScmiDxeEntryPoint (
|
||||
// Apart from Base protocol, SCMI may implement various other protocols,
|
||||
// query total protocols implemented by the SCP firmware.
|
||||
NumProtocols = 0;
|
||||
Status = BaseProtocol->GetTotalProtocols (BaseProtocol, &NumProtocols);
|
||||
Status = BaseProtocol->GetTotalProtocols (BaseProtocol, &NumProtocols);
|
||||
if (EFI_ERROR (Status)) {
|
||||
ASSERT (FALSE);
|
||||
return Status;
|
||||
@ -110,7 +109,7 @@ ArmScmiDxeEntryPoint (
|
||||
Status = gBS->AllocatePool (
|
||||
EfiBootServicesData,
|
||||
SupportedListSize,
|
||||
(VOID **)&SupportedList
|
||||
(VOID**)&SupportedList
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
ASSERT (FALSE);
|
||||
@ -131,8 +130,7 @@ ArmScmiDxeEntryPoint (
|
||||
|
||||
// Install supported protocol on ImageHandle.
|
||||
for (ProtocolIndex = 1; ProtocolIndex < ARRAY_SIZE (Protocols);
|
||||
ProtocolIndex++)
|
||||
{
|
||||
ProtocolIndex++) {
|
||||
for (Index = 0; Index < NumProtocols; Index++) {
|
||||
if (Protocols[ProtocolIndex].Id == SupportedList[Index]) {
|
||||
Status = Protocols[ProtocolIndex].InitFn (&ImageHandle);
|
||||
@ -140,7 +138,6 @@ ArmScmiDxeEntryPoint (
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -8,13 +8,12 @@
|
||||
http://infocenter.arm.com/help/topic/com.arm.doc.den0056a/
|
||||
DEN0056A_System_Control_and_Management_Interface.pdf
|
||||
**/
|
||||
|
||||
#ifndef SCMI_DXE_H_
|
||||
#define SCMI_DXE_H_
|
||||
|
||||
#include "ScmiPrivate.h"
|
||||
|
||||
#define MAX_VENDOR_LEN SCMI_MAX_STR_LEN
|
||||
#define MAX_VENDOR_LEN SCMI_MAX_STR_LEN
|
||||
|
||||
/** Pointer to protocol initialization function.
|
||||
|
||||
@ -30,8 +29,8 @@ EFI_STATUS
|
||||
);
|
||||
|
||||
typedef struct {
|
||||
SCMI_PROTOCOL_ID Id; // Protocol Id.
|
||||
SCMI_PROTOCOL_INIT_FXN InitFn; // Protocol init function.
|
||||
SCMI_PROTOCOL_ID Id; // Protocol Id.
|
||||
SCMI_PROTOCOL_INIT_FXN InitFn; // Protocol init function.
|
||||
} SCMI_PROTOCOL_ENTRY;
|
||||
|
||||
#endif /* SCMI_DXE_H_ */
|
||||
|
@ -1,12 +1,12 @@
|
||||
/** @file
|
||||
|
||||
Copyright (c) 2017-2023, Arm Limited. All rights reserved.<BR>
|
||||
Copyright (c) 2017-2021, Arm Limited. All rights reserved.<BR>
|
||||
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
System Control and Management Interface V3.2, latest version at:
|
||||
- https://developer.arm.com/documentation/den0056/latest/
|
||||
|
||||
System Control and Management Interface V1.0
|
||||
http://infocenter.arm.com/help/topic/com.arm.doc.den0056a/
|
||||
DEN0056A_System_Control_and_Management_Interface.pdf
|
||||
**/
|
||||
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
@ -51,12 +51,12 @@ PerformanceGetVersion (
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
PerformanceGetAttributes (
|
||||
IN SCMI_PERFORMANCE_PROTOCOL *This,
|
||||
OUT SCMI_PERFORMANCE_PROTOCOL_ATTRIBUTES *Attributes
|
||||
IN SCMI_PERFORMANCE_PROTOCOL *This,
|
||||
OUT SCMI_PERFORMANCE_PROTOCOL_ATTRIBUTES *Attributes
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINT32 *ReturnValues;
|
||||
UINT32* ReturnValues;
|
||||
|
||||
Status = ScmiGetProtocolAttributes (
|
||||
ScmiProtocolIdPerformance,
|
||||
@ -90,7 +90,7 @@ STATIC
|
||||
EFI_STATUS
|
||||
PerformanceDomainAttributes (
|
||||
IN SCMI_PERFORMANCE_PROTOCOL *This,
|
||||
IN UINT32 DomainId,
|
||||
IN UINT32 DomainId,
|
||||
OUT SCMI_PERFORMANCE_DOMAIN_ATTRIBUTES *DomainAttributes
|
||||
)
|
||||
{
|
||||
@ -160,21 +160,21 @@ PerformanceDescribeLevels (
|
||||
EFI_STATUS Status;
|
||||
UINT32 PayloadLength;
|
||||
SCMI_COMMAND Cmd;
|
||||
UINT32 *MessageParams;
|
||||
UINT32* MessageParams;
|
||||
UINT32 LevelIndex;
|
||||
UINT32 RequiredSize;
|
||||
UINT32 LevelNo;
|
||||
UINT32 ReturnNumLevels;
|
||||
UINT32 ReturnRemainNumLevels;
|
||||
|
||||
PERF_DESCRIBE_LEVELS *Levels;
|
||||
PERF_DESCRIBE_LEVELS *Levels;
|
||||
|
||||
Status = ScmiCommandGetPayload (&MessageParams);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
LevelIndex = 0;
|
||||
LevelIndex = 0;
|
||||
RequiredSize = 0;
|
||||
|
||||
*MessageParams++ = DomainId;
|
||||
@ -183,6 +183,7 @@ PerformanceDescribeLevels (
|
||||
Cmd.MessageId = ScmiMessageIdPerformanceDescribeLevels;
|
||||
|
||||
do {
|
||||
|
||||
*MessageParams = LevelIndex;
|
||||
|
||||
// Note, PayloadLength is an IN/OUT parameter.
|
||||
@ -191,13 +192,13 @@ PerformanceDescribeLevels (
|
||||
Status = ScmiCommandExecute (
|
||||
&Cmd,
|
||||
&PayloadLength,
|
||||
(UINT32 **)&Levels
|
||||
(UINT32**)&Levels
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
ReturnNumLevels = NUM_PERF_LEVELS (Levels->NumLevels);
|
||||
ReturnNumLevels = NUM_PERF_LEVELS (Levels->NumLevels);
|
||||
ReturnRemainNumLevels = NUM_REMAIN_PERF_LEVELS (Levels->NumLevels);
|
||||
|
||||
if (RequiredSize == 0) {
|
||||
@ -212,12 +213,13 @@ PerformanceDescribeLevels (
|
||||
}
|
||||
|
||||
for (LevelNo = 0; LevelNo < ReturnNumLevels; LevelNo++) {
|
||||
CopyMem (
|
||||
&LevelArray[LevelIndex++],
|
||||
&Levels->PerfLevel[LevelNo],
|
||||
sizeof (SCMI_PERFORMANCE_LEVEL)
|
||||
);
|
||||
CopyMem (
|
||||
&LevelArray[LevelIndex++],
|
||||
&Levels->PerfLevel[LevelNo],
|
||||
sizeof (SCMI_PERFORMANCE_LEVEL)
|
||||
);
|
||||
}
|
||||
|
||||
} while (ReturnRemainNumLevels != 0);
|
||||
|
||||
*LevelArraySize = RequiredSize;
|
||||
@ -237,9 +239,9 @@ PerformanceDescribeLevels (
|
||||
**/
|
||||
EFI_STATUS
|
||||
PerformanceLimitsSet (
|
||||
IN SCMI_PERFORMANCE_PROTOCOL *This,
|
||||
IN UINT32 DomainId,
|
||||
IN SCMI_PERFORMANCE_LIMITS *Limits
|
||||
IN SCMI_PERFORMANCE_PROTOCOL *This,
|
||||
IN UINT32 DomainId,
|
||||
IN SCMI_PERFORMANCE_LIMITS *Limits
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
@ -283,9 +285,9 @@ PerformanceLimitsSet (
|
||||
**/
|
||||
EFI_STATUS
|
||||
PerformanceLimitsGet (
|
||||
SCMI_PERFORMANCE_PROTOCOL *This,
|
||||
UINT32 DomainId,
|
||||
SCMI_PERFORMANCE_LIMITS *Limits
|
||||
SCMI_PERFORMANCE_PROTOCOL *This,
|
||||
UINT32 DomainId,
|
||||
SCMI_PERFORMANCE_LIMITS *Limits
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
@ -310,7 +312,7 @@ PerformanceLimitsGet (
|
||||
Status = ScmiCommandExecute (
|
||||
&Cmd,
|
||||
&PayloadLength,
|
||||
(UINT32 **)&ReturnValues
|
||||
(UINT32**)&ReturnValues
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
@ -334,9 +336,9 @@ PerformanceLimitsGet (
|
||||
**/
|
||||
EFI_STATUS
|
||||
PerformanceLevelSet (
|
||||
IN SCMI_PERFORMANCE_PROTOCOL *This,
|
||||
IN UINT32 DomainId,
|
||||
IN UINT32 Level
|
||||
IN SCMI_PERFORMANCE_PROTOCOL *This,
|
||||
IN UINT32 DomainId,
|
||||
IN UINT32 Level
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
@ -379,9 +381,9 @@ PerformanceLevelSet (
|
||||
**/
|
||||
EFI_STATUS
|
||||
PerformanceLevelGet (
|
||||
IN SCMI_PERFORMANCE_PROTOCOL *This,
|
||||
IN UINT32 DomainId,
|
||||
OUT UINT32 *Level
|
||||
IN SCMI_PERFORMANCE_PROTOCOL *This,
|
||||
IN UINT32 DomainId,
|
||||
OUT UINT32 *Level
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
@ -416,77 +418,8 @@ PerformanceLevelGet (
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/** Discover the attributes of the FastChannel for the specified
|
||||
performance domain and the specified message.
|
||||
|
||||
@param[in] This A Pointer to SCMI_PERFORMANCE_PROTOCOL Instance.
|
||||
@param[in] DomainId Identifier for the performance domain.
|
||||
@param[in] MessageId Message Id of the FastChannel to discover.
|
||||
Must be one of:
|
||||
- PERFORMANCE_LIMITS_SET
|
||||
- PERFORMANCE_LIMITS_GET
|
||||
- PERFORMANCE_LEVEL_SET
|
||||
- PERFORMANCE_LEVEL_GET
|
||||
@param[out] FastChannel If success, contains the FastChannel description.
|
||||
|
||||
@retval EFI_SUCCESS Performance level got successfully.
|
||||
@retval EFI_DEVICE_ERROR SCP returns an SCMI error.
|
||||
@retval EFI_INVALID_PARAMETER Invalid parameter.
|
||||
@retval EFI_TIMEOUT Time out.
|
||||
@retval EFI_UNSUPPORTED Unsupported.
|
||||
**/
|
||||
EFI_STATUS
|
||||
DescribeFastchannel (
|
||||
IN SCMI_PERFORMANCE_PROTOCOL *This,
|
||||
IN UINT32 DomainId,
|
||||
IN SCMI_MESSAGE_ID_PERFORMANCE MessageId,
|
||||
OUT SCMI_PERFORMANCE_FASTCHANNEL *FastChannel
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
SCMI_COMMAND Cmd;
|
||||
UINT32 PayloadLength;
|
||||
UINT32 *ReturnValues;
|
||||
UINT32 *MessageParams;
|
||||
|
||||
if ((This == NULL) ||
|
||||
(FastChannel == NULL))
|
||||
{
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Status = ScmiCommandGetPayload (&MessageParams);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
*MessageParams++ = DomainId;
|
||||
*MessageParams = MessageId;
|
||||
|
||||
Cmd.ProtocolId = ScmiProtocolIdPerformance;
|
||||
Cmd.MessageId = ScmiMessageIdPerformanceDescribeFastchannel;
|
||||
PayloadLength = sizeof (DomainId) + sizeof (MessageId);
|
||||
|
||||
Status = ScmiCommandExecute (
|
||||
&Cmd,
|
||||
&PayloadLength,
|
||||
&ReturnValues
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
CopyMem (
|
||||
FastChannel,
|
||||
ReturnValues,
|
||||
sizeof (SCMI_PERFORMANCE_FASTCHANNEL)
|
||||
);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
// Instance of the SCMI performance management protocol.
|
||||
STATIC CONST SCMI_PERFORMANCE_PROTOCOL PerformanceProtocol = {
|
||||
STATIC CONST SCMI_PERFORMANCE_PROTOCOL PerformanceProtocol = {
|
||||
PerformanceGetVersion,
|
||||
PerformanceGetAttributes,
|
||||
PerformanceDomainAttributes,
|
||||
@ -494,8 +427,7 @@ STATIC CONST SCMI_PERFORMANCE_PROTOCOL PerformanceProtocol = {
|
||||
PerformanceLimitsSet,
|
||||
PerformanceLimitsGet,
|
||||
PerformanceLevelSet,
|
||||
PerformanceLevelGet,
|
||||
DescribeFastchannel,
|
||||
PerformanceLevelGet
|
||||
};
|
||||
|
||||
/** Initialize performance management protocol and install on a given Handle.
|
||||
@ -507,7 +439,7 @@ STATIC CONST SCMI_PERFORMANCE_PROTOCOL PerformanceProtocol = {
|
||||
**/
|
||||
EFI_STATUS
|
||||
ScmiPerformanceProtocolInit (
|
||||
IN EFI_HANDLE *Handle
|
||||
IN EFI_HANDLE* Handle
|
||||
)
|
||||
{
|
||||
return gBS->InstallMultipleProtocolInterfaces (
|
||||
|
@ -8,7 +8,6 @@
|
||||
http://infocenter.arm.com/help/topic/com.arm.doc.den0056a/
|
||||
DEN0056A_System_Control_and_Management_Interface.pdf
|
||||
**/
|
||||
|
||||
#ifndef SCMI_PRIVATE_H_
|
||||
#define SCMI_PRIVATE_H_
|
||||
|
||||
@ -53,21 +52,21 @@ typedef enum {
|
||||
|
||||
// Not defined in SCMI specification but will help to identify a message.
|
||||
typedef struct {
|
||||
SCMI_PROTOCOL_ID ProtocolId;
|
||||
UINT32 MessageId;
|
||||
SCMI_PROTOCOL_ID ProtocolId;
|
||||
UINT32 MessageId;
|
||||
} SCMI_COMMAND;
|
||||
|
||||
#pragma pack(1)
|
||||
|
||||
// Response to a SCMI command.
|
||||
typedef struct {
|
||||
INT32 Status;
|
||||
UINT32 ReturnValues[];
|
||||
INT32 Status;
|
||||
UINT32 ReturnValues[];
|
||||
} SCMI_MESSAGE_RESPONSE;
|
||||
|
||||
// Message header. MsgId[7:0], MsgType[9:8], ProtocolId[17:10]
|
||||
#define MESSAGE_TYPE_SHIFT 8
|
||||
#define PROTOCOL_ID_SHIFT 10
|
||||
#define MESSAGE_TYPE_SHIFT 8
|
||||
#define PROTOCOL_ID_SHIFT 10
|
||||
#define SCMI_MESSAGE_HEADER(MsgId, MsgType, ProtocolId) ( \
|
||||
MsgType << MESSAGE_TYPE_SHIFT | \
|
||||
ProtocolId << PROTOCOL_ID_SHIFT | \
|
||||
@ -75,7 +74,7 @@ typedef struct {
|
||||
)
|
||||
// SCMI message header.
|
||||
typedef struct {
|
||||
UINT32 MessageHeader;
|
||||
UINT32 MessageHeader;
|
||||
} SCMI_MESSAGE_HEADER;
|
||||
|
||||
#pragma pack()
|
||||
@ -90,7 +89,7 @@ typedef struct {
|
||||
**/
|
||||
EFI_STATUS
|
||||
ScmiCommandGetPayload (
|
||||
OUT UINT32 **Payload
|
||||
OUT UINT32** Payload
|
||||
);
|
||||
|
||||
/** Execute a SCMI command and receive a response.
|
||||
@ -116,7 +115,7 @@ EFI_STATUS
|
||||
ScmiCommandExecute (
|
||||
IN SCMI_COMMAND *Command,
|
||||
IN OUT UINT32 *PayloadLength,
|
||||
OUT UINT32 **ReturnValues OPTIONAL
|
||||
OUT UINT32 **ReturnValues OPTIONAL
|
||||
);
|
||||
|
||||
/** Return protocol version from SCP for a given protocol ID.
|
||||
|
@ -13,79 +13,57 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
#include <Library/MemoryAllocationLib.h>
|
||||
#include "CpuDxe.h"
|
||||
|
||||
#define INVALID_ENTRY ((UINT64)~0)
|
||||
#define INVALID_ENTRY ((UINT32)~0)
|
||||
|
||||
#define MIN_T0SZ 16
|
||||
#define BITS_PER_LEVEL 9
|
||||
|
||||
/**
|
||||
Parses T0SZ to determine the level and number of entries at the root
|
||||
of the translation table.
|
||||
|
||||
@param T0SZ The T0SZ value to be parsed.
|
||||
@param RootTableLevel The level of the root table.
|
||||
@param RootTableEntryCount The number of entries in the root table.
|
||||
**/
|
||||
STATIC
|
||||
VOID
|
||||
GetRootTranslationTableInfo (
|
||||
IN UINTN T0SZ,
|
||||
OUT UINTN *RootTableLevel,
|
||||
OUT UINTN *RootTableEntryCount
|
||||
IN UINTN T0SZ,
|
||||
OUT UINTN *RootTableLevel,
|
||||
OUT UINTN *RootTableEntryCount
|
||||
)
|
||||
{
|
||||
*RootTableLevel = (T0SZ - MIN_T0SZ) / BITS_PER_LEVEL;
|
||||
*RootTableEntryCount = TT_ENTRY_COUNT >> (T0SZ - MIN_T0SZ) % BITS_PER_LEVEL;
|
||||
*RootTableLevel = (T0SZ - MIN_T0SZ) / BITS_PER_LEVEL;
|
||||
*RootTableEntryCount = TT_ENTRY_COUNT >> (T0SZ - MIN_T0SZ) % BITS_PER_LEVEL;
|
||||
}
|
||||
|
||||
/**
|
||||
Converts ARM translation table attributes to GCD attributes.
|
||||
|
||||
@param PageAttributes The translation table attributes to be converted.
|
||||
|
||||
@retval The analogous GCD attributes.
|
||||
**/
|
||||
STATIC
|
||||
UINT64
|
||||
PageAttributeToGcdAttribute (
|
||||
IN UINT64 PageAttributes
|
||||
IN UINT64 PageAttributes
|
||||
)
|
||||
{
|
||||
UINT64 GcdAttributes;
|
||||
|
||||
switch (PageAttributes & TT_ATTR_INDX_MASK) {
|
||||
case TT_ATTR_INDX_DEVICE_MEMORY:
|
||||
GcdAttributes = EFI_MEMORY_UC;
|
||||
break;
|
||||
case TT_ATTR_INDX_MEMORY_NON_CACHEABLE:
|
||||
GcdAttributes = EFI_MEMORY_WC;
|
||||
break;
|
||||
case TT_ATTR_INDX_MEMORY_WRITE_THROUGH:
|
||||
GcdAttributes = EFI_MEMORY_WT;
|
||||
break;
|
||||
case TT_ATTR_INDX_MEMORY_WRITE_BACK:
|
||||
GcdAttributes = EFI_MEMORY_WB;
|
||||
break;
|
||||
default:
|
||||
DEBUG ((
|
||||
DEBUG_ERROR,
|
||||
"PageAttributeToGcdAttribute: PageAttributes:0x%lX not supported.\n",
|
||||
PageAttributes
|
||||
));
|
||||
ASSERT (0);
|
||||
// The Global Coherency Domain (GCD) value is defined as a bit set.
|
||||
// Returning 0 means no attribute has been set.
|
||||
GcdAttributes = 0;
|
||||
case TT_ATTR_INDX_DEVICE_MEMORY:
|
||||
GcdAttributes = EFI_MEMORY_UC;
|
||||
break;
|
||||
case TT_ATTR_INDX_MEMORY_NON_CACHEABLE:
|
||||
GcdAttributes = EFI_MEMORY_WC;
|
||||
break;
|
||||
case TT_ATTR_INDX_MEMORY_WRITE_THROUGH:
|
||||
GcdAttributes = EFI_MEMORY_WT;
|
||||
break;
|
||||
case TT_ATTR_INDX_MEMORY_WRITE_BACK:
|
||||
GcdAttributes = EFI_MEMORY_WB;
|
||||
break;
|
||||
default:
|
||||
DEBUG ((DEBUG_ERROR,
|
||||
"PageAttributeToGcdAttribute: PageAttributes:0x%lX not supported.\n",
|
||||
PageAttributes));
|
||||
ASSERT (0);
|
||||
// The Global Coherency Domain (GCD) value is defined as a bit set.
|
||||
// Returning 0 means no attribute has been set.
|
||||
GcdAttributes = 0;
|
||||
}
|
||||
|
||||
// Determine protection attributes
|
||||
if ((PageAttributes & TT_AF) == 0) {
|
||||
GcdAttributes |= EFI_MEMORY_RP;
|
||||
}
|
||||
|
||||
if (((PageAttributes & TT_AP_MASK) == TT_AP_NO_RO) ||
|
||||
((PageAttributes & TT_AP_MASK) == TT_AP_RO_RO))
|
||||
{
|
||||
((PageAttributes & TT_AP_MASK) == TT_AP_RO_RO)) {
|
||||
// Read only cases map to write-protect
|
||||
GcdAttributes |= EFI_MEMORY_RO;
|
||||
}
|
||||
@ -98,124 +76,80 @@ PageAttributeToGcdAttribute (
|
||||
return GcdAttributes;
|
||||
}
|
||||
|
||||
/**
|
||||
Convert an arch specific set of page attributes into a mask
|
||||
of EFI_MEMORY_xx constants.
|
||||
|
||||
@param PageAttributes The set of page attributes.
|
||||
|
||||
@retval The mask of EFI_MEMORY_xx constants.
|
||||
|
||||
**/
|
||||
UINT64
|
||||
RegionAttributeToGcdAttribute (
|
||||
IN UINTN PageAttributes
|
||||
)
|
||||
{
|
||||
return PageAttributeToGcdAttribute (PageAttributes);
|
||||
}
|
||||
|
||||
/**
|
||||
Retrieves the attribute of the first page entry in the translation table.
|
||||
|
||||
@param[in] FirstLevelTableAddress The base address of the translation table.
|
||||
@param[in] TableLevel The current level being traversed.
|
||||
|
||||
@retval The attributes of the first page entry found, or INVALID_ENTRY.
|
||||
**/
|
||||
STATIC
|
||||
UINT64
|
||||
GetFirstPageAttribute (
|
||||
IN UINT64 *FirstLevelTableAddress,
|
||||
IN UINTN TableLevel
|
||||
IN UINTN TableLevel
|
||||
)
|
||||
{
|
||||
UINT64 FirstEntry;
|
||||
UINT64 FirstEntry;
|
||||
|
||||
// Get the first entry of the table
|
||||
FirstEntry = *FirstLevelTableAddress;
|
||||
|
||||
if ((TableLevel != 3) && ((FirstEntry & TT_TYPE_MASK) == TT_TYPE_TABLE_ENTRY)) {
|
||||
if ((TableLevel != 3) && (FirstEntry & TT_TYPE_MASK) == TT_TYPE_TABLE_ENTRY) {
|
||||
// Only valid for Levels 0, 1 and 2
|
||||
|
||||
// Get the attribute of the subsequent table
|
||||
return GetFirstPageAttribute ((UINT64 *)(FirstEntry & TT_ADDRESS_MASK_DESCRIPTION_TABLE), TableLevel + 1);
|
||||
return GetFirstPageAttribute ((UINT64*)(FirstEntry & TT_ADDRESS_MASK_DESCRIPTION_TABLE), TableLevel + 1);
|
||||
} else if (((FirstEntry & TT_TYPE_MASK) == TT_TYPE_BLOCK_ENTRY) ||
|
||||
((TableLevel == 3) && ((FirstEntry & TT_TYPE_MASK) == TT_TYPE_BLOCK_ENTRY_LEVEL3)))
|
||||
{
|
||||
return FirstEntry & TT_ATTRIBUTES_MASK;
|
||||
return FirstEntry & TT_ATTR_INDX_MASK;
|
||||
} else {
|
||||
return INVALID_ENTRY;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
This function recursively traverses the translation table heirarchy to
|
||||
synchronise the GCD with the translation table.
|
||||
|
||||
@param[in] TableAddress The address of the table being processed.
|
||||
@param[in] EntryCount The number of entries in the current level of the table.
|
||||
@param[in] TableLevel The current level of the memory table being processed.
|
||||
@param[in] BaseAddress The starting address of the region.
|
||||
@param[in, out] PrevEntryAttribute The attributes of the previous region.
|
||||
@param[in, out] StartGcdRegion The start of the GCD region.
|
||||
|
||||
@retval The address at the end of the last region processed.
|
||||
**/
|
||||
STATIC
|
||||
UINT64
|
||||
GetNextEntryAttribute (
|
||||
IN UINT64 *TableAddress,
|
||||
IN UINT64 *TableAddress,
|
||||
IN UINTN EntryCount,
|
||||
IN UINTN TableLevel,
|
||||
IN UINT64 BaseAddress,
|
||||
IN OUT UINT64 *PrevEntryAttribute,
|
||||
IN OUT UINT64 *StartGcdRegion
|
||||
IN OUT UINT32 *PrevEntryAttribute,
|
||||
IN OUT UINT64 *StartGcdRegion
|
||||
)
|
||||
{
|
||||
UINTN Index;
|
||||
UINT64 Entry;
|
||||
UINT64 EntryAttribute;
|
||||
UINT64 EntryType;
|
||||
EFI_STATUS Status;
|
||||
UINTN NumberOfDescriptors;
|
||||
UINTN Index;
|
||||
UINT64 Entry;
|
||||
UINT32 EntryAttribute;
|
||||
UINT32 EntryType;
|
||||
EFI_STATUS Status;
|
||||
UINTN NumberOfDescriptors;
|
||||
EFI_GCD_MEMORY_SPACE_DESCRIPTOR *MemorySpaceMap;
|
||||
|
||||
// Get the memory space map from GCD
|
||||
MemorySpaceMap = NULL;
|
||||
Status = gDS->GetMemorySpaceMap (&NumberOfDescriptors, &MemorySpaceMap);
|
||||
Status = gDS->GetMemorySpaceMap (&NumberOfDescriptors, &MemorySpaceMap);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
if (EFI_ERROR (Status) || (TableLevel > 3)) {
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
ASSERT (TableLevel <= 3);
|
||||
return 0;
|
||||
}
|
||||
// We cannot get more than 3-level page table
|
||||
ASSERT (TableLevel <= 3);
|
||||
|
||||
// While the top level table might not contain TT_ENTRY_COUNT entries;
|
||||
// the subsequent ones should be filled up
|
||||
for (Index = 0; Index < EntryCount; Index++) {
|
||||
Entry = TableAddress[Index];
|
||||
EntryType = Entry & TT_TYPE_MASK;
|
||||
EntryAttribute = Entry & TT_ATTRIBUTES_MASK;
|
||||
Entry = TableAddress[Index];
|
||||
EntryType = Entry & TT_TYPE_MASK;
|
||||
EntryAttribute = Entry & TT_ATTR_INDX_MASK;
|
||||
|
||||
// If Entry is a Table Descriptor type entry then go through the sub-level table
|
||||
if ((EntryType == TT_TYPE_BLOCK_ENTRY) ||
|
||||
((TableLevel == 3) && (EntryType == TT_TYPE_BLOCK_ENTRY_LEVEL3)))
|
||||
{
|
||||
((TableLevel == 3) && (EntryType == TT_TYPE_BLOCK_ENTRY_LEVEL3))) {
|
||||
if ((*PrevEntryAttribute == INVALID_ENTRY) || (EntryAttribute != *PrevEntryAttribute)) {
|
||||
if (*PrevEntryAttribute != INVALID_ENTRY) {
|
||||
// Update GCD with the last region
|
||||
SetGcdMemorySpaceAttributes (
|
||||
MemorySpaceMap,
|
||||
NumberOfDescriptors,
|
||||
*StartGcdRegion,
|
||||
(BaseAddress + (Index * TT_ADDRESS_AT_LEVEL (TableLevel))) - *StartGcdRegion,
|
||||
PageAttributeToGcdAttribute (*PrevEntryAttribute)
|
||||
);
|
||||
SetGcdMemorySpaceAttributes (MemorySpaceMap, NumberOfDescriptors,
|
||||
*StartGcdRegion,
|
||||
(BaseAddress + (Index * TT_ADDRESS_AT_LEVEL(TableLevel))) - *StartGcdRegion,
|
||||
PageAttributeToGcdAttribute (*PrevEntryAttribute));
|
||||
}
|
||||
|
||||
// Start of the new region
|
||||
*StartGcdRegion = BaseAddress + (Index * TT_ADDRESS_AT_LEVEL (TableLevel));
|
||||
*StartGcdRegion = BaseAddress + (Index * TT_ADDRESS_AT_LEVEL(TableLevel));
|
||||
*PrevEntryAttribute = EntryAttribute;
|
||||
} else {
|
||||
continue;
|
||||
@ -225,27 +159,20 @@ GetNextEntryAttribute (
|
||||
ASSERT (TableLevel < 3);
|
||||
|
||||
// Increase the level number and scan the sub-level table
|
||||
GetNextEntryAttribute (
|
||||
(UINT64 *)(Entry & TT_ADDRESS_MASK_DESCRIPTION_TABLE),
|
||||
TT_ENTRY_COUNT,
|
||||
TableLevel + 1,
|
||||
(BaseAddress + (Index * TT_ADDRESS_AT_LEVEL (TableLevel))),
|
||||
PrevEntryAttribute,
|
||||
StartGcdRegion
|
||||
);
|
||||
GetNextEntryAttribute ((UINT64*)(Entry & TT_ADDRESS_MASK_DESCRIPTION_TABLE),
|
||||
TT_ENTRY_COUNT, TableLevel + 1,
|
||||
(BaseAddress + (Index * TT_ADDRESS_AT_LEVEL(TableLevel))),
|
||||
PrevEntryAttribute, StartGcdRegion);
|
||||
} else {
|
||||
if (*PrevEntryAttribute != INVALID_ENTRY) {
|
||||
// Update GCD with the last region
|
||||
SetGcdMemorySpaceAttributes (
|
||||
MemorySpaceMap,
|
||||
NumberOfDescriptors,
|
||||
*StartGcdRegion,
|
||||
(BaseAddress + (Index * TT_ADDRESS_AT_LEVEL (TableLevel))) - *StartGcdRegion,
|
||||
PageAttributeToGcdAttribute (*PrevEntryAttribute)
|
||||
);
|
||||
SetGcdMemorySpaceAttributes (MemorySpaceMap, NumberOfDescriptors,
|
||||
*StartGcdRegion,
|
||||
(BaseAddress + (Index * TT_ADDRESS_AT_LEVEL(TableLevel))) - *StartGcdRegion,
|
||||
PageAttributeToGcdAttribute (*PrevEntryAttribute));
|
||||
|
||||
// Start of the new region
|
||||
*StartGcdRegion = BaseAddress + (Index * TT_ADDRESS_AT_LEVEL (TableLevel));
|
||||
*StartGcdRegion = BaseAddress + (Index * TT_ADDRESS_AT_LEVEL(TableLevel));
|
||||
*PrevEntryAttribute = INVALID_ENTRY;
|
||||
}
|
||||
}
|
||||
@ -253,34 +180,25 @@ GetNextEntryAttribute (
|
||||
|
||||
FreePool (MemorySpaceMap);
|
||||
|
||||
return BaseAddress + (EntryCount * TT_ADDRESS_AT_LEVEL (TableLevel));
|
||||
return BaseAddress + (EntryCount * TT_ADDRESS_AT_LEVEL(TableLevel));
|
||||
}
|
||||
|
||||
/**
|
||||
Sync the GCD memory space attributes with the translation table.
|
||||
|
||||
@param[in] CpuProtocol The CPU architectural protocol instance.
|
||||
|
||||
@retval EFI_SUCCESS The GCD memory space attributes are synced with
|
||||
the MMU page table.
|
||||
@retval Others The return value of GetMemorySpaceMap().
|
||||
**/
|
||||
EFI_STATUS
|
||||
SyncCacheConfig (
|
||||
IN EFI_CPU_ARCH_PROTOCOL *CpuProtocol
|
||||
IN EFI_CPU_ARCH_PROTOCOL *CpuProtocol
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINT64 PageAttribute;
|
||||
UINT64 *FirstLevelTableAddress;
|
||||
UINTN TableLevel;
|
||||
UINTN TableCount;
|
||||
UINTN NumberOfDescriptors;
|
||||
EFI_GCD_MEMORY_SPACE_DESCRIPTOR *MemorySpaceMap;
|
||||
UINTN Tcr;
|
||||
UINTN T0SZ;
|
||||
UINT64 BaseAddressGcdRegion;
|
||||
UINT64 EndAddressGcdRegion;
|
||||
EFI_STATUS Status;
|
||||
UINT32 PageAttribute;
|
||||
UINT64 *FirstLevelTableAddress;
|
||||
UINTN TableLevel;
|
||||
UINTN TableCount;
|
||||
UINTN NumberOfDescriptors;
|
||||
EFI_GCD_MEMORY_SPACE_DESCRIPTOR *MemorySpaceMap;
|
||||
UINTN Tcr;
|
||||
UINTN T0SZ;
|
||||
UINT64 BaseAddressGcdRegion;
|
||||
UINT64 EndAddressGcdRegion;
|
||||
|
||||
// This code assumes MMU is enabled and filed with section translations
|
||||
ASSERT (ArmMmuEnabled ());
|
||||
@ -289,12 +207,8 @@ SyncCacheConfig (
|
||||
// Get the memory space map from GCD
|
||||
//
|
||||
MemorySpaceMap = NULL;
|
||||
Status = gDS->GetMemorySpaceMap (&NumberOfDescriptors, &MemorySpaceMap);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
return Status;
|
||||
}
|
||||
Status = gDS->GetMemorySpaceMap (&NumberOfDescriptors, &MemorySpaceMap);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
// The GCD implementation maintains its own copy of the state of memory space attributes. GCD needs
|
||||
// to know what the initial memory space attributes are. The CPU Arch. Protocol does not provide a
|
||||
@ -303,7 +217,7 @@ SyncCacheConfig (
|
||||
// with a way for GCD to query the CPU Arch. driver of the existing memory space attributes instead.
|
||||
|
||||
// Obtain page table base
|
||||
FirstLevelTableAddress = (UINT64 *)(ArmGetTTBR0BaseAddress ());
|
||||
FirstLevelTableAddress = (UINT64*)(ArmGetTTBR0BaseAddress ());
|
||||
|
||||
// Get Translation Control Register value
|
||||
Tcr = ArmGetTCR ();
|
||||
@ -318,24 +232,17 @@ SyncCacheConfig (
|
||||
|
||||
// We scan from the start of the memory map (ie: at the address 0x0)
|
||||
BaseAddressGcdRegion = 0x0;
|
||||
EndAddressGcdRegion = GetNextEntryAttribute (
|
||||
FirstLevelTableAddress,
|
||||
TableCount,
|
||||
TableLevel,
|
||||
BaseAddressGcdRegion,
|
||||
&PageAttribute,
|
||||
&BaseAddressGcdRegion
|
||||
);
|
||||
EndAddressGcdRegion = GetNextEntryAttribute (FirstLevelTableAddress,
|
||||
TableCount, TableLevel,
|
||||
BaseAddressGcdRegion,
|
||||
&PageAttribute, &BaseAddressGcdRegion);
|
||||
|
||||
// Update GCD with the last region if valid
|
||||
if ((PageAttribute != INVALID_ENTRY) && (EndAddressGcdRegion > BaseAddressGcdRegion)) {
|
||||
SetGcdMemorySpaceAttributes (
|
||||
MemorySpaceMap,
|
||||
NumberOfDescriptors,
|
||||
BaseAddressGcdRegion,
|
||||
EndAddressGcdRegion - BaseAddressGcdRegion,
|
||||
PageAttributeToGcdAttribute (PageAttribute)
|
||||
);
|
||||
if (PageAttribute != INVALID_ENTRY) {
|
||||
SetGcdMemorySpaceAttributes (MemorySpaceMap, NumberOfDescriptors,
|
||||
BaseAddressGcdRegion,
|
||||
EndAddressGcdRegion - BaseAddressGcdRegion,
|
||||
PageAttributeToGcdAttribute (PageAttribute));
|
||||
}
|
||||
|
||||
FreePool (MemorySpaceMap);
|
||||
@ -343,50 +250,40 @@ SyncCacheConfig (
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
Convert EFI memory attributes to ARM translation table attributes.
|
||||
|
||||
@param[in] EfiAttributes EFI memory attributes.
|
||||
|
||||
@retval The analogous translation table attributes.
|
||||
**/
|
||||
UINT64
|
||||
EfiAttributeToArmAttribute (
|
||||
IN UINT64 EfiAttributes
|
||||
IN UINT64 EfiAttributes
|
||||
)
|
||||
{
|
||||
UINT64 ArmAttributes;
|
||||
UINT64 ArmAttributes;
|
||||
|
||||
switch (EfiAttributes & EFI_MEMORY_CACHETYPE_MASK) {
|
||||
case EFI_MEMORY_UC:
|
||||
if (ArmReadCurrentEL () == AARCH64_EL2) {
|
||||
ArmAttributes = TT_ATTR_INDX_DEVICE_MEMORY | TT_XN_MASK;
|
||||
} else {
|
||||
ArmAttributes = TT_ATTR_INDX_DEVICE_MEMORY | TT_UXN_MASK | TT_PXN_MASK;
|
||||
}
|
||||
|
||||
break;
|
||||
case EFI_MEMORY_WC:
|
||||
ArmAttributes = TT_ATTR_INDX_MEMORY_NON_CACHEABLE;
|
||||
break;
|
||||
case EFI_MEMORY_WT:
|
||||
ArmAttributes = TT_ATTR_INDX_MEMORY_WRITE_THROUGH | TT_SH_INNER_SHAREABLE;
|
||||
break;
|
||||
case EFI_MEMORY_WB:
|
||||
ArmAttributes = TT_ATTR_INDX_MEMORY_WRITE_BACK | TT_SH_INNER_SHAREABLE;
|
||||
break;
|
||||
default:
|
||||
ArmAttributes = TT_ATTR_INDX_MASK;
|
||||
case EFI_MEMORY_UC:
|
||||
if (ArmReadCurrentEL () == AARCH64_EL2) {
|
||||
ArmAttributes = TT_ATTR_INDX_DEVICE_MEMORY | TT_XN_MASK;
|
||||
} else {
|
||||
ArmAttributes = TT_ATTR_INDX_DEVICE_MEMORY | TT_UXN_MASK | TT_PXN_MASK;
|
||||
}
|
||||
break;
|
||||
case EFI_MEMORY_WC:
|
||||
ArmAttributes = TT_ATTR_INDX_MEMORY_NON_CACHEABLE;
|
||||
break;
|
||||
case EFI_MEMORY_WT:
|
||||
ArmAttributes = TT_ATTR_INDX_MEMORY_WRITE_THROUGH | TT_SH_INNER_SHAREABLE;
|
||||
break;
|
||||
case EFI_MEMORY_WB:
|
||||
ArmAttributes = TT_ATTR_INDX_MEMORY_WRITE_BACK | TT_SH_INNER_SHAREABLE;
|
||||
break;
|
||||
default:
|
||||
ArmAttributes = TT_ATTR_INDX_MASK;
|
||||
}
|
||||
|
||||
// Set the access flag to match the block attributes
|
||||
if ((EfiAttributes & EFI_MEMORY_RP) == 0) {
|
||||
ArmAttributes |= TT_AF;
|
||||
}
|
||||
ArmAttributes |= TT_AF;
|
||||
|
||||
// Determine protection attributes
|
||||
if ((EfiAttributes & EFI_MEMORY_RO) != 0) {
|
||||
ArmAttributes |= TT_AP_NO_RO;
|
||||
ArmAttributes |= TT_AP_RO_RO;
|
||||
}
|
||||
|
||||
// Process eXecute Never attribute
|
||||
@ -397,40 +294,23 @@ EfiAttributeToArmAttribute (
|
||||
return ArmAttributes;
|
||||
}
|
||||
|
||||
/**
|
||||
This function returns the attributes of the memory region containing the
|
||||
specified address.
|
||||
|
||||
RegionLength and RegionAttributes are only valid if the result is EFI_SUCCESS.
|
||||
|
||||
@param[in] TranslationTable The translation table base address.
|
||||
@param[in] TableLevel The level of the translation table.
|
||||
@param[in] LastBlockEntry The last block address of the table level.
|
||||
@param[in, out] BaseAddress The base address of the memory region.
|
||||
@param[out] RegionLength The length of the memory region.
|
||||
@param[out] RegionAttributes The attributes of the memory region.
|
||||
|
||||
@retval EFI_SUCCESS The attributes of the memory region were
|
||||
returned successfully.
|
||||
@retval EFI_NOT_FOUND The memory region was not found.
|
||||
@retval EFI_NO_MAPPING The translation table entry associated with
|
||||
BaseAddress is invalid.
|
||||
**/
|
||||
// This function will recursively go down the page table to find the first block address linked to 'BaseAddress'.
|
||||
// And then the function will identify the size of the region that has the same page table attribute.
|
||||
EFI_STATUS
|
||||
GetMemoryRegionRec (
|
||||
IN UINT64 *TranslationTable,
|
||||
IN UINTN TableLevel,
|
||||
IN UINT64 *LastBlockEntry,
|
||||
IN OUT UINTN *BaseAddress,
|
||||
OUT UINTN *RegionLength,
|
||||
OUT UINTN *RegionAttributes
|
||||
IN UINT64 *TranslationTable,
|
||||
IN UINTN TableLevel,
|
||||
IN UINT64 *LastBlockEntry,
|
||||
IN OUT UINTN *BaseAddress,
|
||||
OUT UINTN *RegionLength,
|
||||
OUT UINTN *RegionAttributes
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINT64 *NextTranslationTable;
|
||||
UINT64 *BlockEntry;
|
||||
UINT64 BlockEntryType;
|
||||
UINT64 EntryType;
|
||||
EFI_STATUS Status;
|
||||
UINT64 *NextTranslationTable;
|
||||
UINT64 *BlockEntry;
|
||||
UINT64 BlockEntryType;
|
||||
UINT64 EntryType;
|
||||
|
||||
if (TableLevel != 3) {
|
||||
BlockEntryType = TT_TYPE_BLOCK_ENTRY;
|
||||
@ -439,26 +319,23 @@ GetMemoryRegionRec (
|
||||
}
|
||||
|
||||
// Find the block entry linked to the Base Address
|
||||
BlockEntry = (UINT64 *)TT_GET_ENTRY_FOR_ADDRESS (TranslationTable, TableLevel, *BaseAddress);
|
||||
EntryType = *BlockEntry & TT_TYPE_MASK;
|
||||
BlockEntry = (UINT64*)TT_GET_ENTRY_FOR_ADDRESS (TranslationTable, TableLevel, *BaseAddress);
|
||||
EntryType = *BlockEntry & TT_TYPE_MASK;
|
||||
|
||||
if ((TableLevel < 3) && (EntryType == TT_TYPE_TABLE_ENTRY)) {
|
||||
NextTranslationTable = (UINT64 *)(*BlockEntry & TT_ADDRESS_MASK_DESCRIPTION_TABLE);
|
||||
NextTranslationTable = (UINT64*)(*BlockEntry & TT_ADDRESS_MASK_DESCRIPTION_TABLE);
|
||||
|
||||
// The entry is a page table, so we go to the next level
|
||||
Status = GetMemoryRegionRec (
|
||||
NextTranslationTable, // Address of the next level page table
|
||||
TableLevel + 1, // Next Page Table level
|
||||
(UINTN *)TT_LAST_BLOCK_ADDRESS (NextTranslationTable, TT_ENTRY_COUNT),
|
||||
BaseAddress,
|
||||
RegionLength,
|
||||
RegionAttributes
|
||||
);
|
||||
NextTranslationTable, // Address of the next level page table
|
||||
TableLevel + 1, // Next Page Table level
|
||||
(UINTN*)TT_LAST_BLOCK_ADDRESS(NextTranslationTable, TT_ENTRY_COUNT),
|
||||
BaseAddress, RegionLength, RegionAttributes);
|
||||
|
||||
// EFI_SUCCESS: The end of the end of the region was found.
|
||||
// EFI_NO_MAPPING: The translation entry associated with BaseAddress is invalid.
|
||||
if (Status != EFI_NOT_FOUND) {
|
||||
return Status;
|
||||
// In case of 'Success', it means the end of the block region has been found into the upper
|
||||
// level translation table
|
||||
if (!EFI_ERROR(Status)) {
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
// Now we processed the table move to the next entry
|
||||
@ -466,94 +343,60 @@ GetMemoryRegionRec (
|
||||
} else if (EntryType == BlockEntryType) {
|
||||
// We have found the BlockEntry attached to the address. We save its start address (the start
|
||||
// address might be before the 'BaseAddress') and attributes
|
||||
*BaseAddress = *BaseAddress & ~(TT_ADDRESS_AT_LEVEL (TableLevel) - 1);
|
||||
*BaseAddress = *BaseAddress & ~(TT_ADDRESS_AT_LEVEL(TableLevel) - 1);
|
||||
*RegionLength = 0;
|
||||
*RegionAttributes = *BlockEntry & TT_ATTRIBUTES_MASK;
|
||||
} else {
|
||||
return EFI_NO_MAPPING;
|
||||
// We have an 'Invalid' entry
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
while (BlockEntry <= LastBlockEntry) {
|
||||
if (((*BlockEntry & TT_TYPE_MASK) == BlockEntryType) &&
|
||||
((*BlockEntry & TT_ATTRIBUTES_MASK) == *RegionAttributes))
|
||||
{
|
||||
*RegionLength = *RegionLength + TT_BLOCK_ENTRY_SIZE_AT_LEVEL (TableLevel);
|
||||
if ((*BlockEntry & TT_ATTRIBUTES_MASK) == *RegionAttributes) {
|
||||
*RegionLength = *RegionLength + TT_BLOCK_ENTRY_SIZE_AT_LEVEL(TableLevel);
|
||||
} else {
|
||||
// In case we have found the end of the region we return success
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
BlockEntry++;
|
||||
}
|
||||
|
||||
// If we have reached the end of the TranslationTable and we have not found the end of the region then
|
||||
// we return EFI_NOT_FOUND.
|
||||
// The caller will continue to look for the memory region at its level.
|
||||
// The caller will continue to look for the memory region at its level
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
/**
|
||||
Retrieves a memory region from a given base address.
|
||||
|
||||
This function retrieves a memory region starting from a given base address.
|
||||
|
||||
@param[in, out] BaseAddress The base address from which to retrieve
|
||||
the memory region. On successful return, this is
|
||||
updated to the end address of the retrieved region.
|
||||
@param[out] RegionLength The length of the retrieved memory region.
|
||||
@param[out] RegionAttributes The attributes of the retrieved memory region.
|
||||
|
||||
@retval EFI_STATUS Returns EFI_SUCCESS if the memory region is
|
||||
retrieved successfully, or the status of the
|
||||
recursive call to GetMemoryRegionRec.
|
||||
@retval EFI_NOT_FOUND The memory region was not found.
|
||||
@retval EFI_NO_MAPPING The translation table entry associated with
|
||||
BaseAddress is invalid.
|
||||
@retval EFI_INVALID_PARAMETER One of the input parameters was NULL.
|
||||
**/
|
||||
EFI_STATUS
|
||||
GetMemoryRegion (
|
||||
IN OUT UINTN *BaseAddress,
|
||||
OUT UINTN *RegionLength,
|
||||
OUT UINTN *RegionAttributes
|
||||
IN OUT UINTN *BaseAddress,
|
||||
OUT UINTN *RegionLength,
|
||||
OUT UINTN *RegionAttributes
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINT64 *TranslationTable;
|
||||
UINT64 *TranslationTable;
|
||||
UINTN TableLevel;
|
||||
UINTN EntryCount;
|
||||
UINTN T0SZ;
|
||||
|
||||
if ((BaseAddress == NULL) || (RegionLength == NULL) || (RegionAttributes == NULL)) {
|
||||
ASSERT ((BaseAddress != NULL) && (RegionLength != NULL) && (RegionAttributes != NULL));
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
ASSERT ((BaseAddress != NULL) && (RegionLength != NULL) && (RegionAttributes != NULL));
|
||||
|
||||
TranslationTable = ArmGetTTBR0BaseAddress ();
|
||||
|
||||
// Initialize the output parameters. These paramaters are only valid if the
|
||||
// result is EFI_SUCCESS.
|
||||
*RegionLength = 0;
|
||||
*RegionAttributes = 0;
|
||||
|
||||
T0SZ = ArmGetTCR () & TCR_T0SZ_MASK;
|
||||
// Get the Table info from T0SZ
|
||||
GetRootTranslationTableInfo (T0SZ, &TableLevel, &EntryCount);
|
||||
|
||||
Status = GetMemoryRegionRec (
|
||||
TranslationTable,
|
||||
TableLevel,
|
||||
(UINTN *)TT_LAST_BLOCK_ADDRESS (TranslationTable, EntryCount),
|
||||
BaseAddress,
|
||||
RegionLength,
|
||||
RegionAttributes
|
||||
);
|
||||
Status = GetMemoryRegionRec (TranslationTable, TableLevel,
|
||||
(UINTN*)TT_LAST_BLOCK_ADDRESS(TranslationTable, EntryCount),
|
||||
BaseAddress, RegionLength, RegionAttributes);
|
||||
|
||||
// If the region continues up to the end of the root table then GetMemoryRegionRec()
|
||||
// will return EFI_NOT_FOUND. Check if the region length was updated.
|
||||
if ((Status == EFI_NOT_FOUND) && (*RegionLength > 0)) {
|
||||
// will return EFI_NOT_FOUND
|
||||
if (Status == EFI_NOT_FOUND) {
|
||||
return EFI_SUCCESS;
|
||||
} else {
|
||||
return Status;
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
@ -13,18 +13,6 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
#include <Library/MemoryAllocationLib.h>
|
||||
#include "CpuDxe.h"
|
||||
|
||||
/**
|
||||
Convert a set of ARM short descriptor section attributes into a mask
|
||||
of EFI_MEMORY_xx constants.
|
||||
|
||||
@param[in] SectionAttributes The set of page attributes.
|
||||
@param[out] GcdAttributes Pointer to the return value.
|
||||
|
||||
@retval EFI_SUCCESS The attributes were converted successfully.
|
||||
@retval EFI_UNSUPPORTED The section attributes did not have a
|
||||
GCD transation.
|
||||
**/
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
SectionToGcdAttributes (
|
||||
IN UINT32 SectionAttributes,
|
||||
@ -34,7 +22,7 @@ SectionToGcdAttributes (
|
||||
*GcdAttributes = 0;
|
||||
|
||||
// determine cacheability attributes
|
||||
switch (SectionAttributes & TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK) {
|
||||
switch(SectionAttributes & TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK) {
|
||||
case TT_DESCRIPTOR_SECTION_CACHE_POLICY_STRONGLY_ORDERED:
|
||||
*GcdAttributes |= EFI_MEMORY_UC;
|
||||
break;
|
||||
@ -61,63 +49,34 @@ SectionToGcdAttributes (
|
||||
}
|
||||
|
||||
// determine protection attributes
|
||||
switch (SectionAttributes & TT_DESCRIPTOR_SECTION_AP_MASK) {
|
||||
case TT_DESCRIPTOR_SECTION_AP_NO_RW:
|
||||
switch(SectionAttributes & TT_DESCRIPTOR_SECTION_AP_MASK) {
|
||||
case TT_DESCRIPTOR_SECTION_AP_NO_NO: // no read, no write
|
||||
//*GcdAttributes |= EFI_MEMORY_RO | EFI_MEMORY_RP;
|
||||
break;
|
||||
|
||||
case TT_DESCRIPTOR_SECTION_AP_RW_NO:
|
||||
case TT_DESCRIPTOR_SECTION_AP_RW_RW:
|
||||
// normal read/write access, do not add additional attributes
|
||||
break;
|
||||
|
||||
// read only cases map to write-protect
|
||||
case TT_DESCRIPTOR_SECTION_AP_NO_RO:
|
||||
case TT_DESCRIPTOR_SECTION_AP_RO_NO:
|
||||
case TT_DESCRIPTOR_SECTION_AP_RO_RO:
|
||||
*GcdAttributes |= EFI_MEMORY_RO;
|
||||
break;
|
||||
|
||||
default:
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
// now process eXectue Never attribute
|
||||
if ((SectionAttributes & TT_DESCRIPTOR_SECTION_XN_MASK) != 0) {
|
||||
if ((SectionAttributes & TT_DESCRIPTOR_SECTION_XN_MASK) != 0 ) {
|
||||
*GcdAttributes |= EFI_MEMORY_XP;
|
||||
}
|
||||
|
||||
if ((SectionAttributes & TT_DESCRIPTOR_SECTION_AF) == 0) {
|
||||
*GcdAttributes |= EFI_MEMORY_RP;
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
Convert an arch specific set of page attributes into a mask
|
||||
of EFI_MEMORY_xx constants.
|
||||
|
||||
@param[in] PageAttributes The set of page attributes.
|
||||
|
||||
@retval EFI_SUCCESS The attributes were converted successfully.
|
||||
@retval EFI_UNSUPPORTED The section attributes did not have a
|
||||
GCD transation.
|
||||
**/
|
||||
UINT64
|
||||
RegionAttributeToGcdAttribute (
|
||||
IN UINTN PageAttributes
|
||||
)
|
||||
{
|
||||
UINT64 Result;
|
||||
|
||||
SectionToGcdAttributes (PageAttributes, &Result);
|
||||
return Result;
|
||||
}
|
||||
|
||||
/**
|
||||
Convert a set of ARM short descriptor page attributes into a mask
|
||||
of EFI_MEMORY_xx constants.
|
||||
|
||||
@param[in] PageAttributes The set of page attributes.
|
||||
@param[out] GcdAttributes Pointer to the return value.
|
||||
|
||||
@retval EFI_SUCCESS The attributes were converted successfully.
|
||||
@retval EFI_UNSUPPORTED The page attributes did not have a GCD transation.
|
||||
**/
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
PageToGcdAttributes (
|
||||
IN UINT32 PageAttributes,
|
||||
@ -127,7 +86,7 @@ PageToGcdAttributes (
|
||||
*GcdAttributes = 0;
|
||||
|
||||
// determine cacheability attributes
|
||||
switch (PageAttributes & TT_DESCRIPTOR_PAGE_CACHE_POLICY_MASK) {
|
||||
switch(PageAttributes & TT_DESCRIPTOR_PAGE_CACHE_POLICY_MASK) {
|
||||
case TT_DESCRIPTOR_PAGE_CACHE_POLICY_STRONGLY_ORDERED:
|
||||
*GcdAttributes |= EFI_MEMORY_UC;
|
||||
break;
|
||||
@ -154,156 +113,126 @@ PageToGcdAttributes (
|
||||
}
|
||||
|
||||
// determine protection attributes
|
||||
switch (PageAttributes & TT_DESCRIPTOR_PAGE_AP_MASK) {
|
||||
case TT_DESCRIPTOR_PAGE_AP_NO_RW:
|
||||
switch(PageAttributes & TT_DESCRIPTOR_PAGE_AP_MASK) {
|
||||
case TT_DESCRIPTOR_PAGE_AP_NO_NO: // no read, no write
|
||||
//*GcdAttributes |= EFI_MEMORY_RO | EFI_MEMORY_RP;
|
||||
break;
|
||||
|
||||
case TT_DESCRIPTOR_PAGE_AP_RW_NO:
|
||||
case TT_DESCRIPTOR_PAGE_AP_RW_RW:
|
||||
// normal read/write access, do not add additional attributes
|
||||
break;
|
||||
|
||||
// read only cases map to write-protect
|
||||
case TT_DESCRIPTOR_PAGE_AP_NO_RO:
|
||||
case TT_DESCRIPTOR_PAGE_AP_RO_NO:
|
||||
case TT_DESCRIPTOR_PAGE_AP_RO_RO:
|
||||
*GcdAttributes |= EFI_MEMORY_RO;
|
||||
break;
|
||||
|
||||
default:
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
// now process eXectue Never attribute
|
||||
if ((PageAttributes & TT_DESCRIPTOR_PAGE_XN_MASK) != 0) {
|
||||
if ((PageAttributes & TT_DESCRIPTOR_PAGE_XN_MASK) != 0 ) {
|
||||
*GcdAttributes |= EFI_MEMORY_XP;
|
||||
}
|
||||
|
||||
if ((PageAttributes & TT_DESCRIPTOR_PAGE_AF) == 0) {
|
||||
*GcdAttributes |= EFI_MEMORY_RP;
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
Synchronizes the GCD with the translation table for a specified page.
|
||||
|
||||
This function synchronizes cache configuration for a given page based on its section index
|
||||
and the first level descriptor. It traverses the second level table entries of the page and
|
||||
updates the GCD attributes accordingly for each entry.
|
||||
|
||||
@param[in] SectionIndex The index of the section where the page resides.
|
||||
@param[in] FirstLevelDescriptor The first translation table level of the page.
|
||||
@param[in] NumberOfDescriptors The number of descriptors in the GCD memory space map.
|
||||
@param[in] MemorySpaceMap The GCD memory space descriptor.
|
||||
@param[in, out] NextRegionBase The next region base address.
|
||||
@param[in, out] NextRegionLength The next region length.
|
||||
@param[in, out] NextSectionAttributes The next section attributes.
|
||||
|
||||
@retval EFI_STATUS Always return success
|
||||
**/
|
||||
EFI_STATUS
|
||||
SyncCacheConfigPage (
|
||||
IN UINT32 SectionIndex,
|
||||
IN UINT32 FirstLevelDescriptor,
|
||||
IN UINTN NumberOfDescriptors,
|
||||
IN EFI_GCD_MEMORY_SPACE_DESCRIPTOR *MemorySpaceMap,
|
||||
IN OUT EFI_PHYSICAL_ADDRESS *NextRegionBase,
|
||||
IN OUT UINT64 *NextRegionLength,
|
||||
IN OUT UINT32 *NextSectionAttributes
|
||||
IN UINT32 SectionIndex,
|
||||
IN UINT32 FirstLevelDescriptor,
|
||||
IN UINTN NumberOfDescriptors,
|
||||
IN EFI_GCD_MEMORY_SPACE_DESCRIPTOR *MemorySpaceMap,
|
||||
IN OUT EFI_PHYSICAL_ADDRESS *NextRegionBase,
|
||||
IN OUT UINT64 *NextRegionLength,
|
||||
IN OUT UINT32 *NextSectionAttributes
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINT32 i;
|
||||
volatile ARM_PAGE_TABLE_ENTRY *SecondLevelTable;
|
||||
UINT32 NextPageAttributes;
|
||||
UINT32 PageAttributes;
|
||||
UINT32 BaseAddress;
|
||||
UINT64 GcdAttributes;
|
||||
EFI_STATUS Status;
|
||||
UINT32 i;
|
||||
volatile ARM_PAGE_TABLE_ENTRY *SecondLevelTable;
|
||||
UINT32 NextPageAttributes;
|
||||
UINT32 PageAttributes;
|
||||
UINT32 BaseAddress;
|
||||
UINT64 GcdAttributes;
|
||||
|
||||
// Get the Base Address from FirstLevelDescriptor;
|
||||
BaseAddress = TT_DESCRIPTOR_PAGE_BASE_ADDRESS (SectionIndex << TT_DESCRIPTOR_SECTION_BASE_SHIFT);
|
||||
BaseAddress = TT_DESCRIPTOR_PAGE_BASE_ADDRESS(SectionIndex << TT_DESCRIPTOR_SECTION_BASE_SHIFT);
|
||||
|
||||
// Convert SectionAttributes into PageAttributes
|
||||
NextPageAttributes =
|
||||
TT_DESCRIPTOR_CONVERT_TO_PAGE_CACHE_POLICY (*NextSectionAttributes) |
|
||||
TT_DESCRIPTOR_CONVERT_TO_PAGE_AF (*NextSectionAttributes) |
|
||||
TT_DESCRIPTOR_CONVERT_TO_PAGE_AP (*NextSectionAttributes);
|
||||
TT_DESCRIPTOR_CONVERT_TO_PAGE_CACHE_POLICY(*NextSectionAttributes,0) |
|
||||
TT_DESCRIPTOR_CONVERT_TO_PAGE_AP(*NextSectionAttributes);
|
||||
|
||||
// obtain page table base
|
||||
SecondLevelTable = (ARM_PAGE_TABLE_ENTRY *)(FirstLevelDescriptor & TT_DESCRIPTOR_SECTION_PAGETABLE_ADDRESS_MASK);
|
||||
|
||||
for (i = 0; i < TRANSLATION_TABLE_PAGE_COUNT; i++) {
|
||||
for (i=0; i < TRANSLATION_TABLE_PAGE_COUNT; i++) {
|
||||
if ((SecondLevelTable[i] & TT_DESCRIPTOR_PAGE_TYPE_MASK) == TT_DESCRIPTOR_PAGE_TYPE_PAGE) {
|
||||
// extract attributes (cacheability and permissions)
|
||||
PageAttributes = SecondLevelTable[i] & (TT_DESCRIPTOR_PAGE_CACHE_POLICY_MASK | TT_DESCRIPTOR_PAGE_AP_MASK | TT_DESCRIPTOR_PAGE_AF);
|
||||
PageAttributes = SecondLevelTable[i] & (TT_DESCRIPTOR_PAGE_CACHE_POLICY_MASK | TT_DESCRIPTOR_PAGE_AP_MASK);
|
||||
|
||||
if (NextPageAttributes == 0) {
|
||||
// start on a new region
|
||||
*NextRegionLength = 0;
|
||||
*NextRegionBase = BaseAddress | (i << TT_DESCRIPTOR_PAGE_BASE_SHIFT);
|
||||
*NextRegionLength = 0;
|
||||
*NextRegionBase = BaseAddress | (i << TT_DESCRIPTOR_PAGE_BASE_SHIFT);
|
||||
NextPageAttributes = PageAttributes;
|
||||
} else if (PageAttributes != NextPageAttributes) {
|
||||
// Convert Section Attributes into GCD Attributes
|
||||
Status = PageToGcdAttributes (NextPageAttributes, &GcdAttributes);
|
||||
if (EFI_ERROR (Status)) {
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
GcdAttributes = 0;
|
||||
}
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
// update GCD with these changes (this will recurse into our own CpuSetMemoryAttributes below which is OK)
|
||||
SetGcdMemorySpaceAttributes (MemorySpaceMap, NumberOfDescriptors, *NextRegionBase, *NextRegionLength, GcdAttributes);
|
||||
|
||||
// start on a new region
|
||||
*NextRegionLength = 0;
|
||||
*NextRegionBase = BaseAddress | (i << TT_DESCRIPTOR_PAGE_BASE_SHIFT);
|
||||
*NextRegionLength = 0;
|
||||
*NextRegionBase = BaseAddress | (i << TT_DESCRIPTOR_PAGE_BASE_SHIFT);
|
||||
NextPageAttributes = PageAttributes;
|
||||
}
|
||||
} else if (NextPageAttributes != 0) {
|
||||
// Convert Page Attributes into GCD Attributes
|
||||
Status = PageToGcdAttributes (NextPageAttributes, &GcdAttributes);
|
||||
if (EFI_ERROR (Status)) {
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
GcdAttributes = 0;
|
||||
}
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
// update GCD with these changes (this will recurse into our own CpuSetMemoryAttributes below which is OK)
|
||||
SetGcdMemorySpaceAttributes (MemorySpaceMap, NumberOfDescriptors, *NextRegionBase, *NextRegionLength, GcdAttributes);
|
||||
|
||||
*NextRegionLength = 0;
|
||||
*NextRegionBase = BaseAddress | (i << TT_DESCRIPTOR_PAGE_BASE_SHIFT);
|
||||
*NextRegionLength = 0;
|
||||
*NextRegionBase = BaseAddress | (i << TT_DESCRIPTOR_PAGE_BASE_SHIFT);
|
||||
NextPageAttributes = 0;
|
||||
}
|
||||
|
||||
*NextRegionLength += TT_DESCRIPTOR_PAGE_SIZE;
|
||||
}
|
||||
|
||||
// Convert back PageAttributes into SectionAttributes
|
||||
*NextSectionAttributes =
|
||||
TT_DESCRIPTOR_CONVERT_TO_SECTION_CACHE_POLICY (NextPageAttributes) |
|
||||
TT_DESCRIPTOR_CONVERT_TO_SECTION_AF (NextPageAttributes) |
|
||||
TT_DESCRIPTOR_CONVERT_TO_SECTION_AP (NextPageAttributes);
|
||||
TT_DESCRIPTOR_CONVERT_TO_SECTION_CACHE_POLICY(NextPageAttributes,0) |
|
||||
TT_DESCRIPTOR_CONVERT_TO_SECTION_AP(NextPageAttributes);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
Sync the GCD memory space attributes with the translation table.
|
||||
|
||||
@param[in] CpuProtocol The CPU architectural protocol instance.
|
||||
|
||||
@retval EFI_SUCCESS The GCD memory space attributes are synced with the MMU page table.
|
||||
@retval Others The return value of GetMemorySpaceMap().
|
||||
**/
|
||||
EFI_STATUS
|
||||
SyncCacheConfig (
|
||||
IN EFI_CPU_ARCH_PROTOCOL *CpuProtocol
|
||||
IN EFI_CPU_ARCH_PROTOCOL *CpuProtocol
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINT32 i;
|
||||
EFI_PHYSICAL_ADDRESS NextRegionBase;
|
||||
UINT64 NextRegionLength;
|
||||
UINT32 NextSectionAttributes;
|
||||
UINT32 SectionAttributes;
|
||||
UINT64 GcdAttributes;
|
||||
volatile ARM_FIRST_LEVEL_DESCRIPTOR *FirstLevelTable;
|
||||
UINTN NumberOfDescriptors;
|
||||
EFI_GCD_MEMORY_SPACE_DESCRIPTOR *MemorySpaceMap;
|
||||
EFI_STATUS Status;
|
||||
UINT32 i;
|
||||
EFI_PHYSICAL_ADDRESS NextRegionBase;
|
||||
UINT64 NextRegionLength;
|
||||
UINT32 NextSectionAttributes;
|
||||
UINT32 SectionAttributes;
|
||||
UINT64 GcdAttributes;
|
||||
volatile ARM_FIRST_LEVEL_DESCRIPTOR *FirstLevelTable;
|
||||
UINTN NumberOfDescriptors;
|
||||
EFI_GCD_MEMORY_SPACE_DESCRIPTOR *MemorySpaceMap;
|
||||
|
||||
|
||||
DEBUG ((DEBUG_PAGE, "SyncCacheConfig()\n"));
|
||||
|
||||
@ -314,13 +243,9 @@ SyncCacheConfig (
|
||||
// Get the memory space map from GCD
|
||||
//
|
||||
MemorySpaceMap = NULL;
|
||||
Status = gDS->GetMemorySpaceMap (&NumberOfDescriptors, &MemorySpaceMap);
|
||||
Status = gDS->GetMemorySpaceMap (&NumberOfDescriptors, &MemorySpaceMap);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((DEBUG_ERROR, "SyncCacheConfig - GetMemorySpaceMap() failed! Status: %r\n", Status));
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
// The GCD implementation maintains its own copy of the state of memory space attributes. GCD needs
|
||||
// to know what the initial memory space attributes are. The CPU Arch. Protocol does not provide a
|
||||
@ -332,55 +257,44 @@ SyncCacheConfig (
|
||||
FirstLevelTable = (ARM_FIRST_LEVEL_DESCRIPTOR *)(ArmGetTTBR0BaseAddress ());
|
||||
|
||||
// Get the first region
|
||||
NextSectionAttributes = FirstLevelTable[0] & (TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK | TT_DESCRIPTOR_SECTION_AP_MASK | TT_DESCRIPTOR_SECTION_AF);
|
||||
NextSectionAttributes = FirstLevelTable[0] & (TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK | TT_DESCRIPTOR_SECTION_AP_MASK);
|
||||
|
||||
// iterate through each 1MB descriptor
|
||||
NextRegionBase = NextRegionLength = 0;
|
||||
for (i = 0; i < TRANSLATION_TABLE_SECTION_COUNT; i++) {
|
||||
for (i=0; i < TRANSLATION_TABLE_SECTION_COUNT; i++) {
|
||||
if ((FirstLevelTable[i] & TT_DESCRIPTOR_SECTION_TYPE_MASK) == TT_DESCRIPTOR_SECTION_TYPE_SECTION) {
|
||||
// extract attributes (cacheability and permissions)
|
||||
SectionAttributes = FirstLevelTable[i] & (TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK | TT_DESCRIPTOR_SECTION_AP_MASK | TT_DESCRIPTOR_SECTION_AF);
|
||||
SectionAttributes = FirstLevelTable[i] & (TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK | TT_DESCRIPTOR_SECTION_AP_MASK);
|
||||
|
||||
if (NextSectionAttributes == 0) {
|
||||
// start on a new region
|
||||
NextRegionLength = 0;
|
||||
NextRegionBase = TT_DESCRIPTOR_SECTION_BASE_ADDRESS (i << TT_DESCRIPTOR_SECTION_BASE_SHIFT);
|
||||
NextRegionLength = 0;
|
||||
NextRegionBase = TT_DESCRIPTOR_SECTION_BASE_ADDRESS(i << TT_DESCRIPTOR_SECTION_BASE_SHIFT);
|
||||
NextSectionAttributes = SectionAttributes;
|
||||
} else if (SectionAttributes != NextSectionAttributes) {
|
||||
// Convert Section Attributes into GCD Attributes
|
||||
Status = SectionToGcdAttributes (NextSectionAttributes, &GcdAttributes);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((DEBUG_ERROR, "SyncCacheConfig - SectionToGcdAttributes() failed! Status: %r\n", Status));
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
GcdAttributes = 0;
|
||||
}
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
// update GCD with these changes (this will recurse into our own CpuSetMemoryAttributes below which is OK)
|
||||
SetGcdMemorySpaceAttributes (MemorySpaceMap, NumberOfDescriptors, NextRegionBase, NextRegionLength, GcdAttributes);
|
||||
|
||||
// start on a new region
|
||||
NextRegionLength = 0;
|
||||
NextRegionBase = TT_DESCRIPTOR_SECTION_BASE_ADDRESS (i << TT_DESCRIPTOR_SECTION_BASE_SHIFT);
|
||||
NextRegionLength = 0;
|
||||
NextRegionBase = TT_DESCRIPTOR_SECTION_BASE_ADDRESS(i << TT_DESCRIPTOR_SECTION_BASE_SHIFT);
|
||||
NextSectionAttributes = SectionAttributes;
|
||||
}
|
||||
|
||||
NextRegionLength += TT_DESCRIPTOR_SECTION_SIZE;
|
||||
} else if (TT_DESCRIPTOR_SECTION_TYPE_IS_PAGE_TABLE (FirstLevelTable[i])) {
|
||||
} else if (TT_DESCRIPTOR_SECTION_TYPE_IS_PAGE_TABLE(FirstLevelTable[i])) {
|
||||
// In this case any bits set in the 'NextSectionAttributes' are garbage and were set from
|
||||
// bits that are actually part of the pagetable address. We clear it out to zero so that
|
||||
// the SyncCacheConfigPage will use the page attributes instead of trying to convert the
|
||||
// section attributes into page attributes
|
||||
NextSectionAttributes = 0;
|
||||
Status = SyncCacheConfigPage (
|
||||
i,
|
||||
FirstLevelTable[i],
|
||||
NumberOfDescriptors,
|
||||
MemorySpaceMap,
|
||||
&NextRegionBase,
|
||||
&NextRegionLength,
|
||||
&NextSectionAttributes
|
||||
);
|
||||
Status = SyncCacheConfigPage (
|
||||
i,FirstLevelTable[i],
|
||||
NumberOfDescriptors, MemorySpaceMap,
|
||||
&NextRegionBase,&NextRegionLength,&NextSectionAttributes);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
} else {
|
||||
// We do not support yet 16MB sections
|
||||
@ -390,20 +304,15 @@ SyncCacheConfig (
|
||||
if (NextSectionAttributes != 0) {
|
||||
// Convert Section Attributes into GCD Attributes
|
||||
Status = SectionToGcdAttributes (NextSectionAttributes, &GcdAttributes);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((DEBUG_ERROR, "SyncCacheConfig - SectionToGcdAttributes() failed! Status: %r\n", Status));
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
GcdAttributes = 0;
|
||||
}
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
// update GCD with these changes (this will recurse into our own CpuSetMemoryAttributes below which is OK)
|
||||
SetGcdMemorySpaceAttributes (MemorySpaceMap, NumberOfDescriptors, NextRegionBase, NextRegionLength, GcdAttributes);
|
||||
|
||||
NextRegionLength = 0;
|
||||
NextRegionBase = TT_DESCRIPTOR_SECTION_BASE_ADDRESS (i << TT_DESCRIPTOR_SECTION_BASE_SHIFT);
|
||||
NextRegionLength = 0;
|
||||
NextRegionBase = TT_DESCRIPTOR_SECTION_BASE_ADDRESS(i << TT_DESCRIPTOR_SECTION_BASE_SHIFT);
|
||||
NextSectionAttributes = 0;
|
||||
}
|
||||
|
||||
NextRegionLength += TT_DESCRIPTOR_SECTION_SIZE;
|
||||
}
|
||||
} // section entry loop
|
||||
@ -411,11 +320,7 @@ SyncCacheConfig (
|
||||
if (NextSectionAttributes != 0) {
|
||||
// Convert Section Attributes into GCD Attributes
|
||||
Status = SectionToGcdAttributes (NextSectionAttributes, &GcdAttributes);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((DEBUG_ERROR, "SyncCacheConfig - SectionToGcdAttributes() failed! Status: %r\n", Status));
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
GcdAttributes = 0;
|
||||
}
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
// update GCD with these changes (this will recurse into our own CpuSetMemoryAttributes below which is OK)
|
||||
SetGcdMemorySpaceAttributes (MemorySpaceMap, NumberOfDescriptors, NextRegionBase, NextRegionLength, GcdAttributes);
|
||||
@ -426,19 +331,12 @@ SyncCacheConfig (
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
Convert EFI memory attributes to ARM translation table attributes.
|
||||
|
||||
@param[in] EfiAttributes EFI memory attributes.
|
||||
|
||||
@retval The analogous translation table attributes.
|
||||
**/
|
||||
UINT64
|
||||
EfiAttributeToArmAttribute (
|
||||
IN UINT64 EfiAttributes
|
||||
IN UINT64 EfiAttributes
|
||||
)
|
||||
{
|
||||
UINT64 ArmAttributes;
|
||||
UINT64 ArmAttributes;
|
||||
|
||||
switch (EfiAttributes & EFI_MEMORY_CACHETYPE_MASK) {
|
||||
case EFI_MEMORY_UC:
|
||||
@ -479,100 +377,58 @@ EfiAttributeToArmAttribute (
|
||||
ArmAttributes |= TT_DESCRIPTOR_SECTION_XN_MASK;
|
||||
}
|
||||
|
||||
if ((EfiAttributes & EFI_MEMORY_RP) == 0) {
|
||||
ArmAttributes |= TT_DESCRIPTOR_SECTION_AF;
|
||||
}
|
||||
|
||||
return ArmAttributes;
|
||||
}
|
||||
|
||||
/**
|
||||
This function finds the end of a memory region in a translation table. A
|
||||
memory region is defined as a contiguous set of pages with the same attributes.
|
||||
|
||||
@param[in] PageTable The translation table to traverse.
|
||||
@param[in] BaseAddress The address from which to start the search
|
||||
@param[in] RegionAttributes The attributes of the start of the region.
|
||||
@param[out] RegionLength The length of the region found.
|
||||
|
||||
@retval EFI_SUCCESS The region was found.
|
||||
@retval EFI_NOT_FOUND The end of the region was not found.
|
||||
@retval EFI_NO_MAPPING The region specified by BaseAddress is not mapped
|
||||
in the input translation table.
|
||||
@retval EFI_UNSUPPORTED Large pages are not supported.
|
||||
**/
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
GetMemoryRegionPage (
|
||||
IN UINT32 *PageTable,
|
||||
IN UINTN *BaseAddress,
|
||||
IN UINTN *RegionAttributes,
|
||||
OUT UINTN *RegionLength
|
||||
IN UINT32 *PageTable,
|
||||
IN OUT UINTN *BaseAddress,
|
||||
OUT UINTN *RegionLength,
|
||||
OUT UINTN *RegionAttributes
|
||||
)
|
||||
{
|
||||
UINT32 PageAttributes;
|
||||
UINT32 TableIndex;
|
||||
UINT32 PageDescriptor;
|
||||
EFI_STATUS Status;
|
||||
|
||||
// Convert the section attributes into page attributes
|
||||
PageAttributes = ConvertSectionAttributesToPageAttributes (*RegionAttributes);
|
||||
Status = EFI_NOT_FOUND;
|
||||
*RegionLength = 0;
|
||||
PageAttributes = ConvertSectionAttributesToPageAttributes (*RegionAttributes, 0);
|
||||
|
||||
// Calculate index into first level translation table for start of modification
|
||||
TableIndex = ((*BaseAddress) & TT_DESCRIPTOR_PAGE_INDEX_MASK) >> TT_DESCRIPTOR_PAGE_BASE_SHIFT;
|
||||
ASSERT (TableIndex < TRANSLATION_TABLE_PAGE_COUNT);
|
||||
|
||||
// Go through the page table to find the end of the section
|
||||
for ( ; TableIndex < TRANSLATION_TABLE_PAGE_COUNT; TableIndex++) {
|
||||
for (; TableIndex < TRANSLATION_TABLE_PAGE_COUNT; TableIndex++) {
|
||||
// Get the section at the given index
|
||||
PageDescriptor = PageTable[TableIndex];
|
||||
|
||||
if ((PageDescriptor & TT_DESCRIPTOR_PAGE_TYPE_MASK) == TT_DESCRIPTOR_PAGE_TYPE_FAULT) {
|
||||
Status = (*RegionLength > 0) ? EFI_SUCCESS : EFI_NO_MAPPING;
|
||||
break;
|
||||
// Case: End of the boundary of the region
|
||||
return EFI_SUCCESS;
|
||||
} else if ((PageDescriptor & TT_DESCRIPTOR_PAGE_TYPE_PAGE) == TT_DESCRIPTOR_PAGE_TYPE_PAGE) {
|
||||
if ((PageDescriptor & TT_DESCRIPTOR_PAGE_ATTRIBUTE_MASK) != PageAttributes) {
|
||||
Status = EFI_SUCCESS;
|
||||
break;
|
||||
if ((PageDescriptor & TT_DESCRIPTOR_PAGE_ATTRIBUTE_MASK) == PageAttributes) {
|
||||
*RegionLength = *RegionLength + TT_DESCRIPTOR_PAGE_SIZE;
|
||||
} else {
|
||||
// Case: End of the boundary of the region
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
*RegionLength += TT_DESCRIPTOR_PAGE_SIZE;
|
||||
} else {
|
||||
// Large pages are unsupported.
|
||||
Status = EFI_UNSUPPORTED;
|
||||
ASSERT (0);
|
||||
break;
|
||||
// We do not support Large Page yet. We return EFI_SUCCESS that means end of the region.
|
||||
ASSERT(0);
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
return Status;
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
/**
|
||||
Get the memory region that contains the specified address. A memory region is defined
|
||||
as a contiguous set of pages with the same attributes.
|
||||
|
||||
RegionLength and RegionAttributes are only valid if EFI_SUCCESS is returned.
|
||||
|
||||
@param[in, out] BaseAddress On input, the address to search for.
|
||||
On output, the base address of the region found.
|
||||
@param[out] RegionLength The length of the region found.
|
||||
@param[out] RegionAttributes The attributes of the region found.
|
||||
|
||||
@retval EFI_SUCCESS Region found
|
||||
@retval EFI_NOT_FOUND Region not found
|
||||
@retval EFI_UNSUPPORTED Large pages are unsupported
|
||||
@retval EFI_NO_MAPPING The page specified by BaseAddress is unmapped
|
||||
@retval EFI_INVALID_PARAMETER The BaseAddress exceeds the addressable range of
|
||||
the translation table.
|
||||
**/
|
||||
EFI_STATUS
|
||||
GetMemoryRegion (
|
||||
IN OUT UINTN *BaseAddress,
|
||||
OUT UINTN *RegionLength,
|
||||
OUT UINTN *RegionAttributes
|
||||
IN OUT UINTN *BaseAddress,
|
||||
OUT UINTN *RegionLength,
|
||||
OUT UINTN *RegionAttributes
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
@ -580,9 +436,8 @@ GetMemoryRegion (
|
||||
UINT32 PageAttributes;
|
||||
UINT32 PageTableIndex;
|
||||
UINT32 SectionDescriptor;
|
||||
ARM_FIRST_LEVEL_DESCRIPTOR *FirstLevelTable;
|
||||
UINT32 *PageTable;
|
||||
UINTN Length;
|
||||
ARM_FIRST_LEVEL_DESCRIPTOR *FirstLevelTable;
|
||||
UINT32 *PageTable;
|
||||
|
||||
// Initialize the arguments
|
||||
*RegionLength = 0;
|
||||
@ -592,11 +447,7 @@ GetMemoryRegion (
|
||||
|
||||
// Calculate index into first level translation table for start of modification
|
||||
TableIndex = TT_DESCRIPTOR_SECTION_BASE_ADDRESS (*BaseAddress) >> TT_DESCRIPTOR_SECTION_BASE_SHIFT;
|
||||
|
||||
if (TableIndex >= TRANSLATION_TABLE_SECTION_COUNT) {
|
||||
ASSERT (TableIndex < TRANSLATION_TABLE_SECTION_COUNT);
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
ASSERT (TableIndex < TRANSLATION_TABLE_SECTION_COUNT);
|
||||
|
||||
// Get the section at the given index
|
||||
SectionDescriptor = FirstLevelTable[TableIndex];
|
||||
@ -608,52 +459,42 @@ GetMemoryRegion (
|
||||
if (((SectionDescriptor & TT_DESCRIPTOR_SECTION_TYPE_MASK) == TT_DESCRIPTOR_SECTION_TYPE_SECTION) ||
|
||||
((SectionDescriptor & TT_DESCRIPTOR_SECTION_TYPE_MASK) == TT_DESCRIPTOR_SECTION_TYPE_SUPERSECTION))
|
||||
{
|
||||
*BaseAddress = (*BaseAddress) & TT_DESCRIPTOR_SECTION_BASE_ADDRESS_MASK;
|
||||
*BaseAddress = (*BaseAddress) & TT_DESCRIPTOR_SECTION_BASE_ADDRESS_MASK;
|
||||
*RegionAttributes = SectionDescriptor & TT_DESCRIPTOR_SECTION_ATTRIBUTE_MASK;
|
||||
} else {
|
||||
// Otherwise, we round it to the page boundary
|
||||
*BaseAddress = (*BaseAddress) & TT_DESCRIPTOR_PAGE_BASE_ADDRESS_MASK;
|
||||
|
||||
// Get the attribute at the page table level (Level 2)
|
||||
PageTable = (UINT32 *)(SectionDescriptor & TT_DESCRIPTOR_SECTION_PAGETABLE_ADDRESS_MASK);
|
||||
PageTable = (UINT32*)(SectionDescriptor & TT_DESCRIPTOR_SECTION_PAGETABLE_ADDRESS_MASK);
|
||||
|
||||
// Calculate index into first level translation table for start of modification
|
||||
PageTableIndex = ((*BaseAddress) & TT_DESCRIPTOR_PAGE_INDEX_MASK) >> TT_DESCRIPTOR_PAGE_BASE_SHIFT;
|
||||
ASSERT (PageTableIndex < TRANSLATION_TABLE_PAGE_COUNT);
|
||||
|
||||
PageAttributes = PageTable[PageTableIndex] & TT_DESCRIPTOR_PAGE_ATTRIBUTE_MASK;
|
||||
*RegionAttributes = TT_DESCRIPTOR_CONVERT_TO_SECTION_CACHE_POLICY (PageAttributes) |
|
||||
TT_DESCRIPTOR_CONVERT_TO_SECTION_S (PageAttributes) |
|
||||
TT_DESCRIPTOR_CONVERT_TO_SECTION_XN (PageAttributes) |
|
||||
TT_DESCRIPTOR_CONVERT_TO_SECTION_AF (PageAttributes) |
|
||||
PageAttributes = PageTable[PageTableIndex] & TT_DESCRIPTOR_PAGE_ATTRIBUTE_MASK;
|
||||
*RegionAttributes = TT_DESCRIPTOR_CONVERT_TO_SECTION_CACHE_POLICY (PageAttributes, 0) |
|
||||
TT_DESCRIPTOR_CONVERT_TO_SECTION_AP (PageAttributes);
|
||||
}
|
||||
|
||||
Status = EFI_NOT_FOUND;
|
||||
|
||||
for ( ; TableIndex < TRANSLATION_TABLE_SECTION_COUNT; TableIndex++) {
|
||||
for (;TableIndex < TRANSLATION_TABLE_SECTION_COUNT; TableIndex++) {
|
||||
// Get the section at the given index
|
||||
SectionDescriptor = FirstLevelTable[TableIndex];
|
||||
|
||||
// If the entry is a level-2 page table then we scan it to find the end of the region
|
||||
if (TT_DESCRIPTOR_SECTION_TYPE_IS_PAGE_TABLE (SectionDescriptor)) {
|
||||
// Extract the page table location from the descriptor
|
||||
PageTable = (UINT32 *)(SectionDescriptor & TT_DESCRIPTOR_SECTION_PAGETABLE_ADDRESS_MASK);
|
||||
Length = 0;
|
||||
PageTable = (UINT32*)(SectionDescriptor & TT_DESCRIPTOR_SECTION_PAGETABLE_ADDRESS_MASK);
|
||||
|
||||
// Scan the page table to find the end of the region.
|
||||
Status = GetMemoryRegionPage (PageTable, BaseAddress, RegionAttributes, &Length);
|
||||
*RegionLength += Length;
|
||||
Status = GetMemoryRegionPage (PageTable, BaseAddress, RegionLength, RegionAttributes);
|
||||
|
||||
// Status == EFI_NOT_FOUND implies we have not reached the end of the region.
|
||||
if ((Status == EFI_NOT_FOUND) && (Length > 0)) {
|
||||
continue;
|
||||
// If we have found the end of the region (Status == EFI_SUCCESS) then we exit the for-loop
|
||||
if (Status == EFI_SUCCESS) {
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
} else if (((SectionDescriptor & TT_DESCRIPTOR_SECTION_TYPE_MASK) == TT_DESCRIPTOR_SECTION_TYPE_SECTION) ||
|
||||
((SectionDescriptor & TT_DESCRIPTOR_SECTION_TYPE_MASK) == TT_DESCRIPTOR_SECTION_TYPE_SUPERSECTION))
|
||||
{
|
||||
((SectionDescriptor & TT_DESCRIPTOR_SECTION_TYPE_MASK) == TT_DESCRIPTOR_SECTION_TYPE_SUPERSECTION)) {
|
||||
if ((SectionDescriptor & TT_DESCRIPTOR_SECTION_ATTRIBUTE_MASK) != *RegionAttributes) {
|
||||
// If the attributes of the section differ from the one targeted then we exit the loop
|
||||
break;
|
||||
@ -666,10 +507,5 @@ GetMemoryRegion (
|
||||
}
|
||||
}
|
||||
|
||||
// Check if the region length was updated.
|
||||
if (*RegionLength > 0) {
|
||||
Status = EFI_SUCCESS;
|
||||
}
|
||||
|
||||
return Status;
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
@ -11,9 +11,7 @@
|
||||
|
||||
#include <Guid/IdleLoopEvent.h>
|
||||
|
||||
#include <Library/MemoryAllocationLib.h>
|
||||
|
||||
BOOLEAN mIsFlushingGCD;
|
||||
BOOLEAN mIsFlushingGCD;
|
||||
|
||||
/**
|
||||
This function flushes the range of addresses from Start to Start+Length
|
||||
@ -45,12 +43,13 @@ BOOLEAN mIsFlushingGCD;
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
CpuFlushCpuDataCache (
|
||||
IN EFI_CPU_ARCH_PROTOCOL *This,
|
||||
IN EFI_PHYSICAL_ADDRESS Start,
|
||||
IN UINT64 Length,
|
||||
IN EFI_CPU_FLUSH_TYPE FlushType
|
||||
IN EFI_CPU_ARCH_PROTOCOL *This,
|
||||
IN EFI_PHYSICAL_ADDRESS Start,
|
||||
IN UINT64 Length,
|
||||
IN EFI_CPU_FLUSH_TYPE FlushType
|
||||
)
|
||||
{
|
||||
|
||||
switch (FlushType) {
|
||||
case EfiCpuFlushTypeWriteBack:
|
||||
WriteBackDataCacheRange ((VOID *)(UINTN)Start, (UINTN)Length);
|
||||
@ -68,6 +67,7 @@ CpuFlushCpuDataCache (
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
This function enables interrupt processing by the processor.
|
||||
|
||||
@ -80,7 +80,7 @@ CpuFlushCpuDataCache (
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
CpuEnableInterrupt (
|
||||
IN EFI_CPU_ARCH_PROTOCOL *This
|
||||
IN EFI_CPU_ARCH_PROTOCOL *This
|
||||
)
|
||||
{
|
||||
ArmEnableInterrupts ();
|
||||
@ -88,6 +88,7 @@ CpuEnableInterrupt (
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
This function disables interrupt processing by the processor.
|
||||
|
||||
@ -100,7 +101,7 @@ CpuEnableInterrupt (
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
CpuDisableInterrupt (
|
||||
IN EFI_CPU_ARCH_PROTOCOL *This
|
||||
IN EFI_CPU_ARCH_PROTOCOL *This
|
||||
)
|
||||
{
|
||||
ArmDisableInterrupts ();
|
||||
@ -108,6 +109,7 @@ CpuDisableInterrupt (
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
This function retrieves the processor's current interrupt state a returns it in
|
||||
State. If interrupts are currently enabled, then TRUE is returned. If interrupts
|
||||
@ -124,18 +126,19 @@ CpuDisableInterrupt (
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
CpuGetInterruptState (
|
||||
IN EFI_CPU_ARCH_PROTOCOL *This,
|
||||
OUT BOOLEAN *State
|
||||
IN EFI_CPU_ARCH_PROTOCOL *This,
|
||||
OUT BOOLEAN *State
|
||||
)
|
||||
{
|
||||
if (State == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
*State = ArmGetInterruptState ();
|
||||
*State = ArmGetInterruptState();
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
This function generates an INIT on the processor. If this function succeeds, then the
|
||||
processor will be reset, and control will not be returned to the caller. If InitType is
|
||||
@ -155,8 +158,8 @@ CpuGetInterruptState (
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
CpuInit (
|
||||
IN EFI_CPU_ARCH_PROTOCOL *This,
|
||||
IN EFI_CPU_INIT_TYPE InitType
|
||||
IN EFI_CPU_ARCH_PROTOCOL *This,
|
||||
IN EFI_CPU_INIT_TYPE InitType
|
||||
)
|
||||
{
|
||||
return EFI_UNSUPPORTED;
|
||||
@ -165,9 +168,9 @@ CpuInit (
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
CpuRegisterInterruptHandler (
|
||||
IN EFI_CPU_ARCH_PROTOCOL *This,
|
||||
IN EFI_EXCEPTION_TYPE InterruptType,
|
||||
IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler
|
||||
IN EFI_CPU_ARCH_PROTOCOL *This,
|
||||
IN EFI_EXCEPTION_TYPE InterruptType,
|
||||
IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler
|
||||
)
|
||||
{
|
||||
return RegisterInterruptHandler (InterruptType, InterruptHandler);
|
||||
@ -176,10 +179,10 @@ CpuRegisterInterruptHandler (
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
CpuGetTimerValue (
|
||||
IN EFI_CPU_ARCH_PROTOCOL *This,
|
||||
IN UINT32 TimerIndex,
|
||||
OUT UINT64 *TimerValue,
|
||||
OUT UINT64 *TimerPeriod OPTIONAL
|
||||
IN EFI_CPU_ARCH_PROTOCOL *This,
|
||||
IN UINT32 TimerIndex,
|
||||
OUT UINT64 *TimerValue,
|
||||
OUT UINT64 *TimerPeriod OPTIONAL
|
||||
)
|
||||
{
|
||||
return EFI_UNSUPPORTED;
|
||||
@ -196,8 +199,8 @@ CpuGetTimerValue (
|
||||
VOID
|
||||
EFIAPI
|
||||
IdleLoopEventCallback (
|
||||
IN EFI_EVENT Event,
|
||||
IN VOID *Context
|
||||
IN EFI_EVENT Event,
|
||||
IN VOID *Context
|
||||
)
|
||||
{
|
||||
CpuSleep ();
|
||||
@ -206,8 +209,8 @@ IdleLoopEventCallback (
|
||||
//
|
||||
// Globals used to initialize the protocol
|
||||
//
|
||||
EFI_HANDLE mCpuHandle = NULL;
|
||||
EFI_CPU_ARCH_PROTOCOL mCpu = {
|
||||
EFI_HANDLE mCpuHandle = NULL;
|
||||
EFI_CPU_ARCH_PROTOCOL mCpu = {
|
||||
CpuFlushCpuDataCache,
|
||||
CpuEnableInterrupt,
|
||||
CpuDisableInterrupt,
|
||||
@ -223,118 +226,30 @@ EFI_CPU_ARCH_PROTOCOL mCpu = {
|
||||
STATIC
|
||||
VOID
|
||||
InitializeDma (
|
||||
IN OUT EFI_CPU_ARCH_PROTOCOL *CpuArchProtocol
|
||||
IN OUT EFI_CPU_ARCH_PROTOCOL *CpuArchProtocol
|
||||
)
|
||||
{
|
||||
CpuArchProtocol->DmaBufferAlignment = ArmCacheWritebackGranule ();
|
||||
}
|
||||
|
||||
/**
|
||||
Map all EfiConventionalMemory regions in the memory map with NX
|
||||
attributes so that allocating or freeing EfiBootServicesData regions
|
||||
does not result in changes to memory permission attributes.
|
||||
|
||||
**/
|
||||
STATIC
|
||||
VOID
|
||||
RemapUnusedMemoryNx (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
UINT64 TestBit;
|
||||
UINTN MemoryMapSize;
|
||||
UINTN MapKey;
|
||||
UINTN DescriptorSize;
|
||||
UINT32 DescriptorVersion;
|
||||
EFI_MEMORY_DESCRIPTOR *MemoryMap;
|
||||
EFI_MEMORY_DESCRIPTOR *MemoryMapEntry;
|
||||
EFI_MEMORY_DESCRIPTOR *MemoryMapEnd;
|
||||
EFI_STATUS Status;
|
||||
|
||||
TestBit = LShiftU64 (1, EfiBootServicesData);
|
||||
if ((PcdGet64 (PcdDxeNxMemoryProtectionPolicy) & TestBit) == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
MemoryMapSize = 0;
|
||||
MemoryMap = NULL;
|
||||
|
||||
Status = gBS->GetMemoryMap (
|
||||
&MemoryMapSize,
|
||||
MemoryMap,
|
||||
&MapKey,
|
||||
&DescriptorSize,
|
||||
&DescriptorVersion
|
||||
);
|
||||
ASSERT (Status == EFI_BUFFER_TOO_SMALL);
|
||||
do {
|
||||
MemoryMap = (EFI_MEMORY_DESCRIPTOR *)AllocatePool (MemoryMapSize);
|
||||
ASSERT (MemoryMap != NULL);
|
||||
Status = gBS->GetMemoryMap (
|
||||
&MemoryMapSize,
|
||||
MemoryMap,
|
||||
&MapKey,
|
||||
&DescriptorSize,
|
||||
&DescriptorVersion
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
FreePool (MemoryMap);
|
||||
}
|
||||
} while (Status == EFI_BUFFER_TOO_SMALL);
|
||||
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
MemoryMapEntry = MemoryMap;
|
||||
MemoryMapEnd = (EFI_MEMORY_DESCRIPTOR *)((UINT8 *)MemoryMap + MemoryMapSize);
|
||||
while ((UINTN)MemoryMapEntry < (UINTN)MemoryMapEnd) {
|
||||
if (MemoryMapEntry->Type == EfiConventionalMemory) {
|
||||
ArmSetMemoryAttributes (
|
||||
MemoryMapEntry->PhysicalStart,
|
||||
EFI_PAGES_TO_SIZE (MemoryMapEntry->NumberOfPages),
|
||||
EFI_MEMORY_XP,
|
||||
EFI_MEMORY_XP
|
||||
);
|
||||
}
|
||||
|
||||
MemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize);
|
||||
}
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
CpuDxeInitialize (
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
IN EFI_SYSTEM_TABLE *SystemTable
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
IN EFI_SYSTEM_TABLE *SystemTable
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_EVENT IdleLoopEvent;
|
||||
EFI_EVENT IdleLoopEvent;
|
||||
|
||||
InitializeExceptions (&mCpu);
|
||||
|
||||
InitializeDma (&mCpu);
|
||||
|
||||
//
|
||||
// Once we install the CPU arch protocol, the DXE core's memory
|
||||
// protection routines will invoke them to manage the permissions of page
|
||||
// allocations as they are created. Given that this includes pages
|
||||
// allocated for page tables by this driver, we must ensure that unused
|
||||
// memory is mapped with the same permissions as boot services data
|
||||
// regions. Otherwise, we may end up with unbounded recursion, due to the
|
||||
// fact that updating permissions on a newly allocated page table may trigger
|
||||
// a block entry split, which triggers a page table allocation, etc etc
|
||||
//
|
||||
if (FeaturePcdGet (PcdRemapUnusedMemoryNx)) {
|
||||
RemapUnusedMemoryNx ();
|
||||
}
|
||||
|
||||
Status = gBS->InstallMultipleProtocolInterfaces (
|
||||
&mCpuHandle,
|
||||
&gEfiCpuArchProtocolGuid,
|
||||
&mCpu,
|
||||
&gEfiMemoryAttributeProtocolGuid,
|
||||
&mMemoryAttribute,
|
||||
NULL
|
||||
);
|
||||
&mCpuHandle,
|
||||
&gEfiCpuArchProtocolGuid, &mCpu,
|
||||
NULL
|
||||
);
|
||||
|
||||
//
|
||||
// Make sure GCD and MMU settings match. This API calls gDS->SetMemorySpaceAttributes ()
|
||||
@ -345,6 +260,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
|
||||
//
|
||||
|
@ -30,11 +30,8 @@
|
||||
#include <Protocol/Cpu.h>
|
||||
#include <Protocol/DebugSupport.h>
|
||||
#include <Protocol/LoadedImage.h>
|
||||
#include <Protocol/MemoryAttribute.h>
|
||||
|
||||
extern BOOLEAN mIsFlushingGCD;
|
||||
|
||||
extern EFI_MEMORY_ATTRIBUTE_PROTOCOL mMemoryAttribute;
|
||||
extern BOOLEAN mIsFlushingGCD;
|
||||
|
||||
/**
|
||||
This function registers and enables the handler specified by InterruptHandler for a processor
|
||||
@ -58,10 +55,11 @@ extern EFI_MEMORY_ATTRIBUTE_PROTOCOL mMemoryAttribute;
|
||||
**/
|
||||
EFI_STATUS
|
||||
RegisterInterruptHandler (
|
||||
IN EFI_EXCEPTION_TYPE InterruptType,
|
||||
IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler
|
||||
IN EFI_EXCEPTION_TYPE InterruptType,
|
||||
IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
This function registers and enables the handler specified by InterruptHandler for a processor
|
||||
interrupt or exception type specified by InterruptType. If InterruptHandler is NULL, then the
|
||||
@ -84,63 +82,65 @@ RegisterInterruptHandler (
|
||||
**/
|
||||
EFI_STATUS
|
||||
RegisterDebuggerInterruptHandler (
|
||||
IN EFI_EXCEPTION_TYPE InterruptType,
|
||||
IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler
|
||||
IN EFI_EXCEPTION_TYPE InterruptType,
|
||||
IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler
|
||||
);
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
CpuSetMemoryAttributes (
|
||||
IN EFI_CPU_ARCH_PROTOCOL *This,
|
||||
IN EFI_PHYSICAL_ADDRESS BaseAddress,
|
||||
IN UINT64 Length,
|
||||
IN UINT64 Attributes
|
||||
IN EFI_CPU_ARCH_PROTOCOL *This,
|
||||
IN EFI_PHYSICAL_ADDRESS BaseAddress,
|
||||
IN UINT64 Length,
|
||||
IN UINT64 Attributes
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
InitializeExceptions (
|
||||
IN EFI_CPU_ARCH_PROTOCOL *Cpu
|
||||
IN EFI_CPU_ARCH_PROTOCOL *Cpu
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
SyncCacheConfig (
|
||||
IN EFI_CPU_ARCH_PROTOCOL *CpuProtocol
|
||||
IN EFI_CPU_ARCH_PROTOCOL *CpuProtocol
|
||||
);
|
||||
|
||||
/**
|
||||
* Publish ARM Processor Data table in UEFI SYSTEM Table.
|
||||
* @param HobStart Pointer to the beginning of the HOB List from PEI.
|
||||
*
|
||||
* Description : This function iterates through HOB list and finds ARM processor Table Entry HOB.
|
||||
* If the ARM processor Table Entry HOB is found, the HOB data is copied to run-time memory
|
||||
* and a pointer is assigned to it in ARM processor table. Then the ARM processor table is
|
||||
* installed in EFI configuration table.
|
||||
**/
|
||||
VOID
|
||||
EFIAPI
|
||||
PublishArmProcessorTable(
|
||||
VOID
|
||||
);
|
||||
|
||||
// The ARM Attributes might be defined on 64-bit (case of the long format description table)
|
||||
UINT64
|
||||
EfiAttributeToArmAttribute (
|
||||
IN UINT64 EfiAttributes
|
||||
IN UINT64 EfiAttributes
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
GetMemoryRegion (
|
||||
IN OUT UINTN *BaseAddress,
|
||||
OUT UINTN *RegionLength,
|
||||
OUT UINTN *RegionAttributes
|
||||
IN OUT UINTN *BaseAddress,
|
||||
OUT UINTN *RegionLength,
|
||||
OUT UINTN *RegionAttributes
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
SetGcdMemorySpaceAttributes (
|
||||
IN EFI_GCD_MEMORY_SPACE_DESCRIPTOR *MemorySpaceMap,
|
||||
IN UINTN NumberOfDescriptors,
|
||||
IN EFI_PHYSICAL_ADDRESS BaseAddress,
|
||||
IN UINT64 Length,
|
||||
IN UINT64 Attributes
|
||||
);
|
||||
|
||||
/**
|
||||
Convert an arch specific set of page attributes into a mask
|
||||
of EFI_MEMORY_xx constants.
|
||||
|
||||
@param PageAttributes The set of page attributes.
|
||||
|
||||
@retval The mask of EFI_MEMORY_xx constants.
|
||||
|
||||
**/
|
||||
UINT64
|
||||
RegionAttributeToGcdAttribute (
|
||||
IN UINTN PageAttributes
|
||||
IN EFI_GCD_MEMORY_SPACE_DESCRIPTOR *MemorySpaceMap,
|
||||
IN UINTN NumberOfDescriptors,
|
||||
IN EFI_PHYSICAL_ADDRESS BaseAddress,
|
||||
IN UINT64 Length,
|
||||
IN UINT64 Attributes
|
||||
);
|
||||
|
||||
#endif // CPU_DXE_H_
|
||||
|
@ -21,9 +21,9 @@
|
||||
[Sources.Common]
|
||||
CpuDxe.c
|
||||
CpuDxe.h
|
||||
CpuMpCore.c
|
||||
CpuMmuCommon.c
|
||||
Exception.c
|
||||
MemoryAttribute.c
|
||||
|
||||
[Sources.ARM]
|
||||
Arm/Mmu.c
|
||||
@ -48,14 +48,12 @@
|
||||
DefaultExceptionHandlerLib
|
||||
DxeServicesTableLib
|
||||
HobLib
|
||||
MemoryAllocationLib
|
||||
PeCoffGetEntryPointLib
|
||||
UefiDriverEntryPoint
|
||||
UefiLib
|
||||
|
||||
[Protocols]
|
||||
gEfiCpuArchProtocolGuid
|
||||
gEfiMemoryAttributeProtocolGuid
|
||||
|
||||
[Guids]
|
||||
gEfiDebugImageInfoTableGuid
|
||||
@ -65,11 +63,9 @@
|
||||
|
||||
[Pcd.common]
|
||||
gArmTokenSpaceGuid.PcdVFPEnabled
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy
|
||||
|
||||
[FeaturePcd.common]
|
||||
gArmTokenSpaceGuid.PcdDebuggerExceptionSupport
|
||||
gArmTokenSpaceGuid.PcdRemapUnusedMemoryNx
|
||||
|
||||
[Depex]
|
||||
gHardwareInterruptProtocolGuid OR gHardwareInterrupt2ProtocolGuid
|
||||
|
@ -29,36 +29,33 @@
|
||||
**/
|
||||
EFI_STATUS
|
||||
SearchGcdMemorySpaces (
|
||||
IN EFI_GCD_MEMORY_SPACE_DESCRIPTOR *MemorySpaceMap,
|
||||
IN UINTN NumberOfDescriptors,
|
||||
IN EFI_PHYSICAL_ADDRESS BaseAddress,
|
||||
IN UINT64 Length,
|
||||
OUT UINTN *StartIndex,
|
||||
OUT UINTN *EndIndex
|
||||
IN EFI_GCD_MEMORY_SPACE_DESCRIPTOR *MemorySpaceMap,
|
||||
IN UINTN NumberOfDescriptors,
|
||||
IN EFI_PHYSICAL_ADDRESS BaseAddress,
|
||||
IN UINT64 Length,
|
||||
OUT UINTN *StartIndex,
|
||||
OUT UINTN *EndIndex
|
||||
)
|
||||
{
|
||||
UINTN Index;
|
||||
UINTN Index;
|
||||
|
||||
*StartIndex = 0;
|
||||
*EndIndex = 0;
|
||||
for (Index = 0; Index < NumberOfDescriptors; Index++) {
|
||||
if ((BaseAddress >= MemorySpaceMap[Index].BaseAddress) &&
|
||||
(BaseAddress < (MemorySpaceMap[Index].BaseAddress + MemorySpaceMap[Index].Length)))
|
||||
{
|
||||
(BaseAddress < (MemorySpaceMap[Index].BaseAddress + MemorySpaceMap[Index].Length))) {
|
||||
*StartIndex = Index;
|
||||
}
|
||||
|
||||
if (((BaseAddress + Length - 1) >= MemorySpaceMap[Index].BaseAddress) &&
|
||||
((BaseAddress + Length - 1) < (MemorySpaceMap[Index].BaseAddress + MemorySpaceMap[Index].Length)))
|
||||
{
|
||||
((BaseAddress + Length - 1) < (MemorySpaceMap[Index].BaseAddress + MemorySpaceMap[Index].Length))) {
|
||||
*EndIndex = Index;
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Sets the attributes for a specified range in Gcd Memory Space Map.
|
||||
|
||||
@ -77,11 +74,11 @@ SearchGcdMemorySpaces (
|
||||
**/
|
||||
EFI_STATUS
|
||||
SetGcdMemorySpaceAttributes (
|
||||
IN EFI_GCD_MEMORY_SPACE_DESCRIPTOR *MemorySpaceMap,
|
||||
IN UINTN NumberOfDescriptors,
|
||||
IN EFI_PHYSICAL_ADDRESS BaseAddress,
|
||||
IN UINT64 Length,
|
||||
IN UINT64 Attributes
|
||||
IN EFI_GCD_MEMORY_SPACE_DESCRIPTOR *MemorySpaceMap,
|
||||
IN UINTN NumberOfDescriptors,
|
||||
IN EFI_PHYSICAL_ADDRESS BaseAddress,
|
||||
IN UINT64 Length,
|
||||
IN UINT64 Attributes
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
@ -91,21 +88,14 @@ SetGcdMemorySpaceAttributes (
|
||||
EFI_PHYSICAL_ADDRESS RegionStart;
|
||||
UINT64 RegionLength;
|
||||
|
||||
DEBUG ((
|
||||
DEBUG_GCD,
|
||||
"SetGcdMemorySpaceAttributes[0x%lX; 0x%lX] = 0x%lX\n",
|
||||
BaseAddress,
|
||||
BaseAddress + Length,
|
||||
Attributes
|
||||
));
|
||||
DEBUG ((DEBUG_GCD, "SetGcdMemorySpaceAttributes[0x%lX; 0x%lX] = 0x%lX\n",
|
||||
BaseAddress, BaseAddress + Length, Attributes));
|
||||
|
||||
// We do not support a smaller granularity than 4KB on ARM Architecture
|
||||
if ((Length & EFI_PAGE_MASK) != 0) {
|
||||
DEBUG ((
|
||||
DEBUG_WARN,
|
||||
"Warning: We do not support smaller granularity than 4KB on ARM Architecture (passed length: 0x%lX).\n",
|
||||
Length
|
||||
));
|
||||
DEBUG ((DEBUG_WARN,
|
||||
"Warning: We do not support smaller granularity than 4KB on ARM Architecture (passed length: 0x%lX).\n",
|
||||
Length));
|
||||
}
|
||||
|
||||
//
|
||||
@ -130,7 +120,6 @@ SetGcdMemorySpaceAttributes (
|
||||
if (MemorySpaceMap[Index].GcdMemoryType == EfiGcdMemoryTypeNonExistent) {
|
||||
continue;
|
||||
}
|
||||
|
||||
//
|
||||
// Calculate the start and end address of the overlapping range
|
||||
//
|
||||
@ -139,13 +128,11 @@ SetGcdMemorySpaceAttributes (
|
||||
} else {
|
||||
RegionStart = MemorySpaceMap[Index].BaseAddress;
|
||||
}
|
||||
|
||||
if ((BaseAddress + Length - 1) < (MemorySpaceMap[Index].BaseAddress + MemorySpaceMap[Index].Length)) {
|
||||
RegionLength = BaseAddress + Length - RegionStart;
|
||||
} else {
|
||||
RegionLength = MemorySpaceMap[Index].BaseAddress + MemorySpaceMap[Index].Length - RegionStart;
|
||||
}
|
||||
|
||||
//
|
||||
// Set memory attributes according to MTRR attribute and the original attribute of descriptor
|
||||
//
|
||||
@ -183,10 +170,10 @@ SetGcdMemorySpaceAttributes (
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
CpuSetMemoryAttributes (
|
||||
IN EFI_CPU_ARCH_PROTOCOL *This,
|
||||
IN EFI_PHYSICAL_ADDRESS BaseAddress,
|
||||
IN UINT64 Length,
|
||||
IN UINT64 EfiAttributes
|
||||
IN EFI_CPU_ARCH_PROTOCOL *This,
|
||||
IN EFI_PHYSICAL_ADDRESS BaseAddress,
|
||||
IN UINT64 Length,
|
||||
IN UINT64 EfiAttributes
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
@ -210,14 +197,14 @@ CpuSetMemoryAttributes (
|
||||
|
||||
// Get the region starting from 'BaseAddress' and its 'Attribute'
|
||||
RegionBaseAddress = BaseAddress;
|
||||
Status = GetMemoryRegion (&RegionBaseAddress, &RegionLength, &RegionArmAttributes);
|
||||
Status = GetMemoryRegion (&RegionBaseAddress, &RegionLength, &RegionArmAttributes);
|
||||
|
||||
// Data & Instruction Caches are flushed when we set new memory attributes.
|
||||
// So, we only set the attributes if the new region is different.
|
||||
if (EFI_ERROR (Status) || (RegionArmAttributes != ArmAttributes) ||
|
||||
((BaseAddress + Length) > (RegionBaseAddress + RegionLength)))
|
||||
{
|
||||
return ArmSetMemoryAttributes (BaseAddress, Length, EfiAttributes, 0);
|
||||
return ArmSetMemoryAttributes (BaseAddress, Length, EfiAttributes);
|
||||
} else {
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
97
ArmPkg/Drivers/CpuDxe/CpuMpCore.c
Normal file
97
ArmPkg/Drivers/CpuDxe/CpuMpCore.c
Normal file
@ -0,0 +1,97 @@
|
||||
/** @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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -13,23 +13,23 @@
|
||||
|
||||
EFI_STATUS
|
||||
InitializeExceptions (
|
||||
IN EFI_CPU_ARCH_PROTOCOL *Cpu
|
||||
IN EFI_CPU_ARCH_PROTOCOL *Cpu
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_VECTOR_HANDOFF_INFO *VectorInfoList;
|
||||
EFI_VECTOR_HANDOFF_INFO *VectorInfo;
|
||||
BOOLEAN IrqEnabled;
|
||||
BOOLEAN FiqEnabled;
|
||||
EFI_STATUS Status;
|
||||
EFI_VECTOR_HANDOFF_INFO *VectorInfoList;
|
||||
EFI_VECTOR_HANDOFF_INFO *VectorInfo;
|
||||
BOOLEAN IrqEnabled;
|
||||
BOOLEAN FiqEnabled;
|
||||
|
||||
VectorInfo = (EFI_VECTOR_HANDOFF_INFO *)NULL;
|
||||
Status = EfiGetSystemConfigurationTable (&gEfiVectorHandoffTableGuid, (VOID **)&VectorInfoList);
|
||||
if ((Status == EFI_SUCCESS) && (VectorInfoList != NULL)) {
|
||||
Status = EfiGetSystemConfigurationTable(&gEfiVectorHandoffTableGuid, (VOID **)&VectorInfoList);
|
||||
if (Status == EFI_SUCCESS && VectorInfoList != NULL) {
|
||||
VectorInfo = VectorInfoList;
|
||||
}
|
||||
|
||||
// initialize the CpuExceptionHandlerLib so we take over the exception vector table from the DXE Core
|
||||
InitializeCpuExceptionHandlers (VectorInfo);
|
||||
InitializeCpuExceptionHandlers(VectorInfo);
|
||||
|
||||
Status = EFI_SUCCESS;
|
||||
|
||||
@ -64,7 +64,7 @@ InitializeExceptions (
|
||||
//
|
||||
DEBUG_CODE (
|
||||
ArmEnableAsynchronousAbort ();
|
||||
);
|
||||
);
|
||||
|
||||
return Status;
|
||||
}
|
||||
@ -90,11 +90,11 @@ previously installed.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
RegisterInterruptHandler (
|
||||
IN EFI_EXCEPTION_TYPE InterruptType,
|
||||
IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler
|
||||
RegisterInterruptHandler(
|
||||
IN EFI_EXCEPTION_TYPE InterruptType,
|
||||
IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler
|
||||
)
|
||||
{
|
||||
// pass down to CpuExceptionHandlerLib
|
||||
return (EFI_STATUS)RegisterCpuInterruptHandler (InterruptType, InterruptHandler);
|
||||
return (EFI_STATUS)RegisterCpuInterruptHandler(InterruptType, InterruptHandler);
|
||||
}
|
||||
|
@ -1,273 +0,0 @@
|
||||
/** @file
|
||||
|
||||
Copyright (c) 2023, Google LLC. All rights reserved.
|
||||
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
**/
|
||||
|
||||
#include "CpuDxe.h"
|
||||
|
||||
/**
|
||||
Check whether the provided memory range is covered by a single entry of type
|
||||
EfiGcdSystemMemory in the GCD memory map.
|
||||
|
||||
@param BaseAddress The physical address that is the start address of
|
||||
a memory region.
|
||||
@param Length The size in bytes of the memory region.
|
||||
|
||||
@return Whether the region is system memory or not.
|
||||
**/
|
||||
STATIC
|
||||
BOOLEAN
|
||||
RegionIsSystemMemory (
|
||||
IN EFI_PHYSICAL_ADDRESS BaseAddress,
|
||||
IN UINT64 Length
|
||||
)
|
||||
{
|
||||
EFI_GCD_MEMORY_SPACE_DESCRIPTOR GcdDescriptor;
|
||||
EFI_PHYSICAL_ADDRESS GcdEndAddress;
|
||||
EFI_STATUS Status;
|
||||
|
||||
Status = gDS->GetMemorySpaceDescriptor (BaseAddress, &GcdDescriptor);
|
||||
if (EFI_ERROR (Status) ||
|
||||
(GcdDescriptor.GcdMemoryType != EfiGcdMemoryTypeSystemMemory))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
GcdEndAddress = GcdDescriptor.BaseAddress + GcdDescriptor.Length;
|
||||
|
||||
//
|
||||
// Return TRUE if the GCD descriptor covers the range entirely
|
||||
//
|
||||
return GcdEndAddress >= (BaseAddress + Length);
|
||||
}
|
||||
|
||||
/**
|
||||
This function retrieves the attributes of the memory region specified by
|
||||
BaseAddress and Length. If different attributes are obtained from different
|
||||
parts of the memory region, EFI_NO_MAPPING will be returned.
|
||||
|
||||
@param This The EFI_MEMORY_ATTRIBUTE_PROTOCOL instance.
|
||||
@param BaseAddress The physical address that is the start address of
|
||||
a memory region.
|
||||
@param Length The size in bytes of the memory region.
|
||||
@param Attributes Pointer to attributes returned.
|
||||
|
||||
@retval EFI_SUCCESS The attributes got for the memory region.
|
||||
@retval EFI_INVALID_PARAMETER Length is zero.
|
||||
Attributes is NULL.
|
||||
@retval EFI_NO_MAPPING Attributes are not consistent cross the memory
|
||||
region.
|
||||
@retval EFI_UNSUPPORTED The processor does not support one or more
|
||||
bytes of the memory resource range specified
|
||||
by BaseAddress and Length.
|
||||
|
||||
**/
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
GetMemoryAttributes (
|
||||
IN EFI_MEMORY_ATTRIBUTE_PROTOCOL *This,
|
||||
IN EFI_PHYSICAL_ADDRESS BaseAddress,
|
||||
IN UINT64 Length,
|
||||
OUT UINT64 *Attributes
|
||||
)
|
||||
{
|
||||
UINTN RegionAddress;
|
||||
UINTN RegionLength;
|
||||
UINTN RegionAttributes;
|
||||
UINTN Union;
|
||||
UINTN Intersection;
|
||||
EFI_STATUS Status;
|
||||
|
||||
if ((Length == 0) || (Attributes == NULL)) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (!RegionIsSystemMemory (BaseAddress, Length)) {
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
DEBUG ((
|
||||
DEBUG_VERBOSE,
|
||||
"%a: BaseAddress == 0x%lx, Length == 0x%lx\n",
|
||||
__func__,
|
||||
BaseAddress,
|
||||
Length
|
||||
));
|
||||
|
||||
Union = 0;
|
||||
Intersection = MAX_UINTN;
|
||||
|
||||
for (RegionAddress = (UINTN)BaseAddress;
|
||||
RegionAddress < (UINTN)(BaseAddress + Length);
|
||||
RegionAddress += RegionLength)
|
||||
{
|
||||
Status = GetMemoryRegion (
|
||||
&RegionAddress,
|
||||
&RegionLength,
|
||||
&RegionAttributes
|
||||
);
|
||||
|
||||
DEBUG ((
|
||||
DEBUG_VERBOSE,
|
||||
"%a: RegionAddress == 0x%lx, RegionLength == 0x%lx, RegionAttributes == 0x%lx\n",
|
||||
__func__,
|
||||
(UINT64)RegionAddress,
|
||||
(UINT64)RegionLength,
|
||||
(UINT64)RegionAttributes
|
||||
));
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
return EFI_NO_MAPPING;
|
||||
}
|
||||
|
||||
Union |= RegionAttributes;
|
||||
Intersection &= RegionAttributes;
|
||||
}
|
||||
|
||||
DEBUG ((
|
||||
DEBUG_VERBOSE,
|
||||
"%a: Union == %lx, Intersection == %lx\n",
|
||||
__func__,
|
||||
(UINT64)Union,
|
||||
(UINT64)Intersection
|
||||
));
|
||||
|
||||
if (Union != Intersection) {
|
||||
return EFI_NO_MAPPING;
|
||||
}
|
||||
|
||||
*Attributes = RegionAttributeToGcdAttribute (Union);
|
||||
*Attributes &= EFI_MEMORY_RP | EFI_MEMORY_RO | EFI_MEMORY_XP;
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
This function set given attributes of the memory region specified by
|
||||
BaseAddress and Length.
|
||||
|
||||
The valid Attributes is EFI_MEMORY_RP, EFI_MEMORY_XP, and EFI_MEMORY_RO.
|
||||
|
||||
@param This The EFI_MEMORY_ATTRIBUTE_PROTOCOL instance.
|
||||
@param BaseAddress The physical address that is the start address of
|
||||
a memory region.
|
||||
@param Length The size in bytes of the memory region.
|
||||
@param Attributes The bit mask of attributes to set for the memory
|
||||
region.
|
||||
|
||||
@retval EFI_SUCCESS The attributes were set for the memory region.
|
||||
@retval EFI_INVALID_PARAMETER Length is zero.
|
||||
Attributes specified an illegal combination of
|
||||
attributes that cannot be set together.
|
||||
@retval EFI_UNSUPPORTED The processor does not support one or more
|
||||
bytes of the memory resource range specified
|
||||
by BaseAddress and Length.
|
||||
The bit mask of attributes is not supported for
|
||||
the memory resource range specified by
|
||||
BaseAddress and Length.
|
||||
@retval EFI_OUT_OF_RESOURCES Requested attributes cannot be applied due to
|
||||
lack of system resources.
|
||||
@retval EFI_ACCESS_DENIED Attributes for the requested memory region are
|
||||
controlled by system firmware and cannot be
|
||||
updated via the protocol.
|
||||
|
||||
**/
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
SetMemoryAttributes (
|
||||
IN EFI_MEMORY_ATTRIBUTE_PROTOCOL *This,
|
||||
IN EFI_PHYSICAL_ADDRESS BaseAddress,
|
||||
IN UINT64 Length,
|
||||
IN UINT64 Attributes
|
||||
)
|
||||
{
|
||||
DEBUG ((
|
||||
DEBUG_INFO,
|
||||
"%a: BaseAddress == 0x%lx, Length == 0x%lx, Attributes == 0x%lx\n",
|
||||
__func__,
|
||||
(UINTN)BaseAddress,
|
||||
(UINTN)Length,
|
||||
(UINTN)Attributes
|
||||
));
|
||||
|
||||
if ((Length == 0) ||
|
||||
((Attributes & ~(EFI_MEMORY_RO | EFI_MEMORY_RP | EFI_MEMORY_XP)) != 0))
|
||||
{
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (!RegionIsSystemMemory (BaseAddress, Length)) {
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
return ArmSetMemoryAttributes (BaseAddress, Length, Attributes, Attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
This function clears given attributes of the memory region specified by
|
||||
BaseAddress and Length.
|
||||
|
||||
The valid Attributes is EFI_MEMORY_RP, EFI_MEMORY_XP, and EFI_MEMORY_RO.
|
||||
|
||||
@param This The EFI_MEMORY_ATTRIBUTE_PROTOCOL instance.
|
||||
@param BaseAddress The physical address that is the start address of
|
||||
a memory region.
|
||||
@param Length The size in bytes of the memory region.
|
||||
@param Attributes The bit mask of attributes to clear for the memory
|
||||
region.
|
||||
|
||||
@retval EFI_SUCCESS The attributes were cleared for the memory region.
|
||||
@retval EFI_INVALID_PARAMETER Length is zero.
|
||||
Attributes specified an illegal combination of
|
||||
attributes that cannot be cleared together.
|
||||
@retval EFI_UNSUPPORTED The processor does not support one or more
|
||||
bytes of the memory resource range specified
|
||||
by BaseAddress and Length.
|
||||
The bit mask of attributes is not supported for
|
||||
the memory resource range specified by
|
||||
BaseAddress and Length.
|
||||
@retval EFI_OUT_OF_RESOURCES Requested attributes cannot be applied due to
|
||||
lack of system resources.
|
||||
@retval EFI_ACCESS_DENIED Attributes for the requested memory region are
|
||||
controlled by system firmware and cannot be
|
||||
updated via the protocol.
|
||||
|
||||
**/
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
ClearMemoryAttributes (
|
||||
IN EFI_MEMORY_ATTRIBUTE_PROTOCOL *This,
|
||||
IN EFI_PHYSICAL_ADDRESS BaseAddress,
|
||||
IN UINT64 Length,
|
||||
IN UINT64 Attributes
|
||||
)
|
||||
{
|
||||
DEBUG ((
|
||||
DEBUG_INFO,
|
||||
"%a: BaseAddress == 0x%lx, Length == 0x%lx, Attributes == 0x%lx\n",
|
||||
__func__,
|
||||
(UINTN)BaseAddress,
|
||||
(UINTN)Length,
|
||||
(UINTN)Attributes
|
||||
));
|
||||
|
||||
if ((Length == 0) ||
|
||||
((Attributes & ~(EFI_MEMORY_RO | EFI_MEMORY_RP | EFI_MEMORY_XP)) != 0))
|
||||
{
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (!RegionIsSystemMemory (BaseAddress, Length)) {
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
return ArmSetMemoryAttributes (BaseAddress, Length, 0, Attributes);
|
||||
}
|
||||
|
||||
EFI_MEMORY_ATTRIBUTE_PROTOCOL mMemoryAttribute = {
|
||||
GetMemoryAttributes,
|
||||
SetMemoryAttributes,
|
||||
ClearMemoryAttributes
|
||||
};
|
@ -3,7 +3,6 @@
|
||||
Copyright (c) 2006, Intel Corporation. All rights reserved.<BR>
|
||||
Copyright (c) 2011 Hewlett Packard Corporation. All rights reserved.<BR>
|
||||
Copyright (c) 2011-2013, ARM Limited. All rights reserved.<BR>
|
||||
Copyright (c) 2023, Google, LLC. All rights reserved.<BR>
|
||||
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
@ -17,6 +16,8 @@ Abstract:
|
||||
|
||||
**/
|
||||
|
||||
|
||||
|
||||
//
|
||||
// The package level header files this module uses
|
||||
//
|
||||
@ -25,7 +26,6 @@ Abstract:
|
||||
// The protocols, PPI and GUID definitions for this module
|
||||
//
|
||||
#include <Ppi/ArmMpCoreInfo.h>
|
||||
#include <Ppi/MemoryAttribute.h>
|
||||
|
||||
//
|
||||
// The Library classes this module consumes
|
||||
@ -36,77 +36,6 @@ Abstract:
|
||||
#include <Library/PcdLib.h>
|
||||
#include <Library/HobLib.h>
|
||||
#include <Library/ArmLib.h>
|
||||
#include <Library/ArmMmuLib.h>
|
||||
|
||||
/**
|
||||
Set the requested memory permission attributes on a region of memory.
|
||||
|
||||
BaseAddress and Length must be aligned to EFI_PAGE_SIZE.
|
||||
|
||||
Attributes must contain a combination of EFI_MEMORY_RP, EFI_MEMORY_RO and
|
||||
EFI_MEMORY_XP, and specifies the attributes that must be set for the
|
||||
region in question. Attributes that are omitted will be cleared from the
|
||||
region only if they are set in AttributeMask.
|
||||
|
||||
AttributeMask must contain a combination of EFI_MEMORY_RP, EFI_MEMORY_RO and
|
||||
EFI_MEMORY_XP, and specifies the attributes that the call will operate on.
|
||||
AttributeMask must not be 0x0, and must contain at least the bits set in
|
||||
Attributes.
|
||||
|
||||
@param[in] This The protocol instance pointer.
|
||||
@param[in] BaseAddress The physical address that is the start address
|
||||
of a memory region.
|
||||
@param[in] Length The size in bytes of the memory region.
|
||||
@param[in] Attributes Memory attributes to set or clear.
|
||||
@param[in] AttributeMask Mask of memory attributes to operate on.
|
||||
|
||||
@retval EFI_SUCCESS The attributes were set for the memory region.
|
||||
@retval EFI_INVALID_PARAMETER Length is zero.
|
||||
AttributeMask is zero.
|
||||
AttributeMask lacks bits set in Attributes.
|
||||
BaseAddress or Length is not suitably aligned.
|
||||
@retval EFI_UNSUPPORTED The processor does not support one or more
|
||||
bytes of the memory resource range specified
|
||||
by BaseAddress and Length.
|
||||
The bit mask of attributes is not supported for
|
||||
the memory resource range specified by
|
||||
BaseAddress and Length.
|
||||
@retval EFI_OUT_OF_RESOURCES Requested attributes cannot be applied due to
|
||||
lack of system resources.
|
||||
|
||||
**/
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
SetMemoryPermissions (
|
||||
IN EDKII_MEMORY_ATTRIBUTE_PPI *This,
|
||||
IN EFI_PHYSICAL_ADDRESS BaseAddress,
|
||||
IN UINT64 Length,
|
||||
IN UINT64 Attributes,
|
||||
IN UINT64 AttributeMask
|
||||
)
|
||||
{
|
||||
if ((Length == 0) ||
|
||||
(AttributeMask == 0) ||
|
||||
((AttributeMask & (EFI_MEMORY_RP | EFI_MEMORY_RO | EFI_MEMORY_XP)) == 0) ||
|
||||
((Attributes & ~AttributeMask) != 0) ||
|
||||
(((BaseAddress | Length) & EFI_PAGE_MASK) != 0))
|
||||
{
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
return ArmSetMemoryAttributes (BaseAddress, Length, Attributes, AttributeMask);
|
||||
}
|
||||
|
||||
STATIC CONST EDKII_MEMORY_ATTRIBUTE_PPI mMemoryAttributePpi = {
|
||||
SetMemoryPermissions
|
||||
};
|
||||
|
||||
STATIC CONST EFI_PEI_PPI_DESCRIPTOR mMemoryAttributePpiDesc = {
|
||||
(EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
|
||||
&gEdkiiMemoryAttributePpiGuid,
|
||||
(VOID *)&mMemoryAttributePpi
|
||||
};
|
||||
|
||||
/*++
|
||||
|
||||
@ -129,10 +58,10 @@ InitializeCpuPeim (
|
||||
IN CONST EFI_PEI_SERVICES **PeiServices
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
ARM_MP_CORE_INFO_PPI *ArmMpCoreInfoPpi;
|
||||
UINTN ArmCoreCount;
|
||||
ARM_CORE_INFO *ArmCoreInfoTable;
|
||||
EFI_STATUS Status;
|
||||
ARM_MP_CORE_INFO_PPI *ArmMpCoreInfoPpi;
|
||||
UINTN ArmCoreCount;
|
||||
ARM_CORE_INFO *ArmCoreInfoTable;
|
||||
|
||||
// Enable program flow prediction, if supported.
|
||||
ArmEnableBranchPrediction ();
|
||||
@ -141,19 +70,16 @@ InitializeCpuPeim (
|
||||
BuildCpuHob (ArmGetPhysicalAddressBits (), PcdGet8 (PcdPrePiCpuIoSize));
|
||||
|
||||
// Only MP Core platform need to produce gArmMpCoreInfoPpiGuid
|
||||
Status = PeiServicesLocatePpi (&gArmMpCoreInfoPpiGuid, 0, NULL, (VOID **)&ArmMpCoreInfoPpi);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
Status = PeiServicesLocatePpi (&gArmMpCoreInfoPpiGuid, 0, NULL, (VOID**)&ArmMpCoreInfoPpi);
|
||||
if (!EFI_ERROR(Status)) {
|
||||
// Build the MP Core Info Table
|
||||
ArmCoreCount = 0;
|
||||
Status = ArmMpCoreInfoPpi->GetMpCoreInfo (&ArmCoreCount, &ArmCoreInfoTable);
|
||||
if (!EFI_ERROR (Status) && (ArmCoreCount > 0)) {
|
||||
Status = ArmMpCoreInfoPpi->GetMpCoreInfo (&ArmCoreCount, &ArmCoreInfoTable);
|
||||
if (!EFI_ERROR(Status) && (ArmCoreCount > 0)) {
|
||||
// Build MPCore Info HOB
|
||||
BuildGuidDataHob (&gArmMpCoreInfoGuid, ArmCoreInfoTable, sizeof (ARM_CORE_INFO) * ArmCoreCount);
|
||||
}
|
||||
}
|
||||
|
||||
Status = PeiServicesInstallPpi (&mMemoryAttributePpiDesc);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
@ -3,7 +3,6 @@
|
||||
#
|
||||
# This module provides platform specific function to detect boot mode.
|
||||
# Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
|
||||
# Copyright (c) 2023, Google, LLC. All rights reserved.<BR>
|
||||
#
|
||||
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
#
|
||||
@ -29,7 +28,6 @@
|
||||
CpuPei.c
|
||||
|
||||
[Packages]
|
||||
MdeModulePkg/MdeModulePkg.dec
|
||||
MdePkg/MdePkg.dec
|
||||
EmbeddedPkg/EmbeddedPkg.dec
|
||||
ArmPkg/ArmPkg.dec
|
||||
@ -39,11 +37,9 @@
|
||||
DebugLib
|
||||
HobLib
|
||||
ArmLib
|
||||
ArmMmuLib
|
||||
|
||||
[Ppis]
|
||||
gArmMpCoreInfoPpiGuid
|
||||
gEdkiiMemoryAttributePpiGuid
|
||||
|
||||
[Guids]
|
||||
gArmMpCoreInfoGuid
|
||||
|
@ -1,34 +1,24 @@
|
||||
/** @file
|
||||
*
|
||||
* Copyright (c) 2023, Ampere Computing LLC. All rights reserved.<BR>
|
||||
* Copyright (c) 2013-2017, ARM Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
*
|
||||
* @par Reference(s):
|
||||
* - Generic Watchdog specification in Arm Base System Architecture 1.0C:
|
||||
* https://developer.arm.com/documentation/den0094/c/
|
||||
**/
|
||||
|
||||
#ifndef GENERIC_WATCHDOG_H_
|
||||
#define GENERIC_WATCHDOG_H_
|
||||
|
||||
// Refresh Frame:
|
||||
#define GENERIC_WDOG_REFRESH_REG ((UINTN)FixedPcdGet64 (PcdGenericWatchdogRefreshBase) + 0x000)
|
||||
#define GENERIC_WDOG_REFRESH_REG ((UINTN)FixedPcdGet64 (PcdGenericWatchdogRefreshBase) + 0x000)
|
||||
|
||||
// Control Frame:
|
||||
#define GENERIC_WDOG_CONTROL_STATUS_REG ((UINTN)FixedPcdGet64 (PcdGenericWatchdogControlBase) + 0x000)
|
||||
#define GENERIC_WDOG_OFFSET_REG_LOW ((UINTN)FixedPcdGet64 (PcdGenericWatchdogControlBase) + 0x008)
|
||||
#define GENERIC_WDOG_OFFSET_REG_HIGH ((UINTN)FixedPcdGet64 (PcdGenericWatchdogControlBase) + 0x00C)
|
||||
#define GENERIC_WDOG_COMPARE_VALUE_REG_LOW ((UINTN)FixedPcdGet64 (PcdGenericWatchdogControlBase) + 0x010)
|
||||
#define GENERIC_WDOG_COMPARE_VALUE_REG_HIGH ((UINTN)FixedPcdGet64 (PcdGenericWatchdogControlBase) + 0x014)
|
||||
#define GENERIC_WDOG_IID_REG ((UINTN)FixedPcdGet64 (PcdGenericWatchdogControlBase) + 0xFCC)
|
||||
#define GENERIC_WDOG_CONTROL_STATUS_REG ((UINTN)FixedPcdGet64 (PcdGenericWatchdogControlBase) + 0x000)
|
||||
#define GENERIC_WDOG_OFFSET_REG ((UINTN)FixedPcdGet64 (PcdGenericWatchdogControlBase) + 0x008)
|
||||
#define GENERIC_WDOG_COMPARE_VALUE_REG_LOW ((UINTN)FixedPcdGet64 (PcdGenericWatchdogControlBase) + 0x010)
|
||||
#define GENERIC_WDOG_COMPARE_VALUE_REG_HIGH ((UINTN)FixedPcdGet64 (PcdGenericWatchdogControlBase) + 0x014)
|
||||
|
||||
// Values of bit 0 of the Control/Status Register
|
||||
#define GENERIC_WDOG_ENABLED 1
|
||||
#define GENERIC_WDOG_DISABLED 0
|
||||
#define GENERIC_WDOG_ENABLED 1
|
||||
#define GENERIC_WDOG_DISABLED 0
|
||||
|
||||
#define GENERIC_WDOG_IID_ARCH_REV_SHIFT 16
|
||||
#define GENERIC_WDOG_IID_ARCH_REV_MASK 0xF
|
||||
|
||||
#endif // GENERIC_WATCHDOG_H_
|
||||
#endif // GENERIC_WATCHDOG_H_
|
||||
|
@ -1,6 +1,5 @@
|
||||
/** @file
|
||||
*
|
||||
* Copyright (c) 2023, Ampere Computing LLC. All rights reserved.<BR>
|
||||
* Copyright (c) 2013-2018, ARM Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
@ -26,60 +25,26 @@
|
||||
|
||||
/* The number of 100ns periods (the unit of time passed to these functions)
|
||||
in a second */
|
||||
#define TIME_UNITS_PER_SECOND 10000000
|
||||
#define TIME_UNITS_PER_SECOND 10000000
|
||||
|
||||
// Tick frequency of the generic timer basis of the generic watchdog.
|
||||
STATIC UINTN mTimerFrequencyHz = 0;
|
||||
|
||||
/* In cases where the compare register was set manually, information about
|
||||
how long the watchdog was asked to wait cannot be retrieved from hardware.
|
||||
It is therefore stored here. 0 means the timer is not running. */
|
||||
STATIC UINT64 mTimerPeriod = 0;
|
||||
STATIC UINT64 mNumTimerTicks = 0;
|
||||
|
||||
/* disables watchdog interaction after Exit Boot Services */
|
||||
STATIC BOOLEAN mExitedBootServices = FALSE;
|
||||
|
||||
#define MAX_UINT48 0xFFFFFFFFFFFFULL
|
||||
|
||||
STATIC EFI_HARDWARE_INTERRUPT2_PROTOCOL *mInterruptProtocol;
|
||||
STATIC EFI_WATCHDOG_TIMER_NOTIFY mWatchdogNotify;
|
||||
STATIC EFI_EVENT mEfiExitBootServicesEvent;
|
||||
|
||||
/**
|
||||
This function returns the maximum watchdog offset register value.
|
||||
|
||||
@retval MAX_UINT32 The watchdog offset register holds a 32-bit value.
|
||||
@retval MAX_UINT48 The watchdog offset register holds a 48-bit value.
|
||||
**/
|
||||
STATIC
|
||||
UINT64
|
||||
GetMaxWatchdogOffsetRegisterValue (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
UINT64 MaxWatchdogOffsetValue;
|
||||
UINT32 WatchdogIId;
|
||||
UINT8 WatchdogArchRevision;
|
||||
|
||||
WatchdogIId = MmioRead32 (GENERIC_WDOG_IID_REG);
|
||||
WatchdogArchRevision = (WatchdogIId >> GENERIC_WDOG_IID_ARCH_REV_SHIFT) & GENERIC_WDOG_IID_ARCH_REV_MASK;
|
||||
|
||||
if (WatchdogArchRevision == 0) {
|
||||
MaxWatchdogOffsetValue = MAX_UINT32;
|
||||
} else {
|
||||
MaxWatchdogOffsetValue = MAX_UINT48;
|
||||
}
|
||||
|
||||
return MaxWatchdogOffsetValue;
|
||||
}
|
||||
STATIC EFI_HARDWARE_INTERRUPT2_PROTOCOL *mInterruptProtocol;
|
||||
STATIC EFI_WATCHDOG_TIMER_NOTIFY mWatchdogNotify;
|
||||
|
||||
STATIC
|
||||
VOID
|
||||
WatchdogWriteOffsetRegister (
|
||||
UINT64 Value
|
||||
UINT32 Value
|
||||
)
|
||||
{
|
||||
MmioWrite32 (GENERIC_WDOG_OFFSET_REG_LOW, Value & MAX_UINT32);
|
||||
if (GetMaxWatchdogOffsetRegisterValue () == MAX_UINT48) {
|
||||
MmioWrite32 (GENERIC_WDOG_OFFSET_REG_HIGH, (Value >> 32) & MAX_UINT16);
|
||||
}
|
||||
MmioWrite32 (GENERIC_WDOG_OFFSET_REG, Value);
|
||||
}
|
||||
|
||||
STATIC
|
||||
@ -122,8 +87,7 @@ WatchdogExitBootServicesEvent (
|
||||
)
|
||||
{
|
||||
WatchdogDisable ();
|
||||
mTimerPeriod = 0;
|
||||
mExitedBootServices = TRUE;
|
||||
mNumTimerTicks = 0;
|
||||
}
|
||||
|
||||
/* This function is called when the watchdog's first signal (WS0) goes high.
|
||||
@ -133,11 +97,12 @@ STATIC
|
||||
VOID
|
||||
EFIAPI
|
||||
WatchdogInterruptHandler (
|
||||
IN HARDWARE_INTERRUPT_SOURCE Source,
|
||||
IN EFI_SYSTEM_CONTEXT SystemContext
|
||||
IN HARDWARE_INTERRUPT_SOURCE Source,
|
||||
IN EFI_SYSTEM_CONTEXT SystemContext
|
||||
)
|
||||
{
|
||||
STATIC CONST CHAR16 ResetString[] = L"The generic watchdog timer ran out.";
|
||||
STATIC CONST CHAR16 ResetString[]= L"The generic watchdog timer ran out.";
|
||||
UINT64 TimerPeriod;
|
||||
|
||||
WatchdogDisable ();
|
||||
|
||||
@ -150,15 +115,12 @@ WatchdogInterruptHandler (
|
||||
// the timer period plus 1.
|
||||
//
|
||||
if (mWatchdogNotify != NULL) {
|
||||
mWatchdogNotify (mTimerPeriod + 1);
|
||||
TimerPeriod = ((TIME_UNITS_PER_SECOND / mTimerFrequencyHz) * mNumTimerTicks);
|
||||
mWatchdogNotify (TimerPeriod + 1);
|
||||
}
|
||||
|
||||
gRT->ResetSystem (
|
||||
EfiResetCold,
|
||||
EFI_TIMEOUT,
|
||||
StrSize (ResetString),
|
||||
(CHAR16 *)ResetString
|
||||
);
|
||||
gRT->ResetSystem (EfiResetCold, EFI_TIMEOUT, StrSize (ResetString),
|
||||
(CHAR16 *)ResetString);
|
||||
|
||||
// If we got here then the reset didn't work
|
||||
ASSERT (FALSE);
|
||||
@ -192,15 +154,15 @@ STATIC
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
WatchdogRegisterHandler (
|
||||
IN EFI_WATCHDOG_TIMER_ARCH_PROTOCOL *This,
|
||||
IN EFI_WATCHDOG_TIMER_NOTIFY NotifyFunction
|
||||
IN EFI_WATCHDOG_TIMER_ARCH_PROTOCOL *This,
|
||||
IN EFI_WATCHDOG_TIMER_NOTIFY NotifyFunction
|
||||
)
|
||||
{
|
||||
if ((mWatchdogNotify == NULL) && (NotifyFunction == NULL)) {
|
||||
if (mWatchdogNotify == NULL && NotifyFunction == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if ((mWatchdogNotify != NULL) && (NotifyFunction != NULL)) {
|
||||
if (mWatchdogNotify != NULL && NotifyFunction != NULL) {
|
||||
return EFI_ALREADY_STARTED;
|
||||
}
|
||||
|
||||
@ -220,59 +182,42 @@ WatchdogRegisterHandler (
|
||||
|
||||
@retval EFI_SUCCESS The watchdog timer has been programmed to fire
|
||||
in TimerPeriod 100ns units.
|
||||
@retval EFI_DEVICE_ERROR Boot Services has been exited but TimerPeriod
|
||||
is not zero.
|
||||
|
||||
**/
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
WatchdogSetTimerPeriod (
|
||||
IN EFI_WATCHDOG_TIMER_ARCH_PROTOCOL *This,
|
||||
IN UINT64 TimerPeriod // In 100ns units
|
||||
IN EFI_WATCHDOG_TIMER_ARCH_PROTOCOL *This,
|
||||
IN UINT64 TimerPeriod // In 100ns units
|
||||
)
|
||||
{
|
||||
UINTN SystemCount;
|
||||
UINT64 MaxWatchdogOffsetValue;
|
||||
UINT64 TimerFrequencyHz;
|
||||
UINT64 NumTimerTicks;
|
||||
UINTN SystemCount;
|
||||
|
||||
// If we've exited Boot Services but TimerPeriod isn't zero, this
|
||||
// indicates that the caller is doing something wrong.
|
||||
if (mExitedBootServices && (TimerPeriod != 0)) {
|
||||
mTimerPeriod = 0;
|
||||
WatchdogDisable ();
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
// If TimerPeriod is 0 this is a request to stop the watchdog.
|
||||
// if TimerPeriod is 0, this is a request to stop the watchdog.
|
||||
if (TimerPeriod == 0) {
|
||||
mTimerPeriod = 0;
|
||||
mNumTimerTicks = 0;
|
||||
WatchdogDisable ();
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
// Work out how many timer ticks will equate to TimerPeriod
|
||||
TimerFrequencyHz = ArmGenericTimerGetTimerFreq ();
|
||||
ASSERT (TimerFrequencyHz != 0);
|
||||
mTimerPeriod = TimerPeriod;
|
||||
NumTimerTicks = (TimerFrequencyHz * TimerPeriod) / TIME_UNITS_PER_SECOND;
|
||||
mNumTimerTicks = (mTimerFrequencyHz * TimerPeriod) / TIME_UNITS_PER_SECOND;
|
||||
|
||||
/* If the number of required ticks is greater than the max the watchdog's
|
||||
offset register (WOR) can hold, we need to manually compute and set
|
||||
the compare register (WCV) */
|
||||
MaxWatchdogOffsetValue = GetMaxWatchdogOffsetRegisterValue ();
|
||||
if (NumTimerTicks > MaxWatchdogOffsetValue) {
|
||||
if (mNumTimerTicks > MAX_UINT32) {
|
||||
/* We need to enable the watchdog *before* writing to the compare register,
|
||||
because enabling the watchdog causes an "explicit refresh", which
|
||||
clobbers the compare register (WCV). In order to make sure this doesn't
|
||||
trigger an interrupt, set the offset to max. */
|
||||
WatchdogWriteOffsetRegister (MaxWatchdogOffsetValue);
|
||||
WatchdogWriteOffsetRegister (MAX_UINT32);
|
||||
WatchdogEnable ();
|
||||
SystemCount = ArmGenericTimerGetSystemCount ();
|
||||
WatchdogWriteCompareRegister (SystemCount + NumTimerTicks);
|
||||
WatchdogWriteCompareRegister (SystemCount + mNumTimerTicks);
|
||||
} else {
|
||||
WatchdogWriteOffsetRegister (NumTimerTicks);
|
||||
WatchdogWriteOffsetRegister ((UINT32)mNumTimerTicks);
|
||||
WatchdogEnable ();
|
||||
}
|
||||
|
||||
@ -299,15 +244,15 @@ STATIC
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
WatchdogGetTimerPeriod (
|
||||
IN EFI_WATCHDOG_TIMER_ARCH_PROTOCOL *This,
|
||||
OUT UINT64 *TimerPeriod
|
||||
IN EFI_WATCHDOG_TIMER_ARCH_PROTOCOL *This,
|
||||
OUT UINT64 *TimerPeriod
|
||||
)
|
||||
{
|
||||
if (TimerPeriod == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
*TimerPeriod = mTimerPeriod;
|
||||
*TimerPeriod = ((TIME_UNITS_PER_SECOND / mTimerFrequencyHz) * mNumTimerTicks);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
@ -344,27 +289,26 @@ WatchdogGetTimerPeriod (
|
||||
Retrieves the period of the timer interrupt in 100ns units.
|
||||
|
||||
**/
|
||||
STATIC EFI_WATCHDOG_TIMER_ARCH_PROTOCOL mWatchdogTimer = {
|
||||
STATIC EFI_WATCHDOG_TIMER_ARCH_PROTOCOL mWatchdogTimer = {
|
||||
WatchdogRegisterHandler,
|
||||
WatchdogSetTimerPeriod,
|
||||
WatchdogGetTimerPeriod
|
||||
};
|
||||
|
||||
STATIC EFI_EVENT mEfiExitBootServicesEvent;
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
GenericWatchdogEntry (
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
IN EFI_SYSTEM_TABLE *SystemTable
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
IN EFI_SYSTEM_TABLE *SystemTable
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_HANDLE Handle;
|
||||
EFI_STATUS Status;
|
||||
EFI_HANDLE Handle;
|
||||
|
||||
Status = gBS->LocateProtocol (
|
||||
&gHardwareInterrupt2ProtocolGuid,
|
||||
NULL,
|
||||
(VOID **)&mInterruptProtocol
|
||||
);
|
||||
Status = gBS->LocateProtocol (&gHardwareInterrupt2ProtocolGuid, NULL,
|
||||
(VOID **)&mInterruptProtocol);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
/* Make sure the Watchdog Timer Architectural Protocol has not been installed
|
||||
@ -372,57 +316,48 @@ GenericWatchdogEntry (
|
||||
This will avoid conflicts with the universal watchdog */
|
||||
ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiWatchdogTimerArchProtocolGuid);
|
||||
|
||||
mTimerFrequencyHz = ArmGenericTimerGetTimerFreq ();
|
||||
ASSERT (mTimerFrequencyHz != 0);
|
||||
|
||||
// Install interrupt handler
|
||||
Status = mInterruptProtocol->RegisterInterruptSource (
|
||||
mInterruptProtocol,
|
||||
Status = mInterruptProtocol->RegisterInterruptSource (mInterruptProtocol,
|
||||
FixedPcdGet32 (PcdGenericWatchdogEl2IntrNum),
|
||||
WatchdogInterruptHandler
|
||||
);
|
||||
WatchdogInterruptHandler);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
Status = mInterruptProtocol->SetTriggerType (
|
||||
mInterruptProtocol,
|
||||
Status = mInterruptProtocol->SetTriggerType (mInterruptProtocol,
|
||||
FixedPcdGet32 (PcdGenericWatchdogEl2IntrNum),
|
||||
EFI_HARDWARE_INTERRUPT2_TRIGGER_EDGE_RISING
|
||||
);
|
||||
EFI_HARDWARE_INTERRUPT2_TRIGGER_EDGE_RISING);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto UnregisterHandler;
|
||||
}
|
||||
|
||||
// Install the Timer Architectural Protocol onto a new handle
|
||||
Handle = NULL;
|
||||
Status = gBS->InstallMultipleProtocolInterfaces (
|
||||
&Handle,
|
||||
&gEfiWatchdogTimerArchProtocolGuid,
|
||||
&mWatchdogTimer,
|
||||
NULL
|
||||
);
|
||||
Status = gBS->InstallMultipleProtocolInterfaces (&Handle,
|
||||
&gEfiWatchdogTimerArchProtocolGuid, &mWatchdogTimer,
|
||||
NULL);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto UnregisterHandler;
|
||||
}
|
||||
|
||||
// Register for an ExitBootServicesEvent
|
||||
Status = gBS->CreateEvent (
|
||||
EVT_SIGNAL_EXIT_BOOT_SERVICES,
|
||||
TPL_NOTIFY,
|
||||
WatchdogExitBootServicesEvent,
|
||||
NULL,
|
||||
&mEfiExitBootServicesEvent
|
||||
);
|
||||
Status = gBS->CreateEvent (EVT_SIGNAL_EXIT_BOOT_SERVICES, TPL_NOTIFY,
|
||||
WatchdogExitBootServicesEvent, NULL,
|
||||
&mEfiExitBootServicesEvent);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
mNumTimerTicks = 0;
|
||||
WatchdogDisable ();
|
||||
|
||||
return EFI_SUCCESS;
|
||||
|
||||
UnregisterHandler:
|
||||
// Unregister the handler
|
||||
mInterruptProtocol->RegisterInterruptSource (
|
||||
mInterruptProtocol,
|
||||
mInterruptProtocol->RegisterInterruptSource (mInterruptProtocol,
|
||||
FixedPcdGet32 (PcdGenericWatchdogEl2IntrNum),
|
||||
NULL
|
||||
);
|
||||
NULL);
|
||||
return Status;
|
||||
}
|
||||
|
@ -9,14 +9,14 @@
|
||||
#ifndef MM_COMMUNICATE_H_
|
||||
#define MM_COMMUNICATE_H_
|
||||
|
||||
#define MM_MAJOR_VER_MASK 0xEFFF0000
|
||||
#define MM_MINOR_VER_MASK 0x0000FFFF
|
||||
#define MM_MAJOR_VER_SHIFT 16
|
||||
#define MM_MAJOR_VER_MASK 0xEFFF0000
|
||||
#define MM_MINOR_VER_MASK 0x0000FFFF
|
||||
#define MM_MAJOR_VER_SHIFT 16
|
||||
|
||||
#define MM_MAJOR_VER(x) (((x) & MM_MAJOR_VER_MASK) >> MM_MAJOR_VER_SHIFT)
|
||||
#define MM_MINOR_VER(x) ((x) & MM_MINOR_VER_MASK)
|
||||
#define MM_MAJOR_VER(x) (((x) & MM_MAJOR_VER_MASK) >> MM_MAJOR_VER_SHIFT)
|
||||
#define MM_MINOR_VER(x) ((x) & MM_MINOR_VER_MASK)
|
||||
|
||||
#define MM_CALLER_MAJOR_VER 0x1UL
|
||||
#define MM_CALLER_MINOR_VER 0x0
|
||||
#define MM_CALLER_MAJOR_VER 0x1UL
|
||||
#define MM_CALLER_MINOR_VER 0x0
|
||||
|
||||
#endif /* MM_COMMUNICATE_H_ */
|
||||
|
@ -41,21 +41,15 @@ STATIC EFI_HANDLE mMmCommunicateHandle;
|
||||
|
||||
This function provides a service to send and receive messages from a registered UEFI service.
|
||||
|
||||
@param[in] This The EFI_MM_COMMUNICATION_PROTOCOL instance.
|
||||
@param[in, out] CommBufferPhysical Physical address of the MM communication buffer
|
||||
@param[in, out] CommBufferVirtual Virtual address of the MM communication buffer
|
||||
@param[in, out] CommSize The size of the data buffer being passed in. On input,
|
||||
when not omitted, the buffer should cover EFI_MM_COMMUNICATE_HEADER
|
||||
and the value of MessageLength field. On exit, the size
|
||||
of data being returned. Zero if the handler does not
|
||||
wish to reply with any data. This parameter is optional
|
||||
and may be NULL.
|
||||
@param[in] This The EFI_MM_COMMUNICATION_PROTOCOL instance.
|
||||
@param[in] CommBufferPhysical Physical address of the MM communication buffer
|
||||
@param[in] CommBufferVirtual Virtual address of the MM communication buffer
|
||||
@param[in] CommSize The size of the data buffer being passed in. On exit, the size of data
|
||||
being returned. Zero if the handler does not wish to reply with any data.
|
||||
This parameter is optional and may be NULL.
|
||||
|
||||
@retval EFI_SUCCESS The message was successfully posted.
|
||||
@retval EFI_INVALID_PARAMETER CommBufferPhysical or CommBufferVirtual was NULL, or
|
||||
integer value pointed by CommSize does not cover
|
||||
EFI_MM_COMMUNICATE_HEADER and the value of MessageLength
|
||||
field.
|
||||
@retval EFI_INVALID_PARAMETER CommBufferPhysical was NULL or CommBufferVirtual was NULL.
|
||||
@retval EFI_BAD_BUFFER_SIZE The buffer is too large for the MM implementation.
|
||||
If this error is returned, the MessageLength field
|
||||
in the CommBuffer header or the integer pointed by
|
||||
@ -69,18 +63,18 @@ STATIC EFI_HANDLE mMmCommunicateHandle;
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
MmCommunication2Communicate (
|
||||
IN CONST EFI_MM_COMMUNICATION2_PROTOCOL *This,
|
||||
IN OUT VOID *CommBufferPhysical,
|
||||
IN OUT VOID *CommBufferVirtual,
|
||||
IN OUT UINTN *CommSize OPTIONAL
|
||||
IN CONST EFI_MM_COMMUNICATION2_PROTOCOL *This,
|
||||
IN OUT VOID *CommBufferPhysical,
|
||||
IN OUT VOID *CommBufferVirtual,
|
||||
IN OUT UINTN *CommSize OPTIONAL
|
||||
)
|
||||
{
|
||||
EFI_MM_COMMUNICATE_HEADER *CommunicateHeader;
|
||||
ARM_SMC_ARGS CommunicateSmcArgs;
|
||||
EFI_STATUS Status;
|
||||
UINTN BufferSize;
|
||||
EFI_MM_COMMUNICATE_HEADER *CommunicateHeader;
|
||||
ARM_SMC_ARGS CommunicateSmcArgs;
|
||||
EFI_STATUS Status;
|
||||
UINTN BufferSize;
|
||||
|
||||
Status = EFI_ACCESS_DENIED;
|
||||
Status = EFI_ACCESS_DENIED;
|
||||
BufferSize = 0;
|
||||
|
||||
ZeroMem (&CommunicateSmcArgs, sizeof (ARM_SMC_ARGS));
|
||||
@ -88,11 +82,10 @@ MmCommunication2Communicate (
|
||||
//
|
||||
// Check parameters
|
||||
//
|
||||
if ((CommBufferVirtual == NULL) || (CommBufferPhysical == NULL)) {
|
||||
if (CommBufferVirtual == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Status = EFI_SUCCESS;
|
||||
CommunicateHeader = CommBufferVirtual;
|
||||
// CommBuffer is a mandatory parameter. Hence, Rely on
|
||||
// MessageLength + Header to ascertain the
|
||||
@ -102,41 +95,33 @@ MmCommunication2Communicate (
|
||||
sizeof (CommunicateHeader->HeaderGuid) +
|
||||
sizeof (CommunicateHeader->MessageLength);
|
||||
|
||||
// If CommSize is not omitted, perform size inspection before proceeding.
|
||||
if (CommSize != NULL) {
|
||||
// If the length of the CommBuffer is 0 then return the expected length.
|
||||
if (CommSize != 0) {
|
||||
// This case can be used by the consumer of this driver to find out the
|
||||
// max size that can be used for allocating CommBuffer.
|
||||
if ((*CommSize == 0) ||
|
||||
(*CommSize > mNsCommBuffMemRegion.Length))
|
||||
{
|
||||
(*CommSize > mNsCommBuffMemRegion.Length)) {
|
||||
*CommSize = mNsCommBuffMemRegion.Length;
|
||||
Status = EFI_BAD_BUFFER_SIZE;
|
||||
return EFI_BAD_BUFFER_SIZE;
|
||||
}
|
||||
|
||||
//
|
||||
// CommSize should cover at least MessageLength + sizeof (EFI_MM_COMMUNICATE_HEADER);
|
||||
// CommSize must match MessageLength + sizeof (EFI_MM_COMMUNICATE_HEADER);
|
||||
//
|
||||
if (*CommSize < BufferSize) {
|
||||
Status = EFI_INVALID_PARAMETER;
|
||||
if (*CommSize != BufferSize) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// If the message length is 0 or greater than what can be tolerated by the MM
|
||||
// If the buffer size is 0 or greater than what can be tolerated by the MM
|
||||
// environment then return the expected size.
|
||||
//
|
||||
if ((CommunicateHeader->MessageLength == 0) ||
|
||||
(BufferSize > mNsCommBuffMemRegion.Length))
|
||||
{
|
||||
if ((BufferSize == 0) ||
|
||||
(BufferSize > mNsCommBuffMemRegion.Length)) {
|
||||
CommunicateHeader->MessageLength = mNsCommBuffMemRegion.Length -
|
||||
sizeof (CommunicateHeader->HeaderGuid) -
|
||||
sizeof (CommunicateHeader->MessageLength);
|
||||
Status = EFI_BAD_BUFFER_SIZE;
|
||||
}
|
||||
|
||||
// MessageLength or CommSize check has failed, return here.
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
return EFI_BAD_BUFFER_SIZE;
|
||||
}
|
||||
|
||||
// SMC Function ID
|
||||
@ -158,41 +143,41 @@ MmCommunication2Communicate (
|
||||
ArmCallSmc (&CommunicateSmcArgs);
|
||||
|
||||
switch (CommunicateSmcArgs.Arg0) {
|
||||
case ARM_SMC_MM_RET_SUCCESS:
|
||||
ZeroMem (CommBufferVirtual, BufferSize);
|
||||
// On successful return, the size of data being returned is inferred from
|
||||
// MessageLength + Header.
|
||||
CommunicateHeader = (EFI_MM_COMMUNICATE_HEADER *)mNsCommBuffMemRegion.VirtualBase;
|
||||
BufferSize = CommunicateHeader->MessageLength +
|
||||
sizeof (CommunicateHeader->HeaderGuid) +
|
||||
sizeof (CommunicateHeader->MessageLength);
|
||||
case ARM_SMC_MM_RET_SUCCESS:
|
||||
ZeroMem (CommBufferVirtual, BufferSize);
|
||||
// On successful return, the size of data being returned is inferred from
|
||||
// MessageLength + Header.
|
||||
CommunicateHeader = (EFI_MM_COMMUNICATE_HEADER *)mNsCommBuffMemRegion.VirtualBase;
|
||||
BufferSize = CommunicateHeader->MessageLength +
|
||||
sizeof (CommunicateHeader->HeaderGuid) +
|
||||
sizeof (CommunicateHeader->MessageLength);
|
||||
|
||||
CopyMem (
|
||||
CommBufferVirtual,
|
||||
(VOID *)mNsCommBuffMemRegion.VirtualBase,
|
||||
BufferSize
|
||||
);
|
||||
Status = EFI_SUCCESS;
|
||||
break;
|
||||
CopyMem (
|
||||
CommBufferVirtual,
|
||||
(VOID *)mNsCommBuffMemRegion.VirtualBase,
|
||||
BufferSize
|
||||
);
|
||||
Status = EFI_SUCCESS;
|
||||
break;
|
||||
|
||||
case ARM_SMC_MM_RET_INVALID_PARAMS:
|
||||
Status = EFI_INVALID_PARAMETER;
|
||||
break;
|
||||
case ARM_SMC_MM_RET_INVALID_PARAMS:
|
||||
Status = EFI_INVALID_PARAMETER;
|
||||
break;
|
||||
|
||||
case ARM_SMC_MM_RET_DENIED:
|
||||
Status = EFI_ACCESS_DENIED;
|
||||
break;
|
||||
case ARM_SMC_MM_RET_DENIED:
|
||||
Status = EFI_ACCESS_DENIED;
|
||||
break;
|
||||
|
||||
case ARM_SMC_MM_RET_NO_MEMORY:
|
||||
// Unexpected error since the CommSize was checked for zero length
|
||||
// prior to issuing the SMC
|
||||
Status = EFI_OUT_OF_RESOURCES;
|
||||
ASSERT (0);
|
||||
break;
|
||||
case ARM_SMC_MM_RET_NO_MEMORY:
|
||||
// Unexpected error since the CommSize was checked for zero length
|
||||
// prior to issuing the SMC
|
||||
Status = EFI_OUT_OF_RESOURCES;
|
||||
ASSERT (0);
|
||||
break;
|
||||
|
||||
default:
|
||||
Status = EFI_ACCESS_DENIED;
|
||||
ASSERT (0);
|
||||
default:
|
||||
Status = EFI_ACCESS_DENIED;
|
||||
ASSERT (0);
|
||||
}
|
||||
|
||||
return Status;
|
||||
@ -224,7 +209,7 @@ VOID
|
||||
EFIAPI
|
||||
NotifySetVirtualAddressMap (
|
||||
IN EFI_EVENT Event,
|
||||
IN VOID *Context
|
||||
IN VOID *Context
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
@ -234,23 +219,19 @@ NotifySetVirtualAddressMap (
|
||||
(VOID **)&mNsCommBuffMemRegion.VirtualBase
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((
|
||||
DEBUG_ERROR,
|
||||
"NotifySetVirtualAddressMap():"
|
||||
" Unable to convert MM runtime pointer. Status:0x%r\n",
|
||||
Status
|
||||
));
|
||||
DEBUG ((DEBUG_ERROR, "NotifySetVirtualAddressMap():"
|
||||
" Unable to convert MM runtime pointer. Status:0x%r\n", Status));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
GetMmCompatibility (
|
||||
)
|
||||
GetMmCompatibility ()
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINT32 MmVersion;
|
||||
ARM_SMC_ARGS MmVersionArgs;
|
||||
EFI_STATUS Status;
|
||||
UINT32 MmVersion;
|
||||
ARM_SMC_ARGS MmVersionArgs;
|
||||
|
||||
// MM_VERSION uses SMC32 calling conventions
|
||||
MmVersionArgs.Arg0 = ARM_SMC_ID_MM_VERSION_AARCH32;
|
||||
@ -259,38 +240,27 @@ GetMmCompatibility (
|
||||
|
||||
MmVersion = MmVersionArgs.Arg0;
|
||||
|
||||
if ((MM_MAJOR_VER (MmVersion) == MM_CALLER_MAJOR_VER) &&
|
||||
(MM_MINOR_VER (MmVersion) >= MM_CALLER_MINOR_VER))
|
||||
{
|
||||
DEBUG ((
|
||||
DEBUG_INFO,
|
||||
"MM Version: Major=0x%x, Minor=0x%x\n",
|
||||
MM_MAJOR_VER (MmVersion),
|
||||
MM_MINOR_VER (MmVersion)
|
||||
));
|
||||
if ((MM_MAJOR_VER(MmVersion) == MM_CALLER_MAJOR_VER) &&
|
||||
(MM_MINOR_VER(MmVersion) >= MM_CALLER_MINOR_VER)) {
|
||||
DEBUG ((DEBUG_INFO, "MM Version: Major=0x%x, Minor=0x%x\n",
|
||||
MM_MAJOR_VER(MmVersion), MM_MINOR_VER(MmVersion)));
|
||||
Status = EFI_SUCCESS;
|
||||
} else {
|
||||
DEBUG ((
|
||||
DEBUG_ERROR,
|
||||
"Incompatible MM Versions.\n Current Version: Major=0x%x, Minor=0x%x.\n Expected: Major=0x%x, Minor>=0x%x.\n",
|
||||
MM_MAJOR_VER (MmVersion),
|
||||
MM_MINOR_VER (MmVersion),
|
||||
MM_CALLER_MAJOR_VER,
|
||||
MM_CALLER_MINOR_VER
|
||||
));
|
||||
DEBUG ((DEBUG_ERROR, "Incompatible MM Versions.\n Current Version: Major=0x%x, Minor=0x%x.\n Expected: Major=0x%x, Minor>=0x%x.\n",
|
||||
MM_MAJOR_VER(MmVersion), MM_MINOR_VER(MmVersion), MM_CALLER_MAJOR_VER, MM_CALLER_MINOR_VER));
|
||||
Status = EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
STATIC EFI_GUID *CONST mGuidedEventGuid[] = {
|
||||
STATIC EFI_GUID* CONST mGuidedEventGuid[] = {
|
||||
&gEfiEndOfDxeEventGroupGuid,
|
||||
&gEfiEventExitBootServicesGuid,
|
||||
&gEfiEventReadyToBootGuid,
|
||||
};
|
||||
|
||||
STATIC EFI_EVENT mGuidedEvent[ARRAY_SIZE (mGuidedEventGuid)];
|
||||
STATIC EFI_EVENT mGuidedEvent[ARRAY_SIZE (mGuidedEventGuid)];
|
||||
|
||||
/**
|
||||
Event notification that is fired when GUIDed Event Group is signaled.
|
||||
@ -307,15 +277,15 @@ MmGuidedEventNotify (
|
||||
IN VOID *Context
|
||||
)
|
||||
{
|
||||
EFI_MM_COMMUNICATE_HEADER Header;
|
||||
UINTN Size;
|
||||
EFI_MM_COMMUNICATE_HEADER Header;
|
||||
UINTN Size;
|
||||
|
||||
//
|
||||
// Use Guid to initialize EFI_SMM_COMMUNICATE_HEADER structure
|
||||
//
|
||||
CopyGuid (&Header.HeaderGuid, Context);
|
||||
Header.MessageLength = 1;
|
||||
Header.Data[0] = 0;
|
||||
Header.Data[0] = 0;
|
||||
|
||||
Size = sizeof (Header);
|
||||
MmCommunication2Communicate (&mMmCommunication2, &Header, &Header, &Size);
|
||||
@ -338,23 +308,23 @@ MmGuidedEventNotify (
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
MmCommunication2Initialize (
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
IN EFI_SYSTEM_TABLE *SystemTable
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINTN Index;
|
||||
EFI_STATUS Status;
|
||||
UINTN Index;
|
||||
|
||||
// Check if we can make the MM call
|
||||
Status = GetMmCompatibility ();
|
||||
if (EFI_ERROR (Status)) {
|
||||
if (EFI_ERROR(Status)) {
|
||||
goto ReturnErrorStatus;
|
||||
}
|
||||
|
||||
mNsCommBuffMemRegion.PhysicalBase = PcdGet64 (PcdMmBufferBase);
|
||||
// During boot , Virtual and Physical are same
|
||||
mNsCommBuffMemRegion.VirtualBase = mNsCommBuffMemRegion.PhysicalBase;
|
||||
mNsCommBuffMemRegion.Length = PcdGet64 (PcdMmBufferSize);
|
||||
mNsCommBuffMemRegion.Length = PcdGet64 (PcdMmBufferSize);
|
||||
|
||||
ASSERT (mNsCommBuffMemRegion.PhysicalBase != 0);
|
||||
|
||||
@ -369,11 +339,8 @@ MmCommunication2Initialize (
|
||||
EFI_MEMORY_RUNTIME
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((
|
||||
DEBUG_ERROR,
|
||||
"MmCommunicateInitialize: "
|
||||
"Failed to add MM-NS Buffer Memory Space\n"
|
||||
));
|
||||
DEBUG ((DEBUG_ERROR, "MmCommunicateInitialize: "
|
||||
"Failed to add MM-NS Buffer Memory Space\n"));
|
||||
goto ReturnErrorStatus;
|
||||
}
|
||||
|
||||
@ -383,11 +350,8 @@ MmCommunication2Initialize (
|
||||
EFI_MEMORY_WB | EFI_MEMORY_XP | EFI_MEMORY_RUNTIME
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((
|
||||
DEBUG_ERROR,
|
||||
"MmCommunicateInitialize: "
|
||||
"Failed to set MM-NS Buffer Memory attributes\n"
|
||||
));
|
||||
DEBUG ((DEBUG_ERROR, "MmCommunicateInitialize: "
|
||||
"Failed to set MM-NS Buffer Memory attributes\n"));
|
||||
goto CleanAddedMemorySpace;
|
||||
}
|
||||
|
||||
@ -398,12 +362,9 @@ MmCommunication2Initialize (
|
||||
EFI_NATIVE_INTERFACE,
|
||||
&mMmCommunication2
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((
|
||||
DEBUG_ERROR,
|
||||
"MmCommunicationInitialize: "
|
||||
"Failed to install MM communication protocol\n"
|
||||
));
|
||||
if (EFI_ERROR(Status)) {
|
||||
DEBUG ((DEBUG_ERROR, "MmCommunicationInitialize: "
|
||||
"Failed to install MM communication protocol\n"));
|
||||
goto CleanAddedMemorySpace;
|
||||
}
|
||||
|
||||
@ -420,24 +381,17 @@ MmCommunication2Initialize (
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
for (Index = 0; Index < ARRAY_SIZE (mGuidedEventGuid); Index++) {
|
||||
Status = gBS->CreateEventEx (
|
||||
EVT_NOTIFY_SIGNAL,
|
||||
TPL_CALLBACK,
|
||||
MmGuidedEventNotify,
|
||||
mGuidedEventGuid[Index],
|
||||
mGuidedEventGuid[Index],
|
||||
&mGuidedEvent[Index]
|
||||
);
|
||||
Status = gBS->CreateEventEx (EVT_NOTIFY_SIGNAL, TPL_CALLBACK,
|
||||
MmGuidedEventNotify, mGuidedEventGuid[Index],
|
||||
mGuidedEventGuid[Index], &mGuidedEvent[Index]);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
if (EFI_ERROR (Status)) {
|
||||
while (Index-- > 0) {
|
||||
gBS->CloseEvent (mGuidedEvent[Index]);
|
||||
}
|
||||
|
||||
goto UninstallProtocol;
|
||||
}
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
|
||||
UninstallProtocol:
|
||||
|
@ -1,221 +0,0 @@
|
||||
/** @file -- MmCommunicationPei.c
|
||||
Provides an interface to send MM request in PEI
|
||||
|
||||
Copyright (c) 2016-2021, Arm Limited. All rights reserved.<BR>
|
||||
Copyright (c) Microsoft Corporation.
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
**/
|
||||
|
||||
#include <PiPei.h>
|
||||
#include <IndustryStandard/ArmStdSmc.h>
|
||||
|
||||
#include <Protocol/MmCommunication.h>
|
||||
#include <Ppi/MmCommunication.h>
|
||||
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
#include <Library/ArmSmcLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/PcdLib.h>
|
||||
#include <Library/PeimEntryPoint.h>
|
||||
#include <Library/PeiServicesLib.h>
|
||||
|
||||
/**
|
||||
MmCommunicationPeim
|
||||
Communicates with a registered handler.
|
||||
This function provides a service to send and receive messages from a registered UEFI service during PEI.
|
||||
|
||||
@param[in] This The EFI_PEI_MM_COMMUNICATION_PPI instance.
|
||||
@param[in, out] CommBuffer Pointer to the data buffer
|
||||
@param[in, out] CommSize The size of the data buffer being passed in. On exit, the
|
||||
size of data being returned. Zero if the handler does not
|
||||
wish to reply with any data.
|
||||
|
||||
@retval EFI_SUCCESS The message was successfully posted.
|
||||
@retval EFI_INVALID_PARAMETER CommBuffer or CommSize was NULL, or *CommSize does not
|
||||
match MessageLength + sizeof (EFI_MM_COMMUNICATE_HEADER).
|
||||
@retval EFI_BAD_BUFFER_SIZE The buffer is too large for the MM implementation.
|
||||
If this error is returned, the MessageLength field
|
||||
in the CommBuffer header or the integer pointed by
|
||||
CommSize, are updated to reflect the maximum payload
|
||||
size the implementation can accommodate.
|
||||
@retval EFI_ACCESS_DENIED The CommunicateBuffer parameter or CommSize parameter,
|
||||
if not omitted, are in address range that cannot be
|
||||
accessed by the MM environment.
|
||||
**/
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
MmCommunicationPeim (
|
||||
IN CONST EFI_PEI_MM_COMMUNICATION_PPI *This,
|
||||
IN OUT VOID *CommBuffer,
|
||||
IN OUT UINTN *CommSize
|
||||
)
|
||||
{
|
||||
EFI_MM_COMMUNICATE_HEADER *CommunicateHeader;
|
||||
EFI_MM_COMMUNICATE_HEADER *TempCommHeader;
|
||||
ARM_SMC_ARGS CommunicateSmcArgs;
|
||||
EFI_STATUS Status;
|
||||
UINTN BufferSize;
|
||||
|
||||
ZeroMem (&CommunicateSmcArgs, sizeof (ARM_SMC_ARGS));
|
||||
|
||||
// Check that our static buffer is looking good.
|
||||
// We are using PcdMmBufferBase to transfer variable data.
|
||||
// We are not using the full size of the buffer since there is a cost
|
||||
// of copying data between Normal and Secure World.
|
||||
if ((PcdGet64 (PcdMmBufferBase) == 0) || (PcdGet64 (PcdMmBufferSize) == 0)) {
|
||||
ASSERT (PcdGet64 (PcdMmBufferSize) > 0);
|
||||
ASSERT (PcdGet64 (PcdMmBufferBase) != 0);
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
//
|
||||
// Check parameters
|
||||
//
|
||||
if ((CommBuffer == NULL) || (CommSize == NULL)) {
|
||||
ASSERT (CommBuffer != NULL);
|
||||
ASSERT (CommSize != NULL);
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
// If the length of the CommBuffer is 0 then return the expected length.
|
||||
// This case can be used by the consumer of this driver to find out the
|
||||
// max size that can be used for allocating CommBuffer.
|
||||
if ((*CommSize == 0) || (*CommSize > (UINTN)PcdGet64 (PcdMmBufferSize))) {
|
||||
DEBUG ((
|
||||
DEBUG_ERROR,
|
||||
"%a Invalid CommSize value 0x%llx!\n",
|
||||
__func__,
|
||||
*CommSize
|
||||
));
|
||||
*CommSize = (UINTN)PcdGet64 (PcdMmBufferSize);
|
||||
return EFI_BAD_BUFFER_SIZE;
|
||||
}
|
||||
|
||||
// Given CommBuffer is not NULL here, we use it to test the legitimacy of CommSize.
|
||||
TempCommHeader = (EFI_MM_COMMUNICATE_HEADER *)(UINTN)CommBuffer;
|
||||
|
||||
// CommBuffer is a mandatory parameter. Hence, Rely on
|
||||
// MessageLength + Header to ascertain the
|
||||
// total size of the communication payload rather than
|
||||
// rely on optional CommSize parameter
|
||||
BufferSize = TempCommHeader->MessageLength +
|
||||
sizeof (TempCommHeader->HeaderGuid) +
|
||||
sizeof (TempCommHeader->MessageLength);
|
||||
|
||||
//
|
||||
// If CommSize is supplied it must match MessageLength + sizeof (EFI_MM_COMMUNICATE_HEADER);
|
||||
//
|
||||
if (*CommSize != BufferSize) {
|
||||
DEBUG ((
|
||||
DEBUG_ERROR,
|
||||
"%a Unexpected CommSize value, has: 0x%llx vs. expected: 0x%llx!\n",
|
||||
__func__,
|
||||
*CommSize,
|
||||
BufferSize
|
||||
));
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
// Now we know that the size is something we can handle, copy it over to the designated comm buffer.
|
||||
CommunicateHeader = (EFI_MM_COMMUNICATE_HEADER *)(UINTN)(PcdGet64 (PcdMmBufferBase));
|
||||
|
||||
CopyMem (CommunicateHeader, CommBuffer, *CommSize);
|
||||
|
||||
// SMC Function ID
|
||||
CommunicateSmcArgs.Arg0 = ARM_SMC_ID_MM_COMMUNICATE_AARCH64;
|
||||
|
||||
// Cookie
|
||||
CommunicateSmcArgs.Arg1 = 0;
|
||||
|
||||
// comm_buffer_address (64-bit physical address)
|
||||
CommunicateSmcArgs.Arg2 = (UINTN)CommunicateHeader;
|
||||
|
||||
// comm_size_address (not used, indicated by setting to zero)
|
||||
CommunicateSmcArgs.Arg3 = 0;
|
||||
|
||||
// Call the Standalone MM environment.
|
||||
ArmCallSmc (&CommunicateSmcArgs);
|
||||
|
||||
switch (CommunicateSmcArgs.Arg0) {
|
||||
case ARM_SMC_MM_RET_SUCCESS:
|
||||
// On successful return, the size of data being returned is inferred from
|
||||
// MessageLength + Header.
|
||||
BufferSize = CommunicateHeader->MessageLength +
|
||||
sizeof (CommunicateHeader->HeaderGuid) +
|
||||
sizeof (CommunicateHeader->MessageLength);
|
||||
if (BufferSize > (UINTN)PcdGet64 (PcdMmBufferSize)) {
|
||||
// Something bad has happened, we should have landed in ARM_SMC_MM_RET_NO_MEMORY
|
||||
DEBUG ((
|
||||
DEBUG_ERROR,
|
||||
"%a Returned buffer exceeds communication buffer limit. Has: 0x%llx vs. max: 0x%llx!\n",
|
||||
__func__,
|
||||
BufferSize,
|
||||
(UINTN)PcdGet64 (PcdMmBufferSize)
|
||||
));
|
||||
Status = EFI_BAD_BUFFER_SIZE;
|
||||
break;
|
||||
}
|
||||
|
||||
CopyMem (CommBuffer, CommunicateHeader, BufferSize);
|
||||
*CommSize = BufferSize;
|
||||
Status = EFI_SUCCESS;
|
||||
break;
|
||||
|
||||
case ARM_SMC_MM_RET_INVALID_PARAMS:
|
||||
Status = EFI_INVALID_PARAMETER;
|
||||
break;
|
||||
|
||||
case ARM_SMC_MM_RET_DENIED:
|
||||
Status = EFI_ACCESS_DENIED;
|
||||
break;
|
||||
|
||||
case ARM_SMC_MM_RET_NO_MEMORY:
|
||||
// Unexpected error since the CommSize was checked for zero length
|
||||
// prior to issuing the SMC
|
||||
Status = EFI_OUT_OF_RESOURCES;
|
||||
ASSERT (0);
|
||||
break;
|
||||
|
||||
default:
|
||||
Status = EFI_ACCESS_DENIED;
|
||||
ASSERT (0);
|
||||
break;
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
//
|
||||
// Module globals for the MM Communication PPI
|
||||
//
|
||||
STATIC CONST EFI_PEI_MM_COMMUNICATION_PPI mPeiMmCommunication = {
|
||||
MmCommunicationPeim
|
||||
};
|
||||
|
||||
STATIC CONST EFI_PEI_PPI_DESCRIPTOR mPeiMmCommunicationPpi = {
|
||||
(EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
|
||||
&gEfiPeiMmCommunicationPpiGuid,
|
||||
(VOID *)&mPeiMmCommunication
|
||||
};
|
||||
|
||||
/**
|
||||
Entry point of PEI MM Communication driver
|
||||
|
||||
@param FileHandle Handle of the file being invoked.
|
||||
Type EFI_PEI_FILE_HANDLE is defined in FfsFindNextFile().
|
||||
@param PeiServices General purpose services available to every PEIM.
|
||||
|
||||
@retval EFI_SUCCESS If the interface could be successfully installed
|
||||
@retval Others Returned from PeiServicesInstallPpi()
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
MmCommunicationPeiInitialize (
|
||||
IN EFI_PEI_FILE_HANDLE FileHandle,
|
||||
IN CONST EFI_PEI_SERVICES **PeiServices
|
||||
)
|
||||
{
|
||||
return PeiServicesInstallPpi (&mPeiMmCommunicationPpi);
|
||||
}
|
@ -1,40 +0,0 @@
|
||||
## @file -- MmCommunicationPei.inf
|
||||
# PEI MM Communicate driver
|
||||
#
|
||||
# Copyright (c) 2016 - 2021, Arm Limited. All rights reserved.<BR>
|
||||
# Copyright (c) Microsoft Corporation.
|
||||
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
##
|
||||
|
||||
[Defines]
|
||||
INF_VERSION = 0x0001001B
|
||||
BASE_NAME = MmCommunicationPei
|
||||
FILE_GUID = 58FFB346-1B75-42C7-AD69-37C652423C1A
|
||||
MODULE_TYPE = PEIM
|
||||
VERSION_STRING = 1.0
|
||||
ENTRY_POINT = MmCommunicationPeiInitialize
|
||||
|
||||
[Sources]
|
||||
MmCommunicationPei.c
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
MdeModulePkg/MdeModulePkg.dec
|
||||
ArmPkg/ArmPkg.dec
|
||||
|
||||
[LibraryClasses]
|
||||
DebugLib
|
||||
ArmSmcLib
|
||||
PeimEntryPoint
|
||||
PeiServicesLib
|
||||
HobLib
|
||||
|
||||
[Pcd]
|
||||
gArmTokenSpaceGuid.PcdMmBufferBase
|
||||
gArmTokenSpaceGuid.PcdMmBufferSize
|
||||
|
||||
[Ppis]
|
||||
gEfiPeiMmCommunicationPpiGuid ## PRODUCES
|
||||
|
||||
[Depex]
|
||||
TRUE
|
@ -7,6 +7,7 @@
|
||||
|
||||
**/
|
||||
|
||||
|
||||
#include <PiDxe.h>
|
||||
|
||||
#include <Library/ArmLib.h>
|
||||
@ -23,18 +24,18 @@
|
||||
#include <Protocol/HardwareInterrupt.h>
|
||||
|
||||
// The notification function to call on every timer interrupt.
|
||||
EFI_TIMER_NOTIFY mTimerNotifyFunction = (EFI_TIMER_NOTIFY)NULL;
|
||||
EFI_EVENT EfiExitBootServicesEvent = (EFI_EVENT)NULL;
|
||||
EFI_TIMER_NOTIFY mTimerNotifyFunction = (EFI_TIMER_NOTIFY)NULL;
|
||||
EFI_EVENT EfiExitBootServicesEvent = (EFI_EVENT)NULL;
|
||||
|
||||
// The current period of the timer interrupt
|
||||
UINT64 mTimerPeriod = 0;
|
||||
UINT64 mTimerPeriod = 0;
|
||||
// The latest Timer Tick calculated for mTimerPeriod
|
||||
UINT64 mTimerTicks = 0;
|
||||
UINT64 mTimerTicks = 0;
|
||||
// Number of elapsed period since the last Timer interrupt
|
||||
UINT64 mElapsedPeriod = 1;
|
||||
UINT64 mElapsedPeriod = 1;
|
||||
|
||||
// Cached copy of the Hardware Interrupt protocol instance
|
||||
EFI_HARDWARE_INTERRUPT_PROTOCOL *gInterrupt = NULL;
|
||||
EFI_HARDWARE_INTERRUPT_PROTOCOL *gInterrupt = NULL;
|
||||
|
||||
/**
|
||||
This function registers the handler NotifyFunction so it is called every time
|
||||
@ -132,9 +133,9 @@ TimerDriverSetTimerPeriod (
|
||||
IN UINT64 TimerPeriod
|
||||
)
|
||||
{
|
||||
UINT64 CounterValue;
|
||||
UINT64 TimerTicks;
|
||||
EFI_TPL OriginalTPL;
|
||||
UINT64 CounterValue;
|
||||
UINT64 TimerTicks;
|
||||
EFI_TPL OriginalTPL;
|
||||
|
||||
// Always disable the timer
|
||||
ArmGenericTimerDisableTimer ();
|
||||
@ -165,7 +166,7 @@ TimerDriverSetTimerPeriod (
|
||||
ArmGenericTimerEnableTimer ();
|
||||
} else {
|
||||
// Save the new timer period
|
||||
mTimerPeriod = TimerPeriod;
|
||||
mTimerPeriod = TimerPeriod;
|
||||
// Reset the elapsed period
|
||||
mElapsedPeriod = 1;
|
||||
}
|
||||
@ -191,8 +192,8 @@ TimerDriverSetTimerPeriod (
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
TimerDriverGetTimerPeriod (
|
||||
IN EFI_TIMER_ARCH_PROTOCOL *This,
|
||||
OUT UINT64 *TimerPeriod
|
||||
IN EFI_TIMER_ARCH_PROTOCOL *This,
|
||||
OUT UINT64 *TimerPeriod
|
||||
)
|
||||
{
|
||||
if (TimerPeriod == NULL) {
|
||||
@ -261,7 +262,7 @@ TimerDriverGenerateSoftInterrupt (
|
||||
a period of time.
|
||||
|
||||
**/
|
||||
EFI_TIMER_ARCH_PROTOCOL gTimer = {
|
||||
EFI_TIMER_ARCH_PROTOCOL gTimer = {
|
||||
TimerDriverRegisterHandler,
|
||||
TimerDriverSetTimerPeriod,
|
||||
TimerDriverGetTimerPeriod,
|
||||
@ -284,13 +285,13 @@ EFI_TIMER_ARCH_PROTOCOL gTimer = {
|
||||
VOID
|
||||
EFIAPI
|
||||
TimerInterruptHandler (
|
||||
IN HARDWARE_INTERRUPT_SOURCE Source,
|
||||
IN EFI_SYSTEM_CONTEXT SystemContext
|
||||
IN HARDWARE_INTERRUPT_SOURCE Source,
|
||||
IN EFI_SYSTEM_CONTEXT SystemContext
|
||||
)
|
||||
{
|
||||
EFI_TPL OriginalTPL;
|
||||
UINT64 CurrentValue;
|
||||
UINT64 CompareValue;
|
||||
EFI_TPL OriginalTPL;
|
||||
UINT64 CurrentValue;
|
||||
UINT64 CompareValue;
|
||||
|
||||
//
|
||||
// DXE core uses this callback for the EFI timer tick. The DXE core uses locks
|
||||
@ -304,7 +305,8 @@ TimerInterruptHandler (
|
||||
gInterrupt->EndOfInterrupt (gInterrupt, Source);
|
||||
|
||||
// Check if the timer interrupt is active
|
||||
if ((ArmGenericTimerGetTimerCtrlReg ()) & ARM_ARCH_TIMER_ISTATUS) {
|
||||
if ((ArmGenericTimerGetTimerCtrlReg () ) & ARM_ARCH_TIMER_ISTATUS) {
|
||||
|
||||
if (mTimerNotifyFunction != 0) {
|
||||
mTimerNotifyFunction (mTimerPeriod * mElapsedPeriod);
|
||||
}
|
||||
@ -336,6 +338,7 @@ TimerInterruptHandler (
|
||||
gBS->RestoreTPL (OriginalTPL);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Initialize the state information for the Timer Architectural Protocol and
|
||||
the Timer Debug support protocol that allows the debugger to break into a
|
||||
@ -352,8 +355,8 @@ TimerInterruptHandler (
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
TimerInitialize (
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
IN EFI_SYSTEM_TABLE *SystemTable
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
IN EFI_SYSTEM_TABLE *SystemTable
|
||||
)
|
||||
{
|
||||
EFI_HANDLE Handle;
|
||||
@ -371,7 +374,7 @@ TimerInitialize (
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
// Disable the timer
|
||||
TimerCtrlReg = ArmGenericTimerGetTimerCtrlReg ();
|
||||
TimerCtrlReg = ArmGenericTimerGetTimerCtrlReg ();
|
||||
TimerCtrlReg |= ARM_ARCH_TIMER_IMASK;
|
||||
TimerCtrlReg &= ~ARM_ARCH_TIMER_ENABLE;
|
||||
ArmGenericTimerSetTimerCtrlReg (TimerCtrlReg);
|
||||
@ -402,18 +405,17 @@ TimerInitialize (
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
// Set up default timer
|
||||
Status = TimerDriverSetTimerPeriod (&gTimer, FixedPcdGet32 (PcdTimerPeriod)); // TIMER_DEFAULT_PERIOD
|
||||
Status = TimerDriverSetTimerPeriod (&gTimer, FixedPcdGet32(PcdTimerPeriod)); // TIMER_DEFAULT_PERIOD
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
Handle = NULL;
|
||||
// Install the Timer Architectural Protocol onto a new handle
|
||||
Status = gBS->InstallMultipleProtocolInterfaces (
|
||||
Status = gBS->InstallMultipleProtocolInterfaces(
|
||||
&Handle,
|
||||
&gEfiTimerArchProtocolGuid,
|
||||
&gTimer,
|
||||
&gEfiTimerArchProtocolGuid, &gTimer,
|
||||
NULL
|
||||
);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
ASSERT_EFI_ERROR(Status);
|
||||
|
||||
// Everything is ready, unmask and enable timer interrupts
|
||||
TimerCtrlReg = ARM_ARCH_TIMER_ENABLE;
|
||||
|
@ -27,16 +27,16 @@
|
||||
|
||||
#include "SemihostFs.h"
|
||||
|
||||
#define DEFAULT_SEMIHOST_FS_LABEL L"SemihostFs"
|
||||
#define DEFAULT_SEMIHOST_FS_LABEL L"SemihostFs"
|
||||
|
||||
STATIC CHAR16 *mSemihostFsLabel;
|
||||
STATIC CHAR16 *mSemihostFsLabel;
|
||||
|
||||
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL gSemihostFs = {
|
||||
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL gSemihostFs = {
|
||||
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_REVISION,
|
||||
VolumeOpen
|
||||
};
|
||||
|
||||
EFI_FILE gSemihostFsFile = {
|
||||
EFI_FILE gSemihostFsFile = {
|
||||
EFI_FILE_PROTOCOL_REVISION,
|
||||
FileOpen,
|
||||
FileClose,
|
||||
@ -54,45 +54,43 @@ EFI_FILE gSemihostFsFile = {
|
||||
// Device path for semi-hosting. It contains our auto-generated Caller ID GUID.
|
||||
//
|
||||
typedef struct {
|
||||
VENDOR_DEVICE_PATH Guid;
|
||||
EFI_DEVICE_PATH_PROTOCOL End;
|
||||
VENDOR_DEVICE_PATH Guid;
|
||||
EFI_DEVICE_PATH_PROTOCOL End;
|
||||
} SEMIHOST_DEVICE_PATH;
|
||||
|
||||
SEMIHOST_DEVICE_PATH gDevicePath = {
|
||||
SEMIHOST_DEVICE_PATH gDevicePath = {
|
||||
{
|
||||
{ HARDWARE_DEVICE_PATH, HW_VENDOR_DP, { sizeof (VENDOR_DEVICE_PATH), 0 }
|
||||
},
|
||||
{ HARDWARE_DEVICE_PATH, HW_VENDOR_DP, { sizeof (VENDOR_DEVICE_PATH), 0 } },
|
||||
EFI_CALLER_ID_GUID
|
||||
},
|
||||
{ END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE, { sizeof (EFI_DEVICE_PATH_PROTOCOL), 0 }
|
||||
}
|
||||
{ END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE, { sizeof (EFI_DEVICE_PATH_PROTOCOL), 0 } }
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
LIST_ENTRY Link;
|
||||
UINT64 Signature;
|
||||
EFI_FILE File;
|
||||
CHAR8 *FileName;
|
||||
UINT64 OpenMode;
|
||||
UINT32 Position;
|
||||
UINTN SemihostHandle;
|
||||
BOOLEAN IsRoot;
|
||||
EFI_FILE_INFO Info;
|
||||
LIST_ENTRY Link;
|
||||
UINT64 Signature;
|
||||
EFI_FILE File;
|
||||
CHAR8 *FileName;
|
||||
UINT64 OpenMode;
|
||||
UINT32 Position;
|
||||
UINTN SemihostHandle;
|
||||
BOOLEAN IsRoot;
|
||||
EFI_FILE_INFO Info;
|
||||
} SEMIHOST_FCB;
|
||||
|
||||
#define SEMIHOST_FCB_SIGNATURE SIGNATURE_32( 'S', 'H', 'F', 'C' )
|
||||
#define SEMIHOST_FCB_FROM_THIS(a) CR(a, SEMIHOST_FCB, File, SEMIHOST_FCB_SIGNATURE)
|
||||
#define SEMIHOST_FCB_FROM_LINK(a) CR(a, SEMIHOST_FCB, Link, SEMIHOST_FCB_SIGNATURE);
|
||||
#define SEMIHOST_FCB_SIGNATURE SIGNATURE_32( 'S', 'H', 'F', 'C' )
|
||||
#define SEMIHOST_FCB_FROM_THIS(a) CR(a, SEMIHOST_FCB, File, SEMIHOST_FCB_SIGNATURE)
|
||||
#define SEMIHOST_FCB_FROM_LINK(a) CR(a, SEMIHOST_FCB, Link, SEMIHOST_FCB_SIGNATURE);
|
||||
|
||||
EFI_HANDLE gInstallHandle = NULL;
|
||||
LIST_ENTRY gFileList = INITIALIZE_LIST_HEAD_VARIABLE (gFileList);
|
||||
LIST_ENTRY gFileList = INITIALIZE_LIST_HEAD_VARIABLE (gFileList);
|
||||
|
||||
SEMIHOST_FCB *
|
||||
AllocateFCB (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
SEMIHOST_FCB *Fcb;
|
||||
SEMIHOST_FCB *Fcb;
|
||||
|
||||
Fcb = AllocateZeroPool (sizeof (SEMIHOST_FCB));
|
||||
if (Fcb != NULL) {
|
||||
@ -105,7 +103,7 @@ AllocateFCB (
|
||||
|
||||
VOID
|
||||
FreeFCB (
|
||||
IN SEMIHOST_FCB *Fcb
|
||||
IN SEMIHOST_FCB *Fcb
|
||||
)
|
||||
{
|
||||
// Remove Fcb from gFileList.
|
||||
@ -117,13 +115,15 @@ FreeFCB (
|
||||
FreePool (Fcb);
|
||||
}
|
||||
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
VolumeOpen (
|
||||
IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *This,
|
||||
OUT EFI_FILE **Root
|
||||
IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *This,
|
||||
OUT EFI_FILE **Root
|
||||
)
|
||||
{
|
||||
SEMIHOST_FCB *RootFcb;
|
||||
SEMIHOST_FCB *RootFcb;
|
||||
|
||||
if (Root == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
@ -134,7 +134,7 @@ VolumeOpen (
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
RootFcb->IsRoot = TRUE;
|
||||
RootFcb->IsRoot = TRUE;
|
||||
RootFcb->Info.Attribute = EFI_FILE_READ_ONLY | EFI_FILE_DIRECTORY;
|
||||
|
||||
InsertTailList (&gFileList, &RootFcb->Link);
|
||||
@ -191,33 +191,29 @@ FileOpen (
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if ((OpenMode != EFI_FILE_MODE_READ) &&
|
||||
(OpenMode != (EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE)) &&
|
||||
(OpenMode != (EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE)))
|
||||
{
|
||||
if ( (OpenMode != EFI_FILE_MODE_READ) &&
|
||||
(OpenMode != (EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE)) &&
|
||||
(OpenMode != (EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE)) ) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (((OpenMode & EFI_FILE_MODE_CREATE) != 0) &&
|
||||
((Attributes & EFI_FILE_DIRECTORY) != 0))
|
||||
{
|
||||
((Attributes & EFI_FILE_DIRECTORY) != 0)) {
|
||||
return EFI_WRITE_PROTECTED;
|
||||
}
|
||||
|
||||
Length = StrLen (FileName) + 1;
|
||||
Length = StrLen (FileName) + 1;
|
||||
AsciiFileName = AllocatePool (Length);
|
||||
if (AsciiFileName == NULL) {
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
UnicodeStrToAsciiStrS (FileName, AsciiFileName, Length);
|
||||
|
||||
// Opening '/', '\', '.', or the NULL pathname is trying to open the root directory
|
||||
if ((AsciiStrCmp (AsciiFileName, "\\") == 0) ||
|
||||
(AsciiStrCmp (AsciiFileName, "/") == 0) ||
|
||||
(AsciiStrCmp (AsciiFileName, "") == 0) ||
|
||||
(AsciiStrCmp (AsciiFileName, ".") == 0))
|
||||
{
|
||||
(AsciiStrCmp (AsciiFileName, ".") == 0) ) {
|
||||
FreePool (AsciiFileName);
|
||||
return (VolumeOpen (&gSemihostFs, NewHandle));
|
||||
}
|
||||
@ -236,7 +232,6 @@ FileOpen (
|
||||
} else {
|
||||
SemihostMode = SEMIHOST_FILE_MODE_READ | SEMIHOST_FILE_MODE_BINARY | SEMIHOST_FILE_MODE_UPDATE;
|
||||
}
|
||||
|
||||
Return = SemihostFileOpen (AsciiFileName, SemihostMode, &SemihostHandle);
|
||||
|
||||
if (RETURN_ERROR (Return)) {
|
||||
@ -284,7 +279,7 @@ FileOpen (
|
||||
FileFcb->Info.FileSize = Length;
|
||||
FileFcb->Info.PhysicalSize = Length;
|
||||
FileFcb->Info.Attribute = ((OpenMode & EFI_FILE_MODE_CREATE) != 0) ?
|
||||
Attributes : 0;
|
||||
Attributes : 0;
|
||||
|
||||
InsertTailList (&gFileList, &FileFcb->Link);
|
||||
|
||||
@ -313,7 +308,7 @@ STATIC
|
||||
EFI_STATUS
|
||||
TruncateFile (
|
||||
IN CHAR8 *FileName,
|
||||
IN UINTN Size
|
||||
IN UINTN Size
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
@ -343,7 +338,7 @@ TruncateFile (
|
||||
goto Error;
|
||||
}
|
||||
|
||||
Read = 0;
|
||||
Read = 0;
|
||||
Remaining = Size;
|
||||
while (Remaining > 0) {
|
||||
ToRead = Remaining;
|
||||
@ -351,12 +346,11 @@ TruncateFile (
|
||||
if (RETURN_ERROR (Return)) {
|
||||
goto Error;
|
||||
}
|
||||
|
||||
Remaining -= ToRead;
|
||||
Read += ToRead;
|
||||
}
|
||||
|
||||
Return = SemihostFileClose (FileHandle);
|
||||
Return = SemihostFileClose (FileHandle);
|
||||
FileHandle = 0;
|
||||
if (RETURN_ERROR (Return)) {
|
||||
goto Error;
|
||||
@ -385,12 +379,12 @@ Error:
|
||||
if (FileHandle != 0) {
|
||||
SemihostFileClose (FileHandle);
|
||||
}
|
||||
|
||||
if (Buffer != NULL) {
|
||||
FreePool (Buffer);
|
||||
}
|
||||
|
||||
return (Status);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -408,13 +402,13 @@ FileClose (
|
||||
IN EFI_FILE *This
|
||||
)
|
||||
{
|
||||
SEMIHOST_FCB *Fcb;
|
||||
SEMIHOST_FCB *Fcb;
|
||||
|
||||
if (This == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Fcb = SEMIHOST_FCB_FROM_THIS (This);
|
||||
Fcb = SEMIHOST_FCB_FROM_THIS(This);
|
||||
|
||||
if (!Fcb->IsRoot) {
|
||||
SemihostFileClose (Fcb->SemihostHandle);
|
||||
@ -426,7 +420,6 @@ FileClose (
|
||||
if (Fcb->Info.FileSize < Fcb->Info.PhysicalSize) {
|
||||
TruncateFile (Fcb->FileName, Fcb->Info.FileSize);
|
||||
}
|
||||
|
||||
FreePool (Fcb->FileName);
|
||||
}
|
||||
|
||||
@ -448,7 +441,7 @@ FileClose (
|
||||
**/
|
||||
EFI_STATUS
|
||||
FileDelete (
|
||||
IN EFI_FILE *This
|
||||
IN EFI_FILE *This
|
||||
)
|
||||
{
|
||||
SEMIHOST_FCB *Fcb;
|
||||
@ -478,7 +471,6 @@ FileDelete (
|
||||
if (RETURN_ERROR (Return)) {
|
||||
return EFI_WARN_DELETE_FAILURE;
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
} else {
|
||||
return EFI_WARN_DELETE_FAILURE;
|
||||
@ -574,15 +566,14 @@ ExtendFile (
|
||||
}
|
||||
|
||||
Remaining = Size;
|
||||
ZeroMem (WriteBuffer, sizeof (WriteBuffer));
|
||||
SetMem (WriteBuffer, 0, sizeof(WriteBuffer));
|
||||
while (Remaining > 0) {
|
||||
WriteNb = MIN (Remaining, sizeof (WriteBuffer));
|
||||
WriteNb = MIN (Remaining, sizeof(WriteBuffer));
|
||||
WriteSize = WriteNb;
|
||||
Return = SemihostFileWrite (Fcb->SemihostHandle, &WriteSize, WriteBuffer);
|
||||
Return = SemihostFileWrite (Fcb->SemihostHandle, &WriteSize, WriteBuffer);
|
||||
if (RETURN_ERROR (Return)) {
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
Remaining -= WriteNb;
|
||||
}
|
||||
|
||||
@ -608,9 +599,9 @@ ExtendFile (
|
||||
**/
|
||||
EFI_STATUS
|
||||
FileWrite (
|
||||
IN EFI_FILE *This,
|
||||
IN OUT UINTN *BufferSize,
|
||||
IN VOID *Buffer
|
||||
IN EFI_FILE *This,
|
||||
IN OUT UINTN *BufferSize,
|
||||
IN VOID *Buffer
|
||||
)
|
||||
{
|
||||
SEMIHOST_FCB *Fcb;
|
||||
@ -626,9 +617,8 @@ FileWrite (
|
||||
Fcb = SEMIHOST_FCB_FROM_THIS (This);
|
||||
|
||||
// We cannot write a read-only file
|
||||
if ( (Fcb->Info.Attribute & EFI_FILE_READ_ONLY)
|
||||
|| !(Fcb->OpenMode & EFI_FILE_MODE_WRITE))
|
||||
{
|
||||
if ((Fcb->Info.Attribute & EFI_FILE_READ_ONLY)
|
||||
|| !(Fcb->OpenMode & EFI_FILE_MODE_WRITE)) {
|
||||
return EFI_ACCESS_DENIED;
|
||||
}
|
||||
|
||||
@ -642,12 +632,11 @@ FileWrite (
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
Fcb->Info.FileSize = Fcb->Position;
|
||||
}
|
||||
|
||||
WriteSize = *BufferSize;
|
||||
Return = SemihostFileWrite (Fcb->SemihostHandle, &WriteSize, Buffer);
|
||||
Return = SemihostFileWrite (Fcb->SemihostHandle, &WriteSize, Buffer);
|
||||
if (RETURN_ERROR (Return)) {
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
@ -661,7 +650,6 @@ FileWrite (
|
||||
if (RETURN_ERROR (Return)) {
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
Fcb->Info.PhysicalSize = Length;
|
||||
|
||||
return EFI_SUCCESS;
|
||||
@ -680,17 +668,17 @@ FileWrite (
|
||||
**/
|
||||
EFI_STATUS
|
||||
FileGetPosition (
|
||||
IN EFI_FILE *This,
|
||||
OUT UINT64 *Position
|
||||
IN EFI_FILE *This,
|
||||
OUT UINT64 *Position
|
||||
)
|
||||
{
|
||||
SEMIHOST_FCB *Fcb;
|
||||
SEMIHOST_FCB *Fcb;
|
||||
|
||||
if ((This == NULL) || (Position == NULL)) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Fcb = SEMIHOST_FCB_FROM_THIS (This);
|
||||
Fcb = SEMIHOST_FCB_FROM_THIS(This);
|
||||
|
||||
*Position = Fcb->Position;
|
||||
|
||||
@ -713,8 +701,8 @@ FileGetPosition (
|
||||
**/
|
||||
EFI_STATUS
|
||||
FileSetPosition (
|
||||
IN EFI_FILE *This,
|
||||
IN UINT64 Position
|
||||
IN EFI_FILE *This,
|
||||
IN UINT64 Position
|
||||
)
|
||||
{
|
||||
SEMIHOST_FCB *Fcb;
|
||||
@ -730,7 +718,8 @@ FileSetPosition (
|
||||
if (Position != 0) {
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
//
|
||||
// UEFI Spec section 12.5:
|
||||
// "Seeking to position 0xFFFFFFFFFFFFFFFF causes the current position to
|
||||
@ -739,7 +728,6 @@ FileSetPosition (
|
||||
if (Position == 0xFFFFFFFFFFFFFFFF) {
|
||||
Position = Fcb->Info.FileSize;
|
||||
}
|
||||
|
||||
Return = SemihostFileSeek (Fcb->SemihostHandle, MIN (Position, Fcb->Info.FileSize));
|
||||
if (RETURN_ERROR (Return)) {
|
||||
return EFI_DEVICE_ERROR;
|
||||
@ -772,14 +760,14 @@ GetFileInfo (
|
||||
OUT VOID *Buffer
|
||||
)
|
||||
{
|
||||
EFI_FILE_INFO *Info;
|
||||
UINTN NameSize;
|
||||
UINTN ResultSize;
|
||||
UINTN Index;
|
||||
EFI_FILE_INFO *Info;
|
||||
UINTN NameSize;
|
||||
UINTN ResultSize;
|
||||
UINTN Index;
|
||||
|
||||
if (Fcb->IsRoot) {
|
||||
NameSize = 0;
|
||||
ResultSize = SIZE_OF_EFI_FILE_INFO + sizeof (CHAR16);
|
||||
NameSize = 0;
|
||||
ResultSize = SIZE_OF_EFI_FILE_INFO + sizeof(CHAR16);
|
||||
} else {
|
||||
NameSize = AsciiStrLen (Fcb->FileName) + 1;
|
||||
ResultSize = SIZE_OF_EFI_FILE_INFO + NameSize * sizeof (CHAR16);
|
||||
@ -799,7 +787,7 @@ GetFileInfo (
|
||||
Info->Size = ResultSize;
|
||||
|
||||
if (Fcb->IsRoot) {
|
||||
Info->FileName[0] = L'\0';
|
||||
Info->FileName[0] = L'\0';
|
||||
} else {
|
||||
for (Index = 0; Index < NameSize; Index++) {
|
||||
Info->FileName[Index] = Fcb->FileName[Index];
|
||||
@ -830,9 +818,9 @@ GetFileInfo (
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
GetFilesystemInfo (
|
||||
IN SEMIHOST_FCB *Fcb,
|
||||
IN OUT UINTN *BufferSize,
|
||||
OUT VOID *Buffer
|
||||
IN SEMIHOST_FCB *Fcb,
|
||||
IN OUT UINTN *BufferSize,
|
||||
OUT VOID *Buffer
|
||||
)
|
||||
{
|
||||
EFI_FILE_SYSTEM_INFO *Info;
|
||||
@ -894,19 +882,18 @@ FileGetInfo (
|
||||
OUT VOID *Buffer
|
||||
)
|
||||
{
|
||||
SEMIHOST_FCB *Fcb;
|
||||
EFI_STATUS Status;
|
||||
UINTN ResultSize;
|
||||
SEMIHOST_FCB *Fcb;
|
||||
EFI_STATUS Status;
|
||||
UINTN ResultSize;
|
||||
|
||||
if ((This == NULL) ||
|
||||
(InformationType == NULL) ||
|
||||
(BufferSize == NULL) ||
|
||||
((Buffer == NULL) && (*BufferSize > 0)))
|
||||
{
|
||||
((Buffer == NULL) && (*BufferSize > 0)) ) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Fcb = SEMIHOST_FCB_FROM_THIS (This);
|
||||
Fcb = SEMIHOST_FCB_FROM_THIS(This);
|
||||
|
||||
if (CompareGuid (InformationType, &gEfiFileSystemInfoGuid)) {
|
||||
Status = GetFilesystemInfo (Fcb, BufferSize, Buffer);
|
||||
@ -976,12 +963,11 @@ SetFileInfo (
|
||||
return EFI_ACCESS_DENIED;
|
||||
}
|
||||
|
||||
Length = StrLen (Info->FileName) + 1;
|
||||
Length = StrLen (Info->FileName) + 1;
|
||||
AsciiFileName = AllocatePool (Length);
|
||||
if (AsciiFileName == NULL) {
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
UnicodeStrToAsciiStrS (Info->FileName, AsciiFileName, Length);
|
||||
|
||||
FileSizeIsDifferent = (Info->FileSize != Fcb->Info.FileSize);
|
||||
@ -999,8 +985,7 @@ SetFileInfo (
|
||||
// description.
|
||||
//
|
||||
if ((Fcb->OpenMode == EFI_FILE_MODE_READ) ||
|
||||
(Fcb->Info.Attribute & EFI_FILE_READ_ONLY))
|
||||
{
|
||||
(Fcb->Info.Attribute & EFI_FILE_READ_ONLY) ) {
|
||||
if (FileSizeIsDifferent || FileNameIsDifferent || ReadOnlyIsDifferent) {
|
||||
Status = EFI_ACCESS_DENIED;
|
||||
goto Error;
|
||||
@ -1021,7 +1006,6 @@ SetFileInfo (
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto Error;
|
||||
}
|
||||
|
||||
//
|
||||
// The read/write position from the host file system point of view
|
||||
// is at the end of the file. If the position from this module
|
||||
@ -1032,14 +1016,12 @@ SetFileInfo (
|
||||
FileSetPosition (&Fcb->File, Fcb->Position);
|
||||
}
|
||||
}
|
||||
|
||||
Fcb->Info.FileSize = FileSize;
|
||||
|
||||
Return = SemihostFileLength (Fcb->SemihostHandle, &Length);
|
||||
if (RETURN_ERROR (Return)) {
|
||||
goto Error;
|
||||
}
|
||||
|
||||
Fcb->Info.PhysicalSize = Length;
|
||||
}
|
||||
|
||||
@ -1066,7 +1048,6 @@ SetFileInfo (
|
||||
if (RETURN_ERROR (Return)) {
|
||||
goto Error;
|
||||
}
|
||||
|
||||
FreePool (Fcb->FileName);
|
||||
Fcb->FileName = AsciiFileName;
|
||||
AsciiFileName = NULL;
|
||||
@ -1138,24 +1119,19 @@ FileSetInfo (
|
||||
if (Info->Size < (SIZE_OF_EFI_FILE_INFO + StrSize (Info->FileName))) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (BufferSize < Info->Size) {
|
||||
return EFI_BAD_BUFFER_SIZE;
|
||||
}
|
||||
|
||||
return SetFileInfo (Fcb, Info);
|
||||
} else if (CompareGuid (InformationType, &gEfiFileSystemInfoGuid)) {
|
||||
SystemInfo = Buffer;
|
||||
if (SystemInfo->Size <
|
||||
(SIZE_OF_EFI_FILE_SYSTEM_INFO + StrSize (SystemInfo->VolumeLabel)))
|
||||
{
|
||||
(SIZE_OF_EFI_FILE_SYSTEM_INFO + StrSize (SystemInfo->VolumeLabel))) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (BufferSize < SystemInfo->Size) {
|
||||
return EFI_BAD_BUFFER_SIZE;
|
||||
}
|
||||
|
||||
Buffer = SystemInfo->VolumeLabel;
|
||||
|
||||
if (StrSize (Buffer) > 0) {
|
||||
@ -1179,19 +1155,18 @@ FileSetInfo (
|
||||
|
||||
EFI_STATUS
|
||||
FileFlush (
|
||||
IN EFI_FILE *File
|
||||
IN EFI_FILE *File
|
||||
)
|
||||
{
|
||||
SEMIHOST_FCB *Fcb;
|
||||
SEMIHOST_FCB *Fcb;
|
||||
|
||||
Fcb = SEMIHOST_FCB_FROM_THIS (File);
|
||||
Fcb = SEMIHOST_FCB_FROM_THIS(File);
|
||||
|
||||
if (Fcb->IsRoot) {
|
||||
return EFI_SUCCESS;
|
||||
} else {
|
||||
if ( (Fcb->Info.Attribute & EFI_FILE_READ_ONLY)
|
||||
|| !(Fcb->OpenMode & EFI_FILE_MODE_WRITE))
|
||||
{
|
||||
if ((Fcb->Info.Attribute & EFI_FILE_READ_ONLY)
|
||||
|| !(Fcb->OpenMode & EFI_FILE_MODE_WRITE)) {
|
||||
return EFI_ACCESS_DENIED;
|
||||
} else {
|
||||
return EFI_SUCCESS;
|
||||
@ -1201,11 +1176,11 @@ FileFlush (
|
||||
|
||||
EFI_STATUS
|
||||
SemihostFsEntryPoint (
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
IN EFI_SYSTEM_TABLE *SystemTable
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
IN EFI_SYSTEM_TABLE *SystemTable
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_STATUS Status;
|
||||
|
||||
Status = EFI_NOT_FOUND;
|
||||
|
||||
@ -1217,14 +1192,12 @@ SemihostFsEntryPoint (
|
||||
|
||||
Status = gBS->InstallMultipleProtocolInterfaces (
|
||||
&gInstallHandle,
|
||||
&gEfiSimpleFileSystemProtocolGuid,
|
||||
&gSemihostFs,
|
||||
&gEfiDevicePathProtocolGuid,
|
||||
&gDevicePath,
|
||||
&gEfiSimpleFileSystemProtocolGuid, &gSemihostFs,
|
||||
&gEfiDevicePathProtocolGuid, &gDevicePath,
|
||||
NULL
|
||||
);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
if (EFI_ERROR(Status)) {
|
||||
FreePool (mSemihostFsLabel);
|
||||
}
|
||||
}
|
||||
|
@ -12,8 +12,8 @@
|
||||
|
||||
EFI_STATUS
|
||||
VolumeOpen (
|
||||
IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *This,
|
||||
OUT EFI_FILE **Root
|
||||
IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *This,
|
||||
OUT EFI_FILE **Root
|
||||
);
|
||||
|
||||
/**
|
||||
@ -79,7 +79,7 @@ FileClose (
|
||||
**/
|
||||
EFI_STATUS
|
||||
FileDelete (
|
||||
IN EFI_FILE *This
|
||||
IN EFI_FILE *This
|
||||
);
|
||||
|
||||
/**
|
||||
@ -127,9 +127,9 @@ FileRead (
|
||||
**/
|
||||
EFI_STATUS
|
||||
FileWrite (
|
||||
IN EFI_FILE *This,
|
||||
IN OUT UINTN *BufferSize,
|
||||
IN VOID *Buffer
|
||||
IN EFI_FILE *This,
|
||||
IN OUT UINTN *BufferSize,
|
||||
IN VOID *Buffer
|
||||
);
|
||||
|
||||
/**
|
||||
@ -145,8 +145,8 @@ FileWrite (
|
||||
**/
|
||||
EFI_STATUS
|
||||
FileGetPosition (
|
||||
IN EFI_FILE *File,
|
||||
OUT UINT64 *Position
|
||||
IN EFI_FILE *File,
|
||||
OUT UINT64 *Position
|
||||
);
|
||||
|
||||
/**
|
||||
@ -164,8 +164,8 @@ FileGetPosition (
|
||||
**/
|
||||
EFI_STATUS
|
||||
FileSetPosition (
|
||||
IN EFI_FILE *File,
|
||||
IN UINT64 Position
|
||||
IN EFI_FILE *File,
|
||||
IN UINT64 Position
|
||||
);
|
||||
|
||||
/**
|
||||
@ -239,7 +239,8 @@ FileSetInfo (
|
||||
|
||||
EFI_STATUS
|
||||
FileFlush (
|
||||
IN EFI_FILE *File
|
||||
IN EFI_FILE *File
|
||||
);
|
||||
|
||||
#endif // SEMIHOST_FS_H_
|
||||
|
||||
|
23
ArmPkg/Include/AsmMacroExport.inc
Normal file
23
ArmPkg/Include/AsmMacroExport.inc
Normal file
@ -0,0 +1,23 @@
|
||||
;%HEADER%
|
||||
;/** @file
|
||||
; Macros to centralize the EXPORT, AREA, and definition of an assembly
|
||||
; function. The AREA prefix is required to put the function in its own
|
||||
; section so that removal of unused functions in the final link is performed.
|
||||
; This provides equivalent functionality to the compiler's --split-sections
|
||||
; option.
|
||||
;
|
||||
; Copyright (c) 2015 HP Development Company, L.P.
|
||||
;
|
||||
; SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
;
|
||||
;**/
|
||||
|
||||
|
||||
MACRO
|
||||
RVCT_ASM_EXPORT $func
|
||||
EXPORT $func
|
||||
AREA s_$func, CODE, READONLY
|
||||
$func
|
||||
MEND
|
||||
|
||||
END
|
@ -9,6 +9,7 @@
|
||||
|
||||
**/
|
||||
|
||||
|
||||
#ifndef ASM_MACRO_IO_LIB_H_
|
||||
#define ASM_MACRO_IO_LIB_H_
|
||||
|
||||
@ -19,7 +20,7 @@
|
||||
.p2align 2 ; \
|
||||
Name:
|
||||
|
||||
#define ASM_FUNC(Name) _ASM_FUNC(ASM_PFX(Name), .text. ## Name)
|
||||
#define ASM_FUNC(Name) _ASM_FUNC(ASM_PFX(Name), .text. ## Name)
|
||||
|
||||
#define MOV32(Reg, Val) \
|
||||
movw Reg, #(Val) & 0xffff ; \
|
||||
|
@ -9,6 +9,7 @@
|
||||
|
||||
**/
|
||||
|
||||
|
||||
#ifndef ASM_MACRO_IO_LIBV8_H_
|
||||
#define ASM_MACRO_IO_LIBV8_H_
|
||||
|
||||
@ -23,6 +24,7 @@
|
||||
cbnz SAFE_XREG, 1f ;\
|
||||
b . ;// We should never get here
|
||||
|
||||
|
||||
// CurrentEL : 0xC = EL3; 8 = EL2; 4 = EL1
|
||||
// This only selects between EL1 and EL2 and EL3, else we die.
|
||||
// Provide the Macro with a safe temp xreg to use.
|
||||
@ -38,21 +40,9 @@
|
||||
.global Name ; \
|
||||
.section #Section, "ax" ; \
|
||||
.type Name, %function ; \
|
||||
Name: ; \
|
||||
AARCH64_BTI(c)
|
||||
Name:
|
||||
|
||||
#define _ASM_FUNC_ALIGN(Name, Section, Align) \
|
||||
.global Name ; \
|
||||
.section #Section, "ax" ; \
|
||||
.type Name, %function ; \
|
||||
.balign Align ; \
|
||||
Name: ; \
|
||||
AARCH64_BTI(c)
|
||||
|
||||
#define ASM_FUNC(Name) _ASM_FUNC(ASM_PFX(Name), .text. ## Name)
|
||||
|
||||
#define ASM_FUNC_ALIGN(Name, Align) \
|
||||
_ASM_FUNC_ALIGN(ASM_PFX(Name), .text. ## Name, Align)
|
||||
#define ASM_FUNC(Name) _ASM_FUNC(ASM_PFX(Name), .text. ## Name)
|
||||
|
||||
#define MOV32(Reg, Val) \
|
||||
movz Reg, (Val) >> 16, lsl #16 ; \
|
||||
|
@ -13,119 +13,108 @@
|
||||
#include <Chipset/AArch64Mmu.h>
|
||||
|
||||
// ARM Interrupt ID in Exception Table
|
||||
#define ARM_ARCH_EXCEPTION_IRQ EXCEPT_AARCH64_IRQ
|
||||
#define ARM_ARCH_EXCEPTION_IRQ EXCEPT_AARCH64_IRQ
|
||||
|
||||
// CPACR - Coprocessor Access Control Register definitions
|
||||
#define CPACR_TTA_EN (1UL << 28)
|
||||
#define CPACR_FPEN_EL1 (1UL << 20)
|
||||
#define CPACR_FPEN_FULL (3UL << 20)
|
||||
#define CPACR_CP_FULL_ACCESS 0x300000
|
||||
#define CPACR_TTA_EN (1UL << 28)
|
||||
#define CPACR_FPEN_EL1 (1UL << 20)
|
||||
#define CPACR_FPEN_FULL (3UL << 20)
|
||||
#define CPACR_CP_FULL_ACCESS 0x300000
|
||||
|
||||
// Coprocessor Trap Register (CPTR)
|
||||
#define AARCH64_CPTR_TFP (1 << 10)
|
||||
|
||||
// ID_AA64MMFR1 - AArch64 Memory Model Feature Register 0 definitions
|
||||
#define AARCH64_MMFR1_VH (0xF << 8)
|
||||
#define AARCH64_CPTR_TFP (1 << 10)
|
||||
|
||||
// ID_AA64PFR0 - AArch64 Processor Feature Register 0 definitions
|
||||
#define AARCH64_PFR0_FP (0xF << 16)
|
||||
#define AARCH64_PFR0_GIC (0xF << 24)
|
||||
|
||||
// ID_AA64DFR0 - AArch64 Debug Feature Register 0 definitions
|
||||
#define AARCH64_DFR0_TRACEVER (0xFULL << 4)
|
||||
#define AARCH64_DFR0_TRBE (0xFULL << 44)
|
||||
#define AARCH64_PFR0_FP (0xF << 16)
|
||||
#define AARCH64_PFR0_GIC (0xF << 24)
|
||||
|
||||
// SCR - Secure Configuration Register definitions
|
||||
#define SCR_NS (1 << 0)
|
||||
#define SCR_IRQ (1 << 1)
|
||||
#define SCR_FIQ (1 << 2)
|
||||
#define SCR_EA (1 << 3)
|
||||
#define SCR_FW (1 << 4)
|
||||
#define SCR_AW (1 << 5)
|
||||
#define SCR_NS (1 << 0)
|
||||
#define SCR_IRQ (1 << 1)
|
||||
#define SCR_FIQ (1 << 2)
|
||||
#define SCR_EA (1 << 3)
|
||||
#define SCR_FW (1 << 4)
|
||||
#define SCR_AW (1 << 5)
|
||||
|
||||
// MIDR - Main ID Register definitions
|
||||
#define ARM_CPU_TYPE_SHIFT 4
|
||||
#define ARM_CPU_TYPE_MASK 0xFFF
|
||||
#define ARM_CPU_TYPE_AEMV8 0xD0F
|
||||
#define ARM_CPU_TYPE_A53 0xD03
|
||||
#define ARM_CPU_TYPE_A57 0xD07
|
||||
#define ARM_CPU_TYPE_A72 0xD08
|
||||
#define ARM_CPU_TYPE_A15 0xC0F
|
||||
#define ARM_CPU_TYPE_A9 0xC09
|
||||
#define ARM_CPU_TYPE_A7 0xC07
|
||||
#define ARM_CPU_TYPE_A5 0xC05
|
||||
#define ARM_CPU_TYPE_SHIFT 4
|
||||
#define ARM_CPU_TYPE_MASK 0xFFF
|
||||
#define ARM_CPU_TYPE_AEMV8 0xD0F
|
||||
#define ARM_CPU_TYPE_A53 0xD03
|
||||
#define ARM_CPU_TYPE_A57 0xD07
|
||||
#define ARM_CPU_TYPE_A72 0xD08
|
||||
#define ARM_CPU_TYPE_A15 0xC0F
|
||||
#define ARM_CPU_TYPE_A9 0xC09
|
||||
#define ARM_CPU_TYPE_A7 0xC07
|
||||
#define ARM_CPU_TYPE_A5 0xC05
|
||||
|
||||
#define ARM_CPU_REV_MASK ((0xF << 20) | (0xF) )
|
||||
#define ARM_CPU_REV(rn, pn) ((((rn) & 0xF) << 20) | ((pn) & 0xF))
|
||||
#define ARM_CPU_REV_MASK ((0xF << 20) | (0xF) )
|
||||
#define ARM_CPU_REV(rn, pn) ((((rn) & 0xF) << 20) | ((pn) & 0xF))
|
||||
|
||||
// Hypervisor Configuration Register
|
||||
#define ARM_HCR_FMO BIT3
|
||||
#define ARM_HCR_IMO BIT4
|
||||
#define ARM_HCR_AMO BIT5
|
||||
#define ARM_HCR_TSC BIT19
|
||||
#define ARM_HCR_TGE BIT27
|
||||
#define ARM_HCR_FMO BIT3
|
||||
#define ARM_HCR_IMO BIT4
|
||||
#define ARM_HCR_AMO BIT5
|
||||
#define ARM_HCR_TSC BIT19
|
||||
#define ARM_HCR_TGE BIT27
|
||||
|
||||
// Exception Syndrome Register
|
||||
#define AARCH64_ESR_EC(Ecr) ((0x3F << 26) & (Ecr))
|
||||
#define AARCH64_ESR_ISS(Ecr) ((0x1FFFFFF) & (Ecr))
|
||||
#define AARCH64_ESR_EC(Ecr) ((0x3F << 26) & (Ecr))
|
||||
#define AARCH64_ESR_ISS(Ecr) ((0x1FFFFFF) & (Ecr))
|
||||
|
||||
#define AARCH64_ESR_EC_SMC32 (0x13 << 26)
|
||||
#define AARCH64_ESR_EC_SMC64 (0x17 << 26)
|
||||
#define AARCH64_ESR_EC_SMC32 (0x13 << 26)
|
||||
#define AARCH64_ESR_EC_SMC64 (0x17 << 26)
|
||||
|
||||
// AArch64 Exception Level
|
||||
#define AARCH64_EL3 0xC
|
||||
#define AARCH64_EL2 0x8
|
||||
#define AARCH64_EL1 0x4
|
||||
#define AARCH64_EL3 0xC
|
||||
#define AARCH64_EL2 0x8
|
||||
#define AARCH64_EL1 0x4
|
||||
|
||||
// Saved Program Status Register definitions
|
||||
#define SPSR_A BIT8
|
||||
#define SPSR_I BIT7
|
||||
#define SPSR_F BIT6
|
||||
#define SPSR_A BIT8
|
||||
#define SPSR_I BIT7
|
||||
#define SPSR_F BIT6
|
||||
|
||||
#define SPSR_AARCH32 BIT4
|
||||
#define SPSR_AARCH32 BIT4
|
||||
|
||||
#define SPSR_AARCH32_MODE_USER 0x0
|
||||
#define SPSR_AARCH32_MODE_FIQ 0x1
|
||||
#define SPSR_AARCH32_MODE_IRQ 0x2
|
||||
#define SPSR_AARCH32_MODE_SVC 0x3
|
||||
#define SPSR_AARCH32_MODE_ABORT 0x7
|
||||
#define SPSR_AARCH32_MODE_UNDEF 0xB
|
||||
#define SPSR_AARCH32_MODE_SYS 0xF
|
||||
#define SPSR_AARCH32_MODE_USER 0x0
|
||||
#define SPSR_AARCH32_MODE_FIQ 0x1
|
||||
#define SPSR_AARCH32_MODE_IRQ 0x2
|
||||
#define SPSR_AARCH32_MODE_SVC 0x3
|
||||
#define SPSR_AARCH32_MODE_ABORT 0x7
|
||||
#define SPSR_AARCH32_MODE_UNDEF 0xB
|
||||
#define SPSR_AARCH32_MODE_SYS 0xF
|
||||
|
||||
// Counter-timer Hypervisor Control register definitions
|
||||
#define CNTHCTL_EL2_EL1PCTEN BIT0
|
||||
#define CNTHCTL_EL2_EL1PCEN BIT1
|
||||
#define CNTHCTL_EL2_EL1PCTEN BIT0
|
||||
#define CNTHCTL_EL2_EL1PCEN BIT1
|
||||
|
||||
#define ARM_VECTOR_TABLE_ALIGNMENT ((1 << 11)-1)
|
||||
#define ARM_VECTOR_TABLE_ALIGNMENT ((1 << 11)-1)
|
||||
|
||||
// Vector table offset definitions
|
||||
#define ARM_VECTOR_CUR_SP0_SYNC 0x000
|
||||
#define ARM_VECTOR_CUR_SP0_IRQ 0x080
|
||||
#define ARM_VECTOR_CUR_SP0_FIQ 0x100
|
||||
#define ARM_VECTOR_CUR_SP0_SERR 0x180
|
||||
#define ARM_VECTOR_CUR_SP0_SYNC 0x000
|
||||
#define ARM_VECTOR_CUR_SP0_IRQ 0x080
|
||||
#define ARM_VECTOR_CUR_SP0_FIQ 0x100
|
||||
#define ARM_VECTOR_CUR_SP0_SERR 0x180
|
||||
|
||||
#define ARM_VECTOR_CUR_SPX_SYNC 0x200
|
||||
#define ARM_VECTOR_CUR_SPX_IRQ 0x280
|
||||
#define ARM_VECTOR_CUR_SPX_FIQ 0x300
|
||||
#define ARM_VECTOR_CUR_SPX_SERR 0x380
|
||||
#define ARM_VECTOR_CUR_SPX_SYNC 0x200
|
||||
#define ARM_VECTOR_CUR_SPX_IRQ 0x280
|
||||
#define ARM_VECTOR_CUR_SPX_FIQ 0x300
|
||||
#define ARM_VECTOR_CUR_SPX_SERR 0x380
|
||||
|
||||
#define ARM_VECTOR_LOW_A64_SYNC 0x400
|
||||
#define ARM_VECTOR_LOW_A64_IRQ 0x480
|
||||
#define ARM_VECTOR_LOW_A64_FIQ 0x500
|
||||
#define ARM_VECTOR_LOW_A64_SERR 0x580
|
||||
#define ARM_VECTOR_LOW_A64_SYNC 0x400
|
||||
#define ARM_VECTOR_LOW_A64_IRQ 0x480
|
||||
#define ARM_VECTOR_LOW_A64_FIQ 0x500
|
||||
#define ARM_VECTOR_LOW_A64_SERR 0x580
|
||||
|
||||
#define ARM_VECTOR_LOW_A32_SYNC 0x600
|
||||
#define ARM_VECTOR_LOW_A32_IRQ 0x680
|
||||
#define ARM_VECTOR_LOW_A32_FIQ 0x700
|
||||
#define ARM_VECTOR_LOW_A32_SERR 0x780
|
||||
|
||||
// The ID_AA64ISAR2_EL1 register is not recognized by older
|
||||
// assemblers, we need to define it here.
|
||||
#define ID_AA64ISAR2_EL1 S3_0_C0_C6_2
|
||||
#define ARM_VECTOR_LOW_A32_SYNC 0x600
|
||||
#define ARM_VECTOR_LOW_A32_IRQ 0x680
|
||||
#define ARM_VECTOR_LOW_A32_FIQ 0x700
|
||||
#define ARM_VECTOR_LOW_A32_SERR 0x780
|
||||
|
||||
// The ID_AA64MMFR2_EL1 register was added in ARMv8.2. Since we
|
||||
// build for ARMv8.0, we need to define the register here.
|
||||
#define ID_AA64MMFR2_EL1 S3_0_C0_C7_2
|
||||
#define ID_AA64MMFR2_EL1 S3_0_C0_C7_2
|
||||
|
||||
#define VECTOR_BASE(tbl) \
|
||||
.section .text.##tbl##,"ax"; \
|
||||
@ -162,7 +151,7 @@ ArmReadTpidrurw (
|
||||
VOID
|
||||
EFIAPI
|
||||
ArmWriteTpidrurw (
|
||||
UINTN Value
|
||||
UINTN Value
|
||||
);
|
||||
|
||||
UINTN
|
||||
@ -174,7 +163,7 @@ ArmGetTCR (
|
||||
VOID
|
||||
EFIAPI
|
||||
ArmSetTCR (
|
||||
UINTN Value
|
||||
UINTN Value
|
||||
);
|
||||
|
||||
UINTN
|
||||
@ -186,7 +175,7 @@ ArmGetMAIR (
|
||||
VOID
|
||||
EFIAPI
|
||||
ArmSetMAIR (
|
||||
UINTN Value
|
||||
UINTN Value
|
||||
);
|
||||
|
||||
VOID
|
||||
@ -221,7 +210,7 @@ ArmDisableAllExceptions (
|
||||
|
||||
VOID
|
||||
ArmWriteHcr (
|
||||
IN UINTN Hcr
|
||||
IN UINTN Hcr
|
||||
);
|
||||
|
||||
UINTN
|
||||
@ -236,7 +225,7 @@ ArmReadCurrentEL (
|
||||
|
||||
UINTN
|
||||
ArmWriteCptr (
|
||||
IN UINT64 Cptr
|
||||
IN UINT64 Cptr
|
||||
);
|
||||
|
||||
UINT32
|
||||
@ -246,7 +235,7 @@ ArmReadCntHctl (
|
||||
|
||||
VOID
|
||||
ArmWriteCntHctl (
|
||||
IN UINT32 CntHctl
|
||||
IN UINT32 CntHctl
|
||||
);
|
||||
|
||||
#endif // AARCH64_H_
|
||||
|
@ -12,12 +12,12 @@
|
||||
//
|
||||
// Memory Attribute Indirection register Definitions
|
||||
//
|
||||
#define MAIR_ATTR_DEVICE_MEMORY 0x0ULL
|
||||
#define MAIR_ATTR_NORMAL_MEMORY_NON_CACHEABLE 0x44ULL
|
||||
#define MAIR_ATTR_NORMAL_MEMORY_WRITE_THROUGH 0xBBULL
|
||||
#define MAIR_ATTR_NORMAL_MEMORY_WRITE_BACK 0xFFULL
|
||||
#define MAIR_ATTR_DEVICE_MEMORY 0x0ULL
|
||||
#define MAIR_ATTR_NORMAL_MEMORY_NON_CACHEABLE 0x44ULL
|
||||
#define MAIR_ATTR_NORMAL_MEMORY_WRITE_THROUGH 0xBBULL
|
||||
#define MAIR_ATTR_NORMAL_MEMORY_WRITE_BACK 0xFFULL
|
||||
|
||||
#define MAIR_ATTR(n, value) ((value) << (((n) >> 2)*8))
|
||||
#define MAIR_ATTR(n,value) ((value) << (((n) >> 2)*8))
|
||||
|
||||
//
|
||||
// Long-descriptor Translation Table format
|
||||
@ -27,7 +27,7 @@
|
||||
// The first offset starts at 12bit. There are 4 levels of 9-bit address range from level 3 to level 0
|
||||
#define TT_ADDRESS_OFFSET_AT_LEVEL(TableLevel) (12 + ((3 - (TableLevel)) * 9))
|
||||
|
||||
#define TT_BLOCK_ENTRY_SIZE_AT_LEVEL(Level) (1ULL << TT_ADDRESS_OFFSET_AT_LEVEL(Level))
|
||||
#define TT_BLOCK_ENTRY_SIZE_AT_LEVEL(Level) (1ULL << TT_ADDRESS_OFFSET_AT_LEVEL(Level))
|
||||
|
||||
// Get the associated entry in the given Translation Table
|
||||
#define TT_GET_ENTRY_FOR_ADDRESS(TranslationTable, Level, Address) \
|
||||
@ -35,161 +35,164 @@
|
||||
|
||||
// Return the smallest address granularity from the table level.
|
||||
// The first offset starts at 12bit. There are 4 levels of 9-bit address range from level 3 to level 0
|
||||
#define TT_ADDRESS_AT_LEVEL(TableLevel) (1ULL << TT_ADDRESS_OFFSET_AT_LEVEL(TableLevel))
|
||||
#define TT_ADDRESS_AT_LEVEL(TableLevel) (1ULL << TT_ADDRESS_OFFSET_AT_LEVEL(TableLevel))
|
||||
|
||||
#define TT_LAST_BLOCK_ADDRESS(TranslationTable, EntryCount) \
|
||||
((UINT64*)((EFI_PHYSICAL_ADDRESS)(TranslationTable) + (((EntryCount) - 1) * sizeof(UINT64))))
|
||||
|
||||
// There are 512 entries per table when 4K Granularity
|
||||
#define TT_ENTRY_COUNT 512
|
||||
#define TT_ALIGNMENT_BLOCK_ENTRY BIT12
|
||||
#define TT_ALIGNMENT_DESCRIPTION_TABLE BIT12
|
||||
#define TT_ENTRY_COUNT 512
|
||||
#define TT_ALIGNMENT_BLOCK_ENTRY BIT12
|
||||
#define TT_ALIGNMENT_DESCRIPTION_TABLE BIT12
|
||||
|
||||
#define TT_ADDRESS_MASK_BLOCK_ENTRY (0xFFFFFFFFFULL << 12)
|
||||
#define TT_ADDRESS_MASK_DESCRIPTION_TABLE (0xFFFFFFFFFULL << 12)
|
||||
#define TT_ADDRESS_MASK_BLOCK_ENTRY (0xFFFFFFFFFULL << 12)
|
||||
#define TT_ADDRESS_MASK_DESCRIPTION_TABLE (0xFFFFFFFFFULL << 12)
|
||||
|
||||
#define TT_TYPE_MASK 0x3
|
||||
#define TT_TYPE_TABLE_ENTRY 0x3
|
||||
#define TT_TYPE_BLOCK_ENTRY 0x1
|
||||
#define TT_TYPE_BLOCK_ENTRY_LEVEL3 0x3
|
||||
#define TT_TYPE_MASK 0x3
|
||||
#define TT_TYPE_TABLE_ENTRY 0x3
|
||||
#define TT_TYPE_BLOCK_ENTRY 0x1
|
||||
#define TT_TYPE_BLOCK_ENTRY_LEVEL3 0x3
|
||||
|
||||
#define TT_ATTR_INDX_MASK (0x7 << 2)
|
||||
#define TT_ATTR_INDX_DEVICE_MEMORY (0x0 << 2)
|
||||
#define TT_ATTR_INDX_MEMORY_NON_CACHEABLE (0x1 << 2)
|
||||
#define TT_ATTR_INDX_MEMORY_WRITE_THROUGH (0x2 << 2)
|
||||
#define TT_ATTR_INDX_MEMORY_WRITE_BACK (0x3 << 2)
|
||||
#define TT_ATTR_INDX_MASK (0x7 << 2)
|
||||
#define TT_ATTR_INDX_DEVICE_MEMORY (0x0 << 2)
|
||||
#define TT_ATTR_INDX_MEMORY_NON_CACHEABLE (0x1 << 2)
|
||||
#define TT_ATTR_INDX_MEMORY_WRITE_THROUGH (0x2 << 2)
|
||||
#define TT_ATTR_INDX_MEMORY_WRITE_BACK (0x3 << 2)
|
||||
|
||||
#define TT_AP_MASK (0x3UL << 6)
|
||||
#define TT_AP_NO_RW (0x0UL << 6)
|
||||
#define TT_AP_RW_RW (0x1UL << 6)
|
||||
#define TT_AP_NO_RO (0x2UL << 6)
|
||||
#define TT_AP_RO_RO (0x3UL << 6)
|
||||
#define TT_AP_MASK (0x3UL << 6)
|
||||
#define TT_AP_NO_RW (0x0UL << 6)
|
||||
#define TT_AP_RW_RW (0x1UL << 6)
|
||||
#define TT_AP_NO_RO (0x2UL << 6)
|
||||
#define TT_AP_RO_RO (0x3UL << 6)
|
||||
|
||||
#define TT_NS BIT5
|
||||
#define TT_AF BIT10
|
||||
#define TT_NS BIT5
|
||||
#define TT_AF BIT10
|
||||
|
||||
#define TT_SH_NON_SHAREABLE (0x0 << 8)
|
||||
#define TT_SH_OUTER_SHAREABLE (0x2 << 8)
|
||||
#define TT_SH_INNER_SHAREABLE (0x3 << 8)
|
||||
#define TT_SH_MASK (0x3 << 8)
|
||||
#define TT_SH_NON_SHAREABLE (0x0 << 8)
|
||||
#define TT_SH_OUTER_SHAREABLE (0x2 << 8)
|
||||
#define TT_SH_INNER_SHAREABLE (0x3 << 8)
|
||||
#define TT_SH_MASK (0x3 << 8)
|
||||
|
||||
#define TT_PXN_MASK BIT53
|
||||
#define TT_UXN_MASK BIT54 // EL1&0
|
||||
#define TT_XN_MASK BIT54 // EL2 / EL3
|
||||
#define TT_PXN_MASK BIT53
|
||||
#define TT_UXN_MASK BIT54 // EL1&0
|
||||
#define TT_XN_MASK BIT54 // EL2 / EL3
|
||||
|
||||
#define TT_ATTRIBUTES_MASK ((0xFFFULL << 52) | (0x3FFULL << 2))
|
||||
#define TT_ATTRIBUTES_MASK ((0xFFFULL << 52) | (0x3FFULL << 2))
|
||||
|
||||
#define TT_TABLE_PXN BIT59
|
||||
#define TT_TABLE_UXN BIT60 // EL1&0
|
||||
#define TT_TABLE_XN BIT60 // EL2 / EL3
|
||||
#define TT_TABLE_NS BIT63
|
||||
#define TT_TABLE_PXN BIT59
|
||||
#define TT_TABLE_UXN BIT60 // EL1&0
|
||||
#define TT_TABLE_XN BIT60 // EL2 / EL3
|
||||
#define TT_TABLE_NS BIT63
|
||||
|
||||
#define TT_TABLE_AP_MASK (BIT62 | BIT61)
|
||||
#define TT_TABLE_AP_NO_PERMISSION (0x0ULL << 61)
|
||||
#define TT_TABLE_AP_EL0_NO_ACCESS (0x1ULL << 61)
|
||||
#define TT_TABLE_AP_NO_WRITE_ACCESS (0x2ULL << 61)
|
||||
#define TT_TABLE_AP_MASK (BIT62 | BIT61)
|
||||
#define TT_TABLE_AP_NO_PERMISSION (0x0ULL << 61)
|
||||
#define TT_TABLE_AP_EL0_NO_ACCESS (0x1ULL << 61)
|
||||
#define TT_TABLE_AP_NO_WRITE_ACCESS (0x2ULL << 61)
|
||||
|
||||
//
|
||||
// Translation Control Register
|
||||
//
|
||||
#define TCR_T0SZ_MASK 0x3FUL
|
||||
#define TCR_T0SZ_MASK 0x3FUL
|
||||
|
||||
#define TCR_PS_4GB (0UL << 16)
|
||||
#define TCR_PS_64GB (1UL << 16)
|
||||
#define TCR_PS_1TB (2UL << 16)
|
||||
#define TCR_PS_4TB (3UL << 16)
|
||||
#define TCR_PS_16TB (4UL << 16)
|
||||
#define TCR_PS_256TB (5UL << 16)
|
||||
#define TCR_PS_4GB (0UL << 16)
|
||||
#define TCR_PS_64GB (1UL << 16)
|
||||
#define TCR_PS_1TB (2UL << 16)
|
||||
#define TCR_PS_4TB (3UL << 16)
|
||||
#define TCR_PS_16TB (4UL << 16)
|
||||
#define TCR_PS_256TB (5UL << 16)
|
||||
|
||||
#define TCR_TG0_4KB (0UL << 14)
|
||||
#define TCR_TG1_4KB (2UL << 30)
|
||||
#define TCR_TG0_4KB (0UL << 14)
|
||||
#define TCR_TG1_4KB (2UL << 30)
|
||||
|
||||
#define TCR_IPS_4GB (0ULL << 32)
|
||||
#define TCR_IPS_64GB (1ULL << 32)
|
||||
#define TCR_IPS_1TB (2ULL << 32)
|
||||
#define TCR_IPS_4TB (3ULL << 32)
|
||||
#define TCR_IPS_16TB (4ULL << 32)
|
||||
#define TCR_IPS_256TB (5ULL << 32)
|
||||
#define TCR_IPS_4GB (0ULL << 32)
|
||||
#define TCR_IPS_64GB (1ULL << 32)
|
||||
#define TCR_IPS_1TB (2ULL << 32)
|
||||
#define TCR_IPS_4TB (3ULL << 32)
|
||||
#define TCR_IPS_16TB (4ULL << 32)
|
||||
#define TCR_IPS_256TB (5ULL << 32)
|
||||
|
||||
#define TCR_EPD1 (1UL << 23)
|
||||
#define TCR_EPD1 (1UL << 23)
|
||||
|
||||
#define TTBR_ASID_FIELD (48)
|
||||
#define TTBR_ASID_MASK (0xFF << TTBR_ASID_FIELD)
|
||||
#define TTBR_BADDR_MASK (0xFFFFFFFFFFFF ) // The width of this field depends on the values in TxSZ. Addr occupies bottom 48bits
|
||||
#define TTBR_ASID_FIELD (48)
|
||||
#define TTBR_ASID_MASK (0xFF << TTBR_ASID_FIELD)
|
||||
#define TTBR_BADDR_MASK (0xFFFFFFFFFFFF ) // The width of this field depends on the values in TxSZ. Addr occupies bottom 48bits
|
||||
|
||||
#define TCR_EL1_T0SZ_FIELD (0)
|
||||
#define TCR_EL1_EPD0_FIELD (7)
|
||||
#define TCR_EL1_IRGN0_FIELD (8)
|
||||
#define TCR_EL1_ORGN0_FIELD (10)
|
||||
#define TCR_EL1_SH0_FIELD (12)
|
||||
#define TCR_EL1_TG0_FIELD (14)
|
||||
#define TCR_EL1_T1SZ_FIELD (16)
|
||||
#define TCR_EL1_A1_FIELD (22)
|
||||
#define TCR_EL1_EPD1_FIELD (23)
|
||||
#define TCR_EL1_IRGN1_FIELD (24)
|
||||
#define TCR_EL1_ORGN1_FIELD (26)
|
||||
#define TCR_EL1_SH1_FIELD (28)
|
||||
#define TCR_EL1_TG1_FIELD (30)
|
||||
#define TCR_EL1_IPS_FIELD (32)
|
||||
#define TCR_EL1_AS_FIELD (36)
|
||||
#define TCR_EL1_TBI0_FIELD (37)
|
||||
#define TCR_EL1_TBI1_FIELD (38)
|
||||
#define TCR_EL1_T0SZ_MASK (0x1FUL << TCR_EL1_T0SZ_FIELD)
|
||||
#define TCR_EL1_EPD0_MASK (0x01UL << TCR_EL1_EPD0_FIELD)
|
||||
#define TCR_EL1_IRGN0_MASK (0x03UL << TCR_EL1_IRGN0_FIELD)
|
||||
#define TCR_EL1_ORGN0_MASK (0x03UL << TCR_EL1_ORGN0_FIELD)
|
||||
#define TCR_EL1_SH0_MASK (0x03UL << TCR_EL1_SH0_FIELD)
|
||||
#define TCR_EL1_TG0_MASK (0x01UL << TCR_EL1_TG0_FIELD)
|
||||
#define TCR_EL1_T1SZ_MASK (0x1FUL << TCR_EL1_T1SZ_FIELD)
|
||||
#define TCR_EL1_A1_MASK (0x01UL << TCR_EL1_A1_FIELD)
|
||||
#define TCR_EL1_EPD1_MASK (0x01UL << TCR_EL1_EPD1_FIELD)
|
||||
#define TCR_EL1_IRGN1_MASK (0x03UL << TCR_EL1_IRGN1_FIELD)
|
||||
#define TCR_EL1_ORGN1_MASK (0x03UL << TCR_EL1_ORGN1_FIELD)
|
||||
#define TCR_EL1_SH1_MASK (0x03UL << TCR_EL1_SH1_FIELD)
|
||||
#define TCR_EL1_TG1_MASK (0x01UL << TCR_EL1_TG1_FIELD)
|
||||
#define TCR_EL1_IPS_MASK (0x07UL << TCR_EL1_IPS_FIELD)
|
||||
#define TCR_EL1_AS_MASK (0x01UL << TCR_EL1_AS_FIELD)
|
||||
#define TCR_EL1_TBI0_MASK (0x01UL << TCR_EL1_TBI0_FIELD)
|
||||
#define TCR_EL1_TBI1_MASK (0x01UL << TCR_EL1_TBI1_FIELD)
|
||||
#define TCR_EL1_T0SZ_FIELD (0)
|
||||
#define TCR_EL1_EPD0_FIELD (7)
|
||||
#define TCR_EL1_IRGN0_FIELD (8)
|
||||
#define TCR_EL1_ORGN0_FIELD (10)
|
||||
#define TCR_EL1_SH0_FIELD (12)
|
||||
#define TCR_EL1_TG0_FIELD (14)
|
||||
#define TCR_EL1_T1SZ_FIELD (16)
|
||||
#define TCR_EL1_A1_FIELD (22)
|
||||
#define TCR_EL1_EPD1_FIELD (23)
|
||||
#define TCR_EL1_IRGN1_FIELD (24)
|
||||
#define TCR_EL1_ORGN1_FIELD (26)
|
||||
#define TCR_EL1_SH1_FIELD (28)
|
||||
#define TCR_EL1_TG1_FIELD (30)
|
||||
#define TCR_EL1_IPS_FIELD (32)
|
||||
#define TCR_EL1_AS_FIELD (36)
|
||||
#define TCR_EL1_TBI0_FIELD (37)
|
||||
#define TCR_EL1_TBI1_FIELD (38)
|
||||
#define TCR_EL1_T0SZ_MASK (0x1FUL << TCR_EL1_T0SZ_FIELD)
|
||||
#define TCR_EL1_EPD0_MASK (0x01UL << TCR_EL1_EPD0_FIELD)
|
||||
#define TCR_EL1_IRGN0_MASK (0x03UL << TCR_EL1_IRGN0_FIELD)
|
||||
#define TCR_EL1_ORGN0_MASK (0x03UL << TCR_EL1_ORGN0_FIELD)
|
||||
#define TCR_EL1_SH0_MASK (0x03UL << TCR_EL1_SH0_FIELD)
|
||||
#define TCR_EL1_TG0_MASK (0x01UL << TCR_EL1_TG0_FIELD)
|
||||
#define TCR_EL1_T1SZ_MASK (0x1FUL << TCR_EL1_T1SZ_FIELD)
|
||||
#define TCR_EL1_A1_MASK (0x01UL << TCR_EL1_A1_FIELD)
|
||||
#define TCR_EL1_EPD1_MASK (0x01UL << TCR_EL1_EPD1_FIELD)
|
||||
#define TCR_EL1_IRGN1_MASK (0x03UL << TCR_EL1_IRGN1_FIELD)
|
||||
#define TCR_EL1_ORGN1_MASK (0x03UL << TCR_EL1_ORGN1_FIELD)
|
||||
#define TCR_EL1_SH1_MASK (0x03UL << TCR_EL1_SH1_FIELD)
|
||||
#define TCR_EL1_TG1_MASK (0x01UL << TCR_EL1_TG1_FIELD)
|
||||
#define TCR_EL1_IPS_MASK (0x07UL << TCR_EL1_IPS_FIELD)
|
||||
#define TCR_EL1_AS_MASK (0x01UL << TCR_EL1_AS_FIELD)
|
||||
#define TCR_EL1_TBI0_MASK (0x01UL << TCR_EL1_TBI0_FIELD)
|
||||
#define TCR_EL1_TBI1_MASK (0x01UL << TCR_EL1_TBI1_FIELD)
|
||||
|
||||
#define TCR_EL23_T0SZ_FIELD (0)
|
||||
#define TCR_EL23_IRGN0_FIELD (8)
|
||||
#define TCR_EL23_ORGN0_FIELD (10)
|
||||
#define TCR_EL23_SH0_FIELD (12)
|
||||
#define TCR_EL23_TG0_FIELD (14)
|
||||
#define TCR_EL23_PS_FIELD (16)
|
||||
#define TCR_EL23_T0SZ_MASK (0x1FUL << TCR_EL23_T0SZ_FIELD)
|
||||
#define TCR_EL23_IRGN0_MASK (0x03UL << TCR_EL23_IRGN0_FIELD)
|
||||
#define TCR_EL23_ORGN0_MASK (0x03UL << TCR_EL23_ORGN0_FIELD)
|
||||
#define TCR_EL23_SH0_MASK (0x03UL << TCR_EL23_SH0_FIELD)
|
||||
#define TCR_EL23_TG0_MASK (0x01UL << TCR_EL23_TG0_FIELD)
|
||||
#define TCR_EL23_PS_MASK (0x07UL << TCR_EL23_PS_FIELD)
|
||||
|
||||
#define TCR_RGN_OUTER_NON_CACHEABLE (0x0UL << 10)
|
||||
#define TCR_RGN_OUTER_WRITE_BACK_ALLOC (0x1UL << 10)
|
||||
#define TCR_RGN_OUTER_WRITE_THROUGH (0x2UL << 10)
|
||||
#define TCR_RGN_OUTER_WRITE_BACK_NO_ALLOC (0x3UL << 10)
|
||||
#define TCR_EL23_T0SZ_FIELD (0)
|
||||
#define TCR_EL23_IRGN0_FIELD (8)
|
||||
#define TCR_EL23_ORGN0_FIELD (10)
|
||||
#define TCR_EL23_SH0_FIELD (12)
|
||||
#define TCR_EL23_TG0_FIELD (14)
|
||||
#define TCR_EL23_PS_FIELD (16)
|
||||
#define TCR_EL23_T0SZ_MASK (0x1FUL << TCR_EL23_T0SZ_FIELD)
|
||||
#define TCR_EL23_IRGN0_MASK (0x03UL << TCR_EL23_IRGN0_FIELD)
|
||||
#define TCR_EL23_ORGN0_MASK (0x03UL << TCR_EL23_ORGN0_FIELD)
|
||||
#define TCR_EL23_SH0_MASK (0x03UL << TCR_EL23_SH0_FIELD)
|
||||
#define TCR_EL23_TG0_MASK (0x01UL << TCR_EL23_TG0_FIELD)
|
||||
#define TCR_EL23_PS_MASK (0x07UL << TCR_EL23_PS_FIELD)
|
||||
|
||||
#define TCR_RGN_INNER_NON_CACHEABLE (0x0UL << 8)
|
||||
#define TCR_RGN_INNER_WRITE_BACK_ALLOC (0x1UL << 8)
|
||||
#define TCR_RGN_INNER_WRITE_THROUGH (0x2UL << 8)
|
||||
#define TCR_RGN_INNER_WRITE_BACK_NO_ALLOC (0x3UL << 8)
|
||||
|
||||
#define TCR_SH_NON_SHAREABLE (0x0UL << 12)
|
||||
#define TCR_SH_OUTER_SHAREABLE (0x2UL << 12)
|
||||
#define TCR_SH_INNER_SHAREABLE (0x3UL << 12)
|
||||
#define TCR_RGN_OUTER_NON_CACHEABLE (0x0UL << 10)
|
||||
#define TCR_RGN_OUTER_WRITE_BACK_ALLOC (0x1UL << 10)
|
||||
#define TCR_RGN_OUTER_WRITE_THROUGH (0x2UL << 10)
|
||||
#define TCR_RGN_OUTER_WRITE_BACK_NO_ALLOC (0x3UL << 10)
|
||||
|
||||
#define TCR_PASZ_32BITS_4GB (0x0UL)
|
||||
#define TCR_PASZ_36BITS_64GB (0x1UL)
|
||||
#define TCR_PASZ_40BITS_1TB (0x2UL)
|
||||
#define TCR_PASZ_42BITS_4TB (0x3UL)
|
||||
#define TCR_PASZ_44BITS_16TB (0x4UL)
|
||||
#define TCR_PASZ_48BITS_256TB (0x5UL)
|
||||
#define TCR_RGN_INNER_NON_CACHEABLE (0x0UL << 8)
|
||||
#define TCR_RGN_INNER_WRITE_BACK_ALLOC (0x1UL << 8)
|
||||
#define TCR_RGN_INNER_WRITE_THROUGH (0x2UL << 8)
|
||||
#define TCR_RGN_INNER_WRITE_BACK_NO_ALLOC (0x3UL << 8)
|
||||
|
||||
#define TCR_SH_NON_SHAREABLE (0x0UL << 12)
|
||||
#define TCR_SH_OUTER_SHAREABLE (0x2UL << 12)
|
||||
#define TCR_SH_INNER_SHAREABLE (0x3UL << 12)
|
||||
|
||||
#define TCR_PASZ_32BITS_4GB (0x0UL)
|
||||
#define TCR_PASZ_36BITS_64GB (0x1UL)
|
||||
#define TCR_PASZ_40BITS_1TB (0x2UL)
|
||||
#define TCR_PASZ_42BITS_4TB (0x3UL)
|
||||
#define TCR_PASZ_44BITS_16TB (0x4UL)
|
||||
#define TCR_PASZ_48BITS_256TB (0x5UL)
|
||||
|
||||
// The value written to the T*SZ fields are defined as 2^(64-T*SZ). So a 39Bit
|
||||
// Virtual address range for 512GB of virtual space sets T*SZ to 25
|
||||
#define INPUT_ADDRESS_SIZE_TO_TXSZ(a) (64 - a)
|
||||
#define INPUT_ADDRESS_SIZE_TO_TXSZ(a) (64 - a)
|
||||
|
||||
// Uses LPAE Page Table format
|
||||
|
||||
#endif // AARCH64_MMU_H_
|
||||
|
||||
|
44
ArmPkg/Include/Chipset/ArmCortexA5x.h
Normal file
44
ArmPkg/Include/Chipset/ArmCortexA5x.h
Normal file
@ -0,0 +1,44 @@
|
||||
/** @file
|
||||
|
||||
Copyright (c) 2012 - 2021, Arm Limited. All rights reserved.<BR>
|
||||
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
**/
|
||||
|
||||
#ifndef ARM_CORTEX_A5X_H_
|
||||
#define ARM_CORTEX_A5X_H_
|
||||
|
||||
//
|
||||
// Cortex A5x feature bit definitions
|
||||
//
|
||||
#define A5X_FEATURE_SMP (1 << 6)
|
||||
|
||||
//
|
||||
// Helper functions to access CPU Extended Control Register
|
||||
//
|
||||
UINT64
|
||||
EFIAPI
|
||||
ArmReadCpuExCr (
|
||||
VOID
|
||||
);
|
||||
|
||||
VOID
|
||||
EFIAPI
|
||||
ArmWriteCpuExCr (
|
||||
IN UINT64 Val
|
||||
);
|
||||
|
||||
VOID
|
||||
EFIAPI
|
||||
ArmSetCpuExCrBit (
|
||||
IN UINT64 Bits
|
||||
);
|
||||
|
||||
VOID
|
||||
EFIAPI
|
||||
ArmUnsetCpuExCrBit (
|
||||
IN UINT64 Bits
|
||||
);
|
||||
|
||||
#endif // ARM_CORTEX_A5X_H_
|
59
ArmPkg/Include/Chipset/ArmCortexA9.h
Normal file
59
ArmPkg/Include/Chipset/ArmCortexA9.h
Normal file
@ -0,0 +1,59 @@
|
||||
/** @file
|
||||
|
||||
Copyright (c) 2011, ARM Limited. All rights reserved.
|
||||
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
**/
|
||||
|
||||
#ifndef ARM_CORTEX_A9_H_
|
||||
#define ARM_CORTEX_A9_H_
|
||||
|
||||
#include <Chipset/ArmV7.h>
|
||||
|
||||
//
|
||||
// Cortex A9 feature bit definitions
|
||||
//
|
||||
#define A9_FEATURE_PARITY (1<<9)
|
||||
#define A9_FEATURE_AOW (1<<8)
|
||||
#define A9_FEATURE_EXCL (1<<7)
|
||||
#define A9_FEATURE_SMP (1<<6)
|
||||
#define A9_FEATURE_FOZ (1<<3)
|
||||
#define A9_FEATURE_DPREF (1<<2)
|
||||
#define A9_FEATURE_HINT (1<<1)
|
||||
#define A9_FEATURE_FWD (1<<0)
|
||||
|
||||
//
|
||||
// Cortex A9 Watchdog
|
||||
//
|
||||
#define ARM_A9_WATCHDOG_REGION 0x600
|
||||
|
||||
#define ARM_A9_WATCHDOG_LOAD_REGISTER 0x20
|
||||
#define ARM_A9_WATCHDOG_CONTROL_REGISTER 0x28
|
||||
|
||||
#define ARM_A9_WATCHDOG_WATCHDOG_MODE (1 << 3)
|
||||
#define ARM_A9_WATCHDOG_TIMER_MODE (0 << 3)
|
||||
#define ARM_A9_WATCHDOG_SINGLE_SHOT (0 << 1)
|
||||
#define ARM_A9_WATCHDOG_AUTORELOAD (1 << 1)
|
||||
#define ARM_A9_WATCHDOG_ENABLE 1
|
||||
|
||||
//
|
||||
// SCU register offsets & masks
|
||||
//
|
||||
#define A9_SCU_CONTROL_OFFSET 0x0
|
||||
#define A9_SCU_CONFIG_OFFSET 0x4
|
||||
#define A9_SCU_INVALL_OFFSET 0xC
|
||||
#define A9_SCU_FILT_START_OFFSET 0x40
|
||||
#define A9_SCU_FILT_END_OFFSET 0x44
|
||||
#define A9_SCU_SACR_OFFSET 0x50
|
||||
#define A9_SCU_SSACR_OFFSET 0x54
|
||||
|
||||
|
||||
UINTN
|
||||
EFIAPI
|
||||
ArmGetScuBaseAddress (
|
||||
VOID
|
||||
);
|
||||
|
||||
#endif // ARM_CORTEX_A9_H_
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user