@@ -957,7 +957,7 @@ static void elf_core_copy_regs(target_elf_gregset_t *regs,
}
(*regs)[TARGET_EF_CSR_ERA] = tswapreg(env->pc);
- (*regs)[TARGET_EF_CSR_BADV] = tswapreg(env->badaddr);
+ (*regs)[TARGET_EF_CSR_BADV] = tswapreg(env->badvaddr);
}
#define USE_ELF_CORE_DUMP
@@ -18,7 +18,6 @@
#include "fpu/softfloat-helpers.h"
#include "cpu-csr.h"
#include "sysemu/reset.h"
-#include "hw/loader.h"
const char * const regnames[32] = {
"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
@@ -51,6 +50,7 @@ static const char * const excp_names[] = {
[EXCCODE_IPE] = "Instruction privilege error",
[EXCCODE_FPE] = "Floating Point Exception",
[EXCCODE_DBP] = "Debug breakpoint",
+ [EXCCODE_BCE] = "Bound Check Exception",
};
const char *loongarch_exception_name(int32_t exception)
@@ -82,6 +82,7 @@ static void loongarch_cpu_set_pc(CPUState *cs, vaddr value)
env->pc = value;
}
+#ifndef CONFIG_USER_ONLY
#include "hw/loongarch/virt.h"
void loongarch_cpu_set_irq(void *opaque, int irq, int level)
@@ -172,17 +173,20 @@ static void loongarch_cpu_do_interrupt(CPUState *cs)
update_badinstr = 0;
break;
case EXCCODE_ADEM:
+ case EXCCODE_BCE:
case EXCCODE_SYS:
case EXCCODE_BRK:
+ case EXCCODE_INE:
+ case EXCCODE_IPE:
+ case EXCCODE_FPE:
+ env->badvaddr = env->pc;
+ QEMU_FALLTHROUGH;
case EXCCODE_PIL:
case EXCCODE_PIS:
case EXCCODE_PME:
case EXCCODE_PNR:
case EXCCODE_PNX:
case EXCCODE_PPI:
- case EXCCODE_INE:
- case EXCCODE_IPE:
- case EXCCODE_FPE:
cause = cs->exception_index;
break;
default:
@@ -292,6 +296,7 @@ static bool loongarch_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
}
return false;
}
+#endif
#ifdef CONFIG_TCG
static void loongarch_cpu_synchronize_from_tb(CPUState *cs,
@@ -306,6 +311,9 @@ static void loongarch_cpu_synchronize_from_tb(CPUState *cs,
static bool loongarch_cpu_has_work(CPUState *cs)
{
+#ifdef CONFIG_USER_ONLY
+ return true;
+#else
LoongArchCPU *cpu = LOONGARCH_CPU(cs);
CPULoongArchState *env = &cpu->env;
bool has_work = false;
@@ -316,6 +324,7 @@ static bool loongarch_cpu_has_work(CPUState *cs)
}
return has_work;
+#endif
}
static void loongarch_la464_initfn(Object *obj)
@@ -464,7 +473,9 @@ static void loongarch_cpu_reset(DeviceState *dev)
env->CSR_DMW[n] = FIELD_DP64(env->CSR_DMW[n], CSR_DMW, PLV3, 0);
}
+#ifndef CONFIG_USER_ONLY
env->pc = 0x1c000000;
+#endif
restore_fp_status(env);
cs->exception_index = -1;
@@ -495,6 +506,7 @@ static void loongarch_cpu_realizefn(DeviceState *dev, Error **errp)
lacc->parent_realize(dev, errp);
}
+#ifndef CONFIG_USER_ONLY
static void loongarch_qemu_write(void *opaque, hwaddr addr,
uint64_t val, unsigned size)
{
@@ -529,13 +541,16 @@ static const MemoryRegionOps loongarch_qemu_ops = {
.max_access_size = 8,
},
};
+#endif
static void loongarch_cpu_init(Object *obj)
{
LoongArchCPU *cpu = LOONGARCH_CPU(obj);
- CPULoongArchState *env = &cpu->env;
cpu_set_cpustate_pointers(cpu);
+
+#ifndef CONFIG_USER_ONLY
+ CPULoongArchState *env = &cpu->env;
qdev_init_gpio_in(DEVICE(cpu), loongarch_cpu_set_irq, N_IRQS);
timer_init_ns(&cpu->timer, QEMU_CLOCK_VIRTUAL,
&loongarch_constant_timer_cb, cpu);
@@ -545,6 +560,7 @@ static void loongarch_cpu_init(Object *obj)
memory_region_init_io(&env->iocsr_mem, OBJECT(cpu), &loongarch_qemu_ops,
NULL, "iocsr_misc", 0x428);
memory_region_add_subregion(&env->system_iocsr, 0, &env->iocsr_mem);
+#endif
}
static ObjectClass *loongarch_cpu_class_by_name(const char *cpu_model)
@@ -579,6 +595,7 @@ void loongarch_cpu_dump_state(CPUState *cs, FILE *f, int flags)
}
}
+#ifndef CONFIG_USER_ONLY
qemu_fprintf(f, "CRMD=%016" PRIx64 "\n", env->CSR_CRMD);
qemu_fprintf(f, "PRMD=%016" PRIx64 "\n", env->CSR_PRMD);
qemu_fprintf(f, "EUEN=%016" PRIx64 "\n", env->CSR_EUEN);
@@ -593,6 +610,7 @@ void loongarch_cpu_dump_state(CPUState *cs, FILE *f, int flags)
qemu_fprintf(f, "TLBRENTRY=%016" PRIx64 "\n", env->CSR_TLBRENTRY);
qemu_fprintf(f, "TLBRBADV=%016" PRIx64 "\n", env->CSR_TLBRBADV);
qemu_fprintf(f, "TLBRERA=%016" PRIx64 "\n", env->CSR_TLBRERA);
+#endif
/* fpr */
if (flags & CPU_DUMP_FPU) {
@@ -603,6 +621,7 @@ void loongarch_cpu_dump_state(CPUState *cs, FILE *f, int flags)
}
}
}
+
}
#ifdef CONFIG_TCG
@@ -612,18 +631,22 @@ static struct TCGCPUOps loongarch_tcg_ops = {
.initialize = loongarch_translate_init,
.synchronize_from_tb = loongarch_cpu_synchronize_from_tb,
+#ifndef CONFIG_USER_ONLY
.tlb_fill = loongarch_cpu_tlb_fill,
.cpu_exec_interrupt = loongarch_cpu_exec_interrupt,
.do_interrupt = loongarch_cpu_do_interrupt,
.do_transaction_failed = loongarch_cpu_do_transaction_failed,
+#endif
};
#endif /* CONFIG_TCG */
+#ifndef CONFIG_USER_ONLY
#include "hw/core/sysemu-cpu-ops.h"
static const struct SysemuCPUOps loongarch_sysemu_ops = {
.get_phys_page_debug = loongarch_cpu_get_phys_page_debug,
};
+#endif
static void loongarch_cpu_class_init(ObjectClass *c, void *data)
{
@@ -639,8 +662,10 @@ static void loongarch_cpu_class_init(ObjectClass *c, void *data)
cc->has_work = loongarch_cpu_has_work;
cc->dump_state = loongarch_cpu_dump_state;
cc->set_pc = loongarch_cpu_set_pc;
+#ifndef CONFIG_USER_ONLY
dc->vmsd = &vmstate_loongarch_cpu;
cc->sysemu_ops = &loongarch_sysemu_ops;
+#endif
cc->disas_set_info = loongarch_cpu_disas_set_info;
cc->gdb_read_register = loongarch_cpu_gdb_read_register;
cc->gdb_write_register = loongarch_cpu_gdb_write_register;
@@ -246,7 +246,7 @@ typedef struct CPUArchState {
uint64_t lladdr; /* LL virtual address compared against SC */
uint64_t llval;
- uint64_t badaddr;
+ uint64_t badvaddr;
/* LoongArch CSRs */
uint64_t CSR_CRMD;
@@ -303,6 +303,7 @@ typedef struct CPUArchState {
uint64_t CSR_DERA;
uint64_t CSR_DSAVE;
+#ifndef CONFIG_USER_ONLY
LoongArchTLB tlb[LOONGARCH_TLB_MAX];
AddressSpace address_space_iocsr;
@@ -310,6 +311,7 @@ typedef struct CPUArchState {
MemoryRegion iocsr_mem;
bool load_elf;
uint64_t elf_address;
+#endif
} CPULoongArchState;
/**
@@ -360,12 +362,16 @@ struct LoongArchCPUClass {
static inline int cpu_mmu_index(CPULoongArchState *env, bool ifetch)
{
+#ifdef CONFIG_USER_ONLY
+ return MMU_USER_IDX;
+#else
uint8_t pg = FIELD_EX64(env->CSR_CRMD, CSR_CRMD, PG);
if (!pg) {
return MMU_DA_IDX;
}
return FIELD_EX64(env->CSR_CRMD, CSR_CRMD, PLV);
+#endif
}
static inline void cpu_get_tb_cpu_state(CPULoongArchState *env,
@@ -21,7 +21,7 @@ int loongarch_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
} else if (n == 32) {
return gdb_get_regl(mem_buf, env->pc);
} else if (n == 33) {
- return gdb_get_regl(mem_buf, env->badaddr);
+ return gdb_get_regl(mem_buf, env->badvaddr);
}
return 0;
}
@@ -95,6 +95,7 @@ DEF_HELPER_FLAGS_2(set_rounding_mode, TCG_CALL_NO_RWG, void, env, i32)
DEF_HELPER_1(rdtime_d, i64, env)
+#ifndef CONFIG_USER_ONLY
/* CSRs helper */
DEF_HELPER_1(csrrd_pgd, i64, env)
DEF_HELPER_1(csrrd_tval, i64, env)
@@ -128,3 +129,4 @@ DEF_HELPER_4(lddir, tl, env, tl, tl, i32)
DEF_HELPER_4(ldpte, void, env, tl, tl, i32)
DEF_HELPER_1(ertn, void, env)
DEF_HELPER_1(idle, void, env)
+#endif
@@ -7,6 +7,41 @@
#include "cpu-csr.h"
+#ifdef CONFIG_USER_ONLY
+
+#define GEN_FALSE_TRANS(name) \
+static bool trans_##name(DisasContext *ctx, arg_##name * a) \
+{ \
+ return false; \
+}
+
+GEN_FALSE_TRANS(csrrd)
+GEN_FALSE_TRANS(csrwr)
+GEN_FALSE_TRANS(csrxchg)
+GEN_FALSE_TRANS(iocsrrd_b)
+GEN_FALSE_TRANS(iocsrrd_h)
+GEN_FALSE_TRANS(iocsrrd_w)
+GEN_FALSE_TRANS(iocsrrd_d)
+GEN_FALSE_TRANS(iocsrwr_b)
+GEN_FALSE_TRANS(iocsrwr_h)
+GEN_FALSE_TRANS(iocsrwr_w)
+GEN_FALSE_TRANS(iocsrwr_d)
+GEN_FALSE_TRANS(tlbsrch)
+GEN_FALSE_TRANS(tlbrd)
+GEN_FALSE_TRANS(tlbwr)
+GEN_FALSE_TRANS(tlbfill)
+GEN_FALSE_TRANS(tlbclr)
+GEN_FALSE_TRANS(tlbflush)
+GEN_FALSE_TRANS(invtlb)
+GEN_FALSE_TRANS(cacop)
+GEN_FALSE_TRANS(ldpte)
+GEN_FALSE_TRANS(lddir)
+GEN_FALSE_TRANS(ertn)
+GEN_FALSE_TRANS(dbcl)
+GEN_FALSE_TRANS(idle)
+
+#else
+
typedef void (*GenCSRRead)(TCGv dest, TCGv_ptr env);
typedef void (*GenCSRWrite)(TCGv dest, TCGv_ptr env, TCGv src);
@@ -464,3 +499,4 @@ static bool trans_idle(DisasContext *ctx, arg_idle *a)
ctx->base.is_jmp = DISAS_NORETURN;
return true;
}
+#endif
@@ -33,6 +33,7 @@ const char *loongarch_exception_name(int32_t exception);
void restore_fp_status(CPULoongArchState *env);
+#ifndef CONFIG_USER_ONLY
extern const VMStateDescription vmstate_loongarch_cpu;
void loongarch_cpu_set_irq(void *opaque, int irq, int level);
@@ -48,6 +49,7 @@ bool loongarch_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
bool probe, uintptr_t retaddr);
hwaddr loongarch_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
+#endif
int loongarch_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n);
int loongarch_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n);
@@ -49,14 +49,14 @@ target_ulong helper_bitswap(target_ulong v)
void helper_asrtle_d(CPULoongArchState *env, target_ulong rj, target_ulong rk)
{
if (rj > rk) {
- do_raise_exception(env, EXCCODE_ADEM, GETPC());
+ do_raise_exception(env, EXCCODE_BCE, 0);
}
}
void helper_asrtgt_d(CPULoongArchState *env, target_ulong rj, target_ulong rk)
{
if (rj <= rk) {
- do_raise_exception(env, EXCCODE_ADEM, GETPC());
+ do_raise_exception(env, EXCCODE_BCE, 0);
}
}
@@ -86,6 +86,9 @@ target_ulong helper_cpucfg(CPULoongArchState *env, target_ulong rj)
uint64_t helper_rdtime_d(CPULoongArchState *env)
{
+#ifdef CONFIG_USER_ONLY
+ return cpu_get_host_ticks();
+#else
uint64_t plv;
LoongArchCPU *cpu = env_archcpu(env);
@@ -95,8 +98,11 @@ uint64_t helper_rdtime_d(CPULoongArchState *env)
}
return cpu_loongarch_get_constant_timer_counter(cpu);
+#endif
}
+#ifndef CONFIG_USER_ONLY
+
void helper_ertn(CPULoongArchState *env)
{
uint64_t csr_pplv, csr_pie;
@@ -131,3 +137,4 @@ void helper_idle(CPULoongArchState *env)
cs->halted = 1;
do_raise_exception(env, EXCP_HLT, 0);
}
+#endif