|
| 1 | +/* |
| 2 | + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD |
| 3 | + * |
| 4 | + * SPDX-License-Identifier: Apache-2.0 |
| 5 | + */ |
| 6 | + |
| 7 | +#ifndef __RVSLEEP_FRAMES_H__ |
| 8 | +#define __RVSLEEP_FRAMES_H__ |
| 9 | + |
| 10 | +#include "sdkconfig.h" |
| 11 | + |
| 12 | +/* Align a value up to nearest n-byte boundary, where n is a power of 2. */ |
| 13 | +#define ALIGNUP(n, val) (((val) + (n) - 1) & -(n)) |
| 14 | + |
| 15 | +#ifdef STRUCT_BEGIN |
| 16 | +#undef STRUCT_BEGIN |
| 17 | +#undef STRUCT_FIELD |
| 18 | +#undef STRUCT_AFIELD |
| 19 | +#undef STRUCT_END |
| 20 | +#endif |
| 21 | + |
| 22 | +#if defined(_ASMLANGUAGE) || defined(__ASSEMBLER__) |
| 23 | +#ifdef __clang__ |
| 24 | +#define STRUCT_BEGIN .set RV_STRUCT_OFFSET, 0 |
| 25 | +#define STRUCT_FIELD(ctype,size,asname,name) .set asname, RV_STRUCT_OFFSET; .set RV_STRUCT_OFFSET, asname + size |
| 26 | +#define STRUCT_AFIELD(ctype,size,asname,name,n) .set asname, RV_STRUCT_OFFSET;\ |
| 27 | + .set RV_STRUCT_OFFSET, asname + (size)*(n); |
| 28 | +#define STRUCT_END(sname) .set sname##Size, RV_STRUCT_OFFSET; |
| 29 | +#else // __clang__ |
| 30 | +#define STRUCT_BEGIN .pushsection .text; .struct 0 |
| 31 | +#define STRUCT_FIELD(ctype,size,asname,name) asname: .space size |
| 32 | +#define STRUCT_AFIELD(ctype,size,asname,name,n) asname: .space (size)*(n) |
| 33 | +#define STRUCT_END(sname) sname##Size:; .popsection |
| 34 | +#endif // __clang__ |
| 35 | +#else |
| 36 | +#define STRUCT_BEGIN typedef struct { |
| 37 | +#define STRUCT_FIELD(ctype,size,asname,name) ctype name; |
| 38 | +#define STRUCT_AFIELD(ctype,size,asname,name,n) ctype name[n]; |
| 39 | +#define STRUCT_END(sname) } sname; |
| 40 | +#endif |
| 41 | + |
| 42 | +/* |
| 43 | + * ------------------------------------------------------------------------------- |
| 44 | + * RISC-V CORE CRITICAL REGISTER CONTEXT LAYOUT FOR SLEEP |
| 45 | + * ------------------------------------------------------------------------------- |
| 46 | + */ |
| 47 | +STRUCT_BEGIN |
| 48 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_MEPC, mepc) /* Machine Exception Program Counter */ |
| 49 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_RA, ra) /* Return address */ |
| 50 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_SP, sp) /* Stack pointer */ |
| 51 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_GP, gp) /* Global pointer */ |
| 52 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_TP, tp) /* Thread pointer */ |
| 53 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_T0, t0) /* Temporary/alternate link register */ |
| 54 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_T1, t1) /* t1-2: Temporaries */ |
| 55 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_T2, t2) |
| 56 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_S0, s0) /* Saved register/frame pointer */ |
| 57 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_S1, s1) /* Saved register */ |
| 58 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_A0, a0) /* a0-1: Function arguments/return address */ |
| 59 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_A1, a1) |
| 60 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_A2, a2) /* a2-7: Function arguments */ |
| 61 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_A3, a3) |
| 62 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_A4, a4) |
| 63 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_A5, a5) |
| 64 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_A6, a6) |
| 65 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_A7, a7) |
| 66 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_S2, s2) /* s2-11: Saved registers */ |
| 67 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_S3, s3) |
| 68 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_S4, s4) |
| 69 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_S5, s5) |
| 70 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_S6, s6) |
| 71 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_S7, s7) |
| 72 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_S8, s8) |
| 73 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_S9, s9) |
| 74 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_S10, s10) |
| 75 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_S11, s11) |
| 76 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_T3, t3) /* t3-6: Temporaries */ |
| 77 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_T4, t4) |
| 78 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_T5, t5) |
| 79 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_T6, t6) |
| 80 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_MSTATUS, mstatus) /* Machine Status */ |
| 81 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_MTVEC, mtvec) /* Machine Trap-Vector Base Address */ |
| 82 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_MCAUSE, mcause) /* Machine Trap Cause */ |
| 83 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_MTVAL, mtval) /* Machine Trap Value */ |
| 84 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_MIE, mie) /* Machine intr enable */ |
| 85 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_MIP, mip) /* Machine intr pending */ |
| 86 | + |
| 87 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_PMUFUNC, pmufunc) /* A field is used to identify whether it is going |
| 88 | + * to sleep or has just been awakened. We use the |
| 89 | + * lowest 2 bits as indication information, 3 means |
| 90 | + * being awakened, 1 means going to sleep */ |
| 91 | +#if CONFIG_PM_CHECK_SLEEP_RETENTION_FRAME |
| 92 | + STRUCT_FIELD (long, 4, RV_SLP_CSF_CTX_CRC, frame_crc) /* Used to check RvCoreCriticalSleepFrame integrity */ |
| 93 | +#endif |
| 94 | +STRUCT_END(RvCoreCriticalSleepFrame) |
| 95 | + |
| 96 | +#if defined(_ASMLANGUAGE) || defined(__ASSEMBLER__) |
| 97 | +#define RV_SLEEP_CTX_SZ1 RvCoreCriticalSleepFrameSize |
| 98 | +#else |
| 99 | +#define RV_SLEEP_CTX_SZ1 sizeof(RvCoreCriticalSleepFrame) |
| 100 | +#endif |
| 101 | + |
| 102 | +/* |
| 103 | + * Sleep stack frame size, after align up to 16 bytes boundary |
| 104 | + */ |
| 105 | +#define RV_SLEEP_CTX_FRMSZ (ALIGNUP(0x10, RV_SLEEP_CTX_SZ1)) |
| 106 | + |
| 107 | +/* |
| 108 | + * ------------------------------------------------------------------------------- |
| 109 | + * RISC-V CORE NON-CRITICAL REGISTER CONTEXT LAYOUT FOR SLEEP |
| 110 | + * ------------------------------------------------------------------------------- |
| 111 | + */ |
| 112 | +STRUCT_BEGIN |
| 113 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_MSCRATCH, mscratch) |
| 114 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_MISA, misa) |
| 115 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_MSCRATCHCSW, mscratchcsw) |
| 116 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_MSCRATCHCSW1, mscratchcsw1) |
| 117 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_MCYCLEH, mcycleh) |
| 118 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_MINSTRET, minstret) |
| 119 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_MINSTRETH, minstreth) |
| 120 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_MCOUNTEREN, mcounteren) |
| 121 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_MCOUNTINHIBIT, mcountinhibit) |
| 122 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_MHPMCOUNTER8, mhpmcounter8) |
| 123 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_MHPMCOUNTER9, mhpmcounter9) |
| 124 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_MHPMCOUNTER13, mhpmcounter13) |
| 125 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_MHPMCOUNTER8H, mhpmcounter8h) |
| 126 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_MHPMCOUNTER9H, mhpmcounter9h) |
| 127 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_MHPMCOUNTER13H, mhpmcounter13h) |
| 128 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_MHPMEVENT8, mhpmevent8) |
| 129 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_MHPMEVENT9, mhpmevent9) |
| 130 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_MHPMEVENT13, mhpmevent13) |
| 131 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_MCONTEXT, mcontext) |
| 132 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_USTATUS, ustatus) |
| 133 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_UTVEC, utvec) |
| 134 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_USCRATCH, uscratch) |
| 135 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_UCAUSE, ucause) |
| 136 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_UINTTHRESH, uintthresh) |
| 137 | + |
| 138 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_TSELECT, tselect) |
| 139 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_TDATA1, tdata1) |
| 140 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_TDATA2, tdata2) |
| 141 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_TDATA3, tdata3) |
| 142 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_TCONTROL, tcontrol) |
| 143 | + |
| 144 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_PMPADDR0, pmpaddr0) |
| 145 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_PMPADDR1, pmpaddr1) |
| 146 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_PMPADDR2, pmpaddr2) |
| 147 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_PMPADDR3, pmpaddr3) |
| 148 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_PMPADDR4, pmpaddr4) |
| 149 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_PMPADDR5, pmpaddr5) |
| 150 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_PMPADDR6, pmpaddr6) |
| 151 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_PMPADDR7, pmpaddr7) |
| 152 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_PMPADDR8, pmpaddr8) |
| 153 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_PMPADDR9, pmpaddr9) |
| 154 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_PMPADDR10, pmpaddr10) |
| 155 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_PMPADDR11, pmpaddr11) |
| 156 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_PMPADDR12, pmpaddr12) |
| 157 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_PMPADDR13, pmpaddr13) |
| 158 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_PMPADDR14, pmpaddr14) |
| 159 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_PMPADDR15, pmpaddr15) |
| 160 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_PMPCFG0, pmpcfg0) |
| 161 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_PMPCFG1, pmpcfg1) |
| 162 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_PMPCFG2, pmpcfg2) |
| 163 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_PMPCFG3, pmpcfg3) |
| 164 | + |
| 165 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_PMAADDR0, pmaaddr0) |
| 166 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_PMAADDR1, pmaaddr1) |
| 167 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_PMAADDR2, pmaaddr2) |
| 168 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_PMAADDR3, pmaaddr3) |
| 169 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_PMAADDR4, pmaaddr4) |
| 170 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_PMAADDR5, pmaaddr5) |
| 171 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_PMAADDR6, pmaaddr6) |
| 172 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_PMAADDR7, pmaaddr7) |
| 173 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_PMAADDR8, pmaaddr8) |
| 174 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_PMAADDR9, pmaaddr9) |
| 175 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_PMAADDR10, pmaaddr10) |
| 176 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_PMAADDR11, pmaaddr11) |
| 177 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_PMAADDR12, pmaaddr12) |
| 178 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_PMAADDR13, pmaaddr13) |
| 179 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_PMAADDR14, pmaaddr14) |
| 180 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_PMAADDR15, pmaaddr15) |
| 181 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_PMACFG0, pmacfg0) |
| 182 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_PMACFG1, pmacfg1) |
| 183 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_PMACFG2, pmacfg2) |
| 184 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_PMACFG3, pmacfg3) |
| 185 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_PMACFG4, pmacfg4) |
| 186 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_PMACFG5, pmacfg5) |
| 187 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_PMACFG6, pmacfg6) |
| 188 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_PMACFG7, pmacfg7) |
| 189 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_PMACFG8, pmacfg8) |
| 190 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_PMACFG9, pmacfg9) |
| 191 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_PMACFG10, pmacfg10) |
| 192 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_PMACFG11, pmacfg11) |
| 193 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_PMACFG12, pmacfg12) |
| 194 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_PMACFG13, pmacfg13) |
| 195 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_PMACFG14, pmacfg14) |
| 196 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_PMACFG15, pmacfg15) |
| 197 | + |
| 198 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_MCYCLE, mcycle) |
| 199 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_MTVT, mtvt) |
| 200 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_MINTTHRESH, mintthresh) |
| 201 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_MXSTATUS, mxstatus) |
| 202 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_MHCR, mhcr) |
| 203 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_MHINT, mhint) |
| 204 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_MEXSTATUS, mexstatus) |
| 205 | + STRUCT_FIELD (long, 4, RV_SLP_CTX_JVT, jvt) |
| 206 | + |
| 207 | +#if CONFIG_PM_CHECK_SLEEP_RETENTION_FRAME |
| 208 | + STRUCT_FIELD (long, 4, RV_SLP_NCSF_CTX_CRC, frame_crc) /* Used to check RvCoreNonCriticalSleepFrame integrity */ |
| 209 | +#endif |
| 210 | +STRUCT_END(RvCoreNonCriticalSleepFrame) |
| 211 | + |
| 212 | +#endif /* #ifndef __RVSLEEP_FRAMES_H__ */ |
0 commit comments