1 /* $NetBSD: sbi.c,v 1.1 2023/05/07 12:41:49 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 #include <sys/param.h> 33 #include <sys/types.h> 34 35 #include <sys/device.h> 36 #include <dev/cons.h> 37 38 #include <riscv/sbi.h> 39 40 struct sbiret 41 sbi_get_spec_version(void) 42 { 43 return SBI_CALL0(SBI_EID_BASE, SBI_FID_BASE_GETSPECVERSION); 44 } 45 46 struct sbiret 47 sbi_get_impl_id(void) 48 { 49 return SBI_CALL0(SBI_EID_BASE, SBI_FID_BASE_GETIMPLID); 50 } 51 52 struct sbiret 53 sbi_get_impl_version(void) 54 { 55 return SBI_CALL0(SBI_EID_BASE, SBI_FID_BASE_GETIMPLVERSION); 56 } 57 58 struct sbiret 59 sbi_probe_extension(long extension_id) 60 { 61 return SBI_CALL1(SBI_EID_BASE, SBI_FID_BASE_PROBEEXTENTION, 62 extension_id); 63 } 64 65 struct sbiret 66 sbi_get_mvendorid(void) 67 { 68 return SBI_CALL0(SBI_EID_BASE, SBI_FID_BASE_GETMVENDORID); 69 } 70 71 struct sbiret 72 sbi_get_marchid(void) 73 { 74 return SBI_CALL0(SBI_EID_BASE, SBI_FID_BASE_GETMARCHID); 75 } 76 77 struct sbiret 78 sbi_get_mimpid(void) 79 { 80 return SBI_CALL0(SBI_EID_BASE, SBI_FID_BASE_GETMIMPID); 81 } 82 83 84 struct sbiret 85 sbi_set_timer(uint64_t stime_value) 86 { 87 #ifdef _LP64 88 struct sbiret ret = SBI_CALL1(SBI_EID_TIMER, SBI_FID_TIMER_SET, 89 stime_value); 90 #else 91 struct sbiret ret = SBI_CALL2(SBI_EID_TIMER, SBI_FID_TIMER_SET, 92 stime_value, stime_value >> 32); 93 #endif 94 return ret; 95 } 96 97 struct sbiret 98 sbi_send_ipi(unsigned long hart_mask, unsigned long hart_mask_base) 99 { 100 return SBI_CALL2(SBI_EID_IPI, SBI_FID_IPI_SEND, 101 hart_mask, hart_mask_base); 102 } 103 104 105 struct sbiret 106 sbi_remote_fence_i(unsigned long hart_mask, unsigned long hart_mask_base) 107 { 108 return SBI_CALL2(SBI_EID_RFENCE, SBI_FID_RFENCE_FENCEI, 109 hart_mask, hart_mask_base); 110 } 111 112 struct sbiret 113 sbi_remote_sfence_vma(unsigned long hart_mask, unsigned long hart_mask_base, 114 unsigned long start_addr, unsigned long size) 115 { 116 return SBI_CALL4(SBI_EID_RFENCE, SBI_FID_RFENCE_SFENCEVMA, 117 hart_mask, hart_mask_base, start_addr, size); 118 } 119 120 struct sbiret 121 sbi_remote_sfence_vma_asid(unsigned long hart_mask, 122 unsigned long hart_mask_base, unsigned long start_addr, 123 unsigned long size, unsigned long asid) 124 { 125 return SBI_CALL5(SBI_EID_RFENCE, SBI_FID_RFENCE_SFENCEVMAASID, 126 hart_mask, hart_mask_base, start_addr, size, asid); 127 } 128 129 struct sbiret 130 sbi_remote_hfence_gvma_vmid(unsigned long hart_mask, 131 unsigned long hart_mask_base, unsigned long start_addr, 132 unsigned long size, unsigned long vmid) 133 { 134 return SBI_CALL5(SBI_EID_RFENCE, SBI_FID_RFENCE_HFENCEGVMAVMID, 135 hart_mask, hart_mask_base, start_addr, size, vmid); 136 } 137 138 struct sbiret 139 sbi_remote_hfence_gvma(unsigned long hart_mask, 140 unsigned long hart_mask_base, unsigned long start_addr, 141 unsigned long size) 142 { 143 return SBI_CALL4(SBI_EID_RFENCE, SBI_FID_RFENCE_HFENCEGVMA, 144 hart_mask, hart_mask_base, start_addr, size); 145 } 146 147 struct sbiret 148 sbi_remote_hfence_vvma_asid(unsigned long hart_mask, 149 unsigned long hart_mask_base, unsigned long start_addr, 150 unsigned long size, unsigned long asid) 151 { 152 return SBI_CALL5(SBI_EID_RFENCE, SBI_FID_RFENCE_HFENCEVVMAASID, 153 hart_mask, hart_mask_base, start_addr, size, asid); 154 } 155 156 struct sbiret 157 sbi_remote_hfence_vvma(unsigned long hart_mask, unsigned long hart_mask_base, 158 unsigned long start_addr, unsigned long size) 159 { 160 return SBI_CALL4(SBI_EID_RFENCE, SBI_FID_RFENCE_HFENCEVVMA, 161 hart_mask, hart_mask_base, start_addr, size); 162 } 163 164 struct sbiret 165 sbi_hart_start(unsigned long hartid, unsigned long start_addr, 166 unsigned long opaque) 167 { 168 return SBI_CALL3(SBI_EID_HSM, SBI_FID_HSM_START, 169 hartid, start_addr, opaque); 170 } 171 172 struct sbiret 173 sbi_hart_stop(void) 174 { 175 return SBI_CALL0(SBI_EID_HSM, SBI_FID_HSM_STOP); 176 } 177 178 struct sbiret 179 sbi_hart_get_status(unsigned long hartid) 180 { 181 return SBI_CALL1(SBI_EID_HSM, SBI_FID_HSM_GETSTATUS, 182 hartid); 183 } 184 185 struct sbiret 186 sbi_hart_suspend(uint32_t suspend_type, unsigned long resume_addr, 187 unsigned long opaque) 188 { 189 return SBI_CALL3(SBI_EID_HSM, SBI_FID_HSM_SUSPEND, 190 suspend_type, resume_addr, opaque); 191 } 192 193 struct sbiret 194 sbi_system_reset(uint32_t reset_type, uint32_t reset_reason) 195 { 196 return SBI_CALL2(SBI_EID_SRST, SBI_FID_SRST_SYSTEMRESET, 197 reset_type, reset_reason); 198 } 199 200 struct sbiret 201 sbi_pmu_num_counters(void) 202 { 203 return SBI_CALL0(SBI_EID_PMU, SBU_FID_PMU_GETCOUNTERS); 204 } 205 206 struct sbiret 207 sbi_pmu_counter_get_info(unsigned long counter_idx) 208 { 209 return SBI_CALL1(SBI_EID_PMU, SBU_FID_PMU_COUNTERDETAILS, 210 counter_idx); 211 } 212 213 214 struct sbiret 215 sbi_pmu_counter_config_matching(unsigned long counter_idx_base, 216 unsigned long counter_idx_mask, unsigned long config_flags, 217 unsigned long event_idx, uint64_t event_data) 218 { 219 #ifdef _LP64 220 return SBI_CALL5(SBI_EID_PMU, SBU_FID_PMU_CONFIGCOUNTER, 221 counter_idx_base, counter_idx_mask, config_flags, event_idx, 222 event_data); 223 #else 224 return SBI_CALL6(SBI_EID_PMU, SBU_FID_PMU_CONFIGCOUNTER, 225 counter_idx_base, counter_idx_mask, config_flags, event_idx, 226 event_data, event_data >> 32); 227 #endif 228 } 229 230 struct sbiret 231 sbi_pmu_counter_start(unsigned long counter_idx_base, 232 unsigned long counter_idx_mask, unsigned long start_flags, 233 uint64_t initial_value) 234 { 235 #ifdef _LP64 236 return SBI_CALL4(SBI_EID_PMU, SBU_FID_PMU_STARTCOUNTERS, 237 counter_idx_base, counter_idx_mask, start_flags, 238 initial_value); 239 #else 240 return SBI_CALL5(SBI_EID_PMU, SBU_FID_PMU_STARTCOUNTERS, 241 counter_idx_base, counter_idx_mask, start_flags, 242 initial_value, initial_value >> 32); 243 #endif 244 } 245 246 struct sbiret 247 sbi_pmu_counter_stop(unsigned long counter_idx_base, 248 unsigned long counter_idx_mask, unsigned long stop_flags) 249 { 250 return SBI_CALL3(SBI_EID_PMU, SBU_FID_PMU_STOPCOUNTERS, 251 counter_idx_base, counter_idx_mask, stop_flags); 252 } 253 254 struct sbiret 255 sbi_pmu_counter_fw_read(unsigned long counter_idx) 256 { 257 return SBI_CALL1(SBI_EID_PMU, SBU_FID_PMU_READCOUNTER, 258 counter_idx); 259 } 260