xref: /utopia/UTPA2-700.0.x/modules/irq/hal/curry/irq/halIRQ.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 #if defined(MSOS_TYPE_NOS) || defined(MSOS_TYPE_NUTTX)
96 
97 //-------------------------------------------------------------------------------------------------
98 //  Include Files
99 //-------------------------------------------------------------------------------------------------
100 #include "MsCommon.h"
101 #include "MsOS.h"
102 #include "halIRQTBL.h"
103 #include "regCHIP.h"
104 #include "drvIRQ.h"
105 #include "halIRQ.h"
106 #include "regIRQ.h"
107 
108 #if defined(MSOS_TYPE_NUTTX)
109 #include "debug.h"
110 #endif
111 
112 #define MST_MACRO_START     do {
113 #define MST_MACRO_END       } while (0)
114 
115 #if defined (__mips__)
116 #define mtspr(spr, value)  printf("[NIY] mtspr in line:%s %d\n",__FILE__, __LINE__);
117 #define mfspr(spr)        printf("[NIY] mfspr in line:%s %d\n",__FILE__, __LINE__);
118 
__mhal_lsbit_index(MS_U32 _value_)119 inline MS_U32 __mhal_lsbit_index(MS_U32 _value_)
120 {
121     MS_U32  index = 1;
122 
123     while((_value_&0x01) == 0x00)
124     {
125         _value_ = (_value_ >> 1);
126         index++;
127         if(index == 32)
128         {
129             index = 0;
130             break;
131         }
132     }
133 
134     return index;
135     //printf(const char * fmt, ...)("[NIY] __mhal_lsbit_index in line: %s %d\n",__FILE__, __LINE__);
136 }
137 
138 
139 #define __mhal_interrupt_disable(_old_) (_old_=_old_)
140 
141 #define __mhal_interrupt_restore(_old_) (_old_=_old_)
142 
143 #elif defined (__arm__)
144 #define mtspr(spr, value)  printf("[NIY] mtspr in line:%s %d\n",__FILE__, __LINE__);
145 #define mfspr(spr)		  printf("[NIY] mfspr in line:%s %d\n",__FILE__, __LINE__);
146 
__mhal_lsbit_index(MS_U32 _value_)147 inline MS_U32 __mhal_lsbit_index(MS_U32 _value_)
148 {
149     MS_U32  index = 1;
150 
151     while((_value_&0x01) == 0x00)
152     {
153         _value_ = (_value_ >> 1);
154         index++;
155         if(index == 32)
156         {
157             index = 0;
158             break;
159         }
160     }
161 
162     return index;
163     //printf(const char * fmt, ...)("[NIY] __mhal_lsbit_index in line: %s %d\n",__FILE__, __LINE__);
164 }
165 
166 
167 #define __mhal_interrupt_disable(_old_) (_old_=_old_)
168 
169 #define __mhal_interrupt_restore(_old_) (_old_=_old_)
170 #else
171 #define mtspr(spr, value) \
172     __asm__ __volatile__ ("l.mtspr\t\t%0,%1,0" : : "r" (spr), "r" (value))
173 
174 #define mfspr(spr) \
175     ({ \
176         unsigned long value; \
177         __asm__ __volatile__ ("l.mfspr\t\t%0,%1,0" : "=r" (value) : "r" (spr) : "memory"); \
178         value; \
179     })
180 
181 #define __mhal_lsbit_index(_value_)                                         \
182     ({                                                                      \
183     unsigned long _index_;                                                  \
184     __asm__ __volatile__ ("l.ff1\t\t%0,%1" : "=r" (_index_) : "r" (_value_));\
185     _index_;                                                                \
186     })
187 
188 
189 #define GRP_BITS                (11)
190 #define SPR_SR                  ((0 << GRP_BITS) + 17)
191 #define SPR_SR_TEE              0x00000002  // Tick timer Exception Enable
192 #define SPR_SR_IEE              0x00000004  // Interrupt Exception Enable
193 
194 #define __mhal_interrupt_disable(_old_)                                     \
195     MST_MACRO_START                                                         \
196     _old_ = mfspr(SPR_SR);                                                  \
197     mtspr(SPR_SR, (_old_) & ~(SPR_SR_IEE | SPR_SR_TEE));                    \
198     MST_MACRO_END
199 
200 #define __mhal_interrupt_restore(_old_)                                     \
201     mtspr(SPR_SR, (~(SPR_SR_IEE|SPR_SR_TEE) & mfspr(SPR_SR) ) |             \
202                   ( (SPR_SR_IEE|SPR_SR_TEE) & (_old_) ))
203 #endif
204 
205 
206 //-------------------------------------------------------------------------------------------------
207 //  Driver Compiler Options
208 //-------------------------------------------------------------------------------------------------
209 
210 
211 //-------------------------------------------------------------------------------------------------
212 //  Local Defines
213 //-------------------------------------------------------------------------------------------------
214 #define COUNTOF( array )    (sizeof(array) / sizeof((array)[0]))
215 //#define E_INTERRUPT_FIQ     E_INTERRUPT_02
216 //#define E_INTERRUPT_IRQ     E_INTERRUPT_03
217 
218 //-------------------------------------------------------------------------------------------------
219 //  Local Structures
220 //-------------------------------------------------------------------------------------------------
221 typedef void (*IRQCb)(MS_U32 u32Vector);
222 
223 //-------------------------------------------------------------------------------------------------
224 //  Global Variables
225 //-------------------------------------------------------------------------------------------------
226 
227 
228 //-------------------------------------------------------------------------------------------------
229 //  Local Variables
230 //-------------------------------------------------------------------------------------------------
231 static IRQCb irq_table[E_IRQ_FIQ_ALL] = {0};
232 // static MS_U32 _u32FIQ, _u32IRQ, _u32FIQExp, _u32IRQExp, _u32MIO_MapBase = 0;
233 static MS_U32 _u32FIQ_Msk, _u32IRQ_Msk, _u32FIQExp_Msk, _u32IRQExp_Msk;
234 
235 #if defined(MCU_AEON)
236 static MS_U32  _u32MIO_MapBase= 0xFA200000;
237 #elif defined(MCU_ARM_CA12)
238     #ifdef CONFIG_MBOOT
239         static MS_U32 _u32MIO_MapBase= 0x1f200000;
240     #else
241         static MS_U32 _u32MIO_MapBase= 0xfd200000;
242     #endif
243 #else
244 static MS_U32  _u32MIO_MapBase= 0xbf200000;
245 #endif
246 
247 static MS_BOOL _bInIRQ = FALSE;
248 static MS_BOOL _bInFIQ = FALSE;
249 
250 //-------------------------------------------------------------------------------------------------
251 //  External Functions
252 //-------------------------------------------------------------------------------------------------
253 
254 #define REG16_R(u32RegAddr) ((*((volatile MS_U16*)(_u32MIO_MapBase+ ((u32RegAddr)<< 1)))) & 0xFFFF)
255 #define REG16_W(u32RegAddr, u32Value) (*((volatile MS_U32*)(_u32MIO_MapBase+ ((u32RegAddr)<< 1))))= ((u32Value) & 0xFFFF)
256 
257 /*
258 static MS_U16 REG16_R(MS_U32 u32RegAddr_in)
259 {
260     MS_U32 u32RegAddr1 = (u32RegAddr_in << 1);
261     MS_U32 u32RegAddr = (_u32MIO_MapBase+ (u32RegAddr1));
262     MS_U16 u16RegValue = (*((volatile MS_U16*)(u32RegAddr)) & 0xFFFF);
263 
264     printf("[%s][%d] 0x%08x, 0x%08x\n", __FUNCTION__, __LINE__, u32RegAddr, u16RegValue);
265     return u16RegValue;
266 }
267 
268 static MS_U16 REG16_W(MS_U32 u32RegAddr_in, MS_U32 u32Value)
269 {
270     MS_U32 u32RegAddr1 = (u32RegAddr_in << 1);
271     MS_U32 u32RegAddr = (_u32MIO_MapBase+ (u32RegAddr1));
272     *((volatile MS_U16*)(u32RegAddr)) = ((u32Value) & 0xFFFF);
273 
274     // printf("[%s][%d] 0x%08x, 0x%08x\n", __FUNCTION__, __LINE__, u32RegAddr, u32Value);
275     // REG16_R(u32RegAddr_in);
276 }
277 */
278 
279 //-------------------------------------------------------------------------------------------------
280 //  Local Functions
281 //-------------------------------------------------------------------------------------------------
282 static void _HAL_IRQ_Enable(MS_U32 u32Vector, int enable);
283 
_IRQ_Read2Byte(MS_U32 u32RegAddr)284 static MS_U16 _IRQ_Read2Byte(MS_U32 u32RegAddr)
285 {
286     return REG16_R(u32RegAddr);
287 }
288 
_IRQ_Read4Byte(MS_U32 u32RegAddr)289 static MS_U32 _IRQ_Read4Byte(MS_U32 u32RegAddr)
290 {
291     return (_IRQ_Read2Byte(u32RegAddr) | _IRQ_Read2Byte(u32RegAddr+2) << 16);
292 }
293 
294 #if 0
295 static void _IRQ_WriteByte(MS_U32 u32RegAddr, MS_U8 u8Val)
296 {
297     if (u32RegAddr & 1)
298     {
299         REG16_W(u32RegAddr, (REG16_R(u32RegAddr) & ~(0xFF00))| (u8Val<< 8));
300     }
301     else
302     {
303         REG16_W(u32RegAddr, (REG16_R(u32RegAddr) & ~(0x00FF))| (u8Val));
304     }
305 }
306 #endif
307 
_IRQ_Write2Byte(MS_U32 u32RegAddr,MS_U16 u16Val)308 static void _IRQ_Write2Byte(MS_U32 u32RegAddr, MS_U16 u16Val)
309 {
310     REG16_W(u32RegAddr, u16Val);
311 }
312 
_IRQ_Write4Byte(MS_U32 u32RegAddr,MS_U32 u32Val)313 static void _IRQ_Write4Byte(MS_U32 u32RegAddr, MS_U32 u32Val)
314 {
315     _IRQ_Write2Byte(u32RegAddr, u32Val & 0x0000FFFF);
316     _IRQ_Write2Byte(u32RegAddr+2, u32Val >> 16);
317 }
318 
319 #if defined(MCU_ARM_CA12)
_HAL_IRQ_FIQHnd_ARM(void)320 static void _HAL_IRQ_FIQHnd_ARM(void)
321 {
322     MS_U32 status;
323     MS_U32 index;
324 
325     _bInFIQ = TRUE;
326     status = _IRQ_Read4Byte(REG_FIQ_FINAL_STATUS);
327 
328     index = __mhal_lsbit_index(status);
329     if (index)
330     {
331 
332         _IRQ_Write4Byte(REG_C_FIQ_CLR + 0, status);
333         _IRQ_Write4Byte(REG_C_FIQ_CLR + 0, 0);
334 
335         do
336         {
337             status &= ~(1 << --index);
338             index += (MS_U32)E_FIQL_START;
339             if (irq_table[index])
340             {
341                 _HAL_IRQ_Enable(index, DISABLE);
342                 irq_table[index](HWIdx2IntEnum[index]);
343             }
344             index = __mhal_lsbit_index(status);
345         } while (index);
346     }
347 
348     status = _IRQ_Read4Byte(REG_C_FIQ_EXP_FINAL_STATUS);
349 
350     index = __mhal_lsbit_index(status);
351     if (index)
352     {
353         _IRQ_Write4Byte(REG_C_FIQ_EXP_CLR, status);
354         _IRQ_Write4Byte(REG_C_FIQ_EXP_CLR, 0);
355         do {
356             status &= ~(1 << --index);
357             index += (MS_U32)E_FIQEXPL_START;
358             if (irq_table[index])
359             {
360                 _HAL_IRQ_Enable(index, DISABLE);
361                 irq_table[index](HWIdx2IntEnum[index]);
362             }
363             index = __mhal_lsbit_index(status);
364         } while (index);
365     }
366     _bInFIQ = FALSE;
367 }
368 
_HAL_IRQ_IRQHnd_ARM(void)369 static void _HAL_IRQ_IRQHnd_ARM(void)
370 {
371     MS_U32 status;
372     MS_U32 index;
373 
374     _bInIRQ = TRUE;
375     status = _IRQ_Read4Byte(REG_IRQ_FINAL_STATUS);
376     index = __mhal_lsbit_index(status);
377     if (index)
378     {
379         do {
380             status &= ~(1 << --index);
381             index += (MS_U32)E_IRQL_START;
382             if (irq_table[index])
383             {
384                 _HAL_IRQ_Enable(index, DISABLE);
385                 //fix Uart Rx interrupt can't work
386                 irq_table[index](HWIdx2IntEnum[index]);
387             }
388             index = __mhal_lsbit_index(status);
389         } while (index);
390     }
391 
392     status = _IRQ_Read4Byte(REG_C_IRQ_EXP_FINAL_STATUS);
393     index = __mhal_lsbit_index(status);
394     if (index)
395     {
396         do {
397             status &= ~(1 << --index);
398             index += (MS_U32)E_IRQEXPL_START;
399             if (irq_table[index])
400             {
401                 _HAL_IRQ_Enable(index, DISABLE);
402                 irq_table[index](HWIdx2IntEnum[index]);
403             }
404             index = __mhal_lsbit_index(status);
405         } while (index);
406     }
407     _bInIRQ = FALSE;
408 }
409 
410 #else
_HAL_IRQ_FIQHnd(MHAL_SavedRegisters * pHalReg,MS_U32 u32Vector)411 static void _HAL_IRQ_FIQHnd(MHAL_SavedRegisters *pHalReg, MS_U32 u32Vector)
412 {
413     MS_U32 status;
414     MS_U32 index;
415 
416     _bInFIQ = TRUE;
417 
418     status = _IRQ_Read4Byte(REG_FIQ_FINAL_STATUS);
419     index = __mhal_lsbit_index(status);
420     if (index)
421     {
422 
423         _IRQ_Write4Byte(REG_C_FIQ_CLR + 0, status);
424         _IRQ_Write4Byte(REG_C_FIQ_CLR + 0, 0);
425 
426         do
427         {
428             status &= ~(1 << --index);
429             index += (MS_U32)E_FIQL_START;
430             if (irq_table[index])
431             {
432                 _HAL_IRQ_Enable(index, DISABLE);
433                 irq_table[index](HWIdx2IntEnum[index]);
434             }
435             index = __mhal_lsbit_index(status);
436         } while (index);
437     }
438 
439     status = _IRQ_Read4Byte(REG_C_FIQ_EXP_FINAL_STATUS);
440 
441     index = __mhal_lsbit_index(status);
442     if (index)
443     {
444         _IRQ_Write4Byte(REG_C_FIQ_EXP_CLR, status);
445         _IRQ_Write4Byte(REG_C_FIQ_EXP_CLR, 0);
446         do {
447             status &= ~(1 << --index);
448             index += (MS_U32)E_FIQEXPL_START;
449             if (irq_table[index])
450             {
451                 _HAL_IRQ_Enable(index, DISABLE);
452                 irq_table[index](HWIdx2IntEnum[index]);
453             }
454             index = __mhal_lsbit_index(status);
455         } while (index);
456     }
457 
458     status = _IRQ_Read4Byte(REG_C_FIQ_HYP_FINAL_STATUS);
459 
460     index = __mhal_lsbit_index(status);
461     if (index)
462     {
463         _IRQ_Write4Byte(REG_C_FIQ_HYP_CLR, status);
464         _IRQ_Write4Byte(REG_C_FIQ_HYP_CLR, 0);
465         do {
466             status &= ~(1 << --index);
467             index += (MS_U32)E_FIQHYPL_START;
468             if (irq_table[index])
469             {
470                 _HAL_IRQ_Enable(index, DISABLE);
471                 irq_table[index](HWIdx2IntEnum[index]);
472             }
473             index = __mhal_lsbit_index(status);
474         } while (index);
475     }
476 
477     _bInFIQ = FALSE;
478 }
479 
_HAL_IRQ_IRQHnd(MHAL_SavedRegisters * pHalReg,MS_U32 u32Vector)480 static void _HAL_IRQ_IRQHnd(MHAL_SavedRegisters *pHalReg, MS_U32 u32Vector)
481 {
482     MS_U32 status;
483     MS_U32 index;
484 
485     _bInIRQ = TRUE;
486 
487     status = _IRQ_Read4Byte(REG_IRQ_FINAL_STATUS);
488     index = __mhal_lsbit_index(status);
489     if (index)
490     {
491         do {
492             status &= ~(1 << --index);
493             index += (MS_U32)E_IRQL_START;
494             if (irq_table[index])
495             {
496                 _HAL_IRQ_Enable(index, DISABLE);
497                 // This is for UART debug to get CPU registers temp solution.
498                 // Todo: Should modify the interface to let CPU registers
499                 //       pointer pass to Callback funtion
500                 if (HWIdx2IntEnum[index] == E_INT_IRQ_UART0)
501                 {
502                     irq_table[index]((MS_U32)pHalReg);
503                 }
504                 else
505                 {
506                     irq_table[index](HWIdx2IntEnum[index]);
507                 }
508             }
509             index = __mhal_lsbit_index(status);
510         } while (index);
511     }
512 
513     status = _IRQ_Read4Byte(REG_C_IRQ_EXP_FINAL_STATUS);
514     index = __mhal_lsbit_index(status);
515     if (index)
516     {
517         do {
518             status &= ~(1 << --index);
519             index += (MS_U32)E_IRQEXPL_START;
520             if (irq_table[index])
521             {
522                 _HAL_IRQ_Enable(index, DISABLE);
523                 if (HWIdx2IntEnum[index] == E_INT_IRQ_FRC_INT_FIQ2HST0)//frcr2_integration###
524                 {
525                     MS_U32 reg = E_IRQ_FIQ_INVALID;
526                     MS_U32 status_frc;
527 
528                     irq_table[index](HWIdx2IntEnum[index]);
529                 }
530                 else
531                 {
532                     irq_table[index](HWIdx2IntEnum[index]);
533                 }
534             }
535             index = __mhal_lsbit_index(status);
536         } while (index);
537     }
538 
539     status = _IRQ_Read4Byte(REG_C_IRQ_HYP_FINAL_STATUS);
540     index = __mhal_lsbit_index(status);
541     if (index)
542     {
543         do {
544             status &= ~(1 << --index);
545             index += (MS_U32)E_IRQHYPL_START;
546             if (irq_table[index])
547             {
548                 _HAL_IRQ_Enable(index, DISABLE);
549                 irq_table[index](HWIdx2IntEnum[index]);
550             }
551             index = __mhal_lsbit_index(status);
552         } while (index);
553     }
554 
555     _bInIRQ = FALSE;
556 }
557 #endif
558 
_HAL_IRQ_Enable(MS_U32 u32Vector,int enable)559 static void _HAL_IRQ_Enable(MS_U32 u32Vector, int enable)
560 {
561     MS_U32 reg = E_IRQ_FIQ_INVALID;
562     MS_U32 mask;
563     MS_U32 old = 0;
564 
565     if ((MS_U32)u32Vector <= COUNTOF(irq_table))
566     {
567         if ( (u32Vector >= E_IRQL_START) && (u32Vector <= E_IRQH_END) )
568         {
569             u32Vector -= E_IRQL_START;
570             reg = REG_C_IRQ_MASK;
571         }
572         else if ( (u32Vector >= E_FIQL_START) && (u32Vector <= E_FIQH_END) )
573         {
574             u32Vector -= E_FIQL_START;
575             reg = REG_C_FIQ_MASK;
576         }
577         else if ( (u32Vector >= E_IRQEXPL_START) && (u32Vector <= E_IRQEXPH_END) )
578         {
579             u32Vector -= E_IRQEXPL_START;
580             reg = REG_C_IRQ_EXP_MASK;
581         }
582         else if ( (u32Vector >= E_FIQEXPL_START) && (u32Vector <= E_FIQEXPH_END) )
583         {
584             u32Vector -= E_FIQEXPL_START;
585             reg = REG_C_FIQ_EXP_MASK;
586         }
587         else if ( (u32Vector >= E_IRQHYPL_START) && (u32Vector <= E_IRQHYPH_END) )
588         {
589             u32Vector -= E_IRQHYPL_START;
590             reg = REG_C_IRQ_HYP_MASK;
591         }
592         else if ( (u32Vector >= E_FIQHYPL_START) && (u32Vector <= E_FIQHYPH_END) )
593         {
594             u32Vector -= E_FIQHYPL_START;
595             reg = REG_C_FIQ_HYP_MASK;
596         }
597 
598         if( E_IRQ_FIQ_INVALID == reg )
599         {
600             //printf("_HAL_IRQ_Enable: unknow vector\n");
601             return;
602         }
603 
604         __mhal_interrupt_disable(old);
605         mask = _IRQ_Read4Byte(reg);
606         u32Vector = (1 << u32Vector);
607 
608         if (enable)
609             mask &= ~u32Vector;
610         else
611             mask |= u32Vector;
612 
613         _IRQ_Write4Byte(reg, mask);
614         __mhal_interrupt_restore(old);
615 
616     }
617 }
618 
619 //-------------------------------------------------------------------------------------------------
620 //  Global Functions
621 //-------------------------------------------------------------------------------------------------
HAL_IRQ_Set_IOMap(MS_U32 u32Base)622 void HAL_IRQ_Set_IOMap(MS_U32 u32Base)
623 {
624      _u32MIO_MapBase = u32Base;
625 }
626 
627 #if defined(MSOS_TYPE_NUTTX)
_HAL_IRQ_FIQHnd_Nuttx(int irq,void * context)628 int _HAL_IRQ_FIQHnd_Nuttx(int irq, void *context)
629 {
630     _HAL_IRQ_FIQHnd((MHAL_SavedRegisters *)context, irq);
631     return 1;
632 }
633 
_HAL_IRQ_IRQHnd_Nuttx(int irq,void * context)634 int _HAL_IRQ_IRQHnd_Nuttx(int irq, void *context)
635 {
636     _HAL_IRQ_IRQHnd((MHAL_SavedRegisters *)context, irq);
637     return 1;
638 }
639 #endif
640 
HAL_IRQ_Init(void)641 void HAL_IRQ_Init(void)
642 {
643     HAL_InitIrqTable();
644     #if defined(MCU_ARM_CA12)
645     MsOS_CPU_AttachInterrupt(E_INTERRUPT_FIQ, _HAL_IRQ_FIQHnd_ARM, E_INTERRUPT_FIQ);
646     MsOS_CPU_AttachInterrupt(E_INTERRUPT_IRQ, _HAL_IRQ_IRQHnd_ARM, E_INTERRUPT_IRQ);
647     #else
648     #if defined(MSOS_TYPE_NUTTX)
649         MsOS_CPU_AttachInterrupt(E_INTERRUPT_FIQ, _HAL_IRQ_FIQHnd_Nuttx, E_INTERRUPT_FIQ);
650         MsOS_CPU_AttachInterrupt(E_INTERRUPT_IRQ, _HAL_IRQ_IRQHnd_Nuttx, E_INTERRUPT_IRQ);
651         MsOS_CPU_UnMaskInterrupt(E_INTERRUPT_FIQ);
652         MsOS_CPU_UnMaskInterrupt(E_INTERRUPT_IRQ);
653     #else
654         MsOS_CPU_AttachInterrupt(E_INTERRUPT_FIQ, (mhal_isr_t) _HAL_IRQ_FIQHnd, E_INTERRUPT_FIQ);
655         MsOS_CPU_AttachInterrupt(E_INTERRUPT_IRQ, (mhal_isr_t) _HAL_IRQ_IRQHnd, E_INTERRUPT_IRQ);
656     #endif
657     #endif
658     HAL_IRQ_DetechAll();
659 }
660 
661 
HAL_IRQ_Attach(MS_U32 u32Vector,void * pIntCb,MS_U32 u32IntType)662 void HAL_IRQ_Attach(MS_U32 u32Vector, void *pIntCb , MS_U32 u32IntType )
663 {
664     MS_U32 u32VectorIndex = 0;
665 
666     u32VectorIndex = (MS_U32)IntEnum2HWIdx[u32Vector];
667 
668     if ((MS_U32)u32VectorIndex <= COUNTOF(irq_table))
669         irq_table[u32VectorIndex] = (IRQCb)pIntCb;
670     else
671         printf("%s error vector: %x\n", __FUNCTION__, (unsigned int)u32VectorIndex);
672 }
673 
HAL_IRQ_DetechAll()674 void HAL_IRQ_DetechAll()
675 {
676     MS_U16 u16Cnt= 0;
677     for (; u16Cnt <= COUNTOF(irq_table); u16Cnt++)
678         irq_table[u16Cnt] = 0;
679 }
680 
HAL_IRQ_Detech(MS_U32 u32Vector)681 void HAL_IRQ_Detech(MS_U32 u32Vector)
682 {
683     MS_U32 u32VectorIndex = 0;
684 
685     u32VectorIndex = (MS_U32)IntEnum2HWIdx[u32Vector];
686 
687     if ((MS_U32)u32VectorIndex <= COUNTOF(irq_table))
688         irq_table[u32VectorIndex] = 0;
689     else
690         printf("%s error vector: %x\n", __FUNCTION__, (unsigned int)u32Vector);
691 }
692 
HAL_IRQ_MaskAll(MS_BOOL bMask)693 void HAL_IRQ_MaskAll(MS_BOOL bMask)
694 {
695     if (bMask)
696     {
697         _u32FIQ_Msk = _IRQ_Read4Byte(REG_C_FIQ_MASK);
698         _u32IRQ_Msk = _IRQ_Read4Byte(REG_C_IRQ_MASK);
699         _u32FIQExp_Msk = _IRQ_Read4Byte(REG_C_FIQ_EXP_MASK);
700         _u32IRQExp_Msk = _IRQ_Read4Byte(REG_C_IRQ_EXP_MASK);
701         _IRQ_Write4Byte(REG_C_FIQ_MASK, 0xFFFFFFFF);
702         _IRQ_Write4Byte(REG_C_IRQ_MASK, 0xFFFFFFFF);
703         _IRQ_Write4Byte(REG_C_FIQ_EXP_MASK, 0xFFFFFFFF);
704         _IRQ_Write4Byte(REG_C_IRQ_EXP_MASK, 0xFFFFFFFF);
705     }
706     else
707     {
708         _IRQ_Write4Byte(REG_C_FIQ_MASK, 0);
709         _IRQ_Write4Byte(REG_C_IRQ_MASK, 0);
710         _IRQ_Write4Byte(REG_C_FIQ_EXP_MASK, 0);
711         _IRQ_Write4Byte(REG_C_IRQ_EXP_MASK, 0);
712     }
713 }
714 
HAL_IRQ_Restore()715 void HAL_IRQ_Restore()
716 {
717     _IRQ_Write4Byte(REG_C_FIQ_MASK, _u32FIQ_Msk);
718     _IRQ_Write4Byte(REG_C_IRQ_MASK, _u32IRQ_Msk);
719     _IRQ_Write4Byte(REG_C_FIQ_EXP_MASK, _u32FIQExp_Msk);
720     _IRQ_Write4Byte(REG_C_IRQ_EXP_MASK, _u32IRQExp_Msk);
721 }
722 
HAL_IRQ_Mask(MS_U32 u32Vector)723 void HAL_IRQ_Mask(MS_U32 u32Vector)
724 {
725     MS_U32 u32VectorIndex = 0;
726 
727     u32VectorIndex = (MS_U32)IntEnum2HWIdx[u32Vector];
728     _HAL_IRQ_Enable(u32VectorIndex, DISABLE);
729 }
730 
HAL_IRQ_UnMask(MS_U32 u32Vector)731 void HAL_IRQ_UnMask(MS_U32 u32Vector)
732 {
733     MS_U32 u32VectorIndex = 0;
734 
735     u32VectorIndex = (MS_U32)IntEnum2HWIdx[u32Vector];
736     _HAL_IRQ_Enable(u32VectorIndex, ENABLE);
737 }
738 
HAL_IRQ_NotifyCpu(IRQ_CPU_TYPE type)739 void HAL_IRQ_NotifyCpu(IRQ_CPU_TYPE type)
740 {
741     type = type;
742     printf("[%s][%d] has not implemented yet\n", __FUNCTION__, __LINE__);
743 #if 0
744     switch (type)
745     {
746         case E_IRQ_CPU0_2_CPU1:
747             _IRQ_WriteByte(REG_SEND_IRQ_FROM_CPU0, BIT(0));
748             _IRQ_WriteByte(REG_SEND_IRQ_FROM_CPU0, 0);
749             break;
750         case E_IRQ_CPU0_2_CPU2:
751             _IRQ_WriteByte(REG_SEND_IRQ_FROM_CPU0, BIT(1));
752             _IRQ_WriteByte(REG_SEND_IRQ_FROM_CPU0, 0);
753             break;
754         case E_IRQ_CPU1_2_CPU0:
755             _IRQ_WriteByte(REG_SEND_IRQ_FROM_CPU1, BIT(0));
756             _IRQ_WriteByte(REG_SEND_IRQ_FROM_CPU1, 0);
757             break;
758         case E_IRQ_CPU1_2_CPU2:
759             _IRQ_WriteByte(REG_SEND_IRQ_FROM_CPU1, BIT(1));
760             _IRQ_WriteByte(REG_SEND_IRQ_FROM_CPU1, 0);
761             break;
762         case E_IRQ_CPU2_2_CPU0:
763             _IRQ_WriteByte(REG_SEND_IRQ_FROM_CPU2, BIT(0));
764             _IRQ_WriteByte(REG_SEND_IRQ_FROM_CPU2, 0);
765             break;
766         case E_IRQ_CPU2_2_CPU1:
767             _IRQ_WriteByte(REG_SEND_IRQ_FROM_CPU2, BIT(1));
768             _IRQ_WriteByte(REG_SEND_IRQ_FROM_CPU2, 0);
769             break;
770         default:
771             break;
772     }
773 #endif
774 }
775 
HAL_IRQ_InISR()776 MS_BOOL HAL_IRQ_InISR()
777 {
778     return (_bInIRQ || _bInFIQ);
779 }
780 
781 #endif // #if defined (MSOS_TYPE_NOS)
782 
783 #if defined(MSOS_TYPE_LINUX_KERNEL)
784 #include "linux/interrupt.h"
785 #include "MsCommon.h"
786 #include "halIRQTBL.h"
787 
788 typedef struct
789 {
790     MS_BOOL         bUsed;
791     //MS_BOOL         bRunning;
792     InterruptCb     pInterruptCb;
793 } CHIP_ISR_Info;
794 
795 static CHIP_ISR_Info        _MsOS_ISR_Info[MS_IRQ_MAX];
796 
797 static irqreturn_t _HAL_IRQHandler_Wrapper(int irq, void *desc);
798 
799 //
800 //  Interrupt Service Routine
801 //
802 static                          DEFINE_SPINLOCK(_HAL_IRQ_Mutex);
803 #define IRQ_MUTEX_LOCK()        spin_lock(&_HAL_IRQ_Mutex)
804 #define IRQ_MUTEX_UNLOCK()      spin_unlock(&_HAL_IRQ_Mutex)
805 static MS_BOOL g_bISRInit = FALSE;
806 
807 //Bottom half interrupt handler define
808 #define BH_SOFTIRQ      1
809 #define BH_TASKLET      2
810 #define BH_WORKQUEUE    3
811 #define BH_THREADED     4
812 
813 #define BOTTOM_HALF     BH_THREADED
814 
CHIP_InitISR(void)815 void CHIP_InitISR(void)
816 {
817     IRQ_MUTEX_LOCK();
818     if (g_bISRInit)
819     {
820         IRQ_MUTEX_UNLOCK();
821         return;
822     }
823     g_bISRInit = TRUE;
824     HAL_InitIrqTable();
825     //_HAL_IRQ_Tlb_Init();
826     memset(_MsOS_ISR_Info, 0, MS_IRQ_MAX*sizeof(CHIP_ISR_Info));
827     IRQ_MUTEX_UNLOCK();
828 }
829 
CHIP_EnableIRQ(InterruptNum eIntNum)830 MS_BOOL CHIP_EnableIRQ(InterruptNum eIntNum)
831 {
832     MS_U16 u16VectorIndex = 0;
833     int irq;
834 
835     IRQ_MUTEX_LOCK();
836 
837     u16VectorIndex = (MS_U16)IntEnum2HWIdx[eIntNum];
838     irq = (int)u16VectorIndex + MSTAR_INT_BASE;
839 
840     if (!g_bISRInit || !_MsOS_ISR_Info[u16VectorIndex].bUsed)
841     {
842         IRQ_MUTEX_UNLOCK();
843         return FALSE;   //IRQ number was not register(Attach).
844     }
845     IRQ_MUTEX_UNLOCK();
846 
847     /* do not enable irq if already enableld */
848     if ((irq_to_desc(irq)->irq_data.state_use_accessors & IRQD_IRQ_DISABLED))
849         enable_irq(irq);
850 
851     return TRUE;
852 }
853 
CHIP_DisableIRQ(InterruptNum eIntNum)854 MS_BOOL CHIP_DisableIRQ(InterruptNum eIntNum)
855 {
856     MS_U16 u16VectorIndex = 0;
857     int irq;
858 
859     IRQ_MUTEX_LOCK();
860 
861     u16VectorIndex = (MS_U16)IntEnum2HWIdx[eIntNum];
862     irq = (int)u16VectorIndex + MSTAR_INT_BASE;
863 
864     if (!g_bISRInit || !_MsOS_ISR_Info[u16VectorIndex].bUsed)
865     {
866         IRQ_MUTEX_UNLOCK();
867         return FALSE;   //IRQ number was not register(Attach).
868     }
869     IRQ_MUTEX_UNLOCK();
870 
871     disable_irq_nosync(irq);
872     return TRUE;
873 }
874 
875 typedef struct
876 {
877     int     id;
878     bool        id_auto;
879 }platform_utopia_device;
880 
881 
882 static platform_utopia_device _devUTOPIA =
883 {
884     .id = 6,
885     .id_auto = 0,
886 };
_irq_top(int eIntNum,void * dev_id)887 static irqreturn_t _irq_top(int eIntNum, void* dev_id)
888 {
889     return IRQ_WAKE_THREAD;
890 }
891 
HAL_IRQ_Attach(MS_U32 u32Vector,void * pIntCb,MS_U32 u32IntType)892 void HAL_IRQ_Attach(MS_U32 u32Vector, void *pIntCb, MS_U32 u32IntType )
893 {
894     MS_U16 u16VectorIndex = 0;
895     int irq_flags = SA_INTERRUPT;
896     int err = 0, irq;
897 
898     IRQ_MUTEX_LOCK();
899 
900     u16VectorIndex = (MS_U16)IntEnum2HWIdx[u32Vector];
901     irq = (int)u16VectorIndex + MSTAR_INT_BASE;
902 
903     if (!g_bISRInit || _MsOS_ISR_Info[u16VectorIndex].bUsed)
904     {
905         if (!g_bISRInit)
906             printk("[Utopia2K] IRQ structure did not be initialized\n");
907         else
908             printk("[Utopia2K] IRQ %d has been registered.\n", (unsigned int)u32Vector);
909         IRQ_MUTEX_UNLOCK();
910         return;
911     }
912 
913     _MsOS_ISR_Info[u16VectorIndex].bUsed = TRUE;
914     _MsOS_ISR_Info[u16VectorIndex].pInterruptCb = (InterruptCb)pIntCb;
915 
916     IRQ_MUTEX_UNLOCK();
917 
918 #if   (BOTTOM_HALF == BH_SOFTIRQ)
919 #elif (BOTTOM_HALF == BH_TASKLET)
920 #elif (BOTTOM_HALF == BH_WORKQUEUE)
921 #elif (BOTTOM_HALF == BH_THREADED)
922 
923     if(u32IntType !=  IRQF_SHARED )
924     {
925         irq_flags |= IRQF_ONESHOT;
926 
927         err = request_threaded_irq( irq,
928                                 NULL,
929                                 _HAL_IRQHandler_Wrapper,
930                                 irq_flags,
931                                 HWIdx2IRQname[u16VectorIndex],
932                                 NULL);
933     }else
934     {
935         irq_flags = IRQF_SHARED | IRQF_ONESHOT;
936 
937         err = request_threaded_irq( irq,
938                                 _irq_top,
939                                 _HAL_IRQHandler_Wrapper,
940                                 irq_flags,
941                                 HWIdx2IRQname[u16VectorIndex],
942                                 &_devUTOPIA);
943 
944     }
945     if (0 != err)
946     {
947         printk("[Utopia2K] request_threaded_irq Fail\n");
948         return;
949     }
950 
951     if(!(irq_to_desc(irq)->irq_data.state_use_accessors & IRQD_IRQ_DISABLED))
952         disable_irq_nosync(irq);
953 #endif
954 
955     return;
956 }
957 
HAL_IRQ_Detech(MS_U32 u32Vector)958 void HAL_IRQ_Detech(MS_U32 u32Vector)
959 {
960     MS_U16 u16VectorIndex = 0;
961     int irq;
962 
963     IRQ_MUTEX_LOCK();
964     u16VectorIndex = (MS_U16)IntEnum2HWIdx[u32Vector];
965     irq = (int)u16VectorIndex + MSTAR_INT_BASE;
966 
967     if (!g_bISRInit || !_MsOS_ISR_Info[u16VectorIndex].bUsed)
968     {
969         IRQ_MUTEX_UNLOCK();
970         return;
971     }
972     IRQ_MUTEX_UNLOCK();
973 
974     free_irq(irq, NULL);
975 
976     IRQ_MUTEX_LOCK();
977     _MsOS_ISR_Info[u16VectorIndex].bUsed = FALSE;
978     _MsOS_ISR_Info[u16VectorIndex].pInterruptCb = NULL;
979     IRQ_MUTEX_UNLOCK();
980 
981     return;
982 }
983 
_HAL_IRQHandler_Wrapper(int irq,void * desc)984 static irqreturn_t _HAL_IRQHandler_Wrapper(int irq, void *desc)
985 {
986     InterruptCb pfnIntCb;
987 
988 	disable_irq_nosync(irq);
989 
990     IRQ_MUTEX_LOCK();
991     if (!_MsOS_ISR_Info[(irq-MSTAR_INT_BASE)].bUsed || !_MsOS_ISR_Info[(irq-MSTAR_INT_BASE)].pInterruptCb)
992     {
993         IRQ_MUTEX_UNLOCK();
994         return IRQ_HANDLED;
995     }
996     pfnIntCb = _MsOS_ISR_Info[(irq-MSTAR_INT_BASE)].pInterruptCb;
997     IRQ_MUTEX_UNLOCK();
998 
999     pfnIntCb(irq);
1000 
1001     return IRQ_HANDLED;
1002 }
1003 
1004 #endif
1005