Add ArmPlatformPkg from ARM Ltd. patch.

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@11291 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
andrewfish
2011-02-01 05:41:42 +00:00
parent fb334ef6c5
commit 1d5d0ae92d
103 changed files with 14402 additions and 0 deletions

View File

@@ -0,0 +1,499 @@
#
# Copyright (c) 2011, ARM Limited. All rights reserved.
#
# This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
# which accompanies this distribution. The full text of the license may be found at
# http://opensource.org/licenses/bsd-license.php
#
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#
#
################################################################################
#
# Defines Section - statements that will be processed to create a Makefile.
#
################################################################################
[Defines]
PLATFORM_NAME = ArmVExpressPkg-CTA9x4
PLATFORM_GUID = eb2bd5ff-2379-4a06-9c12-db905cdee9ea
PLATFORM_VERSION = 0.1
DSC_SPECIFICATION = 0x00010005
!if $(EDK2_ARMVE_STANDALONE) == 1
OUTPUT_DIRECTORY = Build/ArmVExpress-CTA9x4-Standalone
!else
OUTPUT_DIRECTORY = Build/ArmVExpress-CTA9x4
!endif
SUPPORTED_ARCHITECTURES = ARM
BUILD_TARGETS = DEBUG|RELEASE
SKUID_IDENTIFIER = DEFAULT
FLASH_DEFINITION = ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-CTA9x4.fdf
[LibraryClasses.common]
!if $(BUILD_TARGETS) == RELEASE
DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
UncachedMemoryAllocationLib|ArmPkg/Library/UncachedMemoryAllocationLib/UncachedMemoryAllocationLib.inf
!else
DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
UncachedMemoryAllocationLib|ArmPkg/Library/UncachedMemoryAllocationLib/UncachedMemoryAllocationLib.inf
# UncachedMemoryAllocationLib|ArmPkg/Library/DebugUncachedMemoryAllocationLib/DebugUncachedMemoryAllocationLib.inf
!endif
ArmLib|ArmPkg/Library/ArmLib/ArmV7/ArmV7MPCoreLib.inf
ArmPlatformLib|ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressLibCTA9x4/ArmVExpressLib.inf
ArmTrustZoneLib|ArmPkg/Library/ArmTrustZoneLib/ArmTrustZoneLib.inf
ArmMPCoreMailBoxLib|ArmPkg/Library/ArmMPCoreMailBoxLib/ArmMPCoreMailBoxLib.inf
BaseLib|MdePkg/Library/BaseLib/BaseLib.inf
BaseMemoryLib|ArmPkg/Library/BaseMemoryLibStm/BaseMemoryLibStm.inf
SynchronizationLib|MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf
EfiResetSystemLib|ArmPlatformPkg/ArmVExpressPkg/Library/ResetSystemLib/ResetSystemLib.inf
PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf
PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
EblCmdLib|ArmPlatformPkg/Library/EblCmdLib/EblCmdLib.inf
EfiFileLib|EmbeddedPkg/Library/EfiFileLib/EfiFileLib.inf
PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf
#
# Uncomment (and comment out the next line) For RealView Debugger. The Standard IO window
# in the debugger will show load and unload commands for symbols. You can cut and paste this
# into the command window to load symbols. We should be able to use a script to do this, but
# the version of RVD I have does not support scripts accessing system memory.
#
# PeCoffExtraActionLib|ArmPkg/Library/RvdPeCoffExtraActionLib/RvdPeCoffExtraActionLib.inf
PeCoffExtraActionLib|ArmPkg/Library/DebugPeCoffExtraActionLib/DebugPeCoffExtraActionLib.inf
# PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf
CacheMaintenanceLib|ArmPkg/Library/ArmCacheMaintenanceLib/ArmCacheMaintenanceLib.inf
DefaultExceptioHandlerLib|ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandlerLib.inf
SemihostLib|ArmPkg/Library/SemihostLib/SemihostLib.inf
RealTimeClockLib|ArmPlatformPkg/Library/PL031RealTimeClockLib/PL031RealTimeClockLib.inf
IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf
UefiDecompressLib|MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.inf
PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
UefiLib|MdePkg/Library/UefiLib/UefiLib.inf
HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf
DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf
DxeServicesTableLib|MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.inf
UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf
UefiApplicationEntryPoint|MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf
# ARM PL341 DMC Driver
PL341DmcLib|ArmPkg/Drivers/PL34xDmc/PL341Dmc.inf
# ARM PL301 Axi Driver
PL301AxiLib|ArmPkg/Drivers/PL301Axi/PL301Axi.inf
#
# Assume everything is fixed at build
#
PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
UefiRuntimeLib|MdePkg/Library/UefiRuntimeLib/UefiRuntimeLib.inf
EblAddExternalCommandLib|EmbeddedPkg/Library/EblAddExternalCommandLib/EblAddExternalCommandLib.inf
CpuLib|MdePkg/Library/BaseCpuLib/BaseCpuLib.inf
PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf
EblNetworkLib|EmbeddedPkg/Library/EblNetworkLib/EblNetworkLib.inf
ArmDisassemblerLib|ArmPkg/Library/ArmDisassemblerLib/ArmDisassemblerLib.inf
DebugAgentLib|MdeModulePkg/Library/DebugAgentLibNull/DebugAgentLibNull.inf
#DebugAgentTimerLib|ArmPlatformPkg/ArmVExpressPkg/Library/DebugAgentTimerLib/DebugAgentTimerLib.inf
SerialPortLib|ArmPlatformPkg/Library/PL011SerialPortLib/PL011SerialPortLib.inf
TimerLib|ArmPlatformPkg/Library/SP804TimerLib/SP804TimerLib.inf
DmaLib|ArmPkg/Library/ArmDmaLib/ArmDmaLib.inf
BdsLib|ArmPkg/Library/BdsLib/BdsLib.inf
[LibraryClasses.common.SEC]
ArmLib|ArmPkg/Library/ArmLib/ArmV7/ArmV7MPCoreLibSec.inf
PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
ArmPlatformLib|ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressLibCTA9x4/ArmVExpressSecLib.inf
# 1/123 faster than Stm or Vstm version
BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
# Uncomment to turn on GDB stub in SEC.
#DebugAgentLib|EmbeddedPkg/Library/GdbDebugAgent/GdbDebugAgent.inf
# ARM PL354 SMC Driver
PL354SmcSecLib|ArmPkg/Drivers/PL35xSmc/PL354SmcSec.inf
# ARM PL310 L2 Cache Driver
L2X0CacheLib|ArmPkg/Drivers/PL310L2Cache/PL310L2CacheSec.inf
# ARM PL390 General Interrupt Driver in Secure and Non-secure
PL390GicSecLib|ArmPkg/Drivers/PL390Gic/PL390GicSec.inf
PL390GicNonSecLib|ArmPkg/Drivers/PL390Gic/PL390GicNonSec.inf
[LibraryClasses.common.PEI_CORE]
BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
# note: this won't actually work since globals in PEI are not writeable
# need to generate an ARM PEI services table pointer implementation
PeiServicesTablePointerLib|ArmPlatformPkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointerLib.inf
PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf
MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf
PeiCoreEntryPoint|MdePkg/Library/PeiCoreEntryPoint/PeiCoreEntryPoint.inf
PerformanceLib|MdeModulePkg/Library/PeiPerformanceLib/PeiPerformanceLib.inf
ReportStatusCodeLib|MdeModulePkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.inf
OemHookStatusCodeLib|MdeModulePkg/Library/OemHookStatusCodeLibNull/OemHookStatusCodeLibNull.inf
PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf
DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
UefiDecompressLib|MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.inf
ExtractGuidedSectionLib|MdePkg/Library/PeiExtractGuidedSectionLib/PeiExtractGuidedSectionLib.inf
[LibraryClasses.common.PEIM]
BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
# note: this won't actually work since globals in PEI are not writeable
# need to generate an ARM PEI services table pointer implementation
PeiServicesTablePointerLib|ArmPlatformPkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointerLib.inf
PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf
MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf
PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf
PerformanceLib|MdeModulePkg/Library/PeiPerformanceLib/PeiPerformanceLib.inf
ReportStatusCodeLib|MdeModulePkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.inf
OemHookStatusCodeLib|MdeModulePkg/Library/OemHookStatusCodeLibNull/OemHookStatusCodeLibNull.inf
PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf
DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
PeiResourcePublicationLib|MdePkg/Library/PeiResourcePublicationLib/PeiResourcePublicationLib.inf
UefiDecompressLib|MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.inf
ExtractGuidedSectionLib|MdePkg/Library/PeiExtractGuidedSectionLib/PeiExtractGuidedSectionLib.inf
[LibraryClasses.common.DXE_CORE]
HobLib|MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.inf
MemoryAllocationLib|MdeModulePkg/Library/DxeCoreMemoryAllocationLib/DxeCoreMemoryAllocationLib.inf
DxeCoreEntryPoint|MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.inf
ReportStatusCodeLib|IntelFrameworkModulePkg/Library/DxeReportStatusCodeLibFramework/DxeReportStatusCodeLib.inf
ExtractGuidedSectionLib|MdePkg/Library/DxeExtractGuidedSectionLib/DxeExtractGuidedSectionLib.inf
UefiDecompressLib|MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.inf
DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf
PerformanceLib|MdeModulePkg/Library/DxeCorePerformanceLib/DxeCorePerformanceLib.inf
[LibraryClasses.common.DXE_DRIVER]
ReportStatusCodeLib|IntelFrameworkModulePkg/Library/DxeReportStatusCodeLibFramework/DxeReportStatusCodeLib.inf
DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf
SecurityManagementLib|MdeModulePkg/Library/DxeSecurityManagementLib/DxeSecurityManagementLib.inf
PerformanceLib|MdeModulePkg/Library/DxePerformanceLib/DxePerformanceLib.inf
MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
[LibraryClasses.common.UEFI_APPLICATION]
ReportStatusCodeLib|IntelFrameworkModulePkg/Library/DxeReportStatusCodeLibFramework/DxeReportStatusCodeLib.inf
UefiDecompressLib|IntelFrameworkModulePkg/Library/BaseUefiTianoCustomDecompressLib/BaseUefiTianoCustomDecompressLib.inf
PerformanceLib|MdeModulePkg/Library/DxePerformanceLib/DxePerformanceLib.inf
MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
[LibraryClasses.common.UEFI_DRIVER]
ReportStatusCodeLib|IntelFrameworkModulePkg/Library/DxeReportStatusCodeLibFramework/DxeReportStatusCodeLib.inf
UefiDecompressLib|IntelFrameworkModulePkg/Library/BaseUefiTianoCustomDecompressLib/BaseUefiTianoCustomDecompressLib.inf
ExtractGuidedSectionLib|MdePkg/Library/DxeExtractGuidedSectionLib/DxeExtractGuidedSectionLib.inf
PerformanceLib|MdeModulePkg/Library/DxePerformanceLib/DxePerformanceLib.inf
MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
[LibraryClasses.common.DXE_RUNTIME_DRIVER]
HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
ReportStatusCodeLib|IntelFrameworkModulePkg/Library/DxeReportStatusCodeLibFramework/DxeReportStatusCodeLib.inf
CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf
# PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
[LibraryClasses.ARM]
#
# It is not possible to prevent the ARM compiler for generic intrinsic functions.
# This library provides the instrinsic functions generate by a given compiler.
# [LibraryClasses.ARM] and NULL mean link this library into all ARM images.
#
NULL|ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf
[BuildOptions]
RVCT:*_*_ARM_ARCHCC_FLAGS == --cpu Cortex-A9 --thumb -I$(WORKSPACE)/ArmPlatformPkg/ArmVExpressPkg/Include/Platform/CTA9x4
RVCT:*_*_ARM_ARCHASM_FLAGS == --cpu Cortex-A9 -I$(WORKSPACE)/ArmPlatformPkg/ArmVExpressPkg/Include/Platform/CTA9x4
RVCT:RELEASE_*_*_CC_FLAGS = -DMDEPKG_NDEBUG -I$(WORKSPACE)/ArmPlatformPkg/ArmVExpressPkg/Include/Platform/CTA9x4
ARMGCC:*_*_ARM_ARCHCC_FLAGS == -I$(WORKSPACE)/ArmPlatformPkg/ArmVExpressPkg/Include/Platform/CTA9x4
ARMGCC:RELEASE_*_*_CC_FLAGS = -DMDEPKG_NDEBUG -I$(WORKSPACE)/ArmPlatformPkg/ArmVExpressPkg/Include/Platform/CTA9x4
################################################################################
#
# Pcd Section - list of all EDK II PCD Entries defined by this Platform
#
################################################################################
[PcdsFeatureFlag.common]
gEfiMdePkgTokenSpaceGuid.PcdComponentNameDisable|TRUE
gEfiMdePkgTokenSpaceGuid.PcdDriverDiagnosticsDisable|TRUE
gEfiMdePkgTokenSpaceGuid.PcdComponentName2Disable|TRUE
gEfiMdePkgTokenSpaceGuid.PcdDriverDiagnostics2Disable|TRUE
#
# Control what commands are supported from the UI
# Turn these on and off to add features or save size
#
gEmbeddedTokenSpaceGuid.PcdEmbeddedMacBoot|TRUE
gEmbeddedTokenSpaceGuid.PcdEmbeddedDirCmd|TRUE
gEmbeddedTokenSpaceGuid.PcdEmbeddedHobCmd|TRUE
gEmbeddedTokenSpaceGuid.PcdEmbeddedHwDebugCmd|TRUE
gEmbeddedTokenSpaceGuid.PcdEmbeddedPciDebugCmd|TRUE
gEmbeddedTokenSpaceGuid.PcdEmbeddedIoEnable|FALSE
gEmbeddedTokenSpaceGuid.PcdEmbeddedScriptCmd|FALSE
gEmbeddedTokenSpaceGuid.PcdCacheEnable|TRUE
# Use the Vector Table location in CpuDxe. We will not copy the Vector Table at PcdCpuVectorBaseAddress
gArmTokenSpaceGuid.PcdRelocateVectorTable|FALSE
gEmbeddedTokenSpaceGuid.PcdPrePiProduceMemoryTypeInformationHob|TRUE
gArmTokenSpaceGuid.PcdCpuDxeProduceDebugSupport|FALSE
gEfiMdeModulePkgTokenSpaceGuid.PcdTurnOffUsbLegacySupport|TRUE
!if $(EDK2_ARMVE_STANDALONE) == 1
gArmPlatformTokenSpaceGuid.PcdStandalone|TRUE
!endif
!if $(EDK2_SKIP_PEICORE) == 1
gArmTokenSpaceGuid.PcdSkipPeiCore|TRUE
!endif
[PcdsFixedAtBuild.common]
gEmbeddedTokenSpaceGuid.PcdEmbeddedPrompt|"ArmVExpress %a"
gEmbeddedTokenSpaceGuid.PcdPrePiCpuMemorySize|32
gEmbeddedTokenSpaceGuid.PcdPrePiCpuIoSize|0
gEfiMdePkgTokenSpaceGuid.PcdMaximumUnicodeStringLength|1000000
gEfiMdePkgTokenSpaceGuid.PcdMaximumAsciiStringLength|1000000
gEfiMdePkgTokenSpaceGuid.PcdMaximumLinkedListLength|1000000
gEfiMdePkgTokenSpaceGuid.PcdSpinLockTimeout|10000000
gEfiMdePkgTokenSpaceGuid.PcdDebugClearMemoryValue|0xAF
gEfiMdePkgTokenSpaceGuid.PcdPerformanceLibraryPropertyMask|1
gEfiMdePkgTokenSpaceGuid.PcdPostCodePropertyMask|0
gEfiMdePkgTokenSpaceGuid.PcdUefiLibMaxPrintBufferSize|320
# DEBUG_ASSERT_ENABLED 0x01
# DEBUG_PRINT_ENABLED 0x02
# DEBUG_CODE_ENABLED 0x04
# CLEAR_MEMORY_ENABLED 0x08
# ASSERT_BREAKPOINT_ENABLED 0x10
# ASSERT_DEADLOOP_ENABLED 0x20
gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x2f
# DEBUG_INIT 0x00000001 // Initialization
# DEBUG_WARN 0x00000002 // Warnings
# DEBUG_LOAD 0x00000004 // Load events
# DEBUG_FS 0x00000008 // EFI File system
# DEBUG_POOL 0x00000010 // Alloc & Free's
# DEBUG_PAGE 0x00000020 // Alloc & Free's
# DEBUG_INFO 0x00000040 // Verbose
# DEBUG_DISPATCH 0x00000080 // PEI/DXE Dispatchers
# DEBUG_VARIABLE 0x00000100 // Variable
# DEBUG_BM 0x00000400 // Boot Manager
# DEBUG_BLKIO 0x00001000 // BlkIo Driver
# DEBUG_NET 0x00004000 // SNI Driver
# DEBUG_UNDI 0x00010000 // UNDI Driver
# DEBUG_LOADFILE 0x00020000 // UNDI Driver
# DEBUG_EVENT 0x00080000 // Event messages
# DEBUG_ERROR 0x80000000 // Error
gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x8000000F
gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x07
gEmbeddedTokenSpaceGuid.PcdEmbeddedAutomaticBootCommand|""
gEmbeddedTokenSpaceGuid.PcdEmbeddedDefaultTextColor|0x07
gEmbeddedTokenSpaceGuid.PcdEmbeddedMemVariableStoreSize|0x10000
#
# Optional feature to help prevent EFI memory map fragments
# Turned on and off via: PcdPrePiProduceMemoryTypeInformationHob
# Values are in EFI Pages (4K). DXE Core will make sure that
# at least this much of each type of memory can be allocated
# from a single memory range. This way you only end up with
# maximum of two fragements for each type in the memory map
# (the memory used, and the free memory that was prereserved
# but not used).
#
gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiACPIReclaimMemory|0
gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiACPIMemoryNVS|0
gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiReservedMemoryType|0
gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesData|50
gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesCode|20
gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiBootServicesCode|400
gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiBootServicesData|20000
gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderCode|20
gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderData|0
gArmPlatformTokenSpaceGuid.PcdMPCoreSupport|1
gArmTokenSpaceGuid.PcdVFPEnabled|1
# Stacks for MPCores in Secure World
gArmPlatformTokenSpaceGuid.PcdCPUCoresSecStackBase|0x49E00000 # Top of SEC Stack for Secure World
gArmPlatformTokenSpaceGuid.PcdCPUCoreSecStackSize|0x2000 # Stack for each of the 4 CPU cores
# Stacks for MPCores in Monitor Mode
gArmPlatformTokenSpaceGuid.PcdCPUCoresSecMonStackBase|0x49D00000 # Top of SEC Stack for Monitor World
gArmPlatformTokenSpaceGuid.PcdCPUCoreSecMonStackSize|0x2000 # Stack for each of the 4 CPU cores
# Stacks for MPCores in Normal World
gArmPlatformTokenSpaceGuid.PcdCPUCoresNonSecStackBase|0x48000000 # Top of SEC Stack for Normal World
gArmPlatformTokenSpaceGuid.PcdCPUCoresNonSecStackSize|0x00020000 # Stack for each of the 4 CPU cores
gArmPlatformTokenSpaceGuid.PcdPeiServicePtrAddr|0x48020004 # pei services ptr just above stack. Overlapped with the stack of CoreId 1
gEmbeddedTokenSpaceGuid.PcdTimerPeriod|100000 # expressed in 100ns units, 100,000 x 100 ns = 10,000,000 ns = 10 ms
#
# ARM Pcds
#
gArmTokenSpaceGuid.PcdArmUncachedMemoryMask|0x0000000040000000
#
# ARM PrimeCell
#
gArmTokenSpaceGuid.PcdPL180SysMciRegAddress|0x10000048
gArmTokenSpaceGuid.PcdPL180MciBaseAddress|0x10005000
#
# ARM PL390 General Interrupt Controller
#
gArmTokenSpaceGuid.PcdGicDistributorBase|0x1e001000
gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase|0x1e000100
#
# ARM OS Loader
#
# Versatile Express machine type (ARM VERSATILE EXPRESS = 2272) required for ARM Linux:
gArmTokenSpaceGuid.PcdArmMachineType|2272
gArmTokenSpaceGuid.PcdLinuxKernelDP|L"VenHw(02118005-9DA7-443a-92D5-781F022AEDBB)/MemoryMapped(0,0x46000000,0x46400000)"
gArmTokenSpaceGuid.PcdLinuxAtag|"rdinit=/bin/ash debug earlyprintk console=ttyAMA0,38400 mem=1G"
gArmTokenSpaceGuid.PcdFdtDP|L""
#
# ARM PL111 Colour LCD Controller
#
gArmVExpressTokenSpaceGuid.PcdPL111RegistersBaseMotherboard|0x1001F000
gArmVExpressTokenSpaceGuid.PcdPL111RegistersBaseDaughterboard|0x10020000
gArmVExpressTokenSpaceGuid.PcdPL111VRamBaseMotherboard|0x4C000000
gArmVExpressTokenSpaceGuid.PcdPL111VRamBaseDaughterboard|0x64000000
gArmVExpressTokenSpaceGuid.PcdPL111VRamSize|0x800000
#
# ARM L2x0 PCDs
#
gArmTokenSpaceGuid.PcdL2x0ControllerBase|0x1E00A000
#
# ARM VE MP Core Mailbox
#
gArmTokenSpaceGuid.PcdMPCoreMailboxSetAddress|0x10000030
gArmTokenSpaceGuid.PcdMPCoreMailboxGetAddress|0x10000030
gArmTokenSpaceGuid.PcdMPCoreMailboxClearAddress|0x10000034
gArmTokenSpaceGuid.PcdMPCoreMailboxClearValue|0xFFFFFFFF
################################################################################
#
# Components Section - list of all EDK II Modules needed by this Platform
#
################################################################################
[Components.common]
#
# SEC
#
ArmPlatformPkg/Sec/Sec.inf
ArmPlatformPkg/PrePeiCore/PrePeiCoreMPCore.inf
#
# PEI Phase modules
#
MdeModulePkg/Core/Pei/PeiMain.inf
MdeModulePkg/Universal/PCD/Pei/Pcd.inf {
<LibraryClasses>
PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
}
ArmPlatformPkg/PlatformPei/PlatformPei.inf
ArmPlatformPkg/MemoryInitPei/MemoryInitPei.inf
IntelFrameworkModulePkg/Universal/StatusCode/Pei/StatusCodePei.inf
Nt32Pkg/BootModePei/BootModePei.inf
MdeModulePkg/Universal/Variable/Pei/VariablePei.inf
MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf {
<LibraryClasses>
NULL|IntelFrameworkModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf
}
#
# DXE
#
MdeModulePkg/Core/Dxe/DxeMain.inf {
<LibraryClasses>
PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
NULL|MdeModulePkg/Library/DxeCrc32GuidedSectionExtractLib/DxeCrc32GuidedSectionExtractLib.inf
}
#
# Architectural Protocols
#
ArmPkg/Drivers/CpuDxe/CpuDxe.inf
MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf
MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf
MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf
MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf
MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf
MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf
EmbeddedPkg/EmbeddedMonotonicCounter/EmbeddedMonotonicCounter.inf
EmbeddedPkg/ResetRuntimeDxe/ResetRuntimeDxe.inf
EmbeddedPkg/RealTimeClockRuntimeDxe/RealTimeClockRuntimeDxe.inf
EmbeddedPkg/MetronomeDxe/MetronomeDxe.inf
EmbeddedPkg/SimpleTextInOutSerial/SimpleTextInOutSerial.inf
ArmPkg/Drivers/PL390Gic/PL390GicDxe.inf
ArmPlatformPkg/ArmVExpressPkg/NorFlashDxe/NorFlashDxe.inf
ArmPlatformPkg/Drivers/SP804TimerDxe/SP804TimerDxe.inf
#
# Semi-hosting filesystem
#
ArmPkg/Filesystem/SemihostFs/SemihostFs.inf
#
# Multimedia Card Interface
#
ArmPkg/Universal/MmcDxe/MmcDxe.inf
ArmPkg/Drivers/PL180MciDxe/PL180MciDxe.inf
#
# FAT filesystem + GPT/MBR partitioning
#
MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf
MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf
FatPkg/EnhancedFatDxe/Fat.inf
MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf
#
# Application
#
EmbeddedPkg/Ebl/Ebl.inf
#
# Bds
#
MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf
ArmPlatformPkg/Bds/Bds.inf

View File

@@ -0,0 +1,391 @@
# FLASH layout file for ARM VE.
#
# Copyright (c) 2011, ARM Limited. All rights reserved.
#
# This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
# which accompanies this distribution. The full text of the license may be found at
# http://opensource.org/licenses/bsd-license.php
#
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#
################################################################################
#
# FD Section
# The [FD] Section is made up of the definition statements and a
# description of what goes into the Flash Device Image. Each FD section
# defines one flash "device" image. A flash device image may be one of
# the following: Removable media bootable image (like a boot floppy
# image,) an Option ROM image (that would be "flashed" into an add-in
# card,) a System "Flash" image (that would be burned into a system's
# flash) or an Update ("Capsule") image that will be used to update and
# existing system flash.
#
################################################################################
[FD.Sec_ArmVExpress_EFI]
BaseAddress = 0x44000000|gArmTokenSpaceGuid.PcdSecureFdBaseAddress #The base address of the Secure FLASH Device.
Size = 0x00200000|gArmTokenSpaceGuid.PcdSecureFdSize #The size in bytes of the Secure FLASH Device
ErasePolarity = 1
BlockSize = 0x00001000
NumBlocks = 0x200
################################################################################
#
# Following are lists of FD Region layout which correspond to the locations of different
# images within the flash device.
#
# Regions must be defined in ascending order and may not overlap.
#
# A Layout Region start with a eight digit hex offset (leading "0x" required) followed by
# the pipe "|" character, followed by the size of the region, also in hex with the leading
# "0x" characters. Like:
# Offset|Size
# PcdOffsetCName|PcdSizeCName
# RegionType <FV, DATA, or FILE>
#
################################################################################
0x00000000|0x00200000
gEmbeddedTokenSpaceGuid.PcdFlashFvSecBase|gEmbeddedTokenSpaceGuid.PcdFlashFvSecSize
FV = FVMAIN_SEC
[FD.ArmVExpress_EFI]
!if $(EDK2_ARMVE_STANDALONE) == 1
BaseAddress = 0x45000000|gEmbeddedTokenSpaceGuid.PcdEmbeddedFdBaseAddress # The base address of the Firmware in NOR Flash.
!else
BaseAddress = 0x80000000|gEmbeddedTokenSpaceGuid.PcdEmbeddedFdBaseAddress # The base address of the Firmware in remapped DRAM.
!endif
Size = 0x00200000|gEmbeddedTokenSpaceGuid.PcdEmbeddedFdSize # The size in bytes of the FLASH Device
ErasePolarity = 1
# This one is tricky, it must be: BlockSize * NumBlocks = Size
BlockSize = 0x00001000
NumBlocks = 0x200
################################################################################
#
# Following are lists of FD Region layout which correspond to the locations of different
# images within the flash device.
#
# Regions must be defined in ascending order and may not overlap.
#
# A Layout Region start with a eight digit hex offset (leading "0x" required) followed by
# the pipe "|" character, followed by the size of the region, also in hex with the leading
# "0x" characters. Like:
# Offset|Size
# PcdOffsetCName|PcdSizeCName
# RegionType <FV, DATA, or FILE>
#
################################################################################
0x00000000|0x00200000
gEmbeddedTokenSpaceGuid.PcdFlashFvMainBase|gEmbeddedTokenSpaceGuid.PcdFlashFvMainSize
FV = FVMAIN_COMPACT
[FD.NVVariableStore]
BaseAddress = 0x47FC0000
Size = 0x00030000
ErasePolarity = 1
BlockSize = 0x00010000
NumBlocks = 0x3
0x00000000|0x00010000
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
#NV_VARIABLE_STORE
DATA = {
## This is the EFI_FIRMWARE_VOLUME_HEADER
# ZeroVector []
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
# FileSystemGuid: gEfiSystemNvDataFvGuid =
# { 0xFFF12B8D, 0x7696, 0x4C8B, { 0xA9, 0x85, 0x27, 0x47, 0x07, 0x5B, 0x4F, 0x50 }}
0x8D, 0x2B, 0xF1, 0xFF, 0x96, 0x76, 0x8B, 0x4C,
0xA9, 0x85, 0x27, 0x47, 0x07, 0x5B, 0x4F, 0x50,
# FvLength: 0x30000
0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
#Signature "_FVH" #Attributes
0x5f, 0x46, 0x56, 0x48, 0xff, 0xfe, 0x04, 0x00,
#HeaderLength #CheckSum #ExtHeaderOffset #Reserved #Revision
0x48, 0x00, 0x34, 0x09, 0x00, 0x00, 0x00, 0x02,
#Blockmap[0]: 3 Blocks * 0x10000 Bytes / Block
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
#Blockmap[1]: End
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
## This is the VARIABLE_STORE_HEADER
#Signature: gEfiVariableGuid =
# { 0xddcf3616, 0x3275, 0x4164, { 0x98, 0xb6, 0xfe, 0x85, 0x70, 0x7f, 0xfe, 0x7d }}
0x16, 0x36, 0xcf, 0xdd, 0x75, 0x32, 0x64, 0x41,
0x98, 0xb6, 0xfe, 0x85, 0x70, 0x7f, 0xfe, 0x7d,
#Size: 0x10000 (gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize) - 0x48 (size of EFI_FIRMWARE_VOLUME_HEADER: HeaderLength) = 0xFFB8
# This can speed up the Variable Dispatch a bit.
0xB8, 0xFF, 0x00, 0x00,
#FORMATTED: 0x5A #HEALTHY: 0xFE #Reserved: UINT16 #Reserved1: UINT32
0x5A, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}
0x00010000|0x00010000
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize
#FTW_SPARE_STORE - See EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER
DATA = {
#Signature: gEfiSystemNvDataFvGuid =
# { 0xfff12b8d, 0x7696, 0x4c8b, { 0xa9, 0x85, 0x27, 0x47, 0x07, 0x5b, 0x4f, 0x50 } }
0x8d, 0x2b, 0xf1, 0xff, 0x96, 0x32, 0x8b, 0x4c,
0xa9, 0x85, 0x27, 0x47, 0x07, 0x5b, 0x4f, 0x50,
#FIXME: 32bit CRC caculated for this header.
0x00, 0x00, 0x00, 0x00,
# Working block valid bit
0x00,
# Total size of the following write queue range. (64bit)
0xB8, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
# Write Queue data: EFI_FAULT_TOLERANT_WRITE_HEADER
# State
0x00,
# CallerId: Guid
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
# NumberOfWrites, PrivateDataSize
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}
0x00020000|0x00010000
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize
DATA = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}
################################################################################
#
# FV Section
#
# [FV] section is used to define what components or modules are placed within a flash
# device file. This section also defines order the components and modules are positioned
# within the image. The [FV] section consists of define statements, set statements and
# module statements.
#
################################################################################
[FV.FVMAIN_SEC]
FvAlignment = 8
ERASE_POLARITY = 1
MEMORY_MAPPED = TRUE
STICKY_WRITE = TRUE
LOCK_CAP = TRUE
LOCK_STATUS = TRUE
WRITE_DISABLED_CAP = TRUE
WRITE_ENABLED_CAP = TRUE
WRITE_STATUS = TRUE
WRITE_LOCK_CAP = TRUE
WRITE_LOCK_STATUS = TRUE
READ_DISABLED_CAP = TRUE
READ_ENABLED_CAP = TRUE
READ_STATUS = TRUE
READ_LOCK_CAP = TRUE
READ_LOCK_STATUS = TRUE
INF ArmPlatformPkg/Sec/Sec.inf
[FV.FvMain]
BlockSize = 0x40
NumBlocks = 0 # This FV gets compressed so make it just big enough
FvAlignment = 8 # FV alignment and FV attributes setting.
ERASE_POLARITY = 1
MEMORY_MAPPED = TRUE
STICKY_WRITE = TRUE
LOCK_CAP = TRUE
LOCK_STATUS = TRUE
WRITE_DISABLED_CAP = TRUE
WRITE_ENABLED_CAP = TRUE
WRITE_STATUS = TRUE
WRITE_LOCK_CAP = TRUE
WRITE_LOCK_STATUS = TRUE
READ_DISABLED_CAP = TRUE
READ_ENABLED_CAP = TRUE
READ_STATUS = TRUE
READ_LOCK_CAP = TRUE
READ_LOCK_STATUS = TRUE
INF MdeModulePkg/Core/Dxe/DxeMain.inf
#
# PI DXE Drivers producing Architectural Protocols (EFI Services)
#
INF ArmPkg/Drivers/CpuDxe/CpuDxe.inf
INF MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf
INF MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf
INF MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf
INF MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf
INF MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf
INF MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf
INF EmbeddedPkg/EmbeddedMonotonicCounter/EmbeddedMonotonicCounter.inf
INF EmbeddedPkg/ResetRuntimeDxe/ResetRuntimeDxe.inf
INF EmbeddedPkg/RealTimeClockRuntimeDxe/RealTimeClockRuntimeDxe.inf
INF EmbeddedPkg/MetronomeDxe/MetronomeDxe.inf
INF EmbeddedPkg/SimpleTextInOutSerial/SimpleTextInOutSerial.inf
INF ArmPkg/Drivers/PL390Gic/PL390GicDxe.inf
INF ArmPlatformPkg/Drivers/SP804TimerDxe/SP804TimerDxe.inf
INF ArmPlatformPkg/ArmVExpressPkg/NorFlashDxe/NorFlashDxe.inf
#
# Semi-hosting filesystem
#
INF ArmPkg/Filesystem/SemihostFs/SemihostFs.inf
#
# FAT filesystem + GPT/MBR partitioning
#
INF MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf
INF MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf
INF FatPkg/EnhancedFatDxe/Fat.inf
INF MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf
#
# Multimedia Card Interface
#
INF ArmPkg/Universal/MmcDxe/MmcDxe.inf
INF ArmPkg/Drivers/PL180MciDxe/PL180MciDxe.inf
#
# UEFI application (Shell Embedded Boot Loader)
#
INF EmbeddedPkg/Ebl/Ebl.inf
#
# Bds
#
INF MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf
INF ArmPlatformPkg/Bds/Bds.inf
[FV.FVMAIN_COMPACT]
FvAlignment = 8
ERASE_POLARITY = 1
MEMORY_MAPPED = TRUE
STICKY_WRITE = TRUE
LOCK_CAP = TRUE
LOCK_STATUS = TRUE
WRITE_DISABLED_CAP = TRUE
WRITE_ENABLED_CAP = TRUE
WRITE_STATUS = TRUE
WRITE_LOCK_CAP = TRUE
WRITE_LOCK_STATUS = TRUE
READ_DISABLED_CAP = TRUE
READ_ENABLED_CAP = TRUE
READ_STATUS = TRUE
READ_LOCK_CAP = TRUE
READ_LOCK_STATUS = TRUE
INF ArmPlatformPkg/PrePeiCore/PrePeiCoreMPCore.inf
INF MdeModulePkg/Core/Pei/PeiMain.inf
INF ArmPlatformPkg/PlatformPei/PlatformPei.inf
INF ArmPlatformPkg/MemoryInitPei/MemoryInitPei.inf
INF MdeModulePkg/Universal/PCD/Pei/Pcd.inf
INF IntelFrameworkModulePkg/Universal/StatusCode/Pei/StatusCodePei.inf
INF MdeModulePkg/Universal/Variable/Pei/VariablePei.inf
INF MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
FILE FV_IMAGE = 9E21FD93-9C72-4c15-8C4B-E77F1DB2D792 {
SECTION GUIDED EE4E5898-3914-4259-9D6E-DC7BD79403CF PROCESSING_REQUIRED = TRUE {
SECTION FV_IMAGE = FVMAIN
}
}
################################################################################
#
# Rules are use with the [FV] section's module INF type to define
# how an FFS file is created for a given INF file. The following Rule are the default
# rules for the different module type. User can add the customized rules to define the
# content of the FFS file.
#
################################################################################
############################################################################
# Example of a DXE_DRIVER FFS file with a Checksum encapsulation section #
############################################################################
#
#[Rule.Common.DXE_DRIVER]
# FILE DRIVER = $(NAMED_GUID) {
# DXE_DEPEX DXE_DEPEX Optional |.depex
# COMPRESS PI_STD {
# GUIDED {
# PE32 PE32 |.efi
# UI STRING="$(MODULE_NAME)" Optional
# VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
# }
# }
# }
#
############################################################################
[Rule.Common.SEC]
FILE SEC = $(NAMED_GUID) RELOCS_STRIPPED {
TE TE Align = 8 |.efi
}
[Rule.Common.PEI_CORE]
FILE PEI_CORE = $(NAMED_GUID) {
TE TE |.efi
UI STRING ="$(MODULE_NAME)" Optional
}
[Rule.Common.PEIM]
FILE PEIM = $(NAMED_GUID) {
PEI_DEPEX PEI_DEPEX Optional |.depex
TE TE |.efi
UI STRING="$(MODULE_NAME)" Optional
}
[Rule.Common.PEIM.TIANOCOMPRESSED]
FILE PEIM = $(NAMED_GUID) DEBUG_MYTOOLS_IA32 {
PEI_DEPEX PEI_DEPEX Optional |.depex
GUIDED A31280AD-481E-41B6-95E8-127F4C984779 PROCESSING_REQUIRED = TRUE {
PE32 PE32 |.efi
UI STRING="$(MODULE_NAME)" Optional
}
}
[Rule.Common.DXE_CORE]
FILE DXE_CORE = $(NAMED_GUID) {
PE32 PE32 |.efi
UI STRING="$(MODULE_NAME)" Optional
}
[Rule.Common.UEFI_DRIVER]
FILE DRIVER = $(NAMED_GUID) {
DXE_DEPEX DXE_DEPEX Optional |.depex
PE32 PE32 |.efi
UI STRING="$(MODULE_NAME)" Optional
}
[Rule.Common.DXE_DRIVER]
FILE DRIVER = $(NAMED_GUID) {
DXE_DEPEX DXE_DEPEX Optional |.depex
PE32 PE32 |.efi
UI STRING="$(MODULE_NAME)" Optional
}
[Rule.Common.DXE_RUNTIME_DRIVER]
FILE DRIVER = $(NAMED_GUID) {
DXE_DEPEX DXE_DEPEX Optional |.depex
PE32 PE32 |.efi
UI STRING="$(MODULE_NAME)" Optional
}
[Rule.Common.UEFI_APPLICATION]
FILE APPLICATION = $(NAMED_GUID) {
UI STRING ="$(MODULE_NAME)" Optional
PE32 PE32 |.efi
}

View File

@@ -0,0 +1,39 @@
#/** @file
# Arm Versatile Express package.
#
# Copyright (c) 2011, ARM Limited. All rights reserved.
#
# This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
# which accompanies this distribution. The full text of the license may be found at
# http://opensource.org/licenses/bsd-license.php
#
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#
#**/
[Defines]
DEC_SPECIFICATION = 0x00010005
PACKAGE_NAME = ArmVExpressPkg
PACKAGE_GUID = 9c0aaed4-74c5-4043-b417-a3223814ce76
PACKAGE_VERSION = 0.1
################################################################################
#
# Include Section - list of Include Paths that are provided by this package.
# Comments are used for Keywords and Module Types.
#
# Supported Module Types:
# BASE SEC PEI_CORE PEIM DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SMM_DRIVER DXE_SAL_DRIVER UEFI_DRIVER UEFI_APPLICATION
#
################################################################################
[Includes.common]
Include # Root include for the package
[Guids.common]
gArmVExpressTokenSpaceGuid = { 0x9c0aaed4, 0x74c5, 0x4043, { 0xb4, 0x17, 0xa3, 0x22, 0x38, 0x14, 0xce, 0x76 } }
[PcdsFeatureFlag.common]
[PcdsFixedAtBuild.common]

View File

@@ -0,0 +1,150 @@
/** @file
* Header defining Versatile Express constants (Base addresses, sizes, flags)
*
* Copyright (c) 2011, ARM Limited. All rights reserved.
*
* This program and the accompanying materials
* are licensed and made available under the terms and conditions of the BSD License
* which accompanies this distribution. The full text of the license may be found at
* http://opensource.org/licenses/bsd-license.php
*
* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
*
**/
#ifndef __ARM_VEXPRESS_H__
#define __ARM_VEXPRESS_H__
/*******************************************
// Platform Memory Map
*******************************************/
// Can be NOR0, NOR1, DRAM
#define ARM_VE_REMAP_BASE 0x00000000
#define ARM_VE_REMAP_SZ 0x04000000
// Motherboard Peripheral and On-chip peripheral
#define ARM_VE_SMB_MB_ON_CHIP_PERIPH_BASE 0x10000000
#define ARM_VE_SMB_MB_ON_CHIP_PERIPH_SZ 0x10000000 /* 256 MB */
#define ARM_VE_BOARD_PERIPH_BASE 0x10000000
#define ARM_VE_CHIP_PERIPH_BASE 0x10020000
// SMC
#define ARM_VE_SMC_BASE 0x40000000
#define ARM_VE_SMC_SZ 0x1C000000
// NOR Flash 1
#define ARM_VE_SMB_NOR0_BASE 0x40000000
#define ARM_VE_SMB_NOR0_SZ 0x04000000 /* 64 MB */
// NOR Flash 2
#define ARM_VE_SMB_NOR1_BASE 0x44000000
#define ARM_VE_SMB_NOR1_SZ 0x04000000 /* 64 MB */
// SRAM
#define ARM_VE_SMB_SRAM_BASE 0x48000000
#define ARM_VE_SMB_SRAM_SZ 0x02000000 /* 32 MB */
// USB, Ethernet, VRAM
#define ARM_VE_SMB_PERIPH_BASE 0x4C000000
#define ARM_VE_SMB_PERIPH_VRAM 0x4C000000
#define ARM_VE_SMB_PERIPH_SZ 0x04000000 /* 32 MB */
// DRAM
#define ARM_VE_DRAM_BASE 0x60000000
#define ARM_VE_DRAM_SZ 0x40000000
// External AXI between daughterboards (Logic Tile)
#define ARM_VE_EXT_AXI_BASE 0xE0000000
#define ARM_VE_EXT_AXI_SZ 0x20000000
/*******************************************
// Motherboard peripherals
*******************************************/
// Define MotherBoard SYS flags offsets (from ARM_VE_BOARD_PERIPH_BASE)
#define ARM_VE_SYS_FLAGS_REG (ARM_VE_BOARD_PERIPH_BASE + 0x00030)
#define ARM_VE_SYS_FLAGS_SET_REG (ARM_VE_BOARD_PERIPH_BASE + 0x00030)
#define ARM_VE_SYS_FLAGS_CLR_REG (ARM_VE_BOARD_PERIPH_BASE + 0x00034)
#define ARM_VE_SYS_FLAGS_NV_REG (ARM_VE_BOARD_PERIPH_BASE + 0x00038)
#define ARM_VE_SYS_FLAGS_NV_SET_REG (ARM_VE_BOARD_PERIPH_BASE + 0x00038)
#define ARM_VE_SYS_FLAGS_NV_CLR_REG (ARM_VE_BOARD_PERIPH_BASE + 0x0003C)
#define ARM_VE_SYS_PROCID0_REG (ARM_VE_BOARD_PERIPH_BASE + 0x00084)
#define ARM_VE_SYS_PROCID1_REG (ARM_VE_BOARD_PERIPH_BASE + 0x00088)
#define ARM_VE_SYS_CFGDATA_REG (ARM_VE_BOARD_PERIPH_BASE + 0x000A0)
#define ARM_VE_SYS_CFGCTRL_REG (ARM_VE_BOARD_PERIPH_BASE + 0x000A4)
#define ARM_VE_SYS_CFGSTAT_REG (ARM_VE_BOARD_PERIPH_BASE + 0x000A8)
// SP810 Controller
#define SP810_CTRL_BASE (ARM_VE_BOARD_PERIPH_BASE + 0x01000)
// Uart0
#define PL011_CONSOLE_UART_BASE (ARM_VE_BOARD_PERIPH_BASE + 0x09000)
#define PL011_CONSOLE_UART_SPEED 38400
// SP804 Timer Bases
#define SP804_TIMER0_BASE (ARM_VE_BOARD_PERIPH_BASE + 0x11000)
#define SP804_TIMER1_BASE (ARM_VE_BOARD_PERIPH_BASE + 0x11020)
#define SP804_TIMER2_BASE (ARM_VE_BOARD_PERIPH_BASE + 0x12000)
#define SP804_TIMER3_BASE (ARM_VE_BOARD_PERIPH_BASE + 0x12020)
// Dynamic Memory Controller Base
#define ARM_VE_DMC_BASE 0x100E0000
// Static Memory Controller Base
#define ARM_VE_SMC_CTRL_BASE 0x100E1000
// System Configuration Controller register Base addresses
//#define ARM_VE_SYS_CFG_CTRL_BASE 0x100E2000
#define ARM_VE_SYS_CFGRW0_REG 0x100E2000
#define ARM_VE_SYS_CFGRW1_REG 0x100E2004
#define ARM_VE_SYS_CFGRW2_REG 0x100E2008
#define ARM_VE_CFGRW1_TZASC_EN_BIT_MASK 0x2000
#define ARM_VE_CFGRW1_REMAP_NOR0 0
#define ARM_VE_CFGRW1_REMAP_NOR1 (1 << 28)
#define ARM_VE_CFGRW1_REMAP_EXT_AXI (1 << 29)
#define ARM_VE_CFGRW1_REMAP_DRAM (1 << 30)
// TZPC Base Address
#define ARM_VE_TZPC_BASE 0x100E6000
// PL301 Fast AXI Base Address
#define ARM_VE_FAXI_BASE 0x100E9000
// TZASC Defintions
#define ARM_VE_TZASC_BASE 0x100EC000
#define ARM_VE_DECPROT_BIT_TZPC (1 << 6)
#define ARM_VE_DECPROT_BIT_DMC_TZASC (1 << 11)
#define ARM_VE_DECPROT_BIT_NMC_TZASC (1 << 12)
#define ARM_VE_DECPROT_BIT_SMC_TZASC (1 << 13)
#define ARM_VE_DECPROT_BIT_EXT_MAST_TZ (1)
#define ARM_VE_DECPROT_BIT_DMC_TZASC_LOCK (1 << 3)
#define ARM_VE_DECPROT_BIT_NMC_TZASC_LOCK (1 << 4)
#define ARM_VE_DECPROT_BIT_SMC_TZASC_LOCK (1 << 5)
// L2x0 Cache Controller Base Address
//#define ARM_VE_L2x0_CTLR_BASE 0x1E00A000
/*******************************************
// Interrupt Map
*******************************************/
// Timer Interrupts
#define TIMER01_INTERRUPT_NUM 34
#define TIMER23_INTERRUPT_NUM 35
/*******************************************
// EFI Memory Map in Permanent Memory (DRAM)
*******************************************/
// This region is allocated at the bottom of the DRAM. It will be used
// for fixed address allocations such as Vector Table
#define ARM_VE_EFI_FIX_ADDRESS_REGION_SZ SIZE_8MB
// This region is the memory declared to PEI as permanent memory for PEI
// and DXE. EFI stacks and heaps will be declared in this region.
#define ARM_VE_EFI_MEMORY_REGION_SZ 0x1000000
#endif

View File

@@ -0,0 +1,49 @@
#/* @file
# Copyright (c) 2011, ARM Limited. All rights reserved.
#
# This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
# which accompanies this distribution. The full text of the license may be found at
# http://opensource.org/licenses/bsd-license.php
#
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#
#*/
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = CTA9x4ArmVExpressLib
FILE_GUID = b16c63a0-f417-11df-b3af-0002a5d5c51b
MODULE_TYPE = BASE
VERSION_STRING = 1.0
LIBRARY_CLASS = ArmPlatformLib
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
EmbeddedPkg/EmbeddedPkg.dec
ArmPkg/ArmPkg.dec
ArmPlatformPkg/ArmPlatformPkg.dec
[LibraryClasses]
IoLib
ArmLib
ArmTrustZoneLib
MemoryAllocationLib
PL341DmcLib
PL301AxiLib
[Sources.common]
CTA9x4.c
CTA9x4Mem.c
[Protocols]
[FeaturePcd]
gEmbeddedTokenSpaceGuid.PcdCacheEnable
gArmPlatformTokenSpaceGuid.PcdStandalone
[FixedPcd]
gEmbeddedTokenSpaceGuid.PcdEmbeddedFdBaseAddress
gEmbeddedTokenSpaceGuid.PcdEmbeddedFdSize

View File

@@ -0,0 +1,50 @@
#/* @file
# Copyright (c) 2011, ARM Limited. All rights reserved.
#
# This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
# which accompanies this distribution. The full text of the license may be found at
# http://opensource.org/licenses/bsd-license.php
#
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#
#*/
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = CTA9x4ArmVExpressLib
FILE_GUID = b16c63a0-f417-11df-b3af-0002a5d5c51b
MODULE_TYPE = BASE
VERSION_STRING = 1.0
LIBRARY_CLASS = ArmPlatformLib
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
EmbeddedPkg/EmbeddedPkg.dec
ArmPkg/ArmPkg.dec
ArmPlatformPkg/ArmPlatformPkg.dec
[LibraryClasses]
IoLib
ArmLib
ArmTrustZoneLib
PL354SmcSecLib
PL341DmcLib
PL301AxiLib
[Sources.common]
CTA9x4.c
CTA9x4Helper.asm | RVCT
CTA9x4Helper.S | GCC
[Protocols]
[FeaturePcd]
gEmbeddedTokenSpaceGuid.PcdCacheEnable
gArmPlatformTokenSpaceGuid.PcdStandalone
[FixedPcd]
gEmbeddedTokenSpaceGuid.PcdEmbeddedFdBaseAddress
gEmbeddedTokenSpaceGuid.PcdEmbeddedFdSize

View File

@@ -0,0 +1,157 @@
/** @file
*
* Copyright (c) 2011, ARM Limited. All rights reserved.
*
* This program and the accompanying materials
* are licensed and made available under the terms and conditions of the BSD License
* which accompanies this distribution. The full text of the license may be found at
* http://opensource.org/licenses/bsd-license.php
*
* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
*
**/
#include <Library/IoLib.h>
#include <Library/ArmTrustZoneLib.h>
#include <Library/ArmPlatformLib.h>
#include <Library/DebugLib.h>
#include <Library/PcdLib.h>
#include <Drivers/PL341Dmc.h>
// DDR2 timings
struct pl341_dmc_config ddr_timings = {
.base = ARM_VE_DMC_BASE,
.has_qos = 1,
.refresh_prd = 0x3D0,
.cas_latency = 0x8,
.write_latency = 0x3,
.t_mrd = 0x2,
.t_ras = 0xA,
.t_rc = 0xE,
.t_rcd = 0x104,
.t_rfc = 0x2f32,
.t_rp = 0x14,
.t_rrd = 0x2,
.t_wr = 0x4,
.t_wtr = 0x2,
.t_xp = 0x2,
.t_xsr = 0xC8,
.t_esr = 0x14,
.memory_cfg = DMC_MEMORY_CONFIG_ACTIVE_CHIP_1 | DMC_MEMORY_CONFIG_BURST_4 |
DMC_MEMORY_CONFIG_ROW_ADDRESS_15 | DMC_MEMORY_CONFIG_COLUMN_ADDRESS_10,
.memory_cfg2 = DMC_MEMORY_CFG2_DQM_INIT | DMC_MEMORY_CFG2_CKE_INIT |
DMC_MEMORY_CFG2_BANK_BITS_3 | DMC_MEMORY_CFG2_MEM_WIDTH_32,
.memory_cfg3 = 0x00000001,
.chip_cfg0 = 0x00010000,
.t_faw = 0x00000A0D,
};
/**
Return if Trustzone is supported by your platform
A non-zero value must be returned if you want to support a Secure World on your platform.
ArmVExpressTrustzoneInit() will later set up the secure regions.
This function can return 0 even if Trustzone is supported by your processor. In this case,
the platform will continue to run in Secure World.
@return A non-zero value if Trustzone supported.
**/
UINTN ArmPlatformTrustzoneSupported(VOID) {
return (MmioRead32(ARM_VE_SYS_CFGRW1_REG) & ARM_VE_CFGRW1_TZASC_EN_BIT_MASK);
}
/**
Initialize the Secure peripherals and memory regions
If Trustzone is supported by your platform then this function makes the required initialization
of the secure peripherals and memory regions.
**/
VOID ArmPlatformTrustzoneInit(VOID) {
//
// Setup TZ Protection Controller
//
// Set Non Secure access for all devices
TZPCSetDecProtBits(ARM_VE_TZPC_BASE, TZPC_DECPROT_0, 0xFFFFFFFF);
TZPCSetDecProtBits(ARM_VE_TZPC_BASE, TZPC_DECPROT_1, 0xFFFFFFFF);
TZPCSetDecProtBits(ARM_VE_TZPC_BASE, TZPC_DECPROT_2, 0xFFFFFFFF);
// Remove Non secure access to secure devices
TZPCClearDecProtBits(ARM_VE_TZPC_BASE, TZPC_DECPROT_0,
ARM_VE_DECPROT_BIT_TZPC | ARM_VE_DECPROT_BIT_DMC_TZASC | ARM_VE_DECPROT_BIT_NMC_TZASC | ARM_VE_DECPROT_BIT_SMC_TZASC);
TZPCClearDecProtBits(ARM_VE_TZPC_BASE, TZPC_DECPROT_2,
ARM_VE_DECPROT_BIT_EXT_MAST_TZ | ARM_VE_DECPROT_BIT_DMC_TZASC_LOCK | ARM_VE_DECPROT_BIT_NMC_TZASC_LOCK | ARM_VE_DECPROT_BIT_SMC_TZASC_LOCK);
//
// Setup TZ Address Space Controller for the SMC. Create 5 Non Secure regions (NOR0, NOR1, SRAM, SMC Peripheral regions)
//
// NOR Flash 0 non secure (BootMon)
TZASCSetRegion(ARM_VE_TZASC_BASE,1,TZASC_REGION_ENABLED,
ARM_VE_SMB_NOR0_BASE,0,
TZASC_REGION_SIZE_64MB, TZASC_REGION_SECURITY_NSRW);
// NOR Flash 1. The first half of the NOR Flash1 must be secure for the secure firmware (sec_uefi.bin)
#if EDK2_ARMVE_SECURE_SYSTEM
//Note: Your OS Kernel must be aware of the secure regions before to enable this region
TZASCSetRegion(ARM_VE_TZASC_BASE,2,TZASC_REGION_ENABLED,
ARM_VE_SMB_NOR1_BASE + SIZE_32MB,0,
TZASC_REGION_SIZE_32MB, TZASC_REGION_SECURITY_NSRW);
#else
TZASCSetRegion(ARM_VE_TZASC_BASE,2,TZASC_REGION_ENABLED,
ARM_VE_SMB_NOR1_BASE,0,
TZASC_REGION_SIZE_64MB, TZASC_REGION_SECURITY_NSRW);
#endif
// Base of SRAM. Only half of SRAM in Non Secure world
// First half non secure (16MB) + Second Half secure (16MB) = 32MB of SRAM
#if EDK2_ARMVE_SECURE_SYSTEM
//Note: Your OS Kernel must be aware of the secure regions before to enable this region
TZASCSetRegion(ARM_VE_TZASC_BASE,3,TZASC_REGION_ENABLED,
ARM_VE_SMB_SRAM_BASE,0,
TZASC_REGION_SIZE_16MB, TZASC_REGION_SECURITY_NSRW);
#else
TZASCSetRegion(ARM_VE_TZASC_BASE,3,TZASC_REGION_ENABLED,
ARM_VE_SMB_SRAM_BASE,0,
TZASC_REGION_SIZE_32MB, TZASC_REGION_SECURITY_NSRW);
#endif
// Memory Mapped Peripherals. All in non secure world
TZASCSetRegion(ARM_VE_TZASC_BASE,4,TZASC_REGION_ENABLED,
ARM_VE_SMB_PERIPH_BASE,0,
TZASC_REGION_SIZE_64MB, TZASC_REGION_SECURITY_NSRW);
// MotherBoard Peripherals and On-chip peripherals.
TZASCSetRegion(ARM_VE_TZASC_BASE,5,TZASC_REGION_ENABLED,
ARM_VE_SMB_MB_ON_CHIP_PERIPH_BASE,0,
TZASC_REGION_SIZE_256MB, TZASC_REGION_SECURITY_NSRW);
}
/**
Remap the memory at 0x0
Some platform requires or gives the ability to remap the memory at the address 0x0.
This function can do nothing if this feature is not relevant to your platform.
**/
VOID ArmPlatformBootRemapping(VOID) {
UINT32 val32 = MmioRead32(ARM_VE_SYS_CFGRW1_REG); //Scc - CFGRW1
// we remap the DRAM to 0x0
MmioWrite32(ARM_VE_SYS_CFGRW1_REG, (val32 & 0x0FFFFFFF) | ARM_VE_CFGRW1_REMAP_DRAM);
}
/**
Initialize the system (or sometimes called permanent) memory
This memory is generally represented by the DRAM.
**/
VOID ArmPlatformInitializeSystemMemory(VOID) {
PL341DmcInit(&ddr_timings);
PL301AxiInit(ARM_VE_FAXI_BASE);
}

View File

@@ -0,0 +1,74 @@
#------------------------------------------------------------------------------
#
# ARM VE Entry point. Reset vector in FV header will brach to
# _ModuleEntryPoint.
#
# We use crazy macros, like LoadConstantToReg, since Xcode assembler
# does not support = assembly syntax for ldr.
#
# Copyright (c) 2011, ARM Limited. All rights reserved.
#
# This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
# which accompanies this distribution. The full text of the license may be found at
# http://opensource.org/licenses/bsd-license.php
#
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#
#------------------------------------------------------------------------------
#include <AsmMacroIoLib.h>
#include <Base.h>
#include <Library/PcdLib.h>
#include <Library/ArmPlatformLib.h>
#include <AutoGen.h>
#Start of Code section
.text
.align 3
GCC_ASM_EXPORT(ArmPlatformIsMemoryInitialized)
GCC_ASM_EXPORT(ArmPlatformInitializeBootMemory)
.extern ASM_PFX(InitializeSMC)
/**
Called at the early stage of the Boot phase to know if the memory has already been initialized
Running the code from the reset vector does not mean we start from cold boot. In some case, we
can go through this code with the memory already initialized.
Because this function is called at the early stage, the implementation must not use the stack.
Its implementation must probably done in assembly to ensure this requirement.
@return Return the condition value into the 'Z' flag
**/
ASM_PFX(ArmPlatformIsMemoryInitialized):
// Check if the memory has been already mapped, if so skipped the memory initialization
LoadConstantToReg (ARM_VE_SYS_CFGRW1_REG ,r0)
ldr r0, [r0, #0]
// 0x40000000 = Value of Physical Configuration Switch SW[0]
and r0, r0, #0x40000000
tst r0, #0x40000000
bx lr
/**
Initialize the memory where the initial stacks will reside
This memory can contain the initial stacks (Secure and Secure Monitor stacks).
In some platform, this region is already initialized and the implementation of this function can
do nothing. This memory can also represent the Secure RAM.
This function is called before the satck has been set up. Its implementation must ensure the stack
pointer is not used (probably required to use assembly language)
**/
ASM_PFX(ArmPlatformInitializeBootMemory):
mov r5, lr
// Initialize PL354 SMC
LoadConstantToReg (ARM_VE_SMC_CTRL_BASE, r1)
LoadConstantToReg (ARM_VE_SMB_PERIPH_VRAM, r2)
blx ASM_PFX(InitializeSMC)
bx r5
.end

View File

@@ -0,0 +1,68 @@
//
// Copyright (c) 2011, ARM Limited. All rights reserved.
//
// This program and the accompanying materials
// are licensed and made available under the terms and conditions of the BSD License
// which accompanies this distribution. The full text of the license may be found at
// http://opensource.org/licenses/bsd-license.php
//
// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
//
//
#include <AsmMacroIoLib.h>
#include <Base.h>
#include <Library/PcdLib.h>
#include <ArmPlatform.h>
#include <AutoGen.h>
INCLUDE AsmMacroIoLib.inc
EXPORT ArmPlatformIsMemoryInitialized
EXPORT ArmPlatformInitializeBootMemory
IMPORT InitializeSMC
PRESERVE8
AREA CTA9x4Helper, CODE, READONLY
/**
Called at the early stage of the Boot phase to know if the memory has already been initialized
Running the code from the reset vector does not mean we start from cold boot. In some case, we
can go through this code with the memory already initialized.
Because this function is called at the early stage, the implementation must not use the stack.
Its implementation must probably done in assembly to ensure this requirement.
@return Return the condition value into the 'Z' flag
**/
ArmPlatformIsMemoryInitialized
// Check if the memory has been already mapped, if so skipped the memory initialization
LoadConstantToReg (ARM_VE_SYS_CFGRW1_REG ,r0)
ldr r0, [r0, #0]
// 0x40000000 = Value of Physical Configuration Switch SW[0]
and r0, r0, #0x40000000
tst r0, #0x40000000
bx lr
/**
Initialize the memory where the initial stacks will reside
This memory can contain the initial stacks (Secure and Secure Monitor stacks).
In some platform, this region is already initialized and the implementation of this function can
do nothing. This memory can also represent the Secure RAM.
This function is called before the satck has been set up. Its implementation must ensure the stack
pointer is not used (probably required to use assembly language)
**/
ArmPlatformInitializeBootMemory
mov r5, lr
// Initialize PL354 SMC
LoadConstantToReg (ARM_VE_SMC_CTRL_BASE, r1)
LoadConstantToReg (ARM_VE_SMB_PERIPH_VRAM, r2)
blx InitializeSMC
bx r5
END

View File

@@ -0,0 +1,212 @@
/** @file
*
* Copyright (c) 2011, ARM Limited. All rights reserved.
*
* This program and the accompanying materials
* are licensed and made available under the terms and conditions of the BSD License
* which accompanies this distribution. The full text of the license may be found at
* http://opensource.org/licenses/bsd-license.php
*
* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
*
**/
#include <Library/ArmPlatformLib.h>
#include <Library/DebugLib.h>
#include <Library/PcdLib.h>
#include <Library/IoLib.h>
#include <Library/MemoryAllocationLib.h>
// DDR attributes
#define DDR_ATTRIBUTES_CACHED ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK
#define DDR_ATTRIBUTES_UNCACHED ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED
#define DDR_ATTRIBUTES_SECURE_CACHED ARM_MEMORY_REGION_ATTRIBUTE_SECURE_WRITE_BACK
#define DDR_ATTRIBUTES_SECURE_UNCACHED ARM_MEMORY_REGION_ATTRIBUTE_SECURE_UNCACHED_UNBUFFERED
/**
Return the information about the memory region in permanent memory used by PEI
One of the PEI Module must install the permament memory used by PEI. This function returns the
information about this region for your platform to this PEIM module.
@param[out] PeiMemoryBase Base of the memory region used by PEI core and modules
@param[out] PeiMemorySize Size of the memory region used by PEI core and modules
**/
VOID ArmPlatformGetPeiMemory (
OUT UINTN* PeiMemoryBase,
OUT UINTN* PeiMemorySize
) {
ASSERT((PeiMemoryBase != NULL) && (PeiMemorySize != NULL));
*PeiMemoryBase = ARM_VE_DRAM_BASE + ARM_VE_EFI_FIX_ADDRESS_REGION_SZ;
*PeiMemorySize = ARM_VE_EFI_MEMORY_REGION_SZ;
}
/**
Return the Virtual Memory Map of your platform
This Virtual Memory Map is used by MemoryInitPei Module to initialize the MMU on your platform.
@param[out] VirtualMemoryMap Array of ARM_MEMORY_REGION_DESCRIPTOR describing a Physical-to-
Virtual Memory mapping. This array must be ended by a zero-filled
entry
**/
VOID ArmPlatformGetVirtualMemoryMap(ARM_MEMORY_REGION_DESCRIPTOR** VirtualMemoryMap) {
UINT32 val32;
UINT32 CacheAttributes;
BOOLEAN bTrustzoneSupport;
UINTN Index = 0;
ARM_MEMORY_REGION_DESCRIPTOR *VirtualMemoryTable;
ASSERT(VirtualMemoryMap != NULL);
VirtualMemoryTable = (ARM_MEMORY_REGION_DESCRIPTOR*)AllocatePages(sizeof(ARM_MEMORY_REGION_DESCRIPTOR) * 9);
if (VirtualMemoryTable == NULL) {
return;
}
// Check if SMC TZASC is enabled. If Trustzone not enabled then all the entries remain in Secure World.
// As this value can be changed in the Board Configuration file, the UEFI firmware needs to work for both case
val32 = MmioRead32(ARM_VE_SYS_CFGRW1_REG);
if (ARM_VE_CFGRW1_TZASC_EN_BIT_MASK & val32) {
bTrustzoneSupport = TRUE;
} else {
bTrustzoneSupport = FALSE;
}
if (FeaturePcdGet(PcdCacheEnable) == TRUE) {
CacheAttributes = (bTrustzoneSupport ? DDR_ATTRIBUTES_CACHED : DDR_ATTRIBUTES_SECURE_CACHED);
} else {
CacheAttributes = (bTrustzoneSupport ? DDR_ATTRIBUTES_UNCACHED : DDR_ATTRIBUTES_SECURE_UNCACHED);
}
// ReMap (Either NOR Flash or DRAM)
VirtualMemoryTable[Index].PhysicalBase = ARM_VE_REMAP_BASE;
VirtualMemoryTable[Index].VirtualBase = ARM_VE_REMAP_BASE;
VirtualMemoryTable[Index].Length = ARM_VE_REMAP_SZ;
VirtualMemoryTable[Index].Attributes = (ARM_MEMORY_REGION_ATTRIBUTES)CacheAttributes;
// DDR
VirtualMemoryTable[++Index].PhysicalBase = ARM_VE_DRAM_BASE;
VirtualMemoryTable[Index].VirtualBase = ARM_VE_DRAM_BASE;
VirtualMemoryTable[Index].Length = ARM_VE_DRAM_SZ;
VirtualMemoryTable[Index].Attributes = (ARM_MEMORY_REGION_ATTRIBUTES)CacheAttributes;
// SMC CS7
VirtualMemoryTable[++Index].PhysicalBase = ARM_VE_SMB_MB_ON_CHIP_PERIPH_BASE;
VirtualMemoryTable[Index].VirtualBase = ARM_VE_SMB_MB_ON_CHIP_PERIPH_BASE;
VirtualMemoryTable[Index].Length = ARM_VE_SMB_MB_ON_CHIP_PERIPH_SZ;
VirtualMemoryTable[Index].Attributes = (bTrustzoneSupport ? ARM_MEMORY_REGION_ATTRIBUTE_DEVICE : ARM_MEMORY_REGION_ATTRIBUTE_SECURE_DEVICE);
// SMB CS0-CS1 - NOR Flash 1 & 2
VirtualMemoryTable[++Index].PhysicalBase = ARM_VE_SMB_NOR0_BASE;
VirtualMemoryTable[Index].VirtualBase = ARM_VE_SMB_NOR0_BASE;
VirtualMemoryTable[Index].Length = ARM_VE_SMB_NOR0_SZ + ARM_VE_SMB_NOR1_SZ;
VirtualMemoryTable[Index].Attributes = (bTrustzoneSupport ? ARM_MEMORY_REGION_ATTRIBUTE_DEVICE : ARM_MEMORY_REGION_ATTRIBUTE_SECURE_DEVICE);
// SMB CS2 - SRAM
VirtualMemoryTable[++Index].PhysicalBase = ARM_VE_SMB_SRAM_BASE;
VirtualMemoryTable[Index].VirtualBase = ARM_VE_SMB_SRAM_BASE;
VirtualMemoryTable[Index].Length = ARM_VE_SMB_SRAM_SZ;
VirtualMemoryTable[Index].Attributes = (ARM_MEMORY_REGION_ATTRIBUTES)CacheAttributes;
// SMB CS3-CS6 - Motherboard Peripherals
VirtualMemoryTable[++Index].PhysicalBase = ARM_VE_SMB_PERIPH_BASE;
VirtualMemoryTable[Index].VirtualBase = ARM_VE_SMB_PERIPH_BASE;
VirtualMemoryTable[Index].Length = ARM_VE_SMB_PERIPH_SZ;
VirtualMemoryTable[Index].Attributes = (bTrustzoneSupport ? ARM_MEMORY_REGION_ATTRIBUTE_DEVICE : ARM_MEMORY_REGION_ATTRIBUTE_SECURE_DEVICE);
// If a Logic Tile is connected to The ARM Versatile Express Motherboard
if (MmioRead32(ARM_VE_SYS_PROCID1_REG) != 0) {
VirtualMemoryTable[++Index].PhysicalBase = ARM_VE_EXT_AXI_BASE;
VirtualMemoryTable[Index].VirtualBase = ARM_VE_EXT_AXI_BASE;
VirtualMemoryTable[Index].Length = ARM_VE_EXT_AXI_SZ;
VirtualMemoryTable[Index].Attributes = (bTrustzoneSupport ? ARM_MEMORY_REGION_ATTRIBUTE_DEVICE : ARM_MEMORY_REGION_ATTRIBUTE_SECURE_DEVICE);
}
// End of Table
VirtualMemoryTable[++Index].PhysicalBase = 0;
VirtualMemoryTable[Index].VirtualBase = 0;
VirtualMemoryTable[Index].Length = 0;
VirtualMemoryTable[Index].Attributes = (ARM_MEMORY_REGION_ATTRIBUTES)0;
*VirtualMemoryMap = VirtualMemoryTable;
}
/**
Return the EFI Memory Map of your platform
This EFI Memory Map of the System Memory is used by MemoryInitPei module to create the Resource
Descriptor HOBs used by DXE core.
@param[out] EfiMemoryMap Array of ARM_SYSTEM_MEMORY_REGION_DESCRIPTOR describing an
EFI Memory region. This array must be ended by a zero-filled entry
**/
VOID ArmPlatformGetEfiMemoryMap (
OUT ARM_SYSTEM_MEMORY_REGION_DESCRIPTOR** EfiMemoryMap
) {
EFI_RESOURCE_ATTRIBUTE_TYPE Attributes;
UINT64 MemoryBase;
UINTN Index = 0;
ARM_SYSTEM_MEMORY_REGION_DESCRIPTOR *EfiMemoryTable;
ASSERT(EfiMemoryMap != NULL);
EfiMemoryTable = (ARM_SYSTEM_MEMORY_REGION_DESCRIPTOR*)AllocatePages(sizeof(ARM_SYSTEM_MEMORY_REGION_DESCRIPTOR) * 6);
Attributes =
(
EFI_RESOURCE_ATTRIBUTE_PRESENT |
EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE |
EFI_RESOURCE_ATTRIBUTE_TESTED
);
MemoryBase = ARM_VE_DRAM_BASE;
// Memory Reserved for fixed address allocations (such as Exception Vector Table)
EfiMemoryTable[Index].ResourceAttribute = Attributes;
EfiMemoryTable[Index].PhysicalStart = MemoryBase;
EfiMemoryTable[Index].NumberOfBytes = ARM_VE_EFI_FIX_ADDRESS_REGION_SZ;
MemoryBase += ARM_VE_EFI_FIX_ADDRESS_REGION_SZ;
// Memory declared to PEI as permanent memory for PEI and DXE
EfiMemoryTable[++Index].ResourceAttribute = Attributes;
EfiMemoryTable[Index].PhysicalStart = MemoryBase;
EfiMemoryTable[Index].NumberOfBytes = ARM_VE_EFI_MEMORY_REGION_SZ;
MemoryBase += ARM_VE_EFI_MEMORY_REGION_SZ;
// We must reserve the memory used by the Firmware Volume copied in DRAM at 0x80000000
if (FeaturePcdGet(PcdStandalone) == FALSE) {
// Chunk between the EFI Memory region and the firmware
EfiMemoryTable[++Index].ResourceAttribute = Attributes;
EfiMemoryTable[Index].PhysicalStart = MemoryBase;
EfiMemoryTable[Index].NumberOfBytes = PcdGet32(PcdEmbeddedFdBaseAddress) - MemoryBase;
// Chunk reserved by the firmware in DRAM
EfiMemoryTable[++Index].ResourceAttribute = Attributes & (~EFI_RESOURCE_ATTRIBUTE_PRESENT);
EfiMemoryTable[Index].PhysicalStart = PcdGet32(PcdEmbeddedFdBaseAddress);
EfiMemoryTable[Index].NumberOfBytes = PcdGet32(PcdEmbeddedFdSize);
MemoryBase = PcdGet32(PcdEmbeddedFdBaseAddress) + PcdGet32(PcdEmbeddedFdSize);
}
// We allocate all the remain memory as untested system memory
EfiMemoryTable[++Index].ResourceAttribute = Attributes & (~EFI_RESOURCE_ATTRIBUTE_TESTED);
EfiMemoryTable[Index].PhysicalStart = MemoryBase;
EfiMemoryTable[Index].NumberOfBytes = ARM_VE_DRAM_SZ - (MemoryBase-ARM_VE_DRAM_BASE);
EfiMemoryTable[++Index].ResourceAttribute = 0;
EfiMemoryTable[Index].PhysicalStart = 0;
EfiMemoryTable[Index].NumberOfBytes = 0;
*EfiMemoryMap = EfiMemoryTable;
}

View File

@@ -0,0 +1,84 @@
/** @file
Template library implementation to support ResetSystem Runtime call.
Fill in the templates with what ever makes you system reset.
Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include <PiDxe.h>
#include <Library/BaseLib.h>
#include <Library/PcdLib.h>
#include <Library/DebugLib.h>
#include <Library/EfiResetSystemLib.h>
#include <ArmPlatform.h>
/**
Resets the entire platform.
@param ResetType The type of reset to perform.
@param ResetStatus The status code for the reset.
@param DataSize The size, in bytes, of WatchdogData.
@param ResetData For a ResetType of EfiResetCold, EfiResetWarm, or
EfiResetShutdown the data buffer starts with a Null-terminated
Unicode string, optionally followed by additional binary data.
**/
EFI_STATUS
EFIAPI
LibResetSystem (
IN EFI_RESET_TYPE ResetType,
IN EFI_STATUS ResetStatus,
IN UINTN DataSize,
IN CHAR16 *ResetData OPTIONAL
)
{
if (ResetData != NULL) {
DEBUG ((EFI_D_ERROR, "%s", ResetData));
}
switch (ResetType) {
case EfiResetWarm:
// Map a warm reset into a cold reset
case EfiResetCold:
case EfiResetShutdown:
default:
CpuDeadLoop ();
break;
}
// If the reset didn't work, return an error.
ASSERT (FALSE);
return EFI_DEVICE_ERROR;
}
/**
Initialize any infrastructure required for LibResetSystem () to function.
@param ImageHandle The firmware allocated handle for the EFI image.
@param SystemTable A pointer to the EFI System Table.
@retval EFI_SUCCESS The constructor always returns EFI_SUCCESS.
**/
EFI_STATUS
EFIAPI
LibInitializeResetSystem (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
return EFI_SUCCESS;
}

View File

@@ -0,0 +1,34 @@
#/** @file
# Reset System lib to make it easy to port new platforms
#
# Copyright (c) 2008, Apple Inc. All rights reserved.<BR>
#
# This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
# which accompanies this distribution. The full text of the license may be found at
# http://opensource.org/licenses/bsd-license.php
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#
#
#**/
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = ArmVeResetSystemLib
FILE_GUID = 36885202-0854-4373-bfd2-95d229b44d44
MODULE_TYPE = BASE
VERSION_STRING = 1.0
LIBRARY_CLASS = EfiResetSystemLib
[Sources.common]
ResetSystemLib.c
[Packages]
MdePkg/MdePkg.dec
EmbeddedPkg/EmbeddedPkg.dec
ArmPlatformPkg/ArmVExpressPkg/ArmVExpressPkg.dec
[LibraryClasses]
DebugLib
BaseLib

View File

@@ -0,0 +1,149 @@
/** @file NorFlashBlockIoDxe.c
Copyright (c) 2010, ARM Ltd. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include <Library/DebugLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include "NorFlashDxe.h"
EFI_STATUS
EFIAPI
NorFlashBlkIoInitialize (
IN NOR_FLASH_INSTANCE* Instance
) {
UINT32 Reply;
EFI_STATUS Status = EFI_SUCCESS;
DEBUG((DEBUG_BLKIO,"NorFlashBlkIoInitialize()\n"));
//
// Verify that there is a physical hardware device where we expect it to be.
//
// Read a specific CFI query that returns back "QRY"
// This ensures that there is really a device present there
SEND_NOR_COMMAND( Instance->BaseAddress, 0, P30_CMD_READ_CFI_QUERY );
// Read CFI 'QRY' data
Status = NorFlashReadCfiData( Instance->BaseAddress,
P30_CFI_ADDR_QUERY_UNIQUE_QRY,
3,
&Reply
);
if (EFI_ERROR(Status)) {
goto EXIT;
}
if ( Reply != CFI_QRY ) {
DEBUG((EFI_D_ERROR, "NorFlashBlkIoInitialize: CFI QRY=0x%x (expected 0x595251)\n", Reply));
Status = EFI_DEVICE_ERROR;
goto EXIT;
}
EXIT:
// Reset the device
Status = NorFlashBlockIoReset( &Instance->BlockIoProtocol, FALSE );
if (EFI_ERROR(Status)) {
goto EXIT;
}
Instance->Initialized = TRUE;
return EFI_SUCCESS;
}
//
// BlockIO Protocol function EFI_BLOCK_IO_PROTOCOL.Reset
//
EFI_STATUS
EFIAPI
NorFlashBlockIoReset (
IN EFI_BLOCK_IO_PROTOCOL *This,
IN BOOLEAN ExtendedVerification
)
{
EFI_STATUS Status;
NOR_FLASH_INSTANCE *Instance;
Instance = INSTANCE_FROM_BLKIO_THIS(This);
DEBUG ((DEBUG_BLKIO, "NorFlashBlockIoReset(MediaId=0x%x)\n", This->Media->MediaId));
Status = NorFlashReset(Instance);
return Status;
}
//
// BlockIO Protocol function EFI_BLOCK_IO_PROTOCOL.ReadBlocks
//
EFI_STATUS
EFIAPI
NorFlashBlockIoReadBlocks (
IN EFI_BLOCK_IO_PROTOCOL *This,
IN UINT32 MediaId,
IN EFI_LBA Lba,
IN UINTN BufferSizeInBytes,
OUT VOID *Buffer
)
{
NOR_FLASH_INSTANCE *Instance;
Instance = INSTANCE_FROM_BLKIO_THIS(This);
DEBUG ((DEBUG_BLKIO, "NorFlashBlockIoReadBlocks(MediaId=0x%x, Lba=%ld, BufferSize=0x%x bytes (%d kB), BufferPtr @ 0x%08x)\n", MediaId, Lba, BufferSizeInBytes, Buffer));
return NorFlashReadBlocks(Instance,Lba,BufferSizeInBytes,Buffer);
}
//
// BlockIO Protocol function EFI_BLOCK_IO_PROTOCOL.WriteBlocks
//
EFI_STATUS
EFIAPI
NorFlashBlockIoWriteBlocks (
IN EFI_BLOCK_IO_PROTOCOL *This,
IN UINT32 MediaId,
IN EFI_LBA Lba,
IN UINTN BufferSizeInBytes,
IN VOID *Buffer
)
{
NOR_FLASH_INSTANCE *Instance;
Instance = INSTANCE_FROM_BLKIO_THIS(This);
DEBUG ((DEBUG_BLKIO, "NorFlashBlockIoWriteBlocks(MediaId=0x%x, Lba=%ld, BufferSize=0x%x bytes (%d kB), BufferPtr @ 0x%08x)\n", MediaId, Lba, BufferSizeInBytes, Buffer));
return NorFlashWriteBlocks(Instance,Lba,BufferSizeInBytes,Buffer);
}
//
// BlockIO Protocol function EFI_BLOCK_IO_PROTOCOL.FlushBlocks
//
EFI_STATUS
EFIAPI
NorFlashBlockIoFlushBlocks (
IN EFI_BLOCK_IO_PROTOCOL *This
)
{
// No Flush required for the NOR Flash driver
// because cache operations are not permitted.
DEBUG ((DEBUG_BLKIO, "NorFlashBlockIoFlushBlocks: Function NOT IMPLEMENTED (not required).\n"));
// Nothing to do so just return without error
return EFI_SUCCESS;
}

View File

@@ -0,0 +1,802 @@
/** @file NorFlashDxe.c
Copyright (c) 2010, ARM Ltd. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include <Library/UefiLib.h>
#include <Library/DebugLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include "NorFlashDxe.h"
//
// Global variable declarations
//
#define NOR_FLASH_LAST_DEVICE 4
NOR_FLASH_DESCRIPTION mNorFlashDescription[NOR_FLASH_LAST_DEVICE] = {
{ // BootMon
ARM_VE_SMB_NOR0_BASE,
SIZE_256KB * 255,
SIZE_256KB,
FALSE,
{0xE7223039, 0x5836, 0x41E1, 0xB5, 0x42, 0xD7, 0xEC, 0x73, 0x6C, 0x5E, 0x59}
},
{ // BootMon non-volatile storage
ARM_VE_SMB_NOR0_BASE + SIZE_256KB * 255,
SIZE_64KB * 4,
SIZE_64KB,
FALSE,
{0x02118005, 0x9DA7, 0x443A, 0x92, 0xD5, 0x78, 0x1F, 0x02, 0x2A, 0xED, 0xBB}
},
{ // UEFI
ARM_VE_SMB_NOR1_BASE,
SIZE_256KB * 255,
SIZE_256KB,
FALSE,
{0x1F15DA3C, 0x37FF, 0x4070, 0xB4, 0x71, 0xBB, 0x4A, 0xF1, 0x2A, 0x72, 0x4A}
},
{ // UEFI Variable Services non-volatile storage
ARM_VE_SMB_NOR1_BASE + SIZE_256KB * 255,
SIZE_64KB * 3, //FIXME: Set 3 blocks because I did not succeed to copy 4 blocks into the ARM Versastile Express NOR Falsh in the last NOR Flash. It should be 4 blocks
SIZE_64KB,
TRUE,
{0xCC2CBF29, 0x1498, 0x4CDD, 0x81, 0x71, 0xF8, 0xB6, 0xB4, 0x1D, 0x09, 0x09}
}
};
NOR_FLASH_INSTANCE *mNorFlashInstances[ NOR_FLASH_LAST_DEVICE ];
NOR_FLASH_INSTANCE mNorFlashInstanceTemplate = {
NOR_FLASH_SIGNATURE, // Signature
NULL, // Handle ... NEED TO BE FILLED
FALSE, // Initialized
NULL, // Initialize
0, // BaseAddress ... NEED TO BE FILLED
0, // Size ... NEED TO BE FILLED
{
EFI_BLOCK_IO_PROTOCOL_REVISION2, // Revision
NULL, // Media ... NEED TO BE FILLED
NorFlashBlockIoReset, // Reset;
NorFlashBlockIoReadBlocks, // ReadBlocks
NorFlashBlockIoWriteBlocks, // WriteBlocks
NorFlashBlockIoFlushBlocks // FlushBlocks
}, // BlockIoProtocol
{
0, // MediaId ... NEED TO BE FILLED
FALSE, // RemovableMedia
TRUE, // MediaPresent
FALSE, // LogicalPartition
FALSE, // ReadOnly
FALSE, // WriteCaching;
0, // BlockSize ... NEED TO BE FILLED
4, // IoAlign
0, // LastBlock ... NEED TO BE FILLED
0, // LowestAlignedLba
1, // LogicalBlocksPerPhysicalBlock
}, //Media;
FALSE, // SupportFvb ... NEED TO BE FILLED
{
FvbGetAttributes, // GetAttributes
FvbSetAttributes, // SetAttributes
FvbGetPhysicalAddress, // GetPhysicalAddress
FvbGetBlockSize, // GetBlockSize
FvbRead, // Read
FvbWrite, // Write
FvbEraseBlocks, // EraseBlocks
NULL, //ParentHandle
}, // FvbProtoccol;
{
{
{
HARDWARE_DEVICE_PATH,
HW_VENDOR_DP,
(UINT8)( sizeof(VENDOR_DEVICE_PATH) ),
(UINT8)((sizeof(VENDOR_DEVICE_PATH)) >> 8),
},
{ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, // GUID ... NEED TO BE FILLED
},
{
END_DEVICE_PATH_TYPE,
END_ENTIRE_DEVICE_PATH_SUBTYPE,
sizeof (EFI_DEVICE_PATH_PROTOCOL),
0
}
} // DevicePath
};
EFI_STATUS NorFlashCreateInstance(
IN UINTN NorFlashBase,
IN UINTN NorFlashSize,
IN UINT32 MediaId,
IN UINT32 BlockSize,
IN BOOLEAN SupportFvb,
IN CONST GUID *NorFlashGuid,
OUT NOR_FLASH_INSTANCE** NorFlashInstance
) {
EFI_STATUS Status;
NOR_FLASH_INSTANCE* Instance;
ASSERT(NorFlashInstance != NULL);
Instance = AllocateCopyPool (sizeof(NOR_FLASH_INSTANCE),&mNorFlashInstanceTemplate);
if (Instance == NULL) {
return EFI_OUT_OF_RESOURCES;
}
Instance->BaseAddress = NorFlashBase;
Instance->Size = NorFlashSize;
Instance->BlockIoProtocol.Media = &Instance->Media;
Instance->Media.MediaId = MediaId;
Instance->Media.BlockSize = BlockSize;
Instance->Media.LastBlock = (NorFlashSize / BlockSize)-1;
CopyGuid (&Instance->DevicePath.Vendor.Guid,NorFlashGuid);
if (SupportFvb) {
Instance->SupportFvb = TRUE;
Instance->Initialize = NorFlashFvbInitialize;
Status = gBS->InstallMultipleProtocolInterfaces (
&Instance->Handle,
&gEfiDevicePathProtocolGuid, &Instance->DevicePath,
//&gEfiBlockIoProtocolGuid, &Instance->BlockIoProtocol,
&gEfiFirmwareVolumeBlockProtocolGuid, &Instance->FvbProtocol,
NULL
);
if (EFI_ERROR(Status)) {
FreePool(Instance);
return Status;
}
} else {
Instance->Initialize = NorFlashBlkIoInitialize;
Status = gBS->InstallMultipleProtocolInterfaces (
&Instance->Handle,
&gEfiDevicePathProtocolGuid, &Instance->DevicePath,
&gEfiBlockIoProtocolGuid, &Instance->BlockIoProtocol,
NULL
);
if (EFI_ERROR(Status)) {
FreePool(Instance);
return Status;
}
}
*NorFlashInstance = Instance;
return Status;
}
EFI_STATUS
NorFlashReadCfiData (
IN UINTN BaseAddress,
IN UINTN CFI_Offset,
IN UINT32 NumberOfBytes,
OUT UINT32 *Data
)
{
UINT32 CurrentByte;
volatile UINTN *ReadAddress;
UINT32 ReadData;
UINT32 Byte1;
UINT32 Byte2;
UINT32 CombinedData = 0;
EFI_STATUS Status = EFI_SUCCESS;
if( NumberOfBytes > 4 ) {
// Using 32 bit variable so can only read 4 bytes
return EFI_INVALID_PARAMETER;
}
// First combine the base address with the offset address
// to create an absolute read address.
// However, because we are in little endian, read from the last address down to the first
ReadAddress = CREATE_NOR_ADDRESS( BaseAddress, CFI_Offset ) + NumberOfBytes - 1;
// Although each read returns 32 bits, because of the NOR Flash structure,
// each 16 bits (16 MSB and 16 LSB) come from two different chips.
// When in CFI mode, each chip read returns valid data in only the 8 LSBits;
// the 8 MSBits are invalid and can be ignored.
// Therefore, each read address returns one byte from each chip.
//
// Also note: As we are in little endian notation and we are reading
// bytes from incremental addresses, we should assemble them in little endian order.
for( CurrentByte=0; CurrentByte<NumberOfBytes; CurrentByte++ ) {
// Read the bytes from the two chips
ReadData = *ReadAddress;
// Check the data validity:
// The 'Dual Data' function means that
// each chip should return identical data.
// If that is not the case then we have a problem.
Byte1 = GET_LOW_BYTE ( ReadData );
Byte2 = GET_HIGH_BYTE( ReadData );
if( Byte1 != Byte2 ) {
// The two bytes should have been identical
return EFI_DEVICE_ERROR;
} else {
// Each successive iteration of the 'for' loop reads a lower address.
// As we read lower addresses and as we use little endian,
// we read lower significance bytes. So combine them in the correct order.
CombinedData = (CombinedData << 8) | Byte1;
// Decrement down to the next address
ReadAddress--;
}
}
*Data = CombinedData;
return Status;
}
EFI_STATUS
NorFlashReadStatusRegister(
IN UINTN SR_Address
)
{
volatile UINT32 *pStatusRegister;
UINT32 StatusRegister;
UINT32 ErrorMask;
EFI_STATUS Status = EFI_SUCCESS;
// Prepare the read address
pStatusRegister = (UINT32 *) SR_Address;
do {
// Prepare to read the status register
SEND_NOR_COMMAND( SR_Address, 0, P30_CMD_READ_STATUS_REGISTER );
// Snapshot the status register
StatusRegister = *pStatusRegister;
}
// The chip is busy while the WRITE bit is not asserted
while ( (StatusRegister & P30_SR_BIT_WRITE) != P30_SR_BIT_WRITE );
// Perform a full status check:
// Mask the relevant bits of Status Register.
// Everything should be zero, if not, we have a problem
// Prepare the Error Mask by setting bits 5, 4, 3, 1
ErrorMask = P30_SR_BIT_ERASE | P30_SR_BIT_PROGRAM | P30_SR_BIT_VPP | P30_SR_BIT_BLOCK_LOCKED ;
if ( (StatusRegister & ErrorMask) != 0 ) {
if ( (StatusRegister & P30_SR_BIT_VPP) != 0 ) {
DEBUG((EFI_D_ERROR,"NorFlashReadStatusRegister: VPP Range Error\n"));
} else if ( (StatusRegister & (P30_SR_BIT_ERASE | P30_SR_BIT_PROGRAM) ) != 0 ) {
DEBUG((EFI_D_ERROR,"NorFlashReadStatusRegister: Command Sequence Error\n"));
} else if ( (StatusRegister & P30_SR_BIT_PROGRAM) != 0 ) {
DEBUG((EFI_D_ERROR,"NorFlashReadStatusRegister: Program Error\n"));
} else if ( (StatusRegister & P30_SR_BIT_BLOCK_LOCKED) != 0 ) {
DEBUG((EFI_D_ERROR,"NorFlashReadStatusRegister: Device Protect Error\n"));
} else {
DEBUG((EFI_D_ERROR,"NorFlashReadStatusRegister: Error (0x%X)\n",Status));
}
// If an error is detected we must clear the Status Register
SEND_NOR_COMMAND( SR_Address, 0, P30_CMD_CLEAR_STATUS_REGISTER );
Status = EFI_DEVICE_ERROR;
}
SEND_NOR_COMMAND( SR_Address, 0, P30_CMD_READ_ARRAY );
return Status;
}
BOOLEAN
NorFlashBlockIsLocked(
IN UINTN BlockAddress
)
{
volatile UINT32 *pReadData;
UINT32 LockStatus;
BOOLEAN BlockIsLocked = TRUE;
// Prepare the read address
pReadData = (UINT32 *) CREATE_NOR_ADDRESS( BlockAddress, 2 );
// Send command for reading device id
SEND_NOR_COMMAND( BlockAddress, 2, P30_CMD_READ_DEVICE_ID );
// Read block lock status
LockStatus = *pReadData;
// Decode block lock status
LockStatus = FOLD_32BIT_INTO_16BIT(LockStatus);
if( (LockStatus & 0x2) != 0 ) {
DEBUG((EFI_D_ERROR, "UnlockSingleBlock: WARNING: Block LOCKED DOWN\n"));
}
if( (LockStatus & 0x1) == 0 ) {
// This means the block is unlocked
DEBUG((DEBUG_BLKIO, "UnlockSingleBlock: Block 0x%08x unlocked\n", BlockAddress ));
BlockIsLocked = FALSE;
}
return BlockIsLocked;
}
EFI_STATUS
NorFlashUnlockSingleBlock(
IN UINTN BlockAddress
)
{
EFI_STATUS Status = EFI_SUCCESS;
// Raise the Task Priority Level to TPL_NOTIFY to serialise all its operations
// and to protect shared data structures.
//while( NorFlashBlockIsLocked( BlockAddress ) )
{
// Request a lock setup
SEND_NOR_COMMAND( BlockAddress, 0, P30_CMD_LOCK_BLOCK_SETUP );
// Request an unlock
SEND_NOR_COMMAND( BlockAddress, 0, P30_CMD_UNLOCK_BLOCK );
}
// Put device back into Read Array mode
SEND_NOR_COMMAND( BlockAddress, 0, P30_CMD_READ_ARRAY );
DEBUG((DEBUG_BLKIO, "UnlockSingleBlock: BlockAddress=0x%08x, Exit Status = \"%r\".\n", BlockAddress, Status));
return Status;
}
EFI_STATUS
NorFlashUnlockSingleBlockIfNecessary(
IN UINTN BlockAddress
)
{
EFI_STATUS Status = EFI_SUCCESS;
if ( NorFlashBlockIsLocked( BlockAddress ) == TRUE ) {
Status = NorFlashUnlockSingleBlock( BlockAddress );
}
return Status;
}
/**
* The following function presumes that the block has already been unlocked.
**/
EFI_STATUS
NorFlashEraseSingleBlock(
IN UINTN BlockAddress
)
{
EFI_STATUS Status = EFI_SUCCESS;
// Request a block erase and then confirm it
SEND_NOR_COMMAND( BlockAddress, 0, P30_CMD_BLOCK_ERASE_SETUP );
SEND_NOR_COMMAND( BlockAddress, 0, P30_CMD_BLOCK_ERASE_CONFIRM );
// Wait until the status register gives us the all clear
Status = NorFlashReadStatusRegister( BlockAddress );
if (EFI_ERROR(Status)) {
DEBUG((DEBUG_BLKIO, "EraseSingleBlock(BlockAddress=0x%08x) = '%r'\n", BlockAddress, Status));
}
return Status;
}
/**
* The following function presumes that the block has already been unlocked.
**/
EFI_STATUS
NorFlashUnlockAndEraseSingleBlock(
IN UINTN BlockAddress
)
{
EFI_STATUS Status;
// Unlock the block if we have to
Status = NorFlashUnlockSingleBlockIfNecessary( BlockAddress );
if (!EFI_ERROR(Status)) {
Status = NorFlashEraseSingleBlock( BlockAddress );
}
return Status;
}
EFI_STATUS
NorFlashWriteSingleWord (
IN UINTN WordAddress,
IN UINT32 WriteData
)
{
EFI_STATUS Status;
volatile UINT32 *Data;
// Prepare the read address
Data = (UINT32 *)WordAddress;
// Request a write single word command
SEND_NOR_COMMAND( WordAddress, 0, P30_CMD_WORD_PROGRAM_SETUP );
// Store the word into NOR Flash;
*Data = WriteData;
// Wait for the write to complete and then check for any errors; i.e. check the Status Register
Status = NorFlashReadStatusRegister( WordAddress );
return Status;
}
/*
* Writes data to the NOR Flash using the Buffered Programming method.
*
* The maximum size of the on-chip buffer is 32-words, because of hardware restrictions.
* Therefore this function will only handle buffers up to 32 words or 128 bytes.
* To deal with larger buffers, call this function again.
*
* This function presumes that both the TargetAddress and the TargetAddress+BufferSize
* exist entirely within the NOR Flash. Therefore these conditions will not be checked here.
*
* In buffered programming, if the target address not at the beginning of a 32-bit word boundary,
* then programming time is doubled and power consumption is increased.
* Therefore, it is a requirement to align buffer writes to 32-bit word boundaries.
* i.e. the last 4 bits of the target start address must be zero: 0x......00
*/
EFI_STATUS
NorFlashWriteBuffer (
IN UINTN TargetAddress,
IN UINTN BufferSizeInBytes,
IN UINT32 *Buffer
)
{
EFI_STATUS Status;
UINTN BufferSizeInWords;
UINTN Count;
volatile UINT32 *Data;
UINTN WaitForBuffer = MAX_BUFFERED_PROG_ITERATIONS;
BOOLEAN BufferAvailable = FALSE;
// Check that the target address does not cross a 32-word boundary.
if ( (TargetAddress & BOUNDARY_OF_32_WORDS) != 0 ) {
return EFI_INVALID_PARAMETER;
}
// Check there are some data to program
if ( BufferSizeInBytes == 0 ) {
return EFI_BUFFER_TOO_SMALL;
}
// Check that the buffer size does not exceed the maximum hardware buffer size on chip.
if ( BufferSizeInBytes > P30_MAX_BUFFER_SIZE_IN_BYTES ) {
return EFI_BAD_BUFFER_SIZE;
}
// Check that the buffer size is a multiple of 32-bit words
if ( (BufferSizeInBytes % 4) != 0 ) {
return EFI_BAD_BUFFER_SIZE;
}
// Pre-programming conditions checked, now start the algorithm.
// Prepare the data destination address
Data = (UINT32 *)TargetAddress;
// Check the availability of the buffer
do {
// Issue the Buffered Program Setup command
SEND_NOR_COMMAND( TargetAddress, 0, P30_CMD_BUFFERED_PROGRAM_SETUP );
// Read back the status register bit#7 from the same address
if ( ((*Data) & P30_SR_BIT_WRITE) == P30_SR_BIT_WRITE ) {
BufferAvailable = TRUE;
}
// Update the loop counter
WaitForBuffer--;
} while (( WaitForBuffer > 0 ) && ( BufferAvailable == FALSE ));
// The buffer was not available for writing
if ( WaitForBuffer == 0 ) {
return EFI_DEVICE_ERROR;
}
// From now on we work in 32-bit words
BufferSizeInWords = BufferSizeInBytes / (UINTN)4;
// Write the word count, which is (buffer_size_in_words - 1),
// because word count 0 means one word.
SEND_NOR_COMMAND( TargetAddress, 0, (BufferSizeInWords - 1) );
// Write the data to the NOR Flash, advancing each address by 4 bytes
for( Count=0; Count<BufferSizeInWords; Count++, Data++, Buffer++ ) {
*Data = *Buffer;
}
// Issue the Buffered Program Confirm command, to start the programming operation
SEND_NOR_COMMAND( TargetAddress, 0, P30_CMD_BUFFERED_PROGRAM_CONFIRM );
// Wait for the write to complete and then check for any errors; i.e. check the Status Register
Status = NorFlashReadStatusRegister( TargetAddress );
return Status;
}
EFI_STATUS
NorFlashWriteSingleBlock (
IN UINTN DeviceBaseAddress,
IN EFI_LBA Lba,
IN UINT32 *DataBuffer,
IN UINT32 BlockSizeInWords
)
{
EFI_STATUS Status = EFI_SUCCESS;
UINTN WordAddress;
UINT32 WordIndex;
UINTN BufferIndex;
UINTN BlockAddress;
UINTN BuffersInBlock;
UINTN RemainingWords;
// Get the physical address of the block
BlockAddress = GET_NOR_BLOCK_ADDRESS(DeviceBaseAddress, Lba, BlockSizeInWords * 4);
Status = NorFlashUnlockAndEraseSingleBlock( BlockAddress );
if (EFI_ERROR(Status)) {
DEBUG((EFI_D_ERROR, "WriteSingleBlock: ERROR - Failed to Unlock and Erase the single block at 0x%X\n", BlockAddress));
return Status;
}
// To speed up the programming operation, NOR Flash is programmed using the Buffered Programming method.
// Start writing from the first address at the start of the block
WordAddress = BlockAddress;
// Check that the address starts at a 32-word boundary, i.e. last 7 bits must be zero
if ( (WordAddress & BOUNDARY_OF_32_WORDS) == 0x00 ) {
// First, break the entire block into buffer-sized chunks.
BuffersInBlock = (UINTN)BlockSizeInWords / P30_MAX_BUFFER_SIZE_IN_BYTES;
// Then feed each buffer chunk to the NOR Flash
for( BufferIndex=0;
BufferIndex < BuffersInBlock;
BufferIndex++, WordAddress += P30_MAX_BUFFER_SIZE_IN_BYTES, DataBuffer += P30_MAX_BUFFER_SIZE_IN_WORDS
) {
Status = NorFlashWriteBuffer ( WordAddress, P30_MAX_BUFFER_SIZE_IN_BYTES, DataBuffer );
if (EFI_ERROR(Status)) {
goto EXIT;
}
}
// Finally, finish off any remaining words that are less than the maximum size of the buffer
RemainingWords = BlockSizeInWords % P30_MAX_BUFFER_SIZE_IN_WORDS;
if( RemainingWords != 0) {
Status = NorFlashWriteBuffer ( WordAddress, (RemainingWords * 4), DataBuffer );
if (EFI_ERROR(Status)) {
goto EXIT;
}
}
} else {
// For now, use the single word programming algorithm
// It is unlikely that the NOR Flash will exist in an address which falls within a 32 word boundary range,
// i.e. which ends in the range 0x......01 - 0x......7F.
for( WordIndex=0; WordIndex<BlockSizeInWords; WordIndex++, DataBuffer++, WordAddress = WordAddress + 4 ) {
Status = NorFlashWriteSingleWord( WordAddress, *DataBuffer );
if (EFI_ERROR(Status)) {
goto EXIT;
}
}
}
EXIT:
if (EFI_ERROR(Status)) {
DEBUG((EFI_D_ERROR, "NOR FLASH Programming [WriteSingleBlock] failed at address 0x%08x. Exit Status = \"%r\".\n", WordAddress, Status));
}
return Status;
}
EFI_STATUS
NorFlashWriteBlocks (
IN NOR_FLASH_INSTANCE *Instance,
IN EFI_LBA Lba,
IN UINTN BufferSizeInBytes,
IN VOID *Buffer
)
{
UINT32 *pWriteBuffer;
EFI_STATUS Status = EFI_SUCCESS;
EFI_LBA CurrentBlock;
UINT32 BlockSizeInWords;
UINT32 NumBlocks;
UINT32 BlockCount;
volatile UINT32 *VersatileExpress_SYS_FLASH;
// The buffer must be valid
if (Buffer == NULL) {
return EFI_INVALID_PARAMETER;
}
if( Instance->Media.ReadOnly == TRUE ) {
return EFI_WRITE_PROTECTED;
}
// We must have some bytes to read
DEBUG((DEBUG_BLKIO, "NorFlashWriteBlocks: BufferSizeInBytes=0x%x\n", BufferSizeInBytes));
if( BufferSizeInBytes == 0 ) {
return EFI_BAD_BUFFER_SIZE;
}
// The size of the buffer must be a multiple of the block size
DEBUG((DEBUG_BLKIO, "NorFlashWriteBlocks: BlockSize in bytes =0x%x\n", Instance->Media.BlockSize ));
if ((BufferSizeInBytes % Instance->Media.BlockSize) != 0) {
return EFI_BAD_BUFFER_SIZE;
}
// All blocks must be within the device
NumBlocks = ((UINT32)BufferSizeInBytes) / Instance->Media.BlockSize ;
DEBUG((DEBUG_BLKIO, "NorFlashWriteBlocks: NumBlocks=%d, LastBlock=%ld, Lba=%ld.\n", NumBlocks, Instance->Media.LastBlock, Lba));
if ( ( Lba + NumBlocks ) > ( Instance->Media.LastBlock + 1 ) ) {
DEBUG((EFI_D_ERROR, "NorFlashWriteBlocks: ERROR - Write will exceed last block.\n"));
return EFI_INVALID_PARAMETER;
}
// Everything seems ok so far, so now we need to disable the platform-specific
// flash write protection for Versatile Express
VersatileExpress_SYS_FLASH = (UINT32 *)VE_REGISTER_SYS_FLASH_ADDR;
if( (*VersatileExpress_SYS_FLASH & 0x1) == 0 ) {
// Writing to NOR FLASH is disabled, so enable it
*VersatileExpress_SYS_FLASH = 0x1;
DEBUG((DEBUG_BLKIO, "NorFlashWriteBlocks: informational - Had to enable HSYS_FLASH flag.\n" ));
}
BlockSizeInWords = Instance->Media.BlockSize / 4;
// Because the target *Buffer is a pointer to VOID, we must put all the data into a pointer
// to a proper data type, so use *ReadBuffer
pWriteBuffer = (UINT32 *)Buffer;
CurrentBlock = Lba;
for( BlockCount=0; BlockCount<NumBlocks; BlockCount++, CurrentBlock++, pWriteBuffer = pWriteBuffer + BlockSizeInWords ) {
DEBUG((DEBUG_BLKIO, "NorFlashWriteBlocks: Writing block #%d\n", (UINTN)CurrentBlock ));
Status = NorFlashWriteSingleBlock( Instance->BaseAddress, CurrentBlock, pWriteBuffer, BlockSizeInWords );
if (EFI_ERROR(Status)) {
break;
}
}
DEBUG((DEBUG_BLKIO, "NorFlashWriteBlocks: Exit Status = \"%r\".\n", Status));
return Status;
}
EFI_STATUS
NorFlashReadBlocks (
IN NOR_FLASH_INSTANCE *Instance,
IN EFI_LBA Lba,
IN UINTN BufferSizeInBytes,
OUT VOID *Buffer
)
{
UINT32 NumBlocks;
UINTN StartAddress;
// The buffer must be valid
if (Buffer == NULL) {
return EFI_INVALID_PARAMETER;
}
// We must have some bytes to read
DEBUG((DEBUG_BLKIO, "NorFlashReadBlocks: BufferSize=0x%x bytes.\n", BufferSizeInBytes));
if( BufferSizeInBytes == 0 ) {
return EFI_BAD_BUFFER_SIZE;
}
// The size of the buffer must be a multiple of the block size
DEBUG((DEBUG_BLKIO, "NorFlashReadBlocks: BlockSize=0x%x bytes.\n", Instance->Media.BlockSize ));
if ((BufferSizeInBytes % Instance->Media.BlockSize) != 0) {
return EFI_BAD_BUFFER_SIZE;
}
// All blocks must be within the device
NumBlocks = ((UINT32)BufferSizeInBytes) / Instance->Media.BlockSize ;
DEBUG((DEBUG_BLKIO, "NorFlashReadBlocks: NumBlocks=%d, LastBlock=%ld, Lba=%ld\n", NumBlocks, Instance->Media.LastBlock, Lba));
if ( ( Lba + NumBlocks ) > (Instance->Media.LastBlock + 1) ) {
DEBUG((EFI_D_ERROR, "NorFlashReadBlocks: ERROR - Read will exceed last block\n"));
return EFI_INVALID_PARAMETER;
}
// Get the address to start reading from
StartAddress = GET_NOR_BLOCK_ADDRESS( Instance->BaseAddress,
Lba,
Instance->Media.BlockSize
);
// Put the device into Read Array mode
SEND_NOR_COMMAND( Instance->BaseAddress, 0, P30_CMD_READ_ARRAY );
// Readout the data
CopyMem(Buffer, (UINTN *)StartAddress, BufferSizeInBytes);
return EFI_SUCCESS;
}
EFI_STATUS
NorFlashReset (
IN NOR_FLASH_INSTANCE *Instance
)
{
DEBUG((DEBUG_BLKIO, "NorFlashReset(BaseAddress=0x%08x)\n", Instance->BaseAddress));
// As there is no specific RESET to perform, ensure that the devices is in the default Read Array mode
SEND_NOR_COMMAND( Instance->BaseAddress, 0, P30_CMD_READ_ARRAY );
return EFI_SUCCESS;
}
EFI_STATUS
EFIAPI
NorFlashInitialise (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EFI_STATUS Status = EFI_SUCCESS;
UINT32 Index;
for (Index = 0; Index < NOR_FLASH_LAST_DEVICE; Index++) {
Status = NorFlashCreateInstance(
mNorFlashDescription[Index].BaseAddress,
mNorFlashDescription[Index].Size,
Index,
mNorFlashDescription[Index].BlockSize,
mNorFlashDescription[Index].SupportFvb,
&mNorFlashDescription[Index].Guid,
&mNorFlashInstances[Index]
);
if (EFI_ERROR(Status)) {
DEBUG((EFI_D_ERROR,"NorFlashInitialise: Fail to create instance for NorFlash[%d]\n",Index));
}
}
return Status;
}

View File

@@ -0,0 +1,328 @@
/** @file NorFlashDxe.h
Copyright (c) 2010, ARM Ltd. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef __NOR_FLASH_DXE_H__
#define __NOR_FLASH_DXE_H__
#include <Base.h>
#include <PiDxe.h>
#include <Protocol/BlockIo.h>
#include <Protocol/FirmwareVolumeBlock.h>
#include <ArmPlatform.h>
#define HIGH_16_BITS 0xFFFF0000
#define LOW_16_BITS 0x0000FFFF
#define LOW_8_BITS 0x000000FF
// Hardware addresses
#define VE_SYSTEM_REGISTERS_OFFSET 0x00000000
#define SYSTEM_REGISTER_SYS_FLASH 0x0000004C
#define VE_REGISTER_SYS_FLASH_ADDR ( ARM_VE_BOARD_PERIPH_BASE + VE_SYSTEM_REGISTERS_OFFSET + SYSTEM_REGISTER_SYS_FLASH )
// Device access macros
// These are necessary because we use 2 x 16bit parts to make up 32bit data
#define FOLD_32BIT_INTO_16BIT(value) ( ( value >> 16 ) | ( value & LOW_16_BITS ) )
#define GET_LOW_BYTE(value) ( value & LOW_8_BITS )
#define GET_HIGH_BYTE(value) ( GET_LOW_BYTE( value >> 16 ) )
// Each command must be sent simultaneously to both chips,
// i.e. at the lower 16 bits AND at the higher 16 bits
#define CREATE_NOR_ADDRESS(BaseAddr,OffsetAddr) ( (volatile UINTN *)((BaseAddr) + ((OffsetAddr) << 2)) )
#define CREATE_DUAL_CMD(Cmd) ( ( Cmd << 16) | ( Cmd & LOW_16_BITS) )
#define SEND_NOR_COMMAND(BaseAddr,OffsetAddr,Cmd) ( *CREATE_NOR_ADDRESS(BaseAddr,OffsetAddr) = CREATE_DUAL_CMD(Cmd) )
#define GET_NOR_BLOCK_ADDRESS(BaseAddr,Lba,LbaSize)( BaseAddr + (UINTN)(Lba * LbaSize) )
// Status Register Bits
#define P30_SR_BIT_WRITE 0x00800080 /* Bit 7 */
#define P30_SR_BIT_ERASE_SUSPEND 0x00400040 /* Bit 6 */
#define P30_SR_BIT_ERASE 0x00200020 /* Bit 5 */
#define P30_SR_BIT_PROGRAM 0x00100010 /* Bit 4 */
#define P30_SR_BIT_VPP 0x00080008 /* Bit 3 */
#define P30_SR_BIT_PROGRAM_SUSPEND 0x00040004 /* Bit 2 */
#define P30_SR_BIT_BLOCK_LOCKED 0x00020002 /* Bit 1 */
#define P30_SR_BIT_BEFP 0x00010001 /* Bit 0 */
// Device Commands for Intel StrataFlash(R) Embedded Memory (P30) Family
// On chip buffer size for buffered programming operations
// There are 2 chips, each chip can buffer up to 32 (16-bit)words, and each word is 2 bytes.
// Therefore the total size of the buffer is 2 x 32 x 2 = 128 bytes
#define P30_MAX_BUFFER_SIZE_IN_BYTES ((UINTN)128)
#define P30_MAX_BUFFER_SIZE_IN_WORDS (P30_MAX_BUFFER_SIZE_IN_BYTES/((UINTN)4))
#define MAX_BUFFERED_PROG_ITERATIONS 10000000
#define BOUNDARY_OF_32_WORDS 0x7F
// CFI Addresses
#define P30_CFI_ADDR_QUERY_UNIQUE_QRY 0x10
#define P30_CFI_ADDR_VENDOR_ID 0x13
// CFI Data
#define CFI_QRY 0x00595251
// READ Commands
#define P30_CMD_READ_DEVICE_ID 0x0090
#define P30_CMD_READ_STATUS_REGISTER 0x0070
#define P30_CMD_CLEAR_STATUS_REGISTER 0x0050
#define P30_CMD_READ_ARRAY 0x00FF
#define P30_CMD_READ_CFI_QUERY 0x0098
// WRITE Commands
#define P30_CMD_WORD_PROGRAM_SETUP 0x0040
#define P30_CMD_ALTERNATE_WORD_PROGRAM_SETUP 0x0010
#define P30_CMD_BUFFERED_PROGRAM_SETUP 0x00E8
#define P30_CMD_BUFFERED_PROGRAM_CONFIRM 0x00D0
#define P30_CMD_BEFP_SETUP 0x0080
#define P30_CMD_BEFP_CONFIRM 0x00D0
// ERASE Commands
#define P30_CMD_BLOCK_ERASE_SETUP 0x0020
#define P30_CMD_BLOCK_ERASE_CONFIRM 0x00D0
// SUSPEND Commands
#define P30_CMD_PROGRAM_OR_ERASE_SUSPEND 0x00B0
#define P30_CMD_SUSPEND_RESUME 0x00D0
// BLOCK LOCKING / UNLOCKING Commands
#define P30_CMD_LOCK_BLOCK_SETUP 0x0060
#define P30_CMD_LOCK_BLOCK 0x0001
#define P30_CMD_UNLOCK_BLOCK 0x00D0
#define P30_CMD_LOCK_DOWN_BLOCK 0x002F
// PROTECTION Commands
#define P30_CMD_PROGRAM_PROTECTION_REGISTER_SETUP 0x00C0
// CONFIGURATION Commands
#define P30_CMD_READ_CONFIGURATION_REGISTER_SETUP 0x0060
#define P30_CMD_READ_CONFIGURATION_REGISTER 0x0003
#define NOR_FLASH_SIGNATURE SIGNATURE_32('n', 'o', 'r', '0')
#define INSTANCE_FROM_FVB_THIS(a) CR(a, NOR_FLASH_INSTANCE, FvbProtocol, NOR_FLASH_SIGNATURE)
#define INSTANCE_FROM_BLKIO_THIS(a) CR(a, NOR_FLASH_INSTANCE, BlockIoProtocol, NOR_FLASH_SIGNATURE)
typedef struct _NOR_FLASH_INSTANCE NOR_FLASH_INSTANCE;
typedef EFI_STATUS (*NOR_FLASH_INITIALIZE) (NOR_FLASH_INSTANCE* Instance);
typedef struct {
UINTN BaseAddress;
UINTN Size;
UINTN BlockSize;
BOOLEAN SupportFvb;
EFI_GUID Guid;
} NOR_FLASH_DESCRIPTION;
typedef struct {
VENDOR_DEVICE_PATH Vendor;
EFI_DEVICE_PATH_PROTOCOL End;
} NOR_FLASH_DEVICE_PATH;
struct _NOR_FLASH_INSTANCE {
UINT32 Signature;
EFI_HANDLE Handle;
BOOLEAN Initialized;
NOR_FLASH_INITIALIZE Initialize;
UINTN BaseAddress;
UINTN Size;
EFI_BLOCK_IO_PROTOCOL BlockIoProtocol;
EFI_BLOCK_IO_MEDIA Media;
BOOLEAN SupportFvb;
EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL FvbProtocol;
NOR_FLASH_DEVICE_PATH DevicePath;
};
EFI_STATUS
EFIAPI
NorFlashBlkIoInitialize (
IN NOR_FLASH_INSTANCE* Instance
);
EFI_STATUS
NorFlashReadCfiData (
IN UINTN BaseAddress,
IN UINTN CFI_Offset,
IN UINT32 NumberOfBytes,
OUT UINT32 *Data
);
EFI_STATUS
NorFlashWriteBuffer (
IN UINTN TargetAddress,
IN UINTN BufferSizeInBytes,
IN UINT32 *Buffer
);
//
// BlockIO Protocol function EFI_BLOCK_IO_PROTOCOL.Reset
//
EFI_STATUS
EFIAPI
NorFlashBlockIoReset (
IN EFI_BLOCK_IO_PROTOCOL *This,
IN BOOLEAN ExtendedVerification
);
//
// BlockIO Protocol function EFI_BLOCK_IO_PROTOCOL.ReadBlocks
//
EFI_STATUS
EFIAPI
NorFlashBlockIoReadBlocks (
IN EFI_BLOCK_IO_PROTOCOL *This,
IN UINT32 MediaId,
IN EFI_LBA Lba,
IN UINTN BufferSizeInBytes,
OUT VOID *Buffer
);
//
// BlockIO Protocol function EFI_BLOCK_IO_PROTOCOL.WriteBlocks
//
EFI_STATUS
EFIAPI
NorFlashBlockIoWriteBlocks (
IN EFI_BLOCK_IO_PROTOCOL *This,
IN UINT32 MediaId,
IN EFI_LBA Lba,
IN UINTN BufferSizeInBytes,
IN VOID *Buffer
);
//
// BlockIO Protocol function EFI_BLOCK_IO_PROTOCOL.FlushBlocks
//
EFI_STATUS
EFIAPI
NorFlashBlockIoFlushBlocks (
IN EFI_BLOCK_IO_PROTOCOL *This
);
//
// NorFlashFvbDxe.c
//
EFI_STATUS
EFIAPI
NorFlashFvbInitialize (
IN NOR_FLASH_INSTANCE* Instance
);
EFI_STATUS
EFIAPI
FvbGetAttributes(
IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,
OUT EFI_FVB_ATTRIBUTES_2 *Attributes
);
EFI_STATUS
EFIAPI
FvbSetAttributes(
IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,
IN OUT EFI_FVB_ATTRIBUTES_2 *Attributes
);
EFI_STATUS
EFIAPI
FvbGetPhysicalAddress(
IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,
OUT EFI_PHYSICAL_ADDRESS *Address
);
EFI_STATUS
EFIAPI
FvbGetBlockSize(
IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,
IN EFI_LBA Lba,
OUT UINTN *BlockSize,
OUT UINTN *NumberOfBlocks
);
EFI_STATUS
EFIAPI
FvbRead(
IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,
IN EFI_LBA Lba,
IN UINTN Offset,
IN OUT UINTN *NumBytes,
IN OUT UINT8 *Buffer
);
EFI_STATUS
EFIAPI
FvbWrite(
IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,
IN EFI_LBA Lba,
IN UINTN Offset,
IN OUT UINTN *NumBytes,
IN UINT8 *Buffer
);
EFI_STATUS
EFIAPI
FvbEraseBlocks(
IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,
...
);
//
// NorFlashDxe.c
//
EFI_STATUS
NorFlashUnlockAndEraseSingleBlock(
IN UINTN BlockAddress
);
EFI_STATUS
NorFlashWriteSingleBlock (
IN UINTN DeviceBaseAddress,
IN EFI_LBA Lba,
IN UINT32 *pDataBuffer,
IN UINT32 BlockSizeInWords
);
EFI_STATUS
NorFlashWriteBlocks (
IN NOR_FLASH_INSTANCE *Instance,
IN EFI_LBA Lba,
IN UINTN BufferSizeInBytes,
IN VOID *Buffer
);
EFI_STATUS
NorFlashReadBlocks (
IN NOR_FLASH_INSTANCE *Instance,
IN EFI_LBA Lba,
IN UINTN BufferSizeInBytes,
OUT VOID *Buffer
);
EFI_STATUS
NorFlashReset (
IN NOR_FLASH_INSTANCE *Instance
);
#endif /* __NOR_FLASH_DXE_H__ */

View File

@@ -0,0 +1,59 @@
#/** @file
#
# Component discription file for NorFlashDxe module
#
# Copyright (c) 2010, ARM Ltd. All rights reserved.<BR>
# This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
# which accompanies this distribution. The full text of the license may be found at
# http://opensource.org/licenses/bsd-license.php
#
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#
#**/
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = ArmVeNorFlashDxe
FILE_GUID = 93E34C7E-B50E-11DF-9223-2443DFD72085
MODULE_TYPE = DXE_DRIVER
VERSION_STRING = 1.0
ENTRY_POINT = NorFlashInitialise
[Sources.common]
NorFlashDxe.c
NorFlashFvbDxe.c
NorFlashBlockIoDxe.c
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
ArmPlatformPkg/ArmVExpressPkg/ArmVExpressPkg.dec
[LibraryClasses]
IoLib
BaseLib
UefiLib
DebugLib
UefiDriverEntryPoint
UefiBootServicesTableLib
[Guids]
gEfiSystemNvDataFvGuid
gEfiVariableGuid
[Protocols]
gEfiBlockIoProtocolGuid
gEfiDevicePathProtocolGuid
gEfiFirmwareVolumeBlockProtocolGuid
[FixedPcd.common]
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase
[Pcd.common]
[Depex]
TRUE

View File

@@ -0,0 +1,796 @@
/*++ @file NorFlashFvbDxe.c
Copyright (c) 2010, ARM Ltd. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
--*/
#include <PiDxe.h>
#include <Library/PcdLib.h>
#include <Library/BaseLib.h>
#include <Library/UefiLib.h>
#include <Library/DebugLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Guid/VariableFormat.h>
#include <Guid/SystemNvDataGuid.h>
#include "NorFlashDxe.h"
///
/// The Firmware Volume Block Protocol is the low-level interface
/// to a firmware volume. File-level access to a firmware volume
/// should not be done using the Firmware Volume Block Protocol.
/// Normal access to a firmware volume must use the Firmware
/// Volume Protocol. Typically, only the file system driver that
/// produces the Firmware Volume Protocol will bind to the
/// Firmware Volume Block Protocol.
///
/**
Initialises the FV Header and Variable Store Header
to support variable operations.
@param[in] Ptr - Location to initialise the headers
**/
EFI_STATUS
InitializeFvAndVariableStoreHeaders (
IN NOR_FLASH_INSTANCE *Instance
)
{
EFI_STATUS Status;
VOID* Headers;
UINTN HeadersLength;
EFI_FIRMWARE_VOLUME_HEADER *FirmwareVolumeHeader;
VARIABLE_STORE_HEADER *VariableStoreHeader;
if (!Instance->Initialized) {
Instance->Initialize(Instance);
}
HeadersLength = sizeof(EFI_FIRMWARE_VOLUME_HEADER) + sizeof(EFI_FV_BLOCK_MAP_ENTRY) + sizeof(VARIABLE_STORE_HEADER);
Headers = AllocatePool(HeadersLength);
ZeroMem (&Headers,HeadersLength);
//
// EFI_FIRMWARE_VOLUME_HEADER
//
FirmwareVolumeHeader = (EFI_FIRMWARE_VOLUME_HEADER*)Headers;
CopyGuid (&FirmwareVolumeHeader->FileSystemGuid, &gEfiSystemNvDataFvGuid);
FirmwareVolumeHeader->FvLength = Instance->Media.BlockSize * (Instance->Media.LastBlock + 1);
FirmwareVolumeHeader->Signature = EFI_FVH_SIGNATURE;
FirmwareVolumeHeader->Attributes = (EFI_FVB_ATTRIBUTES_2) (
EFI_FVB2_READ_ENABLED_CAP | // Reads may be enabled
EFI_FVB2_READ_STATUS | // Reads are currently enabled
EFI_FVB2_STICKY_WRITE | // A block erase is required to flip bits into EFI_FVB2_ERASE_POLARITY
EFI_FVB2_MEMORY_MAPPED | // It is memory mapped
EFI_FVB2_ERASE_POLARITY | // After erasure all bits take this value (i.e. '1')
EFI_FVB2_WRITE_STATUS | // Writes are currently enabled
EFI_FVB2_WRITE_ENABLED_CAP // Writes may be enabled
);
FirmwareVolumeHeader->HeaderLength = sizeof(EFI_FIRMWARE_VOLUME_HEADER) + sizeof(EFI_FV_BLOCK_MAP_ENTRY);
FirmwareVolumeHeader->Revision = EFI_FVH_REVISION;
FirmwareVolumeHeader->BlockMap[0].NumBlocks = Instance->Media.LastBlock + 1;
FirmwareVolumeHeader->BlockMap[0].Length = Instance->Media.BlockSize;
FirmwareVolumeHeader->BlockMap[1].NumBlocks = 0;
FirmwareVolumeHeader->BlockMap[1].Length = 0;
FirmwareVolumeHeader->Checksum = CalculateCheckSum16 (FirmwareVolumeHeader,FirmwareVolumeHeader->HeaderLength);
//
// VARIABLE_STORE_HEADER
//
VariableStoreHeader = (VARIABLE_STORE_HEADER*)((UINT32)Headers + FirmwareVolumeHeader->HeaderLength);
CopyGuid (&VariableStoreHeader->Signature, &gEfiVariableGuid);
VariableStoreHeader->Size = PcdGet32(PcdFlashNvStorageVariableSize) - FirmwareVolumeHeader->HeaderLength;
VariableStoreHeader->Format = VARIABLE_STORE_FORMATTED;
VariableStoreHeader->State = VARIABLE_STORE_HEALTHY;
// Install the combined super-header in the NorFlash
Status = FvbWrite(&Instance->FvbProtocol, 0, 0, &FirmwareVolumeHeader, Headers );
FreePool(Headers);
return Status;
}
/**
Check the integrity of firmware volume header.
@param[in] FwVolHeader - A pointer to a firmware volume header
@retval EFI_SUCCESS - The firmware volume is consistent
@retval EFI_NOT_FOUND - The firmware volume has been corrupted.
**/
EFI_STATUS
ValidateFvHeader (
IN NOR_FLASH_INSTANCE *Instance
)
{
UINT16 Checksum;
EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader;
VARIABLE_STORE_HEADER *VariableStoreHeader;
UINTN VariableStoreLength;
FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER*)Instance->BaseAddress;
//
// Verify the header revision, header signature, length
// Length of FvBlock cannot be 2**64-1
// HeaderLength cannot be an odd number
//
if ( ( FwVolHeader->Revision != EFI_FVH_REVISION )
|| ( FwVolHeader->Signature != EFI_FVH_SIGNATURE )
|| ( FwVolHeader->FvLength != Instance->Media.BlockSize * (Instance->Media.LastBlock + 1) )
) {
return EFI_NOT_FOUND;
}
// Check the Firmware Volume Guid
if( CompareGuid (&FwVolHeader->FileSystemGuid, &gEfiSystemNvDataFvGuid) == FALSE ) {
DEBUG ((EFI_D_ERROR, "ValidateFvHeader: Firmware Volume Guid non-compatible\n"));
return EFI_NOT_FOUND;
}
// Verify the header checksum
/*Checksum = CalculateSum16((VOID*) FwVolHeader, FwVolHeader->HeaderLength);
if (Checksum != 0) {
DEBUG ((EFI_D_ERROR, "ValidateFvHeader: FV checksum is invalid (Checksum:0x%X)\n",Checksum));
return EFI_NOT_FOUND;
}*/
VariableStoreHeader = (VARIABLE_STORE_HEADER*)((UINT32)FwVolHeader + FwVolHeader->HeaderLength);
// Check the Variable Store Guid
if( CompareGuid (&VariableStoreHeader->Signature, &gEfiVariableGuid) == FALSE ) {
DEBUG ((EFI_D_ERROR, "ValidateFvHeader: Variable Store Guid non-compatible\n"));
return EFI_NOT_FOUND;
}
VariableStoreLength = PcdGet32 (PcdFlashNvStorageVariableSize) - FwVolHeader->HeaderLength;
if (VariableStoreHeader->Size != VariableStoreLength) {
DEBUG ((EFI_D_ERROR, "ValidateFvHeader: Variable Store Length does not match\n"));
return EFI_NOT_FOUND;
}
return EFI_SUCCESS;
}
/**
The GetAttributes() function retrieves the attributes and
current settings of the block.
@param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance.
@param Attributes Pointer to EFI_FVB_ATTRIBUTES_2 in which the attributes and
current settings are returned.
Type EFI_FVB_ATTRIBUTES_2 is defined in EFI_FIRMWARE_VOLUME_HEADER.
@retval EFI_SUCCESS The firmware volume attributes were returned.
**/
EFI_STATUS
EFIAPI
FvbGetAttributes(
IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,
OUT EFI_FVB_ATTRIBUTES_2 *Attributes
)
{
EFI_FVB_ATTRIBUTES_2 FlashFvbAttributes;
NOR_FLASH_INSTANCE *Instance;
Instance = INSTANCE_FROM_FVB_THIS(This);
FlashFvbAttributes = (EFI_FVB_ATTRIBUTES_2) (
EFI_FVB2_READ_ENABLED_CAP | // Reads may be enabled
EFI_FVB2_READ_STATUS | // Reads are currently enabled
EFI_FVB2_STICKY_WRITE | // A block erase is required to flip bits into EFI_FVB2_ERASE_POLARITY
EFI_FVB2_MEMORY_MAPPED | // It is memory mapped
EFI_FVB2_ERASE_POLARITY // After erasure all bits take this value (i.e. '1')
);
// Check if it is write protected
if (Instance->Media.ReadOnly != TRUE) {
FlashFvbAttributes = FlashFvbAttributes |
EFI_FVB2_WRITE_STATUS | // Writes are currently enabled
EFI_FVB2_WRITE_ENABLED_CAP; // Writes may be enabled
}
*Attributes = FlashFvbAttributes;
DEBUG ((DEBUG_BLKIO, "FvbGetAttributes(0x%X)\n", *Attributes));
return EFI_SUCCESS;
}
/**
The SetAttributes() function sets configurable firmware volume attributes
and returns the new settings of the firmware volume.
@param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance.
@param Attributes On input, Attributes is a pointer to EFI_FVB_ATTRIBUTES_2
that contains the desired firmware volume settings.
On successful return, it contains the new settings of
the firmware volume.
Type EFI_FVB_ATTRIBUTES_2 is defined in EFI_FIRMWARE_VOLUME_HEADER.
@retval EFI_SUCCESS The firmware volume attributes were returned.
@retval EFI_INVALID_PARAMETER The attributes requested are in conflict with the capabilities
as declared in the firmware volume header.
**/
EFI_STATUS
EFIAPI
FvbSetAttributes(
IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,
IN OUT EFI_FVB_ATTRIBUTES_2 *Attributes
)
{
DEBUG ((DEBUG_BLKIO, "FvbSetAttributes(0x%X) is not supported\n",*Attributes));
return EFI_UNSUPPORTED;
}
/**
The GetPhysicalAddress() function retrieves the base address of
a memory-mapped firmware volume. This function should be called
only for memory-mapped firmware volumes.
@param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance.
@param Address Pointer to a caller-allocated
EFI_PHYSICAL_ADDRESS that, on successful
return from GetPhysicalAddress(), contains the
base address of the firmware volume.
@retval EFI_SUCCESS The firmware volume base address was returned.
@retval EFI_NOT_SUPPORTED The firmware volume is not memory mapped.
**/
EFI_STATUS
EFIAPI
FvbGetPhysicalAddress(
IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,
OUT EFI_PHYSICAL_ADDRESS *Address
)
{
NOR_FLASH_INSTANCE *Instance;
Instance = INSTANCE_FROM_FVB_THIS(This);
DEBUG ((DEBUG_BLKIO, "FvbGetPhysicalAddress(BaseAddress=0x%08x)\n", Instance->BaseAddress));
ASSERT(Address != NULL);
*Address = Instance->BaseAddress;
return EFI_SUCCESS;
}
/**
The GetBlockSize() function retrieves the size of the requested
block. It also returns the number of additional blocks with
the identical size. The GetBlockSize() function is used to
retrieve the block map (see EFI_FIRMWARE_VOLUME_HEADER).
@param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance.
@param Lba Indicates the block for which to return the size.
@param BlockSize Pointer to a caller-allocated UINTN in which
the size of the block is returned.
@param NumberOfBlocks Pointer to a caller-allocated UINTN in
which the number of consecutive blocks,
starting with Lba, is returned. All
blocks in this range have a size of
BlockSize.
@retval EFI_SUCCESS The firmware volume base address was returned.
@retval EFI_INVALID_PARAMETER The requested LBA is out of range.
**/
EFI_STATUS
EFIAPI
FvbGetBlockSize(
IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,
IN EFI_LBA Lba,
OUT UINTN *BlockSize,
OUT UINTN *NumberOfBlocks
)
{
EFI_STATUS Status;
NOR_FLASH_INSTANCE *Instance;
Instance = INSTANCE_FROM_FVB_THIS(This);
DEBUG ((DEBUG_BLKIO, "FvbGetBlockSize(Lba=%ld, BlockSize=0x%x, LastBlock=%ld)\n", Lba, Instance->Media.BlockSize, Instance->Media.LastBlock));
if (Lba > Instance->Media.LastBlock) {
DEBUG ((EFI_D_ERROR, "FvbGetBlockSize: ERROR - Parameter LBA %ld is beyond the last Lba (%ld).\n", Lba, Instance->Media.LastBlock));
Status = EFI_INVALID_PARAMETER;
} else {
// This is easy because in this platform each NorFlash device has equal sized blocks.
*BlockSize = (UINTN) Instance->Media.BlockSize;
*NumberOfBlocks = (UINTN) (Instance->Media.LastBlock - Lba + 1);
DEBUG ((DEBUG_BLKIO, "FvbGetBlockSize: *BlockSize=0x%x, *NumberOfBlocks=0x%x.\n", *BlockSize, *NumberOfBlocks));
Status = EFI_SUCCESS;
}
return Status;
}
/**
Reads the specified number of bytes into a buffer from the specified block.
The Read() function reads the requested number of bytes from the
requested block and stores them in the provided buffer.
Implementations should be mindful that the firmware volume
might be in the ReadDisabled state. If it is in this state,
the Read() function must return the status code
EFI_ACCESS_DENIED without modifying the contents of the
buffer. The Read() function must also prevent spanning block
boundaries. If a read is requested that would span a block
boundary, the read must read up to the boundary but not
beyond. The output parameter NumBytes must be set to correctly
indicate the number of bytes actually read. The caller must be
aware that a read may be partially completed.
@param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance.
@param Lba The starting logical block index from which to read.
@param Offset Offset into the block at which to begin reading.
@param NumBytes Pointer to a UINTN.
At entry, *NumBytes contains the total size of the buffer.
At exit, *NumBytes contains the total number of bytes read.
@param Buffer Pointer to a caller-allocated buffer that will be used
to hold the data that is read.
@retval EFI_SUCCESS The firmware volume was read successfully, and contents are
in Buffer.
@retval EFI_BAD_BUFFER_SIZE Read attempted across an LBA boundary.
On output, NumBytes contains the total number of bytes
returned in Buffer.
@retval EFI_ACCESS_DENIED The firmware volume is in the ReadDisabled state.
@retval EFI_DEVICE_ERROR The block device is not functioning correctly and could not be read.
**/
EFI_STATUS
EFIAPI
FvbRead(
IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,
IN EFI_LBA Lba,
IN UINTN Offset,
IN OUT UINTN *NumBytes,
IN OUT UINT8 *Buffer
)
{
EFI_STATUS Status;
EFI_STATUS TempStatus;
UINTN BlockSize;
UINT8 *BlockBuffer;
NOR_FLASH_INSTANCE *Instance;
Instance = INSTANCE_FROM_FVB_THIS(This);
DEBUG ((DEBUG_BLKIO, "FvbRead(Parameters: Lba=%ld, Offset=0x%x, *NumBytes=0x%x, Buffer @ 0x%08x)\n", Lba, Offset, *NumBytes, Buffer));
if (!Instance->Initialized) {
Instance->Initialize(Instance);
}
Status = EFI_SUCCESS;
TempStatus = Status;
if (FALSE) {
DEBUG ((EFI_D_ERROR, "FvbRead: Can not read: Device is in ReadDisabled state.\n"));
// It is in ReadDisabled state, return an error right away
return EFI_ACCESS_DENIED;
}
// Cache the block size to avoid de-referencing pointers all the time
BlockSize = Instance->Media.BlockSize;
DEBUG ((DEBUG_BLKIO, "FvbRead: Check if (Offset=0x%x + NumBytes=0x%x) <= BlockSize=0x%x\n", Offset, *NumBytes, BlockSize ));
// The read must not span block boundaries.
// We need to check each variable individually because adding two large values together overflows.
if ( ( Offset >= BlockSize ) ||
( *NumBytes > BlockSize ) ||
( (Offset + *NumBytes) > BlockSize ) ) {
DEBUG ((EFI_D_ERROR, "FvbRead: ERROR - EFI_BAD_BUFFER_SIZE: (Offset=0x%x + NumBytes=0x%x) > BlockSize=0x%x\n", Offset, *NumBytes, BlockSize ));
return EFI_BAD_BUFFER_SIZE;
}
// We must have some bytes to read
if (*NumBytes == 0) {
return EFI_BAD_BUFFER_SIZE;
}
// FixMe: Allow an arbitrary number of bytes to be read out, not just a multiple of block size.
// Allocate runtime memory to read in the NOR Flash data. Variable Services are runtime.
BlockBuffer = AllocateRuntimePool(BlockSize);
// Check if the memory allocation was successful
if( BlockBuffer == NULL ) {
DEBUG ((EFI_D_ERROR, "FvbRead: ERROR - Could not allocate BlockBuffer @ 0x%08x.\n", BlockBuffer));
return EFI_DEVICE_ERROR;
}
// Read NOR Flash data into shadow buffer
TempStatus = NorFlashReadBlocks(Instance, Lba, BlockSize, BlockBuffer);
if (EFI_ERROR (TempStatus)) {
// Return one of the pre-approved error statuses
Status = EFI_DEVICE_ERROR;
goto FREE_MEMORY;
}
// Put the data at the appropriate location inside the buffer area
DEBUG ((DEBUG_BLKIO, "FvbRead: CopyMem( Dst=0x%08x, Src=0x%08x, Size=0x%x ).\n", Buffer, BlockBuffer + Offset, *NumBytes));
CopyMem(Buffer, BlockBuffer + Offset, *NumBytes);
FREE_MEMORY:
FreePool(BlockBuffer);
DEBUG ((DEBUG_BLKIO, "FvbRead - end\n"));
return Status;
}
/**
Writes the specified number of bytes from the input buffer to the block.
The Write() function writes the specified number of bytes from
the provided buffer to the specified block and offset. If the
firmware volume is sticky write, the caller must ensure that
all the bits of the specified range to write are in the
EFI_FVB_ERASE_POLARITY state before calling the Write()
function, or else the result will be unpredictable. This
unpredictability arises because, for a sticky-write firmware
volume, a write may negate a bit in the EFI_FVB_ERASE_POLARITY
state but cannot flip it back again. Before calling the
Write() function, it is recommended for the caller to first call
the EraseBlocks() function to erase the specified block to
write. A block erase cycle will transition bits from the
(NOT)EFI_FVB_ERASE_POLARITY state back to the
EFI_FVB_ERASE_POLARITY state. Implementations should be
mindful that the firmware volume might be in the WriteDisabled
state. If it is in this state, the Write() function must
return the status code EFI_ACCESS_DENIED without modifying the
contents of the firmware volume. The Write() function must
also prevent spanning block boundaries. If a write is
requested that spans a block boundary, the write must store up
to the boundary but not beyond. The output parameter NumBytes
must be set to correctly indicate the number of bytes actually
written. The caller must be aware that a write may be
partially completed. All writes, partial or otherwise, must be
fully flushed to the hardware before the Write() service
returns.
@param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance.
@param Lba The starting logical block index to write to.
@param Offset Offset into the block at which to begin writing.
@param NumBytes The pointer to a UINTN.
At entry, *NumBytes contains the total size of the buffer.
At exit, *NumBytes contains the total number of bytes actually written.
@param Buffer The pointer to a caller-allocated buffer that contains the source for the write.
@retval EFI_SUCCESS The firmware volume was written successfully.
@retval EFI_BAD_BUFFER_SIZE The write was attempted across an LBA boundary.
On output, NumBytes contains the total number of bytes
actually written.
@retval EFI_ACCESS_DENIED The firmware volume is in the WriteDisabled state.
@retval EFI_DEVICE_ERROR The block device is malfunctioning and could not be written.
**/
EFI_STATUS
EFIAPI
FvbWrite(
IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,
IN EFI_LBA Lba,
IN UINTN Offset,
IN OUT UINTN *NumBytes,
IN UINT8 *Buffer
)
{
EFI_STATUS Status;
EFI_STATUS TempStatus;
UINTN BlockSize;
UINT8 *BlockBuffer;
NOR_FLASH_INSTANCE *Instance;
Instance = INSTANCE_FROM_FVB_THIS(This);
if (!Instance->Initialized) {
Instance->Initialize(Instance);
}
DEBUG ((DEBUG_BLKIO, "FvbWrite(Parameters: Lba=%ld, Offset=0x%x, *NumBytes=0x%x, Buffer @ 0x%08x)\n", Lba, Offset, *NumBytes, Buffer));
Status = EFI_SUCCESS;
TempStatus = Status;
// Detect WriteDisabled state
if (Instance->Media.ReadOnly == TRUE) {
DEBUG ((EFI_D_ERROR, "FvbWrite: ERROR - Can not write: Device is in WriteDisabled state.\n"));
// It is in WriteDisabled state, return an error right away
return EFI_ACCESS_DENIED;
}
// Cache the block size to avoid de-referencing pointers all the time
BlockSize = Instance->Media.BlockSize;
// The write must not span block boundaries.
// We need to check each variable individually because adding two large values together overflows.
if ( ( Offset >= BlockSize ) ||
( *NumBytes > BlockSize ) ||
( (Offset + *NumBytes) > BlockSize ) ) {
DEBUG ((EFI_D_ERROR, "FvbWrite: ERROR - EFI_BAD_BUFFER_SIZE: (Offset=0x%x + NumBytes=0x%x) > BlockSize=0x%x\n", Offset, *NumBytes, BlockSize ));
return EFI_BAD_BUFFER_SIZE;
}
// We must have some bytes to write
if (*NumBytes == 0) {
DEBUG ((EFI_D_ERROR, "FvbWrite: ERROR - EFI_BAD_BUFFER_SIZE: (Offset=0x%x + NumBytes=0x%x) > BlockSize=0x%x\n", Offset, *NumBytes, BlockSize ));
return EFI_BAD_BUFFER_SIZE;
}
// Allocate runtime memory to read in the NOR Flash data.
// Since the intention is to use this with Variable Services and since these are runtime,
// allocate the memory from the runtime pool.
BlockBuffer = AllocateRuntimePool(BlockSize);
// Check we did get some memory
if( BlockBuffer == NULL ) {
DEBUG ((EFI_D_ERROR, "FvbWrite: ERROR - Can not allocate BlockBuffer @ 0x%08x.\n", BlockBuffer));
return EFI_DEVICE_ERROR;
}
// Read NOR Flash data into shadow buffer
TempStatus = NorFlashReadBlocks(Instance, Lba, BlockSize, BlockBuffer);
if (EFI_ERROR (TempStatus)) {
// Return one of the pre-approved error statuses
Status = EFI_DEVICE_ERROR;
goto FREE_MEMORY;
}
// Put the data at the appropriate location inside the buffer area
CopyMem((BlockBuffer + Offset), Buffer, *NumBytes);
// Write the modified buffer back to the NorFlash
Status = NorFlashWriteBlocks(Instance, Lba, BlockSize, BlockBuffer);
if (EFI_ERROR (TempStatus)) {
// Return one of the pre-approved error statuses
Status = EFI_DEVICE_ERROR;
goto FREE_MEMORY;
}
FREE_MEMORY:
FreePool(BlockBuffer);
return Status;
}
/**
Erases and initialises a firmware volume block.
The EraseBlocks() function erases one or more blocks as denoted
by the variable argument list. The entire parameter list of
blocks must be verified before erasing any blocks. If a block is
requested that does not exist within the associated firmware
volume (it has a larger index than the last block of the
firmware volume), the EraseBlocks() function must return the
status code EFI_INVALID_PARAMETER without modifying the contents
of the firmware volume. Implementations should be mindful that
the firmware volume might be in the WriteDisabled state. If it
is in this state, the EraseBlocks() function must return the
status code EFI_ACCESS_DENIED without modifying the contents of
the firmware volume. All calls to EraseBlocks() must be fully
flushed to the hardware before the EraseBlocks() service
returns.
@param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL
instance.
@param ... The variable argument list is a list of tuples.
Each tuple describes a range of LBAs to erase
and consists of the following:
- An EFI_LBA that indicates the starting LBA
- A UINTN that indicates the number of blocks to erase.
The list is terminated with an EFI_LBA_LIST_TERMINATOR.
For example, the following indicates that two ranges of blocks
(5-7 and 10-11) are to be erased:
EraseBlocks (This, 5, 3, 10, 2, EFI_LBA_LIST_TERMINATOR);
@retval EFI_SUCCESS The erase request successfully completed.
@retval EFI_ACCESS_DENIED The firmware volume is in the WriteDisabled state.
@retval EFI_DEVICE_ERROR The block device is not functioning correctly and could not be written.
The firmware device may have been partially erased.
@retval EFI_INVALID_PARAMETER One or more of the LBAs listed in the variable argument list do
not exist in the firmware volume.
**/
EFI_STATUS
EFIAPI
FvbEraseBlocks(
IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,
...
)
{
EFI_STATUS Status;
VA_LIST args;
UINTN BlockAddress; // Physical address of Lba to erase
EFI_LBA StartingLba; // Lba from which we start erasing
UINTN NumOfLba; // Number of Lba blocks to erase
NOR_FLASH_INSTANCE *Instance;
Instance = INSTANCE_FROM_FVB_THIS(This);
DEBUG ((DEBUG_BLKIO, "FvbEraseBlocks()\n"));
Status = EFI_SUCCESS;
// Detect WriteDisabled state
if (Instance->Media.ReadOnly == TRUE) {
// Firmware volume is in WriteDisabled state
DEBUG ((EFI_D_ERROR, "FvbEraseBlocks: ERROR - Device is in WriteDisabled state.\n"));
return EFI_ACCESS_DENIED;
}
// Before erasing, check the entire list of parameters to ensure all specified blocks are valid
VA_START (args, This);
do {
// Get the Lba from which we start erasing
StartingLba = VA_ARG (args, EFI_LBA);
// Have we reached the end of the list?
if (StartingLba == EFI_LBA_LIST_TERMINATOR) {
//Exit the while loop
break;
}
// How many Lba blocks are we requested to erase?
NumOfLba = VA_ARG (args, UINT32);
// All blocks must be within range
DEBUG ((DEBUG_BLKIO, "FvbEraseBlocks: Check if: ( StartingLba=%ld + NumOfLba=%d - 1 ) > LastBlock=%ld.\n", StartingLba, NumOfLba, Instance->Media.LastBlock));
if ((NumOfLba == 0) || ((StartingLba + NumOfLba - 1) > Instance->Media.LastBlock)) {
VA_END (args);
DEBUG ((DEBUG_BLKIO, "FvbEraseBlocks: Check if: ( StartingLba=%ld + NumOfLba=%d - 1 ) > LastBlock=%ld.\n", StartingLba, NumOfLba, Instance->Media.LastBlock));
DEBUG ((EFI_D_ERROR, "FvbEraseBlocks: ERROR - Lba range goes past the last Lba.\n"));
Status = EFI_INVALID_PARAMETER;
goto EXIT;
}
} while (TRUE);
VA_END (args);
// To get here, all must be ok, so start erasing
VA_START (args, This);
do {
// Get the Lba from which we start erasing
StartingLba = VA_ARG (args, EFI_LBA);
// Have we reached the end of the list?
if (StartingLba == EFI_LBA_LIST_TERMINATOR) {
// Exit the while loop
break;
}
// How many Lba blocks are we requested to erase?
NumOfLba = VA_ARG (args, UINT32);
// Go through each one and erase it
while (NumOfLba > 0) {
// Get the physical address of Lba to erase
BlockAddress = GET_NOR_BLOCK_ADDRESS(
Instance->BaseAddress,
StartingLba,
Instance->Media.BlockSize
);
// Erase it
DEBUG ((DEBUG_BLKIO, "FvbEraseBlocks: Erasing Lba=%ld @ 0x%08x.\n", StartingLba, BlockAddress));
Status = NorFlashUnlockAndEraseSingleBlock(BlockAddress);
if (EFI_ERROR(Status)) {
VA_END (args);
Status = EFI_DEVICE_ERROR;
goto EXIT;
}
// Move to the next Lba
StartingLba++;
NumOfLba--;
}
} while (TRUE);
VA_END (args);
EXIT:
return Status;
}
EFI_STATUS
EFIAPI
NorFlashFvbInitialize (
IN NOR_FLASH_INSTANCE* Instance
) {
EFI_STATUS Status;
DEBUG((DEBUG_BLKIO,"NorFlashFvbInitialize\n"));
Status = NorFlashBlkIoInitialize(Instance);
if (EFI_ERROR(Status)) {
DEBUG((EFI_D_ERROR,"NorFlashFvbInitialize: ERROR - Failed to initialize FVB\n"));
return Status;
}
Instance->Initialized = TRUE;
// Determine if there is a valid header at the beginning of the NorFlash
Status = ValidateFvHeader (Instance);
if (EFI_ERROR(Status)) {
// There is no valid header, so time to install one.
DEBUG((EFI_D_ERROR,"NorFlashFvbInitialize: ERROR - The FVB Header is not valid. Install a correct one for this volume.\n"));
// Erase all the NorFlash that is reserved for variable storage
Status = FvbEraseBlocks ( &Instance->FvbProtocol, (EFI_LBA)0, (UINT32)(Instance->Media.LastBlock + 1), EFI_LBA_LIST_TERMINATOR );
if (EFI_ERROR(Status)) {
return Status;
}
// Install all appropriate headers
InitializeFvAndVariableStoreHeaders ( Instance );
if (EFI_ERROR(Status)) {
return Status;
}
}
return Status;
}