/*-
* Copyright (c) 2023 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Nick Hudson
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
struct sbiret sbi_remote_fence_i(unsigned long hart_mask,
unsigned long hart_mask_base);
struct sbiret sbi_remote_sfence_vma(unsigned long hart_mask,
unsigned long hart_mask_base,
unsigned long start_addr,
unsigned long size);
struct sbiret sbi_remote_sfence_vma_asid(unsigned long hart_mask,
unsigned long hart_mask_base,
unsigned long start_addr,
unsigned long size,
unsigned long asid);
struct sbiret sbi_remote_hfence_gvma_vmid(unsigned long hart_mask,
unsigned long hart_mask_base,
unsigned long start_addr,
unsigned long size,
unsigned long vmid);
struct sbiret sbi_remote_hfence_gvma(unsigned long hart_mask,
unsigned long hart_mask_base,
unsigned long start_addr,
unsigned long size);
struct sbiret sbi_remote_hfence_vvma_asid(unsigned long hart_mask,
unsigned long hart_mask_base,
unsigned long start_addr,
unsigned long size,
unsigned long asid);
struct sbiret sbi_remote_hfence_vvma(unsigned long hart_mask,
unsigned long hart_mask_base,
unsigned long start_addr,
unsigned long size);
struct sbiret sbi_hart_start(unsigned long hartid,
unsigned long start_addr,
unsigned long opaque);
struct sbiret sbi_hart_stop(void);
struct sbiret sbi_hart_get_status(unsigned long hartid);
struct sbiret sbi_hart_suspend(uint32_t suspend_type,
unsigned long resume_addr,
unsigned long opaque);
#define SBI_PMU_HW_NO_EVENT 0 // Unused event because
// ...`event_idx` cannot be zero
#define SBI_PMU_HW_CPU_CYCLES 1 // Event for each CPU cycle
#define SBI_PMU_HW_INSTRUCTIONS 2 // Event for each completed
// ... instruction
#define SBI_PMU_HW_CACHE_REFERENCES 3 // Event for cache hit
#define SBI_PMU_HW_CACHE_MISSES 4 // Event for cache miss
#define SBI_PMU_HW_BRANCH_INSTRUCTIONS 5 // Event for a branch instruction
#define SBI_PMU_HW_BRANCH_MISSES 6 // Event for a branch misprediction
#define SBI_PMU_HW_BUS_CYCLES 7 // Event for each BUS cycle
#define SBI_PMU_HW_STALLED_CYCLES_FRONTEND 8 // Event for a stalled cycle in
// ... microarchitecture frontend
#define SBI_PMU_HW_STALLED_CYCLES_BACKEND 9 // Event for a stalled cycle in
// ... microarchitecture backend
#define SBI_PMU_HW_REF_CPU_CYCLES 10 // Event for each reference
// ... CPU cycle
#define SBI_PMU_FW_MISALIGNED_LOAD 0 // Misaligned load trap event
#define SBI_PMU_FW_MISALIGNED_STORE 1 // Misaligned store trap event
#define SBI_PMU_FW_ACCESS_LOAD 2 // Load access trap event
#define SBI_PMU_FW_ACCESS_STORE 3 // Store access trap event
#define SBI_PMU_FW_ILLEGAL_INSN 4 // Illegal instruction trap event
#define SBI_PMU_FW_SET_TIMER 5 // Set timer event
#define SBI_PMU_FW_IPI_SENT 6 // Sent IPI to other HART event
#define SBI_PMU_FW_IPI_RECEIVED 7 // Received IPI from other
// ... HART event
#define SBI_PMU_FW_FENCE_I_SENT 8 // Sent FENCE.I request to
// ... other HART event
#define SBI_PMU_FW_FENCE_I_RECEIVED 9 // Received FENCE.I request
// ... from other HART event
#define SBI_PMU_FW_SFENCE_VMA_SENT 10 // Sent SFENCE.VMA request
// ... to other HART event
#define SBI_PMU_FW_SFENCE_VMA_RECEIVED 11 // Received SFENCE.VMA request
// ... from other HART event
#define SBI_PMU_FW_SFENCE_VMA_ASID_SENT 12 // Sent SFENCE.VMA with ASID
// ... request to other HART event
#define SBI_PMU_FW_SFENCE_VMA_ASID_RECEIVED 13 // Received SFENCE.VMA with ASID
// ... request from other HART event
#define SBI_PMU_FW_HFENCE_GVMA_SENT 14 // Sent HFENCE.GVMA request to
// ... other HART event
#define SBI_PMU_FW_HFENCE_GVMA_RECEIVED 15 // Received HFENCE.GVMA request
// ... from other HART event
#define SBI_PMU_FW_HFENCE_GVMA_VMID_SENT 16 // Sent HFENCE.GVMA with VMID
// ... request to other HART event
#define SBI_PMU_FW_HFENCE_GVMA_VMID_RECEIVED 17 // Received HFENCE.GVMA with VMID
// ... request from other HART event
#define SBI_PMU_FW_HFENCE_VVMA_SENT 18 // Sent HFENCE.VVMA request to
// ... other HART event
#define SBI_PMU_FW_HFENCE_VVMA_RECEIVED 19 // Received HFENCE.VVMA request
// ... from other HART event
#define SBI_PMU_FW_HFENCE_VVMA_ASID_SENT 20 // Sent HFENCE.VVMA with ASID
// ... request to other HART event
#define SBI_PMU_FW_HFENCE_VVMA_ASID_RECEIVED 21 // Received HFENCE.VVMA with ASID
// ... request from other HART event
struct sbiret sbi_pmu_num_counters(void);
struct sbiret sbi_pmu_counter_get_info(unsigned long counter_idx);
struct sbiret sbi_pmu_counter_config_matching(unsigned long counter_idx_base,
unsigned long counter_idx_mask,
unsigned long config_flags,
unsigned long event_idx,
uint64_t event_data);
struct sbiret sbi_pmu_counter_start(unsigned long counter_idx_base,
unsigned long counter_idx_mask,
unsigned long start_flags,
uint64_t initial_value);
struct sbiret sbi_pmu_counter_stop(unsigned long counter_idx_base,
unsigned long counter_idx_mask,
unsigned long stop_flags);
struct sbiret sbi_pmu_counter_fw_read(unsigned long counter_idx);
static inline struct sbiret
sbi_call(int eid, int fid,
unsigned long arg0, unsigned long arg1, unsigned long arg2,
unsigned long arg3, unsigned long arg4, unsigned long arg5)
{
struct sbiret ret;
static inline long
sbi_legacy_set_timer(uint64_t stime_value)
{
#ifdef _LP64
struct sbiret ret = SBI_LEGACY_CALL1(SBI_LEGACY_SET_TIMER, stime_value);
#else
struct sbiret ret = SBI_LEGACY_CALL2(SBI_LEGACY_SET_TIMER,
stime_value, stime_value >> 32);
#endif
return ret.error;
}
/*
* void sbi_console_putchar(int ch)
*/
static inline long
sbi_legacy_console_putchar(int c) {
struct sbiret ret = SBI_LEGACY_CALL1(SBI_LEGACY_CONSOLE_PUTCHAR, c);
return ret.error;
}
/*
* long sbi_console_getchar(void)
*/
static inline long
sbi_legacy_console_getchar(void) {
struct sbiret ret = SBI_LEGACY_CALL0(SBI_LEGACY_CONSOLE_GETCHAR);
return ret.error;
}
/*
* long sbi_clear_ipi(void)
*/
static inline long
sbi_legacy_clear_ipi(void) {
struct sbiret ret = SBI_LEGACY_CALL0(SBI_LEGACY_CLEAR_IPI);
return ret.error;
}
/*
* hart_mask is a virtual address that points to a bit-vector of harts. The
* bit vector is represented as a sequence of unsigned longs whose length
* equals the number of harts in the system divided by the number of bits
* in an unsigned long, rounded up to the next integer.
*/
/*
* void sbi_send_ipi(const unsigned long *hart_mask)
*/
static inline long
sbi_legacy_send_ipi(const unsigned long *hart_mask) {
struct sbiret ret = SBI_LEGACY_CALL1(SBI_LEGACY_SEND_IPI,
(unsigned long)hart_mask);
return ret.error;
}
/*
* long sbi_remote_fence_i(const unsigned long *hart_mask)
*/
static inline long
sbi_legacy_remote_fence_i(const unsigned long *hart_mask) {
struct sbiret ret = SBI_LEGACY_CALL1(SBI_LEGACY_REMOTE_FENCE_I,
(unsigned long)hart_mask);
return ret.error;
}
/*
* long sbi_remote_sfence_vma(const unsigned long *hart_mask,
* unsigned long start,
* unsigned long size)
*/
static inline long
sbi_legacy_remote_sfence_vma(const unsigned long *hart_mask,
unsigned long start, unsigned long size)
{
struct sbiret ret = SBI_LEGACY_CALL3(SBI_LEGACY_REMOTE_SFENCE_VMA,
(unsigned long)hart_mask, start, size);
return ret.error;
}
/*
* long sbi_remote_sfence_vma_asid(const unsigned long *hart_mask,
* unsigned long start,
* unsigned long size,
* unsigned long asid)
*/
static inline long
sbi_legacy_remote_sfence_vma_asid(const unsigned long *hart_mask,
unsigned long start, unsigned long size, unsigned long asid)
{
struct sbiret ret = SBI_LEGACY_CALL4(SBI_LEGACY_REMOTE_SFENCE_VMA_ASID,
(unsigned long)hart_mask, start, size, asid);