1/*-
2 * Copyright (c) 2015-2024 Ruslan Bukin <br@bsdpad.com>
3 * All rights reserved.
4 *
5 * Portions of this software were developed by SRI International and the
6 * University of Cambridge Computer Laboratory under DARPA/AFRL contract
7 * FA8750-10-C-0237 ("CTSRD"), as part of the DARPA CRASH research programme.
8 *
9 * Portions of this software were developed by the University of Cambridge
10 * Computer Laboratory as part of the CTSRD Project, with support from the
11 * UK Higher Education Innovation Fund (HEIF).
12 *
13 * Redistribution and use in source and binary forms, with or without
14 * modification, are permitted provided that the following conditions
15 * are met:
16 * 1. Redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer.
18 * 2. Redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the distribution.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
33 */
34
35#ifndef _MACHINE_RISCVREG_H_
36#define _MACHINE_RISCVREG_H_
37
38#define SCAUSE_INTR (1ul << 63)
39#define SCAUSE_CODE (~SCAUSE_INTR)
40#define SCAUSE_INST_MISALIGNED 0
41#define SCAUSE_INST_ACCESS_FAULT 1
42#define SCAUSE_ILLEGAL_INSTRUCTION 2
43#define SCAUSE_BREAKPOINT 3
44#define SCAUSE_LOAD_MISALIGNED 4
45#define SCAUSE_LOAD_ACCESS_FAULT 5
46#define SCAUSE_STORE_MISALIGNED 6
47#define SCAUSE_STORE_ACCESS_FAULT 7
48#define SCAUSE_ECALL_USER 8
49#define SCAUSE_ECALL_SUPERVISOR 9
50#define SCAUSE_VIRTUAL_SUPERVISOR_ECALL 10
51#define SCAUSE_MACHINE_ECALL 11
52#define SCAUSE_INST_PAGE_FAULT 12
53#define SCAUSE_LOAD_PAGE_FAULT 13
54#define SCAUSE_STORE_PAGE_FAULT 15
55#define SCAUSE_FETCH_GUEST_PAGE_FAULT 20
56#define SCAUSE_LOAD_GUEST_PAGE_FAULT 21
57#define SCAUSE_VIRTUAL_INSTRUCTION 22
58#define SCAUSE_STORE_GUEST_PAGE_FAULT 23
59
60#define SSTATUS_UIE (1 << 0)
61#define SSTATUS_SIE (1 << 1)
62#define SSTATUS_UPIE (1 << 4)
63#define SSTATUS_SPIE (1 << 5)
64#define SSTATUS_SPIE_SHIFT 5
65#define SSTATUS_SPP (1 << 8)
66#define SSTATUS_SPP_SHIFT 8
67#define SSTATUS_FS_SHIFT 13
68#define SSTATUS_FS_OFF (0x0 << SSTATUS_FS_SHIFT)
69#define SSTATUS_FS_INITIAL (0x1 << SSTATUS_FS_SHIFT)
70#define SSTATUS_FS_CLEAN (0x2 << SSTATUS_FS_SHIFT)
71#define SSTATUS_FS_DIRTY (0x3 << SSTATUS_FS_SHIFT)
72#define SSTATUS_FS_MASK (0x3 << SSTATUS_FS_SHIFT)
73#define SSTATUS_XS_SHIFT 15
74#define SSTATUS_XS_MASK (0x3 << SSTATUS_XS_SHIFT)
75#define SSTATUS_SUM (1 << 18)
76#if __riscv_xlen == 64
77#define SSTATUS_SD (1ul << 63)
78#else
79#define SSTATUS_SD (1 << 31)
80#endif
81
82#define MSTATUS_UIE (1 << 0)
83#define MSTATUS_SIE (1 << 1)
84#define MSTATUS_HIE (1 << 2)
85#define MSTATUS_MIE (1 << 3)
86#define MSTATUS_UPIE (1 << 4)
87#define MSTATUS_SPIE (1 << 5)
88#define MSTATUS_SPIE_SHIFT 5
89#define MSTATUS_HPIE (1 << 6)
90#define MSTATUS_MPIE (1 << 7)
91#define MSTATUS_MPIE_SHIFT 7
92#define MSTATUS_SPP (1 << 8)
93#define MSTATUS_SPP_SHIFT 8
94#define MSTATUS_HPP_MASK 0x3
95#define MSTATUS_HPP_SHIFT 9
96#define MSTATUS_MPP_MASK 0x3
97#define MSTATUS_MPP_SHIFT 11
98#define MSTATUS_FS_MASK 0x3
99#define MSTATUS_FS_SHIFT 13
100#define MSTATUS_XS_MASK 0x3
101#define MSTATUS_XS_SHIFT 15
102#define MSTATUS_MPRV (1 << 17)
103#define MSTATUS_PUM (1 << 18)
104#define MSTATUS_VM_MASK 0x1f
105#define MSTATUS_VM_SHIFT 24
106#define MSTATUS_VM_MBARE 0
107#define MSTATUS_VM_MBB 1
108#define MSTATUS_VM_MBBID 2
109#define MSTATUS_VM_SV32 8
110#define MSTATUS_VM_SV39 9
111#define MSTATUS_VM_SV48 10
112#define MSTATUS_VM_SV57 11
113#define MSTATUS_VM_SV64 12
114#if __riscv_xlen == 64
115#define MSTATUS_SD (1ul << 63)
116#else
117#define MSTATUS_SD (1 << 31)
118#endif
119
120#define MSTATUS_PRV_U 0 /* user */
121#define MSTATUS_PRV_S 1 /* supervisor */
122#define MSTATUS_PRV_H 2 /* hypervisor */
123#define MSTATUS_PRV_M 3 /* machine */
124
125#define HSTATUS_VSBE (1 << 5)
126#define HSTATUS_GVA (1 << 6)
127#define HSTATUS_SPV (1 << 7)
128#define HSTATUS_SPVP (1 << 8)
129#define HSTATUS_HU (1 << 9)
130#define HSTATUS_VGEIN_S 12
131#define HSTATUS_VGEIN_M (0xf << HSTATUS_VGEIN_S)
132#define HSTATUS_VTVM (1 << 20)
133#define HSTATUS_VTW (1 << 21)
134#define HSTATUS_VTSR (1 << 22)
135
136#define MIE_USIE (1 << 0)
137#define MIE_SSIE (1 << 1)
138#define MIE_HSIE (1 << 2)
139#define MIE_MSIE (1 << 3)
140#define MIE_UTIE (1 << 4)
141#define MIE_STIE (1 << 5)
142#define MIE_HTIE (1 << 6)
143#define MIE_MTIE (1 << 7)
144
145#define MIP_USIP (1 << 0)
146#define MIP_SSIP (1 << 1)
147#define MIP_HSIP (1 << 2)
148#define MIP_MSIP (1 << 3)
149#define MIP_UTIP (1 << 4)
150#define MIP_STIP (1 << 5)
151#define MIP_HTIP (1 << 6)
152#define MIP_MTIP (1 << 7)
153
154#define SIE_USIE (1 << 0)
155#define SIE_SSIE (1 << 1)
156#define SIE_UTIE (1 << 4)
157#define SIE_STIE (1 << 5)
158#define SIE_UEIE (1 << 8)
159#define SIE_SEIE (1 << 9)
160
161#define MIP_SEIP (1 << 9)
162
163#define HVIP_VSSIP (1 << 2)
164#define HVIP_VSTIP (1 << 6)
165#define HVIP_VSEIP (1 << 10)
166
167#define HIE_VSSIE (1 << 2)
168#define HIE_VSTIE (1 << 6)
169#define HIE_VSEIE (1 << 10)
170#define HIE_SGEIE (1 << 12)
171
172/* Note: sip register has no SIP_STIP bit in Spike simulator */
173#define SIP_SSIP (1 << 1)
174#define SIP_STIP (1 << 5)
175
176#define HENVCFG_STCE (1UL << 63)
177#define HENVCFG_PBMTE (1UL << 62)
178#define HENVCFG_CBZE (1UL << 7)
179#define HENVCFG_CBCFE (1UL << 6)
180#define HENVCFG_CBIE_S 4
181#define HENVCFG_CBIE_M (0x3 << HENVCFG_CBIE_S)
182#define HENVCFG_FIOM (1UL << 0)
183
184#define HCOUNTEREN_CY (1UL << 0) /* Cycle */
185#define HCOUNTEREN_TM (1UL << 1) /* Time */
186#define HCOUNTEREN_IR (1UL << 2) /* Instret */
187
188#define SATP_PPN_S 0
189#define SATP_PPN_M (0xfffffffffffUL << SATP_PPN_S)
190#define SATP_ASID_S 44
191#define SATP_ASID_M (0xffffUL << SATP_ASID_S)
192#define SATP_MODE_S 60
193#define SATP_MODE_M (0xfUL << SATP_MODE_S)
194#define SATP_MODE_SV39 (8ULL << SATP_MODE_S)
195#define SATP_MODE_SV48 (9ULL << SATP_MODE_S)
196
197#define XLEN __riscv_xlen
198#define XLEN_BYTES (XLEN / 8)
199#define INSN_SIZE 4
200#define INSN_C_SIZE 2
201
202#define X_RA 1
203#define X_SP 2
204#define X_GP 3
205#define X_TP 4
206#define X_T0 5
207#define X_T1 6
208#define X_T2 7
209#define X_T3 28
210
211#define RD_SHIFT 7
212#define RD_MASK (0x1f << RD_SHIFT)
213#define RS1_SHIFT 15
214#define RS1_MASK (0x1f << RS1_SHIFT)
215#define RS1_SP (X_SP << RS1_SHIFT)
216#define RS2_SHIFT 20
217#define RS2_MASK (0x1f << RS2_SHIFT)
218#define RS2_RA (X_RA << RS2_SHIFT)
219#define IMM_SHIFT 20
220#define IMM_MASK (0xfff << IMM_SHIFT)
221
222#define RS2_C_SHIFT 2
223#define RS2_C_MASK (0x1f << RS2_C_SHIFT)
224#define RS2_C_RA (X_RA << RS2_C_SHIFT)
225
226#define CSR_ZIMM(val) \
227 (__builtin_constant_p(val) && ((u_long)(val) < 32))
228
229#define csr_swap(csr, val) \
230({ u_long ret; \
231 if (CSR_ZIMM(val)) \
232 __asm __volatile("csrrwi %0, " #csr ", %1" \
233 : "=r" (ret) : "i" (val)); \
234 else \
235 __asm __volatile("csrrw %0, " #csr ", %1" \
236 : "=r" (ret) : "r" (val)); \
237 ret; \
238})
239
240#define csr_write(csr, val) \
241({ if (CSR_ZIMM(val)) \
242 __asm __volatile("csrwi " #csr ", %0" :: "i" (val)); \
243 else \
244 __asm __volatile("csrw " #csr ", %0" :: "r" (val)); \
245})
246
247#define csr_set(csr, val) \
248({ if (CSR_ZIMM(val)) \
249 __asm __volatile("csrsi " #csr ", %0" :: "i" (val)); \
250 else \
251 __asm __volatile("csrs " #csr ", %0" :: "r" (val)); \
252})
253
254#define csr_clear(csr, val) \
255({ if (CSR_ZIMM(val)) \
256 __asm __volatile("csrci " #csr ", %0" :: "i" (val)); \
257 else \
258 __asm __volatile("csrc " #csr ", %0" :: "r" (val)); \
259})
260
261#define csr_read(csr) \
262({ u_long val; \
263 __asm __volatile("csrr %0, " #csr : "=r" (val)); \
264 val; \
265})
266
267#if __riscv_xlen == 32
268#define csr_read64(csr) \
269({ uint64_t val; \
270 uint32_t high, low; \
271 __asm __volatile("1: " \
272 "csrr t0, " #csr "h\n" \
273 "csrr %0, " #csr "\n" \
274 "csrr %1, " #csr "h\n" \
275 "bne t0, %1, 1b" \
276 : "=r" (low), "=r" (high) \
277 : \
278 : "t0"); \
279 val = (low | ((uint64_t)high << 32)); \
280 val; \
281})
282#else
283#define csr_read64(csr) ((uint64_t)csr_read(csr))
284#endif
285
286#endif /* !_MACHINE_RISCVREG_H_ */