/* swap_macros.h - helper macros for context switch */ /* * Copyright (c) 2014 Wind River Systems, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef _SWAP_MACROS__H_ #define _SWAP_MACROS__H_ #include #include #include #include #ifdef __cplusplus extern "C" { #endif #ifdef _ASMLANGUAGE /* entering this macro, current is in r2 */ .macro _save_callee_saved_regs sub_s sp, sp, __tCalleeSaved_SIZEOF /* save regs on stack */ st_s r13, [sp, __tCalleeSaved_r13_OFFSET] st_s r14, [sp, __tCalleeSaved_r14_OFFSET] st_s r15, [sp, __tCalleeSaved_r15_OFFSET] st r16, [sp, __tCalleeSaved_r16_OFFSET] st r17, [sp, __tCalleeSaved_r17_OFFSET] st r18, [sp, __tCalleeSaved_r18_OFFSET] st r19, [sp, __tCalleeSaved_r19_OFFSET] st r20, [sp, __tCalleeSaved_r20_OFFSET] st r21, [sp, __tCalleeSaved_r21_OFFSET] st r22, [sp, __tCalleeSaved_r22_OFFSET] st r23, [sp, __tCalleeSaved_r23_OFFSET] st r24, [sp, __tCalleeSaved_r24_OFFSET] st r25, [sp, __tCalleeSaved_r25_OFFSET] st r26, [sp, __tCalleeSaved_r26_OFFSET] st fp, [sp, __tCalleeSaved_fp_OFFSET] st r30, [sp, __tCalleeSaved_r30_OFFSET] /* save stack pointer in struct tcs */ st sp, [r2, __tTCS_preempReg_OFFSET + __tPreempt_sp_OFFSET] .endm /* entering this macro, current is in r2 */ .macro _load_callee_saved_regs /* restore stack pointer from struct tcs */ ld sp, [r2, __tTCS_preempReg_OFFSET + __tPreempt_sp_OFFSET] ld_s r13, [sp, __tCalleeSaved_r13_OFFSET] ld_s r14, [sp, __tCalleeSaved_r14_OFFSET] ld_s r15, [sp, __tCalleeSaved_r15_OFFSET] ld r16, [sp, __tCalleeSaved_r16_OFFSET] ld r17, [sp, __tCalleeSaved_r17_OFFSET] ld r18, [sp, __tCalleeSaved_r18_OFFSET] ld r19, [sp, __tCalleeSaved_r19_OFFSET] ld r20, [sp, __tCalleeSaved_r20_OFFSET] ld r21, [sp, __tCalleeSaved_r21_OFFSET] ld r22, [sp, __tCalleeSaved_r22_OFFSET] ld r23, [sp, __tCalleeSaved_r23_OFFSET] ld r24, [sp, __tCalleeSaved_r24_OFFSET] ld r25, [sp, __tCalleeSaved_r25_OFFSET] ld r26, [sp, __tCalleeSaved_r26_OFFSET] ld fp, [sp, __tCalleeSaved_fp_OFFSET] ld r30, [sp, __tCalleeSaved_r30_OFFSET] add_s sp, sp, __tCalleeSaved_SIZEOF .endm /* * Must be called with interrupts locked or in P0. * Upon exit, sp will be pointing to the stack frame. */ .macro _create_irq_stack_frame sub_s sp, sp, __tISF_SIZEOF st blink, [sp, __tISF_blink_OFFSET] /* store these right away so we can use them if needed */ st_s r13, [sp, __tISF_r13_OFFSET] st_s r12, [sp, __tISF_r12_OFFSET] st r11, [sp, __tISF_r11_OFFSET] st r10, [sp, __tISF_r10_OFFSET] st r9, [sp, __tISF_r9_OFFSET] st r8, [sp, __tISF_r8_OFFSET] st r7, [sp, __tISF_r7_OFFSET] st r6, [sp, __tISF_r6_OFFSET] st r5, [sp, __tISF_r5_OFFSET] st r4, [sp, __tISF_r4_OFFSET] st_s r3, [sp, __tISF_r3_OFFSET] st_s r2, [sp, __tISF_r2_OFFSET] st_s r1, [sp, __tISF_r1_OFFSET] st_s r0, [sp, __tISF_r0_OFFSET] mov r0, lp_count st_s r0, [sp, __tISF_lp_count_OFFSET] lr r1, [_ARC_V2_LP_START] lr r0, [_ARC_V2_LP_END] st_s r1, [sp, __tISF_lp_start_OFFSET] st_s r0, [sp, __tISF_lp_end_OFFSET] .endm /* * Must be called with interrupts locked or in P0. * sp must be pointing the to stack frame. */ .macro _pop_irq_stack_frame ld blink, [sp, __tISF_blink_OFFSET] ld_s r0, [sp, __tISF_lp_count_OFFSET] mov lp_count, r0 ld_s r1, [sp, __tISF_lp_start_OFFSET] ld_s r0, [sp, __tISF_lp_end_OFFSET] sr r1, [_ARC_V2_LP_START] sr r0, [_ARC_V2_LP_END] ld_s r13, [sp, __tISF_r13_OFFSET] ld_s r12, [sp, __tISF_r12_OFFSET] ld r11, [sp, __tISF_r11_OFFSET] ld r10, [sp, __tISF_r10_OFFSET] ld r9, [sp, __tISF_r9_OFFSET] ld r8, [sp, __tISF_r8_OFFSET] ld r7, [sp, __tISF_r7_OFFSET] ld r6, [sp, __tISF_r6_OFFSET] ld r5, [sp, __tISF_r5_OFFSET] ld r4, [sp, __tISF_r4_OFFSET] ld_s r3, [sp, __tISF_r3_OFFSET] ld_s r2, [sp, __tISF_r2_OFFSET] ld_s r1, [sp, __tISF_r1_OFFSET] ld_s r0, [sp, __tISF_r0_OFFSET] /* * All gprs have been reloaded, the only one that is still usable is * ilink. * * The pc and status32 values will still be on the stack. We cannot * pop them yet because the callers of _pop_irq_stack_frame must reload * status32 differently depending on the execution context they are running * in (_Swap(), firq or exception). */ add_s sp, sp, __tISF_SIZEOF .endm #endif /* _ASMLANGUAGE */ #ifdef __cplusplus } #endif #endif /* _SWAP_MACROS__H_ */