⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 except.s

📁 本程序为ST公司开发的源代码
💻 S
字号:
    PRESERVE8

    EXPORT init_system
    EXPORT handler_svc
    EXPORT rescheduleFromInterrupt
    EXPORT rescheduleRequired
    EXPORT interruptCount
    EXPORT save_user_state
    EXPORT restore_user_state
    EXPORT os_result_exit
    EXPORT os_void_exit
    EXPORT irqSP
    IMPORT handle_system_call
    IMPORT os_task_select

    AREA    exception, CODE, READONLY

    GET saveregisters.s

    ;-----------------------------------------------------------------------
    ; init_system(unsigned char *superstacktop, unsigned char *irqstacktop);
    ;-----------------------------------------------------------------------

init_system
    ; In OS20 original project it was used to initialize either superSP/irqSP
    ; variables and stacks IRQ/SVC. and only at the end it goes in USER_MODE.
    ; New init_system function only initilize superSP/irqSP.

    ; save SVC mode stack in superSP
    LDR     r2, =superSP              ; r2 = &superSP
    STR     r0, [r2]                  ; *r2 = r0 (= superstacktop)
    ;
    ; save IRQ mode stack in irqSP
    LDR     r2, =irqSP                ; r2 = &irqSP
    STR     r1, [r2]                  ; *r2 = r1 (= irqstacktop)
    ;
    ;continue into user mode with interrupts enabled and restore lr
    MOV     pc, lr                    ;return

    ;-------------
    ; handler_svc
    ;-------------

handler_svc
    ; reset supervisor stack, left in a mess by os_exit
    LDR     sp, =superSP
    LDR     sp, [sp]
    STMFD   sp!, {r0-r2}          ;save some scratch registers

    ; get the SWI operand
    LDR     r0, [lr,#-4]          ;load the SWI instruction into r0
    BIC     r0, r0, #0xff000000   ;mask off the top 8 bits to give SWI instruction number
;>>>>>>>> JUMP TABLE
    MRS     r2 , spsr       ; Save SPSR
    CMP     r0,#0x100       ;check if OS20call
    BLT     OS20call
    SUB     r0,r0,#0x100
    ADD     r0,r0,#0x40000000
    LDR     lr,[r0,#0]
    TST     lr , #0x01      ; Thumb Procedure ?
    BNE     THUMB_LBL
    MSR     spsr_cf , r2
    LDMFD   sp!, {r0-r2}    ;put saved registers back
    MOVS    pc , lr         ;this will return from exception to
THUMB_LBL
    ORR     r2 , r2 , #0x20 ;Set T Flag
    MSR     spsr_cf , r2
    LDMFD   sp!, {r0-r2}        ;put saved registers back
    MOVS    pc , lr
;


OS20call
;
;>>>>>>>> JUMP TABLE
notSemiHost
    ;
    ; deal with interrupt disable/enable directly (using the funky conditional instructions)
    ;
    MRS     r2, spsr              ;get the spsr value (saved cpsr)
    TEQ     r0, #0x0              ;intdis_e
    ORREQ   r2, r2, #0x80
    BEQ     isintop
    TEQ     r0, #0x1              ;intenb_e
    BICEQ   r2, r2, #0x80
    BNE     notintop
isintop
    MSR     spsr_cf, r2
    LDMFD   sp!, {r0-r2}          ;put saved registers back
    MOVS    pc, lr                ;return from exception
notintop
    SAVE_REGISTERS

    BL handle_system_call         ;handle_system_call(swi,regs[numregs])
    ;should never come back here...

    ;---------------------------------
    ; rescheduleFromInterrupt
    ;---------------------------------
    ; pre: running in IRQ mode on IRQ stack
    ;      user state intact

rescheduleFromInterrupt
    ;
    ; get the registers into a state so that SAVE_REGISTERS can be called
    ;
    STMFD   sp!, {r0-r2}          ;save some scratch registers
    MRS     r2, spsr              ;put saved psr into r2
    SAVE_REGISTERS
    ;
    ; rescheduleRequired = 0
    ;
    MOV     r0, #0
    LDR     r1, =rescheduleRequired
    STR     r0, [r1]
    BL      os_task_select
    ;should never come back here....

    ;---------------------------------
    ; unsigned *save_user_state(void)
    ;---------------------------------

save_user_state
    LDR     r0, =savedUserSP;
    LDR     r0, [r0]
    MOV     pc, lr                    ;return

    ;-------------------------------------
    ; void restore_user_state(unsigned *)
    ;-------------------------------------

restore_user_state
    LDR     r1, =savedUserSP;
    STR     r0, [r1];
    MOV     pc, lr                    ;return

    ;---------------------------------
    ; void os_result_exit(int result)
    ;---------------------------------

os_result_exit
    LDR     r1, =savedUserSP;
    LDR     r1, [r1];
    STR     r0, [r1];

    ;---------------------
    ; void os_void_exit()
    ;---------------------

os_void_exit
    ;
    ; rescheduleRequired = 0
    ;
    ;MOV     r0, #0
    ;LDR     r1, =rescheduleRequired
    ;STR     r0, [r1]
    ;
    ; if(mode==IRQ)
    ;   sp = irqSP
    ; else
    ;   sp = superSP
    ;
    MRS     r0, CPSR
    AND     r0, r0, #0x1f ; mask off mode bits
    TEQ     r0, #0x13     ; test eq to SVC mode
    LDRNE   r1, =irqSP
    LDREQ   r1, =superSP
    LDR     sp, [r1]
    ;
    ; r1 = savedUserSP
    ;
    LDR     r1, =savedUserSP
    LDR     r1, [r1]              ;r1 contains pointer to registers, r1/*0*/[0] = register 0 etc
    ;
    ; spsr = savedUserSP[psr]
    ;
    LDR     r0, [r1,#16*4]        ;get cpsr value
    MSR     spsr_cf, r0           ;and restore into spsr
    ;
    ; lr = savedUserSP[pc]
    ;
    LDR     lr, [r1,#15*4]
    ;
    ; r{0..14} = savedUserSP[0..14]
    ;
    LDMFD   r1, {r0 - r14}^
    NOP
    ;
    ; move into user mode with PC = lr
    ;
    MOVS    pc, lr

    AREA    var, DATA, READWRITE

savedUserSP
    DCD     0x00000000  ;Current task user stack pointer
superSP
    DCD     0x00000000  ;contains supervisor stack pointer
irqSP
    DCD     0x00000000  ;contains irq stack pointer
interruptCount
    DCD     0x00000000  ;interrupt nesting count
rescheduleRequired
    DCD     0x00000000  ;a reschedule has been requested from an interrupt handler
    END

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -