1*f439973dSWarner Losh /** @file 2*f439973dSWarner Losh Timer Architectural Protocol as defined in PI Specification VOLUME 2 DXE 3*f439973dSWarner Losh 4*f439973dSWarner Losh This code is used to provide the timer tick for the DXE core. 5*f439973dSWarner Losh 6*f439973dSWarner Losh Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR> 7*f439973dSWarner Losh SPDX-License-Identifier: BSD-2-Clause-Patent 8*f439973dSWarner Losh 9*f439973dSWarner Losh **/ 10*f439973dSWarner Losh 11*f439973dSWarner Losh #ifndef __ARCH_PROTOCOL_TIMER_H__ 12*f439973dSWarner Losh #define __ARCH_PROTOCOL_TIMER_H__ 13*f439973dSWarner Losh 14*f439973dSWarner Losh /// 15*f439973dSWarner Losh /// Global ID for the Timer Architectural Protocol 16*f439973dSWarner Losh /// 17*f439973dSWarner Losh #define EFI_TIMER_ARCH_PROTOCOL_GUID \ 18*f439973dSWarner Losh { 0x26baccb3, 0x6f42, 0x11d4, {0xbc, 0xe7, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 } } 19*f439973dSWarner Losh 20*f439973dSWarner Losh /// 21*f439973dSWarner Losh /// Declare forward reference for the Timer Architectural Protocol 22*f439973dSWarner Losh /// 23*f439973dSWarner Losh typedef struct _EFI_TIMER_ARCH_PROTOCOL EFI_TIMER_ARCH_PROTOCOL; 24*f439973dSWarner Losh 25*f439973dSWarner Losh /** 26*f439973dSWarner Losh This function of this type is called when a timer interrupt fires. This 27*f439973dSWarner Losh function executes at TPL_HIGH_LEVEL. The DXE Core will register a function 28*f439973dSWarner Losh of this type to be called for the timer interrupt, so it can know how much 29*f439973dSWarner Losh time has passed. This information is used to signal timer based events. 30*f439973dSWarner Losh 31*f439973dSWarner Losh @param Time Time since the last timer interrupt in 100 ns units. This will 32*f439973dSWarner Losh typically be TimerPeriod, but if a timer interrupt is missed, and the 33*f439973dSWarner Losh EFI_TIMER_ARCH_PROTOCOL driver can detect missed interrupts, then Time 34*f439973dSWarner Losh will contain the actual amount of time since the last interrupt. 35*f439973dSWarner Losh 36*f439973dSWarner Losh None. 37*f439973dSWarner Losh 38*f439973dSWarner Losh **/ 39*f439973dSWarner Losh typedef 40*f439973dSWarner Losh VOID 41*f439973dSWarner Losh (EFIAPI *EFI_TIMER_NOTIFY)( 42*f439973dSWarner Losh IN UINT64 Time 43*f439973dSWarner Losh ); 44*f439973dSWarner Losh 45*f439973dSWarner Losh /** 46*f439973dSWarner Losh This function registers the handler NotifyFunction so it is called every time 47*f439973dSWarner Losh the timer interrupt fires. It also passes the amount of time since the last 48*f439973dSWarner Losh handler call to the NotifyFunction. If NotifyFunction is NULL, then the 49*f439973dSWarner Losh handler is unregistered. If the handler is registered, then EFI_SUCCESS is 50*f439973dSWarner Losh returned. If the CPU does not support registering a timer interrupt handler, 51*f439973dSWarner Losh then EFI_UNSUPPORTED is returned. If an attempt is made to register a handler 52*f439973dSWarner Losh when a handler is already registered, then EFI_ALREADY_STARTED is returned. 53*f439973dSWarner Losh If an attempt is made to unregister a handler when a handler is not registered, 54*f439973dSWarner Losh then EFI_INVALID_PARAMETER is returned. If an error occurs attempting to 55*f439973dSWarner Losh register the NotifyFunction with the timer interrupt, then EFI_DEVICE_ERROR 56*f439973dSWarner Losh is returned. 57*f439973dSWarner Losh 58*f439973dSWarner Losh @param This The EFI_TIMER_ARCH_PROTOCOL instance. 59*f439973dSWarner Losh @param NotifyFunction The function to call when a timer interrupt fires. This 60*f439973dSWarner Losh function executes at TPL_HIGH_LEVEL. The DXE Core will 61*f439973dSWarner Losh register a handler for the timer interrupt, so it can know 62*f439973dSWarner Losh how much time has passed. This information is used to 63*f439973dSWarner Losh signal timer based events. NULL will unregister the handler. 64*f439973dSWarner Losh 65*f439973dSWarner Losh @retval EFI_SUCCESS The timer handler was registered. 66*f439973dSWarner Losh @retval EFI_UNSUPPORTED The platform does not support timer interrupts. 67*f439973dSWarner Losh @retval EFI_ALREADY_STARTED NotifyFunction is not NULL, and a handler is already 68*f439973dSWarner Losh registered. 69*f439973dSWarner Losh @retval EFI_INVALID_PARAMETER NotifyFunction is NULL, and a handler was not 70*f439973dSWarner Losh previously registered. 71*f439973dSWarner Losh @retval EFI_DEVICE_ERROR The timer handler could not be registered. 72*f439973dSWarner Losh 73*f439973dSWarner Losh **/ 74*f439973dSWarner Losh typedef 75*f439973dSWarner Losh EFI_STATUS 76*f439973dSWarner Losh (EFIAPI *EFI_TIMER_REGISTER_HANDLER)( 77*f439973dSWarner Losh IN EFI_TIMER_ARCH_PROTOCOL *This, 78*f439973dSWarner Losh IN EFI_TIMER_NOTIFY NotifyFunction 79*f439973dSWarner Losh ); 80*f439973dSWarner Losh 81*f439973dSWarner Losh /** 82*f439973dSWarner Losh This function adjusts the period of timer interrupts to the value specified 83*f439973dSWarner Losh by TimerPeriod. If the timer period is updated, then the selected timer 84*f439973dSWarner Losh period is stored in EFI_TIMER.TimerPeriod, and EFI_SUCCESS is returned. If 85*f439973dSWarner Losh the timer hardware is not programmable, then EFI_UNSUPPORTED is returned. 86*f439973dSWarner Losh If an error occurs while attempting to update the timer period, then the 87*f439973dSWarner Losh timer hardware will be put back in its state prior to this call, and 88*f439973dSWarner Losh EFI_DEVICE_ERROR is returned. If TimerPeriod is 0, then the timer interrupt 89*f439973dSWarner Losh is disabled. This is not the same as disabling the CPU's interrupts. 90*f439973dSWarner Losh Instead, it must either turn off the timer hardware, or it must adjust the 91*f439973dSWarner Losh interrupt controller so that a CPU interrupt is not generated when the timer 92*f439973dSWarner Losh interrupt fires. 93*f439973dSWarner Losh 94*f439973dSWarner Losh @param This The EFI_TIMER_ARCH_PROTOCOL instance. 95*f439973dSWarner Losh @param TimerPeriod The rate to program the timer interrupt in 100 nS units. If 96*f439973dSWarner Losh the timer hardware is not programmable, then EFI_UNSUPPORTED is 97*f439973dSWarner Losh returned. If the timer is programmable, then the timer period 98*f439973dSWarner Losh will be rounded up to the nearest timer period that is supported 99*f439973dSWarner Losh by the timer hardware. If TimerPeriod is set to 0, then the 100*f439973dSWarner Losh timer interrupts will be disabled. 101*f439973dSWarner Losh 102*f439973dSWarner Losh @retval EFI_SUCCESS The timer period was changed. 103*f439973dSWarner Losh @retval EFI_UNSUPPORTED The platform cannot change the period of the timer interrupt. 104*f439973dSWarner Losh @retval EFI_DEVICE_ERROR The timer period could not be changed due to a device error. 105*f439973dSWarner Losh 106*f439973dSWarner Losh **/ 107*f439973dSWarner Losh typedef 108*f439973dSWarner Losh EFI_STATUS 109*f439973dSWarner Losh (EFIAPI *EFI_TIMER_SET_TIMER_PERIOD)( 110*f439973dSWarner Losh IN EFI_TIMER_ARCH_PROTOCOL *This, 111*f439973dSWarner Losh IN UINT64 TimerPeriod 112*f439973dSWarner Losh ); 113*f439973dSWarner Losh 114*f439973dSWarner Losh /** 115*f439973dSWarner Losh This function retrieves the period of timer interrupts in 100 ns units, 116*f439973dSWarner Losh returns that value in TimerPeriod, and returns EFI_SUCCESS. If TimerPeriod 117*f439973dSWarner Losh is NULL, then EFI_INVALID_PARAMETER is returned. If a TimerPeriod of 0 is 118*f439973dSWarner Losh returned, then the timer is currently disabled. 119*f439973dSWarner Losh 120*f439973dSWarner Losh @param This The EFI_TIMER_ARCH_PROTOCOL instance. 121*f439973dSWarner Losh @param TimerPeriod A pointer to the timer period to retrieve in 100 ns units. If 122*f439973dSWarner Losh 0 is returned, then the timer is currently disabled. 123*f439973dSWarner Losh 124*f439973dSWarner Losh @retval EFI_SUCCESS The timer period was returned in TimerPeriod. 125*f439973dSWarner Losh @retval EFI_INVALID_PARAMETER TimerPeriod is NULL. 126*f439973dSWarner Losh 127*f439973dSWarner Losh **/ 128*f439973dSWarner Losh typedef 129*f439973dSWarner Losh EFI_STATUS 130*f439973dSWarner Losh (EFIAPI *EFI_TIMER_GET_TIMER_PERIOD)( 131*f439973dSWarner Losh IN EFI_TIMER_ARCH_PROTOCOL *This, 132*f439973dSWarner Losh OUT UINT64 *TimerPeriod 133*f439973dSWarner Losh ); 134*f439973dSWarner Losh 135*f439973dSWarner Losh /** 136*f439973dSWarner Losh This function generates a soft timer interrupt. If the platform does not support soft 137*f439973dSWarner Losh timer interrupts, then EFI_UNSUPPORTED is returned. Otherwise, EFI_SUCCESS is returned. 138*f439973dSWarner Losh If a handler has been registered through the EFI_TIMER_ARCH_PROTOCOL.RegisterHandler() 139*f439973dSWarner Losh service, then a soft timer interrupt will be generated. If the timer interrupt is 140*f439973dSWarner Losh enabled when this service is called, then the registered handler will be invoked. The 141*f439973dSWarner Losh registered handler should not be able to distinguish a hardware-generated timer 142*f439973dSWarner Losh interrupt from a software-generated timer interrupt. 143*f439973dSWarner Losh 144*f439973dSWarner Losh @param This The EFI_TIMER_ARCH_PROTOCOL instance. 145*f439973dSWarner Losh 146*f439973dSWarner Losh @retval EFI_SUCCESS The soft timer interrupt was generated. 147*f439973dSWarner Losh @retval EFI_UNSUPPORTED The platform does not support the generation of soft timer interrupts. 148*f439973dSWarner Losh 149*f439973dSWarner Losh **/ 150*f439973dSWarner Losh typedef 151*f439973dSWarner Losh EFI_STATUS 152*f439973dSWarner Losh (EFIAPI *EFI_TIMER_GENERATE_SOFT_INTERRUPT)( 153*f439973dSWarner Losh IN EFI_TIMER_ARCH_PROTOCOL *This 154*f439973dSWarner Losh ); 155*f439973dSWarner Losh 156*f439973dSWarner Losh /// 157*f439973dSWarner Losh /// This protocol provides the services to initialize a periodic timer 158*f439973dSWarner Losh /// interrupt, and to register a handler that is called each time the timer 159*f439973dSWarner Losh /// interrupt fires. It may also provide a service to adjust the rate of the 160*f439973dSWarner Losh /// periodic timer interrupt. When a timer interrupt occurs, the handler is 161*f439973dSWarner Losh /// passed the amount of time that has passed since the previous timer 162*f439973dSWarner Losh /// interrupt. 163*f439973dSWarner Losh /// 164*f439973dSWarner Losh struct _EFI_TIMER_ARCH_PROTOCOL { 165*f439973dSWarner Losh EFI_TIMER_REGISTER_HANDLER RegisterHandler; 166*f439973dSWarner Losh EFI_TIMER_SET_TIMER_PERIOD SetTimerPeriod; 167*f439973dSWarner Losh EFI_TIMER_GET_TIMER_PERIOD GetTimerPeriod; 168*f439973dSWarner Losh EFI_TIMER_GENERATE_SOFT_INTERRUPT GenerateSoftInterrupt; 169*f439973dSWarner Losh }; 170*f439973dSWarner Losh 171*f439973dSWarner Losh extern EFI_GUID gEfiTimerArchProtocolGuid; 172*f439973dSWarner Losh 173*f439973dSWarner Losh #endif 174