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