aboutsummaryrefslogtreecommitdiff
path: root/target/riscv/kvm.c
diff options
context:
space:
mode:
authorYifei Jiang <jiangyifei@huawei.com>2022-01-12 16:13:24 +0800
committerAlistair Francis <alistair.francis@wdc.com>2022-01-21 15:52:56 +1000
commit4eb471258bd0e331678bece4c894c477928b3b0b (patch)
treec9070d3bf2c411a6a3650a053f0c610f1dbfb5f4 /target/riscv/kvm.c
parent2b650fbbcc2b5d34943bb5697d8799b2c1a885e1 (diff)
downloadqemu-4eb471258bd0e331678bece4c894c477928b3b0b.zip
qemu-4eb471258bd0e331678bece4c894c477928b3b0b.tar.gz
qemu-4eb471258bd0e331678bece4c894c477928b3b0b.tar.bz2
target/riscv: Handle KVM_EXIT_RISCV_SBI exit
Use char-fe to handle console sbi call, which implement early console io while apply 'earlycon=sbi' into kernel parameters. Signed-off-by: Yifei Jiang <jiangyifei@huawei.com> Signed-off-by: Mingwang Li <limingwang@huawei.com> Reviewed-by: Anup Patel <anup.patel@wdc.com> Reviewed-by: Alistair Francis <alistair.francis@wdc.com> Message-id: 20220112081329.1835-9-jiangyifei@huawei.com Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
Diffstat (limited to 'target/riscv/kvm.c')
-rw-r--r--target/riscv/kvm.c42
1 files changed, 41 insertions, 1 deletions
diff --git a/target/riscv/kvm.c b/target/riscv/kvm.c
index 0ba6479..e90e2a6 100644
--- a/target/riscv/kvm.c
+++ b/target/riscv/kvm.c
@@ -38,6 +38,8 @@
#include "qemu/log.h"
#include "hw/loader.h"
#include "kvm_riscv.h"
+#include "sbi_ecall_interface.h"
+#include "chardev/char-fe.h"
static uint64_t kvm_riscv_reg_id(CPURISCVState *env, uint64_t type,
uint64_t idx)
@@ -367,9 +369,47 @@ bool kvm_arch_stop_on_emulation_error(CPUState *cs)
return true;
}
+static int kvm_riscv_handle_sbi(CPUState *cs, struct kvm_run *run)
+{
+ int ret = 0;
+ unsigned char ch;
+ switch (run->riscv_sbi.extension_id) {
+ case SBI_EXT_0_1_CONSOLE_PUTCHAR:
+ ch = run->riscv_sbi.args[0];
+ qemu_chr_fe_write(serial_hd(0)->be, &ch, sizeof(ch));
+ break;
+ case SBI_EXT_0_1_CONSOLE_GETCHAR:
+ ret = qemu_chr_fe_read_all(serial_hd(0)->be, &ch, sizeof(ch));
+ if (ret == sizeof(ch)) {
+ run->riscv_sbi.args[0] = ch;
+ } else {
+ run->riscv_sbi.args[0] = -1;
+ }
+ break;
+ default:
+ qemu_log_mask(LOG_UNIMP,
+ "%s: un-handled SBI EXIT, specific reasons is %lu\n",
+ __func__, run->riscv_sbi.extension_id);
+ ret = -1;
+ break;
+ }
+ return ret;
+}
+
int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run)
{
- return 0;
+ int ret = 0;
+ switch (run->exit_reason) {
+ case KVM_EXIT_RISCV_SBI:
+ ret = kvm_riscv_handle_sbi(cs, run);
+ break;
+ default:
+ qemu_log_mask(LOG_UNIMP, "%s: un-handled exit reason %d\n",
+ __func__, run->exit_reason);
+ ret = -1;
+ break;
+ }
+ return ret;
}
void kvm_riscv_reset_vcpu(RISCVCPU *cpu)