Add ArmPlatformPkg from ARM Ltd. patch.

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

View File

@@ -0,0 +1,386 @@
/** @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 <PiDxe.h>
#include <Library/ArmLib.h>
#include <Library/CacheMaintenanceLib.h>
#include <Library/EblCmdLib.h>
#include <Library/BaseLib.h>
#include <Library/DxeServicesTableLib.h>
#include <Library/DebugLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiRuntimeServicesTableLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/UefiLib.h>
#include <Library/PcdLib.h>
#include <Library/EfiFileLib.h>
#include <Library/ArmDisassemblerLib.h>
#include <Library/PeCoffGetEntryPointLib.h>
#include <Library/PerformanceLib.h>
#include <Library/TimerLib.h>
#include <Guid/DebugImageInfoTable.h>
#include <Protocol/DebugSupport.h>
#include <Protocol/LoadedImage.h>
EFI_STATUS
EblDumpMmu (
IN UINTN Argc,
IN CHAR8 **Argv
);
/**
Simple arm disassembler via a library
Argv[0] - symboltable
Argv[1] - Optional qoted format string
Argv[2] - Optional flag
@param Argc Number of command arguments in Argv
@param Argv Array of strings that represent the parsed command line.
Argv[0] is the comamnd name
@return EFI_SUCCESS
**/
EFI_STATUS
EblSymbolTable (
IN UINTN Argc,
IN CHAR8 **Argv
)
{
EFI_STATUS Status;
EFI_DEBUG_IMAGE_INFO_TABLE_HEADER *DebugImageTableHeader = NULL;
EFI_DEBUG_IMAGE_INFO *DebugTable;
UINTN Entry;
CHAR8 *Format;
CHAR8 *Pdb;
UINT32 PeCoffSizeOfHeaders;
UINT32 ImageBase;
BOOLEAN Elf;
// Need to add lots of error checking on the passed in string
// Default string is for RealView debugger
Format = (Argc > 1) ? Argv[1] : "load /a /ni /np %a &0x%x";
Elf = (Argc > 2) ? FALSE : TRUE;
Status = EfiGetSystemConfigurationTable (&gEfiDebugImageInfoTableGuid, (VOID **)&DebugImageTableHeader);
if (EFI_ERROR (Status)) {
return Status;
}
DebugTable = DebugImageTableHeader->EfiDebugImageInfoTable;
if (DebugTable == NULL) {
return EFI_SUCCESS;
}
for (Entry = 0; Entry < DebugImageTableHeader->TableSize; Entry++, DebugTable++) {
if (DebugTable->NormalImage != NULL) {
if ((DebugTable->NormalImage->ImageInfoType == EFI_DEBUG_IMAGE_INFO_TYPE_NORMAL) && (DebugTable->NormalImage->LoadedImageProtocolInstance != NULL)) {
ImageBase = (UINT32)DebugTable->NormalImage->LoadedImageProtocolInstance->ImageBase;
PeCoffSizeOfHeaders = PeCoffGetSizeOfHeaders ((VOID *)(UINTN)ImageBase);
Pdb = PeCoffLoaderGetPdbPointer (DebugTable->NormalImage->LoadedImageProtocolInstance->ImageBase);
if (Pdb != NULL) {
if (Elf) {
// ELF and Mach-O images don't include the header so the linked address does not include header
ImageBase += PeCoffSizeOfHeaders;
}
AsciiPrint (Format, Pdb, ImageBase);
AsciiPrint ("\n");
} else {
}
}
}
}
return EFI_SUCCESS;
}
/**
Simple arm disassembler via a library
Argv[0] - disasm
Argv[1] - Address to start disassembling from
ARgv[2] - Number of instructions to disassembly (optional)
@param Argc Number of command arguments in Argv
@param Argv Array of strings that represent the parsed command line.
Argv[0] is the comamnd name
@return EFI_SUCCESS
**/
EFI_STATUS
EblDisassembler (
IN UINTN Argc,
IN CHAR8 **Argv
)
{
UINT8 *Ptr, *CurrentAddress;
UINT32 Address;
UINT32 Count;
CHAR8 Buffer[80];
UINT32 ItBlock;
if (Argc < 2) {
return EFI_INVALID_PARAMETER;
}
Address = AsciiStrHexToUintn (Argv[1]);
Count = (Argc > 2) ? (UINT32)AsciiStrHexToUintn (Argv[2]) : 20;
Ptr = (UINT8 *)(UINTN)Address;
ItBlock = 0;
do {
CurrentAddress = Ptr;
DisassembleInstruction (&Ptr, TRUE, TRUE, &ItBlock, Buffer, sizeof (Buffer));
AsciiPrint ("0x%08x: %a\n", CurrentAddress, Buffer);
} while (Count-- > 0);
return EFI_SUCCESS;
}
CHAR8 *
ImageHandleToPdbFileName (
IN EFI_HANDLE Handle
)
{
EFI_STATUS Status;
EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
CHAR8 *Pdb;
CHAR8 *StripLeading;
Status = gBS->HandleProtocol (Handle, &gEfiLoadedImageProtocolGuid, (VOID **)&LoadedImage);
if (EFI_ERROR (Status)) {
return "";
}
Pdb = PeCoffLoaderGetPdbPointer (LoadedImage->ImageBase);
StripLeading = AsciiStrStr (Pdb, "\\ARM\\");
if (StripLeading == NULL) {
StripLeading = AsciiStrStr (Pdb, "/ARM/");
if (StripLeading == NULL) {
return Pdb;
}
}
// Hopefully we hacked off the unneeded part
return (StripLeading + 5);
}
CHAR8 *mTokenList[] = {
/*"SEC",*/
"PEI",
"DXE",
/*"BDS",*/
NULL
};
/**
Simple arm disassembler via a library
Argv[0] - disasm
Argv[1] - Address to start disassembling from
ARgv[2] - Number of instructions to disassembly (optional)
@param Argc Number of command arguments in Argv
@param Argv Array of strings that represent the parsed command line.
Argv[0] is the comamnd name
@return EFI_SUCCESS
**/
EFI_STATUS
EblPerformance (
IN UINTN Argc,
IN CHAR8 **Argv
)
{
UINTN Key;
CONST VOID *Handle;
CONST CHAR8 *Token, *Module;
UINT64 Start, Stop, TimeStamp;
UINT64 Delta, TicksPerSecond, Milliseconds, Microseconds;
UINTN Index;
TicksPerSecond = GetPerformanceCounterProperties (NULL, NULL);
Key = 0;
do {
Key = GetPerformanceMeasurement (Key, (CONST VOID **)&Handle, &Token, &Module, &Start, &Stop);
if (Key != 0) {
if (AsciiStriCmp ("StartImage:", Token) == 0) {
if (Stop == 0) {
// The entry for EBL is still running so the stop time will be zero. Skip it
AsciiPrint (" running %a\n", ImageHandleToPdbFileName ((EFI_HANDLE)Handle));
} else {
Delta = Start - Stop;
Microseconds = DivU64x64Remainder (MultU64x32 (Delta, 1000000), TicksPerSecond, NULL);
AsciiPrint ("%10ld us %a\n", Microseconds, ImageHandleToPdbFileName ((EFI_HANDLE)Handle));
}
}
}
} while (Key != 0);
AsciiPrint ("\n");
TimeStamp = 0;
Key = 0;
do {
Key = GetPerformanceMeasurement (Key, (CONST VOID **)&Handle, &Token, &Module, &Start, &Stop);
if (Key != 0) {
for (Index = 0; mTokenList[Index] != NULL; Index++) {
if (AsciiStriCmp (mTokenList[Index], Token) == 0) {
Delta = Start - Stop;
TimeStamp += Delta;
Milliseconds = DivU64x64Remainder (MultU64x32 (Delta, 1000), TicksPerSecond, NULL);
AsciiPrint ("%6a %6ld ms\n", Token, Milliseconds);
break;
}
}
}
} while (Key != 0);
AsciiPrint ("Total Time = %ld ms\n\n", DivU64x64Remainder (MultU64x32 (TimeStamp, 1000), TicksPerSecond, NULL));
return EFI_SUCCESS;
}
#define EFI_MEMORY_PORT_IO 0x4000000000000000ULL
EFI_STATUS
EblDumpGcd (
IN UINTN Argc,
IN CHAR8 **Argv
)
{
EFI_STATUS Status;
UINTN NumberOfDescriptors;
UINTN i;
EFI_GCD_MEMORY_SPACE_DESCRIPTOR *MemorySpaceMap;
EFI_GCD_IO_SPACE_DESCRIPTOR *IoSpaceMap;
Status = gDS->GetMemorySpaceMap(&NumberOfDescriptors,&MemorySpaceMap);
if (EFI_ERROR (Status)) {
return Status;
}
AsciiPrint (" Address Range Image Device Attributes\n");
AsciiPrint ("__________________________________________________________\n");
for (i=0; i < NumberOfDescriptors; i++) {
//AsciiPrint ("%016lx - %016lx",MemorySpaceMap[i].BaseAddress,MemorySpaceMap[i].BaseAddress+MemorySpaceMap[i].Length);
AsciiPrint ("MEM %08lx - %08lx",(UINT64)MemorySpaceMap[i].BaseAddress,MemorySpaceMap[i].BaseAddress+MemorySpaceMap[i].Length-1);
AsciiPrint (" %08x %08x",MemorySpaceMap[i].ImageHandle,MemorySpaceMap[i].DeviceHandle);
if (MemorySpaceMap[i].Attributes & EFI_MEMORY_RUNTIME)
AsciiPrint (" RUNTIME");
if (MemorySpaceMap[i].Attributes & EFI_MEMORY_PORT_IO)
AsciiPrint (" PORT_IO");
if (MemorySpaceMap[i].Attributes & EFI_MEMORY_UC)
AsciiPrint (" MEM_UC");
if (MemorySpaceMap[i].Attributes & EFI_MEMORY_WC)
AsciiPrint (" MEM_WC");
if (MemorySpaceMap[i].Attributes & EFI_MEMORY_WT)
AsciiPrint (" MEM_WT");
if (MemorySpaceMap[i].Attributes & EFI_MEMORY_WB)
AsciiPrint (" MEM_WB");
if (MemorySpaceMap[i].Attributes & EFI_MEMORY_UCE)
AsciiPrint (" MEM_UCE");
if (MemorySpaceMap[i].Attributes & EFI_MEMORY_WP)
AsciiPrint (" MEM_WP");
if (MemorySpaceMap[i].Attributes & EFI_MEMORY_RP)
AsciiPrint (" MEM_RP");
if (MemorySpaceMap[i].Attributes & EFI_MEMORY_XP)
AsciiPrint (" MEM_XP");
if (MemorySpaceMap[i].GcdMemoryType & EfiGcdMemoryTypeNonExistent)
AsciiPrint (" TYPE_NONEXISTENT");
if (MemorySpaceMap[i].GcdMemoryType & EfiGcdMemoryTypeReserved)
AsciiPrint (" TYPE_RESERVED");
if (MemorySpaceMap[i].GcdMemoryType & EfiGcdMemoryTypeSystemMemory)
AsciiPrint (" TYPE_SYSMEM");
if (MemorySpaceMap[i].GcdMemoryType & EfiGcdMemoryTypeMemoryMappedIo)
AsciiPrint (" TYPE_MEMMAP");
AsciiPrint ("\n");
}
Status = gDS->GetIoSpaceMap(&NumberOfDescriptors,&IoSpaceMap);
if (EFI_ERROR (Status)) {
return Status;
}
for (i=0; i < NumberOfDescriptors; i++) {
AsciiPrint ("IO %08lx - %08lx",IoSpaceMap[i].BaseAddress,IoSpaceMap[i].BaseAddress+IoSpaceMap[i].Length);
AsciiPrint ("\t%08x %08x",IoSpaceMap[i].ImageHandle,IoSpaceMap[i].DeviceHandle);
if (IoSpaceMap[i].GcdIoType & EfiGcdMemoryTypeNonExistent)
AsciiPrint (" TYPE_NONEXISTENT");
if (IoSpaceMap[i].GcdIoType & EfiGcdMemoryTypeReserved)
AsciiPrint (" TYPE_RESERVED");
if (IoSpaceMap[i].GcdIoType & EfiGcdIoTypeIo)
AsciiPrint (" TYPE_IO");
AsciiPrint ("\n");
}
return EFI_SUCCESS;
}
GLOBAL_REMOVE_IF_UNREFERENCED const EBL_COMMAND_TABLE mLibCmdTemplate[] =
{
{
"disasm address [count]",
" disassemble count instructions",
NULL,
EblDisassembler
},
{
"performance",
" Display boot performance info",
NULL,
EblPerformance
},
{
"symboltable [\"format string\"] [PECOFF]",
" show symbol table commands for debugger",
NULL,
EblSymbolTable
},
{
"dumpgcd",
" dump Global Coherency Domain",
NULL,
EblDumpGcd
},
{
"dumpmmu",
" dump MMU Table",
NULL,
EblDumpMmu
}
};
VOID
EblInitializeExternalCmd (
VOID
)
{
EblAddCommands (mLibCmdTemplate, sizeof (mLibCmdTemplate)/sizeof (EBL_COMMAND_TABLE));
return;
}

View File

@@ -0,0 +1,53 @@
#/** @file
#
# Copyright (c) 2010, ARM Ltd. All rights reserved.<BR>
# This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
# which accompanies this distribution. The full text of the license may be found at
# http://opensource.org/licenses/bsd-license.php
#
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#
#**/
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = ArmVeEblCmdLib
FILE_GUID = 6085e1ca-0d2d-4ba4-9872-c59b36ffd6ad
MODULE_TYPE = UEFI_DRIVER
VERSION_STRING = 1.0
LIBRARY_CLASS = EblCmdLib|DXE_DRIVER UEFI_APPLICATION UEFI_DRIVER
#
# The following information is for reference only and not required by the build tools.
#
# VALID_ARCHITECTURES = IA32 X64 IPF EBC
#
[Sources.common]
EblCmdLib.c
EblCmdMmu.c
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
EmbeddedPkg/EmbeddedPkg.dec
ArmPkg/ArmPkg.dec
[LibraryClasses]
BaseLib
ArmLib
DebugLib
ArmDisassemblerLib
PerformanceLib
TimerLib
[Protocols]
gEfiDebugSupportProtocolGuid
gEfiLoadedImageProtocolGuid
[Guids]
gEfiDebugImageInfoTableGuid

View File

@@ -0,0 +1,354 @@
/** @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 <PiDxe.h>
#include <Library/UefiLib.h>
#include <Library/ArmLib.h>
#include <Chipset/ArmV7.h>
#include <Library/CacheMaintenanceLib.h>
#include <Library/EblCmdLib.h>
#include <Library/BaseLib.h>
#include <Library/DebugLib.h>
#define GET_TT_ATTRIBUTES(TTEntry) ((TTEntry) & ~(TT_DESCRIPTOR_SECTION_BASE_ADDRESS_MASK))
#define GET_TT_PAGE_ATTRIBUTES(TTEntry) ((TTEntry) & 0xFFF)
#define GET_TT_LARGEPAGE_ATTRIBUTES(TTEntry) ((TTEntry) & 0xFFFF)
// Section
#define TT_DESCRIPTOR_SECTION_STRONGLY_ORDER (TT_DESCRIPTOR_SECTION_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_STRONGLY_ORDERED)
// Small Page
#define TT_DESCRIPTOR_PAGE_WRITE_BACK (TT_DESCRIPTOR_PAGE_TYPE_PAGE | \
TT_DESCRIPTOR_PAGE_NG_GLOBAL | \
TT_DESCRIPTOR_PAGE_S_NOT_SHARED | \
TT_DESCRIPTOR_PAGE_AP_RW_RW | \
TT_DESCRIPTOR_PAGE_CACHE_POLICY_WRITE_BACK_ALLOC)
#define TT_DESCRIPTOR_PAGE_WRITE_THROUGH (TT_DESCRIPTOR_PAGE_TYPE_PAGE | \
TT_DESCRIPTOR_PAGE_NG_GLOBAL | \
TT_DESCRIPTOR_PAGE_S_NOT_SHARED | \
TT_DESCRIPTOR_PAGE_AP_RW_RW | \
TT_DESCRIPTOR_PAGE_CACHE_POLICY_WRITE_THROUGH_NO_ALLOC)
#define TT_DESCRIPTOR_PAGE_DEVICE (TT_DESCRIPTOR_PAGE_TYPE_PAGE | \
TT_DESCRIPTOR_PAGE_NG_GLOBAL | \
TT_DESCRIPTOR_PAGE_S_NOT_SHARED | \
TT_DESCRIPTOR_PAGE_AP_RW_RW | \
TT_DESCRIPTOR_PAGE_CACHE_POLICY_SHAREABLE_DEVICE)
#define TT_DESCRIPTOR_PAGE_UNCACHED (TT_DESCRIPTOR_PAGE_TYPE_PAGE | \
TT_DESCRIPTOR_PAGE_NG_GLOBAL | \
TT_DESCRIPTOR_PAGE_S_NOT_SHARED | \
TT_DESCRIPTOR_PAGE_AP_RW_RW | \
TT_DESCRIPTOR_PAGE_CACHE_POLICY_NON_CACHEABLE)
#define TT_DESCRIPTOR_PAGE_STRONGLY_ORDER (TT_DESCRIPTOR_PAGE_TYPE_PAGE | \
TT_DESCRIPTOR_PAGE_NG_GLOBAL | \
TT_DESCRIPTOR_PAGE_S_NOT_SHARED | \
TT_DESCRIPTOR_PAGE_AP_RW_RW | \
TT_DESCRIPTOR_PAGE_CACHE_POLICY_STRONGLY_ORDERED)
// Large Page
#define TT_DESCRIPTOR_LARGEPAGE_WRITE_BACK (TT_DESCRIPTOR_PAGE_TYPE_LARGEPAGE | \
TT_DESCRIPTOR_PAGE_NG_GLOBAL | \
TT_DESCRIPTOR_PAGE_S_NOT_SHARED | \
TT_DESCRIPTOR_PAGE_AP_RW_RW | \
TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_BACK_ALLOC)
#define TT_DESCRIPTOR_LARGEPAGE_WRITE_THROUGH (TT_DESCRIPTOR_PAGE_TYPE_LARGEPAGE | \
TT_DESCRIPTOR_PAGE_NG_GLOBAL | \
TT_DESCRIPTOR_PAGE_S_NOT_SHARED | \
TT_DESCRIPTOR_PAGE_AP_RW_RW | \
TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_THROUGH_NO_ALLOC)
#define TT_DESCRIPTOR_LARGEPAGE_DEVICE (TT_DESCRIPTOR_PAGE_TYPE_LARGEPAGE | \
TT_DESCRIPTOR_PAGE_NG_GLOBAL | \
TT_DESCRIPTOR_PAGE_S_NOT_SHARED | \
TT_DESCRIPTOR_PAGE_AP_RW_RW | \
TT_DESCRIPTOR_SECTION_CACHE_POLICY_SHAREABLE_DEVICE)
#define TT_DESCRIPTOR_LARGEPAGE_UNCACHED (TT_DESCRIPTOR_PAGE_TYPE_LARGEPAGE | \
TT_DESCRIPTOR_PAGE_NG_GLOBAL | \
TT_DESCRIPTOR_PAGE_S_NOT_SHARED | \
TT_DESCRIPTOR_PAGE_AP_RW_RW | \
TT_DESCRIPTOR_SECTION_CACHE_POLICY_NON_CACHEABLE)
typedef enum { Level0, Level1,Level2 } MMU_LEVEL;
typedef struct {
MMU_LEVEL Level;
UINT32 Value;
UINT32 Index;
UINT32* Table;
} MMU_ENTRY;
MMU_ENTRY MmuEntryCreate(MMU_LEVEL Level,UINT32* Table,UINT32 Index) {
MMU_ENTRY Entry;
Entry.Level = Level;
Entry.Value = Table[Index];
Entry.Table = Table;
Entry.Index = Index;
return Entry;
}
UINT32 MmuEntryIsValidAddress(MMU_LEVEL Level, UINT32 Entry) {
if (Level == Level0) {
return 0;
} else if (Level == Level1) {
if ((Entry & 0x3) == 0) { // Ignored
return 0;
} else if ((Entry & 0x3) == 2) { // Section Type
return 1;
} else { // Page Type
return 0;
}
} else if (Level == Level2){
if ((Entry & 0x3) == 0) { // Ignored
return 0;
} else { // Page Type
return 1;
}
} else {
DEBUG((EFI_D_ERROR,"MmuEntryIsValidAddress: Level:%d Entry:0x%X\n",(UINT32)Level,(UINT32)Entry));
ASSERT(0);
return 0;
}
}
UINT32 MmuEntryGetAddress(MMU_ENTRY Entry) {
if (Entry.Level == Level1) {
if ((Entry.Value & 0x3) == 0) {
return 0;
} else if ((Entry.Value & 0x3) == 2) { // Section Type
return Entry.Value & TT_DESCRIPTOR_SECTION_BASE_ADDRESS_MASK;
} else if ((Entry.Value & 0x3) == 1) { // Level2 Table
MMU_ENTRY Entry = MmuEntryCreate(Level2,(UINT32*)(Entry.Value & 0xFFFFC000),0);
return MmuEntryGetAddress(Entry);
} else { // Page Type
return 0;
}
} else if (Entry.Level == Level2) {
if ((Entry.Value & 0x3) == 0) { // Ignored
return 0;
} else if ((Entry.Value & 0x3) == 1) { // Large Page
return Entry.Value & 0xFFFF0000;
} else if ((Entry.Value & 0x2) == 2) { // Small Page
return Entry.Value & 0xFFFFF000;
} else {
return 0;
}
} else {
ASSERT(0);
return 0;
}
}
UINT32 MmuEntryGetSize(MMU_ENTRY Entry) {
if (Entry.Level == Level1) {
if ((Entry.Value & 0x3) == 0) {
return 0;
} else if ((Entry.Value & 0x3) == 2) {
if (Entry.Value & (1 << 18))
return 16*SIZE_1MB;
else
return SIZE_1MB;
} else if ((Entry.Value & 0x3) == 1) { // Level2 Table split 1MB section
return SIZE_1MB;
} else {
DEBUG((EFI_D_ERROR, "MmuEntryGetSize: Value:0x%X",Entry.Value));
ASSERT(0);
return 0;
}
} else if (Entry.Level == Level2) {
if ((Entry.Value & 0x3) == 0) { // Ignored
return 0;
} else if ((Entry.Value & 0x3) == 1) { // Large Page
return SIZE_64KB;
} else if ((Entry.Value & 0x2) == 2) { // Small Page
return SIZE_4KB;
} else {
ASSERT(0);
return 0;
}
} else {
ASSERT(0);
return 0;
}
}
CONST CHAR8* MmuEntryGetAttributesName(MMU_ENTRY Entry) {
if (Entry.Level == Level1) {
if (GET_TT_ATTRIBUTES(Entry.Value) == TT_DESCRIPTOR_SECTION_WRITE_BACK(0))
return "TT_DESCRIPTOR_SECTION_WRITE_BACK";
else if (GET_TT_ATTRIBUTES(Entry.Value) == TT_DESCRIPTOR_SECTION_WRITE_THROUGH(0))
return "TT_DESCRIPTOR_SECTION_WRITE_THROUGH";
else if (GET_TT_ATTRIBUTES(Entry.Value) == TT_DESCRIPTOR_SECTION_DEVICE(0))
return "TT_DESCRIPTOR_SECTION_DEVICE";
else if (GET_TT_ATTRIBUTES(Entry.Value) == TT_DESCRIPTOR_SECTION_UNCACHED(0))
return "TT_DESCRIPTOR_SECTION_UNCACHED";
else if (GET_TT_ATTRIBUTES(Entry.Value) == TT_DESCRIPTOR_SECTION_STRONGLY_ORDER)
return "TT_DESCRIPTOR_SECTION_STRONGLY_ORDERED";
else {
return "SectionUnknown";
}
} else if ((Entry.Level == Level2) && ((Entry.Value & 0x2) == 2)) { //Small Page
if (GET_TT_PAGE_ATTRIBUTES(Entry.Value) == TT_DESCRIPTOR_PAGE_WRITE_BACK)
return "TT_DESCRIPTOR_PAGE_WRITE_BACK";
else if (GET_TT_PAGE_ATTRIBUTES(Entry.Value) == TT_DESCRIPTOR_PAGE_WRITE_THROUGH)
return "TT_DESCRIPTOR_PAGE_WRITE_THROUGH";
else if (GET_TT_PAGE_ATTRIBUTES(Entry.Value) == TT_DESCRIPTOR_PAGE_DEVICE)
return "TT_DESCRIPTOR_PAGE_DEVICE";
else if (GET_TT_PAGE_ATTRIBUTES(Entry.Value) == TT_DESCRIPTOR_PAGE_UNCACHED)
return "TT_DESCRIPTOR_PAGE_UNCACHED";
else if (GET_TT_PAGE_ATTRIBUTES(Entry.Value) == TT_DESCRIPTOR_PAGE_STRONGLY_ORDER)
return "TT_DESCRIPTOR_PAGE_STRONGLY_ORDERED";
else {
return "PageUnknown";
}
} else if ((Entry.Level == Level2) && ((Entry.Value & 0x3) == 1)) { //Large Page
if (GET_TT_LARGEPAGE_ATTRIBUTES(Entry.Value) == TT_DESCRIPTOR_LARGEPAGE_WRITE_BACK)
return "TT_DESCRIPTOR_LARGEPAGE_WRITE_BACK";
else if (GET_TT_LARGEPAGE_ATTRIBUTES(Entry.Value) == TT_DESCRIPTOR_LARGEPAGE_WRITE_THROUGH)
return "TT_DESCRIPTOR_LARGEPAGE_WRITE_THROUGH";
else if (GET_TT_LARGEPAGE_ATTRIBUTES(Entry.Value) == TT_DESCRIPTOR_LARGEPAGE_DEVICE)
return "TT_DESCRIPTOR_LARGEPAGE_DEVICE";
else if (GET_TT_LARGEPAGE_ATTRIBUTES(Entry.Value) == TT_DESCRIPTOR_LARGEPAGE_UNCACHED)
return "TT_DESCRIPTOR_LARGEPAGE_UNCACHED";
else {
return "LargePageUnknown";
}
} else {
ASSERT(0);
return "";
}
}
UINT32 MmuEntryGetAttributes(MMU_ENTRY Entry) {
if (Entry.Level == Level1) {
if ((Entry.Value & 0x3) == 0) {
return 0;
} else if ((Entry.Value & 0x3) == 2) {
return GET_TT_ATTRIBUTES(Entry.Value);
} else {
return 0;
}
} else if ((Entry.Level == Level2) && ((Entry.Value & 0x2) == 2)) { //Small Page
if (GET_TT_PAGE_ATTRIBUTES(Entry.Value) == TT_DESCRIPTOR_PAGE_WRITE_BACK)
return TT_DESCRIPTOR_SECTION_WRITE_BACK(0);
else if (GET_TT_PAGE_ATTRIBUTES(Entry.Value) == TT_DESCRIPTOR_PAGE_WRITE_THROUGH)
return TT_DESCRIPTOR_SECTION_WRITE_THROUGH(0);
else if (GET_TT_PAGE_ATTRIBUTES(Entry.Value) == TT_DESCRIPTOR_PAGE_DEVICE)
return TT_DESCRIPTOR_SECTION_DEVICE(0);
else if (GET_TT_PAGE_ATTRIBUTES(Entry.Value) == TT_DESCRIPTOR_PAGE_UNCACHED)
return TT_DESCRIPTOR_SECTION_UNCACHED(0);
else if (GET_TT_PAGE_ATTRIBUTES(Entry.Value) == TT_DESCRIPTOR_PAGE_STRONGLY_ORDER)
return TT_DESCRIPTOR_SECTION_STRONGLY_ORDER;
else {
return 0;
}
} else if ((Entry.Level == Level2) && ((Entry.Value & 0x3) == 1)) { //Large Page
if (GET_TT_LARGEPAGE_ATTRIBUTES(Entry.Value) == TT_DESCRIPTOR_LARGEPAGE_WRITE_BACK)
return TT_DESCRIPTOR_SECTION_WRITE_BACK(0);
else if (GET_TT_LARGEPAGE_ATTRIBUTES(Entry.Value) == TT_DESCRIPTOR_LARGEPAGE_WRITE_THROUGH)
return TT_DESCRIPTOR_SECTION_WRITE_THROUGH(0);
else if (GET_TT_LARGEPAGE_ATTRIBUTES(Entry.Value) == TT_DESCRIPTOR_LARGEPAGE_DEVICE)
return TT_DESCRIPTOR_SECTION_DEVICE(0);
else if (GET_TT_LARGEPAGE_ATTRIBUTES(Entry.Value) == TT_DESCRIPTOR_LARGEPAGE_UNCACHED)
return TT_DESCRIPTOR_SECTION_UNCACHED(0);
else {
return 0;
}
} else {
return 0;
}
}
MMU_ENTRY DumpMmuLevel(MMU_LEVEL Level, UINT32* Table, MMU_ENTRY PreviousEntry) {
UINT32 Index = 0, Count;
MMU_ENTRY LastEntry, Entry;
ASSERT((Level == Level1) || (Level == Level2));
if (Level == Level1) Count = 4096;
else Count = 256;
// At Level1, we will get into this function because PreviousEntry is not valid
if (!MmuEntryIsValidAddress((MMU_LEVEL)(Level-1),PreviousEntry.Value)) {
// Find the first valid address
for (; (Index < Count) && (!MmuEntryIsValidAddress(Level,Table[Index])); Index++);
LastEntry = MmuEntryCreate(Level,Table,Index);
Index++;
} else {
LastEntry = PreviousEntry;
}
for (; Index < Count; Index++) {
Entry = MmuEntryCreate(Level,Table,Index);
if ((Level == Level1) && ((Entry.Value & 0x3) == 1)) { // We have got a Level2 table redirection
LastEntry = DumpMmuLevel(Level2,(UINT32*)(Entry.Value & 0xFFFFFC00),LastEntry);
} else if (!MmuEntryIsValidAddress(Level,Table[Index])) {
if (MmuEntryIsValidAddress(LastEntry.Level,LastEntry.Value)) {
AsciiPrint("0x%08X-0x%08X\t%a\n",
MmuEntryGetAddress(LastEntry),MmuEntryGetAddress(PreviousEntry)+MmuEntryGetSize(PreviousEntry)-1,
MmuEntryGetAttributesName(LastEntry));
}
LastEntry = Entry;
} else {
if (MmuEntryGetAttributes(LastEntry) != MmuEntryGetAttributes(Entry)) {
if (MmuEntryIsValidAddress(Level,LastEntry.Value)) {
AsciiPrint("0x%08X-0x%08X\t%a\n",
MmuEntryGetAddress(LastEntry),MmuEntryGetAddress(PreviousEntry)+MmuEntryGetSize(PreviousEntry)-1,
MmuEntryGetAttributesName(LastEntry));
}
LastEntry = Entry;
} else {
ASSERT(LastEntry.Value != 0);
}
}
PreviousEntry = Entry;
}
if ((Level == Level1) && (LastEntry.Index != Index) && MmuEntryIsValidAddress(Level,LastEntry.Value)) {
AsciiPrint("0x%08X-0x%08X\t%a\n",
MmuEntryGetAddress(LastEntry),MmuEntryGetAddress(PreviousEntry)+MmuEntryGetSize(PreviousEntry)-1,
MmuEntryGetAttributesName(LastEntry));
}
return LastEntry;
}
EFI_STATUS
EblDumpMmu (
IN UINTN Argc,
IN CHAR8 **Argv
)
{
UINT32 *TTEntry;
MMU_ENTRY NoEntry;
TTEntry = ArmGetTTBR0BaseAddress();
AsciiPrint ("\nTranslation Table:0x%X\n",TTEntry);
AsciiPrint ("Address Range\t\tAttributes\n");
AsciiPrint ("____________________________________________________\n");
NoEntry.Level = (MMU_LEVEL)200;
DumpMmuLevel(Level1,TTEntry,NoEntry);
return EFI_SUCCESS;
}

View File

@@ -0,0 +1,133 @@
/** @file
Serial I/O Port library functions with no library constructor/destructor
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.
**/
#include <Include/Uefi.h>
#include <Library/SerialPortLib.h>
#include <Library/IoLib.h>
#include <Drivers/PL011Uart.h>
#include <ArmPlatform.h>
/*
Programmed hardware of Serial port.
@return Always return EFI_UNSUPPORTED.
**/
RETURN_STATUS
EFIAPI
SerialPortInitialize (
VOID
)
{
if (PL011_CONSOLE_UART_SPEED == 115200) {
// Initialize baud rate generator
MmioWrite32 (PL011_CONSOLE_UART_BASE + UARTIBRD, UART_115200_IDIV);
MmioWrite32 (PL011_CONSOLE_UART_BASE + UARTFBRD, UART_115200_FDIV);
} else if (PL011_CONSOLE_UART_SPEED == 38400) {
// Initialize baud rate generator
MmioWrite32 (PL011_CONSOLE_UART_BASE + UARTIBRD, UART_38400_IDIV);
MmioWrite32 (PL011_CONSOLE_UART_BASE + UARTFBRD, UART_38400_FDIV);
} else if (PL011_CONSOLE_UART_SPEED == 19200) {
// Initialize baud rate generator
MmioWrite32 (PL011_CONSOLE_UART_BASE + UARTIBRD, UART_19200_IDIV);
MmioWrite32 (PL011_CONSOLE_UART_BASE + UARTFBRD, UART_19200_FDIV);
} else {
return EFI_INVALID_PARAMETER;
}
// No parity, 1 stop, no fifo, 8 data bits
MmioWrite32 (PL011_CONSOLE_UART_BASE + UARTLCR_H, 0x60);
// Clear any pending errors
MmioWrite32 (PL011_CONSOLE_UART_BASE + UARTECR, 0);
// enable tx, rx, and uart overall
MmioWrite32 (PL011_CONSOLE_UART_BASE + UARTCR, 0x301);
return EFI_SUCCESS;
}
/**
Write data to serial device.
@param Buffer Point of data buffer which need to be writed.
@param NumberOfBytes Number of output bytes which are cached in Buffer.
@retval 0 Write data failed.
@retval !0 Actual number of bytes writed to serial device.
**/
UINTN
EFIAPI
SerialPortWrite (
IN UINT8 *Buffer,
IN UINTN NumberOfBytes
)
{
UINTN Count;
for (Count = 0; Count < NumberOfBytes; Count++, Buffer++) {
while ((MmioRead32 (PL011_CONSOLE_UART_BASE + UARTFR) & UART_TX_EMPTY_FLAG_MASK) == 0);
MmioWrite8 (PL011_CONSOLE_UART_BASE + UARTDR, *Buffer);
}
return NumberOfBytes;
}
/**
Read data from serial device and save the datas in buffer.
@param Buffer Point of data buffer which need to be writed.
@param NumberOfBytes Number of output bytes which are cached in Buffer.
@retval 0 Read data failed.
@retval !0 Aactual number of bytes read from serial device.
**/
UINTN
EFIAPI
SerialPortRead (
OUT UINT8 *Buffer,
IN UINTN NumberOfBytes
)
{
UINTN Count;
for (Count = 0; Count < NumberOfBytes; Count++, Buffer++) {
while ((MmioRead32 (PL011_CONSOLE_UART_BASE + UARTFR) & UART_RX_EMPTY_FLAG_MASK) != 0);
*Buffer = MmioRead8 (PL011_CONSOLE_UART_BASE + UARTDR);
}
return NumberOfBytes;
}
/**
Check to see if any data is avaiable to be read from the debug device.
@retval EFI_SUCCESS At least one byte of data is avaiable to be read
@retval EFI_NOT_READY No data is avaiable to be read
@retval EFI_DEVICE_ERROR The serial device is not functioning properly
**/
BOOLEAN
EFIAPI
SerialPortPoll (
VOID
)
{
return ((MmioRead32 (PL011_CONSOLE_UART_BASE + UARTFR) & UART_RX_EMPTY_FLAG_MASK) == 0);
}

View File

@@ -0,0 +1,32 @@
#/** @file
#
# Component discription file for NorFlashDxe module
#
# Copyright (c) 2010, ARM Ltd. All rights reserved.<BR>
# This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
# which accompanies this distribution. The full text of the license may be found at
# http://opensource.org/licenses/bsd-license.php
#
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#
#**/
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = PL011SerialPortLib
FILE_GUID = 8ecefc8f-a2c4-4091-b80f-20f7aeb0567f
MODULE_TYPE = BASE
VERSION_STRING = 1.0
LIBRARY_CLASS = SerialPortLib
[Sources.common]
PL011SerialPortLib.c
[LibraryClasses]
IoLib
[Packages]
MdePkg/MdePkg.dec
ArmPlatformPkg/ArmPlatformPkg.dec

View File

@@ -0,0 +1,172 @@
/** @file
Implement EFI RealTimeClock runtime services via RTC Lib.
Currently this driver does not support runtime virtual calling.
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.
**/
#include <PiDxe.h>
#include <Library/BaseLib.h>
#include <Library/DebugLib.h>
#include <Library/IoLib.h>
#include <Library/RealTimeClockLib.h>
/**
Returns the current time and date information, and the time-keeping capabilities
of the hardware platform.
@param Time A pointer to storage to receive a snapshot of the current time.
@param Capabilities An optional pointer to a buffer to receive the real time clock
device's capabilities.
@retval EFI_SUCCESS The operation completed successfully.
@retval EFI_INVALID_PARAMETER Time is NULL.
@retval EFI_DEVICE_ERROR The time could not be retrieved due to hardware error.
**/
EFI_STATUS
EFIAPI
LibGetTime (
OUT EFI_TIME *Time,
OUT EFI_TIME_CAPABILITIES *Capabilities
)
{
//
// Fill in Time and Capabilities via data from you RTC
//
return EFI_DEVICE_ERROR;
}
/**
Sets the current local time and date information.
@param Time A pointer to the current time.
@retval EFI_SUCCESS The operation completed successfully.
@retval EFI_INVALID_PARAMETER A time field is out of range.
@retval EFI_DEVICE_ERROR The time could not be set due due to hardware error.
**/
EFI_STATUS
EFIAPI
LibSetTime (
IN EFI_TIME *Time
)
{
//
// Use Time, to set the time in your RTC hardware
//
return EFI_DEVICE_ERROR;
}
/**
Returns the current wakeup alarm clock setting.
@param Enabled Indicates if the alarm is currently enabled or disabled.
@param Pending Indicates if the alarm signal is pending and requires acknowledgement.
@param Time The current alarm setting.
@retval EFI_SUCCESS The alarm settings were returned.
@retval EFI_INVALID_PARAMETER Any parameter is NULL.
@retval EFI_DEVICE_ERROR The wakeup time could not be retrieved due to a hardware error.
**/
EFI_STATUS
EFIAPI
LibGetWakeupTime (
OUT BOOLEAN *Enabled,
OUT BOOLEAN *Pending,
OUT EFI_TIME *Time
)
{
// Not a required feature
return EFI_UNSUPPORTED;
}
/**
Sets the system wakeup alarm clock time.
@param Enabled Enable or disable the wakeup alarm.
@param Time If Enable is TRUE, the time to set the wakeup alarm for.
@retval EFI_SUCCESS If Enable is TRUE, then the wakeup alarm was enabled. If
Enable is FALSE, then the wakeup alarm was disabled.
@retval EFI_INVALID_PARAMETER A time field is out of range.
@retval EFI_DEVICE_ERROR The wakeup time could not be set due to a hardware error.
@retval EFI_UNSUPPORTED A wakeup timer is not supported on this platform.
**/
EFI_STATUS
EFIAPI
LibSetWakeupTime (
IN BOOLEAN Enabled,
OUT EFI_TIME *Time
)
{
// Not a required feature
return EFI_UNSUPPORTED;
}
/**
This is the declaration of an EFI image entry point. This can be the entry point to an application
written to this specification, an EFI boot service driver, or an EFI runtime driver.
@param ImageHandle Handle that identifies the loaded image.
@param SystemTable System Table for this image.
@retval EFI_SUCCESS The operation completed successfully.
**/
EFI_STATUS
EFIAPI
LibRtcInitialize (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
//
// Do some initialization if reqruied to turn on the RTC
//
return EFI_SUCCESS;
}
/**
Fixup internal data so that EFI can be call in virtual mode.
Call the passed in Child Notify event and convert any pointers in
lib to virtual mode.
@param[in] Event The Event that is being processed
@param[in] Context Event Context
**/
VOID
EFIAPI
LibRtcVirtualNotifyEvent (
IN EFI_EVENT Event,
IN VOID *Context
)
{
//
// Only needed if you are going to support the OS calling RTC functions in virtual mode.
// You will need to call EfiConvertPointer (). To convert any stored physical addresses
// to virtual address. After the OS transistions to calling in virtual mode, all future
// runtime calls will be made in virtual mode.
//
return;
}

View File

@@ -0,0 +1,35 @@
#/** @file
# Memory Status Code Library for UEFI drivers
#
# Lib to provide memory journal status code reporting Routines
# Copyright (c) 2006, Intel Corporation. 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 = PL031RealTimeClockLib
FILE_GUID = 470DFB96-E205-4515-A75E-2E60F853E79D
MODULE_TYPE = BASE
VERSION_STRING = 1.0
LIBRARY_CLASS = RealTimeClockLib
[Sources.common]
PL031RealTimeClockLib.c
[Packages]
MdePkg/MdePkg.dec
EmbeddedPkg/EmbeddedPkg.dec
[LibraryClasses]
IoLib
DebugLib

View File

@@ -0,0 +1,70 @@
/** @file
PEI Services Table Pointer Library.
This library is used for PEIM which does executed from flash device directly but
executed in memory.
Copyright (c) 2006 - 2010, Intel Corporation. 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 <PiPei.h>
#include <Library/PeiServicesTablePointerLib.h>
#include <Library/DebugLib.h>
#include <Library/PcdLib.h>
/**
Caches a pointer PEI Services Table.
Caches the pointer to the PEI Services Table specified by PeiServicesTablePointer
in a platform specific manner.
If PeiServicesTablePointer is NULL, then ASSERT().
@param PeiServicesTablePointer The address of PeiServices pointer.
**/
VOID
EFIAPI
SetPeiServicesTablePointer (
IN CONST EFI_PEI_SERVICES ** PeiServicesTablePointer
)
{
UINTN *PeiPtrLoc;
ASSERT (PeiServicesTablePointer != NULL);
PeiPtrLoc = (UINTN *)(UINTN)PcdGet32(PcdPeiServicePtrAddr);
*PeiPtrLoc = (UINTN)PeiServicesTablePointer;
}
/**
Retrieves the cached value of the PEI Services Table pointer.
Returns the cached value of the PEI Services Table pointer in a CPU specific manner
as specified in the CPU binding section of the Platform Initialization Pre-EFI
Initialization Core Interface Specification.
If the cached PEI Services Table pointer is NULL, then ASSERT().
@return The pointer to PeiServices.
**/
CONST EFI_PEI_SERVICES **
EFIAPI
GetPeiServicesTablePointer (
VOID
)
{
UINTN *PeiPtrLoc;
PeiPtrLoc = (UINTN *)(UINTN)PcdGet32(PcdPeiServicePtrAddr);
return (CONST EFI_PEI_SERVICES **)*PeiPtrLoc;
}

View File

@@ -0,0 +1,43 @@
## @file
# Instance of PEI Services Table Pointer Library using global variable for the table pointer.
#
# PEI Services Table Pointer Library implementation that retrieves a pointer to the
# PEI Services Table from a global variable. Not available to modules that execute from
# read-only memory.
#
# Copyright (c) 2007 - 2010, Intel Corporation. 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 = PeiServicesTablePointerLib
FILE_GUID = 1c747f6b-0a58-49ae-8ea3-0327a4fa10e3
MODULE_TYPE = PEIM
VERSION_STRING = 1.0
LIBRARY_CLASS = PeiServicesTablePointerLib|PEIM PEI_CORE SEC
#
# VALID_ARCHITECTURES = IA32 X64 IPF EBC (EBC is for build only)
#
[Sources]
PeiServicesTablePointer.c
[Packages]
MdePkg/MdePkg.dec
ArmPlatformPkg/ArmPlatformPkg.dec
[LibraryClasses]
DebugLib
[Pcd]
gArmPlatformTokenSpaceGuid.PcdPeiServicePtrAddr

View File

@@ -0,0 +1,193 @@
/** @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.
**/
#include <Base.h>
#include <Library/BaseLib.h>
#include <Library/TimerLib.h>
#include <Library/DebugLib.h>
#include <Library/PcdLib.h>
#include <Library/IoLib.h>
#include <Drivers/SP804Timer.h>
#include <ArmPlatform.h>
// Setup SP810's Timer2 for managing delay functions. And Timer3 for Performance counter
// Note: ArmVE's Timer0 and Timer1 are used by TimerDxe.
RETURN_STATUS
EFIAPI
TimerConstructor (
VOID
)
{
// Check if Timer 2 is already initialized
if (MmioRead32(SP804_TIMER2_BASE + SP804_TIMER_CONTROL_REG) & SP804_TIMER_CTRL_ENABLE) {
return RETURN_SUCCESS;
} else {
// configure SP810 to use 1MHz clock and disable
MmioAndThenOr32 (SP810_CTRL_BASE + SP810_SYS_CTRL_REG, ~SP810_SYS_CTRL_TIMER2_EN, SP810_SYS_CTRL_TIMER2_TIMCLK);
// configure timer 2 for one shot operation, 32 bits, no prescaler, and interrupt disabled
MmioOr32 (SP804_TIMER2_BASE + SP804_TIMER_CONTROL_REG, SP804_TIMER_CTRL_ONESHOT | SP804_TIMER_CTRL_32BIT | SP804_PRESCALE_DIV_1);
// preload the timer count register
MmioWrite32 (SP804_TIMER2_BASE + SP804_TIMER_LOAD_REG, 1);
// enable the timer
MmioOr32 (SP804_TIMER2_BASE + SP804_TIMER_CONTROL_REG, SP804_TIMER_CTRL_ENABLE);
}
// Check if Timer 3 is already initialized
if (MmioRead32(SP804_TIMER3_BASE + SP804_TIMER_CONTROL_REG) & SP804_TIMER_CTRL_ENABLE) {
return RETURN_SUCCESS;
} else {
// configure SP810 to use 1MHz clock and disable
MmioAndThenOr32 (SP810_CTRL_BASE + SP810_SYS_CTRL_REG, ~SP810_SYS_CTRL_TIMER3_EN, SP810_SYS_CTRL_TIMER3_TIMCLK);
// configure timer 3 for free running operation, 32 bits, no prescaler, interrupt disabled
MmioOr32 (SP804_TIMER3_BASE + SP804_TIMER_CONTROL_REG, SP804_TIMER_CTRL_32BIT | SP804_PRESCALE_DIV_1);
// enable the timer
MmioOr32 (SP804_TIMER3_BASE + SP804_TIMER_CONTROL_REG, SP804_TIMER_CTRL_ENABLE);
}
return RETURN_SUCCESS;
}
/**
Stalls the CPU for at least the given number of microseconds.
Stalls the CPU for the number of microseconds specified by MicroSeconds.
@param MicroSeconds The minimum number of microseconds to delay.
@return The value of MicroSeconds inputted.
**/
UINTN
EFIAPI
MicroSecondDelay (
IN UINTN MicroSeconds
)
{
// load the timer count register
MmioWrite32 (SP804_TIMER2_BASE + SP804_TIMER_LOAD_REG, MicroSeconds);
while (MmioRead32 (SP804_TIMER2_BASE + SP804_TIMER_CURRENT_REG) > 0) {
;
}
return MicroSeconds;
}
/**
Stalls the CPU for at least the given number of nanoseconds.
Stalls the CPU for the number of nanoseconds specified by NanoSeconds.
@param NanoSeconds The minimum number of nanoseconds to delay.
@return The value of NanoSeconds inputted.
**/
UINTN
EFIAPI
NanoSecondDelay (
IN UINTN NanoSeconds
)
{
UINT32 MicroSeconds;
// Round up to 1us Tick Number
MicroSeconds = (UINT32)NanoSeconds / 1000;
MicroSeconds += ((UINT32)NanoSeconds % 1000) == 0 ? 0 : 1;
// load the timer count register
MmioWrite32 (SP804_TIMER2_BASE + SP804_TIMER_LOAD_REG, MicroSeconds);
while (MmioRead32 (SP804_TIMER2_BASE + SP804_TIMER_CURRENT_REG) > 0) {
;
}
return NanoSeconds;
}
/**
Retrieves the current value of a 64-bit free running performance counter.
The counter can either count up by 1 or count down by 1. If the physical
performance counter counts by a larger increment, then the counter values
must be translated. The properties of the counter can be retrieved from
GetPerformanceCounterProperties().
@return The current value of the free running performance counter.
**/
UINT64
EFIAPI
GetPerformanceCounter (
VOID
)
{
// Free running 64-bit/32-bit counter is needed here.
// Don't think we need this to boot, just to do performance profile
// ASSERT (FALSE);
UINT32 val = MmioRead32 (SP804_TIMER3_BASE + SP804_TIMER_CURRENT_REG);
ASSERT(val > 0);
return (UINT64)val;
}
/**
Retrieves the 64-bit frequency in Hz and the range of performance counter
values.
If StartValue is not NULL, then the value that the performance counter starts
with immediately after is it rolls over is returned in StartValue. If
EndValue is not NULL, then the value that the performance counter end with
immediately before it rolls over is returned in EndValue. The 64-bit
frequency of the performance counter in Hz is always returned. If StartValue
is less than EndValue, then the performance counter counts up. If StartValue
is greater than EndValue, then the performance counter counts down. For
example, a 64-bit free running counter that counts up would have a StartValue
of 0 and an EndValue of 0xFFFFFFFFFFFFFFFF. A 24-bit free running counter
that counts down would have a StartValue of 0xFFFFFF and an EndValue of 0.
@param StartValue The value the performance counter starts with when it
rolls over.
@param EndValue The value that the performance counter ends with before
it rolls over.
@return The frequency in Hz.
**/
UINT64
EFIAPI
GetPerformanceCounterProperties (
OUT UINT64 *StartValue, OPTIONAL
OUT UINT64 *EndValue OPTIONAL
)
{
if (StartValue != NULL) {
// Timer starts with the reload value
*StartValue = (UINT64)0ULL;
}
if (EndValue != NULL) {
// Timer counts up to 0xFFFFFFFF
*EndValue = 0xFFFFFFFF;
}
return 1000000;
}

View File

@@ -0,0 +1,37 @@
#/** @file
# Timer library implementation
#
#
# Copyright (c) 2010, ARM Ltd. All rights reserved.<BR>
# This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
# which accompanies this distribution. The full text of the license may be found at
# http://opensource.org/licenses/bsd-license.php
#
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#
#**/
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = SP804TimerLib
FILE_GUID = 09cefa99-0d07-487f-a651-fb44f094b1c7
MODULE_TYPE = BASE
VERSION_STRING = 1.0
LIBRARY_CLASS = TimerLib
CONSTRUCTOR = TimerConstructor
[Sources.common]
SP804TimerLib.c
[Packages]
MdePkg/MdePkg.dec
ArmPkg/ArmPkg.dec
ArmPlatformPkg/ArmPlatformPkg.dec
[LibraryClasses]
DebugLib
IoLib
BaseLib