| #include "kvm/csr.h" |
| #include "kvm/kvm-cpu.h" |
| #include "kvm/kvm.h" |
| #include "kvm/virtio.h" |
| #include "kvm/sbi.h" |
| #include "kvm/term.h" |
| |
| #include <asm/ptrace.h> |
| |
| static int debug_fd; |
| |
| void kvm_cpu__set_debug_fd(int fd) |
| { |
| debug_fd = fd; |
| } |
| |
| int kvm_cpu__get_debug_fd(void) |
| { |
| return debug_fd; |
| } |
| |
| struct kvm_cpu *kvm_cpu__arch_init(struct kvm *kvm, unsigned long cpu_id) |
| { |
| struct kvm_cpu *vcpu; |
| u64 timebase = 0; |
| unsigned long isa = 0, id = 0; |
| unsigned long masks[KVM_REG_RISCV_SBI_MULTI_REG_LAST + 1] = { 0 }; |
| int i, coalesced_offset, mmap_size; |
| struct kvm_one_reg reg; |
| |
| vcpu = calloc(1, sizeof(struct kvm_cpu)); |
| if (!vcpu) |
| return NULL; |
| |
| vcpu->vcpu_fd = ioctl(kvm->vm_fd, KVM_CREATE_VCPU, cpu_id); |
| if (vcpu->vcpu_fd < 0) |
| die_perror("KVM_CREATE_VCPU ioctl"); |
| |
| reg.id = RISCV_CONFIG_REG(isa); |
| reg.addr = (unsigned long)&isa; |
| if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) |
| die("KVM_GET_ONE_REG failed (config.isa)"); |
| |
| reg.id = RISCV_TIMER_REG(frequency); |
| reg.addr = (unsigned long)&timebase; |
| if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) |
| die("KVM_GET_ONE_REG failed (timer.frequency)"); |
| |
| mmap_size = ioctl(kvm->sys_fd, KVM_GET_VCPU_MMAP_SIZE, 0); |
| if (mmap_size < 0) |
| die_perror("KVM_GET_VCPU_MMAP_SIZE ioctl"); |
| |
| vcpu->kvm_run = mmap(NULL, mmap_size, PROT_RW, MAP_SHARED, |
| vcpu->vcpu_fd, 0); |
| if (vcpu->kvm_run == MAP_FAILED) |
| die("unable to mmap vcpu fd"); |
| |
| coalesced_offset = ioctl(kvm->sys_fd, KVM_CHECK_EXTENSION, |
| KVM_CAP_COALESCED_MMIO); |
| if (coalesced_offset) |
| vcpu->ring = (void *)vcpu->kvm_run + |
| (coalesced_offset * PAGE_SIZE); |
| |
| reg.id = RISCV_CONFIG_REG(isa); |
| reg.addr = (unsigned long)&isa; |
| if (ioctl(vcpu->vcpu_fd, KVM_SET_ONE_REG, ®) < 0) |
| die("KVM_SET_ONE_REG failed (config.isa)"); |
| |
| if (kvm->cfg.arch.custom_mvendorid) { |
| id = kvm->cfg.arch.custom_mvendorid; |
| reg.id = RISCV_CONFIG_REG(mvendorid); |
| reg.addr = (unsigned long)&id; |
| if (ioctl(vcpu->vcpu_fd, KVM_SET_ONE_REG, ®) < 0) |
| die("KVM_SET_ONE_REG failed (config.mvendorid)"); |
| } |
| |
| if (kvm->cfg.arch.custom_marchid) { |
| id = kvm->cfg.arch.custom_marchid; |
| reg.id = RISCV_CONFIG_REG(marchid); |
| reg.addr = (unsigned long)&id; |
| if (ioctl(vcpu->vcpu_fd, KVM_SET_ONE_REG, ®) < 0) |
| die("KVM_SET_ONE_REG failed (config.marchid)"); |
| } |
| |
| if (kvm->cfg.arch.custom_mimpid) { |
| id = kvm->cfg.arch.custom_mimpid; |
| reg.id = RISCV_CONFIG_REG(mimpid); |
| reg.addr = (unsigned long)&id; |
| if (ioctl(vcpu->vcpu_fd, KVM_SET_ONE_REG, ®) < 0) |
| die("KVM_SET_ONE_REG failed (config.mimpid)"); |
| } |
| |
| for (i = 0; i < KVM_RISCV_SBI_EXT_MAX; i++) { |
| if (!kvm->cfg.arch.sbi_ext_disabled[i]) |
| continue; |
| masks[KVM_REG_RISCV_SBI_MULTI_REG(i)] |= |
| KVM_REG_RISCV_SBI_MULTI_MASK(i); |
| } |
| for (i = 0; i <= KVM_REG_RISCV_SBI_MULTI_REG_LAST; i++) { |
| if (!masks[i]) |
| continue; |
| |
| reg.id = RISCV_SBI_EXT_REG(KVM_REG_RISCV_SBI_MULTI_DIS, i); |
| reg.addr = (unsigned long)&masks[i]; |
| if (ioctl(vcpu->vcpu_fd, KVM_SET_ONE_REG, ®) < 0) |
| die("KVM_SET_ONE_REG failed (sbi_ext %d)", i); |
| } |
| |
| /* Force enable SBI debug console if not disabled from command line */ |
| if (!kvm->cfg.arch.sbi_ext_disabled[KVM_RISCV_SBI_EXT_DBCN]) { |
| id = 1; |
| reg.id = RISCV_SBI_EXT_REG(KVM_REG_RISCV_SBI_SINGLE, |
| KVM_RISCV_SBI_EXT_DBCN); |
| reg.addr = (unsigned long)&id; |
| if (ioctl(vcpu->vcpu_fd, KVM_SET_ONE_REG, ®) < 0) |
| pr_warning("KVM_SET_ONE_REG failed (sbi_ext %d)", |
| KVM_RISCV_SBI_EXT_DBCN); |
| } |
| |
| /* Populate the vcpu structure. */ |
| vcpu->kvm = kvm; |
| vcpu->cpu_id = cpu_id; |
| vcpu->riscv_isa = isa; |
| vcpu->riscv_xlen = __riscv_xlen; |
| vcpu->riscv_timebase = timebase; |
| vcpu->is_running = true; |
| |
| return vcpu; |
| } |
| |
| void kvm_cpu__arch_nmi(struct kvm_cpu *cpu) |
| { |
| } |
| |
| void kvm_cpu__delete(struct kvm_cpu *vcpu) |
| { |
| free(vcpu); |
| } |
| |
| static bool kvm_cpu_riscv_sbi(struct kvm_cpu *vcpu) |
| { |
| char ch; |
| u64 addr; |
| bool ret = true; |
| char *str_start, *str_end; |
| int dfd = kvm_cpu__get_debug_fd(); |
| |
| switch (vcpu->kvm_run->riscv_sbi.extension_id) { |
| case SBI_EXT_0_1_CONSOLE_PUTCHAR: |
| ch = vcpu->kvm_run->riscv_sbi.args[0]; |
| term_putc(&ch, 1, 0); |
| vcpu->kvm_run->riscv_sbi.ret[0] = 0; |
| break; |
| case SBI_EXT_0_1_CONSOLE_GETCHAR: |
| if (term_readable(0)) |
| vcpu->kvm_run->riscv_sbi.ret[0] = |
| term_getc(vcpu->kvm, 0); |
| else |
| vcpu->kvm_run->riscv_sbi.ret[0] = SBI_ERR_FAILURE; |
| break; |
| case SBI_EXT_DBCN: |
| switch (vcpu->kvm_run->riscv_sbi.function_id) { |
| case SBI_EXT_DBCN_CONSOLE_WRITE: |
| case SBI_EXT_DBCN_CONSOLE_READ: |
| addr = vcpu->kvm_run->riscv_sbi.args[1]; |
| #if __riscv_xlen == 32 |
| addr |= (u64)vcpu->kvm_run->riscv_sbi.args[2] << 32; |
| #endif |
| if (!vcpu->kvm_run->riscv_sbi.args[0]) |
| break; |
| str_start = guest_flat_to_host(vcpu->kvm, addr); |
| addr += vcpu->kvm_run->riscv_sbi.args[0] - 1; |
| str_end = guest_flat_to_host(vcpu->kvm, addr); |
| if (!str_start || !str_end) { |
| vcpu->kvm_run->riscv_sbi.ret[0] = |
| SBI_ERR_INVALID_PARAM; |
| break; |
| } |
| vcpu->kvm_run->riscv_sbi.ret[1] = 0; |
| while (str_start <= str_end) { |
| if (vcpu->kvm_run->riscv_sbi.function_id == |
| SBI_EXT_DBCN_CONSOLE_WRITE) { |
| term_putc(str_start, 1, 0); |
| } else { |
| if (!term_readable(0)) |
| break; |
| *str_start = term_getc(vcpu->kvm, 0); |
| } |
| vcpu->kvm_run->riscv_sbi.ret[1]++; |
| str_start++; |
| } |
| break; |
| case SBI_EXT_DBCN_CONSOLE_WRITE_BYTE: |
| ch = vcpu->kvm_run->riscv_sbi.args[0]; |
| term_putc(&ch, 1, 0); |
| vcpu->kvm_run->riscv_sbi.ret[0] = 0; |
| vcpu->kvm_run->riscv_sbi.ret[1] = 0; |
| break; |
| default: |
| vcpu->kvm_run->riscv_sbi.ret[0] = |
| SBI_ERR_NOT_SUPPORTED; |
| break; |
| } |
| break; |
| default: |
| dprintf(dfd, "Unhandled SBI call\n"); |
| dprintf(dfd, "extension_id=0x%lx function_id=0x%lx\n", |
| vcpu->kvm_run->riscv_sbi.extension_id, |
| vcpu->kvm_run->riscv_sbi.function_id); |
| dprintf(dfd, "args[0]=0x%lx args[1]=0x%lx\n", |
| vcpu->kvm_run->riscv_sbi.args[0], |
| vcpu->kvm_run->riscv_sbi.args[1]); |
| dprintf(dfd, "args[2]=0x%lx args[3]=0x%lx\n", |
| vcpu->kvm_run->riscv_sbi.args[2], |
| vcpu->kvm_run->riscv_sbi.args[3]); |
| dprintf(dfd, "args[4]=0x%lx args[5]=0x%lx\n", |
| vcpu->kvm_run->riscv_sbi.args[4], |
| vcpu->kvm_run->riscv_sbi.args[5]); |
| ret = false; |
| break; |
| }; |
| |
| return ret; |
| } |
| |
| static bool kvm_cpu_riscv_csr(struct kvm_cpu *vcpu) |
| { |
| int dfd = kvm_cpu__get_debug_fd(); |
| bool ret = true; |
| |
| switch (vcpu->kvm_run->riscv_csr.csr_num) { |
| case CSR_SEED: |
| /* |
| * We ignore the new_value and write_mask and simply |
| * return a random value as SEED. |
| */ |
| vcpu->kvm_run->riscv_csr.ret_value = SEED_OPST_ES16; |
| vcpu->kvm_run->riscv_csr.ret_value |= rand() & SEED_ENTROPY_MASK; |
| break; |
| default: |
| dprintf(dfd, "Unhandled CSR access\n"); |
| dprintf(dfd, "csr_num=0x%lx new_value=0x%lx\n", |
| vcpu->kvm_run->riscv_csr.csr_num, |
| vcpu->kvm_run->riscv_csr.new_value); |
| dprintf(dfd, "write_mask=0x%lx ret_value=0x%lx\n", |
| vcpu->kvm_run->riscv_csr.write_mask, |
| vcpu->kvm_run->riscv_csr.ret_value); |
| ret = false; |
| break; |
| } |
| |
| return ret; |
| } |
| |
| bool kvm_cpu__handle_exit(struct kvm_cpu *vcpu) |
| { |
| switch (vcpu->kvm_run->exit_reason) { |
| case KVM_EXIT_RISCV_SBI: |
| return kvm_cpu_riscv_sbi(vcpu); |
| case KVM_EXIT_RISCV_CSR: |
| return kvm_cpu_riscv_csr(vcpu); |
| default: |
| break; |
| }; |
| |
| return false; |
| } |
| |
| void kvm_cpu__show_page_tables(struct kvm_cpu *vcpu) |
| { |
| } |
| |
| void kvm_cpu__reset_vcpu(struct kvm_cpu *vcpu) |
| { |
| struct kvm *kvm = vcpu->kvm; |
| struct kvm_mp_state mp_state; |
| struct kvm_one_reg reg; |
| unsigned long data; |
| |
| if (ioctl(vcpu->vcpu_fd, KVM_GET_MP_STATE, &mp_state) < 0) |
| die_perror("KVM_GET_MP_STATE failed"); |
| |
| /* |
| * If MP state is stopped then it means Linux KVM RISC-V emulates |
| * SBI v0.2 (or higher) with HART power managment and give VCPU |
| * will power-up at boot-time by boot VCPU. For such VCPU, we |
| * don't update PC, A0 and A1 here. |
| */ |
| if (mp_state.mp_state == KVM_MP_STATE_STOPPED) |
| return; |
| |
| reg.addr = (unsigned long)&data; |
| |
| data = kvm->arch.kern_guest_start; |
| reg.id = RISCV_CORE_REG(regs.pc); |
| if (ioctl(vcpu->vcpu_fd, KVM_SET_ONE_REG, ®) < 0) |
| die_perror("KVM_SET_ONE_REG failed (pc)"); |
| |
| data = vcpu->cpu_id; |
| reg.id = RISCV_CORE_REG(regs.a0); |
| if (ioctl(vcpu->vcpu_fd, KVM_SET_ONE_REG, ®) < 0) |
| die_perror("KVM_SET_ONE_REG failed (a0)"); |
| |
| data = kvm->arch.dtb_guest_start; |
| reg.id = RISCV_CORE_REG(regs.a1); |
| if (ioctl(vcpu->vcpu_fd, KVM_SET_ONE_REG, ®) < 0) |
| die_perror("KVM_SET_ONE_REG failed (a1)"); |
| } |
| |
| int kvm_cpu__get_endianness(struct kvm_cpu *vcpu) |
| { |
| return VIRTIO_ENDIAN_LE; |
| } |
| |
| void kvm_cpu__show_code(struct kvm_cpu *vcpu) |
| { |
| struct kvm_one_reg reg; |
| unsigned long data; |
| int debug_fd = kvm_cpu__get_debug_fd(); |
| |
| reg.addr = (unsigned long)&data; |
| |
| dprintf(debug_fd, "\n*PC:\n"); |
| reg.id = RISCV_CORE_REG(regs.pc); |
| if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) |
| die("KVM_GET_ONE_REG failed (show_code @ PC)"); |
| |
| kvm__dump_mem(vcpu->kvm, data, 32, debug_fd); |
| |
| dprintf(debug_fd, "\n*RA:\n"); |
| reg.id = RISCV_CORE_REG(regs.ra); |
| if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) |
| die("KVM_GET_ONE_REG failed (show_code @ RA)"); |
| |
| kvm__dump_mem(vcpu->kvm, data, 32, debug_fd); |
| } |
| |
| static void kvm_cpu__show_csrs(struct kvm_cpu *vcpu) |
| { |
| struct kvm_one_reg reg; |
| struct kvm_riscv_csr csr; |
| unsigned long data; |
| int debug_fd = kvm_cpu__get_debug_fd(); |
| |
| reg.addr = (unsigned long)&data; |
| dprintf(debug_fd, "\n Control Status Registers:\n"); |
| dprintf(debug_fd, " ------------------------\n"); |
| |
| reg.id = RISCV_CSR_REG(sstatus); |
| if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) |
| die("KVM_GET_ONE_REG failed (sstatus)"); |
| csr.sstatus = data; |
| |
| reg.id = RISCV_CSR_REG(sie); |
| if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) |
| die("KVM_GET_ONE_REG failed (sie)"); |
| csr.sie = data; |
| |
| reg.id = RISCV_CSR_REG(stvec); |
| if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) |
| die("KVM_GET_ONE_REG failed (stvec)"); |
| csr.stvec = data; |
| |
| reg.id = RISCV_CSR_REG(sip); |
| if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) |
| die("KVM_GET_ONE_REG failed (sip)"); |
| csr.sip = data; |
| |
| reg.id = RISCV_CSR_REG(satp); |
| if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) |
| die("KVM_GET_ONE_REG failed (satp)"); |
| csr.satp = data; |
| |
| reg.id = RISCV_CSR_REG(stval); |
| if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) |
| die("KVM_GET_ONE_REG failed (stval)"); |
| csr.stval = data; |
| |
| reg.id = RISCV_CSR_REG(scause); |
| if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) |
| die("KVM_GET_ONE_REG failed (SCAUSE)"); |
| csr.scause = data; |
| |
| reg.id = RISCV_CSR_REG(sscratch); |
| if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) |
| die("KVM_GET_ONE_REG failed (sscartch)"); |
| csr.sscratch = data; |
| dprintf(debug_fd, " SSTATUS: 0x%016lx\n", csr.sstatus); |
| dprintf(debug_fd, " SIE: 0x%016lx\n", csr.sie); |
| dprintf(debug_fd, " STVEC: 0x%016lx\n", csr.stvec); |
| dprintf(debug_fd, " SIP: 0x%016lx\n", csr.sip); |
| dprintf(debug_fd, " SATP: 0x%016lx\n", csr.satp); |
| dprintf(debug_fd, " STVAL: 0x%016lx\n", csr.stval); |
| dprintf(debug_fd, " SCAUSE: 0x%016lx\n", csr.scause); |
| dprintf(debug_fd, " SSCRATCH: 0x%016lx\n", csr.sscratch); |
| } |
| |
| void kvm_cpu__show_registers(struct kvm_cpu *vcpu) |
| { |
| struct kvm_one_reg reg; |
| unsigned long data; |
| int debug_fd = kvm_cpu__get_debug_fd(); |
| struct kvm_riscv_core core; |
| |
| reg.addr = (unsigned long)&data; |
| |
| reg.id = RISCV_CORE_REG(mode); |
| if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) |
| die("KVM_GET_ONE_REG failed (mode)"); |
| core.mode = data; |
| |
| reg.id = RISCV_CORE_REG(regs.pc); |
| if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) |
| die("KVM_GET_ONE_REG failed (pc)"); |
| core.regs.pc = data; |
| |
| reg.id = RISCV_CORE_REG(regs.ra); |
| if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) |
| die("KVM_GET_ONE_REG failed (ra)"); |
| core.regs.ra = data; |
| |
| reg.id = RISCV_CORE_REG(regs.sp); |
| if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) |
| die("KVM_GET_ONE_REG failed (sp)"); |
| core.regs.sp = data; |
| |
| reg.id = RISCV_CORE_REG(regs.gp); |
| if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) |
| die("KVM_GET_ONE_REG failed (gp)"); |
| core.regs.gp = data; |
| |
| reg.id = RISCV_CORE_REG(regs.tp); |
| if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) |
| die("KVM_GET_ONE_REG failed (tp)"); |
| core.regs.tp = data; |
| |
| reg.id = RISCV_CORE_REG(regs.t0); |
| if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) |
| die("KVM_GET_ONE_REG failed (t0)"); |
| core.regs.t0 = data; |
| |
| reg.id = RISCV_CORE_REG(regs.t1); |
| if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) |
| die("KVM_GET_ONE_REG failed (t1)"); |
| core.regs.t1 = data; |
| |
| reg.id = RISCV_CORE_REG(regs.t2); |
| if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) |
| die("KVM_GET_ONE_REG failed (t2)"); |
| core.regs.t2 = data; |
| |
| reg.id = RISCV_CORE_REG(regs.s0); |
| if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) |
| die("KVM_GET_ONE_REG failed (s0)"); |
| core.regs.s0 = data; |
| |
| reg.id = RISCV_CORE_REG(regs.s1); |
| if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) |
| die("KVM_GET_ONE_REG failed (s1)"); |
| core.regs.s1 = data; |
| |
| reg.id = RISCV_CORE_REG(regs.a0); |
| if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) |
| die("KVM_GET_ONE_REG failed (a0)"); |
| core.regs.a0 = data; |
| |
| reg.id = RISCV_CORE_REG(regs.a1); |
| if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) |
| die("KVM_GET_ONE_REG failed (a1)"); |
| core.regs.a1 = data; |
| |
| reg.id = RISCV_CORE_REG(regs.a2); |
| if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) |
| die("KVM_GET_ONE_REG failed (a2)"); |
| core.regs.a2 = data; |
| |
| reg.id = RISCV_CORE_REG(regs.a3); |
| if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) |
| die("KVM_GET_ONE_REG failed (a3)"); |
| core.regs.a3 = data; |
| |
| reg.id = RISCV_CORE_REG(regs.a4); |
| if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) |
| die("KVM_GET_ONE_REG failed (a4)"); |
| core.regs.a4 = data; |
| |
| reg.id = RISCV_CORE_REG(regs.a5); |
| if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) |
| die("KVM_GET_ONE_REG failed (a5)"); |
| core.regs.a5 = data; |
| |
| reg.id = RISCV_CORE_REG(regs.a6); |
| if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) |
| die("KVM_GET_ONE_REG failed (a6)"); |
| core.regs.a6 = data; |
| |
| reg.id = RISCV_CORE_REG(regs.a7); |
| if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) |
| die("KVM_GET_ONE_REG failed (a7)"); |
| core.regs.a7 = data; |
| |
| reg.id = RISCV_CORE_REG(regs.s2); |
| if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) |
| die("KVM_GET_ONE_REG failed (s2)"); |
| core.regs.s2 = data; |
| |
| reg.id = RISCV_CORE_REG(regs.s3); |
| if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) |
| die("KVM_GET_ONE_REG failed (s3)"); |
| core.regs.s3 = data; |
| |
| reg.id = RISCV_CORE_REG(regs.s4); |
| if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) |
| die("KVM_GET_ONE_REG failed (s4)"); |
| core.regs.s4 = data; |
| |
| reg.id = RISCV_CORE_REG(regs.s5); |
| if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) |
| die("KVM_GET_ONE_REG failed (s5)"); |
| core.regs.s5 = data; |
| |
| reg.id = RISCV_CORE_REG(regs.s6); |
| if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) |
| die("KVM_GET_ONE_REG failed (s6)"); |
| core.regs.s6 = data; |
| |
| reg.id = RISCV_CORE_REG(regs.s7); |
| if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) |
| die("KVM_GET_ONE_REG failed (s7)"); |
| core.regs.s7 = data; |
| |
| reg.id = RISCV_CORE_REG(regs.s8); |
| if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) |
| die("KVM_GET_ONE_REG failed (s8)"); |
| core.regs.s8 = data; |
| |
| reg.id = RISCV_CORE_REG(regs.s9); |
| if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) |
| die("KVM_GET_ONE_REG failed (s9)"); |
| core.regs.s9 = data; |
| |
| reg.id = RISCV_CORE_REG(regs.s10); |
| if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) |
| die("KVM_GET_ONE_REG failed (s10)"); |
| core.regs.s10 = data; |
| |
| reg.id = RISCV_CORE_REG(regs.s11); |
| if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) |
| die("KVM_GET_ONE_REG failed (s11)"); |
| core.regs.s11 = data; |
| |
| reg.id = RISCV_CORE_REG(regs.t3); |
| if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) |
| die("KVM_GET_ONE_REG failed (t3)"); |
| core.regs.t3 = data; |
| |
| reg.id = RISCV_CORE_REG(regs.t4); |
| if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) |
| die("KVM_GET_ONE_REG failed (t4)"); |
| core.regs.t4 = data; |
| |
| reg.id = RISCV_CORE_REG(regs.t5); |
| if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) |
| die("KVM_GET_ONE_REG failed (t5)"); |
| core.regs.t5 = data; |
| |
| reg.id = RISCV_CORE_REG(regs.t6); |
| if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) |
| die("KVM_GET_ONE_REG failed (t6)"); |
| core.regs.t6 = data; |
| |
| dprintf(debug_fd, "\n General Purpose Registers:\n"); |
| dprintf(debug_fd, " -------------------------\n"); |
| dprintf(debug_fd, " MODE: 0x%lx\n", data); |
| dprintf(debug_fd, " PC: 0x%016lx RA: 0x%016lx SP: 0x%016lx GP: 0x%016lx\n", |
| core.regs.pc, core.regs.ra, core.regs.sp, core.regs.gp); |
| dprintf(debug_fd, " TP: 0x%016lx T0: 0x%016lx T1: 0x%016lx T2: 0x%016lx\n", |
| core.regs.tp, core.regs.t0, core.regs.t1, core.regs.t2); |
| dprintf(debug_fd, " S0: 0x%016lx S1: 0x%016lx A0: 0x%016lx A1: 0x%016lx\n", |
| core.regs.s0, core.regs.s1, core.regs.a0, core.regs.a1); |
| dprintf(debug_fd, " A2: 0x%016lx A3: 0x%016lx A4: 0x%016lx A5: 0x%016lx\n", |
| core.regs.a2, core.regs.a3, core.regs.a4, core.regs.a5); |
| dprintf(debug_fd, " A6: 0x%016lx A7: 0x%016lx S2: 0x%016lx S3: 0x%016lx\n", |
| core.regs.a6, core.regs.a7, core.regs.s2, core.regs.s3); |
| dprintf(debug_fd, " S4: 0x%016lx S5: 0x%016lx S6: 0x%016lx S7: 0x%016lx\n", |
| core.regs.s4, core.regs.s5, core.regs.s6, core.regs.s7); |
| dprintf(debug_fd, " S8: 0x%016lx S9: 0x%016lx S10: 0x%016lx S11: 0x%016lx\n", |
| core.regs.s8, core.regs.s9, core.regs.s10, core.regs.s11); |
| dprintf(debug_fd, " T3: 0x%016lx T4: 0x%016lx T5: 0x%016lx T6: 0x%016lx\n", |
| core.regs.t3, core.regs.t4, core.regs.t5, core.regs.t6); |
| |
| kvm_cpu__show_csrs(vcpu); |
| } |