diff --git a/hypervisor/arch/riscv/Makefile b/hypervisor/arch/riscv/Makefile index 1c3f122da..6a3d33c51 100644 --- a/hypervisor/arch/riscv/Makefile +++ b/hypervisor/arch/riscv/Makefile @@ -76,6 +76,7 @@ VP_C_SRCS += arch/riscv/guest/vsbi/vsbi_base.c VP_C_SRCS += arch/riscv/guest/vsbi/vsbi_hsm.c VP_C_SRCS += arch/riscv/guest/vsbi/vsbi_srst.c VP_C_SRCS += arch/riscv/guest/vsbi/vsbi_acrn.c +VP_C_SRCS += arch/riscv/guest/vsbi/vsbi_dbcn.c VM_CFG_C_SRCS += $(SCENARIO_CFG_DIR)/vm_configurations.c VM_CFG_C_SRCS += $(BOARD_CFG_DIR)/pci_dev.c diff --git a/hypervisor/arch/riscv/guest/vsbi.c b/hypervisor/arch/riscv/guest/vsbi.c index b2dea252e..5e12e99a9 100644 --- a/hypervisor/arch/riscv/guest/vsbi.c +++ b/hypervisor/arch/riscv/guest/vsbi.c @@ -75,11 +75,13 @@ extern const struct acrn_vsbi_extension vsbi_ext_base; extern const struct acrn_vsbi_extension vsbi_ext_hsm; extern const struct acrn_vsbi_extension vsbi_ext_srst; extern const struct acrn_vsbi_extension vsbi_ext_acrn; +extern const struct acrn_vsbi_extension vsbi_ext_dbcn; static const struct acrn_vsbi_extension *vsbi_extensions[MAX_NUM_SUPPORTED_VSBI_EXT] = { &vsbi_ext_base, &vsbi_ext_hsm, &vsbi_ext_srst, &vsbi_ext_acrn, + &vsbi_ext_dbcn, }; void init_vsbi(struct acrn_vm *vm) diff --git a/hypervisor/arch/riscv/guest/vsbi/vsbi_dbcn.c b/hypervisor/arch/riscv/guest/vsbi/vsbi_dbcn.c new file mode 100644 index 000000000..fd271e46a --- /dev/null +++ b/hypervisor/arch/riscv/guest/vsbi/vsbi_dbcn.c @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2018-2025 Intel Corporation. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include + +#include +#include + +#include + +static int32_t vcpu_sbi_debug_console_handler(struct acrn_vcpu *vcpu, __unused uint64_t ext_id, + uint64_t func_id, uint64_t *args, struct vsbi_ret *out) +{ + int32_t ret = SBI_SUCCESS; + uint64_t gpa_hi, gpa_lo; + char *hva, ch; + size_t nbytes, i; + + switch (func_id) { + case SBI_EXT_DBCN_CONSOLE_WRITE: + case SBI_EXT_DBCN_CONSOLE_READ: + nbytes = args[0]; + gpa_lo = args[1]; + gpa_hi = args[2]; + /* TODO: Check that address is valid */ + hva = (char *)gpa2hva(vcpu->vm, (gpa_hi << 32) | gpa_lo); + + if (hva != NULL) { + pre_user_access(); + if (func_id == SBI_EXT_DBCN_CONSOLE_WRITE) { + for (i = 0; i < nbytes; i++) { + /* TODO: We should redirect the output to ACRN shell's vm_console buffer. + * For now just output directly to physical uart. + */ + console_putc(&hva[i]); + } + } else { + for (i = 0; i < nbytes; i++) { + ch = console_getc(); + if (ch == -1) { + break; + } + hva[i] = ch; + } + } + out->value = i; + post_user_access(); + } else { + ret = SBI_ERR_INVALID_PARAM; + } + break; + case SBI_EXT_DBCN_CONSOLE_WRITE_BYTE: + ch = (char)args[0]; + console_putc(&ch); + out->value = 0; + break; + default: + ret = SBI_ERR_NOT_SUPPORTED; + break; + } + + return ret; +} + +const struct acrn_vsbi_extension vsbi_ext_dbcn = { + .name = "dbcn", + .eid_start = SBI_EID_DBCN, + .eid_end = SBI_EID_DBCN, + .handler = vcpu_sbi_debug_console_handler, +}; diff --git a/hypervisor/include/arch/riscv/asm/sbi.h b/hypervisor/include/arch/riscv/asm/sbi.h index 3bb9f0793..d52f87800 100644 --- a/hypervisor/include/arch/riscv/asm/sbi.h +++ b/hypervisor/include/arch/riscv/asm/sbi.h @@ -20,6 +20,7 @@ enum sbi_eid { SBI_EID_HSM = 0x48534D, SBI_EID_SRST = 0x53525354, SBI_EID_PMU = 0x504D55, + SBI_EID_DBCN = 0x4442434E, SBI_EID_MPXY = 0x4D505859, /* Experimental extensions must lie within this range */ @@ -92,6 +93,11 @@ enum sbi_eid { #define SBI_SRST_RESET_REASON_NONE 0x0 #define SBI_SRST_RESET_REASON_SYSFAIL 0x1 +/* SBI function IDs for DBCN extension */ +#define SBI_EXT_DBCN_CONSOLE_WRITE 0x0 +#define SBI_EXT_DBCN_CONSOLE_READ 0x1 +#define SBI_EXT_DBCN_CONSOLE_WRITE_BYTE 0x2 + /* SBI return error codes */ #define SBI_SUCCESS 0 #define SBI_ERR_FAILED -1