1 /* $NetBSD: sysreg.h,v 1.3 2015/03/31 01:14:02 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, sstatus" : "=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, sstatus, %1" : "=r"(__sr) : "i"(__mask)); 138 } else { 139 __asm("csrrc\t%0, sstatus, %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, sstatus, %1" : "=r"(__sr) : "i"(__mask)); 150 } else { 151 __asm("csrrs\t%0, sstatus, %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_MISALIGNED_LOAD 4 162 #define CAUSE_FAULT_LOAD 5 163 #define CAUSE_MISALIGNED_STORE 6 164 #define CAUSE_FAULT_STORE 7 165 #define CAUSE_SYSCALL 8 166 #define CAUSE_BREAKPOINT 9 167 #define CAUSE_FP_DISABLED 10 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 static inline uintptr_t 193 riscvreg_ptbr_read(void) 194 { 195 uintptr_t __ptbr; 196 __asm("csrr\t%0, sptbr" : "=r"(__ptbr)); 197 return __ptbr; 198 } 199 200 static inline void 201 riscvreg_ptbr_write(uint32_t __ptbr) 202 { 203 __asm("csrw\tsptbr, %0" :: "r"(__ptbr)); 204 } 205 206 static inline uint32_t 207 riscvreg_asid_read(void) 208 { 209 uint32_t __asid; 210 __asm __volatile("csrr\t%0, sasid" : "=r"(__asid)); 211 return __asid; 212 } 213 214 static inline void 215 riscvreg_asid_write(uint32_t __asid) 216 { 217 __asm __volatile("csrw\tsasid, %0" :: "r"(__asid)); 218 } 219 220 #endif /* _RISCV_SYSREG_H_ */ 221