mbed client lightswitch demo

Dependencies:   mbed Socket lwip-eth lwip-sys lwip

Fork of mbed-client-classic-example-lwip by Austin Blackstone

Committer:
mbedAustin
Date:
Thu Jun 09 17:08:36 2016 +0000
Revision:
11:cada08fc8a70
Commit for public Consumption

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mbedAustin 11:cada08fc8a70 1 /*----------------------------------------------------------------------------
mbedAustin 11:cada08fc8a70 2 * RL-ARM - RTX
mbedAustin 11:cada08fc8a70 3 *----------------------------------------------------------------------------
mbedAustin 11:cada08fc8a70 4 * Name: HAL_CA9.c
mbedAustin 11:cada08fc8a70 5 * Purpose: Hardware Abstraction Layer for Cortex-A9
mbedAustin 11:cada08fc8a70 6 * Rev.: 8 April 2015
mbedAustin 11:cada08fc8a70 7 *----------------------------------------------------------------------------
mbedAustin 11:cada08fc8a70 8 *
mbedAustin 11:cada08fc8a70 9 * Copyright (c) 2012 - 2015 ARM Limited
mbedAustin 11:cada08fc8a70 10 * All rights reserved.
mbedAustin 11:cada08fc8a70 11 * Redistribution and use in source and binary forms, with or without
mbedAustin 11:cada08fc8a70 12 * modification, are permitted provided that the following conditions are met:
mbedAustin 11:cada08fc8a70 13 * - Redistributions of source code must retain the above copyright
mbedAustin 11:cada08fc8a70 14 * notice, this list of conditions and the following disclaimer.
mbedAustin 11:cada08fc8a70 15 * - Redistributions in binary form must reproduce the above copyright
mbedAustin 11:cada08fc8a70 16 * notice, this list of conditions and the following disclaimer in the
mbedAustin 11:cada08fc8a70 17 * documentation and/or other materials provided with the distribution.
mbedAustin 11:cada08fc8a70 18 * - Neither the name of ARM nor the names of its contributors may be used
mbedAustin 11:cada08fc8a70 19 * to endorse or promote products derived from this software without
mbedAustin 11:cada08fc8a70 20 * specific prior written permission.
mbedAustin 11:cada08fc8a70 21 *
mbedAustin 11:cada08fc8a70 22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
mbedAustin 11:cada08fc8a70 23 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
mbedAustin 11:cada08fc8a70 24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
mbedAustin 11:cada08fc8a70 25 * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
mbedAustin 11:cada08fc8a70 26 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
mbedAustin 11:cada08fc8a70 27 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
mbedAustin 11:cada08fc8a70 28 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
mbedAustin 11:cada08fc8a70 29 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
mbedAustin 11:cada08fc8a70 30 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
mbedAustin 11:cada08fc8a70 31 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
mbedAustin 11:cada08fc8a70 32 * POSSIBILITY OF SUCH DAMAGE.
mbedAustin 11:cada08fc8a70 33 *---------------------------------------------------------------------------*/
mbedAustin 11:cada08fc8a70 34
mbedAustin 11:cada08fc8a70 35 PUBLIC rt_set_PSP
mbedAustin 11:cada08fc8a70 36 PUBLIC rt_get_PSP
mbedAustin 11:cada08fc8a70 37 PUBLIC _alloc_box
mbedAustin 11:cada08fc8a70 38 PUBLIC _free_box
mbedAustin 11:cada08fc8a70 39 PUBLIC SWI_Handler
mbedAustin 11:cada08fc8a70 40 PUBLIC PendSV_Handler
mbedAustin 11:cada08fc8a70 41 PUBLIC OS_Tick_Handler
mbedAustin 11:cada08fc8a70 42
mbedAustin 11:cada08fc8a70 43 /* macro defines form rt_HAL_CA.h */
mbedAustin 11:cada08fc8a70 44 #define CPSR_T_BIT 0x20
mbedAustin 11:cada08fc8a70 45 #define CPSR_I_BIT 0x80
mbedAustin 11:cada08fc8a70 46 #define CPSR_F_BIT 0x40
mbedAustin 11:cada08fc8a70 47
mbedAustin 11:cada08fc8a70 48 #define MODE_USR 0x10
mbedAustin 11:cada08fc8a70 49 #define MODE_FIQ 0x11
mbedAustin 11:cada08fc8a70 50 #define MODE_IRQ 0x12
mbedAustin 11:cada08fc8a70 51 #define MODE_SVC 0x13
mbedAustin 11:cada08fc8a70 52 #define MODE_ABT 0x17
mbedAustin 11:cada08fc8a70 53 #define MODE_UND 0x1B
mbedAustin 11:cada08fc8a70 54 #define MODE_SYS 0x1F
mbedAustin 11:cada08fc8a70 55
mbedAustin 11:cada08fc8a70 56 /* macro defines form rt_TypeDef.h */
mbedAustin 11:cada08fc8a70 57 #define TCB_TID 3 /* 'task id' offset */
mbedAustin 11:cada08fc8a70 58 #define TCB_STACKF 37 /* 'stack_frame' offset */
mbedAustin 11:cada08fc8a70 59 #ifndef __LARGE_PRIV_STACK
mbedAustin 11:cada08fc8a70 60 #define TCB_TSTACK 40 /* 'tsk_stack' offset */
mbedAustin 11:cada08fc8a70 61 #else
mbedAustin 11:cada08fc8a70 62 #define TCB_TSTACK 44 /* 'tsk_stack' offset for LARGE_STACK */
mbedAustin 11:cada08fc8a70 63 #endif
mbedAustin 11:cada08fc8a70 64
mbedAustin 11:cada08fc8a70 65
mbedAustin 11:cada08fc8a70 66 IMPORT rt_alloc_box
mbedAustin 11:cada08fc8a70 67 IMPORT rt_free_box
mbedAustin 11:cada08fc8a70 68 IMPORT os_tsk
mbedAustin 11:cada08fc8a70 69 IMPORT GICInterface_BASE
mbedAustin 11:cada08fc8a70 70 IMPORT rt_pop_req
mbedAustin 11:cada08fc8a70 71 IMPORT os_tick_irqack
mbedAustin 11:cada08fc8a70 72 IMPORT rt_systick
mbedAustin 11:cada08fc8a70 73
mbedAustin 11:cada08fc8a70 74 SECTION `.text`:CODE:ROOT(2)
mbedAustin 11:cada08fc8a70 75
mbedAustin 11:cada08fc8a70 76 /*----------------------------------------------------------------------------
mbedAustin 11:cada08fc8a70 77 * Functions
mbedAustin 11:cada08fc8a70 78 *---------------------------------------------------------------------------*/
mbedAustin 11:cada08fc8a70 79
mbedAustin 11:cada08fc8a70 80 //For A-class, set USR/SYS stack
mbedAustin 11:cada08fc8a70 81 //__asm void rt_set_PSP (U32 stack) {
mbedAustin 11:cada08fc8a70 82 rt_set_PSP:
mbedAustin 11:cada08fc8a70 83 ARM
mbedAustin 11:cada08fc8a70 84
mbedAustin 11:cada08fc8a70 85 MRS R1, CPSR
mbedAustin 11:cada08fc8a70 86 CPS #MODE_SYS ;no effect in USR mode
mbedAustin 11:cada08fc8a70 87 ISB
mbedAustin 11:cada08fc8a70 88 MOV SP, R0
mbedAustin 11:cada08fc8a70 89 MSR CPSR_c, R1 ;no effect in USR mode
mbedAustin 11:cada08fc8a70 90 ISB
mbedAustin 11:cada08fc8a70 91 BX LR
mbedAustin 11:cada08fc8a70 92
mbedAustin 11:cada08fc8a70 93 //}
mbedAustin 11:cada08fc8a70 94
mbedAustin 11:cada08fc8a70 95 //For A-class, get USR/SYS stack
mbedAustin 11:cada08fc8a70 96 //__asm U32 rt_get_PSP (void) {
mbedAustin 11:cada08fc8a70 97 rt_get_PSP:
mbedAustin 11:cada08fc8a70 98 ARM
mbedAustin 11:cada08fc8a70 99
mbedAustin 11:cada08fc8a70 100 MRS R1, CPSR
mbedAustin 11:cada08fc8a70 101 CPS #MODE_SYS ;no effect in USR mode
mbedAustin 11:cada08fc8a70 102 ISB
mbedAustin 11:cada08fc8a70 103 MOV R0, SP
mbedAustin 11:cada08fc8a70 104 MSR CPSR_c, R1 ;no effect in USR mode
mbedAustin 11:cada08fc8a70 105 ISB
mbedAustin 11:cada08fc8a70 106 BX LR
mbedAustin 11:cada08fc8a70 107 //}
mbedAustin 11:cada08fc8a70 108
mbedAustin 11:cada08fc8a70 109 /*--------------------------- _alloc_box ------------------------------------*/
mbedAustin 11:cada08fc8a70 110 //__asm void *_alloc_box (void *box_mem) {
mbedAustin 11:cada08fc8a70 111 _alloc_box:
mbedAustin 11:cada08fc8a70 112 /* Function wrapper for Unprivileged/Privileged mode. */
mbedAustin 11:cada08fc8a70 113 ARM
mbedAustin 11:cada08fc8a70 114
mbedAustin 11:cada08fc8a70 115 LDR R12,=(rt_alloc_box)
mbedAustin 11:cada08fc8a70 116 MRS R2, CPSR
mbedAustin 11:cada08fc8a70 117 LSLS R2, R2,#28
mbedAustin 11:cada08fc8a70 118 BXNE R12
mbedAustin 11:cada08fc8a70 119 SVC 0
mbedAustin 11:cada08fc8a70 120 BX LR
mbedAustin 11:cada08fc8a70 121 //}
mbedAustin 11:cada08fc8a70 122
mbedAustin 11:cada08fc8a70 123
mbedAustin 11:cada08fc8a70 124 /*--------------------------- _free_box -------------------------------------*/
mbedAustin 11:cada08fc8a70 125 //__asm int _free_box (void *box_mem, void *box) {
mbedAustin 11:cada08fc8a70 126 _free_box:
mbedAustin 11:cada08fc8a70 127 /* Function wrapper for Unprivileged/Privileged mode. */
mbedAustin 11:cada08fc8a70 128
mbedAustin 11:cada08fc8a70 129 LDR R12,=(rt_free_box)
mbedAustin 11:cada08fc8a70 130 MRS R2, CPSR
mbedAustin 11:cada08fc8a70 131 LSLS R2, R2,#28
mbedAustin 11:cada08fc8a70 132 BXNE R12
mbedAustin 11:cada08fc8a70 133 SVC 0
mbedAustin 11:cada08fc8a70 134 BX LR
mbedAustin 11:cada08fc8a70 135
mbedAustin 11:cada08fc8a70 136 //}
mbedAustin 11:cada08fc8a70 137
mbedAustin 11:cada08fc8a70 138 /*-------------------------- SWI_Handler -----------------------------------*/
mbedAustin 11:cada08fc8a70 139
mbedAustin 11:cada08fc8a70 140 //#pragma push
mbedAustin 11:cada08fc8a70 141 //#pragma arm
mbedAustin 11:cada08fc8a70 142 //__asm void SWI_Handler (void) {
mbedAustin 11:cada08fc8a70 143 SWI_Handler:
mbedAustin 11:cada08fc8a70 144 PRESERVE8
mbedAustin 11:cada08fc8a70 145 ARM
mbedAustin 11:cada08fc8a70 146
mbedAustin 11:cada08fc8a70 147 IMPORT rt_tsk_lock
mbedAustin 11:cada08fc8a70 148 IMPORT rt_tsk_unlock
mbedAustin 11:cada08fc8a70 149 IMPORT SVC_Count
mbedAustin 11:cada08fc8a70 150 IMPORT SVC_Table
mbedAustin 11:cada08fc8a70 151 IMPORT rt_stk_check
mbedAustin 11:cada08fc8a70 152 IMPORT FPUEnable
mbedAustin 11:cada08fc8a70 153 IMPORT scheduler_suspended ; flag set by rt_suspend, cleared by rt_resume, read by SWI_Handler
mbedAustin 11:cada08fc8a70 154
mbedAustin 11:cada08fc8a70 155 Mode_SVC EQU 0x13
mbedAustin 11:cada08fc8a70 156
mbedAustin 11:cada08fc8a70 157 SRSDB #Mode_SVC! ; Push LR_SVC and SPRS_SVC onto SVC mode stack
mbedAustin 11:cada08fc8a70 158 STR R4,[SP,#-0x4]! ; Push R4 so we can use it as a temp
mbedAustin 11:cada08fc8a70 159
mbedAustin 11:cada08fc8a70 160 MRS R4,SPSR ; Get SPSR
mbedAustin 11:cada08fc8a70 161 TST R4,#CPSR_T_BIT ; Check Thumb Bit
mbedAustin 11:cada08fc8a70 162 LDRNEH R4,[LR,#-2] ; Thumb: Load Halfword
mbedAustin 11:cada08fc8a70 163 BICNE R4,R4,#0xFF00 ; Extract SVC Number
mbedAustin 11:cada08fc8a70 164 LDREQ R4,[LR,#-4] ; ARM: Load Word
mbedAustin 11:cada08fc8a70 165 BICEQ R4,R4,#0xFF000000 ; Extract SVC Number
mbedAustin 11:cada08fc8a70 166
mbedAustin 11:cada08fc8a70 167 /* Lock out systick and re-enable interrupts */
mbedAustin 11:cada08fc8a70 168 STMDB SP!,{R0-R3,R12,LR}
mbedAustin 11:cada08fc8a70 169
mbedAustin 11:cada08fc8a70 170 AND R12, SP, #4 ; Ensure stack is 8-byte aligned
mbedAustin 11:cada08fc8a70 171 SUB SP, SP, R12 ; Adjust stack
mbedAustin 11:cada08fc8a70 172 STMDB SP!,{R12, LR} ; Store stack adjustment and dummy LR to SVC stack
mbedAustin 11:cada08fc8a70 173
mbedAustin 11:cada08fc8a70 174 BLX rt_tsk_lock
mbedAustin 11:cada08fc8a70 175 CPSIE i
mbedAustin 11:cada08fc8a70 176
mbedAustin 11:cada08fc8a70 177 LDMIA SP!,{R12,LR} ; Get stack adjustment & discard dummy LR
mbedAustin 11:cada08fc8a70 178 ADD SP, SP, R12 ; Unadjust stack
mbedAustin 11:cada08fc8a70 179
mbedAustin 11:cada08fc8a70 180 LDMIA SP!,{R0-R3,R12,LR}
mbedAustin 11:cada08fc8a70 181
mbedAustin 11:cada08fc8a70 182 CMP R4,#0
mbedAustin 11:cada08fc8a70 183 BNE SVC_User
mbedAustin 11:cada08fc8a70 184
mbedAustin 11:cada08fc8a70 185 MRS R4,SPSR
mbedAustin 11:cada08fc8a70 186 STR R4,[SP,#-0x4]! ; Push R4 so we can use it as a temp
mbedAustin 11:cada08fc8a70 187 AND R4, SP, #4 ; Ensure stack is 8-byte aligned
mbedAustin 11:cada08fc8a70 188 SUB SP, SP, R4 ; Adjust stack
mbedAustin 11:cada08fc8a70 189 STMDB SP!,{R4, LR} ; Store stack adjustment and dummy LR
mbedAustin 11:cada08fc8a70 190 BLX R12
mbedAustin 11:cada08fc8a70 191 LDMIA SP!,{R4, LR} ; Get stack adjustment & discard dummy LR
mbedAustin 11:cada08fc8a70 192 ADD SP, SP, R4 ; Unadjust stack
mbedAustin 11:cada08fc8a70 193 LDR R4,[SP],#0x4 ; Restore R4
mbedAustin 11:cada08fc8a70 194 MSR SPSR_CXSF,R4
mbedAustin 11:cada08fc8a70 195
mbedAustin 11:cada08fc8a70 196 /* Here we will be in SVC mode (even if coming in from PendSV_Handler or OS_Tick_Handler) */
mbedAustin 11:cada08fc8a70 197 Sys_Switch:
mbedAustin 11:cada08fc8a70 198 LDR LR,=(os_tsk)
mbedAustin 11:cada08fc8a70 199 LDMIA LR,{R4,LR} ; os_tsk.run, os_tsk.new
mbedAustin 11:cada08fc8a70 200 CMP R4,LR
mbedAustin 11:cada08fc8a70 201 BNE switching
mbedAustin 11:cada08fc8a70 202
mbedAustin 11:cada08fc8a70 203 STMDB SP!,{R0-R3,R12,LR}
mbedAustin 11:cada08fc8a70 204
mbedAustin 11:cada08fc8a70 205 AND R12, SP, #4 ; Ensure stack is 8-byte aligned
mbedAustin 11:cada08fc8a70 206 SUB SP, SP, R12 ; Adjust stack
mbedAustin 11:cada08fc8a70 207 STMDB SP!,{R12,LR} ; Store stack adjustment and dummy LR to SVC stack
mbedAustin 11:cada08fc8a70 208
mbedAustin 11:cada08fc8a70 209 CPSID i
mbedAustin 11:cada08fc8a70 210 ; Do not unlock scheduler if it has just been suspended by rt_suspend()
mbedAustin 11:cada08fc8a70 211 LDR R1,=scheduler_suspended
mbedAustin 11:cada08fc8a70 212 LDRB R0, [R1]
mbedAustin 11:cada08fc8a70 213 CMP R0, #1
mbedAustin 11:cada08fc8a70 214 BEQ dont_unlock
mbedAustin 11:cada08fc8a70 215 BLX rt_tsk_unlock
mbedAustin 11:cada08fc8a70 216 dont_unlock:
mbedAustin 11:cada08fc8a70 217
mbedAustin 11:cada08fc8a70 218 LDMIA SP!,{R12,LR} ; Get stack adjustment & discard dummy LR
mbedAustin 11:cada08fc8a70 219 ADD SP, SP, R12 ; Unadjust stack
mbedAustin 11:cada08fc8a70 220
mbedAustin 11:cada08fc8a70 221 LDMIA SP!,{R0-R3,R12,LR}
mbedAustin 11:cada08fc8a70 222 LDR R4,[SP],#0x4
mbedAustin 11:cada08fc8a70 223 RFEFD SP! ; Return from exception, no task switch
mbedAustin 11:cada08fc8a70 224
mbedAustin 11:cada08fc8a70 225 switching:
mbedAustin 11:cada08fc8a70 226 CLREX
mbedAustin 11:cada08fc8a70 227 CMP R4,#0
mbedAustin 11:cada08fc8a70 228 ADDEQ SP,SP,#12 ; Original R4, LR & SPSR do not need to be popped when we are paging in a different task
mbedAustin 11:cada08fc8a70 229 BEQ SVC_Next ; Runtask deleted?
mbedAustin 11:cada08fc8a70 230
mbedAustin 11:cada08fc8a70 231
mbedAustin 11:cada08fc8a70 232 STMDB SP!,{R8-R11} //R4 and LR already stacked
mbedAustin 11:cada08fc8a70 233 MOV R10,R4 ; Preserve os_tsk.run
mbedAustin 11:cada08fc8a70 234 MOV R11,LR ; Preserve os_tsk.new
mbedAustin 11:cada08fc8a70 235
mbedAustin 11:cada08fc8a70 236 ADD R8,SP,#16 ; Unstack R4,LR
mbedAustin 11:cada08fc8a70 237 LDMIA R8,{R4,LR}
mbedAustin 11:cada08fc8a70 238
mbedAustin 11:cada08fc8a70 239 SUB SP,SP,#4 ; Make space on the stack for the next instn
mbedAustin 11:cada08fc8a70 240 STMIA SP,{SP}^ ; Put User SP onto stack
mbedAustin 11:cada08fc8a70 241 LDR R8,[SP],#0x4 ; Pop User SP into R8
mbedAustin 11:cada08fc8a70 242
mbedAustin 11:cada08fc8a70 243 MRS R9,SPSR
mbedAustin 11:cada08fc8a70 244 STMDB R8!,{R9} ; User CPSR
mbedAustin 11:cada08fc8a70 245 STMDB R8!,{LR} ; User PC
mbedAustin 11:cada08fc8a70 246 STMDB R8,{LR}^ ; User LR
mbedAustin 11:cada08fc8a70 247 SUB R8,R8,#4 ; No writeback for store of User LR
mbedAustin 11:cada08fc8a70 248 STMDB R8!,{R0-R3,R12} ; User R0-R3,R12
mbedAustin 11:cada08fc8a70 249 MOV R3,R10 ; os_tsk.run
mbedAustin 11:cada08fc8a70 250 MOV LR,R11 ; os_tsk.new
mbedAustin 11:cada08fc8a70 251 LDMIA SP!,{R9-R12}
mbedAustin 11:cada08fc8a70 252 ADD SP,SP,#12 ; Fix up SP for unstack of R4, LR & SPSR
mbedAustin 11:cada08fc8a70 253 STMDB R8!,{R4-R7,R9-R12} ; User R4-R11
mbedAustin 11:cada08fc8a70 254
mbedAustin 11:cada08fc8a70 255 //If applicable, stack VFP/NEON state
mbedAustin 11:cada08fc8a70 256 MRC p15,0,R1,c1,c0,2 ; VFP/NEON access enabled? (CPACR)
mbedAustin 11:cada08fc8a70 257 AND R2,R1,#0x00F00000
mbedAustin 11:cada08fc8a70 258 CMP R2,#0x00F00000
mbedAustin 11:cada08fc8a70 259 BNE no_outgoing_vfp
mbedAustin 11:cada08fc8a70 260 VMRS R2,FPSCR
mbedAustin 11:cada08fc8a70 261 STMDB R8!,{R2,R4} ; Push FPSCR, maintain 8-byte alignment
mbedAustin 11:cada08fc8a70 262 //IF {TARGET_FEATURE_EXTENSION_REGISTER_COUNT} == 32
mbedAustin 11:cada08fc8a70 263 VSTMDB R8!,{D0-D15}
mbedAustin 11:cada08fc8a70 264 VSTMDB R8!,{D16-D31}
mbedAustin 11:cada08fc8a70 265 LDRB R2,[R3,#TCB_STACKF] ; Record in TCB that NEON/D32 state is stacked
mbedAustin 11:cada08fc8a70 266 ORR R2,R2,#4
mbedAustin 11:cada08fc8a70 267 STRB R2,[R3,#TCB_STACKF]
mbedAustin 11:cada08fc8a70 268 //ENDIF
mbedAustin 11:cada08fc8a70 269
mbedAustin 11:cada08fc8a70 270 no_outgoing_vfp:
mbedAustin 11:cada08fc8a70 271 STR R8,[R3,#TCB_TSTACK]
mbedAustin 11:cada08fc8a70 272 MOV R4,LR
mbedAustin 11:cada08fc8a70 273
mbedAustin 11:cada08fc8a70 274 STR R4,[SP,#-0x4]! ; Push R4 so we can use it as a temp
mbedAustin 11:cada08fc8a70 275 AND R4, SP, #4 ; Ensure stack is 8-byte aligned
mbedAustin 11:cada08fc8a70 276 SUB SP, SP, R4 ; Adjust stack
mbedAustin 11:cada08fc8a70 277 STMDB SP!,{R4, LR} ; Store stack adjustment and dummy LR to SVC stack
mbedAustin 11:cada08fc8a70 278
mbedAustin 11:cada08fc8a70 279 BLX rt_stk_check
mbedAustin 11:cada08fc8a70 280
mbedAustin 11:cada08fc8a70 281 LDMIA SP!,{R4, LR} ; Get stack adjustment & discard dummy LR
mbedAustin 11:cada08fc8a70 282 ADD SP, SP, R4 ; Unadjust stack
mbedAustin 11:cada08fc8a70 283 LDR R4,[SP],#0x4 ; Restore R4
mbedAustin 11:cada08fc8a70 284
mbedAustin 11:cada08fc8a70 285 MOV LR,R4
mbedAustin 11:cada08fc8a70 286
mbedAustin 11:cada08fc8a70 287 SVC_Next: //R4 == os_tsk.run, LR == os_tsk.new, R0-R3, R5-R12 corruptible
mbedAustin 11:cada08fc8a70 288 LDR R1,=(os_tsk) ; os_tsk.run = os_tsk.new
mbedAustin 11:cada08fc8a70 289 STR LR,[R1]
mbedAustin 11:cada08fc8a70 290 LDRB R1,[LR,#TCB_TID] ; os_tsk.run->task_id
mbedAustin 11:cada08fc8a70 291 LSL R1,R1,#8 ; Store PROCID
mbedAustin 11:cada08fc8a70 292 MCR p15,0,R1,c13,c0,1 ; Write CONTEXTIDR
mbedAustin 11:cada08fc8a70 293
mbedAustin 11:cada08fc8a70 294 LDR R0,[LR,#TCB_TSTACK] ; os_tsk.run->tsk_stack
mbedAustin 11:cada08fc8a70 295
mbedAustin 11:cada08fc8a70 296 //Does incoming task have VFP/NEON state in stack?
mbedAustin 11:cada08fc8a70 297 LDRB R3,[LR,#TCB_STACKF]
mbedAustin 11:cada08fc8a70 298 ANDS R3, R3, #0x6
mbedAustin 11:cada08fc8a70 299 MRC p15,0,R1,c1,c0,2 ; Read CPACR
mbedAustin 11:cada08fc8a70 300 BICEQ R1,R1,#0x00F00000 ; Disable VFP/NEON access if incoming task does not have stacked VFP/NEON state
mbedAustin 11:cada08fc8a70 301 ORRNE R1,R1,#0x00F00000 ; Enable VFP/NEON access if incoming task does have stacked VFP/NEON state
mbedAustin 11:cada08fc8a70 302 MCR p15,0,R1,c1,c0,2 ; Write CPACR
mbedAustin 11:cada08fc8a70 303 BEQ no_incoming_vfp
mbedAustin 11:cada08fc8a70 304 ISB ; We only need the sync if we enabled, otherwise we will context switch before next VFP/NEON instruction anyway
mbedAustin 11:cada08fc8a70 305 //IF {TARGET_FEATURE_EXTENSION_REGISTER_COUNT} == 32
mbedAustin 11:cada08fc8a70 306 VLDMIA R0!,{D16-D31}
mbedAustin 11:cada08fc8a70 307 //ENDIF
mbedAustin 11:cada08fc8a70 308 VLDMIA R0!,{D0-D15}
mbedAustin 11:cada08fc8a70 309 LDR R2,[R0]
mbedAustin 11:cada08fc8a70 310 VMSR FPSCR,R2
mbedAustin 11:cada08fc8a70 311 ADD R0,R0,#8
mbedAustin 11:cada08fc8a70 312
mbedAustin 11:cada08fc8a70 313 no_incoming_vfp:
mbedAustin 11:cada08fc8a70 314 LDR R1,[R0,#60] ; Restore User CPSR
mbedAustin 11:cada08fc8a70 315 MSR SPSR_CXSF,R1
mbedAustin 11:cada08fc8a70 316 LDMIA R0!,{R4-R11} ; Restore User R4-R11
mbedAustin 11:cada08fc8a70 317 ADD R0,R0,#4 ; Restore User R1-R3,R12
mbedAustin 11:cada08fc8a70 318 LDMIA R0!,{R1-R3,R12}
mbedAustin 11:cada08fc8a70 319 LDMIA R0,{LR}^ ; Restore User LR
mbedAustin 11:cada08fc8a70 320 ADD R0,R0,#4 ; No writeback for load to user LR
mbedAustin 11:cada08fc8a70 321 LDMIA R0!,{LR} ; Restore User PC
mbedAustin 11:cada08fc8a70 322 ADD R0,R0,#4 ; Correct User SP for unstacked user CPSR
mbedAustin 11:cada08fc8a70 323
mbedAustin 11:cada08fc8a70 324 STR R0,[SP,#-0x4]! ; Push R0 onto stack
mbedAustin 11:cada08fc8a70 325 LDMIA SP,{SP}^ ; Get R0 off stack into User SP
mbedAustin 11:cada08fc8a70 326 ADD SP,SP,#4 ; Put SP back
mbedAustin 11:cada08fc8a70 327
mbedAustin 11:cada08fc8a70 328 LDR R0,[R0,#-32] ; Restore R0
mbedAustin 11:cada08fc8a70 329
mbedAustin 11:cada08fc8a70 330 STMDB SP!,{R0-R3,R12,LR}
mbedAustin 11:cada08fc8a70 331
mbedAustin 11:cada08fc8a70 332 AND R12, SP, #4 ; Ensure stack is 8-byte aligned
mbedAustin 11:cada08fc8a70 333 SUB SP, SP, R12 ; Adjust stack
mbedAustin 11:cada08fc8a70 334 STMDB sp!,{R12, LR} ; Store stack adjustment and dummy LR to SVC stack
mbedAustin 11:cada08fc8a70 335
mbedAustin 11:cada08fc8a70 336 CPSID i
mbedAustin 11:cada08fc8a70 337 BLX rt_tsk_unlock
mbedAustin 11:cada08fc8a70 338
mbedAustin 11:cada08fc8a70 339 LDMIA sp!,{R12, LR} ; Get stack adjustment & discard dummy LR
mbedAustin 11:cada08fc8a70 340 ADD SP, SP, R12 ; Unadjust stack
mbedAustin 11:cada08fc8a70 341
mbedAustin 11:cada08fc8a70 342 LDMIA SP!,{R0-R3,R12,LR}
mbedAustin 11:cada08fc8a70 343
mbedAustin 11:cada08fc8a70 344 MOVS PC,LR ; Return from exception
mbedAustin 11:cada08fc8a70 345
mbedAustin 11:cada08fc8a70 346
mbedAustin 11:cada08fc8a70 347 /*------------------- User SVC -------------------------------*/
mbedAustin 11:cada08fc8a70 348
mbedAustin 11:cada08fc8a70 349 SVC_User:
mbedAustin 11:cada08fc8a70 350 LDR R12,=SVC_Count
mbedAustin 11:cada08fc8a70 351 LDR R12,[R12]
mbedAustin 11:cada08fc8a70 352 CMP R4,R12 ; Check for overflow
mbedAustin 11:cada08fc8a70 353 BHI SVC_Done
mbedAustin 11:cada08fc8a70 354
mbedAustin 11:cada08fc8a70 355 LDR R12,=SVC_Table-4
mbedAustin 11:cada08fc8a70 356 LDR R12,[R12,R4,LSL #2] ; Load SVC Function Address
mbedAustin 11:cada08fc8a70 357 MRS R4,SPSR ; Save SPSR
mbedAustin 11:cada08fc8a70 358 STR R4,[SP,#-0x4]! ; Push R4 so we can use it as a temp
mbedAustin 11:cada08fc8a70 359 AND R4, SP, #4 ; Ensure stack is 8-byte aligned
mbedAustin 11:cada08fc8a70 360 SUB SP, SP, R4 ; Adjust stack
mbedAustin 11:cada08fc8a70 361 STMDB SP!,{R4, LR} ; Store stack adjustment and dummy LR
mbedAustin 11:cada08fc8a70 362 BLX R12 ; Call SVC Function
mbedAustin 11:cada08fc8a70 363 LDMIA SP!,{R4, LR} ; Get stack adjustment & discard dummy LR
mbedAustin 11:cada08fc8a70 364 ADD SP, SP, R4 ; Unadjust stack
mbedAustin 11:cada08fc8a70 365 LDR R4,[SP],#0x4 ; Restore R4
mbedAustin 11:cada08fc8a70 366 MSR SPSR_CXSF,R4 ; Restore SPSR
mbedAustin 11:cada08fc8a70 367
mbedAustin 11:cada08fc8a70 368 SVC_Done:
mbedAustin 11:cada08fc8a70 369 STMDB sp!,{R0-R3,R12,LR}
mbedAustin 11:cada08fc8a70 370
mbedAustin 11:cada08fc8a70 371 STR R4,[sp,#-0x4]! ; Push R4 so we can use it as a temp
mbedAustin 11:cada08fc8a70 372 AND R4, SP, #4 ; Ensure stack is 8-byte aligned
mbedAustin 11:cada08fc8a70 373 SUB SP, SP, R4 ; Adjust stack
mbedAustin 11:cada08fc8a70 374 STMDB SP!,{R4, LR} ; Store stack adjustment and dummy LR
mbedAustin 11:cada08fc8a70 375
mbedAustin 11:cada08fc8a70 376 CPSID i
mbedAustin 11:cada08fc8a70 377 BLX rt_tsk_unlock
mbedAustin 11:cada08fc8a70 378
mbedAustin 11:cada08fc8a70 379 LDMIA SP!,{R4, LR} ; Get stack adjustment & discard dummy LR
mbedAustin 11:cada08fc8a70 380 ADD SP, SP, R4 ; Unadjust stack
mbedAustin 11:cada08fc8a70 381 LDR R4,[SP],#0x4 ; Restore R4
mbedAustin 11:cada08fc8a70 382
mbedAustin 11:cada08fc8a70 383 LDMIA SP!,{R0-R3,R12,LR}
mbedAustin 11:cada08fc8a70 384 LDR R4,[SP],#0x4
mbedAustin 11:cada08fc8a70 385 RFEFD SP! ; Return from exception
mbedAustin 11:cada08fc8a70 386 //}
mbedAustin 11:cada08fc8a70 387 //#pragma pop
mbedAustin 11:cada08fc8a70 388
mbedAustin 11:cada08fc8a70 389 //#pragma push
mbedAustin 11:cada08fc8a70 390 //#pragma arm
mbedAustin 11:cada08fc8a70 391 //__asm void PendSV_Handler (U32 IRQn) {
mbedAustin 11:cada08fc8a70 392 PendSV_Handler:
mbedAustin 11:cada08fc8a70 393 ARM
mbedAustin 11:cada08fc8a70 394
mbedAustin 11:cada08fc8a70 395 IMPORT rt_tsk_lock
mbedAustin 11:cada08fc8a70 396 IMPORT IRQNestLevel ; Flag indicates whether inside an ISR, and the depth of nesting. 0 = not in ISR.
mbedAustin 11:cada08fc8a70 397 IMPORT seen_id0_active ; Flag used to workaround GIC 390 errata 733075 - set in startup_Renesas_RZ_A1.s
mbedAustin 11:cada08fc8a70 398
mbedAustin 11:cada08fc8a70 399 ADD SP,SP,#8 //fix up stack pointer (R0 has been pushed and will never be popped, R1 was pushed for stack alignment)
mbedAustin 11:cada08fc8a70 400
mbedAustin 11:cada08fc8a70 401 //Disable systick interrupts, then write EOIR. We want interrupts disabled before we enter the context switcher.
mbedAustin 11:cada08fc8a70 402 STMDB SP!,{R0, R1}
mbedAustin 11:cada08fc8a70 403 BLX rt_tsk_lock
mbedAustin 11:cada08fc8a70 404 LDMIA SP!,{R0, R1}
mbedAustin 11:cada08fc8a70 405 LDR R1,=(GICInterface_BASE)
mbedAustin 11:cada08fc8a70 406 LDR R1, [R1, #0]
mbedAustin 11:cada08fc8a70 407 STR R0, [R1, #0x10]
mbedAustin 11:cada08fc8a70 408
mbedAustin 11:cada08fc8a70 409 ; If it was interrupt ID0, clear the seen flag, otherwise return as normal
mbedAustin 11:cada08fc8a70 410 CMP R0, #0
mbedAustin 11:cada08fc8a70 411 LDREQ R1, =seen_id0_active
mbedAustin 11:cada08fc8a70 412 STRBEQ R0, [R1] ; Clear the seen flag, using R0 (which is 0), to save loading another register
mbedAustin 11:cada08fc8a70 413
mbedAustin 11:cada08fc8a70 414 LDR R0, =IRQNestLevel ; Get address of nesting counter
mbedAustin 11:cada08fc8a70 415 LDR R1, [R0]
mbedAustin 11:cada08fc8a70 416 SUB R1, R1, #1 ; Decrement nesting counter
mbedAustin 11:cada08fc8a70 417 STR R1, [R0]
mbedAustin 11:cada08fc8a70 418
mbedAustin 11:cada08fc8a70 419 BLX (rt_pop_req)
mbedAustin 11:cada08fc8a70 420
mbedAustin 11:cada08fc8a70 421 LDMIA SP!,{R1, LR} ; Get stack adjustment & discard dummy LR
mbedAustin 11:cada08fc8a70 422 ADD SP, SP, R1 ; Unadjust stack
mbedAustin 11:cada08fc8a70 423
mbedAustin 11:cada08fc8a70 424 LDR R0,[SP,#24]
mbedAustin 11:cada08fc8a70 425 MSR SPSR_CXSF,R0
mbedAustin 11:cada08fc8a70 426 LDMIA SP!,{R0-R3,R12} ; Leave SPSR & LR on the stack
mbedAustin 11:cada08fc8a70 427 STR R4,[SP,#-0x4]!
mbedAustin 11:cada08fc8a70 428 B Sys_Switch
mbedAustin 11:cada08fc8a70 429 //}
mbedAustin 11:cada08fc8a70 430 //#pragma pop
mbedAustin 11:cada08fc8a70 431
mbedAustin 11:cada08fc8a70 432
mbedAustin 11:cada08fc8a70 433 //#pragma push
mbedAustin 11:cada08fc8a70 434 //#pragma arm
mbedAustin 11:cada08fc8a70 435 //__asm void OS_Tick_Handler (U32 IRQn) {
mbedAustin 11:cada08fc8a70 436 OS_Tick_Handler:
mbedAustin 11:cada08fc8a70 437 ARM
mbedAustin 11:cada08fc8a70 438
mbedAustin 11:cada08fc8a70 439 IMPORT rt_tsk_lock
mbedAustin 11:cada08fc8a70 440 IMPORT IRQNestLevel ; Flag indicates whether inside an ISR, and the depth of nesting. 0 = not in ISR.
mbedAustin 11:cada08fc8a70 441 IMPORT seen_id0_active ; Flag used to workaround GIC 390 errata 733075 - set in startup_Renesas_RZ_A1.s
mbedAustin 11:cada08fc8a70 442
mbedAustin 11:cada08fc8a70 443 ADD SP,SP,#8 //fix up stack pointer (R0 has been pushed and will never be popped, R1 was pushed for stack alignment)
mbedAustin 11:cada08fc8a70 444
mbedAustin 11:cada08fc8a70 445 STMDB SP!,{R0, R1}
mbedAustin 11:cada08fc8a70 446 BLX rt_tsk_lock
mbedAustin 11:cada08fc8a70 447 LDMIA SP!,{R0, R1}
mbedAustin 11:cada08fc8a70 448 LDR R1, =(GICInterface_BASE)
mbedAustin 11:cada08fc8a70 449 LDR R1, [R1, #0]
mbedAustin 11:cada08fc8a70 450 STR R0, [R1, #0x10]
mbedAustin 11:cada08fc8a70 451
mbedAustin 11:cada08fc8a70 452 ; If it was interrupt ID0, clear the seen flag, otherwise return as normal
mbedAustin 11:cada08fc8a70 453 CMP R0, #0
mbedAustin 11:cada08fc8a70 454 LDREQ R1, =seen_id0_active
mbedAustin 11:cada08fc8a70 455 STRBEQ R0, [R1] ; Clear the seen flag, using R0 (which is 0), to save loading another register
mbedAustin 11:cada08fc8a70 456
mbedAustin 11:cada08fc8a70 457 LDR R0, =IRQNestLevel ; Get address of nesting counter
mbedAustin 11:cada08fc8a70 458 LDR R1, [R0]
mbedAustin 11:cada08fc8a70 459 SUB R1, R1, #1 ; Decrement nesting counter
mbedAustin 11:cada08fc8a70 460 STR R1, [R0]
mbedAustin 11:cada08fc8a70 461
mbedAustin 11:cada08fc8a70 462 BLX (os_tick_irqack)
mbedAustin 11:cada08fc8a70 463 BLX (rt_systick)
mbedAustin 11:cada08fc8a70 464
mbedAustin 11:cada08fc8a70 465 LDMIA SP!,{R1, LR} ; Get stack adjustment & discard dummy LR
mbedAustin 11:cada08fc8a70 466 ADD SP, SP, R1 ; Unadjust stack
mbedAustin 11:cada08fc8a70 467
mbedAustin 11:cada08fc8a70 468 LDR R0,[SP,#24]
mbedAustin 11:cada08fc8a70 469 MSR SPSR_CXSF,R0
mbedAustin 11:cada08fc8a70 470 LDMIA SP!,{R0-R3,R12} ; Leave SPSR & LR on the stack
mbedAustin 11:cada08fc8a70 471 STR R4,[SP,#-0x4]!
mbedAustin 11:cada08fc8a70 472 B Sys_Switch
mbedAustin 11:cada08fc8a70 473 //}
mbedAustin 11:cada08fc8a70 474 //#pragma pop
mbedAustin 11:cada08fc8a70 475
mbedAustin 11:cada08fc8a70 476
mbedAustin 11:cada08fc8a70 477 END
mbedAustin 11:cada08fc8a70 478 /*----------------------------------------------------------------------------
mbedAustin 11:cada08fc8a70 479 * end of file
mbedAustin 11:cada08fc8a70 480 *---------------------------------------------------------------------------*/