Home | History | Annotate | Line # | Download | only in riscv
      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