• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
3  * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without modification,
6  * are permitted provided that the following conditions are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright notice, this list of
9  *    conditions and the following disclaimer.
10  *
11  * 2. Redistributions in binary form must reproduce the above copyright notice, this list
12  *    of conditions and the following disclaimer in the documentation and/or other materials
13  *    provided with the distribution.
14  *
15  * 3. Neither the name of the copyright holder nor the names of its contributors may be used
16  *    to endorse or promote products derived from this software without specific prior written
17  *    permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
23  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
26  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
28  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
29  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  */
31 #include "los_interrupt.h"
32 #include <stdarg.h>
33 #include "securec.h"
34 #include "los_context.h"
35 #include "los_arch_interrupt.h"
36 #include "los_debug.h"
37 #include "los_hook.h"
38 #include "los_task.h"
39 #include "los_sched.h"
40 #include "los_memory.h"
41 #include "los_membox.h"
42 #if (LOSCFG_CPUP_INCLUDE_IRQ == 1)
43 #include "los_cpup.h"
44 #endif
45 #include "los_reg.h"
46 
47 #define OS_INT_IRQ_ENABLE           (1U << 0)
48 #define OS_INT_FIQ_ENABLE           (1U << 1)
49 #define OS_INT_REG_BASE             0x00802040UL
50 #define OS_INT_GLOBAL_ENABLE_ADDR   (OS_INT_REG_BASE + 4)
51 #define OS_INT_ENABLE_ADDR          (OS_INT_REG_BASE)
52 #define OS_INT_STATUS_ADDR          (OS_INT_REG_BASE + 12)
53 
54 #define OS_INSTR_SET_MASK           0x01000020U
55 #define OS_ARM_INSTR_LEN            4
56 #define OS_THUMB_INSTR_LEN          2
57 
58 UINT32 g_intCount = 0;
59 ExcInfo g_excInfo = {0};
60 
61 /* *
62  * @ingroup los_hwi
63  * hardware interrupt form mapping handling function array.
64  */
65 STATIC HWI_PROC_FUNC g_hwiForm[OS_VECTOR_CNT] = {0};
66 
67 #if (LOSCFG_DEBUG_TOOLS == 1)
68 STATIC UINT32 g_hwiFormCnt[OS_HWI_MAX_NUM] = {0};
69 STATIC CHAR *g_hwiFormName[OS_HWI_MAX_NUM] = {0};
70 
OsGetHwiFormCnt(UINT32 index)71 UINT32 OsGetHwiFormCnt(UINT32 index)
72 {
73     return g_hwiFormCnt[index];
74 }
75 
OsGetHwiFormName(UINT32 index)76 CHAR *OsGetHwiFormName(UINT32 index)
77 {
78     return g_hwiFormName[index];
79 }
80 
OsGetHwiCreated(UINT32 index)81 BOOL OsGetHwiCreated(UINT32 index)
82 {
83     if (g_hwiForm[index] != (HWI_PROC_FUNC)HalHwiDefaultHandler) {
84         return TRUE;
85     }
86 
87     return FALSE;
88 }
89 #endif
90 
91 #if (LOSCFG_PLATFORM_HWI_WITH_ARG == 1)
92 
93 typedef struct {
94     HWI_PROC_FUNC pfnHandler;
95     VOID *pParm;
96 } HWI_HANDLER_FUNC;
97 
98 /* *
99  * @ingroup los_hwi
100  * hardware interrupt handler form mapping handling function array.
101  */
102 STATIC HWI_HANDLER_FUNC g_hwiHandlerForm[OS_VECTOR_CNT] = {{ (HWI_PROC_FUNC)0, (HWI_ARG_T)0 }};
103 
104 /* *
105  * @ingroup los_hwi
106  * Set interrupt vector table.
107  */
OsSetVector(UINT32 num,HWI_PROC_FUNC vector,VOID * arg)108 VOID OsSetVector(UINT32 num, HWI_PROC_FUNC vector, VOID *arg)
109 {
110     if ((num + OS_SYS_VECTOR_CNT) < OS_VECTOR_CNT) {
111         g_hwiForm[num + OS_SYS_VECTOR_CNT] = (HWI_PROC_FUNC)HalInterrupt;
112         g_hwiHandlerForm[num + OS_SYS_VECTOR_CNT].pfnHandler = vector;
113         g_hwiHandlerForm[num + OS_SYS_VECTOR_CNT].pParm = arg;
114     }
115 }
116 
117 #else
118 /* *
119  * @ingroup los_hwi
120  * hardware interrupt handler form mapping handling function array.
121  */
122 STATIC HWI_PROC_FUNC g_hwiHandlerForm[OS_VECTOR_CNT] = {0};
123 
124 /* *
125  * @ingroup los_hwi
126  * Set interrupt vector table.
127  */
OsSetVector(UINT32 num,HWI_PROC_FUNC vector)128 VOID OsSetVector(UINT32 num, HWI_PROC_FUNC vector)
129 {
130     if ((num + OS_SYS_VECTOR_CNT) < OS_VECTOR_CNT) {
131         g_hwiForm[num + OS_SYS_VECTOR_CNT] = HalInterrupt;
132         g_hwiHandlerForm[num + OS_SYS_VECTOR_CNT] = vector;
133     }
134 }
135 #endif
136 
137 
138 /* ****************************************************************************
139  Function    : HwiNumGet
140  Description : Get an interrupt number
141  Input       : None
142  Output      : None
143  Return      : Interrupt Indexes number
144  **************************************************************************** */
HwiNumGet(VOID)145 STATIC UINT32 HwiNumGet(VOID)
146 {
147     UINT32 status;
148 
149     READ_UINT32(status, OS_INT_STATUS_ADDR);
150 
151     return (31 - CLZ(status));
152 }
153 
HwiUnmask(HWI_HANDLE_T hwiNum)154 STATIC UINT32 HwiUnmask(HWI_HANDLE_T hwiNum)
155 {
156     if (hwiNum >= OS_HWI_MAX_NUM) {
157         return OS_ERRNO_HWI_NUM_INVALID;
158     }
159 
160     *((volatile UINT32 *)OS_INT_ENABLE_ADDR) |= (1U << (hwiNum));
161 
162     return LOS_OK;
163 }
164 
HwiMask(HWI_HANDLE_T hwiNum)165 STATIC UINT32 HwiMask(HWI_HANDLE_T hwiNum)
166 {
167     if (hwiNum >= OS_HWI_MAX_NUM) {
168         return OS_ERRNO_HWI_NUM_INVALID;
169     }
170 
171     *((volatile UINT32 *)OS_INT_ENABLE_ADDR) &= ~(1U << (hwiNum));
172 
173     return LOS_OK;
174 }
175 
176 HwiControllerOps g_archHwiOps = {
177     .enableIrq      = HwiUnmask,
178     .disableIrq     = HwiMask,
179     .getCurIrqNum   = HwiNumGet,
180 };
181 
ArchIsIntActive(VOID)182 inline UINT32 ArchIsIntActive(VOID)
183 {
184     return (g_intCount > 0);
185 }
186 /* ****************************************************************************
187  Function    : HalHwiDefaultHandler
188  Description : default handler of the hardware interrupt
189  Input       : None
190  Output      : None
191  Return      : None
192  **************************************************************************** */
HalHwiDefaultHandler(VOID)193 LITE_OS_SEC_TEXT_MINOR VOID HalHwiDefaultHandler(VOID)
194 {
195     PRINT_ERR("%s irqnum:%u\n", __FUNCTION__, HwiNumGet());
196     while (1) {}
197 }
198 
HalPreInterruptHandler(UINT32 arg)199 WEAK VOID HalPreInterruptHandler(UINT32 arg)
200 {
201     (VOID)arg;
202     return;
203 }
204 
HalAftInterruptHandler(UINT32 arg)205 WEAK VOID HalAftInterruptHandler(UINT32 arg)
206 {
207     (VOID)arg;
208     return;
209 }
210 
211 /* ****************************************************************************
212  Function    : HalInterrupt
213  Description : Hardware interrupt entry function
214  Input       : None
215  Output      : None
216  Return      : None
217  **************************************************************************** */
HalInterrupt(VOID)218 LITE_OS_SEC_TEXT VOID HalInterrupt(VOID)
219 {
220     UINT32 intSave;
221     UINT32 hwiIndex;
222 
223     intSave = LOS_IntLock();
224     g_intCount++;
225     LOS_IntRestore(intSave);
226 
227 #if (LOSCFG_BASE_CORE_SCHED_SLEEP == 1)
228     OsSchedUpdateSleepTime();
229 #endif
230 
231     hwiIndex = HwiNumGet();
232 
233     OsHookCall(LOS_HOOK_TYPE_ISR_ENTER, hwiIndex);
234 #if (LOSCFG_CPUP_INCLUDE_IRQ == 1)
235     OsCpupIrqStart(hwiIndex);
236 #endif
237 
238     HalPreInterruptHandler(hwiIndex);
239 
240 #if (LOSCFG_PLATFORM_HWI_WITH_ARG == 1)
241     if (g_hwiHandlerForm[hwiIndex].pfnHandler != 0) {
242         g_hwiHandlerForm[hwiIndex].pfnHandler((VOID *)g_hwiHandlerForm[hwiIndex].pParm);
243     }
244 #else
245     if (g_hwiHandlerForm[hwiIndex] != 0) {
246         g_hwiHandlerForm[hwiIndex]();
247     }
248 #endif
249 
250 #if (LOSCFG_DEBUG_TOOLS == 1)
251     ++g_hwiFormCnt[hwiIndex];
252 #endif
253 
254     HalAftInterruptHandler(hwiIndex);
255 
256 #if (LOSCFG_CPUP_INCLUDE_IRQ == 1)
257     OsCpupIrqEnd(hwiIndex);
258 #endif
259 
260     OsHookCall(LOS_HOOK_TYPE_ISR_EXIT, hwiIndex);
261 
262     intSave = LOS_IntLock();
263     g_intCount--;
264     LOS_IntRestore(intSave);
265 }
266 
267 /* ****************************************************************************
268  Function    : ArchHwiCreate
269  Description : create hardware interrupt
270  Input       : hwiNum   --- hwi num to create
271                hwiPrio  --- priority of the hwi
272                hwiMode  --- unused
273                hwiHandler  --- hwi handler
274                irqParam --- param of the hwi handler
275  Output      : None
276  Return      : LOS_OK on success or error code on failure
277  **************************************************************************** */
ArchHwiCreate(HWI_HANDLE_T hwiNum,HWI_PRIOR_T hwiPrio,HWI_MODE_T hwiMode,HWI_PROC_FUNC hwiHandler,HwiIrqParam * irqParam)278 LITE_OS_SEC_TEXT_INIT UINT32 ArchHwiCreate(HWI_HANDLE_T hwiNum,
279                                            HWI_PRIOR_T hwiPrio,
280                                            HWI_MODE_T hwiMode,
281                                            HWI_PROC_FUNC hwiHandler,
282                                            HwiIrqParam *irqParam)
283 {
284     (VOID)hwiMode;
285     UINT32 intSave;
286 
287     if (hwiHandler == NULL) {
288         return OS_ERRNO_HWI_PROC_FUNC_NULL;
289     }
290 
291     if (hwiNum >= OS_HWI_MAX_NUM) {
292         return OS_ERRNO_HWI_NUM_INVALID;
293     }
294 
295     if (g_hwiForm[hwiNum + OS_SYS_VECTOR_CNT] != (HWI_PROC_FUNC)HalHwiDefaultHandler) {
296         return OS_ERRNO_HWI_ALREADY_CREATED;
297     }
298 
299     intSave = LOS_IntLock();
300 #if (LOSCFG_PLATFORM_HWI_WITH_ARG == 1)
301     if (irqParam != NULL) {
302         OsSetVector(hwiNum, hwiHandler, irqParam->pDevId);
303     } else {
304         OsSetVector(hwiNum, hwiHandler, NULL);
305     }
306 #else
307     (VOID)irqParam;
308     OsSetVector(hwiNum, hwiHandler);
309 #endif
310 #if (LOSCFG_DEBUG_TOOLS == 1)
311     if ((irqParam != NULL) && (irqParam->pName != NULL)) {
312         g_hwiFormName[hwiNum + OS_SYS_VECTOR_CNT] = (CHAR *)irqParam->pName;
313     }
314     g_hwiFormCnt[hwiNum + OS_SYS_VECTOR_CNT] = 0;
315 #endif
316     HwiUnmask(hwiNum);
317     LOS_IntRestore(intSave);
318 
319     return LOS_OK;
320 }
321 
322 /* ****************************************************************************
323  Function    : ArchHwiDelete
324  Description : Delete hardware interrupt
325  Input       : hwiNum   --- hwi num to delete
326                irqParam --- param of the hwi handler
327  Output      : None
328  Return      : LOS_OK on success or error code on failure
329  **************************************************************************** */
ArchHwiDelete(HWI_HANDLE_T hwiNum,HwiIrqParam * irqParam)330 LITE_OS_SEC_TEXT_INIT UINT32 ArchHwiDelete(HWI_HANDLE_T hwiNum, HwiIrqParam *irqParam)
331 {
332     (VOID)irqParam;
333     UINT32 intSave;
334 
335     if (hwiNum >= OS_HWI_MAX_NUM) {
336         return OS_ERRNO_HWI_NUM_INVALID;
337     }
338 
339     HwiMask(hwiNum);
340 
341     intSave = LOS_IntLock();
342     g_hwiForm[hwiNum + OS_SYS_VECTOR_CNT] = (HWI_PROC_FUNC)HalHwiDefaultHandler;
343     LOS_IntRestore(intSave);
344 
345     return LOS_OK;
346 }
347 
348 #if (LOSCFG_KERNEL_PRINTF != 0)
OsExcTypeInfo(const ExcInfo * excInfo)349 STATIC VOID OsExcTypeInfo(const ExcInfo *excInfo)
350 {
351     CHAR *phaseStr[] = {"exc in init", "exc in task", "exc in hwi"};
352 
353     PRINTK("Type      = %d\n", excInfo->type);
354     PRINTK("ThrdPid   = %d\n", excInfo->thrdPid);
355     PRINTK("Phase     = %s\n", phaseStr[excInfo->phase]);
356     PRINTK("FaultAddr = 0x%x\n", excInfo->faultAddr);
357 }
358 
OsExcCurTaskInfo(const ExcInfo * excInfo)359 STATIC VOID OsExcCurTaskInfo(const ExcInfo *excInfo)
360 {
361     PRINTK("Current task info:\n");
362     if (excInfo->phase == OS_EXC_IN_TASK) {
363         LosTaskCB *taskCB = OS_TCB_FROM_TID(LOS_CurTaskIDGet());
364         PRINTK("Task name = %s\n", taskCB->taskName);
365         PRINTK("Task ID   = %d\n", taskCB->taskID);
366         PRINTK("Task SP   = 0x%x\n", taskCB->stackPointer);
367         PRINTK("Task ST   = 0x%x\n", taskCB->topOfStack);
368         PRINTK("Task SS   = 0x%x\n", taskCB->stackSize);
369     } else if (excInfo->phase == OS_EXC_IN_HWI) {
370         PRINTK("Exception occur in interrupt phase!\n");
371     } else {
372         PRINTK("Exception occur in system init phase!\n");
373     }
374 }
375 
OsExcRegInfo(const ExcInfo * excInfo)376 STATIC VOID OsExcRegInfo(const ExcInfo *excInfo)
377 {
378     PRINTK("Exception reg dump:\n");
379     PRINTK("PC        = 0x%x\n", excInfo->context->pc);
380     PRINTK("LR        = 0x%x\n", excInfo->context->lr);
381     PRINTK("R0        = 0x%x\n", excInfo->context->r0);
382     PRINTK("R1        = 0x%x\n", excInfo->context->r1);
383     PRINTK("R2        = 0x%x\n", excInfo->context->r2);
384     PRINTK("R3        = 0x%x\n", excInfo->context->r3);
385     PRINTK("R4        = 0x%x\n", excInfo->context->r4);
386     PRINTK("R5        = 0x%x\n", excInfo->context->r5);
387     PRINTK("R6        = 0x%x\n", excInfo->context->r6);
388     PRINTK("R7        = 0x%x\n", excInfo->context->r7);
389     PRINTK("R8        = 0x%x\n", excInfo->context->r8);
390     PRINTK("R9        = 0x%x\n", excInfo->context->r9);
391     PRINTK("R10       = 0x%x\n", excInfo->context->r10);
392     PRINTK("R11       = 0x%x\n", excInfo->context->r11);
393     PRINTK("R12       = 0x%x\n", excInfo->context->r12);
394     PRINTK("xPSR      = 0x%x\n", excInfo->context->spsr);
395 }
396 
397 #if (LOSCFG_KERNEL_BACKTRACE == 1)
OsExcBackTraceInfo(const ExcInfo * excInfo)398 STATIC VOID OsExcBackTraceInfo(const ExcInfo *excInfo)
399 {
400     UINTPTR LR[LOSCFG_BACKTRACE_DEPTH] = {0};
401     UINT32 index;
402 
403     OsBackTraceHookCall(LR, LOSCFG_BACKTRACE_DEPTH, 0, excInfo->context->sp);
404 
405     PRINTK("----- backtrace start -----\n");
406     for (index = 0; index < LOSCFG_BACKTRACE_DEPTH; index++) {
407         if (LR[index] == 0) {
408             break;
409         }
410         PRINTK("backtrace %d -- lr = 0x%x\n", index, LR[index]);
411     }
412     PRINTK("----- backtrace end -----\n");
413 }
414 #endif
415 
OsExcMemPoolCheckInfo(VOID)416 STATIC VOID OsExcMemPoolCheckInfo(VOID)
417 {
418     PRINTK("\r\nmemory pools check:\n");
419 #if (LOSCFG_PLATFORM_EXC == 1)
420     MemInfoCB memExcInfo[OS_SYS_MEM_NUM];
421     UINT32 errCnt;
422     UINT32 i;
423 
424     (VOID)memset_s(memExcInfo, sizeof(memExcInfo), 0, sizeof(memExcInfo));
425 
426     errCnt = OsMemExcInfoGet(OS_SYS_MEM_NUM, memExcInfo);
427     if (errCnt < OS_SYS_MEM_NUM) {
428         errCnt += OsMemboxExcInfoGet(OS_SYS_MEM_NUM - errCnt, memExcInfo + errCnt);
429     }
430 
431     if (errCnt == 0) {
432         PRINTK("all memory pool check passed!\n");
433         return;
434     }
435 
436     for (i = 0; i < errCnt; i++) {
437         PRINTK("pool num    = %d\n", i);
438         PRINTK("pool type   = %d\n", memExcInfo[i].type);
439         PRINTK("pool addr   = 0x%x\n", memExcInfo[i].startAddr);
440         PRINTK("pool size   = 0x%x\n", memExcInfo[i].size);
441         PRINTK("pool free   = 0x%x\n", memExcInfo[i].free);
442         PRINTK("pool blkNum = %d\n", memExcInfo[i].blockSize);
443         PRINTK("pool error node addr  = 0x%x\n", memExcInfo[i].errorAddr);
444         PRINTK("pool error node len   = 0x%x\n", memExcInfo[i].errorLen);
445         PRINTK("pool error node owner = %d\n", memExcInfo[i].errorOwner);
446     }
447 #endif
448     UINT32 ret = LOS_MemIntegrityCheck(LOSCFG_SYS_HEAP_ADDR);
449     if (ret == LOS_OK) {
450         PRINTK("system heap memcheck over, all passed!\n");
451     }
452 
453     PRINTK("memory pool check end!\n");
454 }
455 #endif
456 
OsExcInfoDisplay(const ExcInfo * excInfo)457 STATIC VOID OsExcInfoDisplay(const ExcInfo *excInfo)
458 {
459 #if (LOSCFG_KERNEL_PRINTF != 0)
460     PRINTK("*************Exception Information**************\n");
461     OsExcTypeInfo(excInfo);
462     OsExcCurTaskInfo(excInfo);
463     OsExcRegInfo(excInfo);
464 #if (LOSCFG_KERNEL_BACKTRACE == 1)
465     OsExcBackTraceInfo(excInfo);
466 #endif
467     OsGetAllTskInfo();
468     OsExcMemPoolCheckInfo();
469 #endif
470 }
471 
HalExcHandleEntry(UINT32 excType,UINT32 faultAddr,UINT32 pid,EXC_CONTEXT_S * excBufAddr)472 LITE_OS_SEC_TEXT_INIT VOID HalExcHandleEntry(UINT32 excType, UINT32 faultAddr, UINT32 pid, EXC_CONTEXT_S *excBufAddr)
473 {
474     g_intCount++;
475     g_excInfo.nestCnt++;
476 
477     g_excInfo.type = excType;
478 
479     if ((excType == OS_EXCEPT_UNDEF_INSTR) || (excType == OS_EXCEPT_SWI)) {
480         if ((excBufAddr->spsr & OS_INSTR_SET_MASK) == 0) { /* Work status: ARM */
481             excBufAddr->pc -= OS_ARM_INSTR_LEN;
482         } else if ((excBufAddr->spsr & OS_INSTR_SET_MASK) == 0x20) { /* Work status: Thumb */
483             excBufAddr->pc -= OS_THUMB_INSTR_LEN;
484         }
485     }
486     g_excInfo.faultAddr = OS_EXC_IMPRECISE_ACCESS_ADDR;
487 
488     if (g_losTask.runTask != NULL) {
489         g_excInfo.phase = OS_EXC_IN_TASK;
490         g_excInfo.thrdPid = g_losTask.runTask->taskID;
491     } else {
492         g_excInfo.phase = OS_EXC_IN_INIT;
493         g_excInfo.thrdPid = OS_NULL_INT;
494     }
495     g_excInfo.context = excBufAddr;
496 
497     OsDoExcHook(EXC_INTERRUPT);
498     OsExcInfoDisplay(&g_excInfo);
499     ArchSysExit();
500 }
501 
502 /* ****************************************************************************
503  Function    : HalHwiInit
504  Description : initialization of the hardware interrupt
505  Input       : None
506  Output      : None
507  Return      : None
508  **************************************************************************** */
HalHwiInit(VOID)509 LITE_OS_SEC_TEXT_INIT VOID HalHwiInit(VOID)
510 {
511 #if (LOSCFG_USE_SYSTEM_DEFINED_INTERRUPT == 1)
512     UINT32 reg;
513     UINT32 val;
514 
515     for (val = OS_SYS_VECTOR_CNT; val < OS_VECTOR_CNT; val++) {
516 #if (LOSCFG_PLATFORM_HWI_WITH_ARG == 1)
517         g_hwiForm[val].pfnHook = HalHwiDefaultHandler;
518         g_hwiForm[val].uwParam = 0;
519 #else
520         g_hwiForm[val] = (HWI_PROC_FUNC)HalHwiDefaultHandler;
521 #endif
522     }
523 
524     val = OS_INT_IRQ_ENABLE | OS_INT_FIQ_ENABLE;
525     READ_UINT32(reg, OS_INT_GLOBAL_ENABLE_ADDR);
526     reg |= val;
527     WRITE_UINT32(reg, OS_INT_GLOBAL_ENABLE_ADDR);
528 #endif
529     return;
530 }
531 
ArchIntLock(VOID)532 UINT32 ArchIntLock(VOID)
533 {
534     UINT32 ret;
535     UINT32 temp;
536 
537     __asm__ __volatile__("MRS %0, CPSR\n"
538                          "ORR %1, %0, #0xC0\n"
539                          "MSR CPSR_c, %1"
540                          : "=r"(ret), "=r"(temp)
541                          :
542                          : "memory");
543     return ret;
544 }
545 
ArchIntRestore(UINT32 intSave)546 VOID ArchIntRestore(UINT32 intSave)
547 {
548     __asm__ __volatile__("MSR CPSR_c, %0" : : "r"(intSave));
549 }
550 
ArchIntUnLock(VOID)551 UINT32 ArchIntUnLock(VOID)
552 {
553     UINT32 intSave;
554 
555     __asm__ __volatile__("MRS %0, CPSR\n"
556                          "BIC %0, %0, #0xC0\n"
557                          "MSR CPSR_c, %0"
558                          : "=r"(intSave)
559                          :
560                          : "memory");
561     return intSave;
562 }
563 
564