mirror of https://github.com/acidanthera/audk.git
Added support for L2 (4K) page tables and made the CPU driver change cachability attributes on request. Also got the DebugUncache infrastructure working for the first time. Looks like it works for the simple case. Checking in so we can get more eyes looking at the code.
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@9734 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
parent
66b631f5e0
commit
f659880bfa
|
@ -49,6 +49,7 @@
|
||||||
DxeServicesTableLib|MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.inf
|
DxeServicesTableLib|MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.inf
|
||||||
|
|
||||||
ArmLib|ArmPkg/Library/ArmLib/ArmCortexA/ArmCortexArmLib.inf
|
ArmLib|ArmPkg/Library/ArmLib/ArmCortexA/ArmCortexArmLib.inf
|
||||||
|
CpuLib|MdePkg/Library/BaseCpuLib/BaseCpuLib.inf
|
||||||
|
|
||||||
[LibraryClasses.ARM]
|
[LibraryClasses.ARM]
|
||||||
#
|
#
|
||||||
|
|
|
@ -16,6 +16,34 @@
|
||||||
|
|
||||||
BOOLEAN mInterruptState = FALSE;
|
BOOLEAN mInterruptState = FALSE;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
This function flushes the range of addresses from Start to Start+Length
|
||||||
|
from the processor's data cache. If Start is not aligned to a cache line
|
||||||
|
boundary, then the bytes before Start to the preceding cache line boundary
|
||||||
|
are also flushed. If Start+Length is not aligned to a cache line boundary,
|
||||||
|
then the bytes past Start+Length to the end of the next cache line boundary
|
||||||
|
are also flushed. The FlushType of EfiCpuFlushTypeWriteBackInvalidate must be
|
||||||
|
supported. If the data cache is fully coherent with all DMA operations, then
|
||||||
|
this function can just return EFI_SUCCESS. If the processor does not support
|
||||||
|
flushing a range of the data cache, then the entire data cache can be flushed.
|
||||||
|
|
||||||
|
@param This The EFI_CPU_ARCH_PROTOCOL instance.
|
||||||
|
@param Start The beginning physical address to flush from the processor's data
|
||||||
|
cache.
|
||||||
|
@param Length The number of bytes to flush from the processor's data cache. This
|
||||||
|
function may flush more bytes than Length specifies depending upon
|
||||||
|
the granularity of the flush operation that the processor supports.
|
||||||
|
@param FlushType Specifies the type of flush operation to perform.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS The address range from Start to Start+Length was flushed from
|
||||||
|
the processor's data cache.
|
||||||
|
@retval EFI_UNSUPPORTEDT The processor does not support the cache flush type specified
|
||||||
|
by FlushType.
|
||||||
|
@retval EFI_DEVICE_ERROR The address range from Start to Start+Length could not be flushed
|
||||||
|
from the processor's data cache.
|
||||||
|
|
||||||
|
**/
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
EFIAPI
|
EFIAPI
|
||||||
CpuFlushCpuDataCache (
|
CpuFlushCpuDataCache (
|
||||||
|
@ -25,6 +53,8 @@ CpuFlushCpuDataCache (
|
||||||
IN EFI_CPU_FLUSH_TYPE FlushType
|
IN EFI_CPU_FLUSH_TYPE FlushType
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
DEBUG ((EFI_D_ERROR, "CpuFlushCpuDataCache (%lx, %lx, %x)\n", Start, Length, FlushType));
|
||||||
|
|
||||||
switch (FlushType) {
|
switch (FlushType) {
|
||||||
case EfiCpuFlushTypeWriteBack:
|
case EfiCpuFlushTypeWriteBack:
|
||||||
WriteBackDataCacheRange ((VOID *)(UINTN)Start, (UINTN)Length);
|
WriteBackDataCacheRange ((VOID *)(UINTN)Start, (UINTN)Length);
|
||||||
|
@ -42,6 +72,16 @@ CpuFlushCpuDataCache (
|
||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
This function enables interrupt processing by the processor.
|
||||||
|
|
||||||
|
@param This The EFI_CPU_ARCH_PROTOCOL instance.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS Interrupts are enabled on the processor.
|
||||||
|
@retval EFI_DEVICE_ERROR Interrupts could not be enabled on the processor.
|
||||||
|
|
||||||
|
**/
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
EFIAPI
|
EFIAPI
|
||||||
CpuEnableInterrupt (
|
CpuEnableInterrupt (
|
||||||
|
@ -55,6 +95,15 @@ CpuEnableInterrupt (
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
This function disables interrupt processing by the processor.
|
||||||
|
|
||||||
|
@param This The EFI_CPU_ARCH_PROTOCOL instance.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS Interrupts are disabled on the processor.
|
||||||
|
@retval EFI_DEVICE_ERROR Interrupts could not be disabled on the processor.
|
||||||
|
|
||||||
|
**/
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
EFIAPI
|
EFIAPI
|
||||||
CpuDisableInterrupt (
|
CpuDisableInterrupt (
|
||||||
|
@ -67,6 +116,20 @@ CpuDisableInterrupt (
|
||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
This function retrieves the processor's current interrupt state a returns it in
|
||||||
|
State. If interrupts are currently enabled, then TRUE is returned. If interrupts
|
||||||
|
are currently disabled, then FALSE is returned.
|
||||||
|
|
||||||
|
@param This The EFI_CPU_ARCH_PROTOCOL instance.
|
||||||
|
@param State A pointer to the processor's current interrupt state. Set to TRUE if
|
||||||
|
interrupts are enabled and FALSE if interrupts are disabled.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS The processor's current interrupt state was returned in State.
|
||||||
|
@retval EFI_INVALID_PARAMETER State is NULL.
|
||||||
|
|
||||||
|
**/
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
EFIAPI
|
EFIAPI
|
||||||
CpuGetInterruptState (
|
CpuGetInterruptState (
|
||||||
|
@ -82,6 +145,23 @@ CpuGetInterruptState (
|
||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
This function generates an INIT on the processor. If this function succeeds, then the
|
||||||
|
processor will be reset, and control will not be returned to the caller. If InitType is
|
||||||
|
not supported by this processor, or the processor cannot programmatically generate an
|
||||||
|
INIT without help from external hardware, then EFI_UNSUPPORTED is returned. If an error
|
||||||
|
occurs attempting to generate an INIT, then EFI_DEVICE_ERROR is returned.
|
||||||
|
|
||||||
|
@param This The EFI_CPU_ARCH_PROTOCOL instance.
|
||||||
|
@param InitType The type of processor INIT to perform.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS The processor INIT was performed. This return code should never be seen.
|
||||||
|
@retval EFI_UNSUPPORTED The processor INIT operation specified by InitType is not supported
|
||||||
|
by this processor.
|
||||||
|
@retval EFI_DEVICE_ERROR The processor INIT failed.
|
||||||
|
|
||||||
|
**/
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
EFIAPI
|
EFIAPI
|
||||||
CpuInit (
|
CpuInit (
|
||||||
|
@ -115,17 +195,6 @@ CpuGetTimerValue (
|
||||||
return EFI_UNSUPPORTED;
|
return EFI_UNSUPPORTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
EFI_STATUS
|
|
||||||
EFIAPI
|
|
||||||
CpuSetMemoryAttributes (
|
|
||||||
IN EFI_CPU_ARCH_PROTOCOL *This,
|
|
||||||
IN EFI_PHYSICAL_ADDRESS BaseAddress,
|
|
||||||
IN UINT64 Length,
|
|
||||||
IN UINT64 Attributes
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return EFI_UNSUPPORTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Globals used to initialize the protocol
|
// Globals used to initialize the protocol
|
||||||
|
@ -150,7 +219,25 @@ CpuDxeInitialize (
|
||||||
IN EFI_SYSTEM_TABLE *SystemTable
|
IN EFI_SYSTEM_TABLE *SystemTable
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
EFI_STATUS Status;
|
||||||
|
|
||||||
InitializeExceptions (&mCpu);
|
InitializeExceptions (&mCpu);
|
||||||
return gBS->InstallMultipleProtocolInterfaces (&mCpuHandle, &gEfiCpuArchProtocolGuid, &mCpu, NULL);
|
|
||||||
|
|
||||||
|
Status = gBS->InstallMultipleProtocolInterfaces (
|
||||||
|
&mCpuHandle,
|
||||||
|
&gEfiCpuArchProtocolGuid, &mCpu,
|
||||||
|
&gVirtualUncachedPagesProtocolGuid, &gVirtualUncachedPages,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Make sure GCD and MMU settings match. This API calls gDS->SetMemorySpaceAttributes ()
|
||||||
|
// and that calls EFI_CPU_ARCH_PROTOCOL.SetMemoryAttributes, so this code needs to go
|
||||||
|
// after the protocol is installed
|
||||||
|
//
|
||||||
|
SyncCacheConfig (&mCpu);
|
||||||
|
|
||||||
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,14 +19,29 @@
|
||||||
|
|
||||||
#include <Library/ArmLib.h>
|
#include <Library/ArmLib.h>
|
||||||
#include <Library/BaseMemoryLib.h>
|
#include <Library/BaseMemoryLib.h>
|
||||||
#include <Library/CacheMaintenanceLib.h>
|
|
||||||
#include <Library/DebugLib.h>
|
#include <Library/DebugLib.h>
|
||||||
#include <Library/PcdLib.h>
|
#include <Library/PcdLib.h>
|
||||||
#include <Library/UefiBootServicesTableLib.h>
|
#include <Library/UefiBootServicesTableLib.h>
|
||||||
|
#include <Library/DxeServicesTableLib.h>
|
||||||
|
#include <Library/CacheMaintenanceLib.h>
|
||||||
|
#include <Library/PeCoffGetEntryPointLib.h>
|
||||||
|
#include <Library/UefiLib.h>
|
||||||
|
#include <Library/CpuLib.h>
|
||||||
|
|
||||||
|
#include <Guid/DebugImageInfoTable.h>
|
||||||
#include <Protocol/Cpu.h>
|
#include <Protocol/Cpu.h>
|
||||||
#include <Protocol/DebugSupport.h>
|
#include <Protocol/DebugSupport.h>
|
||||||
#include <Protocol/DebugSupportPeriodicCallback.h>
|
#include <Protocol/DebugSupportPeriodicCallback.h>
|
||||||
|
#include <Protocol/VirtualUncachedPages.h>
|
||||||
|
#include <Protocol/LoadedImage.h>
|
||||||
|
|
||||||
|
|
||||||
|
#define EFI_MEMORY_CACHETYPE_MASK (EFI_MEMORY_UC | \
|
||||||
|
EFI_MEMORY_WC | \
|
||||||
|
EFI_MEMORY_WT | \
|
||||||
|
EFI_MEMORY_WB | \
|
||||||
|
EFI_MEMORY_UCE \
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -83,9 +98,31 @@ RegisterDebuggerInterruptHandler (
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
CpuSetMemoryAttributes (
|
||||||
|
IN EFI_CPU_ARCH_PROTOCOL *This,
|
||||||
|
IN EFI_PHYSICAL_ADDRESS BaseAddress,
|
||||||
|
IN UINT64 Length,
|
||||||
|
IN UINT64 Attributes
|
||||||
|
);
|
||||||
|
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
InitializeExceptions (
|
InitializeExceptions (
|
||||||
IN EFI_CPU_ARCH_PROTOCOL *Cpu
|
IN EFI_CPU_ARCH_PROTOCOL *Cpu
|
||||||
);
|
);
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
SyncCacheConfig (
|
||||||
|
IN EFI_CPU_ARCH_PROTOCOL *CpuProtocol
|
||||||
|
);
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
ConvertSectionToPages (
|
||||||
|
IN EFI_PHYSICAL_ADDRESS BaseAddress
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
extern VIRTUAL_UNCACHED_PAGES_PROTOCOL gVirtualUncachedPages;
|
||||||
|
|
||||||
#endif // __CPU_DXE_ARM_EXCEPTION_H__
|
#endif // __CPU_DXE_ARM_EXCEPTION_H__
|
||||||
|
|
|
@ -39,6 +39,7 @@
|
||||||
#
|
#
|
||||||
ExceptionSupport.ARMv6.asm | RVCT
|
ExceptionSupport.ARMv6.asm | RVCT
|
||||||
# ExceptionSupport.ARMv6.S | GCC
|
# ExceptionSupport.ARMv6.S | GCC
|
||||||
|
Mmu.c
|
||||||
|
|
||||||
[Packages]
|
[Packages]
|
||||||
ArmPkg/ArmPkg.dec
|
ArmPkg/ArmPkg.dec
|
||||||
|
@ -50,10 +51,18 @@
|
||||||
CacheMaintenanceLib
|
CacheMaintenanceLib
|
||||||
UefiDriverEntryPoint
|
UefiDriverEntryPoint
|
||||||
ArmLib
|
ArmLib
|
||||||
|
DxeServicesTableLib
|
||||||
|
PeCoffGetEntryPointLib
|
||||||
|
UefiLib
|
||||||
|
CpuLib
|
||||||
|
|
||||||
[Protocols]
|
[Protocols]
|
||||||
gEfiCpuArchProtocolGuid
|
gEfiCpuArchProtocolGuid
|
||||||
gEfiDebugSupportPeriodicCallbackProtocolGuid
|
gEfiDebugSupportPeriodicCallbackProtocolGuid
|
||||||
|
gVirtualUncachedPagesProtocolGuid
|
||||||
|
|
||||||
|
[Guids]
|
||||||
|
gEfiDebugImageInfoTableGuid
|
||||||
|
|
||||||
[Pcd.common]
|
[Pcd.common]
|
||||||
gArmTokenSpaceGuid.PcdCpuVectorBaseAddress
|
gArmTokenSpaceGuid.PcdCpuVectorBaseAddress
|
||||||
|
|
|
@ -13,7 +13,8 @@
|
||||||
**/
|
**/
|
||||||
|
|
||||||
#include "CpuDxe.h"
|
#include "CpuDxe.h"
|
||||||
#include <Library/CacheMaintenanceLib.h>
|
|
||||||
|
EFI_DEBUG_IMAGE_INFO_TABLE_HEADER *gDebugImageTableHeader = NULL;
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
ExceptionHandlersStart (
|
ExceptionHandlersStart (
|
||||||
|
@ -120,6 +121,76 @@ RegisterDebuggerInterruptHandler (
|
||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
UINT32
|
||||||
|
EFIAPI
|
||||||
|
PeCoffGetSizeOfHeaders (
|
||||||
|
IN VOID *Pe32Data
|
||||||
|
)
|
||||||
|
{
|
||||||
|
EFI_IMAGE_DOS_HEADER *DosHdr;
|
||||||
|
EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr;
|
||||||
|
UINTN SizeOfHeaders;
|
||||||
|
|
||||||
|
DosHdr = (EFI_IMAGE_DOS_HEADER *)Pe32Data;
|
||||||
|
if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) {
|
||||||
|
//
|
||||||
|
// DOS image header is present, so read the PE header after the DOS image header.
|
||||||
|
//
|
||||||
|
Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)((UINTN) Pe32Data + (UINTN) ((DosHdr->e_lfanew) & 0x0ffff));
|
||||||
|
} else {
|
||||||
|
//
|
||||||
|
// DOS image header is not present, so PE header is at the image base.
|
||||||
|
//
|
||||||
|
Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)Pe32Data;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Hdr.Te->Signature == EFI_TE_IMAGE_HEADER_SIGNATURE) {
|
||||||
|
SizeOfHeaders = sizeof (EFI_TE_IMAGE_HEADER) + (UINTN)Hdr.Te->BaseOfCode - (UINTN)Hdr.Te->StrippedSize;
|
||||||
|
} else if (Hdr.Pe32->Signature == EFI_IMAGE_NT_SIGNATURE) {
|
||||||
|
SizeOfHeaders = Hdr.Pe32->OptionalHeader.SizeOfHeaders;
|
||||||
|
}
|
||||||
|
|
||||||
|
return SizeOfHeaders;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
CHAR8 *
|
||||||
|
GetImageName (
|
||||||
|
IN UINT32 FaultAddress,
|
||||||
|
OUT UINT32 *ImageBase,
|
||||||
|
OUT UINT32 *PeCoffSizeOfHeaders
|
||||||
|
)
|
||||||
|
{
|
||||||
|
EFI_DEBUG_IMAGE_INFO *DebugTable;
|
||||||
|
UINTN Entry;
|
||||||
|
CHAR8 *Address;
|
||||||
|
|
||||||
|
|
||||||
|
DebugTable = gDebugImageTableHeader->EfiDebugImageInfoTable;
|
||||||
|
if (DebugTable == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
Address = (CHAR8 *)(UINTN)FaultAddress;
|
||||||
|
for (Entry = 0; Entry < gDebugImageTableHeader->TableSize; Entry++, DebugTable++) {
|
||||||
|
if (DebugTable->NormalImage != NULL) {
|
||||||
|
if ((DebugTable->NormalImage->ImageInfoType == EFI_DEBUG_IMAGE_INFO_TYPE_NORMAL) &&
|
||||||
|
(DebugTable->NormalImage->LoadedImageProtocolInstance != NULL)) {
|
||||||
|
if ((Address >= DebugTable->NormalImage->LoadedImageProtocolInstance->ImageBase) &&
|
||||||
|
(Address <= ((CHAR8 *)DebugTable->NormalImage->LoadedImageProtocolInstance->ImageBase + DebugTable->NormalImage->LoadedImageProtocolInstance->ImageSize))) {
|
||||||
|
*ImageBase = (UINT32)DebugTable->NormalImage->LoadedImageProtocolInstance->ImageBase;
|
||||||
|
*PeCoffSizeOfHeaders = PeCoffGetSizeOfHeaders ((VOID *)(UINTN)*ImageBase);
|
||||||
|
return PeCoffLoaderGetPdbPointer (DebugTable->NormalImage->LoadedImageProtocolInstance->ImageBase);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
CHAR8 *gExceptionTypeString[] = {
|
CHAR8 *gExceptionTypeString[] = {
|
||||||
"Reset",
|
"Reset",
|
||||||
"Undefined Instruction",
|
"Undefined Instruction",
|
||||||
|
@ -174,11 +245,41 @@ CommonCExceptionHandler (
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Code after here is the default exception handler...
|
// Code after here is the default exception handler... Dump the context
|
||||||
//
|
//
|
||||||
DEBUG ((EFI_D_ERROR, "%a Exception from %08x\n", gExceptionTypeString[ExceptionType], SystemContext.SystemContextArm->PC));
|
DEBUG ((EFI_D_ERROR, "\n%a Exception from instruction at 0x%08x CPSR 0x%08x\n", gExceptionTypeString[ExceptionType], SystemContext.SystemContextArm->PC, SystemContext.SystemContextArm->CPSR));
|
||||||
ASSERT (FALSE);
|
DEBUG_CODE_BEGIN ();
|
||||||
|
CHAR8 *Pdb;
|
||||||
|
UINT32 ImageBase;
|
||||||
|
UINT32 PeCoffSizeOfHeader;
|
||||||
|
UINT32 Offset;
|
||||||
|
|
||||||
|
Pdb = GetImageName (SystemContext.SystemContextArm->PC, &ImageBase, &PeCoffSizeOfHeader);
|
||||||
|
Offset = SystemContext.SystemContextArm->PC - ImageBase;
|
||||||
|
if (Pdb != NULL) {
|
||||||
|
DEBUG ((EFI_D_ERROR, "%a\n", Pdb));
|
||||||
|
|
||||||
|
//
|
||||||
|
// A PE/COFF image loads its headers into memory so the headers are
|
||||||
|
// included in the linked addressess. ELF and Mach-O images do not
|
||||||
|
// include the headers so the first byte of the image is usually
|
||||||
|
// text (code). If you look at link maps from ELF or Mach-O images
|
||||||
|
// you need to subtact out the size of the PE/COFF header to get
|
||||||
|
// get the offset that matches the link map.
|
||||||
|
//
|
||||||
|
DEBUG ((EFI_D_ERROR, "loadded at 0x%08x (PE/COFF offset) 0x%08x (ELF or Mach-O offset) 0x%08x\n", ImageBase, Offset, Offset - PeCoffSizeOfHeader));
|
||||||
|
}
|
||||||
|
DEBUG_CODE_END ();
|
||||||
|
DEBUG ((EFI_D_ERROR, " R0 0x%08x R1 0x%08x R2 0x%08x R3 0x%08x\n", SystemContext.SystemContextArm->R0, SystemContext.SystemContextArm->R1, SystemContext.SystemContextArm->R2, SystemContext.SystemContextArm->R3));
|
||||||
|
DEBUG ((EFI_D_ERROR, " R4 0x%08x R5 0x%08x R6 0x%08x R7 0x%08x\n", SystemContext.SystemContextArm->R4, SystemContext.SystemContextArm->R5, SystemContext.SystemContextArm->R6, SystemContext.SystemContextArm->R7));
|
||||||
|
DEBUG ((EFI_D_ERROR, " R8 0x%08x R9 0x%08x R10 0x%08x R11 0x%08x\n", SystemContext.SystemContextArm->R8, SystemContext.SystemContextArm->R9, SystemContext.SystemContextArm->R10, SystemContext.SystemContextArm->R11));
|
||||||
|
DEBUG ((EFI_D_ERROR, "R12 0x%08x SP 0x%08x LR 0x%08x PC 0x%08x\n", SystemContext.SystemContextArm->R12, SystemContext.SystemContextArm->SP, SystemContext.SystemContextArm->LR, SystemContext.SystemContextArm->PC));
|
||||||
|
DEBUG ((EFI_D_ERROR, "DFSR 0x%08x DFAR 0x%08x IFSR 0x%08x IFAR 0x%08x\n\n", SystemContext.SystemContextArm->DFSR, SystemContext.SystemContextArm->DFAR, SystemContext.SystemContextArm->IFSR, SystemContext.SystemContextArm->IFAR));
|
||||||
|
|
||||||
|
ASSERT (FALSE);
|
||||||
|
// while (TRUE) {
|
||||||
|
// CpuSleep ();
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -195,6 +296,11 @@ InitializeExceptions (
|
||||||
BOOLEAN Enabled;
|
BOOLEAN Enabled;
|
||||||
EFI_PHYSICAL_ADDRESS Base;
|
EFI_PHYSICAL_ADDRESS Base;
|
||||||
|
|
||||||
|
Status = EfiGetSystemConfigurationTable (&gEfiDebugImageInfoTableGuid, (VOID **)&gDebugImageTableHeader);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
gDebugImageTableHeader = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Disable interrupts
|
// Disable interrupts
|
||||||
//
|
//
|
||||||
|
|
|
@ -16,6 +16,11 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||||
|
|
||||||
#include "CpuDxe.h"
|
#include "CpuDxe.h"
|
||||||
|
|
||||||
|
//
|
||||||
|
// For debug switch me back to to EFI_D_PAGE when done
|
||||||
|
//
|
||||||
|
#define L_EFI_D_PAGE EFI_D_ERROR
|
||||||
|
|
||||||
//
|
//
|
||||||
// Translation/page table definitions
|
// Translation/page table definitions
|
||||||
//
|
//
|
||||||
|
@ -170,13 +175,12 @@ SectionToGcdAttributes (
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return EFI_UNSUPPORTED;
|
return EFI_UNSUPPORTED;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// determine protection attributes
|
// determine protection attributes
|
||||||
switch(SectionAttributes & ARM_SECTION_RW_PERMISSIONS_MASK) {
|
switch(SectionAttributes & ARM_SECTION_RW_PERMISSIONS_MASK) {
|
||||||
case ARM_SECTION_NO_ACCESS: // no read, no write
|
case ARM_SECTION_NO_ACCESS: // no read, no write
|
||||||
*GcdAttributes |= EFI_MEMORY_WP | EFI_MEMORY_RP;
|
//*GcdAttributes |= EFI_MEMORY_WP | EFI_MEMORY_RP;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ARM_SECTION_PRIV_ACCESS_ONLY:
|
case ARM_SECTION_PRIV_ACCESS_ONLY:
|
||||||
|
@ -193,7 +197,6 @@ SectionToGcdAttributes (
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return EFI_UNSUPPORTED;
|
return EFI_UNSUPPORTED;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// now process eXectue Never attribute
|
// now process eXectue Never attribute
|
||||||
|
@ -204,6 +207,132 @@ SectionToGcdAttributes (
|
||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Searches memory descriptors covered by given memory range.
|
||||||
|
|
||||||
|
This function searches into the Gcd Memory Space for descriptors
|
||||||
|
(from StartIndex to EndIndex) that contains the memory range
|
||||||
|
specified by BaseAddress and Length.
|
||||||
|
|
||||||
|
@param MemorySpaceMap Gcd Memory Space Map as array.
|
||||||
|
@param NumberOfDescriptors Number of descriptors in map.
|
||||||
|
@param BaseAddress BaseAddress for the requested range.
|
||||||
|
@param Length Length for the requested range.
|
||||||
|
@param StartIndex Start index into the Gcd Memory Space Map.
|
||||||
|
@param EndIndex End index into the Gcd Memory Space Map.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS Search successfully.
|
||||||
|
@retval EFI_NOT_FOUND The requested descriptors does not exist.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
SearchGcdMemorySpaces (
|
||||||
|
IN EFI_GCD_MEMORY_SPACE_DESCRIPTOR *MemorySpaceMap,
|
||||||
|
IN UINTN NumberOfDescriptors,
|
||||||
|
IN EFI_PHYSICAL_ADDRESS BaseAddress,
|
||||||
|
IN UINT64 Length,
|
||||||
|
OUT UINTN *StartIndex,
|
||||||
|
OUT UINTN *EndIndex
|
||||||
|
)
|
||||||
|
{
|
||||||
|
UINTN Index;
|
||||||
|
|
||||||
|
*StartIndex = 0;
|
||||||
|
*EndIndex = 0;
|
||||||
|
for (Index = 0; Index < NumberOfDescriptors; Index++) {
|
||||||
|
if (BaseAddress >= MemorySpaceMap[Index].BaseAddress &&
|
||||||
|
BaseAddress < MemorySpaceMap[Index].BaseAddress + MemorySpaceMap[Index].Length) {
|
||||||
|
*StartIndex = Index;
|
||||||
|
}
|
||||||
|
if (BaseAddress + Length - 1 >= MemorySpaceMap[Index].BaseAddress &&
|
||||||
|
BaseAddress + Length - 1 < MemorySpaceMap[Index].BaseAddress + MemorySpaceMap[Index].Length) {
|
||||||
|
*EndIndex = Index;
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return EFI_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Sets the attributes for a specified range in Gcd Memory Space Map.
|
||||||
|
|
||||||
|
This function sets the attributes for a specified range in
|
||||||
|
Gcd Memory Space Map.
|
||||||
|
|
||||||
|
@param MemorySpaceMap Gcd Memory Space Map as array
|
||||||
|
@param NumberOfDescriptors Number of descriptors in map
|
||||||
|
@param BaseAddress BaseAddress for the range
|
||||||
|
@param Length Length for the range
|
||||||
|
@param Attributes Attributes to set
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS Memory attributes set successfully
|
||||||
|
@retval EFI_NOT_FOUND The specified range does not exist in Gcd Memory Space
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
SetGcdMemorySpaceAttributes (
|
||||||
|
IN EFI_GCD_MEMORY_SPACE_DESCRIPTOR *MemorySpaceMap,
|
||||||
|
IN UINTN NumberOfDescriptors,
|
||||||
|
IN EFI_PHYSICAL_ADDRESS BaseAddress,
|
||||||
|
IN UINT64 Length,
|
||||||
|
IN UINT64 Attributes
|
||||||
|
)
|
||||||
|
{
|
||||||
|
EFI_STATUS Status;
|
||||||
|
UINTN Index;
|
||||||
|
UINTN StartIndex;
|
||||||
|
UINTN EndIndex;
|
||||||
|
EFI_PHYSICAL_ADDRESS RegionStart;
|
||||||
|
UINT64 RegionLength;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Get all memory descriptors covered by the memory range
|
||||||
|
//
|
||||||
|
Status = SearchGcdMemorySpaces (
|
||||||
|
MemorySpaceMap,
|
||||||
|
NumberOfDescriptors,
|
||||||
|
BaseAddress,
|
||||||
|
Length,
|
||||||
|
&StartIndex,
|
||||||
|
&EndIndex
|
||||||
|
);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Go through all related descriptors and set attributes accordingly
|
||||||
|
//
|
||||||
|
for (Index = StartIndex; Index <= EndIndex; Index++) {
|
||||||
|
if (MemorySpaceMap[Index].GcdMemoryType == EfiGcdMemoryTypeNonExistent) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Calculate the start and end address of the overlapping range
|
||||||
|
//
|
||||||
|
if (BaseAddress >= MemorySpaceMap[Index].BaseAddress) {
|
||||||
|
RegionStart = BaseAddress;
|
||||||
|
} else {
|
||||||
|
RegionStart = MemorySpaceMap[Index].BaseAddress;
|
||||||
|
}
|
||||||
|
if (BaseAddress + Length - 1 < MemorySpaceMap[Index].BaseAddress + MemorySpaceMap[Index].Length) {
|
||||||
|
RegionLength = BaseAddress + Length - RegionStart;
|
||||||
|
} else {
|
||||||
|
RegionLength = MemorySpaceMap[Index].BaseAddress + MemorySpaceMap[Index].Length - RegionStart;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Set memory attributes according to MTRR attribute and the original attribute of descriptor
|
||||||
|
//
|
||||||
|
gDS->SetMemorySpaceAttributes (
|
||||||
|
RegionStart,
|
||||||
|
RegionLength,
|
||||||
|
(MemorySpaceMap[Index].Attributes & ~EFI_MEMORY_CACHETYPE_MASK) | (MemorySpaceMap[Index].Capabilities & Attributes)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
|
@ -211,20 +340,31 @@ SyncCacheConfig (
|
||||||
IN EFI_CPU_ARCH_PROTOCOL *CpuProtocol
|
IN EFI_CPU_ARCH_PROTOCOL *CpuProtocol
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
UINT32 i;
|
UINT32 i;
|
||||||
UINT32 Descriptor;
|
UINT32 Descriptor;
|
||||||
UINT32 SectionAttributes;
|
UINT32 SectionAttributes;
|
||||||
EFI_PHYSICAL_ADDRESS NextRegionBase;
|
EFI_PHYSICAL_ADDRESS NextRegionBase;
|
||||||
UINT64 NextRegionLength;
|
UINT64 NextRegionLength;
|
||||||
UINT64 GcdAttributes;
|
UINT64 GcdAttributes;
|
||||||
UINT32 NextRegionAttributes = 0;
|
UINT32 NextRegionAttributes = 0;
|
||||||
volatile ARM_FIRST_LEVEL_DESCRIPTOR *FirstLevelTable;
|
volatile ARM_FIRST_LEVEL_DESCRIPTOR *FirstLevelTable;
|
||||||
|
UINTN NumberOfDescriptors;
|
||||||
|
EFI_GCD_MEMORY_SPACE_DESCRIPTOR *MemorySpaceMap;
|
||||||
|
|
||||||
|
|
||||||
|
DEBUG ((L_EFI_D_PAGE, "SyncCacheConfig()\n"));
|
||||||
|
|
||||||
// This code assumes MMU is enabled and filed with section translations
|
// This code assumes MMU is enabled and filed with section translations
|
||||||
ASSERT (ArmMmuEnabled ());
|
ASSERT (ArmMmuEnabled ());
|
||||||
|
|
||||||
|
//
|
||||||
|
// Get the memory space map from GCD
|
||||||
|
//
|
||||||
|
MemorySpaceMap = NULL;
|
||||||
|
Status = gDS->GetMemorySpaceMap (&NumberOfDescriptors, &MemorySpaceMap);
|
||||||
|
ASSERT_EFI_ERROR (Status);
|
||||||
|
|
||||||
|
|
||||||
// The GCD implementation maintains its own copy of the state of memory space attributes. GCD needs
|
// The GCD implementation maintains its own copy of the state of memory space attributes. GCD needs
|
||||||
// to know what the initial memory space attributes are. The CPU Arch. Protocol does not provide a
|
// to know what the initial memory space attributes are. The CPU Arch. Protocol does not provide a
|
||||||
|
@ -240,8 +380,8 @@ SyncCacheConfig (
|
||||||
NextRegionBase = NextRegionLength = 0;
|
NextRegionBase = NextRegionLength = 0;
|
||||||
for (i=0; i< FIRST_LEVEL_ENTRY_COUNT; i++) {
|
for (i=0; i< FIRST_LEVEL_ENTRY_COUNT; i++) {
|
||||||
|
|
||||||
// obtain existing descriptor
|
// obtain existing descriptor and make sure it contains a valid Base Address even if it is a fault section
|
||||||
Descriptor = FirstLevelTable[i];
|
Descriptor = FirstLevelTable[i] | (ARM_SECTION_BASE_MASK & (i << ARM_SECTION_BASE_SHIFT));
|
||||||
|
|
||||||
// extract attributes (cacheability and permissions)
|
// extract attributes (cacheability and permissions)
|
||||||
SectionAttributes = Descriptor & 0xDEC;
|
SectionAttributes = Descriptor & 0xDEC;
|
||||||
|
@ -254,11 +394,11 @@ SyncCacheConfig (
|
||||||
|
|
||||||
// convert section entry attributes to GCD bitmask
|
// convert section entry attributes to GCD bitmask
|
||||||
Status = SectionToGcdAttributes (NextRegionAttributes, &GcdAttributes);
|
Status = SectionToGcdAttributes (NextRegionAttributes, &GcdAttributes);
|
||||||
ASSERT_EFI_ERROR(Status);
|
ASSERT_EFI_ERROR (Status);
|
||||||
|
|
||||||
// update GCD with these changes (this will recurse into our own CpuSetMemoryAttributes below which is OK)
|
// update GCD with these changes (this will recurse into our own CpuSetMemoryAttributes below which is OK)
|
||||||
Status = gDS->SetMemorySpaceAttributes (NextRegionBase, NextRegionLength, GcdAttributes);
|
SetGcdMemorySpaceAttributes (MemorySpaceMap, NumberOfDescriptors, NextRegionBase, NextRegionLength, GcdAttributes);
|
||||||
ASSERT_EFI_ERROR(Status);
|
|
||||||
|
|
||||||
// start on a new region
|
// start on a new region
|
||||||
NextRegionLength = 0;
|
NextRegionLength = 0;
|
||||||
|
@ -343,12 +483,11 @@ UpdatePageEntries (
|
||||||
// Cause a page fault if these ranges are accessed.
|
// Cause a page fault if these ranges are accessed.
|
||||||
EntryMask = 0x3;
|
EntryMask = 0x3;
|
||||||
EntryValue = 0;
|
EntryValue = 0;
|
||||||
DEBUG ((EFI_D_PAGE, "SetMemoryAttributes(): setting page %lx with unsupported attribute %x will page fault on access\n", BaseAddress, Attributes));
|
DEBUG ((L_EFI_D_PAGE, "SetMemoryAttributes(): setting page %lx with unsupported attribute %x will page fault on access\n", BaseAddress, Attributes));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return EFI_UNSUPPORTED;
|
return EFI_UNSUPPORTED;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// obtain page table base
|
// obtain page table base
|
||||||
|
@ -369,7 +508,7 @@ UpdatePageEntries (
|
||||||
Descriptor = FirstLevelTable[FirstLevelIdx];
|
Descriptor = FirstLevelTable[FirstLevelIdx];
|
||||||
|
|
||||||
// does this descriptor need to be converted from section entry to 4K pages?
|
// does this descriptor need to be converted from section entry to 4K pages?
|
||||||
if ((Descriptor & ARM_DESC_TYPE_MASK) == ARM_DESC_TYPE_SECTION ) {
|
if ((Descriptor & ARM_DESC_TYPE_MASK) != ARM_DESC_TYPE_PAGE_TABLE ) {
|
||||||
Status = ConvertSectionToPages (FirstLevelIdx << ARM_SECTION_BASE_SHIFT);
|
Status = ConvertSectionToPages (FirstLevelIdx << ARM_SECTION_BASE_SHIFT);
|
||||||
if (EFI_ERROR(Status)) {
|
if (EFI_ERROR(Status)) {
|
||||||
// exit for loop
|
// exit for loop
|
||||||
|
@ -385,7 +524,7 @@ UpdatePageEntries (
|
||||||
|
|
||||||
// calculate index into the page table
|
// calculate index into the page table
|
||||||
PageTableIndex = ((BaseAddress + Offset) & ARM_SMALL_PAGE_INDEX_MASK) >> ARM_SMALL_PAGE_BASE_SHIFT;
|
PageTableIndex = ((BaseAddress + Offset) & ARM_SMALL_PAGE_INDEX_MASK) >> ARM_SMALL_PAGE_BASE_SHIFT;
|
||||||
ASSERT(PageTableIndex < SMALL_PAGE_TABLE_ENTRY_COUNT);
|
ASSERT (PageTableIndex < SMALL_PAGE_TABLE_ENTRY_COUNT);
|
||||||
|
|
||||||
// get the entry
|
// get the entry
|
||||||
PageTableEntry = PageTable[PageTableIndex];
|
PageTableEntry = PageTable[PageTableIndex];
|
||||||
|
@ -436,35 +575,39 @@ UpdateSectionEntries (
|
||||||
// EntryMask: bitmask of values to change (1 = change this value, 0 = leave alone)
|
// EntryMask: bitmask of values to change (1 = change this value, 0 = leave alone)
|
||||||
// EntryValue: values at bit positions specified by EntryMask
|
// EntryValue: values at bit positions specified by EntryMask
|
||||||
|
|
||||||
|
// Make sure we handle a section range that is unmapped
|
||||||
|
EntryMask = ARM_DESC_TYPE_MASK;
|
||||||
|
EntryValue = ARM_DESC_TYPE_SECTION;
|
||||||
|
|
||||||
// Although the PI spec is unclear on this the GCD guarantees that only
|
// Although the PI spec is unclear on this the GCD guarantees that only
|
||||||
// one Attribute bit is set at a time, so we can safely use a switch statement
|
// one Attribute bit is set at a time, so we can safely use a switch statement
|
||||||
switch(Attributes) {
|
switch(Attributes) {
|
||||||
case EFI_MEMORY_UC:
|
case EFI_MEMORY_UC:
|
||||||
// modify cacheability attributes
|
// modify cacheability attributes
|
||||||
EntryMask = ARM_SECTION_TEX_MASK | ARM_SECTION_C | ARM_SECTION_B;
|
EntryMask |= ARM_SECTION_TEX_MASK | ARM_SECTION_C | ARM_SECTION_B;
|
||||||
// map to strongly ordered
|
// map to strongly ordered
|
||||||
EntryValue = 0; // TEX[2:0] = 0, C=0, B=0
|
EntryValue |= 0; // TEX[2:0] = 0, C=0, B=0
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EFI_MEMORY_WC:
|
case EFI_MEMORY_WC:
|
||||||
// modify cacheability attributes
|
// modify cacheability attributes
|
||||||
EntryMask = ARM_SECTION_TEX_MASK | ARM_SECTION_C | ARM_SECTION_B;
|
EntryMask |= ARM_SECTION_TEX_MASK | ARM_SECTION_C | ARM_SECTION_B;
|
||||||
// map to normal non-cachable
|
// map to normal non-cachable
|
||||||
EntryValue = (0x1 << ARM_SECTION_TEX_SHIFT); // TEX [2:0]= 001 = 0x2, B=0, C=0
|
EntryValue |= (0x1 << ARM_SECTION_TEX_SHIFT); // TEX [2:0]= 001 = 0x2, B=0, C=0
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EFI_MEMORY_WT:
|
case EFI_MEMORY_WT:
|
||||||
// modify cacheability attributes
|
// modify cacheability attributes
|
||||||
EntryMask = ARM_SECTION_TEX_MASK | ARM_SECTION_C | ARM_SECTION_B;
|
EntryMask |= ARM_SECTION_TEX_MASK | ARM_SECTION_C | ARM_SECTION_B;
|
||||||
// write through with no-allocate
|
// write through with no-allocate
|
||||||
EntryValue = ARM_SECTION_C; // TEX [2:0] = 0, C=1, B=0
|
EntryValue |= ARM_SECTION_C; // TEX [2:0] = 0, C=1, B=0
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EFI_MEMORY_WB:
|
case EFI_MEMORY_WB:
|
||||||
// modify cacheability attributes
|
// modify cacheability attributes
|
||||||
EntryMask = ARM_SECTION_TEX_MASK | ARM_SECTION_C | ARM_SECTION_B;
|
EntryMask |= ARM_SECTION_TEX_MASK | ARM_SECTION_C | ARM_SECTION_B;
|
||||||
// write back (with allocate)
|
// write back (with allocate)
|
||||||
EntryValue = (0x1 << ARM_SECTION_TEX_SHIFT) | ARM_SECTION_C | ARM_SECTION_B; // TEX [2:0] = 001, C=1, B=1
|
EntryValue |= (0x1 << ARM_SECTION_TEX_SHIFT) | ARM_SECTION_C | ARM_SECTION_B; // TEX [2:0] = 001, C=1, B=1
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EFI_MEMORY_WP:
|
case EFI_MEMORY_WP:
|
||||||
|
@ -473,15 +616,13 @@ UpdateSectionEntries (
|
||||||
case EFI_MEMORY_UCE:
|
case EFI_MEMORY_UCE:
|
||||||
// cannot be implemented UEFI definition unclear for ARM
|
// cannot be implemented UEFI definition unclear for ARM
|
||||||
// Cause a page fault if these ranges are accessed.
|
// Cause a page fault if these ranges are accessed.
|
||||||
EntryMask = 0x3;
|
EntryValue = ARM_DESC_TYPE_FAULT;
|
||||||
EntryValue = 0;
|
DEBUG ((L_EFI_D_PAGE, "SetMemoryAttributes(): setting section %lx with unsupported attribute %x will page fault on access\n", BaseAddress, Attributes));
|
||||||
DEBUG ((EFI_D_PAGE, "SetMemoryAttributes(): setting section %lx with unsupported attribute %x will page fault on access\n", BaseAddress, Attributes));
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return EFI_UNSUPPORTED;
|
return EFI_UNSUPPORTED;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// obtain page table base
|
// obtain page table base
|
||||||
|
@ -499,7 +640,7 @@ UpdateSectionEntries (
|
||||||
Descriptor = FirstLevelTable[FirstLevelIdx + i];
|
Descriptor = FirstLevelTable[FirstLevelIdx + i];
|
||||||
|
|
||||||
// has this descriptor already been coverted to pages?
|
// has this descriptor already been coverted to pages?
|
||||||
if ((Descriptor & ARM_DESC_TYPE_MASK) == ARM_DESC_TYPE_PAGE_TABLE ) {
|
if ((Descriptor & ARM_DESC_TYPE_MASK) != ARM_DESC_TYPE_PAGE_TABLE ) {
|
||||||
// forward this 1MB range to page table function instead
|
// forward this 1MB range to page table function instead
|
||||||
Status = UpdatePageEntries ((FirstLevelIdx + i) << ARM_SECTION_BASE_SHIFT, ARM_PAGE_DESC_ENTRY_MVA_SIZE, Attributes, VirtualMask);
|
Status = UpdatePageEntries ((FirstLevelIdx + i) << ARM_SECTION_BASE_SHIFT, ARM_PAGE_DESC_ENTRY_MVA_SIZE, Attributes, VirtualMask);
|
||||||
} else {
|
} else {
|
||||||
|
@ -539,14 +680,14 @@ ConvertSectionToPages (
|
||||||
volatile ARM_FIRST_LEVEL_DESCRIPTOR *FirstLevelTable;
|
volatile ARM_FIRST_LEVEL_DESCRIPTOR *FirstLevelTable;
|
||||||
volatile ARM_PAGE_TABLE_ENTRY *PageTable;
|
volatile ARM_PAGE_TABLE_ENTRY *PageTable;
|
||||||
|
|
||||||
DEBUG ((EFI_D_PAGE, "Converting section at 0x%x to pages\n", (UINTN)BaseAddress));
|
DEBUG ((L_EFI_D_PAGE, "Converting section at 0x%x to pages\n", (UINTN)BaseAddress));
|
||||||
|
|
||||||
// obtain page table base
|
// obtain page table base
|
||||||
FirstLevelTable = (ARM_FIRST_LEVEL_DESCRIPTOR *)ArmGetTranslationTableBaseAddress ();
|
FirstLevelTable = (ARM_FIRST_LEVEL_DESCRIPTOR *)ArmGetTranslationTableBaseAddress ();
|
||||||
|
|
||||||
// calculate index into first level translation table for start of modification
|
// calculate index into first level translation table for start of modification
|
||||||
FirstLevelIdx = (BaseAddress & ARM_SECTION_BASE_MASK) >> ARM_SECTION_BASE_SHIFT;
|
FirstLevelIdx = (BaseAddress & ARM_SECTION_BASE_MASK) >> ARM_SECTION_BASE_SHIFT;
|
||||||
ASSERT(FirstLevelIdx < FIRST_LEVEL_ENTRY_COUNT);
|
ASSERT (FirstLevelIdx < FIRST_LEVEL_ENTRY_COUNT);
|
||||||
|
|
||||||
// get section attributes and convert to page attributes
|
// get section attributes and convert to page attributes
|
||||||
SectionDescriptor = FirstLevelTable[FirstLevelIdx];
|
SectionDescriptor = FirstLevelTable[FirstLevelIdx];
|
||||||
|
@ -588,7 +729,9 @@ ConvertSectionToPages (
|
||||||
// flush d-cache so descriptors make it back to uncached memory for subsequent table walks
|
// flush d-cache so descriptors make it back to uncached memory for subsequent table walks
|
||||||
// TODO: change to use only PageTable base and length
|
// TODO: change to use only PageTable base and length
|
||||||
// ArmInvalidateDataCache ();
|
// ArmInvalidateDataCache ();
|
||||||
InvalidateDataCacheRange ((VOID *)&PageTableAddr, EFI_PAGE_SIZE);
|
DEBUG ((EFI_D_ERROR, "InvalidateDataCacheRange (%x, %x)\n", (UINTN)PageTableAddr, EFI_PAGE_SIZE));
|
||||||
|
|
||||||
|
InvalidateDataCacheRange ((VOID *)(UINTN)PageTableAddr, EFI_PAGE_SIZE);
|
||||||
|
|
||||||
// formulate page table entry, Domain=0, NS=0
|
// formulate page table entry, Domain=0, NS=0
|
||||||
PageTableDescriptor = (((UINTN)PageTableAddr) & ARM_PAGE_DESC_BASE_MASK) | ARM_DESC_TYPE_PAGE_TABLE;
|
PageTableDescriptor = (((UINTN)PageTableAddr) & ARM_PAGE_DESC_BASE_MASK) | ARM_DESC_TYPE_PAGE_TABLE;
|
||||||
|
@ -613,11 +756,11 @@ SetMemoryAttributes (
|
||||||
|
|
||||||
if(((BaseAddress & 0xFFFFF) == 0) && ((Length & 0xFFFFF) == 0)) {
|
if(((BaseAddress & 0xFFFFF) == 0) && ((Length & 0xFFFFF) == 0)) {
|
||||||
// is the base and length a multiple of 1 MB?
|
// is the base and length a multiple of 1 MB?
|
||||||
DEBUG ((EFI_D_PAGE, "SetMemoryAttributes(): MMU section 0x%x length 0x%x to %lx\n", (UINTN)BaseAddress, (UINTN)Length, Attributes));
|
DEBUG ((L_EFI_D_PAGE, "SetMemoryAttributes(): MMU section 0x%x length 0x%x to %lx\n", (UINTN)BaseAddress, (UINTN)Length, Attributes));
|
||||||
Status = UpdateSectionEntries (BaseAddress, Length, Attributes, VirtualMask);
|
Status = UpdateSectionEntries (BaseAddress, Length, Attributes, VirtualMask);
|
||||||
} else {
|
} else {
|
||||||
// base and/or length is not a multiple of 1 MB
|
// base and/or length is not a multiple of 1 MB
|
||||||
DEBUG ((EFI_D_PAGE, "SetMemoryAttributes(): MMU page 0x%x length 0x%x to %lx\n", (UINTN)BaseAddress, (UINTN)Length, Attributes));
|
DEBUG ((L_EFI_D_PAGE, "SetMemoryAttributes(): MMU page 0x%x length 0x%x to %lx\n", (UINTN)BaseAddress, (UINTN)Length, Attributes));
|
||||||
Status = UpdatePageEntries (BaseAddress, Length, Attributes, VirtualMask);
|
Status = UpdatePageEntries (BaseAddress, Length, Attributes, VirtualMask);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -664,8 +807,10 @@ CpuSetMemoryAttributes (
|
||||||
IN UINT64 Attributes
|
IN UINT64 Attributes
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
DEBUG ((L_EFI_D_PAGE, "SetMemoryAttributes(%lx, %lx, %lx)\n", BaseAddress, Length, Attributes));
|
||||||
if ( ((BaseAddress & (EFI_PAGE_SIZE-1)) != 0) || ((Length & (EFI_PAGE_SIZE-1)) != 0)){
|
if ( ((BaseAddress & (EFI_PAGE_SIZE-1)) != 0) || ((Length & (EFI_PAGE_SIZE-1)) != 0)){
|
||||||
// minimum granularity is EFI_PAGE_SIZE (4KB on ARM)
|
// minimum granularity is EFI_PAGE_SIZE (4KB on ARM)
|
||||||
|
DEBUG ((L_EFI_D_PAGE, "SetMemoryAttributes(%lx, %lx, %lx): minimum ganularity is EFI_PAGE_SIZE\n", BaseAddress, Length, Attributes));
|
||||||
return EFI_UNSUPPORTED;
|
return EFI_UNSUPPORTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -698,13 +843,13 @@ CpuConvertPagesToUncachedVirtualAddress (
|
||||||
*Attributes = GcdDescriptor.Attributes;
|
*Attributes = GcdDescriptor.Attributes;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ASSERT (FALSE);
|
||||||
//
|
//
|
||||||
// Make this address range page fault if accessed. If it is a DMA buffer than this would
|
// Make this address range page fault if accessed. If it is a DMA buffer than this would
|
||||||
// be the PCI address. Code should always use the CPU address, and we will or in VirtualMask
|
// be the PCI address. Code should always use the CPU address, and we will or in VirtualMask
|
||||||
// to that address.
|
// to that address.
|
||||||
//
|
//
|
||||||
Status = SetMemoryAttributes (Address, Length, EFI_MEMORY_XP, 0);
|
Status = SetMemoryAttributes (Address, Length, EFI_MEMORY_WP, 0);
|
||||||
if (!EFI_ERROR (Status)) {
|
if (!EFI_ERROR (Status)) {
|
||||||
Status = SetMemoryAttributes (Address | VirtualMask, Length, EFI_MEMORY_UC, VirtualMask);
|
Status = SetMemoryAttributes (Address | VirtualMask, Length, EFI_MEMORY_UC, VirtualMask);
|
||||||
}
|
}
|
||||||
|
@ -715,7 +860,7 @@ CpuConvertPagesToUncachedVirtualAddress (
|
||||||
|
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
EFIAPI
|
EFIAPI
|
||||||
CpuFreeConvertedPages (
|
CpuReconvertPagesPages (
|
||||||
IN VIRTUAL_UNCACHED_PAGES_PROTOCOL *This,
|
IN VIRTUAL_UNCACHED_PAGES_PROTOCOL *This,
|
||||||
IN EFI_PHYSICAL_ADDRESS Address,
|
IN EFI_PHYSICAL_ADDRESS Address,
|
||||||
IN UINTN Length,
|
IN UINTN Length,
|
||||||
|
@ -728,7 +873,7 @@ CpuFreeConvertedPages (
|
||||||
//
|
//
|
||||||
// Unmap the alaised Address
|
// Unmap the alaised Address
|
||||||
//
|
//
|
||||||
Status = SetMemoryAttributes (Address | VirtualMask, Length, EFI_MEMORY_XP, 0);
|
Status = SetMemoryAttributes (Address | VirtualMask, Length, EFI_MEMORY_WP, 0);
|
||||||
if (!EFI_ERROR (Status)) {
|
if (!EFI_ERROR (Status)) {
|
||||||
//
|
//
|
||||||
// Restore atttributes
|
// Restore atttributes
|
||||||
|
@ -742,7 +887,7 @@ CpuFreeConvertedPages (
|
||||||
|
|
||||||
VIRTUAL_UNCACHED_PAGES_PROTOCOL gVirtualUncachedPages = {
|
VIRTUAL_UNCACHED_PAGES_PROTOCOL gVirtualUncachedPages = {
|
||||||
CpuConvertPagesToUncachedVirtualAddress,
|
CpuConvertPagesToUncachedVirtualAddress,
|
||||||
CpuFreeConvertedPages
|
CpuReconvertPagesPages
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -263,6 +263,7 @@ ArmSetTranslationTableBaseAddress (
|
||||||
VOID *
|
VOID *
|
||||||
EFIAPI
|
EFIAPI
|
||||||
ArmGetTranslationTableBaseAddress (
|
ArmGetTranslationTableBaseAddress (
|
||||||
|
VOID
|
||||||
);
|
);
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
|
|
|
@ -52,7 +52,7 @@ EFI_STATUS
|
||||||
|
|
||||||
struct _VIRTUAL_UNCACHED_PAGES_PROTOCOL {
|
struct _VIRTUAL_UNCACHED_PAGES_PROTOCOL {
|
||||||
CONVERT_PAGES_TO_UNCACHED_VIRTUAL_ADDRESS ConvertPages;
|
CONVERT_PAGES_TO_UNCACHED_VIRTUAL_ADDRESS ConvertPages;
|
||||||
FREE_CONVERTED_PAGES FreeConvertedPages;
|
FREE_CONVERTED_PAGES RevertPages;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern EFI_GUID gVirtualUncachedPagesProtocolGuid;
|
extern EFI_GUID gVirtualUncachedPagesProtocolGuid;
|
||||||
|
|
|
@ -27,19 +27,15 @@ CacheRangeOperation (
|
||||||
UINTN ArmCacheLineAlignmentMask = ArmCacheLineLength - 1;
|
UINTN ArmCacheLineAlignmentMask = ArmCacheLineLength - 1;
|
||||||
UINTN ArmCacheOperationThreshold = PcdGet32(PcdArmCacheOperationThreshold);
|
UINTN ArmCacheOperationThreshold = PcdGet32(PcdArmCacheOperationThreshold);
|
||||||
|
|
||||||
if ((CacheOperation != NULL) && (Length >= ArmCacheOperationThreshold))
|
if ((CacheOperation != NULL) && (Length >= ArmCacheOperationThreshold)) {
|
||||||
{
|
CacheOperation ();
|
||||||
CacheOperation();
|
} else {
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Align address (rounding down)
|
// Align address (rounding down)
|
||||||
UINTN AlignedAddress = (UINTN)Start - ((UINTN)Start & ArmCacheLineAlignmentMask);
|
UINTN AlignedAddress = (UINTN)Start - ((UINTN)Start & ArmCacheLineAlignmentMask);
|
||||||
UINTN EndAddress = (UINTN)Start + Length;
|
UINTN EndAddress = (UINTN)Start + Length;
|
||||||
|
|
||||||
// Perform the line operation on an address in each cache line
|
// Perform the line operation on an address in each cache line
|
||||||
while (AlignedAddress < EndAddress)
|
while (AlignedAddress < EndAddress) {
|
||||||
{
|
|
||||||
LineOperation(AlignedAddress);
|
LineOperation(AlignedAddress);
|
||||||
AlignedAddress += ArmCacheLineLength;
|
AlignedAddress += ArmCacheLineLength;
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,7 +66,7 @@ ArmSetTranslationTableBaseAddress
|
||||||
mcr p15,0,r0,c2,c0,0
|
mcr p15,0,r0,c2,c0,0
|
||||||
bx lr
|
bx lr
|
||||||
|
|
||||||
ArmSetTranslationTableBaseAddress
|
ArmGetTranslationTableBaseAddress
|
||||||
mrc p15,0,r0,c2,c0,0
|
mrc p15,0,r0,c2,c0,0
|
||||||
bx lr
|
bx lr
|
||||||
|
|
||||||
|
|
|
@ -49,7 +49,7 @@ UncachedInternalAllocateAlignedPages (
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
EFI_CPU_ARCH_PROTOCOL *gCpu;
|
EFI_CPU_ARCH_PROTOCOL *gDebugUncachedCpu;
|
||||||
VIRTUAL_UNCACHED_PAGES_PROTOCOL *gVirtualUncachedPages;
|
VIRTUAL_UNCACHED_PAGES_PROTOCOL *gVirtualUncachedPages;
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -641,7 +641,7 @@ DebugUncachedMemoryAllocationLibConstructor (
|
||||||
{
|
{
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
|
|
||||||
Status = gBS->LocateProtocol (&gEfiCpuArchProtocolGuid, NULL, (VOID **)&gCpu);
|
Status = gBS->LocateProtocol (&gEfiCpuArchProtocolGuid, NULL, (VOID **)&gDebugUncachedCpu);
|
||||||
ASSERT_EFI_ERROR(Status);
|
ASSERT_EFI_ERROR(Status);
|
||||||
|
|
||||||
Status = gBS->LocateProtocol (&gVirtualUncachedPagesProtocolGuid, NULL, (VOID **)&gVirtualUncachedPages);
|
Status = gBS->LocateProtocol (&gVirtualUncachedPagesProtocolGuid, NULL, (VOID **)&gVirtualUncachedPages);
|
||||||
|
|
|
@ -29,19 +29,19 @@
|
||||||
MdePkg/MdePkg.dec
|
MdePkg/MdePkg.dec
|
||||||
ArmPkg/ArmPkg.dec
|
ArmPkg/ArmPkg.dec
|
||||||
|
|
||||||
[Protocols]
|
|
||||||
gEfiCpuArchProtocolGuid
|
|
||||||
|
|
||||||
[LibraryClasses]
|
[LibraryClasses]
|
||||||
BaseLib
|
BaseLib
|
||||||
UefiMemoryAllocationLib
|
MemoryAllocationLib
|
||||||
ArmLib
|
ArmLib
|
||||||
|
|
||||||
|
[Protocols]
|
||||||
|
gEfiCpuArchProtocolGuid
|
||||||
|
gVirtualUncachedPagesProtocolGuid
|
||||||
|
|
||||||
[FixedPcd]
|
[FixedPcd]
|
||||||
gArmTokenSpaceGuid.PcdArmUncachedMemoryMask
|
gArmTokenSpaceGuid.PcdArmUncachedMemoryMask
|
||||||
|
|
||||||
|
|
||||||
[Depex]
|
[Depex]
|
||||||
gEfiCpuArchProtocolGuid
|
gEfiCpuArchProtocolGuid AND gVirtualUncachedPagesProtocolGuid
|
||||||
gVirtualUncachedPagesProtocolGuid
|
|
|
@ -40,6 +40,7 @@
|
||||||
|
|
||||||
|
|
||||||
ArmLib|ArmPkg/Library/ArmLib/ArmCortexA/ArmCortexArmLib.inf
|
ArmLib|ArmPkg/Library/ArmLib/ArmCortexA/ArmCortexArmLib.inf
|
||||||
|
MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
|
||||||
|
|
||||||
BaseLib|MdePkg/Library/BaseLib/BaseLib.inf
|
BaseLib|MdePkg/Library/BaseLib/BaseLib.inf
|
||||||
BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
|
BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
|
||||||
|
@ -90,7 +91,10 @@
|
||||||
UefiUsbLib|MdePkg/Library/UefiUsbLib/UefiUsbLib.inf
|
UefiUsbLib|MdePkg/Library/UefiUsbLib/UefiUsbLib.inf
|
||||||
EblAddExternalCommandLib|EmbeddedPkg/Library/EblAddExternalCommandLib/EblAddExternalCommandLib.inf
|
EblAddExternalCommandLib|EmbeddedPkg/Library/EblAddExternalCommandLib/EblAddExternalCommandLib.inf
|
||||||
|
|
||||||
UncachedMemoryAllocationLib|ArmPkg/Library/UncachedMemoryAllocationLib/UncachedMemoryAllocationLib.inf
|
# UncachedMemoryAllocationLib|ArmPkg/Library/UncachedMemoryAllocationLib/UncachedMemoryAllocationLib.inf
|
||||||
|
UncachedMemoryAllocationLib|ArmPkg/Library/DebugUncachedMemoryAllocationLib/DebugUncachedMemoryAllocationLib.inf
|
||||||
|
|
||||||
|
CpuLib|MdePkg/Library/BaseCpuLib/BaseCpuLib.inf
|
||||||
|
|
||||||
TimerLib|BeagleBoardPkg/Library/BeagleBoardTimerLib/BeagleBoardTimerLib.inf
|
TimerLib|BeagleBoardPkg/Library/BeagleBoardTimerLib/BeagleBoardTimerLib.inf
|
||||||
OmapLib|BeagleBoardPkg/Library/OmapLib/OmapLib.inf
|
OmapLib|BeagleBoardPkg/Library/OmapLib/OmapLib.inf
|
||||||
|
@ -206,49 +210,29 @@
|
||||||
gEfiMdePkgTokenSpaceGuid.PcdUefiLibMaxPrintBufferSize|320
|
gEfiMdePkgTokenSpaceGuid.PcdUefiLibMaxPrintBufferSize|320
|
||||||
|
|
||||||
# DEBUG_ASSERT_ENABLED 0x01
|
# DEBUG_ASSERT_ENABLED 0x01
|
||||||
|
|
||||||
# DEBUG_PRINT_ENABLED 0x02
|
# DEBUG_PRINT_ENABLED 0x02
|
||||||
|
|
||||||
# DEBUG_CODE_ENABLED 0x04
|
# DEBUG_CODE_ENABLED 0x04
|
||||||
|
|
||||||
# CLEAR_MEMORY_ENABLED 0x08
|
# CLEAR_MEMORY_ENABLED 0x08
|
||||||
|
|
||||||
# ASSERT_BREAKPOINT_ENABLED 0x10
|
# ASSERT_BREAKPOINT_ENABLED 0x10
|
||||||
|
|
||||||
# ASSERT_DEADLOOP_ENABLED 0x20
|
# ASSERT_DEADLOOP_ENABLED 0x20
|
||||||
|
|
||||||
gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x2f
|
gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x2f
|
||||||
|
|
||||||
# DEBUG_INIT 0x00000001 // Initialization
|
# DEBUG_INIT 0x00000001 // Initialization
|
||||||
|
|
||||||
# DEBUG_WARN 0x00000002 // Warnings
|
# DEBUG_WARN 0x00000002 // Warnings
|
||||||
|
|
||||||
# DEBUG_LOAD 0x00000004 // Load events
|
# DEBUG_LOAD 0x00000004 // Load events
|
||||||
|
|
||||||
# DEBUG_FS 0x00000008 // EFI File system
|
# DEBUG_FS 0x00000008 // EFI File system
|
||||||
|
|
||||||
# DEBUG_POOL 0x00000010 // Alloc & Free's
|
# DEBUG_POOL 0x00000010 // Alloc & Free's
|
||||||
|
|
||||||
# DEBUG_PAGE 0x00000020 // Alloc & Free's
|
# DEBUG_PAGE 0x00000020 // Alloc & Free's
|
||||||
|
|
||||||
# DEBUG_INFO 0x00000040 // Verbose
|
# DEBUG_INFO 0x00000040 // Verbose
|
||||||
|
|
||||||
# DEBUG_DISPATCH 0x00000080 // PEI/DXE Dispatchers
|
# DEBUG_DISPATCH 0x00000080 // PEI/DXE Dispatchers
|
||||||
|
|
||||||
# DEBUG_VARIABLE 0x00000100 // Variable
|
# DEBUG_VARIABLE 0x00000100 // Variable
|
||||||
|
|
||||||
# DEBUG_BM 0x00000400 // Boot Manager
|
# DEBUG_BM 0x00000400 // Boot Manager
|
||||||
|
|
||||||
# DEBUG_BLKIO 0x00001000 // BlkIo Driver
|
# DEBUG_BLKIO 0x00001000 // BlkIo Driver
|
||||||
|
|
||||||
# DEBUG_NET 0x00004000 // SNI Driver
|
# DEBUG_NET 0x00004000 // SNI Driver
|
||||||
|
|
||||||
# DEBUG_UNDI 0x00010000 // UNDI Driver
|
# DEBUG_UNDI 0x00010000 // UNDI Driver
|
||||||
|
|
||||||
# DEBUG_LOADFILE 0x00020000 // UNDI Driver
|
# DEBUG_LOADFILE 0x00020000 // UNDI Driver
|
||||||
|
|
||||||
# DEBUG_EVENT 0x00080000 // Event messages
|
# DEBUG_EVENT 0x00080000 // Event messages
|
||||||
|
|
||||||
# DEBUG_ERROR 0x80000000 // Error
|
# DEBUG_ERROR 0x80000000 // Error
|
||||||
|
|
||||||
gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x80000004
|
gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x80000004
|
||||||
|
|
|
@ -58,29 +58,23 @@ InitCache (
|
||||||
MemoryTable[0].Length = MemoryLength;
|
MemoryTable[0].Length = MemoryLength;
|
||||||
MemoryTable[0].Attributes = (ARM_MEMORY_REGION_ATTRIBUTES)CacheAttributes;
|
MemoryTable[0].Attributes = (ARM_MEMORY_REGION_ATTRIBUTES)CacheAttributes;
|
||||||
|
|
||||||
// Uncached DDR Mirror
|
|
||||||
MemoryTable[1].PhysicalBase = MemoryBase;
|
|
||||||
MemoryTable[1].VirtualBase = MemoryBase | UncachedMemoryMask;
|
|
||||||
MemoryTable[1].Length = MemoryLength;
|
|
||||||
MemoryTable[1].Attributes = DDR_ATTRIBUTES_UNCACHED;
|
|
||||||
|
|
||||||
// SOC Registers. L3 interconnects
|
// SOC Registers. L3 interconnects
|
||||||
MemoryTable[2].PhysicalBase = SOC_REGISTERS_L3_PHYSICAL_BASE;
|
MemoryTable[1].PhysicalBase = SOC_REGISTERS_L3_PHYSICAL_BASE;
|
||||||
MemoryTable[2].VirtualBase = SOC_REGISTERS_L3_PHYSICAL_BASE;
|
MemoryTable[1].VirtualBase = SOC_REGISTERS_L3_PHYSICAL_BASE;
|
||||||
MemoryTable[2].Length = SOC_REGISTERS_L3_PHYSICAL_LENGTH;
|
MemoryTable[1].Length = SOC_REGISTERS_L3_PHYSICAL_LENGTH;
|
||||||
MemoryTable[2].Attributes = SOC_REGISTERS_L3_ATTRIBUTES;
|
MemoryTable[1].Attributes = SOC_REGISTERS_L3_ATTRIBUTES;
|
||||||
|
|
||||||
// SOC Registers. L4 interconnects
|
// SOC Registers. L4 interconnects
|
||||||
MemoryTable[3].PhysicalBase = SOC_REGISTERS_L4_PHYSICAL_BASE;
|
MemoryTable[2].PhysicalBase = SOC_REGISTERS_L4_PHYSICAL_BASE;
|
||||||
MemoryTable[3].VirtualBase = SOC_REGISTERS_L4_PHYSICAL_BASE;
|
MemoryTable[2].VirtualBase = SOC_REGISTERS_L4_PHYSICAL_BASE;
|
||||||
MemoryTable[3].Length = SOC_REGISTERS_L4_PHYSICAL_LENGTH;
|
MemoryTable[2].Length = SOC_REGISTERS_L4_PHYSICAL_LENGTH;
|
||||||
MemoryTable[3].Attributes = SOC_REGISTERS_L4_ATTRIBUTES;
|
MemoryTable[2].Attributes = SOC_REGISTERS_L4_ATTRIBUTES;
|
||||||
|
|
||||||
// End of Table
|
// End of Table
|
||||||
MemoryTable[4].PhysicalBase = 0;
|
MemoryTable[3].PhysicalBase = 0;
|
||||||
MemoryTable[4].VirtualBase = 0;
|
MemoryTable[3].VirtualBase = 0;
|
||||||
MemoryTable[4].Length = 0;
|
MemoryTable[3].Length = 0;
|
||||||
MemoryTable[4].Attributes = (ARM_MEMORY_REGION_ATTRIBUTES)0;
|
MemoryTable[3].Attributes = (ARM_MEMORY_REGION_ATTRIBUTES)0;
|
||||||
|
|
||||||
ArmConfigureMmu (MemoryTable, &TranslationTableBase, &TranslationTableSize);
|
ArmConfigureMmu (MemoryTable, &TranslationTableBase, &TranslationTableSize);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue