xref: /utopia/UTPA2-700.0.x/mxlib/hal/mainz/halCHIP.c (revision 53ee8cc121a030b8d368113ac3e966b4705770ef)
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