]> git.proxmox.com Git - mirror_edk2.git/blobdiff - ArmEbPkg/Library/TimerLib/TimerLib.c
Report correct MediaPresentSupported value from Nt32 SNP mode data.
[mirror_edk2.git] / ArmEbPkg / Library / TimerLib / TimerLib.c
index c2a2a90736fc2b797256fad89dfc2cd19a5a1c69..c56b77acaa888cc5e6c6b21e7b15ba19fe5747c2 100755 (executable)
@@ -1,4 +1,22 @@
 /** @file\r
+  TimerLib for ARM EB. Hardcoded to 100ns period\r
+\r
+  This library assume the following initialization, usually done in SEC. \r
+\r
+  // configure SP810 to use 1MHz clock and disable\r
+  MmioAndThenOr32 (EB_SP810_CTRL_BASE + SP810_SYS_CTRL_REG, ~SP810_SYS_CTRL_TIMER2_EN, SP810_SYS_CTRL_TIMER2_TIMCLK);\r
+  // Enable\r
+  MmioOr32 (EB_SP810_CTRL_BASE + SP810_SYS_CTRL_REG, SP810_SYS_CTRL_TIMER2_EN);\r
+\r
+  // configure timer 2 for one shot operation, 32 bits, no prescaler, and interrupt disabled\r
+  MmioOr32 (EB_SP804_TIMER2_BASE + SP804_TIMER_CONTROL_REG, SP804_TIMER_CTRL_ONESHOT | SP804_TIMER_CTRL_32BIT | SP804_PRESCALE_DIV_1);\r
+\r
+  // preload the timer count register\r
+  MmioWrite32 (EB_SP804_TIMER2_BASE + SP804_TIMER_LOAD_REG, 1);\r
+\r
+  // enable the timer\r
+  MmioOr32 (EB_SP804_TIMER2_BASE + SP804_TIMER_CONTROL_REG, SP804_TIMER_CTRL_ENABLE);\r
+\r
 \r
   Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>\r
   \r
 #include <Library/PcdLib.h>\r
 #include <Library/IoLib.h>\r
 \r
+#include <ArmEb/ArmEb.h>\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
+\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
@@ -41,41 +71,89 @@ MicroSecondDelay (
   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
+  @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
-  UINT32  Delay;\r
-  UINT32  StartTime;\r
-  UINT32  CurrentTime;\r
-  UINT32  ElapsedTime;\r
+  UINT32  TickNumber;\r
 \r
\r
-  Delay = (NanoSeconds / PcdGet32(PcdEmbeddedPerformanceCounterPeriodInNanoseconds)) + 1;\r
+  if (NanoSeconds == 0) {\r
+    return NanoSeconds;\r
+  }\r
 \r
-  StartTime = MmioRead32 (0);\r
-  do \r
-  {\r
-    CurrentTime = 0ULL;\r
-    ElapsedTime = CurrentTime - StartTime;\r
-  } while (ElapsedTime < Delay);\r
+  // Round up to 100ns Tick Number\r
+  TickNumber =   (UINT32)NanoSeconds / 100;\r
+  TickNumber += ((UINT32)NanoSeconds % 100) == 0 ? 0 : 1;\r
 \r
-  NanoSeconds = ElapsedTime * PcdGet32 (PcdEmbeddedPerformanceCounterPeriodInNanoseconds);\r
+  // load the timer count register\r
+  MmioWrite32 (EB_SP804_TIMER2_BASE + SP804_TIMER_LOAD_REG, TickNumber);\r
 \r
+  while (MmioRead32 (EB_SP804_TIMER2_BASE + SP804_TIMER_CURRENT_REG) > 0) {\r
+    ;\r
+  } \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
+  ASSERT (FALSE);\r
   return (UINT64)0ULL;\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
@@ -93,5 +171,7 @@ GetPerformanceCounterProperties (
     *EndValue = 0xFFFFFFFF;\r
   }\r
   \r
-  return PcdGet64(PcdEmbeddedPerformanceCounterFrequencyInHz);\r
+  return 100;\r
 }\r
+\r
+\r