summaryrefslogtreecommitdiff
path: root/ArmPkg
diff options
context:
space:
mode:
authorLeif Lindholm <leif.lindholm@linaro.org>2013-06-19 11:07:03 +0100
committerLeif Lindholm <leif.lindholm@linaro.org>2013-06-19 11:07:03 +0100
commit4a21c40a5f30d67cdf876bc50f48abd37d9eea68 (patch)
tree49f9dd09a6ad18c45a9c1a5b9eca633a6f1a9f32 /ArmPkg
parent4cbfd417d24602d2d9c05cc5693a6e6087d1c96d (diff)
parent162fed6be629c847e162462331565e9204e47fa2 (diff)
Merging linaro-tracking-2013.06 into linaro-releaselinaro-uefi-2013.06
Signed-off-by: Leif Lindholm <leif.lindholm@linaro.org>
Diffstat (limited to 'ArmPkg')
-rw-r--r--ArmPkg/ArmPkg.dec19
-rw-r--r--ArmPkg/Drivers/ArmCpuLib/ArmCortexA15Lib/ArmCortexA15Lib.c2
-rw-r--r--ArmPkg/Drivers/ArmCpuLib/ArmCortexA15Lib/ArmCortexA15Lib.inf5
-rw-r--r--ArmPkg/Drivers/ArmCpuLib/ArmCortexA9Lib/ArmCortexA9Lib.c3
-rw-r--r--ArmPkg/Drivers/ArmCpuLib/ArmCortexA9Lib/ArmCortexA9Lib.inf9
-rw-r--r--ArmPkg/Drivers/PL390Gic/PL390GicSec.c18
-rw-r--r--ArmPkg/Drivers/PL390Gic/PL390GicSecLib.inf6
-rw-r--r--ArmPkg/Filesystem/SemihostFs/Arm/SemihostFs.c152
-rw-r--r--ArmPkg/Include/AsmMacroIoLib.h14
-rw-r--r--ArmPkg/Include/AsmMacroIoLib.inc7
-rw-r--r--ArmPkg/Include/IndustryStandard/ArmTrustZoneSmc.h2
-rw-r--r--ArmPkg/Include/Library/ArmLib.h2
-rw-r--r--ArmPkg/Library/BdsLib/BdsLib.inf2
-rw-r--r--ArmPkg/Library/BdsLib/BdsLinuxFdt.c285
14 files changed, 342 insertions, 184 deletions
diff --git a/ArmPkg/ArmPkg.dec b/ArmPkg/ArmPkg.dec
index 86a3dba7c3..81c4db6a6f 100644
--- a/ArmPkg/ArmPkg.dec
+++ b/ArmPkg/ArmPkg.dec
@@ -2,7 +2,7 @@
# ARM processor package.
#
# Copyright (c) 2009 - 2010, Apple Inc. All rights reserved.<BR>
-# Copyright (c) 2011 - 2012, ARM Limited. All rights reserved.
+# Copyright (c) 2011 - 2013, 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
@@ -137,8 +137,6 @@
# 0xC00 = cp10 | cp11
gArmTokenSpaceGuid.PcdArmNsacr|0xC00|UINT32|0x00000039
- gArmTokenSpaceGuid.PcdArmNonSecModeTransition|0x0|UINT32|0x0000003E
-
# System Memory (DRAM): These PCDs define the region of in-built system memory
# Some platforms can get DRAM extensions, these additional regions will be declared
# to UEFI by ArmPLatformPlib
@@ -163,15 +161,10 @@
# BdsLib
#
gArmTokenSpaceGuid.PcdArmMachineType|0|UINT32|0x0000001E
- # The compressed Linux kernel is expected to load at MemStart + 0x8000 (e.g. 0x8000_8000)
- gArmTokenSpaceGuid.PcdArmLinuxKernelFixedOffset|0x00008000|UINT32|0x00000027
# The compressed Linux kernel is expected to be under 128MB from the beginning of the System Memory
gArmTokenSpaceGuid.PcdArmLinuxKernelMaxOffset|0x08000000|UINT32|0x0000001F
# The Linux ATAGs are expected to be under 0x4000 (16KB) from the beginning of the System Memory
gArmTokenSpaceGuid.PcdArmLinuxAtagMaxOffset|0x4000|UINT32|0x00000020
- # If the fixed FDT address is not available, then it should be loaded the below the kernel
- # The recommandation from the Linux kernel is to have the FDT below 16KB
- gArmTokenSpaceGuid.PcdArmLinuxFdtMaxOffset|0x4000|UINT32|0x00000023
#
# ARM Architectural Timer
@@ -180,3 +173,13 @@
# ARM Architectural Timer Interrupt(GIC PPI) number
gArmTokenSpaceGuid.PcdArmArchTimerSecIntrNum|29|UINT32|0x00000035
gArmTokenSpaceGuid.PcdArmArchTimerIntrNum|30|UINT32|0x00000036
+
+[PcdsFixedAtBuild.ARM]
+ # By default we do not do a transition to non-secure mode
+ gArmTokenSpaceGuid.PcdArmNonSecModeTransition|0x0|UINT32|0x0000003E
+ # If the fixed FDT address is not available, then it should be loaded below the kernel.
+ # The recommendation from the Linux kernel is to have the FDT below 16KB.
+ # (see the kernel doc: Documentation/arm/Booting)
+ gArmTokenSpaceGuid.PcdArmLinuxFdtMaxOffset|0x4000|UINT32|0x00000023
+ # The FDT blob must be loaded at a 64bit aligned address.
+ gArmTokenSpaceGuid.PcdArmLinuxFdtAlignment|0x8|UINT32|0x00000026
diff --git a/ArmPkg/Drivers/ArmCpuLib/ArmCortexA15Lib/ArmCortexA15Lib.c b/ArmPkg/Drivers/ArmCpuLib/ArmCortexA15Lib/ArmCortexA15Lib.c
index 95ab073e18..b15597893a 100644
--- a/ArmPkg/Drivers/ArmCpuLib/ArmCortexA15Lib/ArmCortexA15Lib.c
+++ b/ArmPkg/Drivers/ArmCpuLib/ArmCortexA15Lib/ArmCortexA15Lib.c
@@ -55,7 +55,7 @@ ArmCpuSetupSmpNonSecure (
)
{
/*// Make the SCU accessible in Non Secure world
- if (IS_PRIMARY_CORE(MpId)) {
+ if (ArmPlatformIsPrimaryCore (MpId)) {
ScuBase = ArmGetScuBaseAddress();
// Allow NS access to SCU register
diff --git a/ArmPkg/Drivers/ArmCpuLib/ArmCortexA15Lib/ArmCortexA15Lib.inf b/ArmPkg/Drivers/ArmCpuLib/ArmCortexA15Lib/ArmCortexA15Lib.inf
index bcf7f6bfba..3ddd4c5704 100644
--- a/ArmPkg/Drivers/ArmCpuLib/ArmCortexA15Lib/ArmCortexA15Lib.inf
+++ b/ArmPkg/Drivers/ArmCpuLib/ArmCortexA15Lib/ArmCortexA15Lib.inf
@@ -31,10 +31,5 @@
[Sources.common]
ArmCortexA15Lib.c
-[FeaturePcd]
-
[FixedPcd]
- gArmTokenSpaceGuid.PcdArmPrimaryCoreMask
- gArmTokenSpaceGuid.PcdArmPrimaryCore
-
gArmTokenSpaceGuid.PcdArmArchTimerFreqInHz
diff --git a/ArmPkg/Drivers/ArmCpuLib/ArmCortexA9Lib/ArmCortexA9Lib.c b/ArmPkg/Drivers/ArmCpuLib/ArmCortexA9Lib/ArmCortexA9Lib.c
index 2bf2d81070..aed43cb3ef 100644
--- a/ArmPkg/Drivers/ArmCpuLib/ArmCortexA9Lib/ArmCortexA9Lib.c
+++ b/ArmPkg/Drivers/ArmCpuLib/ArmCortexA9Lib/ArmCortexA9Lib.c
@@ -15,6 +15,7 @@
#include <Base.h>
#include <Library/ArmLib.h>
#include <Library/ArmCpuLib.h>
+#include <Library/ArmPlatformLib.h>
#include <Library/IoLib.h>
#include <Library/PcdLib.h>
@@ -63,7 +64,7 @@ ArmCpuSetupSmpNonSecure (
ArmSetAuxCrBit (A9_FEATURE_SMP);
// Make the SCU accessible in Non Secure world
- if (IS_PRIMARY_CORE(MpId)) {
+ if (ArmPlatformIsPrimaryCore (MpId)) {
ScuBase = ArmGetScuBaseAddress();
// Allow NS access to SCU register
diff --git a/ArmPkg/Drivers/ArmCpuLib/ArmCortexA9Lib/ArmCortexA9Lib.inf b/ArmPkg/Drivers/ArmCpuLib/ArmCortexA9Lib/ArmCortexA9Lib.inf
index 866736f6ff..a84501dea4 100644
--- a/ArmPkg/Drivers/ArmCpuLib/ArmCortexA9Lib/ArmCortexA9Lib.inf
+++ b/ArmPkg/Drivers/ArmCpuLib/ArmCortexA9Lib/ArmCortexA9Lib.inf
@@ -1,5 +1,5 @@
#/* @file
-# Copyright (c) 2011-2012, ARM Limited. All rights reserved.
+# Copyright (c) 2011-2013, 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
@@ -22,9 +22,11 @@
[Packages]
MdePkg/MdePkg.dec
ArmPkg/ArmPkg.dec
+ ArmPlatformPkg/ArmPlatformPkg.dec
[LibraryClasses]
ArmLib
+ ArmPlatformLib
IoLib
PcdLib
@@ -33,8 +35,3 @@
ArmCortexA9Helper.asm | RVCT
ArmCortexA9Helper.S | GCC
-[FeaturePcd]
-
-[FixedPcd]
- gArmTokenSpaceGuid.PcdArmPrimaryCoreMask
- gArmTokenSpaceGuid.PcdArmPrimaryCore
diff --git a/ArmPkg/Drivers/PL390Gic/PL390GicSec.c b/ArmPkg/Drivers/PL390Gic/PL390GicSec.c
index e47e23d581..bae76e441b 100644
--- a/ArmPkg/Drivers/PL390Gic/PL390GicSec.c
+++ b/ArmPkg/Drivers/PL390Gic/PL390GicSec.c
@@ -1,6 +1,6 @@
/** @file
*
-* Copyright (c) 2011-2012, ARM Limited. All rights reserved.
+* Copyright (c) 2011-2013, 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
@@ -14,6 +14,7 @@
#include <Base.h>
#include <Library/ArmLib.h>
+#include <Library/ArmPlatformLib.h>
#include <Library/DebugLib.h>
#include <Library/IoLib.h>
#include <Library/ArmGicLib.h>
@@ -39,18 +40,19 @@ ArmGicSetupNonSecure (
// Set priority Mask so that no interrupts get through to CPU
MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCPMR, 0);
- // Check if there are any pending interrupts
- //TODO: could be extended to take Peripheral interrupts into consideration, but at the moment only SGI's are taken into consideration.
- while(0 != (MmioRead32 (GicDistributorBase + ARM_GIC_ICDICPR) & 0xF)) {
- // Some of the SGI's are still pending, read Ack register and send End of Interrupt Signal
- InterruptId = MmioRead32 (GicInterruptInterfaceBase + ARM_GIC_ICCIAR);
+ InterruptId = MmioRead32 (GicInterruptInterfaceBase + ARM_GIC_ICCIAR);
- // Write to End of interrupt signal
+ // Only try to clear valid interrupts. Ignore spurious interrupts.
+ while ((InterruptId & 0x3FF) < ArmGicGetMaxNumInterrupts (GicDistributorBase)) {
+ // Some of the SGI's are still pending, read Ack register and send End of Interrupt Signal
MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCEIOR, InterruptId);
+
+ // Next
+ InterruptId = MmioRead32 (GicInterruptInterfaceBase + ARM_GIC_ICCIAR);
}
// Only the primary core should set the Non Secure bit to the SPIs (Shared Peripheral Interrupt).
- if (IS_PRIMARY_CORE(MpId)) {
+ if (ArmPlatformIsPrimaryCore (MpId)) {
// Ensure all GIC interrupts are Non-Secure
for (Index = 0; Index < (ArmGicGetMaxNumInterrupts (GicDistributorBase) / 32); Index++) {
MmioWrite32 (GicDistributorBase + ARM_GIC_ICDISR + (Index * 4), 0xffffffff);
diff --git a/ArmPkg/Drivers/PL390Gic/PL390GicSecLib.inf b/ArmPkg/Drivers/PL390Gic/PL390GicSecLib.inf
index 73faa39b66..205e503427 100644
--- a/ArmPkg/Drivers/PL390Gic/PL390GicSecLib.inf
+++ b/ArmPkg/Drivers/PL390Gic/PL390GicSecLib.inf
@@ -25,14 +25,14 @@
[Packages]
ArmPkg/ArmPkg.dec
+ ArmPlatformPkg/ArmPlatformPkg.dec
MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
[LibraryClasses]
ArmLib
+ ArmPlatformLib
DebugLib
IoLib
PcdLib
-[FixedPcd.common]
- gArmTokenSpaceGuid.PcdArmPrimaryCoreMask
- gArmTokenSpaceGuid.PcdArmPrimaryCore
diff --git a/ArmPkg/Filesystem/SemihostFs/Arm/SemihostFs.c b/ArmPkg/Filesystem/SemihostFs/Arm/SemihostFs.c
index b04e866a99..5f1159d81a 100644
--- a/ArmPkg/Filesystem/SemihostFs/Arm/SemihostFs.c
+++ b/ArmPkg/Filesystem/SemihostFs/Arm/SemihostFs.c
@@ -2,7 +2,7 @@
Support a Semi Host file system over a debuggers JTAG
Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
- Portions copyright (c) 2011-2013, ARM Ltd. All rights reserved.<BR>
+ Portions copyright (c) 2011 - 2013, 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
@@ -18,6 +18,7 @@
#include <Guid/FileInfo.h>
#include <Guid/FileSystemInfo.h>
+#include <Guid/FileSystemVolumeLabelInfo.h>
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
@@ -32,6 +33,9 @@
#include "SemihostFs.h"
+#define DEFAULT_SEMIHOST_FS_LABEL L"SemihostFs"
+
+STATIC CHAR16 *mSemihostFsLabel;
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL gSemihostFs = {
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_REVISION,
@@ -69,13 +73,15 @@ SEMIHOST_DEVICE_PATH gDevicePath = {
};
typedef struct {
- LIST_ENTRY Link;
- UINT64 Signature;
- EFI_FILE File;
- CHAR8 *FileName;
- UINT32 Position;
- UINTN SemihostHandle;
- BOOLEAN IsRoot;
+ LIST_ENTRY Link;
+ UINT64 Signature;
+ EFI_FILE File;
+ CHAR8 *FileName;
+ UINT64 OpenMode;
+ UINT32 Position;
+ UINTN SemihostHandle;
+ BOOLEAN IsRoot;
+ EFI_FILE_INFO Info;
} SEMIHOST_FCB;
#define SEMIHOST_FCB_SIGNATURE SIGNATURE_32( 'S', 'H', 'F', 'C' )
@@ -134,6 +140,7 @@ VolumeOpen (
}
RootFcb->IsRoot = TRUE;
+ RootFcb->Info.Attribute = EFI_FILE_READ_ONLY | EFI_FILE_DIRECTORY;
InsertTailList (&gFileList, &RootFcb->Link);
@@ -157,11 +164,17 @@ FileOpen (
CHAR8 *AsciiFileName;
UINT32 SemihostMode;
BOOLEAN IsRoot;
+ UINTN Length;
if ((FileName == NULL) || (NewHandle == NULL)) {
return EFI_INVALID_PARAMETER;
}
+ // Semihosting does not support directories
+ if (Attributes & EFI_FILE_DIRECTORY) {
+ return EFI_UNSUPPORTED;
+ }
+
// Semihost interface requires ASCII filenames
AsciiFileName = AllocatePool ((StrLen (FileName) + 1) * sizeof (CHAR8));
if (AsciiFileName == NULL) {
@@ -213,6 +226,18 @@ FileOpen (
FileFcb->SemihostHandle = SemihostHandle;
FileFcb->Position = 0;
FileFcb->IsRoot = IsRoot;
+ FileFcb->OpenMode = OpenMode;
+
+ if (!IsRoot) {
+ Status = SemihostFileLength (SemihostHandle, &Length);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ FileFcb->Info.FileSize = Length;
+ FileFcb->Info.PhysicalSize = Length;
+ FileFcb->Info.Attribute = Attributes;
+ }
InsertTailList (&gFileList, &FileFcb->Link);
@@ -271,8 +296,11 @@ FileDelete (
// Call the semihost interface to delete the file.
Status = SemihostFileRemove (FileName);
+ if (EFI_ERROR(Status)) {
+ Status = EFI_WARN_DELETE_FAILURE;
+ }
} else {
- Status = EFI_UNSUPPORTED;
+ Status = EFI_WARN_DELETE_FAILURE;
}
return Status;
@@ -316,6 +344,11 @@ FileWrite (
Fcb = SEMIHOST_FCB_FROM_THIS(File);
+ // We cannot write a read-only file
+ if (Fcb->OpenMode & EFI_FILE_READ_ONLY) {
+ return EFI_ACCESS_DENIED;
+ }
+
Status = SemihostFileWrite (Fcb->SemihostHandle, &WriteSize, Buffer);
if (!EFI_ERROR(Status)) {
@@ -388,8 +421,6 @@ GetFileInfo (
UINTN NameSize = 0;
UINTN ResultSize;
UINTN Index;
- UINTN Length;
- EFI_STATUS Status;
if (Fcb->IsRoot == TRUE) {
ResultSize = SIZE_OF_EFI_FILE_INFO + sizeof(CHAR16);
@@ -405,30 +436,20 @@ GetFileInfo (
Info = Buffer;
- // Zero out the structure
- ZeroMem (Info, SIZE_OF_EFI_FILE_INFO);
+ // Copy the current file info
+ CopyMem (Info, &Fcb->Info, SIZE_OF_EFI_FILE_INFO);
// Fill in the structure
Info->Size = ResultSize;
if (Fcb->IsRoot == TRUE) {
- Info->Attribute = EFI_FILE_READ_ONLY | EFI_FILE_DIRECTORY;
Info->FileName[0] = L'\0';
} else {
- Status = SemihostFileLength (Fcb->SemihostHandle, &Length);
- if (EFI_ERROR(Status)) {
- return Status;
- }
-
- Info->FileSize = Length;
- Info->PhysicalSize = Length;
-
for (Index = 0; Index < NameSize; Index++) {
Info->FileName[Index] = Fcb->FileName[Index];
}
}
-
*BufferSize = ResultSize;
return EFI_SUCCESS;
@@ -444,10 +465,9 @@ GetFilesystemInfo (
{
EFI_FILE_SYSTEM_INFO *Info = NULL;
EFI_STATUS Status;
- STATIC CHAR16 Label[] = L"SemihostFs";
- UINTN ResultSize = SIZE_OF_EFI_FILE_SYSTEM_INFO + StrSize(Label);
+ UINTN ResultSize = SIZE_OF_EFI_FILE_SYSTEM_INFO + StrSize (mSemihostFsLabel);
- if(*BufferSize >= ResultSize) {
+ if (*BufferSize >= ResultSize) {
ZeroMem (Buffer, ResultSize);
Status = EFI_SUCCESS;
@@ -459,7 +479,7 @@ GetFilesystemInfo (
Info->FreeSpace = 0;
Info->BlockSize = 0;
- StrCpy (Info->VolumeLabel, Label);
+ StrCpy (Info->VolumeLabel, mSemihostFsLabel);
} else {
Status = EFI_BUFFER_TOO_SMALL;
}
@@ -476,17 +496,31 @@ FileGetInfo (
OUT VOID *Buffer
)
{
- SEMIHOST_FCB *Fcb = NULL;
- EFI_STATUS Status = EFI_UNSUPPORTED;
+ SEMIHOST_FCB *Fcb;
+ EFI_STATUS Status;
+ UINTN ResultSize;
Fcb = SEMIHOST_FCB_FROM_THIS(File);
- if (CompareGuid(InformationType, &gEfiFileSystemInfoGuid) != 0) {
- Status = GetFilesystemInfo(Fcb, BufferSize, Buffer);
- } else if (CompareGuid(InformationType, &gEfiFileInfoGuid) != 0) {
- Status = GetFileInfo(Fcb, BufferSize, Buffer);
+ if (CompareGuid (InformationType, &gEfiFileSystemInfoGuid) != 0) {
+ Status = GetFilesystemInfo (Fcb, BufferSize, Buffer);
+ } else if (CompareGuid (InformationType, &gEfiFileInfoGuid) != 0) {
+ Status = GetFileInfo (Fcb, BufferSize, Buffer);
+ } else if (CompareGuid (InformationType, &gEfiFileSystemVolumeLabelInfoIdGuid) != 0) {
+ ResultSize = StrSize (mSemihostFsLabel);
+
+ if (*BufferSize >= ResultSize) {
+ StrCpy (Buffer, mSemihostFsLabel);
+ Status = EFI_SUCCESS;
+ } else {
+ Status = EFI_BUFFER_TOO_SMALL;
+ }
+
+ *BufferSize = ResultSize;
+ } else {
+ Status = EFI_UNSUPPORTED;
}
-
+
return Status;
}
@@ -498,7 +532,27 @@ FileSetInfo (
IN VOID *Buffer
)
{
- return EFI_UNSUPPORTED;
+ EFI_STATUS Status;
+
+ if (Buffer == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = EFI_UNSUPPORTED;
+
+ if (CompareGuid (InformationType, &gEfiFileSystemInfoGuid) != 0) {
+ //Status = SetFilesystemInfo (Fcb, BufferSize, Buffer);
+ } else if (CompareGuid (InformationType, &gEfiFileInfoGuid) != 0) {
+ //Status = SetFileInfo (Fcb, BufferSize, Buffer);
+ } else if (CompareGuid (InformationType, &gEfiFileSystemVolumeLabelInfoIdGuid) != 0) {
+ if (StrSize (Buffer) > 0) {
+ FreePool (mSemihostFsLabel);
+ mSemihostFsLabel = AllocateCopyPool (StrSize (Buffer), Buffer);
+ Status = EFI_SUCCESS;
+ }
+ }
+
+ return Status;
}
EFI_STATUS
@@ -506,7 +560,19 @@ FileFlush (
IN EFI_FILE *File
)
{
- return EFI_SUCCESS;
+ SEMIHOST_FCB *Fcb;
+
+ Fcb = SEMIHOST_FCB_FROM_THIS(File);
+
+ if (Fcb->IsRoot) {
+ return EFI_SUCCESS;
+ } else {
+ if (Fcb->Info.Attribute & EFI_FILE_READ_ONLY) {
+ return EFI_ACCESS_DENIED;
+ } else {
+ return EFI_SUCCESS;
+ }
+ }
}
EFI_STATUS
@@ -515,17 +581,27 @@ SemihostFsEntryPoint (
IN EFI_SYSTEM_TABLE *SystemTable
)
{
- EFI_STATUS Status = EFI_NOT_FOUND;
+ EFI_STATUS Status;
+
+ Status = EFI_NOT_FOUND;
if (SemihostConnectionSupported ()) {
+ mSemihostFsLabel = AllocateCopyPool (StrSize (DEFAULT_SEMIHOST_FS_LABEL), DEFAULT_SEMIHOST_FS_LABEL);
+ if (mSemihostFsLabel == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
Status = gBS->InstallMultipleProtocolInterfaces (
&gInstallHandle,
&gEfiSimpleFileSystemProtocolGuid, &gSemihostFs,
&gEfiDevicePathProtocolGuid, &gDevicePath,
NULL
);
+
+ if (EFI_ERROR(Status)) {
+ FreePool (mSemihostFsLabel);
+ }
}
return Status;
}
-
diff --git a/ArmPkg/Include/AsmMacroIoLib.h b/ArmPkg/Include/AsmMacroIoLib.h
index c8692fcfd7..dac2e150cc 100644
--- a/ArmPkg/Include/AsmMacroIoLib.h
+++ b/ArmPkg/Include/AsmMacroIoLib.h
@@ -120,13 +120,6 @@
.long (_Data) ; \
1:
-// Convert the (ClusterId,CoreId) into a Core Position
-// We assume there are 4 cores per cluster
-#define GetCorePositionFromMpId(Pos, MpId, Tmp) \
- lsr Pos, MpId, #6 ; \
- and Tmp, MpId, #3 ; \
- add Pos, Pos, Tmp
-
// Reserve a region at the top of the Primary Core stack
// for Global variables for the XIP phase
#define SetPrimaryStack(StackTop, GlobalSize, Tmp) \
@@ -207,11 +200,6 @@ _InitializePrimaryStackEnd:
#define LoadConstantToReg(Data, Reg) \
ldr Reg, =Data
-
-#define GetCorePositionFromMpId(Pos, MpId, Tmp) \
- lsr Pos, MpId, #6 ; \
- and Tmp, MpId, #3 ; \
- add Pos, Pos, Tmp
#define SetPrimaryStack(StackTop, GlobalSize, Tmp) \
and Tmp, GlobalSize, #7 ; \
@@ -305,8 +293,6 @@ _InitializePrimaryStackEnd:
// conditional load testing eq flag
#define LoadConstantToRegIfEq(Data, Reg) LoadConstantToRegIfEqMacro Data, Reg
-#define GetCorePositionFromMpId(Pos, MpId, Tmp) GetCorePositionFromMpId Pos, MpId, Tmp
-
#define SetPrimaryStack(StackTop,GlobalSize,Tmp) SetPrimaryStack StackTop, GlobalSize, Tmp
// Initialize the Global Variable with '0'
diff --git a/ArmPkg/Include/AsmMacroIoLib.inc b/ArmPkg/Include/AsmMacroIoLib.inc
index 1ca99fdd1d..54c32d4c34 100644
--- a/ArmPkg/Include/AsmMacroIoLib.inc
+++ b/ArmPkg/Include/AsmMacroIoLib.inc
@@ -80,13 +80,6 @@
ldr $Reg, =($Data)
MEND
- MACRO
- GetCorePositionFromMpId $Pos, $MpId, $Tmp
- lsr $Pos, $MpId, #6
- and $Tmp, $MpId, #3
- add $Pos, $Pos, $Tmp
- MEND
-
; The reserved place must be 8-bytes aligned for pushing 64-bit variable on the stack
; Note: Global Size will be modified
MACRO
diff --git a/ArmPkg/Include/IndustryStandard/ArmTrustZoneSmc.h b/ArmPkg/Include/IndustryStandard/ArmTrustZoneSmc.h
index 62f8f61a7e..71b4327ebf 100644
--- a/ArmPkg/Include/IndustryStandard/ArmTrustZoneSmc.h
+++ b/ArmPkg/Include/IndustryStandard/ArmTrustZoneSmc.h
@@ -18,6 +18,8 @@
#define ARM_TRUSTZONE_UID_4LETTERID 0x1
#define ARM_TRUSTZONE_UID_MD5 0x2
+#define ARM_TRUSTZONE_ARM_UID 0x40524d48 // "ARMH"
+
#define IS_ARM_TRUSTZONE_SUPPORTED_SMC(Rx,Region) (((UINTN)(Rx) >= (UINTN)ARM_TRUSTZONE_##Region##_SMC_ID_START) && ((UINTN)(Rx) <= (UINTN)ARM_TRUSTZONE_##Region##_SMC_ID_END))
#define IS_ARM_TRUSTZONE_DEPRECIATED_SMC(Rx) ((UINTN)(Rx) <= (UINTN)ARM_TRUSTZONE_DEPRECIATED_SMC_ID_END)
diff --git a/ArmPkg/Include/Library/ArmLib.h b/ArmPkg/Include/Library/ArmLib.h
index b12be1424e..5663844b1f 100644
--- a/ArmPkg/Include/Library/ArmLib.h
+++ b/ArmPkg/Include/Library/ArmLib.h
@@ -112,11 +112,11 @@ typedef enum {
//
// ARM MP Core IDs
//
-#define IS_PRIMARY_CORE(MpId) (((MpId) & PcdGet32(PcdArmPrimaryCoreMask)) == PcdGet32(PcdArmPrimaryCore))
#define ARM_CORE_MASK 0xFF
#define ARM_CLUSTER_MASK (0xFF << 8)
#define GET_CORE_ID(MpId) ((MpId) & ARM_CORE_MASK)
#define GET_CLUSTER_ID(MpId) (((MpId) & ARM_CLUSTER_MASK) >> 8)
+#define GET_MPID(ClusterId, CoreId) (((ClusterId) << 8) | (CoreId))
// Get the position of the core for the Stack Offset (4 Core per Cluster)
// Position = (ClusterId * 4) + CoreId
#define GET_CORE_POS(MpId) ((((MpId) & ARM_CLUSTER_MASK) >> 6) + ((MpId) & ARM_CORE_MASK))
diff --git a/ArmPkg/Library/BdsLib/BdsLib.inf b/ArmPkg/Library/BdsLib/BdsLib.inf
index ccca39ab91..b6712a4fe2 100644
--- a/ArmPkg/Library/BdsLib/BdsLib.inf
+++ b/ArmPkg/Library/BdsLib/BdsLib.inf
@@ -76,7 +76,7 @@
gArmTokenSpaceGuid.PcdArmMachineType
gArmTokenSpaceGuid.PcdArmLinuxFdtMaxOffset
- gArmTokenSpaceGuid.PcdArmLinuxKernelFixedOffset
+ gArmTokenSpaceGuid.PcdArmLinuxFdtAlignment
gArmTokenSpaceGuid.PcdArmLinuxKernelMaxOffset
gArmTokenSpaceGuid.PcdArmLinuxAtagMaxOffset
diff --git a/ArmPkg/Library/BdsLib/BdsLinuxFdt.c b/ArmPkg/Library/BdsLib/BdsLinuxFdt.c
index b5dd237136..4ff0afeb7d 100644
--- a/ArmPkg/Library/BdsLib/BdsLinuxFdt.c
+++ b/ArmPkg/Library/BdsLib/BdsLinuxFdt.c
@@ -25,6 +25,22 @@
#define PALIGN(p, a) ((void *)(ALIGN((unsigned long)(p), (a))))
#define GET_CELL(p) (p += 4, *((const UINT32 *)(p-4)))
+STATIC inline
+UINTN
+cpu_to_fdtn (UINTN x) {
+ if (sizeof (UINTN) == sizeof (UINT32)) {
+ return cpu_to_fdt32 (x);
+ } else {
+ return cpu_to_fdt64 (x);
+ }
+}
+
+typedef struct {
+ UINTN Base;
+ UINTN Size;
+} FdtRegion;
+
+
STATIC
UINTN
IsPrintableString (
@@ -198,10 +214,110 @@ IsLinuxReservedRegion (
}
-typedef struct {
- UINTN Base;
- UINTN Size;
-} FdtRegion;
+STATIC
+BOOLEAN
+IsPsciSmcSupported (
+ VOID
+ )
+{
+ BOOLEAN PsciSmcSupported;
+ UINTN Rx;
+
+ PsciSmcSupported = FALSE;
+
+ // Check the SMC response to the Presence SMC
+ Rx = ARM_SMC_ID_PRESENCE;
+ ArmCallSmc (&Rx);
+ if (Rx == 1) {
+ // Check the SMC UID
+ Rx = ARM_SMC_ID_UID;
+ ArmCallSmc (&Rx);
+ if (Rx == ARM_TRUSTZONE_UID_4LETTERID) {
+ Rx = ARM_SMC_ID_UID + 1;
+ ArmCallSmc (&Rx);
+ if (Rx == ARM_TRUSTZONE_ARM_UID) {
+ PsciSmcSupported = TRUE;
+ }
+ }
+ }
+
+ return PsciSmcSupported;
+}
+
+
+/**
+** Relocate the FDT blob to a more appropriate location for the Linux kernel.
+** This function will allocate memory for the relocated FDT blob.
+**
+** @retval EFI_SUCCESS on success.
+** @retval EFI_OUT_OF_RESOURCES or EFI_INVALID_PARAMETER on failure.
+*/
+STATIC
+EFI_STATUS
+RelocateFdt (
+ EFI_PHYSICAL_ADDRESS OriginalFdt,
+ UINTN OriginalFdtSize,
+ EFI_PHYSICAL_ADDRESS *RelocatedFdt,
+ UINTN *RelocatedFdtSize,
+ EFI_PHYSICAL_ADDRESS *RelocatedFdtAlloc
+ )
+{
+ EFI_STATUS Status;
+ INTN Error;
+ UINT32 FdtAlignment;
+
+ *RelocatedFdtSize = OriginalFdtSize + FDT_ADDITIONAL_ENTRIES_SIZE;
+
+ // If FDT load address needs to be aligned, allocate more space.
+ FdtAlignment = PcdGet32 (PcdArmLinuxFdtAlignment);
+ if (FdtAlignment != 0) {
+ *RelocatedFdtSize += FdtAlignment;
+ }
+
+ // Try below a watermark address.
+ Status = EFI_NOT_FOUND;
+ if (PcdGet32 (PcdArmLinuxFdtMaxOffset) != 0) {
+ *RelocatedFdt = LINUX_FDT_MAX_OFFSET;
+ Status = gBS->AllocatePages (AllocateMaxAddress, EfiBootServicesData,
+ EFI_SIZE_TO_PAGES (*RelocatedFdtSize), RelocatedFdt);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_WARN, "Warning: Failed to load FDT below address 0x%lX (%r). Will try again at a random address anywhere.\n", *RelocatedFdt, Status));
+ }
+ }
+
+ // Try anywhere there is available space.
+ if (EFI_ERROR (Status)) {
+ Status = gBS->AllocatePages (AllocateAnyPages, EfiBootServicesData,
+ EFI_SIZE_TO_PAGES (*RelocatedFdtSize), RelocatedFdt);
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ return EFI_OUT_OF_RESOURCES;
+ } else {
+ DEBUG ((EFI_D_WARN, "WARNING: Loaded FDT at random address 0x%lX.\nWARNING: There is a risk of accidental overwriting by other code/data.\n", *RelocatedFdt));
+ }
+ }
+
+ *RelocatedFdtAlloc = *RelocatedFdt;
+ if (FdtAlignment != 0) {
+ *RelocatedFdt = ALIGN (*RelocatedFdt, FdtAlignment);
+ }
+
+ // Load the Original FDT tree into the new region
+ Error = fdt_open_into ((VOID*)(UINTN) OriginalFdt,
+ (VOID*)(UINTN)(*RelocatedFdt), *RelocatedFdtSize);
+ if (Error) {
+ DEBUG ((EFI_D_ERROR, "fdt_open_into(): %a\n", fdt_strerror (Error)));
+ gBS->FreePages (*RelocatedFdtAlloc, EFI_SIZE_TO_PAGES (*RelocatedFdtSize));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ DEBUG_CODE_BEGIN();
+ //DebugDumpFdt (fdt);
+ DEBUG_CODE_END();
+
+ return EFI_SUCCESS;
+}
+
EFI_STATUS
PrepareFdt (
@@ -214,6 +330,7 @@ PrepareFdt (
{
EFI_STATUS Status;
EFI_PHYSICAL_ADDRESS NewFdtBlobBase;
+ EFI_PHYSICAL_ADDRESS NewFdtBlobAllocation;
UINTN NewFdtBlobSize;
VOID* fdt;
INTN err;
@@ -242,35 +359,12 @@ PrepareFdt (
UINT32 DescriptorVersion;
UINTN Pages;
BOOLEAN PsciSmcSupported;
- UINTN Rx;
UINTN OriginalFdtSize;
+ BOOLEAN CpusNodeExist;
+ UINTN CoreMpId;
+ UINTN Smc;
- //
- // Ensure the Power State Coordination Interface (PSCI) SMCs are there if supported
- //
- PsciSmcSupported = FALSE;
- if (FeaturePcdGet (PcdArmPsciSupport) == TRUE) {
- // Check the SMC response to the Presence SMC
- Rx = ARM_SMC_ID_PRESENCE;
- ArmCallSmc (&Rx);
- if (Rx == 1) {
- // Check the SMC UID
- Rx = ARM_SMC_ID_UID;
- ArmCallSmc (&Rx);
- if (Rx == ARM_TRUSTZONE_UID_4LETTERID) {
- Rx = ARM_SMC_ID_UID + 1;
- ArmCallSmc (&Rx);
- //TODO: Replace ARM magic number
- if (Rx == 0x40524d48) {
- PsciSmcSupported = TRUE;
- }
- }
- if (PsciSmcSupported == FALSE) {
- DEBUG((EFI_D_ERROR,"Warning: The Power State Coordination Interface (PSCI) is not supported"
- "by your platform Trusted Firmware.\n"));
- }
- }
- }
+ NewFdtBlobAllocation = 0;
//
// Sanity checks on the original FDT blob.
@@ -291,52 +385,35 @@ PrepareFdt (
}
//
- // Allocate memory for the new FDT
+ // Relocate the FDT to its final location.
//
- NewFdtBlobSize = OriginalFdtSize + FDT_ADDITIONAL_ENTRIES_SIZE;
-
- // Try below a watermark address
- Status = EFI_NOT_FOUND;
- if (PcdGet32(PcdArmLinuxFdtMaxOffset) != 0) {
- NewFdtBlobBase = LINUX_FDT_MAX_OFFSET;
- Status = gBS->AllocatePages (AllocateMaxAddress, EfiBootServicesData, EFI_SIZE_TO_PAGES(NewFdtBlobSize), &NewFdtBlobBase);
- if (EFI_ERROR(Status)) {
- DEBUG ((EFI_D_WARN, "Warning: Failed to load FDT below address 0x%lX (%r). Will try again at a random address anywhere.\n", NewFdtBlobBase, Status));
- }
+ Status = RelocateFdt (*FdtBlobBase, OriginalFdtSize,
+ &NewFdtBlobBase, &NewFdtBlobSize, &NewFdtBlobAllocation);
+ if (EFI_ERROR (Status)) {
+ goto FAIL_RELOCATE_FDT;
}
- // Try anywhere there is available space
- if (EFI_ERROR(Status)) {
- Status = gBS->AllocatePages (AllocateAnyPages, EfiBootServicesData, EFI_SIZE_TO_PAGES(NewFdtBlobSize), &NewFdtBlobBase);
- if (EFI_ERROR(Status)) {
- ASSERT_EFI_ERROR(Status);
- goto FAIL_ALLOCATE_NEW_FDT;
- } else {
- DEBUG ((EFI_D_WARN, "WARNING: Loaded FDT at random address 0x%lX.\nWARNING: There is a risk of accidental overwriting by other code/data.\n", NewFdtBlobBase));
+ //
+ // Ensure the Power State Coordination Interface (PSCI) SMCs are there if supported
+ //
+ PsciSmcSupported = FALSE;
+ if (FeaturePcdGet (PcdArmPsciSupport) == TRUE) {
+ PsciSmcSupported = IsPsciSmcSupported();
+ if (PsciSmcSupported == FALSE) {
+ DEBUG ((EFI_D_ERROR, "Warning: The Power State Coordination Interface (PSCI) is not supported by your platform Trusted Firmware.\n"));
}
}
- // Load the Original FDT tree into the new region
fdt = (VOID*)(UINTN)NewFdtBlobBase;
- err = fdt_open_into((VOID*)(UINTN)(*FdtBlobBase), fdt, NewFdtBlobSize);
- if (err) {
- DEBUG((EFI_D_ERROR, "fdt_open_into(): %a\n", fdt_strerror(err)));
- Status = EFI_INVALID_PARAMETER;
- goto FAIL_NEW_FDT;
- }
-
- DEBUG_CODE_BEGIN();
- //DebugDumpFdt (fdt);
- DEBUG_CODE_END();
- node = fdt_subnode_offset(fdt, 0, "chosen");
+ node = fdt_subnode_offset (fdt, 0, "chosen");
if (node < 0) {
// The 'chosen' node does not exist, create it
node = fdt_add_subnode(fdt, 0, "chosen");
if (node < 0) {
DEBUG((EFI_D_ERROR,"Error on finding 'chosen' node\n"));
Status = EFI_INVALID_PARAMETER;
- goto FAIL_NEW_FDT;
+ goto FAIL_COMPLETE_FDT;
}
}
@@ -387,13 +464,8 @@ PrepareFdt (
GetSystemMemoryResources (&ResourceList);
Resource = (BDS_SYSTEM_MEMORY_RESOURCE*)ResourceList.ForwardLink;
- if (sizeof(UINTN) == sizeof(UINT32)) {
- Region.Base = cpu_to_fdt32((UINTN)Resource->PhysicalStart);
- Region.Size = cpu_to_fdt32((UINTN)Resource->ResourceLength);
- } else {
- Region.Base = cpu_to_fdt64((UINTN)Resource->PhysicalStart);
- Region.Size = cpu_to_fdt64((UINTN)Resource->ResourceLength);
- }
+ Region.Base = cpu_to_fdtn ((UINTN)Resource->PhysicalStart);
+ Region.Size = cpu_to_fdtn ((UINTN)Resource->ResourceLength);
err = fdt_setprop(fdt, node, "reg", &Region, sizeof(Region));
if (err) {
@@ -433,7 +505,11 @@ PrepareFdt (
}
//
- // Setup Arm Mpcore Info if it is a multi-core or multi-cluster platforms
+ // Setup Arm Mpcore Info if it is a multi-core or multi-cluster platforms.
+ //
+ // For 'cpus' and 'cpu' device tree nodes bindings, refer to this file
+ // in the kernel documentation:
+ // Documentation/devicetree/bindings/arm/cpus.txt
//
for (Index=0; Index < gST->NumberOfTableEntries; Index++) {
// Check for correct GUID type
@@ -447,8 +523,11 @@ PrepareFdt (
// Create the /cpus node
node = fdt_add_subnode(fdt, 0, "cpus");
fdt_setprop_string(fdt, node, "name", "cpus");
- fdt_setprop_cell(fdt, node, "#address-cells", 1);
+ fdt_setprop_cell (fdt, node, "#address-cells", sizeof (UINTN) / 4);
fdt_setprop_cell(fdt, node, "#size-cells", 0);
+ CpusNodeExist = FALSE;
+ } else {
+ CpusNodeExist = TRUE;
}
// Get pointer to ARM processor table
@@ -457,16 +536,33 @@ PrepareFdt (
for (Index = 0; Index < ArmProcessorTable->NumberOfEntries; Index++) {
AsciiSPrint (Name, 10, "cpu@%d", Index);
- cpu_node = fdt_subnode_offset(fdt, node, Name);
- if (cpu_node < 0) {
- cpu_node = fdt_add_subnode(fdt, node, Name);
- fdt_setprop_string(fdt, cpu_node, "device-type", "cpu");
- fdt_setprop(fdt, cpu_node, "reg", &Index, sizeof(Index));
+
+ // If the 'cpus' node did not exist then create all the 'cpu' nodes.
+ // In case 'cpus' node is provided in the original FDT then we do not add
+ // any 'cpu' node.
+ if (!CpusNodeExist) {
+ cpu_node = fdt_add_subnode (fdt, node, Name);
+ if (cpu_node < 0) {
+ DEBUG ((EFI_D_ERROR, "Error on creating '%s' node\n", Name));
+ Status = EFI_INVALID_PARAMETER;
+ goto FAIL_COMPLETE_FDT;
+ }
+
+ fdt_setprop_string (fdt, cpu_node, "device_type", "cpu");
+ CoreMpId = (UINTN) GET_MPID (ArmCoreInfoTable[Index].ClusterId,
+ ArmCoreInfoTable[Index].CoreId);
+ CoreMpId = cpu_to_fdtn (CoreMpId);
+ fdt_setprop (fdt, cpu_node, "reg", &CoreMpId, sizeof (CoreMpId));
+ if (PsciSmcSupported) {
+ fdt_setprop_string (fdt, cpu_node, "enable-method", "psci");
+ }
+ } else {
+ cpu_node = fdt_subnode_offset(fdt, node, Name);
}
// If Power State Coordination Interface (PSCI) is not supported then it is expected the secondary
// cores are spinning waiting for the Operating System to release them
- if (PsciSmcSupported == FALSE) {
+ if ((PsciSmcSupported == FALSE) && (cpu_node >= 0)) {
// We as the bootloader are responsible for either creating or updating
// these entries. Do not trust the entries in the DT. We only know about
// 'spin-table' type. Do not try to update other types if defined.
@@ -499,14 +595,22 @@ PrepareFdt (
if (node < 0) {
DEBUG((EFI_D_ERROR,"Error on creating 'psci' node\n"));
Status = EFI_INVALID_PARAMETER;
- goto FAIL_NEW_FDT;
+ goto FAIL_COMPLETE_FDT;
} else {
- fdt_setprop_string(fdt, node, "compatible", "arm,psci");
- fdt_setprop_string(fdt, node, "method", "smc");
- fdt_setprop_cell(fdt, node, "cpu_suspend", ARM_SMC_ARM_CPU_SUSPEND);
- fdt_setprop_cell(fdt, node, "cpu_off", ARM_SMC_ARM_CPU_OFF);
- fdt_setprop_cell(fdt, node, "cpu_on", ARM_SMC_ARM_CPU_ON);
- fdt_setprop_cell(fdt, node, "cpu_migrate", ARM_SMC_ARM_MIGRATE);
+ fdt_setprop_string (fdt, node, "compatible", "arm,psci");
+ fdt_setprop_string (fdt, node, "method", "smc");
+
+ Smc = cpu_to_fdtn (ARM_SMC_ARM_CPU_SUSPEND);
+ fdt_setprop (fdt, node, "cpu_suspend", &Smc, sizeof (Smc));
+
+ Smc = cpu_to_fdtn (ARM_SMC_ARM_CPU_OFF);
+ fdt_setprop (fdt, node, "cpu_off", &Smc, sizeof (Smc));
+
+ Smc = cpu_to_fdtn (ARM_SMC_ARM_CPU_ON);
+ fdt_setprop (fdt, node, "cpu_on", &Smc, sizeof (Smc));
+
+ Smc = cpu_to_fdtn (ARM_SMC_ARM_MIGRATE);
+ fdt_setprop (fdt, node, "migrate", &Smc, sizeof (Smc));
}
}
}
@@ -522,13 +626,12 @@ PrepareFdt (
*FdtBlobSize = (UINTN)fdt_totalsize ((VOID*)(UINTN)(NewFdtBlobBase));
return EFI_SUCCESS;
-FAIL_NEW_FDT:
- gBS->FreePages (NewFdtBlobBase, EFI_SIZE_TO_PAGES (NewFdtBlobSize));
+FAIL_COMPLETE_FDT:
+ gBS->FreePages (NewFdtBlobAllocation, EFI_SIZE_TO_PAGES (NewFdtBlobSize));
-FAIL_ALLOCATE_NEW_FDT:
+FAIL_RELOCATE_FDT:
*FdtBlobSize = (UINTN)fdt_totalsize ((VOID*)(UINTN)(*FdtBlobBase));
- // Return success even if we failed to update the FDT blob. The original one is still valid.
+ // Return success even if we failed to update the FDT blob.
+ // The original one is still valid.
return EFI_SUCCESS;
}
-
-