Compare commits
	
		
			99 Commits
		
	
	
		
			edk2-stabl
			...
			dev/ec-fmp
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					153b1e1afb | ||
| 
						 | 
					102042deda | ||
| 
						 | 
					045b938884 | ||
| 
						 | 
					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"
 | 
			
		||||
							
								
								
									
										350
									
								
								.github/workflows/codeql.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										350
									
								
								.github/workflows/codeql.yml
									
									
									
									
										vendored
									
									
								
							@@ -1,350 +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@v4
 | 
			
		||||
      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: 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@v3
 | 
			
		||||
      if: (success() || failure()) && steps.get_ci_file_operations.outputs.setup_supported == 'true'
 | 
			
		||||
      with:
 | 
			
		||||
        name: ${{ matrix.Package }}-Logs
 | 
			
		||||
        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@v3
 | 
			
		||||
      if: (success() || failure()) && steps.get_ci_file_operations.outputs.ci_setup_supported == 'true'
 | 
			
		||||
      with:
 | 
			
		||||
        name: ${{ matrix.Package }}-Logs
 | 
			
		||||
        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@v3
 | 
			
		||||
      if: success() || failure()
 | 
			
		||||
      with:
 | 
			
		||||
        name: ${{ matrix.Package }}-Logs
 | 
			
		||||
        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@v3
 | 
			
		||||
      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@v3
 | 
			
		||||
      if: success() || failure()
 | 
			
		||||
      with:
 | 
			
		||||
        name: ${{ matrix.Package }}-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@v3
 | 
			
		||||
      if: steps.env_data.outputs.upload_sarif_file == 'true'
 | 
			
		||||
      with:
 | 
			
		||||
        name: ${{ matrix.Package }}-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@v2
 | 
			
		||||
      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 }}
 | 
			
		||||
							
								
								
									
										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
 | 
			
		||||
							
								
								
									
										15
									
								
								.gitmodules
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										15
									
								
								.gitmodules
									
									
									
									
										vendored
									
									
								
							@@ -20,18 +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
 | 
			
		||||
 
 | 
			
		||||
@@ -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,14 +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))
 | 
			
		||||
        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))
 | 
			
		||||
            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")
 | 
			
		||||
        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:
 | 
			
		||||
                # Delete temp directory
 | 
			
		||||
                if os.path.exists(temp_path):
 | 
			
		||||
                    shutil.rmtree(temp_path)
 | 
			
		||||
            tc.SetSuccess()
 | 
			
		||||
            self.RemoveFile(ecc_log)
 | 
			
		||||
            return 0
 | 
			
		||||
        else:
 | 
			
		||||
            with open(ecc_log, encoding='utf8') as output:
 | 
			
		||||
                ecc_output = output.readlines()
 | 
			
		||||
                for line in ecc_output:
 | 
			
		||||
                    logging.error(line.strip())
 | 
			
		||||
                # 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
 | 
			
		||||
            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:
 | 
			
		||||
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.
 | 
			
		||||
* Detailed reports and logs per package are captured in the `Build` directory.
 | 
			
		||||
     * 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,16 +131,6 @@
 | 
			
		||||
  # Define if the GICv3 controller should use the GICv2 legacy
 | 
			
		||||
  gArmTokenSpaceGuid.PcdArmGicV3WithV2Legacy|FALSE|BOOLEAN|0x00000042
 | 
			
		||||
 | 
			
		||||
  ## Define the conduit to use for monitor calls.
 | 
			
		||||
  # Default PcdMonitorConduitHvc = FALSE, conduit = SMC
 | 
			
		||||
  # If PcdMonitorConduitHvc = TRUE, conduit = HVC
 | 
			
		||||
  gArmTokenSpaceGuid.PcdMonitorConduitHvc|FALSE|BOOLEAN|0x00000047
 | 
			
		||||
 | 
			
		||||
  # 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
 | 
			
		||||
@@ -226,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
 | 
			
		||||
@@ -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
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -24,11 +24,9 @@ ArmCrashDumpDxeInitialize (
 | 
			
		||||
  EFI_STATUS      Status;
 | 
			
		||||
 | 
			
		||||
  Status = gBS->LocateProtocol (&gEfiCpuArchProtocolGuid, NULL, (VOID **)&mCpu);
 | 
			
		||||
  ASSERT_EFI_ERROR (Status);
 | 
			
		||||
  ASSERT_EFI_ERROR(Status);
 | 
			
		||||
 | 
			
		||||
  return mCpu->RegisterInterruptHandler (
 | 
			
		||||
                 mCpu,
 | 
			
		||||
  return mCpu->RegisterInterruptHandler (mCpu,
 | 
			
		||||
                                         EXCEPT_AARCH64_SYNCHRONOUS_EXCEPTIONS,
 | 
			
		||||
                 &DefaultExceptionHandler
 | 
			
		||||
                 );
 | 
			
		||||
                                         &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,6 +8,20 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
 | 
			
		||||
 | 
			
		||||
#include "ArmGicDxe.h"
 | 
			
		||||
 | 
			
		||||
VOID
 | 
			
		||||
EFIAPI
 | 
			
		||||
IrqInterruptHandler (
 | 
			
		||||
  IN EFI_EXCEPTION_TYPE           InterruptType,
 | 
			
		||||
  IN EFI_SYSTEM_CONTEXT           SystemContext
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
VOID
 | 
			
		||||
EFIAPI
 | 
			
		||||
ExitBootServicesEvent (
 | 
			
		||||
  IN EFI_EVENT  Event,
 | 
			
		||||
  IN VOID       *Context
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
// Making this global saves a few bytes in image size
 | 
			
		||||
EFI_HANDLE  gHardwareInterruptHandle = NULL;
 | 
			
		||||
 | 
			
		||||
@@ -19,6 +33,7 @@ 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.
 | 
			
		||||
@@ -41,13 +56,13 @@ GicGetDistributorIcfgBaseAndBit (
 | 
			
		||||
  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)
 | 
			
		||||
  *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.
 | 
			
		||||
 | 
			
		||||
@@ -76,7 +93,7 @@ RegisterInterruptSource (
 | 
			
		||||
  )
 | 
			
		||||
{
 | 
			
		||||
  if (Source >= mGicNumInterrupts) {
 | 
			
		||||
    ASSERT (FALSE);
 | 
			
		||||
    ASSERT(FALSE);
 | 
			
		||||
    return EFI_UNSUPPORTED;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@@ -91,7 +108,7 @@ 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);
 | 
			
		||||
@@ -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);
 | 
			
		||||
@@ -157,7 +163,7 @@ InstallAndRegisterInterruptService (
 | 
			
		||||
{
 | 
			
		||||
  EFI_STATUS               Status;
 | 
			
		||||
  CONST UINTN              RihArraySize =
 | 
			
		||||
    (sizeof (HARDWARE_INTERRUPT_HANDLER) * mGicNumInterrupts);
 | 
			
		||||
    (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 (
 | 
			
		||||
 
 | 
			
		||||
@@ -55,6 +55,7 @@ GicV3DxeInitialize (
 | 
			
		||||
  IN EFI_SYSTEM_TABLE   *SystemTable
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// Shared code
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 
 | 
			
		||||
@@ -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))
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -104,17 +104,10 @@ GicGetCpuRedistributorBase (
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
  Return the GIC CPU Interrupt Interface ID.
 | 
			
		||||
 | 
			
		||||
  @param GicInterruptInterfaceBase  Base address of the GIC Interrupt Interface.
 | 
			
		||||
 | 
			
		||||
  @retval CPU Interface Identification information.
 | 
			
		||||
**/
 | 
			
		||||
UINT32
 | 
			
		||||
UINTN
 | 
			
		||||
EFIAPI
 | 
			
		||||
ArmGicGetInterfaceIdentification (
 | 
			
		||||
  IN  UINTN  GicInterruptInterfaceBase
 | 
			
		||||
  IN  INTN          GicInterruptInterfaceBase
 | 
			
		||||
  )
 | 
			
		||||
{
 | 
			
		||||
  // Read the GIC Identification Register
 | 
			
		||||
@@ -124,7 +117,7 @@ ArmGicGetInterfaceIdentification (
 | 
			
		||||
UINTN
 | 
			
		||||
EFIAPI
 | 
			
		||||
ArmGicGetMaxNumInterrupts (
 | 
			
		||||
  IN  UINTN  GicDistributorBase
 | 
			
		||||
  IN  INTN          GicDistributorBase
 | 
			
		||||
  )
 | 
			
		||||
{
 | 
			
		||||
  UINTN ItLines;
 | 
			
		||||
@@ -140,17 +133,15 @@ ArmGicGetMaxNumInterrupts (
 | 
			
		||||
VOID
 | 
			
		||||
EFIAPI
 | 
			
		||||
ArmGicSendSgiTo (
 | 
			
		||||
  IN  UINTN  GicDistributorBase,
 | 
			
		||||
  IN  UINT8  TargetListFilter,
 | 
			
		||||
  IN  UINT8  CPUTargetList,
 | 
			
		||||
  IN  UINT8  SgiId
 | 
			
		||||
  IN  INTN          GicDistributorBase,
 | 
			
		||||
  IN  INTN          TargetListFilter,
 | 
			
		||||
  IN  INTN          CPUTargetList,
 | 
			
		||||
  IN  INTN          SgiId
 | 
			
		||||
  )
 | 
			
		||||
{
 | 
			
		||||
  MmioWrite32 (
 | 
			
		||||
    GicDistributorBase + ARM_GIC_ICDSGIR,
 | 
			
		||||
    ((TargetListFilter & 0x3) << 24) |
 | 
			
		||||
    ((CPUTargetList & 0xFF) << 16)   |
 | 
			
		||||
    (SgiId & 0xF)
 | 
			
		||||
    ((TargetListFilter & 0x3) << 24) | ((CPUTargetList & 0xFF) << 16) | SgiId
 | 
			
		||||
    );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -176,17 +167,19 @@ ArmGicAcknowledgeInterrupt (
 | 
			
		||||
  )
 | 
			
		||||
{
 | 
			
		||||
  UINTN Value;
 | 
			
		||||
  UINTN                  IntId;
 | 
			
		||||
  ARM_GIC_ARCH_REVISION Revision;
 | 
			
		||||
 | 
			
		||||
  ASSERT (InterruptId != NULL);
 | 
			
		||||
  Revision = ArmGicGetSupportedArchRevision ();
 | 
			
		||||
  if (Revision == ARM_GIC_ARCH_REVISION_2) {
 | 
			
		||||
    Value = ArmGicV2AcknowledgeInterrupt (GicInterruptInterfaceBase);
 | 
			
		||||
    IntId = Value & ARM_GIC_ICCIAR_ACKINTID;
 | 
			
		||||
    // InterruptId is required for the caller to know if a valid or spurious
 | 
			
		||||
    // interrupt has been read
 | 
			
		||||
    ASSERT (InterruptId != NULL);
 | 
			
		||||
    if (InterruptId != NULL) {
 | 
			
		||||
      *InterruptId = Value & ARM_GIC_ICCIAR_ACKINTID;
 | 
			
		||||
    }
 | 
			
		||||
  } else if (Revision == ARM_GIC_ARCH_REVISION_3) {
 | 
			
		||||
    Value = ArmGicV3AcknowledgeInterrupt ();
 | 
			
		||||
    IntId = Value;
 | 
			
		||||
  } else {
 | 
			
		||||
    ASSERT_EFI_ERROR (EFI_UNSUPPORTED);
 | 
			
		||||
    // Report Spurious interrupt which is what the above controllers would
 | 
			
		||||
@@ -194,12 +187,6 @@ ArmGicAcknowledgeInterrupt (
 | 
			
		||||
    Value = 1023;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (InterruptId != NULL) {
 | 
			
		||||
    // InterruptId is required for the caller to know if a valid or spurious
 | 
			
		||||
    // interrupt has been read
 | 
			
		||||
    *InterruptId = IntId;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return Value;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -232,19 +219,18 @@ ArmGicSetInterruptPriority (
 | 
			
		||||
  )
 | 
			
		||||
{
 | 
			
		||||
  UINT32                RegOffset;
 | 
			
		||||
  UINT8                  RegShift;
 | 
			
		||||
  UINTN                 RegShift;
 | 
			
		||||
  ARM_GIC_ARCH_REVISION Revision;
 | 
			
		||||
  UINTN                 GicCpuRedistributorBase;
 | 
			
		||||
 | 
			
		||||
  // Calculate register offset and bit position
 | 
			
		||||
  RegOffset = (UINT32)(Source / 4);
 | 
			
		||||
  RegShift  = (UINT8)((Source % 4) * 8);
 | 
			
		||||
  RegOffset = Source / 4;
 | 
			
		||||
  RegShift = (Source % 4) * 8;
 | 
			
		||||
 | 
			
		||||
  Revision = ArmGicGetSupportedArchRevision ();
 | 
			
		||||
  if ((Revision == ARM_GIC_ARCH_REVISION_2) ||
 | 
			
		||||
      FeaturePcdGet (PcdArmGicV3WithV2Legacy) ||
 | 
			
		||||
      SourceIsSpi (Source))
 | 
			
		||||
  {
 | 
			
		||||
      SourceIsSpi (Source)) {
 | 
			
		||||
    MmioAndThenOr32 (
 | 
			
		||||
      GicDistributorBase + ARM_GIC_ICDIPR + (4 * RegOffset),
 | 
			
		||||
      ~(0xff << RegShift),
 | 
			
		||||
@@ -276,19 +262,18 @@ ArmGicEnableInterrupt (
 | 
			
		||||
  )
 | 
			
		||||
{
 | 
			
		||||
  UINT32                RegOffset;
 | 
			
		||||
  UINT8                  RegShift;
 | 
			
		||||
  UINTN                 RegShift;
 | 
			
		||||
  ARM_GIC_ARCH_REVISION Revision;
 | 
			
		||||
  UINTN                 GicCpuRedistributorBase;
 | 
			
		||||
 | 
			
		||||
  // Calculate enable register offset and bit position
 | 
			
		||||
  RegOffset = (UINT32)(Source / 32);
 | 
			
		||||
  RegShift  = (UINT8)(Source % 32);
 | 
			
		||||
  RegOffset = Source / 32;
 | 
			
		||||
  RegShift = Source % 32;
 | 
			
		||||
 | 
			
		||||
  Revision = ArmGicGetSupportedArchRevision ();
 | 
			
		||||
  if ((Revision == ARM_GIC_ARCH_REVISION_2) ||
 | 
			
		||||
      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
 | 
			
		||||
      );
 | 
			
		||||
  }
 | 
			
		||||
@@ -321,19 +306,18 @@ ArmGicDisableInterrupt (
 | 
			
		||||
  )
 | 
			
		||||
{
 | 
			
		||||
  UINT32                RegOffset;
 | 
			
		||||
  UINT8                  RegShift;
 | 
			
		||||
  UINTN                 RegShift;
 | 
			
		||||
  ARM_GIC_ARCH_REVISION Revision;
 | 
			
		||||
  UINTN                 GicCpuRedistributorBase;
 | 
			
		||||
 | 
			
		||||
  // Calculate enable register offset and bit position
 | 
			
		||||
  RegOffset = (UINT32)(Source / 32);
 | 
			
		||||
  RegShift  = (UINT8)(Source % 32);
 | 
			
		||||
  RegOffset = Source / 32;
 | 
			
		||||
  RegShift = Source % 32;
 | 
			
		||||
 | 
			
		||||
  Revision = ArmGicGetSupportedArchRevision ();
 | 
			
		||||
  if ((Revision == ARM_GIC_ARCH_REVISION_2) ||
 | 
			
		||||
      FeaturePcdGet (PcdArmGicV3WithV2Legacy) ||
 | 
			
		||||
      SourceIsSpi (Source))
 | 
			
		||||
  {
 | 
			
		||||
      SourceIsSpi (Source)) {
 | 
			
		||||
    // Write clear-enable register
 | 
			
		||||
    MmioWrite32 (
 | 
			
		||||
      GicDistributorBase + ARM_GIC_ICDICER + (4 * RegOffset),
 | 
			
		||||
@@ -350,7 +334,7 @@ ArmGicDisableInterrupt (
 | 
			
		||||
 | 
			
		||||
    // Write clear-enable register
 | 
			
		||||
    MmioWrite32 (
 | 
			
		||||
      ICENABLER_ADDRESS (GicCpuRedistributorBase, RegOffset),
 | 
			
		||||
      ICENABLER_ADDRESS(GicCpuRedistributorBase, RegOffset),
 | 
			
		||||
      1 << RegShift
 | 
			
		||||
      );
 | 
			
		||||
  }
 | 
			
		||||
@@ -365,23 +349,23 @@ ArmGicIsInterruptEnabled (
 | 
			
		||||
  )
 | 
			
		||||
{
 | 
			
		||||
  UINT32                RegOffset;
 | 
			
		||||
  UINT8                  RegShift;
 | 
			
		||||
  UINTN                 RegShift;
 | 
			
		||||
  ARM_GIC_ARCH_REVISION Revision;
 | 
			
		||||
  UINTN                 GicCpuRedistributorBase;
 | 
			
		||||
  UINT32                Interrupts;
 | 
			
		||||
 | 
			
		||||
  // Calculate enable register offset and bit position
 | 
			
		||||
  RegOffset = (UINT32)(Source / 32);
 | 
			
		||||
  RegShift  = (UINT8)(Source % 32);
 | 
			
		||||
  RegOffset = Source / 32;
 | 
			
		||||
  RegShift = Source % 32;
 | 
			
		||||
 | 
			
		||||
  Revision = ArmGicGetSupportedArchRevision ();
 | 
			
		||||
  if ((Revision == ARM_GIC_ARCH_REVISION_2) ||
 | 
			
		||||
      FeaturePcdGet (PcdArmGicV3WithV2Legacy) ||
 | 
			
		||||
      SourceIsSpi (Source))
 | 
			
		||||
  {
 | 
			
		||||
    Interrupts = MmioRead32 (
 | 
			
		||||
      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,7 +397,7 @@ ArmGicDisableDistributor (
 | 
			
		||||
VOID
 | 
			
		||||
EFIAPI
 | 
			
		||||
ArmGicEnableInterruptInterface (
 | 
			
		||||
  IN  UINTN  GicInterruptInterfaceBase
 | 
			
		||||
  IN  INTN          GicInterruptInterfaceBase
 | 
			
		||||
  )
 | 
			
		||||
{
 | 
			
		||||
  ARM_GIC_ARCH_REVISION Revision;
 | 
			
		||||
@@ -431,7 +415,7 @@ ArmGicEnableInterruptInterface (
 | 
			
		||||
VOID
 | 
			
		||||
EFIAPI
 | 
			
		||||
ArmGicDisableInterruptInterface (
 | 
			
		||||
  IN  UINTN  GicInterruptInterfaceBase
 | 
			
		||||
  IN  INTN          GicInterruptInterfaceBase
 | 
			
		||||
  )
 | 
			
		||||
{
 | 
			
		||||
  ARM_GIC_ARCH_REVISION Revision;
 | 
			
		||||
 
 | 
			
		||||
@@ -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;
 | 
			
		||||
 | 
			
		||||
  /*
 | 
			
		||||
   * 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
 | 
			
		||||
 | 
			
		||||
@@ -25,8 +25,8 @@ Abstract:
 | 
			
		||||
extern EFI_HARDWARE_INTERRUPT_PROTOCOL gHardwareInterruptV2Protocol;
 | 
			
		||||
extern EFI_HARDWARE_INTERRUPT2_PROTOCOL gHardwareInterrupt2V2Protocol;
 | 
			
		||||
 | 
			
		||||
STATIC UINTN  mGicInterruptInterfaceBase;
 | 
			
		||||
STATIC UINTN  mGicDistributorBase;
 | 
			
		||||
STATIC UINT32 mGicInterruptInterfaceBase;
 | 
			
		||||
STATIC UINT32 mGicDistributorBase;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
  Enable interrupt source Source.
 | 
			
		||||
@@ -47,7 +47,7 @@ GicV2EnableInterruptSource (
 | 
			
		||||
  )
 | 
			
		||||
{
 | 
			
		||||
  if (Source >= mGicNumInterrupts) {
 | 
			
		||||
    ASSERT (FALSE);
 | 
			
		||||
    ASSERT(FALSE);
 | 
			
		||||
    return EFI_UNSUPPORTED;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@@ -75,7 +75,7 @@ GicV2DisableInterruptSource (
 | 
			
		||||
  )
 | 
			
		||||
{
 | 
			
		||||
  if (Source >= mGicNumInterrupts) {
 | 
			
		||||
    ASSERT (FALSE);
 | 
			
		||||
    ASSERT(FALSE);
 | 
			
		||||
    return EFI_UNSUPPORTED;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@@ -105,7 +105,7 @@ GicV2GetInterruptSourceState (
 | 
			
		||||
  )
 | 
			
		||||
{
 | 
			
		||||
  if (Source >= mGicNumInterrupts) {
 | 
			
		||||
    ASSERT (FALSE);
 | 
			
		||||
    ASSERT(FALSE);
 | 
			
		||||
    return EFI_UNSUPPORTED;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@@ -134,7 +134,7 @@ GicV2EndOfInterrupt (
 | 
			
		||||
  )
 | 
			
		||||
{
 | 
			
		||||
  if (Source >= mGicNumInterrupts) {
 | 
			
		||||
    ASSERT (FALSE);
 | 
			
		||||
    ASSERT(FALSE);
 | 
			
		||||
    return EFI_UNSUPPORTED;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@@ -162,7 +162,7 @@ GicV2IrqInterruptHandler (
 | 
			
		||||
  IN EFI_SYSTEM_CONTEXT           SystemContext
 | 
			
		||||
  )
 | 
			
		||||
{
 | 
			
		||||
  UINTN                       GicInterrupt;
 | 
			
		||||
  UINT32                      GicInterrupt;
 | 
			
		||||
  HARDWARE_INTERRUPT_HANDLER  InterruptHandler;
 | 
			
		||||
 | 
			
		||||
  GicInterrupt = ArmGicV2AcknowledgeInterrupt (mGicInterruptInterfaceBase);
 | 
			
		||||
@@ -179,7 +179,7 @@ GicV2IrqInterruptHandler (
 | 
			
		||||
    // Call the registered interrupt handler.
 | 
			
		||||
    InterruptHandler (GicInterrupt, SystemContext);
 | 
			
		||||
  } else {
 | 
			
		||||
    DEBUG ((DEBUG_ERROR, "Spurious GIC interrupt: 0x%x\n", (UINT32)GicInterrupt));
 | 
			
		||||
    DEBUG ((DEBUG_ERROR, "Spurious GIC interrupt: 0x%x\n", GicInterrupt));
 | 
			
		||||
    GicV2EndOfInterrupt (&gHardwareInterruptV2Protocol, GicInterrupt);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -261,13 +261,9 @@ GicV2SetTriggerType (
 | 
			
		||||
  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
 | 
			
		||||
      ));
 | 
			
		||||
      && (TriggerType != EFI_HARDWARE_INTERRUPT2_TRIGGER_LEVEL_HIGH)) {
 | 
			
		||||
          DEBUG ((DEBUG_ERROR, "Invalid interrupt trigger type: %d\n", \
 | 
			
		||||
                  TriggerType));
 | 
			
		||||
          ASSERT (FALSE);
 | 
			
		||||
          return EFI_UNSUPPORTED;
 | 
			
		||||
  }
 | 
			
		||||
@@ -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
 | 
			
		||||
      );
 | 
			
		||||
  }
 | 
			
		||||
@@ -350,7 +346,7 @@ GicV2ExitBootServicesEvent (
 | 
			
		||||
  )
 | 
			
		||||
{
 | 
			
		||||
  UINTN    Index;
 | 
			
		||||
  UINTN  GicInterrupt;
 | 
			
		||||
  UINT32   GicInterrupt;
 | 
			
		||||
 | 
			
		||||
  // Disable all the interrupts
 | 
			
		||||
  for (Index = 0; Index < mGicNumInterrupts; Index++) {
 | 
			
		||||
@@ -393,26 +389,23 @@ GicV2DxeInitialize (
 | 
			
		||||
  EFI_STATUS              Status;
 | 
			
		||||
  UINTN                   Index;
 | 
			
		||||
  UINT32                  RegOffset;
 | 
			
		||||
  UINT8       RegShift;
 | 
			
		||||
  UINTN                   RegShift;
 | 
			
		||||
  UINT32                  CpuTarget;
 | 
			
		||||
 | 
			
		||||
  // Make sure the Interrupt Controller Protocol is not already installed in
 | 
			
		||||
  // the system.
 | 
			
		||||
  ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gHardwareInterruptProtocolGuid);
 | 
			
		||||
 | 
			
		||||
  ASSERT (PcdGet64 (PcdGicInterruptInterfaceBase) <= MAX_UINTN);
 | 
			
		||||
  ASSERT (PcdGet64 (PcdGicDistributorBase) <= MAX_UINTN);
 | 
			
		||||
 | 
			
		||||
  mGicInterruptInterfaceBase = (UINTN)PcdGet64 (PcdGicInterruptInterfaceBase);
 | 
			
		||||
  mGicDistributorBase        = (UINTN)PcdGet64 (PcdGicDistributorBase);
 | 
			
		||||
  mGicInterruptInterfaceBase = PcdGet64 (PcdGicInterruptInterfaceBase);
 | 
			
		||||
  mGicDistributorBase = PcdGet64 (PcdGicDistributorBase);
 | 
			
		||||
  mGicNumInterrupts = ArmGicGetMaxNumInterrupts (mGicDistributorBase);
 | 
			
		||||
 | 
			
		||||
  for (Index = 0; Index < mGicNumInterrupts; Index++) {
 | 
			
		||||
    GicV2DisableInterruptSource (&gHardwareInterruptV2Protocol, Index);
 | 
			
		||||
 | 
			
		||||
    // Set Priority
 | 
			
		||||
    RegOffset = (UINT32)(Index / 4);
 | 
			
		||||
    RegShift  = (UINT8)((Index % 4) * 8);
 | 
			
		||||
    RegOffset = Index / 4;
 | 
			
		||||
    RegShift = (Index % 4) * 8;
 | 
			
		||||
    MmioAndThenOr32 (
 | 
			
		||||
      mGicDistributorBase + ARM_GIC_ICDIPR + (4 * RegOffset),
 | 
			
		||||
      ~(0xff << RegShift),
 | 
			
		||||
 
 | 
			
		||||
@@ -1,13 +1,12 @@
 | 
			
		||||
/** @file
 | 
			
		||||
*
 | 
			
		||||
*  Copyright (c) 2013-2023, ARM Limited. All rights reserved.
 | 
			
		||||
*  Copyright (c) 2013-2014, ARM Limited. All rights reserved.
 | 
			
		||||
*
 | 
			
		||||
*  SPDX-License-Identifier: BSD-2-Clause-Patent
 | 
			
		||||
*
 | 
			
		||||
**/
 | 
			
		||||
 | 
			
		||||
#include <Library/ArmGicLib.h>
 | 
			
		||||
#include <Library/DebugLib.h>
 | 
			
		||||
#include <Library/IoLib.h>
 | 
			
		||||
 | 
			
		||||
UINTN
 | 
			
		||||
@@ -27,6 +26,5 @@ ArmGicV2EndOfInterrupt (
 | 
			
		||||
  IN UINTN                  Source
 | 
			
		||||
  )
 | 
			
		||||
{
 | 
			
		||||
  ASSERT (Source <= MAX_UINT32);
 | 
			
		||||
  MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCEIOR, (UINT32)Source);
 | 
			
		||||
  MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCEIOR, Source);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
*
 | 
			
		||||
@@ -37,7 +37,7 @@ GicV3EnableInterruptSource (
 | 
			
		||||
  )
 | 
			
		||||
{
 | 
			
		||||
  if (Source >= mGicNumInterrupts) {
 | 
			
		||||
    ASSERT (FALSE);
 | 
			
		||||
    ASSERT(FALSE);
 | 
			
		||||
    return EFI_UNSUPPORTED;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@@ -65,7 +65,7 @@ GicV3DisableInterruptSource (
 | 
			
		||||
  )
 | 
			
		||||
{
 | 
			
		||||
  if (Source >= mGicNumInterrupts) {
 | 
			
		||||
    ASSERT (FALSE);
 | 
			
		||||
    ASSERT(FALSE);
 | 
			
		||||
    return EFI_UNSUPPORTED;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@@ -95,7 +95,7 @@ GicV3GetInterruptSourceState (
 | 
			
		||||
  )
 | 
			
		||||
{
 | 
			
		||||
  if (Source >= mGicNumInterrupts) {
 | 
			
		||||
    ASSERT (FALSE);
 | 
			
		||||
    ASSERT(FALSE);
 | 
			
		||||
    return EFI_UNSUPPORTED;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@@ -128,7 +128,7 @@ GicV3EndOfInterrupt (
 | 
			
		||||
  )
 | 
			
		||||
{
 | 
			
		||||
  if (Source >= mGicNumInterrupts) {
 | 
			
		||||
    ASSERT (FALSE);
 | 
			
		||||
    ASSERT(FALSE);
 | 
			
		||||
    return EFI_UNSUPPORTED;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@@ -156,7 +156,7 @@ GicV3IrqInterruptHandler (
 | 
			
		||||
  IN EFI_SYSTEM_CONTEXT           SystemContext
 | 
			
		||||
  )
 | 
			
		||||
{
 | 
			
		||||
  UINTN                       GicInterrupt;
 | 
			
		||||
  UINT32                      GicInterrupt;
 | 
			
		||||
  HARDWARE_INTERRUPT_HANDLER  InterruptHandler;
 | 
			
		||||
 | 
			
		||||
  GicInterrupt = ArmGicV3AcknowledgeInterrupt ();
 | 
			
		||||
@@ -173,7 +173,7 @@ GicV3IrqInterruptHandler (
 | 
			
		||||
    // Call the registered interrupt handler.
 | 
			
		||||
    InterruptHandler (GicInterrupt, SystemContext);
 | 
			
		||||
  } else {
 | 
			
		||||
    DEBUG ((DEBUG_ERROR, "Spurious GIC interrupt: 0x%x\n", (UINT32)GicInterrupt));
 | 
			
		||||
    DEBUG ((DEBUG_ERROR, "Spurious GIC interrupt: 0x%x\n", GicInterrupt));
 | 
			
		||||
    GicV3EndOfInterrupt (&gHardwareInterruptV3Protocol, GicInterrupt);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -255,13 +255,9 @@ GicV3SetTriggerType (
 | 
			
		||||
  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
 | 
			
		||||
      ));
 | 
			
		||||
      && (TriggerType != EFI_HARDWARE_INTERRUPT2_TRIGGER_LEVEL_HIGH)) {
 | 
			
		||||
          DEBUG ((DEBUG_ERROR, "Invalid interrupt trigger type: %d\n", \
 | 
			
		||||
                 TriggerType));
 | 
			
		||||
          ASSERT (FALSE);
 | 
			
		||||
          return EFI_UNSUPPORTED;
 | 
			
		||||
  }
 | 
			
		||||
@@ -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
 | 
			
		||||
      );
 | 
			
		||||
  }
 | 
			
		||||
@@ -348,6 +344,10 @@ GicV3ExitBootServicesEvent (
 | 
			
		||||
    GicV3DisableInterruptSource (&gHardwareInterruptV3Protocol, Index);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  for (Index = 0; Index < mGicNumInterrupts; Index++) {
 | 
			
		||||
    GicV3EndOfInterrupt (&gHardwareInterruptV3Protocol, Index);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Disable Gic Interface
 | 
			
		||||
  ArmGicV3DisableInterruptInterface ();
 | 
			
		||||
 | 
			
		||||
@@ -381,7 +381,7 @@ GicV3DxeInitialize (
 | 
			
		||||
  // the system.
 | 
			
		||||
  ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gHardwareInterruptProtocolGuid);
 | 
			
		||||
 | 
			
		||||
  mGicDistributorBase    = (UINTN)PcdGet64 (PcdGicDistributorBase);
 | 
			
		||||
  mGicDistributorBase    = PcdGet64 (PcdGicDistributorBase);
 | 
			
		||||
  mGicRedistributorsBase = PcdGet64 (PcdGicRedistributorsBase);
 | 
			
		||||
  mGicNumInterrupts      = ArmGicGetMaxNumInterrupts (mGicDistributorBase);
 | 
			
		||||
 | 
			
		||||
@@ -434,8 +434,8 @@ GicV3DxeInitialize (
 | 
			
		||||
 | 
			
		||||
    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)
 | 
			
		||||
 
 | 
			
		||||
@@ -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;
 | 
			
		||||
    }
 | 
			
		||||
@@ -243,7 +242,7 @@ CpuMemoryServiceRead (
 | 
			
		||||
  //
 | 
			
		||||
  InStride = mInStride[Width];
 | 
			
		||||
  OutStride = mOutStride[Width];
 | 
			
		||||
  OperationWidth = (EFI_CPU_IO_PROTOCOL_WIDTH)(Width & 0x03);
 | 
			
		||||
  OperationWidth = (EFI_CPU_IO_PROTOCOL_WIDTH) (Width & 0x03);
 | 
			
		||||
  for (Uint8Buffer = Buffer; Count > 0; Address += InStride, Uint8Buffer += OutStride, Count--) {
 | 
			
		||||
    if (OperationWidth == EfiCpuIoWidthUint8) {
 | 
			
		||||
      *Uint8Buffer = MmioRead8 ((UINTN)Address);
 | 
			
		||||
@@ -255,7 +254,6 @@ CpuMemoryServiceRead (
 | 
			
		||||
      *((UINT64 *)Uint8Buffer) = MmioRead64 ((UINTN)Address);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return EFI_SUCCESS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -325,7 +323,7 @@ CpuMemoryServiceWrite (
 | 
			
		||||
  //
 | 
			
		||||
  InStride = mInStride[Width];
 | 
			
		||||
  OutStride = mOutStride[Width];
 | 
			
		||||
  OperationWidth = (EFI_CPU_IO_PROTOCOL_WIDTH)(Width & 0x03);
 | 
			
		||||
  OperationWidth = (EFI_CPU_IO_PROTOCOL_WIDTH) (Width & 0x03);
 | 
			
		||||
  for (Uint8Buffer = Buffer; Count > 0; Address += InStride, Uint8Buffer += OutStride, Count--) {
 | 
			
		||||
    if (OperationWidth == EfiCpuIoWidthUint8) {
 | 
			
		||||
      MmioWrite8 ((UINTN)Address, *Uint8Buffer);
 | 
			
		||||
@@ -337,7 +335,6 @@ CpuMemoryServiceWrite (
 | 
			
		||||
      MmioWrite64 ((UINTN)Address, *((UINT64 *)Uint8Buffer));
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return EFI_SUCCESS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -409,7 +406,7 @@ CpuIoServiceRead (
 | 
			
		||||
  //
 | 
			
		||||
  InStride = mInStride[Width];
 | 
			
		||||
  OutStride = mOutStride[Width];
 | 
			
		||||
  OperationWidth = (EFI_CPU_IO_PROTOCOL_WIDTH)(Width & 0x03);
 | 
			
		||||
  OperationWidth = (EFI_CPU_IO_PROTOCOL_WIDTH) (Width & 0x03);
 | 
			
		||||
 | 
			
		||||
  for (Uint8Buffer = Buffer; Count > 0; Address += InStride, Uint8Buffer += OutStride, Count--) {
 | 
			
		||||
    if (OperationWidth == EfiCpuIoWidthUint8) {
 | 
			
		||||
@@ -495,7 +492,7 @@ CpuIoServiceWrite (
 | 
			
		||||
  //
 | 
			
		||||
  InStride = mInStride[Width];
 | 
			
		||||
  OutStride = mOutStride[Width];
 | 
			
		||||
  OperationWidth = (EFI_CPU_IO_PROTOCOL_WIDTH)(Width & 0x03);
 | 
			
		||||
  OperationWidth = (EFI_CPU_IO_PROTOCOL_WIDTH) (Width & 0x03);
 | 
			
		||||
 | 
			
		||||
  for (Uint8Buffer = (UINT8 *)Buffer; Count > 0; Address += InStride, Uint8Buffer += OutStride, Count--) {
 | 
			
		||||
    if (OperationWidth == EfiCpuIoWidthUint8) {
 | 
			
		||||
@@ -524,6 +521,7 @@ STATIC EFI_CPU_IO2_PROTOCOL  mCpuIo2 = {
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
  The user Entry Point for module CpuIo2Dxe. The user code starts with this function.
 | 
			
		||||
 | 
			
		||||
@@ -546,8 +544,7 @@ ArmPciCpuIo2Initialize (
 | 
			
		||||
  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_ */
 | 
			
		||||
@@ -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_ */
 | 
			
		||||
 
 | 
			
		||||
@@ -53,6 +53,7 @@ typedef struct {
 | 
			
		||||
  CLOCK_RATE_DWORD Rate;
 | 
			
		||||
} CLOCK_RATE_SET_ATTRIBUTES;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// Message parameters for CLOCK_CONFIG_SET command.
 | 
			
		||||
typedef struct {
 | 
			
		||||
  UINT32 ClockId;
 | 
			
		||||
 
 | 
			
		||||
@@ -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;
 | 
			
		||||
@@ -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.
 | 
			
		||||
 | 
			
		||||
@@ -198,7 +196,7 @@ ScmiGetProtocolVersion (
 | 
			
		||||
  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;
 | 
			
		||||
@@ -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 (
 | 
			
		||||
 
 | 
			
		||||
@@ -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.
 | 
			
		||||
  *Enabled = CLOCK_ENABLED (ClockAttributes->Attributes);
 | 
			
		||||
 | 
			
		||||
  AsciiStrCpyS (
 | 
			
		||||
    ClockAsciiName,
 | 
			
		||||
    SCMI_MAX_STR_LEN,
 | 
			
		||||
    (CONST CHAR8 *)ClockAttributes->ClockName
 | 
			
		||||
    (CONST CHAR8*)ClockAttributes->ClockName
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
  return EFI_SUCCESS;
 | 
			
		||||
@@ -210,6 +209,7 @@ ClockDescribeRates (
 | 
			
		||||
  *MessageParams++  = ClockId;
 | 
			
		||||
 | 
			
		||||
  do {
 | 
			
		||||
 | 
			
		||||
    *MessageParams = RateIndex;
 | 
			
		||||
 | 
			
		||||
    // Set Payload length, note PayloadLength is a IN/OUT parameter.
 | 
			
		||||
@@ -219,7 +219,7 @@ ClockDescribeRates (
 | 
			
		||||
    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);
 | 
			
		||||
 | 
			
		||||
      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,6 +259,7 @@ ClockDescribeRates (
 | 
			
		||||
          ConvertTo64Bit (Rate->Low, Rate->High);
 | 
			
		||||
      }
 | 
			
		||||
    } else {
 | 
			
		||||
      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++];
 | 
			
		||||
@@ -270,6 +276,7 @@ ClockDescribeRates (
 | 
			
		||||
        RateArray[RateIndex++].ContinuousRate.Step =
 | 
			
		||||
          ConvertTo64Bit (Rate->Low, Rate->High);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  } while (NUM_REMAIN_RATES (DescribeRates->NumRatesFlags) != 0);
 | 
			
		||||
 | 
			
		||||
  // Update RateArraySize with RequiredArraySize.
 | 
			
		||||
@@ -322,7 +329,7 @@ ClockRateGet (
 | 
			
		||||
  Status = ScmiCommandExecute (
 | 
			
		||||
             &Cmd,
 | 
			
		||||
             &PayloadLength,
 | 
			
		||||
             (UINT32 **)&ClockRate
 | 
			
		||||
             (UINT32**)&ClockRate
 | 
			
		||||
             );
 | 
			
		||||
  if (EFI_ERROR (Status)) {
 | 
			
		||||
    return Status;
 | 
			
		||||
@@ -356,7 +363,7 @@ ClockRateSet (
 | 
			
		||||
  SCMI_COMMAND                Cmd;
 | 
			
		||||
  UINT32                      PayloadLength;
 | 
			
		||||
 | 
			
		||||
  Status = ScmiCommandGetPayload ((UINT32 **)&ClockRateSetAttributes);
 | 
			
		||||
  Status = ScmiCommandGetPayload ((UINT32**)&ClockRateSetAttributes);
 | 
			
		||||
  if (EFI_ERROR (Status)) {
 | 
			
		||||
    return Status;
 | 
			
		||||
  }
 | 
			
		||||
@@ -405,7 +412,7 @@ ClockEnable (
 | 
			
		||||
  SCMI_COMMAND                Cmd;
 | 
			
		||||
  UINT32                      PayloadLength;
 | 
			
		||||
 | 
			
		||||
  Status = ScmiCommandGetPayload ((UINT32 **)&ClockConfigSetAttributes);
 | 
			
		||||
  Status = ScmiCommandGetPayload ((UINT32**)&ClockConfigSetAttributes);
 | 
			
		||||
  if (EFI_ERROR (Status)) {
 | 
			
		||||
    return Status;
 | 
			
		||||
  }
 | 
			
		||||
@@ -437,7 +444,7 @@ STATIC CONST SCMI_CLOCK_PROTOCOL  ScmiClockProtocol = {
 | 
			
		||||
  ClockDescribeRates,
 | 
			
		||||
  ClockRateGet,
 | 
			
		||||
  ClockRateSet
 | 
			
		||||
};
 | 
			
		||||
 };
 | 
			
		||||
 | 
			
		||||
// Instance of the SCMI clock management protocol.
 | 
			
		||||
STATIC CONST SCMI_CLOCK2_PROTOCOL ScmiClock2Protocol = {
 | 
			
		||||
@@ -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 (
 | 
			
		||||
 
 | 
			
		||||
@@ -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;
 | 
			
		||||
  }
 | 
			
		||||
@@ -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,7 +8,6 @@
 | 
			
		||||
    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_
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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>
 | 
			
		||||
@@ -56,7 +56,7 @@ PerformanceGetAttributes (
 | 
			
		||||
  )
 | 
			
		||||
{
 | 
			
		||||
  EFI_STATUS  Status;
 | 
			
		||||
  UINT32      *ReturnValues;
 | 
			
		||||
  UINT32* ReturnValues;
 | 
			
		||||
 | 
			
		||||
  Status = ScmiGetProtocolAttributes (
 | 
			
		||||
             ScmiProtocolIdPerformance,
 | 
			
		||||
@@ -160,7 +160,7 @@ PerformanceDescribeLevels (
 | 
			
		||||
  EFI_STATUS    Status;
 | 
			
		||||
  UINT32        PayloadLength;
 | 
			
		||||
  SCMI_COMMAND  Cmd;
 | 
			
		||||
  UINT32        *MessageParams;
 | 
			
		||||
  UINT32*       MessageParams;
 | 
			
		||||
  UINT32        LevelIndex;
 | 
			
		||||
  UINT32        RequiredSize;
 | 
			
		||||
  UINT32        LevelNo;
 | 
			
		||||
@@ -183,6 +183,7 @@ PerformanceDescribeLevels (
 | 
			
		||||
  Cmd.MessageId  = ScmiMessageIdPerformanceDescribeLevels;
 | 
			
		||||
 | 
			
		||||
  do {
 | 
			
		||||
 | 
			
		||||
    *MessageParams = LevelIndex;
 | 
			
		||||
 | 
			
		||||
    // Note, PayloadLength is an IN/OUT parameter.
 | 
			
		||||
@@ -191,7 +192,7 @@ PerformanceDescribeLevels (
 | 
			
		||||
    Status = ScmiCommandExecute (
 | 
			
		||||
               &Cmd,
 | 
			
		||||
               &PayloadLength,
 | 
			
		||||
               (UINT32 **)&Levels
 | 
			
		||||
               (UINT32**)&Levels
 | 
			
		||||
               );
 | 
			
		||||
    if (EFI_ERROR (Status)) {
 | 
			
		||||
      return Status;
 | 
			
		||||
@@ -218,6 +219,7 @@ PerformanceDescribeLevels (
 | 
			
		||||
         sizeof (SCMI_PERFORMANCE_LEVEL)
 | 
			
		||||
         );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  } while (ReturnRemainNumLevels != 0);
 | 
			
		||||
 | 
			
		||||
  *LevelArraySize = RequiredSize;
 | 
			
		||||
@@ -310,7 +312,7 @@ PerformanceLimitsGet (
 | 
			
		||||
  Status = ScmiCommandExecute (
 | 
			
		||||
             &Cmd,
 | 
			
		||||
             &PayloadLength,
 | 
			
		||||
             (UINT32 **)&ReturnValues
 | 
			
		||||
             (UINT32**)&ReturnValues
 | 
			
		||||
             );
 | 
			
		||||
  if (EFI_ERROR (Status)) {
 | 
			
		||||
    return Status;
 | 
			
		||||
@@ -416,75 +418,6 @@ PerformanceLevelGet (
 | 
			
		||||
  return EFI_SUCCESS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** Discover the attributes of the FastChannel for the specified
 | 
			
		||||
    performance domain and the specified message.
 | 
			
		||||
 | 
			
		||||
  @param[in]  This        A Pointer to SCMI_PERFORMANCE_PROTOCOL Instance.
 | 
			
		||||
  @param[in]  DomainId    Identifier for the performance domain.
 | 
			
		||||
  @param[in]  MessageId   Message Id of the FastChannel to discover.
 | 
			
		||||
                          Must be one of:
 | 
			
		||||
                           - PERFORMANCE_LIMITS_SET
 | 
			
		||||
                           - PERFORMANCE_LIMITS_GET
 | 
			
		||||
                           - PERFORMANCE_LEVEL_SET
 | 
			
		||||
                           - PERFORMANCE_LEVEL_GET
 | 
			
		||||
  @param[out] FastChannel If success, contains the FastChannel description.
 | 
			
		||||
 | 
			
		||||
  @retval EFI_SUCCESS             Performance level got successfully.
 | 
			
		||||
  @retval EFI_DEVICE_ERROR        SCP returns an SCMI error.
 | 
			
		||||
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
 | 
			
		||||
  @retval EFI_TIMEOUT             Time out.
 | 
			
		||||
  @retval EFI_UNSUPPORTED         Unsupported.
 | 
			
		||||
**/
 | 
			
		||||
EFI_STATUS
 | 
			
		||||
DescribeFastchannel (
 | 
			
		||||
  IN  SCMI_PERFORMANCE_PROTOCOL     *This,
 | 
			
		||||
  IN  UINT32                        DomainId,
 | 
			
		||||
  IN  SCMI_MESSAGE_ID_PERFORMANCE   MessageId,
 | 
			
		||||
  OUT SCMI_PERFORMANCE_FASTCHANNEL  *FastChannel
 | 
			
		||||
  )
 | 
			
		||||
{
 | 
			
		||||
  EFI_STATUS    Status;
 | 
			
		||||
  SCMI_COMMAND  Cmd;
 | 
			
		||||
  UINT32        PayloadLength;
 | 
			
		||||
  UINT32        *ReturnValues;
 | 
			
		||||
  UINT32        *MessageParams;
 | 
			
		||||
 | 
			
		||||
  if ((This == NULL)  ||
 | 
			
		||||
      (FastChannel == NULL))
 | 
			
		||||
  {
 | 
			
		||||
    return EFI_INVALID_PARAMETER;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  Status = ScmiCommandGetPayload (&MessageParams);
 | 
			
		||||
  if (EFI_ERROR (Status)) {
 | 
			
		||||
    return Status;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  *MessageParams++ = DomainId;
 | 
			
		||||
  *MessageParams   = MessageId;
 | 
			
		||||
 | 
			
		||||
  Cmd.ProtocolId = ScmiProtocolIdPerformance;
 | 
			
		||||
  Cmd.MessageId  = ScmiMessageIdPerformanceDescribeFastchannel;
 | 
			
		||||
  PayloadLength  = sizeof (DomainId) + sizeof (MessageId);
 | 
			
		||||
 | 
			
		||||
  Status = ScmiCommandExecute (
 | 
			
		||||
             &Cmd,
 | 
			
		||||
             &PayloadLength,
 | 
			
		||||
             &ReturnValues
 | 
			
		||||
             );
 | 
			
		||||
  if (EFI_ERROR (Status)) {
 | 
			
		||||
    return Status;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  CopyMem (
 | 
			
		||||
    FastChannel,
 | 
			
		||||
    ReturnValues,
 | 
			
		||||
    sizeof (SCMI_PERFORMANCE_FASTCHANNEL)
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
  return Status;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Instance of the SCMI performance management protocol.
 | 
			
		||||
STATIC CONST SCMI_PERFORMANCE_PROTOCOL PerformanceProtocol = {
 | 
			
		||||
  PerformanceGetVersion,
 | 
			
		||||
@@ -494,8 +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_
 | 
			
		||||
 | 
			
		||||
@@ -90,7 +89,7 @@ typedef struct {
 | 
			
		||||
**/
 | 
			
		||||
EFI_STATUS
 | 
			
		||||
ScmiCommandGetPayload (
 | 
			
		||||
  OUT UINT32  **Payload
 | 
			
		||||
  OUT UINT32** Payload
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
/** Execute a SCMI command and receive a response.
 | 
			
		||||
 
 | 
			
		||||
@@ -13,19 +13,11 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
 | 
			
		||||
#include <Library/MemoryAllocationLib.h>
 | 
			
		||||
#include "CpuDxe.h"
 | 
			
		||||
 | 
			
		||||
#define INVALID_ENTRY  ((UINT64)~0)
 | 
			
		||||
#define INVALID_ENTRY   ((UINT32)~0)
 | 
			
		||||
 | 
			
		||||
#define MIN_T0SZ        16
 | 
			
		||||
#define BITS_PER_LEVEL  9
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
  Parses T0SZ to determine the level and number of entries at the root
 | 
			
		||||
  of the translation table.
 | 
			
		||||
 | 
			
		||||
  @param T0SZ                 The T0SZ value to be parsed.
 | 
			
		||||
  @param RootTableLevel       The level of the root table.
 | 
			
		||||
  @param RootTableEntryCount  The number of entries in the root table.
 | 
			
		||||
**/
 | 
			
		||||
STATIC
 | 
			
		||||
VOID
 | 
			
		||||
GetRootTranslationTableInfo (
 | 
			
		||||
@@ -38,13 +30,6 @@ GetRootTranslationTableInfo (
 | 
			
		||||
  *RootTableEntryCount  = TT_ENTRY_COUNT >> (T0SZ - MIN_T0SZ) % BITS_PER_LEVEL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
  Converts ARM translation table attributes to GCD attributes.
 | 
			
		||||
 | 
			
		||||
  @param PageAttributes The translation table attributes to be converted.
 | 
			
		||||
 | 
			
		||||
  @retval The analogous GCD attributes.
 | 
			
		||||
**/
 | 
			
		||||
STATIC
 | 
			
		||||
UINT64
 | 
			
		||||
PageAttributeToGcdAttribute (
 | 
			
		||||
@@ -67,11 +52,9 @@ PageAttributeToGcdAttribute (
 | 
			
		||||
    GcdAttributes = EFI_MEMORY_WB;
 | 
			
		||||
    break;
 | 
			
		||||
  default:
 | 
			
		||||
      DEBUG ((
 | 
			
		||||
        DEBUG_ERROR,
 | 
			
		||||
    DEBUG ((DEBUG_ERROR,
 | 
			
		||||
      "PageAttributeToGcdAttribute: PageAttributes:0x%lX not supported.\n",
 | 
			
		||||
        PageAttributes
 | 
			
		||||
        ));
 | 
			
		||||
      PageAttributes));
 | 
			
		||||
    ASSERT (0);
 | 
			
		||||
    // The Global Coherency Domain (GCD) value is defined as a bit set.
 | 
			
		||||
    // Returning 0 means no attribute has been set.
 | 
			
		||||
@@ -79,13 +62,8 @@ PageAttributeToGcdAttribute (
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Determine protection attributes
 | 
			
		||||
  if ((PageAttributes & TT_AF) == 0) {
 | 
			
		||||
    GcdAttributes |= EFI_MEMORY_RP;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (((PageAttributes & TT_AP_MASK) == TT_AP_NO_RO) ||
 | 
			
		||||
      ((PageAttributes & TT_AP_MASK) == TT_AP_RO_RO))
 | 
			
		||||
  {
 | 
			
		||||
      ((PageAttributes & TT_AP_MASK) == TT_AP_RO_RO)) {
 | 
			
		||||
    // Read only cases map to write-protect
 | 
			
		||||
    GcdAttributes |= EFI_MEMORY_RO;
 | 
			
		||||
  }
 | 
			
		||||
@@ -98,31 +76,6 @@ PageAttributeToGcdAttribute (
 | 
			
		||||
  return GcdAttributes;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
  Convert an arch specific set of page attributes into a mask
 | 
			
		||||
  of EFI_MEMORY_xx constants.
 | 
			
		||||
 | 
			
		||||
  @param  PageAttributes  The set of page attributes.
 | 
			
		||||
 | 
			
		||||
  @retval The mask of EFI_MEMORY_xx constants.
 | 
			
		||||
 | 
			
		||||
**/
 | 
			
		||||
UINT64
 | 
			
		||||
RegionAttributeToGcdAttribute (
 | 
			
		||||
  IN UINTN  PageAttributes
 | 
			
		||||
  )
 | 
			
		||||
{
 | 
			
		||||
  return PageAttributeToGcdAttribute (PageAttributes);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
  Retrieves the attribute of the first page entry in the translation table.
 | 
			
		||||
 | 
			
		||||
  @param[in] FirstLevelTableAddress   The base address of the translation table.
 | 
			
		||||
  @param[in] TableLevel               The current level being traversed.
 | 
			
		||||
 | 
			
		||||
  @retval The attributes of the first page entry found, or INVALID_ENTRY.
 | 
			
		||||
**/
 | 
			
		||||
STATIC
 | 
			
		||||
UINT64
 | 
			
		||||
GetFirstPageAttribute (
 | 
			
		||||
@@ -135,33 +88,20 @@ GetFirstPageAttribute (
 | 
			
		||||
  // 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 (
 | 
			
		||||
@@ -169,14 +109,14 @@ GetNextEntryAttribute (
 | 
			
		||||
  IN     UINTN   EntryCount,
 | 
			
		||||
  IN     UINTN   TableLevel,
 | 
			
		||||
  IN     UINT64  BaseAddress,
 | 
			
		||||
  IN OUT UINT64  *PrevEntryAttribute,
 | 
			
		||||
  IN OUT UINT32 *PrevEntryAttribute,
 | 
			
		||||
  IN OUT UINT64 *StartGcdRegion
 | 
			
		||||
  )
 | 
			
		||||
{
 | 
			
		||||
  UINTN                             Index;
 | 
			
		||||
  UINT64                            Entry;
 | 
			
		||||
  UINT64                           EntryAttribute;
 | 
			
		||||
  UINT64                           EntryType;
 | 
			
		||||
  UINT32                            EntryAttribute;
 | 
			
		||||
  UINT32                            EntryType;
 | 
			
		||||
  EFI_STATUS                        Status;
 | 
			
		||||
  UINTN                             NumberOfDescriptors;
 | 
			
		||||
  EFI_GCD_MEMORY_SPACE_DESCRIPTOR  *MemorySpaceMap;
 | 
			
		||||
@@ -184,38 +124,32 @@ GetNextEntryAttribute (
 | 
			
		||||
  // Get the memory space map from GCD
 | 
			
		||||
  MemorySpaceMap = NULL;
 | 
			
		||||
  Status = gDS->GetMemorySpaceMap (&NumberOfDescriptors, &MemorySpaceMap);
 | 
			
		||||
 | 
			
		||||
  if (EFI_ERROR (Status) || (TableLevel > 3)) {
 | 
			
		||||
  ASSERT_EFI_ERROR (Status);
 | 
			
		||||
 | 
			
		||||
  // We cannot get more than 3-level page table
 | 
			
		||||
  ASSERT (TableLevel <= 3);
 | 
			
		||||
    return 0;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // While the top level table might not contain TT_ENTRY_COUNT entries;
 | 
			
		||||
  // the subsequent ones should be filled up
 | 
			
		||||
  for (Index = 0; Index < EntryCount; Index++) {
 | 
			
		||||
    Entry = TableAddress[Index];
 | 
			
		||||
    EntryType = Entry & TT_TYPE_MASK;
 | 
			
		||||
    EntryAttribute = Entry & TT_ATTRIBUTES_MASK;
 | 
			
		||||
    EntryAttribute = Entry  & TT_ATTR_INDX_MASK;
 | 
			
		||||
 | 
			
		||||
    // If Entry is a Table Descriptor type entry then go through the sub-level table
 | 
			
		||||
    if ((EntryType == TT_TYPE_BLOCK_ENTRY) ||
 | 
			
		||||
        ((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,
 | 
			
		||||
          SetGcdMemorySpaceAttributes (MemorySpaceMap, NumberOfDescriptors,
 | 
			
		||||
              *StartGcdRegion,
 | 
			
		||||
            (BaseAddress + (Index * TT_ADDRESS_AT_LEVEL (TableLevel))) - *StartGcdRegion,
 | 
			
		||||
            PageAttributeToGcdAttribute (*PrevEntryAttribute)
 | 
			
		||||
            );
 | 
			
		||||
              (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,
 | 
			
		||||
        SetGcdMemorySpaceAttributes (MemorySpaceMap, NumberOfDescriptors,
 | 
			
		||||
            *StartGcdRegion,
 | 
			
		||||
          (BaseAddress + (Index * TT_ADDRESS_AT_LEVEL (TableLevel))) - *StartGcdRegion,
 | 
			
		||||
          PageAttributeToGcdAttribute (*PrevEntryAttribute)
 | 
			
		||||
          );
 | 
			
		||||
            (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,25 +180,16 @@ 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
 | 
			
		||||
  )
 | 
			
		||||
{
 | 
			
		||||
  EFI_STATUS                          Status;
 | 
			
		||||
  UINT64                           PageAttribute;
 | 
			
		||||
  UINT32                              PageAttribute;
 | 
			
		||||
  UINT64                             *FirstLevelTableAddress;
 | 
			
		||||
  UINTN                               TableLevel;
 | 
			
		||||
  UINTN                               TableCount;
 | 
			
		||||
@@ -290,11 +208,7 @@ SyncCacheConfig (
 | 
			
		||||
  //
 | 
			
		||||
  MemorySpaceMap = NULL;
 | 
			
		||||
  Status = gDS->GetMemorySpaceMap (&NumberOfDescriptors, &MemorySpaceMap);
 | 
			
		||||
 | 
			
		||||
  if (EFI_ERROR (Status)) {
 | 
			
		||||
  ASSERT_EFI_ERROR (Status);
 | 
			
		||||
    return Status;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // The GCD implementation maintains its own copy of the state of memory space attributes.  GCD needs
 | 
			
		||||
  // 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,
 | 
			
		||||
  EndAddressGcdRegion = GetNextEntryAttribute (FirstLevelTableAddress,
 | 
			
		||||
                                               TableCount, TableLevel,
 | 
			
		||||
                                               BaseAddressGcdRegion,
 | 
			
		||||
                           &PageAttribute,
 | 
			
		||||
                           &BaseAddressGcdRegion
 | 
			
		||||
                           );
 | 
			
		||||
                                               &PageAttribute, &BaseAddressGcdRegion);
 | 
			
		||||
 | 
			
		||||
  // Update GCD with the last region if valid
 | 
			
		||||
  if ((PageAttribute != INVALID_ENTRY) && (EndAddressGcdRegion > BaseAddressGcdRegion)) {
 | 
			
		||||
    SetGcdMemorySpaceAttributes (
 | 
			
		||||
      MemorySpaceMap,
 | 
			
		||||
      NumberOfDescriptors,
 | 
			
		||||
  if (PageAttribute != INVALID_ENTRY) {
 | 
			
		||||
    SetGcdMemorySpaceAttributes (MemorySpaceMap, NumberOfDescriptors,
 | 
			
		||||
        BaseAddressGcdRegion,
 | 
			
		||||
        EndAddressGcdRegion - BaseAddressGcdRegion,
 | 
			
		||||
      PageAttributeToGcdAttribute (PageAttribute)
 | 
			
		||||
      );
 | 
			
		||||
        PageAttributeToGcdAttribute (PageAttribute));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  FreePool (MemorySpaceMap);
 | 
			
		||||
@@ -343,13 +250,6 @@ SyncCacheConfig (
 | 
			
		||||
  return EFI_SUCCESS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
  Convert EFI memory attributes to ARM translation table attributes.
 | 
			
		||||
 | 
			
		||||
  @param[in]  EfiAttributes  EFI memory attributes.
 | 
			
		||||
 | 
			
		||||
  @retval The analogous translation table attributes.
 | 
			
		||||
**/
 | 
			
		||||
UINT64
 | 
			
		||||
EfiAttributeToArmAttribute (
 | 
			
		||||
  IN UINT64                    EfiAttributes
 | 
			
		||||
@@ -364,7 +264,6 @@ EfiAttributeToArmAttribute (
 | 
			
		||||
    } 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;
 | 
			
		||||
@@ -380,13 +279,11 @@ EfiAttributeToArmAttribute (
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Set the access flag to match the block attributes
 | 
			
		||||
  if ((EfiAttributes & EFI_MEMORY_RP) == 0) {
 | 
			
		||||
  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,25 +294,8 @@ EfiAttributeToArmAttribute (
 | 
			
		||||
  return ArmAttributes;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
  This function returns the attributes of the memory region containing the
 | 
			
		||||
  specified address.
 | 
			
		||||
 | 
			
		||||
  RegionLength and RegionAttributes are only valid if the result is EFI_SUCCESS.
 | 
			
		||||
 | 
			
		||||
  @param[in]        TranslationTable  The translation table base address.
 | 
			
		||||
  @param[in]        TableLevel        The level of the translation table.
 | 
			
		||||
  @param[in]        LastBlockEntry    The last block address of the table level.
 | 
			
		||||
  @param[in, out]   BaseAddress       The base address of the memory region.
 | 
			
		||||
  @param[out]       RegionLength      The length of the memory region.
 | 
			
		||||
  @param[out]       RegionAttributes  The attributes of the memory region.
 | 
			
		||||
 | 
			
		||||
  @retval EFI_SUCCESS     The attributes of the memory region were
 | 
			
		||||
                          returned successfully.
 | 
			
		||||
  @retval EFI_NOT_FOUND   The memory region was not found.
 | 
			
		||||
  @retval EFI_NO_MAPPING  The translation table entry associated with
 | 
			
		||||
                          BaseAddress is invalid.
 | 
			
		||||
**/
 | 
			
		||||
// This function will recursively go down the page table to find the first block address linked to 'BaseAddress'.
 | 
			
		||||
// And then the function will identify the size of the region that has the same page table attribute.
 | 
			
		||||
EFI_STATUS
 | 
			
		||||
GetMemoryRegionRec (
 | 
			
		||||
  IN     UINT64                  *TranslationTable,
 | 
			
		||||
@@ -439,26 +319,23 @@ GetMemoryRegionRec (
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Find the block entry linked to the Base Address
 | 
			
		||||
  BlockEntry = (UINT64 *)TT_GET_ENTRY_FOR_ADDRESS (TranslationTable, TableLevel, *BaseAddress);
 | 
			
		||||
  BlockEntry = (UINT64*)TT_GET_ENTRY_FOR_ADDRESS (TranslationTable, TableLevel, *BaseAddress);
 | 
			
		||||
  EntryType = *BlockEntry & TT_TYPE_MASK;
 | 
			
		||||
 | 
			
		||||
  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
 | 
			
		||||
               );
 | 
			
		||||
        (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,51 +343,30 @@ 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,
 | 
			
		||||
@@ -524,36 +380,23 @@ GetMemoryRegion (
 | 
			
		||||
  UINTN       EntryCount;
 | 
			
		||||
  UINTN       T0SZ;
 | 
			
		||||
 | 
			
		||||
  if ((BaseAddress == NULL) || (RegionLength == NULL) || (RegionAttributes == NULL)) {
 | 
			
		||||
  ASSERT ((BaseAddress != NULL) && (RegionLength != NULL) && (RegionAttributes != NULL));
 | 
			
		||||
    return EFI_INVALID_PARAMETER;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  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;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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,48 +113,34 @@ 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,
 | 
			
		||||
@@ -216,21 +161,20 @@ SyncCacheConfigPage (
 | 
			
		||||
  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
 | 
			
		||||
@@ -240,10 +184,7 @@ SyncCacheConfigPage (
 | 
			
		||||
      } else if (PageAttributes != NextPageAttributes) {
 | 
			
		||||
        // Convert Section Attributes into GCD Attributes
 | 
			
		||||
        Status = PageToGcdAttributes (NextPageAttributes, &GcdAttributes);
 | 
			
		||||
        if (EFI_ERROR (Status)) {
 | 
			
		||||
        ASSERT_EFI_ERROR (Status);
 | 
			
		||||
          GcdAttributes = 0;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // update GCD with these changes (this will recurse into our own CpuSetMemoryAttributes below which is OK)
 | 
			
		||||
        SetGcdMemorySpaceAttributes (MemorySpaceMap, NumberOfDescriptors, *NextRegionBase, *NextRegionLength, GcdAttributes);
 | 
			
		||||
@@ -256,10 +197,7 @@ SyncCacheConfigPage (
 | 
			
		||||
    } else if (NextPageAttributes != 0) {
 | 
			
		||||
      // Convert Page Attributes into GCD Attributes
 | 
			
		||||
      Status = PageToGcdAttributes (NextPageAttributes, &GcdAttributes);
 | 
			
		||||
      if (EFI_ERROR (Status)) {
 | 
			
		||||
      ASSERT_EFI_ERROR (Status);
 | 
			
		||||
        GcdAttributes = 0;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      // update GCD with these changes (this will recurse into our own CpuSetMemoryAttributes below which is OK)
 | 
			
		||||
      SetGcdMemorySpaceAttributes (MemorySpaceMap, NumberOfDescriptors, *NextRegionBase, *NextRegionLength, GcdAttributes);
 | 
			
		||||
@@ -268,27 +206,17 @@ SyncCacheConfigPage (
 | 
			
		||||
      *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
 | 
			
		||||
@@ -305,6 +233,7 @@ SyncCacheConfig (
 | 
			
		||||
  UINTN                               NumberOfDescriptors;
 | 
			
		||||
  EFI_GCD_MEMORY_SPACE_DESCRIPTOR     *MemorySpaceMap;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  DEBUG ((DEBUG_PAGE, "SyncCacheConfig()\n"));
 | 
			
		||||
 | 
			
		||||
  // This code assumes MMU is enabled and filed with section translations
 | 
			
		||||
@@ -315,12 +244,8 @@ SyncCacheConfig (
 | 
			
		||||
  //
 | 
			
		||||
  MemorySpaceMap = NULL;
 | 
			
		||||
  Status = gDS->GetMemorySpaceMap (&NumberOfDescriptors, &MemorySpaceMap);
 | 
			
		||||
 | 
			
		||||
  if (EFI_ERROR (Status)) {
 | 
			
		||||
    DEBUG ((DEBUG_ERROR, "SyncCacheConfig - GetMemorySpaceMap() failed! Status: %r\n", Status));
 | 
			
		||||
  ASSERT_EFI_ERROR (Status);
 | 
			
		||||
    return Status;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  // 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);
 | 
			
		||||
        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;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // 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);
 | 
			
		||||
        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
 | 
			
		||||
                                );
 | 
			
		||||
          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;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // 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);
 | 
			
		||||
        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;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // update GCD with these changes (this will recurse into our own CpuSetMemoryAttributes below which is OK)
 | 
			
		||||
    SetGcdMemorySpaceAttributes (MemorySpaceMap, NumberOfDescriptors, NextRegionBase, NextRegionLength, GcdAttributes);
 | 
			
		||||
@@ -426,13 +331,6 @@ SyncCacheConfig (
 | 
			
		||||
  return EFI_SUCCESS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
  Convert EFI memory attributes to ARM translation table attributes.
 | 
			
		||||
 | 
			
		||||
  @param[in]  EfiAttributes  EFI memory attributes.
 | 
			
		||||
 | 
			
		||||
  @retval The analogous translation table attributes.
 | 
			
		||||
**/
 | 
			
		||||
UINT64
 | 
			
		||||
EfiAttributeToArmAttribute (
 | 
			
		||||
  IN UINT64                    EfiAttributes
 | 
			
		||||
@@ -479,95 +377,53 @@ EfiAttributeToArmAttribute (
 | 
			
		||||
    ArmAttributes |= TT_DESCRIPTOR_SECTION_XN_MASK;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if ((EfiAttributes & EFI_MEMORY_RP) == 0) {
 | 
			
		||||
    ArmAttributes |= TT_DESCRIPTOR_SECTION_AF;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return ArmAttributes;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
  This function finds the end of a memory region in a translation table. A
 | 
			
		||||
  memory region is defined as a contiguous set of pages with the same attributes.
 | 
			
		||||
 | 
			
		||||
  @param[in]    PageTable         The translation table to traverse.
 | 
			
		||||
  @param[in]    BaseAddress       The address from which to start the search
 | 
			
		||||
  @param[in]    RegionAttributes  The attributes of the start of the region.
 | 
			
		||||
  @param[out]   RegionLength      The length of the region found.
 | 
			
		||||
 | 
			
		||||
  @retval EFI_SUCCESS       The region was found.
 | 
			
		||||
  @retval EFI_NOT_FOUND     The end of the region was not found.
 | 
			
		||||
  @retval EFI_NO_MAPPING    The region specified by BaseAddress is not mapped
 | 
			
		||||
                            in the input translation table.
 | 
			
		||||
  @retval EFI_UNSUPPORTED   Large pages are not supported.
 | 
			
		||||
**/
 | 
			
		||||
STATIC
 | 
			
		||||
EFI_STATUS
 | 
			
		||||
GetMemoryRegionPage (
 | 
			
		||||
  IN     UINT32                  *PageTable,
 | 
			
		||||
  IN     UINTN   *BaseAddress,
 | 
			
		||||
  IN     UINTN   *RegionAttributes,
 | 
			
		||||
  OUT    UINTN   *RegionLength
 | 
			
		||||
  IN OUT UINTN                   *BaseAddress,
 | 
			
		||||
  OUT    UINTN                   *RegionLength,
 | 
			
		||||
  OUT    UINTN                   *RegionAttributes
 | 
			
		||||
  )
 | 
			
		||||
{
 | 
			
		||||
  UINT32      PageAttributes;
 | 
			
		||||
  UINT32      TableIndex;
 | 
			
		||||
  UINT32      PageDescriptor;
 | 
			
		||||
  EFI_STATUS  Status;
 | 
			
		||||
 | 
			
		||||
  // 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;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      *RegionLength += TT_DESCRIPTOR_PAGE_SIZE;
 | 
			
		||||
      if ((PageDescriptor & TT_DESCRIPTOR_PAGE_ATTRIBUTE_MASK) == PageAttributes) {
 | 
			
		||||
        *RegionLength = *RegionLength + TT_DESCRIPTOR_PAGE_SIZE;
 | 
			
		||||
      } else {
 | 
			
		||||
      // Large pages are unsupported.
 | 
			
		||||
      Status = EFI_UNSUPPORTED;
 | 
			
		||||
      ASSERT (0);
 | 
			
		||||
      break;
 | 
			
		||||
        // Case: End of the boundary of the region
 | 
			
		||||
        return EFI_SUCCESS;
 | 
			
		||||
      }
 | 
			
		||||
    } else {
 | 
			
		||||
      // We do not support Large Page yet. We return EFI_SUCCESS that means end of the region.
 | 
			
		||||
      ASSERT(0);
 | 
			
		||||
      return EFI_SUCCESS;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return Status;
 | 
			
		||||
  return EFI_NOT_FOUND;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
  Get the memory region that contains the specified address. A memory region is defined
 | 
			
		||||
  as a contiguous set of pages with the same attributes.
 | 
			
		||||
 | 
			
		||||
  RegionLength and RegionAttributes are only valid if EFI_SUCCESS is returned.
 | 
			
		||||
 | 
			
		||||
  @param[in, out]   BaseAddress       On input, the address to search for.
 | 
			
		||||
                                      On output, the base address of the region found.
 | 
			
		||||
  @param[out]       RegionLength      The length of the region found.
 | 
			
		||||
  @param[out]       RegionAttributes  The attributes of the region found.
 | 
			
		||||
 | 
			
		||||
  @retval   EFI_SUCCESS             Region found
 | 
			
		||||
  @retval   EFI_NOT_FOUND           Region not found
 | 
			
		||||
  @retval   EFI_UNSUPPORTED         Large pages are unsupported
 | 
			
		||||
  @retval   EFI_NO_MAPPING          The page specified by BaseAddress is unmapped
 | 
			
		||||
  @retval   EFI_INVALID_PARAMETER   The BaseAddress exceeds the addressable range of
 | 
			
		||||
                                    the translation table.
 | 
			
		||||
**/
 | 
			
		||||
EFI_STATUS
 | 
			
		||||
GetMemoryRegion (
 | 
			
		||||
  IN OUT UINTN                   *BaseAddress,
 | 
			
		||||
@@ -582,7 +438,6 @@ GetMemoryRegion (
 | 
			
		||||
  UINT32                      SectionDescriptor;
 | 
			
		||||
  ARM_FIRST_LEVEL_DESCRIPTOR *FirstLevelTable;
 | 
			
		||||
  UINT32                     *PageTable;
 | 
			
		||||
  UINTN                       Length;
 | 
			
		||||
 | 
			
		||||
  // 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;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Get the section at the given index
 | 
			
		||||
  SectionDescriptor = FirstLevelTable[TableIndex];
 | 
			
		||||
@@ -615,45 +466,35 @@ GetMemoryRegion (
 | 
			
		||||
    *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) |
 | 
			
		||||
    *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 == EFI_NOT_FOUND implies we have not reached the end of the region.
 | 
			
		||||
      if ((Status == EFI_NOT_FOUND) && (Length > 0)) {
 | 
			
		||||
        continue;
 | 
			
		||||
      }
 | 
			
		||||
      Status = GetMemoryRegionPage (PageTable, BaseAddress, RegionLength, RegionAttributes);
 | 
			
		||||
 | 
			
		||||
      // If we have found the end of the region (Status == EFI_SUCCESS) then we exit the for-loop
 | 
			
		||||
      if (Status == EFI_SUCCESS) {
 | 
			
		||||
        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,8 +11,6 @@
 | 
			
		||||
 | 
			
		||||
#include <Guid/IdleLoopEvent.h>
 | 
			
		||||
 | 
			
		||||
#include <Library/MemoryAllocationLib.h>
 | 
			
		||||
 | 
			
		||||
BOOLEAN                   mIsFlushingGCD;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -51,6 +49,7 @@ CpuFlushCpuDataCache (
 | 
			
		||||
  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.
 | 
			
		||||
 | 
			
		||||
@@ -88,6 +88,7 @@ CpuEnableInterrupt (
 | 
			
		||||
  return EFI_SUCCESS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
  This function disables interrupt processing by the processor.
 | 
			
		||||
 | 
			
		||||
@@ -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
 | 
			
		||||
@@ -132,10 +134,11 @@ CpuGetInterruptState (
 | 
			
		||||
    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
 | 
			
		||||
@@ -229,77 +232,6 @@ InitializeDma (
 | 
			
		||||
  CpuArchProtocol->DmaBufferAlignment = ArmCacheWritebackGranule ();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
  Map all EfiConventionalMemory regions in the memory map with NX
 | 
			
		||||
  attributes so that allocating or freeing EfiBootServicesData regions
 | 
			
		||||
  does not result in changes to memory permission attributes.
 | 
			
		||||
 | 
			
		||||
**/
 | 
			
		||||
STATIC
 | 
			
		||||
VOID
 | 
			
		||||
RemapUnusedMemoryNx (
 | 
			
		||||
  VOID
 | 
			
		||||
  )
 | 
			
		||||
{
 | 
			
		||||
  UINT64                 TestBit;
 | 
			
		||||
  UINTN                  MemoryMapSize;
 | 
			
		||||
  UINTN                  MapKey;
 | 
			
		||||
  UINTN                  DescriptorSize;
 | 
			
		||||
  UINT32                 DescriptorVersion;
 | 
			
		||||
  EFI_MEMORY_DESCRIPTOR  *MemoryMap;
 | 
			
		||||
  EFI_MEMORY_DESCRIPTOR  *MemoryMapEntry;
 | 
			
		||||
  EFI_MEMORY_DESCRIPTOR  *MemoryMapEnd;
 | 
			
		||||
  EFI_STATUS             Status;
 | 
			
		||||
 | 
			
		||||
  TestBit = LShiftU64 (1, EfiBootServicesData);
 | 
			
		||||
  if ((PcdGet64 (PcdDxeNxMemoryProtectionPolicy) & TestBit) == 0) {
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  MemoryMapSize = 0;
 | 
			
		||||
  MemoryMap     = NULL;
 | 
			
		||||
 | 
			
		||||
  Status = gBS->GetMemoryMap (
 | 
			
		||||
                  &MemoryMapSize,
 | 
			
		||||
                  MemoryMap,
 | 
			
		||||
                  &MapKey,
 | 
			
		||||
                  &DescriptorSize,
 | 
			
		||||
                  &DescriptorVersion
 | 
			
		||||
                  );
 | 
			
		||||
  ASSERT (Status == EFI_BUFFER_TOO_SMALL);
 | 
			
		||||
  do {
 | 
			
		||||
    MemoryMap = (EFI_MEMORY_DESCRIPTOR *)AllocatePool (MemoryMapSize);
 | 
			
		||||
    ASSERT (MemoryMap != NULL);
 | 
			
		||||
    Status = gBS->GetMemoryMap (
 | 
			
		||||
                    &MemoryMapSize,
 | 
			
		||||
                    MemoryMap,
 | 
			
		||||
                    &MapKey,
 | 
			
		||||
                    &DescriptorSize,
 | 
			
		||||
                    &DescriptorVersion
 | 
			
		||||
                    );
 | 
			
		||||
    if (EFI_ERROR (Status)) {
 | 
			
		||||
      FreePool (MemoryMap);
 | 
			
		||||
    }
 | 
			
		||||
  } while (Status == EFI_BUFFER_TOO_SMALL);
 | 
			
		||||
 | 
			
		||||
  ASSERT_EFI_ERROR (Status);
 | 
			
		||||
 | 
			
		||||
  MemoryMapEntry = MemoryMap;
 | 
			
		||||
  MemoryMapEnd   = (EFI_MEMORY_DESCRIPTOR *)((UINT8 *)MemoryMap + MemoryMapSize);
 | 
			
		||||
  while ((UINTN)MemoryMapEntry < (UINTN)MemoryMapEnd) {
 | 
			
		||||
    if (MemoryMapEntry->Type == EfiConventionalMemory) {
 | 
			
		||||
      ArmSetMemoryAttributes (
 | 
			
		||||
        MemoryMapEntry->PhysicalStart,
 | 
			
		||||
        EFI_PAGES_TO_SIZE (MemoryMapEntry->NumberOfPages),
 | 
			
		||||
        EFI_MEMORY_XP,
 | 
			
		||||
        EFI_MEMORY_XP
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    MemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
EFI_STATUS
 | 
			
		||||
CpuDxeInitialize (
 | 
			
		||||
  IN EFI_HANDLE         ImageHandle,
 | 
			
		||||
@@ -313,26 +245,9 @@ CpuDxeInitialize (
 | 
			
		||||
 | 
			
		||||
  InitializeDma (&mCpu);
 | 
			
		||||
 | 
			
		||||
  //
 | 
			
		||||
  // Once we install the CPU arch protocol, the DXE core's memory
 | 
			
		||||
  // protection routines will invoke them to manage the permissions of page
 | 
			
		||||
  // allocations as they are created. Given that this includes pages
 | 
			
		||||
  // allocated for page tables by this driver, we must ensure that unused
 | 
			
		||||
  // memory is mapped with the same permissions as boot services data
 | 
			
		||||
  // regions. Otherwise, we may end up with unbounded recursion, due to the
 | 
			
		||||
  // fact that updating permissions on a newly allocated page table may trigger
 | 
			
		||||
  // a block entry split, which triggers a page table allocation, etc etc
 | 
			
		||||
  //
 | 
			
		||||
  if (FeaturePcdGet (PcdRemapUnusedMemoryNx)) {
 | 
			
		||||
    RemapUnusedMemoryNx ();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  Status = gBS->InstallMultipleProtocolInterfaces (
 | 
			
		||||
                &mCpuHandle,
 | 
			
		||||
                  &gEfiCpuArchProtocolGuid,
 | 
			
		||||
                  &mCpu,
 | 
			
		||||
                  &gEfiMemoryAttributeProtocolGuid,
 | 
			
		||||
                  &mMemoryAttribute,
 | 
			
		||||
                &gEfiCpuArchProtocolGuid,           &mCpu,
 | 
			
		||||
                NULL
 | 
			
		||||
                );
 | 
			
		||||
 | 
			
		||||
@@ -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,12 +30,9 @@
 | 
			
		||||
#include <Protocol/Cpu.h>
 | 
			
		||||
#include <Protocol/DebugSupport.h>
 | 
			
		||||
#include <Protocol/LoadedImage.h>
 | 
			
		||||
#include <Protocol/MemoryAttribute.h>
 | 
			
		||||
 | 
			
		||||
extern BOOLEAN mIsFlushingGCD;
 | 
			
		||||
 | 
			
		||||
extern EFI_MEMORY_ATTRIBUTE_PROTOCOL  mMemoryAttribute;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
  This function registers and enables the handler specified by InterruptHandler for a processor
 | 
			
		||||
  interrupt or exception type specified by InterruptType. If InterruptHandler is NULL, then the
 | 
			
		||||
@@ -62,6 +59,7 @@ RegisterInterruptHandler (
 | 
			
		||||
  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
 | 
			
		||||
@@ -88,6 +86,7 @@ RegisterDebuggerInterruptHandler (
 | 
			
		||||
  IN EFI_CPU_INTERRUPT_HANDLER      InterruptHandler
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
EFI_STATUS
 | 
			
		||||
EFIAPI
 | 
			
		||||
CpuSetMemoryAttributes (
 | 
			
		||||
@@ -107,6 +106,21 @@ SyncCacheConfig (
 | 
			
		||||
  IN  EFI_CPU_ARCH_PROTOCOL *CpuProtocol
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Publish ARM Processor Data table in UEFI SYSTEM Table.
 | 
			
		||||
 * @param  HobStart               Pointer to the beginning of the HOB List from PEI.
 | 
			
		||||
 *
 | 
			
		||||
 * Description : This function iterates through HOB list and finds ARM processor Table Entry HOB.
 | 
			
		||||
 *               If  the ARM processor Table Entry HOB is found, the HOB data is copied to run-time memory
 | 
			
		||||
 *               and a pointer is assigned to it in ARM processor table. Then the ARM processor table is
 | 
			
		||||
 *               installed in EFI configuration table.
 | 
			
		||||
**/
 | 
			
		||||
VOID
 | 
			
		||||
EFIAPI
 | 
			
		||||
PublishArmProcessorTable(
 | 
			
		||||
  VOID
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
// The ARM Attributes might be defined on 64-bit (case of the long format description table)
 | 
			
		||||
UINT64
 | 
			
		||||
EfiAttributeToArmAttribute (
 | 
			
		||||
@@ -129,18 +143,4 @@ SetGcdMemorySpaceAttributes (
 | 
			
		||||
  IN UINT64                              Attributes
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
  Convert an arch specific set of page attributes into a mask
 | 
			
		||||
  of EFI_MEMORY_xx constants.
 | 
			
		||||
 | 
			
		||||
  @param  PageAttributes  The set of page attributes.
 | 
			
		||||
 | 
			
		||||
  @retval The mask of EFI_MEMORY_xx constants.
 | 
			
		||||
 | 
			
		||||
**/
 | 
			
		||||
UINT64
 | 
			
		||||
RegionAttributeToGcdAttribute (
 | 
			
		||||
  IN UINTN  PageAttributes
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
#endif // CPU_DXE_H_
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
 
 | 
			
		||||
@@ -43,22 +43,19 @@ SearchGcdMemorySpaces (
 | 
			
		||||
  *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.
 | 
			
		||||
 | 
			
		||||
@@ -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,
 | 
			
		||||
    DEBUG ((DEBUG_WARN,
 | 
			
		||||
            "Warning: We do not support smaller granularity than 4KB on ARM Architecture (passed length: 0x%lX).\n",
 | 
			
		||||
      Length
 | 
			
		||||
      ));
 | 
			
		||||
            Length));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  //
 | 
			
		||||
@@ -130,7 +120,6 @@ SetGcdMemorySpaceAttributes (
 | 
			
		||||
    if (MemorySpaceMap[Index].GcdMemoryType == EfiGcdMemoryTypeNonExistent) {
 | 
			
		||||
      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
 | 
			
		||||
    //
 | 
			
		||||
@@ -217,7 +204,7 @@ CpuSetMemoryAttributes (
 | 
			
		||||
  if (EFI_ERROR (Status) || (RegionArmAttributes != ArmAttributes) ||
 | 
			
		||||
      ((BaseAddress + Length) > (RegionBaseAddress + RegionLength)))
 | 
			
		||||
  {
 | 
			
		||||
    return ArmSetMemoryAttributes (BaseAddress, Length, EfiAttributes, 0);
 | 
			
		||||
    return ArmSetMemoryAttributes (BaseAddress, Length, EfiAttributes);
 | 
			
		||||
  } else {
 | 
			
		||||
    return EFI_SUCCESS;
 | 
			
		||||
  }
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										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);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -23,13 +23,13 @@ InitializeExceptions (
 | 
			
		||||
  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;
 | 
			
		||||
 | 
			
		||||
@@ -90,11 +90,11 @@ previously installed.
 | 
			
		||||
 | 
			
		||||
**/
 | 
			
		||||
EFI_STATUS
 | 
			
		||||
RegisterInterruptHandler (
 | 
			
		||||
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
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/*++
 | 
			
		||||
 | 
			
		||||
@@ -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)) {
 | 
			
		||||
    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,15 +1,10 @@
 | 
			
		||||
/** @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_
 | 
			
		||||
 | 
			
		||||
@@ -18,17 +13,12 @@
 | 
			
		||||
 | 
			
		||||
// Control Frame:
 | 
			
		||||
#define GENERIC_WDOG_CONTROL_STATUS_REG       ((UINTN)FixedPcdGet64 (PcdGenericWatchdogControlBase) + 0x000)
 | 
			
		||||
#define GENERIC_WDOG_OFFSET_REG_LOW          ((UINTN)FixedPcdGet64 (PcdGenericWatchdogControlBase) + 0x008)
 | 
			
		||||
#define GENERIC_WDOG_OFFSET_REG_HIGH         ((UINTN)FixedPcdGet64 (PcdGenericWatchdogControlBase) + 0x00C)
 | 
			
		||||
#define GENERIC_WDOG_OFFSET_REG               ((UINTN)FixedPcdGet64 (PcdGenericWatchdogControlBase) + 0x008)
 | 
			
		||||
#define GENERIC_WDOG_COMPARE_VALUE_REG_LOW    ((UINTN)FixedPcdGet64 (PcdGenericWatchdogControlBase) + 0x010)
 | 
			
		||||
#define GENERIC_WDOG_COMPARE_VALUE_REG_HIGH   ((UINTN)FixedPcdGet64 (PcdGenericWatchdogControlBase) + 0x014)
 | 
			
		||||
#define GENERIC_WDOG_IID_REG                 ((UINTN)FixedPcdGet64 (PcdGenericWatchdogControlBase) + 0xFCC)
 | 
			
		||||
 | 
			
		||||
// Values of bit 0 of the Control/Status Register
 | 
			
		||||
#define GENERIC_WDOG_ENABLED          1
 | 
			
		||||
#define GENERIC_WDOG_DISABLED         0
 | 
			
		||||
 | 
			
		||||
#define GENERIC_WDOG_IID_ARCH_REV_SHIFT  16
 | 
			
		||||
#define GENERIC_WDOG_IID_ARCH_REV_MASK   0xF
 | 
			
		||||
 | 
			
		||||
#endif  // GENERIC_WATCHDOG_H_
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,5 @@
 | 
			
		||||
/** @file
 | 
			
		||||
*
 | 
			
		||||
*  Copyright (c) 2023, Ampere Computing LLC. All rights reserved.<BR>
 | 
			
		||||
*  Copyright (c) 2013-2018, ARM Limited. All rights reserved.
 | 
			
		||||
*
 | 
			
		||||
*  SPDX-License-Identifier: BSD-2-Clause-Patent
 | 
			
		||||
@@ -28,58 +27,24 @@
 | 
			
		||||
   in a second */
 | 
			
		||||
#define TIME_UNITS_PER_SECOND 10000000
 | 
			
		||||
 | 
			
		||||
// Tick frequency of the generic timer basis of the generic watchdog.
 | 
			
		||||
STATIC UINTN mTimerFrequencyHz = 0;
 | 
			
		||||
 | 
			
		||||
/* In cases where the compare register was set manually, information about
 | 
			
		||||
   how long the watchdog was asked to wait cannot be retrieved from hardware.
 | 
			
		||||
   It is therefore stored here. 0 means the timer is not running. */
 | 
			
		||||
STATIC UINT64  mTimerPeriod = 0;
 | 
			
		||||
 | 
			
		||||
/* disables watchdog interaction after Exit Boot Services */
 | 
			
		||||
STATIC BOOLEAN  mExitedBootServices = FALSE;
 | 
			
		||||
 | 
			
		||||
#define MAX_UINT48  0xFFFFFFFFFFFFULL
 | 
			
		||||
STATIC UINT64 mNumTimerTicks = 0;
 | 
			
		||||
 | 
			
		||||
STATIC EFI_HARDWARE_INTERRUPT2_PROTOCOL *mInterruptProtocol;
 | 
			
		||||
STATIC EFI_WATCHDOG_TIMER_NOTIFY        mWatchdogNotify;
 | 
			
		||||
STATIC EFI_EVENT                         mEfiExitBootServicesEvent;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
  This function returns the maximum watchdog offset register value.
 | 
			
		||||
 | 
			
		||||
  @retval MAX_UINT32 The watchdog offset register holds a 32-bit value.
 | 
			
		||||
  @retval MAX_UINT48 The watchdog offset register holds a 48-bit value.
 | 
			
		||||
**/
 | 
			
		||||
STATIC
 | 
			
		||||
UINT64
 | 
			
		||||
GetMaxWatchdogOffsetRegisterValue (
 | 
			
		||||
  VOID
 | 
			
		||||
  )
 | 
			
		||||
{
 | 
			
		||||
  UINT64  MaxWatchdogOffsetValue;
 | 
			
		||||
  UINT32  WatchdogIId;
 | 
			
		||||
  UINT8   WatchdogArchRevision;
 | 
			
		||||
 | 
			
		||||
  WatchdogIId          = MmioRead32 (GENERIC_WDOG_IID_REG);
 | 
			
		||||
  WatchdogArchRevision = (WatchdogIId >> GENERIC_WDOG_IID_ARCH_REV_SHIFT) & GENERIC_WDOG_IID_ARCH_REV_MASK;
 | 
			
		||||
 | 
			
		||||
  if (WatchdogArchRevision == 0) {
 | 
			
		||||
    MaxWatchdogOffsetValue = MAX_UINT32;
 | 
			
		||||
  } else {
 | 
			
		||||
    MaxWatchdogOffsetValue = MAX_UINT48;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return MaxWatchdogOffsetValue;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
STATIC
 | 
			
		||||
VOID
 | 
			
		||||
WatchdogWriteOffsetRegister (
 | 
			
		||||
  UINT64  Value
 | 
			
		||||
  UINT32  Value
 | 
			
		||||
  )
 | 
			
		||||
{
 | 
			
		||||
  MmioWrite32 (GENERIC_WDOG_OFFSET_REG_LOW, Value & MAX_UINT32);
 | 
			
		||||
  if (GetMaxWatchdogOffsetRegisterValue () == MAX_UINT48) {
 | 
			
		||||
    MmioWrite32 (GENERIC_WDOG_OFFSET_REG_HIGH, (Value >> 32) & MAX_UINT16);
 | 
			
		||||
  }
 | 
			
		||||
  MmioWrite32 (GENERIC_WDOG_OFFSET_REG, Value);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
STATIC
 | 
			
		||||
@@ -122,8 +87,7 @@ WatchdogExitBootServicesEvent (
 | 
			
		||||
  )
 | 
			
		||||
{
 | 
			
		||||
  WatchdogDisable ();
 | 
			
		||||
  mTimerPeriod        = 0;
 | 
			
		||||
  mExitedBootServices = TRUE;
 | 
			
		||||
  mNumTimerTicks = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* This function is called when the watchdog's first signal (WS0) goes high.
 | 
			
		||||
@@ -137,7 +101,8 @@ WatchdogInterruptHandler (
 | 
			
		||||
  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);
 | 
			
		||||
@@ -196,11 +158,11 @@ WatchdogRegisterHandler (
 | 
			
		||||
  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,8 +182,6 @@ WatchdogRegisterHandler (
 | 
			
		||||
 | 
			
		||||
  @retval EFI_SUCCESS           The watchdog timer has been programmed to fire
 | 
			
		||||
                                in TimerPeriod 100ns units.
 | 
			
		||||
  @retval EFI_DEVICE_ERROR      Boot Services has been exited but TimerPeriod
 | 
			
		||||
                                is not zero.
 | 
			
		||||
 | 
			
		||||
**/
 | 
			
		||||
STATIC
 | 
			
		||||
@@ -233,46 +193,31 @@ WatchdogSetTimerPeriod (
 | 
			
		||||
  )
 | 
			
		||||
{
 | 
			
		||||
  UINTN       SystemCount;
 | 
			
		||||
  UINT64  MaxWatchdogOffsetValue;
 | 
			
		||||
  UINT64  TimerFrequencyHz;
 | 
			
		||||
  UINT64  NumTimerTicks;
 | 
			
		||||
 | 
			
		||||
  // If we've exited Boot Services but TimerPeriod isn't zero, this
 | 
			
		||||
  // indicates that the caller is doing something wrong.
 | 
			
		||||
  if (mExitedBootServices && (TimerPeriod != 0)) {
 | 
			
		||||
    mTimerPeriod = 0;
 | 
			
		||||
    WatchdogDisable ();
 | 
			
		||||
    return EFI_DEVICE_ERROR;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // If TimerPeriod is 0 this is a request to stop the watchdog.
 | 
			
		||||
  // if TimerPeriod is 0, this is a request to stop the watchdog.
 | 
			
		||||
  if (TimerPeriod == 0) {
 | 
			
		||||
    mTimerPeriod = 0;
 | 
			
		||||
    mNumTimerTicks = 0;
 | 
			
		||||
    WatchdogDisable ();
 | 
			
		||||
    return EFI_SUCCESS;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Work out how many timer ticks will equate to TimerPeriod
 | 
			
		||||
  TimerFrequencyHz = ArmGenericTimerGetTimerFreq ();
 | 
			
		||||
  ASSERT (TimerFrequencyHz != 0);
 | 
			
		||||
  mTimerPeriod  = TimerPeriod;
 | 
			
		||||
  NumTimerTicks = (TimerFrequencyHz * TimerPeriod) / TIME_UNITS_PER_SECOND;
 | 
			
		||||
  mNumTimerTicks = (mTimerFrequencyHz * TimerPeriod) / TIME_UNITS_PER_SECOND;
 | 
			
		||||
 | 
			
		||||
  /* If the number of required ticks is greater than the max the watchdog's
 | 
			
		||||
     offset register (WOR) can hold, we need to manually compute and set
 | 
			
		||||
     the compare register (WCV) */
 | 
			
		||||
  MaxWatchdogOffsetValue = GetMaxWatchdogOffsetRegisterValue ();
 | 
			
		||||
  if (NumTimerTicks > MaxWatchdogOffsetValue) {
 | 
			
		||||
  if (mNumTimerTicks > MAX_UINT32) {
 | 
			
		||||
    /* We need to enable the watchdog *before* writing to the compare register,
 | 
			
		||||
       because enabling the watchdog causes an "explicit refresh", which
 | 
			
		||||
       clobbers the compare register (WCV). In order to make sure this doesn't
 | 
			
		||||
       trigger an interrupt, set the offset to max. */
 | 
			
		||||
    WatchdogWriteOffsetRegister (MaxWatchdogOffsetValue);
 | 
			
		||||
    WatchdogWriteOffsetRegister (MAX_UINT32);
 | 
			
		||||
    WatchdogEnable ();
 | 
			
		||||
    SystemCount = ArmGenericTimerGetSystemCount ();
 | 
			
		||||
    WatchdogWriteCompareRegister (SystemCount + NumTimerTicks);
 | 
			
		||||
    WatchdogWriteCompareRegister (SystemCount + mNumTimerTicks);
 | 
			
		||||
  } else {
 | 
			
		||||
    WatchdogWriteOffsetRegister (NumTimerTicks);
 | 
			
		||||
    WatchdogWriteOffsetRegister ((UINT32)mNumTimerTicks);
 | 
			
		||||
    WatchdogEnable ();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@@ -307,7 +252,7 @@ WatchdogGetTimerPeriod (
 | 
			
		||||
    return EFI_INVALID_PARAMETER;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  *TimerPeriod = mTimerPeriod;
 | 
			
		||||
  *TimerPeriod = ((TIME_UNITS_PER_SECOND / mTimerFrequencyHz) * mNumTimerTicks);
 | 
			
		||||
 | 
			
		||||
  return EFI_SUCCESS;
 | 
			
		||||
}
 | 
			
		||||
@@ -350,6 +295,8 @@ STATIC EFI_WATCHDOG_TIMER_ARCH_PROTOCOL  mWatchdogTimer = {
 | 
			
		||||
  WatchdogGetTimerPeriod
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
STATIC EFI_EVENT mEfiExitBootServicesEvent;
 | 
			
		||||
 | 
			
		||||
EFI_STATUS
 | 
			
		||||
EFIAPI
 | 
			
		||||
GenericWatchdogEntry (
 | 
			
		||||
@@ -360,11 +307,8 @@ GenericWatchdogEntry (
 | 
			
		||||
  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;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -42,20 +42,14 @@ 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] 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
 | 
			
		||||
@@ -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
 | 
			
		||||
@@ -234,19 +219,15 @@ 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;
 | 
			
		||||
@@ -259,32 +240,21 @@ 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,
 | 
			
		||||
@@ -347,7 +317,7 @@ MmCommunication2Initialize (
 | 
			
		||||
 | 
			
		||||
  // Check if we can make the MM call
 | 
			
		||||
  Status = GetMmCompatibility ();
 | 
			
		||||
  if (EFI_ERROR (Status)) {
 | 
			
		||||
  if (EFI_ERROR(Status)) {
 | 
			
		||||
    goto ReturnErrorStatus;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@@ -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>
 | 
			
		||||
@@ -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
 | 
			
		||||
@@ -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;
 | 
			
		||||
 
 | 
			
		||||
@@ -60,12 +60,10 @@ typedef struct {
 | 
			
		||||
 | 
			
		||||
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 {
 | 
			
		||||
@@ -117,6 +115,8 @@ FreeFCB (
 | 
			
		||||
  FreePool (Fcb);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
EFI_STATUS
 | 
			
		||||
VolumeOpen (
 | 
			
		||||
  IN  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *This,
 | 
			
		||||
@@ -191,16 +191,14 @@ FileOpen (
 | 
			
		||||
    return EFI_INVALID_PARAMETER;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if ((OpenMode != EFI_FILE_MODE_READ) &&
 | 
			
		||||
  if ( (OpenMode != EFI_FILE_MODE_READ) &&
 | 
			
		||||
       (OpenMode != (EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE)) &&
 | 
			
		||||
      (OpenMode != (EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE)))
 | 
			
		||||
  {
 | 
			
		||||
       (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;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@@ -209,15 +207,13 @@ FileOpen (
 | 
			
		||||
  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)) {
 | 
			
		||||
@@ -351,7 +346,6 @@ TruncateFile (
 | 
			
		||||
    if (RETURN_ERROR (Return)) {
 | 
			
		||||
      goto Error;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Remaining -= ToRead;
 | 
			
		||||
    Read      += ToRead;
 | 
			
		||||
  }
 | 
			
		||||
@@ -385,12 +379,12 @@ Error:
 | 
			
		||||
  if (FileHandle != 0) {
 | 
			
		||||
    SemihostFileClose (FileHandle);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (Buffer != NULL) {
 | 
			
		||||
    FreePool (Buffer);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return (Status);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -414,7 +408,7 @@ FileClose (
 | 
			
		||||
    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);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@@ -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);
 | 
			
		||||
    if (RETURN_ERROR (Return)) {
 | 
			
		||||
      return EFI_DEVICE_ERROR;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Remaining -= WriteNb;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@@ -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,7 +632,6 @@ FileWrite (
 | 
			
		||||
    if (EFI_ERROR (Status)) {
 | 
			
		||||
      return Status;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Fcb->Info.FileSize = Fcb->Position;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@@ -661,7 +650,6 @@ FileWrite (
 | 
			
		||||
  if (RETURN_ERROR (Return)) {
 | 
			
		||||
    return EFI_DEVICE_ERROR;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  Fcb->Info.PhysicalSize = Length;
 | 
			
		||||
 | 
			
		||||
  return EFI_SUCCESS;
 | 
			
		||||
@@ -690,7 +678,7 @@ FileGetPosition (
 | 
			
		||||
    return EFI_INVALID_PARAMETER;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  Fcb = SEMIHOST_FCB_FROM_THIS (This);
 | 
			
		||||
  Fcb = SEMIHOST_FCB_FROM_THIS(This);
 | 
			
		||||
 | 
			
		||||
  *Position = Fcb->Position;
 | 
			
		||||
 | 
			
		||||
@@ -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;
 | 
			
		||||
@@ -779,7 +767,7 @@ GetFileInfo (
 | 
			
		||||
 | 
			
		||||
  if (Fcb->IsRoot) {
 | 
			
		||||
    NameSize = 0;
 | 
			
		||||
    ResultSize = SIZE_OF_EFI_FILE_INFO + sizeof (CHAR16);
 | 
			
		||||
    ResultSize = SIZE_OF_EFI_FILE_INFO + sizeof(CHAR16);
 | 
			
		||||
  } else {
 | 
			
		||||
    NameSize   = AsciiStrLen (Fcb->FileName) + 1;
 | 
			
		||||
    ResultSize = SIZE_OF_EFI_FILE_INFO + NameSize * sizeof (CHAR16);
 | 
			
		||||
@@ -901,12 +889,11 @@ FileGetInfo (
 | 
			
		||||
  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);
 | 
			
		||||
@@ -981,7 +968,6 @@ SetFileInfo (
 | 
			
		||||
  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) {
 | 
			
		||||
@@ -1184,14 +1160,13 @@ FileFlush (
 | 
			
		||||
{
 | 
			
		||||
  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;
 | 
			
		||||
@@ -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);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 
 | 
			
		||||
@@ -243,3 +243,4 @@ FileFlush (
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
#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_
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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,22 +40,10 @@
 | 
			
		||||
  .global   Name                  ; \
 | 
			
		||||
  .section  #Section, "ax"        ; \
 | 
			
		||||
  .type     Name, %function       ; \
 | 
			
		||||
  Name:                           ; \
 | 
			
		||||
  AARCH64_BTI(c)
 | 
			
		||||
 | 
			
		||||
#define _ASM_FUNC_ALIGN(Name, Section, Align)       \
 | 
			
		||||
  .global   Name                                  ; \
 | 
			
		||||
  .section  #Section, "ax"                        ; \
 | 
			
		||||
  .type     Name, %function                       ; \
 | 
			
		||||
  .balign   Align                                 ; \
 | 
			
		||||
  Name:                                           ; \
 | 
			
		||||
  AARCH64_BTI(c)
 | 
			
		||||
  Name:
 | 
			
		||||
 | 
			
		||||
#define ASM_FUNC(Name)            _ASM_FUNC(ASM_PFX(Name), .text. ## Name)
 | 
			
		||||
 | 
			
		||||
#define ASM_FUNC_ALIGN(Name, Align)  \
 | 
			
		||||
  _ASM_FUNC_ALIGN(ASM_PFX(Name), .text. ## Name, Align)
 | 
			
		||||
 | 
			
		||||
#define MOV32(Reg, Val)                   \
 | 
			
		||||
  movz      Reg, (Val) >> 16, lsl #16   ; \
 | 
			
		||||
  movk      Reg, (Val) & 0xffff
 | 
			
		||||
 
 | 
			
		||||
@@ -24,17 +24,10 @@
 | 
			
		||||
// Coprocessor Trap Register (CPTR)
 | 
			
		||||
#define AARCH64_CPTR_TFP        (1 << 10)
 | 
			
		||||
 | 
			
		||||
// ID_AA64MMFR1 - AArch64 Memory Model Feature Register 0 definitions
 | 
			
		||||
#define AARCH64_MMFR1_VH  (0xF << 8)
 | 
			
		||||
 | 
			
		||||
// ID_AA64PFR0 - AArch64 Processor Feature Register 0 definitions
 | 
			
		||||
#define AARCH64_PFR0_FP         (0xF << 16)
 | 
			
		||||
#define AARCH64_PFR0_GIC        (0xF << 24)
 | 
			
		||||
 | 
			
		||||
// ID_AA64DFR0 - AArch64 Debug Feature Register 0 definitions
 | 
			
		||||
#define AARCH64_DFR0_TRACEVER  (0xFULL << 4)
 | 
			
		||||
#define AARCH64_DFR0_TRBE      (0xFULL << 44)
 | 
			
		||||
 | 
			
		||||
// SCR - Secure Configuration Register definitions
 | 
			
		||||
#define SCR_NS                  (1 << 0)
 | 
			
		||||
#define SCR_IRQ                 (1 << 1)
 | 
			
		||||
@@ -119,10 +112,6 @@
 | 
			
		||||
#define ARM_VECTOR_LOW_A32_FIQ  0x700
 | 
			
		||||
#define ARM_VECTOR_LOW_A32_SERR 0x780
 | 
			
		||||
 | 
			
		||||
// The ID_AA64ISAR2_EL1 register is not recognized by older
 | 
			
		||||
// assemblers, we need to define it here.
 | 
			
		||||
#define ID_AA64ISAR2_EL1  S3_0_C0_C6_2
 | 
			
		||||
 | 
			
		||||
// The ID_AA64MMFR2_EL1 register was added in ARMv8.2. Since we
 | 
			
		||||
// build for ARMv8.0, we need to define the register here.
 | 
			
		||||
#define ID_AA64MMFR2_EL1 S3_0_C0_C7_2
 | 
			
		||||
 
 | 
			
		||||
@@ -17,7 +17,7 @@
 | 
			
		||||
#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
 | 
			
		||||
@@ -152,6 +152,7 @@
 | 
			
		||||
#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)
 | 
			
		||||
@@ -165,6 +166,7 @@
 | 
			
		||||
#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)
 | 
			
		||||
@@ -193,3 +195,4 @@
 | 
			
		||||
// Uses LPAE Page Table format
 | 
			
		||||
 | 
			
		||||
#endif // AARCH64_MMU_H_
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -48,6 +48,7 @@
 | 
			
		||||
#define A9_SCU_SACR_OFFSET          0x50
 | 
			
		||||
#define A9_SCU_SSACR_OFFSET         0x54
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
UINTN
 | 
			
		||||
EFIAPI
 | 
			
		||||
ArmGetScuBaseAddress (
 | 
			
		||||
@@ -55,3 +56,4 @@ ArmGetScuBaseAddress (
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
#endif // ARM_CORTEX_A9_H_
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -41,6 +41,7 @@
 | 
			
		||||
#define CPSR_IRQ             (1 << 7)
 | 
			
		||||
#define CPSR_FIQ             (1 << 6)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// CPACR - Coprocessor Access Control Register definitions
 | 
			
		||||
#define CPACR_CP_DENIED(cp)     0x00
 | 
			
		||||
#define CPACR_CP_PRIV(cp)       ((0x1 << ((cp) << 1)) & 0x0FFFFFFF)
 | 
			
		||||
 
 | 
			
		||||
@@ -33,6 +33,7 @@
 | 
			
		||||
#define TTBR_MP_NON_CACHEABLE           ( TTBR_RGN_OUTER_NON_CACHEABLE | TTBR_RGN_INNER_NON_CACHEABLE )
 | 
			
		||||
#define TTBR_MP_WRITE_BACK_ALLOC        ( TTBR_RGN_OUTER_WRITE_BACK_ALLOC | TTBR_RGN_INNER_WRITE_BACK_ALLOC | TTBR_SHAREABLE)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define TRANSLATION_TABLE_SECTION_COUNT                 4096
 | 
			
		||||
#define TRANSLATION_TABLE_SECTION_SIZE                  (sizeof(UINT32) * TRANSLATION_TABLE_SECTION_COUNT)
 | 
			
		||||
#define TRANSLATION_TABLE_SECTION_ALIGNMENT             (sizeof(UINT32) * TRANSLATION_TABLE_SECTION_COUNT)
 | 
			
		||||
@@ -54,9 +55,11 @@
 | 
			
		||||
#define TT_DESCRIPTOR_SECTION_TYPE_IS_PAGE_TABLE(Desc) (((Desc) & 3UL) == TT_DESCRIPTOR_SECTION_TYPE_PAGE_TABLE)
 | 
			
		||||
 | 
			
		||||
// Translation table descriptor types
 | 
			
		||||
#define TT_DESCRIPTOR_PAGE_TYPE_MASK   (1UL << 1)
 | 
			
		||||
#define TT_DESCRIPTOR_PAGE_TYPE_FAULT  (0UL << 1)
 | 
			
		||||
#define TT_DESCRIPTOR_PAGE_TYPE_PAGE   (1UL << 1)
 | 
			
		||||
#define TT_DESCRIPTOR_PAGE_TYPE_MASK         (3UL << 0)
 | 
			
		||||
#define TT_DESCRIPTOR_PAGE_TYPE_FAULT        (0UL << 0)
 | 
			
		||||
#define TT_DESCRIPTOR_PAGE_TYPE_PAGE         (2UL << 0)
 | 
			
		||||
#define TT_DESCRIPTOR_PAGE_TYPE_PAGE_XN      (3UL << 0)
 | 
			
		||||
#define TT_DESCRIPTOR_PAGE_TYPE_LARGEPAGE    (1UL << 0)
 | 
			
		||||
 | 
			
		||||
// Section descriptor definitions
 | 
			
		||||
#define TT_DESCRIPTOR_SECTION_SIZE                              (0x00100000)
 | 
			
		||||
@@ -80,24 +83,25 @@
 | 
			
		||||
#define TT_DESCRIPTOR_PAGE_S_NOT_SHARED                         (0UL << 10)
 | 
			
		||||
#define TT_DESCRIPTOR_PAGE_S_SHARED                             (1UL << 10)
 | 
			
		||||
 | 
			
		||||
#define TT_DESCRIPTOR_SECTION_AP_MASK   ((1UL << 15) | (1UL << 11))
 | 
			
		||||
#define TT_DESCRIPTOR_SECTION_AP_NO_RW  ((0UL << 15) | (0UL << 11))
 | 
			
		||||
#define TT_DESCRIPTOR_SECTION_AP_RW_RW  ((0UL << 15) | (1UL << 11))
 | 
			
		||||
#define TT_DESCRIPTOR_SECTION_AP_NO_RO  ((1UL << 15) | (0UL << 11))
 | 
			
		||||
#define TT_DESCRIPTOR_SECTION_AP_RO_RO  ((1UL << 15) | (1UL << 11))
 | 
			
		||||
#define TT_DESCRIPTOR_SECTION_AP_MASK                           ((1UL << 15) | (3UL << 10))
 | 
			
		||||
#define TT_DESCRIPTOR_SECTION_AP_NO_NO                          ((0UL << 15) | (0UL << 10))
 | 
			
		||||
#define TT_DESCRIPTOR_SECTION_AP_RW_NO                          ((0UL << 15) | (1UL << 10))
 | 
			
		||||
#define TT_DESCRIPTOR_SECTION_AP_RW_RO                          ((0UL << 15) | (2UL << 10))
 | 
			
		||||
#define TT_DESCRIPTOR_SECTION_AP_RW_RW                          ((0UL << 15) | (3UL << 10))
 | 
			
		||||
#define TT_DESCRIPTOR_SECTION_AP_RO_NO                          ((1UL << 15) | (1UL << 10))
 | 
			
		||||
#define TT_DESCRIPTOR_SECTION_AP_RO_RO                          ((1UL << 15) | (3UL << 10))
 | 
			
		||||
 | 
			
		||||
#define TT_DESCRIPTOR_SECTION_AF  (1UL << 10)
 | 
			
		||||
 | 
			
		||||
#define TT_DESCRIPTOR_PAGE_AP_MASK   ((1UL << 9) | (1UL << 5))
 | 
			
		||||
#define TT_DESCRIPTOR_PAGE_AP_NO_RW  ((0UL << 9) | (0UL << 5))
 | 
			
		||||
#define TT_DESCRIPTOR_PAGE_AP_RW_RW  ((0UL << 9) | (1UL << 5))
 | 
			
		||||
#define TT_DESCRIPTOR_PAGE_AP_NO_RO  ((1UL << 9) | (0UL << 5))
 | 
			
		||||
#define TT_DESCRIPTOR_PAGE_AP_RO_RO  ((1UL << 9) | (1UL << 5))
 | 
			
		||||
 | 
			
		||||
#define TT_DESCRIPTOR_PAGE_AF  (1UL << 4)
 | 
			
		||||
#define TT_DESCRIPTOR_PAGE_AP_MASK                              ((1UL << 9) | (3UL << 4))
 | 
			
		||||
#define TT_DESCRIPTOR_PAGE_AP_NO_NO                             ((0UL << 9) | (0UL << 4))
 | 
			
		||||
#define TT_DESCRIPTOR_PAGE_AP_RW_NO                             ((0UL << 9) | (1UL << 4))
 | 
			
		||||
#define TT_DESCRIPTOR_PAGE_AP_RW_RO                             ((0UL << 9) | (2UL << 4))
 | 
			
		||||
#define TT_DESCRIPTOR_PAGE_AP_RW_RW                             ((0UL << 9) | (3UL << 4))
 | 
			
		||||
#define TT_DESCRIPTOR_PAGE_AP_RO_NO                             ((1UL << 9) | (1UL << 4))
 | 
			
		||||
#define TT_DESCRIPTOR_PAGE_AP_RO_RO                             ((1UL << 9) | (3UL << 4))
 | 
			
		||||
 | 
			
		||||
#define TT_DESCRIPTOR_SECTION_XN_MASK                           (0x1UL << 4)
 | 
			
		||||
#define TT_DESCRIPTOR_PAGE_XN_MASK                              (0x1UL << 0)
 | 
			
		||||
#define TT_DESCRIPTOR_LARGEPAGE_XN_MASK                         (0x1UL << 15)
 | 
			
		||||
 | 
			
		||||
#define TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK                   ((3UL << 12) | (1UL << 3) | (1UL << 2))
 | 
			
		||||
#define TT_DESCRIPTOR_SECTION_CACHEABLE_MASK                      (1UL << 3)
 | 
			
		||||
@@ -121,27 +125,37 @@
 | 
			
		||||
#define TT_DESCRIPTOR_PAGE_CACHE_POLICY_WRITE_BACK_ALLOC       ((1UL << 6) | (1UL << 3) | (1UL << 2))
 | 
			
		||||
#define TT_DESCRIPTOR_PAGE_CACHE_POLICY_NON_SHAREABLE_DEVICE   ((2UL << 6) | (0UL << 3) | (0UL << 2))
 | 
			
		||||
 | 
			
		||||
#define TT_DESCRIPTOR_LARGEPAGE_CACHE_POLICY_MASK                   ((3UL << 12) | (1UL << 3) | (1UL << 2))
 | 
			
		||||
#define TT_DESCRIPTOR_LARGEPAGE_CACHE_POLICY_STRONGLY_ORDERED       ((0UL << 12) | (0UL << 3) | (0UL << 2))
 | 
			
		||||
#define TT_DESCRIPTOR_LARGEPAGE_CACHE_POLICY_SHAREABLE_DEVICE       ((0UL << 12) | (0UL << 3) | (1UL << 2))
 | 
			
		||||
#define TT_DESCRIPTOR_LARGEPAGE_CACHE_POLICY_WRITE_THROUGH_NO_ALLOC ((0UL << 12) | (1UL << 3) | (0UL << 2))
 | 
			
		||||
#define TT_DESCRIPTOR_LARGEPAGE_CACHE_POLICY_WRITE_BACK_NO_ALLOC    ((0UL << 12) | (1UL << 3) | (1UL << 2))
 | 
			
		||||
#define TT_DESCRIPTOR_LARGEPAGE_CACHE_POLICY_NON_CACHEABLE          ((1UL << 12) | (0UL << 3) | (0UL << 2))
 | 
			
		||||
#define TT_DESCRIPTOR_LARGEPAGE_CACHE_POLICY_WRITE_BACK_ALLOC       ((1UL << 12) | (1UL << 3) | (1UL << 2))
 | 
			
		||||
#define TT_DESCRIPTOR_LARGEPAGE_CACHE_POLICY_NON_SHAREABLE_DEVICE   ((2UL << 12) | (0UL << 3) | (0UL << 2))
 | 
			
		||||
 | 
			
		||||
#define TT_DESCRIPTOR_CONVERT_TO_PAGE_AP(Desc)                  ((((Desc) & TT_DESCRIPTOR_SECTION_AP_MASK) >> 6) & TT_DESCRIPTOR_PAGE_AP_MASK)
 | 
			
		||||
#define TT_DESCRIPTOR_CONVERT_TO_PAGE_NG(Desc)                  ((((Desc) & TT_DESCRIPTOR_SECTION_NG_MASK) >> 6) & TT_DESCRIPTOR_PAGE_NG_MASK)
 | 
			
		||||
#define TT_DESCRIPTOR_CONVERT_TO_PAGE_S(Desc)                  ((((Desc) & TT_DESCRIPTOR_SECTION_S_MASK) >> 6) & TT_DESCRIPTOR_PAGE_S_MASK)
 | 
			
		||||
#define TT_DESCRIPTOR_CONVERT_TO_PAGE_AF(Desc)            ((((Desc) & TT_DESCRIPTOR_SECTION_AF) >> 6) & TT_DESCRIPTOR_PAGE_AF)
 | 
			
		||||
#define TT_DESCRIPTOR_CONVERT_TO_PAGE_XN(Desc)            ((((Desc) & TT_DESCRIPTOR_SECTION_XN_MASK) >> 4) & TT_DESCRIPTOR_PAGE_XN_MASK)
 | 
			
		||||
#define TT_DESCRIPTOR_CONVERT_TO_PAGE_CACHE_POLICY(Desc)  ((((Desc) & (0x3 << 12)) >> 6) | (Desc & (0x3 << 2)))
 | 
			
		||||
#define TT_DESCRIPTOR_CONVERT_TO_PAGE_XN(Desc,IsLargePage)      ((IsLargePage)? \
 | 
			
		||||
                                                                    ((((Desc) & TT_DESCRIPTOR_SECTION_XN_MASK) << 11) & TT_DESCRIPTOR_LARGEPAGE_XN_MASK):    \
 | 
			
		||||
                                                                    ((((Desc) & TT_DESCRIPTOR_SECTION_XN_MASK) >> 4) & TT_DESCRIPTOR_PAGE_XN_MASK))
 | 
			
		||||
#define TT_DESCRIPTOR_CONVERT_TO_PAGE_CACHE_POLICY(Desc,IsLargePage)      (IsLargePage? \
 | 
			
		||||
                                                                    (((Desc) & TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK) & TT_DESCRIPTOR_LARGEPAGE_CACHE_POLICY_MASK): \
 | 
			
		||||
                                                                    (((((Desc) & (0x3 << 12)) >> 6) | (Desc & (0x3 << 2)))))
 | 
			
		||||
 | 
			
		||||
#define TT_DESCRIPTOR_CONVERT_TO_SECTION_AP(Desc)                  ((((Desc) & TT_DESCRIPTOR_PAGE_AP_MASK) << 6) & TT_DESCRIPTOR_SECTION_AP_MASK)
 | 
			
		||||
#define TT_DESCRIPTOR_CONVERT_TO_SECTION_S(Desc)             ((((Desc) & TT_DESCRIPTOR_PAGE_S_MASK) << 6) & TT_DESCRIPTOR_SECTION_S_MASK)
 | 
			
		||||
#define TT_DESCRIPTOR_CONVERT_TO_SECTION_AF(Desc)            ((((Desc) & TT_DESCRIPTOR_PAGE_AF) << 6) & TT_DESCRIPTOR_SECTION_AF)
 | 
			
		||||
#define TT_DESCRIPTOR_CONVERT_TO_SECTION_XN(Desc)            ((((Desc) & TT_DESCRIPTOR_PAGE_XN_MASK) << 4) & TT_DESCRIPTOR_SECTION_XN_MASK)
 | 
			
		||||
#define TT_DESCRIPTOR_CONVERT_TO_SECTION_CACHE_POLICY(Desc)  ((((Desc) & (0x3 << 6)) << 6) | (Desc & (0x3 << 2)))
 | 
			
		||||
 | 
			
		||||
#define TT_DESCRIPTOR_CONVERT_TO_SECTION_CACHE_POLICY(Desc,IsLargePage)      (IsLargePage? \
 | 
			
		||||
                                                                    (((Desc) & TT_DESCRIPTOR_LARGEPAGE_CACHE_POLICY_MASK) & TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK): \
 | 
			
		||||
                                                                    (((((Desc) & (0x3 << 6)) << 6) | (Desc & (0x3 << 2)))))
 | 
			
		||||
 | 
			
		||||
#define TT_DESCRIPTOR_SECTION_ATTRIBUTE_MASK                (TT_DESCRIPTOR_SECTION_NS_MASK | TT_DESCRIPTOR_SECTION_NG_MASK | \
 | 
			
		||||
                                                             TT_DESCRIPTOR_SECTION_S_MASK | TT_DESCRIPTOR_SECTION_AP_MASK | \
 | 
			
		||||
                                                             TT_DESCRIPTOR_SECTION_AF | \
 | 
			
		||||
                                                             TT_DESCRIPTOR_SECTION_XN_MASK | TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK)
 | 
			
		||||
 | 
			
		||||
#define TT_DESCRIPTOR_PAGE_ATTRIBUTE_MASK                   (TT_DESCRIPTOR_PAGE_NG_MASK | TT_DESCRIPTOR_PAGE_S_MASK | \
 | 
			
		||||
                                                             TT_DESCRIPTOR_PAGE_AP_MASK | TT_DESCRIPTOR_PAGE_XN_MASK | \
 | 
			
		||||
                                                             TT_DESCRIPTOR_PAGE_AF | \
 | 
			
		||||
                                                             TT_DESCRIPTOR_PAGE_CACHE_POLICY_MASK)
 | 
			
		||||
 | 
			
		||||
#define TT_DESCRIPTOR_SECTION_DOMAIN_MASK                       (0x0FUL << 5)
 | 
			
		||||
@@ -157,49 +171,56 @@
 | 
			
		||||
#define TT_DESCRIPTOR_PAGE_BASE_ADDRESS(a)                   ((a) & TT_DESCRIPTOR_PAGE_BASE_ADDRESS_MASK)
 | 
			
		||||
#define TT_DESCRIPTOR_PAGE_BASE_SHIFT                        12
 | 
			
		||||
 | 
			
		||||
#define TT_DESCRIPTOR_SECTION_DEFAULT  (TT_DESCRIPTOR_SECTION_TYPE_SECTION | \
 | 
			
		||||
#define TT_DESCRIPTOR_SECTION_WRITE_BACK(NonSecure)         (TT_DESCRIPTOR_SECTION_TYPE_SECTION                                                           | \
 | 
			
		||||
                                                            ((NonSecure) ?  TT_DESCRIPTOR_SECTION_NS : 0)    | \
 | 
			
		||||
                                                            TT_DESCRIPTOR_SECTION_NG_GLOBAL                         | \
 | 
			
		||||
                                                            TT_DESCRIPTOR_SECTION_S_SHARED                          | \
 | 
			
		||||
                                                            TT_DESCRIPTOR_SECTION_DOMAIN(0)                         | \
 | 
			
		||||
                                                            TT_DESCRIPTOR_SECTION_AP_RW_RW                          | \
 | 
			
		||||
                                        TT_DESCRIPTOR_SECTION_AF)
 | 
			
		||||
 | 
			
		||||
#define TT_DESCRIPTOR_SECTION_WRITE_BACK  (TT_DESCRIPTOR_SECTION_DEFAULT | \
 | 
			
		||||
                                                            TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_BACK_ALLOC)
 | 
			
		||||
 | 
			
		||||
#define TT_DESCRIPTOR_SECTION_WRITE_THROUGH  (TT_DESCRIPTOR_SECTION_DEFAULT | \
 | 
			
		||||
#define TT_DESCRIPTOR_SECTION_WRITE_THROUGH(NonSecure)      (TT_DESCRIPTOR_SECTION_TYPE_SECTION                                                           | \
 | 
			
		||||
                                                            ((NonSecure) ?  TT_DESCRIPTOR_SECTION_NS : 0)    | \
 | 
			
		||||
                                                            TT_DESCRIPTOR_SECTION_NG_GLOBAL                         | \
 | 
			
		||||
                                                            TT_DESCRIPTOR_SECTION_S_SHARED                          | \
 | 
			
		||||
                                                            TT_DESCRIPTOR_SECTION_DOMAIN(0)                         | \
 | 
			
		||||
                                                            TT_DESCRIPTOR_SECTION_AP_RW_RW                          | \
 | 
			
		||||
                                                            TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_THROUGH_NO_ALLOC)
 | 
			
		||||
 | 
			
		||||
#define TT_DESCRIPTOR_SECTION_DEVICE  (TT_DESCRIPTOR_SECTION_DEFAULT | \
 | 
			
		||||
#define TT_DESCRIPTOR_SECTION_DEVICE(NonSecure)             (TT_DESCRIPTOR_SECTION_TYPE_SECTION                                                           | \
 | 
			
		||||
                                                            ((NonSecure) ?  TT_DESCRIPTOR_SECTION_NS : 0)    | \
 | 
			
		||||
                                                            TT_DESCRIPTOR_SECTION_NG_GLOBAL                         | \
 | 
			
		||||
                                                            TT_DESCRIPTOR_SECTION_S_NOT_SHARED                      | \
 | 
			
		||||
                                                            TT_DESCRIPTOR_SECTION_DOMAIN(0)                         | \
 | 
			
		||||
                                                            TT_DESCRIPTOR_SECTION_AP_RW_RW                          | \
 | 
			
		||||
                                                            TT_DESCRIPTOR_SECTION_XN_MASK                           | \
 | 
			
		||||
                                                            TT_DESCRIPTOR_SECTION_CACHE_POLICY_SHAREABLE_DEVICE)
 | 
			
		||||
 | 
			
		||||
#define TT_DESCRIPTOR_SECTION_UNCACHED  (TT_DESCRIPTOR_SECTION_DEFAULT | \
 | 
			
		||||
#define TT_DESCRIPTOR_SECTION_UNCACHED(NonSecure)          (TT_DESCRIPTOR_SECTION_TYPE_SECTION                                                           | \
 | 
			
		||||
                                                           ((NonSecure) ?  TT_DESCRIPTOR_SECTION_NS : 0)    | \
 | 
			
		||||
                                                           TT_DESCRIPTOR_SECTION_NG_GLOBAL                         | \
 | 
			
		||||
                                                           TT_DESCRIPTOR_SECTION_S_NOT_SHARED                      | \
 | 
			
		||||
                                                           TT_DESCRIPTOR_SECTION_DOMAIN(0)                         | \
 | 
			
		||||
                                                           TT_DESCRIPTOR_SECTION_AP_RW_RW                          | \
 | 
			
		||||
                                                           TT_DESCRIPTOR_SECTION_CACHE_POLICY_NON_CACHEABLE)
 | 
			
		||||
 | 
			
		||||
#define TT_DESCRIPTOR_PAGE_WRITE_BACK              (TT_DESCRIPTOR_PAGE_TYPE_PAGE                                                           | \
 | 
			
		||||
                                                        TT_DESCRIPTOR_PAGE_NG_GLOBAL                                                      | \
 | 
			
		||||
                                                        TT_DESCRIPTOR_PAGE_S_SHARED                                                       | \
 | 
			
		||||
                                                        TT_DESCRIPTOR_PAGE_AP_RW_RW                                                       | \
 | 
			
		||||
                                                        TT_DESCRIPTOR_PAGE_AF                                                             | \
 | 
			
		||||
                                                        TT_DESCRIPTOR_PAGE_CACHE_POLICY_WRITE_BACK_ALLOC)
 | 
			
		||||
#define TT_DESCRIPTOR_PAGE_WRITE_THROUGH           (TT_DESCRIPTOR_PAGE_TYPE_PAGE                                                           | \
 | 
			
		||||
                                                        TT_DESCRIPTOR_PAGE_NG_GLOBAL                                                      | \
 | 
			
		||||
                                                        TT_DESCRIPTOR_PAGE_S_SHARED                                                       | \
 | 
			
		||||
                                                        TT_DESCRIPTOR_PAGE_AP_RW_RW                                                       | \
 | 
			
		||||
                                                        TT_DESCRIPTOR_PAGE_AF                                                             | \
 | 
			
		||||
                                                        TT_DESCRIPTOR_PAGE_CACHE_POLICY_WRITE_THROUGH_NO_ALLOC)
 | 
			
		||||
#define TT_DESCRIPTOR_PAGE_DEVICE                  (TT_DESCRIPTOR_PAGE_TYPE_PAGE                                                           | \
 | 
			
		||||
                                                        TT_DESCRIPTOR_PAGE_NG_GLOBAL                                                      | \
 | 
			
		||||
                                                        TT_DESCRIPTOR_PAGE_S_NOT_SHARED                                                   | \
 | 
			
		||||
                                                        TT_DESCRIPTOR_PAGE_AP_RW_RW                                                       | \
 | 
			
		||||
                                                        TT_DESCRIPTOR_PAGE_AF                                                             | \
 | 
			
		||||
                                                        TT_DESCRIPTOR_PAGE_XN_MASK                                                        | \
 | 
			
		||||
                                                        TT_DESCRIPTOR_PAGE_CACHE_POLICY_SHAREABLE_DEVICE)
 | 
			
		||||
#define TT_DESCRIPTOR_PAGE_UNCACHED                (TT_DESCRIPTOR_PAGE_TYPE_PAGE                                                           | \
 | 
			
		||||
                                                        TT_DESCRIPTOR_PAGE_NG_GLOBAL                                                      | \
 | 
			
		||||
                                                        TT_DESCRIPTOR_PAGE_S_NOT_SHARED                                                   | \
 | 
			
		||||
                                                        TT_DESCRIPTOR_PAGE_AP_RW_RW                                                       | \
 | 
			
		||||
                                                        TT_DESCRIPTOR_PAGE_AF                                                             | \
 | 
			
		||||
                                                        TT_DESCRIPTOR_PAGE_CACHE_POLICY_NON_CACHEABLE)
 | 
			
		||||
 | 
			
		||||
// First Level Descriptors
 | 
			
		||||
@@ -210,7 +231,8 @@ typedef UINT32 ARM_PAGE_TABLE_ENTRY;
 | 
			
		||||
 | 
			
		||||
UINT32
 | 
			
		||||
ConvertSectionAttributesToPageAttributes (
 | 
			
		||||
  IN UINT32  SectionAttributes
 | 
			
		||||
  IN UINT32   SectionAttributes,
 | 
			
		||||
  IN BOOLEAN  IsLargePage
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
#endif // ARMV7_MMU_H_
 | 
			
		||||
 
 | 
			
		||||
@@ -14,7 +14,8 @@
 | 
			
		||||
#define MPIDR_U_BIT_MASK              0x40000000
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
  UINT64                  Mpidr;
 | 
			
		||||
  UINT32                ClusterId;
 | 
			
		||||
  UINT32                CoreId;
 | 
			
		||||
 | 
			
		||||
  // MP Core Mailbox
 | 
			
		||||
  EFI_PHYSICAL_ADDRESS  MailboxSetAddress;
 | 
			
		||||
@@ -23,9 +24,37 @@ typedef struct {
 | 
			
		||||
  UINT64                MailboxClearValue;
 | 
			
		||||
} ARM_CORE_INFO;
 | 
			
		||||
 | 
			
		||||
typedef struct{
 | 
			
		||||
        UINT64   Signature;
 | 
			
		||||
        UINT32   Length;
 | 
			
		||||
        UINT32   Revision;
 | 
			
		||||
        UINT64   OemId;
 | 
			
		||||
        UINT64   OemTableId;
 | 
			
		||||
        UINTN    OemRevision;
 | 
			
		||||
        UINTN    CreatorId;
 | 
			
		||||
        UINTN    CreatorRevision;
 | 
			
		||||
        EFI_GUID Identifier;
 | 
			
		||||
        UINTN    DataLen;
 | 
			
		||||
} ARM_PROCESSOR_TABLE_HEADER;
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
        ARM_PROCESSOR_TABLE_HEADER   Header;
 | 
			
		||||
        UINTN                        NumberOfEntries;
 | 
			
		||||
        ARM_CORE_INFO                *ArmCpus;
 | 
			
		||||
} ARM_PROCESSOR_TABLE;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define ARM_MP_CORE_INFO_GUID \
 | 
			
		||||
  { 0xa4ee0728, 0xe5d7, 0x4ac5,  {0xb2, 0x1e, 0x65, 0x8e, 0xd8, 0x57, 0xe8, 0x34} }
 | 
			
		||||
 | 
			
		||||
#define EFI_ARM_PROCESSOR_TABLE_SIGNATURE        SIGNATURE_64 ('C', 'P', 'U', 'T', 'A', 'B', 'L', 'E')
 | 
			
		||||
#define EFI_ARM_PROCESSOR_TABLE_REVISION         0x00010000 //1.0
 | 
			
		||||
#define EFI_ARM_PROCESSOR_TABLE_OEM_ID           SIGNATURE_64('A','R','M',' ', 'L', 't', 'd', ' ')
 | 
			
		||||
#define EFI_ARM_PROCESSOR_TABLE_OEM_TABLE_ID     SIGNATURE_64('V', 'E', 'R', 'S', 'A', 'T', 'I', 'L')
 | 
			
		||||
#define EFI_ARM_PROCESSOR_TABLE_OEM_REVISION     0x00000001
 | 
			
		||||
#define EFI_ARM_PROCESSOR_TABLE_CREATOR_ID       0xA5A5A5A5
 | 
			
		||||
#define EFI_ARM_PROCESSOR_TABLE_CREATOR_REVISION 0x01000001
 | 
			
		||||
 | 
			
		||||
extern EFI_GUID gArmMpCoreInfoGuid;
 | 
			
		||||
 | 
			
		||||
#endif /* ARM_MP_CORE_INFO_GUID_H_ */
 | 
			
		||||
 
 | 
			
		||||
@@ -18,16 +18,17 @@
 | 
			
		||||
/// Defines the structure of the CSSELR (Cache Size Selection) register
 | 
			
		||||
typedef union {
 | 
			
		||||
  struct {
 | 
			
		||||
    UINT32    InD      : 1;  ///< Instruction not Data bit
 | 
			
		||||
    UINT32    Level    : 3;  ///< Cache level (zero based)
 | 
			
		||||
    UINT32    TnD      : 1;  ///< Allocation not Data bit
 | 
			
		||||
    UINT32    Reserved : 27; ///< Reserved, RES0
 | 
			
		||||
    UINT32    InD       :1;  ///< Instruction not Data bit
 | 
			
		||||
    UINT32    Level     :3;  ///< Cache level (zero based)
 | 
			
		||||
    UINT32    TnD       :1;  ///< Allocation not Data bit
 | 
			
		||||
    UINT32    Reserved  :27; ///< Reserved, RES0
 | 
			
		||||
  } Bits; ///< Bitfield definition of the register
 | 
			
		||||
  UINT32 Data; ///< The entire 32-bit value
 | 
			
		||||
} CSSELR_DATA;
 | 
			
		||||
 | 
			
		||||
/// The cache type values for the InD field of the CSSELR register
 | 
			
		||||
typedef enum {
 | 
			
		||||
typedef enum
 | 
			
		||||
{
 | 
			
		||||
  /// Select the data or unified cache
 | 
			
		||||
  CsselrCacheTypeDataOrUnified = 0,
 | 
			
		||||
  /// Select the instruction cache
 | 
			
		||||
@@ -38,18 +39,18 @@ typedef enum {
 | 
			
		||||
/// Defines the structure of the CCSIDR (Current Cache Size ID) register
 | 
			
		||||
typedef union {
 | 
			
		||||
  struct {
 | 
			
		||||
    UINT64    LineSize      : 3;      ///< Line size (Log2(Num bytes in cache) - 4)
 | 
			
		||||
    UINT64    Associativity : 10;     ///< Associativity - 1
 | 
			
		||||
    UINT64    NumSets       : 15;     ///< Number of sets in the cache -1
 | 
			
		||||
    UINT64    Unknown       : 4;      ///< Reserved, UNKNOWN
 | 
			
		||||
    UINT64    Reserved      : 32;     ///< Reserved, RES0
 | 
			
		||||
    UINT64    LineSize           :3;  ///< Line size (Log2(Num bytes in cache) - 4)
 | 
			
		||||
    UINT64    Associativity      :10; ///< Associativity - 1
 | 
			
		||||
    UINT64    NumSets            :15; ///< Number of sets in the cache -1
 | 
			
		||||
    UINT64    Unknown            :4;  ///< Reserved, UNKNOWN
 | 
			
		||||
    UINT64    Reserved           :32; ///< Reserved, RES0
 | 
			
		||||
  } BitsNonCcidx; ///< Bitfield definition of the register when FEAT_CCIDX is not supported.
 | 
			
		||||
  struct {
 | 
			
		||||
    UINT64    LineSize      : 3;      ///< Line size (Log2(Num bytes in cache) - 4)
 | 
			
		||||
    UINT64    Associativity : 21;     ///< Associativity - 1
 | 
			
		||||
    UINT64    Reserved1     : 8;      ///< Reserved, RES0
 | 
			
		||||
    UINT64    NumSets       : 24;     ///< Number of sets in the cache -1
 | 
			
		||||
    UINT64    Reserved2     : 8;      ///< Reserved, RES0
 | 
			
		||||
    UINT64    LineSize           :3;  ///< Line size (Log2(Num bytes in cache) - 4)
 | 
			
		||||
    UINT64    Associativity      :21; ///< Associativity - 1
 | 
			
		||||
    UINT64    Reserved1          :8;  ///< Reserved, RES0
 | 
			
		||||
    UINT64    NumSets            :24; ///< Number of sets in the cache -1
 | 
			
		||||
    UINT64    Reserved2          :8;  ///< Reserved, RES0
 | 
			
		||||
  } BitsCcidxAA64; ///< Bitfield definition of the register when FEAT_IDX is supported.
 | 
			
		||||
  struct {
 | 
			
		||||
    UINT64    LineSize           : 3;
 | 
			
		||||
@@ -63,8 +64,8 @@ typedef union {
 | 
			
		||||
/// Defines the structure of the AARCH32 CCSIDR2 register.
 | 
			
		||||
typedef union {
 | 
			
		||||
  struct {
 | 
			
		||||
    UINT32    NumSets  : 24;          ///< Number of sets in the cache - 1
 | 
			
		||||
    UINT32    Reserved : 8;           ///< Reserved, RES0
 | 
			
		||||
    UINT32 NumSets               :24; ///< Number of sets in the cache - 1
 | 
			
		||||
    UINT32 Reserved              :8;  ///< Reserved, RES0
 | 
			
		||||
  } Bits; ///< Bitfield definition of the register
 | 
			
		||||
  UINT32 Data; ///< The entire 32-bit value
 | 
			
		||||
} CCSIDR2_DATA;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,20 +1,13 @@
 | 
			
		||||
/** @file
 | 
			
		||||
*
 | 
			
		||||
*  Copyright (c) 2020, NUVIA Inc. All rights reserved.<BR>
 | 
			
		||||
*  Copyright (c) 2012 - 2022, Arm Limited. All rights reserved.
 | 
			
		||||
*  Copyright (c) 2012-2017, ARM Limited. All rights reserved.
 | 
			
		||||
*
 | 
			
		||||
*  SPDX-License-Identifier: BSD-2-Clause-Patent
 | 
			
		||||
*
 | 
			
		||||
* @par Revision Reference:
 | 
			
		||||
*  - [1] SMC Calling Convention version 1.2
 | 
			
		||||
*  - SMC Calling Convention version 1.2
 | 
			
		||||
*    (https://developer.arm.com/documentation/den0028/c/?lang=en)
 | 
			
		||||
*  - [2] Arm True Random Number Generator Firmware, Interface 1.0,
 | 
			
		||||
*    Platform Design Document.
 | 
			
		||||
*    (https://developer.arm.com/documentation/den0098/latest/)
 | 
			
		||||
*
 | 
			
		||||
*  @par Glossary:
 | 
			
		||||
*    - TRNG - True Random Number Generator
 | 
			
		||||
*
 | 
			
		||||
**/
 | 
			
		||||
 | 
			
		||||
#ifndef ARM_STD_SMC_H_
 | 
			
		||||
@@ -100,8 +93,6 @@
 | 
			
		||||
#define ARM_SMC_ID_PSCI_MIGRATE_AARCH32        0x84000005
 | 
			
		||||
#define ARM_SMC_ID_PSCI_SYSTEM_OFF             0x84000008
 | 
			
		||||
#define ARM_SMC_ID_PSCI_SYSTEM_RESET           0x84000009
 | 
			
		||||
#define ARM_SMC_ID_PSCI_FEATURES               0x8400000A
 | 
			
		||||
#define ARM_SMC_ID_PSCI_SYSTEM_RESET2_AARCH64  0xC4000012
 | 
			
		||||
 | 
			
		||||
/* The current PSCI version is:  0.2 */
 | 
			
		||||
#define ARM_SMC_PSCI_VERSION_MAJOR  0
 | 
			
		||||
@@ -146,111 +137,4 @@
 | 
			
		||||
/*                                    0xbf00ff02 is reserved */
 | 
			
		||||
#define ARM_SMC_ID_TOS_REVISION       0xbf00ff03
 | 
			
		||||
 | 
			
		||||
// Firmware TRNG interface Function IDs
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
  SMC/HVC call to get the version of the TRNG backend,
 | 
			
		||||
  Cf. [2], 2.1 TRNG_VERSION
 | 
			
		||||
  Input values:
 | 
			
		||||
    W0    0x8400_0050
 | 
			
		||||
    W1-W7 Reserved (MBZ)
 | 
			
		||||
  Return values:
 | 
			
		||||
    Success (W0 > 0) W0[31] MBZ
 | 
			
		||||
      W0[30:16] Major revision
 | 
			
		||||
      W0[15:0] Minor revision
 | 
			
		||||
      W1 - W3 Reserved (MBZ)
 | 
			
		||||
    Error (W0 < 0)
 | 
			
		||||
      NOT_SUPPORTED Function not implemented
 | 
			
		||||
*/
 | 
			
		||||
#define ARM_SMC_ID_TRNG_VERSION  0x84000050
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
  SMC/HVC call to check if a TRNG function ID is implemented by the backend,
 | 
			
		||||
  Cf. [2], Section 2.2 TRNG_FEATURES
 | 
			
		||||
  Input Values
 | 
			
		||||
    W0    0x8400_0051
 | 
			
		||||
    W1    trng_func_id
 | 
			
		||||
    W2-W7 Reserved (MBZ)
 | 
			
		||||
  Return values:
 | 
			
		||||
    Success (W0 >= 0):
 | 
			
		||||
      SUCCESS Function is implemented.
 | 
			
		||||
        > 0     Function is implemented and
 | 
			
		||||
                has specific capabilities,
 | 
			
		||||
                see function definition.
 | 
			
		||||
    Error (W0 < 0)
 | 
			
		||||
      NOT_SUPPORTED Function with FID=trng_func_id
 | 
			
		||||
      is not implemented
 | 
			
		||||
*/
 | 
			
		||||
#define ARM_SMC_ID_TRNG_FEATURES  0x84000051
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
  SMC/HVC call to get the UUID of the TRNG backend,
 | 
			
		||||
  Cf. [2], Section 2.3 TRNG_GET_UUID
 | 
			
		||||
  Input Values:
 | 
			
		||||
    W0    0x8400_0052
 | 
			
		||||
    W1-W7 Reserved (MBZ)
 | 
			
		||||
  Return Values:
 | 
			
		||||
    Success (W0 != -1)
 | 
			
		||||
        W0 UUID[31:0]
 | 
			
		||||
        W1 UUID[63:32]
 | 
			
		||||
        W2 UUID[95:64]
 | 
			
		||||
        W3 UUID[127:96]
 | 
			
		||||
    Error (W0 = -1)
 | 
			
		||||
        W0 NOT_SUPPORTED
 | 
			
		||||
*/
 | 
			
		||||
#define ARM_SMC_ID_TRNG_GET_UUID  0x84000052
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
  AARCH32 SMC/HVC call to get entropy bits, Cf. [2], Section 2.4 TRNG_RND.
 | 
			
		||||
  Input values:
 | 
			
		||||
    W0    0x8400_0053
 | 
			
		||||
    W2-W7 Reserved (MBZ)
 | 
			
		||||
  Return values:
 | 
			
		||||
    Success (W0 = 0):
 | 
			
		||||
      W0 MBZ
 | 
			
		||||
      W1 Entropy[95:64]
 | 
			
		||||
      W2 Entropy[63:32]
 | 
			
		||||
      W3 Entropy[31:0]
 | 
			
		||||
    Error (W0 < 0)
 | 
			
		||||
          W0 NOT_SUPPORTED
 | 
			
		||||
          NO_ENTROPY
 | 
			
		||||
          INVALID_PARAMETERS
 | 
			
		||||
          W1 - W3 Reserved (MBZ)
 | 
			
		||||
*/
 | 
			
		||||
#define ARM_SMC_ID_TRNG_RND_AARCH32  0x84000053
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
  AARCH64 SMC/HVC call to get entropy bits, Cf. [2], Section 2.4 TRNG_RND.
 | 
			
		||||
  Input values:
 | 
			
		||||
      X0    0xC400_0053
 | 
			
		||||
      X2-X7 Reserved (MBZ)
 | 
			
		||||
  Return values:
 | 
			
		||||
    Success (X0 = 0):
 | 
			
		||||
      X0 MBZ
 | 
			
		||||
      X1 Entropy[191:128]
 | 
			
		||||
      X2 Entropy[127:64]
 | 
			
		||||
      X3 Entropy[63:0]
 | 
			
		||||
    Error (X0 < 0)
 | 
			
		||||
          X0 NOT_SUPPORTED
 | 
			
		||||
          NO_ENTROPY
 | 
			
		||||
          INVALID_PARAMETERS
 | 
			
		||||
          X1 - X3 Reserved (MBZ)
 | 
			
		||||
*/
 | 
			
		||||
#define ARM_SMC_ID_TRNG_RND_AARCH64  0xC4000053
 | 
			
		||||
 | 
			
		||||
// Firmware TRNG status codes
 | 
			
		||||
#define TRNG_STATUS_SUCCESS            (INT32)(0)
 | 
			
		||||
#define TRNG_STATUS_NOT_SUPPORTED      (INT32)(-1)
 | 
			
		||||
#define TRNG_STATUS_INVALID_PARAMETER  (INT32)(-2)
 | 
			
		||||
#define TRNG_STATUS_NO_ENTROPY         (INT32)(-3)
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 *  SMC64 SiP Service Calls
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#define SMC_FASTCALL      0x80000000
 | 
			
		||||
#define SMC64_FUNCTION    (SMC_FASTCALL     | 0x40000000)
 | 
			
		||||
#define SMC_SIP_FUNCTION  (SMC64_FUNCTION   | 0x02000000)
 | 
			
		||||
#define SMC_SIP_FUNCTION_ID(n)  (SMC_SIP_FUNCTION | (n))
 | 
			
		||||
 | 
			
		||||
#endif // ARM_STD_SMC_H_
 | 
			
		||||
 
 | 
			
		||||
@@ -17,6 +17,7 @@ typedef enum {
 | 
			
		||||
  ARM_GIC_ARCH_REVISION_3
 | 
			
		||||
} ARM_GIC_ARCH_REVISION;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
ARM_GIC_ARCH_REVISION
 | 
			
		||||
EFIAPI
 | 
			
		||||
ArmGicGetSupportedArchRevision (
 | 
			
		||||
 
 | 
			
		||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user