summaryrefslogtreecommitdiff
path: root/ArmPlatformPkg
diff options
context:
space:
mode:
Diffstat (limited to 'ArmPlatformPkg')
-rw-r--r--ArmPlatformPkg/Include/Drivers/PL031RealTimeClock.h34
-rw-r--r--ArmPlatformPkg/Library/PL031RealTimeClockLib/PL031RealTimeClockLib.c122
-rw-r--r--ArmPlatformPkg/Library/PL031RealTimeClockLib/PL031RealTimeClockLib.inf7
3 files changed, 103 insertions, 60 deletions
diff --git a/ArmPlatformPkg/Include/Drivers/PL031RealTimeClock.h b/ArmPlatformPkg/Include/Drivers/PL031RealTimeClock.h
index 4c559c0c95..76fbd0eb82 100644
--- a/ArmPlatformPkg/Include/Drivers/PL031RealTimeClock.h
+++ b/ArmPlatformPkg/Include/Drivers/PL031RealTimeClock.h
@@ -1,6 +1,6 @@
/** @file
*
-* Copyright (c) 2011, ARM Limited. All rights reserved.
+* Copyright (c) 2011 - 2014, ARM Limited. All rights reserved.
*
* This program and the accompanying materials
* are licensed and made available under the terms and conditions of the BSD License
@@ -17,22 +17,22 @@
#define __PL031_REAL_TIME_CLOCK_H__
// PL031 Registers
-#define PL031_RTC_DR_DATA_REGISTER ((UINT32)PcdGet32(PcdPL031RtcBase) + 0x000)
-#define PL031_RTC_MR_MATCH_REGISTER ((UINT32)PcdGet32(PcdPL031RtcBase) + 0x004)
-#define PL031_RTC_LR_LOAD_REGISTER ((UINT32)PcdGet32(PcdPL031RtcBase) + 0x008)
-#define PL031_RTC_CR_CONTROL_REGISTER ((UINT32)PcdGet32(PcdPL031RtcBase) + 0x00C)
-#define PL031_RTC_IMSC_IRQ_MASK_SET_CLEAR_REGISTER ((UINT32)PcdGet32(PcdPL031RtcBase) + 0x010)
-#define PL031_RTC_RIS_RAW_IRQ_STATUS_REGISTER ((UINT32)PcdGet32(PcdPL031RtcBase) + 0x014)
-#define PL031_RTC_MIS_MASKED_IRQ_STATUS_REGISTER ((UINT32)PcdGet32(PcdPL031RtcBase) + 0x018)
-#define PL031_RTC_ICR_IRQ_CLEAR_REGISTER ((UINT32)PcdGet32(PcdPL031RtcBase) + 0x01C)
-#define PL031_RTC_PERIPH_ID0 ((UINT32)PcdGet32(PcdPL031RtcBase) + 0xFE0)
-#define PL031_RTC_PERIPH_ID1 ((UINT32)PcdGet32(PcdPL031RtcBase) + 0xFE4)
-#define PL031_RTC_PERIPH_ID2 ((UINT32)PcdGet32(PcdPL031RtcBase) + 0xFE8)
-#define PL031_RTC_PERIPH_ID3 ((UINT32)PcdGet32(PcdPL031RtcBase) + 0xFEC)
-#define PL031_RTC_PCELL_ID0 ((UINT32)PcdGet32(PcdPL031RtcBase) + 0xFF0)
-#define PL031_RTC_PCELL_ID1 ((UINT32)PcdGet32(PcdPL031RtcBase) + 0xFF4)
-#define PL031_RTC_PCELL_ID2 ((UINT32)PcdGet32(PcdPL031RtcBase) + 0xFF8)
-#define PL031_RTC_PCELL_ID3 ((UINT32)PcdGet32(PcdPL031RtcBase) + 0xFFC)
+#define PL031_RTC_DR_DATA_REGISTER 0x000
+#define PL031_RTC_MR_MATCH_REGISTER 0x004
+#define PL031_RTC_LR_LOAD_REGISTER 0x008
+#define PL031_RTC_CR_CONTROL_REGISTER 0x00C
+#define PL031_RTC_IMSC_IRQ_MASK_SET_CLEAR_REGISTER 0x010
+#define PL031_RTC_RIS_RAW_IRQ_STATUS_REGISTER 0x014
+#define PL031_RTC_MIS_MASKED_IRQ_STATUS_REGISTER 0x018
+#define PL031_RTC_ICR_IRQ_CLEAR_REGISTER 0x01C
+#define PL031_RTC_PERIPH_ID0 0xFE0
+#define PL031_RTC_PERIPH_ID1 0xFE4
+#define PL031_RTC_PERIPH_ID2 0xFE8
+#define PL031_RTC_PERIPH_ID3 0xFEC
+#define PL031_RTC_PCELL_ID0 0xFF0
+#define PL031_RTC_PCELL_ID1 0xFF4
+#define PL031_RTC_PCELL_ID2 0xFF8
+#define PL031_RTC_PCELL_ID3 0xFFC
// PL031 Values
#define PL031_RTC_ENABLED 0x00000001
diff --git a/ArmPlatformPkg/Library/PL031RealTimeClockLib/PL031RealTimeClockLib.c b/ArmPlatformPkg/Library/PL031RealTimeClockLib/PL031RealTimeClockLib.c
index 980f809b2c..b43d8dc4ba 100644
--- a/ArmPlatformPkg/Library/PL031RealTimeClockLib/PL031RealTimeClockLib.c
+++ b/ArmPlatformPkg/Library/PL031RealTimeClockLib/PL031RealTimeClockLib.c
@@ -4,7 +4,7 @@
Currently this driver does not support runtime virtual calling.
Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
- Copyright (c) 2011-2013, ARM Ltd. All rights reserved.<BR>
+ Copyright (c) 2011 - 2014, 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
@@ -26,10 +26,16 @@
#include <Library/MemoryAllocationLib.h>
#include <Library/PcdLib.h>
#include <Library/ArmPlatformSysConfigLib.h>
+#include <Library/DxeServicesTableLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/UefiRuntimeLib.h>
+
#include <Protocol/RealTimeClock.h>
+
#include <Guid/GlobalVariable.h>
+#include <Guid/EventGroup.h>
+
#include <Drivers/PL031RealTimeClock.h>
#include <ArmPlatform.h>
@@ -37,6 +43,8 @@
STATIC CONST CHAR16 mTimeZoneVariableName[] = L"PL031RtcTimeZone";
STATIC CONST CHAR16 mDaylightVariableName[] = L"PL031RtcDaylight";
STATIC BOOLEAN mPL031Initialized = FALSE;
+STATIC EFI_EVENT mRtcVirtualAddrChangeEvent;
+STATIC UINTN mPL031RtcBase;
EFI_STATUS
IdentifyPL031 (
@@ -46,19 +54,19 @@ IdentifyPL031 (
EFI_STATUS Status;
// Check if this is a PrimeCell Peripheral
- if ( (MmioRead8 (PL031_RTC_PCELL_ID0) != 0x0D)
- || (MmioRead8 (PL031_RTC_PCELL_ID1) != 0xF0)
- || (MmioRead8 (PL031_RTC_PCELL_ID2) != 0x05)
- || (MmioRead8 (PL031_RTC_PCELL_ID3) != 0xB1)) {
+ if ( (MmioRead8 (mPL031RtcBase + PL031_RTC_PCELL_ID0) != 0x0D)
+ || (MmioRead8 (mPL031RtcBase + PL031_RTC_PCELL_ID1) != 0xF0)
+ || (MmioRead8 (mPL031RtcBase + PL031_RTC_PCELL_ID2) != 0x05)
+ || (MmioRead8 (mPL031RtcBase + PL031_RTC_PCELL_ID3) != 0xB1)) {
Status = EFI_NOT_FOUND;
goto EXIT;
}
// Check if this PrimeCell Peripheral is the PL031 Real Time Clock
- if ( (MmioRead8 (PL031_RTC_PERIPH_ID0) != 0x31)
- || (MmioRead8 (PL031_RTC_PERIPH_ID1) != 0x10)
- || ((MmioRead8 (PL031_RTC_PERIPH_ID2) & 0xF) != 0x04)
- || (MmioRead8 (PL031_RTC_PERIPH_ID3) != 0x00)) {
+ if ( (MmioRead8 (mPL031RtcBase + PL031_RTC_PERIPH_ID0) != 0x31)
+ || (MmioRead8 (mPL031RtcBase + PL031_RTC_PERIPH_ID1) != 0x10)
+ || ((MmioRead8 (mPL031RtcBase + PL031_RTC_PERIPH_ID2) & 0xF) != 0x04)
+ || (MmioRead8 (mPL031RtcBase + PL031_RTC_PERIPH_ID3) != 0x00)) {
Status = EFI_NOT_FOUND;
goto EXIT;
}
@@ -83,18 +91,18 @@ InitializePL031 (
}
// Ensure interrupts are masked. We do not want RTC interrupts in UEFI
- if ((MmioRead32 (PL031_RTC_IMSC_IRQ_MASK_SET_CLEAR_REGISTER) & PL031_SET_IRQ_MASK) != PL031_SET_IRQ_MASK) {
- MmioOr32 (PL031_RTC_IMSC_IRQ_MASK_SET_CLEAR_REGISTER, PL031_SET_IRQ_MASK);
+ if ((MmioRead32 (mPL031RtcBase + PL031_RTC_IMSC_IRQ_MASK_SET_CLEAR_REGISTER) & PL031_SET_IRQ_MASK) != PL031_SET_IRQ_MASK) {
+ MmioOr32 (mPL031RtcBase + PL031_RTC_IMSC_IRQ_MASK_SET_CLEAR_REGISTER, PL031_SET_IRQ_MASK);
}
// Clear any existing interrupts
- if ((MmioRead32 (PL031_RTC_RIS_RAW_IRQ_STATUS_REGISTER) & PL031_IRQ_TRIGGERED) == PL031_IRQ_TRIGGERED) {
- MmioOr32 (PL031_RTC_ICR_IRQ_CLEAR_REGISTER, PL031_CLEAR_IRQ);
+ if ((MmioRead32 (mPL031RtcBase + PL031_RTC_RIS_RAW_IRQ_STATUS_REGISTER) & PL031_IRQ_TRIGGERED) == PL031_IRQ_TRIGGERED) {
+ MmioOr32 (mPL031RtcBase + PL031_RTC_ICR_IRQ_CLEAR_REGISTER, PL031_CLEAR_IRQ);
}
// Start the clock counter
- if ((MmioRead32 (PL031_RTC_CR_CONTROL_REGISTER) & PL031_RTC_ENABLED) != PL031_RTC_ENABLED) {
- MmioOr32 (PL031_RTC_CR_CONTROL_REGISTER, PL031_RTC_ENABLED);
+ if ((MmioRead32 (mPL031RtcBase + PL031_RTC_CR_CONTROL_REGISTER) & PL031_RTC_ENABLED) != PL031_RTC_ENABLED) {
+ MmioOr32 (mPL031RtcBase + PL031_RTC_CR_CONTROL_REGISTER, PL031_RTC_ENABLED);
}
mPL031Initialized = TRUE;
@@ -267,7 +275,7 @@ LibGetTime (
Status = ArmPlatformSysConfigGet (SYS_CFG_RTC, &EpochSeconds);
if (Status == EFI_UNSUPPORTED) {
// Battery backed up hardware RTC does not exist, revert to PL031
- EpochSeconds = MmioRead32 (PL031_RTC_DR_DATA_REGISTER);
+ EpochSeconds = MmioRead32 (mPL031RtcBase + PL031_RTC_DR_DATA_REGISTER);
Status = EFI_SUCCESS;
} else if (EFI_ERROR (Status)) {
// Battery backed up hardware RTC exists but could not be read due to error. Abort.
@@ -275,7 +283,7 @@ LibGetTime (
} else {
// Battery backed up hardware RTC exists and we read the time correctly from it.
// Now sync the PL031 to the new time.
- MmioWrite32 (PL031_RTC_LR_LOAD_REGISTER, EpochSeconds);
+ MmioWrite32 (mPL031RtcBase + PL031_RTC_LR_LOAD_REGISTER, EpochSeconds);
}
// Ensure Time is a valid pointer
@@ -484,7 +492,7 @@ LibSetTime (
// Set the PL031
- MmioWrite32 (PL031_RTC_LR_LOAD_REGISTER, EpochSeconds);
+ MmioWrite32 (mPL031RtcBase + PL031_RTC_LR_LOAD_REGISTER, EpochSeconds);
// The accesses to Variable Services can be very slow, because we may be writing to Flash.
// Do this after having set the RTC.
@@ -579,7 +587,30 @@ LibSetWakeupTime (
return EFI_UNSUPPORTED;
}
+/**
+ 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 transitions to calling in virtual mode, all future
+ // runtime calls will be made in virtual mode.
+ //
+ EfiConvertPointer (0x0, (VOID**)&mPL031RtcBase);
+ return;
+}
/**
This is the declaration of an EFI image entry point. This can be the entry point to an application
@@ -601,6 +632,24 @@ LibRtcInitialize (
EFI_STATUS Status;
EFI_HANDLE Handle;
+ // Initialize RTC Base Address
+ mPL031RtcBase = PcdGet32 (PcdPL031RtcBase);
+
+ // Declare the controller as EFI_MEMORY_RUNTIME
+ Status = gDS->AddMemorySpace (
+ EfiGcdMemoryTypeMemoryMappedIo,
+ mPL031RtcBase, SIZE_4KB,
+ EFI_MEMORY_UC | EFI_MEMORY_RUNTIME
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = gDS->SetMemorySpaceAttributes (mPL031RtcBase, SIZE_4KB, EFI_MEMORY_UC | EFI_MEMORY_RUNTIME);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
// Setup the setters and getters
gRT->GetTime = LibGetTime;
gRT->SetTime = LibSetTime;
@@ -614,31 +663,20 @@ LibRtcInitialize (
&gEfiRealTimeClockArchProtocolGuid, NULL,
NULL
);
+ ASSERT_EFI_ERROR (Status);
- return Status;
-}
-
-
-/**
- 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 transitions to calling in virtual mode, all future
- // runtime calls will be made in virtual mode.
+ // Register for the virtual address change event
//
- return;
+ Status = gBS->CreateEventEx (
+ EVT_NOTIFY_SIGNAL,
+ TPL_NOTIFY,
+ LibRtcVirtualNotifyEvent,
+ NULL,
+ &gEfiEventVirtualAddressChangeGuid,
+ &mRtcVirtualAddrChangeEvent
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ return Status;
}
diff --git a/ArmPlatformPkg/Library/PL031RealTimeClockLib/PL031RealTimeClockLib.inf b/ArmPlatformPkg/Library/PL031RealTimeClockLib/PL031RealTimeClockLib.inf
index add982ce8e..3a98fc757e 100644
--- a/ArmPlatformPkg/Library/PL031RealTimeClockLib/PL031RealTimeClockLib.inf
+++ b/ArmPlatformPkg/Library/PL031RealTimeClockLib/PL031RealTimeClockLib.inf
@@ -1,7 +1,7 @@
#/** @file
#
# Copyright (c) 2006, Intel Corporation. All rights reserved.<BR>
-# Copyright (c) 2011-2013, ARM Ltd. All rights reserved.<BR>
+# Copyright (c) 2011 - 2014, 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
@@ -35,6 +35,11 @@
DebugLib
PcdLib
ArmPlatformSysConfigLib
+ DxeServicesTableLib
+ UefiRuntimeLib
+
+[Guids]
+ gEfiEventVirtualAddressChangeGuid
[Pcd]
gArmPlatformTokenSpaceGuid.PcdPL031RtcBase