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:
andrewfish 2011-02-02 22:35:30 +00:00
parent 7373d15a98
commit 1bfda055df
113 changed files with 7979 additions and 964 deletions

View File

@ -44,11 +44,76 @@
[Protocols.common]
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]
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]
# 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.PcdArmCacheOperationThreshold|1024|UINT32|0x00000003
gArmTokenSpaceGuid.PcdCpuVectorBaseAddress|0xfff00000|UINT32|0x00000004
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

View File

@ -67,6 +67,24 @@
CpuLib|MdePkg/Library/BaseCpuLib/BaseCpuLib.inf
ArmDisassemblerLib|ArmPkg/Library/ArmDisassemblerLib/ArmDisassemblerLib.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]
NULL|ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf
@ -74,22 +92,47 @@
[Components.common]
ArmPkg/Library/ArmCacheMaintenanceLib/ArmCacheMaintenanceLib.inf
## ArmPkg/Library/ArmLib/Arm11/Arm11ArmLib.inf
## ArmPkg/Library/ArmLib/Arm11/Arm11ArmLibPrePi.inf
## ArmPkg/Library/ArmLib/Arm9/Arm9ArmLib.inf
## ArmPkg/Library/ArmLib/Arm9/Arm9ArmLibPrePi.inf
ArmPkg/Library/ArmDisassemblerLib/ArmDisassemblerLib.inf
ArmPkg/Library/ArmDmaLib/ArmDmaLib.inf
ArmPkg/Library/ArmLib/Arm11/Arm11ArmLib.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/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/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/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/SemiHostingSerialPortLib/SemiHostingSerialPortLib.inf
ArmPkg/Library/SemihostLib/SemihostLib.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/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/Universal/MmcDxe/MmcDxe.inf

View File

@ -67,10 +67,13 @@
gEfiDebugImageInfoTableGuid
[Pcd.common]
gArmTokenSpaceGuid.PcdVFPEnabled
gArmTokenSpaceGuid.PcdCpuVectorBaseAddress
[FeaturePcd.common]
gArmTokenSpaceGuid.PcdCpuDxeProduceDebugSupport
gArmTokenSpaceGuid.PcdRelocateVectorTable
gArmTokenSpaceGuid.PcdEfiUncachedMemoryToStronglyOrdered
[depex]
gHardwareInterruptProtocolGuid

View File

@ -14,6 +14,8 @@
#include "CpuDxe.h"
//FIXME: Will not compile on non-ARMv7 builds
#include <Chipset/ArmV7.h>
VOID
ExceptionHandlersStart (
@ -127,6 +129,7 @@ InitializeExceptions (
EFI_PHYSICAL_ADDRESS Base;
UINT32 *VectorBase;
Status = EFI_SUCCESS;
//
// Disable interrupts
//
@ -140,54 +143,63 @@ InitializeExceptions (
FiqEnabled = ArmGetFiqState ();
ArmDisableFiq ();
//
// Copy an implementation of the ARM exception vectors to PcdCpuVectorBaseAddress.
//
Length = (UINTN)ExceptionHandlersEnd - (UINTN)ExceptionHandlersStart;
if (FeaturePcdGet(PcdRelocateVectorTable) == TRUE) {
//
// Copy an implementation of the ARM exception vectors to PcdCpuVectorBaseAddress.
//
Length = (UINTN)ExceptionHandlersEnd - (UINTN)ExceptionHandlersStart;
//
// Reserve space for the exception handlers
//
Base = (EFI_PHYSICAL_ADDRESS)PcdGet32 (PcdCpuVectorBaseAddress);
VectorBase = (UINT32 *)(UINTN)Base;
Status = gBS->AllocatePages (AllocateAddress, EfiBootServicesCode, EFI_SIZE_TO_PAGES (Length), &Base);
// If the request was for memory that's not in the memory map (which is often the case for 0x00000000
// on embedded systems, for example, we don't want to hang up. So we'll check here for a status of
// EFI_NOT_FOUND, and continue in that case.
if (EFI_ERROR(Status) && (Status != EFI_NOT_FOUND)) {
ASSERT_EFI_ERROR (Status);
}
// Save existing vector table, in case debugger is already hooked in
CopyMem ((VOID *)gDebuggerExceptionHandlers, (VOID *)VectorBase, sizeof (gDebuggerExceptionHandlers));
// Copy our assembly code into the page that contains the exception vectors.
CopyMem ((VOID *)VectorBase, (VOID *)ExceptionHandlersStart, Length);
//
// Patch in the common Assembly exception handler
//
Offset = (UINTN)CommonExceptionEntry - (UINTN)ExceptionHandlersStart;
*(UINTN *) ((UINT8 *)(UINTN)PcdGet32 (PcdCpuVectorBaseAddress) + Offset) = (UINTN)AsmCommonExceptionEntry;
//
// Initialize the C entry points for interrupts
//
for (Index = 0; Index <= MAX_ARM_EXCEPTION; Index++) {
if ((gDebuggerExceptionHandlers[Index] == 0) || (gDebuggerExceptionHandlers[Index] == (VOID *)(UINTN)0xEAFFFFFE)) {
// Exception handler contains branch to vector location (jmp $) so no handler
// NOTE: This code assumes vectors are ARM and not Thumb code
Status = RegisterInterruptHandler (Index, NULL);
ASSERT_EFI_ERROR (Status);
} else {
// If the debugger has alread hooked put its vector back
VectorBase[Index] = (UINT32)(UINTN)gDebuggerExceptionHandlers[Index];
}
}
// Flush Caches since we updated executable stuff
InvalidateInstructionCacheRange ((VOID *)PcdGet32(PcdCpuVectorBaseAddress), Length);
//
// Reserve space for the exception handlers
//
Base = (EFI_PHYSICAL_ADDRESS)PcdGet32 (PcdCpuVectorBaseAddress);
VectorBase = (UINT32 *)(UINTN)Base;
Status = gBS->AllocatePages (AllocateAddress, EfiBootServicesCode, EFI_SIZE_TO_PAGES (Length), &Base);
// If the request was for memory that's not in the memory map (which is often the case for 0x00000000
// on embedded systems, for example, we don't want to hang up. So we'll check here for a status of
// EFI_NOT_FOUND, and continue in that case.
if (EFI_ERROR(Status) && (Status != EFI_NOT_FOUND)) {
ASSERT_EFI_ERROR (Status);
//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);
}
// Save existing vector table, in case debugger is already hooked in
CopyMem ((VOID *)gDebuggerExceptionHandlers, (VOID *)VectorBase, sizeof (gDebuggerExceptionHandlers));
// Copy our assembly code into the page that contains the exception vectors.
CopyMem ((VOID *)VectorBase, (VOID *)ExceptionHandlersStart, Length);
//
// Patch in the common Assembly exception handler
//
Offset = (UINTN)CommonExceptionEntry - (UINTN)ExceptionHandlersStart;
*(UINTN *) ((UINT8 *)(UINTN)PcdGet32 (PcdCpuVectorBaseAddress) + Offset) = (UINTN)AsmCommonExceptionEntry;
//
// Initialize the C entry points for interrupts
//
for (Index = 0; Index <= MAX_ARM_EXCEPTION; Index++) {
if ((gDebuggerExceptionHandlers[Index] == 0) || (gDebuggerExceptionHandlers[Index] == (VOID *)(UINTN)0xEAFFFFFE)) {
// Exception handler contains branch to vector location (jmp $) so no handler
// NOTE: This code assumes vectors are ARM and not Thumb code
Status = RegisterInterruptHandler (Index, NULL);
ASSERT_EFI_ERROR (Status);
} else {
// If the debugger has alread hooked put its vector back
VectorBase[Index] = (UINT32)(UINTN)gDebuggerExceptionHandlers[Index];
}
}
// Flush Caches since we updated executable stuff
InvalidateInstructionCacheRange ((VOID *)PcdGet32(PcdCpuVectorBaseAddress), Length);
if (FiqEnabled) {
ArmEnableFiq ();
}

View File

@ -14,6 +14,8 @@
#
#------------------------------------------------------------------------------
#include <Library/PcdLib.h>
/*
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)
INTERWORK_FUNC(ExceptionHandlersStart)
.globl ASM_PFX(ExceptionHandlersEnd)
INTERWORK_FUNC(ExceptionHandlersEnd)
.globl ASM_PFX(CommonExceptionEntry)
INTERWORK_FUNC(CommonExceptionEntry)
.globl ASM_PFX(AsmCommonExceptionEntry)
INTERWORK_FUNC(AsmCommonExceptionEntry)
.globl ASM_PFX(CommonCExceptionHandler)
INTERWORK_FUNC(CommonCExceptionHandler)
GCC_ASM_EXPORT(ExceptionHandlersStart)
GCC_ASM_EXPORT(ExceptionHandlersEnd)
GCC_ASM_EXPORT(CommonExceptionEntry)
GCC_ASM_EXPORT(AsmCommonExceptionEntry)
GCC_ASM_EXPORT(CommonCExceptionHandler)
.text
#if !defined(__APPLE__)
.fpu neon @ makes vpush/vpop assemble
#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
//
ASM_PFX(CommonExceptionEntry):
.byte 0x12
.byte 0x34
.byte 0x56
.byte 0x78
.word ASM_PFX(AsmCommonExceptionEntry)
ASM_PFX(ExceptionHandlersEnd):
@ -254,8 +248,9 @@ NoAdjustNeeded:
@ R0 is ExceptionType
mov R1,SP @ R1 is SystemContext
#if (FixedPcdGet32(PcdVFPEnabled))
vpush {d0-d15} @ save vstm registers in case they are used in optimizations
#endif
/*
VOID
@ -268,7 +263,9 @@ CommonCExceptionHandler (
*/
blx ASM_PFX(CommonCExceptionHandler) @ Call exception handler
#if (FixedPcdGet32(PcdVFPEnabled))
vpop {d0-d15}
#endif
ldr R1, [SP, #0x4c] @ Restore EFI_SYSTEM_CONTEXT_ARM.IFSR
mcr p15, 0, R1, c5, c0, 1 @ Write IFSR

View File

@ -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
AREA DxeExceptionHandlers, CODE, READONLY
ALIGN 32
//
// This code gets copied to the ARM vector table
// ExceptionHandlersStart - ExceptionHandlersEnd gets copied
@ -190,7 +192,7 @@ FiqEntry
// This gets patched by the C code that patches in the vector table
//
CommonExceptionEntry
dcd 0x12345678
dcd AsmCommonExceptionEntry
ExceptionHandlersEnd
@ -243,7 +245,9 @@ NoAdjustNeeded
; R0 is ExceptionType
mov R1,SP ; R1 is SystemContext
#if (FixedPcdGet32(PcdVFPEnabled))
vpush {d0-d15} ; save vstm registers in case they are used in optimizations
#endif
/*
VOID
@ -256,7 +260,9 @@ CommonCExceptionHandler (
*/
blx CommonCExceptionHandler ; Call exception handler
#if (FixedPcdGet32(PcdVFPEnabled))
vpop {d0-d15}
#endif
ldr R1, [SP, #0x4c] ; Restore EFI_SYSTEM_CONTEXT_ARM.IFSR
mcr p15, 0, R1, c5, c0, 1 ; Write IFSR

View File

@ -15,11 +15,11 @@
.text
.align 3
.globl ASM_PFX(ExceptionHandlersStart)
.globl ASM_PFX(ExceptionHandlersEnd)
.globl ASM_PFX(CommonExceptionEntry)
.globl ASM_PFX(AsmCommonExceptionEntry)
.globl ASM_PFX(CommonCExceptionHandler)
GCC_ASM_EXPORT(ExceptionHandlersStart)
GCC_ASM_EXPORT(ExceptionHandlersEnd)
GCC_ASM_EXPORT(CommonExceptionEntry)
GCC_ASM_EXPORT(AsmCommonExceptionEntry)
GCC_ASM_EXPORT(CommonCExceptionHandler)
ASM_PFX(ExceptionHandlersStart):

View File

@ -15,129 +15,15 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
--*/
#include "CpuDxe.h"
//
// Translation/page table definitions
//
//FIXME: Remove this ARMv7 specific header
#include <Chipset/ArmV7.h>
// First Level Descriptors
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
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
SectionToGcdAttributes (
IN UINT32 SectionAttributes,
@ -147,47 +33,46 @@ SectionToGcdAttributes (
*GcdAttributes = 0;
// determine cacheability attributes
switch(SectionAttributes & ARM_SECTION_CACHEABILITY_MASK) {
case ARM_SECTION_STRONGLY_ORDERED:
switch(SectionAttributes & TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK) {
case TT_DESCRIPTOR_SECTION_CACHE_POLICY_STRONGLY_ORDERED:
*GcdAttributes |= EFI_MEMORY_UC;
break;
case ARM_SECTION_SHAREABLE_DEVICE:
case TT_DESCRIPTOR_SECTION_CACHE_POLICY_SHAREABLE_DEVICE:
*GcdAttributes |= EFI_MEMORY_UC;
break;
case ARM_SECTION_WRITE_THROUGH:
case TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_THROUGH_NO_ALLOC:
*GcdAttributes |= EFI_MEMORY_WT;
break;
case ARM_SECTION_WRITE_BACK_NWA:
case TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_BACK_NO_ALLOC:
*GcdAttributes |= EFI_MEMORY_WB;
break;
case ARM_SECTION_NORMAL_UNCACHEABLE:
case TT_DESCRIPTOR_SECTION_CACHE_POLICY_NON_CACHEABLE:
*GcdAttributes |= EFI_MEMORY_WC;
break;
case ARM_SECTION_WRITE_BACK:
case TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_BACK_ALLOC:
*GcdAttributes |= EFI_MEMORY_WB;
break;
case ARM_SECTION_NONSHAREABLE_DEVICE:
case TT_DESCRIPTOR_SECTION_CACHE_POLICY_NON_SHAREABLE_DEVICE:
*GcdAttributes |= EFI_MEMORY_UC;
break;
default:
return EFI_UNSUPPORTED;
}
// determine protection attributes
switch(SectionAttributes & ARM_SECTION_RW_PERMISSIONS_MASK) {
case ARM_SECTION_NO_ACCESS: // no read, no write
switch(SectionAttributes & TT_DESCRIPTOR_SECTION_AP_MASK) {
case TT_DESCRIPTOR_SECTION_AP_NO_NO: // no read, no write
//*GcdAttributes |= EFI_MEMORY_WP | EFI_MEMORY_RP;
break;
case ARM_SECTION_PRIV_ACCESS_ONLY:
case ARM_SECTION_FULL_ACCESS:
case TT_DESCRIPTOR_SECTION_AP_RW_NO:
case TT_DESCRIPTOR_SECTION_AP_RW_RW:
// normal read/write access, do not add additional attributes
break;
// read only cases map to write-protect
case ARM_SECTION_PRIV_READ_ONLY:
case ARM_SECTION_READ_ONLY_DEP:
case ARM_SECTION_READ_ONLY:
case TT_DESCRIPTOR_SECTION_AP_RO_NO:
case TT_DESCRIPTOR_SECTION_AP_RO_RO:
*GcdAttributes |= EFI_MEMORY_WP;
break;
@ -196,7 +81,7 @@ SectionToGcdAttributes (
}
// now process eXectue Never attribute
if ((SectionAttributes & ARM_SECTION_XN) != 0 ) {
if ((SectionAttributes & TT_DESCRIPTOR_SECTION_XN_MASK) != 0 ) {
*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.
// obtain page table base
FirstLevelTable = (ARM_FIRST_LEVEL_DESCRIPTOR *)(ArmGetTranslationTableBaseAddress ());
FirstLevelTable = (ARM_FIRST_LEVEL_DESCRIPTOR *)(ArmGetTTBR0BaseAddress ());
// iterate through each 1MB descriptor
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
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)
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)?
// 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
if (SectionAttributes != NextRegionAttributes) {
@ -398,7 +283,7 @@ SyncCacheConfig (
// start on a new region
NextRegionLength = 0;
NextRegionBase = Descriptor & ARM_SECTION_BASE_MASK;
NextRegionBase = TT_DESCRIPTOR_SECTION_BASE_ADDRESS(Descriptor);
}
}
@ -407,7 +292,7 @@ SyncCacheConfig (
NextRegionAttributes = SectionAttributes;
}
NextRegionLength += ARM_PAGE_DESC_ENTRY_MVA_SIZE;
NextRegionLength += TT_DESCRIPTOR_SECTION_SIZE;
} // section entry loop
@ -444,37 +329,42 @@ UpdatePageEntries (
// EntryMask: bitmask of values to change (1 = change this value, 0 = leave alone)
// EntryValue: values at bit positions specified by EntryMask
EntryMask = ARM_PAGE_DESC_TYPE_MASK;
EntryValue = ARM_PAGE_TYPE_SMALL;
EntryMask = TT_DESCRIPTOR_PAGE_TYPE_MASK;
EntryValue = TT_DESCRIPTOR_PAGE_TYPE_PAGE;
// 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
switch (Attributes) {
case EFI_MEMORY_UC:
// modify cacheability attributes
EntryMask |= ARM_SMALL_PAGE_TEX_MASK | ARM_PAGE_C | ARM_PAGE_B;
// map to strongly ordered
EntryValue |= 0; // TEX[2:0] = 0, C=0, B=0
EntryMask |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_MASK;
if (FeaturePcdGet(PcdEfiUncachedMemoryToStronglyOrdered)) {
// map to strongly ordered
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;
case EFI_MEMORY_WC:
// 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
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;
case EFI_MEMORY_WT:
// 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
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;
case EFI_MEMORY_WB:
// 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)
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;
case EFI_MEMORY_WP:
@ -482,7 +372,7 @@ UpdatePageEntries (
case EFI_MEMORY_UCE:
// cannot be implemented UEFI definition unclear for ARM
// 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));
break;
@ -491,7 +381,7 @@ UpdatePageEntries (
}
// 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
NumPageEntries = Length/SIZE_4KB;
@ -501,15 +391,15 @@ UpdatePageEntries (
for(p=0; p<NumPageEntries; p++) {
// calculate index into first level translation table for page table value
FirstLevelIdx = ((BaseAddress + Offset) & ARM_SECTION_BASE_MASK) >> ARM_SECTION_BASE_SHIFT;
ASSERT (FirstLevelIdx < FIRST_LEVEL_ENTRY_COUNT);
FirstLevelIdx = TT_DESCRIPTOR_SECTION_BASE_ADDRESS(BaseAddress + Offset) >> TT_DESCRIPTOR_SECTION_BASE_SHIFT;
ASSERT (FirstLevelIdx < TRANSLATION_TABLE_SECTION_COUNT);
// read the descriptor from the first level page table
Descriptor = FirstLevelTable[FirstLevelIdx];
// does this descriptor need to be converted from section entry to 4K pages?
if ((Descriptor & ARM_DESC_TYPE_MASK) != ARM_DESC_TYPE_PAGE_TABLE ) {
Status = ConvertSectionToPages (FirstLevelIdx << ARM_SECTION_BASE_SHIFT);
if (!TT_DESCRIPTOR_SECTION_TYPE_IS_PAGE_TABLE(Descriptor)) {
Status = ConvertSectionToPages (FirstLevelIdx << TT_DESCRIPTOR_SECTION_BASE_SHIFT);
if (EFI_ERROR(Status)) {
// exit for loop
break;
@ -520,11 +410,11 @@ UpdatePageEntries (
}
// 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
PageTableIndex = ((BaseAddress + Offset) & ARM_SMALL_PAGE_INDEX_MASK) >> ARM_SMALL_PAGE_BASE_SHIFT;
ASSERT (PageTableIndex < SMALL_PAGE_TABLE_ENTRY_COUNT);
PageTableIndex = ((BaseAddress + Offset) & TT_DESCRIPTOR_PAGE_INDEX_MASK) >> TT_DESCRIPTOR_PAGE_BASE_SHIFT;
ASSERT (PageTableIndex < TRANSLATION_TABLE_PAGE_COUNT);
// get the entry
CurrentPageTableEntry = PageTable[PageTableIndex];
@ -541,8 +431,8 @@ UpdatePageEntries (
}
if (CurrentPageTableEntry != PageTableEntry) {
Mva = (VOID *)(UINTN)((((UINTN)FirstLevelIdx) << ARM_SECTION_BASE_SHIFT) + (PageTableIndex << ARM_SMALL_PAGE_BASE_SHIFT));
if ((CurrentPageTableEntry & ARM_PAGE_C) == ARM_PAGE_C) {
Mva = (VOID *)(UINTN)((((UINTN)FirstLevelIdx) << TT_DESCRIPTOR_SECTION_BASE_SHIFT) + (PageTableIndex << TT_DESCRIPTOR_PAGE_BASE_SHIFT));
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
// Note assumes switch(Attributes), not ARMv7 possibilities
WriteBackInvalidateDataCacheRange (Mva, SIZE_4KB);
@ -586,38 +476,43 @@ UpdateSectionEntries (
// EntryValue: values at bit positions specified by EntryMask
// Make sure we handle a section range that is unmapped
EntryMask = ARM_DESC_TYPE_MASK;
EntryValue = ARM_DESC_TYPE_SECTION;
EntryMask = TT_DESCRIPTOR_SECTION_TYPE_MASK;
EntryValue = TT_DESCRIPTOR_SECTION_TYPE_SECTION;
// 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
switch(Attributes) {
case EFI_MEMORY_UC:
// modify cacheability attributes
EntryMask |= ARM_SECTION_CACHEABILITY_MASK;
// map to strongly ordered
EntryValue |= 0; // TEX[2:0] = 0, C=0, B=0
EntryMask |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK;
if (FeaturePcdGet(PcdEfiUncachedMemoryToStronglyOrdered)) {
// map to strongly ordered
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;
case EFI_MEMORY_WC:
// modify cacheability attributes
EntryMask |= ARM_SECTION_CACHEABILITY_MASK;
EntryMask |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK;
// 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;
case EFI_MEMORY_WT:
// modify cacheability attributes
EntryMask |= ARM_SECTION_CACHEABILITY_MASK;
EntryMask |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK;
// 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;
case EFI_MEMORY_WB:
// modify cacheability attributes
EntryMask |= ARM_SECTION_CACHEABILITY_MASK;
EntryMask |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK;
// 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;
case EFI_MEMORY_WP:
@ -626,7 +521,7 @@ UpdateSectionEntries (
case EFI_MEMORY_UCE:
// cannot be implemented UEFI definition unclear for ARM
// 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));
break;
@ -636,23 +531,23 @@ UpdateSectionEntries (
}
// 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
FirstLevelIdx = (BaseAddress & ARM_SECTION_BASE_MASK) >> ARM_SECTION_BASE_SHIFT;
ASSERT (FirstLevelIdx < FIRST_LEVEL_ENTRY_COUNT);
FirstLevelIdx = TT_DESCRIPTOR_SECTION_BASE_ADDRESS(BaseAddress) >> TT_DESCRIPTOR_SECTION_BASE_SHIFT;
ASSERT (FirstLevelIdx < TRANSLATION_TABLE_SECTION_COUNT);
// 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
for(i=0; i<NumSections; i++) {
CurrentDescriptor = FirstLevelTable[FirstLevelIdx + i];
// 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
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 {
// still a section entry
@ -666,8 +561,8 @@ UpdateSectionEntries (
}
if (CurrentDescriptor != Descriptor) {
Mva = (VOID *)(UINTN)(((UINTN)FirstLevelTable) << ARM_SECTION_BASE_SHIFT);
if ((CurrentDescriptor & ARM_SECTION_C) == ARM_SECTION_C) {
Mva = (VOID *)(UINTN)(((UINTN)FirstLevelTable) << TT_DESCRIPTOR_SECTION_BASE_SHIFT);
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
// Note assumes switch(Attributes), not ARMv7 possabilities
WriteBackInvalidateDataCacheRange (Mva, SIZE_1MB);
@ -704,35 +599,20 @@ ConvertSectionToPages (
DEBUG ((EFI_D_PAGE, "Converting section at 0x%x to pages\n", (UINTN)BaseAddress));
// 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
FirstLevelIdx = (BaseAddress & ARM_SECTION_BASE_MASK) >> ARM_SECTION_BASE_SHIFT;
ASSERT (FirstLevelIdx < FIRST_LEVEL_ENTRY_COUNT);
FirstLevelIdx = TT_DESCRIPTOR_SECTION_BASE_ADDRESS(BaseAddress) >> TT_DESCRIPTOR_SECTION_BASE_SHIFT;
ASSERT (FirstLevelIdx < TRANSLATION_TABLE_SECTION_COUNT);
// get section attributes and convert to page attributes
SectionDescriptor = FirstLevelTable[FirstLevelIdx];
PageDescriptor = ARM_PAGE_TYPE_SMALL;
PageDescriptor |= ((SectionDescriptor & ARM_SECTION_TEX_MASK) >> ARM_SECTION_TEX_SHIFT) << ARM_SMALL_PAGE_TEX_SHIFT;
if ((SectionDescriptor & ARM_SECTION_B) != 0) {
PageDescriptor |= ARM_PAGE_B;
}
if ((SectionDescriptor & ARM_SECTION_C) != 0) {
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;
}
PageDescriptor = TT_DESCRIPTOR_PAGE_TYPE_PAGE;
PageDescriptor |= TT_DESCRIPTOR_CONVERT_TO_PAGE_CACHE_POLICY(SectionDescriptor,0);
PageDescriptor |= TT_DESCRIPTOR_CONVERT_TO_PAGE_AP(SectionDescriptor);
PageDescriptor |= TT_DESCRIPTOR_CONVERT_TO_PAGE_XN(SectionDescriptor,0);
PageDescriptor |= TT_DESCRIPTOR_CONVERT_TO_PAGE_NG(SectionDescriptor);
PageDescriptor |= TT_DESCRIPTOR_CONVERT_TO_PAGE_S(SectionDescriptor);
// 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);
@ -743,15 +623,15 @@ ConvertSectionToPages (
PageTable = (volatile ARM_PAGE_TABLE_ENTRY *)(UINTN)PageTableAddr;
// write the page table entries out
for (i=0; i<(ARM_PAGE_DESC_ENTRY_MVA_SIZE/SIZE_4KB); i++) {
PageTable[i] = ((BaseAddress + (i << 12)) & ARM_SMALL_PAGE_BASE_MASK) | PageDescriptor;
for (i=0; i < TRANSLATION_TABLE_PAGE_COUNT; i++) {
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
WriteBackInvalidateDataCacheRange ((VOID *)(UINTN)PageTableAddr, SIZE_4KB);
// 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
FirstLevelTable[FirstLevelIdx] = PageTableDescriptor;
@ -910,7 +790,3 @@ VIRTUAL_UNCACHED_PAGES_PROTOCOL gVirtualUncachedPages = {
CpuConvertPagesToUncachedVirtualAddress,
CpuReconvertPages
};

View File

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

View 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;
}

View 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

View 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

View 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);
}

View 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]

View 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);
}
}

View 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

View 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);
}
}

View 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]

View 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

View 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

View 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]

View 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;
}

View File

@ -1,44 +1,55 @@
#/** @file
#
# DXE CPU driver
#
# Copyright (c) 2009 - 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.
#
#**/
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = ArmDebugSupportDxe
FILE_GUID = 2e7c151b-cbd8-4df6-a0e3-cde660067c6a
MODULE_TYPE = DXE_DRIVER
VERSION_STRING = 1.0
ENTRY_POINT = DebugSupportDxeInitialize
[Sources.common]
DebugSupport.c
[Packages]
ArmPkg/ArmPkg.dec
MdePkg/MdePkg.dec
[LibraryClasses]
BaseMemoryLib
CacheMaintenanceLib
UefiDriverEntryPoint
ArmLib
[Protocols]
gEfiCpuArchProtocolGuid
gEfiDebugSupportProtocolGuid
gTimerDebugSupportProtocolGuid
[Depex]
TRUE
#/** @file
#
# Copyright (c) 2008 - 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.
#
#**/
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = PL390GicDxe
FILE_GUID = DE371F7C-DEC4-4D21-ADF1-593ABCC15882
MODULE_TYPE = DXE_DRIVER
VERSION_STRING = 1.0
ENTRY_POINT = InterruptDxeInitialize
[Sources.common]
PL390GicDxe.c
[Packages]
MdePkg/MdePkg.dec
EmbeddedPkg/EmbeddedPkg.dec
ArmPkg/ArmPkg.dec
[LibraryClasses]
BaseLib
UefiLib
UefiBootServicesTableLib
DebugLib
PrintLib
UefiDriverEntryPoint
IoLib
[Guids]
[Protocols]
gHardwareInterruptProtocolGuid
gEfiCpuArchProtocolGuid
[FixedPcd.common]
gArmTokenSpaceGuid.PcdGicDistributorBase
gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase
gArmTokenSpaceGuid.PcdGicNumInterrupts
[depex]
TRUE

View 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;
}
}

View 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]

View 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;
}
}

View 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]

View File

@ -86,22 +86,22 @@
#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_WRITE_BACK (TT_DESCRIPTOR_TYPE_SECTION | \
TT_DESCRIPTOR_SECTION_NS_NON_SECURE | \
#define TT_DESCRIPTOR_SECTION_WRITE_BACK(Secure) (TT_DESCRIPTOR_TYPE_SECTION | \
(Secure ? TT_DESCRIPTOR_SECTION_NS_SECURE : TT_DESCRIPTOR_SECTION_NS_NON_SECURE ) | \
TT_DESCRIPTOR_SECTION_NG_GLOBAL | \
TT_DESCRIPTOR_SECTION_S_NOT_SHARED | \
TT_DESCRIPTOR_SECTION_DOMAIN(0) | \
TT_DESCRIPTOR_SECTION_AP_RW_RW | \
TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_BACK_ALLOC)
#define TT_DESCRIPTOR_SECTION_WRITE_THROUGH (TT_DESCRIPTOR_TYPE_SECTION | \
TT_DESCRIPTOR_SECTION_NS_NON_SECURE | \
#define TT_DESCRIPTOR_SECTION_WRITE_THROUGH(Secure) (TT_DESCRIPTOR_TYPE_SECTION | \
(Secure ? TT_DESCRIPTOR_SECTION_NS_SECURE : TT_DESCRIPTOR_SECTION_NS_NON_SECURE ) | \
TT_DESCRIPTOR_SECTION_NG_GLOBAL | \
TT_DESCRIPTOR_SECTION_S_NOT_SHARED | \
TT_DESCRIPTOR_SECTION_DOMAIN(0) | \
TT_DESCRIPTOR_SECTION_AP_RW_RW | \
TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_THROUGH_NO_ALLOC)
#define TT_DESCRIPTOR_SECTION_UNCACHED (TT_DESCRIPTOR_TYPE_SECTION | \
TT_DESCRIPTOR_SECTION_NS_NON_SECURE | \
#define TT_DESCRIPTOR_SECTION_UNCACHED(Secure) (TT_DESCRIPTOR_TYPE_SECTION | \
(Secure ? TT_DESCRIPTOR_SECTION_NS_SECURE : TT_DESCRIPTOR_SECTION_NS_NON_SECURE ) | \
TT_DESCRIPTOR_SECTION_NG_GLOBAL | \
TT_DESCRIPTOR_SECTION_S_NOT_SHARED | \
TT_DESCRIPTOR_SECTION_DOMAIN(0) | \

View File

@ -22,17 +22,52 @@
#define DOMAIN_ACCESS_CONTROL_RESERVED(a) (2UL << (2 * (a)))
#define DOMAIN_ACCESS_CONTROL_MANAGER(a) (3UL << (2 * (a)))
#define TRANSLATION_TABLE_SIZE (16 * 1024)
#define TRANSLATION_TABLE_ALIGNMENT (16 * 1024)
#define TRANSLATION_TABLE_ALIGNMENT_MASK (TRANSLATION_TABLE_ALIGNMENT - 1)
#define TTBR_NOT_OUTER_SHAREABLE BIT5
#define TTBR_RGN_OUTER_NON_CACHEABLE 0
#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))
// Translation table descriptor types
#define TT_DESCRIPTOR_TYPE_MASK ((1UL << 18) | (3UL << 0))
#define TT_DESCRIPTOR_TYPE_PAGE_TABLE ((0UL << 18) | (1UL << 0))
#define TT_DESCRIPTOR_TYPE_SECTION ((0UL << 18) | (2UL << 0))
#define TT_DESCRIPTOR_TYPE_SUPERSECTION ((1UL << 18) | (2UL << 0))
#define TT_DESCRIPTOR_SECTION_TYPE_MASK ((1UL << 18) | (3UL << 0))
#define TT_DESCRIPTOR_SECTION_TYPE_FAULT (0UL << 0)
#define TT_DESCRIPTOR_SECTION_TYPE_PAGE_TABLE (1UL << 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
#define TT_DESCRIPTOR_SECTION_SIZE (0x00100000)
@ -45,10 +80,18 @@
#define TT_DESCRIPTOR_SECTION_NG_GLOBAL (0UL << 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_NOT_SHARED (0UL << 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_NO_NO ((0UL << 15) | (0UL << 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_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_SHAREABLE_DEVICE ((0UL << 12) | (0UL << 3) | (1UL << 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_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(a) (((a) & 0x0FUL) << 5)
#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_PAGE_BASE_ADDRESS_MASK (0xFFFFF000)
#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_S_NOT_SHARED | \
TT_DESCRIPTOR_SECTION_DOMAIN(0) | \
TT_DESCRIPTOR_SECTION_AP_RW_RW | \
TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_BACK_ALLOC)
#define TT_DESCRIPTOR_SECTION_WRITE_THROUGH(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_S_NOT_SHARED | \
TT_DESCRIPTOR_SECTION_DOMAIN(0) | \
TT_DESCRIPTOR_SECTION_AP_RW_RW | \
TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_THROUGH_NO_ALLOC)
#define TT_DESCRIPTOR_SECTION_DEVICE(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_S_NOT_SHARED | \
TT_DESCRIPTOR_SECTION_DOMAIN(0) | \
TT_DESCRIPTOR_SECTION_AP_RW_RW | \
TT_DESCRIPTOR_SECTION_CACHE_POLICY_SHAREABLE_DEVICE)
#define TT_DESCRIPTOR_SECTION_UNCACHED(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_S_NOT_SHARED | \
TT_DESCRIPTOR_SECTION_DOMAIN(0) | \
TT_DESCRIPTOR_SECTION_AP_RW_RW | \
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
);
#define TT_DESCRIPTOR_SECTION_WRITE_BACK (TT_DESCRIPTOR_TYPE_SECTION | \
TT_DESCRIPTOR_SECTION_NS_NON_SECURE | \
TT_DESCRIPTOR_SECTION_NG_GLOBAL | \
TT_DESCRIPTOR_SECTION_S_NOT_SHARED | \
TT_DESCRIPTOR_SECTION_DOMAIN(0) | \
TT_DESCRIPTOR_SECTION_AP_RW_RW | \
TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_BACK_ALLOC)
#define TT_DESCRIPTOR_SECTION_WRITE_THROUGH (TT_DESCRIPTOR_TYPE_SECTION | \
TT_DESCRIPTOR_SECTION_NS_NON_SECURE | \
TT_DESCRIPTOR_SECTION_NG_GLOBAL | \
TT_DESCRIPTOR_SECTION_S_NOT_SHARED | \
TT_DESCRIPTOR_SECTION_DOMAIN(0) | \
TT_DESCRIPTOR_SECTION_AP_RW_RW | \
TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_THROUGH_NO_ALLOC)
#define TT_DESCRIPTOR_SECTION_DEVICE (TT_DESCRIPTOR_TYPE_SECTION | \
TT_DESCRIPTOR_SECTION_NS_NON_SECURE | \
TT_DESCRIPTOR_SECTION_NG_GLOBAL | \
TT_DESCRIPTOR_SECTION_S_NOT_SHARED | \
TT_DESCRIPTOR_SECTION_DOMAIN(0) | \
TT_DESCRIPTOR_SECTION_AP_RW_RW | \
TT_DESCRIPTOR_SECTION_CACHE_POLICY_SHAREABLE_DEVICE)
#define TT_DESCRIPTOR_SECTION_UNCACHED (TT_DESCRIPTOR_TYPE_SECTION | \
TT_DESCRIPTOR_SECTION_NS_NON_SECURE | \
TT_DESCRIPTOR_SECTION_NG_GLOBAL | \
TT_DESCRIPTOR_SECTION_S_NOT_SHARED | \
TT_DESCRIPTOR_SECTION_DOMAIN(0) | \
TT_DESCRIPTOR_SECTION_AP_RW_RW | \
TT_DESCRIPTOR_SECTION_CACHE_POLICY_NON_CACHEABLE)
#endif // __ARM_V7_H__

View 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_ */

View 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

View File

@ -43,7 +43,11 @@ typedef enum {
ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED,
ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK,
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;
typedef struct {
@ -145,6 +149,12 @@ Cp15CacheInfo (
VOID
);
BOOLEAN
EFIAPI
ArmIsMPCore (
VOID
);
VOID
EFIAPI
ArmInvalidateDataCache (
@ -224,6 +234,12 @@ ArmDisableMmu (
VOID
);
VOID
EFIAPI
ArmDisableCachesAndMmu (
VOID
);
VOID
EFIAPI
ArmEnableInterrupts (
@ -241,6 +257,7 @@ EFIAPI
ArmGetInterruptState (
VOID
);
VOID
EFIAPI
ArmEnableFiq (
@ -280,13 +297,13 @@ ArmSetDomainAccessControl (
VOID
EFIAPI
ArmSetTranslationTableBaseAddress (
ArmSetTTBR0 (
IN VOID *TranslationTableBase
);
VOID *
EFIAPI
ArmGetTranslationTableBaseAddress (
ArmGetTTBR0BaseAddress (
VOID
);

View 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

View 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

View 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

View 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_ */

View 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

View File

@ -215,7 +215,7 @@ DmaAllocateBuffer (
//
if (MemoryType == EfiBootServicesData) {
*HostAddress = UncachedAllocatePages (Pages);
} else if (MemoryType != EfiRuntimeServicesData) {
} else if (MemoryType == EfiRuntimeServicesData) {
*HostAddress = UncachedAllocateRuntimePages (Pages);
} else {
return EFI_INVALID_PARAMETER;

View File

@ -31,14 +31,25 @@ FillTranslationTable (
switch (MemoryRegion->Attributes) {
case ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK:
Attributes = TT_DESCRIPTOR_SECTION_WRITE_BACK;
Attributes = TT_DESCRIPTOR_SECTION_WRITE_BACK(0);
break;
case ARM_MEMORY_REGION_ATTRIBUTE_WRITE_THROUGH:
Attributes = TT_DESCRIPTOR_SECTION_WRITE_THROUGH;
Attributes = TT_DESCRIPTOR_SECTION_WRITE_THROUGH(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_UNCACHED_UNBUFFERED:
Attributes = TT_DESCRIPTOR_SECTION_UNCACHED(1);
break;
default:
Attributes = TT_DESCRIPTOR_SECTION_UNCACHED;
Attributes = TT_DESCRIPTOR_SECTION_UNCACHED(0);
break;
}
@ -93,7 +104,7 @@ ArmConfigureMmu (
MemoryTable++;
}
ArmSetTranslationTableBaseAddress(TranslationTable);
ArmSetTTBR0(TranslationTable);
ArmSetDomainAccessControl(DOMAIN_ACCESS_CONTROL_NONE(15) |
DOMAIN_ACCESS_CONTROL_NONE(14) |

View File

@ -12,46 +12,29 @@
#
#------------------------------------------------------------------------------
#include <AsmMacroIoLib.h>
.text
.align 2
.globl ASM_PFX(ArmCleanInvalidateDataCache)
INTERWORK_FUNC(ArmCleanInvalidateDataCache)
.globl ASM_PFX(ArmCleanDataCache)
INTERWORK_FUNC(ArmCleanDataCache)
.globl ASM_PFX(ArmInvalidateDataCache)
INTERWORK_FUNC(ArmInvalidateDataCache)
.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(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(ArmDataMemoryBarrier)
INTERWORK_FUNC(ArmDataMemoryBarrier)
.globl ASM_PFX(ArmDataSyncronizationBarrier)
INTERWORK_FUNC(ArmDataSyncronizationBarrier)
.globl ASM_PFX(ArmInstructionSynchronizationBarrier)
INTERWORK_FUNC(ArmInstructionSynchronizationBarrier)
GCC_ASM_EXPORT(ArmCleanInvalidateDataCache)
GCC_ASM_EXPORT(ArmCleanDataCache)
GCC_ASM_EXPORT(ArmInvalidateDataCache)
GCC_ASM_EXPORT(ArmInvalidateInstructionCache)
GCC_ASM_EXPORT(ArmInvalidateDataCacheEntryByMVA)
GCC_ASM_EXPORT(ArmCleanDataCacheEntryByMVA)
GCC_ASM_EXPORT(ArmCleanInvalidateDataCacheEntryByMVA)
GCC_ASM_EXPORT(ArmEnableMmu)
GCC_ASM_EXPORT(ArmDisableMmu)
GCC_ASM_EXPORT(ArmMmuEnabled)
GCC_ASM_EXPORT(ArmEnableDataCache)
GCC_ASM_EXPORT(ArmDisableDataCache)
GCC_ASM_EXPORT(ArmEnableInstructionCache)
GCC_ASM_EXPORT(ArmDisableInstructionCache)
GCC_ASM_EXPORT(ArmEnableBranchPrediction)
GCC_ASM_EXPORT(ArmDisableBranchPrediction)
GCC_ASM_EXPORT(ArmDataMemoryBarrier)
GCC_ASM_EXPORT(ArmDataSyncronizationBarrier)
GCC_ASM_EXPORT(ArmInstructionSynchronizationBarrier)
.set DC_ON, (0x1<<2)
@ -116,14 +99,14 @@ ASM_PFX(ArmDisableMmu):
bx LR
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
orr R0,R0,R1 @Set C bit
mcr p15,0,r0,c1,c0,0 @Write control register configuration data
bx LR
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
bic R0,R0,R1 @Clear C bit
mcr p15,0,r0,c1,c0,0 @Write control register configuration data

View File

@ -16,6 +16,7 @@
#include <Library/ArmLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/DebugLib.h>
VOID
FillTranslationTable (
@ -37,6 +38,12 @@ FillTranslationTable (
Attributes = TT_DESCRIPTOR_SECTION_WRITE_THROUGH;
break;
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:
Attributes = TT_DESCRIPTOR_SECTION_UNCACHED_UNBUFFERED;
break;
@ -93,7 +100,7 @@ ArmConfigureMmu (
MemoryTable++;
}
ArmSetTranslationTableBaseAddress(TranslationTable);
ArmSetTTBR0(TranslationTable);
ArmSetDomainAccessControl(DOMAIN_ACCESS_CONTROL_NONE(15) |
DOMAIN_ACCESS_CONTROL_NONE(14) |

View File

@ -14,44 +14,25 @@
.text
.align 2
.globl ASM_PFX(ArmCleanInvalidateDataCache)
INTERWORK_FUNC(ArmCleanInvalidateDataCache)
.globl ASM_PFX(ArmCleanDataCache)
INTERWORK_FUNC(ArmCleanDataCache)
.globl ASM_PFX(ArmInvalidateDataCache)
INTERWORK_FUNC(ArmInvalidateDataCache)
.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(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(ArmDataMemoryBarrier)
INTERWORK_FUNC(ArmDataMemoryBarrier)
.globl ASM_PFX(ArmDataSyncronizationBarrier)
INTERWORK_FUNC(ArmDataSyncronizationBarrier)
.globl ASM_PFX(ArmInstructionSynchronizationBarrier)
INTERWORK_FUNC(ArmInstructionSynchronizationBarrier)
GCC_ASM_EXPORT(ArmCleanInvalidateDataCache)
GCC_ASM_EXPORT(ArmCleanDataCache)
GCC_ASM_EXPORT(ArmInvalidateDataCache)
GCC_ASM_EXPORT(ArmInvalidateInstructionCache)
GCC_ASM_EXPORT(ArmInvalidateDataCacheEntryByMVA)
GCC_ASM_EXPORT(ArmCleanDataCacheEntryByMVA)
GCC_ASM_EXPORT(ArmCleanInvalidateDataCacheEntryByMVA)
GCC_ASM_EXPORT(ArmEnableMmu)
GCC_ASM_EXPORT(ArmDisableMmu)
GCC_ASM_EXPORT(ArmMmuEnabled)
GCC_ASM_EXPORT(ArmEnableDataCache)
GCC_ASM_EXPORT(ArmDisableDataCache)
GCC_ASM_EXPORT(ArmEnableInstructionCache)
GCC_ASM_EXPORT(ArmDisableInstructionCache)
GCC_ASM_EXPORT(ArmEnableBranchPrediction)
GCC_ASM_EXPORT(ArmDisableBranchPrediction)
GCC_ASM_EXPORT(ArmDataMemoryBarrier)
GCC_ASM_EXPORT(ArmDataSyncronizationBarrier)
GCC_ASM_EXPORT(ArmInstructionSynchronizationBarrier)
.set DC_ON, (1<<2)

View File

@ -12,44 +12,36 @@
#
#------------------------------------------------------------------------------
.globl ASM_PFX(Cp15IdCode)
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)
#include <AsmMacroIoLib.h>
.text
.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):
@ -60,35 +52,67 @@ ASM_PFX(Cp15CacheInfo):
mrc p15,0,R0,c0,c0,1
bx LR
ASM_PFX(ArmEnableInterrupts):
cpsie i
bx LR
ASM_PFX(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
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
bx LR
isb
bx LR
ASM_PFX(ArmGetInterruptState):
mrs R0,CPSR
tst R0,#0x80 @Check if IRQ is enabled.
moveq R0,#1
movne R0,#0
bx LR
mrs R0,CPSR
tst R0,#0x80 @Check if IRQ is enabled.
moveq R0,#1
movne R0,#0
bx LR
ASM_PFX(ArmEnableFiq):
cpsie f
bx LR
isb
bx LR
ASM_PFX(ArmDisableFiq):
cpsid f
bx LR
isb
bx LR
ASM_PFX(ArmEnableInterrupts):
cpsie if
isb
bx LR
ASM_PFX(ArmDisableInterrupts):
cpsid if
isb
bx LR
ASM_PFX(ArmGetFiqState):
mrs R0,CPSR
tst R0,#0x40 @Check if FIQ is enabled.
moveq R0,#1
movne R0,#0
bx LR
mrs R0,CPSR
tst R0,#0x40 @Check if FIQ is enabled.
moveq R0,#1
movne R0,#0
bx LR
ASM_PFX(ArmInvalidateTlb):
mov r0,#0
@ -98,13 +122,15 @@ ASM_PFX(ArmInvalidateTlb):
isb
bx lr
ASM_PFX(ArmSetTranslationTableBaseAddress):
ASM_PFX(ArmSetTTBR0):
mcr p15,0,r0,c2,c0,0
isb
bx lr
ASM_PFX(ArmGetTranslationTableBaseAddress):
ASM_PFX(ArmGetTTBR0BaseAddress):
mrc p15,0,r0,c2,c0,0
LoadConstantToReg(0xFFFFC000, r1)
and r0, r0, r1
isb
bx lr

View File

@ -15,15 +15,20 @@
EXPORT Cp15IdCode
EXPORT Cp15CacheInfo
EXPORT ArmEnableInterrupts
EXPORT ArmDisableInterrupts
EXPORT ArmIsMPCore
EXPORT ArmEnableAsynchronousAbort
EXPORT ArmDisableAsynchronousAbort
EXPORT ArmEnableIrq
EXPORT ArmDisableIrq
EXPORT ArmGetInterruptState
EXPORT ArmEnableFiq
EXPORT ArmDisableFiq
EXPORT ArmEnableInterrupts
EXPORT ArmDisableInterrupts
EXPORT ArmGetFiqState
EXPORT ArmInvalidateTlb
EXPORT ArmSetTranslationTableBaseAddress
EXPORT ArmGetTranslationTableBaseAddress
EXPORT ArmSetTTBR0
EXPORT ArmGetTTBR0BaseAddress
EXPORT ArmSetDomainAccessControl
EXPORT ArmUpdateTranslationTableEntry
EXPORT CPSRMaskInsert
@ -44,27 +49,59 @@ Cp15CacheInfo
mrc p15,0,R0,c0,c0,1
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
isb
bx LR
ArmDisableInterrupts
ArmDisableIrq
cpsid i
bx LR
ArmGetInterruptState
mrs R0,CPSR
tst R0,#0x80 ;Check if IRQ is enabled.
moveq R0,#1
movne R0,#0
isb
bx LR
ArmEnableFiq
cpsie f
isb
bx LR
ArmDisableFiq
cpsid f
isb
bx LR
ArmEnableInterrupts
cpsie if
isb
bx LR
ArmDisableInterrupts
cpsid if
isb
bx LR
ArmGetInterruptState
mrs R0,CPSR
tst R0,#0x80 ;Check if IRQ is enabled.
moveq R0,#1
movne R0,#0
bx LR
ArmGetFiqState
@ -82,13 +119,15 @@ ArmInvalidateTlb
isb
bx lr
ArmSetTranslationTableBaseAddress
ArmSetTTBR0
mcr p15,0,r0,c2,c0,0
isb
bx lr
ArmGetTranslationTableBaseAddress
ArmGetTTBR0BaseAddress
mrc p15,0,r0,c2,c0,0
ldr r1, = 0xFFFFC000
and r0, r0, r1
isb
bx lr
@ -150,7 +189,4 @@ ReadCLIDR
mrc p15,1,r0,c0,c0,1 ; Read CP15 Cache Level ID Register
bx lr
END

View File

@ -15,113 +15,10 @@
#include <Chipset/ArmV7.h>
#include <Library/ArmLib.h>
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/IoLib.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;
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
EFIAPI
ArmCacheType (
@ -139,7 +36,7 @@ ArmCacheArchitecture (
{
UINT32 CLIDR = ReadCLIDR ();
return CLIDR; // BugBug Fix Me
return (ARM_CACHE_ARCHITECTURE)CLIDR; // BugBug Fix Me
}
BOOLEAN
@ -173,7 +70,7 @@ ArmDataCacheSize (
UINT32 LineSize;
UINT32 CCSIDR = ReadCCSIDR (0);
LineSize = (1 << (CCSIDR + 2));
LineSize = (1 << ((CCSIDR & 0x7) + 2));
Associativity = ((CCSIDR >> 3) & 0x3ff) + 1;
NumSets = ((CCSIDR >> 13) & 0x7fff) + 1;
@ -245,7 +142,7 @@ ArmInstructionCacheSize (
UINT32 LineSize;
UINT32 CCSIDR = ReadCCSIDR (1);
LineSize = (1 << (CCSIDR + 2));
LineSize = (1 << ((CCSIDR & 0x7) + 2));
Associativity = ((CCSIDR >> 3) & 0x3ff) + 1;
NumSets = ((CCSIDR >> 13) & 0x7fff) + 1;
@ -299,6 +196,8 @@ ArmV7DataCacheOperation (
UINTN SavedInterruptState;
SavedInterruptState = ArmGetInterruptState ();
ArmDisableInterrupts();
ArmV7AllDataCachesOperation (DataCacheOperation);
@ -335,3 +234,14 @@ ArmCleanDataCache (
{
ArmV7DataCacheOperation (ArmCleanDataCacheEntryBySetWay);
}
VOID
EFIAPI
ArmSetAuxCrBit (
IN UINT32 Bits
)
{
UINT32 val = ArmReadAuxCr();
val |= Bits;
ArmWriteAuxCr(val);
}

View File

@ -40,5 +40,41 @@ ArmCleanInvalidateDataCacheEntryBySetWay (
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__

View File

@ -30,6 +30,7 @@
ArmV7Support.asm | RVCT
ArmV7Lib.c
ArmV7Mmu.c
[Packages]
ArmPkg/ArmPkg.dec

View File

@ -30,6 +30,7 @@
ArmV7Support.asm | RVCT
ArmV7Lib.c
ArmV7Mmu.c
[Packages]
ArmPkg/ArmPkg.dec

View 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

View 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);
}

View 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

View 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

View 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

View File

@ -0,0 +1,49 @@
#/** @file
#
# Copyright (c) 2011, ARM Limited. All rights reserved.
#
# This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
# which accompanies this distribution. The full text of the license may be found at
# http://opensource.org/licenses/bsd-license.php
#
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#
#**/
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = 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

View 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

View 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();
}

View File

@ -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
.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 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):
@ -69,7 +65,6 @@ ASM_PFX(ArmInvalidateDataCacheEntryByMVA):
isb
bx lr
ASM_PFX(ArmCleanDataCacheEntryByMVA):
mcr p15, 0, r0, c7, c10, 1 @clean single data cache line
dsb
@ -104,7 +99,6 @@ ASM_PFX(ArmCleanDataCacheEntryBySetWay):
isb
bx lr
ASM_PFX(ArmInvalidateInstructionCache):
mcr p15,0,R0,c7,c5,0 @Invalidate entire instruction cache
dsb
@ -119,10 +113,6 @@ ASM_PFX(ArmEnableMmu):
isb
bx LR
ASM_PFX(ArmMmuEnabled):
mrc p15,0,R0,c1,c0,0
and R0,R0,#1
bx LR
ASM_PFX(ArmDisableMmu):
mrc p15,0,R0,c1,c0,0
@ -135,6 +125,21 @@ ASM_PFX(ArmDisableMmu):
isb
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):
ldr R1,=DC_ON
mrc p15,0,R0,c1,c0,0 @Read control register configuration data
@ -171,6 +176,13 @@ ASM_PFX(ArmDisableInstructionCache):
isb
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):
mrc p15, 0, r0, c1, c0, 0
orr r0, r0, #0x00000800
@ -254,5 +266,59 @@ ASM_PFX(ArmInstructionSynchronizationBarrier):
isb
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

View File

@ -22,24 +22,42 @@
EXPORT ArmDrainWriteBuffer
EXPORT ArmEnableMmu
EXPORT ArmDisableMmu
EXPORT ArmDisableCachesAndMmu
EXPORT ArmMmuEnabled
EXPORT ArmEnableDataCache
EXPORT ArmDisableDataCache
EXPORT ArmEnableInstructionCache
EXPORT ArmDisableInstructionCache
EXPORT ArmEnableSWPInstruction
EXPORT ArmEnableBranchPrediction
EXPORT ArmDisableBranchPrediction
EXPORT ArmV7AllDataCachesOperation
EXPORT ArmDataMemoryBarrier
EXPORT ArmDataSyncronizationBarrier
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
PRESERVE8
DC_ON EQU ( 0x1:SHL:2 )
IC_ON EQU ( 0x1:SHL:12 )
DC_ON EQU ( 0x1:SHL:2 )
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
@ -90,75 +108,91 @@ ArmInvalidateInstructionCache
bx LR
ArmEnableMmu
mrc p15,0,R0,c1,c0,0
orr R0,R0,#1
mcr 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 ; Set SCTLR.M bit : Enable MMU
mcr p15,0,R0,c1,c0,0 ; Write R0 into SCTLR (Write control register configuration data)
dsb
isb
bx LR
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
bx LR
ArmDisableMmu
mrc p15,0,R0,c1,c0,0
bic R0,R0,#1
mcr p15,0,R0,c1,c0,0 ;Disable MMU
mrc p15,0,R0,c1,c0,0 ; Read SCTLR into R0 (Read control register configuration data)
bic R0,R0,#1 ; Clear SCTLR.M bit : 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,c7,c5,6 ;Invalidate Branch predictor array
mcr p15,0,R0,c8,c7,0 ; TLBIALL : Invalidate unified TLB
mcr p15,0,R0,c7,c5,6 ; BPIALL : Invalidate entire branch predictor array
dsb
isb
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
ldr R1,=DC_ON
mrc p15,0,R0,c1,c0,0 ;Read control register configuration data
orr R0,R0,R1 ;Set C bit
mcr p15,0,R0,c1,c0,0 ;Write control register configuration data
ldr R1,=DC_ON ; Specify SCTLR.C bit : (Data) Cache enable bit
mrc p15,0,R0,c1,c0,0 ; Read SCTLR into R0 (Read control register configuration data)
orr R0,R0,R1 ; Set SCTLR.C bit : Data and unified caches enabled
mcr p15,0,R0,c1,c0,0 ; Write R0 into SCTLR (Write control register configuration data)
dsb
isb
bx LR
ArmDisableDataCache
ldr R1,=DC_ON
mrc p15,0,R0,c1,c0,0 ;Read control register configuration data
bic R0,R0,R1 ;Clear C bit
mcr p15,0,R0,c1,c0,0 ;Write control register configuration data
ldr R1,=DC_ON ; Specify SCTLR.C bit : (Data) Cache enable bit
mrc p15,0,R0,c1,c0,0 ; Read SCTLR into R0 (Read control register configuration data)
bic R0,R0,R1 ; Clear SCTLR.C bit : Data and unified caches disabled
mcr p15,0,R0,c1,c0,0 ; Write R0 into SCTLR (Write control register configuration data)
isb
bx LR
ArmEnableInstructionCache
ldr R1,=IC_ON
mrc p15,0,R0,c1,c0,0 ;Read control register configuration data
orr R0,R0,R1 ;Set I bit
mcr p15,0,R0,c1,c0,0 ;Write control register configuration data
ldr R1,=IC_ON ; Specify SCTLR.I bit : Instruction cache enable bit
mrc p15,0,R0,c1,c0,0 ; Read SCTLR into R0 (Read control register configuration data)
orr R0,R0,R1 ; Set SCTLR.I bit : Instruction caches enabled
mcr p15,0,R0,c1,c0,0 ; Write R0 into SCTLR (Write control register configuration data)
dsb
isb
bx LR
ArmDisableInstructionCache
ldr R1,=IC_ON
mrc p15,0,R0,c1,c0,0 ;Read control register configuration data
BIC R0,R0,R1 ;Clear I bit.
mcr p15,0,R0,c1,c0,0 ;Write control register configuration data
ldr R1,=IC_ON ; Specify SCTLR.I bit : Instruction cache enable bit
mrc p15,0,R0,c1,c0,0 ; Read SCTLR into R0 (Read control register configuration data)
BIC R0,R0,R1 ; Clear SCTLR.I bit : Instruction caches disabled
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
bx LR
ArmEnableBranchPrediction
mrc p15, 0, r0, c1, c0, 0
orr r0, r0, #0x00000800
mcr 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 ;
mcr p15, 0, r0, c1, c0, 0 ; Write R0 into SCTLR (Write control register configuration data)
isb
bx LR
ArmDisableBranchPrediction
mrc p15, 0, r0, c1, c0, 0
bic r0, r0, #0x00000800
mcr 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 ;
mcr p15, 0, r0, c1, c0, 0 ; Write R0 into SCTLR (Write control register configuration data)
isb
bx LR
@ -173,9 +207,9 @@ ArmV7AllDataCachesOperation
mov R10, #0
Loop1
add R2, R10, R10, LSR #1 ; Work out 3xcachelevel
mov R12, R6, LSR R2 ; bottom 3 bits are the Cache type for this level
and R12, R12, #7 ; get those 3 bits alone
add R2, R10, R10, LSR #1 ; Work out 3xcachelevel
mov R12, R6, LSR R2 ; bottom 3 bits are the Cache type for this level
and R12, R12, #7 ; get those 3 bits alone
cmp R12, #2
blt Skip ; no cache or only instruction cache at this level
mcr p15, 2, R10, c0, c0, 0 ; write the Cache Size selection register (CSSELR) // OR in 1 for Instruction
@ -226,5 +260,64 @@ ArmInstructionSynchronizationBarrier
isb
bx LR
END
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

View File

@ -12,37 +12,24 @@
#
#------------------------------------------------------------------------------
#include <AsmMacroIoLib.h>
.text
.align 2
.globl ASM_PFX(Cp15IdCode)
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(CPSRMaskInsert)
INTERWORK_FUNC(CPSRMaskInsert)
.globl ASM_PFX(CPSRRead)
INTERWORK_FUNC(CPSRRead)
GCC_ASM_EXPORT(Cp15IdCode)
GCC_ASM_EXPORT(Cp15CacheInfo)
GCC_ASM_EXPORT(ArmEnableInterrupts)
GCC_ASM_EXPORT(ArmDisableInterrupts)
GCC_ASM_EXPORT(ArmGetInterruptState)
GCC_ASM_EXPORT(ArmEnableFiq)
GCC_ASM_EXPORT(ArmDisableFiq)
GCC_ASM_EXPORT(ArmGetFiqState)
GCC_ASM_EXPORT(ArmInvalidateTlb)
GCC_ASM_EXPORT(ArmSetTTBR0)
GCC_ASM_EXPORT(ArmGetTTBR0BaseAddress)
GCC_ASM_EXPORT(ArmSetDomainAccessControl)
GCC_ASM_EXPORT(CPSRMaskInsert)
GCC_ASM_EXPORT(CPSRRead)
#------------------------------------------------------------------------------
@ -103,12 +90,14 @@ ASM_PFX(ArmInvalidateTlb):
mcr p15,0,r0,c8,c7,0
bx lr
ASM_PFX(ArmSetTranslationTableBaseAddress):
ASM_PFX(ArmSetTTBR0):
mcr p15,0,r0,c2,c0,0
bx lr
ASM_PFX(ArmGetTranslationTableBaseAddress):
ASM_PFX(ArmGetTTBR0BaseAddress):
mrc p15,0,r0,c2,c0,0
LoadConstantToReg(0xFFFFC000, r1) @ and r0, r0, #0xFFFFC000
and r0, r0, r1
bx lr

View File

@ -15,6 +15,7 @@
EXPORT Cp15IdCode
EXPORT Cp15CacheInfo
EXPORT ArmIsMPCore
EXPORT ArmEnableInterrupts
EXPORT ArmDisableInterrupts
EXPORT ArmGetInterruptState
@ -22,8 +23,8 @@
EXPORT ArmDisableFiq
EXPORT ArmGetFiqState
EXPORT ArmInvalidateTlb
EXPORT ArmSetTranslationTableBaseAddress
EXPORT ArmGetTranslationTableBaseAddress
EXPORT ArmSetTTBR0
EXPORT ArmGetTTBR0BaseAddress
EXPORT ArmSetDomainAccessControl
EXPORT CPSRMaskInsert
EXPORT CPSRRead
@ -38,6 +39,14 @@ Cp15CacheInfo
mrc p15,0,R0,c0,c0,1
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
mrs R0,CPSR
bic R0,R0,#0x80 ;Enable IRQ interrupts
@ -87,12 +96,13 @@ ArmInvalidateTlb
mcr p15,0,r0,c8,c7,0
bx lr
ArmSetTranslationTableBaseAddress
ArmSetTTBR0
mcr p15,0,r0,c2,c0,0
bx lr
ArmGetTranslationTableBaseAddress
ArmGetTTBR0BaseAddress
mrc p15,0,r0,c2,c0,0
and r0, r0, #0xFFFFC000
bx lr
ArmSetDomainAccessControl

View 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));
}

View 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

View 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;
}

View 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

View File

@ -39,8 +39,7 @@ InternalMemCopyMem (
**/
.text
.align 2
.globl ASM_PFX(InternalMemCopyMem)
INTERWORK_FUNC(InternalMemCopyMem)
GCC_ASM_EXPORT(InternalMemCopyMem)
ASM_PFX(InternalMemCopyMem):
stmfd sp!, {r4-r11, lr}

View File

@ -37,8 +37,7 @@ InternalMemSetMem (
.text
.align 2
.globl ASM_PFX(InternalMemSetMem)
INTERWORK_FUNC(InternalMemSetMem)
GCC_ASM_EXPORT(InternalMemSetMem)
ASM_PFX(InternalMemSetMem):
stmfd sp!, {r4-r11, lr}

View File

@ -39,8 +39,7 @@ InternalMemCopyMem (
**/
.text
.align 2
.globl ASM_PFX(InternalMemCopyMem)
INTERWORK_FUNC(InternalMemCopyMem)
GCC_ASM_EXPORT(InternalMemCopyMem)
ASM_PFX(InternalMemCopyMem):
stmfd sp!, {r4, r9, lr}

View File

@ -37,8 +37,7 @@ InternalMemSetMem (
.text
.align 2
.globl ASM_PFX(InternalMemSetMem)
INTERWORK_FUNC(InternalMemSetMem)
GCC_ASM_EXPORT(InternalMemSetMem)
ASM_PFX(InternalMemSetMem):
stmfd sp!, {r4-r7, lr}

View File

@ -913,7 +913,7 @@ PeCoffLoaderLoadImage (
ImageContext->Handle,
0,
&ImageContext->SizeOfHeaders,
(void *)(UINTN)ImageContext->ImageAddress
(VOID*)(UINTN)ImageContext->ImageAddress
);
Hdr.Te = (EFI_TE_IMAGE_HEADER *)(UINTN)(ImageContext->ImageAddress);

View 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;
}

View 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;
}
}

View 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;
}

View 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;
}

View 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;
}

View 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;
}

View 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

View 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

View 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;
}

View 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

View File

@ -14,8 +14,7 @@
.text
.align 2
.globl ASM_PFX(__ashldi3)
INTERWORK_FUNC(__ashldi3)
GCC_ASM_EXPORT(__ashldi3)
ASM_PFX(__ashldi3):
cmp r2, #31

View File

@ -14,8 +14,7 @@
.text
.align 2
.globl ASM_PFX(__ashrdi3)
INTERWORK_FUNC(__ashrdi3)
GCC_ASM_EXPORT(__ashrdi3)
ASM_PFX(__ashrdi3):
cmp r2, #31

View File

@ -14,8 +14,7 @@
.text
.align 2
.globl ASM_PFX(__clzsi2)
INTERWORK_FUNC(__clzsi2)
GCC_ASM_EXPORT(__clzsi2)
ASM_PFX(__clzsi2):
@ frame_needed = 1, uses_anonymous_args = 0

View File

@ -14,8 +14,7 @@
.text
.align 2
.globl ASM_PFX(__ctzsi2)
INTERWORK_FUNC(__ctzsi2)
GCC_ASM_EXPORT(__ctzsi2)
ASM_PFX(__ctzsi2):
uxth r3, r0

View File

@ -14,8 +14,7 @@
.text
.align 2
.globl ASM_PFX(__divdi3)
INTERWORK_FUNC(__divdi3)
GCC_ASM_EXPORT(__divdi3)
ASM_PFX(__divdi3):
@ args = 0, pretend = 0, frame = 0

View File

@ -14,8 +14,7 @@
.text
.align 2
.globl ASM_PFX(__divsi3)
INTERWORK_FUNC(__divsi3)
GCC_ASM_EXPORT(__divsi3)
ASM_PFX(__divsi3):
eor r3, r0, r0, asr #31

View File

@ -15,8 +15,7 @@
.text
.align 2
.globl ASM_PFX(__aeabi_ldivmod)
INTERWORK_FUNC(__aeabi_ldivmod)
GCC_ASM_EXPORT(__aeabi_ldivmod)
//
// A pair of (unsigned) long longs is returned in {{r0, r1}, {r2, r3}},

View File

@ -14,8 +14,7 @@
.text
.align 2
.globl ASM_PFX(__lshrdi3)
INTERWORK_FUNC(__lshrdi3)
GCC_ASM_EXPORT(__lshrdi3)
ASM_PFX(__lshrdi3):
cmp r2, #31

View File

@ -14,8 +14,7 @@
.text
.align 2
.globl ASM_PFX(memcpy)
INTERWORK_FUNC(memcpy)
GCC_ASM_EXPORT(memcpy)
ASM_PFX(memcpy):
stmfd sp!, {r7, lr}

View File

@ -15,8 +15,7 @@
.text
.align 2
.globl ASM_PFX(memset)
INTERWORK_FUNC(memset)
GCC_ASM_EXPORT (memset)
ASM_PFX(memset):
@ args = 0, pretend = 0, frame = 0

View File

@ -14,8 +14,7 @@
.text
.align 2
.globl ASM_PFX(__moddi3)
INTERWORK_FUNC(__moddi3)
GCC_ASM_EXPORT(__moddi3)
ASM_PFX(__moddi3):
stmfd sp!, {r4, r5, r7, lr}

View File

@ -14,8 +14,7 @@
.text
.align 2
.globl ASM_PFX(__modsi3)
INTERWORK_FUNC(__modsi3)
GCC_ASM_EXPORT(__modsi3)
ASM_PFX(__modsi3):
stmfd sp!, {r4, r5, r7, lr}

View File

@ -14,8 +14,7 @@
.text
.align 2
.globl ASM_PFX(__muldi3)
INTERWORK_FUNC(__muldi3)
GCC_ASM_EXPORT(__muldi3)
ASM_PFX(__muldi3):
stmfd sp!, {r4, r5, r6, r7, lr}

View File

@ -15,8 +15,7 @@
.text
.align 2
.globl ASM_PFX(__aeabi_ulcmp)
INTERWORK_FUNC(__aeabi_ulcmp)
GCC_ASM_EXPORT(__aeabi_ulcmp)
ASM_PFX(__aeabi_ulcmp):
stmfd sp!, {r4, r5, r8}

View File

@ -16,8 +16,7 @@
.text
.p2align 2
.globl ASM_PFX(__switch16)
INTERWORK_FUNC(__switch16)
GCC_ASM_EXPORT(__switch16)
ASM_PFX(__switch16):
ldrh ip, [lr, #-1]

View File

@ -16,8 +16,7 @@
.text
.p2align 2
.globl ASM_PFX(__switch32)
INTERWORK_FUNC(__switch32)
GCC_ASM_EXPORT(__switch32)
ASM_PFX(__switch32):
ldr ip, [lr, #-1]

View File

@ -16,9 +16,7 @@
.text
.p2align 2
.globl ASM_PFX(__switch8)
INTERWORK_FUNC(__switch8)
GCC_ASM_EXPORT(__switch8)
ASM_PFX(__switch8):
ldrb ip, [lr, #-1]

View File

@ -16,8 +16,7 @@
.text
.p2align 2
.globl ASM_PFX(__switchu8)
INTERWORK_FUNC(__switchu8)
GCC_ASM_EXPORT(__switchu8)
ASM_PFX(__switchu8):

View File

@ -14,8 +14,7 @@
.text
.align 2
.globl ASM_PFX(__ucmpdi2)
INTERWORK_FUNC(__ucmpdi2)
GCC_ASM_EXPORT(__ucmpdi2)
ASM_PFX(__ucmpdi2):
stmfd sp!, {r4, r5, r8, lr}

View File

@ -14,8 +14,7 @@
.text
.align 2
.globl ASM_PFX(__udivdi3)
INTERWORK_FUNC(__udivdi3)
GCC_ASM_EXPORT(__udivdi3)
ASM_PFX(__udivdi3):
stmfd sp!, {r7, lr}

View File

@ -14,9 +14,8 @@
.text
.align 2
.globl ASM_PFX(__udivmoddi4)
INTERWORK_FUNC(__udivmoddi4)
GCC_ASM_EXPORT(__udivmoddi4)
ASM_PFX(__udivmoddi4):
stmfd sp!, {r4, r5, r6, r7, lr}
add r7, sp, #12

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