extract exceptions.h

This commit is contained in:
daishengdong
2020-01-19 20:37:57 +08:00
parent 3d9d6198c8
commit 8588240c82
4 changed files with 235 additions and 228 deletions

View File

@@ -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

View 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

View File

@@ -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 */

View File

@@ -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;
}