| /** @file | |
| Debug Agent timer lib for OMAP 35xx. | |
| Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR> | |
| 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 <Base.h> | |
| #include <Library/BaseLib.h> | |
| #include <Library/IoLib.h> | |
| #include <Library/OmapLib.h> | |
| #include <Library/ArmLib.h> | |
| #include <Library/PcdLib.h> | |
| #include <Omap3530/Omap3530.h> | |
| volatile UINT32 gVector; | |
| // Cached registers | |
| volatile UINT32 gTISR; | |
| volatile UINT32 gTCLR; | |
| volatile UINT32 gTLDR; | |
| volatile UINT32 gTCRR; | |
| volatile UINT32 gTIER; | |
| VOID | |
| EnableInterruptSource ( | |
| VOID | |
| ) | |
| { | |
| UINTN Bank; | |
| UINTN Bit; | |
| // Map vector to FIQ, IRQ is default | |
| MmioWrite32 (INTCPS_ILR (gVector), 1); | |
| Bank = gVector / 32; | |
| Bit = 1UL << (gVector % 32); | |
| MmioWrite32 (INTCPS_MIR_CLEAR(Bank), Bit); | |
| } | |
| VOID | |
| DisableInterruptSource ( | |
| VOID | |
| ) | |
| { | |
| UINTN Bank; | |
| UINTN Bit; | |
| Bank = gVector / 32; | |
| Bit = 1UL << (gVector % 32); | |
| MmioWrite32 (INTCPS_MIR_SET(Bank), Bit); | |
| } | |
| /** | |
| Setup all the hardware needed for the debug agents timer. | |
| This function is used to set up debug enviroment. It may enable interrupts. | |
| **/ | |
| VOID | |
| EFIAPI | |
| DebugAgentTimerIntialize ( | |
| VOID | |
| ) | |
| { | |
| UINT32 TimerBaseAddress; | |
| UINT32 TimerNumber; | |
| TimerNumber = PcdGet32(PcdOmap35xxDebugAgentTimer); | |
| gVector = InterruptVectorForTimer (TimerNumber); | |
| // Set up the timer registers | |
| TimerBaseAddress = TimerBase (TimerNumber); | |
| gTISR = TimerBaseAddress + GPTIMER_TISR; | |
| gTCLR = TimerBaseAddress + GPTIMER_TCLR; | |
| gTLDR = TimerBaseAddress + GPTIMER_TLDR; | |
| gTCRR = TimerBaseAddress + GPTIMER_TCRR; | |
| gTIER = TimerBaseAddress + GPTIMER_TIER; | |
| if ((TimerNumber < 2) || (TimerNumber > 9)) { | |
| // This code assumes one the General Purpose timers is used | |
| // GPT2 - GPT9 | |
| CpuDeadLoop (); | |
| } | |
| // Set source clock for GPT2 - GPT9 to SYS_CLK | |
| MmioOr32 (CM_CLKSEL_PER, 1 << (TimerNumber - 2)); | |
| } | |
| /** | |
| 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 | |
| ) | |
| { | |
| UINT64 TimerCount; | |
| INT32 LoadValue; | |
| if (TimerPeriodMilliseconds == 0) { | |
| // Turn off GPTIMER3 | |
| MmioWrite32 (gTCLR, TCLR_ST_OFF); | |
| DisableInterruptSource (); | |
| } else { | |
| // Calculate required timer count | |
| TimerCount = DivU64x32(TimerPeriodMilliseconds * 1000000, PcdGet32(PcdDebugAgentTimerFreqNanoSeconds)); | |
| // Set GPTIMER5 Load register | |
| LoadValue = (INT32) -TimerCount; | |
| MmioWrite32 (gTLDR, LoadValue); | |
| MmioWrite32 (gTCRR, LoadValue); | |
| // Enable Overflow interrupt | |
| MmioWrite32 (gTIER, TIER_TCAR_IT_DISABLE | TIER_OVF_IT_ENABLE | TIER_MAT_IT_DISABLE); | |
| // Turn on GPTIMER3, it will reload at overflow | |
| MmioWrite32 (gTCLR, TCLR_AR_AUTORELOAD | TCLR_ST_ON); | |
| EnableInterruptSource (); | |
| } | |
| } | |
| /** | |
| 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 | |
| ) | |
| { | |
| // Clear all timer interrupts | |
| MmioWrite32 (gTISR, TISR_CLEAR_ALL); | |
| // Poll interrupt status bits to ensure clearing | |
| while ((MmioRead32 (gTISR) & TISR_ALL_INTERRUPT_MASK) != TISR_NO_INTERRUPTS_PENDING); | |
| MmioWrite32 (INTCPS_CONTROL, INTCPS_CONTROL_NEWFIQAGR); | |
| ArmDataSynchronizationBarrier (); | |
| } | |