None of the platforms we support use these so remove them.
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>
# ARM Primecells\r
#\r
\r
- ## SP804 DualTimer\r
- gArmPlatformTokenSpaceGuid.PcdSP804TimerFrequencyInMHz|1|UINT32|0x0000001D\r
- gArmPlatformTokenSpaceGuid.PcdSP804TimerPeriodicInterruptNum|0|UINT32|0x0000001E\r
- gArmPlatformTokenSpaceGuid.PcdSP804TimerPeriodicBase|0|UINT32|0x0000002A\r
- gArmPlatformTokenSpaceGuid.PcdSP804TimerPerformanceBase|0|UINT32|0x0000002B\r
- gArmPlatformTokenSpaceGuid.PcdSP804TimerMetronomeBase|0|UINT32|0x0000002C\r
-\r
## SP805 Watchdog\r
gArmPlatformTokenSpaceGuid.PcdSP805WatchdogBase|0x0|UINT32|0x00000023\r
gArmPlatformTokenSpaceGuid.PcdSP805WatchdogClockFrequencyInHz|32000|UINT32|0x00000021\r
+++ /dev/null
-/** @file\r
- Template for Timer Architecture Protocol driver of the ARM flavor\r
-\r
- Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>\r
- Copyright (c) 2011 - 2012, ARM Ltd. All rights reserved.<BR>\r
-\r
- This program and the accompanying materials\r
- are licensed and made available under the terms and conditions of the BSD License\r
- which accompanies this distribution. The full text of the license may be found at\r
- http://opensource.org/licenses/bsd-license.php\r
-\r
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
- WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-**/\r
-\r
-\r
-#include <PiDxe.h>\r
-\r
-#include <Library/BaseLib.h>\r
-#include <Library/DebugLib.h>\r
-#include <Library/BaseMemoryLib.h>\r
-#include <Library/UefiBootServicesTableLib.h>\r
-#include <Library/UefiLib.h>\r
-#include <Library/PcdLib.h>\r
-#include <Library/IoLib.h>\r
-\r
-#include <Protocol/Timer.h>\r
-#include <Protocol/HardwareInterrupt.h>\r
-\r
-#include <Drivers/SP804Timer.h>\r
-\r
-#define SP804_TIMER_PERIODIC_BASE ((UINTN)PcdGet32 (PcdSP804TimerPeriodicBase))\r
-#define SP804_TIMER_METRONOME_BASE ((UINTN)PcdGet32 (PcdSP804TimerMetronomeBase))\r
-#define SP804_TIMER_PERFORMANCE_BASE ((UINTN)PcdGet32 (PcdSP804TimerPerformanceBase))\r
-\r
-// The notification function to call on every timer interrupt.\r
-EFI_TIMER_NOTIFY mTimerNotifyFunction = (EFI_TIMER_NOTIFY)NULL;\r
-EFI_EVENT EfiExitBootServicesEvent = (EFI_EVENT)NULL;\r
-\r
-// The current period of the timer interrupt\r
-UINT64 mTimerPeriod = 0;\r
-\r
-// Cached copy of the Hardware Interrupt protocol instance\r
-EFI_HARDWARE_INTERRUPT_PROTOCOL *gInterrupt = NULL;\r
-\r
-// Cached interrupt vector\r
-UINTN gVector;\r
-\r
-\r
-/**\r
-\r
- C Interrupt Handler called in the interrupt context when Source interrupt is active.\r
-\r
-\r
- @param Source Source of the interrupt. Hardware routing off a specific platform defines\r
- what source means.\r
-\r
- @param SystemContext Pointer to system register context. Mostly used by debuggers and will\r
- update the system context after the return from the interrupt if\r
- modified. Don't change these values unless you know what you are doing\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-TimerInterruptHandler (\r
- IN HARDWARE_INTERRUPT_SOURCE Source,\r
- IN EFI_SYSTEM_CONTEXT SystemContext\r
- )\r
-{\r
- EFI_TPL OriginalTPL;\r
-\r
- //\r
- // DXE core uses this callback for the EFI timer tick. The DXE core uses locks\r
- // that raise to TPL_HIGH and then restore back to current level. Thus we need\r
- // to make sure TPL level is set to TPL_HIGH while we are handling the timer tick.\r
- //\r
- OriginalTPL = gBS->RaiseTPL (TPL_HIGH_LEVEL);\r
-\r
- // If the interrupt is shared then we must check if this interrupt source is the one associated to this Timer\r
- if (MmioRead32 (SP804_TIMER_PERIODIC_BASE + SP804_TIMER_MSK_INT_STS_REG) != 0) {\r
- // Clear the periodic interrupt\r
- MmioWrite32 (SP804_TIMER_PERIODIC_BASE + SP804_TIMER_INT_CLR_REG, 0);\r
-\r
- // Signal end of interrupt early to help avoid losing subsequent ticks from long duration handlers\r
- gInterrupt->EndOfInterrupt (gInterrupt, Source);\r
-\r
- if (mTimerNotifyFunction) {\r
- mTimerNotifyFunction (mTimerPeriod);\r
- }\r
- }\r
-\r
- gBS->RestoreTPL (OriginalTPL);\r
-}\r
-\r
-/**\r
- This function registers the handler NotifyFunction so it is called every time\r
- the timer interrupt fires. It also passes the amount of time since the last\r
- handler call to the NotifyFunction. If NotifyFunction is NULL, then the\r
- handler is unregistered. If the handler is registered, then EFI_SUCCESS is\r
- returned. If the CPU does not support registering a timer interrupt handler,\r
- then EFI_UNSUPPORTED is returned. If an attempt is made to register a handler\r
- when a handler is already registered, then EFI_ALREADY_STARTED is returned.\r
- If an attempt is made to unregister a handler when a handler is not registered,\r
- then EFI_INVALID_PARAMETER is returned. If an error occurs attempting to\r
- register the NotifyFunction with the timer interrupt, then EFI_DEVICE_ERROR\r
- is returned.\r
-\r
- @param This The EFI_TIMER_ARCH_PROTOCOL instance.\r
- @param NotifyFunction The function to call when a timer interrupt fires. This\r
- function executes at TPL_HIGH_LEVEL. The DXE Core will\r
- register a handler for the timer interrupt, so it can know\r
- how much time has passed. This information is used to\r
- signal timer based events. NULL will unregister the handler.\r
- @retval EFI_SUCCESS The timer handler was registered.\r
- @retval EFI_UNSUPPORTED The platform does not support timer interrupts.\r
- @retval EFI_ALREADY_STARTED NotifyFunction is not NULL, and a handler is already\r
- registered.\r
- @retval EFI_INVALID_PARAMETER NotifyFunction is NULL, and a handler was not\r
- previously registered.\r
- @retval EFI_DEVICE_ERROR The timer handler could not be registered.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-TimerDriverRegisterHandler (\r
- IN EFI_TIMER_ARCH_PROTOCOL *This,\r
- IN EFI_TIMER_NOTIFY NotifyFunction\r
- )\r
-{\r
- if ((NotifyFunction == NULL) && (mTimerNotifyFunction == NULL)) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if ((NotifyFunction != NULL) && (mTimerNotifyFunction != NULL)) {\r
- return EFI_ALREADY_STARTED;\r
- }\r
-\r
- mTimerNotifyFunction = NotifyFunction;\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Make sure all Dual Timers are disabled\r
-**/\r
-VOID\r
-EFIAPI\r
-ExitBootServicesEvent (\r
- IN EFI_EVENT Event,\r
- IN VOID *Context\r
- )\r
-{\r
- // Disable 'Periodic Operation' timer if enabled\r
- if (MmioRead32(SP804_TIMER_PERIODIC_BASE + SP804_TIMER_CONTROL_REG) & SP804_TIMER_CTRL_ENABLE) {\r
- MmioAnd32 (SP804_TIMER_PERIODIC_BASE + SP804_TIMER_CONTROL_REG, 0);\r
- }\r
-\r
- // Disable 'Metronome/Delay' timer if enabled\r
- if (MmioRead32(SP804_TIMER_METRONOME_BASE + SP804_TIMER_CONTROL_REG) & SP804_TIMER_CTRL_ENABLE) {\r
- MmioAnd32 (SP804_TIMER_METRONOME_BASE + SP804_TIMER_CONTROL_REG, 0);\r
- }\r
-\r
- // Disable 'Performance' timer if enabled\r
- if (MmioRead32(SP804_TIMER_PERFORMANCE_BASE + SP804_TIMER_CONTROL_REG) & SP804_TIMER_CTRL_ENABLE) {\r
- MmioAnd32 (SP804_TIMER_PERFORMANCE_BASE + SP804_TIMER_CONTROL_REG, 0);\r
- }\r
-}\r
-\r
-/**\r
-\r
- This function adjusts the period of timer interrupts to the value specified\r
- by TimerPeriod. If the timer period is updated, then the selected timer\r
- period is stored in EFI_TIMER.TimerPeriod, and EFI_SUCCESS is returned. If\r
- the timer hardware is not programmable, then EFI_UNSUPPORTED is returned.\r
- If an error occurs while attempting to update the timer period, then the\r
- timer hardware will be put back in its state prior to this call, and\r
- EFI_DEVICE_ERROR is returned. If TimerPeriod is 0, then the timer interrupt\r
- is disabled. This is not the same as disabling the CPU's interrupts.\r
- Instead, it must either turn off the timer hardware, or it must adjust the\r
- interrupt controller so that a CPU interrupt is not generated when the timer\r
- interrupt fires.\r
-\r
- @param This The EFI_TIMER_ARCH_PROTOCOL instance.\r
- @param TimerPeriod The rate to program the timer interrupt in 100 nS units. If\r
- the timer hardware is not programmable, then EFI_UNSUPPORTED is\r
- returned. If the timer is programmable, then the timer period\r
- will be rounded up to the nearest timer period that is supported\r
- by the timer hardware. If TimerPeriod is set to 0, then the\r
- timer interrupts will be disabled.\r
-\r
-\r
- @retval EFI_SUCCESS The timer period was changed.\r
- @retval EFI_UNSUPPORTED The platform cannot change the period of the timer interrupt.\r
- @retval EFI_DEVICE_ERROR The timer period could not be changed due to a device error.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-TimerDriverSetTimerPeriod (\r
- IN EFI_TIMER_ARCH_PROTOCOL *This,\r
- IN UINT64 TimerPeriod\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINT64 TimerTicks;\r
-\r
- // always disable the timer\r
- MmioAnd32 (SP804_TIMER_PERIODIC_BASE + SP804_TIMER_CONTROL_REG, ~SP804_TIMER_CTRL_ENABLE);\r
-\r
- if (TimerPeriod == 0) {\r
- // Leave timer disabled from above, and...\r
-\r
- // Disable timer 0/1 interrupt for a TimerPeriod of 0\r
- Status = gInterrupt->DisableInterruptSource (gInterrupt, gVector);\r
- } else {\r
- // Convert TimerPeriod into 1MHz clock counts (us units = 100ns units * 10)\r
- TimerTicks = DivU64x32 (TimerPeriod, 10);\r
- TimerTicks = MultU64x32 (TimerTicks, PcdGet32(PcdSP804TimerFrequencyInMHz));\r
-\r
- // if it's larger than 32-bits, pin to highest value\r
- if (TimerTicks > 0xffffffff) {\r
- TimerTicks = 0xffffffff;\r
- }\r
-\r
- // Program the SP804 timer with the new count value\r
- MmioWrite32 (SP804_TIMER_PERIODIC_BASE + SP804_TIMER_LOAD_REG, TimerTicks);\r
-\r
- // enable the timer\r
- MmioOr32 (SP804_TIMER_PERIODIC_BASE + SP804_TIMER_CONTROL_REG, SP804_TIMER_CTRL_ENABLE);\r
-\r
- // enable timer 0/1 interrupts\r
- Status = gInterrupt->EnableInterruptSource (gInterrupt, gVector);\r
- }\r
-\r
- // Save the new timer period\r
- mTimerPeriod = TimerPeriod;\r
- return Status;\r
-}\r
-\r
-/**\r
- This function retrieves the period of timer interrupts in 100 ns units,\r
- returns that value in TimerPeriod, and returns EFI_SUCCESS. If TimerPeriod\r
- is NULL, then EFI_INVALID_PARAMETER is returned. If a TimerPeriod of 0 is\r
- returned, then the timer is currently disabled.\r
-\r
- @param This The EFI_TIMER_ARCH_PROTOCOL instance.\r
- @param TimerPeriod A pointer to the timer period to retrieve in 100 ns units. If\r
- 0 is returned, then the timer is currently disabled.\r
-\r
-\r
- @retval EFI_SUCCESS The timer period was returned in TimerPeriod.\r
- @retval EFI_INVALID_PARAMETER TimerPeriod is NULL.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-TimerDriverGetTimerPeriod (\r
- IN EFI_TIMER_ARCH_PROTOCOL *This,\r
- OUT UINT64 *TimerPeriod\r
- )\r
-{\r
- if (TimerPeriod == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- *TimerPeriod = mTimerPeriod;\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- This function generates a soft timer interrupt. If the platform does not support soft\r
- timer interrupts, then EFI_UNSUPPORTED is returned. Otherwise, EFI_SUCCESS is returned.\r
- If a handler has been registered through the EFI_TIMER_ARCH_PROTOCOL.RegisterHandler()\r
- service, then a soft timer interrupt will be generated. If the timer interrupt is\r
- enabled when this service is called, then the registered handler will be invoked. The\r
- registered handler should not be able to distinguish a hardware-generated timer\r
- interrupt from a software-generated timer interrupt.\r
-\r
- @param This The EFI_TIMER_ARCH_PROTOCOL instance.\r
-\r
- @retval EFI_SUCCESS The soft timer interrupt was generated.\r
- @retval EFI_UNSUPPORTED The platform does not support the generation of soft timer interrupts.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-TimerDriverGenerateSoftInterrupt (\r
- IN EFI_TIMER_ARCH_PROTOCOL *This\r
- )\r
-{\r
- return EFI_UNSUPPORTED;\r
-}\r
-\r
-/**\r
- Interface structure for the Timer Architectural Protocol.\r
-\r
- @par Protocol Description:\r
- This protocol provides the services to initialize a periodic timer\r
- interrupt, and to register a handler that is called each time the timer\r
- interrupt fires. It may also provide a service to adjust the rate of the\r
- periodic timer interrupt. When a timer interrupt occurs, the handler is\r
- passed the amount of time that has passed since the previous timer\r
- interrupt.\r
-\r
- @param RegisterHandler\r
- Registers a handler that will be called each time the\r
- timer interrupt fires. TimerPeriod defines the minimum\r
- time between timer interrupts, so TimerPeriod will also\r
- be the minimum time between calls to the registered\r
- handler.\r
-\r
- @param SetTimerPeriod\r
- Sets the period of the timer interrupt in 100 nS units.\r
- This function is optional, and may return EFI_UNSUPPORTED.\r
- If this function is supported, then the timer period will\r
- be rounded up to the nearest supported timer period.\r
-\r
-\r
- @param GetTimerPeriod\r
- Retrieves the period of the timer interrupt in 100 nS units.\r
-\r
- @param GenerateSoftInterrupt\r
- Generates a soft timer interrupt that simulates the firing of\r
- the timer interrupt. This service can be used to invoke the registered handler if the timer interrupt has been masked for\r
- a period of time.\r
-\r
-**/\r
-EFI_TIMER_ARCH_PROTOCOL gTimer = {\r
- TimerDriverRegisterHandler,\r
- TimerDriverSetTimerPeriod,\r
- TimerDriverGetTimerPeriod,\r
- TimerDriverGenerateSoftInterrupt\r
-};\r
-\r
-\r
-/**\r
- Initialize the state information for the Timer Architectural Protocol and\r
- the Timer Debug support protocol that allows the debugger to break into a\r
- running program.\r
-\r
- @param ImageHandle of the loaded driver\r
- @param SystemTable Pointer to the System Table\r
-\r
- @retval EFI_SUCCESS Protocol registered\r
- @retval EFI_OUT_OF_RESOURCES Cannot allocate protocol data structure\r
- @retval EFI_DEVICE_ERROR Hardware problems\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-TimerInitialize (\r
- IN EFI_HANDLE ImageHandle,\r
- IN EFI_SYSTEM_TABLE *SystemTable\r
- )\r
-{\r
- EFI_HANDLE Handle = NULL;\r
- EFI_STATUS Status;\r
-\r
- // Set the interrupt timer number\r
- gVector = PcdGet32(PcdSP804TimerPeriodicInterruptNum);\r
-\r
- // Find the interrupt controller protocol. ASSERT if not found.\r
- Status = gBS->LocateProtocol (&gHardwareInterruptProtocolGuid, NULL, (VOID **)&gInterrupt);\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- // Disable the timer\r
- Status = TimerDriverSetTimerPeriod (&gTimer, 0);\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- // Install interrupt handler\r
- Status = gInterrupt->RegisterInterruptSource (gInterrupt, gVector, TimerInterruptHandler);\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- // configure timer 0 for periodic operation, 32 bits, no prescaler, and interrupt enabled\r
- MmioWrite32 (SP804_TIMER_PERIODIC_BASE + SP804_TIMER_CONTROL_REG, SP804_TIMER_CTRL_PERIODIC | SP804_TIMER_CTRL_32BIT | SP804_PRESCALE_DIV_1 | SP804_TIMER_CTRL_INT_ENABLE);\r
-\r
- // Set up default timer\r
- Status = TimerDriverSetTimerPeriod (&gTimer, FixedPcdGet32(PcdTimerPeriod)); // TIMER_DEFAULT_PERIOD\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- // Install the Timer Architectural Protocol onto a new handle\r
- Status = gBS->InstallMultipleProtocolInterfaces(\r
- &Handle,\r
- &gEfiTimerArchProtocolGuid, &gTimer,\r
- NULL\r
- );\r
- ASSERT_EFI_ERROR(Status);\r
-\r
- // Register for an ExitBootServicesEvent\r
- Status = gBS->CreateEvent (EVT_SIGNAL_EXIT_BOOT_SERVICES, TPL_NOTIFY, ExitBootServicesEvent, NULL, &EfiExitBootServicesEvent);\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- return Status;\r
-}\r
+++ /dev/null
-#/** @file\r
-#\r
-# Component description file for Timer module\r
-#\r
-# Copyright (c) 2009 - 2010, Apple Inc. All rights reserved.<BR>\r
-# This program and the accompanying materials\r
-# are licensed and made available under the terms and conditions of the BSD License\r
-# which accompanies this distribution. The full text of the license may be found at\r
-# http://opensource.org/licenses/bsd-license.php\r
-#\r
-# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-#\r
-#**/\r
-\r
-[Defines]\r
- INF_VERSION = 0x00010005\r
- BASE_NAME = ArmVeTimerDxe\r
- FILE_GUID = a73d663d-a491-4278-9a69-9521be3379f2\r
- MODULE_TYPE = DXE_DRIVER\r
- VERSION_STRING = 1.0\r
-\r
- ENTRY_POINT = TimerInitialize\r
-\r
-[Sources.common]\r
- SP804Timer.c\r
-\r
-[Packages]\r
- MdePkg/MdePkg.dec\r
- EmbeddedPkg/EmbeddedPkg.dec\r
- ArmPkg/ArmPkg.dec\r
- ArmPlatformPkg/ArmPlatformPkg.dec\r
-\r
-[LibraryClasses]\r
- BaseLib\r
- UefiRuntimeServicesTableLib\r
- UefiLib\r
- UefiBootServicesTableLib\r
- BaseMemoryLib\r
- DebugLib\r
- UefiDriverEntryPoint\r
- IoLib\r
-\r
-[Guids]\r
-\r
-[Protocols]\r
- gEfiTimerArchProtocolGuid\r
- gHardwareInterruptProtocolGuid\r
-\r
-[Pcd.common]\r
- gArmPlatformTokenSpaceGuid.PcdSP804TimerFrequencyInMHz\r
- gArmPlatformTokenSpaceGuid.PcdSP804TimerPeriodicInterruptNum\r
- gArmPlatformTokenSpaceGuid.PcdSP804TimerPeriodicBase\r
- gArmPlatformTokenSpaceGuid.PcdSP804TimerPerformanceBase\r
- gArmPlatformTokenSpaceGuid.PcdSP804TimerMetronomeBase\r
- gEmbeddedTokenSpaceGuid.PcdTimerPeriod\r
-\r
-[Depex]\r
- gHardwareInterruptProtocolGuid\r
+++ /dev/null
-/** @file\r
-*\r
-* Copyright (c) 2011, ARM Limited. All rights reserved.\r
-*\r
-* This program and the accompanying materials\r
-* are licensed and made available under the terms and conditions of the BSD License\r
-* which accompanies this distribution. The full text of the license may be found at\r
-* http://opensource.org/licenses/bsd-license.php\r
-*\r
-* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-*\r
-**/\r
-\r
-\r
-#ifndef _SP804_TIMER_H__\r
-#define _SP804_TIMER_H__\r
-\r
-// SP804 Timer constants\r
-// Note: The SP804 Timer module comprises two timers, Timer_0 and Timer_1\r
-// These timers are identical and all their registers have an offset of 0x20\r
-// i.e. SP804_TIMER_0_LOAD_REG = 0x00 and SP804_TIMER_1_LOAD_REG = 0x20\r
-// Therefore, define all registers only once and adjust the base addresses by 0x20\r
-#define SP804_TIMER_LOAD_REG 0x00\r
-#define SP804_TIMER_CURRENT_REG 0x04\r
-#define SP804_TIMER_CONTROL_REG 0x08\r
-#define SP804_TIMER_INT_CLR_REG 0x0C\r
-#define SP804_TIMER_RAW_INT_STS_REG 0x10\r
-#define SP804_TIMER_MSK_INT_STS_REG 0x14\r
-#define SP804_TIMER_BG_LOAD_REG 0x18\r
-\r
-// Timer control register bit definitions\r
-#define SP804_TIMER_CTRL_ONESHOT BIT0\r
-#define SP804_TIMER_CTRL_32BIT BIT1\r
-#define SP804_TIMER_CTRL_PRESCALE_MASK (BIT3|BIT2)\r
-#define SP804_PRESCALE_DIV_1 0\r
-#define SP804_PRESCALE_DIV_16 BIT2\r
-#define SP804_PRESCALE_DIV_256 BIT3\r
-#define SP804_TIMER_CTRL_INT_ENABLE BIT5\r
-#define SP804_TIMER_CTRL_PERIODIC BIT6\r
-#define SP804_TIMER_CTRL_ENABLE BIT7\r
-\r
-// Other SP804 Timer definitions\r
-#define SP804_MAX_TICKS 0xFFFFFFFF\r
-\r
-// SP810 System Controller constants\r
-#define SP810_SYS_CTRL_REG 0x00\r
-#define SP810_SYS_CTRL_TIMER0_TIMCLK BIT15 // 0=REFCLK, 1=TIMCLK\r
-#define SP810_SYS_CTRL_TIMER0_EN BIT16\r
-#define SP810_SYS_CTRL_TIMER1_TIMCLK BIT17 // 0=REFCLK, 1=TIMCLK\r
-#define SP810_SYS_CTRL_TIMER1_EN BIT18\r
-#define SP810_SYS_CTRL_TIMER2_TIMCLK BIT19 // 0=REFCLK, 1=TIMCLK\r
-#define SP810_SYS_CTRL_TIMER2_EN BIT20\r
-#define SP810_SYS_CTRL_TIMER3_TIMCLK BIT21 // 0=REFCLK, 1=TIMCLK\r
-#define SP810_SYS_CTRL_TIMER3_EN BIT22\r
-\r
-#endif\r
+++ /dev/null
-/** @file\r
-\r
- Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>\r
- Copyright (c) 2011 - 2014, ARM Limited. All rights reserved.\r
-\r
- This program and the accompanying materials\r
- are licensed and made available under the terms and conditions of the BSD License\r
- which accompanies this distribution. The full text of the license may be found at\r
- http://opensource.org/licenses/bsd-license.php\r
-\r
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
- WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-**/\r
-\r
-#include <Base.h>\r
-\r
-#include <Library/BaseLib.h>\r
-#include <Library/TimerLib.h>\r
-#include <Library/DebugLib.h>\r
-#include <Library/PcdLib.h>\r
-#include <Library/IoLib.h>\r
-#include <Drivers/SP804Timer.h>\r
-\r
-#define SP804_TIMER_METRONOME_BASE ((UINTN)PcdGet32 (PcdSP804TimerMetronomeBase))\r
-#define SP804_TIMER_PERFORMANCE_BASE ((UINTN)PcdGet32 (PcdSP804TimerPerformanceBase))\r
-\r
-// Setup SP810's Timer2 for managing delay functions. And Timer3 for Performance counter\r
-// Note: ArmVE's Timer0 and Timer1 are used by TimerDxe.\r
-RETURN_STATUS\r
-EFIAPI\r
-TimerConstructor (\r
- VOID\r
- )\r
-{\r
- // Check if the Metronome Timer is already initialized\r
- if ((MmioRead32 (SP804_TIMER_METRONOME_BASE + SP804_TIMER_CONTROL_REG) & SP804_TIMER_CTRL_ENABLE) == 0) {\r
- // Configure the Metronome Timer for free running operation, 32 bits, no prescaler, and interrupt disabled\r
- MmioWrite32 (SP804_TIMER_METRONOME_BASE + SP804_TIMER_CONTROL_REG, SP804_TIMER_CTRL_32BIT | SP804_PRESCALE_DIV_1);\r
-\r
- // Start the Metronome Timer ticking\r
- MmioOr32 (SP804_TIMER_METRONOME_BASE + SP804_TIMER_CONTROL_REG, SP804_TIMER_CTRL_ENABLE);\r
- }\r
-\r
- // Check if the Performance Timer is already initialized\r
- if ((MmioRead32 (SP804_TIMER_PERFORMANCE_BASE + SP804_TIMER_CONTROL_REG) & SP804_TIMER_CTRL_ENABLE) == 0) {\r
- // Configure the Performance timer for free running operation, 32 bits, no prescaler, interrupt disabled\r
- MmioWrite32 (SP804_TIMER_PERFORMANCE_BASE + SP804_TIMER_CONTROL_REG, SP804_TIMER_CTRL_32BIT | SP804_PRESCALE_DIV_1);\r
-\r
- // Start the Performance Timer ticking\r
- MmioOr32 (SP804_TIMER_PERFORMANCE_BASE + SP804_TIMER_CONTROL_REG, SP804_TIMER_CTRL_ENABLE);\r
- }\r
-\r
- return RETURN_SUCCESS;\r
-}\r
-\r
-/**\r
- Stalls the CPU for at least the given number of microseconds.\r
-\r
- Stalls the CPU for the number of microseconds specified by MicroSeconds.\r
- The hardware timer is 32 bits.\r
- The maximum possible delay is (0xFFFFFFFF / TimerFrequencyMHz), i.e. ([32bits] / FreqInMHz)\r
- For example:\r
- +----------------+------------+----------+----------+\r
- | TimerFrequency | MaxDelay | MaxDelay | MaxDelay |\r
- | (MHz) | (us) | (s) | (min) |\r
- +----------------+------------+----------+----------+\r
- | 1 | 0xFFFFFFFF | 4294 | 71.5 |\r
- | 5 | 0x33333333 | 859 | 14.3 |\r
- | 10 | 0x19999999 | 429 | 7.2 |\r
- | 50 | 0x051EB851 | 86 | 1.4 |\r
- +----------------+------------+----------+----------+\r
- If it becomes necessary to support higher delays, then consider using the\r
- real time clock.\r
-\r
- During this delay, the cpu is not yielded to any other process, with one exception:\r
- events that are triggered off a timer and which execute at a higher TPL than\r
- this function. These events may call MicroSecondDelay (or NanoSecondDelay) to\r
- fulfil their own needs.\r
- Therefore, this function must be re-entrant, as it may be interrupted and re-started.\r
-\r
- @param MicroSeconds The minimum number of microseconds to delay.\r
-\r
- @return The value of MicroSeconds inputted.\r
-\r
-**/\r
-UINTN\r
-EFIAPI\r
-MicroSecondDelay (\r
- IN UINTN MicroSeconds\r
- )\r
-{\r
- UINT64 DelayTicks64; // Convert from microseconds to timer ticks, more bits to detect over-range conditions.\r
- UINTN DelayTicks; // Convert from microseconds to timer ticks, native size for general calculations.\r
- UINTN StartTicks; // Timer value snapshot at the start of the delay\r
- UINTN TargetTicks; // Timer value to signal the end of the delay\r
- UINTN CurrentTicks; // Current value of the 64-bit timer value at any given moment\r
-\r
- // If we snapshot the timer at the start of the delay function then we minimise unaccounted overheads.\r
- StartTicks = MmioRead32 (SP804_TIMER_METRONOME_BASE + SP804_TIMER_CURRENT_REG);\r
-\r
- // We are operating at the limit of 32bits. For the range checking work in 64 bits to avoid overflows.\r
- DelayTicks64 = MultU64x32((UINT64)MicroSeconds, PcdGet32(PcdSP804TimerFrequencyInMHz));\r
-\r
- // We are limited to 32 bits.\r
- // If the specified delay is exactly equal to the max range of the timer,\r
- // then the start will be equal to the stop plus one timer overflow (wrap-around).\r
- // To avoid having to check for that, reduce the maximum acceptable range by 1 tick,\r
- // i.e. reject delays equal or greater than the max range of the timer.\r
- if (DelayTicks64 >= (UINT64)SP804_MAX_TICKS) {\r
- DEBUG((EFI_D_ERROR,"MicroSecondDelay: ERROR: MicroSeconds=%d exceed SP804 count range. Max MicroSeconds=%d\n",\r
- MicroSeconds,\r
- ((UINTN)SP804_MAX_TICKS/PcdGet32(PcdSP804TimerFrequencyInMHz))));\r
- }\r
- ASSERT(DelayTicks64 < (UINT64)SP804_MAX_TICKS);\r
-\r
- // From now on do calculations only in native bit size.\r
- DelayTicks = (UINTN)DelayTicks64;\r
-\r
- // Calculate the target value of the timer.\r
-\r
- //Note: SP804 timer is counting down\r
- if (StartTicks >= DelayTicks) {\r
- // In this case we do not expect a wrap-around of the timer to occur.\r
- // CurrentTicks must be less than StartTicks and higher than TargetTicks.\r
- // If this is not the case, then the delay has been reached and may even have been exceeded if this\r
- // function was suspended by a higher priority interrupt.\r
-\r
- TargetTicks = StartTicks - DelayTicks;\r
-\r
- do {\r
- CurrentTicks = MmioRead32 (SP804_TIMER_METRONOME_BASE + SP804_TIMER_CURRENT_REG);\r
- } while ((CurrentTicks > TargetTicks) && (CurrentTicks <= StartTicks));\r
-\r
- } else {\r
- // In this case TargetTicks is larger than StartTicks.\r
- // This means we expect a wrap-around of the timer to occur and we must wait for it.\r
- // Before the wrap-around, CurrentTicks must be less than StartTicks and less than TargetTicks.\r
- // After the wrap-around, CurrentTicks must be larger than StartTicks and larger than TargetTicks.\r
- // If this is not the case, then the delay has been reached and may even have been exceeded if this\r
- // function was suspended by a higher priority interrupt.\r
-\r
- // The order of operations is essential to avoid arithmetic overflow problems\r
- TargetTicks = ((UINTN)SP804_MAX_TICKS - DelayTicks) + StartTicks;\r
-\r
- // First wait for the wrap-around to occur\r
- do {\r
- CurrentTicks = MmioRead32 (SP804_TIMER_METRONOME_BASE + SP804_TIMER_CURRENT_REG);\r
- } while (CurrentTicks <= StartTicks);\r
-\r
- // Then wait for the target\r
- do {\r
- CurrentTicks = MmioRead32 (SP804_TIMER_METRONOME_BASE + SP804_TIMER_CURRENT_REG);\r
- } while (CurrentTicks > TargetTicks);\r
- }\r
-\r
- return MicroSeconds;\r
-}\r
-\r
-/**\r
- Stalls the CPU for at least the given number of nanoseconds.\r
-\r
- Stalls the CPU for the number of nanoseconds specified by NanoSeconds.\r
-\r
- When the timer frequency is 1MHz, each tick corresponds to 1 microsecond.\r
- Therefore, the nanosecond delay will be rounded up to the nearest 1 microsecond.\r
-\r
- @param NanoSeconds The minimum number of nanoseconds to delay.\r
-\r
- @return The value of NanoSeconds inputted.\r
-\r
-**/\r
-UINTN\r
-EFIAPI\r
-NanoSecondDelay (\r
- IN UINTN NanoSeconds\r
- )\r
-{\r
- UINTN MicroSeconds;\r
-\r
- // Round up to 1us Tick Number\r
- MicroSeconds = NanoSeconds / 1000;\r
- MicroSeconds += ((NanoSeconds % 1000) == 0) ? 0 : 1;\r
-\r
- MicroSecondDelay (MicroSeconds);\r
-\r
- return NanoSeconds;\r
-}\r
-\r
-/**\r
- Retrieves the current value of a 64-bit free running performance counter.\r
-\r
- The counter can either count up by 1 or count down by 1. If the physical\r
- performance counter counts by a larger increment, then the counter values\r
- must be translated. The properties of the counter can be retrieved from\r
- GetPerformanceCounterProperties().\r
-\r
- @return The current value of the free running performance counter.\r
-\r
-**/\r
-UINT64\r
-EFIAPI\r
-GetPerformanceCounter (\r
- VOID\r
- )\r
-{\r
- // Free running 64-bit/32-bit counter is needed here.\r
- // Don't think we need this to boot, just to do performance profile\r
- UINT64 Value;\r
- Value = MmioRead32 (SP804_TIMER_PERFORMANCE_BASE + SP804_TIMER_CURRENT_REG);\r
- return Value;\r
-}\r
-\r
-\r
-/**\r
- Retrieves the 64-bit frequency in Hz and the range of performance counter\r
- values.\r
-\r
- If StartValue is not NULL, then the value that the performance counter starts\r
- with immediately after is it rolls over is returned in StartValue. If\r
- EndValue is not NULL, then the value that the performance counter end with\r
- immediately before it rolls over is returned in EndValue. The 64-bit\r
- frequency of the performance counter in Hz is always returned. If StartValue\r
- is less than EndValue, then the performance counter counts up. If StartValue\r
- is greater than EndValue, then the performance counter counts down. For\r
- example, a 64-bit free running counter that counts up would have a StartValue\r
- of 0 and an EndValue of 0xFFFFFFFFFFFFFFFF. A 24-bit free running counter\r
- that counts down would have a StartValue of 0xFFFFFF and an EndValue of 0.\r
-\r
- @param StartValue The value the performance counter starts with when it\r
- rolls over.\r
- @param EndValue The value that the performance counter ends with before\r
- it rolls over.\r
-\r
- @return The frequency in Hz.\r
-\r
-**/\r
-UINT64\r
-EFIAPI\r
-GetPerformanceCounterProperties (\r
- OUT UINT64 *StartValue, OPTIONAL\r
- OUT UINT64 *EndValue OPTIONAL\r
- )\r
-{\r
- if (StartValue != NULL) {\r
- // Timer starts with the reload value\r
- *StartValue = 0xFFFFFFFF;\r
- }\r
-\r
- if (EndValue != NULL) {\r
- // Timer counts down to 0x0\r
- *EndValue = (UINT64)0ULL;\r
- }\r
-\r
- return PcdGet64 (PcdEmbeddedPerformanceCounterFrequencyInHz);\r
-}\r
+++ /dev/null
-#/** @file\r
-# Timer library implementation\r
-#\r
-#\r
-# Copyright (c) 2011, ARM Ltd. All rights reserved.<BR>\r
-# This program and the accompanying materials\r
-# are licensed and made available under the terms and conditions of the BSD License\r
-# which accompanies this distribution. The full text of the license may be found at\r
-# http://opensource.org/licenses/bsd-license.php\r
-#\r
-# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-#\r
-#**/\r
-\r
-[Defines]\r
- INF_VERSION = 0x00010005\r
- BASE_NAME = SP804TimerLib\r
- FILE_GUID = 09cefa99-0d07-487f-a651-fb44f094b1c7\r
- MODULE_TYPE = BASE\r
- VERSION_STRING = 1.0\r
- LIBRARY_CLASS = TimerLib\r
-\r
- CONSTRUCTOR = TimerConstructor\r
-\r
-[Sources.common]\r
- SP804TimerLib.c\r
-\r
-[Packages]\r
- MdePkg/MdePkg.dec\r
- ArmPkg/ArmPkg.dec\r
- ArmPlatformPkg/ArmPlatformPkg.dec\r
- EmbeddedPkg/EmbeddedPkg.dec\r
-\r
-[LibraryClasses]\r
- DebugLib\r
- IoLib\r
- BaseLib\r
-\r
-[Pcd]\r
- gArmPlatformTokenSpaceGuid.PcdSP804TimerFrequencyInMHz\r
- gArmPlatformTokenSpaceGuid.PcdSP804TimerPerformanceBase\r
- gArmPlatformTokenSpaceGuid.PcdSP804TimerMetronomeBase\r
- gEmbeddedTokenSpaceGuid.PcdEmbeddedPerformanceCounterFrequencyInHz\r