qemu-riscv
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH RFC 8/9] target/riscv: Handler KVM_EXIT_RISCV_SBI exit


From: Yifei Jiang
Subject: [PATCH RFC 8/9] target/riscv: Handler KVM_EXIT_RISCV_SBI exit
Date: Fri, 13 Mar 2020 11:49:48 +0800

Use char-fe handler console sbi call, which implement early
console io while apply 'earlycon=sbi' into kernel parameters.

Signed-off-by: Yifei Jiang <address@hidden>
Signed-off-by: Yipeng Yin <address@hidden>
---
 target/riscv/kvm.c | 54 +++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 53 insertions(+), 1 deletion(-)

diff --git a/target/riscv/kvm.c b/target/riscv/kvm.c
index 0f429fd802..1df70fbb29 100644
--- a/target/riscv/kvm.c
+++ b/target/riscv/kvm.c
@@ -38,6 +38,7 @@
 #include "qemu/log.h"
 #include "hw/loader.h"
 #include "kvm_riscv.h"
+#include "chardev/char-fe.h"
 
 static __u64 kvm_riscv_reg_id(__u64 type, __u64 idx)
 {
@@ -61,6 +62,19 @@ static __u64 kvm_riscv_reg_id(__u64 type, __u64 idx)
 
 #define RISCV_FP_D_REG(idx)  kvm_riscv_reg_id(KVM_REG_RISCV_FP_D, idx)
 
+enum sbi_ext_id {
+    SBI_EXT_0_1_SET_TIMER = 0x0,
+    SBI_EXT_0_1_CONSOLE_PUTCHAR = 0x1,
+    SBI_EXT_0_1_CONSOLE_GETCHAR = 0x2,
+    SBI_EXT_0_1_CLEAR_IPI = 0x3,
+    SBI_EXT_0_1_SEND_IPI = 0x4,
+    SBI_EXT_0_1_REMOTE_FENCE_I = 0x5,
+    SBI_EXT_0_1_REMOTE_SFENCE_VMA = 0x6,
+    SBI_EXT_0_1_REMOTE_SFENCE_VMA_ASID = 0x7,
+    SBI_EXT_0_1_SHUTDOWN = 0x8,
+    SBI_EXT_BASE = 0x10,
+};
+
 static int kvm_riscv_get_regs_core(CPUState *cs)
 {
     int ret = 0;
@@ -423,9 +437,47 @@ bool kvm_arch_stop_on_emulation_error(CPUState *cs)
     return true;
 }
 
+static int kvm_riscv_handle_sbi(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(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)
-- 
2.19.1





reply via email to

[Prev in Thread] Current Thread [Next in Thread]