xref: /utopia/UTPA2-700.0.x/mxlib/hal/mustang/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 #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