summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorRichard Henderson <richard.henderson@linaro.org>2022-07-05 16:30:52 +0530
committerRichard Henderson <richard.henderson@linaro.org>2022-07-05 16:30:52 +0530
commit19361471b59441cd6f2aa22d4fbee7a6e9e76586 (patch)
treed4cf184b9d138c117e58339d5c2f1cc9bc534e34
parent1437479e5ee1a49ccd84cad9e7b010fb2ee9d805 (diff)
parentbf7ce37f8f40149dfa354bdb74810c8e586a11e4 (diff)
downloadfocaccia-qemu-19361471b59441cd6f2aa22d4fbee7a6e9e76586.tar.gz
focaccia-qemu-19361471b59441cd6f2aa22d4fbee7a6e9e76586.zip
Merge tag 'pull-la-20220705' of https://gitlab.com/rth7680/qemu into staging
Loongarch patch queue:

Build fix for --enable-debug --enable-tcg-interpreter.
Build fix for ls7a_rtc.
Clear tlb on reset.
Fixes for ipi mailboxes.
Minor tweak to scripts/qemu-binfmt-conf.

# -----BEGIN PGP SIGNATURE-----
#
# iQFRBAABCgA7FiEEekgeeIaLTbaoWgXAZN846K9+IV8FAmLEGVIdHHJpY2hhcmQu
# aGVuZGVyc29uQGxpbmFyby5vcmcACgkQZN846K9+IV+SYAgAqMk+GHMT6VQANEsk
# So58d9WCPG0XSavowl9oD4w/YSSvPZe5P4KVpJbC3WAgVwEI0RRKTX3RMAeg5z0I
# zEEzFUSplSl7cO/7vQG86JRf5C7C/n4V9Q1pQUstNnTEf1s7MdgcG9597OZbV+cF
# G5KY1RTQRUr6gpChZQSrv+6j6+aQCA5ZgNwjiVnkBjsNefz1GVFKYppanwHXmMiX
# qjxVLgZb1FwOysiKpHKObLsC9pV7ub0QKrlBBk90UyidNjXxcLvV+oQrkyaVwB0m
# UM/NN/x5Ive2dqEDfq007TXUc1RpFgwDvKU8EffavBYxx8hCed3DysroiYN+v2MK
# qoYWmg==
# =+zUy
# -----END PGP SIGNATURE-----
# gpg: Signature made Tue 05 Jul 2022 04:28:26 PM +0530
# gpg:                using RSA key 7A481E78868B4DB6A85A05C064DF38E8AF7E215F
# gpg:                issuer "richard.henderson@linaro.org"
# gpg: Good signature from "Richard Henderson <richard.henderson@linaro.org>" [ultimate]

* tag 'pull-la-20220705' of https://gitlab.com/rth7680/qemu:
  hw/intc/loongarch_ipi: Fix mail send and any send function
  hw/intc/loongarch_ipi: Fix ipi device access of 64bits
  tcg/tci: Remove CONFIG_DEBUG_TCG_INTERPRETER
  scripts/qemu-binfmt-conf: Add LoongArch to qemu_get_family()
  target/loongarch: Clean up tlb when cpu reset
  hw/rtc/ls7a_rtc: Drop unused inline functions

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
-rw-r--r--hw/intc/loongarch_ipi.c92
-rw-r--r--hw/loongarch/loongson3.c5
-rw-r--r--hw/rtc/ls7a_rtc.c27
-rw-r--r--include/hw/intc/loongarch_ipi.h7
-rwxr-xr-xscripts/qemu-binfmt-conf.sh3
-rw-r--r--target/loongarch/cpu.c1
-rw-r--r--tcg/tci/tcg-target.c.inc7
-rw-r--r--tcg/tci/tcg-target.h5
8 files changed, 80 insertions, 67 deletions
diff --git a/hw/intc/loongarch_ipi.c b/hw/intc/loongarch_ipi.c
index 66bee93675..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,
@@ -150,12 +158,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 +174,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 +215,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/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);
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
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"
         ;;
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);
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