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