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 #ifdef CONFIG_ENABLE_MENUCONFIG
607 #include "autoconf.h"
608 #endif
609
610 //-------------------------------------------------------------------------------------------------
611 // Driver Compiler Options
612 //-------------------------------------------------------------------------------------------------
613
614 //-------------------------------------------------------------------------------------------------
615 // Local Defines
616 //-------------------------------------------------------------------------------------------------
617 // support 8 vector inerrupts on 4KEc
618 #define CHIP_LISR_MAX 2 //vector0: IRQ, vector1: FRQ, vector5: Timer INT
619 #define MAX_NAME 30 //max thread_name_length
620 #define SEND_ACK 0 //send ack to kernel before executing registered ISR
621
622 #ifdef CONFIG_INT_SPI_MODE
623 #define CHIP_INT_BASE 32 //vector0: IRQ, vector1: FIQ, vector5: Timer INT
624 #else
625 #define CHIP_INT_BASE 128 //vector0: IRQ, vector1: FIQ, vector5: Timer INT
626 #endif
627
628 //-------------------------------------------------------------------------------------------------
629 // Local Structures
630 //-------------------------------------------------------------------------------------------------
631 struct irq_desc
632 {
633 void *driverp;
634 void (*handler)(InterruptNum eIntNum);
635 int irqfd;
636 MS_U16 u16irq;
637 };
638
639 struct pollfd
640 {
641 int fd; /* File descriptor to poll. */
642 short int events; /* Types of events poller cares about. */
643 short int revents; /* Types of events that actually occurred. */
644 };
645
646 typedef struct
647 {
648 MS_BOOL bUsed;
649 MS_BOOL bPending;
650 MS_BOOL bEnable;
651 pthread_t ithr;
652 InterruptCb pIntCb;
653 void *pThreadParam;
654
655 } CHIP_HISR_Info;
656
657 typedef unsigned long int nfds_t;
658 extern int poll (struct pollfd *__fds, nfds_t __nfds, int __timeout);
659
660 //-------------------------------------------------------------------------------------------------
661 // Local Variables
662 //-------------------------------------------------------------------------------------------------
663 static CHIP_HISR_Info _HISR_Info[MS_IRQ_MAX];
664 static MS_BOOL _bInHISR = FALSE;
665 static MS_BOOL _bInLISR = FALSE;
666 //static MS_BOOL _bEnableAll = FALSE;
667
668 //-------------------------------------------------------------------------------------------------
669 // Debug Functions
670 //-------------------------------------------------------------------------------------------------
671
672 //-------------------------------------------------------------------------------------------------
673 // Local Functions
674 //-------------------------------------------------------------------------------------------------
675
676 // -- Jerry --
677 // Leave these to be chip independent. Different chip can have the opportunities to
678 // revise the priority policy for different interrupts.
679
680 //-------------------------------------------------------------------------------------------------
681 // ISR of IRQ
682 // @param u32VectorNum \b IN: 0: IRQ 1: FIQ
683 // @param u32Data \b IN: argument 3 of cyg_interrupt_create
684 // @return ISR result
685 //-------------------------------------------------------------------------------------------------
686 /*
687 static MS_U32 _CHIP_LISR0(MS_U32 u32VectorNum, MS_U32 u32Data)
688 {
689 return FALSE;
690 }
691 */
692
693 //-------------------------------------------------------------------------------------------------
694 // ISR of FIQ
695 // @param u32VectorNum \b IN: 0: IRQ 1: FIQ
696 // @param u32Data \b IN: argument 3 of cyg_interrupt_create
697 // @return ISR result
698 // @note FIQ - handle interrupt service routine in ISR
699 //-------------------------------------------------------------------------------------------------
700 /*
701 static MS_U32 _CHIP_LISR1(MS_U32 u32VectorNum, MS_U32 u32Data)
702 {
703 return FALSE;
704 }
705 */
706
707 //-------------------------------------------------------------------------------------------------
708 // DSR of IRQ
709 // @param u32VectorNum \b IN: 0: IRQ 1: FIQ
710 // @param u32Count \b IN: # of occurrences
711 // @param u32Data \b IN: argument 3 of cyg_interrupt_create
712 // @return None
713 //-------------------------------------------------------------------------------------------------
714 /*
715 static void _CHIP_HISR0(MS_U32 u32VectorNum, MS_U32 u32Count, MS_U32 u32Data)
716 {
717 }
718
719
720 static void _CHIP_HISR1(MS_U32 u32VectorNum, MS_U32 u32Count, MS_U32 u32Data)
721 {
722 }
723 */
724
725 //-------------------------------------------------------------------------------------------------
726 // Global Functions
727 //-------------------------------------------------------------------------------------------------
728
interrupt_thread(void * arg)729 static void *interrupt_thread(void *arg)
730 {
731 struct irq_desc *ip = (struct irq_desc *)arg;
732 int fd = ip->irqfd;
733 int err;
734 struct pollfd PollFd;
735 int irq;
736 char irq_thd_name[MAX_NAME];
737
738 //naming the irq thread
739 irq = ip->u16irq + CHIP_INT_BASE;
740 memset(irq_thd_name, '\0', sizeof(irq_thd_name));
741 snprintf(irq_thd_name, MAX_NAME - 1, "IRQThread_%d", irq);
742 prctl(PR_SET_NAME, (unsigned long) irq_thd_name, NULL, NULL, NULL);
743 memset(irq_thd_name, '\0', sizeof(irq_thd_name));
744 prctl(PR_GET_NAME, (unsigned long) irq_thd_name, NULL, NULL, NULL);
745 //printf("%s\n", irq_thd_name);
746
747 PollFd.fd = fd;
748 PollFd.events = POLLIN;
749 PollFd.revents = 0;
750
751 for(;;)
752 {
753 if(!_HISR_Info[ip->u16irq].bUsed)
754 {
755 //normal exit
756 break;
757 }
758
759
760 err = poll(&PollFd, 1, 100);
761 if (err == -1)
762 {
763 if(errno==EINTR)
764 {
765 continue;
766 }
767 else
768 {
769 printf("IRQ %d ", (ip->u16irq + CHIP_INT_BASE));
770 perror("polling error!!");
771 break;
772 }
773 }
774 else if(PollFd.revents & (0x08 | 0x10 | 0x20)) //<= we can not include poll.h so use 0x08=POLLERR 0x10=POLLHUP 0x20=POLLNVAL
775 {
776 printf("IRQ %d ",(ip->u16irq + CHIP_INT_BASE));
777 perror("polling error!!");
778 break;
779 }
780
781 if(PollFd.revents & POLLIN)
782 {
783 //after successful polling, interrupt had been disable by Kernel
784 _HISR_Info[(IRQFIQNum)ip->u16irq].bEnable = FALSE;
785 #if SEND_ACK == 1
786 int enable = E_IRQ_ACK;
787 write(fd, &enable, sizeof(enable));
788 #endif
789 (void)(ip->handler)((InterruptNum) HWIdx2IntEnum[ip->u16irq]);
790 }
791
792
793 }
794
795 return NULL;
796 }
797
CHIP_EnableAllInterrupt(void)798 MS_BOOL CHIP_EnableAllInterrupt(void)
799 {
800 //_bEnableAll = TRUE;
801 return TRUE;
802 }
803
CHIP_DisableAllInterrupt(void)804 MS_BOOL CHIP_DisableAllInterrupt(void)
805 {
806 //_bEnableAll = FALSE;
807 return TRUE;
808 }
809
CHIP_ProcessIRQ(InterruptNum eIntNum,IrqDebugOpt eIrqDebugOpt)810 static MS_BOOL CHIP_ProcessIRQ(InterruptNum eIntNum, IrqDebugOpt eIrqDebugOpt)
811 {
812 int opt = eIrqDebugOpt;
813 int fd;
814 MS_U8 u8VectorIndex = 0;
815
816 u8VectorIndex = (MS_U8)IntEnum2HWIdx[eIntNum];
817
818 if (_HISR_Info[u8VectorIndex].pThreadParam)
819 {
820 fd = ((struct irq_desc *)_HISR_Info[u8VectorIndex].pThreadParam)->irqfd;
821 write(fd, &opt, sizeof(opt));
822 }
823
824 if (eIrqDebugOpt == E_IRQ_ENABLE)
825 {
826 _HISR_Info[u8VectorIndex].bEnable = TRUE ;
827 }
828 else if (eIrqDebugOpt == E_IRQ_DISABLE)
829 {
830 _HISR_Info[u8VectorIndex].bEnable = FALSE ;
831 }
832
833 return TRUE ;
834 }
835
CHIP_DebugIRQ(InterruptNum eIntNum,IrqDebugOpt eIrqDebugOpt)836 MS_BOOL CHIP_DebugIRQ(InterruptNum eIntNum, IrqDebugOpt eIrqDebugOpt)
837 {
838 return CHIP_ProcessIRQ(eIntNum, eIrqDebugOpt);
839 }
840
CHIP_EnableIRQ(InterruptNum eIntNum)841 MS_BOOL CHIP_EnableIRQ(InterruptNum eIntNum)
842 {
843 return CHIP_ProcessIRQ(eIntNum, E_IRQ_ENABLE);
844 }
845
CHIP_DisableIRQ(InterruptNum eIntNum)846 MS_BOOL CHIP_DisableIRQ(InterruptNum eIntNum)
847 {
848 return CHIP_ProcessIRQ(eIntNum, E_IRQ_DISABLE);
849 }
850
CHIP_CompleteIRQ(InterruptNum eIntNum)851 MS_BOOL CHIP_CompleteIRQ(InterruptNum eIntNum)
852 {
853 return CHIP_ProcessIRQ(eIntNum, E_IRQ_COMPLETE);
854 }
855
UTL_memset(void * d,int c,size_t n)856 void *UTL_memset(void *d, int c, size_t n)
857 {
858 MS_U8 *pu8Dst = d;
859 register MS_U32 u32Cnt = n;
860 register MS_U32 u32Val;
861 register MS_U32 *pu32Dst;
862
863 c &= 0xff;
864
865 while((MS_U32)pu8Dst & 3 && u32Cnt)
866 {
867 *pu8Dst++ = (MS_U8)c;
868 u32Cnt--;
869 }
870
871 pu32Dst = (MS_U32 *)pu8Dst;
872 u32Val = (c << 8) | c;
873 u32Val = (u32Val << 16) | u32Val;
874 while(u32Cnt >= 32)
875 {
876 pu32Dst[0]= u32Val;
877 pu32Dst[1]= u32Val;
878 pu32Dst[2]= u32Val;
879 pu32Dst[3]= u32Val;
880 pu32Dst[4]= u32Val;
881 pu32Dst[5]= u32Val;
882 pu32Dst[6]= u32Val;
883 pu32Dst[7]= u32Val;
884 pu32Dst += 8;
885 u32Cnt -= 32;
886 }
887
888 while(u32Cnt >= 4)
889 {
890 *pu32Dst++ = u32Val;
891 u32Cnt -= 4;
892 }
893
894 pu8Dst = (MS_U8 *)pu32Dst;
895 while(u32Cnt)
896 {
897 *pu8Dst++ = (MS_U8)c;
898 u32Cnt--;
899 }
900
901 return d;
902 }
903
CHIP_AttachISR(InterruptNum eIntNum,InterruptCb pIntCb)904 MS_BOOL CHIP_AttachISR(InterruptNum eIntNum, InterruptCb pIntCb)
905 {
906 int fd = 0;
907 char name[48];
908 struct irq_desc *idp;
909 pthread_attr_t attr;
910 struct sched_param schp;
911 MS_U8 u8VectorIndex = 0;
912
913 u8VectorIndex = (MS_U8)IntEnum2HWIdx[eIntNum];
914
915 idp = (struct irq_desc*) malloc(sizeof(*idp));
916 MS_ASSERT(idp != NULL);
917 snprintf(name, sizeof(name) - 1, "/proc/irq/%d/irq", (u8VectorIndex + CHIP_INT_BASE));
918 //printf("name=%s\n", name);
919
920 fd = open(name, O_RDWR | O_EXCL);
921 if (fd < 0)
922 {
923 printf("Cannot open interrupt descriptor for irq=%d ", (MS_U16)(u8VectorIndex + CHIP_INT_BASE));
924 perror("");
925 free(idp);
926 return FALSE;
927 }
928
929 idp->irqfd = fd;
930 idp->u16irq = (MS_U16)u8VectorIndex;
931 idp->driverp = &(idp->u16irq);
932 idp->handler = (pIntCb);
933
934 UTL_memset(&schp, 0, sizeof(schp));
935 schp.sched_priority = sched_get_priority_max(SCHED_FIFO);
936
937 pthread_attr_init(&attr);
938 pthread_attr_setschedpolicy(&attr, SCHED_FIFO);
939 pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
940 pthread_attr_setschedparam(&attr, &schp);
941
942 _HISR_Info[u8VectorIndex].pIntCb = pIntCb;
943 _HISR_Info[u8VectorIndex].pThreadParam = idp;
944 _HISR_Info[u8VectorIndex].bUsed = TRUE;
945 _HISR_Info[u8VectorIndex].bEnable = FALSE;
946
947 pthread_create(&_HISR_Info[u8VectorIndex].ithr, &attr, interrupt_thread, idp);
948
949 return TRUE;
950 }
951
952
CHIP_DetachISR(InterruptNum eIntNum)953 MS_BOOL CHIP_DetachISR(InterruptNum eIntNum)
954 {
955 MS_U8 u8VectorIndex = 0;
956
957 u8VectorIndex = (MS_U8)IntEnum2HWIdx[eIntNum];
958
959 if(TRUE == _HISR_Info[u8VectorIndex].bEnable)
960 {
961 CHIP_DisableIRQ(eIntNum);
962 }
963
964 _HISR_Info[u8VectorIndex].bUsed = FALSE;
965
966 if(_HISR_Info[u8VectorIndex].ithr)
967 {
968 int ret;
969
970 if((ret=pthread_join(_HISR_Info[u8VectorIndex].ithr, NULL))!=0)
971 {
972 printf("IRQ %d ", (MS_U16)(u8VectorIndex + CHIP_INT_BASE));
973 perror("polling thread destroy failed");
974 }
975 else
976 {
977 printf("IRQ %d polling thread destroyed\n", (MS_U16)(u8VectorIndex + CHIP_INT_BASE));
978
979 }
980 _HISR_Info[u8VectorIndex].ithr = 0;
981 }
982
983
984
985 if(_HISR_Info[u8VectorIndex].pThreadParam)
986 {
987 int ret;
988
989 if(-1 == ioctl(((struct irq_desc *)_HISR_Info[u8VectorIndex].pThreadParam)->irqfd, 137))
990 {
991 printf("%s.%d ioctl fail\n",__FUNCTION__, __LINE__);
992 }
993 if((ret = close(((struct irq_desc *) _HISR_Info[u8VectorIndex].pThreadParam)->irqfd)) == -1)
994 {
995 printf("IRQ %d ", (MS_U16)(u8VectorIndex + CHIP_INT_BASE));
996 perror("polling fd close failed");
997 }
998 else
999 {
1000 printf("IRQ %d polling fd closed!!\n", (MS_U16)(u8VectorIndex + CHIP_INT_BASE));
1001 }
1002 free(_HISR_Info[u8VectorIndex].pThreadParam);
1003 _HISR_Info[u8VectorIndex].pThreadParam = NULL;
1004 }
1005
1006 return TRUE;
1007 }
1008
CHIP_InISRContext(void)1009 MS_BOOL CHIP_InISRContext(void)
1010 {
1011 if (_bInLISR || _bInHISR)
1012 {
1013 return TRUE;
1014 }
1015 else
1016 {
1017 return FALSE;
1018 }
1019 }
1020
CHIP_InitISR(void)1021 void CHIP_InitISR(void)
1022 {
1023 MS_U16 i = 0;
1024
1025 HAL_InitIrqTable();
1026
1027 for(i = 0; i < MS_IRQ_MAX; i++)
1028 {
1029 _HISR_Info[i].bUsed = 0;
1030 _HISR_Info[i].bPending = 0;
1031 _HISR_Info[i].bEnable = 0;
1032 _HISR_Info[i].ithr = 0;
1033 _HISR_Info[i].pIntCb = 0;
1034 _HISR_Info[i].pThreadParam = NULL;
1035 }
1036
1037 //printf("+pthread_mutex_init\n");
1038 //pthread_mutex_init(&_HISR_Info,NULL);
1039 //printf("-CHIP_InitISR\n");
1040 }
1041
1042 #endif
1043