lwp_rvds.S 4.6 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
;/*
; * File      : lwp_rvds.S
; * This file is part of RT-Thread RTOS
; * COPYRIGHT (C) 2006 - 2018, RT-Thread Development Team
; *
; *  This program is free software; you can redistribute it and/or modify
; *  it under the terms of the GNU General Public License as published by
; *  the Free Software Foundation; either version 2 of the License, or
; *  (at your option) any later version.
; *
; *  This program is distributed in the hope that it will be useful,
; *  but WITHOUT ANY WARRANTY; without even the implied warranty of
; *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
; *  GNU General Public License for more details.
; *
; *  You should have received a copy of the GNU General Public License along
; *  with this program; if not, write to the Free Software Foundation, Inc.,
; *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
; *
; * Change Logs:
; * Date           Author       Notes
; */

    AREA |.text|, CODE, READONLY, ALIGN=2
    THUMB
    REQUIRE8
    PRESERVE8

;/*
; * void* lwp_get_sys_api(rt_uint32_t number);
; */
    IMPORT lwp_get_sys_api
    IMPORT lwp_get_kernel_sp
    IMPORT lwp_set_kernel_sp

;/*
H
heyuanjie 已提交
37
; * void lwp_user_entry(args, text, data);
38 39 40 41
; */
lwp_user_entry    PROC
    EXPORT  lwp_user_entry

H
heyuanjie 已提交
42
    PUSH    {R0-R3}             ; push text&data addr.
43 44 45 46 47 48 49 50 51

    MOV     R0, SP              ; v1 = SP
    BL      lwp_set_kernel_sp   ; lwp_set_kernel_sp(v1)

    ; set CPU to user-thread mode.
    MRS     R2, CONTROL
    ORR     R2, R2, #0x03       ; use PSP, user-thread mode.
    MSR     CONTROL, R2

H
heyuanjie 已提交
52
    POP     {R0-R3}             ; pop app address to R1.
53
    ; set data address.
H
heyuanjie 已提交
54
    MOV     R9, R2
55 56

    ; run app, only Thumb-mode.
H
heyuanjie 已提交
57 58
    ORR     R1, R1, #0x01
    BX      R1
59 60 61 62

    ; never reach here!
    ENDP

H
heyuanjie 已提交
63

64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184
;/*
; * void SVC_Handler(void);
; */
SVC_Handler    PROC
    EXPORT SVC_Handler

    PUSH    {LR}

    ; get user SP.
    TST     LR, #0x4
    ITE     EQ
    MRSEQ   R1, MSP
    MRSNE   R1, PSP

    PUSH    {R1}                        ; push app SP.
    MOV     R2, R1

    STMFD   R2!, {R4 - R11}              ; push app R4-R11 to app stack , and R1 not change.

    ; get SVC number.
    LDR     R0, [R1, #24]               ; get the app LR.
    LDRB    R0, [R0, #-2]               ; get the SVC No. from instruction.

    ; get kernel system API
    BL      lwp_get_sys_api

    ; if(api == NULL) return;
    CMP     R0, #0
    POPEQ   {R1}
    POPEQ   {LR}
    BXEQ    LR

    ; push api
    PUSH    {R0}

    ; get kernel SP to R0.
    BL lwp_get_kernel_sp

    POP     {R2}                        ; pop api to R2.
    POP     {R1}                        ; pop app SP to R1.

    ; copy R1(app SP) to R0(server SP).
    LDMFD   R1,   {R4 - R11}     ; pop exception_stack_frame to r4 - r11 register
    STMFD   R0!,  {R4 - R11}     ; push exception_stack_frame to server SP.

    POP     {LR}
    PUSH    {LR}

    ; save app SP.
    PUSH    {R0 - R3}
    SUB     R0, R1, #0x20               ; keep {R4 - R11}
    BL      lwp_set_kernel_sp
    POP     {R0 - R3}

    ; set to thread-privilege mode.
    MRS     R3, CONTROL
    BIC     R3, R3, #0x01
    ORR     R3, R3, #0x02
    MSR     CONTROL, R3

    ; call api.
    LDR     R3, =svc_exit
    STR     R3, [R0, #20]       ; update LR
    STR     R2, [R0, #24]       ; update api to PC
    MSR     PSP, R0             ; update stack pointer
    POP     {LR}                ; 0xFFFFFFED

    ORR     LR, LR, #0x10

    BX      LR

    ENDP

;/*
; * void svc_exit(void);
; */
svc_exit     PROC
    EXPORT svc_exit

    ; get user SP.
    PUSH    {R0}                    ; push result to SP.
    BL      lwp_get_kernel_sp

    LDMFD   R0!, {R4 - R11}         ; pop app {R4 - R11}

    ADD     R0, R0, #16             ; skip R0-R3
    LDMFD   R0!, {R12, LR}          ;
    LDMFD   R0!, {R1}               ; pop PC to R1
    LDMFD   R0!, {R2}               ; pop PSR to R2

    ; align to 2 words
    ADD     R0, R0, #0x07
    BIC     R0, R0, #0x07
    PUSH    {R0}                    ; push user-SP to SP

    ; save server SP.
    ADD     R0, SP, #0x08           ; [user-SP, result]
    PUSH    {R1 - R2, LR}
    BL      lwp_set_kernel_sp
    POP     {R1 - R2, LR}

    POP     {R3}                    ; pop user-SP to R3
    POP     {R0}                    ; restore API result.

    MSR     APSR, R2                ; restore PSR
    MSR     PSP, R3                 ; restore app stack pointer

    ; restore to PSP & thread-unprivilege mode.
    MRS     R2, CONTROL
    ORR     R2, R2, #0x03
    MSR     CONTROL, R2

    ; return to lwp.
    ORR     R1, R1, #0x01           ; only Thumb-mode.
    BX      R1                      ; return to user app.

    ENDP

    ALIGN

    END