1 /*
2 * Copyright (c) 2016-2018, Texas Instruments Incorporated
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * * Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * * Neither the name of Texas Instruments Incorporated nor the names of
17 * its contributors may be used to endorse or promote products derived
18 * from this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32 /*
33 * ======== HwiP_tirtos.c ========
34 */
36 #include <c6x.h>
38 #include <stdint.h>
39 #include <stdbool.h>
40 #include <stdlib.h>
41 #include <string.h>
42 #include <ti/csl/csl_tsc.h>
43 #include <ti/osal/src/nonos/Nonos_config.h>
44 #include <ti/csl/tistdtypes.h>
46 /* Local structure definition */
47 typedef struct HwiP_nonOs_s {
48 bool used;
49 Hwi_Struct hwi;
50 } HwiP_nonOs;
52 /* Local hwi structures */
53 static HwiP_nonOs hwiStructs[OSAL_NONOS_CONFIGNUM_HWI];
56 /*
57 * Dummy function to check size during compile time
58 * ======== HwiP_compileTime_SizeChk ========
59 */
61 void OsalArch_compileTime_SizeChk(void)
62 {
63 #pragma diag_suppress 179
64 OSAL_COMPILE_TIME_SIZE_CHECK ((uint32_t)sizeof(HwiP_nonOs),OSAL_NONOS_HWIP_SIZE_BYTES);
65 }
67 static bool gFirstTime = (bool)false;
68 static CSL_IntcContext gContext;
69 static CSL_IntcEventHandlerRecord gEventRecord[OSAL_NONOS_CONFIGNUM_HWI];
70 static bool gTimestampFirstTime = (bool)true;
71 static bool gHwiInitialized = (bool)false;
72 /* This function enables the interrupt for a given interrupt number */
73 void OsalArch_enableInterrupt(uint32_t intNum)
74 {
75 (void)CSL_intcInterruptEnable((CSL_IntcVectId)intNum);
76 return;
77 }
79 /* This function disables the interrupt for a given interrupt number */
80 void OsalArch_disableInterrupt(uint32_t intNum)
81 {
82 (void)CSL_intcInterruptDisable((CSL_IntcVectId)intNum);
83 return;
84 }
86 /* Below function clears interrupt in the chip level */
87 void OsalArch_clearInterrupt(uint32_t intNum)
88 {
89 CSL_intcInterruptClear((CSL_IntcVectId)intNum);
90 return;
91 }
92 /* Below function globally disable interrupt in the chip level */
93 uintptr_t OsalArch_globalDisableInterrupt(void)
94 {
95 return (uintptr_t)(_disable_interrupts());
96 }
98 /* Below function globally restore interrupt in the chip level */
99 void OsalArch_globalRestoreInterrupt (uintptr_t restoreValue)
100 {
101 (void)_restore_interrupts(restoreValue);
102 }
104 /* Below function registers the interrupt for a given ISR */
105 HwiP_Handle OsalArch_HwiPCreate(int32_t interruptNum, HwiP_Fxn hwiFxn,
106 const HwiP_Params *params)
107 {
108 Hwi_Struct *hwi_handle = (Hwi_Struct *) NULL_PTR;
109 CSL_IntcParam vectId;
111 uint32_t i;
112 uintptr_t key;
114 uintptr_t temp;
115 HwiP_nonOs *hwiPool;
116 uint32_t maxHwi;
117 HwiP_Handle retHandle;
119 /* Check if user has specified any memory block to be used, which gets
120 * the precedence over the internal static memory block
121 */
122 if (gOsal_HwAttrs.extHwiPBlock.base != 0U)
123 {
124 /* pick up the external memory block configured */
125 hwiPool = (HwiP_nonOs *) gOsal_HwAttrs.extHwiPBlock.base;
126 temp = ((uintptr_t) hwiPool) + gOsal_HwAttrs.extHwiPBlock.size;
127 maxHwi = (uint32_t)(temp/(sizeof(Hwi_Struct)));
128 }
129 else
130 {
131 /* Pick up the internal static memory block */
132 hwiPool = (HwiP_nonOs *) &hwiStructs[0];
133 maxHwi = OSAL_NONOS_CONFIGNUM_HWI;
135 if(gHwiInitialized==(bool)false)
136 {
137 /* Initializing the first time */
138 (void)memset((void *)hwiStructs,0,sizeof(hwiStructs));
139 gHwiInitialized = (bool)true;
140 }
141 }
143 if (params == NULL_PTR)
144 {
145 retHandle = NULL_PTR;
146 }
147 else
148 {
150 key = OsalArch_globalDisableInterrupt();
151 for (i = 0u; i < maxHwi; i++)
152 {
153 if (hwiPool[i].used == (bool)false) {
154 hwiPool[i].used = (bool)true;
155 break;
156 }
157 }
158 OsalArch_globalRestoreInterrupt(key);
160 if (i != maxHwi)
161 {
162 hwi_handle = &(hwiPool[i].hwi);
163 retHandle = (HwiP_Handle)&hwiPool[i];
164 }
165 else
166 {
167 retHandle = NULL_PTR;
168 }
169 }
170 if (hwi_handle != NULL_PTR)
171 {
172 if (gFirstTime == (bool)false) {
173 /* record the index in the handle */
174 gContext.numEvtEntries = (Uint16)OSAL_NONOS_CONFIGNUM_HWI;
175 gContext.eventhandlerRecord = gEventRecord;
176 (void)CSL_intcInit(&gContext);
177 gFirstTime = (bool)true;
178 }
180 (void)CSL_intcGlobalNmiEnable();
181 (void)CSL_intcGlobalEnable((CSL_IntcGlobalEnableState *)NULL_PTR);
183 vectId = (CSL_IntcParam)interruptNum;
184 hwi_handle->handle = CSL_intcOpen (&hwi_handle->intcObj, (CSL_IntcEventId)params->evtId, &vectId, (CSL_Status *) NULL_PTR);
186 if(hwi_handle->handle != NULL_PTR)
187 {
188 CSL_IntcEventHandlerRecord evtHandler;
189 evtHandler.handler = (CSL_IntcEventHandler)hwiFxn;
190 evtHandler.arg = (void *) params->arg;
192 (void)CSL_intcPlugEventHandler(hwi_handle->handle, &evtHandler);
193 (void)CSL_intcHwControl(hwi_handle->handle,CSL_INTC_CMD_EVTCLEAR,NULL_PTR);
194 (void)CSL_intcHwControl(hwi_handle->handle,CSL_INTC_CMD_EVTENABLE,NULL_PTR);
196 /* Enabling the interrupt if configured */
197 if (params->enableIntr == 1U)
198 {
199 /* Enabling the interrupt in INTC. */
200 OsalArch_enableInterrupt((uint32_t)interruptNum);
201 }
202 else
203 {
204 /* Disabling the interrupt in INTC. */
205 OsalArch_disableInterrupt((uint32_t)interruptNum);
206 }
207 }
208 else
209 {
210 /* Free the pool */
211 hwiPool[i].used = (bool)false;
212 retHandle = NULL_PTR;
213 }
214 }
216 return ( (HwiP_Handle) (retHandle) ); /* _TMS320C6X */
217 }
219 HwiP_Status OsalArch_HwiPDelete(HwiP_Handle handle)
220 {
221 CSL_Status status = CSL_SOK;
222 HwiP_nonOs *hwi_hnd = (HwiP_nonOs*) handle;
223 uintptr_t key;
224 HwiP_Status ret_val;
226 /* mark that handle as free */
227 key = OsalArch_globalDisableInterrupt();
228 hwi_hnd->used = (bool)false;
229 OsalArch_globalRestoreInterrupt(key);
230 status = CSL_intcClose(hwi_hnd->hwi.handle);
232 if (status == CSL_SOK)
233 {
234 ret_val = (HwiP_OK);
235 }
236 else
237 {
238 ret_val = (HwiP_FAILURE);
239 }
240 return (ret_val);
241 }
243 /*
244 * ======== HwiP_getHandle ========
245 * Returns the HwiP handle associated with an interrupt number
246 */
247 HwiP_Handle OsalArch_getHandle(int32_t interruptNum)
248 {
249 uint32_t i;
250 Hwi_Struct *handle= (Hwi_Struct *) NULL_PTR, *handle_temp;
251 uintptr_t temp;
252 HwiP_nonOs *hwiPool;
253 uint32_t maxHwi = 0;
255 if (gOsal_HwAttrs.extHwiPBlock.base != 0U)
256 {
257 /* pick up the external memory block configured */
258 hwiPool = (HwiP_nonOs *) gOsal_HwAttrs.extHwiPBlock.base;
259 temp = ((uintptr_t) hwiPool) + gOsal_HwAttrs.extHwiPBlock.size;
260 maxHwi = (uint32_t)(temp/(sizeof(Hwi_Struct)));
261 }
262 else
263 {
264 /* Pick up the internal static memory block */
265 hwiPool = (HwiP_nonOs *) &hwiStructs[0];
266 maxHwi = OSAL_NONOS_CONFIGNUM_HWI;
267 }
269 /* Fetch it if it is already allocated, else return NULL_PTR */
270 /* Go through the list and find out if there is an HWI whose interrupt number matches */
272 /* First go through the external memory pool */
273 for (i = 0; i < maxHwi; i++)
274 {
275 if(hwiPool[i].used == (bool)true) {
276 handle_temp=&hwiPool[i].hwi;
277 if(handle_temp->intcObj.vectId==(CSL_IntcVectId)interruptNum) {
278 handle=handle_temp;
279 break;
280 }
281 }
282 }
284 /* Now check the internal static pool, if not found already */
285 if (handle != NULL_PTR)
286 {
287 for(i=0;i<OSAL_NONOS_CONFIGNUM_HWI;i++) {
288 if(hwiStructs[i].used == (bool)true) {
289 handle_temp=&hwiStructs[i].hwi;
290 if(handle_temp->intcObj.vectId==(CSL_IntcVectId)interruptNum) {
291 handle=handle_temp;
292 break;
293 }
294 }
295 }
296 }
297 return((HwiP_Handle)handle);
298 }
299 /*
300 * ======== HwiP_getEventId ========
301 * Returns the Event ID associated with an interrupt
302 */
303 int32_t OsalArch_getEventId(int32_t interruptNum)
304 {
305 Hwi_Struct *handle;
306 int32_t retVal=-1;
307 /* Find the handle registered to this interrupt number */
308 handle=(Hwi_Struct *)OsalArch_getHandle(interruptNum);
309 if(handle!=NULL_PTR) {
310 retVal = handle->intcObj.eventId;
311 }
313 return(retVal);
314 }
316 /* Return the cycle frequency used for timeStamp */
317 int32_t osalArch_TimeStampGetFreqKHz(void)
318 {
319 /* TSCH/TSCL runs at CPU speed*/
320 return (gOsal_HwAttrs.cpuFreqKHz);
321 }
323 /* Initialize the time stamp module */
324 void osalArch_TimestampInit(void)
325 {
326 if (gTimestampFirstTime == (bool)true)
327 {
328 /* Initialize TSCL to 0, for count */
329 CSL_tscEnable();
330 gTimestampFirstTime = (bool)false;
331 }
333 return;
334 }
336 /* Osal time stamp provider implementations */
337 void osalArch_TimestampGet64(TimeStamp_Struct *tStamp)
338 {
339 uintptr_t key;
340 uint64_t cycle, cycleHi;
341 uint32_t lo, hi;
343 osalArch_TimestampInit();
345 key = HwiP_disable();
346 cycle = CSL_tscRead();
347 cycleHi = ((uint64_t)(cycle >> 32U));
349 /* get the lo and hi parts */
350 lo = ((uint32_t)(cycle & ((uint32_t)(0xFFFFFFFFU))));
351 hi = ((uint32_t)(cycleHi & ((uint32_t)(0xFFFFFFFFU))));
353 tStamp->lo = lo;
354 tStamp->hi = hi;
356 /* restore */
357 HwiP_restore(key);
358 }
361 /* Nothing past this point */