xref: /openbsd/sys/arch/riscv64/include/riscvreg.h (revision dd81489d)
1 /*	$OpenBSD: riscvreg.h,v 1.5 2022/08/29 02:01:18 jsg Exp $	*/
2 
3 /*-
4  * Copyright (c) 2019 Brian Bamsch <bbamsch@google.com>
5  * Copyright (c) 2015-2017 Ruslan Bukin <br@bsdpad.com>
6  * All rights reserved.
7  *
8  * Portions of this software were developed by SRI International and the
9  * University of Cambridge Computer Laboratory under DARPA/AFRL contract
10  * FA8750-10-C-0237 ("CTSRD"), as part of the DARPA CRASH research programme.
11  *
12  * Portions of this software were developed by the University of Cambridge
13  * Computer Laboratory as part of the CTSRD Project, with support from the
14  * UK Higher Education Innovation Fund (HEIF).
15  *
16  * Redistribution and use in source and binary forms, with or without
17  * modification, are permitted provided that the following conditions
18  * are met:
19  * 1. Redistributions of source code must retain the above copyright
20  *    notice, this list of conditions and the following disclaimer.
21  * 2. Redistributions in binary form must reproduce the above copyright
22  *    notice, this list of conditions and the following disclaimer in the
23  *    documentation and/or other materials provided with the distribution.
24  * 3. Neither the name of the copyright holder nor the names of its
25  *    contributors may be used to endorse or promote products derived from
26  *    this software without specific prior written permission.
27  *
28  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
29  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
30  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
31  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
32  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
36  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
37  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
38  * SUCH DAMAGE.
39  */
40 
41 #ifndef _MACHINE_RISCVREG_H_
42 #define _MACHINE_RISCVREG_H_
43 
44 #define EXCP_SHIFT			0
45 #define EXCP_MASK			(0xf << EXCP_SHIFT)
46 #define EXCP_MISALIGNED_FETCH		0
47 #define EXCP_FAULT_FETCH		1
48 #define EXCP_ILLEGAL_INSTRUCTION	2
49 #define EXCP_BREAKPOINT			3
50 #define EXCP_MISALIGNED_LOAD		4
51 #define EXCP_FAULT_LOAD			5
52 #define EXCP_MISALIGNED_STORE		6
53 #define EXCP_FAULT_STORE		7
54 #define EXCP_USER_ECALL			8
55 #define EXCP_SUPERVISOR_ECALL		9
56 #define EXCP_HYPERVISOR_ECALL		10
57 #define EXCP_MACHINE_ECALL		11
58 #define EXCP_INST_PAGE_FAULT		12
59 #define EXCP_LOAD_PAGE_FAULT		13
60 #define EXCP_STORE_PAGE_FAULT		15
61 #define EXCP_INTR			(1ULL << 63)
62 
63 #define MSTATUS_UIE		(1 << 0)
64 #define MSTATUS_SIE		(1 << 1)
65 #define MSTATUS_MIE		(1 << 3)
66 #define MSTATUS_UPIE		(1 << 4)
67 #define MSTATUS_SPIE		(1 << 5)
68 #define MSTATUS_MPIE		(1 << 7)
69 #define MSTATUS_SPP		(1 << 8)
70 #define MSTATUS_MPP_SHIFT	11
71 #define MSTATUS_MPP_MASK	(0x3 << MSTATUS_MPP_SHIFT)
72 #define MSTATUS_FS_SHIFT	13
73 #define MSTATUS_FS_MASK		(0x3 << MSTATUS_FS_SHIFT)
74 #define MSTATUS_XS_SHIFT	15
75 #define MSTATUS_XS_MASK		(0x3 << MSTATUS_XS_SHIFT)
76 #define MSTATUS_MPRV		(1 << 17)
77 #define MSTATUS_SUM		(1 << 18)
78 #define MSTATUS_MXR		(1 << 19)
79 #define MSTATUS_TVM		(1 << 20)
80 #define MSTATUS_TW		(1 << 21)
81 #define MSTATUS_TSR		(1 << 22)
82 #define MSTATUS_UXL_SHIFT	32
83 #define MSTATUS_UXL_MASK	(0x3ULL << MSTATUS_UXL_SHIFT)
84 #define MSTATUS_SXL_SHIFT	34
85 #define MSTATUS_SXL_MASK	(0x3ULL << MSTATUS_SXL_SHIFT)
86 #define MSTATUS_SD		(1ULL << (MXLEN - 1))
87 
88 #define SSTATUS_UIE		(1 << 0)
89 #define SSTATUS_SIE		(1 << 1)
90 #define SSTATUS_UPIE		(1 << 4)
91 #define SSTATUS_SPIE		(1 << 5)
92 #define SSTATUS_SPP		(1 << 8)
93 #define SSTATUS_FS_SHIFT	13
94 #define SSTATUS_FS_MASK		(0x3 << SSTATUS_FS_SHIFT)
95 #define SSTATUS_FS_OFF		(0x0 << SSTATUS_FS_SHIFT)
96 #define SSTATUS_FS_INITIAL	(0x1 << SSTATUS_FS_SHIFT)
97 #define SSTATUS_FS_CLEAN	(0x2 << SSTATUS_FS_SHIFT)
98 #define SSTATUS_FS_DIRTY	(0x3 << SSTATUS_FS_SHIFT)
99 #define SSTATUS_XS_SHIFT	15
100 #define SSTATUS_XS_MASK		(0x3 << SSTATUS_XS_SHIFT)
101 #define SSTATUS_SUM		(1 << 18)
102 #define SSTATUS_MXR		(1 << 19)
103 #define SSTATUS_UXL_SHIFT	32
104 #define SSTATUS_UXL_MASK	(0x3ULL << SSTATUS_UXL_SHIFT)
105 #define SSTATUS_SD		(1ULL << (SXLEN - 1))
106 
107 #define USTATUS_UIE		(1 << 0)
108 #define USTATUS_UPIE		(1 << 4)
109 
110 #define MSTATUS_PRV_U		0	/* user */
111 #define MSTATUS_PRV_S		1	/* supervisor */
112 #define MSTATUS_PRV_H		2	/* hypervisor */
113 #define MSTATUS_PRV_M		3	/* machine */
114 
115 #define MIE_USIE	(1 << 0)
116 #define MIE_SSIE	(1 << 1)
117 #define MIE_MSIE	(1 << 3)
118 #define MIE_UTIE	(1 << 4)
119 #define MIE_STIE	(1 << 5)
120 #define MIE_MTIE	(1 << 7)
121 #define MIE_UEIE	(1 << 8)
122 #define MIE_SEIE	(1 << 9)
123 #define MIE_MEIE	(1 << 11)
124 
125 #define MIP_USIP	(1 << 0)
126 #define MIP_SSIP	(1 << 1)
127 #define MIP_MSIP	(1 << 3)
128 #define MIP_UTIP	(1 << 4)
129 #define MIP_STIP	(1 << 5)
130 #define MIP_MTIP	(1 << 7)
131 #define MIP_UEIP	(1 << 8)
132 #define MIP_SEIP	(1 << 9)
133 #define MIP_MEIP	(1 << 11)
134 
135 #define SIE_USIE	(1 << 0)
136 #define SIE_SSIE	(1 << 1)
137 #define SIE_UTIE	(1 << 4)
138 #define SIE_STIE	(1 << 5)
139 #define SIE_UEIE	(1 << 8)
140 #define SIE_SEIE	(1 << 9)
141 
142 #define SIP_USIP	(1 << 0)
143 #define SIP_SSIP	(1 << 1)
144 #define SIP_UTIP	(1 << 4)
145 #define SIP_STIP	(1 << 5)
146 #define SIP_UEIP	(1 << 8)
147 #define SIP_SEIP	(1 << 9)
148 
149 #define UIE_USIE	(1 << 0)
150 #define UIE_UTIE	(1 << 4)
151 #define UIE_UEIE	(1 << 8)
152 
153 #define UIP_USIP	(1 << 0)
154 #define UIP_UTIP	(1 << 4)
155 #define UIP_UEIP	(1 << 8)
156 
157 #define PPN(pa)			((pa) >> PAGE_SHIFT)
158 #define SATP_PPN_SHIFT		0
159 #define SATP_PPN_MASK		(0xfffffffffffULL << SATP_PPN_SHIFT)
160 #define SATP_PPN(satp)		(((satp) & SATP_PPN_MASK) >> SATP_PPN_SHIFT)
161 #define SATP_FORMAT_PPN(ppn)	(((uint64_t)(ppn) << SATP_PPN_SHIFT) & SATP_PPN_MASK)
162 #define SATP_ASID_SHIFT		44
163 #define SATP_ASID_MASK		(0xffffULL << SATP_ASID_SHIFT)
164 #define SATP_ASID(satp)		(((satp) & SATP_ASID_MASK) >> SATP_ASID_SHIFT)
165 #define SATP_FORMAT_ASID(asid)	(((uint64_t)(asid) << SATP_ASID_SHIFT) & SATP_ASID_MASK)
166 #define SATP_MODE_SHIFT		60
167 #define SATP_MODE_MASK		(0xfULL << SATP_MODE_SHIFT)
168 #define SATP_MODE(mode)		(((satp) & SATP_MODE_MASK) >> SATP_MODE_SHIFT)
169 
170 #define SATP_MODE_SV39		(8ULL  << SATP_MODE_SHIFT)
171 #define SATP_MODE_SV48		(9ULL  << SATP_MODE_SHIFT)
172 #define SATP_MODE_SV57		(10ULL << SATP_MODE_SHIFT)
173 #define SATP_MODE_SV64		(11ULL << SATP_MODE_SHIFT)
174 
175 /**
176  * As of RISC-V Machine ISA v1.11, the XLEN can vary between
177  * Machine, Supervisor, and User modes. The Machine XLEN (MXLEN)
178  * is resolved from the MXL field of the 'misa' CSR. The
179  * Supervisor XLEN (SXLEN) and User XLEN (UXLEN) are resolved
180  * from the SXL and UXL fields of the 'mstatus' CSR, respectively.
181  *
182  * The Machine XLEN is reset to the widest supported ISA variant
183  * at machine reset. For now, assume that all modes will always
184  * use the same, static XLEN of 64 bits.
185  */
186 #define XLEN			64
187 #define XLEN_BYTES		(XLEN / 8)
188 #define MXLEN			XLEN
189 #define SXLEN			XLEN
190 #define UXLEN			XLEN
191 #define INSN_SIZE		4
192 #define INSN_C_SIZE		2
193 
194 // Check if val can fit in the CSR immediate form
195 #define CSR_ZIMM(val)							\
196 	(__builtin_constant_p(val) && ((u_long)(val) < 32))
197 
198 #define csr_swap(csr, val)						\
199 ({	if (CSR_ZIMM(val))						\
200 		__asm volatile("csrrwi %0, " #csr ", %1"		\
201 				: "=r" (val) : "i" (val));		\
202 	else								\
203 		__asm volatile("csrrw %0, " #csr ", %1"		\
204 				: "=r" (val) : "r" (val));		\
205 	val;								\
206 })
207 
208 #define csr_write(csr, val)						\
209 ({	if (CSR_ZIMM(val))						\
210 		__asm volatile("csrwi " #csr ", %0" :: "i" (val));	\
211 	else								\
212 		__asm volatile("csrw " #csr ", %0" ::  "r" (val));	\
213 })
214 
215 #define csr_set(csr, val)						\
216 ({	if (CSR_ZIMM(val))						\
217 		__asm volatile("csrsi " #csr ", %0" :: "i" (val));	\
218 	else								\
219 		__asm volatile("csrs " #csr ", %0" :: "r" (val));	\
220 })
221 
222 #define csr_clear(csr, val)						\
223 ({	if (CSR_ZIMM(val))						\
224 		__asm volatile("csrci " #csr ", %0" :: "i" (val));	\
225 	else								\
226 		__asm volatile("csrc " #csr ", %0" :: "r" (val));	\
227 })
228 
229 #define csr_read(csr)							\
230 ({	u_long val;							\
231 	__asm volatile("csrr %0, " #csr : "=r" (val));		\
232 	val;								\
233 })
234 
235 #endif /* !_MACHINE_RISCVREG_H_ */
236