diff --git a/ArmEbPkg/ArmEbPkg.dec b/ArmEbPkg/ArmEbPkg.dec index aab0e4164e..1c25d96029 100644 --- a/ArmEbPkg/ArmEbPkg.dec +++ b/ArmEbPkg/ArmEbPkg.dec @@ -37,5 +37,6 @@ [PcdsFeatureFlag.common] [PcdsFixedAtBuild.common] - gArmEbTokenSpaceGuid.PcdConsoleUart|0x12345678|UINT32|0x00000202 + gArmEbTokenSpaceGuid.PcdConsoleUartBase|0x10009000|UINT32|0x00000001 + gArmEbTokenSpaceGuid.PcdGdbUartBase|0x1000a000|UINT32|0x00000002 diff --git a/ArmEbPkg/ArmEbPkg.dsc b/ArmEbPkg/ArmEbPkg.dsc index 41ff7426dd..dd0d24c4fe 100644 --- a/ArmEbPkg/ArmEbPkg.dsc +++ b/ArmEbPkg/ArmEbPkg.dsc @@ -71,7 +71,7 @@ SemihostLib|ArmPkg/Library/SemihostLib/SemihostLib.inf - RealTimeClockLib|EmbeddedPkg/Library/TemplateRealTimeClockLib/TemplateRealTimeClockLib.inf + RealTimeClockLib|ArmEbPkg/Library/RealTimeClockLib/RealTimeClockLib.inf IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf @@ -113,6 +113,7 @@ ArmDisassemblerLib|ArmPkg/Library/ArmDisassemblerLib/ArmDisassemblerLib.inf DebugAgentLib|MdeModulePkg/Library/DebugAgentLibNull/DebugAgentLibNull.inf + DebugAgentTimerLib|ArmEbPkg/Library/DebugAgentTimerLib/DebugAgentTimerLib.inf SerialPortLib|ArmEbPkg/Library/SerialPortLib/SerialPortLib.inf TimerLib|ArmEbPkg/Library/TimerLib/TimerLib.inf @@ -120,6 +121,7 @@ GdbSerialLib|ArmEbPkg/Library/GdbSerialLib/GdbSerialLib.inf + [LibraryClasses.common.SEC] ArmLib|ArmPkg/Library/ArmLib/ArmV7/ArmV7LibPrePi.inf PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf @@ -134,6 +136,9 @@ # 1/123 faster than Stm or Vstm version BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf + # Uncomment to turn on GDB stub in SEC. + #DebugAgentLib|EmbeddedPkg/Library/GdbDebugAgent/GdbDebugAgent.inf + [LibraryClasses.common.DXE_CORE] HobLib|MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.inf MemoryAllocationLib|MdeModulePkg/Library/DxeCoreMemoryAllocationLib/DxeCoreMemoryAllocationLib.inf @@ -313,6 +318,13 @@ # gArmTokenSpaceGuid.PcdArmUncachedMemoryMask|0x0000000040000000 + # + # ARM EB PCDS + # + gArmEbTokenSpaceGuid.PcdConsoleUartBase|0x10009000 + gArmEbTokenSpaceGuid.PcdGdbUartBase|0x1000a000 + + ################################################################################ # # Components Section - list of all EDK II Modules needed by this Platform diff --git a/ArmEbPkg/Library/DebugAgentTimerLib/DebugAgentTimerLib.c b/ArmEbPkg/Library/DebugAgentTimerLib/DebugAgentTimerLib.c new file mode 100755 index 0000000000..e62384217f --- /dev/null +++ b/ArmEbPkg/Library/DebugAgentTimerLib/DebugAgentTimerLib.c @@ -0,0 +1,80 @@ +/** @file + Template for ArmEb DebugAgentLib. + + For ARM we reserve FIQ for the Debug Agent Timer. We don't care about + laytency as we only really need the timer to run a few times a second + (how fast can some one type a ctrl-c?), but it works much better if + the interrupt we are using to break into the debugger is not being + used, and masked, by the system. + + Copyright (c) 2008 - 2010, Apple Inc. 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 + + +/** + Setup all the hardware needed for the debug agents timer. + + This function is used to set up debug enviroment. + +**/ +VOID +EFIAPI +DebugAgentTimerIntialize ( + VOID + ) +{ + // Map Timer to FIQ +} + + +/** + Set the period for the debug agent timer. Zero means disable the timer. + + @param[in] TimerPeriodMilliseconds Frequency of the debug agent timer. + +**/ +VOID +EFIAPI +DebugAgentTimerSetPeriod ( + IN UINT32 TimerPeriodMilliseconds + ) +{ + if (TimerPeriodMilliseconds == 0) { + // Disable timer and Disable FIQ + return; + } + + // Set timer period and unmask FIQ +} + + +/** + Perform End Of Interrupt for the debug agent timer. This is called in the + interrupt handler after the interrupt has been processed. + +**/ +VOID +EFIAPI +DebugAgentTimerEndOfInterrupt ( + VOID + ) +{ + // EOI Timer interrupt for FIQ +} + + \ No newline at end of file diff --git a/ArmEbPkg/Library/DebugAgentTimerLib/DebugAgentTimerLib.inf b/ArmEbPkg/Library/DebugAgentTimerLib/DebugAgentTimerLib.inf new file mode 100755 index 0000000000..7431f65a8d --- /dev/null +++ b/ArmEbPkg/Library/DebugAgentTimerLib/DebugAgentTimerLib.inf @@ -0,0 +1,38 @@ +#/** @file +# Component description file for Base PCI Cf8 Library. +# +# PCI CF8 Library that uses I/O ports 0xCF8 and 0xCFC to perform PCI Configuration cycles. +# Layers on top of an I/O Library instance. +# Copyright (c) 2007, Intel Corporation. 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 = ArmEbDebugAgentTimerLib + FILE_GUID = 80949BBB-68EE-4a4c-B434-D5DB5A232F0C + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = DebugAgentTimerLib|SEC BASE DXE_CORE + + +[Sources.common] + DebugAgentTimerLib.c + + +[Packages] + MdePkg/MdePkg.dec + EmbeddedPkg/EmbeddedPkg.dec + ArmEbPkg/ArmEbPkg.dec + +[LibraryClasses] + IoLib + diff --git a/ArmEbPkg/Library/GdbSerialLib/GdbSerialLib.c b/ArmEbPkg/Library/GdbSerialLib/GdbSerialLib.c index 8da36811fa..7a87754906 100755 --- a/ArmEbPkg/Library/GdbSerialLib/GdbSerialLib.c +++ b/ArmEbPkg/Library/GdbSerialLib/GdbSerialLib.c @@ -17,7 +17,7 @@ #include #include #include -#include + #include RETURN_STATUS @@ -26,7 +26,7 @@ GdbSerialLibConstructor ( VOID ) { - return RETURN_SUCCESS; + return GdbSerialInit (115200, 0, 8, 1); } RETURN_STATUS @@ -38,7 +38,31 @@ GdbSerialInit ( IN UINT8 StopBits ) { - return RETURN_SUCCESS; + if ((Parity != 0) || (DataBits != 8) || (StopBits != 1)) { + return RETURN_UNSUPPORTED; + } + + if (BaudRate != 115200) { + // Could add support for different Baud rates.... + return RETURN_UNSUPPORTED; + } + + UINT32 Base = PcdGet32 (PcdGdbUartBase); + + // initialize baud rate generator to 115200 based on EB clock REFCLK24MHZ + MmioWrite32 (Base + UARTIBRD, UART_115200_IDIV); + MmioWrite32 (Base + UARTFBRD, UART_115200_FDIV); + + // no parity, 1 stop, no fifo, 8 data bits + MmioWrite32 (Base + UARTLCR_H, 0x60); + + // clear any pending errors + MmioWrite32 (Base + UARTECR, 0); + + // enable tx, rx, and uart overall + MmioWrite32 (Base + UARTCR, 0x301); + + return RETURN_SUCCESS; } BOOLEAN @@ -47,7 +71,13 @@ GdbIsCharAvailable ( VOID ) { - return FALSE; + UINT32 FR = PcdGet32 (PcdGdbUartBase) + UARTFR; + + if ((MmioRead32 (FR) & UART_RX_EMPTY_FLAG_MASK) == 0) { + return TRUE; + } else { + return FALSE; + } } CHAR8 @@ -56,7 +86,11 @@ GdbGetChar ( VOID ) { - return (CHAR8)0; + UINT32 FR = PcdGet32 (PcdGdbUartBase) + UARTFR; + UINT32 DR = PcdGet32 (PcdGdbUartBase) + UARTDR; + + while ((MmioRead32 (FR) & UART_RX_EMPTY_FLAG_MASK) == 0); + return MmioRead8 (DR); } VOID @@ -65,6 +99,11 @@ GdbPutChar ( IN CHAR8 Char ) { + UINT32 FR = PcdGet32 (PcdGdbUartBase) + UARTFR; + UINT32 DR = PcdGet32 (PcdGdbUartBase) + UARTDR; + + while ((MmioRead32 (FR) & UART_TX_EMPTY_FLAG_MASK) != 0); + MmioWrite8 (DR, Char); return; } diff --git a/ArmEbPkg/Library/GdbSerialLib/GdbSerialLib.inf b/ArmEbPkg/Library/GdbSerialLib/GdbSerialLib.inf index 86c9dc9541..359d2618fd 100755 --- a/ArmEbPkg/Library/GdbSerialLib/GdbSerialLib.inf +++ b/ArmEbPkg/Library/GdbSerialLib/GdbSerialLib.inf @@ -35,3 +35,5 @@ DebugLib IoLib +[FixedPcd] + gArmEbTokenSpaceGuid.PcdGdbUartBase \ No newline at end of file diff --git a/ArmEbPkg/Library/RealTimeClockLib/RealTimeClockLib.c b/ArmEbPkg/Library/RealTimeClockLib/RealTimeClockLib.c new file mode 100755 index 0000000000..cef6dd9791 --- /dev/null +++ b/ArmEbPkg/Library/RealTimeClockLib/RealTimeClockLib.c @@ -0,0 +1,175 @@ +/** @file + Implement EFI RealTimeClock runtime services via RTC Lib. + + Currently this driver does not support runtime virtual calling. + + Copyright (c) 2008 - 2010, Apple Inc. 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 + + +/** + Returns the current time and date information, and the time-keeping capabilities + of the hardware platform. + + @param Time A pointer to storage to receive a snapshot of the current time. + @param Capabilities An optional pointer to a buffer to receive the real time clock + device's capabilities. + + @retval EFI_SUCCESS The operation completed successfully. + @retval EFI_INVALID_PARAMETER Time is NULL. + @retval EFI_DEVICE_ERROR The time could not be retrieved due to hardware error. + +**/ +EFI_STATUS +EFIAPI +LibGetTime ( + OUT EFI_TIME *Time, + OUT EFI_TIME_CAPABILITIES *Capabilities + ) +{ + // + // Fill in Time and Capabilities via data from you RTC + // + return EFI_DEVICE_ERROR; +} + + +/** + Sets the current local time and date information. + + @param Time A pointer to the current time. + + @retval EFI_SUCCESS The operation completed successfully. + @retval EFI_INVALID_PARAMETER A time field is out of range. + @retval EFI_DEVICE_ERROR The time could not be set due due to hardware error. + +**/ +EFI_STATUS +EFIAPI +LibSetTime ( + IN EFI_TIME *Time + ) +{ + // + // Use Time, to set the time in your RTC hardware + // + return EFI_DEVICE_ERROR; +} + + +/** + Returns the current wakeup alarm clock setting. + + @param Enabled Indicates if the alarm is currently enabled or disabled. + @param Pending Indicates if the alarm signal is pending and requires acknowledgement. + @param Time The current alarm setting. + + @retval EFI_SUCCESS The alarm settings were returned. + @retval EFI_INVALID_PARAMETER Any parameter is NULL. + @retval EFI_DEVICE_ERROR The wakeup time could not be retrieved due to a hardware error. + +**/ +EFI_STATUS +EFIAPI +LibGetWakeupTime ( + OUT BOOLEAN *Enabled, + OUT BOOLEAN *Pending, + OUT EFI_TIME *Time + ) +{ + // Not a required feature + return EFI_UNSUPPORTED; +} + + +/** + Sets the system wakeup alarm clock time. + + @param Enabled Enable or disable the wakeup alarm. + @param Time If Enable is TRUE, the time to set the wakeup alarm for. + + @retval EFI_SUCCESS If Enable is TRUE, then the wakeup alarm was enabled. If + Enable is FALSE, then the wakeup alarm was disabled. + @retval EFI_INVALID_PARAMETER A time field is out of range. + @retval EFI_DEVICE_ERROR The wakeup time could not be set due to a hardware error. + @retval EFI_UNSUPPORTED A wakeup timer is not supported on this platform. + +**/ +EFI_STATUS +EFIAPI +LibSetWakeupTime ( + IN BOOLEAN Enabled, + OUT EFI_TIME *Time + ) +{ + // Not a required feature + return EFI_UNSUPPORTED; +} + + + +/** + This is the declaration of an EFI image entry point. This can be the entry point to an application + written to this specification, an EFI boot service driver, or an EFI runtime driver. + + @param ImageHandle Handle that identifies the loaded image. + @param SystemTable System Table for this image. + + @retval EFI_SUCCESS The operation completed successfully. + +**/ +EFI_STATUS +EFIAPI +LibRtcInitialize ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + // + // Do some initialization if reqruied to turn on the RTC + // + return EFI_SUCCESS; +} + + +/** + Fixup internal data so that EFI can be call in virtual mode. + Call the passed in Child Notify event and convert any pointers in + lib to virtual mode. + + @param[in] Event The Event that is being processed + @param[in] Context Event Context +**/ +VOID +EFIAPI +LibRtcVirtualNotifyEvent ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + // + // Only needed if you are going to support the OS calling RTC functions in virtual mode. + // You will need to call EfiConvertPointer (). To convert any stored physical addresses + // to virtual address. After the OS transistions to calling in virtual mode, all future + // runtime calls will be made in virtual mode. + // + return; +} + + + diff --git a/ArmEbPkg/Library/RealTimeClockLib/RealTimeClockLib.inf b/ArmEbPkg/Library/RealTimeClockLib/RealTimeClockLib.inf new file mode 100755 index 0000000000..a3a7e93cab --- /dev/null +++ b/ArmEbPkg/Library/RealTimeClockLib/RealTimeClockLib.inf @@ -0,0 +1,37 @@ +#/** @file +# Memory Status Code Library for UEFI drivers +# +# Lib to provide memory journal status code reporting Routines +# Copyright (c) 2006, Intel Corporation. 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 = ArmEbRealTimeClockLib + FILE_GUID = 470DFB96-E205-4515-A75E-2E60F853E79D + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = RealTimeClockLib + + +[Sources.common] + RealTimeClockLib.c + + +[Packages] + MdePkg/MdePkg.dec + EmbeddedPkg/EmbeddedPkg.dec + +[LibraryClasses] + IoLib + DebugLib + \ No newline at end of file diff --git a/ArmEbPkg/Library/ResetSystemLib/ResetSystemLib.c b/ArmEbPkg/Library/ResetSystemLib/ResetSystemLib.c index 85f347f4d0..ff9819a8d1 100644 --- a/ArmEbPkg/Library/ResetSystemLib/ResetSystemLib.c +++ b/ArmEbPkg/Library/ResetSystemLib/ResetSystemLib.c @@ -55,6 +55,7 @@ LibResetSystem ( case EfiResetCold: case EfiResetShutdown: default: + CpuDeadLoop (); break; } diff --git a/ArmEbPkg/Library/SerialPortLib/SerialPortLib.c b/ArmEbPkg/Library/SerialPortLib/SerialPortLib.c index 735c5ddab8..09a9333785 100644 --- a/ArmEbPkg/Library/SerialPortLib/SerialPortLib.c +++ b/ArmEbPkg/Library/SerialPortLib/SerialPortLib.c @@ -15,7 +15,6 @@ **/ #include -#include #include #include #include @@ -35,7 +34,7 @@ SerialPortInitialize ( VOID ) { - UINT32 Base = PcdGet32 (PcdConsoleUart); + UINT32 Base = PcdGet32 (PcdConsoleUartBase); // initialize baud rate generator to 115200 based on EB clock REFCLK24MHZ MmioWrite32 (Base + UARTIBRD, UART_115200_IDIV); @@ -70,8 +69,8 @@ SerialPortWrite ( IN UINTN NumberOfBytes ) { - UINT32 FR = PcdGet32(PcdConsoleUart) + UARTFR; - UINT32 DR = PcdGet32(PcdConsoleUart) + UARTDR; + UINT32 FR = PcdGet32 (PcdConsoleUartBase) + UARTFR; + UINT32 DR = PcdGet32 (PcdConsoleUartBase) + UARTDR; UINTN Count; for (Count = 0; Count < NumberOfBytes; Count++, Buffer++) { @@ -100,8 +99,8 @@ SerialPortRead ( IN UINTN NumberOfBytes ) { - UINT32 FR = PcdGet32(PcdConsoleUart) + UARTFR; - UINT32 DR = PcdGet32(PcdConsoleUart) + UARTDR; + UINT32 FR = PcdGet32 (PcdConsoleUartBase) + UARTFR; + UINT32 DR = PcdGet32 (PcdConsoleUartBase) + UARTDR; UINTN Count; for (Count = 0; Count < NumberOfBytes; Count++, Buffer++) { @@ -127,7 +126,7 @@ SerialPortPoll ( VOID ) { - UINT32 FR = PcdGet32(PcdConsoleUart) + UARTFR; + UINT32 FR = PcdGet32 (PcdConsoleUartBase) + UARTFR; if ((MmioRead32 (FR) & UART_RX_EMPTY_FLAG_MASK) == 0) { return TRUE; diff --git a/ArmEbPkg/Library/SerialPortLib/SerialPortLib.inf b/ArmEbPkg/Library/SerialPortLib/SerialPortLib.inf index 298e7e78c0..ee4eed90be 100644 --- a/ArmEbPkg/Library/SerialPortLib/SerialPortLib.inf +++ b/ArmEbPkg/Library/SerialPortLib/SerialPortLib.inf @@ -30,7 +30,6 @@ SerialPortLib.c [LibraryClasses] - DebugLib IoLib [Packages] @@ -38,5 +37,5 @@ ArmEbPkg/ArmEbPkg.dec [FixedPcd] - gArmEbTokenSpaceGuid.PcdConsoleUart + gArmEbTokenSpaceGuid.PcdConsoleUartBase diff --git a/ArmEbPkg/Library/TimerLib/TimerLib.c b/ArmEbPkg/Library/TimerLib/TimerLib.c index c2a2a90736..c56b77acaa 100755 --- a/ArmEbPkg/Library/TimerLib/TimerLib.c +++ b/ArmEbPkg/Library/TimerLib/TimerLib.c @@ -1,4 +1,22 @@ /** @file + TimerLib for ARM EB. Hardcoded to 100ns period + + This library assume the following initialization, usually done in SEC. + + // configure SP810 to use 1MHz clock and disable + MmioAndThenOr32 (EB_SP810_CTRL_BASE + SP810_SYS_CTRL_REG, ~SP810_SYS_CTRL_TIMER2_EN, SP810_SYS_CTRL_TIMER2_TIMCLK); + // Enable + MmioOr32 (EB_SP810_CTRL_BASE + SP810_SYS_CTRL_REG, SP810_SYS_CTRL_TIMER2_EN); + + // configure timer 2 for one shot operation, 32 bits, no prescaler, and interrupt disabled + MmioOr32 (EB_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 (EB_SP804_TIMER2_BASE + SP804_TIMER_LOAD_REG, 1); + + // enable the timer + MmioOr32 (EB_SP804_TIMER2_BASE + SP804_TIMER_CONTROL_REG, SP804_TIMER_CTRL_ENABLE); + Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.
@@ -20,7 +38,19 @@ #include #include +#include + +/** + 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 ( @@ -41,41 +71,89 @@ MicroSecondDelay ( 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 Delay; - UINT32 StartTime; - UINT32 CurrentTime; - UINT32 ElapsedTime; + UINT32 TickNumber; + if (NanoSeconds == 0) { + return NanoSeconds; + } + + // Round up to 100ns Tick Number + TickNumber = (UINT32)NanoSeconds / 100; + TickNumber += ((UINT32)NanoSeconds % 100) == 0 ? 0 : 1; + + // load the timer count register + MmioWrite32 (EB_SP804_TIMER2_BASE + SP804_TIMER_LOAD_REG, TickNumber); + + while (MmioRead32 (EB_SP804_TIMER2_BASE + SP804_TIMER_CURRENT_REG) > 0) { + ; + } - Delay = (NanoSeconds / PcdGet32(PcdEmbeddedPerformanceCounterPeriodInNanoseconds)) + 1; - - StartTime = MmioRead32 (0); - do - { - CurrentTime = 0ULL; - ElapsedTime = CurrentTime - StartTime; - } while (ElapsedTime < Delay); - - NanoSeconds = ElapsedTime * PcdGet32 (PcdEmbeddedPerformanceCounterPeriodInNanoseconds); - 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); return (UINT64)0ULL; } + +/** + 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 ( @@ -93,5 +171,7 @@ GetPerformanceCounterProperties ( *EndValue = 0xFFFFFFFF; } - return PcdGet64(PcdEmbeddedPerformanceCounterFrequencyInHz); + return 100; } + + diff --git a/ArmEbPkg/Sec/Sec.c b/ArmEbPkg/Sec/Sec.c index 3118abb9df..8b161ef4c7 100755 --- a/ArmEbPkg/Sec/Sec.c +++ b/ArmEbPkg/Sec/Sec.c @@ -21,10 +21,13 @@ #include #include #include +#include #include #include +#include + #include "LzmaDecompress.h" VOID @@ -56,6 +59,27 @@ UartInit ( SerialPortInitialize (); } +VOID +TimerInit ( + VOID + ) +{ + // configure SP810 to use 1MHz clock and disable + MmioAndThenOr32 (EB_SP810_CTRL_BASE + SP810_SYS_CTRL_REG, ~SP810_SYS_CTRL_TIMER2_EN, SP810_SYS_CTRL_TIMER2_TIMCLK); + // Enable + MmioOr32 (EB_SP810_CTRL_BASE + SP810_SYS_CTRL_REG, SP810_SYS_CTRL_TIMER2_EN); + + // configure timer 2 for one shot operation, 32 bits, no prescaler, and interrupt disabled + MmioOr32 (EB_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 (EB_SP804_TIMER2_BASE + SP804_TIMER_LOAD_REG, 1); + + // enable the timer + MmioOr32 (EB_SP804_TIMER2_BASE + SP804_TIMER_CONTROL_REG, SP804_TIMER_CTRL_ENABLE); +} + + VOID InitCache ( IN UINT32 MemoryBase, @@ -74,52 +98,6 @@ LzmaDecompressLibConstructor ( VOID ); -/** - If the build is done on cygwin the paths are cygpaths. - /cygdrive/c/tmp.txt vs c:\tmp.txt so we need to convert - them to work with RVD commands - - This is just code to help print out RVD symbol load command. - If you build with cygwin paths aren't compatible with RVD. - - @param Name Path to convert if needed - -**/ -CHAR8 * -SecDeCygwinPathIfNeeded ( - IN CHAR8 *Name - ) -{ - CHAR8 *Ptr; - UINTN Index; - UINTN Len; - - Ptr = AsciiStrStr (Name, "/cygdrive/"); - if (Ptr == NULL) { - return Name; - } - - Len = AsciiStrLen (Ptr); - - // convert "/cygdrive" to spaces - for (Index = 0; Index < 9; Index++) { - Ptr[Index] = ' '; - } - - // convert /c to c: - Ptr[9] = Ptr[10]; - Ptr[10] = ':'; - - // switch path seperators - for (Index = 11; Index < Len; Index++) { - if (Ptr[Index] == '/') { - Ptr[Index] = '\\' ; - } - } - - return Name; -} - VOID CEntryPoint ( @@ -150,51 +128,14 @@ CEntryPoint ( // Start talking UartInit (); + + InitializeDebugAgent (DEBUG_AGENT_INIT_PREMEM_SEC, NULL); + SaveAndSetDebugTimerInterrupt (TRUE); + DEBUG ((EFI_D_ERROR, "UART Enabled\n")); - DEBUG_CODE_BEGIN (); - // - // On a debug build print out information about the SEC. This is really info about - // the PE/COFF file we are currently running from. Useful for loading symbols in a - // debugger. Remember our image is really part of the FV. - // - RETURN_STATUS Status; - EFI_PEI_FV_HANDLE VolumeHandle; - EFI_PEI_FILE_HANDLE FileHandle; - VOID *PeCoffImage; - UINT32 Offset; - CHAR8 *FilePath; - FfsAnyFvFindFirstFile (EFI_FV_FILETYPE_SECURITY_CORE, &VolumeHandle, &FileHandle); - Status = FfsFindSectionData (EFI_SECTION_TE, FileHandle, &PeCoffImage); - if (EFI_ERROR (Status)) { - // Usually is a TE (PI striped down PE/COFF), but could be a full PE/COFF - Status = FfsFindSectionData (EFI_SECTION_PE32, FileHandle, &PeCoffImage); - } - if (!EFI_ERROR (Status)) { - Offset = PeCoffGetSizeOfHeaders (PeCoffImage); - FilePath = PeCoffLoaderGetPdbPointer (PeCoffImage); - if (FilePath != NULL) { - - // - // In general you should never have to use #ifdef __CC_ARM in the code. It - // is hidden in the away in the MdePkg. But here we would like to print differnt things - // for different toolchains. - // -#ifdef __CC_ARM - // Print out the command for the RVD debugger to load symbols for this image - DEBUG ((EFI_D_ERROR, "load /a /ni /np %a &0x%08x\n", SecDeCygwinPathIfNeeded (FilePath), (CHAR8 *)PeCoffImage + Offset)); -#elif __GNUC__ - // This may not work correctly if you generate PE/COFF directlyas then the Offset would not be required - DEBUG ((EFI_D_ERROR, "add-symbol-file %a 0x%08x\n", FilePath, PeCoffImage + Offset)); -#else - DEBUG ((EFI_D_ERROR, "SEC starts at 0x%08x with an entry point at 0x%08x %a\n", PeCoffImage, _ModuleEntryPoint, FilePath)); -#endif - } - } - - - DEBUG_CODE_END (); - + // Start up a free running timer so that the timer lib will work + TimerInit (); // SEC phase needs to run library constructors by hand. ExtractGuidedSectionLibConstructor (); diff --git a/ArmEbPkg/Sec/Sec.inf b/ArmEbPkg/Sec/Sec.inf index d9b96e77be..ed46f96f21 100755 --- a/ArmEbPkg/Sec/Sec.inf +++ b/ArmEbPkg/Sec/Sec.inf @@ -35,6 +35,8 @@ EmbeddedPkg/EmbeddedPkg.dec ArmPkg/ArmPkg.dec IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec + ArmEbPkg/ArmEbPkg.dec + [LibraryClasses] BaseLib @@ -44,6 +46,8 @@ ExtractGuidedSectionLib LzmaDecompressLib PeCoffGetEntryPointLib + DebugAgentLib + [FeaturePcd] gEmbeddedTokenSpaceGuid.PcdCacheEnable