mirror of
https://github.com/riscv-software-src/opensbi.git
synced 2025-08-24 23:41:23 +01:00

The SBI_ETRAP error code was introduced only for doing trap redirection in generic sbi_ecall_handler(). Now the trap redirection is moved into sbi_ecall_legacy.c and SBI_ETRAP error code is only used in this source file so let us remove it. Signed-off-by: Anup Patel <apatel@ventanamicro.com>
144 lines
3.5 KiB
C
144 lines
3.5 KiB
C
/*
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
*
|
|
* Copyright (c) 2020 Western Digital Corporation or its affiliates.
|
|
*
|
|
* Authors:
|
|
* Anup Patel <anup.patel@wdc.com>
|
|
* Atish Patra <atish.patra@wdc.com>
|
|
*/
|
|
|
|
#include <sbi/riscv_asm.h>
|
|
#include <sbi/sbi_console.h>
|
|
#include <sbi/sbi_domain.h>
|
|
#include <sbi/sbi_ecall.h>
|
|
#include <sbi/sbi_ecall_interface.h>
|
|
#include <sbi/sbi_error.h>
|
|
#include <sbi/sbi_hsm.h>
|
|
#include <sbi/sbi_ipi.h>
|
|
#include <sbi/sbi_platform.h>
|
|
#include <sbi/sbi_system.h>
|
|
#include <sbi/sbi_timer.h>
|
|
#include <sbi/sbi_tlb.h>
|
|
#include <sbi/sbi_trap.h>
|
|
#include <sbi/sbi_unpriv.h>
|
|
#include <sbi/sbi_hart.h>
|
|
|
|
static bool sbi_load_hart_mask_unpriv(ulong *pmask, ulong *hmask,
|
|
struct sbi_trap_info *uptrap)
|
|
{
|
|
ulong mask = 0;
|
|
|
|
if (pmask) {
|
|
mask = sbi_load_ulong(pmask, uptrap);
|
|
if (uptrap->cause)
|
|
return false;
|
|
} else {
|
|
sbi_hsm_hart_interruptible_mask(sbi_domain_thishart_ptr(),
|
|
0, &mask);
|
|
}
|
|
*hmask = mask;
|
|
|
|
return true;
|
|
}
|
|
|
|
static int sbi_ecall_legacy_handler(unsigned long extid, unsigned long funcid,
|
|
struct sbi_trap_regs *regs,
|
|
struct sbi_ecall_return *out)
|
|
{
|
|
int ret = 0;
|
|
struct sbi_tlb_info tlb_info;
|
|
u32 source_hart = current_hartid();
|
|
struct sbi_trap_info trap = {0};
|
|
ulong hmask = 0;
|
|
|
|
switch (extid) {
|
|
case SBI_EXT_0_1_SET_TIMER:
|
|
#if __riscv_xlen == 32
|
|
sbi_timer_event_start((((u64)regs->a1 << 32) | (u64)regs->a0));
|
|
#else
|
|
sbi_timer_event_start((u64)regs->a0);
|
|
#endif
|
|
break;
|
|
case SBI_EXT_0_1_CONSOLE_PUTCHAR:
|
|
sbi_putc(regs->a0);
|
|
break;
|
|
case SBI_EXT_0_1_CONSOLE_GETCHAR:
|
|
ret = sbi_getc();
|
|
break;
|
|
case SBI_EXT_0_1_CLEAR_IPI:
|
|
sbi_ipi_clear_smode();
|
|
break;
|
|
case SBI_EXT_0_1_SEND_IPI:
|
|
if (sbi_load_hart_mask_unpriv((ulong *)regs->a0,
|
|
&hmask, &trap)) {
|
|
ret = sbi_ipi_send_smode(hmask, 0);
|
|
} else {
|
|
trap.epc = regs->mepc;
|
|
sbi_trap_redirect(regs, &trap);
|
|
out->skip_regs_update = true;
|
|
}
|
|
break;
|
|
case SBI_EXT_0_1_REMOTE_FENCE_I:
|
|
if (sbi_load_hart_mask_unpriv((ulong *)regs->a0,
|
|
&hmask, &trap)) {
|
|
SBI_TLB_INFO_INIT(&tlb_info, 0, 0, 0, 0,
|
|
SBI_TLB_FENCE_I, source_hart);
|
|
ret = sbi_tlb_request(hmask, 0, &tlb_info);
|
|
} else {
|
|
trap.epc = regs->mepc;
|
|
sbi_trap_redirect(regs, &trap);
|
|
out->skip_regs_update = true;
|
|
}
|
|
break;
|
|
case SBI_EXT_0_1_REMOTE_SFENCE_VMA:
|
|
if (sbi_load_hart_mask_unpriv((ulong *)regs->a0,
|
|
&hmask, &trap)) {
|
|
SBI_TLB_INFO_INIT(&tlb_info, regs->a1, regs->a2, 0, 0,
|
|
SBI_TLB_SFENCE_VMA, source_hart);
|
|
ret = sbi_tlb_request(hmask, 0, &tlb_info);
|
|
} else {
|
|
trap.epc = regs->mepc;
|
|
sbi_trap_redirect(regs, &trap);
|
|
out->skip_regs_update = true;
|
|
}
|
|
break;
|
|
case SBI_EXT_0_1_REMOTE_SFENCE_VMA_ASID:
|
|
if (sbi_load_hart_mask_unpriv((ulong *)regs->a0,
|
|
&hmask, &trap)) {
|
|
SBI_TLB_INFO_INIT(&tlb_info, regs->a1,
|
|
regs->a2, regs->a3, 0,
|
|
SBI_TLB_SFENCE_VMA_ASID,
|
|
source_hart);
|
|
ret = sbi_tlb_request(hmask, 0, &tlb_info);
|
|
} else {
|
|
trap.epc = regs->mepc;
|
|
sbi_trap_redirect(regs, &trap);
|
|
out->skip_regs_update = true;
|
|
}
|
|
break;
|
|
case SBI_EXT_0_1_SHUTDOWN:
|
|
sbi_system_reset(SBI_SRST_RESET_TYPE_SHUTDOWN,
|
|
SBI_SRST_RESET_REASON_NONE);
|
|
break;
|
|
default:
|
|
ret = SBI_ENOTSUPP;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
struct sbi_ecall_extension ecall_legacy;
|
|
|
|
static int sbi_ecall_legacy_register_extensions(void)
|
|
{
|
|
return sbi_ecall_register_extension(&ecall_legacy);
|
|
}
|
|
|
|
struct sbi_ecall_extension ecall_legacy = {
|
|
.extid_start = SBI_EXT_0_1_SET_TIMER,
|
|
.extid_end = SBI_EXT_0_1_SHUTDOWN,
|
|
.register_extensions = sbi_ecall_legacy_register_extensions,
|
|
.handle = sbi_ecall_legacy_handler,
|
|
};
|