mirror of
https://github.com/acidanthera/audk.git
synced 2025-07-27 15:44:04 +02:00
Sync up ArmPkg with patch from mailing list. Changed name of BdsLib.h to BdsUnixLib.h and fixed a lot of issues with Xcode building.
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@11293 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
parent
7373d15a98
commit
1bfda055df
@ -44,11 +44,76 @@
|
|||||||
[Protocols.common]
|
[Protocols.common]
|
||||||
gVirtualUncachedPagesProtocolGuid = { 0xAD651C7D, 0x3C22, 0x4DBF, { 0x92, 0xe8, 0x38, 0xa7, 0xcd, 0xae, 0x87, 0xb2 } }
|
gVirtualUncachedPagesProtocolGuid = { 0xAD651C7D, 0x3C22, 0x4DBF, { 0x92, 0xe8, 0x38, 0xa7, 0xcd, 0xae, 0x87, 0xb2 } }
|
||||||
|
|
||||||
|
## Include/Protocol/MmcHost.h
|
||||||
|
gEfiMmcHostProtocolGuid = { 0x3e591c00, 0x9e4a, 0x11df, {0x92, 0x44, 0x00, 0x02, 0xA5, 0xD5, 0xC5, 0x1B }}
|
||||||
|
|
||||||
[PcdsFeatureFlag.common]
|
[PcdsFeatureFlag.common]
|
||||||
gArmTokenSpaceGuid.PcdCpuDxeProduceDebugSupport|FALSE|BOOLEAN|0x00000001
|
gArmTokenSpaceGuid.PcdCpuDxeProduceDebugSupport|FALSE|BOOLEAN|0x00000001
|
||||||
|
|
||||||
|
# On ARM Architecture with the Security Extension, the address for the
|
||||||
|
# Vector Table can be mapped anywhere in the memory map. It means we can
|
||||||
|
# point the Exception Vector Table to its location in CpuDxe.
|
||||||
|
# By default we copy the Vector Table at PcdGet32(PcdCpuVectorBaseAddress)
|
||||||
|
gArmTokenSpaceGuid.PcdRelocateVectorTable|TRUE|BOOLEAN|0x00000022
|
||||||
|
|
||||||
|
gArmTokenSpaceGuid.PcdEfiUncachedMemoryToStronglyOrdered|FALSE|BOOLEAN|0x00000025
|
||||||
|
gArmTokenSpaceGuid.PcdSkipPeiCore|FALSE|BOOLEAN|0x00000026
|
||||||
|
|
||||||
[PcdsFixedAtBuild.common]
|
[PcdsFixedAtBuild.common]
|
||||||
|
# This PCD should be a FeaturePcd. But we used this PCD as an '#if' in an ASM file.
|
||||||
|
# Using a FeaturePcd make a '(BOOLEAN) casting for its value which is not understood by the preprocessor.
|
||||||
|
gArmTokenSpaceGuid.PcdVFPEnabled|0|UINT32|0x00000024
|
||||||
|
|
||||||
gArmTokenSpaceGuid.PcdArmUncachedMemoryMask|0x0000000080000000|UINT64|0x00000002
|
gArmTokenSpaceGuid.PcdArmUncachedMemoryMask|0x0000000080000000|UINT64|0x00000002
|
||||||
gArmTokenSpaceGuid.PcdArmCacheOperationThreshold|1024|UINT32|0x00000003
|
gArmTokenSpaceGuid.PcdArmCacheOperationThreshold|1024|UINT32|0x00000003
|
||||||
gArmTokenSpaceGuid.PcdCpuVectorBaseAddress|0xfff00000|UINT32|0x00000004
|
gArmTokenSpaceGuid.PcdCpuVectorBaseAddress|0xfff00000|UINT32|0x00000004
|
||||||
gArmTokenSpaceGuid.PcdCpuResetAddress|0x00000000|UINT32|0x00000005
|
gArmTokenSpaceGuid.PcdCpuResetAddress|0x00000000|UINT32|0x00000005
|
||||||
|
|
||||||
|
#
|
||||||
|
# ARM PL180 MCI
|
||||||
|
#
|
||||||
|
gArmTokenSpaceGuid.PcdPL180SysMciRegAddress|0x00000000|UINT32|0x00000006
|
||||||
|
gArmTokenSpaceGuid.PcdPL180MciBaseAddress|0x00000000|UINT32|0x00000007
|
||||||
|
|
||||||
|
#
|
||||||
|
# ARM PL390 General Interrupt Controller
|
||||||
|
#
|
||||||
|
gArmTokenSpaceGuid.PcdGicDistributorBase|0|UINT32|0x0000000C
|
||||||
|
gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase|0|UINT32|0x0000000D
|
||||||
|
gArmTokenSpaceGuid.PcdGicNumInterrupts|96|UINT32|0x00000023
|
||||||
|
|
||||||
|
#
|
||||||
|
# ARM Secure SEC PCDs
|
||||||
|
#
|
||||||
|
gArmTokenSpaceGuid.PcdSecureFdBaseAddress|0|UINT32|0x00000015
|
||||||
|
gArmTokenSpaceGuid.PcdSecureFdSize|0|UINT32|0x00000016
|
||||||
|
|
||||||
|
#
|
||||||
|
# ARM MPCore MailBox PCDs
|
||||||
|
#
|
||||||
|
# Address to Set/Get to Mailbox in Multicore system
|
||||||
|
gArmTokenSpaceGuid.PcdMPCoreMailboxSetAddress|0|UINT32|0x00000017
|
||||||
|
gArmTokenSpaceGuid.PcdMPCoreMailboxGetAddress|0|UINT32|0x00000018
|
||||||
|
# Address/Value to clear Mailbox in Multicore system
|
||||||
|
gArmTokenSpaceGuid.PcdMPCoreMailboxClearAddress|0|UINT32|0x00000019
|
||||||
|
gArmTokenSpaceGuid.PcdMPCoreMailboxClearValue|0|UINT32|0x0000001A
|
||||||
|
|
||||||
|
#
|
||||||
|
# ARM L2x0 PCDs
|
||||||
|
#
|
||||||
|
gArmTokenSpaceGuid.PcdL2x0ControllerBase|0|UINT32|0x0000001B
|
||||||
|
|
||||||
|
#
|
||||||
|
# ARM PL390 General Interrupt Controller
|
||||||
|
#
|
||||||
|
gArmTokenSpaceGuid.PcdGicDistributorBase|0|UINT32|0x0000001C
|
||||||
|
gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase|0|UINT32|0x0000001D
|
||||||
|
|
||||||
|
#
|
||||||
|
# BdsLib
|
||||||
|
#
|
||||||
|
gArmTokenSpaceGuid.PcdArmMachineType|0|UINT32|0x0000001E
|
||||||
|
gArmTokenSpaceGuid.PcdLinuxKernelDP|L""|VOID*|0x0000001F
|
||||||
|
gArmTokenSpaceGuid.PcdLinuxAtag|""|VOID*|0x00000020
|
||||||
|
gArmTokenSpaceGuid.PcdFdtDP|L""|VOID*|0x00000021
|
||||||
|
|
||||||
|
@ -67,6 +67,24 @@
|
|||||||
CpuLib|MdePkg/Library/BaseCpuLib/BaseCpuLib.inf
|
CpuLib|MdePkg/Library/BaseCpuLib/BaseCpuLib.inf
|
||||||
ArmDisassemblerLib|ArmPkg/Library/ArmDisassemblerLib/ArmDisassemblerLib.inf
|
ArmDisassemblerLib|ArmPkg/Library/ArmDisassemblerLib/ArmDisassemblerLib.inf
|
||||||
DmaLib|ArmPkg/Library/ArmDmaLib/ArmDmaLib.inf
|
DmaLib|ArmPkg/Library/ArmDmaLib/ArmDmaLib.inf
|
||||||
|
ArmTrustZoneLib|ArmPkg/Library/ArmTrustZoneLib/ArmTrustZoneLib.inf
|
||||||
|
ArmMPCoreMailBoxLib|ArmPkg/Library/ArmMPCoreMailBoxLib/ArmMPCoreMailBoxLib.inf
|
||||||
|
|
||||||
|
PL354SmcSecLib|ArmPkg/Drivers/PL35xSmc/PL354SmcSec.inf
|
||||||
|
PL341DmcLib|ArmPkg/Drivers/PL34xDmc/PL341Dmc.inf
|
||||||
|
PL301AxiLib|ArmPkg/Drivers/PL301Axi/PL301Axi.inf
|
||||||
|
PL310L2CacheSecLib|ArmPkg/Drivers/PL310L2Cache/PL310L2CacheSec.inf
|
||||||
|
|
||||||
|
BdsLib|ArmPkg/Library/BdsLib/BdsLib.inf
|
||||||
|
|
||||||
|
IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf
|
||||||
|
|
||||||
|
[LibraryClasses.common.PEIM]
|
||||||
|
HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
|
||||||
|
PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf
|
||||||
|
MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf
|
||||||
|
PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf
|
||||||
|
PeiServicesTablePointerLib|MdePkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointerLib.inf
|
||||||
|
|
||||||
[LibraryClasses.ARM]
|
[LibraryClasses.ARM]
|
||||||
NULL|ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf
|
NULL|ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf
|
||||||
@ -74,22 +92,47 @@
|
|||||||
|
|
||||||
[Components.common]
|
[Components.common]
|
||||||
ArmPkg/Library/ArmCacheMaintenanceLib/ArmCacheMaintenanceLib.inf
|
ArmPkg/Library/ArmCacheMaintenanceLib/ArmCacheMaintenanceLib.inf
|
||||||
## ArmPkg/Library/ArmLib/Arm11/Arm11ArmLib.inf
|
ArmPkg/Library/ArmDisassemblerLib/ArmDisassemblerLib.inf
|
||||||
## ArmPkg/Library/ArmLib/Arm11/Arm11ArmLibPrePi.inf
|
ArmPkg/Library/ArmDmaLib/ArmDmaLib.inf
|
||||||
## ArmPkg/Library/ArmLib/Arm9/Arm9ArmLib.inf
|
ArmPkg/Library/ArmLib/Arm11/Arm11ArmLib.inf
|
||||||
## ArmPkg/Library/ArmLib/Arm9/Arm9ArmLibPrePi.inf
|
ArmPkg/Library/ArmLib/Arm11/Arm11ArmLibPrePi.inf
|
||||||
|
ArmPkg/Library/ArmLib/Arm9/Arm9ArmLib.inf
|
||||||
|
ArmPkg/Library/ArmLib/Arm9/Arm9ArmLibPrePi.inf
|
||||||
ArmPkg/Library/ArmLib/ArmV7/ArmV7Lib.inf
|
ArmPkg/Library/ArmLib/ArmV7/ArmV7Lib.inf
|
||||||
ArmPkg/Library/ArmLib/ArmV7/ArmV7LibPrePi.inf
|
ArmPkg/Library/ArmLib/ArmV7/ArmV7LibPrePi.inf
|
||||||
|
ArmPkg/Library/ArmLib/ArmV7/ArmV7LibSec.inf
|
||||||
|
ArmPkg/Library/ArmLib/ArmV7/ArmV7MPCoreLib.inf
|
||||||
|
ArmPkg/Library/ArmLib/ArmV7/ArmV7MPCoreLibPrePi.inf
|
||||||
|
ArmPkg/Library/ArmLib/ArmV7/ArmV7MPCoreLibSec.inf
|
||||||
ArmPkg/Library/ArmLib/Null/NullArmLib.inf
|
ArmPkg/Library/ArmLib/Null/NullArmLib.inf
|
||||||
|
ArmPkg/Library/ArmMPCoreMailBoxLib/ArmMPCoreMailBoxLib.inf
|
||||||
|
ArmPkg/Library/ArmTrustZoneLib/ArmTrustZoneLib.inf
|
||||||
|
ArmPkg/Library/BaseMemoryLibStm/BaseMemoryLibStm.inf
|
||||||
|
ArmPkg/Library/BaseMemoryLibVstm/BaseMemoryLibVstm.inf
|
||||||
|
ArmPkg/Library/BasePeCoffLib/BasePeCoffLib.inf
|
||||||
|
ArmPkg/Library/BdsLib/BdsLib.inf
|
||||||
ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf
|
ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf
|
||||||
|
ArmPkg/Library/DebugPeCoffExtraActionLib/DebugPeCoffExtraActionLib.inf
|
||||||
|
ArmPkg/Library/DebugUncachedMemoryAllocationLib/DebugUncachedMemoryAllocationLib.inf
|
||||||
|
ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandlerLib.inf
|
||||||
|
ArmPkg/Library/L2X0CacheLibNull/L2X0CacheLibNull.inf
|
||||||
|
ArmPkg/Library/RvdPeCoffExtraActionLib/RvdPeCoffExtraActionLib.inf
|
||||||
ArmPkg/Library/SemiHostingDebugLib/SemiHostingDebugLib.inf
|
ArmPkg/Library/SemiHostingDebugLib/SemiHostingDebugLib.inf
|
||||||
ArmPkg/Library/SemiHostingSerialPortLib/SemiHostingSerialPortLib.inf
|
ArmPkg/Library/SemiHostingSerialPortLib/SemiHostingSerialPortLib.inf
|
||||||
ArmPkg/Library/SemihostLib/SemihostLib.inf
|
ArmPkg/Library/SemihostLib/SemihostLib.inf
|
||||||
ArmPkg/Library/UncachedMemoryAllocationLib/UncachedMemoryAllocationLib.inf
|
ArmPkg/Library/UncachedMemoryAllocationLib/UncachedMemoryAllocationLib.inf
|
||||||
ArmPkg/Library/DebugUncachedMemoryAllocationLib/DebugUncachedMemoryAllocationLib.inf
|
|
||||||
ArmPkg/Library/RvdPeCoffExtraActionLib/RvdPeCoffExtraActionLib.inf
|
|
||||||
ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandlerLib.inf
|
|
||||||
ArmPkg/Library/ArmDmaLib/ArmDmaLib.inf
|
|
||||||
|
|
||||||
ArmPkg/Drivers/CpuDxe/CpuDxe.inf
|
ArmPkg/Drivers/CpuDxe/CpuDxe.inf
|
||||||
|
ArmPkg/Drivers/CpuPei/CpuPei.inf
|
||||||
|
ArmPkg/Drivers/PL180MciDxe/PL180MciDxe.inf
|
||||||
|
ArmPkg/Drivers/PL301Axi/PL301Axi.inf
|
||||||
|
ArmPkg/Drivers/PL310L2Cache/PL310L2CacheSec.inf
|
||||||
|
ArmPkg/Drivers/PL34xDmc/PL341Dmc.inf
|
||||||
|
ArmPkg/Drivers/PL35xSmc/PL354SmcSec.inf
|
||||||
|
ArmPkg/Drivers/PL390Gic/PL390GicDxe.inf
|
||||||
|
ArmPkg/Drivers/PL390Gic/PL390GicNonSec.inf
|
||||||
|
ArmPkg/Drivers/PL390Gic/PL390GicSec.inf
|
||||||
ArmPkg/Filesystem/SemihostFs/SemihostFs.inf
|
ArmPkg/Filesystem/SemihostFs/SemihostFs.inf
|
||||||
|
ArmPkg/Universal/MmcDxe/MmcDxe.inf
|
||||||
|
|
||||||
|
|
||||||
|
@ -67,10 +67,13 @@
|
|||||||
gEfiDebugImageInfoTableGuid
|
gEfiDebugImageInfoTableGuid
|
||||||
|
|
||||||
[Pcd.common]
|
[Pcd.common]
|
||||||
|
gArmTokenSpaceGuid.PcdVFPEnabled
|
||||||
gArmTokenSpaceGuid.PcdCpuVectorBaseAddress
|
gArmTokenSpaceGuid.PcdCpuVectorBaseAddress
|
||||||
|
|
||||||
[FeaturePcd.common]
|
[FeaturePcd.common]
|
||||||
gArmTokenSpaceGuid.PcdCpuDxeProduceDebugSupport
|
gArmTokenSpaceGuid.PcdCpuDxeProduceDebugSupport
|
||||||
|
gArmTokenSpaceGuid.PcdRelocateVectorTable
|
||||||
|
gArmTokenSpaceGuid.PcdEfiUncachedMemoryToStronglyOrdered
|
||||||
|
|
||||||
[depex]
|
[depex]
|
||||||
gHardwareInterruptProtocolGuid
|
gHardwareInterruptProtocolGuid
|
||||||
|
@ -14,6 +14,8 @@
|
|||||||
|
|
||||||
#include "CpuDxe.h"
|
#include "CpuDxe.h"
|
||||||
|
|
||||||
|
//FIXME: Will not compile on non-ARMv7 builds
|
||||||
|
#include <Chipset/ArmV7.h>
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
ExceptionHandlersStart (
|
ExceptionHandlersStart (
|
||||||
@ -127,6 +129,7 @@ InitializeExceptions (
|
|||||||
EFI_PHYSICAL_ADDRESS Base;
|
EFI_PHYSICAL_ADDRESS Base;
|
||||||
UINT32 *VectorBase;
|
UINT32 *VectorBase;
|
||||||
|
|
||||||
|
Status = EFI_SUCCESS;
|
||||||
//
|
//
|
||||||
// Disable interrupts
|
// Disable interrupts
|
||||||
//
|
//
|
||||||
@ -140,6 +143,7 @@ InitializeExceptions (
|
|||||||
FiqEnabled = ArmGetFiqState ();
|
FiqEnabled = ArmGetFiqState ();
|
||||||
ArmDisableFiq ();
|
ArmDisableFiq ();
|
||||||
|
|
||||||
|
if (FeaturePcdGet(PcdRelocateVectorTable) == TRUE) {
|
||||||
//
|
//
|
||||||
// Copy an implementation of the ARM exception vectors to PcdCpuVectorBaseAddress.
|
// Copy an implementation of the ARM exception vectors to PcdCpuVectorBaseAddress.
|
||||||
//
|
//
|
||||||
@ -188,6 +192,14 @@ InitializeExceptions (
|
|||||||
// Flush Caches since we updated executable stuff
|
// Flush Caches since we updated executable stuff
|
||||||
InvalidateInstructionCacheRange ((VOID *)PcdGet32(PcdCpuVectorBaseAddress), Length);
|
InvalidateInstructionCacheRange ((VOID *)PcdGet32(PcdCpuVectorBaseAddress), Length);
|
||||||
|
|
||||||
|
//Note: On ARM processor with the Security Extension, the Vector Table can be located anywhere in the memory.
|
||||||
|
// The Vector Base Address Register defines the location
|
||||||
|
ArmWriteVBar(PcdGet32(PcdCpuVectorBaseAddress));
|
||||||
|
} else {
|
||||||
|
// We do not copy the Exception Table at PcdGet32(PcdCpuVectorBaseAddress). We just set Vector Base Address to point into CpuDxe code.
|
||||||
|
ArmWriteVBar((UINT32)ExceptionHandlersStart);
|
||||||
|
}
|
||||||
|
|
||||||
if (FiqEnabled) {
|
if (FiqEnabled) {
|
||||||
ArmEnableFiq ();
|
ArmEnableFiq ();
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,8 @@
|
|||||||
#
|
#
|
||||||
#------------------------------------------------------------------------------
|
#------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include <Library/PcdLib.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
This is the stack constructed by the exception handler (low address to high address)
|
This is the stack constructed by the exception handler (low address to high address)
|
||||||
@ -50,22 +52,17 @@ This is the stack constructed by the exception handler (low address to high addr
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
.globl ASM_PFX(ExceptionHandlersStart)
|
GCC_ASM_EXPORT(ExceptionHandlersStart)
|
||||||
INTERWORK_FUNC(ExceptionHandlersStart)
|
GCC_ASM_EXPORT(ExceptionHandlersEnd)
|
||||||
.globl ASM_PFX(ExceptionHandlersEnd)
|
GCC_ASM_EXPORT(CommonExceptionEntry)
|
||||||
INTERWORK_FUNC(ExceptionHandlersEnd)
|
GCC_ASM_EXPORT(AsmCommonExceptionEntry)
|
||||||
.globl ASM_PFX(CommonExceptionEntry)
|
GCC_ASM_EXPORT(CommonCExceptionHandler)
|
||||||
INTERWORK_FUNC(CommonExceptionEntry)
|
|
||||||
.globl ASM_PFX(AsmCommonExceptionEntry)
|
|
||||||
INTERWORK_FUNC(AsmCommonExceptionEntry)
|
|
||||||
.globl ASM_PFX(CommonCExceptionHandler)
|
|
||||||
INTERWORK_FUNC(CommonCExceptionHandler)
|
|
||||||
|
|
||||||
.text
|
.text
|
||||||
#if !defined(__APPLE__)
|
#if !defined(__APPLE__)
|
||||||
.fpu neon @ makes vpush/vpop assemble
|
.fpu neon @ makes vpush/vpop assemble
|
||||||
#endif
|
#endif
|
||||||
.align 3
|
.align 5
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -198,10 +195,7 @@ ASM_PFX(FiqEntry):
|
|||||||
// This gets patched by the C code that patches in the vector table
|
// This gets patched by the C code that patches in the vector table
|
||||||
//
|
//
|
||||||
ASM_PFX(CommonExceptionEntry):
|
ASM_PFX(CommonExceptionEntry):
|
||||||
.byte 0x12
|
.word ASM_PFX(AsmCommonExceptionEntry)
|
||||||
.byte 0x34
|
|
||||||
.byte 0x56
|
|
||||||
.byte 0x78
|
|
||||||
|
|
||||||
ASM_PFX(ExceptionHandlersEnd):
|
ASM_PFX(ExceptionHandlersEnd):
|
||||||
|
|
||||||
@ -254,8 +248,9 @@ NoAdjustNeeded:
|
|||||||
@ R0 is ExceptionType
|
@ R0 is ExceptionType
|
||||||
mov R1,SP @ R1 is SystemContext
|
mov R1,SP @ R1 is SystemContext
|
||||||
|
|
||||||
|
#if (FixedPcdGet32(PcdVFPEnabled))
|
||||||
vpush {d0-d15} @ save vstm registers in case they are used in optimizations
|
vpush {d0-d15} @ save vstm registers in case they are used in optimizations
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
VOID
|
VOID
|
||||||
@ -268,7 +263,9 @@ CommonCExceptionHandler (
|
|||||||
*/
|
*/
|
||||||
blx ASM_PFX(CommonCExceptionHandler) @ Call exception handler
|
blx ASM_PFX(CommonCExceptionHandler) @ Call exception handler
|
||||||
|
|
||||||
|
#if (FixedPcdGet32(PcdVFPEnabled))
|
||||||
vpop {d0-d15}
|
vpop {d0-d15}
|
||||||
|
#endif
|
||||||
|
|
||||||
ldr R1, [SP, #0x4c] @ Restore EFI_SYSTEM_CONTEXT_ARM.IFSR
|
ldr R1, [SP, #0x4c] @ Restore EFI_SYSTEM_CONTEXT_ARM.IFSR
|
||||||
mcr p15, 0, R1, c5, c0, 1 @ Write IFSR
|
mcr p15, 0, R1, c5, c0, 1 @ Write IFSR
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
//
|
//
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include <Library/PcdLib.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
@ -61,6 +61,8 @@ This is the stack constructed by the exception handler (low address to high addr
|
|||||||
PRESERVE8
|
PRESERVE8
|
||||||
AREA DxeExceptionHandlers, CODE, READONLY
|
AREA DxeExceptionHandlers, CODE, READONLY
|
||||||
|
|
||||||
|
ALIGN 32
|
||||||
|
|
||||||
//
|
//
|
||||||
// This code gets copied to the ARM vector table
|
// This code gets copied to the ARM vector table
|
||||||
// ExceptionHandlersStart - ExceptionHandlersEnd gets copied
|
// ExceptionHandlersStart - ExceptionHandlersEnd gets copied
|
||||||
@ -190,7 +192,7 @@ FiqEntry
|
|||||||
// This gets patched by the C code that patches in the vector table
|
// This gets patched by the C code that patches in the vector table
|
||||||
//
|
//
|
||||||
CommonExceptionEntry
|
CommonExceptionEntry
|
||||||
dcd 0x12345678
|
dcd AsmCommonExceptionEntry
|
||||||
|
|
||||||
ExceptionHandlersEnd
|
ExceptionHandlersEnd
|
||||||
|
|
||||||
@ -243,7 +245,9 @@ NoAdjustNeeded
|
|||||||
; R0 is ExceptionType
|
; R0 is ExceptionType
|
||||||
mov R1,SP ; R1 is SystemContext
|
mov R1,SP ; R1 is SystemContext
|
||||||
|
|
||||||
|
#if (FixedPcdGet32(PcdVFPEnabled))
|
||||||
vpush {d0-d15} ; save vstm registers in case they are used in optimizations
|
vpush {d0-d15} ; save vstm registers in case they are used in optimizations
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
VOID
|
VOID
|
||||||
@ -256,7 +260,9 @@ CommonCExceptionHandler (
|
|||||||
*/
|
*/
|
||||||
blx CommonCExceptionHandler ; Call exception handler
|
blx CommonCExceptionHandler ; Call exception handler
|
||||||
|
|
||||||
|
#if (FixedPcdGet32(PcdVFPEnabled))
|
||||||
vpop {d0-d15}
|
vpop {d0-d15}
|
||||||
|
#endif
|
||||||
|
|
||||||
ldr R1, [SP, #0x4c] ; Restore EFI_SYSTEM_CONTEXT_ARM.IFSR
|
ldr R1, [SP, #0x4c] ; Restore EFI_SYSTEM_CONTEXT_ARM.IFSR
|
||||||
mcr p15, 0, R1, c5, c0, 1 ; Write IFSR
|
mcr p15, 0, R1, c5, c0, 1 ; Write IFSR
|
||||||
|
@ -15,11 +15,11 @@
|
|||||||
.text
|
.text
|
||||||
.align 3
|
.align 3
|
||||||
|
|
||||||
.globl ASM_PFX(ExceptionHandlersStart)
|
GCC_ASM_EXPORT(ExceptionHandlersStart)
|
||||||
.globl ASM_PFX(ExceptionHandlersEnd)
|
GCC_ASM_EXPORT(ExceptionHandlersEnd)
|
||||||
.globl ASM_PFX(CommonExceptionEntry)
|
GCC_ASM_EXPORT(CommonExceptionEntry)
|
||||||
.globl ASM_PFX(AsmCommonExceptionEntry)
|
GCC_ASM_EXPORT(AsmCommonExceptionEntry)
|
||||||
.globl ASM_PFX(CommonCExceptionHandler)
|
GCC_ASM_EXPORT(CommonCExceptionHandler)
|
||||||
|
|
||||||
ASM_PFX(ExceptionHandlersStart):
|
ASM_PFX(ExceptionHandlersStart):
|
||||||
|
|
||||||
|
@ -15,129 +15,15 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|||||||
--*/
|
--*/
|
||||||
|
|
||||||
#include "CpuDxe.h"
|
#include "CpuDxe.h"
|
||||||
|
//FIXME: Remove this ARMv7 specific header
|
||||||
|
#include <Chipset/ArmV7.h>
|
||||||
//
|
|
||||||
// Translation/page table definitions
|
|
||||||
//
|
|
||||||
|
|
||||||
// First Level Descriptors
|
// First Level Descriptors
|
||||||
typedef UINT32 ARM_FIRST_LEVEL_DESCRIPTOR;
|
typedef UINT32 ARM_FIRST_LEVEL_DESCRIPTOR;
|
||||||
|
|
||||||
// memory space covered by a first level descriptor
|
|
||||||
#define ARM_PAGE_DESC_ENTRY_MVA_SIZE 0x00100000 // 1MB
|
|
||||||
|
|
||||||
// number of first level descriptors to cover entire 32-bit memory space
|
|
||||||
#define FIRST_LEVEL_ENTRY_COUNT (0xFFFFFFFF / ARM_PAGE_DESC_ENTRY_MVA_SIZE + 1)
|
|
||||||
|
|
||||||
|
|
||||||
// page table 1st level descriptor entries
|
|
||||||
#define ARM_PAGE_DESC_BASE_MASK 0xFFFFFC00
|
|
||||||
#define ARM_PAGE_DESC_BASE_SHFIT 10
|
|
||||||
#define ARM_PAGE_DESC_DOMAIN_MASK 0x000001E0
|
|
||||||
#define ARM_PAGE_DESC_DOMAIN_SHIFT 5
|
|
||||||
#define ARM_PAGE_DESC_NS 0x00000008
|
|
||||||
|
|
||||||
#define ARM_FIRST_LEVEL_DESC_ALIGN 0x00004000 // 16KB
|
|
||||||
|
|
||||||
// section 1st level desriptor entries
|
|
||||||
#define ARM_SECTION_BASE_MASK 0xFFF00000
|
|
||||||
#define ARM_SECTION_BASE_SHIFT 20
|
|
||||||
#define ARM_SECTION_NS 0x00080000
|
|
||||||
#define ARM_SECTION_nG 0x00020000
|
|
||||||
#define ARM_SECTION_S 0x00010000
|
|
||||||
#define ARM_SECTION_AP2 0x00008000
|
|
||||||
#define ARM_SECTION_TEX_MASK 0x00007000
|
|
||||||
#define ARM_SECTION_TEX_SHIFT 12
|
|
||||||
#define ARM_SECTION_AP10_MASK 0x00000C00
|
|
||||||
#define ARM_SECTION_AP10_SHIFT 10
|
|
||||||
#define ARM_SECTION_DOMAIN_MASK 0x000001E0
|
|
||||||
#define ARM_SECTION_DOMAIN_SHIFT 5
|
|
||||||
#define ARM_SECTION_XN 0x00000010
|
|
||||||
#define ARM_SECTION_C 0x00000008
|
|
||||||
#define ARM_SECTION_B 0x00000004
|
|
||||||
|
|
||||||
// section level AP[2:0] definitions
|
|
||||||
#define ARM_SECTION_AP_NO_ACCESS 0 // AP[2:0] = 0
|
|
||||||
#define ARM_SECTION_AP_READ_WRITE ARM_SECTION_AP10_MASK // AP[2:0] = 011
|
|
||||||
#define ARM_SECTION_AP_READ_ONLY (ARM_SECTION_AP2 | ARM_SECTION_AP10_MASK) // AP[2:0] = 111
|
|
||||||
|
|
||||||
// common 1st level descriptor fields
|
|
||||||
#define ARM_DESC_TYPE_MASK 0x00000003
|
|
||||||
|
|
||||||
// descriptor type values
|
|
||||||
#define ARM_DESC_TYPE_FAULT 0x0
|
|
||||||
#define ARM_DESC_TYPE_PAGE_TABLE 0x1
|
|
||||||
#define ARM_DESC_TYPE_SECTION 0x2
|
|
||||||
|
|
||||||
|
|
||||||
// Second Level Descriptors
|
// Second Level Descriptors
|
||||||
typedef UINT32 ARM_PAGE_TABLE_ENTRY;
|
typedef UINT32 ARM_PAGE_TABLE_ENTRY;
|
||||||
|
|
||||||
// small page 2nd level descriptor entries
|
|
||||||
#define ARM_SMALL_PAGE_BASE_MASK 0xFFFFF000
|
|
||||||
#define ARM_SMALL_PAGE_INDEX_MASK 0x000FF000
|
|
||||||
#define ARM_SMALL_PAGE_BASE_SHIFT 12
|
|
||||||
#define ARM_SMALL_PAGE_TEX_MASK 0x000001C0
|
|
||||||
#define ARM_SMALL_PAGE_TEX_SHIFT 6
|
|
||||||
#define ARM_SMALL_PAGE_XN 0x00000001
|
|
||||||
|
|
||||||
// large page 2nd level descriptor entries
|
|
||||||
#define ARM_LARGE_PAGE_BASE_MASK 0xFFFF0000
|
|
||||||
#define ARM_LARGE_PAGE_BASE_SHIFT 16
|
|
||||||
#define ARM_LARGE_PAGE_TEX_MASK 0x00007000
|
|
||||||
#define ARM_LARGE_PAGE_TEX_SHIFT 12
|
|
||||||
#define ARM_LARGE_PAGE_XN 0x00008000
|
|
||||||
|
|
||||||
// common 2nd level desriptor fields
|
|
||||||
#define ARM_PAGE_nG 0x00000800
|
|
||||||
#define ARM_PAGE_S 0x00000400
|
|
||||||
#define ARM_PAGE_AP2 0x00000200
|
|
||||||
#define ARM_PAGE_AP10_MASK 0x00000030
|
|
||||||
#define ARM_PAGE_AP10_SHIFT 4
|
|
||||||
#define ARM_PAGE_C 0x00000008
|
|
||||||
#define ARM_PAGE_B 0x00000004
|
|
||||||
#define ARM_PAGE_DESC_TYPE_MASK 0x00000003
|
|
||||||
|
|
||||||
// descriptor type values
|
|
||||||
#define ARM_PAGE_TYPE_FAULT 0x0
|
|
||||||
#define ARM_PAGE_TYPE_LARGE 0x1
|
|
||||||
#define ARM_PAGE_TYPE_SMALL 0x2
|
|
||||||
#define ARM_PAGE_TYPE_SMALL_XN 0x3
|
|
||||||
|
|
||||||
#define SMALL_PAGE_TABLE_ENTRY_COUNT (ARM_PAGE_DESC_ENTRY_MVA_SIZE / SIZE_4KB)
|
|
||||||
|
|
||||||
|
|
||||||
// Translation Table Base 0 fields
|
|
||||||
#define ARM_TTBR0_BASE_MASK 0xFFFFC000
|
|
||||||
#define ARM_TTBR0_BASE_SHIFT 14
|
|
||||||
#define ARM_TTRB0_NOS 0x00000020
|
|
||||||
|
|
||||||
// define the combination of interesting attributes: cacheability and access permissions
|
|
||||||
#define ARM_SECTION_CACHEABILITY_MASK ( ARM_SECTION_TEX_MASK | ARM_SECTION_C | ARM_SECTION_B )
|
|
||||||
#define ARM_SECTION_RW_PERMISSIONS_MASK ( ARM_SECTION_AP2 | ARM_SECTION_AP10_MASK )
|
|
||||||
#define ARM_DESCRIPTOR_ATTRIBUTES ( ARM_SECTION_CACHEABILITY_MASK | ARM_SECTION_RW_PERMISSIONS_MASK | ARM_SECTION_XN )
|
|
||||||
|
|
||||||
// cacheability values for section entries
|
|
||||||
#define ARM_SECTION_STRONGLY_ORDERED 0
|
|
||||||
#define ARM_SECTION_SHAREABLE_DEVICE ARM_SECTION_B
|
|
||||||
#define ARM_SECTION_WRITE_THROUGH ARM_SECTION_C
|
|
||||||
#define ARM_SECTION_WRITE_BACK_NWA ( ARM_SECTION_C| ARM_SECTION_B )
|
|
||||||
#define ARM_SECTION_NORMAL_UNCACHEABLE ( 0x1 << ARM_SECTION_TEX_SHIFT )
|
|
||||||
#define ARM_SECTION_WRITE_BACK ( ( 0x1 << ARM_SECTION_TEX_SHIFT ) | ARM_SECTION_C | ARM_SECTION_B )
|
|
||||||
#define ARM_SECTION_NONSHAREABLE_DEVICE ( 0x2 << ARM_SECTION_TEX_SHIFT )
|
|
||||||
|
|
||||||
// permissions values for section entries
|
|
||||||
#define ARM_SECTION_NO_ACCESS 0
|
|
||||||
#define ARM_SECTION_PRIV_ACCESS_ONLY ( 0x1 << ARM_SECTION_AP10_SHIFT)
|
|
||||||
#define ARM_SECTION_USER_READ_ONLY ( 0x2 << ARM_SECTION_AP10_SHIFT)
|
|
||||||
#define ARM_SECTION_FULL_ACCESS ( 0x3 << ARM_SECTION_AP10_SHIFT)
|
|
||||||
#define ARM_SECTION_PRIV_READ_ONLY ( ARM_SECTION_AP2 | (0x1 << ARM_SECTION_AP10_SHIFT) )
|
|
||||||
#define ARM_SECTION_READ_ONLY_DEP ( ARM_SECTION_AP2 | (0x2 << ARM_SECTION_AP10_SHIFT) )
|
|
||||||
#define ARM_SECTION_READ_ONLY ( ARM_SECTION_AP2 | (0x3 << ARM_SECTION_AP10_SHIFT) )
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
SectionToGcdAttributes (
|
SectionToGcdAttributes (
|
||||||
IN UINT32 SectionAttributes,
|
IN UINT32 SectionAttributes,
|
||||||
@ -147,26 +33,26 @@ SectionToGcdAttributes (
|
|||||||
*GcdAttributes = 0;
|
*GcdAttributes = 0;
|
||||||
|
|
||||||
// determine cacheability attributes
|
// determine cacheability attributes
|
||||||
switch(SectionAttributes & ARM_SECTION_CACHEABILITY_MASK) {
|
switch(SectionAttributes & TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK) {
|
||||||
case ARM_SECTION_STRONGLY_ORDERED:
|
case TT_DESCRIPTOR_SECTION_CACHE_POLICY_STRONGLY_ORDERED:
|
||||||
*GcdAttributes |= EFI_MEMORY_UC;
|
*GcdAttributes |= EFI_MEMORY_UC;
|
||||||
break;
|
break;
|
||||||
case ARM_SECTION_SHAREABLE_DEVICE:
|
case TT_DESCRIPTOR_SECTION_CACHE_POLICY_SHAREABLE_DEVICE:
|
||||||
*GcdAttributes |= EFI_MEMORY_UC;
|
*GcdAttributes |= EFI_MEMORY_UC;
|
||||||
break;
|
break;
|
||||||
case ARM_SECTION_WRITE_THROUGH:
|
case TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_THROUGH_NO_ALLOC:
|
||||||
*GcdAttributes |= EFI_MEMORY_WT;
|
*GcdAttributes |= EFI_MEMORY_WT;
|
||||||
break;
|
break;
|
||||||
case ARM_SECTION_WRITE_BACK_NWA:
|
case TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_BACK_NO_ALLOC:
|
||||||
*GcdAttributes |= EFI_MEMORY_WB;
|
*GcdAttributes |= EFI_MEMORY_WB;
|
||||||
break;
|
break;
|
||||||
case ARM_SECTION_NORMAL_UNCACHEABLE:
|
case TT_DESCRIPTOR_SECTION_CACHE_POLICY_NON_CACHEABLE:
|
||||||
*GcdAttributes |= EFI_MEMORY_WC;
|
*GcdAttributes |= EFI_MEMORY_WC;
|
||||||
break;
|
break;
|
||||||
case ARM_SECTION_WRITE_BACK:
|
case TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_BACK_ALLOC:
|
||||||
*GcdAttributes |= EFI_MEMORY_WB;
|
*GcdAttributes |= EFI_MEMORY_WB;
|
||||||
break;
|
break;
|
||||||
case ARM_SECTION_NONSHAREABLE_DEVICE:
|
case TT_DESCRIPTOR_SECTION_CACHE_POLICY_NON_SHAREABLE_DEVICE:
|
||||||
*GcdAttributes |= EFI_MEMORY_UC;
|
*GcdAttributes |= EFI_MEMORY_UC;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -174,20 +60,19 @@ SectionToGcdAttributes (
|
|||||||
}
|
}
|
||||||
|
|
||||||
// determine protection attributes
|
// determine protection attributes
|
||||||
switch(SectionAttributes & ARM_SECTION_RW_PERMISSIONS_MASK) {
|
switch(SectionAttributes & TT_DESCRIPTOR_SECTION_AP_MASK) {
|
||||||
case ARM_SECTION_NO_ACCESS: // no read, no write
|
case TT_DESCRIPTOR_SECTION_AP_NO_NO: // no read, no write
|
||||||
//*GcdAttributes |= EFI_MEMORY_WP | EFI_MEMORY_RP;
|
//*GcdAttributes |= EFI_MEMORY_WP | EFI_MEMORY_RP;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ARM_SECTION_PRIV_ACCESS_ONLY:
|
case TT_DESCRIPTOR_SECTION_AP_RW_NO:
|
||||||
case ARM_SECTION_FULL_ACCESS:
|
case TT_DESCRIPTOR_SECTION_AP_RW_RW:
|
||||||
// normal read/write access, do not add additional attributes
|
// normal read/write access, do not add additional attributes
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// read only cases map to write-protect
|
// read only cases map to write-protect
|
||||||
case ARM_SECTION_PRIV_READ_ONLY:
|
case TT_DESCRIPTOR_SECTION_AP_RO_NO:
|
||||||
case ARM_SECTION_READ_ONLY_DEP:
|
case TT_DESCRIPTOR_SECTION_AP_RO_RO:
|
||||||
case ARM_SECTION_READ_ONLY:
|
|
||||||
*GcdAttributes |= EFI_MEMORY_WP;
|
*GcdAttributes |= EFI_MEMORY_WP;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -196,7 +81,7 @@ SectionToGcdAttributes (
|
|||||||
}
|
}
|
||||||
|
|
||||||
// now process eXectue Never attribute
|
// now process eXectue Never attribute
|
||||||
if ((SectionAttributes & ARM_SECTION_XN) != 0 ) {
|
if ((SectionAttributes & TT_DESCRIPTOR_SECTION_XN_MASK) != 0 ) {
|
||||||
*GcdAttributes |= EFI_MEMORY_XP;
|
*GcdAttributes |= EFI_MEMORY_XP;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -369,22 +254,22 @@ SyncCacheConfig (
|
|||||||
// with a way for GCD to query the CPU Arch. driver of the existing memory space attributes instead.
|
// with a way for GCD to query the CPU Arch. driver of the existing memory space attributes instead.
|
||||||
|
|
||||||
// obtain page table base
|
// obtain page table base
|
||||||
FirstLevelTable = (ARM_FIRST_LEVEL_DESCRIPTOR *)(ArmGetTranslationTableBaseAddress ());
|
FirstLevelTable = (ARM_FIRST_LEVEL_DESCRIPTOR *)(ArmGetTTBR0BaseAddress ());
|
||||||
|
|
||||||
|
|
||||||
// iterate through each 1MB descriptor
|
// iterate through each 1MB descriptor
|
||||||
NextRegionBase = NextRegionLength = 0;
|
NextRegionBase = NextRegionLength = 0;
|
||||||
for (i=0; i< FIRST_LEVEL_ENTRY_COUNT; i++) {
|
for (i=0; i< TRANSLATION_TABLE_SECTION_COUNT; i++) {
|
||||||
|
|
||||||
// obtain existing descriptor and make sure it contains a valid Base Address even if it is a fault section
|
// obtain existing descriptor and make sure it contains a valid Base Address even if it is a fault section
|
||||||
Descriptor = FirstLevelTable[i] | (ARM_SECTION_BASE_MASK & (i << ARM_SECTION_BASE_SHIFT));
|
Descriptor = FirstLevelTable[i] | TT_DESCRIPTOR_SECTION_BASE_ADDRESS(i << TT_DESCRIPTOR_SECTION_BASE_SHIFT);
|
||||||
|
|
||||||
// extract attributes (cacheability and permissions)
|
// extract attributes (cacheability and permissions)
|
||||||
SectionAttributes = Descriptor & 0xDEC;
|
SectionAttributes = Descriptor & (TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK | TT_DESCRIPTOR_SECTION_AP_MASK);
|
||||||
|
|
||||||
// do we already have an existing region (or are we about to finish)?
|
// do we already have an existing region (or are we about to finish)?
|
||||||
// Skip the first entry, and make sure we close on the last entry
|
// Skip the first entry, and make sure we close on the last entry
|
||||||
if ( (NextRegionLength > 0) || (i == (FIRST_LEVEL_ENTRY_COUNT-1)) ) {
|
if ( (NextRegionLength > 0) || (i == (TRANSLATION_TABLE_SECTION_COUNT-1)) ) {
|
||||||
// attributes are changing, update attributes in GCD
|
// attributes are changing, update attributes in GCD
|
||||||
if (SectionAttributes != NextRegionAttributes) {
|
if (SectionAttributes != NextRegionAttributes) {
|
||||||
|
|
||||||
@ -398,7 +283,7 @@ SyncCacheConfig (
|
|||||||
|
|
||||||
// start on a new region
|
// start on a new region
|
||||||
NextRegionLength = 0;
|
NextRegionLength = 0;
|
||||||
NextRegionBase = Descriptor & ARM_SECTION_BASE_MASK;
|
NextRegionBase = TT_DESCRIPTOR_SECTION_BASE_ADDRESS(Descriptor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -407,7 +292,7 @@ SyncCacheConfig (
|
|||||||
NextRegionAttributes = SectionAttributes;
|
NextRegionAttributes = SectionAttributes;
|
||||||
}
|
}
|
||||||
|
|
||||||
NextRegionLength += ARM_PAGE_DESC_ENTRY_MVA_SIZE;
|
NextRegionLength += TT_DESCRIPTOR_SECTION_SIZE;
|
||||||
|
|
||||||
} // section entry loop
|
} // section entry loop
|
||||||
|
|
||||||
@ -444,37 +329,42 @@ UpdatePageEntries (
|
|||||||
|
|
||||||
// EntryMask: bitmask of values to change (1 = change this value, 0 = leave alone)
|
// EntryMask: bitmask of values to change (1 = change this value, 0 = leave alone)
|
||||||
// EntryValue: values at bit positions specified by EntryMask
|
// EntryValue: values at bit positions specified by EntryMask
|
||||||
EntryMask = ARM_PAGE_DESC_TYPE_MASK;
|
EntryMask = TT_DESCRIPTOR_PAGE_TYPE_MASK;
|
||||||
EntryValue = ARM_PAGE_TYPE_SMALL;
|
EntryValue = TT_DESCRIPTOR_PAGE_TYPE_PAGE;
|
||||||
// Although the PI spec is unclear on this the GCD guarantees that only
|
// Although the PI spec is unclear on this the GCD guarantees that only
|
||||||
// one Attribute bit is set at a time, so we can safely use a switch statement
|
// one Attribute bit is set at a time, so we can safely use a switch statement
|
||||||
switch (Attributes) {
|
switch (Attributes) {
|
||||||
case EFI_MEMORY_UC:
|
case EFI_MEMORY_UC:
|
||||||
// modify cacheability attributes
|
// modify cacheability attributes
|
||||||
EntryMask |= ARM_SMALL_PAGE_TEX_MASK | ARM_PAGE_C | ARM_PAGE_B;
|
EntryMask |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_MASK;
|
||||||
|
if (FeaturePcdGet(PcdEfiUncachedMemoryToStronglyOrdered)) {
|
||||||
// map to strongly ordered
|
// map to strongly ordered
|
||||||
EntryValue |= 0; // TEX[2:0] = 0, C=0, B=0
|
EntryValue |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_STRONGLY_ORDERED; // TEX[2:0] = 0, C=0, B=0
|
||||||
|
} else {
|
||||||
|
// map to normal non-cachable
|
||||||
|
EntryValue |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_NON_CACHEABLE; // TEX [2:0]= 001 = 0x2, B=0, C=0
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EFI_MEMORY_WC:
|
case EFI_MEMORY_WC:
|
||||||
// modify cacheability attributes
|
// modify cacheability attributes
|
||||||
EntryMask |= ARM_SMALL_PAGE_TEX_MASK | ARM_PAGE_C | ARM_PAGE_B;
|
EntryMask |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_MASK;
|
||||||
// map to normal non-cachable
|
// map to normal non-cachable
|
||||||
EntryValue |= (0x1 << ARM_SMALL_PAGE_TEX_SHIFT); // TEX [2:0]= 001 = 0x2, B=0, C=0
|
EntryValue |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_NON_CACHEABLE; // TEX [2:0]= 001 = 0x2, B=0, C=0
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EFI_MEMORY_WT:
|
case EFI_MEMORY_WT:
|
||||||
// modify cacheability attributes
|
// modify cacheability attributes
|
||||||
EntryMask |= ARM_SMALL_PAGE_TEX_MASK | ARM_PAGE_C | ARM_PAGE_B;
|
EntryMask |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_MASK;
|
||||||
// write through with no-allocate
|
// write through with no-allocate
|
||||||
EntryValue |= ARM_PAGE_C; // TEX [2:0] = 0, C=1, B=0
|
EntryValue |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_WRITE_THROUGH_NO_ALLOC; // TEX [2:0] = 0, C=1, B=0
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EFI_MEMORY_WB:
|
case EFI_MEMORY_WB:
|
||||||
// modify cacheability attributes
|
// modify cacheability attributes
|
||||||
EntryMask |= ARM_SMALL_PAGE_TEX_MASK | ARM_PAGE_C | ARM_PAGE_B;
|
EntryMask |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_MASK;
|
||||||
// write back (with allocate)
|
// write back (with allocate)
|
||||||
EntryValue |= (0x1 << ARM_SMALL_PAGE_TEX_SHIFT) | ARM_PAGE_C | ARM_PAGE_B; // TEX [2:0] = 001, C=1, B=1
|
EntryValue |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_WRITE_BACK_ALLOC; // TEX [2:0] = 001, C=1, B=1
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EFI_MEMORY_WP:
|
case EFI_MEMORY_WP:
|
||||||
@ -482,7 +372,7 @@ UpdatePageEntries (
|
|||||||
case EFI_MEMORY_UCE:
|
case EFI_MEMORY_UCE:
|
||||||
// cannot be implemented UEFI definition unclear for ARM
|
// cannot be implemented UEFI definition unclear for ARM
|
||||||
// Cause a page fault if these ranges are accessed.
|
// Cause a page fault if these ranges are accessed.
|
||||||
EntryValue = ARM_PAGE_TYPE_FAULT;
|
EntryValue = TT_DESCRIPTOR_PAGE_TYPE_FAULT;
|
||||||
DEBUG ((EFI_D_PAGE, "SetMemoryAttributes(): setting page %lx with unsupported attribute %x will page fault on access\n", BaseAddress, Attributes));
|
DEBUG ((EFI_D_PAGE, "SetMemoryAttributes(): setting page %lx with unsupported attribute %x will page fault on access\n", BaseAddress, Attributes));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -491,7 +381,7 @@ UpdatePageEntries (
|
|||||||
}
|
}
|
||||||
|
|
||||||
// obtain page table base
|
// obtain page table base
|
||||||
FirstLevelTable = (ARM_FIRST_LEVEL_DESCRIPTOR *)ArmGetTranslationTableBaseAddress ();
|
FirstLevelTable = (ARM_FIRST_LEVEL_DESCRIPTOR *)ArmGetTTBR0BaseAddress ();
|
||||||
|
|
||||||
// calculate number of 4KB page table entries to change
|
// calculate number of 4KB page table entries to change
|
||||||
NumPageEntries = Length/SIZE_4KB;
|
NumPageEntries = Length/SIZE_4KB;
|
||||||
@ -501,15 +391,15 @@ UpdatePageEntries (
|
|||||||
for(p=0; p<NumPageEntries; p++) {
|
for(p=0; p<NumPageEntries; p++) {
|
||||||
// calculate index into first level translation table for page table value
|
// calculate index into first level translation table for page table value
|
||||||
|
|
||||||
FirstLevelIdx = ((BaseAddress + Offset) & ARM_SECTION_BASE_MASK) >> ARM_SECTION_BASE_SHIFT;
|
FirstLevelIdx = TT_DESCRIPTOR_SECTION_BASE_ADDRESS(BaseAddress + Offset) >> TT_DESCRIPTOR_SECTION_BASE_SHIFT;
|
||||||
ASSERT (FirstLevelIdx < FIRST_LEVEL_ENTRY_COUNT);
|
ASSERT (FirstLevelIdx < TRANSLATION_TABLE_SECTION_COUNT);
|
||||||
|
|
||||||
// read the descriptor from the first level page table
|
// read the descriptor from the first level page table
|
||||||
Descriptor = FirstLevelTable[FirstLevelIdx];
|
Descriptor = FirstLevelTable[FirstLevelIdx];
|
||||||
|
|
||||||
// does this descriptor need to be converted from section entry to 4K pages?
|
// does this descriptor need to be converted from section entry to 4K pages?
|
||||||
if ((Descriptor & ARM_DESC_TYPE_MASK) != ARM_DESC_TYPE_PAGE_TABLE ) {
|
if (!TT_DESCRIPTOR_SECTION_TYPE_IS_PAGE_TABLE(Descriptor)) {
|
||||||
Status = ConvertSectionToPages (FirstLevelIdx << ARM_SECTION_BASE_SHIFT);
|
Status = ConvertSectionToPages (FirstLevelIdx << TT_DESCRIPTOR_SECTION_BASE_SHIFT);
|
||||||
if (EFI_ERROR(Status)) {
|
if (EFI_ERROR(Status)) {
|
||||||
// exit for loop
|
// exit for loop
|
||||||
break;
|
break;
|
||||||
@ -520,11 +410,11 @@ UpdatePageEntries (
|
|||||||
}
|
}
|
||||||
|
|
||||||
// obtain page table base address
|
// obtain page table base address
|
||||||
PageTable = (ARM_PAGE_TABLE_ENTRY *)(Descriptor & ARM_SMALL_PAGE_BASE_MASK);
|
PageTable = (ARM_PAGE_TABLE_ENTRY *)TT_DESCRIPTOR_PAGE_BASE_ADDRESS(Descriptor);
|
||||||
|
|
||||||
// calculate index into the page table
|
// calculate index into the page table
|
||||||
PageTableIndex = ((BaseAddress + Offset) & ARM_SMALL_PAGE_INDEX_MASK) >> ARM_SMALL_PAGE_BASE_SHIFT;
|
PageTableIndex = ((BaseAddress + Offset) & TT_DESCRIPTOR_PAGE_INDEX_MASK) >> TT_DESCRIPTOR_PAGE_BASE_SHIFT;
|
||||||
ASSERT (PageTableIndex < SMALL_PAGE_TABLE_ENTRY_COUNT);
|
ASSERT (PageTableIndex < TRANSLATION_TABLE_PAGE_COUNT);
|
||||||
|
|
||||||
// get the entry
|
// get the entry
|
||||||
CurrentPageTableEntry = PageTable[PageTableIndex];
|
CurrentPageTableEntry = PageTable[PageTableIndex];
|
||||||
@ -541,8 +431,8 @@ UpdatePageEntries (
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (CurrentPageTableEntry != PageTableEntry) {
|
if (CurrentPageTableEntry != PageTableEntry) {
|
||||||
Mva = (VOID *)(UINTN)((((UINTN)FirstLevelIdx) << ARM_SECTION_BASE_SHIFT) + (PageTableIndex << ARM_SMALL_PAGE_BASE_SHIFT));
|
Mva = (VOID *)(UINTN)((((UINTN)FirstLevelIdx) << TT_DESCRIPTOR_SECTION_BASE_SHIFT) + (PageTableIndex << TT_DESCRIPTOR_PAGE_BASE_SHIFT));
|
||||||
if ((CurrentPageTableEntry & ARM_PAGE_C) == ARM_PAGE_C) {
|
if ((CurrentPageTableEntry & TT_DESCRIPTOR_PAGE_CACHEABLE_MASK) == TT_DESCRIPTOR_PAGE_CACHEABLE_MASK) {
|
||||||
// The current section mapping is cacheable so Clean/Invalidate the MVA of the page
|
// The current section mapping is cacheable so Clean/Invalidate the MVA of the page
|
||||||
// Note assumes switch(Attributes), not ARMv7 possibilities
|
// Note assumes switch(Attributes), not ARMv7 possibilities
|
||||||
WriteBackInvalidateDataCacheRange (Mva, SIZE_4KB);
|
WriteBackInvalidateDataCacheRange (Mva, SIZE_4KB);
|
||||||
@ -586,38 +476,43 @@ UpdateSectionEntries (
|
|||||||
// EntryValue: values at bit positions specified by EntryMask
|
// EntryValue: values at bit positions specified by EntryMask
|
||||||
|
|
||||||
// Make sure we handle a section range that is unmapped
|
// Make sure we handle a section range that is unmapped
|
||||||
EntryMask = ARM_DESC_TYPE_MASK;
|
EntryMask = TT_DESCRIPTOR_SECTION_TYPE_MASK;
|
||||||
EntryValue = ARM_DESC_TYPE_SECTION;
|
EntryValue = TT_DESCRIPTOR_SECTION_TYPE_SECTION;
|
||||||
|
|
||||||
// Although the PI spec is unclear on this the GCD guarantees that only
|
// Although the PI spec is unclear on this the GCD guarantees that only
|
||||||
// one Attribute bit is set at a time, so we can safely use a switch statement
|
// one Attribute bit is set at a time, so we can safely use a switch statement
|
||||||
switch(Attributes) {
|
switch(Attributes) {
|
||||||
case EFI_MEMORY_UC:
|
case EFI_MEMORY_UC:
|
||||||
// modify cacheability attributes
|
// modify cacheability attributes
|
||||||
EntryMask |= ARM_SECTION_CACHEABILITY_MASK;
|
EntryMask |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK;
|
||||||
|
if (FeaturePcdGet(PcdEfiUncachedMemoryToStronglyOrdered)) {
|
||||||
// map to strongly ordered
|
// map to strongly ordered
|
||||||
EntryValue |= 0; // TEX[2:0] = 0, C=0, B=0
|
EntryValue |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_STRONGLY_ORDERED; // TEX[2:0] = 0, C=0, B=0
|
||||||
|
} else {
|
||||||
|
// map to normal non-cachable
|
||||||
|
EntryValue |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_NON_CACHEABLE; // TEX [2:0]= 001 = 0x2, B=0, C=0
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EFI_MEMORY_WC:
|
case EFI_MEMORY_WC:
|
||||||
// modify cacheability attributes
|
// modify cacheability attributes
|
||||||
EntryMask |= ARM_SECTION_CACHEABILITY_MASK;
|
EntryMask |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK;
|
||||||
// map to normal non-cachable
|
// map to normal non-cachable
|
||||||
EntryValue |= (0x1 << ARM_SECTION_TEX_SHIFT); // TEX [2:0]= 001 = 0x2, B=0, C=0
|
EntryValue |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_NON_CACHEABLE; // TEX [2:0]= 001 = 0x2, B=0, C=0
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EFI_MEMORY_WT:
|
case EFI_MEMORY_WT:
|
||||||
// modify cacheability attributes
|
// modify cacheability attributes
|
||||||
EntryMask |= ARM_SECTION_CACHEABILITY_MASK;
|
EntryMask |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK;
|
||||||
// write through with no-allocate
|
// write through with no-allocate
|
||||||
EntryValue |= ARM_SECTION_C; // TEX [2:0] = 0, C=1, B=0
|
EntryValue |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_THROUGH_NO_ALLOC; // TEX [2:0] = 0, C=1, B=0
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EFI_MEMORY_WB:
|
case EFI_MEMORY_WB:
|
||||||
// modify cacheability attributes
|
// modify cacheability attributes
|
||||||
EntryMask |= ARM_SECTION_CACHEABILITY_MASK;
|
EntryMask |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK;
|
||||||
// write back (with allocate)
|
// write back (with allocate)
|
||||||
EntryValue |= (0x1 << ARM_SECTION_TEX_SHIFT) | ARM_SECTION_C | ARM_SECTION_B; // TEX [2:0] = 001, C=1, B=1
|
EntryValue |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_BACK_ALLOC; // TEX [2:0] = 001, C=1, B=1
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EFI_MEMORY_WP:
|
case EFI_MEMORY_WP:
|
||||||
@ -626,7 +521,7 @@ UpdateSectionEntries (
|
|||||||
case EFI_MEMORY_UCE:
|
case EFI_MEMORY_UCE:
|
||||||
// cannot be implemented UEFI definition unclear for ARM
|
// cannot be implemented UEFI definition unclear for ARM
|
||||||
// Cause a page fault if these ranges are accessed.
|
// Cause a page fault if these ranges are accessed.
|
||||||
EntryValue = ARM_DESC_TYPE_FAULT;
|
EntryValue = TT_DESCRIPTOR_SECTION_TYPE_FAULT;
|
||||||
DEBUG ((EFI_D_PAGE, "SetMemoryAttributes(): setting section %lx with unsupported attribute %x will page fault on access\n", BaseAddress, Attributes));
|
DEBUG ((EFI_D_PAGE, "SetMemoryAttributes(): setting section %lx with unsupported attribute %x will page fault on access\n", BaseAddress, Attributes));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -636,23 +531,23 @@ UpdateSectionEntries (
|
|||||||
}
|
}
|
||||||
|
|
||||||
// obtain page table base
|
// obtain page table base
|
||||||
FirstLevelTable = (ARM_FIRST_LEVEL_DESCRIPTOR *)ArmGetTranslationTableBaseAddress ();
|
FirstLevelTable = (ARM_FIRST_LEVEL_DESCRIPTOR *)ArmGetTTBR0BaseAddress ();
|
||||||
|
|
||||||
// calculate index into first level translation table for start of modification
|
// calculate index into first level translation table for start of modification
|
||||||
FirstLevelIdx = (BaseAddress & ARM_SECTION_BASE_MASK) >> ARM_SECTION_BASE_SHIFT;
|
FirstLevelIdx = TT_DESCRIPTOR_SECTION_BASE_ADDRESS(BaseAddress) >> TT_DESCRIPTOR_SECTION_BASE_SHIFT;
|
||||||
ASSERT (FirstLevelIdx < FIRST_LEVEL_ENTRY_COUNT);
|
ASSERT (FirstLevelIdx < TRANSLATION_TABLE_SECTION_COUNT);
|
||||||
|
|
||||||
// calculate number of 1MB first level entries this applies to
|
// calculate number of 1MB first level entries this applies to
|
||||||
NumSections = Length / ARM_PAGE_DESC_ENTRY_MVA_SIZE;
|
NumSections = Length / TT_DESCRIPTOR_SECTION_SIZE;
|
||||||
|
|
||||||
// iterate through each descriptor
|
// iterate through each descriptor
|
||||||
for(i=0; i<NumSections; i++) {
|
for(i=0; i<NumSections; i++) {
|
||||||
CurrentDescriptor = FirstLevelTable[FirstLevelIdx + i];
|
CurrentDescriptor = FirstLevelTable[FirstLevelIdx + i];
|
||||||
|
|
||||||
// has this descriptor already been coverted to pages?
|
// has this descriptor already been coverted to pages?
|
||||||
if ((CurrentDescriptor & ARM_DESC_TYPE_MASK) != ARM_DESC_TYPE_PAGE_TABLE ) {
|
if (TT_DESCRIPTOR_SECTION_TYPE_IS_PAGE_TABLE(CurrentDescriptor)) {
|
||||||
// forward this 1MB range to page table function instead
|
// forward this 1MB range to page table function instead
|
||||||
Status = UpdatePageEntries ((FirstLevelIdx + i) << ARM_SECTION_BASE_SHIFT, ARM_PAGE_DESC_ENTRY_MVA_SIZE, Attributes, VirtualMask);
|
Status = UpdatePageEntries ((FirstLevelIdx + i) << TT_DESCRIPTOR_SECTION_BASE_SHIFT, TT_DESCRIPTOR_SECTION_SIZE, Attributes, VirtualMask);
|
||||||
} else {
|
} else {
|
||||||
// still a section entry
|
// still a section entry
|
||||||
|
|
||||||
@ -666,8 +561,8 @@ UpdateSectionEntries (
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (CurrentDescriptor != Descriptor) {
|
if (CurrentDescriptor != Descriptor) {
|
||||||
Mva = (VOID *)(UINTN)(((UINTN)FirstLevelTable) << ARM_SECTION_BASE_SHIFT);
|
Mva = (VOID *)(UINTN)(((UINTN)FirstLevelTable) << TT_DESCRIPTOR_SECTION_BASE_SHIFT);
|
||||||
if ((CurrentDescriptor & ARM_SECTION_C) == ARM_SECTION_C) {
|
if ((CurrentDescriptor & TT_DESCRIPTOR_SECTION_CACHEABLE_MASK) == TT_DESCRIPTOR_SECTION_CACHEABLE_MASK) {
|
||||||
// The current section mapping is cacheable so Clean/Invalidate the MVA of the section
|
// The current section mapping is cacheable so Clean/Invalidate the MVA of the section
|
||||||
// Note assumes switch(Attributes), not ARMv7 possabilities
|
// Note assumes switch(Attributes), not ARMv7 possabilities
|
||||||
WriteBackInvalidateDataCacheRange (Mva, SIZE_1MB);
|
WriteBackInvalidateDataCacheRange (Mva, SIZE_1MB);
|
||||||
@ -704,35 +599,20 @@ ConvertSectionToPages (
|
|||||||
DEBUG ((EFI_D_PAGE, "Converting section at 0x%x to pages\n", (UINTN)BaseAddress));
|
DEBUG ((EFI_D_PAGE, "Converting section at 0x%x to pages\n", (UINTN)BaseAddress));
|
||||||
|
|
||||||
// obtain page table base
|
// obtain page table base
|
||||||
FirstLevelTable = (ARM_FIRST_LEVEL_DESCRIPTOR *)ArmGetTranslationTableBaseAddress ();
|
FirstLevelTable = (ARM_FIRST_LEVEL_DESCRIPTOR *)ArmGetTTBR0BaseAddress ();
|
||||||
|
|
||||||
// calculate index into first level translation table for start of modification
|
// calculate index into first level translation table for start of modification
|
||||||
FirstLevelIdx = (BaseAddress & ARM_SECTION_BASE_MASK) >> ARM_SECTION_BASE_SHIFT;
|
FirstLevelIdx = TT_DESCRIPTOR_SECTION_BASE_ADDRESS(BaseAddress) >> TT_DESCRIPTOR_SECTION_BASE_SHIFT;
|
||||||
ASSERT (FirstLevelIdx < FIRST_LEVEL_ENTRY_COUNT);
|
ASSERT (FirstLevelIdx < TRANSLATION_TABLE_SECTION_COUNT);
|
||||||
|
|
||||||
// get section attributes and convert to page attributes
|
// get section attributes and convert to page attributes
|
||||||
SectionDescriptor = FirstLevelTable[FirstLevelIdx];
|
SectionDescriptor = FirstLevelTable[FirstLevelIdx];
|
||||||
PageDescriptor = ARM_PAGE_TYPE_SMALL;
|
PageDescriptor = TT_DESCRIPTOR_PAGE_TYPE_PAGE;
|
||||||
PageDescriptor |= ((SectionDescriptor & ARM_SECTION_TEX_MASK) >> ARM_SECTION_TEX_SHIFT) << ARM_SMALL_PAGE_TEX_SHIFT;
|
PageDescriptor |= TT_DESCRIPTOR_CONVERT_TO_PAGE_CACHE_POLICY(SectionDescriptor,0);
|
||||||
if ((SectionDescriptor & ARM_SECTION_B) != 0) {
|
PageDescriptor |= TT_DESCRIPTOR_CONVERT_TO_PAGE_AP(SectionDescriptor);
|
||||||
PageDescriptor |= ARM_PAGE_B;
|
PageDescriptor |= TT_DESCRIPTOR_CONVERT_TO_PAGE_XN(SectionDescriptor,0);
|
||||||
}
|
PageDescriptor |= TT_DESCRIPTOR_CONVERT_TO_PAGE_NG(SectionDescriptor);
|
||||||
if ((SectionDescriptor & ARM_SECTION_C) != 0) {
|
PageDescriptor |= TT_DESCRIPTOR_CONVERT_TO_PAGE_S(SectionDescriptor);
|
||||||
PageDescriptor |= ARM_PAGE_C;
|
|
||||||
}
|
|
||||||
PageDescriptor |= ((SectionDescriptor & ARM_SECTION_AP10_MASK) >> ARM_SECTION_AP10_SHIFT) << ARM_PAGE_AP10_SHIFT;
|
|
||||||
if ((SectionDescriptor & ARM_SECTION_AP2) != 0) {
|
|
||||||
PageDescriptor |= ARM_PAGE_AP2;
|
|
||||||
}
|
|
||||||
if ((SectionDescriptor & ARM_SECTION_XN) != 0) {
|
|
||||||
PageDescriptor |= ARM_PAGE_TYPE_SMALL_XN;
|
|
||||||
}
|
|
||||||
if ((SectionDescriptor & ARM_SECTION_nG) != 0) {
|
|
||||||
PageDescriptor |= ARM_PAGE_nG;
|
|
||||||
}
|
|
||||||
if ((SectionDescriptor & ARM_SECTION_S) != 0) {
|
|
||||||
PageDescriptor |= ARM_PAGE_S;
|
|
||||||
}
|
|
||||||
|
|
||||||
// allocate a page table for the 4KB entries (we use up a full page even though we only need 1KB)
|
// allocate a page table for the 4KB entries (we use up a full page even though we only need 1KB)
|
||||||
Status = gBS->AllocatePages (AllocateAnyPages, EfiBootServicesData, 1, &PageTableAddr);
|
Status = gBS->AllocatePages (AllocateAnyPages, EfiBootServicesData, 1, &PageTableAddr);
|
||||||
@ -743,15 +623,15 @@ ConvertSectionToPages (
|
|||||||
PageTable = (volatile ARM_PAGE_TABLE_ENTRY *)(UINTN)PageTableAddr;
|
PageTable = (volatile ARM_PAGE_TABLE_ENTRY *)(UINTN)PageTableAddr;
|
||||||
|
|
||||||
// write the page table entries out
|
// write the page table entries out
|
||||||
for (i=0; i<(ARM_PAGE_DESC_ENTRY_MVA_SIZE/SIZE_4KB); i++) {
|
for (i=0; i < TRANSLATION_TABLE_PAGE_COUNT; i++) {
|
||||||
PageTable[i] = ((BaseAddress + (i << 12)) & ARM_SMALL_PAGE_BASE_MASK) | PageDescriptor;
|
PageTable[i] = TT_DESCRIPTOR_PAGE_BASE_ADDRESS(BaseAddress + (i << 12)) | PageDescriptor;
|
||||||
}
|
}
|
||||||
|
|
||||||
// flush d-cache so descriptors make it back to uncached memory for subsequent table walks
|
// flush d-cache so descriptors make it back to uncached memory for subsequent table walks
|
||||||
WriteBackInvalidateDataCacheRange ((VOID *)(UINTN)PageTableAddr, SIZE_4KB);
|
WriteBackInvalidateDataCacheRange ((VOID *)(UINTN)PageTableAddr, SIZE_4KB);
|
||||||
|
|
||||||
// formulate page table entry, Domain=0, NS=0
|
// formulate page table entry, Domain=0, NS=0
|
||||||
PageTableDescriptor = (((UINTN)PageTableAddr) & ARM_PAGE_DESC_BASE_MASK) | ARM_DESC_TYPE_PAGE_TABLE;
|
PageTableDescriptor = (((UINTN)PageTableAddr) & TT_DESCRIPTOR_SECTION_PAGETABLE_ADDRESS_MASK) | TT_DESCRIPTOR_SECTION_TYPE_PAGE_TABLE;
|
||||||
|
|
||||||
// write the page table entry out, repalcing section entry
|
// write the page table entry out, repalcing section entry
|
||||||
FirstLevelTable[FirstLevelIdx] = PageTableDescriptor;
|
FirstLevelTable[FirstLevelIdx] = PageTableDescriptor;
|
||||||
@ -910,7 +790,3 @@ VIRTUAL_UNCACHED_PAGES_PROTOCOL gVirtualUncachedPages = {
|
|||||||
CpuConvertPagesToUncachedVirtualAddress,
|
CpuConvertPagesToUncachedVirtualAddress,
|
||||||
CpuReconvertPages
|
CpuReconvertPages
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,119 +0,0 @@
|
|||||||
/** @file
|
|
||||||
|
|
||||||
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 <Uefi.h>
|
|
||||||
|
|
||||||
#include <Library/CacheMaintenanceLib.h>
|
|
||||||
#include <Library/DebugLib.h>
|
|
||||||
#include <Library/UefiBootServicesTableLib.h>
|
|
||||||
|
|
||||||
#include <Protocol/Cpu.h>
|
|
||||||
#include <Protocol/DebugSupport.h>
|
|
||||||
#include <Protocol/TimerDebugSupport.h>
|
|
||||||
|
|
||||||
EFI_STATUS
|
|
||||||
EFIAPI
|
|
||||||
DebugSupportGetMaximumProcessorIndex (
|
|
||||||
IN EFI_DEBUG_SUPPORT_PROTOCOL *This,
|
|
||||||
OUT UINTN *MaxProcessorIndex
|
|
||||||
)
|
|
||||||
{
|
|
||||||
if (MaxProcessorIndex == NULL) {
|
|
||||||
return EFI_INVALID_PARAMETER;
|
|
||||||
}
|
|
||||||
|
|
||||||
*MaxProcessorIndex = 0;
|
|
||||||
|
|
||||||
return EFI_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
EFI_STATUS
|
|
||||||
EFIAPI
|
|
||||||
DebugSupportRegisterPeriodicCallback (
|
|
||||||
IN EFI_DEBUG_SUPPORT_PROTOCOL *This,
|
|
||||||
IN UINTN ProcessorIndex,
|
|
||||||
IN EFI_PERIODIC_CALLBACK PeriodicCallback
|
|
||||||
)
|
|
||||||
{
|
|
||||||
TIMER_DEBUG_SUPPORT_PROTOCOL *Timer;
|
|
||||||
EFI_STATUS Status;
|
|
||||||
|
|
||||||
Status = gBS->LocateProtocol(&gTimerDebugSupportProtocolGuid, NULL, (VOID **)&Timer);
|
|
||||||
if (EFI_ERROR(Status)) {
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
Status = Timer->RegisterPeriodicCallback(Timer, PeriodicCallback);
|
|
||||||
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
EFI_STATUS
|
|
||||||
EFIAPI
|
|
||||||
DebugSupportRegisterExceptionCallback (
|
|
||||||
IN EFI_DEBUG_SUPPORT_PROTOCOL *This,
|
|
||||||
IN UINTN ProcessorIndex,
|
|
||||||
IN EFI_EXCEPTION_CALLBACK ExceptionCallback,
|
|
||||||
IN EFI_EXCEPTION_TYPE ExceptionType
|
|
||||||
)
|
|
||||||
{
|
|
||||||
EFI_CPU_ARCH_PROTOCOL *Cpu;
|
|
||||||
EFI_STATUS Status;
|
|
||||||
|
|
||||||
Status = gBS->LocateProtocol(&gEfiCpuArchProtocolGuid, NULL, (VOID **)&Cpu);
|
|
||||||
if (EFI_ERROR(Status)) {
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
Status = Cpu->RegisterInterruptHandler(Cpu, ExceptionType, (EFI_CPU_INTERRUPT_HANDLER)ExceptionCallback);
|
|
||||||
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
EFI_STATUS
|
|
||||||
EFIAPI
|
|
||||||
DebugSupportInvalidateInstructionCache (
|
|
||||||
IN EFI_DEBUG_SUPPORT_PROTOCOL *This,
|
|
||||||
IN UINTN ProcessorIndex,
|
|
||||||
IN VOID *Start,
|
|
||||||
IN UINT64 Length
|
|
||||||
)
|
|
||||||
{
|
|
||||||
InvalidateInstructionCacheRange(Start, Length);
|
|
||||||
return EFI_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
EFI_DEBUG_SUPPORT_PROTOCOL mDebugSupport = {
|
|
||||||
IsaArm,
|
|
||||||
DebugSupportGetMaximumProcessorIndex,
|
|
||||||
DebugSupportRegisterPeriodicCallback,
|
|
||||||
DebugSupportRegisterExceptionCallback,
|
|
||||||
DebugSupportInvalidateInstructionCache
|
|
||||||
};
|
|
||||||
|
|
||||||
EFI_STATUS
|
|
||||||
DebugSupportDxeInitialize (
|
|
||||||
IN EFI_HANDLE ImageHandle,
|
|
||||||
IN EFI_SYSTEM_TABLE *SystemTable
|
|
||||||
)
|
|
||||||
{
|
|
||||||
EFI_STATUS Status;
|
|
||||||
EFI_HANDLE Handle = NULL;
|
|
||||||
|
|
||||||
ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiDebugSupportProtocolGuid);
|
|
||||||
Status = gBS->InstallMultipleProtocolInterfaces(&Handle, &gEfiDebugSupportProtocolGuid, &mDebugSupport, NULL);
|
|
||||||
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
387
ArmPkg/Drivers/PL180MciDxe/PL180Mci.c
Normal file
387
ArmPkg/Drivers/PL180MciDxe/PL180Mci.c
Normal file
@ -0,0 +1,387 @@
|
|||||||
|
/** @file
|
||||||
|
This file implement the MMC Host Protocol for the ARM PrimeCell PL180.
|
||||||
|
|
||||||
|
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 "PL180Mci.h"
|
||||||
|
|
||||||
|
#include <Library/DevicePathLib.h>
|
||||||
|
#include <Library/BaseMemoryLib.h>
|
||||||
|
|
||||||
|
EFI_MMC_HOST_PROTOCOL *gpMmcHost;
|
||||||
|
|
||||||
|
// Untested ...
|
||||||
|
//#define USE_STREAM
|
||||||
|
|
||||||
|
#define MMCI0_BLOCKLEN 512
|
||||||
|
#define MMCI0_POW2_BLOCKLEN 9
|
||||||
|
#define MMCI0_TIMEOUT 1000
|
||||||
|
|
||||||
|
BOOLEAN MciIsPowerOn() {
|
||||||
|
return ((MmioRead32(MCI_POWER_CONTROL_REG) & 0x3) == MCI_POWER_ON);
|
||||||
|
}
|
||||||
|
|
||||||
|
EFI_STATUS MciInitialize() {
|
||||||
|
MCI_TRACE("MciInitialize()");
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOLEAN MciIsCardPresent() {
|
||||||
|
return (MmioRead32(FixedPcdGet32(PcdPL180SysMciRegAddress)) & 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOLEAN MciIsReadOnly() {
|
||||||
|
return (MmioRead32(FixedPcdGet32(PcdPL180SysMciRegAddress)) & 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert block size to 2^n
|
||||||
|
UINT32 GetPow2BlockLen(UINT32 BlockLen) {
|
||||||
|
UINTN Loop;
|
||||||
|
UINTN Pow2BlockLen;
|
||||||
|
|
||||||
|
Loop = 0x8000;
|
||||||
|
Pow2BlockLen = 15;
|
||||||
|
do {
|
||||||
|
Loop = (Loop >> 1) & 0xFFFF;
|
||||||
|
Pow2BlockLen--;
|
||||||
|
} while (Pow2BlockLen && (!(Loop & BlockLen)));
|
||||||
|
|
||||||
|
return Pow2BlockLen;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID MciPrepareDataPath(UINTN TransferDirection) {
|
||||||
|
// Set Data Length & Data Timer
|
||||||
|
MmioWrite32(MCI_DATA_TIMER_REG,0xFFFFFFF);
|
||||||
|
MmioWrite32(MCI_DATA_LENGTH_REG,MMCI0_BLOCKLEN);
|
||||||
|
|
||||||
|
#ifndef USE_STREAM
|
||||||
|
//Note: we are using a hardcoded BlockLen (=512). If we decide to use a variable size, we could
|
||||||
|
// compute the pow2 of BlockLen with the above function GetPow2BlockLen()
|
||||||
|
MmioWrite32(MCI_DATA_CTL_REG, MCI_DATACTL_ENABLE | TransferDirection | (MMCI0_POW2_BLOCKLEN << 4));
|
||||||
|
#else
|
||||||
|
MmioWrite32(MCI_DATA_CTL_REG, MCI_DATACTL_ENABLE | TransferDirection | MCI_DATACTL_STREAM_TRANS);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
EFI_STATUS MciSendCommand(MMC_CMD MmcCmd, UINT32 Argument) {
|
||||||
|
UINT32 Status;
|
||||||
|
UINT32 Timer;
|
||||||
|
UINT32 Cmd;
|
||||||
|
|
||||||
|
if ((MmcCmd == MMC_CMD17) || (MmcCmd == MMC_CMD11)) {
|
||||||
|
MciPrepareDataPath(MCI_DATACTL_CARD_TO_CONT);
|
||||||
|
} else if ((MmcCmd == MMC_CMD24) || (MmcCmd == MMC_CMD20)) {
|
||||||
|
MciPrepareDataPath(MCI_DATACTL_CONT_TO_CARD);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create Command for PL180
|
||||||
|
Cmd = INDX(MmcCmd);
|
||||||
|
if (MmcCmd & MMC_CMD_WAIT_RESPONSE)
|
||||||
|
Cmd |= MCI_CPSM_WAIT_RESPONSE;
|
||||||
|
if (MmcCmd & MMC_CMD_LONG_RESPONSE)
|
||||||
|
Cmd |= MCI_CPSM_LONG_RESPONSE;
|
||||||
|
|
||||||
|
MmioWrite32(MCI_CLEAR_STATUS_REG,0x5FFF);
|
||||||
|
MmioWrite32(MCI_ARGUMENT_REG,Argument);
|
||||||
|
MmioWrite32(MCI_COMMAND_REG,Cmd);
|
||||||
|
|
||||||
|
Timer = 1000;
|
||||||
|
if (Cmd & MCI_CPSM_WAIT_RESPONSE) {
|
||||||
|
Status = MmioRead32(MCI_STATUS_REG);
|
||||||
|
while (!(Status & (MCI_STATUS_CMD_RESPEND | MCI_STATUS_CMD_CMDCRCFAIL | MCI_STATUS_CMD_CMDTIMEOUT)) && Timer) {
|
||||||
|
//NanoSecondDelay(10);
|
||||||
|
Status = MmioRead32(MCI_STATUS_REG);
|
||||||
|
Timer--;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((Timer == 0) || (Status == MCI_STATUS_CMD_CMDTIMEOUT)) {
|
||||||
|
//DEBUG ((EFI_D_ERROR, "MciSendCommand(CmdIndex:%d) TIMEOUT! Response:0x%X Status:0x%X\n",Cmd & 0x3F,MmioRead32(MCI_RESPONSE0_REG),Status));
|
||||||
|
return EFI_TIMEOUT;
|
||||||
|
} else if (!((Cmd & 0x3F) == INDX(1)) && (Status & MCI_STATUS_CMD_CMDCRCFAIL)) {
|
||||||
|
// The CMD1 does not contain CRC. We should ignore the CRC failed Status.
|
||||||
|
return EFI_CRC_ERROR;
|
||||||
|
} else {
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Status = MmioRead32(MCI_STATUS_REG);
|
||||||
|
while (!(Status & MCI_STATUS_CMD_SENT) && Timer) {
|
||||||
|
//NanoSecondDelay(10);
|
||||||
|
Status = MmioRead32(MCI_STATUS_REG);
|
||||||
|
Timer--;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Timer == 0) {
|
||||||
|
//DEBUG ((EFI_D_ERROR, "MciSendCommand(CmdIndex:%d) TIMEOUT2! 0x%X\n",Cmd & 0x3F,MmioRead32(MCI_RESPONSE0_REG)));
|
||||||
|
return EFI_TIMEOUT;
|
||||||
|
} else {
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
EFI_STATUS MciReceiveResponse(MMC_RESPONSE_TYPE Type, UINT32* Buffer) {
|
||||||
|
if (Buffer == NULL) {
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((Type == MMC_RESPONSE_TYPE_R1) || (Type == MMC_RESPONSE_TYPE_R1b) ||
|
||||||
|
(Type == MMC_RESPONSE_TYPE_R3) || (Type == MMC_RESPONSE_TYPE_R6) ||
|
||||||
|
(Type == MMC_RESPONSE_TYPE_R7)) {
|
||||||
|
Buffer[0] = MmioRead32(MCI_RESPONSE0_REG);
|
||||||
|
Buffer[1] = MmioRead32(MCI_RESPONSE1_REG);
|
||||||
|
} else if (Type == MMC_RESPONSE_TYPE_R2) {
|
||||||
|
Buffer[0] = MmioRead32(MCI_RESPONSE0_REG);
|
||||||
|
Buffer[1] = MmioRead32(MCI_RESPONSE1_REG);
|
||||||
|
Buffer[2] = MmioRead32(MCI_RESPONSE2_REG);
|
||||||
|
Buffer[3] = MmioRead32(MCI_RESPONSE3_REG);
|
||||||
|
}
|
||||||
|
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
EFI_STATUS MciReadBlockData(EFI_LBA Lba, UINTN Length, UINT32* Buffer) {
|
||||||
|
UINTN Loop;
|
||||||
|
UINTN Finish;
|
||||||
|
UINTN Timer;
|
||||||
|
UINTN Status;
|
||||||
|
|
||||||
|
// Read data from the RX FIFO
|
||||||
|
Loop = 0;
|
||||||
|
Finish = MMCI0_BLOCKLEN / 4;
|
||||||
|
Timer = MMCI0_TIMEOUT * 10;
|
||||||
|
do {
|
||||||
|
// Read the Status flags
|
||||||
|
Status = MmioRead32(MCI_STATUS_REG);
|
||||||
|
// Do eight reads if possible else a single read
|
||||||
|
if (Status & MCI_STATUS_CMD_RXFIFOHALFFULL) {
|
||||||
|
Buffer[Loop] = MmioRead32(MCI_FIFO_REG);
|
||||||
|
Loop++;
|
||||||
|
Buffer[Loop] = MmioRead32(MCI_FIFO_REG);
|
||||||
|
Loop++;
|
||||||
|
Buffer[Loop] = MmioRead32(MCI_FIFO_REG);
|
||||||
|
Loop++;
|
||||||
|
Buffer[Loop] = MmioRead32(MCI_FIFO_REG);
|
||||||
|
Loop++;
|
||||||
|
Buffer[Loop] = MmioRead32(MCI_FIFO_REG);
|
||||||
|
Loop++;
|
||||||
|
Buffer[Loop] = MmioRead32(MCI_FIFO_REG);
|
||||||
|
Loop++;
|
||||||
|
Buffer[Loop] = MmioRead32(MCI_FIFO_REG);
|
||||||
|
Loop++;
|
||||||
|
Buffer[Loop] = MmioRead32(MCI_FIFO_REG);
|
||||||
|
Loop++;
|
||||||
|
}
|
||||||
|
else if (!(Status & MCI_STATUS_CMD_RXFIFOEMPTY)) {
|
||||||
|
Buffer[Loop] = MmioRead32(MCI_FIFO_REG);
|
||||||
|
Loop++;
|
||||||
|
} else
|
||||||
|
Timer--;
|
||||||
|
} while ((Loop < Finish) && Timer);
|
||||||
|
|
||||||
|
if (Timer == 0) {
|
||||||
|
DEBUG ((EFI_D_ERROR, "MciReadBlockData: Timeout Status:0x%X Loop:%d // Finish:%d\n",MmioRead32(MCI_STATUS_REG),Loop,Finish));
|
||||||
|
return EFI_TIMEOUT;
|
||||||
|
} else
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
EFI_STATUS MciWriteBlockData(EFI_LBA Lba, UINTN Length, UINT32* Buffer) {
|
||||||
|
UINTN Loop;
|
||||||
|
UINTN Finish;
|
||||||
|
UINTN Timer;
|
||||||
|
UINTN Status;
|
||||||
|
|
||||||
|
// Write the data to the TX FIFO
|
||||||
|
Loop = 0;
|
||||||
|
Finish = MMCI0_BLOCKLEN / 4;
|
||||||
|
Timer = MMCI0_TIMEOUT * 100;
|
||||||
|
do {
|
||||||
|
// Read the Status flags
|
||||||
|
Status = MmioRead32(MCI_STATUS_REG);
|
||||||
|
|
||||||
|
// Do eight writes if possible else a single write
|
||||||
|
if (Status & MCI_STATUS_CMD_TXFIFOHALFEMPTY) {
|
||||||
|
MmioWrite32(MCI_FIFO_REG, Buffer[Loop]);
|
||||||
|
Loop++;
|
||||||
|
MmioWrite32(MCI_FIFO_REG, Buffer[Loop]);
|
||||||
|
Loop++;
|
||||||
|
MmioWrite32(MCI_FIFO_REG, Buffer[Loop]);
|
||||||
|
Loop++;
|
||||||
|
MmioWrite32(MCI_FIFO_REG, Buffer[Loop]);
|
||||||
|
Loop++;
|
||||||
|
MmioWrite32(MCI_FIFO_REG, Buffer[Loop]);
|
||||||
|
Loop++;
|
||||||
|
MmioWrite32(MCI_FIFO_REG, Buffer[Loop]);
|
||||||
|
Loop++;
|
||||||
|
MmioWrite32(MCI_FIFO_REG, Buffer[Loop]);
|
||||||
|
Loop++;
|
||||||
|
MmioWrite32(MCI_FIFO_REG, Buffer[Loop]);
|
||||||
|
Loop++;
|
||||||
|
}
|
||||||
|
else if (!(Status & MCI_STATUS_CMD_TXFIFOFULL)) {
|
||||||
|
MmioWrite32(MCI_FIFO_REG, Buffer[Loop]);
|
||||||
|
Loop++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Timer--;
|
||||||
|
} while ((Loop < Finish) && Timer);
|
||||||
|
|
||||||
|
ASSERT(Timer > 0);
|
||||||
|
|
||||||
|
// Wait for FIFO to drain
|
||||||
|
Timer = MMCI0_TIMEOUT;
|
||||||
|
Status = MmioRead32(MCI_STATUS_REG);
|
||||||
|
/*#ifndef USE_STREAM
|
||||||
|
// Single block
|
||||||
|
while (((Status & MCI_STATUS_CMD_TXDONE) != MCI_STATUS_CMD_TXDONE) && Timer) {
|
||||||
|
#else*/
|
||||||
|
// Stream
|
||||||
|
while (((Status & MCI_STATUS_CMD_DATAEND) != MCI_STATUS_CMD_DATAEND) && Timer) {
|
||||||
|
//#endif
|
||||||
|
NanoSecondDelay(10);
|
||||||
|
Status = MmioRead32(MCI_STATUS_REG);
|
||||||
|
Timer--;
|
||||||
|
}
|
||||||
|
|
||||||
|
ASSERT(Timer > 0);
|
||||||
|
|
||||||
|
if (Timer == 0)
|
||||||
|
return EFI_TIMEOUT;
|
||||||
|
else
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
EFI_STATUS MciNotifyState(MMC_STATE State) {
|
||||||
|
UINT32 Data32;
|
||||||
|
|
||||||
|
switch(State) {
|
||||||
|
case MmcInvalidState:
|
||||||
|
ASSERT(0);
|
||||||
|
break;
|
||||||
|
case MmcHwInitializationState:
|
||||||
|
// If device already turn on then restart it
|
||||||
|
Data32 = MmioRead32(MCI_POWER_CONTROL_REG);
|
||||||
|
if ((Data32 & 0x2) == MCI_POWER_UP) {
|
||||||
|
MCI_TRACE("MciNotifyState(MmcHwInitializationState): TurnOff MCI");
|
||||||
|
|
||||||
|
// Turn off
|
||||||
|
MmioWrite32(MCI_CLOCK_CONTROL_REG, 0);
|
||||||
|
MmioWrite32(MCI_POWER_CONTROL_REG, 0);
|
||||||
|
MicroSecondDelay(100);
|
||||||
|
}
|
||||||
|
|
||||||
|
MCI_TRACE("MciNotifyState(MmcHwInitializationState): TurnOn MCI");
|
||||||
|
// Setup clock
|
||||||
|
// - 0x1D = 29 => should be the clock divider to be less than 400kHz at MCLK = 24Mhz
|
||||||
|
MmioWrite32(MCI_CLOCK_CONTROL_REG,0x1D | MCI_CLOCK_ENABLE | MCI_CLOCK_POWERSAVE);
|
||||||
|
//MmioWrite32(MCI_CLOCK_CONTROL_REG,0x1D | MCI_CLOCK_ENABLE);
|
||||||
|
|
||||||
|
// Set the voltage
|
||||||
|
MmioWrite32(MCI_POWER_CONTROL_REG,MCI_POWER_OPENDRAIN | (15<<2));
|
||||||
|
MmioWrite32(MCI_POWER_CONTROL_REG,MCI_POWER_ROD | MCI_POWER_OPENDRAIN | (15<<2) | MCI_POWER_UP);
|
||||||
|
MicroSecondDelay(10);
|
||||||
|
MmioWrite32(MCI_POWER_CONTROL_REG,MCI_POWER_ROD | MCI_POWER_OPENDRAIN | (15<<2) | MCI_POWER_ON);
|
||||||
|
MicroSecondDelay(100);
|
||||||
|
|
||||||
|
// Set Data Length & Data Timer
|
||||||
|
MmioWrite32(MCI_DATA_TIMER_REG,0xFFFFF);
|
||||||
|
MmioWrite32(MCI_DATA_LENGTH_REG,8);
|
||||||
|
|
||||||
|
ASSERT((MmioRead32(MCI_POWER_CONTROL_REG) & 0x3) == MCI_POWER_ON);
|
||||||
|
break;
|
||||||
|
case MmcIdleState:
|
||||||
|
MCI_TRACE("MciNotifyState(MmcIdleState)");
|
||||||
|
break;
|
||||||
|
case MmcReadyState:
|
||||||
|
MCI_TRACE("MciNotifyState(MmcReadyState)");
|
||||||
|
break;
|
||||||
|
case MmcIdentificationState:
|
||||||
|
MCI_TRACE("MciNotifyState(MmcIdentificationState)");
|
||||||
|
break;
|
||||||
|
case MmcStandByState:
|
||||||
|
MCI_TRACE("MciNotifyState(MmcStandByState)");
|
||||||
|
|
||||||
|
// Enable MCICMD push-pull drive
|
||||||
|
MmioWrite32(MCI_POWER_CONTROL_REG,MCI_POWER_ROD | (15<<2) | MCI_POWER_ON);
|
||||||
|
|
||||||
|
/*// Set MMCI0 clock to 4MHz (24MHz may be possible with cache enabled)
|
||||||
|
MmioWrite32(MCI_CLOCK_CONTROL_REG,0x02 | MCI_CLOCK_ENABLE | MCI_CLOCK_POWERSAVE);*/
|
||||||
|
// Set MMCI0 clock to 24MHz (by bypassing the divider)
|
||||||
|
MmioWrite32(MCI_CLOCK_CONTROL_REG,MCI_CLOCK_BYPASS | MCI_CLOCK_ENABLE);
|
||||||
|
break;
|
||||||
|
case MmcTransferState:
|
||||||
|
//MCI_TRACE("MciNotifyState(MmcTransferState)");
|
||||||
|
break;
|
||||||
|
case MmcSendingDataState:
|
||||||
|
MCI_TRACE("MciNotifyState(MmcSendingDataState)");
|
||||||
|
break;
|
||||||
|
case MmcReceiveDataState:
|
||||||
|
MCI_TRACE("MciNotifyState(MmcReceiveDataState)");
|
||||||
|
break;
|
||||||
|
case MmcProgrammingState:
|
||||||
|
MCI_TRACE("MciNotifyState(MmcProgrammingState)");
|
||||||
|
break;
|
||||||
|
case MmcDisconnectState:
|
||||||
|
MCI_TRACE("MciNotifyState(MmcDisconnectState)");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ASSERT(0);
|
||||||
|
}
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
EFI_GUID mPL180MciDevicePathGuid = { 0x621b6fa5, 0x4dc1, 0x476f, 0xb9, 0xd8, 0x52, 0xc5, 0x57, 0xd8, 0x10, 0x70 };
|
||||||
|
|
||||||
|
EFI_STATUS MciBuildDevicePath(EFI_DEVICE_PATH_PROTOCOL **DevicePath) {
|
||||||
|
EFI_DEVICE_PATH_PROTOCOL *NewDevicePathNode;
|
||||||
|
|
||||||
|
NewDevicePathNode = CreateDeviceNode(HARDWARE_DEVICE_PATH,HW_VENDOR_DP,sizeof(VENDOR_DEVICE_PATH));
|
||||||
|
CopyGuid(&((VENDOR_DEVICE_PATH*)NewDevicePathNode)->Guid,&mPL180MciDevicePathGuid);
|
||||||
|
|
||||||
|
*DevicePath = NewDevicePathNode;
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
EFI_MMC_HOST_PROTOCOL gMciHost = {
|
||||||
|
MciIsCardPresent,
|
||||||
|
MciIsReadOnly,
|
||||||
|
MciBuildDevicePath,
|
||||||
|
MciNotifyState,
|
||||||
|
MciSendCommand,
|
||||||
|
MciReceiveResponse,
|
||||||
|
MciReadBlockData,
|
||||||
|
MciWriteBlockData
|
||||||
|
};
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
PL180MciDxeInitialize (
|
||||||
|
IN EFI_HANDLE ImageHandle,
|
||||||
|
IN EFI_SYSTEM_TABLE *SystemTable
|
||||||
|
)
|
||||||
|
{
|
||||||
|
EFI_STATUS Status;
|
||||||
|
EFI_HANDLE Handle = NULL;
|
||||||
|
|
||||||
|
MCI_TRACE("PL180MciDxeInitialize()");
|
||||||
|
|
||||||
|
//Publish Component Name, BlockIO protocol interfaces
|
||||||
|
Status = gBS->InstallMultipleProtocolInterfaces (
|
||||||
|
&Handle,
|
||||||
|
&gEfiMmcHostProtocolGuid, &gMciHost,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
ASSERT_EFI_ERROR (Status);
|
||||||
|
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
117
ArmPkg/Drivers/PL180MciDxe/PL180Mci.h
Normal file
117
ArmPkg/Drivers/PL180MciDxe/PL180Mci.h
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
/** @file
|
||||||
|
Header for the MMC Host Protocol implementation for the ARM PrimeCell PL180.
|
||||||
|
|
||||||
|
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 __PL180_MCI_H
|
||||||
|
#define __PL180_MCI_H
|
||||||
|
|
||||||
|
#include <Uefi.h>
|
||||||
|
|
||||||
|
#include <Protocol/MmcHost.h>
|
||||||
|
|
||||||
|
#include <Library/UefiLib.h>
|
||||||
|
#include <Library/DebugLib.h>
|
||||||
|
#include <Library/UefiBootServicesTableLib.h>
|
||||||
|
#include <Library/IoLib.h>
|
||||||
|
#include <Library/TimerLib.h>
|
||||||
|
#include <Library/PcdLib.h>
|
||||||
|
|
||||||
|
#define PL180_MCI_DXE_VERSION 0x10
|
||||||
|
|
||||||
|
#define MCI_SYSCTL FixedPcdGet32(PcdPL180MciBaseAddress)
|
||||||
|
|
||||||
|
#define MCI_POWER_CONTROL_REG (MCI_SYSCTL+0x000)
|
||||||
|
#define MCI_CLOCK_CONTROL_REG (MCI_SYSCTL+0x004)
|
||||||
|
#define MCI_ARGUMENT_REG (MCI_SYSCTL+0x008)
|
||||||
|
#define MCI_COMMAND_REG (MCI_SYSCTL+0x00C)
|
||||||
|
#define MCI_RESPCMD_REG (MCI_SYSCTL+0x010)
|
||||||
|
#define MCI_RESPONSE0_REG (MCI_SYSCTL+0x014)
|
||||||
|
#define MCI_RESPONSE1_REG (MCI_SYSCTL+0x018)
|
||||||
|
#define MCI_RESPONSE2_REG (MCI_SYSCTL+0x01C)
|
||||||
|
#define MCI_RESPONSE3_REG (MCI_SYSCTL+0x020)
|
||||||
|
#define MCI_DATA_TIMER_REG (MCI_SYSCTL+0x024)
|
||||||
|
#define MCI_DATA_LENGTH_REG (MCI_SYSCTL+0x028)
|
||||||
|
#define MCI_DATA_CTL_REG (MCI_SYSCTL+0x02C)
|
||||||
|
#define MCI_DATA_COUNTER (MCI_SYSCTL+0x030)
|
||||||
|
#define MCI_STATUS_REG (MCI_SYSCTL+0x034)
|
||||||
|
#define MCI_CLEAR_STATUS_REG (MCI_SYSCTL+0x038)
|
||||||
|
#define MCI_INT0_MASK_REG (MCI_SYSCTL+0x03C)
|
||||||
|
#define MCI_INT1_MASK_REG (MCI_SYSCTL+0x040)
|
||||||
|
#define MCI_FIFOCOUNT_REG (MCI_SYSCTL+0x048)
|
||||||
|
#define MCI_FIFO_REG (MCI_SYSCTL+0x080)
|
||||||
|
|
||||||
|
#define MCI_POWER_UP 0x2
|
||||||
|
#define MCI_POWER_ON 0x3
|
||||||
|
#define MCI_POWER_OPENDRAIN (1 << 6)
|
||||||
|
#define MCI_POWER_ROD (1 << 7)
|
||||||
|
|
||||||
|
#define MCI_CLOCK_ENABLE 0x100
|
||||||
|
#define MCI_CLOCK_POWERSAVE 0x200
|
||||||
|
#define MCI_CLOCK_BYPASS 0x400
|
||||||
|
|
||||||
|
#define MCI_STATUS_CMD_CMDCRCFAIL 0x1
|
||||||
|
#define MCI_STATUS_CMD_DATACRCFAIL 0x2
|
||||||
|
#define MCI_STATUS_CMD_CMDTIMEOUT 0x4
|
||||||
|
#define MCI_STATUS_CMD_DATATIMEOUT 0x8
|
||||||
|
#define MCI_STATUS_CMD_RXOVERRUN 0x20
|
||||||
|
#define MCI_STATUS_CMD_RESPEND 0x40
|
||||||
|
#define MCI_STATUS_CMD_SENT 0x80
|
||||||
|
#define MCI_STATUS_CMD_TXDONE (MCI_STATUS_CMD_DATAEND | MCI_STATUS_CMD_DATABLOCKEND)
|
||||||
|
#define MCI_STATUS_CMD_DATAEND 0x000100 // Command Status - Data end
|
||||||
|
#define MCI_STATUS_CMD_DATABLOCKEND 0x000400 // Command Status - Data end
|
||||||
|
#define MCI_STATUS_CMD_ACTIVE 0x800
|
||||||
|
#define MCI_STATUS_CMD_RXACTIVE (1 << 13)
|
||||||
|
#define MCI_STATUS_CMD_RXFIFOHALFFULL 0x008000
|
||||||
|
#define MCI_STATUS_CMD_RXFIFOEMPTY 0x080000
|
||||||
|
#define MCI_STATUS_CMD_RXDATAAVAILBL (1 << 21)
|
||||||
|
#define MCI_STATUS_CMD_TXACTIVE (1 << 12)
|
||||||
|
#define MCI_STATUS_CMD_TXFIFOFULL (1 << 16)
|
||||||
|
#define MCI_STATUS_CMD_TXFIFOHALFEMPTY (1 << 14)
|
||||||
|
#define MCI_STATUS_CMD_TXFIFOEMPTY (1 << 18)
|
||||||
|
#define MCI_STATUS_CMD_TXDATAAVAILBL (1 << 20)
|
||||||
|
|
||||||
|
#define MCI_DATACTL_ENABLE 1
|
||||||
|
#define MCI_DATACTL_CONT_TO_CARD 0
|
||||||
|
#define MCI_DATACTL_CARD_TO_CONT 2
|
||||||
|
#define MCI_DATACTL_BLOCK_TRANS 0
|
||||||
|
#define MCI_DATACTL_STREAM_TRANS 4
|
||||||
|
#define MCI_DATACTL_DMA_ENABLE 8
|
||||||
|
|
||||||
|
#define INDX(CMD_INDX) ((CMD_INDX & 0x3F) | MCI_CPSM_ENABLED)
|
||||||
|
|
||||||
|
#define MCI_CPSM_ENABLED (1 << 10)
|
||||||
|
#define MCI_CPSM_WAIT_RESPONSE (1 << 6)
|
||||||
|
#define MCI_CPSM_LONG_RESPONSE (1 << 7)
|
||||||
|
|
||||||
|
#define MCI_TRACE(txt) DEBUG((EFI_D_BLKIO, "ARM_MCI: " txt "\n"))
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
MciGetDriverName (
|
||||||
|
IN EFI_COMPONENT_NAME_PROTOCOL *This,
|
||||||
|
IN CHAR8 *Language,
|
||||||
|
OUT CHAR16 **DriverName
|
||||||
|
);
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
MciGetControllerName (
|
||||||
|
IN EFI_COMPONENT_NAME_PROTOCOL *This,
|
||||||
|
IN EFI_HANDLE ControllerHandle,
|
||||||
|
IN EFI_HANDLE ChildHandle OPTIONAL,
|
||||||
|
IN CHAR8 *Language,
|
||||||
|
OUT CHAR16 **ControllerName
|
||||||
|
);
|
||||||
|
|
||||||
|
#endif
|
51
ArmPkg/Drivers/PL180MciDxe/PL180MciDxe.inf
Normal file
51
ArmPkg/Drivers/PL180MciDxe/PL180MciDxe.inf
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
#/** @file
|
||||||
|
# INF file for the MMC Host Protocol implementation for the ARM PrimeCell PL180.
|
||||||
|
#
|
||||||
|
# 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 = PL180MciDxe
|
||||||
|
FILE_GUID = 09831032-6fa3-4484-af4f-0a000a8d3a82
|
||||||
|
MODULE_TYPE = DXE_DRIVER
|
||||||
|
VERSION_STRING = 1.0
|
||||||
|
|
||||||
|
ENTRY_POINT = PL180MciDxeInitialize
|
||||||
|
|
||||||
|
[Sources.common]
|
||||||
|
PL180Mci.c
|
||||||
|
|
||||||
|
[Packages]
|
||||||
|
ArmPkg/ArmPkg.dec
|
||||||
|
MdePkg/MdePkg.dec
|
||||||
|
|
||||||
|
[LibraryClasses]
|
||||||
|
BaseLib
|
||||||
|
UefiLib
|
||||||
|
UefiDriverEntryPoint
|
||||||
|
BaseMemoryLib
|
||||||
|
ArmLib
|
||||||
|
IoLib
|
||||||
|
TimerLib
|
||||||
|
|
||||||
|
[Protocols]
|
||||||
|
gEfiCpuArchProtocolGuid
|
||||||
|
gEfiDevicePathProtocolGuid
|
||||||
|
gEfiMmcHostProtocolGuid
|
||||||
|
|
||||||
|
[Pcd]
|
||||||
|
gArmTokenSpaceGuid.PcdPL180SysMciRegAddress
|
||||||
|
gArmTokenSpaceGuid.PcdPL180MciBaseAddress
|
||||||
|
|
||||||
|
[Depex]
|
||||||
|
TRUE
|
108
ArmPkg/Drivers/PL301Axi/PL301Axi.c
Normal file
108
ArmPkg/Drivers/PL301Axi/PL301Axi.c
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
/** @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/DebugLib.h>
|
||||||
|
|
||||||
|
#define PL301_QOS_TIDEMARK_MI_0 0x400
|
||||||
|
#define PL301_QOS_ACCESSCONTROL_MI_0 0x404
|
||||||
|
|
||||||
|
#define PL301_QOS_TIDEMARK_MI_1 0x420
|
||||||
|
#define PL301_QOS_ACCESSCONTROL_MI_1 0x424
|
||||||
|
|
||||||
|
#define PL301_QOS_TIDEMARK_MI_2 0x440
|
||||||
|
#define PL301_QOS_ACCESSCONTROL_MI_2 0x444
|
||||||
|
|
||||||
|
#define PL301_AR_ARB_MI_0 0x408
|
||||||
|
#define PL301_AW_ARB_MI_0 0x40C
|
||||||
|
|
||||||
|
#define PL301_AR_ARB_MI_1 0x428
|
||||||
|
#define PL301_AW_ARB_MI_1 0x42C
|
||||||
|
|
||||||
|
#define PL301_AR_ARB_MI_2 0x448
|
||||||
|
#define PL301_AW_ARB_MI_2 0x44C
|
||||||
|
|
||||||
|
#define PL301_MI_1_OFFSET 0x20
|
||||||
|
#define PL301_MI_2_OFFSET 0x40
|
||||||
|
#define PL301_MI_3_OFFSET 0x60
|
||||||
|
#define PL301_MI_4_OFFSET 0x80
|
||||||
|
#define PL301_MI_5_OFFSET 0xa0
|
||||||
|
|
||||||
|
#define V2P_CA9_FAXI_MI0_TIDEMARK_VAL 0x6
|
||||||
|
#define V2P_CA9_FAXI_MI0_ACCESSCNTRL_VAL 0x1
|
||||||
|
|
||||||
|
#define V2P_CA9_FAXI_MI1_TIDEMARK_VAL 0x6
|
||||||
|
#define V2P_CA9_FAXI_MI1_ACCESSCNTRL_VAL 0x1
|
||||||
|
|
||||||
|
#define V2P_CA9_FAXI_MI2_TIDEMARK_VAL 0x6
|
||||||
|
#define V2P_CA9_FAXI_MI2_ACCESSCNTRL_VAL 0x1
|
||||||
|
|
||||||
|
|
||||||
|
#define FAxiWriteReg(reg,val) MmioWrite32(FAxiBase + reg, val)
|
||||||
|
#define FAxiReadReg(reg) MmioRead32(FAxiBase + reg)
|
||||||
|
|
||||||
|
// IN FAxiBase
|
||||||
|
// Initialize PL301 Dynamic Memory Controller
|
||||||
|
VOID PL301AxiInit(UINTN FAxiBase) {
|
||||||
|
// Configure Tidemark Register for Master Port 0 (MI 0)
|
||||||
|
FAxiWriteReg(PL301_QOS_TIDEMARK_MI_0, V2P_CA9_FAXI_MI0_TIDEMARK_VAL);
|
||||||
|
|
||||||
|
// Configure the Access Control Register (MI 0)
|
||||||
|
FAxiWriteReg(PL301_QOS_ACCESSCONTROL_MI_0, V2P_CA9_FAXI_MI0_ACCESSCNTRL_VAL);
|
||||||
|
|
||||||
|
// MP0
|
||||||
|
// Set priority for Read
|
||||||
|
FAxiWriteReg(PL301_AR_ARB_MI_0, 0x00000100);
|
||||||
|
FAxiWriteReg(PL301_AR_ARB_MI_0, 0x01000200);
|
||||||
|
FAxiWriteReg(PL301_AR_ARB_MI_0, 0x02000200);
|
||||||
|
FAxiWriteReg(PL301_AR_ARB_MI_0, 0x03000200);
|
||||||
|
FAxiWriteReg(PL301_AR_ARB_MI_0, 0x04000200);
|
||||||
|
|
||||||
|
// Set priority for Write
|
||||||
|
FAxiWriteReg(PL301_AW_ARB_MI_0, 0x00000100);
|
||||||
|
FAxiWriteReg(PL301_AW_ARB_MI_0, 0x01000200);
|
||||||
|
FAxiWriteReg(PL301_AW_ARB_MI_0, 0x02000200);
|
||||||
|
FAxiWriteReg(PL301_AW_ARB_MI_0, 0x03000200);
|
||||||
|
FAxiWriteReg(PL301_AW_ARB_MI_0, 0x04000200);
|
||||||
|
|
||||||
|
// MP1
|
||||||
|
// Set priority for Read
|
||||||
|
FAxiWriteReg(PL301_AR_ARB_MI_1, 0x00000100);
|
||||||
|
FAxiWriteReg(PL301_AR_ARB_MI_1, 0x01000200);
|
||||||
|
FAxiWriteReg(PL301_AR_ARB_MI_1, 0x02000200);
|
||||||
|
FAxiWriteReg(PL301_AR_ARB_MI_1, 0x03000200);
|
||||||
|
FAxiWriteReg(PL301_AR_ARB_MI_1, 0x04000200);
|
||||||
|
|
||||||
|
// Set priority for Write
|
||||||
|
FAxiWriteReg(PL301_AW_ARB_MI_1, 0x00000100);
|
||||||
|
FAxiWriteReg(PL301_AW_ARB_MI_1, 0x01000200);
|
||||||
|
FAxiWriteReg(PL301_AW_ARB_MI_1, 0x02000200);
|
||||||
|
FAxiWriteReg(PL301_AW_ARB_MI_1, 0x03000200);
|
||||||
|
FAxiWriteReg(PL301_AW_ARB_MI_1, 0x04000200);
|
||||||
|
|
||||||
|
// MP2
|
||||||
|
// Set priority for Read
|
||||||
|
FAxiWriteReg(PL301_AR_ARB_MI_2, 0x00000100);
|
||||||
|
FAxiWriteReg(PL301_AR_ARB_MI_2, 0x01000100);
|
||||||
|
FAxiWriteReg(PL301_AR_ARB_MI_2, 0x02000100);
|
||||||
|
FAxiWriteReg(PL301_AR_ARB_MI_2, 0x03000100);
|
||||||
|
FAxiWriteReg(PL301_AR_ARB_MI_2, 0x04000100);
|
||||||
|
|
||||||
|
// Set priority for Write
|
||||||
|
FAxiWriteReg(PL301_AW_ARB_MI_2, 0x00000100);
|
||||||
|
FAxiWriteReg(PL301_AW_ARB_MI_2, 0x01000200);
|
||||||
|
FAxiWriteReg(PL301_AW_ARB_MI_2, 0x02000200);
|
||||||
|
FAxiWriteReg(PL301_AW_ARB_MI_2, 0x03000200);
|
||||||
|
FAxiWriteReg(PL301_AW_ARB_MI_2, 0x04000200);
|
||||||
|
}
|
29
ArmPkg/Drivers/PL301Axi/PL301Axi.inf
Normal file
29
ArmPkg/Drivers/PL301Axi/PL301Axi.inf
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
#/* @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 = PL301AxiSec
|
||||||
|
FILE_GUID = 2ea84160-aba0-11df-9896-0002a5d5c51b
|
||||||
|
MODULE_TYPE = BASE
|
||||||
|
VERSION_STRING = 1.0
|
||||||
|
LIBRARY_CLASS = PL301AxiLib
|
||||||
|
|
||||||
|
[Sources]
|
||||||
|
PL301Axi.c
|
||||||
|
|
||||||
|
[Packages]
|
||||||
|
ArmPkg/ArmPkg.dec
|
||||||
|
MdePkg/MdePkg.dec
|
||||||
|
|
||||||
|
[FixedPcd]
|
130
ArmPkg/Drivers/PL310L2Cache/PL310L2Cache.c
Normal file
130
ArmPkg/Drivers/PL310L2Cache/PL310L2Cache.c
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
/** @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/DebugLib.h>
|
||||||
|
#include <Library/ArmLib.h>
|
||||||
|
#include <Library/L2X0CacheLib.h>
|
||||||
|
#include <Library/PcdLib.h>
|
||||||
|
|
||||||
|
#define L2x0WriteReg(reg,val) MmioWrite32(PcdGet32(PcdL2x0ControllerBase) + reg, val)
|
||||||
|
#define L2x0ReadReg(reg) MmioRead32(PcdGet32(PcdL2x0ControllerBase) + reg)
|
||||||
|
|
||||||
|
// Initialize PL320 L2 Cache Controller
|
||||||
|
VOID L2x0CacheInit(UINTN L2x0Base, BOOLEAN CacheEnabled) {
|
||||||
|
UINT32 Data;
|
||||||
|
UINT32 Revision;
|
||||||
|
UINT32 Aux;
|
||||||
|
UINT32 PfCtl;
|
||||||
|
UINT32 PwrCtl;
|
||||||
|
|
||||||
|
// Check if L2x0 is present and is an ARM implementation
|
||||||
|
Data = L2x0ReadReg(L2X0_CACHEID);
|
||||||
|
if ((Data >> 24) != L2X0_CACHEID_IMPLEMENTER_ARM) {
|
||||||
|
ASSERT(0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if L2x0 is PL310
|
||||||
|
if (((Data >> 6) & 0xF) != L2X0_CACHEID_PARTNUM_PL310) {
|
||||||
|
ASSERT(0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// RTL release
|
||||||
|
Revision = Data & 0x3F;
|
||||||
|
|
||||||
|
// Check if L2x0 is already enabled then we disable it
|
||||||
|
Data = L2x0ReadReg(L2X0_CTRL);
|
||||||
|
if (Data & L2X0_CTRL_ENABLED) {
|
||||||
|
L2x0WriteReg(L2X0_CTRL, L2X0_CTRL_DISABLED);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Set up global configurations
|
||||||
|
//
|
||||||
|
|
||||||
|
// Auxiliary register: Non-secure interrupt access Control + Event monitor bus enable + SBO
|
||||||
|
Aux = L2X0_AUXCTRL_NSAC | L2X0_AUXCTRL_EM | L2X0_AUXCTRL_SBO;
|
||||||
|
// Use AWCACHE attributes for WA
|
||||||
|
Aux |= L2x0_AUXCTRL_AW_AWCACHE;
|
||||||
|
// Use default Size
|
||||||
|
Data = L2x0ReadReg(L2X0_AUXCTRL);
|
||||||
|
Aux |= Data & (0x7 << 17);
|
||||||
|
// Use default associativity
|
||||||
|
Aux |= Data & (0x1 << 16);
|
||||||
|
// Enabled I & D Prefetch
|
||||||
|
Aux |= L2x0_AUXCTRL_IPREFETCH | L2x0_AUXCTRL_DPREFETCH;
|
||||||
|
|
||||||
|
if (Revision >= 5) {
|
||||||
|
// Prefetch Offset Register
|
||||||
|
PfCtl = L2x0ReadReg(L2X0_PFCTRL);
|
||||||
|
// - Prefetch increment set to 0
|
||||||
|
// - Prefetch dropping off
|
||||||
|
// - Double linefills off
|
||||||
|
L2x0WriteReg(L2X0_PFCTRL, PfCtl);
|
||||||
|
|
||||||
|
// Power Control Register - L2X0_PWRCTRL
|
||||||
|
PwrCtl = L2x0ReadReg(L2X0_PWRCTRL);
|
||||||
|
// - Standby when idle off
|
||||||
|
// - Dynamic clock gating off
|
||||||
|
// - Nc,NC-shared dropping off
|
||||||
|
L2x0WriteReg(L2X0_PWRCTRL, PwrCtl);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Revision >= 4) {
|
||||||
|
// Tag RAM Latency register
|
||||||
|
// - Use default latency
|
||||||
|
|
||||||
|
// Data RAM Latency Control register
|
||||||
|
// - Use default latency
|
||||||
|
} else if (Revision >= 2) {
|
||||||
|
L2x0WriteReg(L230_TAG_LATENCY,
|
||||||
|
(L2_TAG_ACCESS_LATENCY << 8)
|
||||||
|
| (L2_TAG_ACCESS_LATENCY << 4)
|
||||||
|
| L2_TAG_SETUP_LATENCY
|
||||||
|
);
|
||||||
|
|
||||||
|
L2x0WriteReg(L230_DATA_LATENCY,
|
||||||
|
(L2_DATA_ACCESS_LATENCY << 8)
|
||||||
|
| (L2_DATA_ACCESS_LATENCY << 4)
|
||||||
|
| L2_DATA_SETUP_LATENCY
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
Aux |= (L2_TAG_ACCESS_LATENCY << 6)
|
||||||
|
| (L2_DATA_ACCESS_LATENCY << 3)
|
||||||
|
| L2_DATA_ACCESS_LATENCY;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write Auxiliary value
|
||||||
|
L2x0WriteReg(L2X0_AUXCTRL, Aux);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Invalidate all entries in cache
|
||||||
|
//
|
||||||
|
L2x0WriteReg(L2X0_INVWAY, 0xffff);
|
||||||
|
// Poll cache maintenance register until invalidate operation is complete
|
||||||
|
while(L2x0ReadReg(L2X0_INVWAY) & 0xffff);
|
||||||
|
|
||||||
|
// Write to the Lockdown D and Lockdown I Register 9 if required
|
||||||
|
// - Not required
|
||||||
|
|
||||||
|
// Clear any residual raw interrupts
|
||||||
|
L2x0WriteReg(L2X0_INTCLEAR, 0x1FF);
|
||||||
|
|
||||||
|
// Enable the cache
|
||||||
|
if (CacheEnabled) {
|
||||||
|
L2x0WriteReg(L2X0_CTRL, L2X0_CTRL_ENABLED);
|
||||||
|
}
|
||||||
|
}
|
30
ArmPkg/Drivers/PL310L2Cache/PL310L2CacheSec.inf
Normal file
30
ArmPkg/Drivers/PL310L2Cache/PL310L2CacheSec.inf
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
#/* @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 = PL310L2Cache
|
||||||
|
FILE_GUID = 16ad4fe0-b5b1-11df-8cbf-0002a5d5c51b
|
||||||
|
MODULE_TYPE = SEC
|
||||||
|
VERSION_STRING = 1.0
|
||||||
|
LIBRARY_CLASS = L2X0CacheLib
|
||||||
|
|
||||||
|
[Sources]
|
||||||
|
PL310L2Cache.c
|
||||||
|
|
||||||
|
[Packages]
|
||||||
|
ArmPkg/ArmPkg.dec
|
||||||
|
MdePkg/MdePkg.dec
|
||||||
|
|
||||||
|
[FixedPcd]
|
||||||
|
gArmTokenSpaceGuid.PcdL2x0ControllerBase
|
373
ArmPkg/Drivers/PL34xDmc/PL341Dmc.c
Normal file
373
ArmPkg/Drivers/PL34xDmc/PL341Dmc.c
Normal file
@ -0,0 +1,373 @@
|
|||||||
|
/** @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/DebugLib.h>
|
||||||
|
#include <Drivers/PL341Dmc.h>
|
||||||
|
|
||||||
|
//
|
||||||
|
// DMC Configuration Register Map
|
||||||
|
//
|
||||||
|
#define DMC_STATUS_REG 0x00
|
||||||
|
#define DMC_COMMAND_REG 0x04
|
||||||
|
#define DMC_DIRECT_CMD_REG 0x08
|
||||||
|
#define DMC_MEMORY_CONFIG_REG 0x0C
|
||||||
|
#define DMC_REFRESH_PRD_REG 0x10
|
||||||
|
#define DMC_CAS_LATENCY_REG 0x14
|
||||||
|
#define DMC_WRITE_LATENCY_REG 0x18
|
||||||
|
#define DMC_T_MRD_REG 0x1C
|
||||||
|
#define DMC_T_RAS_REG 0x20
|
||||||
|
#define DMC_T_RC_REG 0x24
|
||||||
|
#define DMC_T_RCD_REG 0x28
|
||||||
|
#define DMC_T_RFC_REG 0x2C
|
||||||
|
#define DMC_T_RP_REG 0x30
|
||||||
|
#define DMC_T_RRD_REG 0x34
|
||||||
|
#define DMC_T_WR_REG 0x38
|
||||||
|
#define DMC_T_WTR_REG 0x3C
|
||||||
|
#define DMC_T_XP_REG 0x40
|
||||||
|
#define DMC_T_XSR_REG 0x44
|
||||||
|
#define DMC_T_ESR_REG 0x48
|
||||||
|
#define DMC_MEMORY_CFG2_REG 0x4C
|
||||||
|
#define DMC_MEMORY_CFG3_REG 0x50
|
||||||
|
#define DMC_T_FAW_REG 0x54
|
||||||
|
|
||||||
|
// Returns the state of the memory controller:
|
||||||
|
#define DMC_STATUS_CONFIG 0x0
|
||||||
|
#define DMC_STATUS_READY 0x1
|
||||||
|
#define DMC_STATUS_PAUSED 0x2
|
||||||
|
#define DMC_STATUS_LOWPOWER 0x3
|
||||||
|
|
||||||
|
// Changes the state of the memory controller:
|
||||||
|
#define DMC_COMMAND_GO 0x0
|
||||||
|
#define DMC_COMMAND_SLEEP 0x1
|
||||||
|
#define DMC_COMMAND_WAKEUP 0x2
|
||||||
|
#define DMC_COMMAND_PAUSE 0x3
|
||||||
|
#define DMC_COMMAND_CONFIGURE 0x4
|
||||||
|
#define DMC_COMMAND_ACTIVEPAUSE 0x7
|
||||||
|
|
||||||
|
// Determines the command required
|
||||||
|
#define DMC_DIRECT_CMD_MEMCMD_PRECHARGEALL 0x0
|
||||||
|
#define DMC_DIRECT_CMD_MEMCMD_AUTOREFRESH (0x1 << 18)
|
||||||
|
#define DMC_DIRECT_CMD_MEMCMD_MODEREG (0x2 << 18)
|
||||||
|
#define DMC_DIRECT_CMD_MEMCMD_EXTMODEREG (0x2 << 18)
|
||||||
|
#define DMC_DIRECT_CMD_MEMCMD_NOP (0x3 << 18)
|
||||||
|
#define DMC_DIRECT_CMD_MEMCMD_DPD (0x1 << 22)
|
||||||
|
#define DMC_DIRECT_CMD_BANKADDR(n) ((n & 0x3) << 16)
|
||||||
|
#define DMC_DIRECT_CMD_CHIP_ADDR(n) ((n & 0x3) << 20)
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// AXI ID configuration register map
|
||||||
|
//
|
||||||
|
#define DMC_ID_0_CFG_REG 0x100
|
||||||
|
#define DMC_ID_1_CFG_REG 0x104
|
||||||
|
#define DMC_ID_2_CFG_REG 0x108
|
||||||
|
#define DMC_ID_3_CFG_REG 0x10C
|
||||||
|
#define DMC_ID_4_CFG_REG 0x110
|
||||||
|
#define DMC_ID_5_CFG_REG 0x114
|
||||||
|
#define DMC_ID_6_CFG_REG 0x118
|
||||||
|
#define DMC_ID_7_CFG_REG 0x11C
|
||||||
|
#define DMC_ID_8_CFG_REG 0x120
|
||||||
|
#define DMC_ID_9_CFG_REG 0x124
|
||||||
|
#define DMC_ID_10_CFG_REG 0x128
|
||||||
|
#define DMC_ID_11_CFG_REG 0x12C
|
||||||
|
#define DMC_ID_12_CFG_REG 0x130
|
||||||
|
#define DMC_ID_13_CFG_REG 0x134
|
||||||
|
#define DMC_ID_14_CFG_REG 0x138
|
||||||
|
#define DMC_ID_15_CFG_REG 0x13C
|
||||||
|
|
||||||
|
// Set the QoS
|
||||||
|
#define DMC_ID_CFG_QOS_DISABLE 0
|
||||||
|
#define DMC_ID_CFG_QOS_ENABLE 1
|
||||||
|
#define DMC_ID_CFG_QOS_MIN 2
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Chip configuration register map
|
||||||
|
//
|
||||||
|
#define DMC_CHIP_0_CFG_REG 0x200
|
||||||
|
#define DMC_CHIP_1_CFG_REG 0x204
|
||||||
|
#define DMC_CHIP_2_CFG_REG 0x208
|
||||||
|
#define DMC_CHIP_3_CFG_REG 0x20C
|
||||||
|
|
||||||
|
//
|
||||||
|
// User Defined Pins
|
||||||
|
//
|
||||||
|
#define DMC_USER_STATUS_REG 0x300
|
||||||
|
#define DMC_USER_0_CFG_REG 0x304
|
||||||
|
#define DMC_USER_1_CFG_REG 0x308
|
||||||
|
#define DMC_FEATURE_CRTL_REG 0x30C
|
||||||
|
#define DMC_USER_2_CFG_REG 0x310
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// PHY Register Settings
|
||||||
|
//
|
||||||
|
#define TC_UIOLHNC_MASK 0x000003C0
|
||||||
|
#define TC_UIOLHNC_SHIFT 0x6
|
||||||
|
#define TC_UIOLHPC_MASK 0x0000003F
|
||||||
|
#define TC_UIOLHPC_SHIFT 0x2
|
||||||
|
#define TC_UIOHOCT_MASK 0x2
|
||||||
|
#define TC_UIOHOCT_SHIFT 0x1
|
||||||
|
#define TC_UIOHSTOP_SHIFT 0x0
|
||||||
|
#define TC_UIOLHXC_VALUE 0x4
|
||||||
|
|
||||||
|
//
|
||||||
|
// Extended Mode Register settings
|
||||||
|
//
|
||||||
|
#define DDR_EMR_OCD_MASK 0x0000380
|
||||||
|
#define DDR_EMR_OCD_SHIFT 0x7
|
||||||
|
#define DDR_EMR_RTT_MASK 0x00000044 // DDR2 Device RTT (ODT) settings
|
||||||
|
#define DDR_EMR_RTT_SHIFT 0x2
|
||||||
|
#define DDR_EMR_ODS_MASK 0x00000002 // DDR2 Output Drive Strength
|
||||||
|
#define DDR_EMR_ODS_SHIFT 0x0001
|
||||||
|
// Termination Values:
|
||||||
|
#define DDR_EMR_RTT_50 0x00000044 // DDR2 50 Ohm termination
|
||||||
|
#define DDR_EMR_RTT_75R 0x00000004 // DDR2 75 Ohm termination
|
||||||
|
#define DDR_EMR_RTT_150 0x00000040 // DDR2 150 Ohm termination
|
||||||
|
// Output Drive Strength Values:
|
||||||
|
#define DDR_EMR_ODS_FULL 0x0 // DDR2 Full Drive Strength
|
||||||
|
#define DDR_EMR_ODS_HALF 0x1 // DDR2 Half Drive Strength
|
||||||
|
// OCD values
|
||||||
|
#define DDR_EMR_OCD_DEFAULT 0x7
|
||||||
|
#define DDR_EMR_OCD_NS 0x0
|
||||||
|
|
||||||
|
#define DDR_EMR_ODS_VAL DDR_EMR_ODS_FULL
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#define DmcWriteReg(reg,val) MmioWrite32(DmcBase + reg, val)
|
||||||
|
#define DmcReadReg(reg) MmioRead32(DmcBase + reg)
|
||||||
|
|
||||||
|
// Initialize PL341 Dynamic Memory Controller
|
||||||
|
VOID PL341DmcInit(struct pl341_dmc_config *config) {
|
||||||
|
UINTN DmcBase = config->base;
|
||||||
|
UINT32 i, chip, val32;
|
||||||
|
|
||||||
|
// Set config mode
|
||||||
|
DmcWriteReg(DMC_COMMAND_REG, DMC_COMMAND_CONFIGURE);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Setup the QoS AXI ID bits
|
||||||
|
//
|
||||||
|
|
||||||
|
if (config->has_qos) {
|
||||||
|
// CLCD AXIID = 000
|
||||||
|
DmcWriteReg(DMC_ID_0_CFG_REG, DMC_ID_CFG_QOS_ENABLE | DMC_ID_CFG_QOS_MIN);
|
||||||
|
|
||||||
|
// Default disable QoS
|
||||||
|
DmcWriteReg(DMC_ID_1_CFG_REG, DMC_ID_CFG_QOS_DISABLE);
|
||||||
|
DmcWriteReg(DMC_ID_2_CFG_REG, DMC_ID_CFG_QOS_DISABLE);
|
||||||
|
DmcWriteReg(DMC_ID_3_CFG_REG, DMC_ID_CFG_QOS_DISABLE);
|
||||||
|
DmcWriteReg(DMC_ID_4_CFG_REG, DMC_ID_CFG_QOS_DISABLE);
|
||||||
|
DmcWriteReg(DMC_ID_5_CFG_REG, DMC_ID_CFG_QOS_DISABLE);
|
||||||
|
DmcWriteReg(DMC_ID_6_CFG_REG, DMC_ID_CFG_QOS_DISABLE);
|
||||||
|
DmcWriteReg(DMC_ID_7_CFG_REG, DMC_ID_CFG_QOS_DISABLE);
|
||||||
|
DmcWriteReg(DMC_ID_8_CFG_REG, DMC_ID_CFG_QOS_DISABLE);
|
||||||
|
DmcWriteReg(DMC_ID_9_CFG_REG, DMC_ID_CFG_QOS_DISABLE);
|
||||||
|
DmcWriteReg(DMC_ID_10_CFG_REG, DMC_ID_CFG_QOS_DISABLE);
|
||||||
|
DmcWriteReg(DMC_ID_11_CFG_REG, DMC_ID_CFG_QOS_DISABLE);
|
||||||
|
DmcWriteReg(DMC_ID_12_CFG_REG, DMC_ID_CFG_QOS_DISABLE);
|
||||||
|
DmcWriteReg(DMC_ID_13_CFG_REG, DMC_ID_CFG_QOS_DISABLE);
|
||||||
|
DmcWriteReg(DMC_ID_14_CFG_REG, DMC_ID_CFG_QOS_DISABLE);
|
||||||
|
DmcWriteReg(DMC_ID_15_CFG_REG, DMC_ID_CFG_QOS_DISABLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Initialise memory controlller
|
||||||
|
//
|
||||||
|
DmcWriteReg(DMC_REFRESH_PRD_REG, config->refresh_prd);
|
||||||
|
DmcWriteReg(DMC_CAS_LATENCY_REG, config->cas_latency);
|
||||||
|
DmcWriteReg(DMC_WRITE_LATENCY_REG, config->write_latency);
|
||||||
|
DmcWriteReg(DMC_T_MRD_REG, config->t_mrd);
|
||||||
|
DmcWriteReg(DMC_T_RAS_REG, config->t_ras);
|
||||||
|
DmcWriteReg(DMC_T_RC_REG, config->t_rc);
|
||||||
|
DmcWriteReg(DMC_T_RCD_REG, config->t_rcd);
|
||||||
|
DmcWriteReg(DMC_T_RFC_REG, config->t_rfc);
|
||||||
|
DmcWriteReg(DMC_T_RP_REG, config->t_rp);
|
||||||
|
DmcWriteReg(DMC_T_RRD_REG, config->t_rrd);
|
||||||
|
DmcWriteReg(DMC_T_WR_REG, config->t_wr);
|
||||||
|
DmcWriteReg(DMC_T_WTR_REG, config->t_wtr);
|
||||||
|
DmcWriteReg(DMC_T_XP_REG, config->t_xp);
|
||||||
|
DmcWriteReg(DMC_T_XSR_REG, config->t_xsr);
|
||||||
|
DmcWriteReg(DMC_T_ESR_REG, config->t_esr);
|
||||||
|
DmcWriteReg(DMC_T_FAW_REG, config->t_faw);
|
||||||
|
|
||||||
|
// =======================================================================
|
||||||
|
// Initialise PL341 Mem Config Registers
|
||||||
|
// =======================================================================
|
||||||
|
|
||||||
|
// |======================================
|
||||||
|
// | Set PL341 Memory Config
|
||||||
|
// |======================================
|
||||||
|
DmcWriteReg(DMC_MEMORY_CONFIG_REG, config->memory_cfg);
|
||||||
|
|
||||||
|
// |======================================
|
||||||
|
// | Set PL341 Memory Config 2
|
||||||
|
// |======================================
|
||||||
|
DmcWriteReg(DMC_MEMORY_CFG2_REG, config->memory_cfg2);
|
||||||
|
|
||||||
|
// |======================================
|
||||||
|
// | Set PL341 Chip Select <n>
|
||||||
|
// |======================================
|
||||||
|
DmcWriteReg(DMC_CHIP_0_CFG_REG, config->chip_cfg0);
|
||||||
|
DmcWriteReg(DMC_CHIP_1_CFG_REG, config->chip_cfg1);
|
||||||
|
DmcWriteReg(DMC_CHIP_2_CFG_REG, config->chip_cfg2);
|
||||||
|
DmcWriteReg(DMC_CHIP_3_CFG_REG, config->chip_cfg3);
|
||||||
|
|
||||||
|
// |======================================
|
||||||
|
// | Set PL341 Memory Config 3
|
||||||
|
// |======================================
|
||||||
|
DmcWriteReg(DMC_MEMORY_CFG3_REG, config->memory_cfg3);
|
||||||
|
|
||||||
|
// |========================================================
|
||||||
|
// |Set Test Chip PHY Registers via PL341 User Config Reg
|
||||||
|
// |Note that user_cfgX registers are Write Only
|
||||||
|
// |
|
||||||
|
// |DLL Freq set = 250MHz - 266MHz
|
||||||
|
// |========================================================
|
||||||
|
DmcWriteReg(DMC_USER_0_CFG_REG, 0x7C924924);
|
||||||
|
|
||||||
|
// user_config2
|
||||||
|
// ------------
|
||||||
|
// Set defaults before calibrating the DDR2 buffer impendence
|
||||||
|
// -Disable ODT
|
||||||
|
// -Default drive strengths
|
||||||
|
DmcWriteReg(DMC_USER_2_CFG_REG, 0x40000198);
|
||||||
|
|
||||||
|
// |=======================================================
|
||||||
|
// |Auto calibrate the DDR2 buffers impendence
|
||||||
|
// |=======================================================
|
||||||
|
val32 = DmcReadReg(DMC_USER_STATUS_REG);
|
||||||
|
while (!(val32 & 0x100)) {
|
||||||
|
val32 = DmcReadReg(DMC_USER_STATUS_REG);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the output driven strength
|
||||||
|
DmcWriteReg(DMC_USER_2_CFG_REG, 0x40800000 |
|
||||||
|
(TC_UIOLHXC_VALUE << TC_UIOLHNC_SHIFT) |
|
||||||
|
(TC_UIOLHXC_VALUE << TC_UIOLHPC_SHIFT) |
|
||||||
|
(0x1 << TC_UIOHOCT_SHIFT) |
|
||||||
|
(0x1 << TC_UIOHSTOP_SHIFT));
|
||||||
|
|
||||||
|
// |======================================
|
||||||
|
// | Set PL341 Feature Control Register
|
||||||
|
// |======================================
|
||||||
|
// | Disable early BRESP - use to optimise CLCD performance
|
||||||
|
DmcWriteReg(DMC_FEATURE_CRTL_REG, 0x00000001);
|
||||||
|
|
||||||
|
//=================
|
||||||
|
// Config memories
|
||||||
|
//=================
|
||||||
|
|
||||||
|
for (chip = 0; chip <= config-> max_chip; chip++) {
|
||||||
|
// send nop
|
||||||
|
DmcWriteReg(DMC_DIRECT_CMD_REG, DMC_DIRECT_CMD_CHIP_ADDR(chip) | DMC_DIRECT_CMD_MEMCMD_NOP);
|
||||||
|
// pre-charge all
|
||||||
|
DmcWriteReg(DMC_DIRECT_CMD_REG, DMC_DIRECT_CMD_CHIP_ADDR(chip) | DMC_DIRECT_CMD_MEMCMD_PRECHARGEALL);
|
||||||
|
|
||||||
|
// delay
|
||||||
|
for (i = 0; i < 10; i++) {
|
||||||
|
val32 = DmcReadReg(DMC_STATUS_REG);
|
||||||
|
}
|
||||||
|
|
||||||
|
// set (EMR2) extended mode register 2
|
||||||
|
DmcWriteReg(DMC_DIRECT_CMD_REG,
|
||||||
|
DMC_DIRECT_CMD_CHIP_ADDR(chip) |
|
||||||
|
DMC_DIRECT_CMD_BANKADDR(2) |
|
||||||
|
DMC_DIRECT_CMD_MEMCMD_EXTMODEREG);
|
||||||
|
// set (EMR3) extended mode register 3
|
||||||
|
DmcWriteReg(DMC_DIRECT_CMD_REG,
|
||||||
|
DMC_DIRECT_CMD_CHIP_ADDR(chip) |
|
||||||
|
DMC_DIRECT_CMD_BANKADDR(3) |
|
||||||
|
DMC_DIRECT_CMD_MEMCMD_EXTMODEREG);
|
||||||
|
|
||||||
|
// =================================
|
||||||
|
// set (EMR) Extended Mode Register
|
||||||
|
// ==================================
|
||||||
|
// Put into OCD default state
|
||||||
|
DmcWriteReg(DMC_DIRECT_CMD_REG,
|
||||||
|
DMC_DIRECT_CMD_CHIP_ADDR(chip) |
|
||||||
|
DMC_DIRECT_CMD_BANKADDR(1) |
|
||||||
|
DMC_DIRECT_CMD_MEMCMD_EXTMODEREG);
|
||||||
|
|
||||||
|
// ===========================================================
|
||||||
|
// set (MR) mode register - With DLL reset
|
||||||
|
// ===========================================================
|
||||||
|
// Burst Length = 4 (010)
|
||||||
|
// Burst Type = Seq (0)
|
||||||
|
// Latency = 4 (100)
|
||||||
|
// Test mode = Off (0)
|
||||||
|
// DLL reset = Yes (1)
|
||||||
|
// Wr Recovery = 4 (011)
|
||||||
|
// PD = Normal (0)
|
||||||
|
DmcWriteReg(DMC_DIRECT_CMD_REG, DMC_DIRECT_CMD_CHIP_ADDR(chip) | 0x00080742);
|
||||||
|
|
||||||
|
// pre-charge all
|
||||||
|
DmcWriteReg(DMC_DIRECT_CMD_REG, DMC_DIRECT_CMD_CHIP_ADDR(chip) | DMC_DIRECT_CMD_MEMCMD_PRECHARGEALL);
|
||||||
|
// auto-refresh
|
||||||
|
DmcWriteReg(DMC_DIRECT_CMD_REG, DMC_DIRECT_CMD_CHIP_ADDR(chip) | DMC_DIRECT_CMD_MEMCMD_AUTOREFRESH);
|
||||||
|
// auto-refresh
|
||||||
|
DmcWriteReg(DMC_DIRECT_CMD_REG, DMC_DIRECT_CMD_CHIP_ADDR(chip) | DMC_DIRECT_CMD_MEMCMD_AUTOREFRESH);
|
||||||
|
|
||||||
|
// delay
|
||||||
|
for (i = 0; i < 10; i++) {
|
||||||
|
val32 = DmcReadReg(DMC_STATUS_REG);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ===========================================================
|
||||||
|
// set (MR) mode register - Without DLL reset
|
||||||
|
// ===========================================================
|
||||||
|
// auto-refresh
|
||||||
|
DmcWriteReg(DMC_DIRECT_CMD_REG, DMC_DIRECT_CMD_CHIP_ADDR(chip) | DMC_DIRECT_CMD_MEMCMD_AUTOREFRESH);
|
||||||
|
DmcWriteReg(DMC_DIRECT_CMD_REG, DMC_DIRECT_CMD_CHIP_ADDR(chip) | 0x00080642);
|
||||||
|
|
||||||
|
// delay
|
||||||
|
for (i = 0; i < 10; i++) {
|
||||||
|
val32 = DmcReadReg(DMC_STATUS_REG);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ======================================================
|
||||||
|
// set (EMR) extended mode register - Enable OCD defaults
|
||||||
|
// ======================================================
|
||||||
|
val32 = 0; //NOP
|
||||||
|
DmcWriteReg(DMC_DIRECT_CMD_REG, DMC_DIRECT_CMD_CHIP_ADDR(chip) | 0x00090000 |
|
||||||
|
(DDR_EMR_OCD_DEFAULT << DDR_EMR_OCD_SHIFT) |
|
||||||
|
DDR_EMR_RTT_75R |
|
||||||
|
(DDR_EMR_ODS_VAL << DDR_EMR_ODS_MASK));
|
||||||
|
|
||||||
|
// delay
|
||||||
|
for (i = 0; i < 10; i++) {
|
||||||
|
val32 = DmcReadReg(DMC_STATUS_REG);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set (EMR) extended mode register - OCD Exit
|
||||||
|
val32 = 0; //NOP
|
||||||
|
DmcWriteReg(DMC_DIRECT_CMD_REG, DMC_DIRECT_CMD_CHIP_ADDR(chip) | 0x00090000 |
|
||||||
|
(DDR_EMR_OCD_NS << DDR_EMR_OCD_SHIFT) |
|
||||||
|
DDR_EMR_RTT_75R |
|
||||||
|
(DDR_EMR_ODS_VAL << DDR_EMR_ODS_MASK));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------
|
||||||
|
// go command
|
||||||
|
DmcWriteReg(DMC_COMMAND_REG, DMC_COMMAND_GO);
|
||||||
|
|
||||||
|
// wait for ready
|
||||||
|
val32 = DmcReadReg(DMC_STATUS_REG);
|
||||||
|
while (!(val32 & DMC_STATUS_READY)) {
|
||||||
|
val32 = DmcReadReg(DMC_STATUS_REG);
|
||||||
|
}
|
||||||
|
}
|
29
ArmPkg/Drivers/PL34xDmc/PL341Dmc.inf
Normal file
29
ArmPkg/Drivers/PL34xDmc/PL341Dmc.inf
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
#/* @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 = PL341Dmc
|
||||||
|
FILE_GUID = edf8da40-aad1-11df-a1f4-0002a5d5c51b
|
||||||
|
MODULE_TYPE = BASE
|
||||||
|
VERSION_STRING = 1.0
|
||||||
|
LIBRARY_CLASS = PL341DmcLib
|
||||||
|
|
||||||
|
[Sources]
|
||||||
|
PL341Dmc.c
|
||||||
|
|
||||||
|
[Packages]
|
||||||
|
ArmPkg/ArmPkg.dec
|
||||||
|
MdePkg/MdePkg.dec
|
||||||
|
|
||||||
|
[FixedPcd]
|
189
ArmPkg/Drivers/PL35xSmc/InitializeSMC.S
Normal file
189
ArmPkg/Drivers/PL35xSmc/InitializeSMC.S
Normal file
@ -0,0 +1,189 @@
|
|||||||
|
#
|
||||||
|
# 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 <Library/PcdLib.h>
|
||||||
|
#include <AutoGen.h>
|
||||||
|
#include <AsmMacroIoLib.h>
|
||||||
|
|
||||||
|
#Start of the code section
|
||||||
|
.text
|
||||||
|
|
||||||
|
#Maintain 8 byte alignment
|
||||||
|
.align 3
|
||||||
|
|
||||||
|
#Export Initialize SMC symbol
|
||||||
|
GCC_ASM_EXPORT(InitializeSMC)
|
||||||
|
|
||||||
|
# Static memory configuation definitions for SMC
|
||||||
|
.set SmcDirectCmd, 0x10
|
||||||
|
.set SmcSetCycles, 0x14
|
||||||
|
.set SmcSetOpMode, 0x18
|
||||||
|
|
||||||
|
# CS0 CS0-Interf0 NOR1 flash on the motherboard
|
||||||
|
# CS1 CS1-Interf0 Reserved for the motherboard
|
||||||
|
# CS2 CS2-Interf0 SRAM on the motherboard
|
||||||
|
# CS3 CS3-Interf0 memory-mapped Ethernet and USB controllers on the motherboard
|
||||||
|
# CS4 CS0-Interf1 NOR2 flash on the motherboard
|
||||||
|
# CS5 CS1-Interf1 memory-mapped peripherals
|
||||||
|
# CS6 CS2-Interf1 memory-mapped peripherals
|
||||||
|
# CS7 CS3-Interf1 system memory-mapped peripherals on the motherboard.
|
||||||
|
|
||||||
|
# IN r1 SmcBase
|
||||||
|
# IN r2 VideoSRamBase
|
||||||
|
# NOTE: This code is been called before any stack has been setup. It means some registers
|
||||||
|
# could be overwritten (case of 'r0')
|
||||||
|
|
||||||
|
|
||||||
|
ASM_PFX(InitializeSMC):
|
||||||
|
#
|
||||||
|
# Setup NOR1 (CS0-Interface0)
|
||||||
|
#
|
||||||
|
|
||||||
|
#Write to set_cycle register(holding register for NOR 1 cycle register or NAND cycle register)
|
||||||
|
#Read cycle timeout = 0xA (0:3)
|
||||||
|
#Write cycle timeout = 0x3(7:4)
|
||||||
|
#OE Assertion Delay = 0x9(11:8)
|
||||||
|
#WE Assertion delay = 0x3(15:12)
|
||||||
|
#Page cycle timeout = 0x2(19:16)
|
||||||
|
LoadConstantToReg (0x0002393A,r0) @ldr r0, = 0x0002393A
|
||||||
|
str r0, [r1, #SmcSetCycles]
|
||||||
|
|
||||||
|
#Write to set_opmode register(holding register for NOR 1 opomode register or NAND opmode register)
|
||||||
|
# 0x00000002 = MemoryWidth: 32bit
|
||||||
|
# 0x00000028 = ReadMemoryBurstLength:continuous
|
||||||
|
# 0x00000280 = WriteMemoryBurstLength:continuous
|
||||||
|
# 0x00000800 = Set Address Valid
|
||||||
|
LoadConstantToReg (0x00000AAA,r0) @ldr r0, = 0x00000AAA
|
||||||
|
str r0, [r1, #SmcSetOpMode]
|
||||||
|
|
||||||
|
#Write to direct_cmd register so that the NOR 1 registers(set-cycles and opmode) are updated with holding registers
|
||||||
|
# 0x00000000 = ChipSelect0-Interface 0
|
||||||
|
# 0x00400000 = CmdTypes: UpdateRegs
|
||||||
|
LoadConstantToReg (0x00400000,r0) @ldr r0, = 0x00400000
|
||||||
|
str r0, [r1, #SmcDirectCmd]
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Setup SRAM (CS2-Interface0)
|
||||||
|
#
|
||||||
|
LoadConstantToReg (0x00027158,r0) @ldr r0, = 0x00027158
|
||||||
|
str r0, [r1, #SmcSetCycles]
|
||||||
|
|
||||||
|
# 0x00000002 = MemoryWidth: 32bit
|
||||||
|
# 0x00000800 = Set Address Valid
|
||||||
|
LoadConstantToReg (0x00000802,r0) @ldr r0, = 0x00000802
|
||||||
|
str r0, [r1, #SmcSetOpMode]
|
||||||
|
|
||||||
|
# 0x01000000 = ChipSelect2-Interface 0
|
||||||
|
# 0x00400000 = CmdTypes: UpdateRegs
|
||||||
|
LoadConstantToReg (0x01400000,r0) @ldr r0, = 0x01400000
|
||||||
|
str r0, [r1, #SmcDirectCmd]
|
||||||
|
|
||||||
|
#
|
||||||
|
# USB/Eth/VRAM (CS3-Interface0)
|
||||||
|
#
|
||||||
|
LoadConstantToReg (0x000CD2AA,r0) @ldr r0, = 0x000CD2AA
|
||||||
|
str r0, [r1, #SmcSetCycles]
|
||||||
|
|
||||||
|
# 0x00000002 = MemoryWidth: 32bit
|
||||||
|
# 0x00000004 = Memory reads are synchronous
|
||||||
|
# 0x00000040 = Memory writes are synchronous
|
||||||
|
LoadConstantToReg (0x00000046,r0) @ldr r0, = 0x00000046
|
||||||
|
str r0, [r1, #SmcSetOpMode]
|
||||||
|
|
||||||
|
# 0x01800000 = ChipSelect3-Interface 0
|
||||||
|
# 0x00400000 = CmdTypes: UpdateRegs
|
||||||
|
LoadConstantToReg (0x01C00000,r0) @ldr r0, = 0x01C00000
|
||||||
|
str r0, [r1, #SmcDirectCmd]
|
||||||
|
|
||||||
|
#
|
||||||
|
# Setup NOR3 (CS0-Interface1)
|
||||||
|
#
|
||||||
|
LoadConstantToReg (0x0002393A,r0) @ldr r0, = 0x0002393A
|
||||||
|
str r0, [r1, #SmcSetCycles]
|
||||||
|
|
||||||
|
# 0x00000002 = MemoryWidth: 32bit
|
||||||
|
# 0x00000028 = ReadMemoryBurstLength:continuous
|
||||||
|
# 0x00000280 = WriteMemoryBurstLength:continuous
|
||||||
|
# 0x00000800 = Set Address Valid
|
||||||
|
LoadConstantToReg (0x00000AAA,r0) @ldr r0, = 0x00000AAA
|
||||||
|
str r0, [r1, #SmcSetOpMode]
|
||||||
|
|
||||||
|
# 0x02000000 = ChipSelect0-Interface 1
|
||||||
|
# 0x00400000 = CmdTypes: UpdateRegs
|
||||||
|
LoadConstantToReg (0x02400000,r0) @ldr r0, = 0x02400000
|
||||||
|
str r0, [r1, #SmcDirectCmd]
|
||||||
|
|
||||||
|
#
|
||||||
|
# Setup Peripherals (CS3-Interface1)
|
||||||
|
#
|
||||||
|
LoadConstantToReg (0x00025156,r0) @ldr r0, = 0x00025156
|
||||||
|
str r0, [r1, #SmcSetCycles]
|
||||||
|
|
||||||
|
# 0x00000002 = MemoryWidth: 32bit
|
||||||
|
# 0x00000004 = Memory reads are synchronous
|
||||||
|
# 0x00000040 = Memory writes are synchronous
|
||||||
|
LoadConstantToReg (0x00000046,r0) @ldr r0, = 0x00000046
|
||||||
|
str r0, [r1, #SmcSetOpMode]
|
||||||
|
|
||||||
|
# 0x03800000 = ChipSelect3-Interface 1
|
||||||
|
# 0x00400000 = CmdTypes: UpdateRegs
|
||||||
|
LoadConstantToReg (0x03C00000,r0) @ldr r0, = 0x03C00000
|
||||||
|
str r0, [r1, #SmcDirectCmd]
|
||||||
|
|
||||||
|
#
|
||||||
|
# Setup VRAM (CS1-Interface0)
|
||||||
|
#
|
||||||
|
LoadConstantToReg (0x00049249,r0) @ldr r0, = 0x00049249
|
||||||
|
str r0, [r1, #SmcSetCycles]
|
||||||
|
|
||||||
|
# 0x00000002 = MemoryWidth: 32bit
|
||||||
|
# 0x00000004 = Memory reads are synchronous
|
||||||
|
# 0x00000040 = Memory writes are synchronous
|
||||||
|
LoadConstantToReg (0x00000046,r0) @ldr r0, = 0x00000046
|
||||||
|
str r0, [r1, #SmcSetOpMode]
|
||||||
|
|
||||||
|
# 0x00800000 = ChipSelect1-Interface 0
|
||||||
|
# 0x00400000 = CmdTypes: UpdateRegs
|
||||||
|
LoadConstantToReg (0x00C00000,r0) @ldr r0, = 0x00C00000
|
||||||
|
str r0, [r1, #SmcDirectCmd]
|
||||||
|
|
||||||
|
#
|
||||||
|
# Page mode setup for VRAM
|
||||||
|
#
|
||||||
|
#read current state
|
||||||
|
ldr r0, [r2, #0]
|
||||||
|
ldr r0, [r2, #0]
|
||||||
|
LoadConstantToReg (0x00000000,r0) @ldr r0, = 0x00000000
|
||||||
|
str r0, [r2, #0]
|
||||||
|
ldr r0, [r2, #0]
|
||||||
|
|
||||||
|
#enable page mode
|
||||||
|
ldr r0, [r2, #0]
|
||||||
|
ldr r0, [r2, #0]
|
||||||
|
LoadConstantToReg (0x00000000,r0) @ldr r0, = 0x00000000
|
||||||
|
str r0, [r2, #0]
|
||||||
|
LoadConstantToReg (0x00900090,r0) @ldr r0, = 0x00900090
|
||||||
|
str r0, [r2, #0]
|
||||||
|
|
||||||
|
#confirm page mode enabled
|
||||||
|
ldr r0, [r2, #0]
|
||||||
|
ldr r0, [r2, #0]
|
||||||
|
LoadConstantToReg (0x00000000,r0) @ldr r0, = 0x00000000
|
||||||
|
str r0, [r2, #0]
|
||||||
|
ldr r0, [r2, #0]
|
||||||
|
|
||||||
|
bx lr
|
||||||
|
|
||||||
|
ASM_FUNCTION_REMOVE_IF_UNREFERENCED
|
183
ArmPkg/Drivers/PL35xSmc/InitializeSMC.asm
Normal file
183
ArmPkg/Drivers/PL35xSmc/InitializeSMC.asm
Normal file
@ -0,0 +1,183 @@
|
|||||||
|
//
|
||||||
|
// 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 <Library/PcdLib.h>
|
||||||
|
#include <AutoGen.h>
|
||||||
|
|
||||||
|
INCLUDE AsmMacroIoLib.inc
|
||||||
|
|
||||||
|
EXPORT InitializeSMC
|
||||||
|
|
||||||
|
PRESERVE8
|
||||||
|
AREA ModuleInitializeSMC, CODE, READONLY
|
||||||
|
|
||||||
|
// Static memory configuation definitions for SMC
|
||||||
|
SmcDirectCmd EQU 0x10
|
||||||
|
SmcSetCycles EQU 0x14
|
||||||
|
SmcSetOpMode EQU 0x18
|
||||||
|
|
||||||
|
// CS0 CS0-Interf0 NOR1 flash on the motherboard
|
||||||
|
// CS1 CS1-Interf0 Reserved for the motherboard
|
||||||
|
// CS2 CS2-Interf0 SRAM on the motherboard
|
||||||
|
// CS3 CS3-Interf0 memory-mapped Ethernet and USB controllers on the motherboard
|
||||||
|
// CS4 CS0-Interf1 NOR2 flash on the motherboard
|
||||||
|
// CS5 CS1-Interf1 memory-mapped peripherals
|
||||||
|
// CS6 CS2-Interf1 memory-mapped peripherals
|
||||||
|
// CS7 CS3-Interf1 system memory-mapped peripherals on the motherboard.
|
||||||
|
|
||||||
|
// IN r1 SmcBase
|
||||||
|
// IN r2 VideoSRamBase
|
||||||
|
// NOTE: This code is been called before any stack has been setup. It means some registers
|
||||||
|
// could be overwritten (case of 'r0')
|
||||||
|
InitializeSMC
|
||||||
|
//
|
||||||
|
// Setup NOR1 (CS0-Interface0)
|
||||||
|
//
|
||||||
|
|
||||||
|
//Write to set_cycle register(holding register for NOR 1 cycle register or NAND cycle register)
|
||||||
|
//Read cycle timeout = 0xA (0:3)
|
||||||
|
//Write cycle timeout = 0x3(7:4)
|
||||||
|
//OE Assertion Delay = 0x9(11:8)
|
||||||
|
//WE Assertion delay = 0x3(15:12)
|
||||||
|
//Page cycle timeout = 0x2(19:16)
|
||||||
|
ldr r0, = 0x0002393A
|
||||||
|
str r0, [r1, #SmcSetCycles]
|
||||||
|
|
||||||
|
//Write to set_opmode register(holding register for NOR 1 opomode register or NAND opmode register)
|
||||||
|
// 0x00000002 = MemoryWidth: 32bit
|
||||||
|
// 0x00000028 = ReadMemoryBurstLength:continuous
|
||||||
|
// 0x00000280 = WriteMemoryBurstLength:continuous
|
||||||
|
// 0x00000800 = Set Address Valid
|
||||||
|
ldr r0, = 0x00000AAA
|
||||||
|
str r0, [r1, #SmcSetOpMode]
|
||||||
|
|
||||||
|
//Write to direct_cmd register so that the NOR 1 registers(set-cycles and opmode) are updated with holding registers
|
||||||
|
// 0x00000000 = ChipSelect0-Interface 0
|
||||||
|
// 0x00400000 = CmdTypes: UpdateRegs
|
||||||
|
ldr r0, = 0x00400000
|
||||||
|
str r0, [r1, #SmcDirectCmd]
|
||||||
|
|
||||||
|
//
|
||||||
|
// Setup SRAM (CS2-Interface0)
|
||||||
|
//
|
||||||
|
ldr r0, = 0x00027158
|
||||||
|
str r0, [r1, #SmcSetCycles]
|
||||||
|
|
||||||
|
// 0x00000002 = MemoryWidth: 32bit
|
||||||
|
// 0x00000800 = Set Address Valid
|
||||||
|
ldr r0, = 0x00000802
|
||||||
|
str r0, [r1, #SmcSetOpMode]
|
||||||
|
|
||||||
|
// 0x01000000 = ChipSelect2-Interface 0
|
||||||
|
// 0x00400000 = CmdTypes: UpdateRegs
|
||||||
|
ldr r0, = 0x01400000
|
||||||
|
str r0, [r1, #SmcDirectCmd]
|
||||||
|
|
||||||
|
//
|
||||||
|
// USB/Eth/VRAM (CS3-Interface0)
|
||||||
|
//
|
||||||
|
ldr r0, = 0x000CD2AA
|
||||||
|
str r0, [r1, #SmcSetCycles]
|
||||||
|
|
||||||
|
// 0x00000002 = MemoryWidth: 32bit
|
||||||
|
// 0x00000004 = Memory reads are synchronous
|
||||||
|
// 0x00000040 = Memory writes are synchronous
|
||||||
|
ldr r0, = 0x00000046
|
||||||
|
str r0, [r1, #SmcSetOpMode]
|
||||||
|
|
||||||
|
// 0x01800000 = ChipSelect3-Interface 0
|
||||||
|
// 0x00400000 = CmdTypes: UpdateRegs
|
||||||
|
ldr r0, = 0x01C00000
|
||||||
|
str r0, [r1, #SmcDirectCmd]
|
||||||
|
|
||||||
|
//
|
||||||
|
// Setup NOR3 (CS0-Interface1)
|
||||||
|
//
|
||||||
|
ldr r0, = 0x0002393A
|
||||||
|
str r0, [r1, #SmcSetCycles]
|
||||||
|
|
||||||
|
// 0x00000002 = MemoryWidth: 32bit
|
||||||
|
// 0x00000028 = ReadMemoryBurstLength:continuous
|
||||||
|
// 0x00000280 = WriteMemoryBurstLength:continuous
|
||||||
|
// 0x00000800 = Set Address Valid
|
||||||
|
ldr r0, = 0x00000AAA
|
||||||
|
str r0, [r1, #SmcSetOpMode]
|
||||||
|
|
||||||
|
// 0x02000000 = ChipSelect0-Interface 1
|
||||||
|
// 0x00400000 = CmdTypes: UpdateRegs
|
||||||
|
ldr r0, = 0x02400000
|
||||||
|
str r0, [r1, #SmcDirectCmd]
|
||||||
|
|
||||||
|
//
|
||||||
|
// Setup Peripherals (CS3-Interface1)
|
||||||
|
//
|
||||||
|
ldr r0, = 0x00025156
|
||||||
|
str r0, [r1, #SmcSetCycles]
|
||||||
|
|
||||||
|
// 0x00000002 = MemoryWidth: 32bit
|
||||||
|
// 0x00000004 = Memory reads are synchronous
|
||||||
|
// 0x00000040 = Memory writes are synchronous
|
||||||
|
ldr r0, = 0x00000046
|
||||||
|
str r0, [r1, #SmcSetOpMode]
|
||||||
|
|
||||||
|
// 0x03800000 = ChipSelect3-Interface 1
|
||||||
|
// 0x00400000 = CmdTypes: UpdateRegs
|
||||||
|
ldr r0, = 0x03C00000
|
||||||
|
str r0, [r1, #SmcDirectCmd]
|
||||||
|
|
||||||
|
//
|
||||||
|
// Setup VRAM (CS1-Interface0)
|
||||||
|
//
|
||||||
|
ldr r0, = 0x00049249
|
||||||
|
str r0, [r1, #SmcSetCycles]
|
||||||
|
|
||||||
|
// 0x00000002 = MemoryWidth: 32bit
|
||||||
|
// 0x00000004 = Memory reads are synchronous
|
||||||
|
// 0x00000040 = Memory writes are synchronous
|
||||||
|
ldr r0, = 0x00000046
|
||||||
|
str r0, [r1, #SmcSetOpMode]
|
||||||
|
|
||||||
|
// 0x00800000 = ChipSelect1-Interface 0
|
||||||
|
// 0x00400000 = CmdTypes: UpdateRegs
|
||||||
|
ldr r0, = 0x00C00000
|
||||||
|
str r0, [r1, #SmcDirectCmd]
|
||||||
|
|
||||||
|
//
|
||||||
|
// Page mode setup for VRAM
|
||||||
|
//
|
||||||
|
//read current state
|
||||||
|
ldr r0, [r2, #0]
|
||||||
|
ldr r0, [r2, #0]
|
||||||
|
ldr r0, = 0x00000000
|
||||||
|
str r0, [r2, #0]
|
||||||
|
ldr r0, [r2, #0]
|
||||||
|
|
||||||
|
//enable page mode
|
||||||
|
ldr r0, [r2, #0]
|
||||||
|
ldr r0, [r2, #0]
|
||||||
|
ldr r0, = 0x00000000
|
||||||
|
str r0, [r2, #0]
|
||||||
|
ldr r0, = 0x00900090
|
||||||
|
str r0, [r2, #0]
|
||||||
|
|
||||||
|
//confirm page mode enabled
|
||||||
|
ldr r0, [r2, #0]
|
||||||
|
ldr r0, [r2, #0]
|
||||||
|
ldr r0, = 0x00000000
|
||||||
|
str r0, [r2, #0]
|
||||||
|
ldr r0, [r2, #0]
|
||||||
|
|
||||||
|
bx lr
|
||||||
|
|
||||||
|
END
|
30
ArmPkg/Drivers/PL35xSmc/PL354SmcSec.inf
Normal file
30
ArmPkg/Drivers/PL35xSmc/PL354SmcSec.inf
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
#/* @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 = PL354SmcSec
|
||||||
|
FILE_GUID = 10952220-aa32-11df-a438-0002a5d5c51b
|
||||||
|
MODULE_TYPE = SEC
|
||||||
|
VERSION_STRING = 1.0
|
||||||
|
LIBRARY_CLASS = PL354SmcSecLib
|
||||||
|
|
||||||
|
[Sources.common]
|
||||||
|
InitializeSMC.asm | RVCT
|
||||||
|
InitializeSMC.S | GCC
|
||||||
|
|
||||||
|
[Packages]
|
||||||
|
ArmPkg/ArmPkg.dec
|
||||||
|
MdePkg/MdePkg.dec
|
||||||
|
|
||||||
|
[FixedPcd]
|
435
ArmPkg/Drivers/PL390Gic/PL390GicDxe.c
Normal file
435
ArmPkg/Drivers/PL390Gic/PL390GicDxe.c
Normal file
@ -0,0 +1,435 @@
|
|||||||
|
/*++
|
||||||
|
|
||||||
|
Copyright (c) 2009, Hewlett-Packard Company. All rights reserved.<BR>
|
||||||
|
Portions copyright (c) 2010, 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.
|
||||||
|
|
||||||
|
Module Name:
|
||||||
|
|
||||||
|
Gic.c
|
||||||
|
|
||||||
|
Abstract:
|
||||||
|
|
||||||
|
Driver implementing the GIC interrupt controller protocol
|
||||||
|
|
||||||
|
--*/
|
||||||
|
|
||||||
|
#include <PiDxe.h>
|
||||||
|
|
||||||
|
#include <Library/BaseLib.h>
|
||||||
|
#include <Library/DebugLib.h>
|
||||||
|
#include <Library/BaseMemoryLib.h>
|
||||||
|
#include <Library/UefiBootServicesTableLib.h>
|
||||||
|
#include <Library/UefiLib.h>
|
||||||
|
#include <Library/PcdLib.h>
|
||||||
|
#include <Library/IoLib.h>
|
||||||
|
|
||||||
|
#include <Protocol/Cpu.h>
|
||||||
|
#include <Protocol/HardwareInterrupt.h>
|
||||||
|
|
||||||
|
#include <Drivers/PL390Gic.h>
|
||||||
|
|
||||||
|
// number of 32-bit registers needed to represent those interrupts as a bit
|
||||||
|
// (used for enable set, enable clear, pending set, pending clear, and active regs)
|
||||||
|
#define GIC_NUM_REG_PER_INT_BITS (PcdGet32(PcdGicNumInterrupts) / 32)
|
||||||
|
|
||||||
|
// number of 32-bit registers needed to represent those interrupts as two bits
|
||||||
|
// (used for configuration reg)
|
||||||
|
#define GIC_NUM_REG_PER_INT_CFG (PcdGet32(PcdGicNumInterrupts) / 16)
|
||||||
|
|
||||||
|
// number of 32-bit registers needed to represent interrupts as 8-bit priority field
|
||||||
|
// (used for priority regs)
|
||||||
|
#define GIC_NUM_REG_PER_INT_BYTES (PcdGet32(PcdGicNumInterrupts) / 4)
|
||||||
|
|
||||||
|
#define GIC_DEFAULT_PRIORITY 0x80
|
||||||
|
|
||||||
|
extern EFI_HARDWARE_INTERRUPT_PROTOCOL gHardwareInterruptProtocol;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Notifications
|
||||||
|
//
|
||||||
|
VOID *CpuProtocolNotificationToken = NULL;
|
||||||
|
EFI_EVENT CpuProtocolNotificationEvent = (EFI_EVENT)NULL;
|
||||||
|
EFI_EVENT EfiExitBootServicesEvent = (EFI_EVENT)NULL;
|
||||||
|
|
||||||
|
HARDWARE_INTERRUPT_HANDLER gRegisteredInterruptHandlers[FixedPcdGet32(PcdGicNumInterrupts)];
|
||||||
|
|
||||||
|
/**
|
||||||
|
Register Handler for the specified interrupt source.
|
||||||
|
|
||||||
|
@param This Instance pointer for this protocol
|
||||||
|
@param Source Hardware source of the interrupt
|
||||||
|
@param Handler Callback for interrupt. NULL to unregister
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS Source was updated to support Handler.
|
||||||
|
@retval EFI_DEVICE_ERROR Hardware could not be programmed.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
RegisterInterruptSource (
|
||||||
|
IN EFI_HARDWARE_INTERRUPT_PROTOCOL *This,
|
||||||
|
IN HARDWARE_INTERRUPT_SOURCE Source,
|
||||||
|
IN HARDWARE_INTERRUPT_HANDLER Handler
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (Source > PcdGet32(PcdGicNumInterrupts)) {
|
||||||
|
ASSERT(FALSE);
|
||||||
|
return EFI_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((Handler == NULL) && (gRegisteredInterruptHandlers[Source] == NULL)) {
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((Handler != NULL) && (gRegisteredInterruptHandlers[Source] != NULL)) {
|
||||||
|
return EFI_ALREADY_STARTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
gRegisteredInterruptHandlers[Source] = Handler;
|
||||||
|
return This->EnableInterruptSource(This, Source);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Enable interrupt source Source.
|
||||||
|
|
||||||
|
@param This Instance pointer for this protocol
|
||||||
|
@param Source Hardware source of the interrupt
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS Source interrupt enabled.
|
||||||
|
@retval EFI_DEVICE_ERROR Hardware could not be programmed.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
EnableInterruptSource (
|
||||||
|
IN EFI_HARDWARE_INTERRUPT_PROTOCOL *This,
|
||||||
|
IN HARDWARE_INTERRUPT_SOURCE Source
|
||||||
|
)
|
||||||
|
{
|
||||||
|
UINT32 RegOffset;
|
||||||
|
UINTN RegShift;
|
||||||
|
|
||||||
|
if (Source > PcdGet32(PcdGicNumInterrupts)) {
|
||||||
|
ASSERT(FALSE);
|
||||||
|
return EFI_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
// calculate enable register offset and bit position
|
||||||
|
RegOffset = Source / 32;
|
||||||
|
RegShift = Source % 32;
|
||||||
|
|
||||||
|
// write set-enable register
|
||||||
|
MmioWrite32 (PcdGet32(PcdGicDistributorBase) + GIC_ICDISER+(4*RegOffset), 1 << RegShift);
|
||||||
|
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Disable interrupt source Source.
|
||||||
|
|
||||||
|
@param This Instance pointer for this protocol
|
||||||
|
@param Source Hardware source of the interrupt
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS Source interrupt disabled.
|
||||||
|
@retval EFI_DEVICE_ERROR Hardware could not be programmed.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
DisableInterruptSource (
|
||||||
|
IN EFI_HARDWARE_INTERRUPT_PROTOCOL *This,
|
||||||
|
IN HARDWARE_INTERRUPT_SOURCE Source
|
||||||
|
)
|
||||||
|
{
|
||||||
|
UINT32 RegOffset;
|
||||||
|
UINTN RegShift;
|
||||||
|
|
||||||
|
if (Source > PcdGet32(PcdGicNumInterrupts)) {
|
||||||
|
ASSERT(FALSE);
|
||||||
|
return EFI_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
// calculate enable register offset and bit position
|
||||||
|
RegOffset = Source / 32;
|
||||||
|
RegShift = Source % 32;
|
||||||
|
|
||||||
|
// write set-enable register
|
||||||
|
MmioWrite32 (PcdGet32(PcdGicDistributorBase) + GIC_ICDICER+(4*RegOffset), 1 << RegShift);
|
||||||
|
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Return current state of interrupt source Source.
|
||||||
|
|
||||||
|
@param This Instance pointer for this protocol
|
||||||
|
@param Source Hardware source of the interrupt
|
||||||
|
@param InterruptState TRUE: source enabled, FALSE: source disabled.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS InterruptState is valid
|
||||||
|
@retval EFI_DEVICE_ERROR InterruptState is not valid
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
GetInterruptSourceState (
|
||||||
|
IN EFI_HARDWARE_INTERRUPT_PROTOCOL *This,
|
||||||
|
IN HARDWARE_INTERRUPT_SOURCE Source,
|
||||||
|
IN BOOLEAN *InterruptState
|
||||||
|
)
|
||||||
|
{
|
||||||
|
UINT32 RegOffset;
|
||||||
|
UINTN RegShift;
|
||||||
|
|
||||||
|
if (Source > PcdGet32(PcdGicNumInterrupts)) {
|
||||||
|
ASSERT(FALSE);
|
||||||
|
return EFI_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
// calculate enable register offset and bit position
|
||||||
|
RegOffset = Source / 32;
|
||||||
|
RegShift = Source % 32;
|
||||||
|
|
||||||
|
if ((MmioRead32 (PcdGet32(PcdGicDistributorBase) + GIC_ICDISER+(4*RegOffset)) & (1<<RegShift)) == 0) {
|
||||||
|
*InterruptState = FALSE;
|
||||||
|
} else {
|
||||||
|
*InterruptState = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Signal to the hardware that the End Of Intrrupt state
|
||||||
|
has been reached.
|
||||||
|
|
||||||
|
@param This Instance pointer for this protocol
|
||||||
|
@param Source Hardware source of the interrupt
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS Source interrupt EOI'ed.
|
||||||
|
@retval EFI_DEVICE_ERROR Hardware could not be programmed.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
EndOfInterrupt (
|
||||||
|
IN EFI_HARDWARE_INTERRUPT_PROTOCOL *This,
|
||||||
|
IN HARDWARE_INTERRUPT_SOURCE Source
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (Source > PcdGet32(PcdGicNumInterrupts)) {
|
||||||
|
ASSERT(FALSE);
|
||||||
|
return EFI_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
MmioWrite32 (PcdGet32(PcdGicInterruptInterfaceBase) + GIC_ICCEIOR, Source);
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
EFI_CPU_INTERRUPT_HANDLER that is called when a processor interrupt occurs.
|
||||||
|
|
||||||
|
@param InterruptType Defines the type of interrupt or exception that
|
||||||
|
occurred on the processor.This parameter is processor architecture specific.
|
||||||
|
@param SystemContext A pointer to the processor context when
|
||||||
|
the interrupt occurred on the processor.
|
||||||
|
|
||||||
|
@return None
|
||||||
|
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
EFIAPI
|
||||||
|
IrqInterruptHandler (
|
||||||
|
IN EFI_EXCEPTION_TYPE InterruptType,
|
||||||
|
IN EFI_SYSTEM_CONTEXT SystemContext
|
||||||
|
)
|
||||||
|
{
|
||||||
|
UINT32 GicInterrupt;
|
||||||
|
HARDWARE_INTERRUPT_HANDLER InterruptHandler;
|
||||||
|
|
||||||
|
GicInterrupt = MmioRead32 (PcdGet32(PcdGicInterruptInterfaceBase) + GIC_ICCIAR);
|
||||||
|
if (GicInterrupt >= PcdGet32(PcdGicNumInterrupts)) {
|
||||||
|
MmioWrite32 (PcdGet32(PcdGicInterruptInterfaceBase) + GIC_ICCEIOR, GicInterrupt);
|
||||||
|
}
|
||||||
|
|
||||||
|
InterruptHandler = gRegisteredInterruptHandlers[GicInterrupt];
|
||||||
|
if (InterruptHandler != NULL) {
|
||||||
|
// Call the registered interrupt handler.
|
||||||
|
InterruptHandler (GicInterrupt, SystemContext);
|
||||||
|
} else {
|
||||||
|
DEBUG ((EFI_D_ERROR, "Spurious GIC interrupt: 0x%x\n", GicInterrupt));
|
||||||
|
}
|
||||||
|
|
||||||
|
EndOfInterrupt (&gHardwareInterruptProtocol, GicInterrupt);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Making this global saves a few bytes in image size
|
||||||
|
//
|
||||||
|
EFI_HANDLE gHardwareInterruptHandle = NULL;
|
||||||
|
|
||||||
|
//
|
||||||
|
// The protocol instance produced by this driver
|
||||||
|
//
|
||||||
|
EFI_HARDWARE_INTERRUPT_PROTOCOL gHardwareInterruptProtocol = {
|
||||||
|
RegisterInterruptSource,
|
||||||
|
EnableInterruptSource,
|
||||||
|
DisableInterruptSource,
|
||||||
|
GetInterruptSourceState,
|
||||||
|
EndOfInterrupt
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
Shutdown our hardware
|
||||||
|
|
||||||
|
DXE Core will disable interrupts and turn off the timer and disable interrupts
|
||||||
|
after all the event handlers have run.
|
||||||
|
|
||||||
|
@param[in] Event The Event that is being processed
|
||||||
|
@param[in] Context Event Context
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
EFIAPI
|
||||||
|
ExitBootServicesEvent (
|
||||||
|
IN EFI_EVENT Event,
|
||||||
|
IN VOID *Context
|
||||||
|
)
|
||||||
|
{
|
||||||
|
UINTN i;
|
||||||
|
|
||||||
|
for (i = 0; i < PcdGet32(PcdGicNumInterrupts); i++) {
|
||||||
|
DisableInterruptSource (&gHardwareInterruptProtocol, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Acknowledge all pending interrupts
|
||||||
|
for (i = 0; i < PcdGet32(PcdGicNumInterrupts); i++) {
|
||||||
|
DisableInterruptSource (&gHardwareInterruptProtocol, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < PcdGet32(PcdGicNumInterrupts); i++) {
|
||||||
|
EndOfInterrupt (&gHardwareInterruptProtocol, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Disable Gic Interface
|
||||||
|
MmioWrite32 (PcdGet32(PcdGicInterruptInterfaceBase) + GIC_ICCICR, 0x0);
|
||||||
|
MmioWrite32 (PcdGet32(PcdGicInterruptInterfaceBase) + GIC_ICCPMR, 0x0);
|
||||||
|
|
||||||
|
// Disable Gic Distributor
|
||||||
|
MmioWrite32 (PcdGet32(PcdGicDistributorBase) + GIC_ICDDCR, 0x0);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Notification routines
|
||||||
|
//
|
||||||
|
VOID
|
||||||
|
CpuProtocolInstalledNotification (
|
||||||
|
IN EFI_EVENT Event,
|
||||||
|
IN VOID *Context
|
||||||
|
)
|
||||||
|
{
|
||||||
|
EFI_STATUS Status;
|
||||||
|
EFI_CPU_ARCH_PROTOCOL *Cpu;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Get the cpu protocol that this driver requires.
|
||||||
|
//
|
||||||
|
Status = gBS->LocateProtocol(&gEfiCpuArchProtocolGuid, NULL, (VOID **)&Cpu);
|
||||||
|
ASSERT_EFI_ERROR(Status);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Unregister the default exception handler.
|
||||||
|
//
|
||||||
|
Status = Cpu->RegisterInterruptHandler(Cpu, EXCEPT_ARM_IRQ, NULL);
|
||||||
|
ASSERT_EFI_ERROR(Status);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Register to receive interrupts
|
||||||
|
//
|
||||||
|
Status = Cpu->RegisterInterruptHandler(Cpu, EXCEPT_ARM_IRQ, IrqInterruptHandler);
|
||||||
|
ASSERT_EFI_ERROR(Status);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Initialize the state information for the CPU Architectural Protocol
|
||||||
|
|
||||||
|
@param ImageHandle of the loaded driver
|
||||||
|
@param SystemTable Pointer to the System Table
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS Protocol registered
|
||||||
|
@retval EFI_OUT_OF_RESOURCES Cannot allocate protocol data structure
|
||||||
|
@retval EFI_DEVICE_ERROR Hardware problems
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
InterruptDxeInitialize (
|
||||||
|
IN EFI_HANDLE ImageHandle,
|
||||||
|
IN EFI_SYSTEM_TABLE *SystemTable
|
||||||
|
)
|
||||||
|
{
|
||||||
|
EFI_STATUS Status;
|
||||||
|
UINTN i;
|
||||||
|
UINT32 RegOffset;
|
||||||
|
UINTN RegShift;
|
||||||
|
|
||||||
|
// Make sure the Interrupt Controller Protocol is not already installed in the system.
|
||||||
|
ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gHardwareInterruptProtocolGuid);
|
||||||
|
|
||||||
|
for (i = 0; i < PcdGet32(PcdGicNumInterrupts); i++) {
|
||||||
|
DisableInterruptSource (&gHardwareInterruptProtocol, i);
|
||||||
|
|
||||||
|
// Set Priority
|
||||||
|
RegOffset = i / 4;
|
||||||
|
RegShift = (i % 4) * 8;
|
||||||
|
MmioAndThenOr32 (
|
||||||
|
PcdGet32(PcdGicDistributorBase) + GIC_ICDIPR+(4*RegOffset),
|
||||||
|
~(0xff << RegShift),
|
||||||
|
GIC_DEFAULT_PRIORITY << RegShift
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// configure interrupts for cpu 0
|
||||||
|
for (i = 0; i < GIC_NUM_REG_PER_INT_BYTES; i++) {
|
||||||
|
MmioWrite32 (PcdGet32(PcdGicDistributorBase) + GIC_ICDIPTR + (i*4), 0x01010101);
|
||||||
|
}
|
||||||
|
|
||||||
|
// set binary point reg to 0x7 (no preemption)
|
||||||
|
MmioWrite32 (PcdGet32(PcdGicInterruptInterfaceBase) + GIC_ICCBPR, 0x7);
|
||||||
|
|
||||||
|
// set priority mask reg to 0xff to allow all priorities through
|
||||||
|
MmioWrite32 (PcdGet32(PcdGicInterruptInterfaceBase) + GIC_ICCPMR, 0xff);
|
||||||
|
|
||||||
|
// enable gic cpu interface
|
||||||
|
MmioWrite32 (PcdGet32(PcdGicInterruptInterfaceBase) + GIC_ICCICR, 0x1);
|
||||||
|
|
||||||
|
// enable gic distributor
|
||||||
|
MmioWrite32 (PcdGet32(PcdGicDistributorBase) + GIC_ICDDCR, 0x1);
|
||||||
|
|
||||||
|
ZeroMem (&gRegisteredInterruptHandlers, sizeof (gRegisteredInterruptHandlers));
|
||||||
|
|
||||||
|
Status = gBS->InstallMultipleProtocolInterfaces (
|
||||||
|
&gHardwareInterruptHandle,
|
||||||
|
&gHardwareInterruptProtocolGuid, &gHardwareInterruptProtocol,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
ASSERT_EFI_ERROR (Status);
|
||||||
|
|
||||||
|
// Set up to be notified when the Cpu protocol is installed.
|
||||||
|
Status = gBS->CreateEvent (EVT_NOTIFY_SIGNAL, TPL_CALLBACK, CpuProtocolInstalledNotification, NULL, &CpuProtocolNotificationEvent);
|
||||||
|
ASSERT_EFI_ERROR (Status);
|
||||||
|
|
||||||
|
Status = gBS->RegisterProtocolNotify (&gEfiCpuArchProtocolGuid, CpuProtocolNotificationEvent, (VOID *)&CpuProtocolNotificationToken);
|
||||||
|
ASSERT_EFI_ERROR (Status);
|
||||||
|
|
||||||
|
// Register for an ExitBootServicesEvent
|
||||||
|
Status = gBS->CreateEvent (EVT_SIGNAL_EXIT_BOOT_SERVICES, TPL_NOTIFY, ExitBootServicesEvent, NULL, &EfiExitBootServicesEvent);
|
||||||
|
ASSERT_EFI_ERROR (Status);
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
@ -1,8 +1,6 @@
|
|||||||
#/** @file
|
#/** @file
|
||||||
#
|
#
|
||||||
# DXE CPU driver
|
# Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
|
||||||
#
|
|
||||||
# Copyright (c) 2009 - 2010, Apple Inc. All rights reserved.<BR>
|
|
||||||
# This program and the accompanying materials
|
# This program and the accompanying materials
|
||||||
# are licensed and made available under the terms and conditions of the BSD License
|
# 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
|
# which accompanies this distribution. The full text of the license may be found at
|
||||||
@ -15,30 +13,43 @@
|
|||||||
|
|
||||||
[Defines]
|
[Defines]
|
||||||
INF_VERSION = 0x00010005
|
INF_VERSION = 0x00010005
|
||||||
BASE_NAME = ArmDebugSupportDxe
|
BASE_NAME = PL390GicDxe
|
||||||
FILE_GUID = 2e7c151b-cbd8-4df6-a0e3-cde660067c6a
|
FILE_GUID = DE371F7C-DEC4-4D21-ADF1-593ABCC15882
|
||||||
MODULE_TYPE = DXE_DRIVER
|
MODULE_TYPE = DXE_DRIVER
|
||||||
VERSION_STRING = 1.0
|
VERSION_STRING = 1.0
|
||||||
|
|
||||||
ENTRY_POINT = DebugSupportDxeInitialize
|
ENTRY_POINT = InterruptDxeInitialize
|
||||||
|
|
||||||
|
|
||||||
[Sources.common]
|
[Sources.common]
|
||||||
DebugSupport.c
|
PL390GicDxe.c
|
||||||
|
|
||||||
|
|
||||||
[Packages]
|
[Packages]
|
||||||
ArmPkg/ArmPkg.dec
|
|
||||||
MdePkg/MdePkg.dec
|
MdePkg/MdePkg.dec
|
||||||
|
EmbeddedPkg/EmbeddedPkg.dec
|
||||||
|
ArmPkg/ArmPkg.dec
|
||||||
|
|
||||||
[LibraryClasses]
|
[LibraryClasses]
|
||||||
BaseMemoryLib
|
BaseLib
|
||||||
CacheMaintenanceLib
|
UefiLib
|
||||||
|
UefiBootServicesTableLib
|
||||||
|
DebugLib
|
||||||
|
PrintLib
|
||||||
UefiDriverEntryPoint
|
UefiDriverEntryPoint
|
||||||
ArmLib
|
IoLib
|
||||||
|
|
||||||
|
[Guids]
|
||||||
|
|
||||||
|
|
||||||
[Protocols]
|
[Protocols]
|
||||||
|
gHardwareInterruptProtocolGuid
|
||||||
gEfiCpuArchProtocolGuid
|
gEfiCpuArchProtocolGuid
|
||||||
gEfiDebugSupportProtocolGuid
|
|
||||||
gTimerDebugSupportProtocolGuid
|
|
||||||
|
|
||||||
[Depex]
|
[FixedPcd.common]
|
||||||
|
gArmTokenSpaceGuid.PcdGicDistributorBase
|
||||||
|
gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase
|
||||||
|
gArmTokenSpaceGuid.PcdGicNumInterrupts
|
||||||
|
|
||||||
|
[depex]
|
||||||
TRUE
|
TRUE
|
97
ArmPkg/Drivers/PL390Gic/PL390GicNonSec.c
Normal file
97
ArmPkg/Drivers/PL390Gic/PL390GicNonSec.c
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
/** @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 <Drivers/PL390Gic.h>
|
||||||
|
|
||||||
|
|
||||||
|
VOID
|
||||||
|
EFIAPI
|
||||||
|
PL390GicEnableInterruptInterface (
|
||||||
|
IN INTN GicInterruptInterfaceBase
|
||||||
|
)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Enable the CPU interface in Non-Secure world
|
||||||
|
* Note: The ICCICR register is banked when Security extensions are implemented
|
||||||
|
*/
|
||||||
|
MmioWrite32(GicInterruptInterfaceBase + GIC_ICCICR,0x00000001);
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
EFIAPI
|
||||||
|
PL390GicEnableDistributor (
|
||||||
|
IN INTN GicDistributorBase
|
||||||
|
)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Enable GIC distributor in Non-Secure world.
|
||||||
|
* Note: The ICDDCR register is banked when Security extensions are implemented
|
||||||
|
*/
|
||||||
|
MmioWrite32(GicDistributorBase + GIC_ICDDCR, 0x00000001);
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
EFIAPI
|
||||||
|
PL390GicSendSgiTo (
|
||||||
|
IN INTN GicDistributorBase,
|
||||||
|
IN INTN TargetListFilter,
|
||||||
|
IN INTN CPUTargetList
|
||||||
|
)
|
||||||
|
{
|
||||||
|
MmioWrite32(GicDistributorBase + GIC_ICDSGIR, ((TargetListFilter & 0x3) << 24) | ((CPUTargetList & 0xFF) << 16));
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT32
|
||||||
|
EFIAPI
|
||||||
|
PL390GicAcknowledgeSgiFrom (
|
||||||
|
IN INTN GicInterruptInterfaceBase,
|
||||||
|
IN INTN CoreId
|
||||||
|
)
|
||||||
|
{
|
||||||
|
INTN InterruptId;
|
||||||
|
|
||||||
|
InterruptId = MmioRead32(GicInterruptInterfaceBase + GIC_ICCIAR);
|
||||||
|
|
||||||
|
//Check if the Interrupt ID is valid, The read from Interrupt Ack register returns CPU ID and Interrupt ID
|
||||||
|
if (((CoreId & 0x7) << 10) == (InterruptId & 0x1C00)) {
|
||||||
|
//Got SGI number 0 hence signal End of Interrupt by writing to ICCEOIR
|
||||||
|
MmioWrite32(GicInterruptInterfaceBase + GIC_ICCEIOR, InterruptId);
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT32
|
||||||
|
EFIAPI
|
||||||
|
PL390GicAcknowledgeSgi2From (
|
||||||
|
IN INTN GicInterruptInterfaceBase,
|
||||||
|
IN INTN CoreId,
|
||||||
|
IN INTN SgiId
|
||||||
|
)
|
||||||
|
{
|
||||||
|
INTN InterruptId;
|
||||||
|
|
||||||
|
InterruptId = MmioRead32(GicInterruptInterfaceBase + GIC_ICCIAR);
|
||||||
|
|
||||||
|
//Check if the Interrupt ID is valid, The read from Interrupt Ack register returns CPU ID and Interrupt ID
|
||||||
|
if((((CoreId & 0x7) << 10) | (SgiId & 0x3FF)) == (InterruptId & 0x1FFF)) {
|
||||||
|
//Got SGI number 0 hence signal End of Interrupt by writing to ICCEOIR
|
||||||
|
MmioWrite32(GicInterruptInterfaceBase + GIC_ICCEIOR, InterruptId);
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
29
ArmPkg/Drivers/PL390Gic/PL390GicNonSec.inf
Normal file
29
ArmPkg/Drivers/PL390Gic/PL390GicNonSec.inf
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
#/* @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 = PL390GicNonSec
|
||||||
|
FILE_GUID = 03d05ee4-cdeb-458c-9dfc-993f09bdf405
|
||||||
|
MODULE_TYPE = SEC
|
||||||
|
VERSION_STRING = 1.0
|
||||||
|
LIBRARY_CLASS = PL390GicNonSecLib
|
||||||
|
|
||||||
|
[Sources]
|
||||||
|
PL390GicNonSec.c
|
||||||
|
|
||||||
|
[Packages]
|
||||||
|
ArmPkg/ArmPkg.dec
|
||||||
|
MdePkg/MdePkg.dec
|
||||||
|
|
||||||
|
[FixedPcd]
|
135
ArmPkg/Drivers/PL390Gic/PL390GicSec.c
Normal file
135
ArmPkg/Drivers/PL390Gic/PL390GicSec.c
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
/** @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 <Drivers/PL390Gic.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This function configures the all interrupts to be Non-secure.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
VOID
|
||||||
|
EFIAPI
|
||||||
|
PL390GicSetupNonSecure (
|
||||||
|
IN INTN GicDistributorBase,
|
||||||
|
IN INTN GicInterruptInterfaceBase
|
||||||
|
)
|
||||||
|
{
|
||||||
|
UINTN CachedPriorityMask = MmioRead32(GicInterruptInterfaceBase + GIC_ICCPMR);
|
||||||
|
|
||||||
|
//Set priority Mask so that no interrupts get through to CPU
|
||||||
|
MmioWrite32(GicInterruptInterfaceBase + GIC_ICCPMR, 0);
|
||||||
|
|
||||||
|
//Check if there are any pending interrupts
|
||||||
|
while(0 != (MmioRead32(GicDistributorBase + GIC_ICDICPR) & 0xF))
|
||||||
|
{
|
||||||
|
//Some of the SGI's are still pending, read Ack register and send End of Interrupt Signal
|
||||||
|
UINTN InterruptId = MmioRead32(GicInterruptInterfaceBase + GIC_ICCIAR);
|
||||||
|
|
||||||
|
//Write to End of interrupt signal
|
||||||
|
MmioWrite32(GicInterruptInterfaceBase + GIC_ICCEIOR, InterruptId);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure all GIC interrupts are Non-Secure
|
||||||
|
MmioWrite32(GicDistributorBase + GIC_ICDISR, 0xffffffff); // IRQs 0-31 are Non-Secure : Private Peripheral Interrupt[31:16] & Software Generated Interrupt[15:0]
|
||||||
|
MmioWrite32(GicDistributorBase + GIC_ICDISR + 4, 0xffffffff); // IRQs 32-63 are Non-Secure : Shared Peripheral Interrupt
|
||||||
|
MmioWrite32(GicDistributorBase + GIC_ICDISR + 8, 0xffffffff); // And another 32 in case we're on the testchip : Shared Peripheral Interrupt (2)
|
||||||
|
|
||||||
|
// Ensure all interrupts can get through the priority mask
|
||||||
|
MmioWrite32(GicInterruptInterfaceBase + GIC_ICCPMR, CachedPriorityMask);
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
EFIAPI
|
||||||
|
PL390GicEnableInterruptInterface (
|
||||||
|
IN INTN GicInterruptInterfaceBase
|
||||||
|
)
|
||||||
|
{
|
||||||
|
MmioWrite32(GicInterruptInterfaceBase + GIC_ICCPMR, 0x000000FF); /* Set Priority Mask to allow interrupts */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Enable CPU interface in Secure world
|
||||||
|
* Enable CPU inteface in Non-secure World
|
||||||
|
* Signal Secure Interrupts to CPU using FIQ line *
|
||||||
|
*/
|
||||||
|
MmioWrite32(GicInterruptInterfaceBase + GIC_ICCICR,
|
||||||
|
GIC_ICCICR_ENABLE_SECURE(1) |
|
||||||
|
GIC_ICCICR_ENABLE_NS(1) |
|
||||||
|
GIC_ICCICR_ACK_CTL(0) |
|
||||||
|
GIC_ICCICR_SIGNAL_SECURE_TO_FIQ(1) |
|
||||||
|
GIC_ICCICR_USE_SBPR(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
EFIAPI
|
||||||
|
PL390GicEnableDistributor (
|
||||||
|
IN INTN GicDistributorBase
|
||||||
|
)
|
||||||
|
{
|
||||||
|
MmioWrite32(GicDistributorBase + GIC_ICDDCR, 1); // turn on the GIC distributor
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
EFIAPI
|
||||||
|
PL390GicSendSgiTo (
|
||||||
|
IN INTN GicDistributorBase,
|
||||||
|
IN INTN TargetListFilter,
|
||||||
|
IN INTN CPUTargetList
|
||||||
|
)
|
||||||
|
{
|
||||||
|
MmioWrite32(GicDistributorBase + GIC_ICDSGIR, ((TargetListFilter & 0x3) << 24) | ((CPUTargetList & 0xFF) << 16));
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT32
|
||||||
|
EFIAPI
|
||||||
|
PL390GicAcknowledgeSgiFrom (
|
||||||
|
IN INTN GicInterruptInterfaceBase,
|
||||||
|
IN INTN CoreId
|
||||||
|
)
|
||||||
|
{
|
||||||
|
INTN InterruptId;
|
||||||
|
|
||||||
|
InterruptId = MmioRead32(GicInterruptInterfaceBase + GIC_ICCIAR);
|
||||||
|
|
||||||
|
//Check if the Interrupt ID is valid, The read from Interrupt Ack register returns CPU ID and Interrupt ID
|
||||||
|
if (((CoreId & 0x7) << 10) == (InterruptId & 0x1C00)) {
|
||||||
|
//Got SGI number 0 hence signal End of Interrupt by writing to ICCEOIR
|
||||||
|
MmioWrite32(GicInterruptInterfaceBase + GIC_ICCEIOR, InterruptId);
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT32
|
||||||
|
EFIAPI
|
||||||
|
PL390GicAcknowledgeSgi2From (
|
||||||
|
IN INTN GicInterruptInterfaceBase,
|
||||||
|
IN INTN CoreId,
|
||||||
|
IN INTN SgiId
|
||||||
|
)
|
||||||
|
{
|
||||||
|
INTN InterruptId;
|
||||||
|
|
||||||
|
InterruptId = MmioRead32(GicInterruptInterfaceBase + GIC_ICCIAR);
|
||||||
|
|
||||||
|
//Check if the Interrupt ID is valid, The read from Interrupt Ack register returns CPU ID and Interrupt ID
|
||||||
|
if((((CoreId & 0x7) << 10) | (SgiId & 0x3FF)) == (InterruptId & 0x1FFF)) {
|
||||||
|
//Got SGI number 0 hence signal End of Interrupt by writing to ICCEOIR
|
||||||
|
MmioWrite32(GicInterruptInterfaceBase + GIC_ICCEIOR, InterruptId);
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
29
ArmPkg/Drivers/PL390Gic/PL390GicSec.inf
Normal file
29
ArmPkg/Drivers/PL390Gic/PL390GicSec.inf
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
#/* @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 = PL390GicSec
|
||||||
|
FILE_GUID = 85f3cf80-b5f4-11df-9855-0002a5d5c51b
|
||||||
|
MODULE_TYPE = SEC
|
||||||
|
VERSION_STRING = 1.0
|
||||||
|
LIBRARY_CLASS = PL390GicSecLib
|
||||||
|
|
||||||
|
[Sources]
|
||||||
|
PL390GicSec.c
|
||||||
|
|
||||||
|
[Packages]
|
||||||
|
ArmPkg/ArmPkg.dec
|
||||||
|
MdePkg/MdePkg.dec
|
||||||
|
|
||||||
|
[FixedPcd]
|
@ -86,22 +86,22 @@
|
|||||||
#define TT_DESCRIPTOR_SECTION_BASE_ADDRESS_MASK (0xFFF00000)
|
#define TT_DESCRIPTOR_SECTION_BASE_ADDRESS_MASK (0xFFF00000)
|
||||||
#define TT_DESCRIPTOR_SECTION_BASE_ADDRESS(a) (a & TT_DESCRIPTOR_SECTION_BASE_ADDRESS_MASK)
|
#define TT_DESCRIPTOR_SECTION_BASE_ADDRESS(a) (a & TT_DESCRIPTOR_SECTION_BASE_ADDRESS_MASK)
|
||||||
|
|
||||||
#define TT_DESCRIPTOR_SECTION_WRITE_BACK (TT_DESCRIPTOR_TYPE_SECTION | \
|
#define TT_DESCRIPTOR_SECTION_WRITE_BACK(Secure) (TT_DESCRIPTOR_TYPE_SECTION | \
|
||||||
TT_DESCRIPTOR_SECTION_NS_NON_SECURE | \
|
(Secure ? TT_DESCRIPTOR_SECTION_NS_SECURE : TT_DESCRIPTOR_SECTION_NS_NON_SECURE ) | \
|
||||||
TT_DESCRIPTOR_SECTION_NG_GLOBAL | \
|
TT_DESCRIPTOR_SECTION_NG_GLOBAL | \
|
||||||
TT_DESCRIPTOR_SECTION_S_NOT_SHARED | \
|
TT_DESCRIPTOR_SECTION_S_NOT_SHARED | \
|
||||||
TT_DESCRIPTOR_SECTION_DOMAIN(0) | \
|
TT_DESCRIPTOR_SECTION_DOMAIN(0) | \
|
||||||
TT_DESCRIPTOR_SECTION_AP_RW_RW | \
|
TT_DESCRIPTOR_SECTION_AP_RW_RW | \
|
||||||
TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_BACK_ALLOC)
|
TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_BACK_ALLOC)
|
||||||
#define TT_DESCRIPTOR_SECTION_WRITE_THROUGH (TT_DESCRIPTOR_TYPE_SECTION | \
|
#define TT_DESCRIPTOR_SECTION_WRITE_THROUGH(Secure) (TT_DESCRIPTOR_TYPE_SECTION | \
|
||||||
TT_DESCRIPTOR_SECTION_NS_NON_SECURE | \
|
(Secure ? TT_DESCRIPTOR_SECTION_NS_SECURE : TT_DESCRIPTOR_SECTION_NS_NON_SECURE ) | \
|
||||||
TT_DESCRIPTOR_SECTION_NG_GLOBAL | \
|
TT_DESCRIPTOR_SECTION_NG_GLOBAL | \
|
||||||
TT_DESCRIPTOR_SECTION_S_NOT_SHARED | \
|
TT_DESCRIPTOR_SECTION_S_NOT_SHARED | \
|
||||||
TT_DESCRIPTOR_SECTION_DOMAIN(0) | \
|
TT_DESCRIPTOR_SECTION_DOMAIN(0) | \
|
||||||
TT_DESCRIPTOR_SECTION_AP_RW_RW | \
|
TT_DESCRIPTOR_SECTION_AP_RW_RW | \
|
||||||
TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_THROUGH_NO_ALLOC)
|
TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_THROUGH_NO_ALLOC)
|
||||||
#define TT_DESCRIPTOR_SECTION_UNCACHED (TT_DESCRIPTOR_TYPE_SECTION | \
|
#define TT_DESCRIPTOR_SECTION_UNCACHED(Secure) (TT_DESCRIPTOR_TYPE_SECTION | \
|
||||||
TT_DESCRIPTOR_SECTION_NS_NON_SECURE | \
|
(Secure ? TT_DESCRIPTOR_SECTION_NS_SECURE : TT_DESCRIPTOR_SECTION_NS_NON_SECURE ) | \
|
||||||
TT_DESCRIPTOR_SECTION_NG_GLOBAL | \
|
TT_DESCRIPTOR_SECTION_NG_GLOBAL | \
|
||||||
TT_DESCRIPTOR_SECTION_S_NOT_SHARED | \
|
TT_DESCRIPTOR_SECTION_S_NOT_SHARED | \
|
||||||
TT_DESCRIPTOR_SECTION_DOMAIN(0) | \
|
TT_DESCRIPTOR_SECTION_DOMAIN(0) | \
|
||||||
|
@ -22,17 +22,52 @@
|
|||||||
#define DOMAIN_ACCESS_CONTROL_RESERVED(a) (2UL << (2 * (a)))
|
#define DOMAIN_ACCESS_CONTROL_RESERVED(a) (2UL << (2 * (a)))
|
||||||
#define DOMAIN_ACCESS_CONTROL_MANAGER(a) (3UL << (2 * (a)))
|
#define DOMAIN_ACCESS_CONTROL_MANAGER(a) (3UL << (2 * (a)))
|
||||||
|
|
||||||
#define TRANSLATION_TABLE_SIZE (16 * 1024)
|
#define TTBR_NOT_OUTER_SHAREABLE BIT5
|
||||||
#define TRANSLATION_TABLE_ALIGNMENT (16 * 1024)
|
#define TTBR_RGN_OUTER_NON_CACHEABLE 0
|
||||||
#define TRANSLATION_TABLE_ALIGNMENT_MASK (TRANSLATION_TABLE_ALIGNMENT - 1)
|
#define TTBR_RGN_OUTER_WRITE_BACK_ALLOC BIT3
|
||||||
|
#define TTBR_RGN_OUTER_WRITE_THROUGH BIT4
|
||||||
|
#define TTBR_RGN_OUTER_WRITE_BACK_NO_ALLOC (BIT3|BIT4)
|
||||||
|
#define TTBR_SHAREABLE BIT1
|
||||||
|
#define TTBR_NON_SHAREABLE 0
|
||||||
|
#define TTBR_INNER_CACHEABLE BIT0
|
||||||
|
#define TTBR_NON_INNER_CACHEABLE BIT0
|
||||||
|
#define TTBR_RGN_INNER_NON_CACHEABLE 0
|
||||||
|
#define TTBR_RGN_INNER_WRITE_BACK_ALLOC BIT6
|
||||||
|
#define TTBR_RGN_INNER_WRITE_THROUGH BIT0
|
||||||
|
#define TTBR_RGN_INNER_WRITE_BACK_NO_ALLOC (BIT0|BIT6)
|
||||||
|
|
||||||
|
#define TTBR_WRITE_THROUGH_NO_ALLOC ( TTBR_RGN_OUTER_WRITE_BACK_ALLOC | TTBR_RGN_INNER_WRITE_BACK_ALLOC )
|
||||||
|
#define TTBR_WRITE_BACK_NO_ALLOC ( TTBR_RGN_OUTER_WRITE_BACK_NO_ALLOC | TTBR_RGN_INNER_WRITE_BACK_NO_ALLOC )
|
||||||
|
#define TTBR_NON_CACHEABLE ( TTBR_RGN_OUTER_NON_CACHEABLE | TTBR_RGN_INNER_NON_CACHEABLE )
|
||||||
|
#define TTBR_WRITE_BACK_ALLOC ( TTBR_RGN_OUTER_WRITE_BACK_ALLOC | TTBR_RGN_INNER_WRITE_BACK_ALLOC )
|
||||||
|
|
||||||
|
|
||||||
|
#define TRANSLATION_TABLE_SECTION_COUNT 4096
|
||||||
|
#define TRANSLATION_TABLE_SECTION_SIZE (sizeof(UINT32) * TRANSLATION_TABLE_SECTION_COUNT)
|
||||||
|
#define TRANSLATION_TABLE_SECTION_ALIGNMENT (sizeof(UINT32) * TRANSLATION_TABLE_SECTION_COUNT)
|
||||||
|
#define TRANSLATION_TABLE_SECTION_ALIGNMENT_MASK (TRANSLATION_TABLE_SECTION_ALIGNMENT - 1)
|
||||||
|
|
||||||
|
#define TRANSLATION_TABLE_PAGE_COUNT 256
|
||||||
|
#define TRANSLATION_TABLE_PAGE_SIZE (sizeof(UINT32) * TRANSLATION_TABLE_PAGE_COUNT)
|
||||||
|
#define TRANSLATION_TABLE_PAGE_ALIGNMENT (sizeof(UINT32) * TRANSLATION_TABLE_PAGE_COUNT)
|
||||||
|
#define TRANSLATION_TABLE_PAGE_ALIGNMENT_MASK (TRANSLATION_TABLE_PAGE_ALIGNMENT - 1)
|
||||||
|
|
||||||
#define TRANSLATION_TABLE_ENTRY_FOR_VIRTUAL_ADDRESS(table, address) ((UINT32 *)(table) + (((UINTN)(address)) >> 20))
|
#define TRANSLATION_TABLE_ENTRY_FOR_VIRTUAL_ADDRESS(table, address) ((UINT32 *)(table) + (((UINTN)(address)) >> 20))
|
||||||
|
|
||||||
// Translation table descriptor types
|
// Translation table descriptor types
|
||||||
#define TT_DESCRIPTOR_TYPE_MASK ((1UL << 18) | (3UL << 0))
|
#define TT_DESCRIPTOR_SECTION_TYPE_MASK ((1UL << 18) | (3UL << 0))
|
||||||
#define TT_DESCRIPTOR_TYPE_PAGE_TABLE ((0UL << 18) | (1UL << 0))
|
#define TT_DESCRIPTOR_SECTION_TYPE_FAULT (0UL << 0)
|
||||||
#define TT_DESCRIPTOR_TYPE_SECTION ((0UL << 18) | (2UL << 0))
|
#define TT_DESCRIPTOR_SECTION_TYPE_PAGE_TABLE (1UL << 0)
|
||||||
#define TT_DESCRIPTOR_TYPE_SUPERSECTION ((1UL << 18) | (2UL << 0))
|
#define TT_DESCRIPTOR_SECTION_TYPE_SECTION ((0UL << 18) | (2UL << 0))
|
||||||
|
#define TT_DESCRIPTOR_SECTION_TYPE_SUPERSECTION ((1UL << 18) | (2UL << 0))
|
||||||
|
#define TT_DESCRIPTOR_SECTION_TYPE_IS_PAGE_TABLE(Desc) (((Desc) & 3UL) == TT_DESCRIPTOR_SECTION_TYPE_PAGE_TABLE)
|
||||||
|
|
||||||
|
// Translation table descriptor types
|
||||||
|
#define TT_DESCRIPTOR_PAGE_TYPE_MASK (3UL << 0)
|
||||||
|
#define TT_DESCRIPTOR_PAGE_TYPE_FAULT (0UL << 0)
|
||||||
|
#define TT_DESCRIPTOR_PAGE_TYPE_PAGE (2UL << 0)
|
||||||
|
#define TT_DESCRIPTOR_PAGE_TYPE_PAGE_XN (3UL << 0)
|
||||||
|
#define TT_DESCRIPTOR_PAGE_TYPE_LARGEPAGE (1UL << 0)
|
||||||
|
|
||||||
// Section descriptor definitions
|
// Section descriptor definitions
|
||||||
#define TT_DESCRIPTOR_SECTION_SIZE (0x00100000)
|
#define TT_DESCRIPTOR_SECTION_SIZE (0x00100000)
|
||||||
@ -45,10 +80,18 @@
|
|||||||
#define TT_DESCRIPTOR_SECTION_NG_GLOBAL (0UL << 17)
|
#define TT_DESCRIPTOR_SECTION_NG_GLOBAL (0UL << 17)
|
||||||
#define TT_DESCRIPTOR_SECTION_NG_LOCAL (1UL << 17)
|
#define TT_DESCRIPTOR_SECTION_NG_LOCAL (1UL << 17)
|
||||||
|
|
||||||
|
#define TT_DESCRIPTOR_PAGE_NG_MASK (1UL << 11)
|
||||||
|
#define TT_DESCRIPTOR_PAGE_NG_GLOBAL (0UL << 11)
|
||||||
|
#define TT_DESCRIPTOR_PAGE_NG_LOCAL (1UL << 11)
|
||||||
|
|
||||||
#define TT_DESCRIPTOR_SECTION_S_MASK (1UL << 16)
|
#define TT_DESCRIPTOR_SECTION_S_MASK (1UL << 16)
|
||||||
#define TT_DESCRIPTOR_SECTION_S_NOT_SHARED (0UL << 16)
|
#define TT_DESCRIPTOR_SECTION_S_NOT_SHARED (0UL << 16)
|
||||||
#define TT_DESCRIPTOR_SECTION_S_SHARED (1UL << 16)
|
#define TT_DESCRIPTOR_SECTION_S_SHARED (1UL << 16)
|
||||||
|
|
||||||
|
#define TT_DESCRIPTOR_PAGE_S_MASK (1UL << 10)
|
||||||
|
#define TT_DESCRIPTOR_PAGE_S_NOT_SHARED (0UL << 10)
|
||||||
|
#define TT_DESCRIPTOR_PAGE_S_SHARED (1UL << 10)
|
||||||
|
|
||||||
#define TT_DESCRIPTOR_SECTION_AP_MASK ((1UL << 15) | (3UL << 10))
|
#define TT_DESCRIPTOR_SECTION_AP_MASK ((1UL << 15) | (3UL << 10))
|
||||||
#define TT_DESCRIPTOR_SECTION_AP_NO_NO ((0UL << 15) | (0UL << 10))
|
#define TT_DESCRIPTOR_SECTION_AP_NO_NO ((0UL << 15) | (0UL << 10))
|
||||||
#define TT_DESCRIPTOR_SECTION_AP_RW_NO ((0UL << 15) | (1UL << 10))
|
#define TT_DESCRIPTOR_SECTION_AP_RW_NO ((0UL << 15) | (1UL << 10))
|
||||||
@ -57,7 +100,20 @@
|
|||||||
#define TT_DESCRIPTOR_SECTION_AP_RO_NO ((1UL << 15) | (1UL << 10))
|
#define TT_DESCRIPTOR_SECTION_AP_RO_NO ((1UL << 15) | (1UL << 10))
|
||||||
#define TT_DESCRIPTOR_SECTION_AP_RO_RO ((1UL << 15) | (3UL << 10))
|
#define TT_DESCRIPTOR_SECTION_AP_RO_RO ((1UL << 15) | (3UL << 10))
|
||||||
|
|
||||||
#define TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK ((3UL << 12) | (0UL << 3) | (0UL << 2))
|
#define TT_DESCRIPTOR_PAGE_AP_MASK ((1UL << 9) | (3UL << 4))
|
||||||
|
#define TT_DESCRIPTOR_PAGE_AP_NO_NO ((0UL << 9) | (0UL << 4))
|
||||||
|
#define TT_DESCRIPTOR_PAGE_AP_RW_NO ((0UL << 9) | (1UL << 4))
|
||||||
|
#define TT_DESCRIPTOR_PAGE_AP_RW_RO ((0UL << 9) | (2UL << 4))
|
||||||
|
#define TT_DESCRIPTOR_PAGE_AP_RW_RW ((0UL << 9) | (3UL << 4))
|
||||||
|
#define TT_DESCRIPTOR_PAGE_AP_RO_NO ((1UL << 9) | (1UL << 4))
|
||||||
|
#define TT_DESCRIPTOR_PAGE_AP_RO_RO ((1UL << 9) | (3UL << 4))
|
||||||
|
|
||||||
|
#define TT_DESCRIPTOR_SECTION_XN_MASK (0x1UL << 4)
|
||||||
|
#define TT_DESCRIPTOR_PAGE_XN_MASK (0x1UL << 0)
|
||||||
|
#define TT_DESCRIPTOR_LARGEPAGE_XN_MASK (0x1UL << 15)
|
||||||
|
|
||||||
|
#define TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK ((3UL << 12) | (1UL << 3) | (1UL << 2))
|
||||||
|
#define TT_DESCRIPTOR_SECTION_CACHEABLE_MASK (1UL << 3)
|
||||||
#define TT_DESCRIPTOR_SECTION_CACHE_POLICY_STRONGLY_ORDERED ((0UL << 12) | (0UL << 3) | (0UL << 2))
|
#define TT_DESCRIPTOR_SECTION_CACHE_POLICY_STRONGLY_ORDERED ((0UL << 12) | (0UL << 3) | (0UL << 2))
|
||||||
#define TT_DESCRIPTOR_SECTION_CACHE_POLICY_SHAREABLE_DEVICE ((0UL << 12) | (0UL << 3) | (1UL << 2))
|
#define TT_DESCRIPTOR_SECTION_CACHE_POLICY_SHAREABLE_DEVICE ((0UL << 12) | (0UL << 3) | (1UL << 2))
|
||||||
#define TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_THROUGH_NO_ALLOC ((0UL << 12) | (1UL << 3) | (0UL << 2))
|
#define TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_THROUGH_NO_ALLOC ((0UL << 12) | (1UL << 3) | (0UL << 2))
|
||||||
@ -66,39 +122,240 @@
|
|||||||
#define TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_BACK_ALLOC ((1UL << 12) | (1UL << 3) | (1UL << 2))
|
#define TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_BACK_ALLOC ((1UL << 12) | (1UL << 3) | (1UL << 2))
|
||||||
#define TT_DESCRIPTOR_SECTION_CACHE_POLICY_NON_SHAREABLE_DEVICE ((2UL << 12) | (0UL << 3) | (0UL << 2))
|
#define TT_DESCRIPTOR_SECTION_CACHE_POLICY_NON_SHAREABLE_DEVICE ((2UL << 12) | (0UL << 3) | (0UL << 2))
|
||||||
|
|
||||||
|
#define TT_DESCRIPTOR_PAGE_CACHE_POLICY_MASK ((3UL << 6) | (1UL << 3) | (1UL << 2))
|
||||||
|
#define TT_DESCRIPTOR_PAGE_CACHEABLE_MASK (1UL << 3)
|
||||||
|
#define TT_DESCRIPTOR_PAGE_CACHE_POLICY_STRONGLY_ORDERED ((0UL << 6) | (0UL << 3) | (0UL << 2))
|
||||||
|
#define TT_DESCRIPTOR_PAGE_CACHE_POLICY_SHAREABLE_DEVICE ((0UL << 6) | (0UL << 3) | (1UL << 2))
|
||||||
|
#define TT_DESCRIPTOR_PAGE_CACHE_POLICY_WRITE_THROUGH_NO_ALLOC ((0UL << 6) | (1UL << 3) | (0UL << 2))
|
||||||
|
#define TT_DESCRIPTOR_PAGE_CACHE_POLICY_WRITE_BACK_NO_ALLOC ((0UL << 6) | (1UL << 3) | (1UL << 2))
|
||||||
|
#define TT_DESCRIPTOR_PAGE_CACHE_POLICY_NON_CACHEABLE ((1UL << 6) | (0UL << 3) | (0UL << 2))
|
||||||
|
#define TT_DESCRIPTOR_PAGE_CACHE_POLICY_WRITE_BACK_ALLOC ((1UL << 6) | (1UL << 3) | (1UL << 2))
|
||||||
|
#define TT_DESCRIPTOR_PAGE_CACHE_POLICY_NON_SHAREABLE_DEVICE ((2UL << 6) | (0UL << 3) | (0UL << 2))
|
||||||
|
|
||||||
|
#define TT_DESCRIPTOR_LARGEPAGE_CACHE_POLICY_MASK ((3UL << 12) | (0UL << 3) | (0UL << 2))
|
||||||
|
#define TT_DESCRIPTOR_LARGEPAGE_CACHE_POLICY_STRONGLY_ORDERED ((0UL << 12) | (0UL << 3) | (0UL << 2))
|
||||||
|
#define TT_DESCRIPTOR_LARGEPAGE_CACHE_POLICY_SHAREABLE_DEVICE ((0UL << 12) | (0UL << 3) | (1UL << 2))
|
||||||
|
#define TT_DESCRIPTOR_LARGEPAGE_CACHE_POLICY_WRITE_THROUGH_NO_ALLOC ((0UL << 12) | (1UL << 3) | (0UL << 2))
|
||||||
|
#define TT_DESCRIPTOR_LARGEPAGE_CACHE_POLICY_WRITE_BACK_NO_ALLOC ((0UL << 12) | (1UL << 3) | (1UL << 2))
|
||||||
|
#define TT_DESCRIPTOR_LARGEPAGE_CACHE_POLICY_NON_CACHEABLE ((1UL << 12) | (0UL << 3) | (0UL << 2))
|
||||||
|
#define TT_DESCRIPTOR_LARGEPAGE_CACHE_POLICY_WRITE_BACK_ALLOC ((1UL << 12) | (1UL << 3) | (1UL << 2))
|
||||||
|
#define TT_DESCRIPTOR_LARGEPAGE_CACHE_POLICY_NON_SHAREABLE_DEVICE ((2UL << 12) | (0UL << 3) | (0UL << 2))
|
||||||
|
|
||||||
|
#define TT_DESCRIPTOR_CONVERT_TO_PAGE_AP(Desc) ((((Desc) & TT_DESCRIPTOR_SECTION_AP_MASK) >> 6) & TT_DESCRIPTOR_PAGE_AP_MASK)
|
||||||
|
#define TT_DESCRIPTOR_CONVERT_TO_PAGE_NG(Desc) ((((Desc) & TT_DESCRIPTOR_SECTION_NG_MASK) >> 6) & TT_DESCRIPTOR_PAGE_NG_MASK)
|
||||||
|
#define TT_DESCRIPTOR_CONVERT_TO_PAGE_S(Desc) ((((Desc) & TT_DESCRIPTOR_SECTION_S_MASK) >> 6) & TT_DESCRIPTOR_PAGE_S_MASK)
|
||||||
|
#define TT_DESCRIPTOR_CONVERT_TO_PAGE_XN(Desc,IsLargePage) ((IsLargePage)? \
|
||||||
|
((((Desc) & TT_DESCRIPTOR_SECTION_XN_MASK) >> 4) & TT_DESCRIPTOR_LARGEPAGE_XN_MASK): \
|
||||||
|
((((Desc) & TT_DESCRIPTOR_SECTION_XN_MASK) << 11) & TT_DESCRIPTOR_PAGE_XN_MASK))
|
||||||
|
#define TT_DESCRIPTOR_CONVERT_TO_PAGE_CACHE_POLICY(Desc,IsLargePage) (IsLargePage? \
|
||||||
|
(((Desc) & TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK) & TT_DESCRIPTOR_LARGEPAGE_CACHE_POLICY_MASK): \
|
||||||
|
(((((Desc) & (0x3 << 12)) >> 6) | (Desc & (0x3 << 2)))))
|
||||||
|
|
||||||
#define TT_DESCRIPTOR_SECTION_DOMAIN_MASK (0x0FUL << 5)
|
#define TT_DESCRIPTOR_SECTION_DOMAIN_MASK (0x0FUL << 5)
|
||||||
#define TT_DESCRIPTOR_SECTION_DOMAIN(a) (((a) & 0x0FUL) << 5)
|
#define TT_DESCRIPTOR_SECTION_DOMAIN(a) (((a) & 0x0FUL) << 5)
|
||||||
|
|
||||||
#define TT_DESCRIPTOR_SECTION_BASE_ADDRESS_MASK (0xFFF00000)
|
#define TT_DESCRIPTOR_SECTION_BASE_ADDRESS_MASK (0xFFF00000)
|
||||||
#define TT_DESCRIPTOR_SECTION_BASE_ADDRESS(a) (a & TT_DESCRIPTOR_SECTION_BASE_ADDRESS_MASK)
|
#define TT_DESCRIPTOR_SECTION_PAGETABLE_ADDRESS_MASK (0xFFFFFC00)
|
||||||
|
#define TT_DESCRIPTOR_SECTION_BASE_ADDRESS(a) ((a) & TT_DESCRIPTOR_SECTION_BASE_ADDRESS_MASK)
|
||||||
|
#define TT_DESCRIPTOR_SECTION_BASE_SHIFT 20
|
||||||
|
|
||||||
#define TT_DESCRIPTOR_SECTION_WRITE_BACK (TT_DESCRIPTOR_TYPE_SECTION | \
|
#define TT_DESCRIPTOR_PAGE_BASE_ADDRESS_MASK (0xFFFFF000)
|
||||||
TT_DESCRIPTOR_SECTION_NS_NON_SECURE | \
|
#define TT_DESCRIPTOR_PAGE_INDEX_MASK (0x000FF000)
|
||||||
|
#define TT_DESCRIPTOR_PAGE_BASE_ADDRESS(a) ((a) & TT_DESCRIPTOR_PAGE_BASE_ADDRESS_MASK)
|
||||||
|
#define TT_DESCRIPTOR_PAGE_BASE_SHIFT 12
|
||||||
|
|
||||||
|
#define TT_DESCRIPTOR_SECTION_WRITE_BACK(Secure) (TT_DESCRIPTOR_SECTION_TYPE_SECTION | \
|
||||||
|
((Secure) ? TT_DESCRIPTOR_SECTION_NS_SECURE : TT_DESCRIPTOR_SECTION_NS_NON_SECURE ) | \
|
||||||
TT_DESCRIPTOR_SECTION_NG_GLOBAL | \
|
TT_DESCRIPTOR_SECTION_NG_GLOBAL | \
|
||||||
TT_DESCRIPTOR_SECTION_S_NOT_SHARED | \
|
TT_DESCRIPTOR_SECTION_S_NOT_SHARED | \
|
||||||
TT_DESCRIPTOR_SECTION_DOMAIN(0) | \
|
TT_DESCRIPTOR_SECTION_DOMAIN(0) | \
|
||||||
TT_DESCRIPTOR_SECTION_AP_RW_RW | \
|
TT_DESCRIPTOR_SECTION_AP_RW_RW | \
|
||||||
TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_BACK_ALLOC)
|
TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_BACK_ALLOC)
|
||||||
#define TT_DESCRIPTOR_SECTION_WRITE_THROUGH (TT_DESCRIPTOR_TYPE_SECTION | \
|
#define TT_DESCRIPTOR_SECTION_WRITE_THROUGH(Secure) (TT_DESCRIPTOR_SECTION_TYPE_SECTION | \
|
||||||
TT_DESCRIPTOR_SECTION_NS_NON_SECURE | \
|
((Secure) ? TT_DESCRIPTOR_SECTION_NS_SECURE : TT_DESCRIPTOR_SECTION_NS_NON_SECURE ) | \
|
||||||
TT_DESCRIPTOR_SECTION_NG_GLOBAL | \
|
TT_DESCRIPTOR_SECTION_NG_GLOBAL | \
|
||||||
TT_DESCRIPTOR_SECTION_S_NOT_SHARED | \
|
TT_DESCRIPTOR_SECTION_S_NOT_SHARED | \
|
||||||
TT_DESCRIPTOR_SECTION_DOMAIN(0) | \
|
TT_DESCRIPTOR_SECTION_DOMAIN(0) | \
|
||||||
TT_DESCRIPTOR_SECTION_AP_RW_RW | \
|
TT_DESCRIPTOR_SECTION_AP_RW_RW | \
|
||||||
TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_THROUGH_NO_ALLOC)
|
TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_THROUGH_NO_ALLOC)
|
||||||
#define TT_DESCRIPTOR_SECTION_DEVICE (TT_DESCRIPTOR_TYPE_SECTION | \
|
#define TT_DESCRIPTOR_SECTION_DEVICE(Secure) (TT_DESCRIPTOR_SECTION_TYPE_SECTION | \
|
||||||
TT_DESCRIPTOR_SECTION_NS_NON_SECURE | \
|
((Secure) ? TT_DESCRIPTOR_SECTION_NS_SECURE : TT_DESCRIPTOR_SECTION_NS_NON_SECURE ) | \
|
||||||
TT_DESCRIPTOR_SECTION_NG_GLOBAL | \
|
TT_DESCRIPTOR_SECTION_NG_GLOBAL | \
|
||||||
TT_DESCRIPTOR_SECTION_S_NOT_SHARED | \
|
TT_DESCRIPTOR_SECTION_S_NOT_SHARED | \
|
||||||
TT_DESCRIPTOR_SECTION_DOMAIN(0) | \
|
TT_DESCRIPTOR_SECTION_DOMAIN(0) | \
|
||||||
TT_DESCRIPTOR_SECTION_AP_RW_RW | \
|
TT_DESCRIPTOR_SECTION_AP_RW_RW | \
|
||||||
TT_DESCRIPTOR_SECTION_CACHE_POLICY_SHAREABLE_DEVICE)
|
TT_DESCRIPTOR_SECTION_CACHE_POLICY_SHAREABLE_DEVICE)
|
||||||
#define TT_DESCRIPTOR_SECTION_UNCACHED (TT_DESCRIPTOR_TYPE_SECTION | \
|
#define TT_DESCRIPTOR_SECTION_UNCACHED(Secure) (TT_DESCRIPTOR_SECTION_TYPE_SECTION | \
|
||||||
TT_DESCRIPTOR_SECTION_NS_NON_SECURE | \
|
((Secure) ? TT_DESCRIPTOR_SECTION_NS_SECURE : TT_DESCRIPTOR_SECTION_NS_NON_SECURE ) | \
|
||||||
TT_DESCRIPTOR_SECTION_NG_GLOBAL | \
|
TT_DESCRIPTOR_SECTION_NG_GLOBAL | \
|
||||||
TT_DESCRIPTOR_SECTION_S_NOT_SHARED | \
|
TT_DESCRIPTOR_SECTION_S_NOT_SHARED | \
|
||||||
TT_DESCRIPTOR_SECTION_DOMAIN(0) | \
|
TT_DESCRIPTOR_SECTION_DOMAIN(0) | \
|
||||||
TT_DESCRIPTOR_SECTION_AP_RW_RW | \
|
TT_DESCRIPTOR_SECTION_AP_RW_RW | \
|
||||||
TT_DESCRIPTOR_SECTION_CACHE_POLICY_NON_CACHEABLE)
|
TT_DESCRIPTOR_SECTION_CACHE_POLICY_NON_CACHEABLE)
|
||||||
|
|
||||||
|
// Cortex A9 feature bit definitions
|
||||||
|
#define A9_FEATURE_PARITY (1<<9)
|
||||||
|
#define A9_FEATURE_AOW (1<<8)
|
||||||
|
#define A9_FEATURE_EXCL (1<<7)
|
||||||
|
#define A9_FEATURE_SMP (1<<6)
|
||||||
|
#define A9_FEATURE_FOZ (1<<3)
|
||||||
|
#define A9_FEATURE_DPREF (1<<2)
|
||||||
|
#define A9_FEATURE_HINT (1<<1)
|
||||||
|
#define A9_FEATURE_FWD (1<<0)
|
||||||
|
|
||||||
|
// SCU register offsets & masks
|
||||||
|
#define SCU_CONTROL_OFFSET 0x0
|
||||||
|
#define SCU_CONFIG_OFFSET 0x4
|
||||||
|
#define SCU_INVALL_OFFSET 0xC
|
||||||
|
#define SCU_FILT_START_OFFSET 0x40
|
||||||
|
#define SCU_FILT_END_OFFSET 0x44
|
||||||
|
#define SCU_SACR_OFFSET 0x50
|
||||||
|
#define SCU_SSACR_OFFSET 0x54
|
||||||
|
|
||||||
|
#define SMP_GIC_CPUIF_BASE 0x100
|
||||||
|
#define SMP_GIC_DIST_BASE 0x1000
|
||||||
|
|
||||||
|
// CPACR - Coprocessor Access Control Register defintions
|
||||||
|
#define CPACR_CP_DENIED(cp) 0x00
|
||||||
|
#define CPACR_CP_PRIV(cp) ((0x1 << ((cp) << 1)) & 0x0FFFFFFF)
|
||||||
|
#define CPACR_CP_FULL(cp) ((0x3 << ((cp) << 1)) & 0x0FFFFFFF)
|
||||||
|
#define CPACR_ASEDIS (1 << 31)
|
||||||
|
#define CPACR_D32DIS (1 << 30)
|
||||||
|
#define CPACR_CP_FULL_ACCESS 0x0FFFFFFF
|
||||||
|
|
||||||
|
// NSACR - Non-Secure Access Control Register defintions
|
||||||
|
#define NSACR_CP(cp) ((1 << (cp)) & 0x3FFF)
|
||||||
|
#define NSACR_NSD32DIS (1 << 14)
|
||||||
|
#define NSACR_NSASEDIS (1 << 15)
|
||||||
|
#define NSACR_PLE (1 << 16)
|
||||||
|
#define NSACR_TL (1 << 17)
|
||||||
|
#define NSACR_NS_SMP (1 << 18)
|
||||||
|
#define NSACR_RFR (1 << 19)
|
||||||
|
|
||||||
|
// SCR - Secure Configuration Register defintions
|
||||||
|
#define SCR_NS (1 << 0)
|
||||||
|
#define SCR_IRQ (1 << 1)
|
||||||
|
#define SCR_FIQ (1 << 2)
|
||||||
|
#define SCR_EA (1 << 3)
|
||||||
|
#define SCR_FW (1 << 4)
|
||||||
|
#define SCR_AW (1 << 5)
|
||||||
|
|
||||||
|
VOID
|
||||||
|
EFIAPI
|
||||||
|
ArmEnableSWPInstruction (
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
EFIAPI
|
||||||
|
ArmWriteNsacr (
|
||||||
|
IN UINT32 SetWayFormat
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
EFIAPI
|
||||||
|
ArmWriteScr (
|
||||||
|
IN UINT32 SetWayFormat
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
EFIAPI
|
||||||
|
ArmWriteVMBar (
|
||||||
|
IN UINT32 SetWayFormat
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
EFIAPI
|
||||||
|
ArmWriteVBar (
|
||||||
|
IN UINT32 SetWayFormat
|
||||||
|
);
|
||||||
|
|
||||||
|
UINT32
|
||||||
|
EFIAPI
|
||||||
|
ArmReadVBar (
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
EFIAPI
|
||||||
|
ArmWriteCPACR (
|
||||||
|
IN UINT32 SetWayFormat
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
EFIAPI
|
||||||
|
ArmEnableVFP (
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
EFIAPI
|
||||||
|
ArmCallWFI (
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
EFIAPI
|
||||||
|
ArmInvalidScu (
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
UINTN
|
||||||
|
EFIAPI
|
||||||
|
ArmGetScuBaseAddress (
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
UINT32
|
||||||
|
EFIAPI
|
||||||
|
ArmIsScuEnable(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
EFIAPI
|
||||||
|
ArmWriteAuxCr (
|
||||||
|
IN UINT32 Bit
|
||||||
|
);
|
||||||
|
|
||||||
|
UINT32
|
||||||
|
EFIAPI
|
||||||
|
ArmReadAuxCr (
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
EFIAPI
|
||||||
|
ArmSetAuxCrBit (
|
||||||
|
IN UINT32 Bits
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
EFIAPI
|
||||||
|
ArmSetupSmpNonSecure (
|
||||||
|
IN UINTN CoreId
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
UINTN
|
||||||
|
EFIAPI
|
||||||
|
ArmReadCbar(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
EFIAPI
|
||||||
|
ArmInvalidateInstructionAndDataTlb(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
UINTN
|
||||||
|
EFIAPI
|
||||||
|
ArmReadMpidr(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
#endif // __ARM_V7_H__
|
#endif // __ARM_V7_H__
|
||||||
|
84
ArmPkg/Include/Drivers/PL341Dmc.h
Normal file
84
ArmPkg/Include/Drivers/PL341Dmc.h
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
/** @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.
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
|
||||||
|
#ifndef PL341DMC_H_
|
||||||
|
#define PL341DMC_H_
|
||||||
|
|
||||||
|
|
||||||
|
struct pl341_dmc_config {
|
||||||
|
UINTN base; // base address for the controller
|
||||||
|
UINTN has_qos; // has QoS registers
|
||||||
|
UINTN max_chip; // number of memory chips accessible
|
||||||
|
UINT32 refresh_prd;
|
||||||
|
UINT32 cas_latency;
|
||||||
|
UINT32 write_latency;
|
||||||
|
UINT32 t_mrd;
|
||||||
|
UINT32 t_ras;
|
||||||
|
UINT32 t_rc;
|
||||||
|
UINT32 t_rcd;
|
||||||
|
UINT32 t_rfc;
|
||||||
|
UINT32 t_rp;
|
||||||
|
UINT32 t_rrd;
|
||||||
|
UINT32 t_wr;
|
||||||
|
UINT32 t_wtr;
|
||||||
|
UINT32 t_xp;
|
||||||
|
UINT32 t_xsr;
|
||||||
|
UINT32 t_esr;
|
||||||
|
UINT32 memory_cfg;
|
||||||
|
UINT32 memory_cfg2;
|
||||||
|
UINT32 memory_cfg3;
|
||||||
|
UINT32 chip_cfg0;
|
||||||
|
UINT32 chip_cfg1;
|
||||||
|
UINT32 chip_cfg2;
|
||||||
|
UINT32 chip_cfg3;
|
||||||
|
UINT32 t_faw;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Memory config bit fields */
|
||||||
|
#define DMC_MEMORY_CONFIG_COLUMN_ADDRESS_9 0x1
|
||||||
|
#define DMC_MEMORY_CONFIG_COLUMN_ADDRESS_10 0x2
|
||||||
|
#define DMC_MEMORY_CONFIG_COLUMN_ADDRESS_11 0x3
|
||||||
|
#define DMC_MEMORY_CONFIG_COLUMN_ADDRESS_12 0x4
|
||||||
|
#define DMC_MEMORY_CONFIG_ROW_ADDRESS_11 (0x0 << 3)
|
||||||
|
#define DMC_MEMORY_CONFIG_ROW_ADDRESS_12 (0x1 << 3)
|
||||||
|
#define DMC_MEMORY_CONFIG_ROW_ADDRESS_13 (0x2 << 3)
|
||||||
|
#define DMC_MEMORY_CONFIG_ROW_ADDRESS_14 (0x3 << 3)
|
||||||
|
#define DMC_MEMORY_CONFIG_ROW_ADDRESS_15 (0x4 << 3)
|
||||||
|
#define DMC_MEMORY_CONFIG_ROW_ADDRESS_16 (0x5 << 3)
|
||||||
|
#define DMC_MEMORY_CONFIG_BURST_2 (0x1 << 15)
|
||||||
|
#define DMC_MEMORY_CONFIG_BURST_4 (0x2 << 15)
|
||||||
|
#define DMC_MEMORY_CONFIG_BURST_8 (0x3 << 15)
|
||||||
|
#define DMC_MEMORY_CONFIG_BURST_16 (0x4 << 15)
|
||||||
|
#define DMC_MEMORY_CONFIG_ACTIVE_CHIP_1 (0x0 << 21)
|
||||||
|
#define DMC_MEMORY_CONFIG_ACTIVE_CHIP_2 (0x1 << 21)
|
||||||
|
#define DMC_MEMORY_CONFIG_ACTIVE_CHIP_3 (0x2 << 21)
|
||||||
|
#define DMC_MEMORY_CONFIG_ACTIVE_CHIP_4 (0x3 << 21)
|
||||||
|
|
||||||
|
#define DMC_MEMORY_CFG2_CLK_ASYNC (0x0 << 0)
|
||||||
|
#define DMC_MEMORY_CFG2_CLK_SYNC (0x1 << 0)
|
||||||
|
#define DMC_MEMORY_CFG2_DQM_INIT (0x1 << 2)
|
||||||
|
#define DMC_MEMORY_CFG2_CKE_INIT (0x1 << 3)
|
||||||
|
#define DMC_MEMORY_CFG2_BANK_BITS_2 (0x0 << 4)
|
||||||
|
#define DMC_MEMORY_CFG2_BANK_BITS_3 (0x3 << 4)
|
||||||
|
#define DMC_MEMORY_CFG2_MEM_WIDTH_16 (0x0 << 6)
|
||||||
|
#define DMC_MEMORY_CFG2_MEM_WIDTH_32 (0x1 << 6)
|
||||||
|
#define DMC_MEMORY_CFG2_MEM_WIDTH_64 (0x2 << 6)
|
||||||
|
#define DMC_MEMORY_CFG2_MEM_WIDTH_RESERVED (0x3 << 6)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
VOID PL341DmcInit(struct pl341_dmc_config *config);
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* PL341DMC_H_ */
|
120
ArmPkg/Include/Drivers/PL390Gic.h
Normal file
120
ArmPkg/Include/Drivers/PL390Gic.h
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
/** @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.
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
|
||||||
|
#ifndef __PL390GIC_H
|
||||||
|
#define __PL390GIC_H
|
||||||
|
|
||||||
|
//
|
||||||
|
// GIC definitions
|
||||||
|
//
|
||||||
|
|
||||||
|
// Distributor
|
||||||
|
#define GIC_ICDDCR 0x000 // Distributor Control Register
|
||||||
|
#define GIC_ICDICTR 0x004 // Interrupt Controller Type Register
|
||||||
|
#define GIC_ICDIIDR 0x008 // Implementer Identification Register
|
||||||
|
|
||||||
|
// each reg base below repeats for VE_NUM_GIC_REG_PER_INT_BITS (see GIC spec)
|
||||||
|
#define GIC_ICDISR 0x080 // Interrupt Security Registers
|
||||||
|
#define GIC_ICDISER 0x100 // Interrupt Set-Enable Registers
|
||||||
|
#define GIC_ICDICER 0x180 // Interrupt Clear-Enable Registers
|
||||||
|
#define GIC_ICDSPR 0x200 // Interrupt Set-Pending Registers
|
||||||
|
#define GIC_ICDICPR 0x280 // Interrupt Clear-Pending Registers
|
||||||
|
#define GIC_ICDABR 0x300 // Active Bit Registers
|
||||||
|
|
||||||
|
// each reg base below repeats for VE_NUM_GIC_REG_PER_INT_BYTES
|
||||||
|
#define GIC_ICDIPR 0x400 // Interrupt Priority Registers
|
||||||
|
|
||||||
|
// each reg base below repeats for VE_NUM_GIC_INTERRUPTS
|
||||||
|
#define GIC_ICDIPTR 0x800 // Interrupt Processor Target Registers
|
||||||
|
#define GIC_ICDICFR 0xC00 // Interrupt Configuration Registers
|
||||||
|
|
||||||
|
// just one of these
|
||||||
|
#define GIC_ICDSGIR 0xF00 // Software Generated Interrupt Register
|
||||||
|
|
||||||
|
// Cpu interface
|
||||||
|
#define GIC_ICCICR 0x00 // CPU Interface Control Register
|
||||||
|
#define GIC_ICCPMR 0x04 // Interrupt Priority Mask Register
|
||||||
|
#define GIC_ICCBPR 0x08 // Binary Point Register
|
||||||
|
#define GIC_ICCIAR 0x0C // Interrupt Acknowledge Register
|
||||||
|
#define GIC_ICCEIOR 0x10 // End Of Interrupt Register
|
||||||
|
#define GIC_ICCRPR 0x14 // Running Priority Register
|
||||||
|
#define GIC_ICCPIR 0x18 // Highest Pending Interrupt Register
|
||||||
|
#define GIC_ICCABPR 0x1C // Aliased Binary Point Register
|
||||||
|
#define GIC_ICCIDR 0xFC // Identification Register
|
||||||
|
|
||||||
|
#define GIC_ICDSGIR_FILTER_TARGETLIST 0x0
|
||||||
|
#define GIC_ICDSGIR_FILTER_EVERYONEELSE 0x1
|
||||||
|
#define GIC_ICDSGIR_FILTER_ITSELF 0x2
|
||||||
|
|
||||||
|
//Bit-masks to configure the CPU Interface Control register
|
||||||
|
#define GIC_ICCICR_ENABLE_SECURE(a) ((a << 0) & 0x01)
|
||||||
|
#define GIC_ICCICR_ENABLE_NS(a) ((a << 1) & 0x02)
|
||||||
|
#define GIC_ICCICR_ACK_CTL(a) ((a << 2) & 0x04)
|
||||||
|
#define GIC_ICCICR_SIGNAL_SECURE_TO_FIQ(a)((a << 3) & 0x08)
|
||||||
|
#define GIC_ICCICR_USE_SBPR(a) ((a << 4) & 0x10)
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// GIC SEC interfaces
|
||||||
|
//
|
||||||
|
VOID
|
||||||
|
EFIAPI
|
||||||
|
PL390GicSetupNonSecure (
|
||||||
|
IN INTN GicDistributorBase,
|
||||||
|
IN INTN GicInterruptInterfaceBase
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
EFIAPI
|
||||||
|
PL390GicEnableInterruptInterface (
|
||||||
|
IN INTN GicInterruptInterfaceBase
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
EFIAPI
|
||||||
|
PL390GicEnableDistributor (
|
||||||
|
IN INTN GicDistributorBase
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
EFIAPI
|
||||||
|
PL390GicSendSgiTo (
|
||||||
|
IN INTN GicDistributorBase,
|
||||||
|
IN INTN TargetListFilter,
|
||||||
|
IN INTN CPUTargetList
|
||||||
|
);
|
||||||
|
|
||||||
|
UINT32
|
||||||
|
EFIAPI
|
||||||
|
PL390GicAcknowledgeSgiFrom (
|
||||||
|
IN INTN GicInterruptInterfaceBase,
|
||||||
|
IN INTN CoreId
|
||||||
|
);
|
||||||
|
|
||||||
|
UINT32
|
||||||
|
EFIAPI
|
||||||
|
PL390GicAcknowledgeSgi2From (
|
||||||
|
IN INTN GicInterruptInterfaceBase,
|
||||||
|
IN INTN CoreId,
|
||||||
|
IN INTN SgiId
|
||||||
|
);
|
||||||
|
|
||||||
|
UINTN
|
||||||
|
EFIAPI
|
||||||
|
PL390GicSetPriorityMask (
|
||||||
|
IN INTN GicInterruptInterfaceBase,
|
||||||
|
IN INTN PriorityMask
|
||||||
|
);
|
||||||
|
|
||||||
|
#endif
|
@ -43,7 +43,11 @@ typedef enum {
|
|||||||
ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED,
|
ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED,
|
||||||
ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK,
|
ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK,
|
||||||
ARM_MEMORY_REGION_ATTRIBUTE_WRITE_THROUGH,
|
ARM_MEMORY_REGION_ATTRIBUTE_WRITE_THROUGH,
|
||||||
ARM_MEMORY_REGION_ATTRIBUTE_DEVICE
|
ARM_MEMORY_REGION_ATTRIBUTE_DEVICE,
|
||||||
|
ARM_MEMORY_REGION_ATTRIBUTE_SECURE_UNCACHED_UNBUFFERED,
|
||||||
|
ARM_MEMORY_REGION_ATTRIBUTE_SECURE_WRITE_BACK,
|
||||||
|
ARM_MEMORY_REGION_ATTRIBUTE_SECURE_WRITE_THROUGH,
|
||||||
|
ARM_MEMORY_REGION_ATTRIBUTE_SECURE_DEVICE
|
||||||
} ARM_MEMORY_REGION_ATTRIBUTES;
|
} ARM_MEMORY_REGION_ATTRIBUTES;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -145,6 +149,12 @@ Cp15CacheInfo (
|
|||||||
VOID
|
VOID
|
||||||
);
|
);
|
||||||
|
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
ArmIsMPCore (
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
EFIAPI
|
EFIAPI
|
||||||
ArmInvalidateDataCache (
|
ArmInvalidateDataCache (
|
||||||
@ -224,6 +234,12 @@ ArmDisableMmu (
|
|||||||
VOID
|
VOID
|
||||||
);
|
);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
EFIAPI
|
||||||
|
ArmDisableCachesAndMmu (
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
EFIAPI
|
EFIAPI
|
||||||
ArmEnableInterrupts (
|
ArmEnableInterrupts (
|
||||||
@ -241,6 +257,7 @@ EFIAPI
|
|||||||
ArmGetInterruptState (
|
ArmGetInterruptState (
|
||||||
VOID
|
VOID
|
||||||
);
|
);
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
EFIAPI
|
EFIAPI
|
||||||
ArmEnableFiq (
|
ArmEnableFiq (
|
||||||
@ -280,13 +297,13 @@ ArmSetDomainAccessControl (
|
|||||||
|
|
||||||
VOID
|
VOID
|
||||||
EFIAPI
|
EFIAPI
|
||||||
ArmSetTranslationTableBaseAddress (
|
ArmSetTTBR0 (
|
||||||
IN VOID *TranslationTableBase
|
IN VOID *TranslationTableBase
|
||||||
);
|
);
|
||||||
|
|
||||||
VOID *
|
VOID *
|
||||||
EFIAPI
|
EFIAPI
|
||||||
ArmGetTranslationTableBaseAddress (
|
ArmGetTTBR0BaseAddress (
|
||||||
VOID
|
VOID
|
||||||
);
|
);
|
||||||
|
|
||||||
|
22
ArmPkg/Include/Library/ArmMPCoreMailBoxLib.h
Normal file
22
ArmPkg/Include/Library/ArmMPCoreMailBoxLib.h
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
/** @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.
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
|
||||||
|
#ifndef _ARM_MPCORE_MAILBOX_LIB_H_
|
||||||
|
#define _ARM_MPCORE_MAILBOX_LIB_H_
|
||||||
|
|
||||||
|
VOID ArmClearMPCoreMailbox(VOID);
|
||||||
|
|
||||||
|
UINTN ArmGetMPCoreMailbox(VOID);
|
||||||
|
|
||||||
|
#endif
|
69
ArmPkg/Include/Library/ArmTrustZoneLib.h
Normal file
69
ArmPkg/Include/Library/ArmTrustZoneLib.h
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
/** @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.
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
|
||||||
|
#ifndef __ARM_TRUSTZONE_LIB_H__
|
||||||
|
#define __ARM_TRUSTZONE_LIB_H__
|
||||||
|
|
||||||
|
#include <Uefi.h>
|
||||||
|
|
||||||
|
// Setup TZ Protection Controller
|
||||||
|
#define TZPC_DECPROT_0 0
|
||||||
|
#define TZPC_DECPROT_1 1
|
||||||
|
#define TZPC_DECPROT_2 2
|
||||||
|
#define TZPC_DECPROT_MAX 2
|
||||||
|
|
||||||
|
/**
|
||||||
|
FIXME: Need documentation
|
||||||
|
**/
|
||||||
|
EFI_STATUS TZPCSetDecProtBits(UINTN tzpc_base, UINTN tzpc_id, UINTN bits);
|
||||||
|
|
||||||
|
/**
|
||||||
|
FIXME: Need documentation
|
||||||
|
**/
|
||||||
|
EFI_STATUS TZPCClearDecProtBits(UINTN tzpc_base, UINTN tzpc_id, UINTN bits);
|
||||||
|
|
||||||
|
// Setup TZ Address Space Controller
|
||||||
|
#define TZASC_REGION_ENABLED 1
|
||||||
|
#define TZASC_REGION_DISABLED 0
|
||||||
|
#define TZASC_REGION_SIZE_32KB 0xE
|
||||||
|
#define TZASC_REGION_SIZE_64KB 0xF
|
||||||
|
#define TZASC_REGION_SIZE_128KB 0x10
|
||||||
|
#define TZASC_REGION_SIZE_256KB 0x11
|
||||||
|
#define TZASC_REGION_SIZE_512KB 0x12
|
||||||
|
#define TZASC_REGION_SIZE_1MB 0x13
|
||||||
|
#define TZASC_REGION_SIZE_2MB 0x14
|
||||||
|
#define TZASC_REGION_SIZE_4MB 0x15
|
||||||
|
#define TZASC_REGION_SIZE_8MB 0x16
|
||||||
|
#define TZASC_REGION_SIZE_16MB 0x17
|
||||||
|
#define TZASC_REGION_SIZE_32MB 0x18
|
||||||
|
#define TZASC_REGION_SIZE_64MB 0x19
|
||||||
|
#define TZASC_REGION_SIZE_128MB 0x1A
|
||||||
|
#define TZASC_REGION_SIZE_256MB 0x1B
|
||||||
|
#define TZASC_REGION_SIZE_512MB 0x1C
|
||||||
|
#define TZASC_REGION_SIZE_1GB 0x1D
|
||||||
|
#define TZASC_REGION_SIZE_2GB 0x1E
|
||||||
|
#define TZASC_REGION_SIZE_4GB 0x1F
|
||||||
|
#define TZASC_REGION_SECURITY_SR (1 << 3)
|
||||||
|
#define TZASC_REGION_SECURITY_SW (1 << 2)
|
||||||
|
#define TZASC_REGION_SECURITY_SRW (TZASC_REGION_SECURITY_SR|TZASC_REGION_SECURITY_SW)
|
||||||
|
#define TZASC_REGION_SECURITY_NSR (1 << 1)
|
||||||
|
#define TZASC_REGION_SECURITY_NSW 1
|
||||||
|
#define TZASC_REGION_SECURITY_NSRW (TZASC_REGION_SECURITY_NSR|TZASC_REGION_SECURITY_NSW)
|
||||||
|
|
||||||
|
/**
|
||||||
|
FIXME: Need documentation
|
||||||
|
**/
|
||||||
|
EFI_STATUS TZASCSetRegion(UINTN tzasc_base, UINTN region_id, UINTN enabled, UINTN low_address, UINTN high_address, UINTN size, UINTN security);
|
||||||
|
|
||||||
|
#endif
|
38
ArmPkg/Include/Library/BdsUnixLib.h
Normal file
38
ArmPkg/Include/Library/BdsUnixLib.h
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
/** @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.
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
|
||||||
|
#ifndef __BDS_ENTRY_H__
|
||||||
|
#define __BDS_ENTRY_H__
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
BdsConnectAllDrivers ( VOID );
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
BdsBootLinux (
|
||||||
|
IN CONST CHAR16* LinuxKernel,
|
||||||
|
IN CONST CHAR8* ATag,
|
||||||
|
IN CONST CHAR16* Fdt
|
||||||
|
);
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
BdsLoadApplication (
|
||||||
|
IN CHAR16* EfiApp
|
||||||
|
);
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
BdsLoadApplicationFromPath (
|
||||||
|
IN CHAR16* EfiAppPath
|
||||||
|
);
|
||||||
|
|
||||||
|
#endif
|
62
ArmPkg/Include/Library/L2X0CacheLib.h
Normal file
62
ArmPkg/Include/Library/L2X0CacheLib.h
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
/** @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.
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
|
||||||
|
#ifndef L2CACHELIB_H_
|
||||||
|
#define L2CACHELIB_H_
|
||||||
|
|
||||||
|
#define L2_LATENCY 7
|
||||||
|
|
||||||
|
#define L2_TAG_ACCESS_LATENCY L2_LATENCY
|
||||||
|
#define L2_TAG_SETUP_LATENCY L2_LATENCY
|
||||||
|
#define L2_DATA_ACCESS_LATENCY L2_LATENCY
|
||||||
|
#define L2_DATA_SETUP_LATENCY L2_LATENCY
|
||||||
|
|
||||||
|
|
||||||
|
#define L2X0_CACHEID 0x000
|
||||||
|
#define L2X0_CTRL 0x100
|
||||||
|
#define L2X0_AUXCTRL 0x104
|
||||||
|
#define L230_TAG_LATENCY 0x108
|
||||||
|
#define L230_DATA_LATENCY 0x10C
|
||||||
|
#define L2X0_INTCLEAR 0x220
|
||||||
|
#define L2X0_CACHE_SYNC 0x730
|
||||||
|
#define L2X0_INVWAY 0x77C
|
||||||
|
#define L2X0_CLEAN_WAY 0x7BC
|
||||||
|
#define L2X0_PFCTRL 0xF60
|
||||||
|
#define L2X0_PWRCTRL 0xF80
|
||||||
|
|
||||||
|
#define L2X0_CACHEID_IMPLEMENTER_ARM 0x41
|
||||||
|
#define L2X0_CACHEID_PARTNUM_PL310 0x03
|
||||||
|
|
||||||
|
#define L2X0_CTRL_ENABLED 0x1
|
||||||
|
#define L2X0_CTRL_DISABLED 0x0
|
||||||
|
|
||||||
|
#define L2X0_AUXCTRL_EXCLUSIVE (1<<12)
|
||||||
|
#define L2X0_AUXCTRL_WAYSIZE_16KB (0x001 << 17)
|
||||||
|
#define L2X0_AUXCTRL_WAYSIZE_32KB (0x010 << 17)
|
||||||
|
#define L2X0_AUXCTRL_WAYSIZE_64KB (0x011 << 17)
|
||||||
|
#define L2X0_AUXCTRL_WAYSIZE_128KB (0x100 << 17)
|
||||||
|
#define L2X0_AUXCTRL_WAYSIZE_256KB (0x101 << 17)
|
||||||
|
#define L2X0_AUXCTRL_WAYSIZE_512KB (0x110 << 17)
|
||||||
|
#define L2X0_AUXCTRL_EM (1 << 20)
|
||||||
|
#define L2x0_AUXCTRL_AW_AWCACHE (0x00 << 23)
|
||||||
|
#define L2x0_AUXCTRL_AW_NOALLOC (0x01 << 23)
|
||||||
|
#define L2x0_AUXCTRL_AW_OVERRIDE (0x10 << 23)
|
||||||
|
#define L2X0_AUXCTRL_SBO (1 << 25)
|
||||||
|
#define L2X0_AUXCTRL_NSAC (1 << 27)
|
||||||
|
#define L2x0_AUXCTRL_DPREFETCH (1 << 28)
|
||||||
|
#define L2x0_AUXCTRL_IPREFETCH (1 << 29)
|
||||||
|
|
||||||
|
VOID L2x0CacheInit(UINTN L2x0Base, BOOLEAN CacheEnabled);
|
||||||
|
|
||||||
|
#endif /* L2CACHELIB_H_ */
|
112
ArmPkg/Include/Protocol/MmcHost.h
Normal file
112
ArmPkg/Include/Protocol/MmcHost.h
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
/** @file
|
||||||
|
Definition of the MMC Host Protocol
|
||||||
|
|
||||||
|
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 __MMC_HOST_H__
|
||||||
|
#define __MMC_HOST_H__
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Global ID for the MMC Host Protocol
|
||||||
|
///
|
||||||
|
#define EFI_MMC_HOST_PROTOCOL_GUID \
|
||||||
|
{ 0x3e591c00, 0x9e4a, 0x11df, {0x92, 0x44, 0x00, 0x02, 0xA5, 0xD5, 0xC5, 0x1B } }
|
||||||
|
|
||||||
|
#define MMC_RESPONSE_TYPE_R1 0
|
||||||
|
#define MMC_RESPONSE_TYPE_R1b 0
|
||||||
|
#define MMC_RESPONSE_TYPE_R2 1
|
||||||
|
#define MMC_RESPONSE_TYPE_R3 0
|
||||||
|
#define MMC_RESPONSE_TYPE_R6 0
|
||||||
|
#define MMC_RESPONSE_TYPE_R7 0
|
||||||
|
#define MMC_RESPONSE_TYPE_OCR 0
|
||||||
|
#define MMC_RESPONSE_TYPE_CID 1
|
||||||
|
#define MMC_RESPONSE_TYPE_CSD 1
|
||||||
|
#define MMC_RESPONSE_TYPE_RCA 0
|
||||||
|
|
||||||
|
typedef UINT32 MMC_RESPONSE_TYPE;
|
||||||
|
|
||||||
|
typedef UINT32 MMC_CMD;
|
||||||
|
|
||||||
|
#define MMC_CMD_WAIT_RESPONSE (1 << 16)
|
||||||
|
#define MMC_CMD_LONG_RESPONSE (1 << 17)
|
||||||
|
|
||||||
|
#define MMC_INDX(CMD_INDX) (CMD_INDX & 0xFFFF)
|
||||||
|
|
||||||
|
#define MMC_CMD0 MMC_INDX(0)
|
||||||
|
#define MMC_CMD1 (MMC_INDX(1) | MMC_CMD_WAIT_RESPONSE)
|
||||||
|
#define MMC_CMD2 (MMC_INDX(2) | MMC_CMD_WAIT_RESPONSE | MMC_CMD_LONG_RESPONSE)
|
||||||
|
#define MMC_CMD3 (MMC_INDX(3) | MMC_CMD_WAIT_RESPONSE)
|
||||||
|
#define MMC_CMD5 (MMC_INDX(5) | MMC_CMD_WAIT_RESPONSE)
|
||||||
|
#define MMC_CMD7 (MMC_INDX(7) | MMC_CMD_WAIT_RESPONSE)
|
||||||
|
#define MMC_CMD8 (MMC_INDX(8) | MMC_CMD_WAIT_RESPONSE)
|
||||||
|
#define MMC_CMD9 (MMC_INDX(9) | MMC_CMD_WAIT_RESPONSE | MMC_CMD_LONG_RESPONSE)
|
||||||
|
#define MMC_CMD11 (MMC_INDX(11) | MMC_CMD_WAIT_RESPONSE)
|
||||||
|
#define MMC_CMD12 (MMC_INDX(12) | MMC_CMD_WAIT_RESPONSE)
|
||||||
|
#define MMC_CMD13 (MMC_INDX(13) | MMC_CMD_WAIT_RESPONSE)
|
||||||
|
#define MMC_CMD16 (MMC_INDX(16) | MMC_CMD_WAIT_RESPONSE)
|
||||||
|
#define MMC_CMD17 (MMC_INDX(17) | MMC_CMD_WAIT_RESPONSE)
|
||||||
|
#define MMC_CMD18 (MMC_INDX(18) | MMC_CMD_WAIT_RESPONSE)
|
||||||
|
#define MMC_CMD20 (MMC_INDX(20) | MMC_CMD_WAIT_RESPONSE)
|
||||||
|
#define MMC_CMD23 (MMC_INDX(23) | MMC_CMD_WAIT_RESPONSE)
|
||||||
|
#define MMC_CMD24 (MMC_INDX(24) | MMC_CMD_WAIT_RESPONSE)
|
||||||
|
#define MMC_CMD55 (MMC_INDX(55) | MMC_CMD_WAIT_RESPONSE)
|
||||||
|
#define MMC_ACMD41 (MMC_INDX(41) | MMC_CMD_WAIT_RESPONSE)
|
||||||
|
|
||||||
|
typedef enum _MMC_STATE {
|
||||||
|
MmcInvalidState = 0,
|
||||||
|
MmcHwInitializationState,
|
||||||
|
MmcIdleState,
|
||||||
|
MmcReadyState,
|
||||||
|
MmcIdentificationState,
|
||||||
|
MmcStandByState,
|
||||||
|
MmcTransferState,
|
||||||
|
MmcSendingDataState,
|
||||||
|
MmcReceiveDataState,
|
||||||
|
MmcProgrammingState,
|
||||||
|
MmcDisconnectState,
|
||||||
|
} MMC_STATE;
|
||||||
|
|
||||||
|
typedef BOOLEAN (*MMC_ISCARDPRESENT)();
|
||||||
|
|
||||||
|
typedef BOOLEAN (*MMC_ISREADONLY)();
|
||||||
|
|
||||||
|
typedef EFI_STATUS (*MMC_BUILDDEVICEPATH)(EFI_DEVICE_PATH_PROTOCOL **DevicePath);
|
||||||
|
|
||||||
|
typedef EFI_STATUS (*MMC_NOTIFYSTATE)(MMC_STATE State);
|
||||||
|
|
||||||
|
typedef EFI_STATUS (*MMC_SENDCOMMAND)(MMC_CMD Cmd, UINT32 Argument);
|
||||||
|
|
||||||
|
typedef EFI_STATUS (*MMC_RECEIVERESPONSE)(MMC_RESPONSE_TYPE Type, UINT32* Buffer);
|
||||||
|
|
||||||
|
typedef EFI_STATUS (*MMC_READBLOCKDATA)(EFI_LBA Lba, UINTN Length, UINT32* Buffer);
|
||||||
|
|
||||||
|
typedef EFI_STATUS (*MMC_WRITEBLOCKDATA)(EFI_LBA Lba, UINTN Length, UINT32* Buffer);
|
||||||
|
|
||||||
|
typedef struct _EFI_MMC_HOST_PROTOCOL {
|
||||||
|
MMC_ISCARDPRESENT IsCardPresent;
|
||||||
|
MMC_ISREADONLY IsReadOnly;
|
||||||
|
MMC_BUILDDEVICEPATH BuildDevicePath;
|
||||||
|
|
||||||
|
MMC_NOTIFYSTATE NotifyState;
|
||||||
|
|
||||||
|
MMC_SENDCOMMAND SendCommand;
|
||||||
|
MMC_RECEIVERESPONSE ReceiveResponse;
|
||||||
|
|
||||||
|
MMC_READBLOCKDATA ReadBlockData;
|
||||||
|
MMC_WRITEBLOCKDATA WriteBlockData;
|
||||||
|
} EFI_MMC_HOST_PROTOCOL;
|
||||||
|
|
||||||
|
extern EFI_GUID gEfiMmcHostProtocolGuid;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -215,7 +215,7 @@ DmaAllocateBuffer (
|
|||||||
//
|
//
|
||||||
if (MemoryType == EfiBootServicesData) {
|
if (MemoryType == EfiBootServicesData) {
|
||||||
*HostAddress = UncachedAllocatePages (Pages);
|
*HostAddress = UncachedAllocatePages (Pages);
|
||||||
} else if (MemoryType != EfiRuntimeServicesData) {
|
} else if (MemoryType == EfiRuntimeServicesData) {
|
||||||
*HostAddress = UncachedAllocateRuntimePages (Pages);
|
*HostAddress = UncachedAllocateRuntimePages (Pages);
|
||||||
} else {
|
} else {
|
||||||
return EFI_INVALID_PARAMETER;
|
return EFI_INVALID_PARAMETER;
|
||||||
|
@ -31,14 +31,25 @@ FillTranslationTable (
|
|||||||
|
|
||||||
switch (MemoryRegion->Attributes) {
|
switch (MemoryRegion->Attributes) {
|
||||||
case ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK:
|
case ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK:
|
||||||
Attributes = TT_DESCRIPTOR_SECTION_WRITE_BACK;
|
Attributes = TT_DESCRIPTOR_SECTION_WRITE_BACK(0);
|
||||||
break;
|
break;
|
||||||
case ARM_MEMORY_REGION_ATTRIBUTE_WRITE_THROUGH:
|
case ARM_MEMORY_REGION_ATTRIBUTE_WRITE_THROUGH:
|
||||||
Attributes = TT_DESCRIPTOR_SECTION_WRITE_THROUGH;
|
Attributes = TT_DESCRIPTOR_SECTION_WRITE_THROUGH(0);
|
||||||
break;
|
break;
|
||||||
case ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED:
|
case ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED:
|
||||||
|
Attributes = TT_DESCRIPTOR_SECTION_UNCACHED(0);
|
||||||
|
break;
|
||||||
|
case ARM_MEMORY_REGION_ATTRIBUTE_SECURE_WRITE_BACK:
|
||||||
|
Attributes = TT_DESCRIPTOR_SECTION_WRITE_BACK(1);
|
||||||
|
break;
|
||||||
|
case ARM_MEMORY_REGION_ATTRIBUTE_SECURE_WRITE_THROUGH:
|
||||||
|
Attributes = TT_DESCRIPTOR_SECTION_WRITE_THROUGH(1);
|
||||||
|
break;
|
||||||
|
case ARM_MEMORY_REGION_ATTRIBUTE_SECURE_UNCACHED_UNBUFFERED:
|
||||||
|
Attributes = TT_DESCRIPTOR_SECTION_UNCACHED(1);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
Attributes = TT_DESCRIPTOR_SECTION_UNCACHED;
|
Attributes = TT_DESCRIPTOR_SECTION_UNCACHED(0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -93,7 +104,7 @@ ArmConfigureMmu (
|
|||||||
MemoryTable++;
|
MemoryTable++;
|
||||||
}
|
}
|
||||||
|
|
||||||
ArmSetTranslationTableBaseAddress(TranslationTable);
|
ArmSetTTBR0(TranslationTable);
|
||||||
|
|
||||||
ArmSetDomainAccessControl(DOMAIN_ACCESS_CONTROL_NONE(15) |
|
ArmSetDomainAccessControl(DOMAIN_ACCESS_CONTROL_NONE(15) |
|
||||||
DOMAIN_ACCESS_CONTROL_NONE(14) |
|
DOMAIN_ACCESS_CONTROL_NONE(14) |
|
||||||
|
@ -12,46 +12,29 @@
|
|||||||
#
|
#
|
||||||
#------------------------------------------------------------------------------
|
#------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include <AsmMacroIoLib.h>
|
||||||
|
|
||||||
.text
|
.text
|
||||||
.align 2
|
.align 2
|
||||||
.globl ASM_PFX(ArmCleanInvalidateDataCache)
|
GCC_ASM_EXPORT(ArmCleanInvalidateDataCache)
|
||||||
INTERWORK_FUNC(ArmCleanInvalidateDataCache)
|
GCC_ASM_EXPORT(ArmCleanDataCache)
|
||||||
.globl ASM_PFX(ArmCleanDataCache)
|
GCC_ASM_EXPORT(ArmInvalidateDataCache)
|
||||||
INTERWORK_FUNC(ArmCleanDataCache)
|
GCC_ASM_EXPORT(ArmInvalidateInstructionCache)
|
||||||
.globl ASM_PFX(ArmInvalidateDataCache)
|
GCC_ASM_EXPORT(ArmInvalidateDataCacheEntryByMVA)
|
||||||
INTERWORK_FUNC(ArmInvalidateDataCache)
|
GCC_ASM_EXPORT(ArmCleanDataCacheEntryByMVA)
|
||||||
.globl ASM_PFX(ArmInvalidateInstructionCache)
|
GCC_ASM_EXPORT(ArmCleanInvalidateDataCacheEntryByMVA)
|
||||||
INTERWORK_FUNC(ArmInvalidateInstructionCache)
|
GCC_ASM_EXPORT(ArmEnableMmu)
|
||||||
.globl ASM_PFX(ArmInvalidateDataCacheEntryByMVA)
|
GCC_ASM_EXPORT(ArmDisableMmu)
|
||||||
INTERWORK_FUNC(ArmInvalidateDataCacheEntryByMVA)
|
GCC_ASM_EXPORT(ArmMmuEnabled)
|
||||||
.globl ASM_PFX(ArmCleanDataCacheEntryByMVA)
|
GCC_ASM_EXPORT(ArmEnableDataCache)
|
||||||
INTERWORK_FUNC(ArmCleanDataCacheEntryByMVA)
|
GCC_ASM_EXPORT(ArmDisableDataCache)
|
||||||
.globl ASM_PFX(ArmCleanInvalidateDataCacheEntryByMVA)
|
GCC_ASM_EXPORT(ArmEnableInstructionCache)
|
||||||
INTERWORK_FUNC(ArmCleanInvalidateDataCacheEntryByMVA)
|
GCC_ASM_EXPORT(ArmDisableInstructionCache)
|
||||||
.globl ASM_PFX(ArmEnableMmu)
|
GCC_ASM_EXPORT(ArmEnableBranchPrediction)
|
||||||
INTERWORK_FUNC(ArmEnableMmu)
|
GCC_ASM_EXPORT(ArmDisableBranchPrediction)
|
||||||
.globl ASM_PFX(ArmDisableMmu)
|
GCC_ASM_EXPORT(ArmDataMemoryBarrier)
|
||||||
INTERWORK_FUNC(ArmDisableMmu)
|
GCC_ASM_EXPORT(ArmDataSyncronizationBarrier)
|
||||||
.globl ASM_PFX(ArmMmuEnabled)
|
GCC_ASM_EXPORT(ArmInstructionSynchronizationBarrier)
|
||||||
INTERWORK_FUNC(ArmMmuEnabled)
|
|
||||||
.globl ASM_PFX(ArmEnableDataCache)
|
|
||||||
INTERWORK_FUNC(ArmEnableDataCache)
|
|
||||||
.globl ASM_PFX(ArmDisableDataCache)
|
|
||||||
INTERWORK_FUNC(ArmDisableDataCache)
|
|
||||||
.globl ASM_PFX(ArmEnableInstructionCache)
|
|
||||||
INTERWORK_FUNC(ArmEnableInstructionCache)
|
|
||||||
.globl ASM_PFX(ArmDisableInstructionCache)
|
|
||||||
INTERWORK_FUNC(ArmDisableInstructionCache)
|
|
||||||
.globl ASM_PFX(ArmEnableBranchPrediction)
|
|
||||||
INTERWORK_FUNC(ArmEnableBranchPrediction)
|
|
||||||
.globl ASM_PFX(ArmDisableBranchPrediction)
|
|
||||||
INTERWORK_FUNC(ArmDisableBranchPrediction)
|
|
||||||
.globl ASM_PFX(ArmDataMemoryBarrier)
|
|
||||||
INTERWORK_FUNC(ArmDataMemoryBarrier)
|
|
||||||
.globl ASM_PFX(ArmDataSyncronizationBarrier)
|
|
||||||
INTERWORK_FUNC(ArmDataSyncronizationBarrier)
|
|
||||||
.globl ASM_PFX(ArmInstructionSynchronizationBarrier)
|
|
||||||
INTERWORK_FUNC(ArmInstructionSynchronizationBarrier)
|
|
||||||
|
|
||||||
|
|
||||||
.set DC_ON, (0x1<<2)
|
.set DC_ON, (0x1<<2)
|
||||||
@ -116,14 +99,14 @@ ASM_PFX(ArmDisableMmu):
|
|||||||
bx LR
|
bx LR
|
||||||
|
|
||||||
ASM_PFX(ArmEnableDataCache):
|
ASM_PFX(ArmEnableDataCache):
|
||||||
ldr R1,=DC_ON
|
LoadConstantToReg(DC_ON, R1) @ldr R1,=DC_ON
|
||||||
mrc p15,0,R0,c1,c0,0 @Read control register configuration data
|
mrc p15,0,R0,c1,c0,0 @Read control register configuration data
|
||||||
orr R0,R0,R1 @Set C bit
|
orr R0,R0,R1 @Set C bit
|
||||||
mcr p15,0,r0,c1,c0,0 @Write control register configuration data
|
mcr p15,0,r0,c1,c0,0 @Write control register configuration data
|
||||||
bx LR
|
bx LR
|
||||||
|
|
||||||
ASM_PFX(ArmDisableDataCache):
|
ASM_PFX(ArmDisableDataCache):
|
||||||
ldr R1,=DC_ON
|
LoadConstantToReg(DC_ON, R1) @ldr R1,=DC_ON
|
||||||
mrc p15,0,R0,c1,c0,0 @Read control register configuration data
|
mrc p15,0,R0,c1,c0,0 @Read control register configuration data
|
||||||
bic R0,R0,R1 @Clear C bit
|
bic R0,R0,R1 @Clear C bit
|
||||||
mcr p15,0,r0,c1,c0,0 @Write control register configuration data
|
mcr p15,0,r0,c1,c0,0 @Write control register configuration data
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
#include <Library/ArmLib.h>
|
#include <Library/ArmLib.h>
|
||||||
#include <Library/BaseMemoryLib.h>
|
#include <Library/BaseMemoryLib.h>
|
||||||
#include <Library/MemoryAllocationLib.h>
|
#include <Library/MemoryAllocationLib.h>
|
||||||
|
#include <Library/DebugLib.h>
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
FillTranslationTable (
|
FillTranslationTable (
|
||||||
@ -37,6 +38,12 @@ FillTranslationTable (
|
|||||||
Attributes = TT_DESCRIPTOR_SECTION_WRITE_THROUGH;
|
Attributes = TT_DESCRIPTOR_SECTION_WRITE_THROUGH;
|
||||||
break;
|
break;
|
||||||
case ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED:
|
case ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED:
|
||||||
|
Attributes = TT_DESCRIPTOR_SECTION_UNCACHED_UNBUFFERED;
|
||||||
|
break;
|
||||||
|
case ARM_MEMORY_REGION_ATTRIBUTE_SECURE_WRITE_BACK:
|
||||||
|
case ARM_MEMORY_REGION_ATTRIBUTE_SECURE_WRITE_THROUGH:
|
||||||
|
case ARM_MEMORY_REGION_ATTRIBUTE_SECURE_UNCACHED_UNBUFFERED:
|
||||||
|
ASSERT(0); // Trustzone is not supported on ARMv5
|
||||||
default:
|
default:
|
||||||
Attributes = TT_DESCRIPTOR_SECTION_UNCACHED_UNBUFFERED;
|
Attributes = TT_DESCRIPTOR_SECTION_UNCACHED_UNBUFFERED;
|
||||||
break;
|
break;
|
||||||
@ -93,7 +100,7 @@ ArmConfigureMmu (
|
|||||||
MemoryTable++;
|
MemoryTable++;
|
||||||
}
|
}
|
||||||
|
|
||||||
ArmSetTranslationTableBaseAddress(TranslationTable);
|
ArmSetTTBR0(TranslationTable);
|
||||||
|
|
||||||
ArmSetDomainAccessControl(DOMAIN_ACCESS_CONTROL_NONE(15) |
|
ArmSetDomainAccessControl(DOMAIN_ACCESS_CONTROL_NONE(15) |
|
||||||
DOMAIN_ACCESS_CONTROL_NONE(14) |
|
DOMAIN_ACCESS_CONTROL_NONE(14) |
|
||||||
|
@ -14,44 +14,25 @@
|
|||||||
|
|
||||||
.text
|
.text
|
||||||
.align 2
|
.align 2
|
||||||
.globl ASM_PFX(ArmCleanInvalidateDataCache)
|
GCC_ASM_EXPORT(ArmCleanInvalidateDataCache)
|
||||||
INTERWORK_FUNC(ArmCleanInvalidateDataCache)
|
GCC_ASM_EXPORT(ArmCleanDataCache)
|
||||||
.globl ASM_PFX(ArmCleanDataCache)
|
GCC_ASM_EXPORT(ArmInvalidateDataCache)
|
||||||
INTERWORK_FUNC(ArmCleanDataCache)
|
GCC_ASM_EXPORT(ArmInvalidateInstructionCache)
|
||||||
.globl ASM_PFX(ArmInvalidateDataCache)
|
GCC_ASM_EXPORT(ArmInvalidateDataCacheEntryByMVA)
|
||||||
INTERWORK_FUNC(ArmInvalidateDataCache)
|
GCC_ASM_EXPORT(ArmCleanDataCacheEntryByMVA)
|
||||||
.globl ASM_PFX(ArmInvalidateInstructionCache)
|
GCC_ASM_EXPORT(ArmCleanInvalidateDataCacheEntryByMVA)
|
||||||
INTERWORK_FUNC(ArmInvalidateInstructionCache)
|
GCC_ASM_EXPORT(ArmEnableMmu)
|
||||||
.globl ASM_PFX(ArmInvalidateDataCacheEntryByMVA)
|
GCC_ASM_EXPORT(ArmDisableMmu)
|
||||||
INTERWORK_FUNC(ArmInvalidateDataCacheEntryByMVA)
|
GCC_ASM_EXPORT(ArmMmuEnabled)
|
||||||
.globl ASM_PFX(ArmCleanDataCacheEntryByMVA)
|
GCC_ASM_EXPORT(ArmEnableDataCache)
|
||||||
INTERWORK_FUNC(ArmCleanDataCacheEntryByMVA)
|
GCC_ASM_EXPORT(ArmDisableDataCache)
|
||||||
.globl ASM_PFX(ArmCleanInvalidateDataCacheEntryByMVA)
|
GCC_ASM_EXPORT(ArmEnableInstructionCache)
|
||||||
INTERWORK_FUNC(ArmCleanInvalidateDataCacheEntryByMVA)
|
GCC_ASM_EXPORT(ArmDisableInstructionCache)
|
||||||
.globl ASM_PFX(ArmEnableMmu)
|
GCC_ASM_EXPORT(ArmEnableBranchPrediction)
|
||||||
INTERWORK_FUNC(ArmEnableMmu)
|
GCC_ASM_EXPORT(ArmDisableBranchPrediction)
|
||||||
.globl ASM_PFX(ArmDisableMmu)
|
GCC_ASM_EXPORT(ArmDataMemoryBarrier)
|
||||||
INTERWORK_FUNC(ArmDisableMmu)
|
GCC_ASM_EXPORT(ArmDataSyncronizationBarrier)
|
||||||
.globl ASM_PFX(ArmMmuEnabled)
|
GCC_ASM_EXPORT(ArmInstructionSynchronizationBarrier)
|
||||||
INTERWORK_FUNC(ArmMmuEnabled)
|
|
||||||
.globl ASM_PFX(ArmEnableDataCache)
|
|
||||||
INTERWORK_FUNC(ArmEnableDataCache)
|
|
||||||
.globl ASM_PFX(ArmDisableDataCache)
|
|
||||||
INTERWORK_FUNC(ArmDisableDataCache)
|
|
||||||
.globl ASM_PFX(ArmEnableInstructionCache)
|
|
||||||
INTERWORK_FUNC(ArmEnableInstructionCache)
|
|
||||||
.globl ASM_PFX(ArmDisableInstructionCache)
|
|
||||||
INTERWORK_FUNC(ArmDisableInstructionCache)
|
|
||||||
.globl ASM_PFX(ArmEnableBranchPrediction)
|
|
||||||
INTERWORK_FUNC(ArmEnableBranchPrediction)
|
|
||||||
.globl ASM_PFX(ArmDisableBranchPrediction)
|
|
||||||
INTERWORK_FUNC(ArmDisableBranchPrediction)
|
|
||||||
.globl ASM_PFX(ArmDataMemoryBarrier)
|
|
||||||
INTERWORK_FUNC(ArmDataMemoryBarrier)
|
|
||||||
.globl ASM_PFX(ArmDataSyncronizationBarrier)
|
|
||||||
INTERWORK_FUNC(ArmDataSyncronizationBarrier)
|
|
||||||
.globl ASM_PFX(ArmInstructionSynchronizationBarrier)
|
|
||||||
INTERWORK_FUNC(ArmInstructionSynchronizationBarrier)
|
|
||||||
|
|
||||||
|
|
||||||
.set DC_ON, (1<<2)
|
.set DC_ON, (1<<2)
|
||||||
|
@ -12,44 +12,36 @@
|
|||||||
#
|
#
|
||||||
#------------------------------------------------------------------------------
|
#------------------------------------------------------------------------------
|
||||||
|
|
||||||
.globl ASM_PFX(Cp15IdCode)
|
#include <AsmMacroIoLib.h>
|
||||||
INTERWORK_FUNC(Cp15IdCode)
|
|
||||||
.globl ASM_PFX(Cp15CacheInfo)
|
|
||||||
INTERWORK_FUNC(Cp15CacheInfo)
|
|
||||||
.globl ASM_PFX(ArmEnableInterrupts)
|
|
||||||
INTERWORK_FUNC(ArmEnableInterrupts)
|
|
||||||
.globl ASM_PFX(ArmDisableInterrupts)
|
|
||||||
INTERWORK_FUNC(ArmDisableInterrupts)
|
|
||||||
.globl ASM_PFX(ArmGetInterruptState)
|
|
||||||
INTERWORK_FUNC(ArmGetInterruptState)
|
|
||||||
.globl ASM_PFX(ArmEnableFiq)
|
|
||||||
INTERWORK_FUNC(ArmEnableFiq)
|
|
||||||
.globl ASM_PFX(ArmDisableFiq)
|
|
||||||
INTERWORK_FUNC(ArmDisableFiq)
|
|
||||||
.globl ASM_PFX(ArmGetFiqState)
|
|
||||||
INTERWORK_FUNC(ArmGetFiqState)
|
|
||||||
.globl ASM_PFX(ArmInvalidateTlb)
|
|
||||||
INTERWORK_FUNC(ArmInvalidateTlb)
|
|
||||||
.globl ASM_PFX(ArmSetTranslationTableBaseAddress)
|
|
||||||
INTERWORK_FUNC(ArmSetTranslationTableBaseAddress)
|
|
||||||
.globl ASM_PFX(ArmGetTranslationTableBaseAddress)
|
|
||||||
INTERWORK_FUNC(ArmGetTranslationTableBaseAddress)
|
|
||||||
.globl ASM_PFX(ArmSetDomainAccessControl)
|
|
||||||
INTERWORK_FUNC(ArmSetDomainAccessControl)
|
|
||||||
.globl ASM_PFX(ArmUpdateTranslationTableEntry)
|
|
||||||
INTERWORK_FUNC(ArmUpdateTranslationTableEntry)
|
|
||||||
.globl ASM_PFX(CPSRMaskInsert)
|
|
||||||
INTERWORK_FUNC(CPSRMaskInsert)
|
|
||||||
.globl ASM_PFX(CPSRRead)
|
|
||||||
INTERWORK_FUNC(CPSRRead)
|
|
||||||
.globl ASM_PFX(ReadCCSIDR)
|
|
||||||
INTERWORK_FUNC(ReadCCSIDR)
|
|
||||||
.globl ASM_PFX(ReadCLIDR)
|
|
||||||
INTERWORK_FUNC(ReadCLIDR)
|
|
||||||
|
|
||||||
.text
|
.text
|
||||||
.align 2
|
.align 2
|
||||||
|
|
||||||
|
GCC_ASM_EXPORT(Cp15IdCode)
|
||||||
|
GCC_ASM_EXPORT(Cp15CacheInfo)
|
||||||
|
GCC_ASM_EXPORT(ArmIsMPCore)
|
||||||
|
GCC_ASM_EXPORT(ArmEnableAsynchronousAbort)
|
||||||
|
GCC_ASM_EXPORT(ArmDisableAsynchronousAbort)
|
||||||
|
GCC_ASM_EXPORT(ArmEnableIrq)
|
||||||
|
GCC_ASM_EXPORT(ArmDisableIrq)
|
||||||
|
GCC_ASM_EXPORT(ArmGetInterruptState)
|
||||||
|
GCC_ASM_EXPORT(ArmEnableFiq)
|
||||||
|
GCC_ASM_EXPORT(ArmDisableFiq)
|
||||||
|
GCC_ASM_EXPORT(ArmEnableInterrupts)
|
||||||
|
GCC_ASM_EXPORT(ArmDisableInterrupts)
|
||||||
|
GCC_ASM_EXPORT(ArmGetFiqState)
|
||||||
|
GCC_ASM_EXPORT(ArmInvalidateTlb)
|
||||||
|
GCC_ASM_EXPORT(ArmSetTTBR0)
|
||||||
|
GCC_ASM_EXPORT(ArmGetTTBR0BaseAddress)
|
||||||
|
GCC_ASM_EXPORT(ArmSetDomainAccessControl)
|
||||||
|
GCC_ASM_EXPORT(ArmUpdateTranslationTableEntry)
|
||||||
|
GCC_ASM_EXPORT(CPSRMaskInsert)
|
||||||
|
GCC_ASM_EXPORT(CPSRRead)
|
||||||
|
GCC_ASM_EXPORT(ReadCCSIDR)
|
||||||
|
GCC_ASM_EXPORT(ReadCLIDR)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#------------------------------------------------------------------------------
|
#------------------------------------------------------------------------------
|
||||||
|
|
||||||
ASM_PFX(Cp15IdCode):
|
ASM_PFX(Cp15IdCode):
|
||||||
@ -60,12 +52,32 @@ ASM_PFX(Cp15CacheInfo):
|
|||||||
mrc p15,0,R0,c0,c0,1
|
mrc p15,0,R0,c0,c0,1
|
||||||
bx LR
|
bx LR
|
||||||
|
|
||||||
ASM_PFX(ArmEnableInterrupts):
|
ASM_PFX(ArmIsMPCore):
|
||||||
cpsie i
|
mrc p15,0,R0,c0,c0,5
|
||||||
|
// Get Multiprocessing extension (bit31) & U bit (bit30)
|
||||||
|
and R0, R0, #0xC0000000
|
||||||
|
// if bit30 == 0 then the processor is part of a multiprocessor system)
|
||||||
|
and R0, R0, #0x80000000
|
||||||
bx LR
|
bx LR
|
||||||
|
|
||||||
ASM_PFX(ArmDisableInterrupts):
|
ASM_PFX(ArmEnableAsynchronousAbort):
|
||||||
|
cpsie a
|
||||||
|
isb
|
||||||
|
bx LR
|
||||||
|
|
||||||
|
ASM_PFX(ArmDisableAsynchronousAbort):
|
||||||
|
cpsid a
|
||||||
|
isb
|
||||||
|
bx LR
|
||||||
|
|
||||||
|
ASM_PFX(ArmEnableIrq):
|
||||||
|
cpsie i
|
||||||
|
isb
|
||||||
|
bx LR
|
||||||
|
|
||||||
|
ASM_PFX(ArmDisableIrq):
|
||||||
cpsid i
|
cpsid i
|
||||||
|
isb
|
||||||
bx LR
|
bx LR
|
||||||
|
|
||||||
ASM_PFX(ArmGetInterruptState):
|
ASM_PFX(ArmGetInterruptState):
|
||||||
@ -77,10 +89,22 @@ ASM_PFX(ArmGetInterruptState):
|
|||||||
|
|
||||||
ASM_PFX(ArmEnableFiq):
|
ASM_PFX(ArmEnableFiq):
|
||||||
cpsie f
|
cpsie f
|
||||||
|
isb
|
||||||
bx LR
|
bx LR
|
||||||
|
|
||||||
ASM_PFX(ArmDisableFiq):
|
ASM_PFX(ArmDisableFiq):
|
||||||
cpsid f
|
cpsid f
|
||||||
|
isb
|
||||||
|
bx LR
|
||||||
|
|
||||||
|
ASM_PFX(ArmEnableInterrupts):
|
||||||
|
cpsie if
|
||||||
|
isb
|
||||||
|
bx LR
|
||||||
|
|
||||||
|
ASM_PFX(ArmDisableInterrupts):
|
||||||
|
cpsid if
|
||||||
|
isb
|
||||||
bx LR
|
bx LR
|
||||||
|
|
||||||
ASM_PFX(ArmGetFiqState):
|
ASM_PFX(ArmGetFiqState):
|
||||||
@ -98,13 +122,15 @@ ASM_PFX(ArmInvalidateTlb):
|
|||||||
isb
|
isb
|
||||||
bx lr
|
bx lr
|
||||||
|
|
||||||
ASM_PFX(ArmSetTranslationTableBaseAddress):
|
ASM_PFX(ArmSetTTBR0):
|
||||||
mcr p15,0,r0,c2,c0,0
|
mcr p15,0,r0,c2,c0,0
|
||||||
isb
|
isb
|
||||||
bx lr
|
bx lr
|
||||||
|
|
||||||
ASM_PFX(ArmGetTranslationTableBaseAddress):
|
ASM_PFX(ArmGetTTBR0BaseAddress):
|
||||||
mrc p15,0,r0,c2,c0,0
|
mrc p15,0,r0,c2,c0,0
|
||||||
|
LoadConstantToReg(0xFFFFC000, r1)
|
||||||
|
and r0, r0, r1
|
||||||
isb
|
isb
|
||||||
bx lr
|
bx lr
|
||||||
|
|
||||||
|
@ -15,15 +15,20 @@
|
|||||||
|
|
||||||
EXPORT Cp15IdCode
|
EXPORT Cp15IdCode
|
||||||
EXPORT Cp15CacheInfo
|
EXPORT Cp15CacheInfo
|
||||||
EXPORT ArmEnableInterrupts
|
EXPORT ArmIsMPCore
|
||||||
EXPORT ArmDisableInterrupts
|
EXPORT ArmEnableAsynchronousAbort
|
||||||
|
EXPORT ArmDisableAsynchronousAbort
|
||||||
|
EXPORT ArmEnableIrq
|
||||||
|
EXPORT ArmDisableIrq
|
||||||
EXPORT ArmGetInterruptState
|
EXPORT ArmGetInterruptState
|
||||||
EXPORT ArmEnableFiq
|
EXPORT ArmEnableFiq
|
||||||
EXPORT ArmDisableFiq
|
EXPORT ArmDisableFiq
|
||||||
|
EXPORT ArmEnableInterrupts
|
||||||
|
EXPORT ArmDisableInterrupts
|
||||||
EXPORT ArmGetFiqState
|
EXPORT ArmGetFiqState
|
||||||
EXPORT ArmInvalidateTlb
|
EXPORT ArmInvalidateTlb
|
||||||
EXPORT ArmSetTranslationTableBaseAddress
|
EXPORT ArmSetTTBR0
|
||||||
EXPORT ArmGetTranslationTableBaseAddress
|
EXPORT ArmGetTTBR0BaseAddress
|
||||||
EXPORT ArmSetDomainAccessControl
|
EXPORT ArmSetDomainAccessControl
|
||||||
EXPORT ArmUpdateTranslationTableEntry
|
EXPORT ArmUpdateTranslationTableEntry
|
||||||
EXPORT CPSRMaskInsert
|
EXPORT CPSRMaskInsert
|
||||||
@ -44,12 +49,52 @@ Cp15CacheInfo
|
|||||||
mrc p15,0,R0,c0,c0,1
|
mrc p15,0,R0,c0,c0,1
|
||||||
bx LR
|
bx LR
|
||||||
|
|
||||||
ArmEnableInterrupts
|
ArmIsMPCore
|
||||||
|
mrc p15,0,R0,c0,c0,5
|
||||||
|
// Get Multiprocessing extension (bit31) & U bit (bit30)
|
||||||
|
and R0, R0, #0xC0000000
|
||||||
|
// if bit30 == 0 then the processor is part of a multiprocessor system)
|
||||||
|
and R0, R0, #0x80000000
|
||||||
|
bx LR
|
||||||
|
|
||||||
|
ArmEnableAsynchronousAbort
|
||||||
|
cpsie a
|
||||||
|
isb
|
||||||
|
bx LR
|
||||||
|
|
||||||
|
ArmDisableAsynchronousAbort
|
||||||
|
cpsid a
|
||||||
|
isb
|
||||||
|
bx LR
|
||||||
|
|
||||||
|
ArmEnableIrq
|
||||||
cpsie i
|
cpsie i
|
||||||
|
isb
|
||||||
|
bx LR
|
||||||
|
|
||||||
|
ArmDisableIrq
|
||||||
|
cpsid i
|
||||||
|
isb
|
||||||
|
bx LR
|
||||||
|
|
||||||
|
ArmEnableFiq
|
||||||
|
cpsie f
|
||||||
|
isb
|
||||||
|
bx LR
|
||||||
|
|
||||||
|
ArmDisableFiq
|
||||||
|
cpsid f
|
||||||
|
isb
|
||||||
|
bx LR
|
||||||
|
|
||||||
|
ArmEnableInterrupts
|
||||||
|
cpsie if
|
||||||
|
isb
|
||||||
bx LR
|
bx LR
|
||||||
|
|
||||||
ArmDisableInterrupts
|
ArmDisableInterrupts
|
||||||
cpsid i
|
cpsid if
|
||||||
|
isb
|
||||||
bx LR
|
bx LR
|
||||||
|
|
||||||
ArmGetInterruptState
|
ArmGetInterruptState
|
||||||
@ -59,14 +104,6 @@ ArmGetInterruptState
|
|||||||
movne R0,#0
|
movne R0,#0
|
||||||
bx LR
|
bx LR
|
||||||
|
|
||||||
ArmEnableFiq
|
|
||||||
cpsie f
|
|
||||||
bx LR
|
|
||||||
|
|
||||||
ArmDisableFiq
|
|
||||||
cpsid f
|
|
||||||
bx LR
|
|
||||||
|
|
||||||
ArmGetFiqState
|
ArmGetFiqState
|
||||||
mrs R0,CPSR
|
mrs R0,CPSR
|
||||||
tst R0,#0x40 ;Check if FIQ is enabled.
|
tst R0,#0x40 ;Check if FIQ is enabled.
|
||||||
@ -82,13 +119,15 @@ ArmInvalidateTlb
|
|||||||
isb
|
isb
|
||||||
bx lr
|
bx lr
|
||||||
|
|
||||||
ArmSetTranslationTableBaseAddress
|
ArmSetTTBR0
|
||||||
mcr p15,0,r0,c2,c0,0
|
mcr p15,0,r0,c2,c0,0
|
||||||
isb
|
isb
|
||||||
bx lr
|
bx lr
|
||||||
|
|
||||||
ArmGetTranslationTableBaseAddress
|
ArmGetTTBR0BaseAddress
|
||||||
mrc p15,0,r0,c2,c0,0
|
mrc p15,0,r0,c2,c0,0
|
||||||
|
ldr r1, = 0xFFFFC000
|
||||||
|
and r0, r0, r1
|
||||||
isb
|
isb
|
||||||
bx lr
|
bx lr
|
||||||
|
|
||||||
@ -150,7 +189,4 @@ ReadCLIDR
|
|||||||
mrc p15,1,r0,c0,c0,1 ; Read CP15 Cache Level ID Register
|
mrc p15,1,r0,c0,c0,1 ; Read CP15 Cache Level ID Register
|
||||||
bx lr
|
bx lr
|
||||||
|
|
||||||
|
|
||||||
END
|
END
|
||||||
|
|
||||||
|
|
||||||
|
@ -15,113 +15,10 @@
|
|||||||
#include <Chipset/ArmV7.h>
|
#include <Chipset/ArmV7.h>
|
||||||
#include <Library/ArmLib.h>
|
#include <Library/ArmLib.h>
|
||||||
#include <Library/BaseLib.h>
|
#include <Library/BaseLib.h>
|
||||||
#include <Library/BaseMemoryLib.h>
|
#include <Library/IoLib.h>
|
||||||
#include <Library/MemoryAllocationLib.h>
|
|
||||||
#include "ArmV7Lib.h"
|
#include "ArmV7Lib.h"
|
||||||
#include "ArmLibPrivate.h"
|
#include "ArmLibPrivate.h"
|
||||||
|
|
||||||
VOID
|
|
||||||
FillTranslationTable (
|
|
||||||
IN UINT32 *TranslationTable,
|
|
||||||
IN ARM_MEMORY_REGION_DESCRIPTOR *MemoryRegion
|
|
||||||
)
|
|
||||||
{
|
|
||||||
UINT32 *Entry;
|
|
||||||
UINTN Sections;
|
|
||||||
UINTN Index;
|
|
||||||
UINT32 Attributes;
|
|
||||||
UINT32 PhysicalBase = MemoryRegion->PhysicalBase;
|
|
||||||
|
|
||||||
switch (MemoryRegion->Attributes) {
|
|
||||||
case ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK:
|
|
||||||
Attributes = TT_DESCRIPTOR_SECTION_WRITE_BACK;
|
|
||||||
break;
|
|
||||||
case ARM_MEMORY_REGION_ATTRIBUTE_WRITE_THROUGH:
|
|
||||||
Attributes = TT_DESCRIPTOR_SECTION_WRITE_THROUGH;
|
|
||||||
break;
|
|
||||||
case ARM_MEMORY_REGION_ATTRIBUTE_DEVICE:
|
|
||||||
Attributes = TT_DESCRIPTOR_SECTION_DEVICE;
|
|
||||||
break;
|
|
||||||
case ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED:
|
|
||||||
default:
|
|
||||||
Attributes = TT_DESCRIPTOR_SECTION_UNCACHED;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
Entry = TRANSLATION_TABLE_ENTRY_FOR_VIRTUAL_ADDRESS(TranslationTable, MemoryRegion->VirtualBase);
|
|
||||||
Sections = MemoryRegion->Length / TT_DESCRIPTOR_SECTION_SIZE;
|
|
||||||
|
|
||||||
for (Index = 0; Index < Sections; Index++) {
|
|
||||||
*Entry++ = TT_DESCRIPTOR_SECTION_BASE_ADDRESS(PhysicalBase) | Attributes;
|
|
||||||
PhysicalBase += TT_DESCRIPTOR_SECTION_SIZE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
VOID
|
|
||||||
EFIAPI
|
|
||||||
ArmConfigureMmu (
|
|
||||||
IN ARM_MEMORY_REGION_DESCRIPTOR *MemoryTable,
|
|
||||||
OUT VOID **TranslationTableBase OPTIONAL,
|
|
||||||
OUT UINTN *TranslationTableSize OPTIONAL
|
|
||||||
)
|
|
||||||
{
|
|
||||||
VOID *TranslationTable;
|
|
||||||
|
|
||||||
// Allocate pages for translation table.
|
|
||||||
TranslationTable = AllocatePages(EFI_SIZE_TO_PAGES(TRANSLATION_TABLE_SIZE + TRANSLATION_TABLE_ALIGNMENT));
|
|
||||||
TranslationTable = (VOID *)(((UINTN)TranslationTable + TRANSLATION_TABLE_ALIGNMENT_MASK) & ~TRANSLATION_TABLE_ALIGNMENT_MASK);
|
|
||||||
|
|
||||||
if (TranslationTableBase != NULL) {
|
|
||||||
*TranslationTableBase = TranslationTable;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (TranslationTableBase != NULL) {
|
|
||||||
*TranslationTableSize = TRANSLATION_TABLE_SIZE;
|
|
||||||
}
|
|
||||||
|
|
||||||
ZeroMem(TranslationTable, TRANSLATION_TABLE_SIZE);
|
|
||||||
|
|
||||||
ArmCleanInvalidateDataCache();
|
|
||||||
ArmInvalidateInstructionCache();
|
|
||||||
ArmInvalidateTlb();
|
|
||||||
|
|
||||||
ArmDisableDataCache();
|
|
||||||
ArmDisableInstructionCache();
|
|
||||||
ArmDisableMmu();
|
|
||||||
|
|
||||||
// Make sure nothing sneaked into the cache
|
|
||||||
ArmCleanInvalidateDataCache();
|
|
||||||
ArmInvalidateInstructionCache();
|
|
||||||
|
|
||||||
while (MemoryTable->Length != 0) {
|
|
||||||
FillTranslationTable(TranslationTable, MemoryTable);
|
|
||||||
MemoryTable++;
|
|
||||||
}
|
|
||||||
|
|
||||||
ArmSetTranslationTableBaseAddress(TranslationTable);
|
|
||||||
|
|
||||||
ArmSetDomainAccessControl(DOMAIN_ACCESS_CONTROL_NONE(15) |
|
|
||||||
DOMAIN_ACCESS_CONTROL_NONE(14) |
|
|
||||||
DOMAIN_ACCESS_CONTROL_NONE(13) |
|
|
||||||
DOMAIN_ACCESS_CONTROL_NONE(12) |
|
|
||||||
DOMAIN_ACCESS_CONTROL_NONE(11) |
|
|
||||||
DOMAIN_ACCESS_CONTROL_NONE(10) |
|
|
||||||
DOMAIN_ACCESS_CONTROL_NONE( 9) |
|
|
||||||
DOMAIN_ACCESS_CONTROL_NONE( 8) |
|
|
||||||
DOMAIN_ACCESS_CONTROL_NONE( 7) |
|
|
||||||
DOMAIN_ACCESS_CONTROL_NONE( 6) |
|
|
||||||
DOMAIN_ACCESS_CONTROL_NONE( 5) |
|
|
||||||
DOMAIN_ACCESS_CONTROL_NONE( 4) |
|
|
||||||
DOMAIN_ACCESS_CONTROL_NONE( 3) |
|
|
||||||
DOMAIN_ACCESS_CONTROL_NONE( 2) |
|
|
||||||
DOMAIN_ACCESS_CONTROL_NONE( 1) |
|
|
||||||
DOMAIN_ACCESS_CONTROL_MANAGER(0));
|
|
||||||
|
|
||||||
ArmEnableInstructionCache();
|
|
||||||
ArmEnableDataCache();
|
|
||||||
ArmEnableMmu();
|
|
||||||
}
|
|
||||||
|
|
||||||
ARM_CACHE_TYPE
|
ARM_CACHE_TYPE
|
||||||
EFIAPI
|
EFIAPI
|
||||||
ArmCacheType (
|
ArmCacheType (
|
||||||
@ -139,7 +36,7 @@ ArmCacheArchitecture (
|
|||||||
{
|
{
|
||||||
UINT32 CLIDR = ReadCLIDR ();
|
UINT32 CLIDR = ReadCLIDR ();
|
||||||
|
|
||||||
return CLIDR; // BugBug Fix Me
|
return (ARM_CACHE_ARCHITECTURE)CLIDR; // BugBug Fix Me
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
@ -173,7 +70,7 @@ ArmDataCacheSize (
|
|||||||
UINT32 LineSize;
|
UINT32 LineSize;
|
||||||
UINT32 CCSIDR = ReadCCSIDR (0);
|
UINT32 CCSIDR = ReadCCSIDR (0);
|
||||||
|
|
||||||
LineSize = (1 << (CCSIDR + 2));
|
LineSize = (1 << ((CCSIDR & 0x7) + 2));
|
||||||
Associativity = ((CCSIDR >> 3) & 0x3ff) + 1;
|
Associativity = ((CCSIDR >> 3) & 0x3ff) + 1;
|
||||||
NumSets = ((CCSIDR >> 13) & 0x7fff) + 1;
|
NumSets = ((CCSIDR >> 13) & 0x7fff) + 1;
|
||||||
|
|
||||||
@ -245,7 +142,7 @@ ArmInstructionCacheSize (
|
|||||||
UINT32 LineSize;
|
UINT32 LineSize;
|
||||||
UINT32 CCSIDR = ReadCCSIDR (1);
|
UINT32 CCSIDR = ReadCCSIDR (1);
|
||||||
|
|
||||||
LineSize = (1 << (CCSIDR + 2));
|
LineSize = (1 << ((CCSIDR & 0x7) + 2));
|
||||||
Associativity = ((CCSIDR >> 3) & 0x3ff) + 1;
|
Associativity = ((CCSIDR >> 3) & 0x3ff) + 1;
|
||||||
NumSets = ((CCSIDR >> 13) & 0x7fff) + 1;
|
NumSets = ((CCSIDR >> 13) & 0x7fff) + 1;
|
||||||
|
|
||||||
@ -299,6 +196,8 @@ ArmV7DataCacheOperation (
|
|||||||
UINTN SavedInterruptState;
|
UINTN SavedInterruptState;
|
||||||
|
|
||||||
SavedInterruptState = ArmGetInterruptState ();
|
SavedInterruptState = ArmGetInterruptState ();
|
||||||
|
ArmDisableInterrupts();
|
||||||
|
|
||||||
|
|
||||||
ArmV7AllDataCachesOperation (DataCacheOperation);
|
ArmV7AllDataCachesOperation (DataCacheOperation);
|
||||||
|
|
||||||
@ -335,3 +234,14 @@ ArmCleanDataCache (
|
|||||||
{
|
{
|
||||||
ArmV7DataCacheOperation (ArmCleanDataCacheEntryBySetWay);
|
ArmV7DataCacheOperation (ArmCleanDataCacheEntryBySetWay);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
EFIAPI
|
||||||
|
ArmSetAuxCrBit (
|
||||||
|
IN UINT32 Bits
|
||||||
|
)
|
||||||
|
{
|
||||||
|
UINT32 val = ArmReadAuxCr();
|
||||||
|
val |= Bits;
|
||||||
|
ArmWriteAuxCr(val);
|
||||||
|
}
|
||||||
|
@ -40,5 +40,41 @@ ArmCleanInvalidateDataCacheEntryBySetWay (
|
|||||||
IN UINT32 SetWayFormat
|
IN UINT32 SetWayFormat
|
||||||
);
|
);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
EFIAPI
|
||||||
|
ArmEnableAsynchronousAbort (
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
UINTN
|
||||||
|
EFIAPI
|
||||||
|
ArmDisableAsynchronousAbort (
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
EFIAPI
|
||||||
|
ArmEnableIrq (
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
UINTN
|
||||||
|
EFIAPI
|
||||||
|
ArmDisableIrq (
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
EFIAPI
|
||||||
|
ArmEnableFiq (
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
UINTN
|
||||||
|
EFIAPI
|
||||||
|
ArmDisableFiq (
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
#endif // __ARM_V7_LIB_H__
|
#endif // __ARM_V7_LIB_H__
|
||||||
|
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
ArmV7Support.asm | RVCT
|
ArmV7Support.asm | RVCT
|
||||||
|
|
||||||
ArmV7Lib.c
|
ArmV7Lib.c
|
||||||
|
ArmV7Mmu.c
|
||||||
|
|
||||||
[Packages]
|
[Packages]
|
||||||
ArmPkg/ArmPkg.dec
|
ArmPkg/ArmPkg.dec
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
ArmV7Support.asm | RVCT
|
ArmV7Support.asm | RVCT
|
||||||
|
|
||||||
ArmV7Lib.c
|
ArmV7Lib.c
|
||||||
|
ArmV7Mmu.c
|
||||||
|
|
||||||
[Packages]
|
[Packages]
|
||||||
ArmPkg/ArmPkg.dec
|
ArmPkg/ArmPkg.dec
|
||||||
|
40
ArmPkg/Library/ArmLib/ArmV7/ArmV7LibSec.inf
Normal file
40
ArmPkg/Library/ArmLib/ArmV7/ArmV7LibSec.inf
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
#/* @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 = ArmV7Lib
|
||||||
|
FILE_GUID = 411cdfd8-f964-4b9d-a3e3-1719a9c15559
|
||||||
|
MODULE_TYPE = BASE
|
||||||
|
VERSION_STRING = 1.0
|
||||||
|
LIBRARY_CLASS = ArmLib
|
||||||
|
|
||||||
|
[Sources.common]
|
||||||
|
ArmLibSupport.S | GCC
|
||||||
|
ArmLibSupport.asm | RVCT
|
||||||
|
../Common/ArmLib.c
|
||||||
|
|
||||||
|
ArmV7Support.S | GCC
|
||||||
|
ArmV7Support.asm | RVCT
|
||||||
|
|
||||||
|
ArmV7Lib.c
|
||||||
|
|
||||||
|
[Packages]
|
||||||
|
ArmPkg/ArmPkg.dec
|
||||||
|
MdePkg/MdePkg.dec
|
||||||
|
|
||||||
|
[Protocols]
|
||||||
|
gEfiCpuArchProtocolGuid
|
||||||
|
|
||||||
|
[FixedPcd]
|
||||||
|
gArmTokenSpaceGuid.PcdArmCacheOperationThreshold
|
57
ArmPkg/Library/ArmLib/ArmV7/ArmV7MPCore.c
Normal file
57
ArmPkg/Library/ArmLib/ArmV7/ArmV7MPCore.c
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
/** @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 <Uefi.h>
|
||||||
|
#include <Chipset/ArmV7.h>
|
||||||
|
#include <Library/ArmLib.h>
|
||||||
|
#include <Library/BaseLib.h>
|
||||||
|
#include <Library/IoLib.h>
|
||||||
|
#include "ArmV7Lib.h"
|
||||||
|
#include "ArmLibPrivate.h"
|
||||||
|
|
||||||
|
VOID
|
||||||
|
EFIAPI
|
||||||
|
ArmSetupSmpNonSecure (
|
||||||
|
IN UINTN CoreId
|
||||||
|
)
|
||||||
|
{
|
||||||
|
INTN scu_base;
|
||||||
|
|
||||||
|
ArmSetAuxCrBit (A9_FEATURE_SMP);
|
||||||
|
|
||||||
|
if (CoreId == 0) {
|
||||||
|
scu_base = ArmGetScuBaseAddress();
|
||||||
|
|
||||||
|
// Allow NS access to SCU register
|
||||||
|
MmioOr32(scu_base + SCU_SACR_OFFSET, 0xf);
|
||||||
|
// Allow NS access to Private Peripherals
|
||||||
|
MmioOr32(scu_base + SCU_SSACR_OFFSET, 0xfff);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
EFIAPI
|
||||||
|
ArmInvalidScu (
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
INTN scu_base;
|
||||||
|
|
||||||
|
scu_base = ArmGetScuBaseAddress();
|
||||||
|
|
||||||
|
/* Invalidate all: write -1 to SCU Invalidate All register */
|
||||||
|
MmioWrite32(scu_base + SCU_INVALL_OFFSET, 0xffffffff);
|
||||||
|
/* Enable SCU */
|
||||||
|
MmioWrite32(scu_base + SCU_CONTROL_OFFSET, 0x1);
|
||||||
|
}
|
48
ArmPkg/Library/ArmLib/ArmV7/ArmV7MPCoreHelper.S
Normal file
48
ArmPkg/Library/ArmLib/ArmV7/ArmV7MPCoreHelper.S
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
#
|
||||||
|
# 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 <Chipset/ArmV7.h>
|
||||||
|
#include <AutoGen.h>
|
||||||
|
#.include AsmMacroIoLib.inc
|
||||||
|
|
||||||
|
.text
|
||||||
|
.align 2
|
||||||
|
|
||||||
|
GCC_ASM_EXPORT(ArmIsScuEnable)
|
||||||
|
GCC_ASM_EXPORT(ArmGetScuBaseAddress)
|
||||||
|
|
||||||
|
# IN None
|
||||||
|
# OUT r0 = SCU Base Address
|
||||||
|
ASM_PFX(ArmGetScuBaseAddress):
|
||||||
|
# Read Configuration Base Address Register. ArmCBar cannot be called to get
|
||||||
|
# the Configuration BAR as a stack is not necessary setup. The SCU is at the
|
||||||
|
# offset 0x0000 from the Private Memory Region.
|
||||||
|
mrc p15, 4, r0, c15, c0, 0
|
||||||
|
bx lr
|
||||||
|
|
||||||
|
# IN None
|
||||||
|
# OUT r1 = SCU enabled (boolean)
|
||||||
|
ASM_PFX(ArmIsScuEnable):
|
||||||
|
# Read Configuration Base Address Register. ArmCBar cannot be called to get
|
||||||
|
# the Configuration BAR as a stack is not necessary setup. The SCU is at the
|
||||||
|
# offset 0x0000 from the Private Memory Region.
|
||||||
|
mrc p15, 4, r0, c15, c0, 0
|
||||||
|
add r1, r0, #SCU_CONTROL_OFFSET
|
||||||
|
ldr r1, [r1]
|
||||||
|
and r1, r1, #1
|
||||||
|
bx lr
|
||||||
|
|
||||||
|
ASM_FUNCTION_REMOVE_IF_UNREFERENCED
|
48
ArmPkg/Library/ArmLib/ArmV7/ArmV7MPCoreHelper.asm
Normal file
48
ArmPkg/Library/ArmLib/ArmV7/ArmV7MPCoreHelper.asm
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
//
|
||||||
|
// 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 <Chipset/ArmV7.h>
|
||||||
|
#include <AutoGen.h>
|
||||||
|
|
||||||
|
INCLUDE AsmMacroIoLib.inc
|
||||||
|
|
||||||
|
EXPORT ArmIsScuEnable
|
||||||
|
EXPORT ArmGetScuBaseAddress
|
||||||
|
|
||||||
|
AREA ArmV7MPCore, CODE, READONLY
|
||||||
|
|
||||||
|
// IN None
|
||||||
|
// OUT r0 = SCU Base Address
|
||||||
|
ArmGetScuBaseAddress
|
||||||
|
// Read Configuration Base Address Register. ArmCBar cannot be called to get
|
||||||
|
// the Configuration BAR as a stack is not necessary setup. The SCU is at the
|
||||||
|
// offset 0x0000 from the Private Memory Region.
|
||||||
|
mrc p15, 4, r0, c15, c0, 0
|
||||||
|
bx lr
|
||||||
|
|
||||||
|
// IN None
|
||||||
|
// OUT r1 = SCU enabled (boolean)
|
||||||
|
ArmIsScuEnable
|
||||||
|
// Read Configuration Base Address Register. ArmCBar cannot be called to get
|
||||||
|
// the Configuration BAR as a stack is not necessary setup. The SCU is at the
|
||||||
|
// offset 0x0000 from the Private Memory Region.
|
||||||
|
mrc p15, 4, r0, c15, c0, 0
|
||||||
|
add r1, r0, #SCU_CONTROL_OFFSET
|
||||||
|
ldr r1, [r1]
|
||||||
|
and r1, r1, #1
|
||||||
|
bx lr
|
||||||
|
|
||||||
|
END
|
51
ArmPkg/Library/ArmLib/ArmV7/ArmV7MPCoreLib.inf
Normal file
51
ArmPkg/Library/ArmLib/ArmV7/ArmV7MPCoreLib.inf
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
#/** @file
|
||||||
|
# Helper Library for ARMv7 MPCore architecture
|
||||||
|
|
||||||
|
# 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 = ArmV7Lib
|
||||||
|
FILE_GUID = 411cdfd8-f964-4b9d-a3e3-1719a9c15559
|
||||||
|
MODULE_TYPE = DXE_DRIVER
|
||||||
|
VERSION_STRING = 1.0
|
||||||
|
LIBRARY_CLASS = ArmLib
|
||||||
|
|
||||||
|
[Sources.common]
|
||||||
|
ArmLibSupport.S | GCC
|
||||||
|
ArmLibSupport.asm | RVCT
|
||||||
|
../Common/ArmLib.c
|
||||||
|
|
||||||
|
ArmV7Support.S | GCC
|
||||||
|
ArmV7Support.asm | RVCT
|
||||||
|
|
||||||
|
ArmV7Lib.c
|
||||||
|
ArmV7Mmu.c
|
||||||
|
|
||||||
|
ArmV7MPCore.c
|
||||||
|
ArmV7MPCoreHelper.S | GCC
|
||||||
|
ArmV7MPCoreHelper.asm | RVCT
|
||||||
|
|
||||||
|
[Packages]
|
||||||
|
ArmPkg/ArmPkg.dec
|
||||||
|
MdePkg/MdePkg.dec
|
||||||
|
|
||||||
|
[LibraryClasses]
|
||||||
|
MemoryAllocationLib
|
||||||
|
|
||||||
|
[Protocols]
|
||||||
|
gEfiCpuArchProtocolGuid
|
||||||
|
|
||||||
|
[FixedPcd]
|
||||||
|
gArmTokenSpaceGuid.PcdArmCacheOperationThreshold
|
49
ArmPkg/Library/ArmLib/ArmV7/ArmV7MPCoreLibPrePi.inf
Normal file
49
ArmPkg/Library/ArmLib/ArmV7/ArmV7MPCoreLibPrePi.inf
Normal 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 = ArmV7LibPrePi
|
||||||
|
FILE_GUID = A150FA0C-F4E8-4207-9BEB-CD6DFB430D73
|
||||||
|
MODULE_TYPE = BASE
|
||||||
|
VERSION_STRING = 1.0
|
||||||
|
LIBRARY_CLASS = ArmLib
|
||||||
|
|
||||||
|
[Sources.common]
|
||||||
|
ArmLibSupport.S | GCC
|
||||||
|
ArmLibSupport.asm | RVCT
|
||||||
|
../Common/ArmLib.c
|
||||||
|
|
||||||
|
ArmV7Support.S | GCC
|
||||||
|
ArmV7Support.asm | RVCT
|
||||||
|
|
||||||
|
ArmV7Lib.c
|
||||||
|
ArmV7Mmu.c
|
||||||
|
|
||||||
|
ArmV7MPCore.c
|
||||||
|
ArmV7MPCoreHelper.S | GCC
|
||||||
|
ArmV7MPCoreHelper.asm | RVCT
|
||||||
|
|
||||||
|
[Packages]
|
||||||
|
ArmPkg/ArmPkg.dec
|
||||||
|
MdePkg/MdePkg.dec
|
||||||
|
|
||||||
|
[LibraryClasses]
|
||||||
|
PrePiLib
|
||||||
|
|
||||||
|
[Protocols]
|
||||||
|
gEfiCpuArchProtocolGuid
|
||||||
|
|
||||||
|
[FixedPcd]
|
||||||
|
gArmTokenSpaceGuid.PcdArmCacheOperationThreshold
|
43
ArmPkg/Library/ArmLib/ArmV7/ArmV7MPCoreLibSec.inf
Normal file
43
ArmPkg/Library/ArmLib/ArmV7/ArmV7MPCoreLibSec.inf
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
#/* @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 = ArmV7Lib
|
||||||
|
FILE_GUID = 411cdfd8-f964-4b9d-a3e3-1719a9c15559
|
||||||
|
MODULE_TYPE = BASE
|
||||||
|
VERSION_STRING = 1.0
|
||||||
|
LIBRARY_CLASS = ArmLib
|
||||||
|
|
||||||
|
[Sources.common]
|
||||||
|
ArmLibSupport.S | GCC
|
||||||
|
ArmLibSupport.asm | RVCT
|
||||||
|
../Common/ArmLib.c
|
||||||
|
|
||||||
|
ArmV7Support.S | GCC
|
||||||
|
ArmV7Support.asm | RVCT
|
||||||
|
|
||||||
|
ArmV7Lib.c
|
||||||
|
ArmV7MPCore.c
|
||||||
|
ArmV7MPCoreHelper.S | GCC
|
||||||
|
ArmV7MPCoreHelper.asm | RVCT
|
||||||
|
|
||||||
|
[Packages]
|
||||||
|
ArmPkg/ArmPkg.dec
|
||||||
|
MdePkg/MdePkg.dec
|
||||||
|
|
||||||
|
[Protocols]
|
||||||
|
gEfiCpuArchProtocolGuid
|
||||||
|
|
||||||
|
[FixedPcd]
|
||||||
|
gArmTokenSpaceGuid.PcdArmCacheOperationThreshold
|
162
ArmPkg/Library/ArmLib/ArmV7/ArmV7Mmu.c
Normal file
162
ArmPkg/Library/ArmLib/ArmV7/ArmV7Mmu.c
Normal file
@ -0,0 +1,162 @@
|
|||||||
|
/** @file
|
||||||
|
* File managing the MMU for ARMv7 architecture
|
||||||
|
*
|
||||||
|
* 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 <Uefi.h>
|
||||||
|
#include <Chipset/ArmV7.h>
|
||||||
|
#include <Library/BaseMemoryLib.h>
|
||||||
|
#include <Library/MemoryAllocationLib.h>
|
||||||
|
#include <Library/ArmLib.h>
|
||||||
|
#include <Library/BaseLib.h>
|
||||||
|
#include "ArmV7Lib.h"
|
||||||
|
#include "ArmLibPrivate.h"
|
||||||
|
|
||||||
|
VOID
|
||||||
|
FillTranslationTable (
|
||||||
|
IN UINT32 *TranslationTable,
|
||||||
|
IN ARM_MEMORY_REGION_DESCRIPTOR *MemoryRegion
|
||||||
|
)
|
||||||
|
{
|
||||||
|
UINT32 *Entry;
|
||||||
|
UINTN Sections;
|
||||||
|
UINTN Index;
|
||||||
|
UINT32 Attributes;
|
||||||
|
UINT32 PhysicalBase = MemoryRegion->PhysicalBase;
|
||||||
|
|
||||||
|
switch (MemoryRegion->Attributes) {
|
||||||
|
case ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK:
|
||||||
|
Attributes = TT_DESCRIPTOR_SECTION_WRITE_BACK(0);
|
||||||
|
break;
|
||||||
|
case ARM_MEMORY_REGION_ATTRIBUTE_WRITE_THROUGH:
|
||||||
|
Attributes = TT_DESCRIPTOR_SECTION_WRITE_THROUGH(0);
|
||||||
|
break;
|
||||||
|
case ARM_MEMORY_REGION_ATTRIBUTE_DEVICE:
|
||||||
|
Attributes = TT_DESCRIPTOR_SECTION_DEVICE(0);
|
||||||
|
break;
|
||||||
|
case ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED:
|
||||||
|
Attributes = TT_DESCRIPTOR_SECTION_UNCACHED(0);
|
||||||
|
break;
|
||||||
|
case ARM_MEMORY_REGION_ATTRIBUTE_SECURE_WRITE_BACK:
|
||||||
|
Attributes = TT_DESCRIPTOR_SECTION_WRITE_BACK(1);
|
||||||
|
break;
|
||||||
|
case ARM_MEMORY_REGION_ATTRIBUTE_SECURE_WRITE_THROUGH:
|
||||||
|
Attributes = TT_DESCRIPTOR_SECTION_WRITE_THROUGH(1);
|
||||||
|
break;
|
||||||
|
case ARM_MEMORY_REGION_ATTRIBUTE_SECURE_DEVICE:
|
||||||
|
Attributes = TT_DESCRIPTOR_SECTION_DEVICE(1);
|
||||||
|
break;
|
||||||
|
case ARM_MEMORY_REGION_ATTRIBUTE_SECURE_UNCACHED_UNBUFFERED:
|
||||||
|
Attributes = TT_DESCRIPTOR_SECTION_UNCACHED(1);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
Attributes = TT_DESCRIPTOR_SECTION_UNCACHED(0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
Entry = TRANSLATION_TABLE_ENTRY_FOR_VIRTUAL_ADDRESS(TranslationTable, MemoryRegion->VirtualBase);
|
||||||
|
Sections = MemoryRegion->Length / TT_DESCRIPTOR_SECTION_SIZE;
|
||||||
|
|
||||||
|
for (Index = 0; Index < Sections; Index++) {
|
||||||
|
*Entry++ = TT_DESCRIPTOR_SECTION_BASE_ADDRESS(PhysicalBase) | Attributes;
|
||||||
|
PhysicalBase += TT_DESCRIPTOR_SECTION_SIZE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
EFIAPI
|
||||||
|
ArmConfigureMmu (
|
||||||
|
IN ARM_MEMORY_REGION_DESCRIPTOR *MemoryTable,
|
||||||
|
OUT VOID **TranslationTableBase OPTIONAL,
|
||||||
|
OUT UINTN *TranslationTableSize OPTIONAL
|
||||||
|
)
|
||||||
|
{
|
||||||
|
UINTN TranslationTable;
|
||||||
|
ARM_MEMORY_REGION_ATTRIBUTES TranslationTableAttribute;
|
||||||
|
UINT32 TTBRAttributes;
|
||||||
|
|
||||||
|
// Allocate pages for translation table.
|
||||||
|
TranslationTable = (UINTN)AllocatePages(EFI_SIZE_TO_PAGES(TRANSLATION_TABLE_SECTION_SIZE + TRANSLATION_TABLE_SECTION_ALIGNMENT));
|
||||||
|
TranslationTable = ((UINTN)TranslationTable + TRANSLATION_TABLE_SECTION_ALIGNMENT_MASK) & ~TRANSLATION_TABLE_SECTION_ALIGNMENT_MASK;
|
||||||
|
|
||||||
|
if (TranslationTableBase != NULL) {
|
||||||
|
*TranslationTableBase = (VOID *)TranslationTable;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TranslationTableBase != NULL) {
|
||||||
|
*TranslationTableSize = TRANSLATION_TABLE_SECTION_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
ZeroMem ((VOID *)TranslationTable, TRANSLATION_TABLE_SECTION_SIZE);
|
||||||
|
|
||||||
|
ArmCleanInvalidateDataCache();
|
||||||
|
ArmInvalidateInstructionCache();
|
||||||
|
ArmInvalidateTlb();
|
||||||
|
|
||||||
|
ArmDisableDataCache();
|
||||||
|
ArmDisableInstructionCache();
|
||||||
|
ArmDisableMmu();
|
||||||
|
|
||||||
|
// Make sure nothing sneaked into the cache
|
||||||
|
ArmCleanInvalidateDataCache();
|
||||||
|
ArmInvalidateInstructionCache();
|
||||||
|
|
||||||
|
TranslationTableAttribute = 0;
|
||||||
|
while (MemoryTable->Length != 0) {
|
||||||
|
// Find the memory attribute for the Translation Table
|
||||||
|
if ((TranslationTable >= MemoryTable->PhysicalBase) && (TranslationTable < MemoryTable->PhysicalBase + MemoryTable->Length)) {
|
||||||
|
TranslationTableAttribute = MemoryTable->Attributes;
|
||||||
|
}
|
||||||
|
|
||||||
|
FillTranslationTable ((VOID *)TranslationTable, MemoryTable);
|
||||||
|
MemoryTable++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Translate the Memory Attributes into Translation Table Register Attributes
|
||||||
|
if ((TranslationTableAttribute == ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED) ||
|
||||||
|
(TranslationTableAttribute == ARM_MEMORY_REGION_ATTRIBUTE_SECURE_UNCACHED_UNBUFFERED)) {
|
||||||
|
TTBRAttributes = TTBR_NON_CACHEABLE;
|
||||||
|
} else if ((TranslationTableAttribute == ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK) ||
|
||||||
|
(TranslationTableAttribute == ARM_MEMORY_REGION_ATTRIBUTE_SECURE_WRITE_BACK)) {
|
||||||
|
TTBRAttributes = TTBR_WRITE_BACK_ALLOC;
|
||||||
|
} else if ((TranslationTableAttribute == ARM_MEMORY_REGION_ATTRIBUTE_WRITE_THROUGH) ||
|
||||||
|
(TranslationTableAttribute == ARM_MEMORY_REGION_ATTRIBUTE_SECURE_WRITE_THROUGH)) {
|
||||||
|
TTBRAttributes = TTBR_WRITE_THROUGH_NO_ALLOC;
|
||||||
|
} else {
|
||||||
|
//TODO: We should raise an error here
|
||||||
|
TTBRAttributes = TTBR_NON_CACHEABLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
ArmSetTTBR0 ((VOID *)(UINTN)((TranslationTable & 0xFFFFC000) | (TTBRAttributes & 0x7F)));
|
||||||
|
|
||||||
|
ArmSetDomainAccessControl (DOMAIN_ACCESS_CONTROL_NONE(15) |
|
||||||
|
DOMAIN_ACCESS_CONTROL_NONE(14) |
|
||||||
|
DOMAIN_ACCESS_CONTROL_NONE(13) |
|
||||||
|
DOMAIN_ACCESS_CONTROL_NONE(12) |
|
||||||
|
DOMAIN_ACCESS_CONTROL_NONE(11) |
|
||||||
|
DOMAIN_ACCESS_CONTROL_NONE(10) |
|
||||||
|
DOMAIN_ACCESS_CONTROL_NONE( 9) |
|
||||||
|
DOMAIN_ACCESS_CONTROL_NONE( 8) |
|
||||||
|
DOMAIN_ACCESS_CONTROL_NONE( 7) |
|
||||||
|
DOMAIN_ACCESS_CONTROL_NONE( 6) |
|
||||||
|
DOMAIN_ACCESS_CONTROL_NONE( 5) |
|
||||||
|
DOMAIN_ACCESS_CONTROL_NONE( 4) |
|
||||||
|
DOMAIN_ACCESS_CONTROL_NONE( 3) |
|
||||||
|
DOMAIN_ACCESS_CONTROL_NONE( 2) |
|
||||||
|
DOMAIN_ACCESS_CONTROL_NONE( 1) |
|
||||||
|
DOMAIN_ACCESS_CONTROL_MANAGER(0));
|
||||||
|
|
||||||
|
ArmEnableInstructionCache();
|
||||||
|
ArmEnableDataCache();
|
||||||
|
ArmEnableMmu();
|
||||||
|
}
|
@ -12,55 +12,51 @@
|
|||||||
#
|
#
|
||||||
#------------------------------------------------------------------------------
|
#------------------------------------------------------------------------------
|
||||||
|
|
||||||
.globl ASM_PFX(ArmInvalidateInstructionCache)
|
|
||||||
INTERWORK_FUNC(ArmInvalidateInstructionCache)
|
|
||||||
.globl ASM_PFX(ArmInvalidateDataCacheEntryByMVA)
|
|
||||||
INTERWORK_FUNC(ArmInvalidateDataCacheEntryByMVA)
|
|
||||||
.globl ASM_PFX(ArmCleanDataCacheEntryByMVA)
|
|
||||||
INTERWORK_FUNC(ArmCleanDataCacheEntryByMVA)
|
|
||||||
.globl ASM_PFX(ArmCleanInvalidateDataCacheEntryByMVA)
|
|
||||||
INTERWORK_FUNC(ArmCleanInvalidateDataCacheEntryByMVA)
|
|
||||||
.globl ASM_PFX(ArmInvalidateDataCacheEntryBySetWay)
|
|
||||||
INTERWORK_FUNC(ArmInvalidateDataCacheEntryBySetWay)
|
|
||||||
.globl ASM_PFX(ArmCleanDataCacheEntryBySetWay)
|
|
||||||
INTERWORK_FUNC(ArmCleanDataCacheEntryBySetWay)
|
|
||||||
.globl ASM_PFX(ArmCleanInvalidateDataCacheEntryBySetWay)
|
|
||||||
INTERWORK_FUNC(ArmCleanInvalidateDataCacheEntryBySetWay)
|
|
||||||
.globl ASM_PFX(ArmDrainWriteBuffer)
|
|
||||||
INTERWORK_FUNC(ArmDrainWriteBuffer)
|
|
||||||
.globl ASM_PFX(ArmEnableMmu)
|
|
||||||
INTERWORK_FUNC(ArmEnableMmu)
|
|
||||||
.globl ASM_PFX(ArmDisableMmu)
|
|
||||||
INTERWORK_FUNC(ArmDisableMmu)
|
|
||||||
.globl ASM_PFX(ArmMmuEnabled)
|
|
||||||
INTERWORK_FUNC(ArmMmuEnabled)
|
|
||||||
.globl ASM_PFX(ArmEnableDataCache)
|
|
||||||
INTERWORK_FUNC(ArmEnableDataCache)
|
|
||||||
.globl ASM_PFX(ArmDisableDataCache)
|
|
||||||
INTERWORK_FUNC(ArmDisableDataCache)
|
|
||||||
.globl ASM_PFX(ArmEnableInstructionCache)
|
|
||||||
INTERWORK_FUNC(ArmEnableInstructionCache)
|
|
||||||
.globl ASM_PFX(ArmDisableInstructionCache)
|
|
||||||
INTERWORK_FUNC(ArmDisableInstructionCache)
|
|
||||||
.globl ASM_PFX(ArmEnableBranchPrediction)
|
|
||||||
INTERWORK_FUNC(ArmEnableBranchPrediction)
|
|
||||||
.globl ASM_PFX(ArmDisableBranchPrediction)
|
|
||||||
INTERWORK_FUNC(ArmDisableBranchPrediction)
|
|
||||||
.globl ASM_PFX(ArmV7AllDataCachesOperation)
|
|
||||||
INTERWORK_FUNC(ArmV7AllDataCachesOperation)
|
|
||||||
.globl ASM_PFX(ArmDataMemoryBarrier)
|
|
||||||
INTERWORK_FUNC(ArmDataMemoryBarrier)
|
|
||||||
.globl ASM_PFX(ArmDataSyncronizationBarrier)
|
|
||||||
INTERWORK_FUNC(ArmDataSyncronizationBarrier)
|
|
||||||
.globl ASM_PFX(ArmInstructionSynchronizationBarrier)
|
|
||||||
INTERWORK_FUNC(ArmInstructionSynchronizationBarrier)
|
|
||||||
|
|
||||||
.text
|
.text
|
||||||
.align 2
|
.align 2
|
||||||
|
|
||||||
|
GCC_ASM_EXPORT (ArmInvalidateInstructionCache)
|
||||||
|
GCC_ASM_EXPORT (ArmInvalidateDataCacheEntryByMVA)
|
||||||
|
GCC_ASM_EXPORT (ArmCleanDataCacheEntryByMVA)
|
||||||
|
GCC_ASM_EXPORT (ArmCleanInvalidateDataCacheEntryByMVA)
|
||||||
|
GCC_ASM_EXPORT (ArmInvalidateDataCacheEntryBySetWay)
|
||||||
|
GCC_ASM_EXPORT (ArmCleanDataCacheEntryBySetWay)
|
||||||
|
GCC_ASM_EXPORT (ArmCleanInvalidateDataCacheEntryBySetWay)
|
||||||
|
GCC_ASM_EXPORT (ArmDrainWriteBuffer)
|
||||||
|
GCC_ASM_EXPORT (ArmEnableMmu)
|
||||||
|
GCC_ASM_EXPORT (ArmDisableMmu)
|
||||||
|
GCC_ASM_EXPORT (ArmDisableCachesAndMmu)
|
||||||
|
GCC_ASM_EXPORT (ArmMmuEnabled)
|
||||||
|
GCC_ASM_EXPORT (ArmEnableDataCache)
|
||||||
|
GCC_ASM_EXPORT (ArmDisableDataCache)
|
||||||
|
GCC_ASM_EXPORT (ArmEnableInstructionCache)
|
||||||
|
GCC_ASM_EXPORT (ArmDisableInstructionCache)
|
||||||
|
GCC_ASM_EXPORT (ArmEnableSWPInstruction)
|
||||||
|
GCC_ASM_EXPORT (ArmEnableBranchPrediction)
|
||||||
|
GCC_ASM_EXPORT (ArmDisableBranchPrediction)
|
||||||
|
GCC_ASM_EXPORT (ArmV7AllDataCachesOperation)
|
||||||
|
GCC_ASM_EXPORT (ArmDataMemoryBarrier)
|
||||||
|
GCC_ASM_EXPORT (ArmDataSyncronizationBarrier)
|
||||||
|
GCC_ASM_EXPORT (ArmInstructionSynchronizationBarrier)
|
||||||
|
GCC_ASM_EXPORT (ArmWriteNsacr)
|
||||||
|
GCC_ASM_EXPORT (ArmWriteScr)
|
||||||
|
GCC_ASM_EXPORT (ArmWriteVMBar)
|
||||||
|
GCC_ASM_EXPORT (ArmWriteVBar)
|
||||||
|
GCC_ASM_EXPORT (ArmWriteCPACR)
|
||||||
|
GCC_ASM_EXPORT (ArmEnableVFP)
|
||||||
|
GCC_ASM_EXPORT (ArmCallWFI)
|
||||||
|
GCC_ASM_EXPORT (ArmWriteAuxCr)
|
||||||
|
GCC_ASM_EXPORT (ArmReadAuxCr)
|
||||||
|
GCC_ASM_EXPORT (ArmReadCbar)
|
||||||
|
GCC_ASM_EXPORT (ArmInvalidateInstructionAndDataTlb)
|
||||||
|
GCC_ASM_EXPORT (ArmReadMpidr)
|
||||||
|
|
||||||
.set DC_ON, (0x1<<2)
|
.set DC_ON, (0x1<<2)
|
||||||
.set IC_ON, (0x1<<12)
|
.set IC_ON, (0x1<<12)
|
||||||
|
.set CTRL_M_BIT, (1 << 0)
|
||||||
|
.set CTRL_C_BIT, (1 << 2)
|
||||||
|
.set CTRL_B_BIT, (1 << 7)
|
||||||
|
.set CTRL_I_BIT, (1 << 12)
|
||||||
|
|
||||||
|
|
||||||
ASM_PFX(ArmInvalidateDataCacheEntryByMVA):
|
ASM_PFX(ArmInvalidateDataCacheEntryByMVA):
|
||||||
@ -69,7 +65,6 @@ ASM_PFX(ArmInvalidateDataCacheEntryByMVA):
|
|||||||
isb
|
isb
|
||||||
bx lr
|
bx lr
|
||||||
|
|
||||||
|
|
||||||
ASM_PFX(ArmCleanDataCacheEntryByMVA):
|
ASM_PFX(ArmCleanDataCacheEntryByMVA):
|
||||||
mcr p15, 0, r0, c7, c10, 1 @clean single data cache line
|
mcr p15, 0, r0, c7, c10, 1 @clean single data cache line
|
||||||
dsb
|
dsb
|
||||||
@ -104,7 +99,6 @@ ASM_PFX(ArmCleanDataCacheEntryBySetWay):
|
|||||||
isb
|
isb
|
||||||
bx lr
|
bx lr
|
||||||
|
|
||||||
|
|
||||||
ASM_PFX(ArmInvalidateInstructionCache):
|
ASM_PFX(ArmInvalidateInstructionCache):
|
||||||
mcr p15,0,R0,c7,c5,0 @Invalidate entire instruction cache
|
mcr p15,0,R0,c7,c5,0 @Invalidate entire instruction cache
|
||||||
dsb
|
dsb
|
||||||
@ -119,10 +113,6 @@ ASM_PFX(ArmEnableMmu):
|
|||||||
isb
|
isb
|
||||||
bx LR
|
bx LR
|
||||||
|
|
||||||
ASM_PFX(ArmMmuEnabled):
|
|
||||||
mrc p15,0,R0,c1,c0,0
|
|
||||||
and R0,R0,#1
|
|
||||||
bx LR
|
|
||||||
|
|
||||||
ASM_PFX(ArmDisableMmu):
|
ASM_PFX(ArmDisableMmu):
|
||||||
mrc p15,0,R0,c1,c0,0
|
mrc p15,0,R0,c1,c0,0
|
||||||
@ -135,6 +125,21 @@ ASM_PFX(ArmDisableMmu):
|
|||||||
isb
|
isb
|
||||||
bx LR
|
bx LR
|
||||||
|
|
||||||
|
ASM_PFX(ArmDisableCachesAndMmu):
|
||||||
|
mrc p15, 0, r0, c1, c0, 0 @ Get control register
|
||||||
|
bic r0, r0, #CTRL_M_BIT @ Disable MMU
|
||||||
|
bic r0, r0, #CTRL_C_BIT @ Disable D Cache
|
||||||
|
bic r0, r0, #CTRL_I_BIT @ Disable I Cache
|
||||||
|
mcr p15, 0, r0, c1, c0, 0 @ Write control register
|
||||||
|
dsb
|
||||||
|
isb
|
||||||
|
bx LR
|
||||||
|
|
||||||
|
ASM_PFX(ArmMmuEnabled):
|
||||||
|
mrc p15,0,R0,c1,c0,0
|
||||||
|
and R0,R0,#1
|
||||||
|
bx LR
|
||||||
|
|
||||||
ASM_PFX(ArmEnableDataCache):
|
ASM_PFX(ArmEnableDataCache):
|
||||||
ldr R1,=DC_ON
|
ldr R1,=DC_ON
|
||||||
mrc p15,0,R0,c1,c0,0 @Read control register configuration data
|
mrc p15,0,R0,c1,c0,0 @Read control register configuration data
|
||||||
@ -171,6 +176,13 @@ ASM_PFX(ArmDisableInstructionCache):
|
|||||||
isb
|
isb
|
||||||
bx LR
|
bx LR
|
||||||
|
|
||||||
|
ASM_PFX(ArmEnableSWPInstruction):
|
||||||
|
mrc p15, 0, r0, c1, c0, 0
|
||||||
|
orr r0, r0, #0x00000400
|
||||||
|
mcr p15, 0, r0, c1, c0, 0
|
||||||
|
isb
|
||||||
|
bx LR
|
||||||
|
|
||||||
ASM_PFX(ArmEnableBranchPrediction):
|
ASM_PFX(ArmEnableBranchPrediction):
|
||||||
mrc p15, 0, r0, c1, c0, 0
|
mrc p15, 0, r0, c1, c0, 0
|
||||||
orr r0, r0, #0x00000800
|
orr r0, r0, #0x00000800
|
||||||
@ -254,5 +266,59 @@ ASM_PFX(ArmInstructionSynchronizationBarrier):
|
|||||||
isb
|
isb
|
||||||
bx LR
|
bx LR
|
||||||
|
|
||||||
|
ASM_PFX(ArmWriteNsacr):
|
||||||
|
mcr p15, 0, r0, c1, c1, 2
|
||||||
|
bx lr
|
||||||
|
|
||||||
|
ASM_PFX(ArmWriteScr):
|
||||||
|
mcr p15, 0, r0, c1, c1, 0
|
||||||
|
bx lr
|
||||||
|
|
||||||
|
ASM_PFX(ArmWriteAuxCr):
|
||||||
|
mcr p15, 0, r0, c1, c0, 1
|
||||||
|
bx lr
|
||||||
|
|
||||||
|
ASM_PFX(ArmReadAuxCr):
|
||||||
|
mrc p15, 0, r0, c1, c0, 1
|
||||||
|
bx lr
|
||||||
|
|
||||||
|
ASM_PFX(ArmWriteVMBar):
|
||||||
|
mcr p15, 0, r0, c12, c0, 1
|
||||||
|
bx lr
|
||||||
|
|
||||||
|
ASM_PFX(ArmWriteVBar):
|
||||||
|
mcr p15, 0, r0, c12, c0, 0
|
||||||
|
bx lr
|
||||||
|
|
||||||
|
ASM_PFX(ArmWriteCPACR):
|
||||||
|
mcr p15, 0, r0, c1, c0, 2
|
||||||
|
bx lr
|
||||||
|
|
||||||
|
ASM_PFX(ArmEnableVFP):
|
||||||
|
// Enable VFP registers
|
||||||
|
mrc p15, 0, r0, c1, c0, 2
|
||||||
|
orr r0, r0, #0x00f00000 // Enable VPF access (V* instructions)
|
||||||
|
mcr p15, 0, r0, c1, c0, 2
|
||||||
|
mov r0, #0x40000000 // Set EN bit in FPEXC
|
||||||
|
mcr p10,#0x7,r0,c8,c0,#0 // msr FPEXC,r0 in ARM assembly
|
||||||
|
bx lr
|
||||||
|
|
||||||
|
ASM_PFX(ArmCallWFI):
|
||||||
|
wfi
|
||||||
|
bx lr
|
||||||
|
|
||||||
|
//Note: Return 0 in Uniprocessor implementation
|
||||||
|
ASM_PFX(ArmReadCbar):
|
||||||
|
mrc p15, 4, r0, c15, c0, 0 //Read Configuration Base Address Register
|
||||||
|
bx lr
|
||||||
|
|
||||||
|
ASM_PFX(ArmInvalidateInstructionAndDataTlb):
|
||||||
|
mcr p15, 0, r0, c8, c7, 0 @ Invalidate Inst TLB and Data TLB
|
||||||
|
dsb
|
||||||
|
bx lr
|
||||||
|
|
||||||
|
ASM_PFX(ArmReadMpidr):
|
||||||
|
mrc p15, 0, r0, c0, c0, 5 @ read MPIDR
|
||||||
|
bx lr
|
||||||
|
|
||||||
ASM_FUNCTION_REMOVE_IF_UNREFERENCED
|
ASM_FUNCTION_REMOVE_IF_UNREFERENCED
|
||||||
|
@ -22,24 +22,42 @@
|
|||||||
EXPORT ArmDrainWriteBuffer
|
EXPORT ArmDrainWriteBuffer
|
||||||
EXPORT ArmEnableMmu
|
EXPORT ArmEnableMmu
|
||||||
EXPORT ArmDisableMmu
|
EXPORT ArmDisableMmu
|
||||||
|
EXPORT ArmDisableCachesAndMmu
|
||||||
EXPORT ArmMmuEnabled
|
EXPORT ArmMmuEnabled
|
||||||
EXPORT ArmEnableDataCache
|
EXPORT ArmEnableDataCache
|
||||||
EXPORT ArmDisableDataCache
|
EXPORT ArmDisableDataCache
|
||||||
EXPORT ArmEnableInstructionCache
|
EXPORT ArmEnableInstructionCache
|
||||||
EXPORT ArmDisableInstructionCache
|
EXPORT ArmDisableInstructionCache
|
||||||
|
EXPORT ArmEnableSWPInstruction
|
||||||
EXPORT ArmEnableBranchPrediction
|
EXPORT ArmEnableBranchPrediction
|
||||||
EXPORT ArmDisableBranchPrediction
|
EXPORT ArmDisableBranchPrediction
|
||||||
EXPORT ArmV7AllDataCachesOperation
|
EXPORT ArmV7AllDataCachesOperation
|
||||||
EXPORT ArmDataMemoryBarrier
|
EXPORT ArmDataMemoryBarrier
|
||||||
EXPORT ArmDataSyncronizationBarrier
|
EXPORT ArmDataSyncronizationBarrier
|
||||||
EXPORT ArmInstructionSynchronizationBarrier
|
EXPORT ArmInstructionSynchronizationBarrier
|
||||||
|
EXPORT ArmWriteNsacr
|
||||||
|
EXPORT ArmWriteScr
|
||||||
|
EXPORT ArmWriteVMBar
|
||||||
|
EXPORT ArmWriteVBar
|
||||||
|
EXPORT ArmReadVBar
|
||||||
|
EXPORT ArmWriteCPACR
|
||||||
|
EXPORT ArmEnableVFP
|
||||||
|
EXPORT ArmCallWFI
|
||||||
|
EXPORT ArmWriteAuxCr
|
||||||
|
EXPORT ArmReadAuxCr
|
||||||
|
EXPORT ArmReadCbar
|
||||||
|
EXPORT ArmInvalidateInstructionAndDataTlb
|
||||||
|
EXPORT ArmReadMpidr
|
||||||
|
|
||||||
AREA ArmCacheLib, CODE, READONLY
|
AREA ArmCacheLib, CODE, READONLY
|
||||||
PRESERVE8
|
PRESERVE8
|
||||||
|
|
||||||
DC_ON EQU ( 0x1:SHL:2 )
|
DC_ON EQU ( 0x1:SHL:2 )
|
||||||
IC_ON EQU ( 0x1:SHL:12 )
|
IC_ON EQU ( 0x1:SHL:12 )
|
||||||
|
CTRL_M_BIT EQU (1 << 0)
|
||||||
|
CTRL_C_BIT EQU (1 << 2)
|
||||||
|
CTRL_B_BIT EQU (1 << 7)
|
||||||
|
CTRL_I_BIT EQU (1 << 12)
|
||||||
|
|
||||||
|
|
||||||
ArmInvalidateDataCacheEntryByMVA
|
ArmInvalidateDataCacheEntryByMVA
|
||||||
@ -90,75 +108,91 @@ ArmInvalidateInstructionCache
|
|||||||
bx LR
|
bx LR
|
||||||
|
|
||||||
ArmEnableMmu
|
ArmEnableMmu
|
||||||
mrc p15,0,R0,c1,c0,0
|
mrc p15,0,R0,c1,c0,0 ; Read SCTLR into R0 (Read control register configuration data)
|
||||||
orr R0,R0,#1
|
orr R0,R0,#1 ; Set SCTLR.M bit : Enable MMU
|
||||||
mcr p15,0,R0,c1,c0,0
|
mcr p15,0,R0,c1,c0,0 ; Write R0 into SCTLR (Write control register configuration data)
|
||||||
dsb
|
dsb
|
||||||
isb
|
isb
|
||||||
bx LR
|
bx LR
|
||||||
|
|
||||||
ArmMmuEnabled
|
ArmMmuEnabled
|
||||||
mrc p15,0,R0,c1,c0,0
|
mrc p15,0,R0,c1,c0,0 ; Read SCTLR into R0 (Read control register configuration data)
|
||||||
and R0,R0,#1
|
and R0,R0,#1
|
||||||
bx LR
|
bx LR
|
||||||
|
|
||||||
ArmDisableMmu
|
ArmDisableMmu
|
||||||
mrc p15,0,R0,c1,c0,0
|
mrc p15,0,R0,c1,c0,0 ; Read SCTLR into R0 (Read control register configuration data)
|
||||||
bic R0,R0,#1
|
bic R0,R0,#1 ; Clear SCTLR.M bit : Disable MMU
|
||||||
mcr p15,0,R0,c1,c0,0 ;Disable MMU
|
mcr p15,0,R0,c1,c0,0 ; Write R0 into SCTLR (Write control register configuration data)
|
||||||
|
|
||||||
mcr p15,0,R0,c8,c7,0 ;Invalidate TLB
|
mcr p15,0,R0,c8,c7,0 ; TLBIALL : Invalidate unified TLB
|
||||||
mcr p15,0,R0,c7,c5,6 ;Invalidate Branch predictor array
|
mcr p15,0,R0,c7,c5,6 ; BPIALL : Invalidate entire branch predictor array
|
||||||
dsb
|
dsb
|
||||||
isb
|
isb
|
||||||
bx LR
|
bx LR
|
||||||
|
|
||||||
|
ArmDisableCachesAndMmu
|
||||||
|
mrc p15, 0, r0, c1, c0, 0 ; Get control register
|
||||||
|
bic r0, r0, #CTRL_M_BIT ; Disable MMU
|
||||||
|
bic r0, r0, #CTRL_C_BIT ; Disable D Cache
|
||||||
|
bic r0, r0, #CTRL_I_BIT ; Disable I Cache
|
||||||
|
mcr p15, 0, r0, c1, c0, 0 ; Write control register
|
||||||
|
dsb
|
||||||
|
isb
|
||||||
|
bx LR
|
||||||
|
|
||||||
ArmEnableDataCache
|
ArmEnableDataCache
|
||||||
ldr R1,=DC_ON
|
ldr R1,=DC_ON ; Specify SCTLR.C bit : (Data) Cache enable bit
|
||||||
mrc p15,0,R0,c1,c0,0 ;Read control register configuration data
|
mrc p15,0,R0,c1,c0,0 ; Read SCTLR into R0 (Read control register configuration data)
|
||||||
orr R0,R0,R1 ;Set C bit
|
orr R0,R0,R1 ; Set SCTLR.C bit : Data and unified caches enabled
|
||||||
mcr p15,0,R0,c1,c0,0 ;Write control register configuration data
|
mcr p15,0,R0,c1,c0,0 ; Write R0 into SCTLR (Write control register configuration data)
|
||||||
dsb
|
dsb
|
||||||
isb
|
isb
|
||||||
bx LR
|
bx LR
|
||||||
|
|
||||||
ArmDisableDataCache
|
ArmDisableDataCache
|
||||||
ldr R1,=DC_ON
|
ldr R1,=DC_ON ; Specify SCTLR.C bit : (Data) Cache enable bit
|
||||||
mrc p15,0,R0,c1,c0,0 ;Read control register configuration data
|
mrc p15,0,R0,c1,c0,0 ; Read SCTLR into R0 (Read control register configuration data)
|
||||||
bic R0,R0,R1 ;Clear C bit
|
bic R0,R0,R1 ; Clear SCTLR.C bit : Data and unified caches disabled
|
||||||
mcr p15,0,R0,c1,c0,0 ;Write control register configuration data
|
mcr p15,0,R0,c1,c0,0 ; Write R0 into SCTLR (Write control register configuration data)
|
||||||
isb
|
isb
|
||||||
bx LR
|
bx LR
|
||||||
|
|
||||||
ArmEnableInstructionCache
|
ArmEnableInstructionCache
|
||||||
ldr R1,=IC_ON
|
ldr R1,=IC_ON ; Specify SCTLR.I bit : Instruction cache enable bit
|
||||||
mrc p15,0,R0,c1,c0,0 ;Read control register configuration data
|
mrc p15,0,R0,c1,c0,0 ; Read SCTLR into R0 (Read control register configuration data)
|
||||||
orr R0,R0,R1 ;Set I bit
|
orr R0,R0,R1 ; Set SCTLR.I bit : Instruction caches enabled
|
||||||
mcr p15,0,R0,c1,c0,0 ;Write control register configuration data
|
mcr p15,0,R0,c1,c0,0 ; Write R0 into SCTLR (Write control register configuration data)
|
||||||
dsb
|
dsb
|
||||||
isb
|
isb
|
||||||
bx LR
|
bx LR
|
||||||
|
|
||||||
ArmDisableInstructionCache
|
ArmDisableInstructionCache
|
||||||
ldr R1,=IC_ON
|
ldr R1,=IC_ON ; Specify SCTLR.I bit : Instruction cache enable bit
|
||||||
mrc p15,0,R0,c1,c0,0 ;Read control register configuration data
|
mrc p15,0,R0,c1,c0,0 ; Read SCTLR into R0 (Read control register configuration data)
|
||||||
BIC R0,R0,R1 ;Clear I bit.
|
BIC R0,R0,R1 ; Clear SCTLR.I bit : Instruction caches disabled
|
||||||
mcr p15,0,R0,c1,c0,0 ;Write control register configuration data
|
mcr p15,0,R0,c1,c0,0 ; Write R0 into SCTLR (Write control register configuration data)
|
||||||
|
isb
|
||||||
|
bx LR
|
||||||
|
|
||||||
|
ArmEnableSWPInstruction
|
||||||
|
mrc p15, 0, r0, c1, c0, 0
|
||||||
|
orr r0, r0, #0x00000400
|
||||||
|
mcr p15, 0, r0, c1, c0, 0
|
||||||
isb
|
isb
|
||||||
bx LR
|
bx LR
|
||||||
|
|
||||||
ArmEnableBranchPrediction
|
ArmEnableBranchPrediction
|
||||||
mrc p15, 0, r0, c1, c0, 0
|
mrc p15, 0, r0, c1, c0, 0 ; Read SCTLR into R0 (Read control register configuration data)
|
||||||
orr r0, r0, #0x00000800
|
orr r0, r0, #0x00000800 ;
|
||||||
mcr p15, 0, r0, c1, c0, 0
|
mcr p15, 0, r0, c1, c0, 0 ; Write R0 into SCTLR (Write control register configuration data)
|
||||||
isb
|
isb
|
||||||
bx LR
|
bx LR
|
||||||
|
|
||||||
ArmDisableBranchPrediction
|
ArmDisableBranchPrediction
|
||||||
mrc p15, 0, r0, c1, c0, 0
|
mrc p15, 0, r0, c1, c0, 0 ; Read SCTLR into R0 (Read control register configuration data)
|
||||||
bic r0, r0, #0x00000800
|
bic r0, r0, #0x00000800 ;
|
||||||
mcr p15, 0, r0, c1, c0, 0
|
mcr p15, 0, r0, c1, c0, 0 ; Write R0 into SCTLR (Write control register configuration data)
|
||||||
isb
|
isb
|
||||||
bx LR
|
bx LR
|
||||||
|
|
||||||
@ -226,5 +260,64 @@ ArmInstructionSynchronizationBarrier
|
|||||||
isb
|
isb
|
||||||
bx LR
|
bx LR
|
||||||
|
|
||||||
|
ArmWriteNsacr
|
||||||
|
mcr p15, 0, r0, c1, c1, 2
|
||||||
|
bx lr
|
||||||
|
|
||||||
|
ArmWriteScr
|
||||||
|
mcr p15, 0, r0, c1, c1, 0
|
||||||
|
bx lr
|
||||||
|
|
||||||
|
ArmWriteAuxCr
|
||||||
|
mcr p15, 0, r0, c1, c0, 1
|
||||||
|
bx lr
|
||||||
|
|
||||||
|
ArmReadAuxCr
|
||||||
|
mrc p15, 0, r0, c1, c0, 1
|
||||||
|
bx lr
|
||||||
|
|
||||||
|
ArmWriteVMBar
|
||||||
|
mcr p15, 0, r0, c12, c0, 1
|
||||||
|
bx lr
|
||||||
|
|
||||||
|
ArmWriteVBar
|
||||||
|
mcr p15, 0, r0, c12, c0, 0
|
||||||
|
bx lr
|
||||||
|
|
||||||
|
ArmReadVBar
|
||||||
|
mrc p15, 0, r0, c12, c0, 0
|
||||||
|
bx lr
|
||||||
|
|
||||||
|
ArmWriteCPACR
|
||||||
|
mcr p15, 0, r0, c1, c0, 2
|
||||||
|
bx lr
|
||||||
|
|
||||||
|
ArmEnableVFP
|
||||||
|
// Enable VFP registers
|
||||||
|
mrc p15, 0, r0, c1, c0, 2
|
||||||
|
orr r0, r0, #0x00f00000 // Enable VPF access (V* instructions)
|
||||||
|
mcr p15, 0, r0, c1, c0, 2
|
||||||
|
mov r0, #0x40000000 // Set EN bit in FPEXC
|
||||||
|
mcr p10,#0x7,r0,c8,c0,#0 // msr FPEXC,r0 in ARM assembly
|
||||||
|
bx lr
|
||||||
|
|
||||||
|
ArmCallWFI
|
||||||
|
wfi
|
||||||
|
bx lr
|
||||||
|
|
||||||
|
//Note: Return 0 in Uniprocessor implementation
|
||||||
|
ArmReadCbar
|
||||||
|
mrc p15, 4, r0, c15, c0, 0 //Read Configuration Base Address Register
|
||||||
|
bx lr
|
||||||
|
|
||||||
|
ArmInvalidateInstructionAndDataTlb
|
||||||
|
mcr p15, 0, r0, c8, c7, 0 ; Invalidate Inst TLB and Data TLB
|
||||||
|
dsb
|
||||||
|
bx lr
|
||||||
|
|
||||||
|
ArmReadMpidr
|
||||||
|
mrc p15, 0, r0, c0, c0, 5 ; read MPIDR
|
||||||
|
bx lr
|
||||||
|
|
||||||
END
|
END
|
||||||
|
|
||||||
|
@ -12,37 +12,24 @@
|
|||||||
#
|
#
|
||||||
#------------------------------------------------------------------------------
|
#------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include <AsmMacroIoLib.h>
|
||||||
|
|
||||||
.text
|
.text
|
||||||
.align 2
|
.align 2
|
||||||
.globl ASM_PFX(Cp15IdCode)
|
GCC_ASM_EXPORT(Cp15IdCode)
|
||||||
INTERWORK_FUNC(Cp15IdCode)
|
GCC_ASM_EXPORT(Cp15CacheInfo)
|
||||||
.globl ASM_PFX(Cp15CacheInfo)
|
GCC_ASM_EXPORT(ArmEnableInterrupts)
|
||||||
INTERWORK_FUNC(Cp15CacheInfo)
|
GCC_ASM_EXPORT(ArmDisableInterrupts)
|
||||||
.globl ASM_PFX(ArmEnableInterrupts)
|
GCC_ASM_EXPORT(ArmGetInterruptState)
|
||||||
INTERWORK_FUNC(ArmEnableInterrupts)
|
GCC_ASM_EXPORT(ArmEnableFiq)
|
||||||
.globl ASM_PFX(ArmDisableInterrupts)
|
GCC_ASM_EXPORT(ArmDisableFiq)
|
||||||
INTERWORK_FUNC(ArmDisableInterrupts)
|
GCC_ASM_EXPORT(ArmGetFiqState)
|
||||||
.globl ASM_PFX(ArmGetInterruptState)
|
GCC_ASM_EXPORT(ArmInvalidateTlb)
|
||||||
INTERWORK_FUNC(ArmGetInterruptState)
|
GCC_ASM_EXPORT(ArmSetTTBR0)
|
||||||
.globl ASM_PFX(ArmEnableFiq)
|
GCC_ASM_EXPORT(ArmGetTTBR0BaseAddress)
|
||||||
INTERWORK_FUNC(ArmEnableFiq)
|
GCC_ASM_EXPORT(ArmSetDomainAccessControl)
|
||||||
.globl ASM_PFX(ArmDisableFiq)
|
GCC_ASM_EXPORT(CPSRMaskInsert)
|
||||||
INTERWORK_FUNC(ArmDisableFiq)
|
GCC_ASM_EXPORT(CPSRRead)
|
||||||
.globl ASM_PFX(ArmGetFiqState)
|
|
||||||
INTERWORK_FUNC(ArmGetFiqState)
|
|
||||||
.globl ASM_PFX(ArmInvalidateTlb)
|
|
||||||
INTERWORK_FUNC(ArmInvalidateTlb)
|
|
||||||
.globl ASM_PFX(ArmSetTranslationTableBaseAddress)
|
|
||||||
INTERWORK_FUNC(ArmSetTranslationTableBaseAddress)
|
|
||||||
.globl ASM_PFX(ArmGetTranslationTableBaseAddress)
|
|
||||||
INTERWORK_FUNC(ArmGetTranslationTableBaseAddress)
|
|
||||||
.globl ASM_PFX(ArmSetDomainAccessControl)
|
|
||||||
INTERWORK_FUNC(ArmSetDomainAccessControl)
|
|
||||||
.globl ASM_PFX(CPSRMaskInsert)
|
|
||||||
INTERWORK_FUNC(CPSRMaskInsert)
|
|
||||||
.globl ASM_PFX(CPSRRead)
|
|
||||||
INTERWORK_FUNC(CPSRRead)
|
|
||||||
|
|
||||||
|
|
||||||
#------------------------------------------------------------------------------
|
#------------------------------------------------------------------------------
|
||||||
|
|
||||||
@ -103,12 +90,14 @@ ASM_PFX(ArmInvalidateTlb):
|
|||||||
mcr p15,0,r0,c8,c7,0
|
mcr p15,0,r0,c8,c7,0
|
||||||
bx lr
|
bx lr
|
||||||
|
|
||||||
ASM_PFX(ArmSetTranslationTableBaseAddress):
|
ASM_PFX(ArmSetTTBR0):
|
||||||
mcr p15,0,r0,c2,c0,0
|
mcr p15,0,r0,c2,c0,0
|
||||||
bx lr
|
bx lr
|
||||||
|
|
||||||
ASM_PFX(ArmGetTranslationTableBaseAddress):
|
ASM_PFX(ArmGetTTBR0BaseAddress):
|
||||||
mrc p15,0,r0,c2,c0,0
|
mrc p15,0,r0,c2,c0,0
|
||||||
|
LoadConstantToReg(0xFFFFC000, r1) @ and r0, r0, #0xFFFFC000
|
||||||
|
and r0, r0, r1
|
||||||
bx lr
|
bx lr
|
||||||
|
|
||||||
|
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
|
|
||||||
EXPORT Cp15IdCode
|
EXPORT Cp15IdCode
|
||||||
EXPORT Cp15CacheInfo
|
EXPORT Cp15CacheInfo
|
||||||
|
EXPORT ArmIsMPCore
|
||||||
EXPORT ArmEnableInterrupts
|
EXPORT ArmEnableInterrupts
|
||||||
EXPORT ArmDisableInterrupts
|
EXPORT ArmDisableInterrupts
|
||||||
EXPORT ArmGetInterruptState
|
EXPORT ArmGetInterruptState
|
||||||
@ -22,8 +23,8 @@
|
|||||||
EXPORT ArmDisableFiq
|
EXPORT ArmDisableFiq
|
||||||
EXPORT ArmGetFiqState
|
EXPORT ArmGetFiqState
|
||||||
EXPORT ArmInvalidateTlb
|
EXPORT ArmInvalidateTlb
|
||||||
EXPORT ArmSetTranslationTableBaseAddress
|
EXPORT ArmSetTTBR0
|
||||||
EXPORT ArmGetTranslationTableBaseAddress
|
EXPORT ArmGetTTBR0BaseAddress
|
||||||
EXPORT ArmSetDomainAccessControl
|
EXPORT ArmSetDomainAccessControl
|
||||||
EXPORT CPSRMaskInsert
|
EXPORT CPSRMaskInsert
|
||||||
EXPORT CPSRRead
|
EXPORT CPSRRead
|
||||||
@ -38,6 +39,14 @@ Cp15CacheInfo
|
|||||||
mrc p15,0,R0,c0,c0,1
|
mrc p15,0,R0,c0,c0,1
|
||||||
bx LR
|
bx LR
|
||||||
|
|
||||||
|
ArmIsMPCore
|
||||||
|
mrc p15,0,R0,c0,c0,5
|
||||||
|
# Get Multiprocessing extension (bit31) & U bit (bit30)
|
||||||
|
and R0, R0, #0xC0000000
|
||||||
|
# if bit30 == 0 then the processor is part of a multiprocessor system)
|
||||||
|
and R0, R0, #0x80000000
|
||||||
|
bx LR
|
||||||
|
|
||||||
ArmEnableInterrupts
|
ArmEnableInterrupts
|
||||||
mrs R0,CPSR
|
mrs R0,CPSR
|
||||||
bic R0,R0,#0x80 ;Enable IRQ interrupts
|
bic R0,R0,#0x80 ;Enable IRQ interrupts
|
||||||
@ -87,12 +96,13 @@ ArmInvalidateTlb
|
|||||||
mcr p15,0,r0,c8,c7,0
|
mcr p15,0,r0,c8,c7,0
|
||||||
bx lr
|
bx lr
|
||||||
|
|
||||||
ArmSetTranslationTableBaseAddress
|
ArmSetTTBR0
|
||||||
mcr p15,0,r0,c2,c0,0
|
mcr p15,0,r0,c2,c0,0
|
||||||
bx lr
|
bx lr
|
||||||
|
|
||||||
ArmGetTranslationTableBaseAddress
|
ArmGetTTBR0BaseAddress
|
||||||
mrc p15,0,r0,c2,c0,0
|
mrc p15,0,r0,c2,c0,0
|
||||||
|
and r0, r0, #0xFFFFC000
|
||||||
bx lr
|
bx lr
|
||||||
|
|
||||||
ArmSetDomainAccessControl
|
ArmSetDomainAccessControl
|
||||||
|
25
ArmPkg/Library/ArmMPCoreMailBoxLib/ArmMPCoreMailBox.c
Normal file
25
ArmPkg/Library/ArmMPCoreMailBoxLib/ArmMPCoreMailBox.c
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
/** @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/ArmMPCoreMailBoxLib.h>
|
||||||
|
#include <Library/PcdLib.h>
|
||||||
|
#include <Library/IoLib.h>
|
||||||
|
|
||||||
|
VOID ArmClearMPCoreMailbox() {
|
||||||
|
MmioWrite32(PcdGet32(PcdMPCoreMailboxClearAddress),PcdGet32(PcdMPCoreMailboxClearValue));
|
||||||
|
}
|
||||||
|
|
||||||
|
UINTN ArmGetMPCoreMailbox() {
|
||||||
|
return MmioRead32(PcdGet32(PcdMPCoreMailboxGetAddress));
|
||||||
|
}
|
37
ArmPkg/Library/ArmMPCoreMailBoxLib/ArmMPCoreMailBoxLib.inf
Normal file
37
ArmPkg/Library/ArmMPCoreMailBoxLib/ArmMPCoreMailBoxLib.inf
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
#/* @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 = ArmMPCoreMailBoxLib
|
||||||
|
FILE_GUID = de76d780-f422-11df-967a-0002a5d5c51b
|
||||||
|
MODULE_TYPE = BASE
|
||||||
|
VERSION_STRING = 1.0
|
||||||
|
LIBRARY_CLASS = ArmMPCoreMailBoxLib
|
||||||
|
|
||||||
|
[Packages]
|
||||||
|
MdePkg/MdePkg.dec
|
||||||
|
ArmPkg/ArmPkg.dec
|
||||||
|
|
||||||
|
[LibraryClasses]
|
||||||
|
IoLib
|
||||||
|
|
||||||
|
[Sources.common]
|
||||||
|
ArmMPCoreMailBox.c
|
||||||
|
|
||||||
|
[Protocols]
|
||||||
|
|
||||||
|
[FixedPcd]
|
||||||
|
gArmTokenSpaceGuid.PcdMPCoreMailboxGetAddress
|
||||||
|
gArmTokenSpaceGuid.PcdMPCoreMailboxClearAddress
|
||||||
|
gArmTokenSpaceGuid.PcdMPCoreMailboxClearValue
|
79
ArmPkg/Library/ArmTrustZoneLib/ArmTrustZone.c
Normal file
79
ArmPkg/Library/ArmTrustZoneLib/ArmTrustZone.c
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
/** @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/BaseLib.h>
|
||||||
|
#include <Library/IoLib.h>
|
||||||
|
#include <Library/ArmTrustZoneLib.h>
|
||||||
|
|
||||||
|
#define TZPC_DECPROT0_STATUS_REG 0x800
|
||||||
|
#define TZPC_DECPROT0_SET_REG 0x804
|
||||||
|
#define TZPC_DECPROT0_CLEAR_REG 0x808
|
||||||
|
|
||||||
|
#define TZASC_CONFIGURATION_REG 0x000
|
||||||
|
#define TZASC_REGIONS_REG 0x100
|
||||||
|
#define TZASC_REGION0_LOW_ADDRESS_REG 0x100
|
||||||
|
#define TZASC_REGION0_HIGH_ADDRESS_REG 0x104
|
||||||
|
#define TZASC_REGION0_ATTRIBUTES 0x108
|
||||||
|
|
||||||
|
/**
|
||||||
|
FIXME: Need documentation
|
||||||
|
**/
|
||||||
|
EFI_STATUS TZPCSetDecProtBits(UINTN TzpcBase, UINTN TzpcId, UINTN Bits) {
|
||||||
|
if (TzpcId > TZPC_DECPROT_MAX) {
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
MmioWrite32((UINTN)TzpcBase + TZPC_DECPROT0_SET_REG + (TzpcId * 0x0C), Bits);
|
||||||
|
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
FIXME: Need documentation
|
||||||
|
**/
|
||||||
|
EFI_STATUS TZPCClearDecProtBits(UINTN TzpcBase, UINTN TzpcId, UINTN Bits) {
|
||||||
|
if (TzpcId> TZPC_DECPROT_MAX) {
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
MmioWrite32((UINTN)TzpcBase + TZPC_DECPROT0_CLEAR_REG + (TzpcId * 0x0C), Bits);
|
||||||
|
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
FIXME: Need documentation
|
||||||
|
**/
|
||||||
|
UINT32 TZASCGetNumRegions(UINTN TzascBase) {
|
||||||
|
return (MmioRead32((UINTN)TzascBase + TZASC_CONFIGURATION_REG) & 0xF);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
FIXME: Need documentation
|
||||||
|
**/
|
||||||
|
EFI_STATUS TZASCSetRegion(UINTN TzascBase, UINTN RegionId, UINTN Enabled, UINTN LowAddress, UINTN HighAddress, UINTN Size, UINTN Security) {
|
||||||
|
UINT32* Region;
|
||||||
|
|
||||||
|
if (RegionId > TZASCGetNumRegions(TzascBase)) {
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
Region = (UINT32*)((UINTN)TzascBase + TZASC_REGIONS_REG + (RegionId * 0x10));
|
||||||
|
|
||||||
|
MmioWrite32((UINTN)(Region), LowAddress&0xFFFF8000);
|
||||||
|
MmioWrite32((UINTN)(Region+1), HighAddress);
|
||||||
|
MmioWrite32((UINTN)(Region+2), ((Security & 0xF) <<28) | ((Size & 0x3F) << 1) | (Enabled & 0x1));
|
||||||
|
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
32
ArmPkg/Library/ArmTrustZoneLib/ArmTrustZoneLib.inf
Normal file
32
ArmPkg/Library/ArmTrustZoneLib/ArmTrustZoneLib.inf
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
#/* @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 = ArmTrustZoneLib
|
||||||
|
FILE_GUID = 5962d040-8b8a-11df-9a71-0002a5d5c51b
|
||||||
|
MODULE_TYPE = BASE
|
||||||
|
VERSION_STRING = 1.0
|
||||||
|
LIBRARY_CLASS = ArmTrustZoneLib
|
||||||
|
|
||||||
|
|
||||||
|
[Sources.common]
|
||||||
|
ArmTrustZone.c
|
||||||
|
|
||||||
|
[Packages]
|
||||||
|
MdePkg/MdePkg.dec
|
||||||
|
ArmPkg/ArmPkg.dec
|
||||||
|
|
||||||
|
[LibraryClasses]
|
||||||
|
BaseLib
|
||||||
|
IoLib
|
@ -39,8 +39,7 @@ InternalMemCopyMem (
|
|||||||
**/
|
**/
|
||||||
.text
|
.text
|
||||||
.align 2
|
.align 2
|
||||||
.globl ASM_PFX(InternalMemCopyMem)
|
GCC_ASM_EXPORT(InternalMemCopyMem)
|
||||||
INTERWORK_FUNC(InternalMemCopyMem)
|
|
||||||
|
|
||||||
ASM_PFX(InternalMemCopyMem):
|
ASM_PFX(InternalMemCopyMem):
|
||||||
stmfd sp!, {r4-r11, lr}
|
stmfd sp!, {r4-r11, lr}
|
||||||
|
@ -37,8 +37,7 @@ InternalMemSetMem (
|
|||||||
|
|
||||||
.text
|
.text
|
||||||
.align 2
|
.align 2
|
||||||
.globl ASM_PFX(InternalMemSetMem)
|
GCC_ASM_EXPORT(InternalMemSetMem)
|
||||||
INTERWORK_FUNC(InternalMemSetMem)
|
|
||||||
|
|
||||||
ASM_PFX(InternalMemSetMem):
|
ASM_PFX(InternalMemSetMem):
|
||||||
stmfd sp!, {r4-r11, lr}
|
stmfd sp!, {r4-r11, lr}
|
||||||
|
@ -39,8 +39,7 @@ InternalMemCopyMem (
|
|||||||
**/
|
**/
|
||||||
.text
|
.text
|
||||||
.align 2
|
.align 2
|
||||||
.globl ASM_PFX(InternalMemCopyMem)
|
GCC_ASM_EXPORT(InternalMemCopyMem)
|
||||||
INTERWORK_FUNC(InternalMemCopyMem)
|
|
||||||
|
|
||||||
ASM_PFX(InternalMemCopyMem):
|
ASM_PFX(InternalMemCopyMem):
|
||||||
stmfd sp!, {r4, r9, lr}
|
stmfd sp!, {r4, r9, lr}
|
||||||
|
@ -37,8 +37,7 @@ InternalMemSetMem (
|
|||||||
|
|
||||||
.text
|
.text
|
||||||
.align 2
|
.align 2
|
||||||
.globl ASM_PFX(InternalMemSetMem)
|
GCC_ASM_EXPORT(InternalMemSetMem)
|
||||||
INTERWORK_FUNC(InternalMemSetMem)
|
|
||||||
|
|
||||||
ASM_PFX(InternalMemSetMem):
|
ASM_PFX(InternalMemSetMem):
|
||||||
stmfd sp!, {r4-r7, lr}
|
stmfd sp!, {r4-r7, lr}
|
||||||
|
@ -913,7 +913,7 @@ PeCoffLoaderLoadImage (
|
|||||||
ImageContext->Handle,
|
ImageContext->Handle,
|
||||||
0,
|
0,
|
||||||
&ImageContext->SizeOfHeaders,
|
&ImageContext->SizeOfHeaders,
|
||||||
(void *)(UINTN)ImageContext->ImageAddress
|
(VOID*)(UINTN)ImageContext->ImageAddress
|
||||||
);
|
);
|
||||||
|
|
||||||
Hdr.Te = (EFI_TE_IMAGE_HEADER *)(UINTN)(ImageContext->ImageAddress);
|
Hdr.Te = (EFI_TE_IMAGE_HEADER *)(UINTN)(ImageContext->ImageAddress);
|
||||||
|
102
ArmPkg/Library/BdsLib/BdsAppLoader.c
Normal file
102
ArmPkg/Library/BdsLib/BdsAppLoader.c
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
/** @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 "BdsInternal.h"
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
BdsLoadPeCoff (
|
||||||
|
IN BDS_FILE *EfiAppFile
|
||||||
|
)
|
||||||
|
{
|
||||||
|
EFI_STATUS Status;
|
||||||
|
EFI_HANDLE ImageHandle;
|
||||||
|
MEDIA_FW_VOL_FILEPATH_DEVICE_PATH NewNode;
|
||||||
|
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
|
||||||
|
|
||||||
|
// Only support loading from FV right now
|
||||||
|
ASSERT(EfiAppFile->Type == BDS_FILETYPE_FV);
|
||||||
|
|
||||||
|
// Generate the Device Path for the file
|
||||||
|
DevicePath = DuplicateDevicePath(EfiAppFile->DevicePath);
|
||||||
|
EfiInitializeFwVolDevicepathNode (&NewNode, &(EfiAppFile->File.Fv.Guid));
|
||||||
|
DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&NewNode);
|
||||||
|
|
||||||
|
Status = gBS->LoadImage (TRUE, gImageHandle, DevicePath, NULL, 0, &ImageHandle);
|
||||||
|
if (!EFI_ERROR (Status)) {
|
||||||
|
Status = gBS->StartImage (ImageHandle, NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
EFI_STATUS BdsLoadApplicationFromPath(
|
||||||
|
IN CHAR16* EfiAppPath
|
||||||
|
) {
|
||||||
|
EFI_STATUS Status;
|
||||||
|
BDS_FILE EfiAppFile;
|
||||||
|
|
||||||
|
// Need to connect every drivers to ensure no dependencies are missing for the application
|
||||||
|
Status = BdsConnectAllDrivers();
|
||||||
|
if (EFI_ERROR(Status)) {
|
||||||
|
DEBUG ((EFI_D_ERROR, "FAIL to connect all drivers\n"));
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Locate the application from a device path
|
||||||
|
Status = BdsLoadFilePath(EfiAppPath, &EfiAppFile);
|
||||||
|
if (EFI_ERROR(Status)) {
|
||||||
|
DEBUG ((EFI_D_ERROR, "ERROR: Do not find EFI application %s\n",EfiAppPath));
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start the application
|
||||||
|
Status = BdsLoadPeCoff(&EfiAppFile);
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
EFI_STATUS BdsLoadApplication(
|
||||||
|
IN CHAR16* EfiApp
|
||||||
|
) {
|
||||||
|
EFI_STATUS Status;
|
||||||
|
UINTN NoHandles, HandleIndex;
|
||||||
|
EFI_HANDLE *Handles;
|
||||||
|
BDS_FILE EfiAppFile;
|
||||||
|
|
||||||
|
// Need to connect every drivers to ensure no dependencies are missing for the application
|
||||||
|
Status = BdsConnectAllDrivers();
|
||||||
|
if (EFI_ERROR(Status)) {
|
||||||
|
DEBUG ((EFI_D_ERROR, "FAIL to connect all drivers\n"));
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Search the application in any Firmware Volume
|
||||||
|
Status = gBS->LocateHandleBuffer (ByProtocol, &gEfiFirmwareVolume2ProtocolGuid, NULL, &NoHandles, &Handles);
|
||||||
|
if (EFI_ERROR (Status) || (NoHandles == 0)) {
|
||||||
|
DEBUG ((EFI_D_ERROR, "FAIL to find Firmware Volume\n"));
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Search in all Firmware Volume for the EFI Application
|
||||||
|
for (HandleIndex = 0; HandleIndex < NoHandles; HandleIndex++) {
|
||||||
|
Status = BdsLoadFileFromFirmwareVolume(Handles[HandleIndex],EfiApp,EFI_FV_FILETYPE_APPLICATION,&EfiAppFile);
|
||||||
|
if (!EFI_ERROR (Status)) {
|
||||||
|
// Start the application
|
||||||
|
Status = BdsLoadPeCoff(&EfiAppFile);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
182
ArmPkg/Library/BdsLib/BdsFilePath.c
Normal file
182
ArmPkg/Library/BdsLib/BdsFilePath.c
Normal file
@ -0,0 +1,182 @@
|
|||||||
|
/** @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 "BdsInternal.h"
|
||||||
|
|
||||||
|
// Count the number of DevicePath Node
|
||||||
|
static UINTN NumberNodeFromDevicePath(
|
||||||
|
IN EFI_DEVICE_PATH_PROTOCOL* DevicePath
|
||||||
|
) {
|
||||||
|
UINTN NumberDevicePathNode = 0;
|
||||||
|
|
||||||
|
while (!IsDevicePathEnd (DevicePath)) {
|
||||||
|
NumberDevicePathNode++;
|
||||||
|
DevicePath = NextDevicePathNode(DevicePath);
|
||||||
|
}
|
||||||
|
return NumberDevicePathNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extract the FilePath from the Device Path
|
||||||
|
CHAR16* BdsExtractFilePathFromDevicePath(
|
||||||
|
IN CONST CHAR16 *StrDevicePath,
|
||||||
|
IN UINTN NumberDevicePathNode
|
||||||
|
) {
|
||||||
|
UINTN Node;
|
||||||
|
CHAR16 *Str;
|
||||||
|
|
||||||
|
Str = (CHAR16*)StrDevicePath;
|
||||||
|
Node = 0;
|
||||||
|
while ((Str != NULL) && (*Str != L'\0') && (Node < NumberDevicePathNode)) {
|
||||||
|
if ((*Str == L'/') || (*Str == L'\\')) {
|
||||||
|
Node++;
|
||||||
|
}
|
||||||
|
Str++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*Str == L'\0') {
|
||||||
|
return NULL;
|
||||||
|
} else {
|
||||||
|
return Str;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
BdsLoadDevicePath(
|
||||||
|
IN EFI_DEVICE_PATH_PROTOCOL* DevicePath,
|
||||||
|
OUT EFI_HANDLE *Handle
|
||||||
|
) {
|
||||||
|
EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath;
|
||||||
|
EFI_STATUS Status;
|
||||||
|
|
||||||
|
if ((DevicePath == NULL) || (Handle == NULL)) {
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
RemainingDevicePath = DevicePath;
|
||||||
|
// The LocateDevicePath() function locates all devices on DevicePath that support Protocol and returns
|
||||||
|
// the handle to the device that is closest to DevicePath. On output, the device path pointer is modified
|
||||||
|
// to point to the remaining part of the device path
|
||||||
|
Status = gBS->LocateDevicePath(&gEfiDevicePathProtocolGuid,&RemainingDevicePath,Handle);
|
||||||
|
if (!EFI_ERROR (Status)) {
|
||||||
|
// Recursive = FALSE: We do not want to start all the device tree
|
||||||
|
Status = gBS->ConnectController (*Handle, NULL, RemainingDevicePath, FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// We need to check if RemainingDevicePath does not point on the last node. Otherwise, calling
|
||||||
|
// NextDevicePathNode() will return an undetermined Device Path Node
|
||||||
|
if (!IsDevicePathEnd (RemainingDevicePath)) {
|
||||||
|
RemainingDevicePath = NextDevicePathNode (RemainingDevicePath);
|
||||||
|
}
|
||||||
|
} while (!EFI_ERROR (Status) && !IsDevicePathEnd (RemainingDevicePath));
|
||||||
|
|
||||||
|
if (!EFI_ERROR (Status)) {
|
||||||
|
// Now, we have got the whole Device Path connected, call again ConnectController to ensure all the supported Driver
|
||||||
|
// Binding Protocol are connected (such as DiskIo and SimpleFileSystem)
|
||||||
|
RemainingDevicePath = DevicePath;
|
||||||
|
Status = gBS->LocateDevicePath(&gEfiDevicePathProtocolGuid,&RemainingDevicePath,Handle);
|
||||||
|
if (!EFI_ERROR (Status)) {
|
||||||
|
Status = gBS->ConnectController (*Handle, NULL, RemainingDevicePath, FALSE);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
// If the last node is a Memory Map Device Path just return EFI_SUCCESS.
|
||||||
|
if ((RemainingDevicePath->Type == HARDWARE_DEVICE_PATH) && (RemainingDevicePath->SubType == HW_MEMMAP_DP)) {
|
||||||
|
Status = EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (IsDevicePathEnd (RemainingDevicePath)) {
|
||||||
|
// Case when the DevicePath contains a MemoryMap Device Path Node and all drivers are connected.
|
||||||
|
// Ensure the Device Path exists
|
||||||
|
RemainingDevicePath = DevicePath;
|
||||||
|
Status = gBS->LocateDevicePath(&gEfiDevicePathProtocolGuid,&RemainingDevicePath,Handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
BdsLoadFilePath (
|
||||||
|
IN CONST CHAR16 *DeviceFilePath,
|
||||||
|
OUT BDS_FILE *File
|
||||||
|
) {
|
||||||
|
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
|
||||||
|
EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL *EfiDevicePathFromTextProtocol;
|
||||||
|
EFI_STATUS Status;
|
||||||
|
EFI_HANDLE Handle;
|
||||||
|
UINTN NumberDevicePathNode;
|
||||||
|
CHAR16 *FilePath;
|
||||||
|
|
||||||
|
//Do a sanity check on the Device file path
|
||||||
|
if (DeviceFilePath == NULL) {
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert the Device Path String into Device Path Protocol
|
||||||
|
Status = gBS->LocateProtocol(&gEfiDevicePathFromTextProtocolGuid, NULL, (VOID **)&EfiDevicePathFromTextProtocol);
|
||||||
|
ASSERT_EFI_ERROR(Status);
|
||||||
|
DevicePath = EfiDevicePathFromTextProtocol->ConvertTextToDevicePath(DeviceFilePath);
|
||||||
|
|
||||||
|
//Do a sanity check on the Device Path
|
||||||
|
if (DevicePath == NULL) {
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Count the number of DevicePath Node
|
||||||
|
NumberDevicePathNode = NumberNodeFromDevicePath(DevicePath);
|
||||||
|
// Extract the FilePath from the Device Path
|
||||||
|
FilePath = BdsExtractFilePathFromDevicePath(DeviceFilePath,NumberDevicePathNode);
|
||||||
|
|
||||||
|
Status = BdsLoadDevicePath(DevicePath,&Handle);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
//If FilePath == NULL then let consider if a MemoryMap Device Path
|
||||||
|
if (FilePath == NULL) {
|
||||||
|
// Check if the Node is a MemoryMap Device Path
|
||||||
|
Status = BdsLoadFileFromMemMap(Handle,DevicePath,File);
|
||||||
|
} else {
|
||||||
|
Status = BdsLoadFileFromSimpleFileSystem(Handle,FilePath,File);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
Status = BdsLoadFileFromFirmwareVolume(Handle,FilePath,EFI_FV_FILETYPE_ALL,File);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!EFI_ERROR (Status)) {
|
||||||
|
File->DevicePath = DevicePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
EFI_STATUS BdsCopyRawFileToRuntimeMemory(
|
||||||
|
IN BDS_FILE *File,
|
||||||
|
OUT VOID **FileImage,
|
||||||
|
OUT UINTN *FileSize
|
||||||
|
) {
|
||||||
|
if (File == NULL) {
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (File->Type == BDS_FILETYPE_FS) {
|
||||||
|
return BdsCopyRawFileToRuntimeMemoryFS(File->File.Fs.Handle,FileImage,FileSize);
|
||||||
|
} else if (File->Type == BDS_FILETYPE_FV) {
|
||||||
|
return BdsCopyRawFileToRuntimeMemoryFV(&(File->File.Fv),FileImage,FileSize);
|
||||||
|
} else if (File->Type == BDS_FILETYPE_MEM) {
|
||||||
|
return BdsCopyRawFileToRuntimeMemoryMemMap(&(File->File.Mem),FileImage,FileSize);
|
||||||
|
} else {
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
}
|
86
ArmPkg/Library/BdsLib/BdsFilePathFs.c
Normal file
86
ArmPkg/Library/BdsLib/BdsFilePathFs.c
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
/** @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 "BdsInternal.h"
|
||||||
|
|
||||||
|
EFI_STATUS BdsLoadFileFromSimpleFileSystem(
|
||||||
|
IN EFI_HANDLE Handle,
|
||||||
|
IN CHAR16 *FilePath,
|
||||||
|
OUT BDS_FILE *File
|
||||||
|
) {
|
||||||
|
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FsProtocol;
|
||||||
|
EFI_FILE_PROTOCOL *Fs;
|
||||||
|
EFI_STATUS Status;
|
||||||
|
EFI_FILE_PROTOCOL *FileHandle = NULL;
|
||||||
|
|
||||||
|
if (File == NULL) {
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = gBS->HandleProtocol(Handle,&gEfiSimpleFileSystemProtocolGuid, (VOID **)&FsProtocol);
|
||||||
|
if (EFI_ERROR(Status)) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Try to Open the volume and get root directory
|
||||||
|
Status = FsProtocol->OpenVolume(FsProtocol, &Fs);
|
||||||
|
if (EFI_ERROR(Status)) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = Fs->Open(Fs, &FileHandle, FilePath, EFI_FILE_MODE_READ, 0);
|
||||||
|
|
||||||
|
File->Type = BDS_FILETYPE_FS;
|
||||||
|
File->FilePath = FilePath;
|
||||||
|
File->File.Fs.Handle = FileHandle;
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
EFI_STATUS BdsCopyRawFileToRuntimeMemoryFS(
|
||||||
|
IN EFI_FILE_PROTOCOL *File,
|
||||||
|
OUT VOID **FileImage,
|
||||||
|
OUT UINTN *FileSize
|
||||||
|
) {
|
||||||
|
EFI_FILE_INFO *FileInfo;
|
||||||
|
UINTN Size;
|
||||||
|
VOID* Image;
|
||||||
|
EFI_STATUS Status;
|
||||||
|
|
||||||
|
Size = 0;
|
||||||
|
File->GetInfo(File, &gEfiFileInfoGuid, &Size, NULL);
|
||||||
|
FileInfo = AllocatePool (Size);
|
||||||
|
Status = File->GetInfo(File, &gEfiFileInfoGuid, &Size, FileInfo);
|
||||||
|
if (EFI_ERROR(Status)) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the file size
|
||||||
|
Size = FileInfo->FileSize;
|
||||||
|
if (FileSize) {
|
||||||
|
*FileSize = Size;
|
||||||
|
}
|
||||||
|
FreePool(FileInfo);
|
||||||
|
|
||||||
|
Image = AllocateRuntimePool(Size);
|
||||||
|
if (Image == NULL) {
|
||||||
|
return EFI_OUT_OF_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = File->Read(File, &Size, Image);
|
||||||
|
if (!EFI_ERROR(Status)) {
|
||||||
|
*FileImage = Image;
|
||||||
|
}
|
||||||
|
return Status;
|
||||||
|
}
|
136
ArmPkg/Library/BdsLib/BdsFilePathFv.c
Normal file
136
ArmPkg/Library/BdsLib/BdsFilePathFv.c
Normal file
@ -0,0 +1,136 @@
|
|||||||
|
/** @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 "BdsInternal.h"
|
||||||
|
|
||||||
|
EFI_STATUS BdsLoadFileFromFirmwareVolume(
|
||||||
|
IN EFI_HANDLE FvHandle,
|
||||||
|
IN CHAR16 *FilePath,
|
||||||
|
IN EFI_FV_FILETYPE FileTypeFilter,
|
||||||
|
OUT BDS_FILE *File
|
||||||
|
) {
|
||||||
|
EFI_FIRMWARE_VOLUME2_PROTOCOL *FvProtocol;
|
||||||
|
VOID *Key;
|
||||||
|
EFI_STATUS Status, FileStatus;
|
||||||
|
EFI_GUID NameGuid;
|
||||||
|
EFI_FV_FILETYPE FileType;
|
||||||
|
EFI_FV_FILE_ATTRIBUTES Attributes;
|
||||||
|
UINTN Size;
|
||||||
|
UINTN UiStringLen;
|
||||||
|
CHAR16 *UiSection;
|
||||||
|
UINT32 Authentication;
|
||||||
|
|
||||||
|
if (File == NULL) {
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = gBS->HandleProtocol(FvHandle,&gEfiFirmwareVolume2ProtocolGuid, (VOID **)&FvProtocol);
|
||||||
|
if (EFI_ERROR(Status)) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Length of FilePath
|
||||||
|
UiStringLen = StrLen (FilePath);
|
||||||
|
|
||||||
|
// Allocate Key
|
||||||
|
Key = AllocatePool (FvProtocol->KeySize);
|
||||||
|
ASSERT (Key != NULL);
|
||||||
|
ZeroMem (Key, FvProtocol->KeySize);
|
||||||
|
|
||||||
|
do {
|
||||||
|
// Search in all files
|
||||||
|
FileType = FileTypeFilter;
|
||||||
|
|
||||||
|
Status = FvProtocol->GetNextFile (FvProtocol, Key, &FileType, &NameGuid, &Attributes, &Size);
|
||||||
|
if (!EFI_ERROR (Status)) {
|
||||||
|
UiSection = NULL;
|
||||||
|
FileStatus = FvProtocol->ReadSection (
|
||||||
|
FvProtocol,
|
||||||
|
&NameGuid,
|
||||||
|
EFI_SECTION_USER_INTERFACE,
|
||||||
|
0,
|
||||||
|
(VOID **)&UiSection,
|
||||||
|
&Size,
|
||||||
|
&Authentication
|
||||||
|
);
|
||||||
|
if (!EFI_ERROR (FileStatus)) {
|
||||||
|
if (StrnCmp (FilePath, UiSection, UiStringLen) == 0) {
|
||||||
|
|
||||||
|
//
|
||||||
|
// We found a UiString match.
|
||||||
|
//
|
||||||
|
//*FileGuid = NameGuid;
|
||||||
|
File->Type = BDS_FILETYPE_FV;
|
||||||
|
File->FilePath = FilePath;
|
||||||
|
CopyGuid (&(File->File.Fv.Guid),&NameGuid);
|
||||||
|
File->File.Fv.FvProtocol = FvProtocol;
|
||||||
|
File->File.Fv.FileType = FileType;
|
||||||
|
|
||||||
|
Status = gBS->HandleProtocol(FvHandle,&gEfiDevicePathProtocolGuid, (VOID **)&(File->DevicePath));
|
||||||
|
|
||||||
|
FreePool (Key);
|
||||||
|
FreePool (UiSection);
|
||||||
|
return FileStatus;
|
||||||
|
}
|
||||||
|
FreePool (UiSection);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while (!EFI_ERROR (Status));
|
||||||
|
|
||||||
|
FreePool(Key);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
EFI_STATUS BdsCopyRawFileToRuntimeMemoryFV(
|
||||||
|
IN BDS_FV_FILE *FvFile,
|
||||||
|
OUT VOID **FileImage,
|
||||||
|
OUT UINTN *FileSize
|
||||||
|
) {
|
||||||
|
EFI_STATUS Status = EFI_INVALID_PARAMETER;
|
||||||
|
EFI_FIRMWARE_VOLUME2_PROTOCOL *FvProtocol;
|
||||||
|
EFI_FV_FILETYPE FileType;
|
||||||
|
EFI_GUID* NameGuid;
|
||||||
|
EFI_FV_FILE_ATTRIBUTES Attributes;
|
||||||
|
UINT32 Authentication;
|
||||||
|
|
||||||
|
FvProtocol = FvFile->FvProtocol;
|
||||||
|
FileType = FvFile->FileType;
|
||||||
|
NameGuid = &(FvFile->Guid);
|
||||||
|
|
||||||
|
if (FileType == EFI_FV_FILETYPE_RAW) {
|
||||||
|
*FileImage = NULL;
|
||||||
|
*FileSize = 0;
|
||||||
|
Status = FvProtocol->ReadFile(
|
||||||
|
FvProtocol,NameGuid, // IN
|
||||||
|
FileImage,FileSize, // IN OUT
|
||||||
|
&FileType,&Attributes,&Authentication // OUT
|
||||||
|
);
|
||||||
|
ASSERT_EFI_ERROR(Status);
|
||||||
|
|
||||||
|
// This raw file also contains a header
|
||||||
|
*FileSize = *FileSize - 4;
|
||||||
|
*FileImage = (UINT8*)FileImage + 4;
|
||||||
|
} else if (FileType == EFI_FV_FILETYPE_FREEFORM) {
|
||||||
|
Status = FvProtocol->ReadSection (
|
||||||
|
FvProtocol,NameGuid,EFI_SECTION_RAW,0, // IN
|
||||||
|
FileImage,FileSize, // IN OUT
|
||||||
|
&Authentication // OUT
|
||||||
|
);
|
||||||
|
ASSERT_EFI_ERROR(Status);
|
||||||
|
} else {
|
||||||
|
ASSERT(0); //Maybe support application as well ???
|
||||||
|
}
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
73
ArmPkg/Library/BdsLib/BdsFilePathMem.c
Normal file
73
ArmPkg/Library/BdsLib/BdsFilePathMem.c
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
/** @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 "BdsInternal.h"
|
||||||
|
|
||||||
|
|
||||||
|
EFI_STATUS BdsLoadFileFromMemMap (
|
||||||
|
IN EFI_HANDLE Handle,
|
||||||
|
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
|
||||||
|
OUT BDS_FILE *File
|
||||||
|
) {
|
||||||
|
EFI_DEVICE_PATH_PROTOCOL *LastDevicePath;
|
||||||
|
|
||||||
|
if ((File == NULL) || (DevicePath == NULL) || (IsDevicePathEnd (DevicePath))) {
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the last node of the device Path is a Memory Map Device Node
|
||||||
|
LastDevicePath = DevicePath;
|
||||||
|
DevicePath = NextDevicePathNode(DevicePath);
|
||||||
|
while (!IsDevicePathEnd (DevicePath)) {
|
||||||
|
LastDevicePath = DevicePath;
|
||||||
|
DevicePath = NextDevicePathNode(DevicePath);
|
||||||
|
}
|
||||||
|
if ((LastDevicePath->Type != HARDWARE_DEVICE_PATH) || (LastDevicePath->SubType != HW_MEMMAP_DP)) {
|
||||||
|
return EFI_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
File->Type = BDS_FILETYPE_MEM;
|
||||||
|
File->File.Mem.MemoryType = ((MEMMAP_DEVICE_PATH*)LastDevicePath)->MemoryType;
|
||||||
|
File->File.Mem.StartingAddress = ((MEMMAP_DEVICE_PATH*)LastDevicePath)->StartingAddress;
|
||||||
|
File->File.Mem.EndingAddress = ((MEMMAP_DEVICE_PATH*)LastDevicePath)->EndingAddress;
|
||||||
|
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
EFI_STATUS BdsCopyRawFileToRuntimeMemoryMemMap(
|
||||||
|
IN BDS_MEM_FILE *MemFile,
|
||||||
|
OUT VOID **FileImage,
|
||||||
|
OUT UINTN *FileSize
|
||||||
|
) {
|
||||||
|
UINTN Size;
|
||||||
|
VOID* Image;
|
||||||
|
|
||||||
|
Size = MemFile->EndingAddress - MemFile->StartingAddress;
|
||||||
|
|
||||||
|
if ((Size == 0) || (FileImage == NULL)) {
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
if (FileSize != NULL) {
|
||||||
|
*FileSize = Size;
|
||||||
|
}
|
||||||
|
|
||||||
|
Image = AllocateRuntimePool(Size);
|
||||||
|
if (Image == NULL) {
|
||||||
|
return EFI_OUT_OF_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
*FileImage = CopyMem(Image,(CONST VOID*)(UINTN)MemFile->StartingAddress,Size);
|
||||||
|
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
183
ArmPkg/Library/BdsLib/BdsHelper.c
Normal file
183
ArmPkg/Library/BdsLib/BdsHelper.c
Normal file
@ -0,0 +1,183 @@
|
|||||||
|
/** @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 "BdsInternal.h"
|
||||||
|
|
||||||
|
#include <Library/DxeServicesTableLib.h>
|
||||||
|
#include <Library/HobLib.h>
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
ShutdownUefiBootServices( VOID )
|
||||||
|
{
|
||||||
|
EFI_STATUS Status;
|
||||||
|
UINTN MemoryMapSize;
|
||||||
|
EFI_MEMORY_DESCRIPTOR *MemoryMap;
|
||||||
|
UINTN MapKey;
|
||||||
|
UINTN DescriptorSize;
|
||||||
|
UINT32 DescriptorVersion;
|
||||||
|
UINTN Pages;
|
||||||
|
|
||||||
|
MemoryMap = NULL;
|
||||||
|
MemoryMapSize = 0;
|
||||||
|
do {
|
||||||
|
Status = gBS->GetMemoryMap (
|
||||||
|
&MemoryMapSize,
|
||||||
|
MemoryMap,
|
||||||
|
&MapKey,
|
||||||
|
&DescriptorSize,
|
||||||
|
&DescriptorVersion
|
||||||
|
);
|
||||||
|
if (Status == EFI_BUFFER_TOO_SMALL) {
|
||||||
|
|
||||||
|
Pages = EFI_SIZE_TO_PAGES (MemoryMapSize) + 1;
|
||||||
|
MemoryMap = AllocatePages (Pages);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Get System MemoryMap
|
||||||
|
//
|
||||||
|
Status = gBS->GetMemoryMap (
|
||||||
|
&MemoryMapSize,
|
||||||
|
MemoryMap,
|
||||||
|
&MapKey,
|
||||||
|
&DescriptorSize,
|
||||||
|
&DescriptorVersion
|
||||||
|
);
|
||||||
|
// Don't do anything between the GetMemoryMap() and ExitBootServices()
|
||||||
|
if (!EFI_ERROR (Status)) {
|
||||||
|
Status = gBS->ExitBootServices (gImageHandle, MapKey);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
FreePages (MemoryMap, Pages);
|
||||||
|
MemoryMap = NULL;
|
||||||
|
MemoryMapSize = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while (EFI_ERROR (Status));
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
BdsConnectAllDrivers( VOID ) {
|
||||||
|
UINTN HandleCount, Index;
|
||||||
|
EFI_HANDLE *HandleBuffer;
|
||||||
|
EFI_STATUS Status;
|
||||||
|
|
||||||
|
do {
|
||||||
|
// Locate all the driver handles
|
||||||
|
Status = gBS->LocateHandleBuffer (
|
||||||
|
AllHandles,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
&HandleCount,
|
||||||
|
&HandleBuffer
|
||||||
|
);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Connect every handles
|
||||||
|
for (Index = 0; Index < HandleCount; Index++) {
|
||||||
|
gBS->ConnectController(HandleBuffer[Index], NULL, NULL, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (HandleBuffer != NULL) {
|
||||||
|
FreePool (HandleBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if new handles have been created after the start of the previous handles
|
||||||
|
Status = gDS->Dispatch ();
|
||||||
|
} while (!EFI_ERROR(Status));
|
||||||
|
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC EFI_STATUS InsertSystemMemoryResources(LIST_ENTRY *ResourceList, EFI_HOB_RESOURCE_DESCRIPTOR *ResHob) {
|
||||||
|
BDS_SYSTEM_MEMORY_RESOURCE NewResource;
|
||||||
|
LIST_ENTRY *Link;
|
||||||
|
BDS_SYSTEM_MEMORY_RESOURCE *Resource;
|
||||||
|
|
||||||
|
//DEBUG ((EFI_D_ERROR, "** InsertSystemMemoryResources(0x%X,0x%X)\n",(UINT32)ResHob->PhysicalStart,(UINT32)ResHob->ResourceLength));
|
||||||
|
|
||||||
|
if (IsListEmpty (ResourceList)) {
|
||||||
|
ZeroMem(&NewResource,sizeof(BDS_SYSTEM_MEMORY_RESOURCE));
|
||||||
|
NewResource.PhysicalStart = ResHob->PhysicalStart;
|
||||||
|
NewResource.ResourceLength = ResHob->ResourceLength;
|
||||||
|
InsertTailList (ResourceList, &NewResource.Link);
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
//for (Link = GetFirstNode (ResourceList); !IsNull (ResourceList,Link); Link = GetNextNode (ResourceList,Link)) {
|
||||||
|
Link = ResourceList->ForwardLink;
|
||||||
|
while (Link != NULL && Link != ResourceList) {
|
||||||
|
Resource = (BDS_SYSTEM_MEMORY_RESOURCE*)Link;
|
||||||
|
//DEBUG ((EFI_D_ERROR, " - (0x%X,0x%X)\n",(UINT32)Resource->PhysicalStart,(UINT32)Resource->ResourceLength));
|
||||||
|
|
||||||
|
// Sanity Check. The resources should not overlapped.
|
||||||
|
ASSERT(!((ResHob->PhysicalStart >= Resource->PhysicalStart) && (ResHob->PhysicalStart < (Resource->PhysicalStart + Resource->ResourceLength))));
|
||||||
|
ASSERT(!((ResHob->PhysicalStart + ResHob->ResourceLength >= Resource->PhysicalStart) &&
|
||||||
|
((ResHob->PhysicalStart + ResHob->ResourceLength) < (Resource->PhysicalStart + Resource->ResourceLength))));
|
||||||
|
|
||||||
|
// The new resource is attached after this resource descriptor
|
||||||
|
if (ResHob->PhysicalStart == Resource->PhysicalStart + Resource->ResourceLength) {
|
||||||
|
Resource->ResourceLength = Resource->ResourceLength + ResHob->ResourceLength;
|
||||||
|
//DEBUG ((EFI_D_ERROR, "** Attached new Length:0x%X\n",(UINT32)Resource->ResourceLength));
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
// The new resource is attached before this resource descriptor
|
||||||
|
else if (ResHob->PhysicalStart + ResHob->ResourceLength == Resource->PhysicalStart) {
|
||||||
|
Resource->PhysicalStart = ResHob->PhysicalStart;
|
||||||
|
Resource->ResourceLength = Resource->ResourceLength + ResHob->ResourceLength;
|
||||||
|
//DEBUG ((EFI_D_ERROR, "** Attached2 new Length:0x%X\n",(UINT32)Resource->ResourceLength));
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
Link = Link->ForwardLink;
|
||||||
|
}
|
||||||
|
|
||||||
|
// None of the Resource of the list is attached to this ResHob. Create a new entry for it
|
||||||
|
ZeroMem(&NewResource,sizeof(BDS_SYSTEM_MEMORY_RESOURCE));
|
||||||
|
NewResource.PhysicalStart = ResHob->PhysicalStart;
|
||||||
|
NewResource.ResourceLength = ResHob->ResourceLength;
|
||||||
|
InsertTailList (ResourceList, &NewResource.Link);
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
EFI_STATUS GetSystemMemoryResources(LIST_ENTRY *ResourceList) {
|
||||||
|
EFI_HOB_RESOURCE_DESCRIPTOR *ResHob;
|
||||||
|
|
||||||
|
InitializeListHead (ResourceList);
|
||||||
|
|
||||||
|
// Find the first System Memory Resource Descriptor
|
||||||
|
ResHob = (EFI_HOB_RESOURCE_DESCRIPTOR *)GetFirstHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR);
|
||||||
|
while ((ResHob != NULL) && (ResHob->ResourceType != EFI_RESOURCE_SYSTEM_MEMORY)) {
|
||||||
|
ResHob = (EFI_HOB_RESOURCE_DESCRIPTOR *)GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR,(VOID *)((UINTN)ResHob + ResHob->Header.HobLength));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Did not find any
|
||||||
|
if (ResHob == NULL) {
|
||||||
|
return EFI_NOT_FOUND;
|
||||||
|
} else {
|
||||||
|
InsertSystemMemoryResources(ResourceList, ResHob);
|
||||||
|
}
|
||||||
|
|
||||||
|
ResHob = (EFI_HOB_RESOURCE_DESCRIPTOR *)GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR,(VOID *)((UINTN)ResHob + ResHob->Header.HobLength));
|
||||||
|
while (ResHob != NULL) {
|
||||||
|
if (ResHob->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) {
|
||||||
|
InsertSystemMemoryResources(ResourceList, ResHob);
|
||||||
|
}
|
||||||
|
ResHob = (EFI_HOB_RESOURCE_DESCRIPTOR *)GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR,(VOID *)((UINTN)ResHob + ResHob->Header.HobLength));
|
||||||
|
}
|
||||||
|
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
136
ArmPkg/Library/BdsLib/BdsInternal.h
Normal file
136
ArmPkg/Library/BdsLib/BdsInternal.h
Normal file
@ -0,0 +1,136 @@
|
|||||||
|
/** @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.
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
|
||||||
|
#ifndef __BDS_INTERNAL_H__
|
||||||
|
#define __BDS_INTERNAL_H__
|
||||||
|
|
||||||
|
#include <PiDxe.h>
|
||||||
|
#include <Library/BaseLib.h>
|
||||||
|
#include <Library/BaseMemoryLib.h>
|
||||||
|
#include <Library/UefiBootServicesTableLib.h>
|
||||||
|
#include <Library/UefiLib.h>
|
||||||
|
#include <Library/DevicePathLib.h>
|
||||||
|
#include <Library/MemoryAllocationLib.h>
|
||||||
|
#include <Library/DebugLib.h>
|
||||||
|
#include <Library/BdsUnixLib.h>
|
||||||
|
|
||||||
|
#include <Guid/FileInfo.h>
|
||||||
|
|
||||||
|
#include <Protocol/DevicePath.h>
|
||||||
|
#include <Protocol/DevicePathFromText.h>
|
||||||
|
#include <Protocol/SimpleFileSystem.h>
|
||||||
|
#include <Protocol/FirmwareVolume2.h>
|
||||||
|
|
||||||
|
|
||||||
|
typedef enum { BDS_FILETYPE_MEM, BDS_FILETYPE_FS, BDS_FILETYPE_FV } BDS_FILE_TYPE;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
UINT32 MemoryType;
|
||||||
|
EFI_PHYSICAL_ADDRESS StartingAddress;
|
||||||
|
EFI_PHYSICAL_ADDRESS EndingAddress;
|
||||||
|
} BDS_MEM_FILE;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
EFI_FILE_PROTOCOL *Handle;
|
||||||
|
} BDS_FS_FILE;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
EFI_FIRMWARE_VOLUME2_PROTOCOL *FvProtocol;
|
||||||
|
EFI_FV_FILETYPE FileType;
|
||||||
|
EFI_GUID Guid;
|
||||||
|
} BDS_FV_FILE;
|
||||||
|
|
||||||
|
typedef struct _BDS_FILE {
|
||||||
|
CHAR16* FilePath;
|
||||||
|
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
|
||||||
|
BDS_FILE_TYPE Type;
|
||||||
|
union {
|
||||||
|
BDS_MEM_FILE Mem;
|
||||||
|
BDS_FS_FILE Fs;
|
||||||
|
BDS_FV_FILE Fv;
|
||||||
|
} File;
|
||||||
|
} BDS_FILE;
|
||||||
|
|
||||||
|
typedef struct _BDS_SYSTEM_MEMORY_RESOURCE {
|
||||||
|
LIST_ENTRY Link; // This attribute must be the first entry of this structure (to avoid pointer computation)
|
||||||
|
EFI_PHYSICAL_ADDRESS PhysicalStart;
|
||||||
|
UINT64 ResourceLength;
|
||||||
|
} BDS_SYSTEM_MEMORY_RESOURCE;
|
||||||
|
|
||||||
|
|
||||||
|
// BdsHelper.c
|
||||||
|
EFI_STATUS
|
||||||
|
ShutdownUefiBootServices( VOID );
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
GetSystemMemoryResources (LIST_ENTRY *ResourceList);
|
||||||
|
|
||||||
|
// BdsFilePath.c
|
||||||
|
EFI_STATUS BdsLoadDevicePath(
|
||||||
|
IN EFI_DEVICE_PATH_PROTOCOL* DevicePath,
|
||||||
|
OUT EFI_HANDLE *Handle
|
||||||
|
);
|
||||||
|
|
||||||
|
EFI_STATUS BdsLoadFilePath(
|
||||||
|
IN CONST CHAR16 *DeviceFilePath,
|
||||||
|
OUT BDS_FILE *File
|
||||||
|
);
|
||||||
|
|
||||||
|
EFI_STATUS BdsCopyRawFileToRuntimeMemory(
|
||||||
|
IN BDS_FILE *File,
|
||||||
|
OUT VOID **FileImage,
|
||||||
|
OUT UINTN *FileSize
|
||||||
|
);
|
||||||
|
|
||||||
|
// BdsFilePathFs.c
|
||||||
|
EFI_STATUS BdsLoadFileFromSimpleFileSystem(
|
||||||
|
IN EFI_HANDLE Handle,
|
||||||
|
IN CHAR16 *FilePath,
|
||||||
|
OUT BDS_FILE *File
|
||||||
|
);
|
||||||
|
|
||||||
|
EFI_STATUS BdsCopyRawFileToRuntimeMemoryFS(
|
||||||
|
IN EFI_FILE_PROTOCOL *File,
|
||||||
|
OUT VOID **FileImage,
|
||||||
|
OUT UINTN *FileSize
|
||||||
|
);
|
||||||
|
|
||||||
|
// BdsFilePathFv.c
|
||||||
|
EFI_STATUS BdsLoadFileFromFirmwareVolume(
|
||||||
|
IN EFI_HANDLE FvHandle,
|
||||||
|
IN CHAR16 *FilePath,
|
||||||
|
IN EFI_FV_FILETYPE FileTypeFilter,
|
||||||
|
OUT BDS_FILE *File
|
||||||
|
);
|
||||||
|
|
||||||
|
EFI_STATUS BdsCopyRawFileToRuntimeMemoryFV(
|
||||||
|
IN BDS_FV_FILE *FvFile,
|
||||||
|
OUT VOID **FileImage,
|
||||||
|
OUT UINTN *FileSize
|
||||||
|
);
|
||||||
|
|
||||||
|
// BdsFilePathMem.c
|
||||||
|
EFI_STATUS BdsLoadFileFromMemMap (
|
||||||
|
IN EFI_HANDLE Handle,
|
||||||
|
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
|
||||||
|
OUT BDS_FILE *File
|
||||||
|
);
|
||||||
|
|
||||||
|
EFI_STATUS BdsCopyRawFileToRuntimeMemoryMemMap(
|
||||||
|
IN BDS_MEM_FILE *MemFile,
|
||||||
|
OUT VOID **FileImage,
|
||||||
|
OUT UINTN *FileSize
|
||||||
|
);
|
||||||
|
|
||||||
|
#endif
|
63
ArmPkg/Library/BdsLib/BdsLib.inf
Normal file
63
ArmPkg/Library/BdsLib/BdsLib.inf
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
#/* @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 = BdsLib
|
||||||
|
FILE_GUID = ddbf73a0-bb25-11df-8e4e-0002a5d5c51b
|
||||||
|
MODULE_TYPE = UEFI_DRIVER
|
||||||
|
VERSION_STRING = 1.0
|
||||||
|
LIBRARY_CLASS = BdsLib
|
||||||
|
|
||||||
|
[Sources.common]
|
||||||
|
BdsFilePath.c
|
||||||
|
BdsFilePathFs.c
|
||||||
|
BdsFilePathFv.c
|
||||||
|
BdsFilePathMem.c
|
||||||
|
BdsLinuxLoader.c
|
||||||
|
BdsAppLoader.c
|
||||||
|
BdsHelper.c
|
||||||
|
|
||||||
|
[Packages]
|
||||||
|
MdePkg/MdePkg.dec
|
||||||
|
EmbeddedPkg/EmbeddedPkg.dec
|
||||||
|
ArmPkg/ArmPkg.dec
|
||||||
|
|
||||||
|
[LibraryClasses]
|
||||||
|
DevicePathLib
|
||||||
|
BaseLib
|
||||||
|
HobLib
|
||||||
|
DebugLib
|
||||||
|
UefiDriverEntryPoint
|
||||||
|
DxeServicesTableLib
|
||||||
|
ArmLib
|
||||||
|
|
||||||
|
[Guids]
|
||||||
|
gEfiFileInfoGuid
|
||||||
|
|
||||||
|
[Protocols]
|
||||||
|
gEfiBdsArchProtocolGuid
|
||||||
|
gEfiDevicePathProtocolGuid
|
||||||
|
gEfiDevicePathFromTextProtocolGuid
|
||||||
|
gEfiSimpleFileSystemProtocolGuid
|
||||||
|
gEfiFirmwareVolume2ProtocolGuid
|
||||||
|
|
||||||
|
[FeaturePcd]
|
||||||
|
|
||||||
|
[FixedPcd]
|
||||||
|
gArmTokenSpaceGuid.PcdArmMachineType
|
||||||
|
|
||||||
|
[Pcd]
|
||||||
|
|
||||||
|
[Depex]
|
||||||
|
TRUE
|
337
ArmPkg/Library/BdsLib/BdsLinuxLoader.c
Normal file
337
ArmPkg/Library/BdsLib/BdsLinuxLoader.c
Normal file
@ -0,0 +1,337 @@
|
|||||||
|
/** @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 "BdsInternal.h"
|
||||||
|
#include "BdsLinuxLoader.h"
|
||||||
|
|
||||||
|
#include <Library/PcdLib.h>
|
||||||
|
#include <Library/ArmLib.h>
|
||||||
|
#include <Library/HobLib.h>
|
||||||
|
|
||||||
|
STATIC
|
||||||
|
EFI_STATUS
|
||||||
|
GetARMLinuxMachineType (
|
||||||
|
IN BOOLEAN FdtSupported,
|
||||||
|
OUT UINT32 *MachineType
|
||||||
|
) {
|
||||||
|
if (FdtSupported)
|
||||||
|
{
|
||||||
|
// FDT requires that the machine type is set to the maximum 32-bit number.
|
||||||
|
*MachineType = 0xFFFFFFFF;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Non-FDT requires a specific machine type.
|
||||||
|
// This OS Boot loader supports just one machine type,
|
||||||
|
// but that could change in the future.
|
||||||
|
*MachineType = PcdGet32(PcdArmMachineType);
|
||||||
|
}
|
||||||
|
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC
|
||||||
|
VOID
|
||||||
|
SetupCoreTag( IN UINT32 PageSize )
|
||||||
|
{
|
||||||
|
Params->header.size = tag_size(atag_core);
|
||||||
|
Params->header.type = ATAG_CORE;
|
||||||
|
|
||||||
|
Params->body.core_tag.flags = 1; /* ensure read-only */
|
||||||
|
Params->body.core_tag.pagesize = PageSize; /* systems PageSize (4k) */
|
||||||
|
Params->body.core_tag.rootdev = 0; /* zero root device (typically overridden from kernel command line )*/
|
||||||
|
|
||||||
|
Params = next_tag_address(Params); /* move pointer to next tag */
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC
|
||||||
|
VOID
|
||||||
|
SetupMemTag( IN UINTN StartAddress, IN UINT32 Size )
|
||||||
|
{
|
||||||
|
Params->header.size = tag_size(atag_mem);
|
||||||
|
Params->header.type = ATAG_MEM;
|
||||||
|
|
||||||
|
Params->body.mem_tag.start = StartAddress; /* Start of memory chunk for AtagMem */
|
||||||
|
Params->body.mem_tag.size = Size; /* Size of memory chunk for AtagMem */
|
||||||
|
|
||||||
|
Params = next_tag_address(Params); /* move pointer to next tag */
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC
|
||||||
|
VOID
|
||||||
|
SetupCmdlineTag( IN CONST CHAR8 *CmdLine )
|
||||||
|
{
|
||||||
|
UINT32 LineLength;
|
||||||
|
|
||||||
|
// Increment the line length by 1 to account for the null string terminator character
|
||||||
|
LineLength = AsciiStrLen(CmdLine) + 1;
|
||||||
|
|
||||||
|
/* Check for NULL strings.
|
||||||
|
* Do not insert a tag for an empty CommandLine, don't even modify the tag address pointer.
|
||||||
|
* Remember, you have at least one null string terminator character.
|
||||||
|
*/
|
||||||
|
if( LineLength > 1 )
|
||||||
|
{
|
||||||
|
Params->header.size = ((UINT32)sizeof(struct atag_header) + LineLength + (UINT32)3) >> 2;
|
||||||
|
Params->header.type = ATAG_CMDLINE;
|
||||||
|
|
||||||
|
/* place CommandLine into tag */
|
||||||
|
AsciiStrCpy(Params->body.cmdline_tag.cmdline, CmdLine);
|
||||||
|
|
||||||
|
Params = next_tag_address(Params); /* move pointer to next tag */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC
|
||||||
|
VOID
|
||||||
|
SetupEndTag( VOID )
|
||||||
|
{
|
||||||
|
// Empty tag ends list; this has zero length and no body
|
||||||
|
Params->header.type = ATAG_NONE;
|
||||||
|
Params->header.size = 0;
|
||||||
|
|
||||||
|
/* We can not calculate the next address by using the standard macro:
|
||||||
|
* Params = next_tag_address(Params);
|
||||||
|
* because it relies on the header.size, which here it is 0 (zero).
|
||||||
|
* The easiest way is to add the sizeof(Params->header).
|
||||||
|
*/
|
||||||
|
Params = (struct atag *)((UINT32)Params + sizeof(Params->header));
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC
|
||||||
|
EFI_STATUS
|
||||||
|
PrepareAtagList(
|
||||||
|
IN OUT struct atag **AtagStartAddress,
|
||||||
|
IN CONST CHAR8* CommandLineString,
|
||||||
|
OUT UINT32 *AtagSize
|
||||||
|
) {
|
||||||
|
LIST_ENTRY *ResourceLink;
|
||||||
|
LIST_ENTRY ResourceList;
|
||||||
|
BDS_SYSTEM_MEMORY_RESOURCE *Resource;
|
||||||
|
|
||||||
|
// If no address supplied then this function will decide where to put it
|
||||||
|
if( *AtagStartAddress == 0 )
|
||||||
|
{
|
||||||
|
/* WARNING: At the time of writing (2010-July-30) the linux kernel expects
|
||||||
|
* the atag list it in the first 1MB of memory and preferably at address 0x100.
|
||||||
|
* This has a very high risk of overwriting UEFI code, but as
|
||||||
|
* the linux kernel does not expect any runtime services from uefi
|
||||||
|
* and there is no afterlife section following the linux kernel termination,
|
||||||
|
* it does not matter if we stamp over that memory area.
|
||||||
|
*
|
||||||
|
* The proposed workaround is to create the atag list somewhere in boot services memory
|
||||||
|
* and then transfer it to address 0x100 (or to runtime services memory) immediately
|
||||||
|
* before starting the kernel.
|
||||||
|
* An additional benefit of this is that when we copy the ATAG list to it's final place,
|
||||||
|
* we can trim down the memory allocation size. Before we create the list we don't know
|
||||||
|
* how much space it is going to take, so we are over-allocating space.
|
||||||
|
*/
|
||||||
|
*AtagStartAddress = (struct atag *) AllocatePool(ATAG_MAX_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure the pointer is not NULL.
|
||||||
|
ASSERT( *AtagStartAddress != (struct atag *)NULL );
|
||||||
|
|
||||||
|
// Ready to setup the atag list
|
||||||
|
Params = *AtagStartAddress;
|
||||||
|
|
||||||
|
// Standard core tag 4k PageSize
|
||||||
|
SetupCoreTag( (UINT32)SIZE_4KB );
|
||||||
|
|
||||||
|
// Physical memory setup
|
||||||
|
GetSystemMemoryResources(&ResourceList);
|
||||||
|
ResourceLink = ResourceList.ForwardLink;
|
||||||
|
while (ResourceLink != NULL && ResourceLink != &ResourceList) {
|
||||||
|
Resource = (BDS_SYSTEM_MEMORY_RESOURCE*)ResourceList.ForwardLink;
|
||||||
|
SetupMemTag( (UINT32)Resource->PhysicalStart, (UINT32)Resource->ResourceLength );
|
||||||
|
ResourceLink = ResourceLink->ForwardLink;
|
||||||
|
}
|
||||||
|
|
||||||
|
// CommandLine setting root device
|
||||||
|
SetupCmdlineTag( CommandLineString );
|
||||||
|
|
||||||
|
// end of tags
|
||||||
|
SetupEndTag();
|
||||||
|
|
||||||
|
// Calculate atag list size
|
||||||
|
*AtagSize = (UINT32)Params - (UINT32)*AtagStartAddress + 1;
|
||||||
|
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC
|
||||||
|
EFI_STATUS
|
||||||
|
PreparePlatformHardware( VOID )
|
||||||
|
{
|
||||||
|
//Note: Interrupts will be disabled by the GIC driver when ExitBootServices() will be called.
|
||||||
|
|
||||||
|
// clean, invalidate, disable data cache
|
||||||
|
ArmCleanInvalidateDataCache();
|
||||||
|
ArmDisableDataCache();
|
||||||
|
|
||||||
|
// Invalidate and disable the Instruction cache
|
||||||
|
ArmInvalidateInstructionCache ();
|
||||||
|
ArmDisableInstructionCache ();
|
||||||
|
|
||||||
|
// turn off MMU
|
||||||
|
ArmInvalidateTlb();
|
||||||
|
ArmDisableMmu();
|
||||||
|
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* R0, R1, R2 correspond to registers R0, R1, R2
|
||||||
|
*************************************************/
|
||||||
|
//STATIC
|
||||||
|
EFI_STATUS
|
||||||
|
StartLinuxKernel( IN VOID* KernelAddress, IN UINTN R0, IN UINTN R1, IN UINTN R2 )
|
||||||
|
{
|
||||||
|
VOID (*Kernel)(UINT32 Zero, UINT32 Arch, UINTN AtagListParams);
|
||||||
|
|
||||||
|
// set the kernel address
|
||||||
|
Kernel = (VOID (*)(UINT32, UINT32, UINTN)) KernelAddress;
|
||||||
|
|
||||||
|
// Outside BootServices, so can't use Print();
|
||||||
|
DEBUG((EFI_D_ERROR, "\nStarting the kernel:\n\n"));
|
||||||
|
|
||||||
|
// jump to kernel with register set
|
||||||
|
Kernel( R0, R1, R2 );
|
||||||
|
|
||||||
|
// Kernel should never exit
|
||||||
|
// After Life services are not provided
|
||||||
|
ASSERT( FALSE );
|
||||||
|
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
EFI_STATUS BdsBootLinux(
|
||||||
|
IN CONST CHAR16* LinuxKernel,
|
||||||
|
IN CONST CHAR8* ATag,
|
||||||
|
IN CONST CHAR16* Fdt
|
||||||
|
) {
|
||||||
|
BDS_FILE LinuxKernelFile;
|
||||||
|
BDS_FILE FdtFile;
|
||||||
|
EFI_STATUS Status;
|
||||||
|
VOID* LinuxImage;
|
||||||
|
|
||||||
|
UINT32 KernelParamsSize;
|
||||||
|
VOID* KernelParamsAddress = NULL;
|
||||||
|
UINTN KernelParamsNewAddress;
|
||||||
|
UINTN *AtagAddress;
|
||||||
|
UINT32 MachineType;
|
||||||
|
BOOLEAN FdtSupported = FALSE;
|
||||||
|
EFI_HOB_RESOURCE_DESCRIPTOR *ResHob;
|
||||||
|
|
||||||
|
// Load the Linux kernel from a device path
|
||||||
|
Status = BdsLoadFilePath(LinuxKernel, &LinuxKernelFile);
|
||||||
|
if (EFI_ERROR(Status)) {
|
||||||
|
DEBUG ((EFI_D_ERROR, "ERROR: Do not find Linux kernel %s\n",LinuxKernel));
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy the Linux Kernel from the raw file to Runtime memory
|
||||||
|
Status = BdsCopyRawFileToRuntimeMemory(&LinuxKernelFile,&LinuxImage,NULL);
|
||||||
|
if (EFI_ERROR(Status)) {
|
||||||
|
goto Exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load the FDT binary from a device path
|
||||||
|
Status = BdsLoadFilePath(Fdt, &FdtFile);
|
||||||
|
if (!EFI_ERROR(Status)) {
|
||||||
|
// Copy the FDT binary from the raw file to Runtime memory
|
||||||
|
Status = BdsCopyRawFileToRuntimeMemory(&FdtFile,&KernelParamsAddress,&KernelParamsSize);
|
||||||
|
if (EFI_ERROR(Status)) {
|
||||||
|
goto Exit;
|
||||||
|
} else {
|
||||||
|
FdtSupported = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**********************************************************
|
||||||
|
* Setup the platform type
|
||||||
|
**********************************************************/
|
||||||
|
Status = GetARMLinuxMachineType(FdtSupported, &MachineType);
|
||||||
|
if(EFI_ERROR(Status))
|
||||||
|
{
|
||||||
|
Print(L"ERROR : Can not prepare ARM Linux machine type. Status=0x%X\n", Status);
|
||||||
|
goto Exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!FdtSupported) {
|
||||||
|
/**********************************************************
|
||||||
|
* Setup the ATAG list
|
||||||
|
**********************************************************/
|
||||||
|
// By setting address=0 we leave the memory allocation to the function
|
||||||
|
AtagAddress = 0;
|
||||||
|
Status = PrepareAtagList( (struct atag **)&AtagAddress, ATag, &KernelParamsSize );
|
||||||
|
KernelParamsAddress = (VOID*)AtagAddress;
|
||||||
|
if(EFI_ERROR(Status))
|
||||||
|
{
|
||||||
|
Print(L"ERROR : Can not prepare ATAG list. Status=0x%X\n", Status);
|
||||||
|
goto Exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**********************************************************
|
||||||
|
* Switch off interrupts, caches, mmu, etc
|
||||||
|
**********************************************************/
|
||||||
|
Status = PreparePlatformHardware();
|
||||||
|
if(EFI_ERROR(Status))
|
||||||
|
{
|
||||||
|
Print(L"ERROR : Can not prepare platform hardware. Status=0x%X\n", Status);
|
||||||
|
goto Exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize the ATag destination
|
||||||
|
KernelParamsNewAddress = 0x100;
|
||||||
|
|
||||||
|
// Update the ATag destination by finding the start address of the first System Memory Resource Descriptor Hob
|
||||||
|
ResHob = (EFI_HOB_RESOURCE_DESCRIPTOR *)GetFirstHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR);
|
||||||
|
while (ResHob != NULL) {
|
||||||
|
if (ResHob->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) {
|
||||||
|
KernelParamsNewAddress = (UINTN)ResHob->PhysicalStart + 0x100;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
ResHob = (EFI_HOB_RESOURCE_DESCRIPTOR *)GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, (VOID *)((UINTN)ResHob + ResHob->Header.HobLength));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Shut down UEFI boot services. ExitBootServices() will notify every driver that created an event on
|
||||||
|
// ExitBootServices event. Example the Interrupt DXE driver will disable the interrupts on this event.
|
||||||
|
Status = ShutdownUefiBootServices();
|
||||||
|
if(EFI_ERROR(Status))
|
||||||
|
{
|
||||||
|
Print(L"ERROR : Can not shutdown UEFI boot services. Status=0x%X\n", Status);
|
||||||
|
goto Exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Move the kernel parameters to any address inside the first 1MB.
|
||||||
|
// This is necessary because the ARM Linux kernel requires
|
||||||
|
// the FTD / ATAG List to reside entirely inside the first 1MB of
|
||||||
|
// physical memory.
|
||||||
|
CopyMem((VOID*)KernelParamsNewAddress, KernelParamsAddress, KernelParamsSize);
|
||||||
|
|
||||||
|
//**********************************************************
|
||||||
|
// * Start the Linux Kernel
|
||||||
|
// **********************************************************
|
||||||
|
// Lift off ...
|
||||||
|
Status = StartLinuxKernel(LinuxImage, (UINTN)0, (UINTN)MachineType, KernelParamsNewAddress );
|
||||||
|
|
||||||
|
// Only be here if we fail to start Linux
|
||||||
|
DEBUG((EFI_D_ERROR, "ERROR : Can not start the kernel. Status=0x%X\n", Status));
|
||||||
|
|
||||||
|
Exit:
|
||||||
|
// Free Runtimee Memory (kernel and FDT)
|
||||||
|
return Status;
|
||||||
|
}
|
165
ArmPkg/Library/BdsLib/BdsLinuxLoader.h
Normal file
165
ArmPkg/Library/BdsLib/BdsLinuxLoader.h
Normal file
@ -0,0 +1,165 @@
|
|||||||
|
/** @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.
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
|
||||||
|
#ifndef __BDSLINUXLOADER_H
|
||||||
|
#define __BDSLINUXLOADER_H
|
||||||
|
|
||||||
|
#define ATAG_MAX_SIZE 0x4000
|
||||||
|
//PcdKernelParamsMaxMemorySize
|
||||||
|
|
||||||
|
/* ATAG : list of possible tags */
|
||||||
|
#define ATAG_NONE 0x00000000
|
||||||
|
#define ATAG_CORE 0x54410001
|
||||||
|
#define ATAG_MEM 0x54410002
|
||||||
|
#define ATAG_VIDEOTEXT 0x54410003
|
||||||
|
#define ATAG_RAMDISK 0x54410004
|
||||||
|
#define ATAG_INITRD2 0x54420005
|
||||||
|
#define ATAG_SERIAL 0x54410006
|
||||||
|
#define ATAG_REVISION 0x54410007
|
||||||
|
#define ATAG_VIDEOLFB 0x54410008
|
||||||
|
#define ATAG_CMDLINE 0x54410009
|
||||||
|
#define ATAG_ARM_MP_CORE 0x5441000A
|
||||||
|
|
||||||
|
// Some system addresses
|
||||||
|
// These should probably come from the platform header file or from pcd values
|
||||||
|
#define DRAM_BASE 0x10000000
|
||||||
|
#define ZIMAGE_LOAD_ADDRESS (DRAM_BASE + 0x8000)
|
||||||
|
#define INITRD_LOAD_ADDRESS (DRAM_BASE + 0x800000)
|
||||||
|
|
||||||
|
#define SIZE_1B 0x00000001
|
||||||
|
#define SIZE_2B 0x00000002
|
||||||
|
#define SIZE_4B 0x00000004
|
||||||
|
#define SIZE_8B 0x00000008
|
||||||
|
#define SIZE_16B 0x00000010
|
||||||
|
#define SIZE_32B 0x00000020
|
||||||
|
#define SIZE_64B 0x00000040
|
||||||
|
#define SIZE_128B 0x00000080
|
||||||
|
#define SIZE_256B 0x00000100
|
||||||
|
#define SIZE_512B 0x00000200
|
||||||
|
#define SIZE_1KB 0x00000400
|
||||||
|
#define SIZE_2KB 0x00000800
|
||||||
|
#define SIZE_4KB 0x00001000
|
||||||
|
#define SIZE_8KB 0x00002000
|
||||||
|
#define SIZE_16KB 0x00004000
|
||||||
|
#define SIZE_32KB 0x00008000
|
||||||
|
#define SIZE_64KB 0x00010000
|
||||||
|
#define SIZE_128KB 0x00020000
|
||||||
|
#define SIZE_256KB 0x00040000
|
||||||
|
#define SIZE_512KB 0x00080000
|
||||||
|
#define SIZE_1MB 0x00100000
|
||||||
|
#define SIZE_2MB 0x00200000
|
||||||
|
#define SIZE_4MB 0x00400000
|
||||||
|
#define SIZE_8MB 0x00800000
|
||||||
|
#define SIZE_16MB 0x01000000
|
||||||
|
#define SIZE_32MB 0x02000000
|
||||||
|
#define SIZE_64MB 0x04000000
|
||||||
|
#define SIZE_100MB 0x06400000
|
||||||
|
#define SIZE_128MB 0x08000000
|
||||||
|
#define SIZE_256MB 0x10000000
|
||||||
|
#define SIZE_512MB 0x20000000
|
||||||
|
#define SIZE_1GB 0x40000000
|
||||||
|
#define SIZE_2GB 0x80000000
|
||||||
|
|
||||||
|
/* structures for each atag */
|
||||||
|
struct atag_header {
|
||||||
|
UINT32 size; /* length of tag in words including this header */
|
||||||
|
UINT32 type; /* tag type */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct atag_core {
|
||||||
|
UINT32 flags;
|
||||||
|
UINT32 pagesize;
|
||||||
|
UINT32 rootdev;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct atag_mem {
|
||||||
|
UINT32 size;
|
||||||
|
UINTN start;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct atag_videotext {
|
||||||
|
UINT8 x;
|
||||||
|
UINT8 y;
|
||||||
|
UINT16 video_page;
|
||||||
|
UINT8 video_mode;
|
||||||
|
UINT8 video_cols;
|
||||||
|
UINT16 video_ega_bx;
|
||||||
|
UINT8 video_lines;
|
||||||
|
UINT8 video_isvga;
|
||||||
|
UINT16 video_points;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct atag_ramdisk {
|
||||||
|
UINT32 flags;
|
||||||
|
UINT32 size;
|
||||||
|
UINTN start;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct atag_initrd2 {
|
||||||
|
UINT32 start;
|
||||||
|
UINT32 size;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct atag_serialnr {
|
||||||
|
UINT32 low;
|
||||||
|
UINT32 high;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct atag_revision {
|
||||||
|
UINT32 rev;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct atag_videolfb {
|
||||||
|
UINT16 lfb_width;
|
||||||
|
UINT16 lfb_height;
|
||||||
|
UINT16 lfb_depth;
|
||||||
|
UINT16 lfb_linelength;
|
||||||
|
UINT32 lfb_base;
|
||||||
|
UINT32 lfb_size;
|
||||||
|
UINT8 red_size;
|
||||||
|
UINT8 red_pos;
|
||||||
|
UINT8 green_size;
|
||||||
|
UINT8 green_pos;
|
||||||
|
UINT8 blue_size;
|
||||||
|
UINT8 blue_pos;
|
||||||
|
UINT8 rsvd_size;
|
||||||
|
UINT8 rsvd_pos;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct atag_cmdline {
|
||||||
|
CHAR8 cmdline[1];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct atag {
|
||||||
|
struct atag_header header;
|
||||||
|
union {
|
||||||
|
struct atag_core core_tag;
|
||||||
|
struct atag_mem mem_tag;
|
||||||
|
struct atag_videotext videotext_tag;
|
||||||
|
struct atag_ramdisk ramdisk_tag;
|
||||||
|
struct atag_initrd2 initrd2_tag;
|
||||||
|
struct atag_serialnr serialnr_tag;
|
||||||
|
struct atag_revision revision_tag;
|
||||||
|
struct atag_videolfb videolfb_tag;
|
||||||
|
struct atag_cmdline cmdline_tag;
|
||||||
|
} body;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define next_tag_address(t) ((struct atag *)((UINT32)(t) + (((t)->header.size) << 2) ))
|
||||||
|
#define tag_size(type) ((UINT32)((sizeof(struct atag_header) + sizeof(struct type)) >> 2))
|
||||||
|
|
||||||
|
STATIC struct atag *Params; /* used to point at the current tag */
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -14,8 +14,7 @@
|
|||||||
|
|
||||||
.text
|
.text
|
||||||
.align 2
|
.align 2
|
||||||
.globl ASM_PFX(__ashldi3)
|
GCC_ASM_EXPORT(__ashldi3)
|
||||||
INTERWORK_FUNC(__ashldi3)
|
|
||||||
|
|
||||||
ASM_PFX(__ashldi3):
|
ASM_PFX(__ashldi3):
|
||||||
cmp r2, #31
|
cmp r2, #31
|
||||||
|
@ -14,8 +14,7 @@
|
|||||||
|
|
||||||
.text
|
.text
|
||||||
.align 2
|
.align 2
|
||||||
.globl ASM_PFX(__ashrdi3)
|
GCC_ASM_EXPORT(__ashrdi3)
|
||||||
INTERWORK_FUNC(__ashrdi3)
|
|
||||||
|
|
||||||
ASM_PFX(__ashrdi3):
|
ASM_PFX(__ashrdi3):
|
||||||
cmp r2, #31
|
cmp r2, #31
|
||||||
|
@ -14,8 +14,7 @@
|
|||||||
|
|
||||||
.text
|
.text
|
||||||
.align 2
|
.align 2
|
||||||
.globl ASM_PFX(__clzsi2)
|
GCC_ASM_EXPORT(__clzsi2)
|
||||||
INTERWORK_FUNC(__clzsi2)
|
|
||||||
|
|
||||||
ASM_PFX(__clzsi2):
|
ASM_PFX(__clzsi2):
|
||||||
@ frame_needed = 1, uses_anonymous_args = 0
|
@ frame_needed = 1, uses_anonymous_args = 0
|
||||||
|
@ -14,8 +14,7 @@
|
|||||||
|
|
||||||
.text
|
.text
|
||||||
.align 2
|
.align 2
|
||||||
.globl ASM_PFX(__ctzsi2)
|
GCC_ASM_EXPORT(__ctzsi2)
|
||||||
INTERWORK_FUNC(__ctzsi2)
|
|
||||||
|
|
||||||
ASM_PFX(__ctzsi2):
|
ASM_PFX(__ctzsi2):
|
||||||
uxth r3, r0
|
uxth r3, r0
|
||||||
|
@ -14,8 +14,7 @@
|
|||||||
|
|
||||||
.text
|
.text
|
||||||
.align 2
|
.align 2
|
||||||
.globl ASM_PFX(__divdi3)
|
GCC_ASM_EXPORT(__divdi3)
|
||||||
INTERWORK_FUNC(__divdi3)
|
|
||||||
|
|
||||||
ASM_PFX(__divdi3):
|
ASM_PFX(__divdi3):
|
||||||
@ args = 0, pretend = 0, frame = 0
|
@ args = 0, pretend = 0, frame = 0
|
||||||
|
@ -14,8 +14,7 @@
|
|||||||
|
|
||||||
.text
|
.text
|
||||||
.align 2
|
.align 2
|
||||||
.globl ASM_PFX(__divsi3)
|
GCC_ASM_EXPORT(__divsi3)
|
||||||
INTERWORK_FUNC(__divsi3)
|
|
||||||
|
|
||||||
ASM_PFX(__divsi3):
|
ASM_PFX(__divsi3):
|
||||||
eor r3, r0, r0, asr #31
|
eor r3, r0, r0, asr #31
|
||||||
|
@ -15,8 +15,7 @@
|
|||||||
|
|
||||||
.text
|
.text
|
||||||
.align 2
|
.align 2
|
||||||
.globl ASM_PFX(__aeabi_ldivmod)
|
GCC_ASM_EXPORT(__aeabi_ldivmod)
|
||||||
INTERWORK_FUNC(__aeabi_ldivmod)
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// A pair of (unsigned) long longs is returned in {{r0, r1}, {r2, r3}},
|
// A pair of (unsigned) long longs is returned in {{r0, r1}, {r2, r3}},
|
||||||
|
@ -14,8 +14,7 @@
|
|||||||
|
|
||||||
.text
|
.text
|
||||||
.align 2
|
.align 2
|
||||||
.globl ASM_PFX(__lshrdi3)
|
GCC_ASM_EXPORT(__lshrdi3)
|
||||||
INTERWORK_FUNC(__lshrdi3)
|
|
||||||
|
|
||||||
ASM_PFX(__lshrdi3):
|
ASM_PFX(__lshrdi3):
|
||||||
cmp r2, #31
|
cmp r2, #31
|
||||||
|
@ -14,8 +14,7 @@
|
|||||||
|
|
||||||
.text
|
.text
|
||||||
.align 2
|
.align 2
|
||||||
.globl ASM_PFX(memcpy)
|
GCC_ASM_EXPORT(memcpy)
|
||||||
INTERWORK_FUNC(memcpy)
|
|
||||||
|
|
||||||
ASM_PFX(memcpy):
|
ASM_PFX(memcpy):
|
||||||
stmfd sp!, {r7, lr}
|
stmfd sp!, {r7, lr}
|
||||||
|
@ -15,8 +15,7 @@
|
|||||||
|
|
||||||
.text
|
.text
|
||||||
.align 2
|
.align 2
|
||||||
.globl ASM_PFX(memset)
|
GCC_ASM_EXPORT (memset)
|
||||||
INTERWORK_FUNC(memset)
|
|
||||||
|
|
||||||
ASM_PFX(memset):
|
ASM_PFX(memset):
|
||||||
@ args = 0, pretend = 0, frame = 0
|
@ args = 0, pretend = 0, frame = 0
|
||||||
|
@ -14,8 +14,7 @@
|
|||||||
|
|
||||||
.text
|
.text
|
||||||
.align 2
|
.align 2
|
||||||
.globl ASM_PFX(__moddi3)
|
GCC_ASM_EXPORT(__moddi3)
|
||||||
INTERWORK_FUNC(__moddi3)
|
|
||||||
|
|
||||||
ASM_PFX(__moddi3):
|
ASM_PFX(__moddi3):
|
||||||
stmfd sp!, {r4, r5, r7, lr}
|
stmfd sp!, {r4, r5, r7, lr}
|
||||||
|
@ -14,8 +14,7 @@
|
|||||||
|
|
||||||
.text
|
.text
|
||||||
.align 2
|
.align 2
|
||||||
.globl ASM_PFX(__modsi3)
|
GCC_ASM_EXPORT(__modsi3)
|
||||||
INTERWORK_FUNC(__modsi3)
|
|
||||||
|
|
||||||
ASM_PFX(__modsi3):
|
ASM_PFX(__modsi3):
|
||||||
stmfd sp!, {r4, r5, r7, lr}
|
stmfd sp!, {r4, r5, r7, lr}
|
||||||
|
@ -14,8 +14,7 @@
|
|||||||
|
|
||||||
.text
|
.text
|
||||||
.align 2
|
.align 2
|
||||||
.globl ASM_PFX(__muldi3)
|
GCC_ASM_EXPORT(__muldi3)
|
||||||
INTERWORK_FUNC(__muldi3)
|
|
||||||
|
|
||||||
ASM_PFX(__muldi3):
|
ASM_PFX(__muldi3):
|
||||||
stmfd sp!, {r4, r5, r6, r7, lr}
|
stmfd sp!, {r4, r5, r6, r7, lr}
|
||||||
|
@ -15,8 +15,7 @@
|
|||||||
|
|
||||||
.text
|
.text
|
||||||
.align 2
|
.align 2
|
||||||
.globl ASM_PFX(__aeabi_ulcmp)
|
GCC_ASM_EXPORT(__aeabi_ulcmp)
|
||||||
INTERWORK_FUNC(__aeabi_ulcmp)
|
|
||||||
|
|
||||||
ASM_PFX(__aeabi_ulcmp):
|
ASM_PFX(__aeabi_ulcmp):
|
||||||
stmfd sp!, {r4, r5, r8}
|
stmfd sp!, {r4, r5, r8}
|
||||||
|
@ -16,8 +16,7 @@
|
|||||||
.text
|
.text
|
||||||
.p2align 2
|
.p2align 2
|
||||||
|
|
||||||
.globl ASM_PFX(__switch16)
|
GCC_ASM_EXPORT(__switch16)
|
||||||
INTERWORK_FUNC(__switch16)
|
|
||||||
|
|
||||||
ASM_PFX(__switch16):
|
ASM_PFX(__switch16):
|
||||||
ldrh ip, [lr, #-1]
|
ldrh ip, [lr, #-1]
|
||||||
|
@ -16,8 +16,7 @@
|
|||||||
.text
|
.text
|
||||||
.p2align 2
|
.p2align 2
|
||||||
|
|
||||||
.globl ASM_PFX(__switch32)
|
GCC_ASM_EXPORT(__switch32)
|
||||||
INTERWORK_FUNC(__switch32)
|
|
||||||
|
|
||||||
ASM_PFX(__switch32):
|
ASM_PFX(__switch32):
|
||||||
ldr ip, [lr, #-1]
|
ldr ip, [lr, #-1]
|
||||||
|
@ -16,9 +16,7 @@
|
|||||||
.text
|
.text
|
||||||
.p2align 2
|
.p2align 2
|
||||||
|
|
||||||
.globl ASM_PFX(__switch8)
|
GCC_ASM_EXPORT(__switch8)
|
||||||
INTERWORK_FUNC(__switch8)
|
|
||||||
|
|
||||||
|
|
||||||
ASM_PFX(__switch8):
|
ASM_PFX(__switch8):
|
||||||
ldrb ip, [lr, #-1]
|
ldrb ip, [lr, #-1]
|
||||||
|
@ -16,8 +16,7 @@
|
|||||||
.text
|
.text
|
||||||
.p2align 2
|
.p2align 2
|
||||||
|
|
||||||
.globl ASM_PFX(__switchu8)
|
GCC_ASM_EXPORT(__switchu8)
|
||||||
INTERWORK_FUNC(__switchu8)
|
|
||||||
|
|
||||||
|
|
||||||
ASM_PFX(__switchu8):
|
ASM_PFX(__switchu8):
|
||||||
|
@ -14,8 +14,7 @@
|
|||||||
|
|
||||||
.text
|
.text
|
||||||
.align 2
|
.align 2
|
||||||
.globl ASM_PFX(__ucmpdi2)
|
GCC_ASM_EXPORT(__ucmpdi2)
|
||||||
INTERWORK_FUNC(__ucmpdi2)
|
|
||||||
|
|
||||||
ASM_PFX(__ucmpdi2):
|
ASM_PFX(__ucmpdi2):
|
||||||
stmfd sp!, {r4, r5, r8, lr}
|
stmfd sp!, {r4, r5, r8, lr}
|
||||||
|
@ -14,8 +14,7 @@
|
|||||||
|
|
||||||
.text
|
.text
|
||||||
.align 2
|
.align 2
|
||||||
.globl ASM_PFX(__udivdi3)
|
GCC_ASM_EXPORT(__udivdi3)
|
||||||
INTERWORK_FUNC(__udivdi3)
|
|
||||||
|
|
||||||
ASM_PFX(__udivdi3):
|
ASM_PFX(__udivdi3):
|
||||||
stmfd sp!, {r7, lr}
|
stmfd sp!, {r7, lr}
|
||||||
|
@ -14,8 +14,7 @@
|
|||||||
|
|
||||||
.text
|
.text
|
||||||
.align 2
|
.align 2
|
||||||
.globl ASM_PFX(__udivmoddi4)
|
GCC_ASM_EXPORT(__udivmoddi4)
|
||||||
INTERWORK_FUNC(__udivmoddi4)
|
|
||||||
|
|
||||||
ASM_PFX(__udivmoddi4):
|
ASM_PFX(__udivmoddi4):
|
||||||
stmfd sp!, {r4, r5, r6, r7, lr}
|
stmfd sp!, {r4, r5, r6, r7, lr}
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user