extract exceptions.h
This commit is contained in:
@@ -1,202 +1,80 @@
|
||||
/* Fuchsia's code is nice here, so I learn from it(fine, almost copy). thanks */
|
||||
|
||||
.syntax unified
|
||||
.text
|
||||
|
||||
/* macros to align and unalign the stack on 8 byte boundary for ABI compliance */
|
||||
.macro stack_align, tempreg
|
||||
/* make sure the stack is aligned */
|
||||
mov \tempreg, sp
|
||||
tst sp, #4
|
||||
subeq sp, #4
|
||||
push { \tempreg }
|
||||
|
||||
/* tempreg holds the original stack */
|
||||
.endm
|
||||
|
||||
.macro stack_restore, tempreg
|
||||
/* restore the potentially unaligned stack */
|
||||
pop { \tempreg }
|
||||
mov sp, \tempreg
|
||||
.endm
|
||||
|
||||
/* save and disable the vfp unit */
|
||||
.macro vfp_save, temp1
|
||||
/* save old fpexc */
|
||||
vmrs \temp1, fpexc
|
||||
|
||||
push { \temp1 }
|
||||
|
||||
/* hard disable the vfp unit */
|
||||
bic \temp1, #(1<<30)
|
||||
vmsr fpexc, \temp1
|
||||
.endm
|
||||
|
||||
/* restore the vfp enable/disable state */
|
||||
.macro vfp_restore, temp1
|
||||
/* restore fpexc */
|
||||
pop { \temp1 }
|
||||
|
||||
vmsr fpexc, \temp1
|
||||
.endm
|
||||
|
||||
/* Save callee trashed registers.
|
||||
* At exit r0 contains a pointer to the register frame.
|
||||
*/
|
||||
.macro save
|
||||
/* save spsr and r14 onto the svc stack */
|
||||
srsdb #0x13!
|
||||
|
||||
/* switch to svc mode, interrupts disabled */
|
||||
cpsid i, #0x13
|
||||
|
||||
/* save callee trashed regs and lr */
|
||||
push { r0-r3, r12, lr }
|
||||
|
||||
#if 0
|
||||
#if (defined(__VFP_FP__) && !defined(__SOFTFP__))
|
||||
/* save and disable the vfp unit */
|
||||
vfp_save r0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* make sure the stack is 8 byte aligned */
|
||||
stack_align r0
|
||||
|
||||
/* r0 now holds the pointer to the original iframe (before alignment) */
|
||||
.endm
|
||||
|
||||
.macro save_offset, offset
|
||||
sub lr, \offset
|
||||
save
|
||||
.endm
|
||||
|
||||
.macro restore
|
||||
/* undo the stack alignment we did before */
|
||||
stack_restore r0
|
||||
|
||||
#if 0
|
||||
#if (defined(__VFP_FP__) && !defined(__SOFTFP__))
|
||||
/* restore the old state of the vfp unit */
|
||||
vfp_restore r0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
pop { r0-r3, r12, lr }
|
||||
|
||||
/* return to whence we came from */
|
||||
rfeia sp!
|
||||
.endm
|
||||
|
||||
/* Save all registers.
|
||||
* At exit r0 contains a pointer to the register frame.
|
||||
*/
|
||||
.macro saveall
|
||||
/* save spsr and r14 onto the svc stack */
|
||||
srsdb #0x13!
|
||||
|
||||
/* switch to svc mode, interrupts disabled */
|
||||
cpsid i,#0x13
|
||||
|
||||
/* save all regs */
|
||||
push { r0-r12, lr }
|
||||
|
||||
#if 0
|
||||
#if (defined(__VFP_FP__) && !defined(__SOFTFP__))
|
||||
/* save and disable the vfp unit */
|
||||
vfp_save r0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* make sure the stack is 8 byte aligned */
|
||||
stack_align r0
|
||||
|
||||
/* r0 now holds the pointer to the original iframe (before alignment) */
|
||||
.endm
|
||||
|
||||
.macro saveall_offset, offset
|
||||
sub lr, \offset
|
||||
saveall
|
||||
.endm
|
||||
|
||||
.macro restoreall
|
||||
/* undo the stack alignment we did before */
|
||||
stack_restore r0
|
||||
|
||||
#if 0
|
||||
#if (defined(__VFP_FP__) && !defined(__SOFTFP__))
|
||||
/* restore the old state of the vfp unit */
|
||||
vfp_restore r0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
pop { r0-r12, r14 }
|
||||
|
||||
/* return to whence we came from */
|
||||
rfeia sp!
|
||||
.endm
|
||||
|
||||
.extern tos_knl_irq_enter
|
||||
.extern tos_knl_irq_leave
|
||||
|
||||
.global arm_undefined
|
||||
arm_undefined:
|
||||
save
|
||||
/* r0 now holds pointer to iframe */
|
||||
|
||||
bl arm_undefined_handler
|
||||
|
||||
restore
|
||||
|
||||
|
||||
.global arm_syscall
|
||||
arm_syscall:
|
||||
b .
|
||||
|
||||
|
||||
.global arm_prefetch_abort
|
||||
arm_prefetch_abort:
|
||||
saveall_offset #4
|
||||
/* r0 now holds pointer to iframe */
|
||||
|
||||
bl arm_prefetch_abort_handler
|
||||
|
||||
restoreall
|
||||
|
||||
|
||||
.global arm_data_abort
|
||||
arm_data_abort:
|
||||
saveall_offset #8
|
||||
/* r0 now holds pointer to iframe */
|
||||
|
||||
bl arm_data_abort_handler
|
||||
|
||||
restoreall
|
||||
|
||||
|
||||
.global arm_reserved
|
||||
arm_reserved:
|
||||
b .
|
||||
|
||||
|
||||
.global arm_irq
|
||||
arm_irq:
|
||||
saveall_offset #4
|
||||
|
||||
/* r0 now holds pointer to iframe */
|
||||
bl tos_knl_irq_enter
|
||||
|
||||
/* call into higher level code */
|
||||
bl interrupt_irq
|
||||
|
||||
bl tos_knl_irq_leave
|
||||
|
||||
restoreall
|
||||
|
||||
|
||||
.global arm_fiq
|
||||
arm_fiq:
|
||||
b .
|
||||
|
||||
.end
|
||||
|
||||
/* Fuchsia's code is nice here, so I learn from it(fine, almost copy). thanks */
|
||||
|
||||
#include "exceptions.h"
|
||||
|
||||
.global arm_undefined
|
||||
.global arm_syscall
|
||||
.global arm_prefetch_abort
|
||||
.global arm_data_abort
|
||||
.global arm_reserved
|
||||
.global arm_irq
|
||||
.global arm_fiq
|
||||
|
||||
.extern tos_knl_irq_enter
|
||||
.extern tos_knl_irq_leave
|
||||
.extern interrupt_irq
|
||||
|
||||
.syntax unified
|
||||
.text
|
||||
|
||||
.type arm_undefined, %function
|
||||
arm_undefined:
|
||||
save
|
||||
/* r0 now holds pointer to iframe */
|
||||
|
||||
bl arm_undefined_handler
|
||||
|
||||
restore
|
||||
|
||||
|
||||
.type arm_syscall, %function
|
||||
arm_syscall:
|
||||
b .
|
||||
|
||||
|
||||
.type arm_prefetch_abort, %function
|
||||
arm_prefetch_abort:
|
||||
saveall_offset #4
|
||||
/* r0 now holds pointer to iframe */
|
||||
|
||||
bl arm_prefetch_abort_handler
|
||||
|
||||
restoreall
|
||||
|
||||
|
||||
.type arm_data_abort, %function
|
||||
arm_data_abort:
|
||||
saveall_offset #8
|
||||
/* r0 now holds pointer to iframe */
|
||||
|
||||
bl arm_data_abort_handler
|
||||
|
||||
restoreall
|
||||
|
||||
|
||||
.type arm_reserved, %function
|
||||
arm_reserved:
|
||||
b .
|
||||
|
||||
|
||||
.type arm_irq, %function
|
||||
arm_irq:
|
||||
saveall_offset #4
|
||||
|
||||
/* r0 now holds pointer to iframe */
|
||||
bl tos_knl_irq_enter
|
||||
|
||||
/* call into higher level code */
|
||||
bl interrupt_irq
|
||||
|
||||
bl tos_knl_irq_leave
|
||||
|
||||
restoreall
|
||||
|
||||
|
||||
.type arm_fiq, %function
|
||||
arm_fiq:
|
||||
b .
|
||||
|
||||
.end
|
||||
|
||||
|
133
arch/arm/arm-v7a/cortex-a7/gcc/exceptions.h
Normal file
133
arch/arm/arm-v7a/cortex-a7/gcc/exceptions.h
Normal file
@@ -0,0 +1,133 @@
|
||||
/* macros to align and unalign the stack on 8 byte boundary for ABI compliance */
|
||||
.macro stack_align, tempreg
|
||||
/* make sure the stack is aligned */
|
||||
mov \tempreg, sp
|
||||
tst sp, #4
|
||||
subeq sp, #4
|
||||
push { \tempreg }
|
||||
|
||||
/* tempreg holds the original stack */
|
||||
.endm
|
||||
|
||||
.macro stack_restore, tempreg
|
||||
/* restore the potentially unaligned stack */
|
||||
pop { \tempreg }
|
||||
mov sp, \tempreg
|
||||
.endm
|
||||
|
||||
/* save and disable the vfp unit */
|
||||
.macro vfp_save, temp1
|
||||
/* save old fpexc */
|
||||
vmrs \temp1, fpexc
|
||||
|
||||
push { \temp1 }
|
||||
|
||||
/* hard disable the vfp unit */
|
||||
bic \temp1, #(1<<30)
|
||||
vmsr fpexc, \temp1
|
||||
.endm
|
||||
|
||||
/* restore the vfp enable/disable state */
|
||||
.macro vfp_restore, temp1
|
||||
/* restore fpexc */
|
||||
pop { \temp1 }
|
||||
|
||||
vmsr fpexc, \temp1
|
||||
.endm
|
||||
|
||||
/* Save callee trashed registers.
|
||||
* At exit r0 contains a pointer to the register frame.
|
||||
*/
|
||||
.macro save
|
||||
/* save spsr and r14 onto the svc stack */
|
||||
srsdb #0x13!
|
||||
|
||||
/* switch to svc mode, interrupts disabled */
|
||||
cpsid i, #0x13
|
||||
|
||||
/* save callee trashed regs and lr */
|
||||
push { r0-r3, r12, lr }
|
||||
|
||||
#if 0
|
||||
#if (defined(__VFP_FP__) && !defined(__SOFTFP__))
|
||||
/* save and disable the vfp unit */
|
||||
vfp_save r0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* make sure the stack is 8 byte aligned */
|
||||
stack_align r0
|
||||
|
||||
/* r0 now holds the pointer to the original iframe (before alignment) */
|
||||
.endm
|
||||
|
||||
.macro save_offset, offset
|
||||
sub lr, \offset
|
||||
save
|
||||
.endm
|
||||
|
||||
.macro restore
|
||||
/* undo the stack alignment we did before */
|
||||
stack_restore r0
|
||||
|
||||
#if 0
|
||||
#if (defined(__VFP_FP__) && !defined(__SOFTFP__))
|
||||
/* restore the old state of the vfp unit */
|
||||
vfp_restore r0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
pop { r0-r3, r12, lr }
|
||||
|
||||
/* return to whence we came from */
|
||||
rfeia sp!
|
||||
.endm
|
||||
|
||||
/* Save all registers.
|
||||
* At exit r0 contains a pointer to the register frame.
|
||||
*/
|
||||
.macro saveall
|
||||
/* save spsr and r14 onto the svc stack */
|
||||
srsdb #0x13!
|
||||
|
||||
/* switch to svc mode, interrupts disabled */
|
||||
cpsid i,#0x13
|
||||
|
||||
/* save all regs */
|
||||
push { r0-r12, lr }
|
||||
|
||||
#if 0
|
||||
#if (defined(__VFP_FP__) && !defined(__SOFTFP__))
|
||||
/* save and disable the vfp unit */
|
||||
vfp_save r0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* make sure the stack is 8 byte aligned */
|
||||
stack_align r0
|
||||
|
||||
/* r0 now holds the pointer to the original iframe (before alignment) */
|
||||
.endm
|
||||
|
||||
.macro saveall_offset, offset
|
||||
sub lr, \offset
|
||||
saveall
|
||||
.endm
|
||||
|
||||
.macro restoreall
|
||||
/* undo the stack alignment we did before */
|
||||
stack_restore r0
|
||||
|
||||
#if 0
|
||||
#if (defined(__VFP_FP__) && !defined(__SOFTFP__))
|
||||
/* restore the old state of the vfp unit */
|
||||
vfp_restore r0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
pop { r0-r12, r14 }
|
||||
|
||||
/* return to whence we came from */
|
||||
rfeia sp!
|
||||
.endm
|
||||
|
@@ -39,42 +39,44 @@ port_sched_start:
|
||||
.type port_context_switch, %function
|
||||
port_context_switch:
|
||||
.L__context_save:
|
||||
STR R0, [SP, #-0xC] /* backup R0 */
|
||||
STR R0, [SP, #-0xC] /* backup R0 */
|
||||
|
||||
MRS R0, CPSR
|
||||
TST LR, #0x01
|
||||
ORRNE R0, R0, 0x20 /* set thumb bit*/
|
||||
MRS R0, CPSR
|
||||
TST LR, #0x01
|
||||
ORRNE R0, R0, 0x20 /* set thumb bit*/
|
||||
|
||||
STMFD SP!, { R0 } /* save CPSR */
|
||||
STMFD SP!, { LR } /* save PC */
|
||||
STMFD SP!, { R0 } /* save CPSR */
|
||||
STMFD SP!, { LR } /* save PC */
|
||||
|
||||
LDR R0, [SP, #-0x4] /* restore R0 */
|
||||
STMFD SP!, { R0 - R12, LR }
|
||||
LDR R0, [SP, #-0x4] /* restore R0 */
|
||||
STMFD SP!, { R0 - R12, LR }
|
||||
|
||||
/* k_curr_task->sp = SP */
|
||||
LDR R0, =k_curr_task
|
||||
LDR R0, [R0]
|
||||
STR SP, [R0]
|
||||
LDR R0, =k_curr_task
|
||||
LDR R0, [R0]
|
||||
STR SP, [R0]
|
||||
|
||||
.L__context_restore:
|
||||
/* k_curr_task = k_next_task */
|
||||
LDR R0, =k_next_task
|
||||
LDR R0, [R0]
|
||||
LDR R1, =k_curr_task
|
||||
STR R0, [R1]
|
||||
LDR R0, =k_next_task
|
||||
LDR R0, [R0]
|
||||
LDR R1, =k_curr_task
|
||||
STR R0, [R1]
|
||||
|
||||
/* SP = k_next_task->sp */
|
||||
LDR SP, [R0]
|
||||
LDR SP, [R0]
|
||||
|
||||
LDMFD SP!, { R0 - R12, LR }
|
||||
RFEIA SP!
|
||||
LDMFD SP!, { R0 - R12, LR }
|
||||
RFEIA SP!
|
||||
|
||||
.type port_irq_context_switch, %function
|
||||
port_irq_context_switch:
|
||||
/* we already store the k_curr_task's context onto its stack by arm_irq(see saveall_offset) */
|
||||
|
||||
/* ATTENTION: our kernel always runs in SVC mode even in user task,
|
||||
/* ATTENTION:
|
||||
our kernel always runs in SVC mode even in user task,
|
||||
if one day we make the user task run in USR mode(although I cannot see any meaning to do this in RTOS),
|
||||
we must deal with more logic */
|
||||
we must deal with more logic
|
||||
*/
|
||||
B .L__context_restore /* magnificent */
|
||||
|
||||
|
@@ -34,8 +34,6 @@ k_stack_t task2_stack[512];
|
||||
|
||||
int main(void)
|
||||
{
|
||||
unsigned char state = OFF;
|
||||
|
||||
uart_init();
|
||||
led_init();
|
||||
beep_init();
|
||||
@@ -54,10 +52,6 @@ int main(void)
|
||||
|
||||
tos_knl_start();
|
||||
|
||||
while (1) {
|
||||
delay(3000);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user