From db5c4f9e1523964ff1dd4139513d84e58d3f1d80 Mon Sep 17 00:00:00 2001 From: AJFISH Date: Fri, 8 Jan 2010 21:07:58 +0000 Subject: [PATCH] Update to support a single stack. GCC update will follow. git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@9695 6f19259b-4bc3-4df7-8a09-765794883524 --- .../InterruptDxe/HardwareInterrupt.c | 1 - BeagleBoardPkg/Sec/Arm/ModuleEntryPoint.asm | 24 --- BeagleBoardPkg/Sec/Cache.c | 2 +- BeagleBoardPkg/TimerDxe/Timer.c | 157 ++++++++++++++++++ 4 files changed, 158 insertions(+), 26 deletions(-) diff --git a/BeagleBoardPkg/InterruptDxe/HardwareInterrupt.c b/BeagleBoardPkg/InterruptDxe/HardwareInterrupt.c index 97361ffbc1..3e69515dfe 100644 --- a/BeagleBoardPkg/InterruptDxe/HardwareInterrupt.c +++ b/BeagleBoardPkg/InterruptDxe/HardwareInterrupt.c @@ -93,7 +93,6 @@ RegisterInterruptSource ( } gRegisteredInterruptHandlers[Source] = Handler; - return This->EnableInterruptSource(This, Source); } diff --git a/BeagleBoardPkg/Sec/Arm/ModuleEntryPoint.asm b/BeagleBoardPkg/Sec/Arm/ModuleEntryPoint.asm index fb30e4dd59..411e3c13ce 100755 --- a/BeagleBoardPkg/Sec/Arm/ModuleEntryPoint.asm +++ b/BeagleBoardPkg/Sec/Arm/ModuleEntryPoint.asm @@ -53,33 +53,9 @@ stack_pointer_setup LoadConstantToReg (FixedPcdGet32(PcdPrePiStackSize) ,r3) /* stack size arg3 */ add r4, r2, r3 - //Enter IRQ mode and set up IRQ stack pointer - mov r0,#0x12|0x80|0x40 - msr CPSR_c,r0 - mov r13,r4 - - //Enter Abort mode and set up Abort stack pointer - mov r0,#0x17|0x80|0x40 - msr CPSR_c,r0 - sub r4, r4, #0x400 - mov r13,r4 - - //Enter Undefined mode and set up Undefined stack pointer - mov r0,#0x1b|0x80|0x40 - msr CPSR_c,r0 - sub r4, r4, #0x400 - mov r13,r4 - //Enter SVC mode and set up SVC stack pointer mov r0,#0x13|0x80|0x40 msr CPSR_c,r0 - sub r4, r4, #0x400 - mov r13,r4 - - //Enter System mode and set up System stack pointer - mov r0,#0x1f|0x80|0x40 - msr CPSR_c,r0 - sub r4, r4, #0x400 mov r13,r4 // Call C entry point diff --git a/BeagleBoardPkg/Sec/Cache.c b/BeagleBoardPkg/Sec/Cache.c index 12bf990812..facc5deae4 100755 --- a/BeagleBoardPkg/Sec/Cache.c +++ b/BeagleBoardPkg/Sec/Cache.c @@ -82,7 +82,7 @@ InitCache ( MemoryTable[4].Length = 0; MemoryTable[4].Attributes = (ARM_MEMORY_REGION_ATTRIBUTES)0; - ArmConfigureMmu(MemoryTable, &TranslationTableBase, &TranslationTableSize); + ArmConfigureMmu (MemoryTable, &TranslationTableBase, &TranslationTableSize); BuildMemoryAllocationHob((EFI_PHYSICAL_ADDRESS)(UINTN)TranslationTableBase, TranslationTableSize, EfiBootServicesData); } diff --git a/BeagleBoardPkg/TimerDxe/Timer.c b/BeagleBoardPkg/TimerDxe/Timer.c index 32ba09c1eb..f43b24bd37 100644 --- a/BeagleBoardPkg/TimerDxe/Timer.c +++ b/BeagleBoardPkg/TimerDxe/Timer.c @@ -53,6 +53,17 @@ volatile UINT32 TIER; // Cached interrupt vector volatile UINTN gVector; + +/** + C Interrupt Handler calledin the interrupt context when Source interrupt is active. + + @param Source Source of the interrupt. Hardware routing off a specific platform defines + what source means. + @param SystemContext Pointer to system register context. Mostly used by debuggers and will + update the system context after the return from the interrupt if + modified. Don't change these values unless you know what you are doing + +**/ VOID EFIAPI TimerInterruptHandler ( @@ -60,6 +71,15 @@ TimerInterruptHandler ( IN EFI_SYSTEM_CONTEXT SystemContext ) { + EFI_TPL OriginalTPL; + + // + // DXE core uses this callback for the EFI timer tick. The DXE core uses locks + // that raise to TPL_HIGH and then restore back to current level. Thus we need + // to make sure TPL level is set to TPL_HIGH while we are handling the timer tick. + // + OriginalTPL = gBS->RaiseTPL (TPL_HIGH_LEVEL); + if (mTimerPeriodicCallback) { mTimerPeriodicCallback(SystemContext); } @@ -73,8 +93,39 @@ TimerInterruptHandler ( // Poll interrupt status bits to ensure clearing while ((MmioRead32(TISR) & TISR_ALL_INTERRUPT_MASK) != TISR_NO_INTERRUPTS_PENDING); + + gBS->RestoreTPL (OriginalTPL); } +/** + This function registers the handler NotifyFunction so it is called every time + the timer interrupt fires. It also passes the amount of time since the last + handler call to the NotifyFunction. If NotifyFunction is NULL, then the + handler is unregistered. If the handler is registered, then EFI_SUCCESS is + returned. If the CPU does not support registering a timer interrupt handler, + then EFI_UNSUPPORTED is returned. If an attempt is made to register a handler + when a handler is already registered, then EFI_ALREADY_STARTED is returned. + If an attempt is made to unregister a handler when a handler is not registered, + then EFI_INVALID_PARAMETER is returned. If an error occurs attempting to + register the NotifyFunction with the timer interrupt, then EFI_DEVICE_ERROR + is returned. + + @param This The EFI_TIMER_ARCH_PROTOCOL instance. + @param NotifyFunction The function to call when a timer interrupt fires. This + function executes at TPL_HIGH_LEVEL. The DXE Core will + register a handler for the timer interrupt, so it can know + how much time has passed. This information is used to + signal timer based events. NULL will unregister the handler. + + @retval EFI_SUCCESS The timer handler was registered. + @retval EFI_UNSUPPORTED The platform does not support timer interrupts. + @retval EFI_ALREADY_STARTED NotifyFunction is not NULL, and a handler is already + registered. + @retval EFI_INVALID_PARAMETER NotifyFunction is NULL, and a handler was not + previously registered. + @retval EFI_DEVICE_ERROR The timer handler could not be registered. + +**/ EFI_STATUS EFIAPI TimerDriverRegisterHandler ( @@ -95,6 +146,32 @@ TimerDriverRegisterHandler ( return EFI_SUCCESS; } +/** + This function adjusts the period of timer interrupts to the value specified + by TimerPeriod. If the timer period is updated, then the selected timer + period is stored in EFI_TIMER.TimerPeriod, and EFI_SUCCESS is returned. If + the timer hardware is not programmable, then EFI_UNSUPPORTED is returned. + If an error occurs while attempting to update the timer period, then the + timer hardware will be put back in its state prior to this call, and + EFI_DEVICE_ERROR is returned. If TimerPeriod is 0, then the timer interrupt + is disabled. This is not the same as disabling the CPU's interrupts. + Instead, it must either turn off the timer hardware, or it must adjust the + interrupt controller so that a CPU interrupt is not generated when the timer + interrupt fires. + + @param This The EFI_TIMER_ARCH_PROTOCOL instance. + @param TimerPeriod The rate to program the timer interrupt in 100 nS units. If + the timer hardware is not programmable, then EFI_UNSUPPORTED is + returned. If the timer is programmable, then the timer period + will be rounded up to the nearest timer period that is supported + by the timer hardware. If TimerPeriod is set to 0, then the + timer interrupts will be disabled. + + @retval EFI_SUCCESS The timer period was changed. + @retval EFI_UNSUPPORTED The platform cannot change the period of the timer interrupt. + @retval EFI_DEVICE_ERROR The timer period could not be changed due to a device error. + +**/ EFI_STATUS EFIAPI TimerDriverSetTimerPeriod ( @@ -136,6 +213,21 @@ TimerDriverSetTimerPeriod ( return Status; } + +/** + This function retrieves the period of timer interrupts in 100 ns units, + returns that value in TimerPeriod, and returns EFI_SUCCESS. If TimerPeriod + is NULL, then EFI_INVALID_PARAMETER is returned. If a TimerPeriod of 0 is + returned, then the timer is currently disabled. + + @param This The EFI_TIMER_ARCH_PROTOCOL instance. + @param TimerPeriod A pointer to the timer period to retrieve in 100 ns units. If + 0 is returned, then the timer is currently disabled. + + @retval EFI_SUCCESS The timer period was returned in TimerPeriod. + @retval EFI_INVALID_PARAMETER TimerPeriod is NULL. + +**/ EFI_STATUS EFIAPI TimerDriverGetTimerPeriod ( @@ -151,6 +243,21 @@ TimerDriverGetTimerPeriod ( return EFI_SUCCESS; } +/** + This function generates a soft timer interrupt. If the platform does not support soft + timer interrupts, then EFI_UNSUPPORTED is returned. Otherwise, EFI_SUCCESS is returned. + If a handler has been registered through the EFI_TIMER_ARCH_PROTOCOL.RegisterHandler() + service, then a soft timer interrupt will be generated. If the timer interrupt is + enabled when this service is called, then the registered handler will be invoked. The + registered handler should not be able to distinguish a hardware-generated timer + interrupt from a software-generated timer interrupt. + + @param This The EFI_TIMER_ARCH_PROTOCOL instance. + + @retval EFI_SUCCESS The soft timer interrupt was generated. + @retval EFI_UNSUPPORTED The platform does not support the generation of soft timer interrupts. + +**/ EFI_STATUS EFIAPI TimerDriverGenerateSoftInterrupt ( @@ -160,6 +267,7 @@ TimerDriverGenerateSoftInterrupt ( return EFI_UNSUPPORTED; } + EFI_STATUS EFIAPI TimerDriverRegisterPeriodicCallback ( @@ -180,6 +288,41 @@ TimerDriverRegisterPeriodicCallback ( return EFI_SUCCESS; } + +/** + Interface stucture for the Timer Architectural Protocol. + + @par Protocol Description: + This protocol provides the services to initialize a periodic timer + interrupt, and to register a handler that is called each time the timer + interrupt fires. It may also provide a service to adjust the rate of the + periodic timer interrupt. When a timer interrupt occurs, the handler is + passed the amount of time that has passed since the previous timer + interrupt. + + @param RegisterHandler + Registers a handler that will be called each time the + timer interrupt fires. TimerPeriod defines the minimum + time between timer interrupts, so TimerPeriod will also + be the minimum time between calls to the registered + handler. + + @param SetTimerPeriod + Sets the period of the timer interrupt in 100 nS units. + This function is optional, and may return EFI_UNSUPPORTED. + If this function is supported, then the timer period will + be rounded up to the nearest supported timer period. + + @param GetTimerPeriod + Retrieves the period of the timer interrupt in 100 nS units. + + @param GenerateSoftInterrupt + Generates a soft timer interrupt that simulates the firing of + the timer interrupt. This service can be used to invoke the + registered handler if the timer interrupt has been masked for + a period of time. + +**/ EFI_TIMER_ARCH_PROTOCOL gTimer = { TimerDriverRegisterHandler, TimerDriverSetTimerPeriod, @@ -191,6 +334,20 @@ TIMER_DEBUG_SUPPORT_PROTOCOL gTimerDebugSupport = { TimerDriverRegisterPeriodicCallback }; + +/** + Initialize the state information for the Timer Architectural Protocol and + the Timer Debug support protocol that allows the debugger to break into a + running program. + + @param ImageHandle of the loaded driver + @param SystemTable Pointer to the System Table + + @retval EFI_SUCCESS Protocol registered + @retval EFI_OUT_OF_RESOURCES Cannot allocate protocol data structure + @retval EFI_DEVICE_ERROR Hardware problems + +**/ EFI_STATUS EFIAPI TimerInitialize ( -- 2.39.2