From: oliviermartin Date: Tue, 27 Sep 2011 16:26:03 +0000 (+0000) Subject: ArmPkg: Introduce ArmCpuLib to abstract ARM Cpu specific initialization (2) X-Git-Tag: edk2-stable201903~14134 X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=commitdiff_plain;h=3127615b4d6ce75b5c22780847a83124c5f2e552 ArmPkg: Introduce ArmCpuLib to abstract ARM Cpu specific initialization (2) Missed new files. git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@12450 6f19259b-4bc3-4df7-8a09-765794883524 --- diff --git a/ArmPkg/Drivers/ArmCpuLib/ArmCortexA8Lib/ArmCortexA8Lib.c b/ArmPkg/Drivers/ArmCpuLib/ArmCortexA8Lib/ArmCortexA8Lib.c new file mode 100644 index 0000000000..d755f68243 --- /dev/null +++ b/ArmPkg/Drivers/ArmCpuLib/ArmCortexA8Lib/ArmCortexA8Lib.c @@ -0,0 +1,59 @@ +/** @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 +#include +#include +#include + +#include + +VOID +ArmCpuSynchronizeWait ( + IN ARM_CPU_SYNCHRONIZE_EVENT Event + ) +{ + // The CortexA8 is a Unicore CPU. We must not use Synchronization functions + ASSERT(0); +} + +VOID +ArmCpuSynchronizeSignal ( + IN ARM_CPU_SYNCHRONIZE_EVENT Event + ) +{ + // The CortexA8 is a Unicore CPU. We must not use Synchronization functions + ASSERT(0); +} + +VOID +ArmCpuSetup ( + IN UINTN MpId + ) +{ + // Enable SWP instructions + ArmEnableSWPInstruction (); + + // Enable program flow prediction, if supported. + ArmEnableBranchPrediction (); +} + +VOID +ArmCpuSetupSmpNonSecure ( + IN UINTN MpId + ) +{ + // The CortexA8 is a Unicore CPU. We must not initialize SMP for Non Secure Accesses + ASSERT(0); +} diff --git a/ArmPkg/Drivers/ArmCpuLib/ArmCortexA8Lib/ArmCortexA8Lib.inf b/ArmPkg/Drivers/ArmCpuLib/ArmCortexA8Lib/ArmCortexA8Lib.inf new file mode 100644 index 0000000000..c6895879c2 --- /dev/null +++ b/ArmPkg/Drivers/ArmCpuLib/ArmCortexA8Lib/ArmCortexA8Lib.inf @@ -0,0 +1,27 @@ +#/* @file +# Copyright (c) 2011, ARM Limited. All rights reserved. +# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +#*/ + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = ArmCortexA8Lib + FILE_GUID = 34b5745e-f575-44ce-ba2e-df0886807c16 + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = ArmCpuLib + +[Packages] + MdePkg/MdePkg.dec + ArmPkg/ArmPkg.dec + +[Sources.common] + ArmCortexA8Lib.c diff --git a/ArmPkg/Drivers/ArmCpuLib/ArmCortexA9Lib/ArmCortexA9Helper.S b/ArmPkg/Drivers/ArmCpuLib/ArmCortexA9Lib/ArmCortexA9Helper.S new file mode 100644 index 0000000000..0d6a62b740 --- /dev/null +++ b/ArmPkg/Drivers/ArmCpuLib/ArmCortexA9Lib/ArmCortexA9Helper.S @@ -0,0 +1,52 @@ +// +// 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 +#include + +.text +.align 3 + +GCC_ASM_EXPORT(ArmCpuSynchronizeWait) +GCC_ASM_EXPORT(ArmGetScuBaseAddress) +GCC_ASM_IMPORT(CArmCpuSynchronizeWait) + +// VOID +// ArmCpuSynchronizeWait ( +// IN ARM_CPU_SYNCHRONIZE_EVENT Event +// ); +ASM_PFX(ArmCpuSynchronizeWait): + cmp r0, #ARM_CPU_EVENT_BOOT_MEM_INIT + // The SCU enabled is the event to tell us the Init Boot Memory is initialized + beq ArmWaitScuEnabled + b CArmCpuSynchronizeWait + +// IN None +// OUT r0 = SCU Base Address +ASM_PFX(ArmGetScuBaseAddress): + // Read Configuration Base Address Register. ArmCBar cannot be called to get + // the Configuration BAR as a stack is not necessary setup. The SCU is at the + // offset 0x0000 from the Private Memory Region. + mrc p15, 4, r0, c15, c0, 0 + bx lr + +ASM_PFX(ArmWaitScuEnabled): + // Read Configuration Base Address Register. ArmCBar cannot be called to get + // the Configuration BAR as a stack is not necessary setup. The SCU is at the + // offset 0x0000 from the Private Memory Region. + mrc p15, 4, r0, c15, c0, 0 + add r0, r0, #A9_SCU_CONTROL_OFFSET + ldr r0, [r0] + cmp r0, #1 + bne ArmWaitScuEnabled + bx lr diff --git a/ArmPkg/Drivers/ArmCpuLib/ArmCortexA9Lib/ArmCortexA9Helper.asm b/ArmPkg/Drivers/ArmCpuLib/ArmCortexA9Lib/ArmCortexA9Helper.asm new file mode 100644 index 0000000000..d0fc2b5a8a --- /dev/null +++ b/ArmPkg/Drivers/ArmCpuLib/ArmCortexA9Lib/ArmCortexA9Helper.asm @@ -0,0 +1,54 @@ +// +// 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 +#include + + EXPORT ArmCpuSynchronizeWait + EXPORT ArmGetScuBaseAddress + IMPORT CArmCpuSynchronizeWait + + PRESERVE8 + AREA ArmCortexA9Helper, CODE, READONLY + +// VOID +// ArmCpuSynchronizeWait ( +// IN ARM_CPU_SYNCHRONIZE_EVENT Event +// ); +ArmCpuSynchronizeWait + cmp r0, #ARM_CPU_EVENT_BOOT_MEM_INIT + // The SCU enabled is the event to tell us the Init Boot Memory is initialized + beq ArmWaitScuEnabled + b CArmCpuSynchronizeWait + +// IN None +// OUT r0 = SCU Base Address +ArmGetScuBaseAddress + // Read Configuration Base Address Register. ArmCBar cannot be called to get + // the Configuration BAR as a stack is not necessary setup. The SCU is at the + // offset 0x0000 from the Private Memory Region. + mrc p15, 4, r0, c15, c0, 0 + bx lr + +ArmWaitScuEnabled + // Read Configuration Base Address Register. ArmCBar cannot be called to get + // the Configuration BAR as a stack is not necessary setup. The SCU is at the + // offset 0x0000 from the Private Memory Region. + mrc p15, 4, r0, c15, c0, 0 + add r0, r0, #A9_SCU_CONTROL_OFFSET + ldr r0, [r0] + cmp r0, #1 + bne ArmWaitScuEnabled + bx lr + + END diff --git a/ArmPkg/Drivers/ArmCpuLib/ArmCortexA9Lib/ArmCortexA9Lib.c b/ArmPkg/Drivers/ArmCpuLib/ArmCortexA9Lib/ArmCortexA9Lib.c new file mode 100644 index 0000000000..7c5c3ee6a9 --- /dev/null +++ b/ArmPkg/Drivers/ArmCpuLib/ArmCortexA9Lib/ArmCortexA9Lib.c @@ -0,0 +1,102 @@ +/** @file + + Copyright (c) 2011, ARM Limited. All rights reserved. + + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include +#include +#include +#include +#include +#include + +#include + +VOID +ArmCpuSynchronizeSignal ( + IN ARM_CPU_SYNCHRONIZE_EVENT Event + ) +{ + if (Event == ARM_CPU_EVENT_BOOT_MEM_INIT) { + // Do nothing, Cortex A9 secondary cores are waiting for the SCU to be + // enabled (done by ArmCpuSetup()) as a way to know when the Init Boot + // Mem as been initialized + } else { + // Send SGI to all Secondary core to wake them up from WFI state. + ArmGicSendSgiTo (PcdGet32(PcdGicDistributorBase), ARM_GIC_ICDSGIR_FILTER_EVERYONEELSE, 0x0E); + } +} + +VOID +CArmCpuSynchronizeWait ( + IN ARM_CPU_SYNCHRONIZE_EVENT Event + ) +{ + // Waiting for the SGI from the primary core + ArmCallWFI (); + + // Acknowledge the interrupt and send End of Interrupt signal. + ArmGicAcknowledgeSgiFrom (PcdGet32(PcdGicInterruptInterfaceBase), PRIMARY_CORE_ID); +} + +VOID +ArmEnableScu ( + VOID + ) +{ + INTN ScuBase; + + ScuBase = ArmGetScuBaseAddress(); + + // Invalidate all: write -1 to SCU Invalidate All register + MmioWrite32(ScuBase + A9_SCU_INVALL_OFFSET, 0xffffffff); + // Enable SCU + MmioWrite32(ScuBase + A9_SCU_CONTROL_OFFSET, 0x1); +} + +VOID +ArmCpuSetup ( + IN UINTN MpId + ) +{ + // Enable SWP instructions + ArmEnableSWPInstruction (); + + // Enable program flow prediction, if supported. + ArmEnableBranchPrediction (); + + // If MPCore then Enable the SCU + if (ArmIsMpCore()) { + ArmEnableScu (); + } +} + + +VOID +ArmCpuSetupSmpNonSecure ( + IN UINTN MpId + ) +{ + INTN ScuBase; + + ArmSetAuxCrBit (A9_FEATURE_SMP); + + // Make the SCU accessible in Non Secure world + if (IS_PRIMARY_CORE(MpId)) { + ScuBase = ArmGetScuBaseAddress(); + + // Allow NS access to SCU register + MmioOr32 (ScuBase + A9_SCU_SACR_OFFSET, 0xf); + // Allow NS access to Private Peripherals + MmioOr32 (ScuBase + A9_SCU_SSACR_OFFSET, 0xfff); + } +} diff --git a/ArmPkg/Drivers/ArmCpuLib/ArmCortexA9Lib/ArmCortexA9Lib.inf b/ArmPkg/Drivers/ArmCpuLib/ArmCortexA9Lib/ArmCortexA9Lib.inf new file mode 100644 index 0000000000..a03efd237b --- /dev/null +++ b/ArmPkg/Drivers/ArmCpuLib/ArmCortexA9Lib/ArmCortexA9Lib.inf @@ -0,0 +1,44 @@ +#/* @file +# Copyright (c) 2011, ARM Limited. All rights reserved. +# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +#*/ + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = ArmCortexA9Lib + FILE_GUID = c9709ea3-1beb-4806-889a-8a1d5e5e1697 + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = ArmCpuLib + +[Packages] + MdePkg/MdePkg.dec + ArmPkg/ArmPkg.dec + +[LibraryClasses] + ArmLib + ArmGicSecLib + IoLib + PcdLib + +[Sources.common] + ArmCortexA9Lib.c + ArmCortexA9Helper.asm | RVCT + ArmCortexA9Helper.S | GCC + +[FeaturePcd] + +[FixedPcd] + gArmTokenSpaceGuid.PcdArmPrimaryCoreMask + gArmTokenSpaceGuid.PcdArmPrimaryCore + + gArmTokenSpaceGuid.PcdGicDistributorBase + gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase diff --git a/ArmPkg/Include/Chipset/ArmCortexA9.h b/ArmPkg/Include/Chipset/ArmCortexA9.h new file mode 100644 index 0000000000..af9a300714 --- /dev/null +++ b/ArmPkg/Include/Chipset/ArmCortexA9.h @@ -0,0 +1,65 @@ +/** @file + + Copyright (c) 2011, ARM Limited. All rights reserved. + + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef __ARM_CORTEX_A9_H__ +#define __ARM_CORTEX_A9_H__ + +#include + +// +// Cortex A9 feature bit definitions +// +#define A9_FEATURE_PARITY (1<<9) +#define A9_FEATURE_AOW (1<<8) +#define A9_FEATURE_EXCL (1<<7) +#define A9_FEATURE_SMP (1<<6) +#define A9_FEATURE_FOZ (1<<3) +#define A9_FEATURE_DPREF (1<<2) +#define A9_FEATURE_HINT (1<<1) +#define A9_FEATURE_FWD (1<<0) + +// +// Cortex A9 Watchdog +// +#define ARM_A9_WATCHDOG_REGION 0x600 + +#define ARM_A9_WATCHDOG_LOAD_REGISTER 0x20 +#define ARM_A9_WATCHDOG_CONTROL_REGISTER 0x28 + +#define ARM_A9_WATCHDOG_WATCHDOG_MODE (1 << 3) +#define ARM_A9_WATCHDOG_TIMER_MODE (0 << 3) +#define ARM_A9_WATCHDOG_SINGLE_SHOT (0 << 1) +#define ARM_A9_WATCHDOG_AUTORELOAD (1 << 1) +#define ARM_A9_WATCHDOG_ENABLE 1 + +// +// SCU register offsets & masks +// +#define A9_SCU_CONTROL_OFFSET 0x0 +#define A9_SCU_CONFIG_OFFSET 0x4 +#define A9_SCU_INVALL_OFFSET 0xC +#define A9_SCU_FILT_START_OFFSET 0x40 +#define A9_SCU_FILT_END_OFFSET 0x44 +#define A9_SCU_SACR_OFFSET 0x50 +#define A9_SCU_SSACR_OFFSET 0x54 + + +UINTN +EFIAPI +ArmGetScuBaseAddress ( + VOID + ); + +#endif + diff --git a/ArmPkg/Include/Library/ArmCpuLib.h b/ArmPkg/Include/Library/ArmCpuLib.h new file mode 100644 index 0000000000..8de5aad632 --- /dev/null +++ b/ArmPkg/Include/Library/ArmCpuLib.h @@ -0,0 +1,46 @@ +/** @file + + Copyright (c) 2011, ARM Limited. All rights reserved. + + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef __ARMCPU_LIB__ +#define __ARMCPU_LIB__ + +// These are #define and not enum to be used in assembly files +#define ARM_CPU_EVENT_DEFAULT 0 +#define ARM_CPU_EVENT_BOOT_MEM_INIT 1 +#define ARM_CPU_EVENT_SECURE_INIT 2 + +typedef UINTN ARM_CPU_SYNCHRONIZE_EVENT; + + +VOID +ArmCpuSynchronizeWait ( + IN ARM_CPU_SYNCHRONIZE_EVENT Event + ); + +VOID +ArmCpuSynchronizeSignal ( + IN ARM_CPU_SYNCHRONIZE_EVENT Event + ); + +VOID +ArmCpuSetup ( + IN UINTN MpId + ); + +VOID +ArmCpuSetupSmpNonSecure ( + IN UINTN MpId + ); + +#endif // __ARMCPU_LIB__