sysreg.h revision 1.1 1 /* $NetBSD: sysreg.h,v 1.1 2014/09/19 17:36:26 matt Exp $ */
2 /*-
3 * Copyright (c) 2014 The NetBSD Foundation, Inc.
4 * All rights reserved.
5 *
6 * This code is derived from software contributed to The NetBSD Foundation
7 * by Matt Thomas of 3am Software Foundry.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
19 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
20 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
22 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 * POSSIBILITY OF SUCH DAMAGE.
29 */
30
31 #ifndef _RISCV_SYSREG_H_
32 #define _RISCV_SYSREG_H_
33
34 #ifndef _KERNEL
35 #include <sys/param.h>
36 #endif
37
38 #define FCSR_FMASK 0 // no exception bits
39 #define FCSR_FRM __BITS(7,5)
40 #define FCSR_FRM_RNE 0b000 // Round Nearest, ties to Even
41 #define FCSR_FRM_RTZ 0b001 // Round Towards Zero
42 #define FCSR_FRM_RDN 0b010 // Round DowN (-infinity)
43 #define FCSR_FRM_RUP 0b011 // Round UP (+infinity)
44 #define FCSR_FRM_RMM 0b100 // Round to nearest, ties to Max Magnitude
45 #define FCSR_FFLAGS __BITS(4,0) // Sticky bits
46 #define FCSR_NV __BIT(4) // iNValid operation
47 #define FCSR_DZ __BIT(3) // Divide by Zero
48 #define FCSR_OF __BIT(2) // OverFlow
49 #define FCSR_UF __BIT(1) // UnderFlow
50 #define FCSR_NX __BIT(0) // iNeXact
51
52 static inline uint32_t
53 riscvreg_fcsr_read(void)
54 {
55 uint32_t __fcsr;
56 __asm("frcsr %0" : "=r"(__fcsr));
57 return __fcsr;
58 }
59
60
61 static inline uint32_t
62 riscvreg_fcsr_write(uint32_t __new)
63 {
64 uint32_t __old;
65 __asm("fscsr %0, %1" : "=r"(__old) : "r"(__new));
66 return __old;
67 }
68
69 static inline uint32_t
70 riscvreg_fcsr_read_fflags(void)
71 {
72 uint32_t __old;
73 __asm("frflags %0" : "=r"(__old));
74 return __SHIFTOUT(__old, FCSR_FFLAGS);
75 }
76
77 static inline uint32_t
78 riscvreg_fcsr_write_fflags(uint32_t __new)
79 {
80 uint32_t __old;
81 __new = __SHIFTIN(__new, FCSR_FFLAGS);
82 __asm("fsflags %0, %1" : "=r"(__old) : "r"(__new));
83 return __SHIFTOUT(__old, FCSR_FFLAGS);
84 }
85
86 static inline uint32_t
87 riscvreg_fcsr_read_frm(void)
88 {
89 uint32_t __old;
90 __asm("frrm\t%0" : "=r"(__old));
91 return __SHIFTOUT(__old, FCSR_FRM);
92 }
93
94 static inline uint32_t
95 riscvreg_fcsr_write_frm(uint32_t __new)
96 {
97 uint32_t __old;
98 __new = __SHIFTIN(__new, FCSR_FRM);
99 __asm volatile("fsrm\t%0, %1" : "=r"(__old) : "r"(__new));
100 return __SHIFTOUT(__old, FCSR_FRM);
101 }
102
103 // Status Register
104 #define SR_IP __BITS(31,24) // Pending interrupts
105 #define SR_IM __BITS(23,16) // Interrupt Mask
106 #define SR_VM __BIT(7) // MMU On
107 #define SR_S64 __BIT(6) // RV64 supervisor mode
108 #define SR_U64 __BIT(5) // RV64 user mode
109 #define SR_EF __BIT(4) // Enable Floating Point
110 #define SR_PEI __BIT(3) // Previous EI setting
111 #define SR_EI __BIT(2) // Enable interrupts
112 #define SR_PS __BIT(1) // Previous (S) supervisor setting
113 #define SR_S __BIT(0) // Supervisor
114
115 #ifdef _LP64
116 #define SR_USER (SR_EI|SR_U64|SR_S64|SR_VM|SR_IM)
117 #define SR_USER32 (SR_USER & ~SR_U64)
118 #define SR_KERNEL (SR_S|SR_EI|SR_U64|SR_S64|SR_VM)
119 #else
120 #define SR_USER (SR_EI|SR_VM|SR_IM)
121 #define SR_KERNEL (SR_S|SR_EI|SR_VM)
122 #endif
123
124 static inline uint32_t
125 riscvreg_status_read(void)
126 {
127 uint32_t __sr;
128 __asm("csrr\t%0, status" : "=r"(__sr));
129 return __sr;
130 }
131
132 static inline uint32_t
133 riscvreg_status_clear(uint32_t __mask)
134 {
135 uint32_t __sr;
136 if (__builtin_constant_p(__mask) && __mask < 0x20) {
137 __asm("csrrci\t%0, status, %1" : "=r"(__sr) : "i"(__mask));
138 } else {
139 __asm("csrrc\t%0, status, %1" : "=r"(__sr) : "r"(__mask));
140 }
141 return __sr;
142 }
143
144 static inline uint32_t
145 riscvreg_status_set(uint32_t __mask)
146 {
147 uint32_t __sr;
148 if (__builtin_constant_p(__mask) && __mask < 0x20) {
149 __asm("csrrsi\t%0, status, %1" : "=r"(__sr) : "i"(__mask));
150 } else {
151 __asm("csrrs\t%0, status, %1" : "=r"(__sr) : "r"(__mask));
152 }
153 return __sr;
154 }
155
156 // Cause register
157 #define CAUSE_MISALIGNED_FETCH 0
158 #define CAUSE_FAULT_FETCH 1
159 #define CAUSE_ILLEGAL_INSTRUCTION 2
160 #define CAUSE_PRIVILEGED_INSTRUCTION 3
161 #define CAUSE_FP_DISABLED 4
162 #define CAUSE_SYSCALL 6
163 #define CAUSE_BREAKPOINT 7
164 #define CAUSE_MISALIGNED_LOAD 8
165 #define CAUSE_MISALIGNED_STORE 9
166 #define CAUSE_FAULT_LOAD 10
167 #define CAUSE_FAULT_STORE 11
168 #define CAUSE_ACCELERATOR_DISABLED 12
169
170 static inline uint64_t
171 riscvreg_cycle_read(void)
172 {
173 #ifdef _LP64
174 uint64_t __lo;
175 __asm __volatile("csrr\t%0,cycle" : "=r"(__lo));
176 return __lo;
177 #else
178 uint32_t __hi0, __hi1, __lo0;
179 do {
180 __asm __volatile(
181 "csrr\t%[__hi0], cycleh"
182 "\n\t" "csrr\t%[__lo0], cycle"
183 "\n\t" "csrr\t%[__hi1], cycleh"
184 : [__hi0] "=r"(__hi0),
185 [__lo0] "=r"(__lo0),
186 [__hi1] "=r"(__hi1));
187 } while (__hi0 != __hi1);
188 return ((uint64_t)__hi0 << 32) | (uint64_t)__lo0;
189 #endif
190 }
191
192 #endif /* _RISCV_SYSREG_H_ */
193