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