1 //<MStar Software>
2 //******************************************************************************
3 // MStar Software
4 // Copyright (c) 2010 - 2012 MStar Semiconductor, Inc. All rights reserved.
5 // All software, firmware and related documentation herein ("MStar Software") are
6 // intellectual property of MStar Semiconductor, Inc. ("MStar") and protected by
7 // law, including, but not limited to, copyright law and international treaties.
8 // Any use, modification, reproduction, retransmission, or republication of all
9 // or part of MStar Software is expressly prohibited, unless prior written
10 // permission has been granted by MStar.
11 //
12 // By accessing, browsing and/or using MStar Software, you acknowledge that you
13 // have read, understood, and agree, to be bound by below terms ("Terms") and to
14 // comply with all applicable laws and regulations:
15 //
16 // 1. MStar shall retain any and all right, ownership and interest to MStar
17 // Software and any modification/derivatives thereof.
18 // No right, ownership, or interest to MStar Software and any
19 // modification/derivatives thereof is transferred to you under Terms.
20 //
21 // 2. You understand that MStar Software might include, incorporate or be
22 // supplied together with third party`s software and the use of MStar
23 // Software may require additional licenses from third parties.
24 // Therefore, you hereby agree it is your sole responsibility to separately
25 // obtain any and all third party right and license necessary for your use of
26 // such third party`s software.
27 //
28 // 3. MStar Software and any modification/derivatives thereof shall be deemed as
29 // MStar`s confidential information and you agree to keep MStar`s
30 // confidential information in strictest confidence and not disclose to any
31 // third party.
32 //
33 // 4. MStar Software is provided on an "AS IS" basis without warranties of any
34 // kind. Any warranties are hereby expressly disclaimed by MStar, including
35 // without limitation, any warranties of merchantability, non-infringement of
36 // intellectual property rights, fitness for a particular purpose, error free
37 // and in conformity with any international standard. You agree to waive any
38 // claim against MStar for any loss, damage, cost or expense that you may
39 // incur related to your use of MStar Software.
40 // In no event shall MStar be liable for any direct, indirect, incidental or
41 // consequential damages, including without limitation, lost of profit or
42 // revenues, lost or damage of data, and unauthorized system use.
43 // You agree that this Section 4 shall still apply without being affected
44 // even if MStar Software has been modified by MStar in accordance with your
45 // request or instruction for your use, except otherwise agreed by both
46 // parties in writing.
47 //
48 // 5. If requested, MStar may from time to time provide technical supports or
49 // services in relation with MStar Software to you for your use of
50 // MStar Software in conjunction with your or your customer`s product
51 // ("Services").
52 // You understand and agree that, except otherwise agreed by both parties in
53 // writing, Services are provided on an "AS IS" basis and the warranty
54 // disclaimer set forth in Section 4 above shall apply.
55 //
56 // 6. Nothing contained herein shall be construed as by implication, estoppels
57 // or otherwise:
58 // (a) conferring any license or right to use MStar name, trademark, service
59 // mark, symbol or any other identification;
60 // (b) obligating MStar or any of its affiliates to furnish any person,
61 // including without limitation, you and your customers, any assistance
62 // of any kind whatsoever, or any information; or
63 // (c) conferring any license or right under any intellectual property right.
64 //
65 // 7. These terms shall be governed by and construed in accordance with the laws
66 // of Taiwan, R.O.C., excluding its conflict of law rules.
67 // Any and all dispute arising out hereof or related hereto shall be finally
68 // settled by arbitration referred to the Chinese Arbitration Association,
69 // Taipei in accordance with the ROC Arbitration Law and the Arbitration
70 // Rules of the Association by three (3) arbitrators appointed in accordance
71 // with the said Rules.
72 // The place of arbitration shall be in Taipei, Taiwan and the language shall
73 // be English.
74 // The arbitration award shall be final and binding to both parties.
75 //
76 //******************************************************************************
77 //<MStar Software>
78
79 //-------------------------------------------------------------------------------------------------
80 // Include Files
81 //-------------------------------------------------------------------------------------------------
82
83 #if defined (MSOS_TYPE_ECOS)
84
85 #include <cyg/kernel/kapi.h>
86 #include "MsCommon.h"
87 #include "MsOS.h"
88 #include "halIRQTBL.h"
89 #include "halCHIP.h"
90 #include "regCHIP.h"
91 #include "asmCPU.h"
92
93 //-------------------------------------------------------------------------------------------------
94 // Driver Compiler Options
95 //-------------------------------------------------------------------------------------------------
96
97 //-------------------------------------------------------------------------------------------------
98 // Local Defines
99 //-------------------------------------------------------------------------------------------------
100 #define CHIP_LISR_MAX 2 //vector0: IRQ, vector1: FIQ, vector5: Timer INT
101
102 //-------------------------------------------------------------------------------------------------
103 // Local Structures
104 //-------------------------------------------------------------------------------------------------
105 //typedef void (*LISR_Entry) (MS_S32);
106 typedef struct
107 {
108 cyg_handle_t stIntr;
109 cyg_interrupt stIntrInfo;
110
111 } CHIP_LISR_Info;
112
113 typedef struct
114 {
115 MS_BOOL bUsed;
116 MS_BOOL bPending;
117 // MS_BOOL priority;
118 InterruptCb pIntCb;
119
120 } CHIP_HISR_Info;
121
122 //-------------------------------------------------------------------------------------------------
123 // Global Variables
124 //-------------------------------------------------------------------------------------------------
125
126 //-------------------------------------------------------------------------------------------------
127 // Local Variables
128 //-------------------------------------------------------------------------------------------------
129 static CHIP_LISR_Info _LISR_Info[CHIP_LISR_MAX];
130 static MS_BOOL _bInLISR = FALSE;
131
132 static CHIP_HISR_Info _HISR_Info[MS_IRQ_MAX];
133 static MS_BOOL _bInHISR = FALSE;
134
135 //-------------------------------------------------------------------------------------------------
136 // Debug Functions
137 //-------------------------------------------------------------------------------------------------
138
139 //-------------------------------------------------------------------------------------------------
140 // Local Functions
141 //-------------------------------------------------------------------------------------------------
142 MS_BOOL CHIP_DisableIRQ(InterruptNum eIntNum);
143
144 // -- Jerry --
145 // Leave these to be chip independent. Different chip can have the opportunities to
146 // revise the priority policy for different interrupts.
147
148 //-------------------------------------------------------------------------------------------------
149 // ISR of IRQ
150 // @param u32VectorNum \b IN: 0: IRQ 1: FIQ
151 // @param u32Data \b IN: argument 3 of cyg_interrupt_create
152 // @return ISR result
153 //-------------------------------------------------------------------------------------------------
_CHIP_LISR0(MS_U32 u32VectorNum,MS_U32 u32Data)154 static MS_U32 _CHIP_LISR0(MS_U32 u32VectorNum, MS_U32 u32Data)
155 {
156 MS_U32 u32Reg;
157 MS_U32 u32Bit;
158 IRQFIQNum eVector;
159 InterruptNum eIntNum;
160
161 u32Reg = 0;
162
163 //in interrupt context
164 _bInLISR = TRUE;
165
166 u32Reg = IRQ_REG(REG_IRQ_PENDING_H);
167 u32Reg <<= 16;
168 u32Reg |= IRQ_REG(REG_IRQ_PENDING_L);
169
170 while(32 != (u32Bit = MAsm_CPU_GetTrailOne(u32Reg)))
171 {
172 if(u32Bit < 16)
173 {
174 eVector = (IRQFIQNum)(u32Bit + E_IRQL_START);
175 }
176 else
177 {
178 eVector = (IRQFIQNum)(u32Bit + E_IRQH_START);
179 }
180
181 eIntNum = (InterruptNum) HWIdx2IntEnum[eVector];
182 CHIP_DisableIRQ(eIntNum);
183 if(_HISR_Info[eVector].bUsed)
184 {
185 _HISR_Info[eVector].bPending = TRUE;
186 }
187 u32Reg &= ~(0x01 << u32Bit);
188 }
189
190 u32Reg = 0;
191 u32Reg = IRQ_REG(REG_IRQEXP_PENDING_H);
192 u32Reg <<= 16;
193 u32Reg |= IRQ_REG(REG_IRQEXP_PENDING_L);
194
195 while(32 != (u32Bit = MAsm_CPU_GetTrailOne(u32Reg)))
196 {
197 if(u32Bit < 16)
198 {
199 eVector = (IRQFIQNum)(u32Bit + E_IRQEXPL_START);
200 }
201 else
202 {
203 eVector = (IRQFIQNum)(u32Bit + E_IRQEXPH_START);
204 }
205
206 eIntNum = (InterruptNum) HWIdx2IntEnum[eVector];
207 CHIP_DisableIRQ(eIntNum);
208 if(_HISR_Info[eVector].bUsed)
209 {
210 _HISR_Info[eVector].bPending = TRUE;
211 }
212 u32Reg &= ~(0x01 << u32Bit);
213 }
214
215 // Mask this interrupt until the DSR completes.
216 cyg_interrupt_mask(E_INTERRUPT_IRQ); //why mask INT0 -> cause can still be 1 ???
217
218 // Tell the processor that we have received the interrupt.
219 cyg_interrupt_acknowledge(E_INTERRUPT_IRQ);
220
221 _bInLISR = FALSE;
222
223 // Tell the kernel that the ISR processing is done and the DSR needs to be executed next.
224 return(CYG_ISR_HANDLED | CYG_ISR_CALL_DSR);
225 }
226
227 //-------------------------------------------------------------------------------------------------
228 // ISR of FIQ
229 // @param u32VectorNum \b IN: 0: IRQ 1: FIQ
230 // @param u32Data \b IN: argument 3 of cyg_interrupt_create
231 // @return ISR result
232 // @note FIQ - handle interrupt service routine in ISR
233 //-------------------------------------------------------------------------------------------------
_CHIP_LISR1(MS_U32 u32VectorNum,MS_U32 u32Data)234 static MS_U32 _CHIP_LISR1(MS_U32 u32VectorNum, MS_U32 u32Data)
235 {
236 MS_U32 u32Reg;
237 MS_U32 u32Bit;
238 IRQFIQNum eVector;
239 InterruptNum eIntNum;
240
241 //in interrupt context
242 _bInLISR = TRUE;
243
244 u32Reg = 0;
245 u32Reg = IRQ_REG(REG_FIQ_PENDING_H);
246 u32Reg <<= 16;
247 u32Reg |= IRQ_REG(REG_FIQ_PENDING_L);
248
249 while(32 != (u32Bit = MAsm_CPU_GetTrailOne(u32Reg)))
250 {
251 if(u32Bit < 16)
252 {
253 eVector = (IRQFIQNum)(u32Bit + E_FIQL_START);
254 }
255 else
256 {
257 eVector = (IRQFIQNum)(u32Bit + E_FIQH_START);
258 }
259 eIntNum = (InterruptNum) HWIdx2IntEnum[eVector];
260 CHIP_DisableIRQ(eIntNum);
261 if(_HISR_Info[eVector].bUsed)
262 {
263 _HISR_Info[eVector].bPending = TRUE;
264 }
265 u32Reg &= ~(0x01 << u32Bit);
266 }
267
268 u32Reg = 0;
269 u32Reg = IRQ_REG(REG_FIQEXP_PENDING_H);
270 u32Reg <<=16;
271 u32Reg |= IRQ_REG(REG_FIQEXP_PENDING_L);
272
273 while(32 != (u32Bit = MAsm_CPU_GetTrailOne(u32Reg)))
274 {
275 if(u32Bit<16)
276 {
277 eVector = (IRQFIQNum)(u32Bit + E_FIQEXPL_START);
278 }
279 else
280 {
281 eVector = (IRQFIQNum)(u32Bit + E_FIQEXPH_START);
282 }
283 eIntNum = (InterruptNum) HWIdx2IntEnum[eVector];
284 CHIP_DisableIRQ(eIntNum);
285 if(_HISR_Info[eVector].bUsed)
286 {
287 _HISR_Info[eVector].bPending = TRUE;
288 }
289 u32Reg &= ~(0x1 << u32Bit);
290 }
291
292 // Mask this interrupt until the ISR completes.
293 cyg_interrupt_mask(E_INTERRUPT_FIQ);
294
295 // Tell the processor that we have received the interrupt.
296 cyg_interrupt_acknowledge(E_INTERRUPT_FIQ);
297
298 _bInLISR = FALSE;
299 return(CYG_ISR_HANDLED | CYG_ISR_CALL_DSR);
300 }
301
302 //-------------------------------------------------------------------------------------------------
303 // DSR of IRQ
304 // @param u32VectorNum \b IN: 0: IRQ 1: FIQ
305 // @param u32Count \b IN: # of occurrences
306 // @param u32Data \b IN: argument 3 of cyg_interrupt_create
307 // @return None
308 //-------------------------------------------------------------------------------------------------
_CHIP_HISR0(MS_U32 u32VectorNum,MS_U32 u32Count,MS_U32 u32Data)309 static void _CHIP_HISR0(MS_U32 u32VectorNum, MS_U32 u32Count, MS_U32 u32Data)
310 {
311 InterruptNum i;
312
313 _bInHISR = TRUE; //in interrupt context
314
315 // Process all pending DSRs, then enable relative IRQ again
316 // The following SW processing flow decides the priorities from high to low
317 //for loop later
318 // IRQ H
319 for(i = (InterruptNum) E_IRQL_START; i <= (InterruptNum) E_IRQL_END; i++)
320 {
321 if (_HISR_Info[i].bPending)
322 {
323 _HISR_Info[i].bPending = FALSE;
324 _HISR_Info[i].pIntCb((InterruptNum) HWIdx2IntEnum[i]);
325 }
326 }
327 for(i = (InterruptNum) E_IRQH_START; i <= (InterruptNum) E_IRQH_END; i++)
328 {
329 if(_HISR_Info[i].bPending)
330 {
331 _HISR_Info[i].bPending = FALSE;
332 _HISR_Info[i].pIntCb((InterruptNum) HWIdx2IntEnum[i]);
333 }
334 }
335
336 for(i = (InterruptNum) E_IRQEXPL_START; i <= (InterruptNum) E_IRQEXPL_END; i++)
337 {
338 if(_HISR_Info[i].bPending)
339 {
340 _HISR_Info[i].bPending = FALSE;
341 _HISR_Info[i].pIntCb((InterruptNum) HWIdx2IntEnum[i]);
342 }
343 }
344
345 for(i = (InterruptNum) E_IRQEXPH_START; i <= (InterruptNum) E_IRQEXPH_END; i++)
346 {
347 if(_HISR_Info[i].bPending)
348 {
349 _HISR_Info[i].bPending = FALSE;
350 _HISR_Info[i].pIntCb((InterruptNum) HWIdx2IntEnum[i]);
351 }
352 }
353 _bInHISR = FALSE;
354 // Allow this interrupt to occur again.
355 cyg_interrupt_unmask(E_INTERRUPT_IRQ);
356 }
357
_CHIP_HISR1(MS_U32 u32VectorNum,MS_U32 u32Count,MS_U32 u32Data)358 static void _CHIP_HISR1(MS_U32 u32VectorNum, MS_U32 u32Count, MS_U32 u32Data)
359 {
360 InterruptNum i;
361
362 _bInHISR = TRUE; //in interrupt context
363
364
365 for(i = (InterruptNum) E_FIQL_START; i <=(InterruptNum) E_IRQL_END; i++)
366 {
367 if(_HISR_Info[i].bPending)
368 {
369 _HISR_Info[i].bPending = FALSE;
370 _HISR_Info[i].pIntCb((InterruptNum) HWIdx2IntEnum[i]);
371 }
372 }
373 for(i = (InterruptNum) E_FIQH_START; i <= (InterruptNum) E_FIQH_END; i++)
374 {
375 if(_HISR_Info[i].bPending)
376 {
377 _HISR_Info[i].bPending = FALSE;
378 _HISR_Info[i].pIntCb((InterruptNum) HWIdx2IntEnum[i]);
379 }
380 }
381
382 for(i = (InterruptNum) E_FIQEXPL_START; i <= (InterruptNum) E_FIQEXPL_END; i++)
383 {
384 if(_HISR_Info[i].bPending)
385 {
386 _HISR_Info[i].bPending = FALSE;
387 _HISR_Info[i].pIntCb((InterruptNum) HWIdx2IntEnum[i]);
388 }
389 }
390
391 for(i = (InterruptNum) E_FIQEXPH_START; i<= (InterruptNum) E_FIQEXPH_END; i++)
392 {
393 if(_HISR_Info[i].bPending)
394 {
395 _HISR_Info[i].bPending = FALSE;
396 _HISR_Info[i].pIntCb((InterruptNum) HWIdx2IntEnum[i]);
397 }
398 }
399
400 //exit interrupt context
401 _bInHISR = FALSE;
402
403 // Allow this interrupt to occur again.
404 cyg_interrupt_unmask(E_INTERRUPT_FIQ);
405 }
406
407 //-------------------------------------------------------------------------------------------------
408 // Global Functions
409 //-------------------------------------------------------------------------------------------------
410
CHIP_EnableIRQ(InterruptNum eIntNum)411 MS_BOOL CHIP_EnableIRQ(InterruptNum eIntNum)
412 {
413 MS_BOOL bRet = TRUE;
414 MS_U8 u8VectorIndex = 0;
415
416 u8VectorIndex = (MS_U8)IntEnum2HWIdx[eIntNum];
417
418 if(_HISR_Info[u8VectorIndex].bUsed)
419 {
420 if (u8VectorIndex == E_IRQ_FIQ_ALL)
421 {
422 IRQ_REG(REG_IRQ_MASK_L) &= ~0xFFFF;
423 IRQ_REG(REG_IRQ_MASK_H) &= ~0xFFFF;
424 IRQ_REG(REG_IRQEXP_MASK_L) &= ~0xFFFF;
425 IRQ_REG(REG_IRQEXP_MASK_H) &= ~0xFFFF;
426 IRQ_REG(REG_FIQ_MASK_L) &= ~0xFFFF;
427 IRQ_REG(REG_FIQ_MASK_H) &= ~0xFFFF;
428 IRQ_REG(REG_FIQEXP_MASK_L) &= ~0xFFFF;
429 IRQ_REG(REG_FIQEXP_MASK_H) &= ~0xFFFF;
430 }
431 else if(/*(u8VectorIndex >= E_IRQL_START) &&*/ (u8VectorIndex <= (MS_U8) E_IRQL_END))
432 {
433 IRQ_REG(REG_IRQ_MASK_L) &= ~(0x01 << (u8VectorIndex - E_IRQL_START));
434 }
435 else if((u8VectorIndex >= (MS_U8) E_IRQH_START) && (u8VectorIndex <= (MS_U8) E_IRQH_END))
436 {
437 IRQ_REG(REG_IRQ_MASK_H) &= ~(0x01 << (u8VectorIndex - E_IRQH_START));
438 }
439 else if((u8VectorIndex >= (MS_U8) E_IRQEXPL_START) && (u8VectorIndex <= (MS_U8) E_IRQEXPL_END))
440 {
441 IRQ_REG(REG_IRQEXP_MASK_L) &= ~(0x01 << (u8VectorIndex - E_IRQEXPL_START));
442 }
443 else if((u8VectorIndex >= (MS_U8) E_IRQEXPH_START) && (u8VectorIndex <= (MS_U8) E_IRQEXPH_END))
444 {
445 IRQ_REG(REG_IRQEXP_MASK_H) &= ~(0x01 << (u8VectorIndex - E_IRQEXPH_START));
446 }
447 else if((u8VectorIndex >= (MS_U8) E_FIQL_START) && (u8VectorIndex <= (MS_U8) E_FIQL_END))
448 {
449 IRQ_REG(REG_FIQ_MASK_L) &= ~(0x01 << (u8VectorIndex - E_FIQL_START));
450 }
451 else if((u8VectorIndex >= (MS_U8) E_FIQH_START) && (u8VectorIndex <= (MS_U8) E_FIQH_END))
452 {
453 IRQ_REG(REG_FIQ_MASK_H) &= ~(0x01 << (u8VectorIndex - E_FIQH_START));
454 }
455 else if((u8VectorIndex >= (MS_U8) E_FIQEXPL_START) && (u8VectorIndex <= (MS_U8) E_FIQEXPL_END))
456 {
457 IRQ_REG(REG_FIQEXP_MASK_L) &= ~(0x01 << (u8VectorIndex - E_FIQEXPL_START));
458 }
459 else if((u8VectorIndex >= (MS_U8) E_FIQEXPH_START) && (u8VectorIndex <= (MS_U8) E_FIQEXPH_END))
460 {
461 IRQ_REG(REG_FIQEXP_MASK_H) &= ~(0x01 << (u8VectorIndex - E_FIQEXPH_START));
462 }
463 }
464 else
465 {
466 bRet = FALSE;
467 }
468
469 return bRet;
470 }
471
CHIP_DisableIRQ(InterruptNum eIntNum)472 MS_BOOL CHIP_DisableIRQ(InterruptNum eIntNum)
473 {
474 MS_U8 u8VectorIndex = 0;
475
476 u8VectorIndex = (MS_U8)IntEnum2HWIdx[eIntNum];
477
478 if (u8VectorIndex == E_IRQ_FIQ_ALL)
479 {
480 IRQ_REG(REG_IRQ_MASK_L) |= 0xFFFF;
481 IRQ_REG(REG_IRQ_MASK_H) |= 0xFFFF;
482 IRQ_REG(REG_IRQEXP_MASK_L) |= 0xFFFF;
483 IRQ_REG(REG_IRQEXP_MASK_H) |= 0xFFFF;
484 IRQ_REG(REG_FIQ_MASK_L) |= 0xFFFF;
485 IRQ_REG(REG_FIQ_MASK_H) |= 0xFFFF;
486 IRQ_REG(REG_FIQEXP_MASK_L) |= 0xFFFF;
487 IRQ_REG(REG_FIQEXP_MASK_H) |= 0xFFFF;
488 }
489 else if(/*(u8VectorIndex >= E_IRQL_START) && */(u8VectorIndex <= (MS_U8) E_IRQL_END))
490 {
491 IRQ_REG(REG_IRQ_MASK_L) |= (0x01 << (u8VectorIndex - E_IRQL_START));
492 }
493 else if((u8VectorIndex >= (MS_U8) E_IRQH_START) && (u8VectorIndex <= (MS_U8) E_IRQH_END))
494 {
495 IRQ_REG(REG_IRQ_MASK_H) |= (0x01 << (u8VectorIndex - E_IRQH_START));
496 }
497 else if((u8VectorIndex >= (MS_U8) E_IRQEXPL_START) && (u8VectorIndex <= (MS_U8) E_IRQEXPL_END))
498 {
499 IRQ_REG(REG_IRQEXP_MASK_L) |= (0x01 << (u8VectorIndex - E_IRQEXPL_START));
500 }
501 else if((u8VectorIndex >= (MS_U8) E_IRQEXPH_START) && (u8VectorIndex <= (MS_U8) E_IRQEXPH_END))
502 {
503 IRQ_REG(REG_IRQEXP_MASK_H) |= (0x01 << (u8VectorIndex - E_IRQEXPH_START));
504 }
505 else if((u8VectorIndex >= (MS_U8) E_FIQL_START) && (u8VectorIndex <= (MS_U8) E_FIQL_END))
506 {
507 IRQ_REG(REG_FIQ_MASK_L) |= (0x01 << (u8VectorIndex - E_FIQL_START));
508 IRQ_REG(REG_FIQ_CLEAR_L) = (0x01 << (u8VectorIndex - E_FIQL_START));
509 }
510 else if((u8VectorIndex >= (MS_U8) E_FIQH_START) && (u8VectorIndex <= (MS_U8) E_FIQH_END))
511 {
512 IRQ_REG(REG_FIQ_MASK_H) |= (0x01 << (u8VectorIndex - E_FIQH_START));
513 IRQ_REG(REG_FIQ_CLEAR_H) = (0x01 << (u8VectorIndex - E_FIQH_START));
514 }
515 else if((u8VectorIndex >= (MS_U8) E_FIQEXPL_START) && (u8VectorIndex <= (MS_U8) E_FIQEXPL_END))
516 {
517 IRQ_REG(REG_FIQEXP_MASK_L) |= (0x01 << (u8VectorIndex - E_FIQEXPL_START));
518 IRQ_REG(REG_FIQEXP_CLEAR_L) = (0x01 << (u8VectorIndex - E_FIQEXPL_START));
519 }
520 else if((u8VectorIndex >= (MS_U8) E_FIQEXPH_START) && (u8VectorIndex <= (MS_U8) E_FIQEXPH_END))
521 {
522 IRQ_REG(REG_FIQEXP_MASK_H) |= (0x01 << (u8VectorIndex - E_FIQEXPH_START));
523 IRQ_REG(REG_FIQEXP_CLEAR_H) = (0x01 << (u8VectorIndex - E_FIQEXPH_START));
524 }
525 return TRUE;
526 }
527
CHIP_AttachISR(InterruptNum eIntNum,InterruptCb pIntCb)528 MS_BOOL CHIP_AttachISR(InterruptNum eIntNum, InterruptCb pIntCb)
529 {
530 MS_U8 u8VectorIndex = 0;
531
532 u8VectorIndex = (MS_U8)IntEnum2HWIdx[eIntNum];
533 _HISR_Info[u8VectorIndex].pIntCb = pIntCb;
534 _HISR_Info[u8VectorIndex].bUsed = TRUE;
535
536 return TRUE;
537 }
538
CHIP_DetachISR(InterruptNum eIntNum)539 MS_BOOL CHIP_DetachISR(InterruptNum eIntNum)
540 {
541 MS_U8 u8VectorIndex = 0;
542
543 u8VectorIndex = (MS_U8)IntEnum2HWIdx[eIntNum];
544 _HISR_Info[u8VectorIndex].bUsed = FALSE;
545
546 return TRUE;
547 }
548
CHIP_InISRContext(void)549 MS_BOOL CHIP_InISRContext(void)
550 {
551 if (_bInLISR || _bInHISR)
552 {
553 return TRUE;
554 }
555 else
556 {
557 return FALSE;
558 }
559 }
560
CHIP_InitISR(void)561 void CHIP_InitISR(void)
562 {
563 MS_U32 i = 0;
564
565 HAL_InitIrqTable();
566
567 for(i = 0; i < MS_IRQ_MAX; i++)
568 {
569 _HISR_Info[i].bUsed = FALSE;
570 _HISR_Info[i].bPending = FALSE;
571 }
572
573 // Create the interrupt (0: IRQ register ISR/DSR; 1:FIQ register ISR)
574 cyg_interrupt_create(E_INTERRUPT_IRQ, 0, 0, (cyg_ISR_t *)_CHIP_LISR0, (cyg_DSR_t *)_CHIP_HISR0, &_LISR_Info[0].stIntr, &_LISR_Info[0].stIntrInfo);
575 cyg_interrupt_create(E_INTERRUPT_FIQ, 0, 1, (cyg_ISR_t*)_CHIP_LISR1, (cyg_DSR_t *)_CHIP_HISR1, &_LISR_Info[1].stIntr, &_LISR_Info[1].stIntrInfo);
576
577 // Attach the interrupt created to the vector.
578 cyg_interrupt_attach(_LISR_Info[0].stIntr);
579 cyg_interrupt_attach(_LISR_Info[1].stIntr);
580
581 // Unmask the interrupt we just configured.
582 cyg_interrupt_unmask(E_INTERRUPT_IRQ);
583 cyg_interrupt_unmask(E_INTERRUPT_FIQ);
584 }
585 #endif
586
587 #if defined (MSOS_TYPE_LINUX)
588
589 #include <fcntl.h>
590 #include <errno.h>
591
592 #include <stdlib.h>
593 #include <unistd.h>
594 #include <pthread.h>
595 #include <signal.h>
596 #include <time.h>
597 #include <limits.h>
598 #include <memory.h>
599 #include <sys/ioctl.h>
600 #include <sys/prctl.h>
601
602 #include "MsCommon.h"
603 #include "MsOS.h"
604 #include "halIRQTBL.h"
605 #include "regCHIP.h"
606
607 //-------------------------------------------------------------------------------------------------
608 // Driver Compiler Options
609 //-------------------------------------------------------------------------------------------------
610
611 //-------------------------------------------------------------------------------------------------
612 // Local Defines
613 //-------------------------------------------------------------------------------------------------
614 // support 8 vector inerrupts on 4KEc
615 #define CHIP_LISR_MAX 2 //vector0: IRQ, vector1: FRQ, vector5: Timer INT
616 #define MAX_NAME 30 //max thread_name_length
617 #define SEND_ACK 0 //send ack to kernel before executing registered ISR
618
619 #ifdef CONFIG_INT_SPI_MODE
620 #define CHIP_INT_BASE 32 //vector0: IRQ, vector1: FIQ, vector5: Timer INT
621 #else
622 #define CHIP_INT_BASE 128 //vector0: IRQ, vector1: FIQ, vector5: Timer INT
623 #endif
624
625 //-------------------------------------------------------------------------------------------------
626 // Local Structures
627 //-------------------------------------------------------------------------------------------------
628 struct irq_desc
629 {
630 void *driverp;
631 void (*handler)(InterruptNum eIntNum);
632 int irqfd;
633 MS_U16 u16irq;
634 };
635
636 struct pollfd
637 {
638 int fd; /* File descriptor to poll. */
639 short int events; /* Types of events poller cares about. */
640 short int revents; /* Types of events that actually occurred. */
641 };
642
643 typedef struct
644 {
645 MS_BOOL bUsed;
646 MS_BOOL bPending;
647 MS_BOOL bEnable;
648 pthread_t ithr;
649 InterruptCb pIntCb;
650 void *pThreadParam;
651
652 } CHIP_HISR_Info;
653
654 typedef unsigned long int nfds_t;
655 extern int poll (struct pollfd *__fds, nfds_t __nfds, int __timeout);
656
657 //-------------------------------------------------------------------------------------------------
658 // Local Variables
659 //-------------------------------------------------------------------------------------------------
660 static CHIP_HISR_Info _HISR_Info[MS_IRQ_MAX];
661 static MS_BOOL _bInHISR = FALSE;
662 static MS_BOOL _bInLISR = FALSE;
663 //static MS_BOOL _bEnableAll = FALSE;
664
665 //-------------------------------------------------------------------------------------------------
666 // Debug Functions
667 //-------------------------------------------------------------------------------------------------
668
669 //-------------------------------------------------------------------------------------------------
670 // Local Functions
671 //-------------------------------------------------------------------------------------------------
672
673 // -- Jerry --
674 // Leave these to be chip independent. Different chip can have the opportunities to
675 // revise the priority policy for different interrupts.
676
677 //-------------------------------------------------------------------------------------------------
678 // ISR of IRQ
679 // @param u32VectorNum \b IN: 0: IRQ 1: FIQ
680 // @param u32Data \b IN: argument 3 of cyg_interrupt_create
681 // @return ISR result
682 //-------------------------------------------------------------------------------------------------
683 /*
684 static MS_U32 _CHIP_LISR0(MS_U32 u32VectorNum, MS_U32 u32Data)
685 {
686 return FALSE;
687 }
688 */
689
690 //-------------------------------------------------------------------------------------------------
691 // ISR of FIQ
692 // @param u32VectorNum \b IN: 0: IRQ 1: FIQ
693 // @param u32Data \b IN: argument 3 of cyg_interrupt_create
694 // @return ISR result
695 // @note FIQ - handle interrupt service routine in ISR
696 //-------------------------------------------------------------------------------------------------
697 /*
698 static MS_U32 _CHIP_LISR1(MS_U32 u32VectorNum, MS_U32 u32Data)
699 {
700 return FALSE;
701 }
702 */
703
704 //-------------------------------------------------------------------------------------------------
705 // DSR of IRQ
706 // @param u32VectorNum \b IN: 0: IRQ 1: FIQ
707 // @param u32Count \b IN: # of occurrences
708 // @param u32Data \b IN: argument 3 of cyg_interrupt_create
709 // @return None
710 //-------------------------------------------------------------------------------------------------
711 /*
712 static void _CHIP_HISR0(MS_U32 u32VectorNum, MS_U32 u32Count, MS_U32 u32Data)
713 {
714 }
715
716
717 static void _CHIP_HISR1(MS_U32 u32VectorNum, MS_U32 u32Count, MS_U32 u32Data)
718 {
719 }
720 */
721
722 //-------------------------------------------------------------------------------------------------
723 // Global Functions
724 //-------------------------------------------------------------------------------------------------
725
interrupt_thread(void * arg)726 static void *interrupt_thread(void *arg)
727 {
728 struct irq_desc *ip = (struct irq_desc *)arg;
729 int fd = ip->irqfd;
730 int err;
731 struct pollfd PollFd;
732 int irq;
733 char irq_thd_name[MAX_NAME];
734
735 //naming the irq thread
736 irq = ip->u16irq + CHIP_INT_BASE;
737 memset(irq_thd_name, '\0', sizeof(irq_thd_name));
738 snprintf(irq_thd_name, MAX_NAME - 1, "IRQThread_%d", irq);
739 prctl(PR_SET_NAME, (unsigned long) irq_thd_name, NULL, NULL, NULL);
740 memset(irq_thd_name, '\0', sizeof(irq_thd_name));
741 prctl(PR_GET_NAME, (unsigned long) irq_thd_name, NULL, NULL, NULL);
742 //printf("%s\n", irq_thd_name);
743
744 PollFd.fd = fd;
745 PollFd.events = POLLIN;
746 PollFd.revents = 0;
747
748 for(;;)
749 {
750 if(!_HISR_Info[ip->u16irq].bUsed)
751 {
752 //normal exit
753 break;
754 }
755
756
757 err = poll(&PollFd, 1, 100);
758 if (err == -1)
759 {
760 if(errno==EINTR)
761 {
762 continue;
763 }
764 else
765 {
766 printf("IRQ %d ", (ip->u16irq + CHIP_INT_BASE));
767 perror("polling error!!");
768 break;
769 }
770 }
771 else if(PollFd.revents & (0x08 | 0x10 | 0x20)) //<= we can not include poll.h so use 0x08=POLLERR 0x10=POLLHUP 0x20=POLLNVAL
772 {
773 printf("IRQ %d ",(ip->u16irq + CHIP_INT_BASE));
774 perror("polling error!!");
775 break;
776 }
777
778 if(PollFd.revents & POLLIN)
779 {
780 //after successful polling, interrupt had been disable by Kernel
781 _HISR_Info[(IRQFIQNum)ip->u16irq].bEnable = FALSE;
782 #if SEND_ACK == 1
783 int enable = E_IRQ_ACK;
784 write(fd, &enable, sizeof(enable));
785 #endif
786 (void)(ip->handler)((InterruptNum) HWIdx2IntEnum[ip->u16irq]);
787 }
788
789
790 }
791
792 return NULL;
793 }
794
CHIP_EnableAllInterrupt(void)795 MS_BOOL CHIP_EnableAllInterrupt(void)
796 {
797 //_bEnableAll = TRUE;
798 return TRUE;
799 }
800
CHIP_DisableAllInterrupt(void)801 MS_BOOL CHIP_DisableAllInterrupt(void)
802 {
803 //_bEnableAll = FALSE;
804 return TRUE;
805 }
806
CHIP_ProcessIRQ(InterruptNum eIntNum,IrqDebugOpt eIrqDebugOpt)807 static MS_BOOL CHIP_ProcessIRQ(InterruptNum eIntNum, IrqDebugOpt eIrqDebugOpt)
808 {
809 int opt = eIrqDebugOpt;
810 int fd;
811 MS_U8 u8VectorIndex = 0;
812
813 u8VectorIndex = (MS_U8)IntEnum2HWIdx[eIntNum];
814
815 if (_HISR_Info[u8VectorIndex].pThreadParam)
816 {
817 fd = ((struct irq_desc *)_HISR_Info[u8VectorIndex].pThreadParam)->irqfd;
818 write(fd, &opt, sizeof(opt));
819 }
820
821 if (eIrqDebugOpt == E_IRQ_ENABLE)
822 {
823 _HISR_Info[u8VectorIndex].bEnable = TRUE ;
824 }
825 else if (eIrqDebugOpt == E_IRQ_DISABLE)
826 {
827 _HISR_Info[u8VectorIndex].bEnable = FALSE ;
828 }
829
830 return TRUE ;
831 }
832
CHIP_DebugIRQ(InterruptNum eIntNum,IrqDebugOpt eIrqDebugOpt)833 MS_BOOL CHIP_DebugIRQ(InterruptNum eIntNum, IrqDebugOpt eIrqDebugOpt)
834 {
835 return CHIP_ProcessIRQ(eIntNum, eIrqDebugOpt);
836 }
837
CHIP_EnableIRQ(InterruptNum eIntNum)838 MS_BOOL CHIP_EnableIRQ(InterruptNum eIntNum)
839 {
840 return CHIP_ProcessIRQ(eIntNum, E_IRQ_ENABLE);
841 }
842
CHIP_DisableIRQ(InterruptNum eIntNum)843 MS_BOOL CHIP_DisableIRQ(InterruptNum eIntNum)
844 {
845 return CHIP_ProcessIRQ(eIntNum, E_IRQ_DISABLE);
846 }
847
CHIP_CompleteIRQ(InterruptNum eIntNum)848 MS_BOOL CHIP_CompleteIRQ(InterruptNum eIntNum)
849 {
850 return CHIP_ProcessIRQ(eIntNum, E_IRQ_COMPLETE);
851 }
852
UTL_memset(void * d,int c,size_t n)853 void *UTL_memset(void *d, int c, size_t n)
854 {
855 MS_U8 *pu8Dst = d;
856 register MS_U32 u32Cnt = n;
857 register MS_U32 u32Val;
858 register MS_U32 *pu32Dst;
859
860 c &= 0xff;
861
862 while ((MS_VIRT)pu8Dst & 3 && u32Cnt)
863 {
864 *pu8Dst++ = (MS_U8)c;
865 u32Cnt--;
866 }
867
868 pu32Dst = (MS_U32 *)pu8Dst;
869 u32Val = (c << 8) | c;
870 u32Val = (u32Val << 16) | u32Val;
871 while(u32Cnt >= 32)
872 {
873 pu32Dst[0]= u32Val;
874 pu32Dst[1]= u32Val;
875 pu32Dst[2]= u32Val;
876 pu32Dst[3]= u32Val;
877 pu32Dst[4]= u32Val;
878 pu32Dst[5]= u32Val;
879 pu32Dst[6]= u32Val;
880 pu32Dst[7]= u32Val;
881 pu32Dst += 8;
882 u32Cnt -= 32;
883 }
884
885 while(u32Cnt >= 4)
886 {
887 *pu32Dst++ = u32Val;
888 u32Cnt -= 4;
889 }
890
891 pu8Dst = (MS_U8 *)pu32Dst;
892 while(u32Cnt)
893 {
894 *pu8Dst++ = (MS_U8)c;
895 u32Cnt--;
896 }
897
898 return d;
899 }
900
CHIP_AttachISR(InterruptNum eIntNum,InterruptCb pIntCb)901 MS_BOOL CHIP_AttachISR(InterruptNum eIntNum, InterruptCb pIntCb)
902 {
903 int fd = 0;
904 char name[48];
905 struct irq_desc *idp;
906 pthread_attr_t attr;
907 struct sched_param schp;
908 MS_U8 u8VectorIndex = 0;
909
910 u8VectorIndex = (MS_U8)IntEnum2HWIdx[eIntNum];
911
912 idp = (struct irq_desc*) malloc(sizeof(*idp));
913 MS_ASSERT(idp != NULL);
914 snprintf(name, sizeof(name) - 1, "/proc/irq/%d/irq", (u8VectorIndex + CHIP_INT_BASE));
915 //printf("name=%s\n", name);
916
917 fd = open(name, O_RDWR | O_EXCL);
918 if (fd < 0)
919 {
920 printf("Cannot open interrupt descriptor for irq=%d ", (MS_U16)(u8VectorIndex + CHIP_INT_BASE));
921 perror("");
922 free(idp);
923 return FALSE;
924 }
925
926 idp->irqfd = fd;
927 idp->u16irq = (MS_U16)u8VectorIndex;
928 idp->driverp = &(idp->u16irq);
929 idp->handler = (pIntCb);
930
931 UTL_memset(&schp, 0, sizeof(schp));
932 schp.sched_priority = sched_get_priority_max(SCHED_FIFO);
933
934 pthread_attr_init(&attr);
935 pthread_attr_setschedpolicy(&attr, SCHED_FIFO);
936 pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
937 pthread_attr_setschedparam(&attr, &schp);
938
939 _HISR_Info[u8VectorIndex].pIntCb = pIntCb;
940 _HISR_Info[u8VectorIndex].pThreadParam = idp;
941 _HISR_Info[u8VectorIndex].bUsed = TRUE;
942 _HISR_Info[u8VectorIndex].bEnable = FALSE;
943
944 pthread_create(&_HISR_Info[u8VectorIndex].ithr, &attr, interrupt_thread, idp);
945
946 return TRUE;
947 }
948
949
CHIP_DetachISR(InterruptNum eIntNum)950 MS_BOOL CHIP_DetachISR(InterruptNum eIntNum)
951 {
952 MS_U8 u8VectorIndex = 0;
953
954 u8VectorIndex = (MS_U8)IntEnum2HWIdx[eIntNum];
955
956 if(TRUE == _HISR_Info[u8VectorIndex].bEnable)
957 {
958 CHIP_DisableIRQ(eIntNum);
959 }
960
961 _HISR_Info[u8VectorIndex].bUsed = FALSE;
962
963 if(_HISR_Info[u8VectorIndex].ithr)
964 {
965 int ret;
966
967 if((ret=pthread_join(_HISR_Info[u8VectorIndex].ithr, NULL))!=0)
968 {
969 printf("IRQ %d ", (MS_U16)(u8VectorIndex + CHIP_INT_BASE));
970 perror("polling thread destroy failed");
971 }
972 else
973 {
974 printf("IRQ %d polling thread destroyed\n", (MS_U16)(u8VectorIndex + CHIP_INT_BASE));
975
976 }
977 _HISR_Info[u8VectorIndex].ithr = 0;
978 }
979
980
981
982 if(_HISR_Info[u8VectorIndex].pThreadParam)
983 {
984 int ret;
985
986 if(-1 == ioctl(((struct irq_desc *)_HISR_Info[u8VectorIndex].pThreadParam)->irqfd, 137))
987 {
988 printf("%s.%d ioctl fail\n",__FUNCTION__, __LINE__);
989 }
990 if((ret = close(((struct irq_desc *) _HISR_Info[u8VectorIndex].pThreadParam)->irqfd)) == -1)
991 {
992 printf("IRQ %d ", (MS_U16)(u8VectorIndex + CHIP_INT_BASE));
993 perror("polling fd close failed");
994 }
995 else
996 {
997 printf("IRQ %d polling fd closed!!\n", (MS_U16)(u8VectorIndex + CHIP_INT_BASE));
998 }
999 free(_HISR_Info[u8VectorIndex].pThreadParam);
1000 _HISR_Info[u8VectorIndex].pThreadParam = NULL;
1001 }
1002
1003 return TRUE;
1004 }
1005
CHIP_InISRContext(void)1006 MS_BOOL CHIP_InISRContext(void)
1007 {
1008 if (_bInLISR || _bInHISR)
1009 {
1010 return TRUE;
1011 }
1012 else
1013 {
1014 return FALSE;
1015 }
1016 }
1017
CHIP_InitISR(void)1018 void CHIP_InitISR(void)
1019 {
1020 MS_U16 i = 0;
1021
1022 HAL_InitIrqTable();
1023
1024 for(i = 0; i < MS_IRQ_MAX; i++)
1025 {
1026 _HISR_Info[i].bUsed = 0;
1027 _HISR_Info[i].bPending = 0;
1028 _HISR_Info[i].bEnable = 0;
1029 _HISR_Info[i].ithr = 0;
1030 _HISR_Info[i].pIntCb = 0;
1031 _HISR_Info[i].pThreadParam = NULL;
1032 }
1033
1034 //printf("+pthread_mutex_init\n");
1035 //pthread_mutex_init(&_HISR_Info,NULL);
1036 //printf("-CHIP_InitISR\n");
1037 }
1038
1039 #endif
1040