From b1caff5a30e3a8893d12b717a4f0811c60839a60 Mon Sep 17 00:00:00 2001 From: "wei.xu" Date: Thu, 29 May 2014 09:48:07 +0800 Subject: HisiPkg: change the GIC to Hisilicon D01 GIC since there are some differences from ARM GIC Signed-off-by: Wei Xu --- HisiPkg/D01BoardPkg/D01BoardPkg.dsc | 9 +- HisiPkg/D01BoardPkg/D01BoardPkg.dsc.inc | 6 +- HisiPkg/D01BoardPkg/D01BoardPkg.fdf | 4 +- HisiPkg/Drivers/HisiliconD01Gic/HisiliconD01Gic.c | 71 ++++ .../Drivers/HisiliconD01Gic/HisiliconD01GicDxe.c | 425 +++++++++++++++++++++ .../Drivers/HisiliconD01Gic/HisiliconD01GicDxe.inf | 59 +++ .../Drivers/HisiliconD01Gic/HisiliconD01GicLib.inf | 32 ++ .../HisiliconD01Gic/HisiliconD01GicNonSec.c | 45 +++ .../Drivers/HisiliconD01Gic/HisiliconD01GicSec.c | 132 +++++++ .../HisiliconD01Gic/HisiliconD01GicSecLib.inf | 41 ++ HisiPkg/Drivers/PL390Gic/PL390Gic.c | 71 ---- HisiPkg/Drivers/PL390Gic/PL390GicDxe.c | 425 --------------------- HisiPkg/Drivers/PL390Gic/PL390GicDxe.inf | 59 --- HisiPkg/Drivers/PL390Gic/PL390GicLib.inf | 29 -- HisiPkg/Drivers/PL390Gic/PL390GicNonSec.c | 45 --- HisiPkg/Drivers/PL390Gic/PL390GicSec.c | 132 ------- HisiPkg/Drivers/PL390Gic/PL390GicSecLib.inf | 39 -- 17 files changed, 816 insertions(+), 808 deletions(-) create mode 100644 HisiPkg/Drivers/HisiliconD01Gic/HisiliconD01Gic.c create mode 100644 HisiPkg/Drivers/HisiliconD01Gic/HisiliconD01GicDxe.c create mode 100644 HisiPkg/Drivers/HisiliconD01Gic/HisiliconD01GicDxe.inf create mode 100644 HisiPkg/Drivers/HisiliconD01Gic/HisiliconD01GicLib.inf create mode 100644 HisiPkg/Drivers/HisiliconD01Gic/HisiliconD01GicNonSec.c create mode 100644 HisiPkg/Drivers/HisiliconD01Gic/HisiliconD01GicSec.c create mode 100644 HisiPkg/Drivers/HisiliconD01Gic/HisiliconD01GicSecLib.inf delete mode 100644 HisiPkg/Drivers/PL390Gic/PL390Gic.c delete mode 100644 HisiPkg/Drivers/PL390Gic/PL390GicDxe.c delete mode 100644 HisiPkg/Drivers/PL390Gic/PL390GicDxe.inf delete mode 100644 HisiPkg/Drivers/PL390Gic/PL390GicLib.inf delete mode 100644 HisiPkg/Drivers/PL390Gic/PL390GicNonSec.c delete mode 100644 HisiPkg/Drivers/PL390Gic/PL390GicSec.c delete mode 100644 HisiPkg/Drivers/PL390Gic/PL390GicSecLib.inf diff --git a/HisiPkg/D01BoardPkg/D01BoardPkg.dsc b/HisiPkg/D01BoardPkg/D01BoardPkg.dsc index cece5aa28..8bd0f15de 100644 --- a/HisiPkg/D01BoardPkg/D01BoardPkg.dsc +++ b/HisiPkg/D01BoardPkg/D01BoardPkg.dsc @@ -190,8 +190,8 @@ HisiPkg/D01BoardPkg/Sec/Sec/Sec.inf { # Use the implementation which set the Secure bits - ArmGicLib|HisiPkg/Drivers/PL390Gic/PL390GicSecLib.inf - #ArmGicLib|ArmPkg/Drivers/PL390Gic/PL390GicSecLib.inf + ArmGicLib|HisiPkg/Drivers/HisiliconD01Gic/HisiliconD01GicSecLib.inf + #ArmGicLib|ArmPkg/Drivers/ArmGic/ArmGicSecLib.inf } # @@ -258,8 +258,9 @@ MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf - HisiPkg/Drivers/PL390Gic/PL390GicDxe.inf - #ArmPkg/Drivers/PL390Gic/PL390GicDxe.inf + HisiPkg/Drivers/HisiliconD01Gic/HisiliconD01GicDxe.inf + #ArmPkg/Drivers/ArmGic/ArmGicDxe.inf + #ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.inf #ArmPkg/Drivers/TimerDxe/TimerDxe.inf HisiPkg/Drivers/TimerDxe/TimerDxe.inf diff --git a/HisiPkg/D01BoardPkg/D01BoardPkg.dsc.inc b/HisiPkg/D01BoardPkg/D01BoardPkg.dsc.inc index 1b0c40702..9c006c37b 100644 --- a/HisiPkg/D01BoardPkg/D01BoardPkg.dsc.inc +++ b/HisiPkg/D01BoardPkg/D01BoardPkg.dsc.inc @@ -58,8 +58,10 @@ CpuExceptionHandlerLib|MdeModulePkg/Library/CpuExceptionHandlerLibNull/CpuExceptionHandlerLibNull.inf ArmDisassemblerLib|ArmPkg/Library/ArmDisassemblerLib/ArmDisassemblerLib.inf DmaLib|ArmPkg/Library/ArmDmaLib/ArmDmaLib.inf - ArmGicLib|HisiPkg/Drivers/PL390Gic/PL390GicLib.inf - #ArmGicLib|ArmPkg/Drivers/PL390Gic/PL390GicLib.inf + + ArmGicLib|HisiPkg/Drivers/HisiliconD01Gic/HisiliconD01GicLib.inf + #ArmGicLib|ArmPkg/Drivers/ArmGic/ArmGicLib.inf + ArmPlatformStackLib|ArmPlatformPkg/Library/ArmPlatformStackLib/ArmPlatformStackLib.inf # Versatile Express Specific Libraries diff --git a/HisiPkg/D01BoardPkg/D01BoardPkg.fdf b/HisiPkg/D01BoardPkg/D01BoardPkg.fdf index d5037c7f1..f191849e7 100644 --- a/HisiPkg/D01BoardPkg/D01BoardPkg.fdf +++ b/HisiPkg/D01BoardPkg/D01BoardPkg.fdf @@ -141,8 +141,8 @@ READ_LOCK_STATUS = TRUE INF MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf INF EmbeddedPkg/SerialDxe/SerialDxe.inf - INF HisiPkg/Drivers/PL390Gic/PL390GicDxe.inf - #INF ArmPkg/Drivers/PL390Gic/PL390GicDxe.inf + INF HisiPkg/Drivers/HisiliconD01Gic/HisiliconD01GicDxe.inf + #INF ArmPkg/Drivers/ArmGic/ArmGicDxe.inf INF HisiPkg/Drivers/TimerDxe/TimerDxe.inf INF MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf diff --git a/HisiPkg/Drivers/HisiliconD01Gic/HisiliconD01Gic.c b/HisiPkg/Drivers/HisiliconD01Gic/HisiliconD01Gic.c new file mode 100644 index 000000000..da5e437b3 --- /dev/null +++ b/HisiPkg/Drivers/HisiliconD01Gic/HisiliconD01Gic.c @@ -0,0 +1,71 @@ +/** @file +* +* Copyright (c) 2011-2012, ARM Limited. All rights reserved. +* Copyright (c) Huawei Technologies Co., Ltd. 2013. 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 + +UINTN +EFIAPI +ArmGicGetMaxNumInterrupts ( + IN INTN GicDistributorBase + ) +{ + return 32 * ((MmioRead32 (GicDistributorBase + ARM_GIC_ICDICTR) & 0x1F) + 1); +} + +VOID +EFIAPI +ArmGicSendSgiTo ( + IN INTN GicDistributorBase, + IN INTN TargetListFilter, + IN INTN CPUTargetList, + IN INTN SgiId + ) +{ + MmioWrite32 (GicDistributorBase + ARM_GIC_ICDSGIR, ((TargetListFilter & 0x3) << 24) | ((CPUTargetList & 0xFF) << 16) | SgiId); +} + +RETURN_STATUS +EFIAPI +ArmGicAcknowledgeInterrupt ( + IN UINTN GicDistributorBase, + IN UINTN GicInterruptInterfaceBase, + OUT UINTN *CoreId, + OUT UINTN *InterruptId + ) +{ + UINT32 Interrupt; + + // Read the Interrupt Acknowledge Register + Interrupt = MmioRead32 (GicInterruptInterfaceBase + ARM_GIC_ICCIAR); + + // Check if it is a valid interrupt ID + if ((Interrupt & 0x3FF) < ArmGicGetMaxNumInterrupts (GicDistributorBase)) { + // Got a valid SGI number hence signal End of Interrupt by writing to ICCEOIR + MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCEIOR, Interrupt); + + if (CoreId) { + *CoreId = (Interrupt >> 10) & 0x7; + } + if (InterruptId) { + *InterruptId = Interrupt & 0x3FF; + } + return RETURN_SUCCESS; + } else { + return RETURN_INVALID_PARAMETER; + } +} diff --git a/HisiPkg/Drivers/HisiliconD01Gic/HisiliconD01GicDxe.c b/HisiPkg/Drivers/HisiliconD01Gic/HisiliconD01GicDxe.c new file mode 100644 index 000000000..a4dfa66d3 --- /dev/null +++ b/HisiPkg/Drivers/HisiliconD01Gic/HisiliconD01GicDxe.c @@ -0,0 +1,425 @@ +/*++ + +Copyright (c) 2009, Hewlett-Packard Company. All rights reserved.
+Portions copyright (c) 2010, Apple Inc. All rights reserved.
+Portions copyright (c) 2011-2012, ARM Ltd. All rights reserved.
+Copyright (c) Huawei Technologies Co., Ltd. 2013. 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. + +Module Name: + + Gic.c + +Abstract: + + Driver implementing the GIC interrupt controller protocol + +--*/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#define ARM_GIC_DEFAULT_PRIORITY 0x80 + +extern EFI_HARDWARE_INTERRUPT_PROTOCOL gHardwareInterruptProtocol; + +// +// Notifications +// +EFI_EVENT EfiExitBootServicesEvent = (EFI_EVENT)NULL; + +// Maximum Number of Interrupts +UINTN mGicNumInterrupts = 0; + +HARDWARE_INTERRUPT_HANDLER *gRegisteredInterruptHandlers = NULL; + +/** + Register Handler for the specified interrupt source. + + @param This Instance pointer for this protocol + @param Source Hardware source of the interrupt + @param Handler Callback for interrupt. NULL to unregister + + @retval EFI_SUCCESS Source was updated to support Handler. + @retval EFI_DEVICE_ERROR Hardware could not be programmed. + +**/ +EFI_STATUS +EFIAPI +RegisterInterruptSource ( + IN EFI_HARDWARE_INTERRUPT_PROTOCOL *This, + IN HARDWARE_INTERRUPT_SOURCE Source, + IN HARDWARE_INTERRUPT_HANDLER Handler + ) +{ + if (Source > mGicNumInterrupts) { + ASSERT(FALSE); + return EFI_UNSUPPORTED; + } + + if ((Handler == NULL) && (gRegisteredInterruptHandlers[Source] == NULL)) { + return EFI_INVALID_PARAMETER; + } + + if ((Handler != NULL) && (gRegisteredInterruptHandlers[Source] != NULL)) { + return EFI_ALREADY_STARTED; + } + + gRegisteredInterruptHandlers[Source] = Handler; + + // If the interrupt handler is unregistered then disable the interrupt + if (NULL == Handler){ + return This->DisableInterruptSource (This, Source); + } else { + return This->EnableInterruptSource (This, Source); + } +} + +/** + Enable interrupt source Source. + + @param This Instance pointer for this protocol + @param Source Hardware source of the interrupt + + @retval EFI_SUCCESS Source interrupt enabled. + @retval EFI_DEVICE_ERROR Hardware could not be programmed. + +**/ +EFI_STATUS +EFIAPI +EnableInterruptSource ( + IN EFI_HARDWARE_INTERRUPT_PROTOCOL *This, + IN HARDWARE_INTERRUPT_SOURCE Source + ) +{ + UINT32 RegOffset; + UINTN RegShift; + + if (Source > mGicNumInterrupts) { + ASSERT(FALSE); + return EFI_UNSUPPORTED; + } + + // Calculate enable register offset and bit position + RegOffset = Source / 32; + RegShift = Source % 32; + + // Write set-enable register + MmioWrite32 (PcdGet32(PcdGicDistributorBase) + ARM_GIC_ICDISER + (4*RegOffset), 1 << RegShift); + + return EFI_SUCCESS; +} + +/** + Disable interrupt source Source. + + @param This Instance pointer for this protocol + @param Source Hardware source of the interrupt + + @retval EFI_SUCCESS Source interrupt disabled. + @retval EFI_DEVICE_ERROR Hardware could not be programmed. + +**/ +EFI_STATUS +EFIAPI +DisableInterruptSource ( + IN EFI_HARDWARE_INTERRUPT_PROTOCOL *This, + IN HARDWARE_INTERRUPT_SOURCE Source + ) +{ + UINT32 RegOffset; + UINTN RegShift; + + if (Source > mGicNumInterrupts) { + ASSERT(FALSE); + return EFI_UNSUPPORTED; + } + + // Calculate enable register offset and bit position + RegOffset = Source / 32; + RegShift = Source % 32; + + // Write set-enable register + MmioWrite32 (PcdGet32(PcdGicDistributorBase) + ARM_GIC_ICDICER + (4*RegOffset), 1 << RegShift); + + return EFI_SUCCESS; +} + +/** + Return current state of interrupt source Source. + + @param This Instance pointer for this protocol + @param Source Hardware source of the interrupt + @param InterruptState TRUE: source enabled, FALSE: source disabled. + + @retval EFI_SUCCESS InterruptState is valid + @retval EFI_DEVICE_ERROR InterruptState is not valid + +**/ +EFI_STATUS +EFIAPI +GetInterruptSourceState ( + IN EFI_HARDWARE_INTERRUPT_PROTOCOL *This, + IN HARDWARE_INTERRUPT_SOURCE Source, + IN BOOLEAN *InterruptState + ) +{ + UINT32 RegOffset; + UINTN RegShift; + + if (Source > mGicNumInterrupts) { + ASSERT(FALSE); + return EFI_UNSUPPORTED; + } + + // calculate enable register offset and bit position + RegOffset = Source / 32; + RegShift = Source % 32; + + if ((MmioRead32 (PcdGet32(PcdGicDistributorBase) + ARM_GIC_ICDISER + (4*RegOffset)) & (1< mGicNumInterrupts) { + ASSERT(FALSE); + return EFI_UNSUPPORTED; + } + + MmioWrite32 (PcdGet32(PcdGicInterruptInterfaceBase) + ARM_GIC_ICCEIOR, Source); + return EFI_SUCCESS; +} + +/** + EFI_CPU_INTERRUPT_HANDLER that is called when a processor interrupt occurs. + + @param InterruptType Defines the type of interrupt or exception that + occurred on the processor.This parameter is processor architecture specific. + @param SystemContext A pointer to the processor context when + the interrupt occurred on the processor. + + @return None + +**/ +VOID +EFIAPI +IrqInterruptHandler ( + IN EFI_EXCEPTION_TYPE InterruptType, + IN EFI_SYSTEM_CONTEXT SystemContext + ) +{ + UINT32 GicInterrupt; + HARDWARE_INTERRUPT_HANDLER InterruptHandler; + + GicInterrupt = MmioRead32 (PcdGet32(PcdGicInterruptInterfaceBase) + ARM_GIC_ICCIAR); + + // Special Interrupts (ID1020-ID1023) have an Interrupt ID greater than the number of interrupt (ie: Spurious interrupt). + if (GicInterrupt >= mGicNumInterrupts) { + // The special interrupt do not need to be acknowledge + return; + } + + InterruptHandler = gRegisteredInterruptHandlers[GicInterrupt]; + if (InterruptHandler != NULL) { + // Call the registered interrupt handler. + InterruptHandler (GicInterrupt, SystemContext); + } else { + DEBUG ((EFI_D_ERROR, "Spurious GIC interrupt: 0x%x\n", GicInterrupt)); + } + + EndOfInterrupt (&gHardwareInterruptProtocol, GicInterrupt); +} + +// +// Making this global saves a few bytes in image size +// +EFI_HANDLE gHardwareInterruptHandle = NULL; + +// +// The protocol instance produced by this driver +// +EFI_HARDWARE_INTERRUPT_PROTOCOL gHardwareInterruptProtocol = { + RegisterInterruptSource, + EnableInterruptSource, + DisableInterruptSource, + GetInterruptSourceState, + EndOfInterrupt +}; + +/** + Shutdown our hardware + + DXE Core will disable interrupts and turn off the timer and disable interrupts + after all the event handlers have run. + + @param[in] Event The Event that is being processed + @param[in] Context Event Context +**/ +VOID +EFIAPI +ExitBootServicesEvent ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + UINTN Index; + + // Acknowledge all pending interrupts + for (Index = 0; Index < mGicNumInterrupts; Index++) { + DisableInterruptSource (&gHardwareInterruptProtocol, Index); + } + + for (Index = 0; Index < mGicNumInterrupts; Index++) { + EndOfInterrupt (&gHardwareInterruptProtocol, Index); + } + + // Disable Gic Interface + MmioWrite32 (PcdGet32(PcdGicInterruptInterfaceBase) + ARM_GIC_ICCICR, 0x0); + MmioWrite32 (PcdGet32(PcdGicInterruptInterfaceBase) + ARM_GIC_ICCPMR, 0x0); + + // Disable Gic Distributor + MmioWrite32 (PcdGet32(PcdGicDistributorBase) + ARM_GIC_ICDDCR, 0x0); +} + +/** + Initialize the state information for the CPU Architectural Protocol + + @param ImageHandle of the loaded driver + @param SystemTable Pointer to the System Table + + @retval EFI_SUCCESS Protocol registered + @retval EFI_OUT_OF_RESOURCES Cannot allocate protocol data structure + @retval EFI_DEVICE_ERROR Hardware problems + +**/ +EFI_STATUS +InterruptDxeInitialize ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + UINTN Index; + UINT32 RegOffset; + UINTN RegShift; + EFI_CPU_ARCH_PROTOCOL *Cpu; + UINT32 CpuTarget; + + // Check PcdGicPrimaryCoreId has been set in case the Primary Core is not the core 0 of Cluster 0 + DEBUG_CODE_BEGIN(); + if ((PcdGet32(PcdArmPrimaryCore) != 0) && (PcdGet32 (PcdGicPrimaryCoreId) == 0)) { + DEBUG((EFI_D_WARN,"Warning: the PCD PcdGicPrimaryCoreId does not seem to be set up for the configuration.\n")); + } + DEBUG_CODE_END(); + + // Make sure the Interrupt Controller Protocol is not already installed in the system. + ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gHardwareInterruptProtocolGuid); + + mGicNumInterrupts = ArmGicGetMaxNumInterrupts (PcdGet32(PcdGicDistributorBase)); + + for (Index = 0; Index < mGicNumInterrupts; Index++) { + DisableInterruptSource (&gHardwareInterruptProtocol, Index); + + // Set Priority + RegOffset = Index / 4; + RegShift = (Index % 4) * 8; + MmioAndThenOr32 ( + PcdGet32(PcdGicDistributorBase) + ARM_GIC_ICDIPR + (4*RegOffset), + ~(0xff << RegShift), + ARM_GIC_DEFAULT_PRIORITY << RegShift + ); + } + // Configure interrupts for Primary Cpu + CpuTarget = (1 << PcdGet32 (PcdGicPrimaryCoreId)); + CpuTarget |= CpuTarget << 16; + for (Index = 0; Index < (mGicNumInterrupts / 2); Index++) { + MmioWrite32 (PcdGet32(PcdGicDistributorBase) + ARM_GIC_ICDIPTR + (Index*4), CpuTarget); + } + + // Set binary point reg to 0x7 (no preemption) + MmioWrite32 (PcdGet32(PcdGicInterruptInterfaceBase) + ARM_GIC_ICCBPR, 0x7); + + // Set priority mask reg to 0xff to allow all priorities through + MmioWrite32 (PcdGet32(PcdGicInterruptInterfaceBase) + ARM_GIC_ICCPMR, 0xff); + + // Enable gic cpu interface + MmioWrite32 (PcdGet32(PcdGicInterruptInterfaceBase) + ARM_GIC_ICCICR, 0x1); + + // Enable gic distributor + MmioWrite32 (PcdGet32(PcdGicDistributorBase) + ARM_GIC_ICDDCR, 0x1); + + // Initialize the array for the Interrupt Handlers + gRegisteredInterruptHandlers = (HARDWARE_INTERRUPT_HANDLER*)AllocateZeroPool (sizeof(HARDWARE_INTERRUPT_HANDLER) * mGicNumInterrupts); + + Status = gBS->InstallMultipleProtocolInterfaces ( + &gHardwareInterruptHandle, + &gHardwareInterruptProtocolGuid, &gHardwareInterruptProtocol, + NULL + ); + ASSERT_EFI_ERROR (Status); + + // + // Get the CPU protocol that this driver requires. + // + Status = gBS->LocateProtocol(&gEfiCpuArchProtocolGuid, NULL, (VOID **)&Cpu); + ASSERT_EFI_ERROR(Status); + + // + // Unregister the default exception handler. + // + Status = Cpu->RegisterInterruptHandler(Cpu, EXCEPT_ARM_IRQ, NULL); + ASSERT_EFI_ERROR(Status); + + // + // Register to receive interrupts + // + Status = Cpu->RegisterInterruptHandler(Cpu, EXCEPT_ARM_IRQ, IrqInterruptHandler); + ASSERT_EFI_ERROR(Status); + + // Register for an ExitBootServicesEvent + Status = gBS->CreateEvent (EVT_SIGNAL_EXIT_BOOT_SERVICES, TPL_NOTIFY, ExitBootServicesEvent, NULL, &EfiExitBootServicesEvent); + ASSERT_EFI_ERROR (Status); + + return Status; +} diff --git a/HisiPkg/Drivers/HisiliconD01Gic/HisiliconD01GicDxe.inf b/HisiPkg/Drivers/HisiliconD01Gic/HisiliconD01GicDxe.inf new file mode 100644 index 000000000..6ade9e63a --- /dev/null +++ b/HisiPkg/Drivers/HisiliconD01Gic/HisiliconD01GicDxe.inf @@ -0,0 +1,59 @@ +#/** @file +# +# Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.
+# Copyright (c) 2012, ARM Ltd. All rights reserved.
+# Copyright Huawei Technologies Co., Ltd. 1998-2013. 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 = HisiliconD01GicDxe + FILE_GUID = DE371F7C-DEC4-4D21-ADF1-593ABCC15882 + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + + ENTRY_POINT = InterruptDxeInitialize + + +[Sources.common] + HisiliconD01Gic.c + HisiliconD01GicDxe.c + +[Packages] + MdePkg/MdePkg.dec + EmbeddedPkg/EmbeddedPkg.dec + ArmPkg/ArmPkg.dec + HisiPkg/HisiPlatformPkg.dec + +[LibraryClasses] + BaseLib + UefiLib + UefiBootServicesTableLib + DebugLib + PrintLib + MemoryAllocationLib + UefiDriverEntryPoint + IoLib + +[Protocols] + gHardwareInterruptProtocolGuid + gEfiCpuArchProtocolGuid + +[FixedPcd.common] + gArmTokenSpaceGuid.PcdGicDistributorBase + gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase + + gArmTokenSpaceGuid.PcdArmPrimaryCore + gHwTokenSpaceGuid.PcdGicPrimaryCoreId + +[Depex] + gEfiCpuArchProtocolGuid diff --git a/HisiPkg/Drivers/HisiliconD01Gic/HisiliconD01GicLib.inf b/HisiPkg/Drivers/HisiliconD01Gic/HisiliconD01GicLib.inf new file mode 100644 index 000000000..6d6c66fdc --- /dev/null +++ b/HisiPkg/Drivers/HisiliconD01Gic/HisiliconD01GicLib.inf @@ -0,0 +1,32 @@ +#/* @file +# Copyright (c) 2011-2012, ARM Limited. All rights reserved. +# Copyright (c) Huawei Technologies Co., Ltd. 2013. 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 = HisiliconD01GicLib + FILE_GUID = 03d05ee4-cdeb-458c-9dfc-993f09bdf405 + MODULE_TYPE = SEC + VERSION_STRING = 1.0 + LIBRARY_CLASS = ArmGicLib + +[Sources] + HisiliconD01Gic.c + HisiliconD01GicNonSec.c + +[LibraryClasses] + IoLib + +[Packages] + ArmPkg/ArmPkg.dec + MdePkg/MdePkg.dec diff --git a/HisiPkg/Drivers/HisiliconD01Gic/HisiliconD01GicNonSec.c b/HisiPkg/Drivers/HisiliconD01Gic/HisiliconD01GicNonSec.c new file mode 100644 index 000000000..17a2cd1cb --- /dev/null +++ b/HisiPkg/Drivers/HisiliconD01Gic/HisiliconD01GicNonSec.c @@ -0,0 +1,45 @@ +/** @file +* +* Copyright (c) 2011, ARM Limited. All rights reserved. +* Copyright (c) Huawei Technologies Co., Ltd. 2013. 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 + + +VOID +EFIAPI +ArmGicEnableInterruptInterface ( + IN INTN GicInterruptInterfaceBase + ) +{ + /* + * Enable the CPU interface in Non-Secure world + * Note: The ICCICR register is banked when Security extensions are implemented + */ + MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCICR, 0x1); +} + +VOID +EFIAPI +ArmGicEnableDistributor ( + IN INTN GicDistributorBase + ) +{ + /* + * Enable GIC distributor in Non-Secure world. + * Note: The ICDDCR register is banked when Security extensions are implemented + */ + MmioWrite32 (GicDistributorBase + ARM_GIC_ICDDCR, 0x1); +} diff --git a/HisiPkg/Drivers/HisiliconD01Gic/HisiliconD01GicSec.c b/HisiPkg/Drivers/HisiliconD01Gic/HisiliconD01GicSec.c new file mode 100644 index 000000000..d097b8a45 --- /dev/null +++ b/HisiPkg/Drivers/HisiliconD01Gic/HisiliconD01GicSec.c @@ -0,0 +1,132 @@ +/** @file +* +* Copyright (c) 2011-2012, ARM Limited. All rights reserved. +# Copyright (c) Huawei Technologies Co., Ltd. 2013. 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 + +/* + * This function configures the all interrupts to be Non-secure. + * + */ +VOID +EFIAPI +ArmGicSetupNonSecure ( + IN UINTN MpId, + IN INTN GicDistributorBase, + IN INTN GicInterruptInterfaceBase + ) +{ + UINTN InterruptId; + UINTN CachedPriorityMask; + UINTN Index; + + CachedPriorityMask = MmioRead32 (GicInterruptInterfaceBase + ARM_GIC_ICCPMR); + + // 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); + + // Write to End of interrupt signal + MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCEIOR, InterruptId); + } + + // Only the primary core should set the Non Secure bit to the SPIs (Shared Peripheral Interrupt). + if (((MpId) & PcdGet32(PcdArmPrimaryCoreMask)) == PcdGet32(PcdArmPrimaryCore)) { + // Ensure all GIC interrupts are Non-Secure + for (Index = 0; Index < (ArmGicGetMaxNumInterrupts (GicDistributorBase) / 32); Index++) { + MmioWrite32 (GicDistributorBase + ARM_GIC_ICDISR + (Index * 4), 0xffffffff); + } + } else { + // The secondary cores only set the Non Secure bit to their banked PPIs + MmioWrite32 (GicDistributorBase + ARM_GIC_ICDISR, 0xffffffff); + } + + // Ensure all interrupts can get through the priority mask + MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCPMR, CachedPriorityMask); +} + +/* + * This function configures the interrupts set by the mask to be secure. + * + */ +VOID +EFIAPI +ArmGicSetSecureInterrupts ( + IN UINTN GicDistributorBase, + IN UINTN* GicSecureInterruptMask, + IN UINTN GicSecureInterruptMaskSize + ) +{ + UINTN Index; + UINT32 InterruptStatus; + + // We must not have more interrupts defined by the mask than the number of available interrupts + ASSERT(GicSecureInterruptMaskSize <= (ArmGicGetMaxNumInterrupts (GicDistributorBase) / 32)); + + // Set all the interrupts defined by the mask as Secure + for (Index = 0; Index < GicSecureInterruptMaskSize; Index++) { + InterruptStatus = MmioRead32 (GicDistributorBase + ARM_GIC_ICDISR + (Index * 4)); + MmioWrite32 (GicDistributorBase + ARM_GIC_ICDISR + (Index * 4), InterruptStatus & (~GicSecureInterruptMask[Index])); + } +} + +VOID +EFIAPI +ArmGicEnableInterruptInterface ( + IN INTN GicInterruptInterfaceBase + ) +{ + // Set Priority Mask to allow interrupts + MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCPMR, 0x000000FF); + + // Enable CPU interface in Secure world + // Enable CPU interface in Non-secure World + // Signal Secure Interrupts to CPU using FIQ line * + MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCICR, + ARM_GIC_ICCICR_ENABLE_SECURE | + ARM_GIC_ICCICR_ENABLE_NS | + ARM_GIC_ICCICR_SIGNAL_SECURE_TO_FIQ); +} + +VOID +EFIAPI +ArmGicDisableInterruptInterface ( + IN INTN GicInterruptInterfaceBase + ) +{ + UINT32 ControlValue; + + // Disable CPU interface in Secure world and Non-secure World + ControlValue = MmioRead32 (GicInterruptInterfaceBase + ARM_GIC_ICCICR); + MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCICR, ControlValue & ~(ARM_GIC_ICCICR_ENABLE_SECURE | ARM_GIC_ICCICR_ENABLE_NS)); +} + +VOID +EFIAPI +ArmGicEnableDistributor ( + IN INTN GicDistributorBase + ) +{ + // Turn on the GIC distributor + MmioWrite32 (GicDistributorBase + ARM_GIC_ICDDCR, 1); +} diff --git a/HisiPkg/Drivers/HisiliconD01Gic/HisiliconD01GicSecLib.inf b/HisiPkg/Drivers/HisiliconD01Gic/HisiliconD01GicSecLib.inf new file mode 100644 index 000000000..07a16a415 --- /dev/null +++ b/HisiPkg/Drivers/HisiliconD01Gic/HisiliconD01GicSecLib.inf @@ -0,0 +1,41 @@ +#/* @file +# Copyright (c) 2011-2012, ARM Limited. All rights reserved. +# Copyright (c) Huawei Technologies Co., Ltd. 2013. 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 = HisiliconD01GicSecLib + FILE_GUID = 85f3cf80-b5f4-11df-9855-0002a5d5c51b + MODULE_TYPE = SEC + VERSION_STRING = 1.0 + LIBRARY_CLASS = ArmGicLib + +[Sources] + HisiliconD01Gic.c + HisiliconD01GicSec.c + +[Packages] + ArmPkg/ArmPkg.dec + ArmPlatformPkg/ArmPlatformPkg.dec + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + +[LibraryClasses] + ArmLib + DebugLib + IoLib + PcdLib + +[FixedPcd.common] + gArmTokenSpaceGuid.PcdArmPrimaryCoreMask + gArmTokenSpaceGuid.PcdArmPrimaryCore diff --git a/HisiPkg/Drivers/PL390Gic/PL390Gic.c b/HisiPkg/Drivers/PL390Gic/PL390Gic.c deleted file mode 100644 index 98d5107bc..000000000 --- a/HisiPkg/Drivers/PL390Gic/PL390Gic.c +++ /dev/null @@ -1,71 +0,0 @@ -/** @file -* -* Copyright (c) 2011-2012, ARM Limited. All rights reserved. -* Copyright (c) Huawei Technologies Co., Ltd. 2013. 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 - -UINTN -EFIAPI -ArmGicGetMaxNumInterrupts ( - IN INTN GicDistributorBase - ) -{ - return 32 * ((MmioRead32 (GicDistributorBase + ARM_GIC_ICDICTR) & 0x1F) + 1); -} - -VOID -EFIAPI -ArmGicSendSgiTo ( - IN INTN GicDistributorBase, - IN INTN TargetListFilter, - IN INTN CPUTargetList, - IN INTN SgiId - ) -{ - MmioWrite32 (GicDistributorBase + ARM_GIC_ICDSGIR, ((TargetListFilter & 0x3) << 24) | ((CPUTargetList & 0xFF) << 16) | SgiId); -} - -RETURN_STATUS -EFIAPI -ArmGicAcknowledgeInterrupt ( - IN UINTN GicDistributorBase, - IN UINTN GicInterruptInterfaceBase, - OUT UINTN *CoreId, - OUT UINTN *InterruptId - ) -{ - UINT32 Interrupt; - - // Read the Interrupt Acknowledge Register - Interrupt = MmioRead32 (GicInterruptInterfaceBase + ARM_GIC_ICCIAR); - - // Check if it is a valid interrupt ID - if ((Interrupt & 0x3FF) < ArmGicGetMaxNumInterrupts (GicDistributorBase)) { - // Got a valid SGI number hence signal End of Interrupt by writing to ICCEOIR - MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCEIOR, Interrupt); - - if (CoreId) { - *CoreId = (Interrupt >> 10) & 0x7; - } - if (InterruptId) { - *InterruptId = Interrupt & 0x3FF; - } - return RETURN_SUCCESS; - } else { - return RETURN_INVALID_PARAMETER; - } -} diff --git a/HisiPkg/Drivers/PL390Gic/PL390GicDxe.c b/HisiPkg/Drivers/PL390Gic/PL390GicDxe.c deleted file mode 100644 index 8a80b667d..000000000 --- a/HisiPkg/Drivers/PL390Gic/PL390GicDxe.c +++ /dev/null @@ -1,425 +0,0 @@ -/*++ - -Copyright (c) 2009, Hewlett-Packard Company. All rights reserved.
-Portions copyright (c) 2010, Apple Inc. All rights reserved.
-Portions copyright (c) 2011-2012, ARM Ltd. All rights reserved.
-Copyright (c) Huawei Technologies Co., Ltd. 2013. 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. - -Module Name: - - Gic.c - -Abstract: - - Driver implementing the GIC interrupt controller protocol - ---*/ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#define ARM_GIC_DEFAULT_PRIORITY 0x80 - -extern EFI_HARDWARE_INTERRUPT_PROTOCOL gHardwareInterruptProtocol; - -// -// Notifications -// -EFI_EVENT EfiExitBootServicesEvent = (EFI_EVENT)NULL; - -// Maximum Number of Interrupts -UINTN mGicNumInterrupts = 0; - -HARDWARE_INTERRUPT_HANDLER *gRegisteredInterruptHandlers = NULL; - -/** - Register Handler for the specified interrupt source. - - @param This Instance pointer for this protocol - @param Source Hardware source of the interrupt - @param Handler Callback for interrupt. NULL to unregister - - @retval EFI_SUCCESS Source was updated to support Handler. - @retval EFI_DEVICE_ERROR Hardware could not be programmed. - -**/ -EFI_STATUS -EFIAPI -RegisterInterruptSource ( - IN EFI_HARDWARE_INTERRUPT_PROTOCOL *This, - IN HARDWARE_INTERRUPT_SOURCE Source, - IN HARDWARE_INTERRUPT_HANDLER Handler - ) -{ - if (Source > mGicNumInterrupts) { - ASSERT(FALSE); - return EFI_UNSUPPORTED; - } - - if ((Handler == NULL) && (gRegisteredInterruptHandlers[Source] == NULL)) { - return EFI_INVALID_PARAMETER; - } - - if ((Handler != NULL) && (gRegisteredInterruptHandlers[Source] != NULL)) { - return EFI_ALREADY_STARTED; - } - - gRegisteredInterruptHandlers[Source] = Handler; - - // If the interrupt handler is unregistered then disable the interrupt - if (NULL == Handler){ - return This->DisableInterruptSource (This, Source); - } else { - return This->EnableInterruptSource (This, Source); - } -} - -/** - Enable interrupt source Source. - - @param This Instance pointer for this protocol - @param Source Hardware source of the interrupt - - @retval EFI_SUCCESS Source interrupt enabled. - @retval EFI_DEVICE_ERROR Hardware could not be programmed. - -**/ -EFI_STATUS -EFIAPI -EnableInterruptSource ( - IN EFI_HARDWARE_INTERRUPT_PROTOCOL *This, - IN HARDWARE_INTERRUPT_SOURCE Source - ) -{ - UINT32 RegOffset; - UINTN RegShift; - - if (Source > mGicNumInterrupts) { - ASSERT(FALSE); - return EFI_UNSUPPORTED; - } - - // calculate enable register offset and bit position - RegOffset = Source / 32; - RegShift = Source % 32; - - // write set-enable register - MmioWrite32 (PcdGet32(PcdGicDistributorBase) + ARM_GIC_ICDISER + (4*RegOffset), 1 << RegShift); - - return EFI_SUCCESS; -} - -/** - Disable interrupt source Source. - - @param This Instance pointer for this protocol - @param Source Hardware source of the interrupt - - @retval EFI_SUCCESS Source interrupt disabled. - @retval EFI_DEVICE_ERROR Hardware could not be programmed. - -**/ -EFI_STATUS -EFIAPI -DisableInterruptSource ( - IN EFI_HARDWARE_INTERRUPT_PROTOCOL *This, - IN HARDWARE_INTERRUPT_SOURCE Source - ) -{ - UINT32 RegOffset; - UINTN RegShift; - - if (Source > mGicNumInterrupts) { - ASSERT(FALSE); - return EFI_UNSUPPORTED; - } - - // Calculate enable register offset and bit position - RegOffset = Source / 32; - RegShift = Source % 32; - - // Write set-enable register - MmioWrite32 (PcdGet32(PcdGicDistributorBase) + ARM_GIC_ICDICER + (4*RegOffset), 1 << RegShift); - - return EFI_SUCCESS; -} - -/** - Return current state of interrupt source Source. - - @param This Instance pointer for this protocol - @param Source Hardware source of the interrupt - @param InterruptState TRUE: source enabled, FALSE: source disabled. - - @retval EFI_SUCCESS InterruptState is valid - @retval EFI_DEVICE_ERROR InterruptState is not valid - -**/ -EFI_STATUS -EFIAPI -GetInterruptSourceState ( - IN EFI_HARDWARE_INTERRUPT_PROTOCOL *This, - IN HARDWARE_INTERRUPT_SOURCE Source, - IN BOOLEAN *InterruptState - ) -{ - UINT32 RegOffset; - UINTN RegShift; - - if (Source > mGicNumInterrupts) { - ASSERT(FALSE); - return EFI_UNSUPPORTED; - } - - // calculate enable register offset and bit position - RegOffset = Source / 32; - RegShift = Source % 32; - - if ((MmioRead32 (PcdGet32(PcdGicDistributorBase) + ARM_GIC_ICDISER + (4*RegOffset)) & (1< mGicNumInterrupts) { - ASSERT(FALSE); - return EFI_UNSUPPORTED; - } - - MmioWrite32 (PcdGet32(PcdGicInterruptInterfaceBase) + ARM_GIC_ICCEIOR, Source); - return EFI_SUCCESS; -} - -/** - EFI_CPU_INTERRUPT_HANDLER that is called when a processor interrupt occurs. - - @param InterruptType Defines the type of interrupt or exception that - occurred on the processor.This parameter is processor architecture specific. - @param SystemContext A pointer to the processor context when - the interrupt occurred on the processor. - - @return None - -**/ -VOID -EFIAPI -IrqInterruptHandler ( - IN EFI_EXCEPTION_TYPE InterruptType, - IN EFI_SYSTEM_CONTEXT SystemContext - ) -{ - UINT32 GicInterrupt; - HARDWARE_INTERRUPT_HANDLER InterruptHandler; - - GicInterrupt = MmioRead32 (PcdGet32(PcdGicInterruptInterfaceBase) + ARM_GIC_ICCIAR); - - // Special Interrupts (ID1020-ID1023) have an Interrupt ID greater than the number of interrupt (ie: Spurious interrupt). - if (GicInterrupt >= mGicNumInterrupts) { - // The special interrupt do not need to be acknowledge - return; - } - - InterruptHandler = gRegisteredInterruptHandlers[GicInterrupt]; - if (InterruptHandler != NULL) { - // Call the registered interrupt handler. - InterruptHandler (GicInterrupt, SystemContext); - } else { - DEBUG ((EFI_D_ERROR, "Spurious GIC interrupt: 0x%x\n", GicInterrupt)); - } - - EndOfInterrupt (&gHardwareInterruptProtocol, GicInterrupt); -} - -// -// Making this global saves a few bytes in image size -// -EFI_HANDLE gHardwareInterruptHandle = NULL; - -// -// The protocol instance produced by this driver -// -EFI_HARDWARE_INTERRUPT_PROTOCOL gHardwareInterruptProtocol = { - RegisterInterruptSource, - EnableInterruptSource, - DisableInterruptSource, - GetInterruptSourceState, - EndOfInterrupt -}; - -/** - Shutdown our hardware - - DXE Core will disable interrupts and turn off the timer and disable interrupts - after all the event handlers have run. - - @param[in] Event The Event that is being processed - @param[in] Context Event Context -**/ -VOID -EFIAPI -ExitBootServicesEvent ( - IN EFI_EVENT Event, - IN VOID *Context - ) -{ - UINTN Index; - - // Acknowledge all pending interrupts - for (Index = 0; Index < mGicNumInterrupts; Index++) { - DisableInterruptSource (&gHardwareInterruptProtocol, Index); - } - - for (Index = 0; Index < mGicNumInterrupts; Index++) { - EndOfInterrupt (&gHardwareInterruptProtocol, Index); - } - - // Disable Gic Interface - MmioWrite32 (PcdGet32(PcdGicInterruptInterfaceBase) + ARM_GIC_ICCICR, 0x0); - MmioWrite32 (PcdGet32(PcdGicInterruptInterfaceBase) + ARM_GIC_ICCPMR, 0x0); - - // Disable Gic Distributor - MmioWrite32 (PcdGet32(PcdGicDistributorBase) + ARM_GIC_ICDDCR, 0x0); -} - -/** - Initialize the state information for the CPU Architectural Protocol - - @param ImageHandle of the loaded driver - @param SystemTable Pointer to the System Table - - @retval EFI_SUCCESS Protocol registered - @retval EFI_OUT_OF_RESOURCES Cannot allocate protocol data structure - @retval EFI_DEVICE_ERROR Hardware problems - -**/ -EFI_STATUS -InterruptDxeInitialize ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable - ) -{ - EFI_STATUS Status; - UINTN Index; - UINT32 RegOffset; - UINTN RegShift; - EFI_CPU_ARCH_PROTOCOL *Cpu; - UINT32 CpuTarget; - - // Check PcdGicPrimaryCoreId has been set in case the Primary Core is not the core 0 of Cluster 0 - DEBUG_CODE_BEGIN(); - if ((PcdGet32(PcdArmPrimaryCore) != 0) && (PcdGet32 (PcdGicPrimaryCoreId) == 0)) { - DEBUG((EFI_D_WARN,"Warning: the PCD PcdGicPrimaryCoreId does not seem to be set up for the configuration.\n")); - } - DEBUG_CODE_END(); - - // Make sure the Interrupt Controller Protocol is not already installed in the system. - ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gHardwareInterruptProtocolGuid); - - mGicNumInterrupts = ArmGicGetMaxNumInterrupts (PcdGet32(PcdGicDistributorBase)); - - for (Index = 0; Index < mGicNumInterrupts; Index++) { - DisableInterruptSource (&gHardwareInterruptProtocol, Index); - - // Set Priority - RegOffset = Index / 4; - RegShift = (Index % 4) * 8; - MmioAndThenOr32 ( - PcdGet32(PcdGicDistributorBase) + ARM_GIC_ICDIPR + (4*RegOffset), - ~(0xff << RegShift), - ARM_GIC_DEFAULT_PRIORITY << RegShift - ); - } - // Configure interrupts for Primary Cpu - CpuTarget = (1 << PcdGet32 (PcdGicPrimaryCoreId)); - CpuTarget |= CpuTarget << 16; - for (Index = 0; Index < (mGicNumInterrupts / 2); Index++) { - MmioWrite32 (PcdGet32(PcdGicDistributorBase) + ARM_GIC_ICDIPTR + (Index*4), CpuTarget); - } - - // Set binary point reg to 0x7 (no preemption) - MmioWrite32 (PcdGet32(PcdGicInterruptInterfaceBase) + ARM_GIC_ICCBPR, 0x7); - - // Set priority mask reg to 0xff to allow all priorities through - MmioWrite32 (PcdGet32(PcdGicInterruptInterfaceBase) + ARM_GIC_ICCPMR, 0xff); - - // Enable gic cpu interface - MmioWrite32 (PcdGet32(PcdGicInterruptInterfaceBase) + ARM_GIC_ICCICR, 0x1); - - // Enable gic distributor - MmioWrite32 (PcdGet32(PcdGicDistributorBase) + ARM_GIC_ICDDCR, 0x1); - - // Initialize the array for the Interrupt Handlers - gRegisteredInterruptHandlers = (HARDWARE_INTERRUPT_HANDLER*)AllocateZeroPool (sizeof(HARDWARE_INTERRUPT_HANDLER) * mGicNumInterrupts); - - Status = gBS->InstallMultipleProtocolInterfaces ( - &gHardwareInterruptHandle, - &gHardwareInterruptProtocolGuid, &gHardwareInterruptProtocol, - NULL - ); - ASSERT_EFI_ERROR (Status); - - // - // Get the CPU protocol that this driver requires. - // - Status = gBS->LocateProtocol(&gEfiCpuArchProtocolGuid, NULL, (VOID **)&Cpu); - ASSERT_EFI_ERROR(Status); - - // - // Unregister the default exception handler. - // - Status = Cpu->RegisterInterruptHandler(Cpu, EXCEPT_ARM_IRQ, NULL); - ASSERT_EFI_ERROR(Status); - - // - // Register to receive interrupts - // - Status = Cpu->RegisterInterruptHandler(Cpu, EXCEPT_ARM_IRQ, IrqInterruptHandler); - ASSERT_EFI_ERROR(Status); - - // Register for an ExitBootServicesEvent - Status = gBS->CreateEvent (EVT_SIGNAL_EXIT_BOOT_SERVICES, TPL_NOTIFY, ExitBootServicesEvent, NULL, &EfiExitBootServicesEvent); - ASSERT_EFI_ERROR (Status); - - return Status; -} diff --git a/HisiPkg/Drivers/PL390Gic/PL390GicDxe.inf b/HisiPkg/Drivers/PL390Gic/PL390GicDxe.inf deleted file mode 100644 index 84650e80e..000000000 --- a/HisiPkg/Drivers/PL390Gic/PL390GicDxe.inf +++ /dev/null @@ -1,59 +0,0 @@ -#/** @file -# -# Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.
-# Copyright (c) 2012, ARM Ltd. All rights reserved.
-# Copyright Huawei Technologies Co., Ltd. 1998-2013. 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 = PL390GicDxe - FILE_GUID = DE371F7C-DEC4-4D21-ADF1-593ABCC15882 - MODULE_TYPE = DXE_DRIVER - VERSION_STRING = 1.0 - - ENTRY_POINT = InterruptDxeInitialize - - -[Sources.common] - PL390Gic.c - PL390GicDxe.c - -[Packages] - MdePkg/MdePkg.dec - EmbeddedPkg/EmbeddedPkg.dec - ArmPkg/ArmPkg.dec - HisiPkg/HisiPlatformPkg.dec - -[LibraryClasses] - BaseLib - UefiLib - UefiBootServicesTableLib - DebugLib - PrintLib - MemoryAllocationLib - UefiDriverEntryPoint - IoLib - -[Protocols] - gHardwareInterruptProtocolGuid - gEfiCpuArchProtocolGuid - -[FixedPcd.common] - gArmTokenSpaceGuid.PcdGicDistributorBase - gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase - - gArmTokenSpaceGuid.PcdArmPrimaryCore - gHwTokenSpaceGuid.PcdGicPrimaryCoreId - -[Depex] - gEfiCpuArchProtocolGuid diff --git a/HisiPkg/Drivers/PL390Gic/PL390GicLib.inf b/HisiPkg/Drivers/PL390Gic/PL390GicLib.inf deleted file mode 100644 index bb605fb52..000000000 --- a/HisiPkg/Drivers/PL390Gic/PL390GicLib.inf +++ /dev/null @@ -1,29 +0,0 @@ -#/* @file -# Copyright (c) 2011-2012, ARM Limited. All rights reserved. -# Copyright (c) Huawei Technologies Co., Ltd. 2013. 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 = PL390GicLib - FILE_GUID = 03d05ee4-cdeb-458c-9dfc-993f09bdf405 - MODULE_TYPE = SEC - VERSION_STRING = 1.0 - LIBRARY_CLASS = ArmGicLib - -[Sources] - PL390Gic.c - PL390GicNonSec.c - -[Packages] - ArmPkg/ArmPkg.dec - MdePkg/MdePkg.dec diff --git a/HisiPkg/Drivers/PL390Gic/PL390GicNonSec.c b/HisiPkg/Drivers/PL390Gic/PL390GicNonSec.c deleted file mode 100644 index c2828dc36..000000000 --- a/HisiPkg/Drivers/PL390Gic/PL390GicNonSec.c +++ /dev/null @@ -1,45 +0,0 @@ -/** @file -* -* Copyright (c) 2011, ARM Limited. All rights reserved. -* Copyright (c) Huawei Technologies Co., Ltd. 2013. 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 - - -VOID -EFIAPI -ArmGicEnableInterruptInterface ( - IN INTN GicInterruptInterfaceBase - ) -{ - /* - * Enable the CPU interface in Non-Secure world - * Note: The ICCICR register is banked when Security extensions are implemented - */ - MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCICR, 0x1); -} - -VOID -EFIAPI -ArmGicEnableDistributor ( - IN INTN GicDistributorBase - ) -{ - /* - * Enable GIC distributor in Non-Secure world. - * Note: The ICDDCR register is banked when Security extensions are implemented - */ - MmioWrite32 (GicDistributorBase + ARM_GIC_ICDDCR, 0x1); -} diff --git a/HisiPkg/Drivers/PL390Gic/PL390GicSec.c b/HisiPkg/Drivers/PL390Gic/PL390GicSec.c deleted file mode 100644 index 060df2f2f..000000000 --- a/HisiPkg/Drivers/PL390Gic/PL390GicSec.c +++ /dev/null @@ -1,132 +0,0 @@ -/** @file -* -* Copyright (c) 2011-2012, ARM Limited. All rights reserved. -# Copyright (c) Huawei Technologies Co., Ltd. 2013. 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 - -/* - * This function configures the all interrupts to be Non-secure. - * - */ -VOID -EFIAPI -ArmGicSetupNonSecure ( - IN UINTN MpId, - IN INTN GicDistributorBase, - IN INTN GicInterruptInterfaceBase - ) -{ - UINTN InterruptId; - UINTN CachedPriorityMask; - UINTN Index; - - CachedPriorityMask = MmioRead32 (GicInterruptInterfaceBase + ARM_GIC_ICCPMR); - - // 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); - - // Write to End of interrupt signal - MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCEIOR, InterruptId); - } - - // Only the primary core should set the Non Secure bit to the SPIs (Shared Peripheral Interrupt). - if (((MpId) & PcdGet32(PcdArmPrimaryCoreMask)) == PcdGet32(PcdArmPrimaryCore)) { - // Ensure all GIC interrupts are Non-Secure - for (Index = 0; Index < (ArmGicGetMaxNumInterrupts (GicDistributorBase) / 32); Index++) { - MmioWrite32 (GicDistributorBase + ARM_GIC_ICDISR + (Index * 4), 0xffffffff); - } - } else { - // The secondary cores only set the Non Secure bit to their banked PPIs - MmioWrite32 (GicDistributorBase + ARM_GIC_ICDISR, 0xffffffff); - } - - // Ensure all interrupts can get through the priority mask - MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCPMR, CachedPriorityMask); -} - -/* - * This function configures the interrupts set by the mask to be secure. - * - */ -VOID -EFIAPI -ArmGicSetSecureInterrupts ( - IN UINTN GicDistributorBase, - IN UINTN* GicSecureInterruptMask, - IN UINTN GicSecureInterruptMaskSize - ) -{ - UINTN Index; - UINT32 InterruptStatus; - - // We must not have more interrupts defined by the mask than the number of available interrupts - ASSERT(GicSecureInterruptMaskSize <= (ArmGicGetMaxNumInterrupts (GicDistributorBase) / 32)); - - // Set all the interrupts defined by the mask as Secure - for (Index = 0; Index < GicSecureInterruptMaskSize; Index++) { - InterruptStatus = MmioRead32 (GicDistributorBase + ARM_GIC_ICDISR + (Index * 4)); - MmioWrite32 (GicDistributorBase + ARM_GIC_ICDISR + (Index * 4), InterruptStatus & (~GicSecureInterruptMask[Index])); - } -} - -VOID -EFIAPI -ArmGicEnableInterruptInterface ( - IN INTN GicInterruptInterfaceBase - ) -{ - // Set Priority Mask to allow interrupts - MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCPMR, 0x000000FF); - - // Enable CPU interface in Secure world - // Enable CPU interface in Non-secure World - // Signal Secure Interrupts to CPU using FIQ line * - MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCICR, - ARM_GIC_ICCICR_ENABLE_SECURE | - ARM_GIC_ICCICR_ENABLE_NS | - ARM_GIC_ICCICR_SIGNAL_SECURE_TO_FIQ); -} - -VOID -EFIAPI -ArmGicDisableInterruptInterface ( - IN INTN GicInterruptInterfaceBase - ) -{ - UINT32 ControlValue; - - // Disable CPU interface in Secure world and Non-secure World - ControlValue = MmioRead32 (GicInterruptInterfaceBase + ARM_GIC_ICCICR); - MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCICR, ControlValue & ~(ARM_GIC_ICCICR_ENABLE_SECURE | ARM_GIC_ICCICR_ENABLE_NS)); -} - -VOID -EFIAPI -ArmGicEnableDistributor ( - IN INTN GicDistributorBase - ) -{ - // Turn on the GIC distributor - MmioWrite32 (GicDistributorBase + ARM_GIC_ICDDCR, 1); -} diff --git a/HisiPkg/Drivers/PL390Gic/PL390GicSecLib.inf b/HisiPkg/Drivers/PL390Gic/PL390GicSecLib.inf deleted file mode 100644 index c8f77d75a..000000000 --- a/HisiPkg/Drivers/PL390Gic/PL390GicSecLib.inf +++ /dev/null @@ -1,39 +0,0 @@ -#/* @file -# Copyright (c) 2011-2012, ARM Limited. All rights reserved. -# Copyright (c) Huawei Technologies Co., Ltd. 2013. 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 = PL390GicSecLib - FILE_GUID = 85f3cf80-b5f4-11df-9855-0002a5d5c51b - MODULE_TYPE = SEC - VERSION_STRING = 1.0 - LIBRARY_CLASS = ArmGicLib - -[Sources] - PL390Gic.c - PL390GicSec.c - -[Packages] - ArmPkg/ArmPkg.dec - MdePkg/MdePkg.dec - -[LibraryClasses] - ArmLib - DebugLib - IoLib - PcdLib - -[FixedPcd.common] - gArmTokenSpaceGuid.PcdArmPrimaryCoreMask - gArmTokenSpaceGuid.PcdArmPrimaryCore -- cgit v1.2.3