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