summaryrefslogtreecommitdiff
path: root/target/loongarch/cpu.c
diff options
context:
space:
mode:
authorXiaojuan Yang <yangxiaojuan@loongson.cn>2022-06-06 20:43:16 +0800
committerRichard Henderson <richard.henderson@linaro.org>2022-06-06 18:09:03 +0000
commitf84a2aacf5d1679b1d1cceabb6006e02864232f3 (patch)
tree7ab99d30271e045fd93932c599aa8d6901aa54ae /target/loongarch/cpu.c
parent5b1dedfe848b61521aa5b46b81a4cc676e9e7c1b (diff)
target/loongarch: Add LoongArch IOCSR instruction
This includes: - IOCSR{RD/WR}.{B/H/W/D} Signed-off-by: Xiaojuan Yang <yangxiaojuan@loongson.cn> Signed-off-by: Song Gao <gaosong@loongson.cn> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-Id: <20220606124333.2060567-27-yangxiaojuan@loongson.cn> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to 'target/loongarch/cpu.c')
-rw-r--r--target/loongarch/cpu.c44
1 files changed, 44 insertions, 0 deletions
diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
index 5ec0ba1cfa..b846bd1a8b 100644
--- a/target/loongarch/cpu.c
+++ b/target/loongarch/cpu.c
@@ -17,6 +17,8 @@
#include "internals.h"
#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",
@@ -489,14 +491,56 @@ static void loongarch_cpu_realizefn(DeviceState *dev, Error **errp)
lacc->parent_realize(dev, errp);
}
+static void loongarch_qemu_write(void *opaque, hwaddr addr,
+ uint64_t val, unsigned size)
+{
+}
+
+static uint64_t loongarch_qemu_read(void *opaque, hwaddr addr, unsigned size)
+{
+ switch (addr) {
+ case FEATURE_REG:
+ return 1ULL << IOCSRF_MSI | 1ULL << IOCSRF_EXTIOI |
+ 1ULL << IOCSRF_CSRIPI;
+ case VENDOR_REG:
+ return 0x6e6f73676e6f6f4cULL; /* "Loongson" */
+ case CPUNAME_REG:
+ return 0x303030354133ULL; /* "3A5000" */
+ case MISC_FUNC_REG:
+ return 1ULL << IOCSRM_EXTIOI_EN;
+ }
+ return 0ULL;
+}
+
+static const MemoryRegionOps loongarch_qemu_ops = {
+ .read = loongarch_qemu_read,
+ .write = loongarch_qemu_write,
+ .endianness = DEVICE_LITTLE_ENDIAN,
+ .valid = {
+ .min_access_size = 4,
+ .max_access_size = 8,
+ },
+ .impl = {
+ .min_access_size = 8,
+ .max_access_size = 8,
+ },
+};
+
static void loongarch_cpu_init(Object *obj)
{
LoongArchCPU *cpu = LOONGARCH_CPU(obj);
+ CPULoongArchState *env = &cpu->env;
cpu_set_cpustate_pointers(cpu);
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);
+ memory_region_init_io(&env->system_iocsr, OBJECT(cpu), NULL,
+ env, "iocsr", UINT64_MAX);
+ address_space_init(&env->address_space_iocsr, &env->system_iocsr, "IOCSR");
+ 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);
}
static ObjectClass *loongarch_cpu_class_by_name(const char *cpu_model)