1 /*
2  * SPDX-FileCopyrightText: 2023 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 infomation, 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_MIDELEG,          mideleg)
115     STRUCT_FIELD (long, 4, RV_SLP_CTX_MISA,             misa)
116     STRUCT_FIELD (long, 4, RV_SLP_CTX_TSELECT,          tselect)
117     STRUCT_FIELD (long, 4, RV_SLP_CTX_TDATA1,           tdata1)
118     STRUCT_FIELD (long, 4, RV_SLP_CTX_TDATA2,           tdata2)
119     STRUCT_FIELD (long, 4, RV_SLP_CTX_TCONTROL,         tcontrol)
120     STRUCT_FIELD (long, 4, RV_SLP_CTX_PMPADDR0,         pmpaddr0)
121     STRUCT_FIELD (long, 4, RV_SLP_CTX_PMPADDR1,         pmpaddr1)
122     STRUCT_FIELD (long, 4, RV_SLP_CTX_PMPADDR2,         pmpaddr2)
123     STRUCT_FIELD (long, 4, RV_SLP_CTX_PMPADDR3,         pmpaddr3)
124     STRUCT_FIELD (long, 4, RV_SLP_CTX_PMPADDR4,         pmpaddr4)
125     STRUCT_FIELD (long, 4, RV_SLP_CTX_PMPADDR5,         pmpaddr5)
126     STRUCT_FIELD (long, 4, RV_SLP_CTX_PMPADDR6,         pmpaddr6)
127     STRUCT_FIELD (long, 4, RV_SLP_CTX_PMPADDR7,         pmpaddr7)
128     STRUCT_FIELD (long, 4, RV_SLP_CTX_PMPADDR8,         pmpaddr8)
129     STRUCT_FIELD (long, 4, RV_SLP_CTX_PMPADDR9,         pmpaddr9)
130     STRUCT_FIELD (long, 4, RV_SLP_CTX_PMPADDR10,        pmpaddr10)
131     STRUCT_FIELD (long, 4, RV_SLP_CTX_PMPADDR11,        pmpaddr11)
132     STRUCT_FIELD (long, 4, RV_SLP_CTX_PMPADDR12,        pmpaddr12)
133     STRUCT_FIELD (long, 4, RV_SLP_CTX_PMPADDR13,        pmpaddr13)
134     STRUCT_FIELD (long, 4, RV_SLP_CTX_PMPADDR14,        pmpaddr14)
135     STRUCT_FIELD (long, 4, RV_SLP_CTX_PMPADDR15,        pmpaddr15)
136     STRUCT_FIELD (long, 4, RV_SLP_CTX_PMPCFG0,          pmpcfg0)
137     STRUCT_FIELD (long, 4, RV_SLP_CTX_PMPCFG1,          pmpcfg1)
138     STRUCT_FIELD (long, 4, RV_SLP_CTX_PMPCFG2,          pmpcfg2)
139     STRUCT_FIELD (long, 4, RV_SLP_CTX_PMPCFG3,          pmpcfg3)
140 
141 #if SOC_CPU_HAS_PMA
142     STRUCT_FIELD (long, 4, RV_SLP_CTX_PMAADDR0,         pmaaddr0)
143     STRUCT_FIELD (long, 4, RV_SLP_CTX_PMAADDR1,         pmaaddr1)
144     STRUCT_FIELD (long, 4, RV_SLP_CTX_PMAADDR2,         pmaaddr2)
145     STRUCT_FIELD (long, 4, RV_SLP_CTX_PMAADDR3,         pmaaddr3)
146     STRUCT_FIELD (long, 4, RV_SLP_CTX_PMAADDR4,         pmaaddr4)
147     STRUCT_FIELD (long, 4, RV_SLP_CTX_PMAADDR5,         pmaaddr5)
148     STRUCT_FIELD (long, 4, RV_SLP_CTX_PMAADDR6,         pmaaddr6)
149     STRUCT_FIELD (long, 4, RV_SLP_CTX_PMAADDR7,         pmaaddr7)
150     STRUCT_FIELD (long, 4, RV_SLP_CTX_PMAADDR8,         pmaaddr8)
151     STRUCT_FIELD (long, 4, RV_SLP_CTX_PMAADDR9,         pmaaddr9)
152     STRUCT_FIELD (long, 4, RV_SLP_CTX_PMAADDR10,        pmaaddr10)
153     STRUCT_FIELD (long, 4, RV_SLP_CTX_PMAADDR11,        pmaaddr11)
154     STRUCT_FIELD (long, 4, RV_SLP_CTX_PMAADDR12,        pmaaddr12)
155     STRUCT_FIELD (long, 4, RV_SLP_CTX_PMAADDR13,        pmaaddr13)
156     STRUCT_FIELD (long, 4, RV_SLP_CTX_PMAADDR14,        pmaaddr14)
157     STRUCT_FIELD (long, 4, RV_SLP_CTX_PMAADDR15,        pmaaddr15)
158     STRUCT_FIELD (long, 4, RV_SLP_CTX_PMACFG0,          pmacfg0)
159     STRUCT_FIELD (long, 4, RV_SLP_CTX_PMACFG1,          pmacfg1)
160     STRUCT_FIELD (long, 4, RV_SLP_CTX_PMACFG2,          pmacfg2)
161     STRUCT_FIELD (long, 4, RV_SLP_CTX_PMACFG3,          pmacfg3)
162     STRUCT_FIELD (long, 4, RV_SLP_CTX_PMACFG4,          pmacfg4)
163     STRUCT_FIELD (long, 4, RV_SLP_CTX_PMACFG5,          pmacfg5)
164     STRUCT_FIELD (long, 4, RV_SLP_CTX_PMACFG6,          pmacfg6)
165     STRUCT_FIELD (long, 4, RV_SLP_CTX_PMACFG7,          pmacfg7)
166     STRUCT_FIELD (long, 4, RV_SLP_CTX_PMACFG8,          pmacfg8)
167     STRUCT_FIELD (long, 4, RV_SLP_CTX_PMACFG9,          pmacfg9)
168     STRUCT_FIELD (long, 4, RV_SLP_CTX_PMACFG10,         pmacfg10)
169     STRUCT_FIELD (long, 4, RV_SLP_CTX_PMACFG11,         pmacfg11)
170     STRUCT_FIELD (long, 4, RV_SLP_CTX_PMACFG12,         pmacfg12)
171     STRUCT_FIELD (long, 4, RV_SLP_CTX_PMACFG13,         pmacfg13)
172     STRUCT_FIELD (long, 4, RV_SLP_CTX_PMACFG14,         pmacfg14)
173     STRUCT_FIELD (long, 4, RV_SLP_CTX_PMACFG15,         pmacfg15)
174 #endif // SOC_CPU_HAS_PMA
175 
176     STRUCT_FIELD (long, 4, RV_SLP_CTX_UTVEC,            utvec)
177     STRUCT_FIELD (long, 4, RV_SLP_CTX_USTATUS,          ustatus)
178     STRUCT_FIELD (long, 4, RV_SLP_CTX_UEPC,             uepc)
179     STRUCT_FIELD (long, 4, RV_SLP_CTX_UCAUSE,           ucause)
180 
181     STRUCT_FIELD (long, 4, RV_SLP_CTX_MPCER,            mpcer)
182     STRUCT_FIELD (long, 4, RV_SLP_CTX_MPCMR,            mpcmr)
183     STRUCT_FIELD (long, 4, RV_SLP_CTX_MPCCR,            mpccr)
184     STRUCT_FIELD (long, 4, RV_SLP_CTX_CPU_TESTBUS_CTRL, cpu_testbus_ctrl)
185     STRUCT_FIELD (long, 4, RV_SLP_CTX_UPCER,            upcer)
186     STRUCT_FIELD (long, 4, RV_SLP_CTX_UPCMR,            upcmr)
187     STRUCT_FIELD (long, 4, RV_SLP_CTX_UPCCR,            upccr)
188     STRUCT_FIELD (long, 4, RV_SLP_CTX_UGPIO_OEN,        ugpio_oen)
189     STRUCT_FIELD (long, 4, RV_SLP_CTX_UGPIO_IN,         ugpio_in)
190     STRUCT_FIELD (long, 4, RV_SLP_CTX_UGPIO_OUT,        ugpio_out)
191 #if CONFIG_PM_CHECK_SLEEP_RETENTION_FRAME
192     STRUCT_FIELD (long, 4, RV_SLP_NCSF_CTX_CRC,         frame_crc)        /* Used to check RvCoreNonCriticalSleepFrame integrity */
193 #endif
194 STRUCT_END(RvCoreNonCriticalSleepFrame)
195 
196 #endif /* #ifndef __RVSLEEP_FRAMES_H__ */
197