mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
Merge remote-tracking branch 'remotes/palmer/tags/riscv-for-master-5.0-sf3' into staging
RISC-V Patches for the 5.0 Soft Freeze, Part 3 This pull request is almost entirely an implementation of the draft hypervisor extension. This extension is still in draft and is expected to have incompatible changes before being frozen, but we've had good luck managing other RISC-V draft extensions in QEMU so far. Additionally, there's a fix to PCI addressing and some improvements to the M-mode timer. This boots linux and passes make check for me. # gpg: Signature made Tue 03 Mar 2020 00:23:20 GMT # gpg: using RSA key 2B3C3747446843B24A943A7A2E1319F35FBB1889 # gpg: issuer "palmer@dabbelt.com" # gpg: Good signature from "Palmer Dabbelt <palmer@dabbelt.com>" [unknown] # gpg: aka "Palmer Dabbelt <palmer@sifive.com>" [unknown] # gpg: aka "Palmer Dabbelt <palmerdabbelt@google.com>" [unknown] # gpg: WARNING: This key is not certified with a trusted signature! # gpg: There is no indication that the signature belongs to the owner. # Primary key fingerprint: 00CE 76D1 8349 60DF CE88 6DF8 EF4C A150 2CCB AB41 # Subkey fingerprint: 2B3C 3747 4468 43B2 4A94 3A7A 2E13 19F3 5FBB 1889 * remotes/palmer/tags/riscv-for-master-5.0-sf3: (38 commits) hw/riscv: Provide rdtime callback for TCG in CLINT emulation target/riscv: Emulate TIME CSRs for privileged mode riscv: virt: Allow PCI address 0 target/riscv: Allow enabling the Hypervisor extension target/riscv: Add the MSTATUS_MPV_ISSET helper macro target/riscv: Add support for the 32-bit MSTATUSH CSR target/riscv: Set htval and mtval2 on execptions target/riscv: Raise the new execptions when 2nd stage translation fails target/riscv: Implement second stage MMU target/riscv: Allow specifying MMU stage target/riscv: Respect MPRV and SPRV for floating point ops target/riscv: Mark both sstatus and msstatus_hs as dirty target/riscv: Disable guest FP support based on virtual status target/riscv: Only set TB flags with FP status if enabled target/riscv: Remove the hret instruction target/riscv: Add hfence instructions target/riscv: Add Hypervisor trap return support target/riscv: Add hypvervisor trap support target/riscv: Generate illegal instruction on WFI when V=1 target/ricsv: Flush the TLB on virtulisation mode changes ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
@@ -227,7 +227,8 @@ type_init(sifive_clint_register_types)
|
||||
* Create CLINT device.
|
||||
*/
|
||||
DeviceState *sifive_clint_create(hwaddr addr, hwaddr size, uint32_t num_harts,
|
||||
uint32_t sip_base, uint32_t timecmp_base, uint32_t time_base)
|
||||
uint32_t sip_base, uint32_t timecmp_base, uint32_t time_base,
|
||||
bool provide_rdtime)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < num_harts; i++) {
|
||||
@@ -236,6 +237,9 @@ DeviceState *sifive_clint_create(hwaddr addr, hwaddr size, uint32_t num_harts,
|
||||
if (!env) {
|
||||
continue;
|
||||
}
|
||||
if (provide_rdtime) {
|
||||
riscv_cpu_set_rdtime_fn(env, cpu_riscv_read_rtc);
|
||||
}
|
||||
env->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
|
||||
&sifive_clint_timer_cb, cpu);
|
||||
env->timecmp = 0;
|
||||
|
||||
+1
-1
@@ -164,7 +164,7 @@ static void riscv_sifive_e_soc_realize(DeviceState *dev, Error **errp)
|
||||
memmap[SIFIVE_E_PLIC].size);
|
||||
sifive_clint_create(memmap[SIFIVE_E_CLINT].base,
|
||||
memmap[SIFIVE_E_CLINT].size, ms->smp.cpus,
|
||||
SIFIVE_SIP_BASE, SIFIVE_TIMECMP_BASE, SIFIVE_TIME_BASE);
|
||||
SIFIVE_SIP_BASE, SIFIVE_TIMECMP_BASE, SIFIVE_TIME_BASE, false);
|
||||
create_unimplemented_device("riscv.sifive.e.aon",
|
||||
memmap[SIFIVE_E_AON].base, memmap[SIFIVE_E_AON].size);
|
||||
sifive_e_prci_create(memmap[SIFIVE_E_PRCI].base);
|
||||
|
||||
+1
-1
@@ -549,7 +549,7 @@ static void riscv_sifive_u_soc_realize(DeviceState *dev, Error **errp)
|
||||
serial_hd(1), qdev_get_gpio_in(DEVICE(s->plic), SIFIVE_U_UART1_IRQ));
|
||||
sifive_clint_create(memmap[SIFIVE_U_CLINT].base,
|
||||
memmap[SIFIVE_U_CLINT].size, ms->smp.cpus,
|
||||
SIFIVE_SIP_BASE, SIFIVE_TIMECMP_BASE, SIFIVE_TIME_BASE);
|
||||
SIFIVE_SIP_BASE, SIFIVE_TIMECMP_BASE, SIFIVE_TIME_BASE, false);
|
||||
|
||||
object_property_set_bool(OBJECT(&s->prci), true, "realized", &err);
|
||||
sysbus_mmio_map(SYS_BUS_DEVICE(&s->prci), 0, memmap[SIFIVE_U_PRCI].base);
|
||||
|
||||
+6
-3
@@ -227,7 +227,8 @@ static void spike_board_init(MachineState *machine)
|
||||
|
||||
/* Core Local Interruptor (timer and IPI) */
|
||||
sifive_clint_create(memmap[SPIKE_CLINT].base, memmap[SPIKE_CLINT].size,
|
||||
smp_cpus, SIFIVE_SIP_BASE, SIFIVE_TIMECMP_BASE, SIFIVE_TIME_BASE);
|
||||
smp_cpus, SIFIVE_SIP_BASE, SIFIVE_TIMECMP_BASE, SIFIVE_TIME_BASE,
|
||||
false);
|
||||
}
|
||||
|
||||
static void spike_v1_10_0_board_init(MachineState *machine)
|
||||
@@ -316,7 +317,8 @@ static void spike_v1_10_0_board_init(MachineState *machine)
|
||||
|
||||
/* Core Local Interruptor (timer and IPI) */
|
||||
sifive_clint_create(memmap[SPIKE_CLINT].base, memmap[SPIKE_CLINT].size,
|
||||
smp_cpus, SIFIVE_SIP_BASE, SIFIVE_TIMECMP_BASE, SIFIVE_TIME_BASE);
|
||||
smp_cpus, SIFIVE_SIP_BASE, SIFIVE_TIMECMP_BASE, SIFIVE_TIME_BASE,
|
||||
false);
|
||||
}
|
||||
|
||||
static void spike_v1_09_1_board_init(MachineState *machine)
|
||||
@@ -424,7 +426,8 @@ static void spike_v1_09_1_board_init(MachineState *machine)
|
||||
|
||||
/* Core Local Interruptor (timer and IPI) */
|
||||
sifive_clint_create(memmap[SPIKE_CLINT].base, memmap[SPIKE_CLINT].size,
|
||||
smp_cpus, SIFIVE_SIP_BASE, SIFIVE_TIMECMP_BASE, SIFIVE_TIME_BASE);
|
||||
smp_cpus, SIFIVE_SIP_BASE, SIFIVE_TIMECMP_BASE, SIFIVE_TIME_BASE,
|
||||
false);
|
||||
|
||||
g_free(config_string);
|
||||
}
|
||||
|
||||
+2
-1
@@ -593,7 +593,7 @@ static void riscv_virt_board_init(MachineState *machine)
|
||||
memmap[VIRT_PLIC].size);
|
||||
sifive_clint_create(memmap[VIRT_CLINT].base,
|
||||
memmap[VIRT_CLINT].size, smp_cpus,
|
||||
SIFIVE_SIP_BASE, SIFIVE_TIMECMP_BASE, SIFIVE_TIME_BASE);
|
||||
SIFIVE_SIP_BASE, SIFIVE_TIMECMP_BASE, SIFIVE_TIME_BASE, true);
|
||||
sifive_test_create(memmap[VIRT_TEST].base);
|
||||
|
||||
for (i = 0; i < VIRTIO_COUNT; i++) {
|
||||
@@ -641,6 +641,7 @@ static void riscv_virt_machine_class_init(ObjectClass *oc, void *data)
|
||||
mc->init = riscv_virt_board_init;
|
||||
mc->max_cpus = 8;
|
||||
mc->default_cpu_type = VIRT_CPU;
|
||||
mc->pci_allow_0_address = true;
|
||||
}
|
||||
|
||||
static const TypeInfo riscv_virt_machine_typeinfo = {
|
||||
|
||||
@@ -41,7 +41,8 @@ typedef struct SiFiveCLINTState {
|
||||
} SiFiveCLINTState;
|
||||
|
||||
DeviceState *sifive_clint_create(hwaddr addr, hwaddr size, uint32_t num_harts,
|
||||
uint32_t sip_base, uint32_t timecmp_base, uint32_t time_base);
|
||||
uint32_t sip_base, uint32_t timecmp_base, uint32_t time_base,
|
||||
bool provide_rdtime);
|
||||
|
||||
enum {
|
||||
SIFIVE_SIP_BASE = 0x0,
|
||||
|
||||
+53
-4
@@ -67,19 +67,27 @@ const char * const riscv_excp_names[] = {
|
||||
"load_page_fault",
|
||||
"reserved",
|
||||
"store_page_fault"
|
||||
"reserved",
|
||||
"reserved",
|
||||
"reserved",
|
||||
"reserved",
|
||||
"guest_exec_page_fault",
|
||||
"guest_load_page_fault",
|
||||
"reserved",
|
||||
"guest_store_page_fault"
|
||||
};
|
||||
|
||||
const char * const riscv_intr_names[] = {
|
||||
"u_software",
|
||||
"s_software",
|
||||
"h_software",
|
||||
"vs_software",
|
||||
"m_software",
|
||||
"u_timer",
|
||||
"s_timer",
|
||||
"h_timer",
|
||||
"vs_timer",
|
||||
"m_timer",
|
||||
"u_external",
|
||||
"s_external",
|
||||
"vs_external",
|
||||
"h_external",
|
||||
"m_external",
|
||||
"reserved",
|
||||
@@ -220,17 +228,53 @@ static void riscv_cpu_dump_state(CPUState *cs, FILE *f, int flags)
|
||||
CPURISCVState *env = &cpu->env;
|
||||
int i;
|
||||
|
||||
#if !defined(CONFIG_USER_ONLY)
|
||||
if (riscv_has_ext(env, RVH)) {
|
||||
qemu_fprintf(f, " %s %d\n", "V = ", riscv_cpu_virt_enabled(env));
|
||||
}
|
||||
#endif
|
||||
qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "pc ", env->pc);
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mhartid ", env->mhartid);
|
||||
qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mstatus ", env->mstatus);
|
||||
qemu_fprintf(f, " %s 0x%x\n", "mip ", env->mip);
|
||||
#ifdef TARGET_RISCV32
|
||||
qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mstatush ", env->mstatush);
|
||||
#endif
|
||||
if (riscv_has_ext(env, RVH)) {
|
||||
qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "hstatus ", env->hstatus);
|
||||
qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "vsstatus ", env->vsstatus);
|
||||
}
|
||||
qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mip ", env->mip);
|
||||
qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mie ", env->mie);
|
||||
qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mideleg ", env->mideleg);
|
||||
if (riscv_has_ext(env, RVH)) {
|
||||
qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "hideleg ", env->hideleg);
|
||||
}
|
||||
qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "medeleg ", env->medeleg);
|
||||
if (riscv_has_ext(env, RVH)) {
|
||||
qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "hedeleg ", env->hedeleg);
|
||||
}
|
||||
qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mtvec ", env->mtvec);
|
||||
qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "stvec ", env->stvec);
|
||||
if (riscv_has_ext(env, RVH)) {
|
||||
qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "vstvec ", env->vstvec);
|
||||
}
|
||||
qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mepc ", env->mepc);
|
||||
qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "sepc ", env->sepc);
|
||||
if (riscv_has_ext(env, RVH)) {
|
||||
qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "vsepc ", env->vsepc);
|
||||
}
|
||||
qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mcause ", env->mcause);
|
||||
qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "scause ", env->scause);
|
||||
if (riscv_has_ext(env, RVH)) {
|
||||
qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "vscause ", env->vscause);
|
||||
}
|
||||
qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mtval ", env->mtval);
|
||||
qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "stval ", env->sbadaddr);
|
||||
if (riscv_has_ext(env, RVH)) {
|
||||
qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "htval ", env->htval);
|
||||
qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mtval2 ", env->mtval2);
|
||||
}
|
||||
#endif
|
||||
|
||||
for (i = 0; i < 32; i++) {
|
||||
@@ -409,6 +453,9 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
|
||||
if (cpu->cfg.ext_u) {
|
||||
target_misa |= RVU;
|
||||
}
|
||||
if (cpu->cfg.ext_h) {
|
||||
target_misa |= RVH;
|
||||
}
|
||||
|
||||
set_misa(env, RVXLEN | target_misa);
|
||||
}
|
||||
@@ -444,6 +491,8 @@ static Property riscv_cpu_properties[] = {
|
||||
DEFINE_PROP_BOOL("c", RISCVCPU, cfg.ext_c, true),
|
||||
DEFINE_PROP_BOOL("s", RISCVCPU, cfg.ext_s, true),
|
||||
DEFINE_PROP_BOOL("u", RISCVCPU, cfg.ext_u, true),
|
||||
/* This is experimental so mark with 'x-' */
|
||||
DEFINE_PROP_BOOL("x-h", RISCVCPU, cfg.ext_h, false),
|
||||
DEFINE_PROP_BOOL("Counters", RISCVCPU, cfg.ext_counters, true),
|
||||
DEFINE_PROP_BOOL("Zifencei", RISCVCPU, cfg.ext_ifencei, true),
|
||||
DEFINE_PROP_BOOL("Zicsr", RISCVCPU, cfg.ext_icsr, true),
|
||||
|
||||
+61
-2
@@ -67,6 +67,7 @@
|
||||
#define RVC RV('C')
|
||||
#define RVS RV('S')
|
||||
#define RVU RV('U')
|
||||
#define RVH RV('H')
|
||||
|
||||
/* S extension denotes that Supervisor mode exists, however it is possible
|
||||
to have a core that support S mode but does not have an MMU and there
|
||||
@@ -103,6 +104,7 @@ struct CPURISCVState {
|
||||
target_ulong frm;
|
||||
|
||||
target_ulong badaddr;
|
||||
target_ulong guest_phys_fault_addr;
|
||||
|
||||
target_ulong priv_ver;
|
||||
target_ulong misa;
|
||||
@@ -116,12 +118,19 @@ struct CPURISCVState {
|
||||
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
target_ulong priv;
|
||||
/* This contains QEMU specific information about the virt state. */
|
||||
target_ulong virt;
|
||||
target_ulong resetvec;
|
||||
|
||||
target_ulong mhartid;
|
||||
target_ulong mstatus;
|
||||
|
||||
uint32_t mip;
|
||||
target_ulong mip;
|
||||
|
||||
#ifdef TARGET_RISCV32
|
||||
target_ulong mstatush;
|
||||
#endif
|
||||
|
||||
uint32_t miclaim;
|
||||
|
||||
target_ulong mie;
|
||||
@@ -142,6 +151,43 @@ struct CPURISCVState {
|
||||
target_ulong mcause;
|
||||
target_ulong mtval; /* since: priv-1.10.0 */
|
||||
|
||||
/* Hypervisor CSRs */
|
||||
target_ulong hstatus;
|
||||
target_ulong hedeleg;
|
||||
target_ulong hideleg;
|
||||
target_ulong hcounteren;
|
||||
target_ulong htval;
|
||||
target_ulong htinst;
|
||||
target_ulong hgatp;
|
||||
uint64_t htimedelta;
|
||||
|
||||
/* Virtual CSRs */
|
||||
target_ulong vsstatus;
|
||||
target_ulong vstvec;
|
||||
target_ulong vsscratch;
|
||||
target_ulong vsepc;
|
||||
target_ulong vscause;
|
||||
target_ulong vstval;
|
||||
target_ulong vsatp;
|
||||
#ifdef TARGET_RISCV32
|
||||
target_ulong vsstatush;
|
||||
#endif
|
||||
|
||||
target_ulong mtval2;
|
||||
target_ulong mtinst;
|
||||
|
||||
/* HS Backup CSRs */
|
||||
target_ulong stvec_hs;
|
||||
target_ulong sscratch_hs;
|
||||
target_ulong sepc_hs;
|
||||
target_ulong scause_hs;
|
||||
target_ulong stval_hs;
|
||||
target_ulong satp_hs;
|
||||
target_ulong mstatus_hs;
|
||||
#ifdef TARGET_RISCV32
|
||||
target_ulong mstatush_hs;
|
||||
#endif
|
||||
|
||||
target_ulong scounteren;
|
||||
target_ulong mcounteren;
|
||||
|
||||
@@ -156,6 +202,9 @@ struct CPURISCVState {
|
||||
/* physical memory protection */
|
||||
pmp_table_t pmp_state;
|
||||
|
||||
/* machine specific rdtime callback */
|
||||
uint64_t (*rdtime_fn)(void);
|
||||
|
||||
/* True if in debugger mode. */
|
||||
bool debugger;
|
||||
#endif
|
||||
@@ -213,6 +262,7 @@ typedef struct RISCVCPU {
|
||||
bool ext_c;
|
||||
bool ext_s;
|
||||
bool ext_u;
|
||||
bool ext_h;
|
||||
bool ext_counters;
|
||||
bool ext_ifencei;
|
||||
bool ext_icsr;
|
||||
@@ -247,6 +297,10 @@ int riscv_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg);
|
||||
int riscv_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
|
||||
bool riscv_cpu_exec_interrupt(CPUState *cs, int interrupt_request);
|
||||
bool riscv_cpu_fp_enabled(CPURISCVState *env);
|
||||
bool riscv_cpu_virt_enabled(CPURISCVState *env);
|
||||
void riscv_cpu_set_virt_enabled(CPURISCVState *env, bool enable);
|
||||
bool riscv_cpu_force_hs_excep_enabled(CPURISCVState *env);
|
||||
void riscv_cpu_set_force_hs_excep(CPURISCVState *env, bool enable);
|
||||
int riscv_cpu_mmu_index(CPURISCVState *env, bool ifetch);
|
||||
hwaddr riscv_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
|
||||
void riscv_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
|
||||
@@ -268,9 +322,11 @@ void riscv_cpu_list(void);
|
||||
#define cpu_mmu_index riscv_cpu_mmu_index
|
||||
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
void riscv_cpu_swap_hypervisor_regs(CPURISCVState *env);
|
||||
int riscv_cpu_claim_interrupts(RISCVCPU *cpu, uint32_t interrupts);
|
||||
uint32_t riscv_cpu_update_mip(RISCVCPU *cpu, uint32_t mask, uint32_t value);
|
||||
#define BOOL_TO_MASK(x) (-!!(x)) /* helper for riscv_cpu_update_mip value */
|
||||
void riscv_cpu_set_rdtime_fn(CPURISCVState *env, uint64_t (*fn)(void));
|
||||
#endif
|
||||
void riscv_cpu_set_mode(CPURISCVState *env, target_ulong newpriv);
|
||||
|
||||
@@ -293,7 +349,10 @@ static inline void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc,
|
||||
#ifdef CONFIG_USER_ONLY
|
||||
*flags = TB_FLAGS_MSTATUS_FS;
|
||||
#else
|
||||
*flags = cpu_mmu_index(env, 0) | (env->mstatus & MSTATUS_FS);
|
||||
*flags = cpu_mmu_index(env, 0);
|
||||
if (riscv_cpu_fp_enabled(env)) {
|
||||
*flags |= env->mstatus & MSTATUS_FS;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
+76
-35
@@ -135,6 +135,9 @@
|
||||
#define CSR_MTVEC 0x305
|
||||
#define CSR_MCOUNTEREN 0x306
|
||||
|
||||
/* 32-bit only */
|
||||
#define CSR_MSTATUSH 0x310
|
||||
|
||||
/* Legacy Counter Setup (priv v1.9.1) */
|
||||
/* Update to #define CSR_MCOUNTINHIBIT 0x320 for 1.11.0 */
|
||||
#define CSR_MUCOUNTEREN 0x320
|
||||
@@ -177,8 +180,14 @@
|
||||
#define CSR_HSTATUS 0x600
|
||||
#define CSR_HEDELEG 0x602
|
||||
#define CSR_HIDELEG 0x603
|
||||
#define CSR_HCOUNTERNEN 0x606
|
||||
#define CSR_HIE 0x604
|
||||
#define CSR_HCOUNTEREN 0x606
|
||||
#define CSR_HTVAL 0x643
|
||||
#define CSR_HIP 0x644
|
||||
#define CSR_HTINST 0x64A
|
||||
#define CSR_HGATP 0x680
|
||||
#define CSR_HTIMEDELTA 0x605
|
||||
#define CSR_HTIMEDELTAH 0x615
|
||||
|
||||
#if defined(TARGET_RISCV32)
|
||||
#define HGATP_MODE SATP32_MODE
|
||||
@@ -191,6 +200,20 @@
|
||||
#define HGATP_PPN SATP64_PPN
|
||||
#endif
|
||||
|
||||
/* Virtual CSRs */
|
||||
#define CSR_VSSTATUS 0x200
|
||||
#define CSR_VSIE 0x204
|
||||
#define CSR_VSTVEC 0x205
|
||||
#define CSR_VSSCRATCH 0x240
|
||||
#define CSR_VSEPC 0x241
|
||||
#define CSR_VSCAUSE 0x242
|
||||
#define CSR_VSTVAL 0x243
|
||||
#define CSR_VSIP 0x244
|
||||
#define CSR_VSATP 0x280
|
||||
|
||||
#define CSR_MTINST 0x34a
|
||||
#define CSR_MTVAL2 0x34b
|
||||
|
||||
/* Physical Memory Protection */
|
||||
#define CSR_PMPCFG0 0x3a0
|
||||
#define CSR_PMPCFG1 0x3a1
|
||||
@@ -313,17 +336,6 @@
|
||||
#define CSR_MHPMCOUNTER30H 0xb9e
|
||||
#define CSR_MHPMCOUNTER31H 0xb9f
|
||||
|
||||
/* Legacy Hypervisor Trap Setup (priv v1.9.1) */
|
||||
#define CSR_HIE 0x204
|
||||
#define CSR_HTVEC 0x205
|
||||
|
||||
/* Legacy Hypervisor Trap Handling (priv v1.9.1) */
|
||||
#define CSR_HSCRATCH 0x240
|
||||
#define CSR_HEPC 0x241
|
||||
#define CSR_HCAUSE 0x242
|
||||
#define CSR_HBADADDR 0x243
|
||||
#define CSR_HIP 0x244
|
||||
|
||||
/* Legacy Machine Protection and Translation (priv v1.9.1) */
|
||||
#define CSR_MBASE 0x380
|
||||
#define CSR_MBOUND 0x381
|
||||
@@ -351,8 +363,19 @@
|
||||
#define MSTATUS_TVM 0x00100000 /* since: priv-1.10 */
|
||||
#define MSTATUS_TW 0x20000000 /* since: priv-1.10 */
|
||||
#define MSTATUS_TSR 0x40000000 /* since: priv-1.10 */
|
||||
#if defined(TARGET_RISCV64)
|
||||
#define MSTATUS_MTL 0x4000000000ULL
|
||||
#define MSTATUS_MPV 0x8000000000ULL
|
||||
#elif defined(TARGET_RISCV32)
|
||||
#define MSTATUS_MTL 0x00000040
|
||||
#define MSTATUS_MPV 0x00000080
|
||||
#endif
|
||||
|
||||
#ifdef TARGET_RISCV32
|
||||
# define MSTATUS_MPV_ISSET(env) get_field(env->mstatush, MSTATUS_MPV)
|
||||
#else
|
||||
# define MSTATUS_MPV_ISSET(env) get_field(env->mstatus, MSTATUS_MPV)
|
||||
#endif
|
||||
|
||||
#define MSTATUS64_UXL 0x0000000300000000ULL
|
||||
#define MSTATUS64_SXL 0x0000000C00000000ULL
|
||||
@@ -400,7 +423,6 @@
|
||||
|
||||
/* hstatus CSR bits */
|
||||
#define HSTATUS_SPRV 0x00000001
|
||||
#define HSTATUS_STL 0x00000040
|
||||
#define HSTATUS_SPV 0x00000080
|
||||
#define HSTATUS_SP2P 0x00000100
|
||||
#define HSTATUS_SP2V 0x00000200
|
||||
@@ -422,6 +444,15 @@
|
||||
#define PRV_H 2 /* Reserved */
|
||||
#define PRV_M 3
|
||||
|
||||
/* Virtulisation Register Fields */
|
||||
#define VIRT_ONOFF 1
|
||||
/* This is used to save state for when we take an exception. If this is set
|
||||
* that means that we want to force a HS level exception (no matter what the
|
||||
* delegation is set to). This will occur for things such as a second level
|
||||
* page table fault.
|
||||
*/
|
||||
#define FORCE_HS_EXCEP 2
|
||||
|
||||
/* RV32 satp CSR field masks */
|
||||
#define SATP32_MODE 0x80000000
|
||||
#define SATP32_ASID 0x7fc00000
|
||||
@@ -480,22 +511,25 @@
|
||||
#define DEFAULT_RSTVEC 0x1000
|
||||
|
||||
/* Exception causes */
|
||||
#define EXCP_NONE -1 /* sentinel value */
|
||||
#define RISCV_EXCP_INST_ADDR_MIS 0x0
|
||||
#define RISCV_EXCP_INST_ACCESS_FAULT 0x1
|
||||
#define RISCV_EXCP_ILLEGAL_INST 0x2
|
||||
#define RISCV_EXCP_BREAKPOINT 0x3
|
||||
#define RISCV_EXCP_LOAD_ADDR_MIS 0x4
|
||||
#define RISCV_EXCP_LOAD_ACCESS_FAULT 0x5
|
||||
#define RISCV_EXCP_STORE_AMO_ADDR_MIS 0x6
|
||||
#define RISCV_EXCP_STORE_AMO_ACCESS_FAULT 0x7
|
||||
#define RISCV_EXCP_U_ECALL 0x8
|
||||
#define RISCV_EXCP_S_ECALL 0x9
|
||||
#define RISCV_EXCP_H_ECALL 0xa
|
||||
#define RISCV_EXCP_M_ECALL 0xb
|
||||
#define RISCV_EXCP_INST_PAGE_FAULT 0xc /* since: priv-1.10.0 */
|
||||
#define RISCV_EXCP_LOAD_PAGE_FAULT 0xd /* since: priv-1.10.0 */
|
||||
#define RISCV_EXCP_STORE_PAGE_FAULT 0xf /* since: priv-1.10.0 */
|
||||
#define EXCP_NONE -1 /* sentinel value */
|
||||
#define RISCV_EXCP_INST_ADDR_MIS 0x0
|
||||
#define RISCV_EXCP_INST_ACCESS_FAULT 0x1
|
||||
#define RISCV_EXCP_ILLEGAL_INST 0x2
|
||||
#define RISCV_EXCP_BREAKPOINT 0x3
|
||||
#define RISCV_EXCP_LOAD_ADDR_MIS 0x4
|
||||
#define RISCV_EXCP_LOAD_ACCESS_FAULT 0x5
|
||||
#define RISCV_EXCP_STORE_AMO_ADDR_MIS 0x6
|
||||
#define RISCV_EXCP_STORE_AMO_ACCESS_FAULT 0x7
|
||||
#define RISCV_EXCP_U_ECALL 0x8
|
||||
#define RISCV_EXCP_S_ECALL 0x9
|
||||
#define RISCV_EXCP_VS_ECALL 0xa
|
||||
#define RISCV_EXCP_M_ECALL 0xb
|
||||
#define RISCV_EXCP_INST_PAGE_FAULT 0xc /* since: priv-1.10.0 */
|
||||
#define RISCV_EXCP_LOAD_PAGE_FAULT 0xd /* since: priv-1.10.0 */
|
||||
#define RISCV_EXCP_STORE_PAGE_FAULT 0xf /* since: priv-1.10.0 */
|
||||
#define RISCV_EXCP_INST_GUEST_PAGE_FAULT 0x14
|
||||
#define RISCV_EXCP_LOAD_GUEST_ACCESS_FAULT 0x15
|
||||
#define RISCV_EXCP_STORE_GUEST_AMO_ACCESS_FAULT 0x17
|
||||
|
||||
#define RISCV_EXCP_INT_FLAG 0x80000000
|
||||
#define RISCV_EXCP_INT_MASK 0x7fffffff
|
||||
@@ -503,29 +537,29 @@
|
||||
/* Interrupt causes */
|
||||
#define IRQ_U_SOFT 0
|
||||
#define IRQ_S_SOFT 1
|
||||
#define IRQ_H_SOFT 2 /* reserved */
|
||||
#define IRQ_VS_SOFT 2
|
||||
#define IRQ_M_SOFT 3
|
||||
#define IRQ_U_TIMER 4
|
||||
#define IRQ_S_TIMER 5
|
||||
#define IRQ_H_TIMER 6 /* reserved */
|
||||
#define IRQ_VS_TIMER 6
|
||||
#define IRQ_M_TIMER 7
|
||||
#define IRQ_U_EXT 8
|
||||
#define IRQ_S_EXT 9
|
||||
#define IRQ_H_EXT 10 /* reserved */
|
||||
#define IRQ_VS_EXT 10
|
||||
#define IRQ_M_EXT 11
|
||||
|
||||
/* mip masks */
|
||||
#define MIP_USIP (1 << IRQ_U_SOFT)
|
||||
#define MIP_SSIP (1 << IRQ_S_SOFT)
|
||||
#define MIP_HSIP (1 << IRQ_H_SOFT)
|
||||
#define MIP_VSSIP (1 << IRQ_VS_SOFT)
|
||||
#define MIP_MSIP (1 << IRQ_M_SOFT)
|
||||
#define MIP_UTIP (1 << IRQ_U_TIMER)
|
||||
#define MIP_STIP (1 << IRQ_S_TIMER)
|
||||
#define MIP_HTIP (1 << IRQ_H_TIMER)
|
||||
#define MIP_VSTIP (1 << IRQ_VS_TIMER)
|
||||
#define MIP_MTIP (1 << IRQ_M_TIMER)
|
||||
#define MIP_UEIP (1 << IRQ_U_EXT)
|
||||
#define MIP_SEIP (1 << IRQ_S_EXT)
|
||||
#define MIP_HEIP (1 << IRQ_H_EXT)
|
||||
#define MIP_VSEIP (1 << IRQ_VS_EXT)
|
||||
#define MIP_MEIP (1 << IRQ_M_EXT)
|
||||
|
||||
/* sip masks */
|
||||
@@ -533,4 +567,11 @@
|
||||
#define SIP_STIP MIP_STIP
|
||||
#define SIP_SEIP MIP_SEIP
|
||||
|
||||
/* MIE masks */
|
||||
#define MIE_SEIE (1 << IRQ_S_EXT)
|
||||
#define MIE_UEIE (1 << IRQ_U_EXT)
|
||||
#define MIE_STIE (1 << IRQ_S_TIMER)
|
||||
#define MIE_UTIE (1 << IRQ_U_TIMER)
|
||||
#define MIE_SSIE (1 << IRQ_S_SOFT)
|
||||
#define MIE_USIE (1 << IRQ_U_SOFT)
|
||||
#endif
|
||||
|
||||
+442
-44
File diff suppressed because it is too large
Load Diff
+438
-17
File diff suppressed because it is too large
Load Diff
@@ -130,6 +130,8 @@ static int csr_register_map[] = {
|
||||
CSR_MCAUSE,
|
||||
CSR_MTVAL,
|
||||
CSR_MIP,
|
||||
CSR_MTINST,
|
||||
CSR_MTVAL2,
|
||||
CSR_PMPCFG0,
|
||||
CSR_PMPCFG1,
|
||||
CSR_PMPCFG2,
|
||||
@@ -252,12 +254,11 @@ static int csr_register_map[] = {
|
||||
CSR_HEDELEG,
|
||||
CSR_HIDELEG,
|
||||
CSR_HIE,
|
||||
CSR_HTVEC,
|
||||
CSR_HSCRATCH,
|
||||
CSR_HEPC,
|
||||
CSR_HCAUSE,
|
||||
CSR_HBADADDR,
|
||||
CSR_HCOUNTEREN,
|
||||
CSR_HTVAL,
|
||||
CSR_HIP,
|
||||
CSR_HTINST,
|
||||
CSR_HGATP,
|
||||
CSR_MBASE,
|
||||
CSR_MBOUND,
|
||||
CSR_MIBASE,
|
||||
|
||||
@@ -63,20 +63,24 @@
|
||||
@r2_rm ....... ..... ..... ... ..... ....... %rs1 %rm %rd
|
||||
@r2 ....... ..... ..... ... ..... ....... %rs1 %rd
|
||||
|
||||
@hfence_gvma ....... ..... ..... ... ..... ....... %rs2 %rs1
|
||||
@hfence_bvma ....... ..... ..... ... ..... ....... %rs2 %rs1
|
||||
|
||||
@sfence_vma ....... ..... ..... ... ..... ....... %rs2 %rs1
|
||||
@sfence_vm ....... ..... ..... ... ..... ....... %rs1
|
||||
|
||||
|
||||
# *** Privileged Instructions ***
|
||||
ecall 000000000000 00000 000 00000 1110011
|
||||
ebreak 000000000001 00000 000 00000 1110011
|
||||
uret 0000000 00010 00000 000 00000 1110011
|
||||
sret 0001000 00010 00000 000 00000 1110011
|
||||
hret 0010000 00010 00000 000 00000 1110011
|
||||
mret 0011000 00010 00000 000 00000 1110011
|
||||
wfi 0001000 00101 00000 000 00000 1110011
|
||||
sfence_vma 0001001 ..... ..... 000 00000 1110011 @sfence_vma
|
||||
sfence_vm 0001000 00100 ..... 000 00000 1110011 @sfence_vm
|
||||
ecall 000000000000 00000 000 00000 1110011
|
||||
ebreak 000000000001 00000 000 00000 1110011
|
||||
uret 0000000 00010 00000 000 00000 1110011
|
||||
sret 0001000 00010 00000 000 00000 1110011
|
||||
mret 0011000 00010 00000 000 00000 1110011
|
||||
wfi 0001000 00101 00000 000 00000 1110011
|
||||
hfence_gvma 0110001 ..... ..... 000 00000 1110011 @hfence_gvma
|
||||
hfence_bvma 0010001 ..... ..... 000 00000 1110011 @hfence_bvma
|
||||
sfence_vma 0001001 ..... ..... 000 00000 1110011 @sfence_vma
|
||||
sfence_vm 0001000 00100 ..... 000 00000 1110011 @sfence_vm
|
||||
|
||||
# *** RV32I Base Instruction Set ***
|
||||
lui .................... ..... 0110111 @u
|
||||
|
||||
@@ -58,11 +58,6 @@ static bool trans_sret(DisasContext *ctx, arg_sret *a)
|
||||
#endif
|
||||
}
|
||||
|
||||
static bool trans_hret(DisasContext *ctx, arg_hret *a)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool trans_mret(DisasContext *ctx, arg_mret *a)
|
||||
{
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
@@ -108,3 +103,43 @@ static bool trans_sfence_vm(DisasContext *ctx, arg_sfence_vm *a)
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool trans_hfence_gvma(DisasContext *ctx, arg_sfence_vma *a)
|
||||
{
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
if (ctx->priv_ver >= PRIV_VERSION_1_10_0 &&
|
||||
has_ext(ctx, RVH)) {
|
||||
/* Hpervisor extensions exist */
|
||||
/*
|
||||
* if (env->priv == PRV_M ||
|
||||
* (env->priv == PRV_S &&
|
||||
* !riscv_cpu_virt_enabled(env) &&
|
||||
* get_field(ctx->mstatus_fs, MSTATUS_TVM))) {
|
||||
*/
|
||||
gen_helper_tlb_flush(cpu_env);
|
||||
return true;
|
||||
/* } */
|
||||
}
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool trans_hfence_bvma(DisasContext *ctx, arg_sfence_vma *a)
|
||||
{
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
if (ctx->priv_ver >= PRIV_VERSION_1_10_0 &&
|
||||
has_ext(ctx, RVH)) {
|
||||
/* Hpervisor extensions exist */
|
||||
/*
|
||||
* if (env->priv == PRV_M ||
|
||||
* (env->priv == PRV_S &&
|
||||
* !riscv_cpu_virt_enabled(env) &&
|
||||
* get_field(ctx->mstatus_fs, MSTATUS_TVM))) {
|
||||
*/
|
||||
gen_helper_tlb_flush(cpu_env);
|
||||
return true;
|
||||
/* } */
|
||||
}
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
+59
-12
@@ -73,6 +73,8 @@ target_ulong helper_csrrc(CPURISCVState *env, target_ulong src,
|
||||
|
||||
target_ulong helper_sret(CPURISCVState *env, target_ulong cpu_pc_deb)
|
||||
{
|
||||
target_ulong prev_priv, prev_virt, mstatus;
|
||||
|
||||
if (!(env->priv >= PRV_S)) {
|
||||
riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
|
||||
}
|
||||
@@ -87,16 +89,46 @@ target_ulong helper_sret(CPURISCVState *env, target_ulong cpu_pc_deb)
|
||||
riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
|
||||
}
|
||||
|
||||
target_ulong mstatus = env->mstatus;
|
||||
target_ulong prev_priv = get_field(mstatus, MSTATUS_SPP);
|
||||
mstatus = set_field(mstatus,
|
||||
env->priv_ver >= PRIV_VERSION_1_10_0 ?
|
||||
MSTATUS_SIE : MSTATUS_UIE << prev_priv,
|
||||
get_field(mstatus, MSTATUS_SPIE));
|
||||
mstatus = set_field(mstatus, MSTATUS_SPIE, 1);
|
||||
mstatus = set_field(mstatus, MSTATUS_SPP, PRV_U);
|
||||
mstatus = env->mstatus;
|
||||
|
||||
if (riscv_has_ext(env, RVH) && !riscv_cpu_virt_enabled(env)) {
|
||||
/* We support Hypervisor extensions and virtulisation is disabled */
|
||||
target_ulong hstatus = env->hstatus;
|
||||
|
||||
prev_priv = get_field(mstatus, MSTATUS_SPP);
|
||||
prev_virt = get_field(hstatus, HSTATUS_SPV);
|
||||
|
||||
hstatus = set_field(hstatus, HSTATUS_SPV,
|
||||
get_field(hstatus, HSTATUS_SP2V));
|
||||
mstatus = set_field(mstatus, MSTATUS_SPP,
|
||||
get_field(hstatus, HSTATUS_SP2P));
|
||||
hstatus = set_field(hstatus, HSTATUS_SP2V, 0);
|
||||
hstatus = set_field(hstatus, HSTATUS_SP2P, 0);
|
||||
mstatus = set_field(mstatus, SSTATUS_SIE,
|
||||
get_field(mstatus, SSTATUS_SPIE));
|
||||
mstatus = set_field(mstatus, SSTATUS_SPIE, 1);
|
||||
|
||||
env->mstatus = mstatus;
|
||||
env->hstatus = hstatus;
|
||||
|
||||
if (prev_virt) {
|
||||
riscv_cpu_swap_hypervisor_regs(env);
|
||||
}
|
||||
|
||||
riscv_cpu_set_virt_enabled(env, prev_virt);
|
||||
} else {
|
||||
prev_priv = get_field(mstatus, MSTATUS_SPP);
|
||||
|
||||
mstatus = set_field(mstatus,
|
||||
env->priv_ver >= PRIV_VERSION_1_10_0 ?
|
||||
MSTATUS_SIE : MSTATUS_UIE << prev_priv,
|
||||
get_field(mstatus, MSTATUS_SPIE));
|
||||
mstatus = set_field(mstatus, MSTATUS_SPIE, 1);
|
||||
mstatus = set_field(mstatus, MSTATUS_SPP, PRV_U);
|
||||
env->mstatus = mstatus;
|
||||
}
|
||||
|
||||
riscv_cpu_set_mode(env, prev_priv);
|
||||
env->mstatus = mstatus;
|
||||
|
||||
return retpc;
|
||||
}
|
||||
@@ -114,14 +146,28 @@ target_ulong helper_mret(CPURISCVState *env, target_ulong cpu_pc_deb)
|
||||
|
||||
target_ulong mstatus = env->mstatus;
|
||||
target_ulong prev_priv = get_field(mstatus, MSTATUS_MPP);
|
||||
target_ulong prev_virt = MSTATUS_MPV_ISSET(env);
|
||||
mstatus = set_field(mstatus,
|
||||
env->priv_ver >= PRIV_VERSION_1_10_0 ?
|
||||
MSTATUS_MIE : MSTATUS_UIE << prev_priv,
|
||||
get_field(mstatus, MSTATUS_MPIE));
|
||||
mstatus = set_field(mstatus, MSTATUS_MPIE, 1);
|
||||
mstatus = set_field(mstatus, MSTATUS_MPP, PRV_U);
|
||||
riscv_cpu_set_mode(env, prev_priv);
|
||||
#ifdef TARGET_RISCV32
|
||||
env->mstatush = set_field(env->mstatush, MSTATUS_MPV, 0);
|
||||
#else
|
||||
mstatus = set_field(mstatus, MSTATUS_MPV, 0);
|
||||
#endif
|
||||
env->mstatus = mstatus;
|
||||
riscv_cpu_set_mode(env, prev_priv);
|
||||
|
||||
if (riscv_has_ext(env, RVH)) {
|
||||
if (prev_virt) {
|
||||
riscv_cpu_swap_hypervisor_regs(env);
|
||||
}
|
||||
|
||||
riscv_cpu_set_virt_enabled(env, prev_virt);
|
||||
}
|
||||
|
||||
return retpc;
|
||||
}
|
||||
@@ -130,9 +176,10 @@ void helper_wfi(CPURISCVState *env)
|
||||
{
|
||||
CPUState *cs = env_cpu(env);
|
||||
|
||||
if (env->priv == PRV_S &&
|
||||
if ((env->priv == PRV_S &&
|
||||
env->priv_ver >= PRIV_VERSION_1_10_0 &&
|
||||
get_field(env->mstatus, MSTATUS_TW)) {
|
||||
get_field(env->mstatus, MSTATUS_TW)) ||
|
||||
riscv_cpu_virt_enabled(env)) {
|
||||
riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
|
||||
} else {
|
||||
cs->halted = 1;
|
||||
|
||||
@@ -44,6 +44,8 @@ typedef struct DisasContext {
|
||||
/* pc_succ_insn points to the instruction following base.pc_next */
|
||||
target_ulong pc_succ_insn;
|
||||
target_ulong priv_ver;
|
||||
bool virt_enabled;
|
||||
uint32_t opcode;
|
||||
uint32_t mstatus_fs;
|
||||
uint32_t misa;
|
||||
uint32_t mem_idx;
|
||||
@@ -395,6 +397,12 @@ static void mark_fs_dirty(DisasContext *ctx)
|
||||
tcg_gen_ld_tl(tmp, cpu_env, offsetof(CPURISCVState, mstatus));
|
||||
tcg_gen_ori_tl(tmp, tmp, MSTATUS_FS | MSTATUS_SD);
|
||||
tcg_gen_st_tl(tmp, cpu_env, offsetof(CPURISCVState, mstatus));
|
||||
|
||||
if (ctx->virt_enabled) {
|
||||
tcg_gen_ld_tl(tmp, cpu_env, offsetof(CPURISCVState, mstatus_hs));
|
||||
tcg_gen_ori_tl(tmp, tmp, MSTATUS_FS | MSTATUS_SD);
|
||||
tcg_gen_st_tl(tmp, cpu_env, offsetof(CPURISCVState, mstatus_hs));
|
||||
}
|
||||
tcg_temp_free(tmp);
|
||||
}
|
||||
#else
|
||||
@@ -742,6 +750,25 @@ static void riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
|
||||
ctx->mem_idx = ctx->base.tb->flags & TB_FLAGS_MMU_MASK;
|
||||
ctx->mstatus_fs = ctx->base.tb->flags & TB_FLAGS_MSTATUS_FS;
|
||||
ctx->priv_ver = env->priv_ver;
|
||||
#if !defined(CONFIG_USER_ONLY)
|
||||
if (riscv_has_ext(env, RVH)) {
|
||||
ctx->virt_enabled = riscv_cpu_virt_enabled(env);
|
||||
if (env->priv_ver == PRV_M &&
|
||||
get_field(env->mstatus, MSTATUS_MPRV) &&
|
||||
MSTATUS_MPV_ISSET(env)) {
|
||||
ctx->virt_enabled = true;
|
||||
} else if (env->priv == PRV_S &&
|
||||
!riscv_cpu_virt_enabled(env) &&
|
||||
get_field(env->hstatus, HSTATUS_SPRV) &&
|
||||
get_field(env->hstatus, HSTATUS_SPV)) {
|
||||
ctx->virt_enabled = true;
|
||||
}
|
||||
} else {
|
||||
ctx->virt_enabled = false;
|
||||
}
|
||||
#else
|
||||
ctx->virt_enabled = false;
|
||||
#endif
|
||||
ctx->misa = env->misa;
|
||||
ctx->frm = -1; /* unknown rounding mode */
|
||||
ctx->ext_ifencei = cpu->cfg.ext_ifencei;
|
||||
@@ -810,7 +837,15 @@ static void riscv_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
|
||||
|
||||
static void riscv_tr_disas_log(const DisasContextBase *dcbase, CPUState *cpu)
|
||||
{
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
RISCVCPU *rvcpu = RISCV_CPU(cpu);
|
||||
CPURISCVState *env = &rvcpu->env;
|
||||
#endif
|
||||
|
||||
qemu_log("IN: %s\n", lookup_symbol(dcbase->pc_first));
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
qemu_log("Priv: "TARGET_FMT_ld"; Virt: "TARGET_FMT_ld"\n", env->priv, env->virt);
|
||||
#endif
|
||||
log_target_disas(cpu, dcbase->pc_first, dcbase->tb->size);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user