1 // Copyright 2020 Espressif Systems (Shanghai) PTE LTD 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #pragma once 16 17 #define RSR(reg, at) asm volatile ("rsr %0, %1" : "=r" (at) : "i" (reg)) 18 #define WSR(reg, at) asm volatile ("wsr %0, %1" : : "r" (at), "i" (reg)) 19 #define XSR(reg, at) asm volatile ("xsr %0, %1" : "+r" (at) : "i" (reg)) 20 21 #define RER(reg, at) asm volatile ("rer %0, %1" : "=r" (at) : "r" (reg)) 22 23 #define WITLB(at, as) asm volatile ("witlb %0, %1; \n isync \n " : : "r" (at), "r" (as)) 24 #define WDTLB(at, as) asm volatile ("wdtlb %0, %1; \n dsync \n " : : "r" (at), "r" (as)) 25 26 /* The SET_STACK implements a setting a new stack pointer (sp or a1). 27 * to do this the need reset PS_WOE, reset WINDOWSTART, update SP, and return PS_WOE. 28 * 29 * Note: It has 2 implementations one for using in assembler files (*.S) and one for using in C. 30 * 31 * C code prototype for SET_STACK: 32 * uint32_t ps_reg; 33 * uint32_t w_base; 34 * RSR(PS, ps_reg); 35 * ps_reg &= ~(PS_WOE_MASK | PS_OWB_MASK | PS_CALLINC_MASK); 36 * WSR(PS, ps_reg); 37 * 38 * RSR(WINDOWBASE, w_base); 39 * WSR(WINDOWSTART, (1 << w_base)); 40 * 41 * asm volatile ( "movi sp, "XTSTR( (SOC_DRAM_LOW + (SOC_DRAM_HIGH - SOC_DRAM_LOW) / 2) )""); 42 * 43 * RSR(PS, ps_reg); 44 * ps_reg |= (PS_WOE_MASK); 45 * WSR(PS, ps_reg); 46 */ 47 #ifdef __ASSEMBLER__ 48 .macro SET_STACK new_sp tmp1 tmp2 49 rsr.ps \tmp1 50 movi \tmp2, ~(PS_WOE_MASK | PS_OWB_MASK | PS_CALLINC_MASK) 51 and \tmp1, \tmp1, \tmp2 52 wsr.ps \tmp1 53 rsync 54 55 rsr.windowbase \tmp1 56 ssl \tmp1 57 movi \tmp1, 1 58 sll \tmp1, \tmp1 59 wsr.windowstart \tmp1 60 rsync 61 62 mov sp, \new_sp 63 64 rsr.ps \tmp1 65 movi \tmp2, (PS_WOE) 66 or \tmp1, \tmp1, \tmp2 67 wsr.ps \tmp1 68 rsync 69 .endm 70 #else 71 #define SET_STACK(new_sp) \ 72 do { \ 73 uint32_t tmp1 = 0, tmp2 = 0; \ 74 asm volatile ( \ 75 "rsr.ps %1 \n"\ 76 "movi %2, ~" XTSTR( PS_WOE_MASK | PS_OWB_MASK | PS_CALLINC_MASK ) " \n"\ 77 "and %1, %1, %2 \n"\ 78 "wsr.ps %1 \n"\ 79 "rsync \n"\ 80 " \n"\ 81 "rsr.windowbase %1 \n"\ 82 "ssl %1 \n"\ 83 "movi %1, 1 \n"\ 84 "sll %1, %1 \n"\ 85 "wsr.windowstart %1 \n"\ 86 "rsync \n"\ 87 " \n"\ 88 "mov sp, %0 \n"\ 89 "rsr.ps %1 \n"\ 90 " \n"\ 91 "movi %2, " XTSTR( PS_WOE_MASK ) "\n"\ 92 " \n"\ 93 "or %1, %1, %2 \n"\ 94 "wsr.ps %1 \n"\ 95 "rsync \n"\ 96 : "+r"(new_sp), "+r"(tmp1), "+r"(tmp2)); \ 97 } while (0); 98 #endif // __ASSEMBLER__ 99