1 /** @file 2 Debug Agent timer lib for OMAP 35xx. 3 4 Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR> 5 6 This program and the accompanying materials 7 are licensed and made available under the terms and conditions of the BSD License 8 which accompanies this distribution. The full text of the license may be found at 9 http://opensource.org/licenses/bsd-license.php 10 11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 13 14 **/ 15 #include <Base.h> 16 #include <Library/BaseLib.h> 17 #include <Library/IoLib.h> 18 #include <Library/OmapLib.h> 19 #include <Library/ArmLib.h> 20 #include <Library/PcdLib.h> 21 22 #include <Omap3530/Omap3530.h> 23 24 25 volatile UINT32 gVector; 26 27 // Cached registers 28 volatile UINT32 gTISR; 29 volatile UINT32 gTCLR; 30 volatile UINT32 gTLDR; 31 volatile UINT32 gTCRR; 32 volatile UINT32 gTIER; 33 34 VOID 35 EnableInterruptSource ( 36 VOID 37 ) 38 { 39 UINTN Bank; 40 UINTN Bit; 41 42 // Map vector to FIQ, IRQ is default 43 MmioWrite32 (INTCPS_ILR (gVector), 1); 44 45 Bank = gVector / 32; 46 Bit = 1UL << (gVector % 32); 47 48 MmioWrite32 (INTCPS_MIR_CLEAR(Bank), Bit); 49 } 50 51 VOID 52 DisableInterruptSource ( 53 VOID 54 ) 55 { 56 UINTN Bank; 57 UINTN Bit; 58 59 Bank = gVector / 32; 60 Bit = 1UL << (gVector % 32); 61 62 MmioWrite32 (INTCPS_MIR_SET(Bank), Bit); 63 } 64 65 66 67 /** 68 Setup all the hardware needed for the debug agents timer. 69 70 This function is used to set up debug enviroment. It may enable interrupts. 71 72 **/ 73 VOID 74 EFIAPI 75 DebugAgentTimerIntialize ( 76 VOID 77 ) 78 { 79 UINT32 TimerBaseAddress; 80 UINT32 TimerNumber; 81 82 TimerNumber = PcdGet32(PcdOmap35xxDebugAgentTimer); 83 gVector = InterruptVectorForTimer (TimerNumber); 84 85 // Set up the timer registers 86 TimerBaseAddress = TimerBase (TimerNumber); 87 gTISR = TimerBaseAddress + GPTIMER_TISR; 88 gTCLR = TimerBaseAddress + GPTIMER_TCLR; 89 gTLDR = TimerBaseAddress + GPTIMER_TLDR; 90 gTCRR = TimerBaseAddress + GPTIMER_TCRR; 91 gTIER = TimerBaseAddress + GPTIMER_TIER; 92 93 if ((TimerNumber < 2) || (TimerNumber > 9)) { 94 // This code assumes one the General Purpose timers is used 95 // GPT2 - GPT9 96 CpuDeadLoop (); 97 } 98 // Set source clock for GPT2 - GPT9 to SYS_CLK 99 MmioOr32 (CM_CLKSEL_PER, 1 << (TimerNumber - 2)); 100 101 } 102 103 104 /** 105 Set the period for the debug agent timer. Zero means disable the timer. 106 107 @param[in] TimerPeriodMilliseconds Frequency of the debug agent timer. 108 109 **/ 110 VOID 111 EFIAPI 112 DebugAgentTimerSetPeriod ( 113 IN UINT32 TimerPeriodMilliseconds 114 ) 115 { 116 UINT64 TimerCount; 117 INT32 LoadValue; 118 119 if (TimerPeriodMilliseconds == 0) { 120 // Turn off GPTIMER3 121 MmioWrite32 (gTCLR, TCLR_ST_OFF); 122 123 DisableInterruptSource (); 124 } else { 125 // Calculate required timer count 126 TimerCount = DivU64x32(TimerPeriodMilliseconds * 1000000, PcdGet32(PcdDebugAgentTimerFreqNanoSeconds)); 127 128 // Set GPTIMER5 Load register 129 LoadValue = (INT32) -TimerCount; 130 MmioWrite32 (gTLDR, LoadValue); 131 MmioWrite32 (gTCRR, LoadValue); 132 133 // Enable Overflow interrupt 134 MmioWrite32 (gTIER, TIER_TCAR_IT_DISABLE | TIER_OVF_IT_ENABLE | TIER_MAT_IT_DISABLE); 135 136 // Turn on GPTIMER3, it will reload at overflow 137 MmioWrite32 (gTCLR, TCLR_AR_AUTORELOAD | TCLR_ST_ON); 138 139 EnableInterruptSource (); 140 } 141 } 142 143 144 /** 145 Perform End Of Interrupt for the debug agent timer. This is called in the 146 interrupt handler after the interrupt has been processed. 147 148 **/ 149 VOID 150 EFIAPI 151 DebugAgentTimerEndOfInterrupt ( 152 VOID 153 ) 154 { 155 // Clear all timer interrupts 156 MmioWrite32 (gTISR, TISR_CLEAR_ALL); 157 158 // Poll interrupt status bits to ensure clearing 159 while ((MmioRead32 (gTISR) & TISR_ALL_INTERRUPT_MASK) != TISR_NO_INTERRUPTS_PENDING); 160 161 MmioWrite32 (INTCPS_CONTROL, INTCPS_CONTROL_NEWFIQAGR); 162 ArmDataSynchronizationBarrier (); 163 164 } 165 166