diff options
author | andrewfish <andrewfish@6f19259b-4bc3-4df7-8a09-765794883524> | 2011-02-01 05:41:42 +0000 |
---|---|---|
committer | andrewfish <andrewfish@6f19259b-4bc3-4df7-8a09-765794883524> | 2011-02-01 05:41:42 +0000 |
commit | 1d5d0ae92d95410f20bc6daab7a47e129fb2547a (patch) | |
tree | 8679c57c5f85cadad47d4604450c1c3702276cf1 /ArmPlatformPkg/Library/SP804TimerLib | |
parent | fb334ef6c543b1babc9d8a613ad5d1ce6fe536e1 (diff) | |
download | edk2-platforms-1d5d0ae92d95410f20bc6daab7a47e129fb2547a.tar.xz |
Add ArmPlatformPkg from ARM Ltd. patch.
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@11291 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'ArmPlatformPkg/Library/SP804TimerLib')
-rw-r--r-- | ArmPlatformPkg/Library/SP804TimerLib/SP804TimerLib.c | 193 | ||||
-rw-r--r-- | ArmPlatformPkg/Library/SP804TimerLib/SP804TimerLib.inf | 37 |
2 files changed, 230 insertions, 0 deletions
diff --git a/ArmPlatformPkg/Library/SP804TimerLib/SP804TimerLib.c b/ArmPlatformPkg/Library/SP804TimerLib/SP804TimerLib.c new file mode 100644 index 0000000000..18be5805d8 --- /dev/null +++ b/ArmPlatformPkg/Library/SP804TimerLib/SP804TimerLib.c @@ -0,0 +1,193 @@ +/** @file + + Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR> + + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include <Base.h> + +#include <Library/BaseLib.h> +#include <Library/TimerLib.h> +#include <Library/DebugLib.h> +#include <Library/PcdLib.h> +#include <Library/IoLib.h> +#include <Drivers/SP804Timer.h> +#include <ArmPlatform.h> + +// Setup SP810's Timer2 for managing delay functions. And Timer3 for Performance counter +// Note: ArmVE's Timer0 and Timer1 are used by TimerDxe. +RETURN_STATUS +EFIAPI +TimerConstructor ( + VOID + ) +{ + // Check if Timer 2 is already initialized + if (MmioRead32(SP804_TIMER2_BASE + SP804_TIMER_CONTROL_REG) & SP804_TIMER_CTRL_ENABLE) { + return RETURN_SUCCESS; + } else { + // configure SP810 to use 1MHz clock and disable + MmioAndThenOr32 (SP810_CTRL_BASE + SP810_SYS_CTRL_REG, ~SP810_SYS_CTRL_TIMER2_EN, SP810_SYS_CTRL_TIMER2_TIMCLK); + + // configure timer 2 for one shot operation, 32 bits, no prescaler, and interrupt disabled + MmioOr32 (SP804_TIMER2_BASE + SP804_TIMER_CONTROL_REG, SP804_TIMER_CTRL_ONESHOT | SP804_TIMER_CTRL_32BIT | SP804_PRESCALE_DIV_1); + + // preload the timer count register + MmioWrite32 (SP804_TIMER2_BASE + SP804_TIMER_LOAD_REG, 1); + + // enable the timer + MmioOr32 (SP804_TIMER2_BASE + SP804_TIMER_CONTROL_REG, SP804_TIMER_CTRL_ENABLE); + } + + // Check if Timer 3 is already initialized + if (MmioRead32(SP804_TIMER3_BASE + SP804_TIMER_CONTROL_REG) & SP804_TIMER_CTRL_ENABLE) { + return RETURN_SUCCESS; + } else { + // configure SP810 to use 1MHz clock and disable + MmioAndThenOr32 (SP810_CTRL_BASE + SP810_SYS_CTRL_REG, ~SP810_SYS_CTRL_TIMER3_EN, SP810_SYS_CTRL_TIMER3_TIMCLK); + + // configure timer 3 for free running operation, 32 bits, no prescaler, interrupt disabled + MmioOr32 (SP804_TIMER3_BASE + SP804_TIMER_CONTROL_REG, SP804_TIMER_CTRL_32BIT | SP804_PRESCALE_DIV_1); + + // enable the timer + MmioOr32 (SP804_TIMER3_BASE + SP804_TIMER_CONTROL_REG, SP804_TIMER_CTRL_ENABLE); + } + + return RETURN_SUCCESS; +} + +/** + Stalls the CPU for at least the given number of microseconds. + + Stalls the CPU for the number of microseconds specified by MicroSeconds. + + @param MicroSeconds The minimum number of microseconds to delay. + + @return The value of MicroSeconds inputted. + +**/ +UINTN +EFIAPI +MicroSecondDelay ( + IN UINTN MicroSeconds + ) +{ + // load the timer count register + MmioWrite32 (SP804_TIMER2_BASE + SP804_TIMER_LOAD_REG, MicroSeconds); + + while (MmioRead32 (SP804_TIMER2_BASE + SP804_TIMER_CURRENT_REG) > 0) { + ; + } + + return MicroSeconds; +} + +/** + Stalls the CPU for at least the given number of nanoseconds. + + Stalls the CPU for the number of nanoseconds specified by NanoSeconds. + + @param NanoSeconds The minimum number of nanoseconds to delay. + + @return The value of NanoSeconds inputted. + +**/ +UINTN +EFIAPI +NanoSecondDelay ( + IN UINTN NanoSeconds + ) +{ + UINT32 MicroSeconds; + + // Round up to 1us Tick Number + MicroSeconds = (UINT32)NanoSeconds / 1000; + MicroSeconds += ((UINT32)NanoSeconds % 1000) == 0 ? 0 : 1; + + // load the timer count register + MmioWrite32 (SP804_TIMER2_BASE + SP804_TIMER_LOAD_REG, MicroSeconds); + + while (MmioRead32 (SP804_TIMER2_BASE + SP804_TIMER_CURRENT_REG) > 0) { + ; + } + + return NanoSeconds; +} + +/** + Retrieves the current value of a 64-bit free running performance counter. + + The counter can either count up by 1 or count down by 1. If the physical + performance counter counts by a larger increment, then the counter values + must be translated. The properties of the counter can be retrieved from + GetPerformanceCounterProperties(). + + @return The current value of the free running performance counter. + +**/ +UINT64 +EFIAPI +GetPerformanceCounter ( + VOID + ) +{ + // Free running 64-bit/32-bit counter is needed here. + // Don't think we need this to boot, just to do performance profile + // ASSERT (FALSE); + UINT32 val = MmioRead32 (SP804_TIMER3_BASE + SP804_TIMER_CURRENT_REG); + ASSERT(val > 0); + + return (UINT64)val; +} + + +/** + Retrieves the 64-bit frequency in Hz and the range of performance counter + values. + + If StartValue is not NULL, then the value that the performance counter starts + with immediately after is it rolls over is returned in StartValue. If + EndValue is not NULL, then the value that the performance counter end with + immediately before it rolls over is returned in EndValue. The 64-bit + frequency of the performance counter in Hz is always returned. If StartValue + is less than EndValue, then the performance counter counts up. If StartValue + is greater than EndValue, then the performance counter counts down. For + example, a 64-bit free running counter that counts up would have a StartValue + of 0 and an EndValue of 0xFFFFFFFFFFFFFFFF. A 24-bit free running counter + that counts down would have a StartValue of 0xFFFFFF and an EndValue of 0. + + @param StartValue The value the performance counter starts with when it + rolls over. + @param EndValue The value that the performance counter ends with before + it rolls over. + + @return The frequency in Hz. + +**/ +UINT64 +EFIAPI +GetPerformanceCounterProperties ( + OUT UINT64 *StartValue, OPTIONAL + OUT UINT64 *EndValue OPTIONAL + ) +{ + if (StartValue != NULL) { + // Timer starts with the reload value + *StartValue = (UINT64)0ULL; + } + + if (EndValue != NULL) { + // Timer counts up to 0xFFFFFFFF + *EndValue = 0xFFFFFFFF; + } + + return 1000000; +} diff --git a/ArmPlatformPkg/Library/SP804TimerLib/SP804TimerLib.inf b/ArmPlatformPkg/Library/SP804TimerLib/SP804TimerLib.inf new file mode 100644 index 0000000000..7481236c2f --- /dev/null +++ b/ArmPlatformPkg/Library/SP804TimerLib/SP804TimerLib.inf @@ -0,0 +1,37 @@ +#/** @file +# Timer library implementation +# +# +# Copyright (c) 2010, ARM Ltd. All rights reserved.<BR> +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +#**/ + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = SP804TimerLib + FILE_GUID = 09cefa99-0d07-487f-a651-fb44f094b1c7 + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = TimerLib + + CONSTRUCTOR = TimerConstructor + +[Sources.common] + SP804TimerLib.c + +[Packages] + MdePkg/MdePkg.dec + ArmPkg/ArmPkg.dec + ArmPlatformPkg/ArmPlatformPkg.dec + +[LibraryClasses] + DebugLib + IoLib + BaseLib |