From c1ca312a6f035adad6558f44e6a3bc9ddeeed4b0 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Tue, 5 Jul 2022 13:55:43 +0530 Subject: [PATCH 1/6] hw/rtc/ls7a_rtc: Drop unused inline functions Remove toy_val_to_time_mon and toy_val_to_time_year as unused, to avoid a build failure with clang. Remove all of the other inline markers too so that this does not creep back in. Reviewed-by: Song Gao Reviewed-by: Thomas Huth Signed-off-by: Richard Henderson --- hw/rtc/ls7a_rtc.c | 27 ++++++--------------------- 1 file changed, 6 insertions(+), 21 deletions(-) diff --git a/hw/rtc/ls7a_rtc.c b/hw/rtc/ls7a_rtc.c index e8b75701e4..1f9e38a735 100644 --- a/hw/rtc/ls7a_rtc.c +++ b/hw/rtc/ls7a_rtc.c @@ -86,46 +86,31 @@ struct LS7ARtcState { }; /* switch nanoseconds time to rtc ticks */ -static inline uint64_t ls7a_rtc_ticks(void) +static uint64_t ls7a_rtc_ticks(void) { return qemu_clock_get_ns(rtc_clock) * LS7A_RTC_FREQ / NANOSECONDS_PER_SECOND; } /* switch rtc ticks to nanoseconds */ -static inline uint64_t ticks_to_ns(uint64_t ticks) +static uint64_t ticks_to_ns(uint64_t ticks) { return ticks * NANOSECONDS_PER_SECOND / LS7A_RTC_FREQ; } -static inline bool toy_enabled(LS7ARtcState *s) +static bool toy_enabled(LS7ARtcState *s) { return FIELD_EX32(s->cntrctl, RTC_CTRL, TOYEN) && FIELD_EX32(s->cntrctl, RTC_CTRL, EO); } -static inline bool rtc_enabled(LS7ARtcState *s) +static bool rtc_enabled(LS7ARtcState *s) { return FIELD_EX32(s->cntrctl, RTC_CTRL, RTCEN) && FIELD_EX32(s->cntrctl, RTC_CTRL, EO); } -/* parse toy value to struct tm */ -static inline void toy_val_to_time_mon(uint64_t toy_val, struct tm *tm) -{ - tm->tm_sec = FIELD_EX32(toy_val, TOY, SEC); - tm->tm_min = FIELD_EX32(toy_val, TOY, MIN); - tm->tm_hour = FIELD_EX32(toy_val, TOY, HOUR); - tm->tm_mday = FIELD_EX32(toy_val, TOY, DAY); - tm->tm_mon = FIELD_EX32(toy_val, TOY, MON) - 1; -} - -static inline void toy_val_to_time_year(uint64_t toy_year, struct tm *tm) -{ - tm->tm_year = toy_year; -} - /* parse struct tm to toy value */ -static inline uint64_t toy_time_to_val_mon(struct tm *tm) +static uint64_t toy_time_to_val_mon(const struct tm *tm) { uint64_t val = 0; @@ -137,7 +122,7 @@ static inline uint64_t toy_time_to_val_mon(struct tm *tm) return val; } -static inline void toymatch_val_to_time(LS7ARtcState *s, uint64_t val, struct tm *tm) +static void toymatch_val_to_time(LS7ARtcState *s, uint64_t val, struct tm *tm) { qemu_get_timedate(tm, s->offset_toy); tm->tm_sec = FIELD_EX32(val, TOY_MATCH, SEC); From 3517fb726741c109cae7995f9ea46f0cab6187d6 Mon Sep 17 00:00:00 2001 From: Song Gao Date: Tue, 5 Jul 2022 15:09:50 +0800 Subject: [PATCH 2/6] target/loongarch: Clean up tlb when cpu reset We should make sure that tlb is clean when cpu reset. Signed-off-by: Song Gao Message-Id: <20220705070950.2364243-1-gaosong@loongson.cn> Reviewed-by: Richard Henderson Signed-off-by: Richard Henderson --- target/loongarch/cpu.c | 1 + 1 file changed, 1 insertion(+) diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c index d2d4667a34..e21715592a 100644 --- a/target/loongarch/cpu.c +++ b/target/loongarch/cpu.c @@ -479,6 +479,7 @@ static void loongarch_cpu_reset(DeviceState *dev) #ifndef CONFIG_USER_ONLY env->pc = 0x1c000000; + memset(env->tlb, 0, sizeof(env->tlb)); #endif restore_fp_status(env); From f8d1ae82623fef4e7fb796efbaaa2ddc63594d09 Mon Sep 17 00:00:00 2001 From: Song Gao Date: Tue, 5 Jul 2022 14:59:42 +0800 Subject: [PATCH 3/6] scripts/qemu-binfmt-conf: Add LoongArch to qemu_get_family() qemu_get_family() needs to add LoongArch support. Signed-off-by: Song Gao Message-Id: <20220705065943.2353930-1-gaosong@loongson.cn> Reviewed-by: Richard Henderson Signed-off-by: Richard Henderson --- scripts/qemu-binfmt-conf.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/scripts/qemu-binfmt-conf.sh b/scripts/qemu-binfmt-conf.sh index 1f4e2cd19d..6ef9f118d9 100755 --- a/scripts/qemu-binfmt-conf.sh +++ b/scripts/qemu-binfmt-conf.sh @@ -171,6 +171,9 @@ qemu_get_family() { riscv*) echo "riscv" ;; + loongarch*) + echo "loongarch" + ;; *) echo "$cpu" ;; From 0df0a6655522f9a9df78aeab39a96f2d0f181c92 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Tue, 5 Jul 2022 14:03:13 +0530 Subject: [PATCH 4/6] tcg/tci: Remove CONFIG_DEBUG_TCG_INTERPRETER MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There is nothing in this environment variable that cannot be done better with -d flags. There is nothing special about TCI that warrants this hack. Moreover, it does not compile -- remove it. Reported-by: Song Gao Reviewed-by: Song Gao Reviewed-by: Alex Bennée Signed-off-by: Richard Henderson --- tcg/tci/tcg-target.c.inc | 7 ------- tcg/tci/tcg-target.h | 5 ----- 2 files changed, 12 deletions(-) diff --git a/tcg/tci/tcg-target.c.inc b/tcg/tci/tcg-target.c.inc index 98337c567a..f3d7441e06 100644 --- a/tcg/tci/tcg-target.c.inc +++ b/tcg/tci/tcg-target.c.inc @@ -823,13 +823,6 @@ static void tcg_out_nop_fill(tcg_insn_unit *p, int count) static void tcg_target_init(TCGContext *s) { -#if defined(CONFIG_DEBUG_TCG_INTERPRETER) - const char *envval = getenv("DEBUG_TCG"); - if (envval) { - qemu_set_log(strtol(envval, NULL, 0)); - } -#endif - /* The current code uses uint8_t for tcg operations. */ tcg_debug_assert(tcg_op_defs_max <= UINT8_MAX); diff --git a/tcg/tci/tcg-target.h b/tcg/tci/tcg-target.h index 033e613f24..ceb36c4f7a 100644 --- a/tcg/tci/tcg-target.h +++ b/tcg/tci/tcg-target.h @@ -53,11 +53,6 @@ # error Unknown pointer size for tci target #endif -#ifdef CONFIG_DEBUG_TCG -/* Enable debug output. */ -#define CONFIG_DEBUG_TCG_INTERPRETER -#endif - /* Optional instructions. */ #define TCG_TARGET_HAS_bswap16_i32 1 From ddf93261847df55137436abe429aae7f9d8228dd Mon Sep 17 00:00:00 2001 From: Xiaojuan Yang Date: Tue, 5 Jul 2022 14:49:00 +0800 Subject: [PATCH 5/6] hw/intc/loongarch_ipi: Fix ipi device access of 64bits In general loongarch ipi device, 32bit registers is emulated, however for anysend/mailsend device only 64bit register access is supported. So separate the ipi memory region into two regions, including 32 bits and 64 bits. Signed-off-by: Xiaojuan Yang Message-Id: <20220705064901.2353349-2-yangxiaojuan@loongson.cn> Signed-off-by: Richard Henderson --- hw/intc/loongarch_ipi.c | 38 +++++++++++++++++++++++++++------ hw/loongarch/loongson3.c | 5 ++++- include/hw/intc/loongarch_ipi.h | 7 +++--- 3 files changed, 39 insertions(+), 11 deletions(-) diff --git a/hw/intc/loongarch_ipi.c b/hw/intc/loongarch_ipi.c index 66bee93675..b8b1b9cd53 100644 --- a/hw/intc/loongarch_ipi.c +++ b/hw/intc/loongarch_ipi.c @@ -150,12 +150,6 @@ static void loongarch_ipi_writel(void *opaque, hwaddr addr, uint64_t val, case IOCSR_IPI_SEND: ipi_send(val); break; - case IOCSR_MAIL_SEND: - mail_send(val); - break; - case IOCSR_ANY_SEND: - any_send(val); - break; default: qemu_log_mask(LOG_UNIMP, "invalid write: %x", (uint32_t)addr); break; @@ -172,6 +166,32 @@ static const MemoryRegionOps loongarch_ipi_ops = { .endianness = DEVICE_LITTLE_ENDIAN, }; +/* mail send and any send only support writeq */ +static void loongarch_ipi_writeq(void *opaque, hwaddr addr, uint64_t val, + unsigned size) +{ + addr &= 0xfff; + switch (addr) { + case MAIL_SEND_OFFSET: + mail_send(val); + break; + case ANY_SEND_OFFSET: + any_send(val); + break; + default: + break; + } +} + +static const MemoryRegionOps loongarch_ipi64_ops = { + .write = loongarch_ipi_writeq, + .impl.min_access_size = 8, + .impl.max_access_size = 8, + .valid.min_access_size = 8, + .valid.max_access_size = 8, + .endianness = DEVICE_LITTLE_ENDIAN, +}; + static void loongarch_ipi_init(Object *obj) { int cpu; @@ -187,8 +207,12 @@ static void loongarch_ipi_init(Object *obj) lams = LOONGARCH_MACHINE(machine); for (cpu = 0; cpu < MAX_IPI_CORE_NUM; cpu++) { memory_region_init_io(&s->ipi_iocsr_mem[cpu], obj, &loongarch_ipi_ops, - &lams->ipi_core[cpu], "loongarch_ipi_iocsr", 0x100); + &lams->ipi_core[cpu], "loongarch_ipi_iocsr", 0x48); sysbus_init_mmio(sbd, &s->ipi_iocsr_mem[cpu]); + + memory_region_init_io(&s->ipi64_iocsr_mem[cpu], obj, &loongarch_ipi64_ops, + &lams->ipi_core[cpu], "loongarch_ipi64_iocsr", 0x118); + sysbus_init_mmio(sbd, &s->ipi64_iocsr_mem[cpu]); qdev_init_gpio_out(DEVICE(obj), &lams->ipi_core[cpu].irq, 1); } } diff --git a/hw/loongarch/loongson3.c b/hw/loongarch/loongson3.c index 403dd91e11..15fddfc4f5 100644 --- a/hw/loongarch/loongson3.c +++ b/hw/loongarch/loongson3.c @@ -230,7 +230,10 @@ static void loongarch_irq_init(LoongArchMachineState *lams) /* IPI iocsr memory region */ memory_region_add_subregion(&env->system_iocsr, SMP_IPI_MAILBOX, sysbus_mmio_get_region(SYS_BUS_DEVICE(ipi), - cpu)); + cpu * 2)); + memory_region_add_subregion(&env->system_iocsr, MAIL_SEND_ADDR, + sysbus_mmio_get_region(SYS_BUS_DEVICE(ipi), + cpu * 2 + 1)); /* extioi iocsr memory region */ memory_region_add_subregion(&env->system_iocsr, APIC_BASE, sysbus_mmio_get_region(SYS_BUS_DEVICE(extioi), diff --git a/include/hw/intc/loongarch_ipi.h b/include/hw/intc/loongarch_ipi.h index 996ed7ea93..0ee48fca55 100644 --- a/include/hw/intc/loongarch_ipi.h +++ b/include/hw/intc/loongarch_ipi.h @@ -24,8 +24,9 @@ #define IOCSR_MAIL_SEND 0x48 #define IOCSR_ANY_SEND 0x158 -/* IPI system memory address */ -#define IPI_SYSTEM_MEM 0x1fe01000 +#define MAIL_SEND_ADDR (SMP_IPI_MAILBOX + IOCSR_MAIL_SEND) +#define MAIL_SEND_OFFSET 0 +#define ANY_SEND_OFFSET (IOCSR_ANY_SEND - IOCSR_MAIL_SEND) #define MAX_IPI_CORE_NUM 4 #define MAX_IPI_MBX_NUM 4 @@ -46,7 +47,7 @@ typedef struct IPICore { struct LoongArchIPI { SysBusDevice parent_obj; MemoryRegion ipi_iocsr_mem[MAX_IPI_CORE_NUM]; - MemoryRegion ipi_system_mem[MAX_IPI_CORE_NUM]; + MemoryRegion ipi64_iocsr_mem[MAX_IPI_CORE_NUM]; }; #endif From bf7ce37f8f40149dfa354bdb74810c8e586a11e4 Mon Sep 17 00:00:00 2001 From: Xiaojuan Yang Date: Tue, 5 Jul 2022 14:49:01 +0800 Subject: [PATCH 6/6] hw/intc/loongarch_ipi: Fix mail send and any send function By the document of ipi mailsend device, byte is written only when the mask bit is 0. The original code discards mask bit and overwrite the data always, this patch fixes the issue. Signed-off-by: Xiaojuan Yang Message-Id: <20220705064901.2353349-3-yangxiaojuan@loongson.cn> Signed-off-by: Richard Henderson --- hw/intc/loongarch_ipi.c | 54 +++++++++++++++++++++++------------------ 1 file changed, 31 insertions(+), 23 deletions(-) diff --git a/hw/intc/loongarch_ipi.c b/hw/intc/loongarch_ipi.c index b8b1b9cd53..4f3c58f872 100644 --- a/hw/intc/loongarch_ipi.c +++ b/hw/intc/loongarch_ipi.c @@ -50,35 +50,45 @@ static uint64_t loongarch_ipi_readl(void *opaque, hwaddr addr, unsigned size) return ret; } -static int get_ipi_data(target_ulong val) +static void send_ipi_data(CPULoongArchState *env, target_ulong val, target_ulong addr) { - int i, mask, data; + int i, mask = 0, data = 0; - data = val >> 32; - mask = (val >> 27) & 0xf; - - for (i = 0; i < 4; i++) { - if ((mask >> i) & 1) { - data &= ~(0xff << (i * 8)); + /* + * bit 27-30 is mask for byte writing, + * if the mask is 0, we need not to do anything. + */ + if ((val >> 27) & 0xf) { + data = address_space_ldl(&env->address_space_iocsr, addr, + MEMTXATTRS_UNSPECIFIED, NULL); + for (i = 0; i < 4; i++) { + /* get mask for byte writing */ + if (val & (0x1 << (27 + i))) { + mask |= 0xff << (i * 8); + } } } - return data; + + data &= mask; + data |= (val >> 32) & ~mask; + address_space_stl(&env->address_space_iocsr, addr, + data, MEMTXATTRS_UNSPECIFIED, NULL); } static void ipi_send(uint64_t val) { int cpuid, data; CPULoongArchState *env; + CPUState *cs; + LoongArchCPU *cpu; cpuid = (val >> 16) & 0x3ff; /* IPI status vector */ data = 1 << (val & 0x1f); - qemu_mutex_lock_iothread(); - CPUState *cs = qemu_get_cpu(cpuid); - LoongArchCPU *cpu = LOONGARCH_CPU(cs); + cs = qemu_get_cpu(cpuid); + cpu = LOONGARCH_CPU(cs); env = &cpu->env; loongarch_cpu_set_irq(cpu, IRQ_IPI, 1); - qemu_mutex_unlock_iothread(); address_space_stl(&env->address_space_iocsr, 0x1008, data, MEMTXATTRS_UNSPECIFIED, NULL); @@ -86,23 +96,23 @@ static void ipi_send(uint64_t val) static void mail_send(uint64_t val) { - int cpuid, data; + int cpuid; hwaddr addr; CPULoongArchState *env; + CPUState *cs; + LoongArchCPU *cpu; cpuid = (val >> 16) & 0x3ff; addr = 0x1020 + (val & 0x1c); - CPUState *cs = qemu_get_cpu(cpuid); - LoongArchCPU *cpu = LOONGARCH_CPU(cs); + cs = qemu_get_cpu(cpuid); + cpu = LOONGARCH_CPU(cs); env = &cpu->env; - data = get_ipi_data(val); - address_space_stl(&env->address_space_iocsr, addr, - data, MEMTXATTRS_UNSPECIFIED, NULL); + send_ipi_data(env, val, addr); } static void any_send(uint64_t val) { - int cpuid, data; + int cpuid; hwaddr addr; CPULoongArchState *env; @@ -111,9 +121,7 @@ static void any_send(uint64_t val) CPUState *cs = qemu_get_cpu(cpuid); LoongArchCPU *cpu = LOONGARCH_CPU(cs); env = &cpu->env; - data = get_ipi_data(val); - address_space_stl(&env->address_space_iocsr, addr, - data, MEMTXATTRS_UNSPECIFIED, NULL); + send_ipi_data(env, val, addr); } static void loongarch_ipi_writel(void *opaque, hwaddr addr, uint64_t val,