1 /* $NetBSD: sbi.h,v 1.1 2023/05/07 12:41:48 skrll Exp $ */ 2 3 /*- 4 * Copyright (c) 2023 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Nick Hudson 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_SBI_H_ 33 #define _RISCV_SBI_H_ 34 35 #include <sys/types.h> 36 37 struct sbiret { 38 long error; 39 long value; 40 }; 41 42 #define SBI_SUCCESS 0 43 #define SBI_ERR_FAILED -1 44 #define SBI_ERR_NOT_SUPPORTED -2 45 #define SBI_ERR_INVALID_PARAM -3 46 #define SBI_ERR_DENIED -4 47 #define SBI_ERR_INVALID_ADDRESS -5 48 #define SBI_ERR_ALREADY_AVAILABLE -6 49 #define SBI_ERR_ALREADY_STARTED -7 50 #define SBI_ERR_ALREADY_STOPPED -8 51 52 #define SBI_EID_BASE 0x10 53 #define SBI_EID_TIMER 0x54494D45 // "TIME" 54 #define SBI_EID_IPI 0x00735049 // "sPI" 55 #define SBI_EID_RFENCE 0x52464E43 // "RFNC" 56 #define SBI_EID_HSM 0x0048534D // "HSM" 57 #define SBI_EID_SRST 0x53525354 // "SRST" 58 #define SBI_EID_PMU 0x00504D55 // "PMU" 59 60 /* 61 | Function Name | SBI Version | FID | EID 62 | sbi_get_sbi_spec_version | 0.2 | 0 | 0x10 63 | sbi_get_sbi_impl_id | 0.2 | 1 | 0x10 64 | sbi_get_sbi_impl_version | 0.2 | 2 | 0x10 65 | sbi_probe_extension | 0.2 | 3 | 0x10 66 | sbi_get_mvendorid | 0.2 | 4 | 0x10 67 | sbi_get_marchid | 0.2 | 5 | 0x10 68 | sbi_get_mimpid | 0.2 | 6 | 0x10 69 */ 70 71 #define SBI_FID_BASE_GETSPECVERSION 0 72 #define SBI_FID_BASE_GETIMPLID 1 73 #define SBI_FID_BASE_GETIMPLVERSION 2 74 #define SBI_FID_BASE_PROBEEXTENTION 3 75 #define SBI_FID_BASE_GETMVENDORID 4 76 #define SBI_FID_BASE_GETMARCHID 5 77 #define SBI_FID_BASE_GETMIMPID 6 78 79 struct sbiret sbi_get_spec_version(void); 80 struct sbiret sbi_get_impl_id(void); 81 struct sbiret sbi_get_impl_version(void); 82 struct sbiret sbi_probe_extension(long extension_id); 83 struct sbiret sbi_get_mvendorid(void); 84 struct sbiret sbi_get_marchid(void); 85 struct sbiret sbi_get_mimpid(void); 86 87 88 /* 89 | Implementation ID | Name 90 | 0 | Berkeley Boot Loader (BBL) 91 | 1 | OpenSBI 92 | 2 | Xvisor 93 | 3 | KVM 94 | 4 | RustSBI 95 | 5 | Diosix 96 */ 97 98 #define SBI_IMPLID_BERKELEY 0 99 #define SBI_IMPLID_OPENSBI 1 100 #define SBI_IMPLID_XVISOR 2 101 #define SBI_IMPLID_KVM 3 102 #define SBI_IMPLID_RUSTSBI 4 103 #define SBI_IMPLID_DIOSIX 5 104 105 106 #define SBI_FID_TIMER_SET 0 107 struct sbiret sbi_set_timer(uint64_t stime_value); 108 109 #define SBI_FID_IPI_SEND 0 110 struct sbiret sbi_send_ipi(unsigned long hart_mask, 111 unsigned long hart_mask_base); 112 113 #define SBI_FID_RFENCE_FENCEI 0 114 #define SBI_FID_RFENCE_SFENCEVMA 1 115 #define SBI_FID_RFENCE_SFENCEVMAASID 2 116 #define SBI_FID_RFENCE_HFENCEGVMAVMID 3 117 #define SBI_FID_RFENCE_HFENCEGVMA 4 118 #define SBI_FID_RFENCE_HFENCEVVMAASID 5 119 #define SBI_FID_RFENCE_HFENCEVVMA 6 120 121 122 struct sbiret sbi_remote_fence_i(unsigned long hart_mask, 123 unsigned long hart_mask_base); 124 struct sbiret sbi_remote_sfence_vma(unsigned long hart_mask, 125 unsigned long hart_mask_base, 126 unsigned long start_addr, 127 unsigned long size); 128 struct sbiret sbi_remote_sfence_vma_asid(unsigned long hart_mask, 129 unsigned long hart_mask_base, 130 unsigned long start_addr, 131 unsigned long size, 132 unsigned long asid); 133 struct sbiret sbi_remote_hfence_gvma_vmid(unsigned long hart_mask, 134 unsigned long hart_mask_base, 135 unsigned long start_addr, 136 unsigned long size, 137 unsigned long vmid); 138 struct sbiret sbi_remote_hfence_gvma(unsigned long hart_mask, 139 unsigned long hart_mask_base, 140 unsigned long start_addr, 141 unsigned long size); 142 struct sbiret sbi_remote_hfence_vvma_asid(unsigned long hart_mask, 143 unsigned long hart_mask_base, 144 unsigned long start_addr, 145 unsigned long size, 146 unsigned long asid); 147 struct sbiret sbi_remote_hfence_vvma(unsigned long hart_mask, 148 unsigned long hart_mask_base, 149 unsigned long start_addr, 150 unsigned long size); 151 152 #define SBI_FID_HSM_START 0 153 #define SBI_FID_HSM_STOP 1 154 #define SBI_FID_HSM_GETSTATUS 2 155 #define SBI_FID_HSM_SUSPEND 3 156 157 struct sbiret sbi_hart_start(unsigned long hartid, 158 unsigned long start_addr, 159 unsigned long opaque); 160 struct sbiret sbi_hart_stop(void); 161 struct sbiret sbi_hart_get_status(unsigned long hartid); 162 struct sbiret sbi_hart_suspend(uint32_t suspend_type, 163 unsigned long resume_addr, 164 unsigned long opaque); 165 166 #define SBI_HART_STARTED 0 167 #define SBI_HART_STOPPED 1 168 #define SBI_HART_STARTPENDING 2 169 #define SBI_HART_STOPPENDING 3 170 #define SBI_HART_SUSPENDED 4 171 #define SBI_HART_SUSPENDPENDING 5 172 #define SBI_HART_RESUMEPENDING 6 173 174 175 #define SBI_FID_SRST_SYSTEMRESET 0 176 struct sbiret sbi_system_reset(uint32_t reset_type, uint32_t reset_reason); 177 178 #define SBI_RESET_TYPE_SHUTDOWN 0 179 #define SBI_RESET_TYPE_COLDREBOOT 1 180 #define SBI_RESET_TYPE_WARNREBOOT 2 181 182 #define SBI_RESET_REASON_NONE 0 183 #define SBI_RESET_REASON_FAILURE 1 184 185 186 187 #define SBU_FID_PMU_GETCOUNTERS 0 188 #define SBU_FID_PMU_COUNTERDETAILS 1 189 #define SBU_FID_PMU_CONFIGCOUNTER 2 190 #define SBU_FID_PMU_STARTCOUNTERS 3 191 #define SBU_FID_PMU_STOPCOUNTERS 4 192 #define SBU_FID_PMU_READCOUNTER 5 193 194 #define SBI_PMU_HW_NO_EVENT 0 // Unused event because 195 // ...`event_idx` cannot be zero 196 #define SBI_PMU_HW_CPU_CYCLES 1 // Event for each CPU cycle 197 #define SBI_PMU_HW_INSTRUCTIONS 2 // Event for each completed 198 // ... instruction 199 #define SBI_PMU_HW_CACHE_REFERENCES 3 // Event for cache hit 200 #define SBI_PMU_HW_CACHE_MISSES 4 // Event for cache miss 201 #define SBI_PMU_HW_BRANCH_INSTRUCTIONS 5 // Event for a branch instruction 202 #define SBI_PMU_HW_BRANCH_MISSES 6 // Event for a branch misprediction 203 #define SBI_PMU_HW_BUS_CYCLES 7 // Event for each BUS cycle 204 #define SBI_PMU_HW_STALLED_CYCLES_FRONTEND 8 // Event for a stalled cycle in 205 // ... microarchitecture frontend 206 #define SBI_PMU_HW_STALLED_CYCLES_BACKEND 9 // Event for a stalled cycle in 207 // ... microarchitecture backend 208 #define SBI_PMU_HW_REF_CPU_CYCLES 10 // Event for each reference 209 // ... CPU cycle 210 211 #define SBI_PMU_HW_CACHE_L1D 0 // Level1 data cache event 212 #define SBI_PMU_HW_CACHE_L1I 1 // Level1 instruction cache event 213 #define SBI_PMU_HW_CACHE_LL 2 // Last level cache event 214 #define SBI_PMU_HW_CACHE_DTLB 3 // Data TLB event 215 #define SBI_PMU_HW_CACHE_ITLB 4 // Instruction TLB event 216 #define SBI_PMU_HW_CACHE_BPU 5 // Branch predictor unit event 217 #define SBI_PMU_HW_CACHE_NODE 6 // NUMA node cache event 218 219 #define SBI_PMU_HW_CACHE_OP_READ 0 // Read cache line 220 #define SBI_PMU_HW_CACHE_OP_WRITE 1 // Write cache line 221 #define SBI_PMU_HW_CACHE_OP_PREFETCH 2 // Prefetch cache line 222 223 #define SBI_PMU_HW_CACHE_RESULT_ACCESS 0 // Cache access 224 #define SBI_PMU_HW_CACHE_RESULT_MISS 1 // Cache miss 225 226 #define SBI_PMU_FW_MISALIGNED_LOAD 0 // Misaligned load trap event 227 #define SBI_PMU_FW_MISALIGNED_STORE 1 // Misaligned store trap event 228 #define SBI_PMU_FW_ACCESS_LOAD 2 // Load access trap event 229 #define SBI_PMU_FW_ACCESS_STORE 3 // Store access trap event 230 #define SBI_PMU_FW_ILLEGAL_INSN 4 // Illegal instruction trap event 231 #define SBI_PMU_FW_SET_TIMER 5 // Set timer event 232 #define SBI_PMU_FW_IPI_SENT 6 // Sent IPI to other HART event 233 #define SBI_PMU_FW_IPI_RECEIVED 7 // Received IPI from other 234 // ... HART event 235 #define SBI_PMU_FW_FENCE_I_SENT 8 // Sent FENCE.I request to 236 // ... other HART event 237 #define SBI_PMU_FW_FENCE_I_RECEIVED 9 // Received FENCE.I request 238 // ... from other HART event 239 #define SBI_PMU_FW_SFENCE_VMA_SENT 10 // Sent SFENCE.VMA request 240 // ... to other HART event 241 #define SBI_PMU_FW_SFENCE_VMA_RECEIVED 11 // Received SFENCE.VMA request 242 // ... from other HART event 243 #define SBI_PMU_FW_SFENCE_VMA_ASID_SENT 12 // Sent SFENCE.VMA with ASID 244 // ... request to other HART event 245 #define SBI_PMU_FW_SFENCE_VMA_ASID_RECEIVED 13 // Received SFENCE.VMA with ASID 246 // ... request from other HART event 247 #define SBI_PMU_FW_HFENCE_GVMA_SENT 14 // Sent HFENCE.GVMA request to 248 // ... other HART event 249 #define SBI_PMU_FW_HFENCE_GVMA_RECEIVED 15 // Received HFENCE.GVMA request 250 // ... from other HART event 251 #define SBI_PMU_FW_HFENCE_GVMA_VMID_SENT 16 // Sent HFENCE.GVMA with VMID 252 // ... request to other HART event 253 #define SBI_PMU_FW_HFENCE_GVMA_VMID_RECEIVED 17 // Received HFENCE.GVMA with VMID 254 // ... request from other HART event 255 #define SBI_PMU_FW_HFENCE_VVMA_SENT 18 // Sent HFENCE.VVMA request to 256 // ... other HART event 257 #define SBI_PMU_FW_HFENCE_VVMA_RECEIVED 19 // Received HFENCE.VVMA request 258 // ... from other HART event 259 #define SBI_PMU_FW_HFENCE_VVMA_ASID_SENT 20 // Sent HFENCE.VVMA with ASID 260 // ... request to other HART event 261 #define SBI_PMU_FW_HFENCE_VVMA_ASID_RECEIVED 21 // Received HFENCE.VVMA with ASID 262 // ... request from other HART event 263 264 265 struct sbiret sbi_pmu_num_counters(void); 266 struct sbiret sbi_pmu_counter_get_info(unsigned long counter_idx); 267 268 struct sbiret sbi_pmu_counter_config_matching(unsigned long counter_idx_base, 269 unsigned long counter_idx_mask, 270 unsigned long config_flags, 271 unsigned long event_idx, 272 uint64_t event_data); 273 struct sbiret sbi_pmu_counter_start(unsigned long counter_idx_base, 274 unsigned long counter_idx_mask, 275 unsigned long start_flags, 276 uint64_t initial_value); 277 struct sbiret sbi_pmu_counter_stop(unsigned long counter_idx_base, 278 unsigned long counter_idx_mask, 279 unsigned long stop_flags); 280 struct sbiret sbi_pmu_counter_fw_read(unsigned long counter_idx); 281 282 283 284 static inline struct sbiret 285 sbi_call(int eid, int fid, 286 unsigned long arg0, unsigned long arg1, unsigned long arg2, 287 unsigned long arg3, unsigned long arg4, unsigned long arg5) 288 { 289 struct sbiret ret; 290 291 register register_t _a7 __asm ("a7") = eid; 292 register register_t _a6 __asm ("a6") = fid; 293 294 register register_t _a0 __asm ("a0") = arg0; 295 register register_t _a1 __asm ("a1") = arg1; 296 register register_t _a2 __asm ("a2") = arg2; 297 register register_t _a3 __asm ("a3") = arg3; 298 register register_t _a4 __asm ("a4") = arg4; 299 register register_t _a5 __asm ("a5") = arg5; 300 301 __asm __volatile ( 302 "ecall" 303 : "+r" (_a0), "+r" (_a1) 304 : "r" (_a2), "r" (_a3), "r" (_a4), "r" (_a5), "r" (_a6), "r" (_a7) 305 : "memory"); 306 ret.error = _a0; 307 ret.value = _a1; 308 309 return ret; 310 } 311 312 313 #define SBI_CALL0(eid, fid) sbi_call(eid, fid, 0, 0, 0, 0, 0, 0) 314 #define SBI_CALL1(eid, fid, a0) sbi_call(eid, fid, a0, 0, 0, 0, 0, 0) 315 #define SBI_CALL2(eid, fid, a0, a1) sbi_call(eid, fid, a0, a1, 0, 0, 0, 0) 316 #define SBI_CALL3(eid, fid, a0, a1, a2) sbi_call(eid, fid, a0, a1, a2, 0, 0, 0) 317 #define SBI_CALL4(eid, fid, a0, a1, a2, a3) sbi_call(eid, fid, a0, a1, a2, a3, 0, 0) 318 #define SBI_CALL5(eid, fid, a0, a1, a2, a3, a4) sbi_call(eid, fid, a0, a1, a2, a3, a4, 0) 319 #define SBI_CALL6(eid, fid, a0, a1, a2, a3, a4, a5) sbi_call(eid, fid, a0, a1, a2, a3, a4, a5) 320 321 322 323 #if defined(__RVSBI_LEGACY) 324 325 #define SBI_LEGACY_SET_TIMER 0 326 #define SBI_LEGACY_CONSOLE_PUTCHAR 1 327 #define SBI_LEGACY_CONSOLE_GETCHAR 2 328 #define SBI_LEGACY_CLEAR_IPI 3 329 #define SBI_LEGACY_SEND_IPI 4 330 #define SBI_LEGACY_REMOTE_FENCE_I 5 331 #define SBI_LEGACY_REMOTE_SFENCE_VMA 6 332 #define SBI_LEGACY_REMOTE_SFENCE_VMA_ASID 7 333 #define SBI_LEGACY_SHUTDOWN 8 334 335 #define SBI_LEGACY_CALL0(eid) sbi_call(eid, 0, 0, 0, 0, 0, 0, 0) 336 #define SBI_LEGACY_CALL1(eid, a0) sbi_call(eid, 0, a0, 0, 0, 0, 0, 0) 337 #define SBI_LEGACY_CALL2(eid, a0, a1) sbi_call(eid, 0, a0, a1, 0, 0, 0, 0) 338 #define SBI_LEGACY_CALL3(eid, a0, a1, a2) sbi_call(eid, 0, a0, a1, a2, 0, 0, 0) 339 #define SBI_LEGACY_CALL4(eid, a0, a1, a2, a3) sbi_call(eid, 0, a0, a1, a2, a3, 0, 0) 340 #define SBI_LEGACY_CALL5(eid, a0, a1, a2, a3, a4) sbi_call(eid, 0, a0, a1, a2, a3, a4, 0) 341 342 343 /* 344 * void sbi_set_timer(uint64_t stime_value) 345 */ 346 347 static inline long 348 sbi_legacy_set_timer(uint64_t stime_value) 349 { 350 #ifdef _LP64 351 struct sbiret ret = SBI_LEGACY_CALL1(SBI_LEGACY_SET_TIMER, stime_value); 352 #else 353 struct sbiret ret = SBI_LEGACY_CALL2(SBI_LEGACY_SET_TIMER, 354 stime_value, stime_value >> 32); 355 #endif 356 return ret.error; 357 } 358 359 /* 360 * void sbi_console_putchar(int ch) 361 */ 362 363 static inline long 364 sbi_legacy_console_putchar(int c) { 365 struct sbiret ret = SBI_LEGACY_CALL1(SBI_LEGACY_CONSOLE_PUTCHAR, c); 366 367 return ret.error; 368 } 369 370 /* 371 * long sbi_console_getchar(void) 372 */ 373 static inline long 374 sbi_legacy_console_getchar(void) { 375 struct sbiret ret = SBI_LEGACY_CALL0(SBI_LEGACY_CONSOLE_GETCHAR); 376 377 return ret.error; 378 } 379 380 /* 381 * long sbi_clear_ipi(void) 382 */ 383 static inline long 384 sbi_legacy_clear_ipi(void) { 385 struct sbiret ret = SBI_LEGACY_CALL0(SBI_LEGACY_CLEAR_IPI); 386 387 return ret.error; 388 } 389 390 391 /* 392 * hart_mask is a virtual address that points to a bit-vector of harts. The 393 * bit vector is represented as a sequence of unsigned longs whose length 394 * equals the number of harts in the system divided by the number of bits 395 * in an unsigned long, rounded up to the next integer. 396 */ 397 398 /* 399 * void sbi_send_ipi(const unsigned long *hart_mask) 400 */ 401 static inline long 402 sbi_legacy_send_ipi(const unsigned long *hart_mask) { 403 struct sbiret ret = SBI_LEGACY_CALL1(SBI_LEGACY_SEND_IPI, 404 (unsigned long)hart_mask); 405 406 return ret.error; 407 } 408 409 /* 410 * long sbi_remote_fence_i(const unsigned long *hart_mask) 411 */ 412 static inline long 413 sbi_legacy_remote_fence_i(const unsigned long *hart_mask) { 414 struct sbiret ret = SBI_LEGACY_CALL1(SBI_LEGACY_REMOTE_FENCE_I, 415 (unsigned long)hart_mask); 416 417 return ret.error; 418 } 419 420 /* 421 * long sbi_remote_sfence_vma(const unsigned long *hart_mask, 422 * unsigned long start, 423 * unsigned long size) 424 */ 425 static inline long 426 sbi_legacy_remote_sfence_vma(const unsigned long *hart_mask, 427 unsigned long start, unsigned long size) 428 { 429 struct sbiret ret = SBI_LEGACY_CALL3(SBI_LEGACY_REMOTE_SFENCE_VMA, 430 (unsigned long)hart_mask, start, size); 431 432 return ret.error; 433 } 434 435 /* 436 * long sbi_remote_sfence_vma_asid(const unsigned long *hart_mask, 437 * unsigned long start, 438 * unsigned long size, 439 * unsigned long asid) 440 */ 441 static inline long 442 sbi_legacy_remote_sfence_vma_asid(const unsigned long *hart_mask, 443 unsigned long start, unsigned long size, unsigned long asid) 444 { 445 struct sbiret ret = SBI_LEGACY_CALL4(SBI_LEGACY_REMOTE_SFENCE_VMA_ASID, 446 (unsigned long)hart_mask, start, size, asid); 447 448 return ret.error; 449 } 450 451 /* 452 * void sbi_shutdown(void) 453 */ 454 static inline void 455 sbi_legacy_shutdown(void) { 456 SBI_LEGACY_CALL0(SBI_LEGACY_SHUTDOWN); 457 } 458 459 #endif 460 461 462 #endif /* _RISCV_SBI_H_ */ 463