Arrow / Mbed OS DAPLink Reset
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers HAL_CM1.c Source File

HAL_CM1.c

Go to the documentation of this file.
00001 /**
00002  * @file    HAL_CM1.c
00003  * @brief   HAL for Cortex-M0(p)
00004  *
00005  * DAPLink Interface Firmware
00006  * Copyright (c) 2009-2016, ARM Limited, All Rights Reserved
00007  * SPDX-License-Identifier: Apache-2.0
00008  *
00009  * Licensed under the Apache License, Version 2.0 (the "License"); you may
00010  * not use this file except in compliance with the License.
00011  * You may obtain a copy of the License at
00012  *
00013  * http://www.apache.org/licenses/LICENSE-2.0
00014  *
00015  * Unless required by applicable law or agreed to in writing, software
00016  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
00017  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00018  * See the License for the specific language governing permissions and
00019  * limitations under the License.
00020  */
00021 
00022 #include "rt_TypeDef.h"
00023 #include "RTX_Config.h"
00024 #include "rt_System.h"
00025 #include "rt_HAL_CM.h"
00026 #include "rt_Task.h"
00027 #include "rt_List.h"
00028 #include "rt_MemBox.h"
00029 
00030 
00031 /*----------------------------------------------------------------------------
00032  *      Functions
00033  *---------------------------------------------------------------------------*/
00034 
00035 
00036 /*--------------------------- rt_set_PSP ------------------------------------*/
00037 
00038 __asm void rt_set_PSP (U32 stack) {
00039         MSR     PSP,R0
00040         BX      LR
00041 }
00042 
00043 
00044 /*--------------------------- rt_get_PSP ------------------------------------*/
00045 
00046 __asm U32 rt_get_PSP (void) {
00047         MRS     R0,PSP
00048         BX      LR
00049 }
00050 
00051 
00052 /*--------------------------- os_set_env ------------------------------------*/
00053 
00054 __asm void os_set_env (void) {
00055    /* Switch to Unprivileged/Privileged Thread mode, use PSP. */
00056         MOV     R0,SP                   ; PSP = MSP
00057         MSR     PSP,R0
00058         LDR     R0,=__cpp(&os_flags)
00059         LDRB    R0,[R0]
00060         LSLS    R0,#31
00061         BNE     PrivilegedE
00062         MOVS    R0,#0x03                ; Unprivileged Thread mode, use PSP
00063         MSR     CONTROL,R0
00064         BX      LR
00065 PrivilegedE
00066         MOVS    R0,#0x02                ; Privileged Thread mode, use PSP
00067         MSR     CONTROL,R0
00068         BX      LR
00069 
00070         ALIGN
00071 }
00072 
00073 
00074 /*--------------------------- _alloc_box ------------------------------------*/
00075 
00076 __asm void *_alloc_box (void *box_mem) {
00077    /* Function wrapper for Unprivileged/Privileged mode. */
00078         LDR     R3,=__cpp(rt_alloc_box)
00079         MOV     R12,R3
00080         MRS     R3,IPSR
00081         LSLS    R3,#24
00082         BNE     PrivilegedA
00083         MRS     R3,CONTROL
00084         LSLS    R3,#31
00085         BEQ     PrivilegedA
00086         SVC     0
00087         BX      LR
00088 PrivilegedA
00089         BX      R12
00090 
00091         ALIGN
00092 }
00093 
00094 
00095 /*--------------------------- _free_box -------------------------------------*/
00096 
00097 __asm int _free_box (void *box_mem, void *box) {
00098    /* Function wrapper for Unprivileged/Privileged mode. */
00099         LDR     R3,=__cpp(rt_free_box)
00100         MOV     R12,R3
00101         MRS     R3,IPSR
00102         LSLS    R3,#24
00103         BNE     PrivilegedF
00104         MRS     R3,CONTROL
00105         LSLS    R3,#31
00106         BEQ     PrivilegedF
00107         SVC     0
00108         BX      LR
00109 PrivilegedF
00110         BX      R12
00111 
00112         ALIGN
00113 }
00114 
00115 
00116 /*-------------------------- SVC_Handler ------------------------------------*/
00117 
00118 __asm void SVC_Handler (void) {
00119         PRESERVE8
00120 
00121         IMPORT  SVC_Count
00122         IMPORT  SVC_Table
00123         IMPORT  rt_stk_check
00124 
00125         MRS     R0,PSP                  ; Read PSP
00126         LDR     R1,[R0,#24]             ; Read Saved PC from Stack
00127         SUBS    R1,R1,#2                ; Point to SVC Instruction
00128         LDRB    R1,[R1]                 ; Load SVC Number
00129         CMP     R1,#0
00130         BNE     SVC_User                ; User SVC Number > 0
00131 
00132         MOV     LR,R4
00133         LDMIA   R0,{R0-R3,R4}           ; Read R0-R3,R12 from stack
00134         MOV     R12,R4
00135         MOV     R4,LR
00136         BLX     R12                     ; Call SVC Function
00137 
00138         LDR     R3,=__cpp(&os_tsk)
00139         LDMIA   R3!,{R1,R2}             ; os_tsk.run, os_tsk.new
00140         CMP     R1,R2
00141         BEQ     SVC_Exit                ; no task switch
00142 
00143         SUBS    R3,#8
00144         CMP     R1,#0                   ; Runtask deleted?
00145         BEQ     SVC_Restore
00146 
00147         PUSH    {R2,R3}
00148         ADDS    R1,#32                  ; for STRB offset < 32
00149         MOVS    R3,#1
00150         STRB    R3,[R1,#TCB_RETUPD-32]  ; os_tsk.run->ret_upd = 1
00151 
00152         MRS     R3,PSP                  ; Read PSP
00153         SUBS    R3,R3,#32               ; Adjust Start Address
00154         STR     R3,[R1,#TCB_TSTACK-32]  ; Update os_tsk.run->tsk_stack
00155         STMIA   R3!,{R4-R7}             ; Save old context (R4-R7)
00156         MOV     R4,R8
00157         MOV     R5,R9
00158         MOV     R6,R10
00159         MOV     R7,R11
00160         STMIA   R3!,{R4-R7}             ; Save old context (R8-R11)
00161         BL      rt_stk_check            ; Check for Stack overflow
00162         POP     {R2,R3}
00163 
00164 SVC_Restore
00165         STR     R2,[R3]                 ; os_tsk.run = os_tsk.new
00166 
00167         ADDS    R2,#32                  ; for STRB offset < 32
00168         LDR     R3,[R2,#TCB_TSTACK-32]  ; os_tsk.new->tsk_stack
00169         ADDS    R3,R3,#16               ; Adjust Start Address
00170         LDMIA   R3!,{R4-R7}             ; Restore new Context (R8-R11)
00171         MOV     R8,R4
00172         MOV     R9,R5
00173         MOV     R10,R6
00174         MOV     R11,R7
00175         MSR     PSP,R3                  ; Write PSP
00176         SUBS    R3,R3,#32               ; Adjust Start Address
00177         LDMIA   R3!,{R4-R7}             ; Restore new Context (R4-R7)
00178 
00179         LDRB    R0,[R2,#TCB_RETUPD-32]  ; Update ret_val ?
00180         CMP     R0,#0
00181         BEQ     SVC_Return
00182         LDRB    R0,[R2,#TCB_RETVAL-32]  ; Write os_tsk.new->ret_val
00183 
00184 SVC_Exit
00185         MRS     R3,PSP                  ; Read PSP
00186         STR     R0,[R3]                 ; Function return value
00187 
00188 SVC_Return
00189         MOVS    R3,#:NOT:0xFFFFFFFD     ; Set EXC_RETURN value
00190         MVNS    R3,R3
00191         BX      R3                      ; RETI to Thread Mode, use PSP
00192 
00193         /*------------------- User SVC ------------------------------*/
00194 
00195 SVC_User
00196         PUSH    {R4,LR}                 ; Save Registers
00197         LDR     R2,=SVC_Count
00198         LDR     R2,[R2]
00199         CMP     R1,R2
00200         BHI     SVC_Done                ; Overflow
00201 
00202         LDR     R4,=SVC_Table-4
00203         LSLS    R1,R1,#2
00204         LDR     R4,[R4,R1]              ; Load SVC Function Address
00205         MOV     LR,R4
00206 
00207         LDMIA   R0,{R0-R3,R4}           ; Read R0-R3,R12 from stack
00208         MOV     R12,R4
00209         BLX     LR                      ; Call SVC Function
00210 
00211         MRS     R4,PSP                  ; Read PSP
00212         STMIA   R4!,{R0-R3}             ; Function return values
00213 SVC_Done
00214         POP     {R4,PC}                 ; RETI
00215 
00216         ALIGN
00217 }
00218 
00219 
00220 /*-------------------------- PendSV_Handler ---------------------------------*/
00221 
00222 __asm void PendSV_Handler (void) {
00223         PRESERVE8
00224 
00225         BL      __cpp(rt_pop_req)
00226 
00227 Sys_Switch
00228         LDR     R3,=__cpp(&os_tsk)
00229         LDMIA   R3!,{R1,R2}             ; os_tsk.run, os_tsk.new
00230         CMP     R1,R2
00231         BEQ     Sys_Exit                ; no task switch
00232 
00233         SUBS    R3,#8
00234         PUSH    {R2,R3}
00235         ADDS    R1,#32                  ; for STRB offset < 32
00236 
00237         MOVS    R3,#0
00238         STRB    R3,[R1,#TCB_RETUPD-32]  ; os_tsk.run->ret_upd = 0
00239         MRS     R3,PSP                  ; Read PSP
00240         SUBS    R3,R3,#32               ; Adjust Start Address
00241         STR     R3,[R1,#TCB_TSTACK-32]  ; Update os_tsk.run->tsk_stack
00242         STMIA   R3!,{R4-R7}             ; Save old context (R4-R7)
00243         MOV     R4,R8
00244         MOV     R5,R9
00245         MOV     R6,R10
00246         MOV     R7,R11
00247         STMIA   R3!,{R4-R7}             ; Save old context (R8-R11)
00248         BL      rt_stk_check            ; Check for Stack overflow
00249 
00250         POP     {R2,R3}
00251         STR     R2,[R3]                 ; os_tsk.run = os_tsk.new
00252         ADDS    R2,#32                  ; for STRB offset < 32
00253 
00254         LDR     R3,[R2,#TCB_TSTACK-32]  ; os_tsk.new->tsk_stack
00255         ADDS    R3,R3,#16               ; Adjust Start Address
00256         LDMIA   R3!,{R4-R7}             ; Restore new Context (R8-R11)
00257         MOV     R8,R4
00258         MOV     R9,R5
00259         MOV     R10,R6
00260         MOV     R11,R7
00261         MSR     PSP,R3                  ; Write PSP
00262         SUBS    R3,R3,#32               ; Adjust Start Address
00263         LDMIA   R3!,{R4-R7}             ; Restore new Context (R4-R7)
00264 
00265         LDRB    R0,[R2,#TCB_RETUPD-32]  ; Update ret_val ?
00266         CMP     R0,#0
00267         BEQ     Sys_Exit
00268         LDRB    R0,[R2,#TCB_RETVAL-32]  ; Write os_tsk.new->ret_val
00269         STR     R0,[R3,#16]
00270 Sys_Exit
00271         MOVS    R3,#:NOT:0xFFFFFFFD     ; Set EXC_RETURN value
00272         MVNS    R3,R3
00273         BX      R3                      ; RETI to Thread Mode, use PSP
00274 
00275         ALIGN
00276 }
00277 
00278 
00279 /*-------------------------- SysTick_Handler --------------------------------*/
00280 
00281 __asm void SysTick_Handler (void) {
00282         PRESERVE8
00283 
00284         BL      __cpp(rt_systick)
00285         B       Sys_Switch
00286 
00287         ALIGN
00288 }
00289 
00290 
00291 /*-------------------------- OS_Tick_Handler --------------------------------*/
00292 
00293 __asm void OS_Tick_Handler (void) {
00294         PRESERVE8
00295 
00296         BL      __cpp(os_tick_irqack)
00297         BL      __cpp(rt_systick)
00298         B       Sys_Switch
00299 
00300         ALIGN
00301 }
00302 
00303 
00304 /*--------------------------- rt_init_stack ---------------------------------*/
00305 
00306 void rt_init_stack (P_TCB p_TCB, FUNCP task_body) {
00307   /* Prepare TCB and saved context for a first time start of a task. */
00308   U32 *stk,i,size;
00309 
00310   /* Prepare a complete interrupt frame for first task start */
00311   size = p_TCB->priv_stack >> 2;
00312   if (size == 0) {
00313     size = (U16)os_stackinfo >> 2;
00314   }
00315 
00316   /* Write to the top of stack. */
00317   stk = &p_TCB->stack[size];
00318 
00319   /* Auto correct to 8-byte ARM stack alignment. */
00320   if ((U32)stk & 0x04) {
00321     stk--;
00322   }
00323 
00324   stk -= 16;
00325 
00326   /* Default xPSR and initial PC */
00327   stk[15] = INITIAL_xPSR;
00328   stk[14] = (U32)task_body;
00329 
00330   /* Clear R1-R12,LR registers. */
00331   for (i = 0; i < 14; i++) {
00332     stk[i] = 0;
00333   }
00334 
00335   /* Assign a void pointer to R0. */
00336   stk[8] = (U32)p_TCB->msg;
00337 
00338   /* Initial Task stack pointer. */
00339   p_TCB->tsk_stack = (U32)stk;
00340 
00341   /* Task entry point. */
00342   p_TCB->ptask = task_body;
00343 
00344   /* Set a magic word for checking of stack overflow. */
00345   p_TCB->stack[0] = MAGIC_WORD;
00346 }
00347 
00348 
00349 /*----------------------------------------------------------------------------
00350  * end of file
00351  *---------------------------------------------------------------------------*/
00352