2022-08-15 04:20:27 -05:00
|
|
|
/*----------------------------------------------------------------------------
|
|
|
|
* RL-ARM - RTX
|
|
|
|
*----------------------------------------------------------------------------
|
|
|
|
* Name: HAL_CA9.c
|
|
|
|
* Purpose: Hardware Abstraction Layer for Cortex-A9
|
|
|
|
* Rev.: 3 Sept 2013
|
|
|
|
*----------------------------------------------------------------------------
|
|
|
|
*
|
|
|
|
* Copyright (c) 2012 - 2013 ARM Limited
|
|
|
|
* All rights reserved.
|
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
|
|
* modification, are permitted provided that the following conditions are met:
|
|
|
|
* - Redistributions of source code must retain the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer.
|
|
|
|
* - Redistributions in binary form must reproduce the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
|
|
* documentation and/or other materials provided with the distribution.
|
|
|
|
* - Neither the name of ARM nor the names of its contributors may be used
|
|
|
|
* to endorse or promote products derived from this software without
|
|
|
|
* specific prior written permission.
|
|
|
|
*
|
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
|
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
|
|
|
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
|
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
|
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
|
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
|
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
|
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
|
|
* POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
*---------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
#include "RTX_Config.h"
|
2023-02-01 14:52:54 -06:00
|
|
|
#include "rt_HAL_CA.h"
|
2022-08-15 04:20:27 -05:00
|
|
|
#include "rt_List.h"
|
|
|
|
#include "rt_MemBox.h"
|
2023-02-01 14:52:54 -06:00
|
|
|
#include "rt_System.h"
|
|
|
|
#include "rt_Task.h"
|
|
|
|
#include "rt_TypeDef.h"
|
2022-08-15 04:20:27 -05:00
|
|
|
|
|
|
|
/*----------------------------------------------------------------------------
|
|
|
|
* Functions
|
|
|
|
*---------------------------------------------------------------------------*/
|
|
|
|
|
2023-02-01 14:52:54 -06:00
|
|
|
// For A-class, set USR/SYS stack
|
|
|
|
__asm void rt_set_PSP(U32 stack) {
|
|
|
|
ARM
|
2022-08-15 04:20:27 -05:00
|
|
|
|
2023-02-01 14:52:54 -06:00
|
|
|
MRS R1,
|
|
|
|
CPSR CPS #MODE_SYS;
|
|
|
|
no effect in USR mode ISB MOV SP, R0 MSR CPSR_c, R1;
|
|
|
|
no effect in USR mode ISB BX LR
|
2022-08-15 04:20:27 -05:00
|
|
|
}
|
|
|
|
|
2023-02-01 14:52:54 -06:00
|
|
|
// For A-class, get USR/SYS stack
|
|
|
|
__asm U32 rt_get_PSP(void) {
|
|
|
|
ARM
|
|
|
|
|
|
|
|
MRS R1,
|
|
|
|
CPSR CPS #MODE_SYS;
|
|
|
|
no effect in USR mode ISB MOV R0, SP MSR CPSR_c, R1;
|
|
|
|
no effect in USR mode ISB BX LR
|
2022-08-15 04:20:27 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/*--------------------------- _alloc_box ------------------------------------*/
|
2023-02-01 14:52:54 -06:00
|
|
|
__asm void *_alloc_box(void *box_mem) {
|
|
|
|
/* Function wrapper for Unprivileged/Privileged mode. */
|
|
|
|
ARM
|
2022-08-15 04:20:27 -05:00
|
|
|
|
2023-02-01 14:52:54 -06:00
|
|
|
LDR R12,
|
|
|
|
= __cpp(rt_alloc_box) MRS R2, CPSR LSLS R2, #28 BXNE R12 SVC 0 BX LR
|
|
|
|
}
|
2022-08-15 04:20:27 -05:00
|
|
|
|
|
|
|
/*--------------------------- _free_box -------------------------------------*/
|
2023-02-01 14:52:54 -06:00
|
|
|
__asm int _free_box(void *box_mem, void *box) {
|
|
|
|
/* Function wrapper for Unprivileged/Privileged mode. */
|
|
|
|
ARM
|
2022-08-15 04:20:27 -05:00
|
|
|
|
2023-02-01 14:52:54 -06:00
|
|
|
LDR R12,
|
|
|
|
= __cpp(rt_free_box) MRS R2, CPSR LSLS R2, #28 BXNE R12 SVC 0 BX LR
|
2022-08-15 04:20:27 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/*-------------------------- SVC_Handler -----------------------------------*/
|
|
|
|
|
|
|
|
#pragma push
|
|
|
|
#pragma arm
|
2023-02-01 14:52:54 -06:00
|
|
|
__asm void SVC_Handler(void) {
|
|
|
|
PRESERVE8
|
|
|
|
ARM
|
|
|
|
|
|
|
|
IMPORT rt_tsk_lock IMPORT rt_tsk_unlock IMPORT SVC_Count IMPORT SVC_Table
|
|
|
|
IMPORT rt_stk_check IMPORT FPUEnable
|
|
|
|
|
|
|
|
Mode_SVC EQU 0x13
|
|
|
|
|
|
|
|
SRSFD SP !,
|
|
|
|
#Mode_SVC;
|
|
|
|
Push LR_SVC and SPRS_SVC onto SVC mode stack PUSH{R4};
|
|
|
|
Push R4 so we can use it as a temp
|
|
|
|
|
|
|
|
MRS R4,
|
|
|
|
SPSR;
|
|
|
|
Get SPSR TST R4, #CPSR_T_BIT;
|
|
|
|
Check Thumb Bit LDRNEH R4, [ LR, # - 2 ];
|
|
|
|
Thumb:
|
|
|
|
Load Halfword BICNE R4, R4, #0xFF00;
|
|
|
|
Extract SVC Number LDREQ R4, [ LR, # - 4 ];
|
|
|
|
ARM:
|
|
|
|
Load Word BICEQ R4, R4, #0xFF000000;
|
|
|
|
Extract SVC Number
|
|
|
|
|
|
|
|
/* Lock out systick and re-enable interrupts */
|
|
|
|
PUSH{R0 - R3, R12, LR}
|
|
|
|
|
|
|
|
AND R12,
|
|
|
|
SP, #4;
|
|
|
|
Ensure stack is 8 - byte aligned SUB SP, SP, R12;
|
|
|
|
Adjust stack PUSH{R12, LR};
|
|
|
|
Store stack adjustment and dummy LR to SVC stack
|
|
|
|
|
|
|
|
BLX rt_tsk_lock CPSIE i
|
|
|
|
|
|
|
|
POP{R12, LR};
|
|
|
|
Get stack adjustment &discard dummy LR ADD SP, SP, R12;
|
|
|
|
Unadjust stack
|
|
|
|
|
|
|
|
POP{R0 - R3, R12, LR}
|
|
|
|
|
|
|
|
CMP R4,
|
|
|
|
# 0 BNE SVC_User
|
|
|
|
|
|
|
|
MRS R4, SPSR PUSH{R4};
|
|
|
|
Push R4 so we can use it as a temp AND R4, SP, #4;
|
|
|
|
Ensure stack is 8 - byte aligned SUB SP, SP, R4;
|
|
|
|
Adjust stack PUSH{R4, LR};
|
|
|
|
Store stack adjustment and dummy LR BLX R12 POP{R4, LR};
|
|
|
|
Get stack adjustment &discard dummy LR ADD SP, SP, R4;
|
|
|
|
Unadjust stack POP{R4};
|
|
|
|
Restore R4 MSR SPSR_CXSF,
|
|
|
|
R4
|
|
|
|
|
|
|
|
/* Here we will be in SVC mode (even if coming in from PendSV_Handler
|
|
|
|
or OS_Tick_Handler) */
|
|
|
|
Sys_Switch LDR LR,
|
|
|
|
= __cpp(&os_tsk) LDM LR, {R4, LR};
|
|
|
|
os_tsk.run, os_tsk.new CMP R4,
|
|
|
|
LR BNE switching
|
|
|
|
|
|
|
|
PUSH{R0 - R3, R12, LR}
|
|
|
|
|
|
|
|
AND R12,
|
|
|
|
SP, #4;
|
|
|
|
Ensure stack is 8 - byte aligned SUB SP, SP, R12;
|
|
|
|
Adjust stack PUSH{R12, LR};
|
|
|
|
Store stack adjustment and dummy LR to SVC stack
|
|
|
|
|
|
|
|
CPSID i BLX rt_tsk_unlock
|
|
|
|
|
|
|
|
POP{R12, LR};
|
|
|
|
Get stack adjustment &discard dummy LR ADD SP, SP, R12;
|
|
|
|
Unadjust stack
|
|
|
|
|
|
|
|
POP{R0 - R3, R12, LR} POP{R4} RFEFD SP !;
|
|
|
|
Return from exception,
|
|
|
|
no task switch
|
|
|
|
|
|
|
|
switching CLREX CMP R4,
|
|
|
|
# 0 ADDEQ SP, SP, #12;
|
|
|
|
Original R4,
|
|
|
|
LR &SPSR do not need to be popped when we are paging in a different task
|
|
|
|
BEQ SVC_Next;
|
|
|
|
Runtask deleted ?
|
|
|
|
|
|
|
|
PUSH{R8 - R11} // R4 and LR already stacked
|
|
|
|
MOV R10,
|
|
|
|
R4;
|
|
|
|
Preserve os_tsk.run MOV R11, LR;
|
|
|
|
Preserve os_tsk.new
|
|
|
|
|
|
|
|
ADD R8,
|
|
|
|
SP, #16;
|
|
|
|
Unstack R4, LR LDMIA R8,
|
|
|
|
{R4, LR}
|
|
|
|
|
|
|
|
SUB SP,
|
|
|
|
SP, #4; Make space on the stack for the next instn
|
|
|
|
STMIA SP,{SP}^ ;
|
|
|
|
Put User SP onto stack POP{R8};
|
|
|
|
Pop User SP into R8
|
|
|
|
|
|
|
|
MRS R9,
|
|
|
|
SPSR STMDB R8 !, {R9};
|
|
|
|
User CPSR STMDB R8 !, {LR};
|
|
|
|
User PC STMDB R8, {LR} ^ ;
|
|
|
|
User LR SUB R8, R8, #4; No writeback for store of User LR
|
|
|
|
STMDB R8!,{R0-R3,R12} ;
|
|
|
|
User R0 - R3, R12 MOV R3, R10;
|
|
|
|
os_tsk.run MOV LR, R11;
|
|
|
|
os_tsk.new POP{R9 - R12} ADD SP, SP, #12; Fix up SP for unstack of R4, LR & SPSR
|
|
|
|
STMDB R8!,{R4-R7,R9-R12} ;
|
|
|
|
User R4 - R11
|
|
|
|
|
|
|
|
// If applicable, stack VFP state
|
|
|
|
MRC p15,
|
|
|
|
0, R1, c1, c0, 2;
|
|
|
|
VFP / NEON access enabled ? (CPACR)AND R2, R1, #0x00F00000 CMP R2,
|
|
|
|
# 0x00F00000 BNE no_outgoing_vfp VMRS R2, FPSCR STMDB R8 !, {R2, R4 };
|
|
|
|
Push FPSCR, maintain 8 - byte alignment VSTMDB R8 !, {S0 - S31} LDRB R2,
|
|
|
|
[ R3, #TCB_STACKF ];
|
|
|
|
Record in TCB that VFP state is stacked ORR R2, #2 STRB R2,
|
|
|
|
[ R3, #TCB_STACKF ]
|
|
|
|
|
|
|
|
no_outgoing_vfp STR R8,
|
|
|
|
[R3, #TCB_TSTACK] MOV R4,
|
|
|
|
LR
|
|
|
|
|
|
|
|
PUSH { R4 };
|
|
|
|
Push R4 so we can use it as a temp AND R4, SP, #4;
|
|
|
|
Ensure stack is 8 - byte aligned SUB SP, SP, R4;
|
|
|
|
Adjust stack PUSH{R4, LR};
|
|
|
|
Store stack adjustment and dummy LR to SVC stack
|
|
|
|
|
|
|
|
BLX rt_stk_check
|
|
|
|
|
|
|
|
POP{R4, LR};
|
|
|
|
Get stack adjustment &discard dummy LR ADD SP, SP, R4;
|
|
|
|
Unadjust stack POP{R4};
|
|
|
|
Restore R4
|
|
|
|
|
|
|
|
MOV LR,
|
|
|
|
R4
|
|
|
|
|
|
|
|
SVC_Next // R4 == os_tsk.run, LR == os_tsk.new, R0-R3, R5-R12
|
|
|
|
// corruptible
|
|
|
|
LDR R1,
|
|
|
|
= __cpp(&os_tsk);
|
|
|
|
os_tsk.run = os_tsk.new STR LR, [ R1 ] LDRB R1, [ LR, #TCB_TID ];
|
|
|
|
os_tsk.run->task_id LSL R1, #8;
|
|
|
|
Store PROCID MCR p15, 0, R1, c13, c0, 1;
|
|
|
|
Write CONTEXTIDR
|
|
|
|
|
|
|
|
LDR R0,
|
|
|
|
[ LR, #TCB_TSTACK ];
|
|
|
|
os_tsk.run->tsk_stack
|
|
|
|
|
|
|
|
// Does incoming task have VFP state in stack?
|
|
|
|
LDRB R3,
|
|
|
|
[ LR, #TCB_STACKF ] TST R3, #0x2 MRC p15, 0, R1, c1, c0, 2;
|
|
|
|
Read CPACR ANDEQ R1, R1, #0xFF0FFFFF;
|
|
|
|
Disable VFP access if incoming task does not have stacked VFP state ORRNE R1,
|
|
|
|
R1, #0x00F00000;
|
|
|
|
Enable VFP access if incoming task does have stacked VFP state MCR p15, 0, R1,
|
|
|
|
c1, c0, 2;
|
|
|
|
Write CPACR BEQ no_incoming_vfp ISB;
|
|
|
|
We only need the sync if we enabled,
|
|
|
|
otherwise we will context switch before next VFP instruction anyway VLDMIA
|
|
|
|
R0 !,
|
|
|
|
{S0 - S31} LDR R2, [R0] VMSR FPSCR, R2 ADD R0, R0,
|
|
|
|
# 8
|
|
|
|
|
|
|
|
no_incoming_vfp LDR R1, [ R0, #60 ];
|
|
|
|
Restore User CPSR MSR SPSR_CXSF, R1 LDMIA R0 !, {R4 - R11};
|
|
|
|
Restore User R4 - R11 ADD R0, R0, #4;
|
|
|
|
Restore User R1 - R3, R12 LDMIA R0 !, {R1 - R3, R12} LDMIA R0, {LR} ^ ;
|
|
|
|
Restore User LR ADD R0, R0, #4; No writeback for load to user LR
|
|
|
|
LDMIA R0!,{LR} ;
|
|
|
|
Restore User PC ADD R0, R0, #4; Correct User SP for unstacked user CPSR
|
|
|
|
|
|
|
|
PUSH {R0} ;
|
|
|
|
Push R0 onto stack LDMIA SP, {SP} ^ ;
|
|
|
|
Get R0 off stack into User SP ADD SP, SP, #4;
|
|
|
|
Put SP back
|
|
|
|
|
|
|
|
LDR R0,
|
|
|
|
[ R0, # - 32 ];
|
|
|
|
Restore R0
|
|
|
|
|
|
|
|
PUSH{R0 - R3, R12, LR}
|
|
|
|
|
|
|
|
AND R12,
|
|
|
|
SP, #4;
|
|
|
|
Ensure stack is 8 - byte aligned SUB SP, SP, R12;
|
|
|
|
Adjust stack PUSH{R12, LR};
|
|
|
|
Store stack adjustment and dummy LR to SVC stack
|
|
|
|
|
|
|
|
CPSID i BLX rt_tsk_unlock
|
|
|
|
|
|
|
|
POP{R12, LR};
|
|
|
|
Get stack adjustment &discard dummy LR ADD SP, SP, R12;
|
|
|
|
Unadjust stack
|
|
|
|
|
|
|
|
POP{R0 - R3, R12, LR}
|
|
|
|
|
|
|
|
MOVS PC,
|
|
|
|
LR;
|
|
|
|
Return from exception
|
|
|
|
|
|
|
|
/*------------------- User SVC -------------------------------*/
|
|
|
|
|
|
|
|
SVC_User LDR R12,
|
|
|
|
= SVC_Count LDR R12, [R12] CMP R4, R12; Check for overflow
|
2022-08-15 04:20:27 -05:00
|
|
|
BHI SVC_Done
|
|
|
|
|
|
|
|
LDR R12,=SVC_Table-4
|
2023-02-01 14:52:54 -06:00
|
|
|
LDR R12,[R12,R4,LSL #2] ;
|
|
|
|
Load SVC Function Address MRS R4, SPSR;
|
|
|
|
Save SPSR PUSH{R4};
|
|
|
|
Push R4 so we can use it as a temp AND R4, SP, #4;
|
|
|
|
Ensure stack is 8 - byte aligned SUB SP, SP, R4;
|
|
|
|
Adjust stack PUSH{R4, LR};
|
|
|
|
Store stack adjustment and dummy LR BLX R12;
|
|
|
|
Call SVC Function POP{R4, LR};
|
|
|
|
Get stack adjustment &discard dummy LR ADD SP, SP, R4;
|
|
|
|
Unadjust stack POP{R4};
|
|
|
|
Restore R4 MSR SPSR_CXSF, R4;
|
|
|
|
Restore SPSR
|
|
|
|
|
|
|
|
SVC_Done PUSH{R0 - R3, R12, LR}
|
|
|
|
|
|
|
|
PUSH{R4};
|
|
|
|
Push R4 so we can use it as a temp AND R4, SP, #4;
|
|
|
|
Ensure stack is 8 - byte aligned SUB SP, SP, R4;
|
|
|
|
Adjust stack PUSH{R4, LR};
|
|
|
|
Store stack adjustment and dummy LR
|
|
|
|
|
|
|
|
CPSID i BLX rt_tsk_unlock
|
|
|
|
|
|
|
|
POP{R4, LR};
|
|
|
|
Get stack adjustment &discard dummy LR ADD SP, SP, R4;
|
|
|
|
Unadjust stack POP{R4};
|
|
|
|
Restore R4
|
|
|
|
|
|
|
|
POP{R0 - R3, R12, LR} POP{R4} RFEFD SP !;
|
|
|
|
Return from exception
|
2022-08-15 04:20:27 -05:00
|
|
|
}
|
|
|
|
#pragma pop
|
|
|
|
|
|
|
|
#pragma push
|
|
|
|
#pragma arm
|
2023-02-01 14:52:54 -06:00
|
|
|
__asm void PendSV_Handler(U32 IRQn) {
|
|
|
|
ARM
|
2022-08-15 04:20:27 -05:00
|
|
|
|
2023-02-01 14:52:54 -06:00
|
|
|
IMPORT rt_tsk_lock IMPORT IRQNestLevel
|
2022-08-15 04:20:27 -05:00
|
|
|
|
2023-02-01 14:52:54 -06:00
|
|
|
ADD SP,
|
|
|
|
SP,
|
|
|
|
# 8 // fix up stack pointer (R0 has been pushed and will never be popped, \
|
|
|
|
// R1 was pushed for stack alignment)
|
2022-08-15 04:20:27 -05:00
|
|
|
|
2023-02-01 14:52:54 -06:00
|
|
|
// Disable systick interrupts, then write EOIR. We want interrupts
|
|
|
|
// disabled before we enter the context switcher.
|
|
|
|
PUSH{R0, R1} BLX rt_tsk_lock POP{R0, R1} LDR R1,
|
|
|
|
= __cpp(&GICInterface_BASE) LDR R1, [ R1, #0 ] STR R0,
|
|
|
|
[ R1, #0x10 ]
|
2022-08-15 04:20:27 -05:00
|
|
|
|
2023-02-01 14:52:54 -06:00
|
|
|
LDR R0,
|
|
|
|
= IRQNestLevel;
|
|
|
|
Get address of nesting counter LDR R1, [R0] SUB R1, R1, #1;
|
|
|
|
Decrement nesting counter STR R1, [R0]
|
2022-08-15 04:20:27 -05:00
|
|
|
|
2023-02-01 14:52:54 -06:00
|
|
|
BLX __cpp(rt_pop_req)
|
2022-08-15 04:20:27 -05:00
|
|
|
|
2023-02-01 14:52:54 -06:00
|
|
|
POP { R1, LR };
|
|
|
|
Get stack adjustment &discard dummy LR ADD SP, SP, R1;
|
|
|
|
Unadjust stack
|
2022-08-15 04:20:27 -05:00
|
|
|
|
2023-02-01 14:52:54 -06:00
|
|
|
LDR R0,
|
|
|
|
[SP, #24] MSR SPSR_CXSF, R0 POP { R0 - R3, R12 };
|
|
|
|
Leave SPSR &LR on the stack PUSH{R4} B Sys_Switch
|
2022-08-15 04:20:27 -05:00
|
|
|
}
|
|
|
|
#pragma pop
|
|
|
|
|
|
|
|
#pragma push
|
|
|
|
#pragma arm
|
2023-02-01 14:52:54 -06:00
|
|
|
__asm void OS_Tick_Handler(U32 IRQn) {
|
|
|
|
ARM
|
2022-08-15 04:20:27 -05:00
|
|
|
|
2023-02-01 14:52:54 -06:00
|
|
|
IMPORT rt_tsk_lock IMPORT IRQNestLevel
|
2022-08-15 04:20:27 -05:00
|
|
|
|
2023-02-01 14:52:54 -06:00
|
|
|
ADD SP,
|
|
|
|
SP,
|
|
|
|
# 8 // fix up stack pointer (R0 has been pushed and will never be popped, \
|
|
|
|
// R1 was pushed for stack alignment)
|
2022-08-15 04:20:27 -05:00
|
|
|
|
2023-02-01 14:52:54 -06:00
|
|
|
PUSH{R0, R1} BLX rt_tsk_lock POP{R0, R1} LDR R1,
|
|
|
|
= __cpp(&GICInterface_BASE) LDR R1, [ R1, #0 ] STR R0,
|
|
|
|
[ R1, #0x10 ]
|
2022-08-15 04:20:27 -05:00
|
|
|
|
2023-02-01 14:52:54 -06:00
|
|
|
LDR R0,
|
|
|
|
= IRQNestLevel;
|
|
|
|
Get address of nesting counter LDR R1, [R0] SUB R1, R1, #1;
|
|
|
|
Decrement nesting counter STR R1, [R0]
|
2022-08-15 04:20:27 -05:00
|
|
|
|
2023-02-01 14:52:54 -06:00
|
|
|
BLX __cpp(os_tick_irqack) BLX __cpp(rt_systick)
|
2022-08-15 04:20:27 -05:00
|
|
|
|
2023-02-01 14:52:54 -06:00
|
|
|
POP { R1, LR };
|
|
|
|
Get stack adjustment &discard dummy LR ADD SP, SP, R1;
|
|
|
|
Unadjust stack
|
2022-08-15 04:20:27 -05:00
|
|
|
|
2023-02-01 14:52:54 -06:00
|
|
|
LDR R0,
|
|
|
|
[SP, #24] MSR SPSR_CXSF, R0 POP { R0 - R3, R12 };
|
|
|
|
Leave SPSR &LR on the stack PUSH{R4} B Sys_Switch
|
2022-08-15 04:20:27 -05:00
|
|
|
}
|
|
|
|
#pragma pop
|
|
|
|
|
|
|
|
/*----------------------------------------------------------------------------
|
|
|
|
* end of file
|
|
|
|
*---------------------------------------------------------------------------*/
|