|
@@ -114,22 +114,6 @@ static uint64_t kvm_riscv_vector_reg_id(RISCVCPU *cpu,
|
|
|
KVM_RISCV_REG_ID_ULONG(KVM_REG_RISCV_VECTOR, \
|
|
|
KVM_REG_RISCV_VECTOR_CSR_REG(name))
|
|
|
|
|
|
-#define KVM_RISCV_GET_CSR(cs, env, csr, reg) \
|
|
|
- do { \
|
|
|
- int _ret = kvm_get_one_reg(cs, RISCV_CSR_REG(csr), ®); \
|
|
|
- if (_ret) { \
|
|
|
- return _ret; \
|
|
|
- } \
|
|
|
- } while (0)
|
|
|
-
|
|
|
-#define KVM_RISCV_SET_CSR(cs, env, csr, reg) \
|
|
|
- do { \
|
|
|
- int _ret = kvm_set_one_reg(cs, RISCV_CSR_REG(csr), ®); \
|
|
|
- if (_ret) { \
|
|
|
- return _ret; \
|
|
|
- } \
|
|
|
- } while (0)
|
|
|
-
|
|
|
#define KVM_RISCV_GET_TIMER(cs, name, reg) \
|
|
|
do { \
|
|
|
int ret = kvm_get_one_reg(cs, RISCV_TIMER_REG(name), ®); \
|
|
@@ -251,6 +235,53 @@ static void kvm_riscv_update_cpu_misa_ext(RISCVCPU *cpu, CPUState *cs)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+#define KVM_CSR_CFG(_name, _env_prop, reg_id) \
|
|
|
+ {.name = _name, .offset = ENV_CSR_OFFSET(_env_prop), \
|
|
|
+ .kvm_reg_id = reg_id}
|
|
|
+
|
|
|
+static KVMCPUConfig kvm_csr_cfgs[] = {
|
|
|
+ KVM_CSR_CFG("sstatus", mstatus, RISCV_CSR_REG(sstatus)),
|
|
|
+ KVM_CSR_CFG("sie", mie, RISCV_CSR_REG(sie)),
|
|
|
+ KVM_CSR_CFG("stvec", stvec, RISCV_CSR_REG(stvec)),
|
|
|
+ KVM_CSR_CFG("sscratch", sscratch, RISCV_CSR_REG(sscratch)),
|
|
|
+ KVM_CSR_CFG("sepc", sepc, RISCV_CSR_REG(sepc)),
|
|
|
+ KVM_CSR_CFG("scause", scause, RISCV_CSR_REG(scause)),
|
|
|
+ KVM_CSR_CFG("stval", stval, RISCV_CSR_REG(stval)),
|
|
|
+ KVM_CSR_CFG("sip", mip, RISCV_CSR_REG(sip)),
|
|
|
+ KVM_CSR_CFG("satp", satp, RISCV_CSR_REG(satp)),
|
|
|
+};
|
|
|
+
|
|
|
+static void *kvmconfig_get_env_addr(RISCVCPU *cpu, KVMCPUConfig *csr_cfg)
|
|
|
+{
|
|
|
+ return (void *)&cpu->env + csr_cfg->offset;
|
|
|
+}
|
|
|
+
|
|
|
+static uint32_t kvm_cpu_csr_get_u32(RISCVCPU *cpu, KVMCPUConfig *csr_cfg)
|
|
|
+{
|
|
|
+ uint32_t *val32 = kvmconfig_get_env_addr(cpu, csr_cfg);
|
|
|
+ return *val32;
|
|
|
+}
|
|
|
+
|
|
|
+static uint64_t kvm_cpu_csr_get_u64(RISCVCPU *cpu, KVMCPUConfig *csr_cfg)
|
|
|
+{
|
|
|
+ uint64_t *val64 = kvmconfig_get_env_addr(cpu, csr_cfg);
|
|
|
+ return *val64;
|
|
|
+}
|
|
|
+
|
|
|
+static void kvm_cpu_csr_set_u32(RISCVCPU *cpu, KVMCPUConfig *csr_cfg,
|
|
|
+ uint32_t val)
|
|
|
+{
|
|
|
+ uint32_t *val32 = kvmconfig_get_env_addr(cpu, csr_cfg);
|
|
|
+ *val32 = val;
|
|
|
+}
|
|
|
+
|
|
|
+static void kvm_cpu_csr_set_u64(RISCVCPU *cpu, KVMCPUConfig *csr_cfg,
|
|
|
+ uint64_t val)
|
|
|
+{
|
|
|
+ uint64_t *val64 = kvmconfig_get_env_addr(cpu, csr_cfg);
|
|
|
+ *val64 = val;
|
|
|
+}
|
|
|
+
|
|
|
#define KVM_EXT_CFG(_name, _prop, _reg_id) \
|
|
|
{.name = _name, .offset = CPU_CFG_OFFSET(_prop), \
|
|
|
.kvm_reg_id = _reg_id}
|
|
@@ -598,34 +629,52 @@ static int kvm_riscv_put_regs_core(CPUState *cs)
|
|
|
|
|
|
static int kvm_riscv_get_regs_csr(CPUState *cs)
|
|
|
{
|
|
|
- CPURISCVState *env = &RISCV_CPU(cs)->env;
|
|
|
+ RISCVCPU *cpu = RISCV_CPU(cs);
|
|
|
+ uint64_t reg;
|
|
|
+ int i, ret;
|
|
|
+
|
|
|
+ for (i = 0; i < ARRAY_SIZE(kvm_csr_cfgs); i++) {
|
|
|
+ KVMCPUConfig *csr_cfg = &kvm_csr_cfgs[i];
|
|
|
|
|
|
- KVM_RISCV_GET_CSR(cs, env, sstatus, env->mstatus);
|
|
|
- KVM_RISCV_GET_CSR(cs, env, sie, env->mie);
|
|
|
- KVM_RISCV_GET_CSR(cs, env, stvec, env->stvec);
|
|
|
- KVM_RISCV_GET_CSR(cs, env, sscratch, env->sscratch);
|
|
|
- KVM_RISCV_GET_CSR(cs, env, sepc, env->sepc);
|
|
|
- KVM_RISCV_GET_CSR(cs, env, scause, env->scause);
|
|
|
- KVM_RISCV_GET_CSR(cs, env, stval, env->stval);
|
|
|
- KVM_RISCV_GET_CSR(cs, env, sip, env->mip);
|
|
|
- KVM_RISCV_GET_CSR(cs, env, satp, env->satp);
|
|
|
+ ret = kvm_get_one_reg(cs, csr_cfg->kvm_reg_id, ®);
|
|
|
+ if (ret) {
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (KVM_REG_SIZE(csr_cfg->kvm_reg_id) == sizeof(uint32_t)) {
|
|
|
+ kvm_cpu_csr_set_u32(cpu, csr_cfg, reg);
|
|
|
+ } else if (KVM_REG_SIZE(csr_cfg->kvm_reg_id) == sizeof(uint64_t)) {
|
|
|
+ kvm_cpu_csr_set_u64(cpu, csr_cfg, reg);
|
|
|
+ } else {
|
|
|
+ g_assert_not_reached();
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
static int kvm_riscv_put_regs_csr(CPUState *cs)
|
|
|
{
|
|
|
- CPURISCVState *env = &RISCV_CPU(cs)->env;
|
|
|
+ RISCVCPU *cpu = RISCV_CPU(cs);
|
|
|
+ uint64_t reg;
|
|
|
+ int i, ret;
|
|
|
+
|
|
|
+ for (i = 0; i < ARRAY_SIZE(kvm_csr_cfgs); i++) {
|
|
|
+ KVMCPUConfig *csr_cfg = &kvm_csr_cfgs[i];
|
|
|
+
|
|
|
+ if (KVM_REG_SIZE(csr_cfg->kvm_reg_id) == sizeof(uint32_t)) {
|
|
|
+ reg = kvm_cpu_csr_get_u32(cpu, csr_cfg);
|
|
|
+ } else if (KVM_REG_SIZE(csr_cfg->kvm_reg_id) == sizeof(uint64_t)) {
|
|
|
+ reg = kvm_cpu_csr_get_u64(cpu, csr_cfg);
|
|
|
+ } else {
|
|
|
+ g_assert_not_reached();
|
|
|
+ }
|
|
|
|
|
|
- KVM_RISCV_SET_CSR(cs, env, sstatus, env->mstatus);
|
|
|
- KVM_RISCV_SET_CSR(cs, env, sie, env->mie);
|
|
|
- KVM_RISCV_SET_CSR(cs, env, stvec, env->stvec);
|
|
|
- KVM_RISCV_SET_CSR(cs, env, sscratch, env->sscratch);
|
|
|
- KVM_RISCV_SET_CSR(cs, env, sepc, env->sepc);
|
|
|
- KVM_RISCV_SET_CSR(cs, env, scause, env->scause);
|
|
|
- KVM_RISCV_SET_CSR(cs, env, stval, env->stval);
|
|
|
- KVM_RISCV_SET_CSR(cs, env, sip, env->mip);
|
|
|
- KVM_RISCV_SET_CSR(cs, env, satp, env->satp);
|
|
|
+ ret = kvm_set_one_reg(cs, csr_cfg->kvm_reg_id, ®);
|
|
|
+ if (ret) {
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
return 0;
|
|
|
}
|