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