123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460 |
- /*++
- Copyright (c) 2014 Minoca Corp.
- This file is licensed under the terms of the GNU General Public License
- version 3. Alternative licensing terms are available. Contact
- info@minocacorp.com for details. See the LICENSE file at the root of this
- project for complete licensing information.
- Module Name:
- timer.c
- Abstract:
- This module implements support for hardware timer services in the UEFI
- core, including the periodic tick and time counter.
- Author:
- Evan Green 3-Mar-3014
- Environment:
- Firmware
- --*/
- //
- // ------------------------------------------------------------------- Includes
- //
- #include "ueficore.h"
- //
- // ---------------------------------------------------------------- Definitions
- //
- //
- // ------------------------------------------------------ Data Type Definitions
- //
- //
- // ----------------------------------------------- Internal Function Prototypes
- //
- //
- // -------------------------------------------------------------------- Globals
- //
- //
- // Define timer services data.
- //
- UINT32 EfiClockTimerInterruptNumber;
- EFI_PLATFORM_SERVICE_TIMER_INTERRUPT EfiClockTimerServiceRoutine;
- EFI_PLATFORM_READ_TIMER EfiReadTimerRoutine;
- UINT64 EfiReadTimerFrequency;
- UINT32 EfiReadTimerWidth;
- UINT64 EfiTimeCounterValue;
- UINTN EfiClockInterruptCount;
- //
- // ------------------------------------------------------------------ Functions
- //
- EFIAPI
- EFI_STATUS
- EfiCoreGetNextMonotonicCount (
- UINT64 *Count
- )
- /*++
- Routine Description:
- This routine returns a monotonically increasing count for the platform.
- Arguments:
- Count - Supplies a pointer where the next count is returned.
- Return Value:
- EFI_SUCCESS on success.
- EFI_INVALID_PARAMETER if the count is NULL.
- EFI_DEVICE_ERROR if the device is not functioning properly.
- --*/
- {
- if (Count == NULL) {
- return EFI_INVALID_PARAMETER;
- }
- if (EfiReadTimerRoutine == NULL) {
- return EFI_UNSUPPORTED;
- }
- *Count = EfiCoreReadTimeCounter();
- return EFI_SUCCESS;
- }
- EFIAPI
- EFI_STATUS
- EfiCoreStall (
- UINTN Microseconds
- )
- /*++
- Routine Description:
- This routine induces a fine-grained delay.
- Arguments:
- Microseconds - Supplies the number of microseconds to stall execution for.
- Return Value:
- EFI_SUCCESS on success.
- --*/
- {
- UINT64 CurrentTime;
- UINT64 EndTime;
- UINT64 Frequency;
- if (EfiReadTimerRoutine == NULL) {
- return EFI_UNSUPPORTED;
- }
- CurrentTime = EfiCoreReadTimeCounter();
- Frequency = EfiCoreGetTimeCounterFrequency();
- if (Frequency == 0) {
- return EFI_DEVICE_ERROR;
- }
- EndTime = CurrentTime + ((Microseconds * Frequency) / 1000000ULL);
- while (EfiCoreReadTimeCounter() < EndTime) {
- NOTHING;
- }
- return EFI_SUCCESS;
- }
- EFIAPI
- EFI_STATUS
- EfiCoreSetWatchdogTimer (
- UINTN Timeout,
- UINT64 WatchdogCode,
- UINTN DataSize,
- CHAR16 *WatchdogData
- )
- /*++
- Routine Description:
- This routine sets the system's watchdog timer.
- Arguments:
- Timeout - Supplies the number of seconds to set the timer for.
- WatchdogCode - Supplies a numeric code to log on a watchdog timeout event.
- DataSize - Supplies the size of the watchdog data.
- WatchdogData - Supplies an optional buffer that includes a null-terminated
- string, optionally followed by additional binary data.
- Return Value:
- EFI_SUCCESS on success.
- EFI_INVALID_PARAMETER if the supplied watchdog code is invalid.
- EFI_UNSUPPORTED if there is no watchdog timer.
- EFI_DEVICE_ERROR if an error occurred accessing the device hardware.
- --*/
- {
- EFI_STATUS Status;
- Status = EfiPlatformSetWatchdogTimer(Timeout,
- WatchdogCode,
- DataSize,
- WatchdogData);
- return Status;
- }
- UINT64
- EfiCoreReadTimeCounter (
- VOID
- )
- /*++
- Routine Description:
- This routine reads the current time counter value.
- Arguments:
- None.
- Return Value:
- Returns a 64-bit non-decreasing value.
- 0 if the time counter is not implemented.
- --*/
- {
- BOOLEAN Enabled;
- UINT64 HardwareMask;
- UINT64 HardwareValue;
- UINT64 HighBit;
- UINT64 Value;
- if (EfiReadTimerRoutine == NULL) {
- return 0;
- }
- Enabled = EfiDisableInterrupts();
- HardwareValue = EfiReadTimerRoutine();
- HardwareMask = (1ULL << EfiReadTimerWidth) - 1;
- HighBit = 1ULL << (EfiReadTimerWidth - 1);
- //
- // If the high bit flipped from one to zero, add one to the software
- // part.
- //
- if (((EfiTimeCounterValue & HighBit) != 0) &&
- ((HardwareValue & HighBit) == 0)) {
- EfiTimeCounterValue += 1ULL << EfiReadTimerWidth;
- }
- Value = (EfiTimeCounterValue & (~HardwareMask)) | HardwareValue;
- EfiTimeCounterValue = Value;
- if (Enabled != FALSE) {
- EfiEnableInterrupts();
- }
- return Value;
- }
- UINT64
- EfiCoreReadRecentTimeCounter (
- VOID
- )
- /*++
- Routine Description:
- This routine reads a relatively recent but not entirely up to date version
- of the time counter.
- Arguments:
- None.
- Return Value:
- Returns a 64-bit non-decreasing value.
- 0 if the time counter is not implemented.
- --*/
- {
- BOOLEAN Enabled;
- UINT64 Value;
- Enabled = EfiDisableInterrupts();
- Value = EfiTimeCounterValue;
- if (Enabled != FALSE) {
- EfiEnableInterrupts();
- }
- return Value;
- }
- UINT64
- EfiCoreGetTimeCounterFrequency (
- VOID
- )
- /*++
- Routine Description:
- This routine returns the frequency of the time counter.
- Arguments:
- None.
- Return Value:
- Returns the frequency of the time counter.
- 0 if the time counter is not implemented.
- --*/
- {
- return EfiReadTimerFrequency;
- }
- VOID
- EfiCoreServiceClockInterrupt (
- UINT32 InterruptNumber
- )
- /*++
- Routine Description:
- This routine is called to service the clock interrupt.
- Arguments:
- InterruptNumber - Supplies the interrupt number that fired.
- Return Value:
- None.
- --*/
- {
- UINT64 NewTime;
- ASSERT(InterruptNumber == EfiClockTimerInterruptNumber);
- ASSERT(EfiClockTimerServiceRoutine != NULL);
- ASSERT(EfiAreInterruptsEnabled() == FALSE);
- EfiClockInterruptCount += 1;
- //
- // Read the time counter to keep it up to date.
- //
- NewTime = EfiCoreReadTimeCounter();
- EfiClockTimerServiceRoutine(InterruptNumber);
- EfipCoreTimerTick(NewTime);
- return;
- }
- EFI_STATUS
- EfiCoreInitializeTimerServices (
- VOID
- )
- /*++
- Routine Description:
- This routine initializes platform timer services, including the periodic
- tick and time counter.
- Arguments:
- None.
- Return Value:
- EFI status code.
- --*/
- {
- BOOLEAN Enabled;
- EFI_STATUS Status;
- Enabled = EfiDisableInterrupts();
- Status = EfiPlatformInitializeTimers(&EfiClockTimerInterruptNumber,
- &EfiClockTimerServiceRoutine,
- &EfiReadTimerRoutine,
- &EfiReadTimerFrequency,
- &EfiReadTimerWidth);
- if (EFI_ERROR(Status)) {
- goto CoreInitializeTimerServicesEnd;
- }
- ASSERT((EfiReadTimerRoutine != NULL) &&
- (EfiReadTimerFrequency != 0) &&
- (EfiReadTimerWidth > 1));
- //
- // Perform an initial read of the counter to get a baseline.
- //
- EfiCoreReadTimeCounter();
- Status = EFI_SUCCESS;
- CoreInitializeTimerServicesEnd:
- if (Enabled != FALSE) {
- EfiEnableInterrupts();
- }
- return Status;
- }
- VOID
- EfiCoreTerminateTimerServices (
- VOID
- )
- /*++
- Routine Description:
- This routine terminates timer services in preparation for the termination
- of boot services.
- Arguments:
- None.
- Return Value:
- None.
- --*/
- {
- EfiPlatformTerminateTimers();
- return;
- }
- //
- // --------------------------------------------------------- Internal Functions
- //
|