Re: [PATCH 0/5] hw/mips/loongson3_virt: Implement IPI support

2024-05-16 Thread Jiaxun Yang



在2024年5月8日五月 下午10:41,Philippe Mathieu-Daudé写道:
> On 8/5/24 15:06, Jiaxun Yang wrote:
>> Hi all,
>> 
>> This series enabled IPI support for loongson3 virt board, loosely
>> based on my previous work[1].
>> It generalized loongarch_ipi device to share among both loongarch
>> and MIPS machines.
>
>
>> Signed-off-by: Jiaxun Yang 
>> ---
>> Jiaxun Yang (5):
>>hw/intc/loongarch_ipi: Remove pointless MAX_CPU check
>>hw/intc/loongarch_ipi: Rename as loongson_ipi
>>hw/intc/loongson_ipi: Implement IOCSR address space for MIPS
>
> So far patches 1-3 queued to hw-misc tree, thanks.

Hi Philippe,

Thanks! What's your plan with the rest of the series and earlier MIPS
CPS SMP series?

Let me know if you need help on testing etc.

Thanks
-- 
- Jiaxun



[PATCH] hw/mips/loongson3_virt: Implement node counter timer

2024-05-12 Thread Jiaxun Yang
Node counter is a timer presents on Loongson-3 chips, which runs
as fast as CPU clock. It's being mapped into a MMIO location.

Emulate this for loongson3_virt machine, in hope that kernel can
use it as a better clock source.

Hardware's behavior on 32-bit read/write is also emulated in case
legacy kernel is trying to use it with hi/lo splitted read.

Signed-off-by: Jiaxun Yang 
---
 hw/mips/loongson3_bootp.h |  1 +
 hw/mips/loongson3_virt.c  | 38 ++
 2 files changed, 35 insertions(+), 4 deletions(-)

diff --git a/hw/mips/loongson3_bootp.h b/hw/mips/loongson3_bootp.h
index 1b0dd3b59171..c6a435397d2c 100644
--- a/hw/mips/loongson3_bootp.h
+++ b/hw/mips/loongson3_bootp.h
@@ -210,6 +210,7 @@ enum {
 VIRT_PCIE_ECAM,
 VIRT_BIOS_ROM,
 VIRT_UART,
+VIRT_NODECNT,
 VIRT_LIOINTC,
 VIRT_PCIE_MMIO,
 VIRT_HIGHMEM
diff --git a/hw/mips/loongson3_virt.c b/hw/mips/loongson3_virt.c
index b10a611a98f4..b78ac8032096 100644
--- a/hw/mips/loongson3_virt.c
+++ b/hw/mips/loongson3_virt.c
@@ -74,6 +74,7 @@ const MemMapEntry virt_memmap[] = {
 [VIRT_PCIE_ECAM] =   { 0x1a00, 0x200 },
 [VIRT_BIOS_ROM] ={ 0x1fc0,  0x20 },
 [VIRT_UART] ={ 0x1fe001e0,   0x8 },
+[VIRT_NODECNT] = { 0x3ff00408,   0x8 },
 [VIRT_LIOINTC] = { 0x3ff01400,  0x64 },
 [VIRT_PCIE_MMIO] =   { 0x4000,0x4000 },
 [VIRT_HIGHMEM] = { 0x8000,   0x0 }, /* Variable */
@@ -92,6 +93,7 @@ static const MemMapEntry loader_rommap[] = {
 
 struct LoongsonMachineState {
 MachineState parent_obj;
+Clock *cpuclk;
 MemoryRegion *pio_alias;
 MemoryRegion *mmio_alias;
 MemoryRegion *ecam_alias;
@@ -145,6 +147,29 @@ static const MemoryRegionOps loongson3_pm_ops = {
 }
 };
 
+static uint64_t loongson3_nodecnt_read(void *opaque,
+hwaddr addr, unsigned size)
+{
+LoongsonMachineState *s = opaque;
+int64_t now_ns = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
+uint64_t ticks = clock_ns_to_ticks(s->cpuclk, now_ns);
+
+if (addr == 0x4) {
+return ticks >> 32;
+}
+
+return ticks;
+}
+
+static const MemoryRegionOps loongson3_nodecnt_ops = {
+.read  = loongson3_nodecnt_read,
+.endianness = DEVICE_NATIVE_ENDIAN,
+.valid.min_access_size = 4,
+.valid.max_access_size = 8,
+.impl.min_access_size = 4,
+.impl.max_access_size = 8,
+};
+
 #define DEF_LOONGSON3_FREQ (800 * 1000 * 1000)
 
 static uint64_t get_cpu_freq_hz(void)
@@ -463,7 +488,6 @@ static void mips_loongson3_virt_init(MachineState *machine)
 int i;
 long bios_size;
 MIPSCPU *cpu;
-Clock *cpuclk;
 CPUMIPSState *env;
 DeviceState *liointc;
 char *filename;
@@ -471,10 +495,12 @@ static void mips_loongson3_virt_init(MachineState 
*machine)
 const char *kernel_filename = machine->kernel_filename;
 const char *initrd_filename = machine->initrd_filename;
 ram_addr_t ram_size = machine->ram_size;
+LoongsonMachineState *ms = LOONGSON_MACHINE(machine);
 MemoryRegion *address_space_mem = get_system_memory();
 MemoryRegion *ram = g_new(MemoryRegion, 1);
 MemoryRegion *bios = g_new(MemoryRegion, 1);
 MemoryRegion *iomem = g_new(MemoryRegion, 1);
+MemoryRegion *nodecnt = g_new(MemoryRegion, 1);
 
 /* TODO: TCG will support all CPU types */
 if (!kvm_enabled()) {
@@ -520,14 +546,14 @@ static void mips_loongson3_virt_init(MachineState 
*machine)
 sysbus_create_simple("goldfish_rtc", virt_memmap[VIRT_RTC].base,
  qdev_get_gpio_in(liointc, RTC_IRQ));
 
-cpuclk = clock_new(OBJECT(machine), "cpu-refclk");
-clock_set_hz(cpuclk, DEF_LOONGSON3_FREQ);
+ms->cpuclk = clock_new(OBJECT(machine), "cpu-refclk");
+clock_set_hz(ms->cpuclk, DEF_LOONGSON3_FREQ);
 
 for (i = 0; i < machine->smp.cpus; i++) {
 int ip;
 
 /* init CPUs */
-cpu = mips_cpu_create_with_clock(machine->cpu_type, cpuclk);
+cpu = mips_cpu_create_with_clock(machine->cpu_type, ms->cpuclk);
 
 /* Init internal devices */
 cpu_mips_irq_init_cpu(cpu);
@@ -553,6 +579,8 @@ static void mips_loongson3_virt_init(MachineState *machine)
machine->ram, 0, virt_memmap[VIRT_LOWMEM].size);
 memory_region_init_io(iomem, NULL, _pm_ops,
NULL, "loongson3_pm", virt_memmap[VIRT_PM].size);
+memory_region_init_io(nodecnt, NULL, _nodecnt_ops, ms,
+  "loongson3_nodecnt", virt_memmap[VIRT_NODECNT].size);
 
 memory_region_add_subregion(address_space_mem,
   virt_memmap[VIRT_LOWMEM].base, ram);
@@ -562,6 +590,8 @@ static void mips_loongson3_virt_init(MachineState *machine)
   virt_memmap[VIRT_HIGHMEM].base, machine->ram);
 memory_

[PATCH] mips64el-softmmu: Enable MTTCG

2024-05-11 Thread Jiaxun Yang
MTTCG was disabled in a092a9554771 ("configure: disable MTTCG
for MIPS guests") due to test case instability.

I was able to reproduce this issue with in latest QEMU and look
into reason behind that.

What actually happend is kernel's CP0 timer synchronisation
mechanism assumed a consistent latency in memory access between
cores, which TCG can't guarantee. Thus there is a huge drift in
count value between cores, and in early kernel versions CP0 timer
is always used as sched_clock.

sched_clock drift back on some cores triggered RCU watchdog in
some extreme cases.

This can be resolved by setting clocksource to MIPS, which allows
clocksource to drift together with sched_clock. However this will
leed to other problems after boot.

Another option would beupdating kernel to later version, which
will use GIC as sched_clock.

In non-MTTCG build, the execution is slow enough so kernel won't
observe back drifts.

Test results:

With clocksource=MIPS
```
 ~/tmp/retry/retry.py -n 100 -c -- ./qemu-system-mips64el \
-display none -vga none -serial mon:stdio \
-machine malta -kernel ./vmlinux-4.7.0-rc1.I6400 \
-cpu I6400 -smp 8 -vga std \
-append "printk.time=0 clocksource=MIPS console=tty0 console=ttyS0 
panic=-1" \
--no-reboot

100, 0, PASS, 5.258126, 100, 100, -
Results summary:
0: 100 times (100.00%), avg time 6.508 (55.53 varience/7.45 deviation)
Ran command 100 times, 100 passes
```

With linux-next:
```
 ~/tmp/retry/retry.py -n 100 -c -- ./qemu-system-mips64el \
-display none -vga none -serial mon:stdio \
-machine malta -kernel ~/linux-next/vmlinux \
-cpu I6400 -smp 8 -vga std \
-append "printk.time=0 console=tty0 console=ttyS0 panic=-1" \
--no-reboot

100, 0, PASS, 4.507921, 100, 100, -
Results summary:
0: 100 times (100.00%), avg time 4.233 (0.04 varience/0.21 deviation)
Ran command 100 times, 100 passes
```

Signed-off-by: Jiaxun Yang 
---
I'll leave the test case alone as it's already marked as QEMU_TEST_FLAKY_TESTS
---
 configs/targets/mips64el-softmmu.mak | 1 +
 1 file changed, 1 insertion(+)

diff --git a/configs/targets/mips64el-softmmu.mak 
b/configs/targets/mips64el-softmmu.mak
index 8d9ab3ddc4b1..199b1d909a7d 100644
--- a/configs/targets/mips64el-softmmu.mak
+++ b/configs/targets/mips64el-softmmu.mak
@@ -1,3 +1,4 @@
 TARGET_ARCH=mips64
 TARGET_BASE_ARCH=mips
+TARGET_SUPPORTS_MTTCG=y
 TARGET_NEED_FDT=y

---
base-commit: 248f6f62df073a3b4158fd0093863ab885feabb5
change-id: 20240511-mips_mttcg-47a6b19074b3

Best regards,
-- 
Jiaxun Yang 




Re: [PATCH] hw/mips/loongson3_virt: Emulate suspend function

2024-05-08 Thread Jiaxun Yang



在2024年5月8日五月 下午5:48,Philippe Mathieu-Daudé写道:
> On 8/5/24 17:35, Philippe Mathieu-Daudé wrote:
>> On 8/5/24 11:31, Jiaxun Yang wrote:
>>> Suspend function is emulated as what hardware actually do.
>>> Doorbell register fields are updates to include suspend value,
>>> suspend vector is encoded in firmware blob and fw_cfg is updated
>>> to include S3 bits as what x86 did.
>>>
>>> Signed-off-by: Jiaxun Yang 
>>> ---
>>>   hw/mips/loongson3_bootp.c |  1 +
>>>   hw/mips/loongson3_virt.c  | 19 +++
>>>   2 files changed, 20 insertions(+)
>> 
>> Thanks, patch queued.
>
> Fixed:
>
> ERROR: use g_memdup2() instead of unsafe g_memdup()
> #76: FILE: hw/mips/loongson3_virt.c:293:
> +fw_cfg_add_file(fw_cfg, "etc/system-states", g_memdup(suspend, 6), 6);

Thanks, I omitted this one as it is copied from hw/acpi/core.c

Should we fix that one as well?

-- 
- Jiaxun



[PATCH 0/5] hw/mips/loongson3_virt: Implement IPI support

2024-05-08 Thread Jiaxun Yang
Hi all,

This series enabled IPI support for loongson3 virt board, loosely
based on my previous work[1].
It generalized loongarch_ipi device to share among both loongarch
and MIPS machines. 

Thanks

[1]: https://lore.kernel.org/all/20230521102307.87081-1-jiaxun.y...@flygoat.com/

To: qemu-devel@nongnu.org
Cc: Song Gao 

Signed-off-by: Jiaxun Yang 
---
Jiaxun Yang (5):
  hw/intc/loongarch_ipi: Remove pointless MAX_CPU check
  hw/intc/loongarch_ipi: Rename as loongson_ipi
  hw/intc/loongson_ipi: Implement IOCSR address space for MIPS
  hw/intc/loongson_ipi: Provide per core MMIO address spaces
  hw/mips/loongson3_virt: Wire up loongson_ipi device

 MAINTAINERS|   4 +
 hw/intc/Kconfig|   2 +-
 hw/intc/loongarch_ipi.c|  19 +-
 hw/intc/loongson_ipi.c | 411 +
 hw/intc/meson.build|   2 +-
 hw/intc/trace-events   |   8 +-
 hw/loongarch/Kconfig   |   2 +-
 hw/loongarch/virt.c|   4 +-
 hw/mips/Kconfig|   1 +
 hw/mips/loongson3_bootp.c  |   2 -
 hw/mips/loongson3_bootp.h  |   3 +
 hw/mips/loongson3_virt.c   |  39 +-
 .../hw/intc/{loongarch_ipi.h => loongson_ipi.h}|  14 +-
 include/hw/loongarch/virt.h|   2 +-
 14 files changed, 475 insertions(+), 38 deletions(-)
---
base-commit: 248f6f62df073a3b4158fd0093863ab885feabb5
change-id: 20240508-loongson3-ipi-65e99b47c400

Best regards,
-- 
Jiaxun Yang 




[PATCH 5/5] hw/mips/loongson3_virt: Wire up loongson_ipi device

2024-05-08 Thread Jiaxun Yang
Wire up loongson_ipi device for loongson3_virt machine, so we
can have SMP support for TCG backend as well.

Signed-off-by: Jiaxun Yang 
---
 hw/mips/Kconfig   |  1 +
 hw/mips/loongson3_bootp.c |  2 --
 hw/mips/loongson3_bootp.h |  3 +++
 hw/mips/loongson3_virt.c  | 39 +--
 4 files changed, 41 insertions(+), 4 deletions(-)

diff --git a/hw/mips/Kconfig b/hw/mips/Kconfig
index 5c83ef49cf6f..6f09fedc946e 100644
--- a/hw/mips/Kconfig
+++ b/hw/mips/Kconfig
@@ -57,6 +57,7 @@ config LOONGSON3V
 imply USB_OHCI_PCI
 select SERIAL
 select GOLDFISH_RTC
+select LOONGSON_IPI
 select LOONGSON_LIOINTC
 select PCI_EXPRESS_GENERIC_BRIDGE
 select MSI_NONBROKEN
diff --git a/hw/mips/loongson3_bootp.c b/hw/mips/loongson3_bootp.c
index f99af229327a..474d3556b2e5 100644
--- a/hw/mips/loongson3_bootp.c
+++ b/hw/mips/loongson3_bootp.c
@@ -25,8 +25,6 @@
 #include "hw/boards.h"
 #include "hw/mips/loongson3_bootp.h"
 
-#define LOONGSON3_CORE_PER_NODE 4
-
 static void init_cpu_info(void *g_cpuinfo, uint64_t cpu_freq)
 {
 struct efi_cpuinfo_loongson *c = g_cpuinfo;
diff --git a/hw/mips/loongson3_bootp.h b/hw/mips/loongson3_bootp.h
index 1b0dd3b59171..9091265df7fc 100644
--- a/hw/mips/loongson3_bootp.h
+++ b/hw/mips/loongson3_bootp.h
@@ -200,6 +200,8 @@ struct boot_params {
 struct efi_reset_system_t reset_system;
 };
 
+#define LOONGSON3_CORE_PER_NODE 4
+
 /* Overall MMIO & Memory layout */
 enum {
 VIRT_LOWMEM,
@@ -211,6 +213,7 @@ enum {
 VIRT_BIOS_ROM,
 VIRT_UART,
 VIRT_LIOINTC,
+VIRT_IPI,
 VIRT_PCIE_MMIO,
 VIRT_HIGHMEM
 };
diff --git a/hw/mips/loongson3_virt.c b/hw/mips/loongson3_virt.c
index b10a611a98f4..1052fb7d6747 100644
--- a/hw/mips/loongson3_virt.c
+++ b/hw/mips/loongson3_virt.c
@@ -36,6 +36,7 @@
 #include "hw/mips/loongson3_bootp.h"
 #include "hw/misc/unimp.h"
 #include "hw/intc/i8259.h"
+#include "hw/intc/loongson_ipi.h"
 #include "hw/loader.h"
 #include "hw/isa/superio.h"
 #include "hw/pci/msi.h"
@@ -74,6 +75,7 @@ const MemMapEntry virt_memmap[] = {
 [VIRT_PCIE_ECAM] =   { 0x1a00, 0x200 },
 [VIRT_BIOS_ROM] ={ 0x1fc0,  0x20 },
 [VIRT_UART] ={ 0x1fe001e0,   0x8 },
+[VIRT_IPI] = { 0x3ff01000, 0x400 },
 [VIRT_LIOINTC] = { 0x3ff01400,  0x64 },
 [VIRT_PCIE_MMIO] =   { 0x4000,0x4000 },
 [VIRT_HIGHMEM] = { 0x8000,   0x0 }, /* Variable */
@@ -466,6 +468,7 @@ static void mips_loongson3_virt_init(MachineState *machine)
 Clock *cpuclk;
 CPUMIPSState *env;
 DeviceState *liointc;
+DeviceState *ipi = NULL;
 char *filename;
 const char *kernel_cmdline = machine->kernel_cmdline;
 const char *kernel_filename = machine->kernel_filename;
@@ -475,6 +478,7 @@ static void mips_loongson3_virt_init(MachineState *machine)
 MemoryRegion *ram = g_new(MemoryRegion, 1);
 MemoryRegion *bios = g_new(MemoryRegion, 1);
 MemoryRegion *iomem = g_new(MemoryRegion, 1);
+MemoryRegion *iocsr = g_new(MemoryRegion, 1);
 
 /* TODO: TCG will support all CPU types */
 if (!kvm_enabled()) {
@@ -508,6 +512,19 @@ static void mips_loongson3_virt_init(MachineState *machine)
 create_unimplemented_device("mmio fallback 0", 0x1000, 256 * MiB);
 create_unimplemented_device("mmio fallback 1", 0x3000, 256 * MiB);
 
+memory_region_init(iocsr, OBJECT(machine), "loongson3.iocsr", UINT32_MAX);
+
+/* IPI controller is in kernel for KVM */
+if (!kvm_enabled()) {
+ipi = qdev_new(TYPE_LOONGSON_IPI);
+qdev_prop_set_uint32(ipi, "num-cpu", machine->smp.cpus);
+sysbus_realize_and_unref(SYS_BUS_DEVICE(ipi), _fatal);
+memory_region_add_subregion(iocsr, SMP_IPI_MAILBOX,
+sysbus_mmio_get_region(SYS_BUS_DEVICE(ipi), 0));
+memory_region_add_subregion(iocsr, MAIL_SEND_ADDR,
+sysbus_mmio_get_region(SYS_BUS_DEVICE(ipi), 1));
+}
+
 liointc = qdev_new("loongson.liointc");
 sysbus_realize_and_unref(SYS_BUS_DEVICE(liointc), _fatal);
 
@@ -524,6 +541,8 @@ static void mips_loongson3_virt_init(MachineState *machine)
 clock_set_hz(cpuclk, DEF_LOONGSON3_FREQ);
 
 for (i = 0; i < machine->smp.cpus; i++) {
+int node = i / LOONGSON3_CORE_PER_NODE;
+int core = i % LOONGSON3_CORE_PER_NODE;
 int ip;
 
 /* init CPUs */
@@ -534,12 +553,28 @@ static void mips_loongson3_virt_init(MachineState 
*machine)
 cpu_mips_clock_init(cpu);
 qemu_register_reset(main_cpu_reset, cpu);
 
-if (i >= 4) {
+if (ipi) {
+hwaddr base = ((hwaddr)node << 44) + virt_memmap[VIRT_IPI].base;
+base += core * 0x100;
+qdev_connect_gpio_out(ipi, i, cpu->env.irq[6]);
+sysbu

[PATCH 4/5] hw/intc/loongson_ipi: Provide per core MMIO address spaces

2024-05-08 Thread Jiaxun Yang
The real IPI hardware have dedicated MMIO registers mapped into
memory address space for every core. This is not used by LoongArch
guest software but it is essential for CPU without IOCSR such as
Loongson-3A1000.

Implement it with existing infrastructure.

Signed-off-by: Jiaxun Yang 
---
 hw/intc/loongson_ipi.c | 81 --
 include/hw/intc/loongson_ipi.h |  2 ++
 2 files changed, 64 insertions(+), 19 deletions(-)

diff --git a/hw/intc/loongson_ipi.c b/hw/intc/loongson_ipi.c
index 93cc50a37a11..c8a25b4eb8e2 100644
--- a/hw/intc/loongson_ipi.c
+++ b/hw/intc/loongson_ipi.c
@@ -23,16 +23,14 @@
 #endif
 #include "trace.h"
 
-static MemTxResult loongson_ipi_readl(void *opaque, hwaddr addr,
+static MemTxResult loongson_ipi_core_readl(void *opaque, hwaddr addr,
uint64_t *data,
unsigned size, MemTxAttrs attrs)
 {
-IPICore *s;
-LoongsonIPI *ipi = opaque;
+IPICore *s = opaque;
 uint64_t ret = 0;
 int index = 0;
 
-s = >cpu[attrs.requester_id];
 addr &= 0xff;
 switch (addr) {
 case CORE_STATUS_OFF:
@@ -61,6 +59,21 @@ static MemTxResult loongson_ipi_readl(void *opaque, hwaddr 
addr,
 return MEMTX_OK;
 }
 
+static MemTxResult loongson_ipi_iocsr_readl(void *opaque, hwaddr addr,
+   uint64_t *data,
+   unsigned size, MemTxAttrs attrs)
+{
+LoongsonIPI *ipi = opaque;
+IPICore *s;
+
+if (attrs.requester_id >= ipi->num_cpu) {
+return MEMTX_DECODE_ERROR;
+}
+
+s = >cpu[attrs.requester_id];
+return loongson_ipi_core_readl(s, addr, data, size, attrs);
+}
+
 static AddressSpace *get_cpu_iocsr_as(CPUState *cpu)
 {
 #ifdef TARGET_LOONGARCH64
@@ -174,17 +187,17 @@ static MemTxResult any_send(uint64_t val, MemTxAttrs 
attrs)
 return send_ipi_data(cs, val, addr, attrs);
 }
 
-static MemTxResult loongson_ipi_writel(void *opaque, hwaddr addr, uint64_t val,
-unsigned size, MemTxAttrs attrs)
+static MemTxResult loongson_ipi_core_writel(void *opaque, hwaddr addr,
+uint64_t val, unsigned size,
+MemTxAttrs attrs)
 {
-LoongsonIPI *ipi = opaque;
-IPICore *s;
+IPICore *s = opaque;
+LoongsonIPI *ipi = s->ipi;
 int index = 0;
 uint32_t cpuid;
 uint8_t vector;
 CPUState *cs;
 
-s = >cpu[attrs.requester_id];
 addr &= 0xff;
 trace_loongson_ipi_write(size, (uint64_t)addr, val);
 switch (addr) {
@@ -215,13 +228,11 @@ static MemTxResult loongson_ipi_writel(void *opaque, 
hwaddr addr, uint64_t val,
 /* IPI status vector */
 vector = extract8(val, 0, 5);
 cs = ipi_getcpu(cpuid);
-if (cs == NULL) {
+if (cs == NULL || cs->cpu_index >= ipi->num_cpu) {
 return MEMTX_DECODE_ERROR;
 }
-
-/* override requester_id */
-attrs.requester_id = cs->cpu_index;
-loongson_ipi_writel(ipi, CORE_SET_OFF, BIT(vector), 4, attrs);
+loongson_ipi_core_writel(>cpu[cs->cpu_index], CORE_SET_OFF,
+ BIT(vector), 4, attrs);
 break;
 default:
 qemu_log_mask(LOG_UNIMP, "invalid write: %x", (uint32_t)addr);
@@ -231,9 +242,34 @@ static MemTxResult loongson_ipi_writel(void *opaque, 
hwaddr addr, uint64_t val,
 return MEMTX_OK;
 }
 
-static const MemoryRegionOps loongson_ipi_ops = {
-.read_with_attrs = loongson_ipi_readl,
-.write_with_attrs = loongson_ipi_writel,
+static MemTxResult loongson_ipi_iocsr_writel(void *opaque, hwaddr addr,
+uint64_t val, unsigned size,
+MemTxAttrs attrs)
+{
+LoongsonIPI *ipi = opaque;
+IPICore *s;
+
+if (attrs.requester_id >= ipi->num_cpu) {
+return MEMTX_DECODE_ERROR;
+}
+
+s = >cpu[attrs.requester_id];
+return loongson_ipi_core_writel(s, addr, val, size, attrs);
+}
+
+static const MemoryRegionOps loongson_ipi_core_ops = {
+.read_with_attrs = loongson_ipi_core_readl,
+.write_with_attrs = loongson_ipi_core_writel,
+.impl.min_access_size = 4,
+.impl.max_access_size = 4,
+.valid.min_access_size = 4,
+.valid.max_access_size = 8,
+.endianness = DEVICE_LITTLE_ENDIAN,
+};
+
+static const MemoryRegionOps loongson_ipi_iocsr_ops = {
+.read_with_attrs = loongson_ipi_iocsr_readl,
+.write_with_attrs = loongson_ipi_iocsr_writel,
 .impl.min_access_size = 4,
 .impl.max_access_size = 4,
 .valid.min_access_size = 4,
@@ -282,7 +318,7 @@ static void loongson_ipi_realize(DeviceState *dev, Error 
**errp)
 return;
 }
 
-memory_region_init_io(>ipi_iocsr_mem, OBJECT(dev), _ipi_ops,
+memory_region_init_io(>ipi_iocsr_mem, OBJECT(

[PATCH 1/5] hw/intc/loongarch_ipi: Remove pointless MAX_CPU check

2024-05-08 Thread Jiaxun Yang
Since cpuid will be checked by ipi_getcpu anyway, there is
no point to enforce MAX_CPU here.

This also saved us from including loongarch board header.

Signed-off-by: Jiaxun Yang 
---
 hw/intc/loongarch_ipi.c | 19 ++-
 hw/intc/trace-events|  2 --
 2 files changed, 2 insertions(+), 19 deletions(-)

diff --git a/hw/intc/loongarch_ipi.c b/hw/intc/loongarch_ipi.c
index a184112b0923..44b3b9c138d6 100644
--- a/hw/intc/loongarch_ipi.c
+++ b/hw/intc/loongarch_ipi.c
@@ -6,6 +6,7 @@
  */
 
 #include "qemu/osdep.h"
+#include "hw/boards.h"
 #include "hw/sysbus.h"
 #include "hw/intc/loongarch_ipi.h"
 #include "hw/irq.h"
@@ -13,9 +14,8 @@
 #include "qapi/error.h"
 #include "qemu/log.h"
 #include "exec/address-spaces.h"
-#include "hw/loongarch/virt.h"
 #include "migration/vmstate.h"
-#include "target/loongarch/internals.h"
+#include "target/loongarch/cpu.h"
 #include "trace.h"
 
 static MemTxResult loongarch_ipi_readl(void *opaque, hwaddr addr,
@@ -122,11 +122,6 @@ static MemTxResult mail_send(uint64_t val, MemTxAttrs 
attrs)
 CPUState *cs;
 
 cpuid = extract32(val, 16, 10);
-if (cpuid >= LOONGARCH_MAX_CPUS) {
-trace_loongarch_ipi_unsupported_cpuid("IOCSR_MAIL_SEND", cpuid);
-return MEMTX_DECODE_ERROR;
-}
-
 cs = ipi_getcpu(cpuid);
 if (cs == NULL) {
 return MEMTX_DECODE_ERROR;
@@ -146,11 +141,6 @@ static MemTxResult any_send(uint64_t val, MemTxAttrs attrs)
 CPUState *cs;
 
 cpuid = extract32(val, 16, 10);
-if (cpuid >= LOONGARCH_MAX_CPUS) {
-trace_loongarch_ipi_unsupported_cpuid("IOCSR_ANY_SEND", cpuid);
-return MEMTX_DECODE_ERROR;
-}
-
 cs = ipi_getcpu(cpuid);
 if (cs == NULL) {
 return MEMTX_DECODE_ERROR;
@@ -201,11 +191,6 @@ static MemTxResult loongarch_ipi_writel(void *opaque, 
hwaddr addr, uint64_t val,
 break;
 case IOCSR_IPI_SEND:
 cpuid = extract32(val, 16, 10);
-if (cpuid >= LOONGARCH_MAX_CPUS) {
-trace_loongarch_ipi_unsupported_cpuid("IOCSR_IPI_SEND", cpuid);
-return MEMTX_DECODE_ERROR;
-}
-
 /* IPI status vector */
 vector = extract8(val, 0, 5);
 cs = ipi_getcpu(cpuid);
diff --git a/hw/intc/trace-events b/hw/intc/trace-events
index 47340b5bc138..a979784f9bee 100644
--- a/hw/intc/trace-events
+++ b/hw/intc/trace-events
@@ -294,8 +294,6 @@ sh_intc_set(int id, int enable) "setting interrupt group %d 
to %d"
 # loongarch_ipi.c
 loongarch_ipi_read(unsigned size, uint64_t addr, uint64_t val) "size: %u addr: 
0x%"PRIx64 "val: 0x%"PRIx64
 loongarch_ipi_write(unsigned size, uint64_t addr, uint64_t val) "size: %u 
addr: 0x%"PRIx64 "val: 0x%"PRIx64
-loongarch_ipi_unsupported_cpuid(const char *s, uint32_t cpuid) "%s unsupported 
cpuid 0x%" PRIx32
-
 # loongarch_pch_pic.c
 loongarch_pch_pic_irq_handler(int irq, int level) "irq %d level %d"
 loongarch_pch_pic_low_readw(unsigned size, uint64_t addr, uint64_t val) "size: 
%u addr: 0x%"PRIx64 "val: 0x%" PRIx64

-- 
2.34.1




[PATCH 2/5] hw/intc/loongarch_ipi: Rename as loongson_ipi

2024-05-08 Thread Jiaxun Yang
This device will be shared among LoongArch and MIPS
based Loongson machine, rename it as loongson_ipi
to reflect this nature.

Signed-off-by: Jiaxun Yang 
---
 MAINTAINERS|   4 +
 hw/intc/Kconfig|   2 +-
 hw/intc/loongson_ipi.c | 347 +
 hw/intc/meson.build|   2 +-
 hw/intc/trace-events   |   6 +-
 hw/loongarch/Kconfig   |   2 +-
 hw/loongarch/virt.c|   4 +-
 .../hw/intc/{loongarch_ipi.h => loongson_ipi.h}|  12 +-
 include/hw/loongarch/virt.h|   2 +-
 9 files changed, 366 insertions(+), 15 deletions(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index 2f08cc528eb6..290dc3227baf 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1241,7 +1241,9 @@ F: configs/devices/loongarch64-softmmu/default.mak
 F: hw/loongarch/
 F: include/hw/loongarch/virt.h
 F: include/hw/intc/loongarch_*.h
+F: include/hw/intc/loongson_ipi.h
 F: hw/intc/loongarch_*.c
+F: hw/intc/loongson_ipi.c
 F: include/hw/pci-host/ls7a.h
 F: hw/rtc/ls7a_rtc.c
 F: gdb-xml/loongarch*.xml
@@ -1375,10 +1377,12 @@ Loongson-3 virtual platforms
 M: Huacai Chen 
 R: Jiaxun Yang 
 S: Maintained
+F: hw/intc/loongson_ipi.c
 F: hw/intc/loongson_liointc.c
 F: hw/mips/loongson3_bootp.c
 F: hw/mips/loongson3_bootp.h
 F: hw/mips/loongson3_virt.c
+F: include/hw/intc/loongson_ipi.h
 F: include/hw/intc/loongson_liointc.h
 F: tests/avocado/machine_mips_loongson3v.py
 
diff --git a/hw/intc/Kconfig b/hw/intc/Kconfig
index ad59abebaa1d..58b6d3a71003 100644
--- a/hw/intc/Kconfig
+++ b/hw/intc/Kconfig
@@ -87,7 +87,7 @@ config GOLDFISH_PIC
 config M68K_IRQC
 bool
 
-config LOONGARCH_IPI
+config LOONGSON_IPI
 bool
 
 config LOONGARCH_PCH_PIC
diff --git a/hw/intc/loongson_ipi.c b/hw/intc/loongson_ipi.c
new file mode 100644
index ..8c888da3b27c
--- /dev/null
+++ b/hw/intc/loongson_ipi.c
@@ -0,0 +1,347 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Loongson ipi interrupt support
+ *
+ * Copyright (C) 2021 Loongson Technology Corporation Limited
+ */
+
+#include "qemu/osdep.h"
+#include "hw/boards.h"
+#include "hw/sysbus.h"
+#include "hw/intc/loongson_ipi.h"
+#include "hw/irq.h"
+#include "hw/qdev-properties.h"
+#include "qapi/error.h"
+#include "qemu/log.h"
+#include "exec/address-spaces.h"
+#include "migration/vmstate.h"
+#include "target/loongarch/cpu.h"
+#include "trace.h"
+
+static MemTxResult loongson_ipi_readl(void *opaque, hwaddr addr,
+   uint64_t *data,
+   unsigned size, MemTxAttrs attrs)
+{
+IPICore *s;
+LoongsonIPI *ipi = opaque;
+uint64_t ret = 0;
+int index = 0;
+
+s = >cpu[attrs.requester_id];
+addr &= 0xff;
+switch (addr) {
+case CORE_STATUS_OFF:
+ret = s->status;
+break;
+case CORE_EN_OFF:
+ret = s->en;
+break;
+case CORE_SET_OFF:
+ret = 0;
+break;
+case CORE_CLEAR_OFF:
+ret = 0;
+break;
+case CORE_BUF_20 ... CORE_BUF_38 + 4:
+index = (addr - CORE_BUF_20) >> 2;
+ret = s->buf[index];
+break;
+default:
+qemu_log_mask(LOG_UNIMP, "invalid read: %x", (uint32_t)addr);
+break;
+}
+
+trace_loongson_ipi_read(size, (uint64_t)addr, ret);
+*data = ret;
+return MEMTX_OK;
+}
+
+static void send_ipi_data(CPULoongArchState *env, uint64_t val, hwaddr addr,
+  MemTxAttrs attrs)
+{
+int i, mask = 0, data = 0;
+
+/*
+ * 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,
+ attrs, NULL);
+for (i = 0; i < 4; i++) {
+/* get mask for byte writing */
+if (val & (0x1 << (27 + i))) {
+mask |= 0xff << (i * 8);
+}
+}
+}
+
+data &= mask;
+data |= (val >> 32) & ~mask;
+address_space_stl(env->address_space_iocsr, addr,
+  data, attrs, NULL);
+}
+
+static int archid_cmp(const void *a, const void *b)
+{
+   CPUArchId *archid_a = (CPUArchId *)a;
+   CPUArchId *archid_b = (CPUArchId *)b;
+
+   return archid_a->arch_id - archid_b->arch_id;
+}
+
+static CPUArchId *find_cpu_by_archid(MachineState *ms, uint32_t id)
+{
+CPUArchId apic_id, *found_cpu;
+
+apic_id.arch_id = id;
+found_cpu = bsearch(_id, ms->possible_cpus->cpus,
+ms->possible_cpus->len, sizeof(*ms->possible_cpus->cpus),
+archid_cmp)

[PATCH 3/5] hw/intc/loongson_ipi: Implement IOCSR address space for MIPS

2024-05-08 Thread Jiaxun Yang
Implement IOCSR address space get functions for MIPS/Loongson CPUs.

For MIPS/Loongson without IOCSR (i.e. Loongson-3A1000), get_cpu_iocsr_as
will return as null, and send_ipi_data will fail with MEMTX_DECODE_ERROR,
which matches expected behavior on hardware.

Signed-off-by: Jiaxun Yang 
---
I understand that there was a review comment stating that I shouldn't
use TARGET_* macros in device drivers. But I still think this is the
best way to handle architectural difference. There are many TARGET_*
usages in hw/virtio for similiar purpose.
---
 hw/intc/loongson_ipi.c | 39 ++-
 1 file changed, 30 insertions(+), 9 deletions(-)

diff --git a/hw/intc/loongson_ipi.c b/hw/intc/loongson_ipi.c
index 8c888da3b27c..93cc50a37a11 100644
--- a/hw/intc/loongson_ipi.c
+++ b/hw/intc/loongson_ipi.c
@@ -15,7 +15,12 @@
 #include "qemu/log.h"
 #include "exec/address-spaces.h"
 #include "migration/vmstate.h"
+#ifdef TARGET_LOONGARCH64
 #include "target/loongarch/cpu.h"
+#endif
+#ifdef TARGET_MIPS
+#include "target/mips/cpu.h"
+#endif
 #include "trace.h"
 
 static MemTxResult loongson_ipi_readl(void *opaque, hwaddr addr,
@@ -56,18 +61,35 @@ static MemTxResult loongson_ipi_readl(void *opaque, hwaddr 
addr,
 return MEMTX_OK;
 }
 
-static void send_ipi_data(CPULoongArchState *env, uint64_t val, hwaddr addr,
+static AddressSpace *get_cpu_iocsr_as(CPUState *cpu)
+{
+#ifdef TARGET_LOONGARCH64
+return LOONGARCH_CPU(cpu)->env.address_space_iocsr;
+#endif
+#ifdef TARGET_MIPS
+if (ase_lcsr_available(_CPU(cpu)->env)) {
+return _CPU(cpu)->env.iocsr.as;
+}
+#endif
+return NULL;
+}
+
+static MemTxResult send_ipi_data(CPUState *cpu, uint64_t val, hwaddr addr,
   MemTxAttrs attrs)
 {
 int i, mask = 0, data = 0;
+AddressSpace *iocsr_as = get_cpu_iocsr_as(cpu);
+
+if (!iocsr_as) {
+return MEMTX_DECODE_ERROR;
+}
 
 /*
  * 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,
- attrs, NULL);
+data = address_space_ldl(iocsr_as, addr, attrs, NULL);
 for (i = 0; i < 4; i++) {
 /* get mask for byte writing */
 if (val & (0x1 << (27 + i))) {
@@ -78,8 +100,9 @@ static void send_ipi_data(CPULoongArchState *env, uint64_t 
val, hwaddr addr,
 
 data &= mask;
 data |= (val >> 32) & ~mask;
-address_space_stl(env->address_space_iocsr, addr,
-  data, attrs, NULL);
+address_space_stl(iocsr_as, addr, data, attrs, NULL);
+
+return MEMTX_OK;
 }
 
 static int archid_cmp(const void *a, const void *b)
@@ -130,8 +153,7 @@ static MemTxResult mail_send(uint64_t val, MemTxAttrs attrs)
 /* override requester_id */
 addr = SMP_IPI_MAILBOX + CORE_BUF_20 + (val & 0x1c);
 attrs.requester_id = cs->cpu_index;
-send_ipi_data(_CPU(cs)->env, val, addr, attrs);
-return MEMTX_OK;
+return send_ipi_data(cs, val, addr, attrs);
 }
 
 static MemTxResult any_send(uint64_t val, MemTxAttrs attrs)
@@ -149,8 +171,7 @@ static MemTxResult any_send(uint64_t val, MemTxAttrs attrs)
 /* override requester_id */
 addr = val & 0x;
 attrs.requester_id = cs->cpu_index;
-send_ipi_data(_CPU(cs)->env, val, addr, attrs);
-return MEMTX_OK;
+return send_ipi_data(cs, val, addr, attrs);
 }
 
 static MemTxResult loongson_ipi_writel(void *opaque, hwaddr addr, uint64_t val,

-- 
2.34.1




[PATCH] hw/mips/loongson3_virt: Emulate suspend function

2024-05-08 Thread Jiaxun Yang
Suspend function is emulated as what hardware actually do.
Doorbell register fields are updates to include suspend value,
suspend vector is encoded in firmware blob and fw_cfg is updated
to include S3 bits as what x86 did.

Signed-off-by: Jiaxun Yang 
---
 hw/mips/loongson3_bootp.c |  1 +
 hw/mips/loongson3_virt.c  | 19 +++
 2 files changed, 20 insertions(+)

diff --git a/hw/mips/loongson3_bootp.c b/hw/mips/loongson3_bootp.c
index f99af229327a..03a10b63c1b4 100644
--- a/hw/mips/loongson3_bootp.c
+++ b/hw/mips/loongson3_bootp.c
@@ -148,4 +148,5 @@ void init_reset_system(struct efi_reset_system_t *reset)
 reset->Shutdown = cpu_to_le64(0xbfc000a8);
 reset->ResetCold = cpu_to_le64(0xbfc00080);
 reset->ResetWarm = cpu_to_le64(0xbfc00080);
+reset->DoSuspend = cpu_to_le64(0xbfc000d0);
 }
diff --git a/hw/mips/loongson3_virt.c b/hw/mips/loongson3_virt.c
index 33eae01eca2b..f06518ad8f54 100644
--- a/hw/mips/loongson3_virt.c
+++ b/hw/mips/loongson3_virt.c
@@ -127,6 +127,9 @@ static void loongson3_pm_write(void *opaque, hwaddr addr,
 case 0x00:
 qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
 return;
+case 0x01:
+qemu_system_suspend_request();
+return;
 case 0xff:
 qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
 return;
@@ -250,6 +253,17 @@ static void init_boot_rom(void)
 0x240D00FF,   /* li  t1, 0xff 
*/
 0xA18D,   /* sb  t1, (t0) 
*/
 0x1000,   /* 1:  b   1b   
*/
+0x,   /* nop  
*/
+  /* Suspend  
*/
+0x3C0C9000,   /* dli t0, 0x900010080010   
*/
+0x358C,
+0x000C6438,
+0x358C1008,
+0x000C6438,
+0x358C0010,
+0x240D0001,   /* li  t1, 0x01 
*/
+0xA18D,   /* sb  t1, (t0) 
*/
+0x03e8,   /* jr  ra   
*/
 0x/* nop  
*/
 };
 
@@ -274,6 +288,10 @@ static void fw_conf_init(unsigned long ram_size)
 fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size);
 fw_cfg_add_i32(fw_cfg, FW_CFG_MACHINE_VERSION, 1);
 fw_cfg_add_i64(fw_cfg, FW_CFG_CPU_FREQ, get_cpu_freq_hz());
+
+uint8_t suspend[6] = {128, 0, 0, 129, 128, 128};
+fw_cfg_add_file(fw_cfg, "etc/system-states", g_memdup(suspend, 6), 6);
+
 qemu_register_boot_set(fw_cfg_boot_set, fw_cfg);
 }
 
@@ -551,6 +569,7 @@ static void mips_loongson3_virt_init(MachineState *machine)
machine->ram, 0, virt_memmap[VIRT_LOWMEM].size);
 memory_region_init_io(iomem, NULL, _pm_ops,
NULL, "loongson3_pm", virt_memmap[VIRT_PM].size);
+qemu_register_wakeup_support();
 
 memory_region_add_subregion(address_space_mem,
   virt_memmap[VIRT_LOWMEM].base, ram);

---
base-commit: d762bf97931b58839316b68a570eecc6143c9e3e
change-id: 20240508-loongson3v-suspend-cdd33a169eab

Best regards,
-- 
Jiaxun Yang 




[PATCH 5/5] hw/mips/boston: Implement multi core support

2024-05-06 Thread Jiaxun Yang
Implement multiple physical core support by passing topology
to CPS subsystem and generate cpu-map fdt node to decribe
new topology.

Signed-off-by: Jiaxun Yang 
---
 hw/mips/boston.c | 37 -
 1 file changed, 36 insertions(+), 1 deletion(-)

diff --git a/hw/mips/boston.c b/hw/mips/boston.c
index 1b44fb354c..4ed7d366fe 100644
--- a/hw/mips/boston.c
+++ b/hw/mips/boston.c
@@ -542,7 +542,10 @@ static const void *create_fdt(BostonState *s,
 qemu_fdt_setprop_cell(fdt, "/cpus", "#size-cells", 0x0);
 qemu_fdt_setprop_cell(fdt, "/cpus", "#address-cells", 0x1);
 
+qemu_fdt_add_subnode(fdt, "/cpus/cpu-map");
 for (cpu = 0; cpu < ms->smp.cpus; cpu++) {
+char *map_path;
+
 name = g_strdup_printf("/cpus/cpu@%d", cpu);
 qemu_fdt_add_subnode(fdt, name);
 qemu_fdt_setprop_string(fdt, name, "compatible", "img,mips");
@@ -550,6 +553,27 @@ static const void *create_fdt(BostonState *s,
 qemu_fdt_setprop_cell(fdt, name, "reg", cpu);
 qemu_fdt_setprop_string(fdt, name, "device_type", "cpu");
 qemu_fdt_setprop_cells(fdt, name, "clocks", clk_ph, 
FDT_BOSTON_CLK_CPU);
+qemu_fdt_setprop_cell(fdt, name, "phandle", 
qemu_fdt_alloc_phandle(fdt));
+
+if (ms->smp.threads > 1) {
+map_path = g_strdup_printf(
+"/cpus/cpu-map/socket%d/cluster%d/core%d/thread%d",
+cpu / (ms->smp.clusters * ms->smp.cores * ms->smp.threads),
+(cpu / (ms->smp.cores * ms->smp.threads)) % ms->smp.clusters,
+(cpu / ms->smp.threads) % ms->smp.cores,
+cpu % ms->smp.threads);
+} else {
+map_path = g_strdup_printf(
+"/cpus/cpu-map/socket%d/cluster%d/core%d",
+cpu / (ms->smp.clusters * ms->smp.cores),
+(cpu / ms->smp.cores) % ms->smp.clusters,
+cpu % ms->smp.cores);
+}
+
+qemu_fdt_add_path(fdt, map_path);
+qemu_fdt_setprop_phandle(fdt, map_path, "cpu", name);
+
+g_free(map_path);
 g_free(name);
 }
 
@@ -591,6 +615,15 @@ static const void *create_fdt(BostonState *s,
 g_free(name);
 g_free(gic_name);
 
+/* CM node */
+name = g_strdup_printf("/soc/cm@%" HWADDR_PRIx, memmap[BOSTON_CM].base);
+qemu_fdt_add_subnode(fdt, name);
+qemu_fdt_setprop_string(fdt, name, "compatible", "mti,mips-cm");
+qemu_fdt_setprop_cells(fdt, name, "reg", memmap[BOSTON_CM].base,
+memmap[BOSTON_CM].size);
+g_free(name);
+
+
 /* CDMM node */
 name = g_strdup_printf("/soc/cdmm@%" HWADDR_PRIx, 
memmap[BOSTON_CDMM].base);
 qemu_fdt_add_subnode(fdt, name);
@@ -703,7 +736,9 @@ static void boston_mach_init(MachineState *machine)
 object_initialize_child(OBJECT(machine), "cps", >cps, TYPE_MIPS_CPS);
 object_property_set_str(OBJECT(>cps), "cpu-type", machine->cpu_type,
 _fatal);
-object_property_set_uint(OBJECT(>cps), "num-vp", machine->smp.cpus,
+object_property_set_uint(OBJECT(>cps), "num-pcore", machine->smp.cores,
+_fatal);
+object_property_set_uint(OBJECT(>cps), "num-vp", machine->smp.threads,
 _fatal);
 qdev_connect_clock_in(DEVICE(>cps), "clk-in",
   qdev_get_clock_out(dev, "cpu-refclk"));

-- 
2.34.1




[PATCH 2/5] hw/msic/mips_cmgcr: Implement multicore functions

2024-05-06 Thread Jiaxun Yang
We implemented following functions to allow software
to probe and control VPs on secondary core

- Reading out pcore count and coherence state
- Two scratch GCRs for firmware
- Semaphore GCR for register locking
- Redirect block to other cores

Signed-off-by: Jiaxun Yang 
---
 hw/misc/mips_cmgcr.c | 168 +++
 include/hw/misc/mips_cmgcr.h |  87 +++---
 2 files changed, 215 insertions(+), 40 deletions(-)

diff --git a/hw/misc/mips_cmgcr.c b/hw/misc/mips_cmgcr.c
index 2703040f45..8c2d184f2c 100644
--- a/hw/misc/mips_cmgcr.c
+++ b/hw/misc/mips_cmgcr.c
@@ -73,14 +73,19 @@ static inline void update_gic_base(MIPSGCRState *gcr, 
uint64_t val)
 static uint64_t gcr_read(void *opaque, hwaddr addr, unsigned size)
 {
 MIPSGCRState *gcr = (MIPSGCRState *) opaque;
-MIPSGCRVPState *current_vps = >vps[current_cpu->cpu_index];
-MIPSGCRVPState *other_vps = >vps[current_vps->other];
+int redirect_corenum = mips_gcr_get_redirect_corenum(gcr);
+int redirect_vpid = mips_gcr_get_redirect_vpid(gcr);
+int current_corenum = mips_gcr_get_current_corenum(gcr);
+int current_vpid = mips_gcr_get_current_vpid(gcr);
+MIPSGCRPCoreState *current_pcore = >pcs[current_corenum];
+MIPSGCRVPState *current_vps = _pcore->vps[current_vpid];
+MIPSGCRPCoreState *other_pcore = >pcs[redirect_corenum];
+MIPSGCRVPState *other_vps = _pcore->vps[redirect_vpid];
 
 switch (addr) {
 /* Global Control Block Register */
 case GCR_CONFIG_OFS:
-/* Set PCORES to 0 */
-return 0;
+return gcr->num_pcores - 1;
 case GCR_BASE_OFS:
 return gcr->gcr_base;
 case GCR_REV_OFS:
@@ -96,7 +101,19 @@ static uint64_t gcr_read(void *opaque, hwaddr addr, 
unsigned size)
 case GCR_L2_CONFIG_OFS:
 /* L2 BYPASS */
 return GCR_L2_CONFIG_BYPASS_MSK;
+case GCR_SYS_CONFIG2_OFS:
+return gcr->num_vps << GCR_SYS_CONFIG2_MAXVP_SHF;
+case GCR_SCRATCH0_OFS:
+return gcr->scratch[0];
+case GCR_SCRATCH1_OFS:
+return gcr->scratch[1];
+case GCR_SEM_OFS:
+return gcr->sem;
 /* Core-Local and Core-Other Control Blocks */
+case MIPS_CLCB_OFS + GCR_CL_COH_EN_OFS:
+return current_pcore->coh_en;
+case MIPS_COCB_OFS + GCR_CL_COH_EN_OFS:
+return other_pcore->coh_en;
 case MIPS_CLCB_OFS + GCR_CL_CONFIG_OFS:
 case MIPS_COCB_OFS + GCR_CL_CONFIG_OFS:
 /* Set PVP to # of VPs - 1 */
@@ -105,10 +122,18 @@ static uint64_t gcr_read(void *opaque, hwaddr addr, 
unsigned size)
 return current_vps->reset_base;
 case MIPS_COCB_OFS + GCR_CL_RESETBASE_OFS:
 return other_vps->reset_base;
-case MIPS_CLCB_OFS + GCR_CL_OTHER_OFS:
-return current_vps->other;
-case MIPS_COCB_OFS + GCR_CL_OTHER_OFS:
-return other_vps->other;
+case MIPS_CLCB_OFS + GCR_CL_REDIRECT_OFS:
+return current_vps->redirect;
+case MIPS_COCB_OFS + GCR_CL_REDIRECT_OFS:
+return other_vps->redirect;
+case MIPS_CLCB_OFS + GCR_CL_ID_OFS:
+return current_corenum;
+case MIPS_COCB_OFS + GCR_CL_ID_OFS:
+return redirect_corenum;
+case MIPS_CLCB_OFS + GCR_CL_SCRATCH_OFS:
+return current_vps->scratch;
+case MIPS_COCB_OFS + GCR_CL_SCRATCH_OFS:
+return other_vps->scratch;
 default:
 qemu_log_mask(LOG_UNIMP, "Read %d bytes at GCR offset 0x%" HWADDR_PRIx
   "\n", size, addr);
@@ -123,12 +148,36 @@ static inline target_ulong 
get_exception_base(MIPSGCRVPState *vps)
 return (int32_t)(vps->reset_base & GCR_CL_RESET_BASE_RESETBASE_MSK);
 }
 
+static inline void set_redirect(MIPSGCRState *gcr,
+MIPSGCRVPState *vps, target_ulong data)
+{
+int new_vpid = data & GCR_CL_REDIRECT_VP_MSK;
+int new_coreid = (data & GCR_CL_REDIRECT_CORE_MSK) >> 
GCR_CL_REDIRECT_CORE_SHF;
+
+if (new_vpid >= gcr->num_vps) {
+return;
+}
+
+if (new_coreid >= gcr->num_pcores) {
+return;
+}
+
+vps->redirect = data & (GCR_CL_REDIRECT_VP_MSK | GCR_CL_REDIRECT_CORE_MSK);
+}
+
 /* Write GCR registers */
 static void gcr_write(void *opaque, hwaddr addr, uint64_t data, unsigned size)
 {
-MIPSGCRState *gcr = (MIPSGCRState *)opaque;
-MIPSGCRVPState *current_vps = >vps[current_cpu->cpu_index];
-MIPSGCRVPState *other_vps = >vps[current_vps->other];
+MIPSGCRState *gcr = (MIPSGCRState *) opaque;
+int redirect_corenum = mips_gcr_get_redirect_corenum(gcr);
+int redirect_vpid = mips_gcr_get_redirect_vpid(gcr);
+int redirect_vpnum = mips_gcr_get_redirect_vpnum(gcr);
+int current_corenum = mips_gcr_get_current_corenum(gcr);
+int current_vpid = mips_gcr_get_current_vpid(gcr);
+MIPSGCRPCoreState *current_pcore = >pcs[current_corenum];
+

[PATCH 1/5] target/mips: Make globalnumber a CPU property

2024-05-06 Thread Jiaxun Yang
GlobalNumber marks topology information of a CPU instance.

Make it a CPU property to allow CPS to override topology information.

Signed-off-by: Jiaxun Yang 
---
 target/mips/cpu.c| 16 +++-
 target/mips/cpu.h| 10 +-
 target/mips/sysemu/machine.c |  5 ++---
 3 files changed, 26 insertions(+), 5 deletions(-)

diff --git a/target/mips/cpu.c b/target/mips/cpu.c
index bbe01d07dd..762000d09b 100644
--- a/target/mips/cpu.c
+++ b/target/mips/cpu.c
@@ -296,7 +296,6 @@ static void mips_cpu_reset_hold(Object *obj, ResetType type)
 env->CP0_Random = env->tlb->nb_tlb - 1;
 env->tlb->tlb_in_use = env->tlb->nb_tlb;
 env->CP0_Wired = 0;
-env->CP0_GlobalNumber = (cs->cpu_index & 0xFF) << CP0GN_VPId;
 env->CP0_EBase = KSEG0_BASE | (cs->cpu_index & 0x3FF);
 if (env->CP0_Config3 & (1 << CP0C3_CMGCR)) {
 env->CP0_CMGCRBase = 0x1fbf8000 >> 4;
@@ -484,6 +483,12 @@ static void mips_cpu_realizefn(DeviceState *dev, Error 
**errp)
 
 env->exception_base = (int32_t)0xBFC0;
 
+#if !defined(CONFIG_USER_ONLY)
+if (env->CP0_GlobalNumber == -1) {
+env->CP0_GlobalNumber = (cs->cpu_index & 0xFF) << CP0GN_VPId;
+}
+#endif
+
 #if defined(CONFIG_TCG) && !defined(CONFIG_USER_ONLY)
 mmu_init(env, env->cpu_model);
 #endif
@@ -563,6 +568,13 @@ static const TCGCPUOps mips_tcg_ops = {
 };
 #endif /* CONFIG_TCG */
 
+static Property mips_cpu_properties[] = {
+#if !defined(CONFIG_USER_ONLY)
+DEFINE_PROP_INT32("globalnumber", MIPSCPU, env.CP0_GlobalNumber, -1),
+#endif
+DEFINE_PROP_END_OF_LIST(),
+};
+
 static void mips_cpu_class_init(ObjectClass *c, void *data)
 {
 MIPSCPUClass *mcc = MIPS_CPU_CLASS(c);
@@ -592,6 +604,8 @@ static void mips_cpu_class_init(ObjectClass *c, void *data)
 #ifdef CONFIG_TCG
 cc->tcg_ops = _tcg_ops;
 #endif /* CONFIG_TCG */
+
+device_class_set_props(dc, mips_cpu_properties);
 }
 
 static const TypeInfo mips_cpu_type_info = {
diff --git a/target/mips/cpu.h b/target/mips/cpu.h
index 3e906a175a..7499608678 100644
--- a/target/mips/cpu.h
+++ b/target/mips/cpu.h
@@ -612,8 +612,13 @@ typedef struct CPUArchState {
 # define CP0EnLo_RI 31
 # define CP0EnLo_XI 30
 #endif
-int32_t CP0_GlobalNumber;
+/* CP0_GlobalNumber is preserved across CPU reset. */
 #define CP0GN_VPId 0
+#define CP0GN_VPId_MASK (0xFFUL << CP0GN_VPId)
+#define CP0GN_CoreNum 8
+#define CP0GN_CoreNum_MASK (0xFUL << CP0GN_CoreNum)
+#define CP0GN_ClusterNum 16
+#define CP0GN_ClusterNum_MASK (0xFUL << CP0GN_ClusterNum)
 /*
  * CP0 Register 4
  */
@@ -1175,6 +1180,9 @@ typedef struct CPUArchState {
 struct {} end_reset_fields;
 
 /* Fields from here on are preserved across CPU reset. */
+#if !defined(CONFIG_USER_ONLY)
+int32_t CP0_GlobalNumber;
+#endif
 CPUMIPSMVPContext *mvp;
 #if !defined(CONFIG_USER_ONLY)
 CPUMIPSTLBContext *tlb;
diff --git a/target/mips/sysemu/machine.c b/target/mips/sysemu/machine.c
index 213fd637fc..235d640862 100644
--- a/target/mips/sysemu/machine.c
+++ b/target/mips/sysemu/machine.c
@@ -218,8 +218,8 @@ static const VMStateDescription vmstate_tlb = {
 
 const VMStateDescription vmstate_mips_cpu = {
 .name = "cpu",
-.version_id = 21,
-.minimum_version_id = 21,
+.version_id = 22,
+.minimum_version_id = 22,
 .post_load = cpu_post_load,
 .fields = (const VMStateField[]) {
 /* Active TC */
@@ -257,7 +257,6 @@ const VMStateDescription vmstate_mips_cpu = {
 VMSTATE_INT32(env.CP0_VPEOpt, MIPSCPU),
 VMSTATE_UINT64(env.CP0_EntryLo0, MIPSCPU),
 VMSTATE_UINT64(env.CP0_EntryLo1, MIPSCPU),
-VMSTATE_INT32(env.CP0_GlobalNumber, MIPSCPU),
 VMSTATE_UINTTL(env.CP0_Context, MIPSCPU),
 VMSTATE_INT32(env.CP0_MemoryMapID, MIPSCPU),
 VMSTATE_INT32(env.CP0_PageMask, MIPSCPU),

-- 
2.34.1




[PATCH 0/5] hw/mips: Proper multi core support

2024-05-06 Thread Jiaxun Yang
Hi all,

This series implemented propper multiple core support for MIPS
CPS systsm.

Previously all CPUs are being implemented as a smt thread in a
single core. Now it respects topology supplied in QEMU args.

To test:
Build a latest kernel with 64r6el_defconfig (tested on 6.6,
next-20240506).

Then run:
```
qemu-system-mips64el -M boston -cpu I6500 -kernel ~/linux-next/vmlinux -smp 
4,cores=2,threads=2 -append "console=ttyS0,115200" -nographic
```
In dmesg of guest kernel:
```
[0.00] VP topology {2,2} total 4
...
[0.085190] smp: Bringing up secondary CPUs ...
[0.090219] Primary instruction cache 64kB, VIPT, 4-way, linesize 64 bytes.
[0.095461] Primary data cache 64kB, 4-way, PIPT, no aliases, linesize 64 
bytes
[0.096658] CPU1 revision is: 0001b000 (MIPS I6500)
[0.096718] FPU revision is: 20f30300
[0.124711] Synchronize counters for CPU 1: done.
[0.940979] Primary instruction cache 64kB, VIPT, 4-way, linesize 64 bytes.
[0.941041] Primary data cache 64kB, 4-way, PIPT, no aliases, linesize 64 
bytes
[0.941256] CPU2 revision is: 0001b000 (MIPS I6500)
[0.941289] FPU revision is: 20f30300
[0.965322] Synchronize counters for CPU 2: done.
[1.260937] Primary instruction cache 64kB, VIPT, 4-way, linesize 64 bytes.
[1.261001] Primary data cache 64kB, 4-way, PIPT, no aliases, linesize 64 
bytes
[1.261172] CPU3 revision is: 0001b000 (MIPS I6500)
[1.261209] FPU revision is: 20f30300
[1.285390] Synchronize counters for CPU 3: done.
[1.346985] smp: Brought up 1 node, 4 CPUs
```

Please review.

Thanks

To: qemu-devel@nongnu.org
Cc: Philippe Mathieu-Daudé 

Signed-off-by: Jiaxun Yang 
---
Jiaxun Yang (5):
  target/mips: Make globalnumber a CPU property
  hw/msic/mips_cmgcr: Implement multicore functions
  hw/msic/mips_cpc: Implement multi core support
  hw/mips/cps: Implement multi core support
  hw/mips/boston: Implement multi core support

 hw/mips/boston.c |  37 +-
 hw/mips/cps.c|  66 ++---
 hw/misc/mips_cmgcr.c | 168 +++
 hw/misc/mips_cpc.c   |  97 ++---
 include/hw/mips/cps.h|   1 +
 include/hw/misc/mips_cmgcr.h |  87 +++---
 include/hw/misc/mips_cpc.h   |  15 +++-
 target/mips/cpu.c|  16 -
 target/mips/cpu.h|  10 ++-
 target/mips/sysemu/machine.c |   5 +-
 10 files changed, 403 insertions(+), 99 deletions(-)
---
base-commit: 248f6f62df073a3b4158fd0093863ab885feabb5
change-id: 20240506-mips-smp-9af9e71ad8c2

Best regards,
-- 
Jiaxun Yang 




[PATCH 4/5] hw/mips/cps: Implement multi core support

2024-05-06 Thread Jiaxun Yang
Implement multiple physical core support by creating
CPU devices accorading to the new topology and passing
pcore/vp information to CPC and CMGCR sub-devices.

Signed-off-by: Jiaxun Yang 
---
 hw/mips/cps.c | 66 +++
 include/hw/mips/cps.h |  1 +
 2 files changed, 41 insertions(+), 26 deletions(-)

diff --git a/hw/mips/cps.c b/hw/mips/cps.c
index 07b73b0a1f..6cf02379a9 100644
--- a/hw/mips/cps.c
+++ b/hw/mips/cps.c
@@ -73,31 +73,43 @@ static void mips_cps_realize(DeviceState *dev, Error **errp)
 return;
 }
 
-for (int i = 0; i < s->num_vp; i++) {
-MIPSCPU *cpu = MIPS_CPU(object_new(s->cpu_type));
-CPUMIPSState *env = >env;
+object_initialize_child(OBJECT(dev), "gcr", >gcr, TYPE_MIPS_GCR);
 
-/* All VPs are halted on reset. Leave powering up to CPC. */
-object_property_set_bool(OBJECT(cpu), "start-powered-off", true,
- _abort);
+for (int corenum = 0; corenum < s->num_pcore; corenum++) {
+for (int vpid = 0; vpid < s->num_vp; vpid++) {
+int vpnum = corenum * s->num_vp + vpid;
+int32_t globalnumber = (corenum << CP0GN_CoreNum) | vpid;
 
-/* All cores use the same clock tree */
-qdev_connect_clock_in(DEVICE(cpu), "clk-in", s->clock);
+MIPSCPU *cpu = MIPS_CPU(object_new(s->cpu_type));
+CPUMIPSState *env = >env;
 
-if (!qdev_realize_and_unref(DEVICE(cpu), NULL, errp)) {
-return;
-}
+/* All VPs are halted on reset. Leave powering up to CPC. */
+object_property_set_bool(OBJECT(cpu), "start-powered-off", true,
+_abort);
+
+object_property_set_int(OBJECT(cpu), "globalnumber", globalnumber,
+_abort);
+
+/* All cores use the same clock tree */
+qdev_connect_clock_in(DEVICE(cpu), "clk-in", s->clock);
+
+if (!qdev_realize_and_unref(DEVICE(cpu), NULL, errp)) {
+return;
+}
+
+g_assert(vpnum == CPU(cpu)->cpu_index);
 
-/* Init internal devices */
-cpu_mips_irq_init_cpu(cpu);
-cpu_mips_clock_init(cpu);
+/* Init internal devices */
+cpu_mips_irq_init_cpu(cpu);
+cpu_mips_clock_init(cpu);
 
-if (cpu_mips_itu_supported(env)) {
-itu_present = true;
-/* Attach ITC Tag to the VP */
-env->itc_tag = mips_itu_get_tag_region(>itu);
+if (cpu_mips_itu_supported(env)) {
+itu_present = true;
+/* Attach ITC Tag to the VP */
+env->itc_tag = mips_itu_get_tag_region(>itu);
+}
+qemu_register_reset(main_cpu_reset, cpu);
 }
-qemu_register_reset(main_cpu_reset, cpu);
 }
 
 /* Inter-Thread Communication Unit */
@@ -119,8 +131,12 @@ static void mips_cps_realize(DeviceState *dev, Error 
**errp)
 object_initialize_child(OBJECT(dev), "cpc", >cpc, TYPE_MIPS_CPC);
 object_property_set_uint(OBJECT(>cpc), "num-vp", s->num_vp,
 _abort);
+object_property_set_uint(OBJECT(>cpc), "num-pcore", s->num_pcore,
+_abort);
 object_property_set_int(OBJECT(>cpc), "vp-start-running", 1,
 _abort);
+object_property_set_link(OBJECT(>cpc), "gcr", OBJECT(>gcr),
+_abort);
 if (!sysbus_realize(SYS_BUS_DEVICE(>cpc), errp)) {
 return;
 }
@@ -130,7 +146,7 @@ static void mips_cps_realize(DeviceState *dev, Error **errp)
 
 /* Global Interrupt Controller */
 object_initialize_child(OBJECT(dev), "gic", >gic, TYPE_MIPS_GIC);
-object_property_set_uint(OBJECT(>gic), "num-vp", s->num_vp,
+object_property_set_uint(OBJECT(>gic), "num-vp", s->num_vp * 
s->num_pcore,
 _abort);
 object_property_set_uint(OBJECT(>gic), "num-irq", 128,
 _abort);
@@ -141,16 +157,13 @@ static void mips_cps_realize(DeviceState *dev, Error 
**errp)
 memory_region_add_subregion(>container, 0,
 sysbus_mmio_get_region(SYS_BUS_DEVICE(>gic), 
0));
 
-/* Global Configuration Registers */
-gcr_base = MIPS_CPU(first_cpu)->env.CP0_CMGCRBase << 4;
-
-object_initialize_child(OBJECT(dev), "gcr", >gcr, TYPE_MIPS_GCR);
+gcr_base = GCR_BASE_ADDR;
+object_property_set_uint(OBJECT(>gcr), "num-pcores", s->num_pcore,
+_abort);
 object_property_set_uint(OBJECT(>gcr), "num-vp"

[PATCH 3/5] hw/msic/mips_cpc: Implement multi core support

2024-05-06 Thread Jiaxun Yang
Implement multiple physical core support for MIPS CPC
controller. Including some R/O configuration registers
and VP bring up support on multiple cores.

Signed-off-by: Jiaxun Yang 
---
 hw/misc/mips_cpc.c | 97 ++
 include/hw/misc/mips_cpc.h | 15 ++-
 2 files changed, 85 insertions(+), 27 deletions(-)

diff --git a/hw/misc/mips_cpc.c b/hw/misc/mips_cpc.c
index 1e8fd2e699..f6a2f29088 100644
--- a/hw/misc/mips_cpc.c
+++ b/hw/misc/mips_cpc.c
@@ -25,9 +25,25 @@
 #include "hw/sysbus.h"
 #include "migration/vmstate.h"
 
+#include "hw/misc/mips_cmgcr.h"
 #include "hw/misc/mips_cpc.h"
 #include "hw/qdev-properties.h"
 
+static inline int cpc_vpnum_to_corenum(MIPSCPCState *cpc, int vpnum)
+{
+return vpnum / cpc->num_vp;
+}
+
+static inline int cpc_vpnum_to_vpid(MIPSCPCState *cpc, int vpnum)
+{
+return vpnum % cpc->num_vp;
+}
+
+static inline MIPSCPCPCoreState *cpc_vpnum_to_pcs(MIPSCPCState *cpc, int vpnum)
+{
+return >pcs[cpc_vpnum_to_corenum(cpc, vpnum)];
+}
+
 static inline uint64_t cpc_vp_run_mask(MIPSCPCState *cpc)
 {
 return (1ULL << cpc->num_vp) - 1;
@@ -39,36 +55,41 @@ static void mips_cpu_reset_async_work(CPUState *cs, 
run_on_cpu_data data)
 
 cpu_reset(cs);
 cs->halted = 0;
-cpc->vp_running |= 1ULL << cs->cpu_index;
+cpc_vpnum_to_pcs(cpc, cs->cpu_index)->vp_running |=
+1 << cpc_vpnum_to_vpid(cpc, cs->cpu_index);
 }
 
-static void cpc_run_vp(MIPSCPCState *cpc, uint64_t vp_run)
+static void cpc_run_vp(MIPSCPCState *cpc, int pcore, uint64_t vp_run)
 {
-CPUState *cs = first_cpu;
+MIPSCPCPCoreState *pcs = >pcs[pcore];
 
-CPU_FOREACH(cs) {
-uint64_t i = 1ULL << cs->cpu_index;
-if (i & vp_run & ~cpc->vp_running) {
+for (int vpid = 0; vpid < cpc->num_vp; vpid++) {
+if ((1 << vpid) & vp_run & ~pcs->vp_running) {
+int vpnum = pcore * cpc->num_vp + vpid;
 /*
  * To avoid racing with a CPU we are just kicking off.
  * We do the final bit of preparation for the work in
  * the target CPUs context.
  */
-async_safe_run_on_cpu(cs, mips_cpu_reset_async_work,
-  RUN_ON_CPU_HOST_PTR(cpc));
+async_safe_run_on_cpu(qemu_get_cpu(vpnum),
+mips_cpu_reset_async_work,
+RUN_ON_CPU_HOST_PTR(cpc));
+pcs->vp_running |= 1 << vpid;
 }
 }
 }
 
-static void cpc_stop_vp(MIPSCPCState *cpc, uint64_t vp_stop)
+static void cpc_stop_vp(MIPSCPCState *cpc, int pcore, uint64_t vp_stop)
 {
-CPUState *cs = first_cpu;
+MIPSCPCPCoreState *pcs = >pcs[pcore];
+
+for (int vpid = 0; vpid < cpc->num_vp; vpid++) {
+if ((1 << vpid) & vp_stop & pcs->vp_running) {
+int vpnum = pcore * cpc->num_vp + vpid;
+CPUState *cs = qemu_get_cpu(vpnum);
 
-CPU_FOREACH(cs) {
-uint64_t i = 1ULL << cs->cpu_index;
-if (i & vp_stop & cpc->vp_running) {
 cpu_interrupt(cs, CPU_INTERRUPT_HALT);
-cpc->vp_running &= ~i;
+pcs->vp_running &= ~(1 << vpid);
 }
 }
 }
@@ -77,15 +98,20 @@ static void cpc_write(void *opaque, hwaddr offset, uint64_t 
data,
   unsigned size)
 {
 MIPSCPCState *s = opaque;
+int current_corenum = cpc_vpnum_to_corenum(s, current_cpu->cpu_index);
 
 switch (offset) {
 case CPC_CL_BASE_OFS + CPC_VP_RUN_OFS:
+cpc_run_vp(s, current_corenum, data);
+break;
 case CPC_CO_BASE_OFS + CPC_VP_RUN_OFS:
-cpc_run_vp(s, data & cpc_vp_run_mask(s));
+cpc_run_vp(s, mips_gcr_get_redirect_corenum(s->gcr), data);
 break;
 case CPC_CL_BASE_OFS + CPC_VP_STOP_OFS:
+cpc_stop_vp(s, current_corenum, data);
+break;
 case CPC_CO_BASE_OFS + CPC_VP_STOP_OFS:
-cpc_stop_vp(s, data & cpc_vp_run_mask(s));
+cpc_stop_vp(s, mips_gcr_get_redirect_corenum(s->gcr), data);
 break;
 default:
 qemu_log_mask(LOG_UNIMP,
@@ -101,9 +127,13 @@ static uint64_t cpc_read(void *opaque, hwaddr offset, 
unsigned size)
 MIPSCPCState *s = opaque;
 
 switch (offset) {
+case CPC_CL_BASE_OFS + CPC_CL_STAT_CONF_OFS:
+case CPC_CO_BASE_OFS + CPC_CL_STAT_CONF_OFS:
+return CPC_CL_STAT_CONF_SEQ_STATE_U6 << CPC_CL_STAT_CONF_SEQ_STATE_SHF;
 case CPC_CL_BASE_OFS + CPC_VP_RUNNING_OFS:
+return cpc_vpnum_to_pcs(s, current_cpu->cpu_index)->vp_running;
 case CPC_CO_BASE_OFS + CPC_VP_RUNNING_OFS:
-return s->vp_running;
+return s->pcs[mips_gcr_get_redirect_corenum(s->gcr)].vp_running;
 default:

Re: [RFC PATCH 00/11] target/mips: Remove I6500 CPU definition

2024-02-09 Thread Jiaxun Yang




在 2024/2/9 09:05, Philippe Mathieu-Daudé 写道:

Alternative to:
https://lore.kernel.org/qemu-devel/20240209085347.8446-1-phi...@linaro.org/
If the I6500 can not be tested or its support is incomplete,
there is no point in wasting energy maintaining it.


Actually all SAAR and ITU stuff are optional for I6500 in real world so 
it's fine

to just leave I6500 defined without SAAR support.

The main difference between I6400 and I6500 is multi-cluster support, I do
have some patch for bringing proper multi-cluster support to QEMU, but
it can't work with boston due to address space limitations.

Should I give mips-virt stuff another go?

Thanks
- Jiaxun



Philippe Mathieu-Daudé (11):
   target/mips: Remove helpers accessing SAAR registers
   hw/misc/mips: Reduce itc_reconfigure() scope
   target/mips: Remove MIPSITUState::itu field
   target/mips: Remove CPUMIPSState::saarp field
   hw/misc/mips_itu: Remove MIPSITUState::cpu0 field
   hw/misc/mips_itu: Remove MIPSITUState::saar field
   target/mips: Remove CPUMIPSState::CP0_SAAR[2] field
   target/mips: Remove helpers accessing SAARI register
   target/mips: Remove CPUMIPSState::CP0_SAARI field
   target/mips: Remove the unused DisasContext::saar field
   target/mips: Remove I6500 CPU definition

  docs/about/removed-features.rst |  5 +++
  include/hw/misc/mips_itu.h  |  6 ---
  target/mips/cpu.h   |  4 --
  target/mips/tcg/translate.h |  1 -
  target/mips/tcg/sysemu_helper.h.inc |  6 ---
  hw/mips/cps.c   |  3 --
  hw/misc/mips_itu.c  | 35 ++--
  target/mips/sysemu/machine.c|  4 +-
  target/mips/tcg/sysemu/cp0_helper.c | 63 -
  target/mips/tcg/translate.c | 62 
  tests/qtest/machine-none-test.c |  2 +-
  target/mips/cpu-defs.c.inc  | 40 --
  12 files changed, 12 insertions(+), 219 deletions(-)



--
---
Jiaxun Yang




Re: why various devices are loading x86 roms on non-x86 architectures?

2024-01-31 Thread Jiaxun Yang




在 2024/1/31 10:28, Michael Tokarev 写道:

Hi!

qemu-system-aarch64 -device virtio-vga

this one loads vgabios-virtio.bin.  Why?
Does this bios work on aarch64 (or any other non-x86 arch)?
Should there may be some conditional in this and similar places?
The same is true for x86 pxe roms and other x86-only roms.


FYI on some systems they use x86emu (or biosemu) to run x86 only
OpROMs, this is at least true for u-boot (u-boot/drivers/bios_emulator),
PMON (MIPS/Loongson) and coreboot.

Thanks
- Jiaxun



Thanks,

/mjt



--
---
Jiaxun Yang




Re: [PATCH] target/mips: enable GINVx support for I6400 and I6500

2023-07-10 Thread Jiaxun Yang




在 2023/6/30 15:28, Marcin Nowakowski 写道:

GINVI and GINVT operations are supported on MIPS I6400 and I6500 cores,
so indicate that properly in CP0.Config5 register bits [16:15].

Signed-off-by: Marcin Nowakowski 


VZ is unimplemented in TCG so perhaps we should leave them as not supported?

Thanks
- Jiaxun


---
  target/mips/cpu-defs.c.inc | 4 ++--
  1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/target/mips/cpu-defs.c.inc b/target/mips/cpu-defs.c.inc
index d45f245a67..da122e72d7 100644
--- a/target/mips/cpu-defs.c.inc
+++ b/target/mips/cpu-defs.c.inc
@@ -709,7 +709,7 @@ const mips_def_t mips_defs[] =
  .CP0_Config4 = MIPS_CONFIG4 | (1U << CP0C4_M) | (3 << CP0C4_IE) |
 (1 << CP0C4_AE) | (0xfc << CP0C4_KScrExist),
  .CP0_Config5 = MIPS_CONFIG5 | (1 << CP0C5_XNP) | (1 << CP0C5_VP) |
-   (1 << CP0C5_LLB) | (1 << CP0C5_MRP),
+   (1 << CP0C5_LLB) | (1 << CP0C5_MRP) | (3 << CP0C5_GI),
  .CP0_Config5_rw_bitmask = (1 << CP0C5_MSAEn) | (1 << CP0C5_SBRI) |
(1 << CP0C5_FRE) | (1 << CP0C5_UFE),
  .CP0_LLAddr_rw_bitmask = 0,
@@ -749,7 +749,7 @@ const mips_def_t mips_defs[] =
  .CP0_Config4 = MIPS_CONFIG4 | (1U << CP0C4_M) | (3 << CP0C4_IE) |
 (1 << CP0C4_AE) | (0xfc << CP0C4_KScrExist),
  .CP0_Config5 = MIPS_CONFIG5 | (1 << CP0C5_XNP) | (1 << CP0C5_VP) |
-   (1 << CP0C5_LLB) | (1 << CP0C5_MRP),
+   (1 << CP0C5_LLB) | (1 << CP0C5_MRP) | (3 << CP0C5_GI),
  .CP0_Config5_rw_bitmask = (1 << CP0C5_MSAEn) | (1 << CP0C5_SBRI) |
(1 << CP0C5_FRE) | (1 << CP0C5_UFE),
  .CP0_LLAddr_rw_bitmask = 0,





Re: [PATCH 1/4] hw/intc/loongarch_ipi: Bring back all 4 IPI mailboxes

2023-06-03 Thread Jiaxun Yang



> 2023年6月3日 01:28,Peter Maydell  写道:
> 
> On Sun, 21 May 2023 at 11:24, Jiaxun Yang  wrote:
>> 
>> As per "Loongson 3A5000/3B5000 Processor Reference Manual",
>> Loongson 3A5000's IPI implementation have 4 mailboxes per
>> core.
>> 
>> However, in 78464f023b54 ("hw/loongarch/virt: Modify ipi as
>> percpu device"), the number of IPI mailboxes was reduced to
>> one, which mismatches actual hardware.
>> 
>> It won't affect LoongArch based system as LoongArch boot code
>> only uses the first mailbox, however MIPS based Loongson boot
>> code uses all 4 mailboxes.
>> 
>> Fixes: 78464f023b54 ("hw/loongarch/virt: Modify ipi as percpu device")
>> Signed-off-by: Jiaxun Yang 
>> ---
>> hw/intc/loongarch_ipi.c | 6 +++---
>> include/hw/intc/loongarch_ipi.h | 4 +++-
>> 2 files changed, 6 insertions(+), 4 deletions(-)
>> 
>> diff --git a/hw/intc/loongarch_ipi.c b/hw/intc/loongarch_ipi.c
>> index d6ab91721ea1..3e453816524e 100644
>> --- a/hw/intc/loongarch_ipi.c
>> +++ b/hw/intc/loongarch_ipi.c
>> @@ -238,14 +238,14 @@ static void loongarch_ipi_init(Object *obj)
>> 
>> static const VMStateDescription vmstate_ipi_core = {
>> .name = "ipi-single",
>> -.version_id = 1,
>> -.minimum_version_id = 1,
>> +.version_id = 2,
>> +.minimum_version_id = 2,
>> .fields = (VMStateField[]) {
>> VMSTATE_UINT32(status, IPICore),
>> VMSTATE_UINT32(en, IPICore),
>> VMSTATE_UINT32(set, IPICore),
>> VMSTATE_UINT32(clear, IPICore),
>> -VMSTATE_UINT32_ARRAY(buf, IPICore, 2),
>> +VMSTATE_UINT32_ARRAY(buf, IPICore, IPI_MBX_NUM * 2),
>> VMSTATE_END_OF_LIST()
>> }
>> };
>> diff --git a/include/hw/intc/loongarch_ipi.h 
>> b/include/hw/intc/loongarch_ipi.h
>> index 664e050b926e..6c6194786e80 100644
>> --- a/include/hw/intc/loongarch_ipi.h
>> +++ b/include/hw/intc/loongarch_ipi.h
>> @@ -28,6 +28,8 @@
>> #define MAIL_SEND_OFFSET  0
>> #define ANY_SEND_OFFSET   (IOCSR_ANY_SEND - IOCSR_MAIL_SEND)
>> 
>> +#define IPI_MBX_NUM   4
>> +
>> #define TYPE_LOONGARCH_IPI "loongarch_ipi"
>> OBJECT_DECLARE_SIMPLE_TYPE(LoongArchIPI, LOONGARCH_IPI)
>> 
>> @@ -37,7 +39,7 @@ typedef struct IPICore {
>> uint32_t set;
>> uint32_t clear;
>> /* 64bit buf divide into 2 32bit buf */
>> -uint32_t buf[2];
>> +uint32_t buf[IPI_MBX_NUM * 2];
>> qemu_irq irq;
>> } IPICore;
> 
> In particular, this fixes Coverity issues CID 1512452 and 1512453,
> where Coverity notices that the code in loongarch_ipi_writel() and
> loongarch_ipi_readl() reads off the end of the too-short buf[].

LoongArch maintainers, do you mind to take this patch while I’m refactoring
rest of the series?

Thanks
Jiaxun

> 
> thanks
> -- PMM





Re: [PATCH 1/4] hw/intc/loongarch_ipi: Bring back all 4 IPI mailboxes

2023-05-23 Thread Jiaxun Yang



> 2023年5月23日 11:01,Song Gao  写道:
> 
> 
> 
> 在 2023/5/23 上午11:22, Jiaxun Yang 写道:
[...]
>> 
>>> 
>> Is totally the same on MIPS and LoongArch. I’m guarding them out because
>> We have different way to get IOCSR address space on MIPS, which is due
>> to be implemented.
>> 
>> I can further abstract out a function to get IOCSR address space. But still,
>> I think the best way to differ those two architecture is using TARGET_* 
>> macros,
>> as it doesn’t make much sense to have unused code for another architecture
>> compiled.
> Most of the code in hw/intc or hw/ uses property to distinguish between 
> different devices,  not TARGE_* macro.

They are the *same* device, with different way to handle IOCSR address space.

Another problem is casting CPUState with LOONGARCH_CPU() is something invalid on
MIPS, vice-versa. We are potentially introducing a security issue here.

I know nobody have done something like this before, but not necessarily to be a 
bad idea.

I’ll introduce something like:

+#ifdef TARGET_LOONGARCH64
+static inline void *AddressSpace get_iocsr_as(int cpuid)
+{
+CPUState *cs = qemu_get_cpu(cpuid);
+LoongArchCPU *cpu = LOONGARCH_CPU(cs);
+
+return >env.address_space_iocsr;
+}
+#endif
+
+#ifdef TARGET_MIPS64
+static inline void *AddressSpace get_iocsr_as(int cpuid)
+{
+CPUState *cs = qemu_get_cpu(cpuid);
+MIPSCPU *cpu = MIPS_CPU(cs);
+
+return >env.iocsr.as;
+}
+#endif

Thanks
- Jiaxun

> 
> I still think it is better to use property.
> 
> Thanks.
> Song Gao
>>> All references to loongarch_ipi should also be changed.
>> Sure.
>> 
>> Thanks
>> - Jiaxun
> 




Re: [PATCH 1/4] hw/intc/loongarch_ipi: Bring back all 4 IPI mailboxes

2023-05-22 Thread Jiaxun Yang



> 2023年5月23日 02:25,Song Gao  写道:
> 
> 
> 
> 在 2023/5/22 下午9:44, Philippe Mathieu-Daudé 写道:
>> On 22/5/23 13:47, Jiaxun Yang wrote:
>>> 
>>> 
>>>> 2023年5月22日 04:52,Huacai Chen  写道:
>>>> 
>>>> Hi, Jiaxun,
>>>> 
>>>> Rename loongarch_ipi to loongson_ipi? It will be shared by both MIPS
>>>> and LoongArch in your series.
>>> 
>>> Hi Huacai,
>>> 
>>> Thanks for the point, what’s the opinion from LoongArch mainatiners?
>>> 
>>> Or perhaps rename it as loong_ipi to reflect the nature that it’s shared
>>> by MIPS based Loongson and LoongArch based Loongson?
>> 
>> I'm not a LoongArch maintainer, but a model named "loong_ipi" makes
>> sense to me.
>> 
>> Please add it to the two Virt machine sections in MAINTAINERS.

Hi Song,

>> 
> 'loonggson_ipi' is better, qemu doesn't have naming with 'loong' as prefix.

Thanks, I’ll take looongson_ipi then.

> 
> And  patch2 should not use macros. Some attributes should be added to 
> distinguish between MIPS and LongArch.

By attribute do you mean property? If so I don’t see any necessity, the IP block
Is totally the same on MIPS and LoongArch. I’m guarding them out because
We have different way to get IOCSR address space on MIPS, which is due
to be implemented.

I can further abstract out a function to get IOCSR address space. But still,
I think the best way to differ those two architecture is using TARGET_* macros,
as it doesn’t make much sense to have unused code for another architecture
compiled.

> 
> All references to loongarch_ipi should also be changed.
Sure.

Thanks
- Jiaxun

> 
> Thanks.
> Song Gao





Re: [PATCH 2/2] hw/mips/loongson3_virt: Remove CPU restrictions for TCG

2023-05-22 Thread Jiaxun Yang



> 2023年5月22日 13:08,Philippe Mathieu-Daudé  写道:
> 
> On 21/5/23 23:48, Jiaxun Yang wrote:
>> After implemented CPUCFG and CSR, we are now able to boot Linux
>> kernel with Loongson-3A4000 CPU, so there is no point to restrict
>> CPU type for TCG.
> 
> Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1639
> ?

Potentially yes, although I think the issue itself is just a question on usage
of the board.

Thanks
- Jiaxun

> 
>> Signed-off-by: Jiaxun Yang 
>> ---
>>  hw/mips/loongson3_virt.c | 4 
>>  1 file changed, 4 deletions(-)
> 
> 




Re: [PATCH 1/4] hw/intc/loongarch_ipi: Bring back all 4 IPI mailboxes

2023-05-22 Thread Jiaxun Yang



> 2023年5月22日 04:52,Huacai Chen  写道:
> 
> Hi, Jiaxun,
> 
> Rename loongarch_ipi to loongson_ipi? It will be shared by both MIPS
> and LoongArch in your series.

Hi Huacai,

Thanks for the point, what’s the opinion from LoongArch mainatiners?

Or perhaps rename it as loong_ipi to reflect the nature that it’s shared
by MIPS based Loongson and LoongArch based Loongson?

Thanks
- Jiaxun

> 
> 
> Huacai
> 
> On Sun, May 21, 2023 at 6:24 PM Jiaxun Yang  wrote:
>> 
>> As per "Loongson 3A5000/3B5000 Processor Reference Manual",
>> Loongson 3A5000's IPI implementation have 4 mailboxes per
>> core.
>> 
>> However, in 78464f023b54 ("hw/loongarch/virt: Modify ipi as
>> percpu device"), the number of IPI mailboxes was reduced to
>> one, which mismatches actual hardware.
>> 
>> It won't affect LoongArch based system as LoongArch boot code
>> only uses the first mailbox, however MIPS based Loongson boot
>> code uses all 4 mailboxes.
>> 
>> Fixes: 78464f023b54 ("hw/loongarch/virt: Modify ipi as percpu device")
>> Signed-off-by: Jiaxun Yang 
>> ---
>> hw/intc/loongarch_ipi.c | 6 +++---
>> include/hw/intc/loongarch_ipi.h | 4 +++-
>> 2 files changed, 6 insertions(+), 4 deletions(-)
>> 
>> diff --git a/hw/intc/loongarch_ipi.c b/hw/intc/loongarch_ipi.c
>> index d6ab91721ea1..3e453816524e 100644
>> --- a/hw/intc/loongarch_ipi.c
>> +++ b/hw/intc/loongarch_ipi.c
>> @@ -238,14 +238,14 @@ static void loongarch_ipi_init(Object *obj)
>> 
>> static const VMStateDescription vmstate_ipi_core = {
>> .name = "ipi-single",
>> -.version_id = 1,
>> -.minimum_version_id = 1,
>> +.version_id = 2,
>> +.minimum_version_id = 2,
>> .fields = (VMStateField[]) {
>> VMSTATE_UINT32(status, IPICore),
>> VMSTATE_UINT32(en, IPICore),
>> VMSTATE_UINT32(set, IPICore),
>> VMSTATE_UINT32(clear, IPICore),
>> -VMSTATE_UINT32_ARRAY(buf, IPICore, 2),
>> +VMSTATE_UINT32_ARRAY(buf, IPICore, IPI_MBX_NUM * 2),
>> VMSTATE_END_OF_LIST()
>> }
>> };
>> diff --git a/include/hw/intc/loongarch_ipi.h 
>> b/include/hw/intc/loongarch_ipi.h
>> index 664e050b926e..6c6194786e80 100644
>> --- a/include/hw/intc/loongarch_ipi.h
>> +++ b/include/hw/intc/loongarch_ipi.h
>> @@ -28,6 +28,8 @@
>> #define MAIL_SEND_OFFSET  0
>> #define ANY_SEND_OFFSET   (IOCSR_ANY_SEND - IOCSR_MAIL_SEND)
>> 
>> +#define IPI_MBX_NUM   4
>> +
>> #define TYPE_LOONGARCH_IPI "loongarch_ipi"
>> OBJECT_DECLARE_SIMPLE_TYPE(LoongArchIPI, LOONGARCH_IPI)
>> 
>> @@ -37,7 +39,7 @@ typedef struct IPICore {
>> uint32_t set;
>> uint32_t clear;
>> /* 64bit buf divide into 2 32bit buf */
>> -uint32_t buf[2];
>> +uint32_t buf[IPI_MBX_NUM * 2];
>> qemu_irq irq;
>> } IPICore;
>> 
>> --
>> 2.39.2 (Apple Git-143)
>> 




[PATCH 0/2] MIPS: Enable Loongson-3A4000 TCG for system emulation

2023-05-21 Thread Jiaxun Yang
Hi there,

This series enables Loongson-3A4000 TCG for system emulation.
It Implemented Loongson CSR insertions which is required for
Linux Kernel to probe CPU features and removed CPU type restrictions
for loongson3_virt board.

This series is based on two of my previous series[1] [2]. However it's
just a soft dependency for me to do boot test, feel free to apply this
series without them.

Note that loongarch_ipi is still not hooked up in IOCSR. I've sucessfully
done it locally but I just want to confirm some details on hardware.

Thanks
- Jiaxun

[1]: 
https://lore.kernel.org/qemu-devel/20230521102307.87081-1-jiaxun.y...@flygoat.com/T/#t
[2]: 
https://lore.kernel.org/qemu-devel/0bb0cded-8450-536e-b90f-1a9d33311...@linaro.org/T/#t

Jiaxun Yang (2):
  target/mips: Implement Loongson CSR instructions
  hw/mips/loongson3_virt: Remove CPU restrictions for TCG

 hw/mips/loongson3_virt.c |  4 --
 target/mips/cpu-defs.c.inc   |  9 
 target/mips/cpu.c|  8 
 target/mips/cpu.h| 40 
 target/mips/helper.h |  4 ++
 target/mips/internal.h   |  2 +
 target/mips/tcg/lcsr.decode  | 17 +++
 target/mips/tcg/lcsr_translate.c | 69 
 target/mips/tcg/meson.build  |  2 +
 target/mips/tcg/op_helper.c  | 16 +++
 target/mips/tcg/sysemu/lcsr_helper.c | 45 ++
 target/mips/tcg/sysemu/meson.build   |  4 ++
 target/mips/tcg/sysemu_helper.h.inc  |  8 
 target/mips/tcg/translate.c  |  3 ++
 target/mips/tcg/translate.h  |  7 +++
 15 files changed, 234 insertions(+), 4 deletions(-)
 create mode 100644 target/mips/tcg/lcsr.decode
 create mode 100644 target/mips/tcg/lcsr_translate.c
 create mode 100644 target/mips/tcg/sysemu/lcsr_helper.c

-- 
2.39.2 (Apple Git-143)




[PATCH 2/2] hw/mips/loongson3_virt: Remove CPU restrictions for TCG

2023-05-21 Thread Jiaxun Yang
After implemented CPUCFG and CSR, we are now able to boot Linux
kernel with Loongson-3A4000 CPU, so there is no point to restrict
CPU type for TCG.

Signed-off-by: Jiaxun Yang 
---
 hw/mips/loongson3_virt.c | 4 
 1 file changed, 4 deletions(-)

diff --git a/hw/mips/loongson3_virt.c b/hw/mips/loongson3_virt.c
index a57245012598..47289fb6bf85 100644
--- a/hw/mips/loongson3_virt.c
+++ b/hw/mips/loongson3_virt.c
@@ -488,10 +488,6 @@ static void mips_loongson3_virt_init(MachineState *machine)
 if (!machine->cpu_type) {
 machine->cpu_type = MIPS_CPU_TYPE_NAME("Loongson-3A1000");
 }
-if (!strstr(machine->cpu_type, "Loongson-3A1000")) {
-error_report("Loongson-3/TCG needs cpu type Loongson-3A1000");
-exit(1);
-}
 } else {
 if (!machine->cpu_type) {
 machine->cpu_type = MIPS_CPU_TYPE_NAME("Loongson-3A4000");
-- 
2.39.2 (Apple Git-143)




[PATCH 1/2] target/mips: Implement Loongson CSR instructions

2023-05-21 Thread Jiaxun Yang
Loongson introduced CSR instructions since 3A4000, which looks
similar to IOCSR and CPUCFG instructions we seen in LoongArch.

Unfortunately we don't have much document about those instructions,
bit fields of CPUCFG instructions and IOCSR registers can be found
at 3A4000's user manual, while instruction encodings can be found
at arch/mips/include/asm/mach-loongson64/loongson_regs.h from
Linux Kernel.

Our predefined CPUCFG bits are differ from actual 3A4000, since
we can't emulate all CPUCFG features present in 3A4000 for now,
we just enable bits for what we have in TCG.

Signed-off-by: Jiaxun Yang 
---
 target/mips/cpu-defs.c.inc   |  9 
 target/mips/cpu.c|  8 
 target/mips/cpu.h| 40 
 target/mips/helper.h |  4 ++
 target/mips/internal.h   |  2 +
 target/mips/tcg/lcsr.decode  | 17 +++
 target/mips/tcg/lcsr_translate.c | 69 
 target/mips/tcg/meson.build  |  2 +
 target/mips/tcg/op_helper.c  | 16 +++
 target/mips/tcg/sysemu/lcsr_helper.c | 45 ++
 target/mips/tcg/sysemu/meson.build   |  4 ++
 target/mips/tcg/sysemu_helper.h.inc  |  8 
 target/mips/tcg/translate.c  |  3 ++
 target/mips/tcg/translate.h  |  7 +++
 14 files changed, 234 insertions(+)
 create mode 100644 target/mips/tcg/lcsr.decode
 create mode 100644 target/mips/tcg/lcsr_translate.c
 create mode 100644 target/mips/tcg/sysemu/lcsr_helper.c

diff --git a/target/mips/cpu-defs.c.inc b/target/mips/cpu-defs.c.inc
index d45f245a6718..167c96cb2748 100644
--- a/target/mips/cpu-defs.c.inc
+++ b/target/mips/cpu-defs.c.inc
@@ -895,6 +895,15 @@ const mips_def_t mips_defs[] =
 .CP1_fcr31 = 0,
 .CP1_fcr31_rw_bitmask = 0xFF83,
 .MSAIR = (0x01 << MSAIR_ProcID) | (0x40 << MSAIR_Rev),
+.lcsr_cpucfg1 = (1 << CPUCFG1_FP) | (2 << CPUCFG1_FPREV) |
+(1 << CPUCFG1_MSA1) | (1 << CPUCFG1_LSLDR0) |
+(1 << CPUCFG1_LSPERF) | (1 << CPUCFG1_LSPERFX) |
+(1 << CPUCFG1_LSSYNCI) | (1 << CPUCFG1_LLEXC) |
+(1 << CPUCFG1_SCRAND) | (1 << CPUCFG1_MUALP) |
+(1 << CPUCFG1_KMUALEN) | (1 << CPUCFG1_ITLBT) |
+(1 << CPUCFG1_SFBP) | (1 << CPUCFG1_CDMAP),
+.lcsr_cpucfg2 = (1 << CPUCFG2_LEXT1) | (1 << CPUCFG2_LCSRP) |
+(1 << CPUCFG2_LDISBLIKELY),
 .SEGBITS = 48,
 .PABITS = 48,
 .insn_flags = CPU_MIPS64R2 | INSN_LOONGSON3A |
diff --git a/target/mips/cpu.c b/target/mips/cpu.c
index b7119cbbb459..e675b9178192 100644
--- a/target/mips/cpu.c
+++ b/target/mips/cpu.c
@@ -244,6 +244,8 @@ static void mips_cpu_reset_hold(Object *obj)
 env->CP0_PageGrain_rw_bitmask = env->cpu_model->CP0_PageGrain_rw_bitmask;
 env->CP0_PageGrain = env->cpu_model->CP0_PageGrain;
 env->CP0_EBaseWG_rw_bitmask = env->cpu_model->CP0_EBaseWG_rw_bitmask;
+env->lcsr_cpucfg1 = env->cpu_model->lcsr_cpucfg1;
+env->lcsr_cpucfg2 = env->cpu_model->lcsr_cpucfg2;
 env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
 env->active_fpu.fcr31_rw_bitmask = env->cpu_model->CP1_fcr31_rw_bitmask;
 env->active_fpu.fcr31 = env->cpu_model->CP1_fcr31;
@@ -507,6 +509,12 @@ static void mips_cpu_initfn(Object *obj)
 cpu->count_div = clock_new(OBJECT(obj), "clk-div-count");
 env->count_clock = clock_new(OBJECT(obj), "clk-count");
 env->cpu_model = mcc->cpu_def;
+if (mcc->cpu_def->lcsr_cpucfg2 & (1 << CPUCFG2_LCSRP)) {
+memory_region_init_io(>system_iocsr, OBJECT(cpu), NULL,
+env, "iocsr", UINT64_MAX);
+address_space_init(>address_space_iocsr,
+>system_iocsr, "IOCSR");
+}
 }
 
 static char *mips_cpu_type_name(const char *cpu_model)
diff --git a/target/mips/cpu.h b/target/mips/cpu.h
index 1b8107b0af86..f63b128ff3d3 100644
--- a/target/mips/cpu.h
+++ b/target/mips/cpu.h
@@ -3,6 +3,9 @@
 
 #include "cpu-qom.h"
 #include "exec/cpu-defs.h"
+#ifndef CONFIG_USER_ONLY
+#include "exec/memory.h"
+#endif
 #include "fpu/softfloat-types.h"
 #include "hw/clock.h"
 #include "mips-defs.h"
@@ -1068,6 +1071,33 @@ typedef struct CPUArchState {
  */
 int32_t CP0_DESAVE;
 target_ulong CP0_KScratch[MIPS_KSCRATCH_NUM];
+/*
+ * Loongson CSR CPUCFG registers
+ */
+uint32_t lcsr_cpucfg1;
+#define CPUCFG1_FP 0
+#define CPUCFG1_FPREV  1
+#define CPUCFG1_MMI4
+#define CPUCFG1_MSA1   5
+#define CPUCFG1_MSA2   6
+#define CPUCFG1_LSLDR0 16
+#define CPUCFG1_LSPERF 17
+#define CPUCFG1_LSPERFX 18
+#define CPUCFG1_LSSYNCI 19
+#d

[PATCH] target/mips: Rework cp0_timer with clock API

2023-05-21 Thread Jiaxun Yang
Previous implementation of MIPS cp0_timer computes a
cp0_count_ns based on input clock. However rounding
error of cp0_count_ns can affect precision of cp0_timer.

Using clock API and a divider for cp0_timer, so we can
use clock_ns_to_ticks/clock_ns_to_ticks to avoid rounding
issue.

Also workaround the situation that in such handler flow:

count = read_c0_count()
write_c0_compare(count)

If timer had not progressed when compare was written, the
interrupt would trigger again.

Signed-off-by: Jiaxun Yang 
---
This seems fixed MTTCG booting issue on malta 5kEc with SMP.
I'm going to do more test and see if we can enable MTTCG for
mips64el.
---
 target/mips/cpu.c  |  8 +---
 target/mips/cpu.h  |  3 ++-
 target/mips/sysemu/cp0_timer.c | 35 ++
 3 files changed, 26 insertions(+), 20 deletions(-)

diff --git a/target/mips/cpu.c b/target/mips/cpu.c
index 01e0fbe10db2..b7119cbbb459 100644
--- a/target/mips/cpu.c
+++ b/target/mips/cpu.c
@@ -449,9 +449,9 @@ static void mips_cp0_period_set(MIPSCPU *cpu)
 {
 CPUMIPSState *env = >env;
 
-env->cp0_count_ns = clock_ticks_to_ns(MIPS_CPU(cpu)->clock,
-  env->cpu_model->CCRes);
-assert(env->cp0_count_ns);
+clock_set_mul_div(cpu->count_div, env->cpu_model->CCRes, 1);
+clock_set_source(cpu->count_div, cpu->clock);
+clock_set_source(env->count_clock, cpu->count_div);
 }
 
 static void mips_cpu_realizefn(DeviceState *dev, Error **errp)
@@ -504,6 +504,8 @@ static void mips_cpu_initfn(Object *obj)
 
 cpu_set_cpustate_pointers(cpu);
 cpu->clock = qdev_init_clock_in(DEVICE(obj), "clk-in", NULL, cpu, 0);
+cpu->count_div = clock_new(OBJECT(obj), "clk-div-count");
+env->count_clock = clock_new(OBJECT(obj), "clk-count");
 env->cpu_model = mcc->cpu_def;
 }
 
diff --git a/target/mips/cpu.h b/target/mips/cpu.h
index 142c55af478b..1b8107b0af86 100644
--- a/target/mips/cpu.h
+++ b/target/mips/cpu.h
@@ -1160,8 +1160,8 @@ typedef struct CPUArchState {
 
 const mips_def_t *cpu_model;
 QEMUTimer *timer; /* Internal timer */
+Clock *count_clock; /* CP0_Count clock */
 target_ulong exception_base; /* ExceptionBase input to the core */
-uint64_t cp0_count_ns; /* CP0_Count clock period (in nanoseconds) */
 } CPUMIPSState;
 
 /**
@@ -1178,6 +1178,7 @@ struct ArchCPU {
 /*< public >*/
 
 Clock *clock;
+Clock *count_div; /* Divider for CP0_Count clock */
 CPUNegativeOffsetState neg;
 CPUMIPSState env;
 };
diff --git a/target/mips/sysemu/cp0_timer.c b/target/mips/sysemu/cp0_timer.c
index 70de95d338f8..9d2bcb0dea21 100644
--- a/target/mips/sysemu/cp0_timer.c
+++ b/target/mips/sysemu/cp0_timer.c
@@ -28,15 +28,26 @@
 #include "internal.h"
 
 /* MIPS R4K timer */
+static uint32_t cpu_mips_get_count_val(CPUMIPSState *env)
+{
+int64_t now_ns;
+now_ns = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
+return env->CP0_Count +
+(uint32_t)clock_ns_to_ticks(env->count_clock, now_ns);
+}
+
 static void cpu_mips_timer_update(CPUMIPSState *env)
 {
 uint64_t now_ns, next_ns;
 uint32_t wait;
 
 now_ns = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
-wait = env->CP0_Compare - env->CP0_Count -
-   (uint32_t)(now_ns / env->cp0_count_ns);
-next_ns = now_ns + (uint64_t)wait * env->cp0_count_ns;
+wait = env->CP0_Compare - cpu_mips_get_count_val(env);
+/* Clamp interval to overflow if virtual time had not progressed */
+if (!wait) {
+wait = UINT32_MAX;
+}
+next_ns = now_ns + clock_ticks_to_ns(env->count_clock, wait);
 timer_mod(env->timer, next_ns);
 }
 
@@ -64,7 +75,7 @@ uint32_t cpu_mips_get_count(CPUMIPSState *env)
 cpu_mips_timer_expire(env);
 }
 
-return env->CP0_Count + (uint32_t)(now_ns / env->cp0_count_ns);
+return cpu_mips_get_count_val(env);
 }
 }
 
@@ -79,9 +90,8 @@ void cpu_mips_store_count(CPUMIPSState *env, uint32_t count)
 env->CP0_Count = count;
 } else {
 /* Store new count register */
-env->CP0_Count = count -
-   (uint32_t)(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) /
-  env->cp0_count_ns);
+env->CP0_Count = count - (uint32_t)clock_ns_to_ticks(env->count_clock,
+qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
 /* Update timer timer */
 cpu_mips_timer_update(env);
 }
@@ -107,8 +117,8 @@ void cpu_mips_start_count(CPUMIPSState *env)
 void cpu_mips_stop_count(CPUMIPSState *env)
 {
 /* Store the current value */
-env->CP0_Count += (uint32_t)(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) /
- env->cp0_count_ns);
+env->CP0_Count += (uint32_t)clock_ns_to_ticks(env->count_clock,
+qe

[PATCH 4/4] tests/avocado: Add boot_linux_console test for loongson3-virt

2023-05-21 Thread Jiaxun Yang
Test loongson3-virt machine againt debian kernel and cpio rootfs.

Signed-off-by: Jiaxun Yang 
---
 tests/avocado/boot_linux_console.py | 46 +
 1 file changed, 46 insertions(+)

diff --git a/tests/avocado/boot_linux_console.py 
b/tests/avocado/boot_linux_console.py
index c0675809e641..fdb479448e47 100644
--- a/tests/avocado/boot_linux_console.py
+++ b/tests/avocado/boot_linux_console.py
@@ -191,6 +191,52 @@ def test_mips64el_fuloong2e(self):
 console_pattern = 'Kernel command line: %s' % kernel_command_line
 self.wait_for_console_pattern(console_pattern)
 
+def test_mips64el_loongson3_virt_cpio(self):
+"""
+:avocado: tags=arch:mips64el
+:avocado: tags=endian:little
+:avocado: tags=machine:loongson3-virt
+:avocado: tags=cpu:Loongson-3A1000
+:avocado: tags=device:liointc
+:avocado: tags=device:loongarch_ipi
+:avocado: tags=device:goldfish_rtc
+"""
+deb_url = ('http://snapshot.debian.org/archive/debian/'
+   '20230501T024743Z/pool/main/l/linux/'
+   'linux-image-5.10.0-22-loongson-3_5.10.178-3_mips64el.deb')
+deb_hash = 'af4fcc721b727df0bef31057325e4cc02725ae0c'
+deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash)
+kernel_path = self.extract_from_deb(deb_path,
+'/boot/vmlinuz-5.10.0-22-loongson-3')
+initrd_url = ('https://github.com/groeck/linux-build-test/'
+  'raw/8584a59e/rootfs/'
+  'mipsel64/rootfs.mipsel64r1.cpio.gz')
+initrd_hash = '1dbb8a396e916847325284dbe2151167'
+initrd_path_gz = self.fetch_asset(initrd_url, algorithm='md5',
+  asset_hash=initrd_hash)
+initrd_path = self.workdir + "rootfs.cpio"
+archive.gzip_uncompress(initrd_path_gz, initrd_path)
+
+self.vm.set_console()
+kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE
+   + 'console=ttyS0,115200 '
+   + 'rdinit=/sbin/init noreboot')
+self.vm.add_args('-kernel', kernel_path,
+ '-initrd', initrd_path,
+ '-append', kernel_command_line,
+ '-no-reboot')
+self.vm.launch()
+wait_for_console_pattern(self, 'Boot successful.')
+
+exec_command_and_wait_for_pattern(self, 'cat /proc/cpuinfo',
+'ICT Loongson-3')
+exec_command_and_wait_for_pattern(self, 'uname -a',
+'5.10.0-22-loongson-3')
+exec_command_and_wait_for_pattern(self, 'reboot',
+'reboot: Restarting system')
+# Wait for VM to shut down gracefully
+self.vm.wait()
+
 def test_mips_malta_cpio(self):
 """
 :avocado: tags=arch:mips
-- 
2.39.2 (Apple Git-143)




[PATCH 2/4] hw/intc/loongarch_ipi: Guard LoongArch only features with ifdef

2023-05-21 Thread Jiaxun Yang
IOCSR based send features are tied to LoongArch's CPU implmentation,
ifdef them for LoongArch only so we can build loongarch_ipi on MIPS.

Note that Loongson-3A4000 have IOCSR as well, so we may implement
those features for MIPS in future.

Signed-off-by: Jiaxun Yang 
---
 hw/intc/loongarch_ipi.c | 20 
 1 file changed, 20 insertions(+)

diff --git a/hw/intc/loongarch_ipi.c b/hw/intc/loongarch_ipi.c
index 3e453816524e..895a2ee96e1e 100644
--- a/hw/intc/loongarch_ipi.c
+++ b/hw/intc/loongarch_ipi.c
@@ -50,6 +50,7 @@ static uint64_t loongarch_ipi_readl(void *opaque, hwaddr 
addr, unsigned size)
 return ret;
 }
 
+#ifdef TARGET_LOONGARCH64
 static void send_ipi_data(CPULoongArchState *env, uint64_t val, hwaddr addr)
 {
 int i, mask = 0, data = 0;
@@ -140,6 +141,25 @@ static void any_send(uint64_t val)
 env = >env;
 send_ipi_data(env, val, addr);
 }
+#else
+static void ipi_send(uint64_t val)
+{
+qemu_log_mask(LOG_UNIMP, "%s: Unimplemented send 0x%" PRIx64 "\n",
+__func__, val);
+}
+
+static void mail_send(uint64_t val)
+{
+qemu_log_mask(LOG_UNIMP, "%s: Unimplemented send 0x%" PRIx64 "\n",
+__func__, val);
+}
+
+static void any_send(uint64_t val)
+{
+qemu_log_mask(LOG_UNIMP, "%s: Unimplemented send 0x%" PRIx64 "\n",
+__func__, val);
+}
+#endif
 
 static void loongarch_ipi_writel(void *opaque, hwaddr addr, uint64_t val,
  unsigned size)
-- 
2.39.2 (Apple Git-143)




[PATCH 0/4] hw/mips/loongson3_virt: Wire up loongarch_ipi device

2023-05-21 Thread Jiaxun Yang
Hi all,

This series wires up loongarch_ipi device for loongson3-virt,
which is required for SMP support.

We also add a new test for loongson3-virt for acceptance harness.

Thanks
- Jiaxun

Jiaxun Yang (4):
  hw/intc/loongarch_ipi: Bring back all 4 IPI mailboxes
  hw/intc/loongarch_ipi: Guard LoongArch only features with ifdef
  hw/mips/loongson3_virt: Wire up loongarch_ipi device
  tests/avocado: Add boot_linux_console test for loongson3-virt

 hw/intc/loongarch_ipi.c | 26 ++--
 hw/mips/Kconfig |  1 +
 hw/mips/loongson3_bootp.c   |  2 --
 hw/mips/loongson3_bootp.h   |  3 ++
 hw/mips/loongson3_virt.c| 20 +++--
 include/hw/intc/loongarch_ipi.h |  4 ++-
 tests/avocado/boot_linux_console.py | 46 +
 7 files changed, 94 insertions(+), 8 deletions(-)

-- 
2.39.2 (Apple Git-143)




[PATCH 3/4] hw/mips/loongson3_virt: Wire up loongarch_ipi device

2023-05-21 Thread Jiaxun Yang
Wire up loongarch_ipi device for loongson3_virt machine, so we
can have SMP support for TCG backend as well.

Signed-off-by: Jiaxun Yang 
---
 hw/mips/Kconfig   |  1 +
 hw/mips/loongson3_bootp.c |  2 --
 hw/mips/loongson3_bootp.h |  3 +++
 hw/mips/loongson3_virt.c  | 20 ++--
 4 files changed, 22 insertions(+), 4 deletions(-)

diff --git a/hw/mips/Kconfig b/hw/mips/Kconfig
index da3a37e215ec..7cb6c1def16c 100644
--- a/hw/mips/Kconfig
+++ b/hw/mips/Kconfig
@@ -40,6 +40,7 @@ config LOONGSON3V
 imply QXL if SPICE
 select SERIAL
 select GOLDFISH_RTC
+select LOONGARCH_IPI
 select LOONGSON_LIOINTC
 select PCI_DEVICES
 select PCI_EXPRESS_GENERIC_BRIDGE
diff --git a/hw/mips/loongson3_bootp.c b/hw/mips/loongson3_bootp.c
index f99af229327a..474d3556b2e5 100644
--- a/hw/mips/loongson3_bootp.c
+++ b/hw/mips/loongson3_bootp.c
@@ -25,8 +25,6 @@
 #include "hw/boards.h"
 #include "hw/mips/loongson3_bootp.h"
 
-#define LOONGSON3_CORE_PER_NODE 4
-
 static void init_cpu_info(void *g_cpuinfo, uint64_t cpu_freq)
 {
 struct efi_cpuinfo_loongson *c = g_cpuinfo;
diff --git a/hw/mips/loongson3_bootp.h b/hw/mips/loongson3_bootp.h
index d525ab745a69..55f98858a5f4 100644
--- a/hw/mips/loongson3_bootp.h
+++ b/hw/mips/loongson3_bootp.h
@@ -200,6 +200,8 @@ struct boot_params {
 struct efi_reset_system_t reset_system;
 };
 
+#define LOONGSON3_CORE_PER_NODE 4
+
 /* Overall MMIO & Memory layout */
 enum {
 VIRT_LOWMEM,
@@ -211,6 +213,7 @@ enum {
 VIRT_BIOS_ROM,
 VIRT_UART,
 VIRT_LIOINTC,
+VIRT_IPI,
 VIRT_PCIE_MMIO,
 VIRT_HIGHMEM
 };
diff --git a/hw/mips/loongson3_virt.c b/hw/mips/loongson3_virt.c
index 25534288dd81..a57245012598 100644
--- a/hw/mips/loongson3_virt.c
+++ b/hw/mips/loongson3_virt.c
@@ -38,6 +38,7 @@
 #include "hw/mips/loongson3_bootp.h"
 #include "hw/misc/unimp.h"
 #include "hw/intc/i8259.h"
+#include "hw/intc/loongarch_ipi.h"
 #include "hw/loader.h"
 #include "hw/isa/superio.h"
 #include "hw/pci/msi.h"
@@ -76,6 +77,7 @@ const MemMapEntry virt_memmap[] = {
 [VIRT_PCIE_ECAM] =   { 0x1a00, 0x200 },
 [VIRT_BIOS_ROM] ={ 0x1fc0,  0x20 },
 [VIRT_UART] ={ 0x1fe001e0,   0x8 },
+[VIRT_IPI] = { 0x3ff01000, 0x400 },
 [VIRT_LIOINTC] = { 0x3ff01400,  0x64 },
 [VIRT_PCIE_MMIO] =   { 0x4000,0x4000 },
 [VIRT_HIGHMEM] = { 0x8000,   0x0 }, /* Variable */
@@ -529,6 +531,8 @@ static void mips_loongson3_virt_init(MachineState *machine)
 clock_set_hz(cpuclk, DEF_LOONGSON3_FREQ);
 
 for (i = 0; i < machine->smp.cpus; i++) {
+int node = i / LOONGSON3_CORE_PER_NODE;
+int core = i % LOONGSON3_CORE_PER_NODE;
 int ip;
 
 /* init CPUs */
@@ -539,12 +543,24 @@ static void mips_loongson3_virt_init(MachineState 
*machine)
 cpu_mips_clock_init(cpu);
 qemu_register_reset(main_cpu_reset, cpu);
 
-if (i >= 4) {
+/* IPI controller is in kernel for KVM */
+if (!kvm_enabled()) {
+DeviceState *ipi;
+
+hwaddr base = ((hwaddr)node << 44) + virt_memmap[VIRT_IPI].base;
+base += core * 0x100;
+ipi = qdev_new(TYPE_LOONGARCH_IPI);
+sysbus_realize_and_unref(SYS_BUS_DEVICE(ipi), _fatal);
+qdev_connect_gpio_out(ipi, 0, cpu->env.irq[6]);
+sysbus_mmio_map(SYS_BUS_DEVICE(ipi), 0, base);
+}
+
+if (node > 0) {
 continue; /* Only node-0 can be connected to LIOINTC */
 }
 
 for (ip = 0; ip < 4 ; ip++) {
-int pin = i * 4 + ip;
+int pin = core * LOONGSON3_CORE_PER_NODE + ip;
 sysbus_connect_irq(SYS_BUS_DEVICE(liointc),
pin, cpu->env.irq[ip + 2]);
 }
-- 
2.39.2 (Apple Git-143)




[PATCH 1/4] hw/intc/loongarch_ipi: Bring back all 4 IPI mailboxes

2023-05-21 Thread Jiaxun Yang
As per "Loongson 3A5000/3B5000 Processor Reference Manual",
Loongson 3A5000's IPI implementation have 4 mailboxes per
core.

However, in 78464f023b54 ("hw/loongarch/virt: Modify ipi as
percpu device"), the number of IPI mailboxes was reduced to
one, which mismatches actual hardware.

It won't affect LoongArch based system as LoongArch boot code
only uses the first mailbox, however MIPS based Loongson boot
code uses all 4 mailboxes.

Fixes: 78464f023b54 ("hw/loongarch/virt: Modify ipi as percpu device")
Signed-off-by: Jiaxun Yang 
---
 hw/intc/loongarch_ipi.c | 6 +++---
 include/hw/intc/loongarch_ipi.h | 4 +++-
 2 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/hw/intc/loongarch_ipi.c b/hw/intc/loongarch_ipi.c
index d6ab91721ea1..3e453816524e 100644
--- a/hw/intc/loongarch_ipi.c
+++ b/hw/intc/loongarch_ipi.c
@@ -238,14 +238,14 @@ static void loongarch_ipi_init(Object *obj)
 
 static const VMStateDescription vmstate_ipi_core = {
 .name = "ipi-single",
-.version_id = 1,
-.minimum_version_id = 1,
+.version_id = 2,
+.minimum_version_id = 2,
 .fields = (VMStateField[]) {
 VMSTATE_UINT32(status, IPICore),
 VMSTATE_UINT32(en, IPICore),
 VMSTATE_UINT32(set, IPICore),
 VMSTATE_UINT32(clear, IPICore),
-VMSTATE_UINT32_ARRAY(buf, IPICore, 2),
+VMSTATE_UINT32_ARRAY(buf, IPICore, IPI_MBX_NUM * 2),
 VMSTATE_END_OF_LIST()
 }
 };
diff --git a/include/hw/intc/loongarch_ipi.h b/include/hw/intc/loongarch_ipi.h
index 664e050b926e..6c6194786e80 100644
--- a/include/hw/intc/loongarch_ipi.h
+++ b/include/hw/intc/loongarch_ipi.h
@@ -28,6 +28,8 @@
 #define MAIL_SEND_OFFSET  0
 #define ANY_SEND_OFFSET   (IOCSR_ANY_SEND - IOCSR_MAIL_SEND)
 
+#define IPI_MBX_NUM   4
+
 #define TYPE_LOONGARCH_IPI "loongarch_ipi"
 OBJECT_DECLARE_SIMPLE_TYPE(LoongArchIPI, LOONGARCH_IPI)
 
@@ -37,7 +39,7 @@ typedef struct IPICore {
 uint32_t set;
 uint32_t clear;
 /* 64bit buf divide into 2 32bit buf */
-uint32_t buf[2];
+uint32_t buf[IPI_MBX_NUM * 2];
 qemu_irq irq;
 } IPICore;
 
-- 
2.39.2 (Apple Git-143)




Re: [PATCH 21/22] tests/avocado: use http for mipsdistros.mips.com

2023-05-10 Thread Jiaxun Yang



> 2023年5月3日 10:12,Alex Bennée  写道:
> 
> As the cached assets have fallen out of our cache new attempts to
> fetch these binaries fail hard due to certificate expirty. It's hard
> to find a contact email for the domain as the root page of mipsdistros
> throws up some random XML. I suspect Amazon are merely the hosts.
> 
> Signed-off-by: Alex Bennée 
> Cc: Philippe Mathieu-Daudé 

Hi  all,

Just reached MIPS to get certification fixed.

Thanks
- Jiaxun


Re: [PATCH] linux-user: Fix mips fp64 executables loading

2023-04-05 Thread Jiaxun Yang



> 2023年4月4日 06:21,Daniil Kovalev  写道:
> 
> If a program requires fr1, we should set the FR bit of CP0 control status
> register and add F64 hardware flag. The corresponding `else if` branch
> statement is copied from the linux kernel sources (see `arch_check_elf` 
> function
> in linux/arch/mips/kernel/elf.c).
> 
> Signed-off-by: Daniil Kovalev 

Reviewed-by: Jiaxun Yang 

Thanks!

> ---
> linux-user/mips/cpu_loop.c | 5 -
> 1 file changed, 4 insertions(+), 1 deletion(-)
> 
> diff --git a/linux-user/mips/cpu_loop.c b/linux-user/mips/cpu_loop.c
> index d5c1c7941d..8735e58bad 100644
> --- a/linux-user/mips/cpu_loop.c
> +++ b/linux-user/mips/cpu_loop.c
> @@ -290,7 +290,10 @@ void target_cpu_copy_regs(CPUArchState *env, struct 
> target_pt_regs *regs)
> env->CP0_Status |= (1 << CP0St_FR);
> env->hflags |= MIPS_HFLAG_F64;
> }
> -} else  if (!prog_req.fre && !prog_req.frdefault &&
> +} else if (prog_req.fr1) {
> +env->CP0_Status |= (1 << CP0St_FR);
> +env->hflags |= MIPS_HFLAG_F64;
> +} else if (!prog_req.fre && !prog_req.frdefault &&
>   !prog_req.fr1 && !prog_req.single && !prog_req.soft) {
> fprintf(stderr, "qemu: Can't find a matching FPU mode\n");
> exit(1);
> -- 
> 2.40.0
> 




Re: [PATCH] linux-user/mips: Low down switchable NaN2008 requirement

2023-03-21 Thread Jiaxun Yang



> 2023年3月15日 08:18,Philippe Mathieu-Daudé  写道:
> 
> On 11/3/23 13:39, Jiaxun Yang wrote:
>>> 2023年3月9日 12:32,Philippe Mathieu-Daudé  写道:
>>> 
>>> Hi Jiaxun,
>>> 
>>> On 11/2/23 18:34, Jiaxun Yang wrote:
>>>> Previously switchable NaN2008 requires fcsr31.nan2008 to be writable
>>>> for guest. However as per MIPS arch spec this bit can never be writable.
>>>> This cause NaN2008 ELF to be rejected by QEMU.
>>>> NaN2008 can be enabled on R2~R5 processors, just make it available
>>>> unconditionally.
>>>> Signed-off-by: Jiaxun Yang 
>>>> ---
>>>>  linux-user/mips/cpu_loop.c | 3 +--
>>>>  1 file changed, 1 insertion(+), 2 deletions(-)
>>>> diff --git a/linux-user/mips/cpu_loop.c b/linux-user/mips/cpu_loop.c
>>>> index d5c1c7941d..b5c2ca4a3e 100644
>>>> --- a/linux-user/mips/cpu_loop.c
>>>> +++ b/linux-user/mips/cpu_loop.c
>>>> @@ -301,8 +301,7 @@ void target_cpu_copy_regs(CPUArchState *env, struct 
>>>> target_pt_regs *regs)
>>>>  }
>>>>  if (((info->elf_flags & EF_MIPS_NAN2008) != 0) !=
>>>>  ((env->active_fpu.fcr31 & (1 << FCR31_NAN2008)) != 0)) {
>>>> -if ((env->active_fpu.fcr31_rw_bitmask &
>>>> -  (1 << FCR31_NAN2008)) == 0) {
>>>> +if (!(env->insn_flags & ISA_MIPS_R2)) {
>>>>  fprintf(stderr, "ELF binary's NaN mode not supported by 
>>>> CPU\n");
>>>>  exit(1);
>>>>  }
>>> 
>>> Looking at R6.06 revision history:
>>> 
>>>  5.03 August 21, 2013
>>> 
>>>  • ABS2008 and NAN2008 fields of Table 5.7 “FCSR RegisterField
>>>Descriptions” were optional in release 3 and could be R/W,
>>>but as of release 5 are required, read-only, and preset by
>>>hardware.
>>> So I tried with this change:
>>> 
>>> -- >8 --
>>> diff --git a/target/mips/cpu.c b/target/mips/cpu.c
>>> index 05caf54999..5f1364ffaf 100644
>>> --- a/target/mips/cpu.c
>>> +++ b/target/mips/cpu.c
>>> @@ -243,6 +243,13 @@ static void mips_cpu_reset_hold(Object *obj)
>>> env->CP0_EBaseWG_rw_bitmask = env->cpu_model->CP0_EBaseWG_rw_bitmask;
>>> env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
>>> env->active_fpu.fcr31_rw_bitmask = env->cpu_model->CP1_fcr31_rw_bitmask;
>>> +if (env->insn_flags & ISA_MIPS_R5) {
>>> +assert(!(env->cpu_model->CP1_fcr31_rw_bitmask & (1 << 
>>> FCR31_ABS2008)));
>>> +assert(!(env->cpu_model->CP1_fcr31_rw_bitmask & (1 << 
>>> FCR31_NAN2008)));
>>> +} else if (env->insn_flags & ISA_MIPS_R3) {
>>> +assert(env->cpu_model->CP1_fcr31_rw_bitmask & (1 << 
>>> FCR31_ABS2008));
>>> +assert(env->cpu_model->CP1_fcr31_rw_bitmask & (1 << 
>>> FCR31_NAN2008));
>>> +}
>>> env->active_fpu.fcr31 = env->cpu_model->CP1_fcr31;
>>> env->msair = env->cpu_model->MSAIR;
>>> env->insn_flags = env->cpu_model->insn_flags;
>>> ---
>>> 
>>> and got:
>>> 
>>> $ for cpu in $(./qemu-system-mips64el -cpu help | cut -d\' -f2); do \
>>>  echo -n ${cpu}...;echo q \
>>>  | ./qemu-system-mips64el -accel tcg -cpu ${cpu} \
>>>   -S -monitor stdio 1> /dev/null || break; \
>>>  echo OK; done
>>> 4Kc...OK
>>> 4Km...OK
>>> 4KEcR1...OK
>>> 4KEmR1...OK
>>> 4KEc...OK
>>> 4KEm...OK
>>> 24Kc...OK
>>> 24KEc...OK
>>> 24Kf...OK
>>> 34Kf...OK
>>> 74Kf...OK
>>> M14K...OK
>>> M14Kc...OK
>>> P5600...OK
>>> mips32r6-generic...OK
>>> I7200...OK
>>> R4000...OK
>>> VR5432...OK
>>> 5Kc...OK
>>> 5Kf...OK
>>> 20Kc...OK
>>> MIPS64R2-generic...OK
>>> 5KEc...OK
>>> 5KEf...OK
>>> I6400...OK
>>> I6500...OK
>>> Loongson-2E...OK
>>> Loongson-2F...OK
>>> Loongson-3A1000...OK
>>> Loongson-3A4000...OK
>>> mips64dspr2...OK
>>> Octeon68XX...OK
>>> $
>> Well that’s because there is no CPU being marked as MIPS Release 3 in QEMU, 
>> and only
>> P5600 is marked as MIPS Release 5.
>> In reality R3 implementations are all advertising themself as R2, and later 
>> RCs of microAptiv
>> and interaptiv can all be configured as NaN2008 only. So for those CPUs we 
>> have binary compiled
>> with -march=mips32r2 -mnan=2008.
>> Given that default CPU of mips32r2 in QEMU is 24Kf, I think the best 
>> approach to deal with such
>> situation is to allow NaN2008 to be enabled for early processors for 
>> linux-user.
>> There is a NAN2008 Debian port for test:
>> http://repo.oss.cipunited.com/mipsel-nan2008/tarball/sid-mipsel-nan2008-20230309-1.tar.xz
> 
> $ qemu-mipsel -L sid-mipsel-nan2008-20230313-1/usr -cpu P5600 usr/bin/uname  
> -ms
> Linux mips
> 
> What about something like:

That would lost capability of testing NaN2008 binaries again other CPU models.

Thanks
- Jiaxun

> 
> -- >8 --
> --- a/linux-user/mips/target_elf.h
> +++ b/linux-user/mips/target_elf.h
> @@ -15,6 +15,9 @@ static inline const char *cpu_get_model(uint32_t eflags)
> if ((eflags & EF_MIPS_MACH) == EF_MIPS_MACH_5900) {
> return "R5900";
> }
> +if (eflags & EF_MIPS_NAN2008) {
> +return "P5600";
> +}
> return "24Kf";
> }
> #endif
> ---





Re: [PATCH] linux-user/mips: Low down switchable NaN2008 requirement

2023-03-11 Thread Jiaxun Yang



> 2023年3月9日 12:32,Philippe Mathieu-Daudé  写道:
> 
> Hi Jiaxun,
> 
> On 11/2/23 18:34, Jiaxun Yang wrote:
>> Previously switchable NaN2008 requires fcsr31.nan2008 to be writable
>> for guest. However as per MIPS arch spec this bit can never be writable.
>> This cause NaN2008 ELF to be rejected by QEMU.
>> NaN2008 can be enabled on R2~R5 processors, just make it available
>> unconditionally.
>> Signed-off-by: Jiaxun Yang 
>> ---
>>  linux-user/mips/cpu_loop.c | 3 +--
>>  1 file changed, 1 insertion(+), 2 deletions(-)
>> diff --git a/linux-user/mips/cpu_loop.c b/linux-user/mips/cpu_loop.c
>> index d5c1c7941d..b5c2ca4a3e 100644
>> --- a/linux-user/mips/cpu_loop.c
>> +++ b/linux-user/mips/cpu_loop.c
>> @@ -301,8 +301,7 @@ void target_cpu_copy_regs(CPUArchState *env, struct 
>> target_pt_regs *regs)
>>  }
>>  if (((info->elf_flags & EF_MIPS_NAN2008) != 0) !=
>>  ((env->active_fpu.fcr31 & (1 << FCR31_NAN2008)) != 0)) {
>> -if ((env->active_fpu.fcr31_rw_bitmask &
>> -  (1 << FCR31_NAN2008)) == 0) {
>> +if (!(env->insn_flags & ISA_MIPS_R2)) {
>>  fprintf(stderr, "ELF binary's NaN mode not supported by CPU\n");
>>  exit(1);
>>  }
> 
> Looking at R6.06 revision history:
> 
>  5.03 August 21, 2013
> 
>  • ABS2008 and NAN2008 fields of Table 5.7 “FCSR RegisterField
>Descriptions” were optional in release 3 and could be R/W,
>but as of release 5 are required, read-only, and preset by
>hardware.
> So I tried with this change:
> 
> -- >8 --
> diff --git a/target/mips/cpu.c b/target/mips/cpu.c
> index 05caf54999..5f1364ffaf 100644
> --- a/target/mips/cpu.c
> +++ b/target/mips/cpu.c
> @@ -243,6 +243,13 @@ static void mips_cpu_reset_hold(Object *obj)
> env->CP0_EBaseWG_rw_bitmask = env->cpu_model->CP0_EBaseWG_rw_bitmask;
> env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
> env->active_fpu.fcr31_rw_bitmask = env->cpu_model->CP1_fcr31_rw_bitmask;
> +if (env->insn_flags & ISA_MIPS_R5) {
> +assert(!(env->cpu_model->CP1_fcr31_rw_bitmask & (1 << 
> FCR31_ABS2008)));
> +assert(!(env->cpu_model->CP1_fcr31_rw_bitmask & (1 << 
> FCR31_NAN2008)));
> +} else if (env->insn_flags & ISA_MIPS_R3) {
> +assert(env->cpu_model->CP1_fcr31_rw_bitmask & (1 << FCR31_ABS2008));
> +assert(env->cpu_model->CP1_fcr31_rw_bitmask & (1 << FCR31_NAN2008));
> +}
> env->active_fpu.fcr31 = env->cpu_model->CP1_fcr31;
> env->msair = env->cpu_model->MSAIR;
> env->insn_flags = env->cpu_model->insn_flags;
> ---
> 
> and got:
> 
> $ for cpu in $(./qemu-system-mips64el -cpu help | cut -d\' -f2); do \
>  echo -n ${cpu}...;echo q \
>  | ./qemu-system-mips64el -accel tcg -cpu ${cpu} \
>   -S -monitor stdio 1> /dev/null || break; \
>  echo OK; done
> 4Kc...OK
> 4Km...OK
> 4KEcR1...OK
> 4KEmR1...OK
> 4KEc...OK
> 4KEm...OK
> 24Kc...OK
> 24KEc...OK
> 24Kf...OK
> 34Kf...OK
> 74Kf...OK
> M14K...OK
> M14Kc...OK
> P5600...OK
> mips32r6-generic...OK
> I7200...OK
> R4000...OK
> VR5432...OK
> 5Kc...OK
> 5Kf...OK
> 20Kc...OK
> MIPS64R2-generic...OK
> 5KEc...OK
> 5KEf...OK
> I6400...OK
> I6500...OK
> Loongson-2E...OK
> Loongson-2F...OK
> Loongson-3A1000...OK
> Loongson-3A4000...OK
> mips64dspr2...OK
> Octeon68XX...OK
> $

Well that’s because there is no CPU being marked as MIPS Release 3 in QEMU, and 
only
P5600 is marked as MIPS Release 5.

In reality R3 implementations are all advertising themself as R2, and later RCs 
of microAptiv
and interaptiv can all be configured as NaN2008 only. So for those CPUs we have 
binary compiled
with -march=mips32r2 -mnan=2008.

Given that default CPU of mips32r2 in QEMU is 24Kf, I think the best approach 
to deal with such
situation is to allow NaN2008 to be enabled for early processors for linux-user.

There is a NAN2008 Debian port for test: 

http://repo.oss.cipunited.com/mipsel-nan2008/tarball/sid-mipsel-nan2008-20230309-1.tar.xz

Thanks

> 
> Which CPU are you testing? Where can I get such ELF binary for testing?
> 
> Thanks,
> 
> Phil.





Re: [PATCH v2 0/2] MIPS Virt machine

2023-03-07 Thread Jiaxun Yang



> 2023年3月7日 21:07,Philippe Mathieu-Daudé  写道:
> 
> On 7/3/23 21:14, Philippe Mathieu-Daudé wrote:
>> On 7/3/23 21:07, Jiaxun Yang wrote:
>>> 
>>> 
>>>> 2023年3月7日 15:01,Philippe Mathieu-Daudé  写道:
>>>> 
>>>> On 4/3/23 23:38, Jiaxun Yang wrote:
>>>>> Hi there,
>>>>> This patchset is to add a new machine type for MIPS architecture, which
>>>>> is purely a VirtIO machine.
>>>> 
>>>>> Jiaxun Yang (2):
>>>>>   hw/misc: Add MIPS Trickbox device
>>>>>   hw/mips: Add MIPS virt board
>>>> Thanks, applied with following changes:
>>> 
>>> Thanks for those clean-ups!
> 
> Unfortunately I have to drop this due to the libfdt
> dependency, which fails the --disable-fdt job:
> https://gitlab.com/philmd/qemu/-/jobs/3890587748

Perhaps we should just select TARGET_NEED_FDT for all MIPS variants?

Thanks
- Jiaxun


Re: [PATCH v2 2/2] hw/mips: Add MIPS virt board

2023-03-07 Thread Jiaxun Yang



> 2023年3月7日 20:10,Philippe Mathieu-Daudé  写道:
> 
> On 4/3/23 23:38, Jiaxun Yang wrote:
>> MIPS virt board is design to utilize existing VirtIO infrastures
>> but also comptitable with MIPS's existing internal simulation tools.
>> It includes virtio-pci, virtio-mmio, pcie gpex, flash rom, fw_cfg,
>> goldfish-rtc and MIPS CPS system.
>> It should be able to cooperate with any MIPS CPU cores.
>> Signed-off-by: Jiaxun Yang 
>> ---
>> v1:
>>  - Rename to virt board
>>  - Convert BIOS flash to ROM
>>  - Cleanups
>> v2:
>>  - Fix fdt flash
>>  - Remove UP variant
>> ---
>>  MAINTAINERS |   7 +
>>  configs/devices/mips-softmmu/common.mak |   1 +
>>  docs/system/target-mips.rst |  22 +
>>  hw/mips/Kconfig |  17 +
>>  hw/mips/meson.build |   1 +
>>  hw/mips/virt.c  | 916 
>>  6 files changed, 964 insertions(+)
>>  create mode 100644 hw/mips/virt.c
> 
> 
>> +static void virt_machine_init(MachineState *machine)
>> +{
>> +MIPSVirtState *s = MIPS_VIRT_MACHINE(machine);
>> +MemoryRegion *system_memory = get_system_memory();
>> +const MemMapEntry *memmap = virt_memmap;
>> +int i;
>> +
>> +s->cpuclk = clock_new(OBJECT(machine), "cpu-refclk");
>> +clock_set_hz(s->cpuclk, VIRT_CPU_REF_CLK_FREQ);
>> +
>> +s->cps = MIPS_CPS(qdev_new(TYPE_MIPS_CPS));
>> +object_property_set_str(OBJECT(s->cps), "cpu-type", machine->cpu_type,
>> +_fatal);
>> +object_property_set_int(OBJECT(s->cps), "num-core", machine->smp.cpus,
>> +_fatal);
>> +qdev_connect_clock_in(DEVICE(s->cps), "clk-in", s->cpuclk);
>> +sysbus_realize(SYS_BUS_DEVICE(s->cps), _fatal);
> 
> qemu-system-mips64el: Property 'mips-cps.num-core' not found
> 
> I'm worried. I suppose you want this property:
> 
>  DEFINE_PROP_UINT32("num-vp", MIPSCPSState, num_vp, 1),

Yes

> 
> Is your series based on mainstream QEMU?


Whoops, rebasing issue not caught by CI…

Accidentally leaked part of following patch into this one, was trying to fix SMP
support for earlier CPUs.

Apologise for this.

Thanks
- Jiaxun








Re: [PATCH v2 0/2] MIPS Virt machine

2023-03-07 Thread Jiaxun Yang



> 2023年3月7日 15:01,Philippe Mathieu-Daudé  写道:
> 
> On 4/3/23 23:38, Jiaxun Yang wrote:
>> Hi there,
>> This patchset is to add a new machine type for MIPS architecture, which
>> is purely a VirtIO machine.
> 
>> Jiaxun Yang (2):
>>  hw/misc: Add MIPS Trickbox device
>>  hw/mips: Add MIPS virt board
> Thanks, applied with following changes:

Thanks for those clean-ups!

> 
> - remove pointless mask in mips_trickbox_write(),
> - declare QOM macros using OBJECT_DECLARE_SIMPLE_TYPE(),
> - declare machine type using DEFINE_TYPES(),
> - do not select PCI in Kconfig,

Hmm, PCI is sort of mandatory for this machine, any reason not to select it?

> - compile virt.o using fdt flags in meson.build,
> - use HWADDR_PRIx,
> - name MachineState variable 'ms',
> - fix conflict in docs/system/target-mips.rst,
> - fix style

Thanks.
- Jiaxun


[PATCH v2 0/2] MIPS Virt machine

2023-03-04 Thread Jiaxun Yang
Hi there,

This patchset is to add a new machine type for MIPS architecture, which
is purely a VirtIO machine.

It is design to utilize existing VirtIO infrastures but also comptitable
with MIPS's existing internal simulation tools.

It should be able to cooperate with any MIPS core and boot Generic MIPS
kernel.

Kernel patch available at: 
https://lore.kernel.org/linux-mips/20230304221524.47160-1-jiaxun.y...@flygoat.com/

Thanks

Jiaxun Yang (2):
  hw/misc: Add MIPS Trickbox device
  hw/mips: Add MIPS virt board

 MAINTAINERS |   7 +
 configs/devices/mips-softmmu/common.mak |   1 +
 docs/system/target-mips.rst |  22 +
 hw/mips/Kconfig |  17 +
 hw/mips/meson.build |   1 +
 hw/mips/virt.c  | 916 
 hw/misc/Kconfig |   3 +
 hw/misc/meson.build |   1 +
 hw/misc/mips_trickbox.c |  97 +++
 hw/misc/trace-events|   4 +
 include/hw/misc/mips_trickbox.h |  41 ++
 11 files changed, 1110 insertions(+)
 create mode 100644 hw/mips/virt.c
 create mode 100644 hw/misc/mips_trickbox.c
 create mode 100644 include/hw/misc/mips_trickbox.h

-- 
2.37.1 (Apple Git-137.1)




[PATCH v2 2/2] hw/mips: Add MIPS virt board

2023-03-04 Thread Jiaxun Yang
MIPS virt board is design to utilize existing VirtIO infrastures
but also comptitable with MIPS's existing internal simulation tools.

It includes virtio-pci, virtio-mmio, pcie gpex, flash rom, fw_cfg,
goldfish-rtc and MIPS CPS system.

It should be able to cooperate with any MIPS CPU cores.

Signed-off-by: Jiaxun Yang 
---
v1:
 - Rename to virt board
 - Convert BIOS flash to ROM
 - Cleanups
v2:
 - Fix fdt flash
 - Remove UP variant
---
 MAINTAINERS |   7 +
 configs/devices/mips-softmmu/common.mak |   1 +
 docs/system/target-mips.rst |  22 +
 hw/mips/Kconfig |  17 +
 hw/mips/meson.build |   1 +
 hw/mips/virt.c  | 916 
 6 files changed, 964 insertions(+)
 create mode 100644 hw/mips/virt.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 9adb6286279d..6884eaa78a76 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1296,6 +1296,13 @@ F: hw/mips/boston.c
 F: hw/pci-host/xilinx-pcie.c
 F: include/hw/pci-host/xilinx-pcie.h
 
+Virt
+M: Jiaxun Yang 
+S: Maintained
+F: hw/mips/virt.c
+F: hw/misc/mips_trickbox.c
+F: include/hw/misc/mips_trickbox.h
+
 OpenRISC Machines
 -
 or1k-sim
diff --git a/configs/devices/mips-softmmu/common.mak 
b/configs/devices/mips-softmmu/common.mak
index 7da99327a779..eb2c32b7c175 100644
--- a/configs/devices/mips-softmmu/common.mak
+++ b/configs/devices/mips-softmmu/common.mak
@@ -24,6 +24,7 @@ CONFIG_I8259=y
 CONFIG_MC146818RTC=y
 CONFIG_MIPS_CPS=y
 CONFIG_MIPS_ITU=y
+CONFIG_MIPS_VIRT=y
 CONFIG_MALTA=y
 CONFIG_PCNET_PCI=y
 CONFIG_MIPSSIM=y
diff --git a/docs/system/target-mips.rst b/docs/system/target-mips.rst
index 138441bdec1c..a11f08ab00a3 100644
--- a/docs/system/target-mips.rst
+++ b/docs/system/target-mips.rst
@@ -10,6 +10,8 @@ machine types are emulated:
 
 -  A generic ISA PC-like machine \"mips\"
 
+-  Generic Virtual Platform \"virt\"
+
 -  The MIPS Malta prototype board \"malta\"
 
 -  An ACER Pica \"pica61\". This machine needs the 64-bit emulator.
@@ -31,6 +33,26 @@ emulated:
 
 -  NE2000 network card
 
+The virt machine supports the following devices:
+
+- A range of MIPS CPUs, default is the P5600 (32-bit) or I6400 (64-bit)
+
+- MIPS CM (Coherence Manager)
+
+- CFI parallel NOR flash memory
+
+- 1 NS16550 compatible UART
+
+- 1 Google Goldfish RTC
+
+- 1 MIPS Trickbox device
+
+- 8 virtio-mmio transport devices
+
+- 1 generic PCIe host bridge
+
+- The fw_cfg device that allows a guest to obtain data from QEMU
+
 The Malta emulation supports the following devices:
 
 -  Core board with MIPS 24Kf CPU and Galileo system controller
diff --git a/hw/mips/Kconfig b/hw/mips/Kconfig
index da3a37e215ec..8a753ec2aee2 100644
--- a/hw/mips/Kconfig
+++ b/hw/mips/Kconfig
@@ -59,5 +59,22 @@ config MIPS_BOSTON
 select AHCI_ICH9
 select SERIAL
 
+config MIPS_VIRT
+bool
+imply PCI_DEVICES
+imply VIRTIO_VGA
+imply TEST_DEVICES
+select MIPS_CPS
+select MIPS_TRICKBOX
+select SERIAL
+select FW_CFG_MIPS
+select GOLDFISH_RTC
+select PCI
+select PCI_EXPRESS_GENERIC_BRIDGE
+select PFLASH_CFI01
+select VIRTIO_MMIO
+select FW_CFG_DMA
+select PLATFORM_BUS
+
 config FW_CFG_MIPS
 bool
diff --git a/hw/mips/meson.build b/hw/mips/meson.build
index 900613fc087f..5670c939fa7b 100644
--- a/hw/mips/meson.build
+++ b/hw/mips/meson.build
@@ -1,6 +1,7 @@
 mips_ss = ss.source_set()
 mips_ss.add(files('bootloader.c', 'mips_int.c'))
 mips_ss.add(when: 'CONFIG_FW_CFG_MIPS', if_true: files('fw_cfg.c'))
+mips_ss.add(when: 'CONFIG_MIPS_VIRT', if_true: files('virt.c'))
 mips_ss.add(when: 'CONFIG_LOONGSON3V', if_true: files('loongson3_bootp.c', 
'loongson3_virt.c'))
 mips_ss.add(when: 'CONFIG_MALTA', if_true: files('malta.c'))
 mips_ss.add(when: 'CONFIG_MIPS_CPS', if_true: files('cps.c'))
diff --git a/hw/mips/virt.c b/hw/mips/virt.c
new file mode 100644
index ..e4359f930104
--- /dev/null
+++ b/hw/mips/virt.c
@@ -0,0 +1,916 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+/*
+ * QEMU MIPS Virt Board
+ * Copyright (C) 2022 Jiaxun Yang 
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/units.h"
+#include "qemu/datadir.h"
+
+#include "chardev/char.h"
+#include "hw/block/flash.h"
+#include "hw/boards.h"
+#include "hw/char/serial.h"
+#include "hw/core/sysbus-fdt.h"
+#include "hw/display/ramfb.h"
+#include "hw/intc/goldfish_pic.h"
+#include "hw/loader-fit.h"
+#include "hw/loader.h"
+#include "hw/mips/bootloader.h"
+#include "hw/mips/cps.h"
+#include "hw/mips/cpudevs.h"
+#include "hw/mips/mips.h"
+#include "hw/misc/mips_trickbox.h"
+#include "hw/pci-host/gpex.h"
+#include "hw/pci/pci.h"
+#include "hw/platform-bus.h"
+#include "hw/qdev-clock.h"
+#include "hw/q

[PATCH v2 1/2] hw/misc: Add MIPS Trickbox device

2023-03-04 Thread Jiaxun Yang
MIPS Trickbox is a emulated device present in MIPS's IASIM simulator
for decades. It's capable of managing simulator status, signaling
interrupts, doing DMA and EJTAG signal stimulations.

For now we just use definition of this device and implement power
management related functions.

Signed-off-by: Jiaxun Yang 
---
v1: Rewording commit message
---
 hw/misc/Kconfig |  3 +
 hw/misc/meson.build |  1 +
 hw/misc/mips_trickbox.c | 97 +
 hw/misc/trace-events|  4 ++
 include/hw/misc/mips_trickbox.h | 41 ++
 5 files changed, 146 insertions(+)
 create mode 100644 hw/misc/mips_trickbox.c
 create mode 100644 include/hw/misc/mips_trickbox.h

diff --git a/hw/misc/Kconfig b/hw/misc/Kconfig
index 2ef5781ef87b..9f09da23c191 100644
--- a/hw/misc/Kconfig
+++ b/hw/misc/Kconfig
@@ -85,6 +85,9 @@ config STM32F4XX_EXTI
 config MIPS_ITU
 bool
 
+config MIPS_TRICKBOX
+bool
+
 config MPS2_FPGAIO
 bool
 select LED
diff --git a/hw/misc/meson.build b/hw/misc/meson.build
index fe869b98ca4d..1b58fd7df7b2 100644
--- a/hw/misc/meson.build
+++ b/hw/misc/meson.build
@@ -134,6 +134,7 @@ specific_ss.add(when: 'CONFIG_MAC_VIA', if_true: 
files('mac_via.c'))
 
 specific_ss.add(when: 'CONFIG_MIPS_CPS', if_true: files('mips_cmgcr.c', 
'mips_cpc.c'))
 specific_ss.add(when: 'CONFIG_MIPS_ITU', if_true: files('mips_itu.c'))
+specific_ss.add(when: 'CONFIG_MIPS_TRICKBOX', if_true: 
files('mips_trickbox.c'))
 
 softmmu_ss.add(when: 'CONFIG_SBSA_REF', if_true: files('sbsa_ec.c'))
 
diff --git a/hw/misc/mips_trickbox.c b/hw/misc/mips_trickbox.c
new file mode 100644
index ..20349b774b2f
--- /dev/null
+++ b/hw/misc/mips_trickbox.c
@@ -0,0 +1,97 @@
+/*
+ * SPDX-License-Identifier: LGPL-2.0-or-later
+ *
+ * MIPS Trickbox
+ */
+
+#include "qemu/osdep.h"
+#include "hw/sysbus.h"
+#include "qapi/error.h"
+#include "qemu/log.h"
+#include "qemu/module.h"
+#include "trace.h"
+#include "sysemu/runstate.h"
+#include "hw/misc/mips_trickbox.h"
+
+static uint64_t mips_trickbox_read(void *opaque, hwaddr addr, unsigned int 
size)
+{
+uint64_t value = 0;
+
+qemu_log_mask(LOG_UNIMP,
+"%s: unimplemented register read 0x%02"HWADDR_PRIx"\n",
+__func__, addr);
+trace_mips_trickbox_read(size, value);
+
+return 0;
+}
+
+static void mips_trickbox_write(void *opaque, hwaddr addr,
+   uint64_t val64, unsigned int size)
+{
+trace_mips_trickbox_write(size, val64);
+
+switch (addr) {
+case REG_SIM_CMD:
+switch (val64 & 0x) {
+case TRICK_PANIC:
+qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_PANIC);
+break;
+case TRICK_HALT:
+qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
+break;
+case TRICK_SUSPEND:
+qemu_system_suspend_request();
+break;
+case TRICK_RESET:
+qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
+break;
+case TRICK_PASS_MIPS:
+case TRICK_PASS_NANOMIPS:
+exit(EXIT_SUCCESS);
+break;
+case TRICK_FAIL_MIPS:
+case TRICK_FAIL_NANOMIPS:
+exit(EXIT_FAILURE);
+break;
+}
+break;
+default:
+qemu_log_mask(LOG_UNIMP,
+  "%s: unimplemented register write 0x%02"HWADDR_PRIx"\n",
+  __func__, addr);
+break;
+}
+}
+
+static const MemoryRegionOps mips_trickbox_ops = {
+.read = mips_trickbox_read,
+.write = mips_trickbox_write,
+.endianness = DEVICE_NATIVE_ENDIAN,
+.valid = {
+.min_access_size = 2,
+.max_access_size = 4
+}
+};
+
+static void mips_trickbox_init(Object *obj)
+{
+MIPSTrickboxState *s = MIPS_TRICKBOX(obj);
+
+memory_region_init_io(>mmio, obj, _trickbox_ops, s,
+  TYPE_MIPS_TRICKBOX, 0x100);
+sysbus_init_mmio(SYS_BUS_DEVICE(obj), >mmio);
+}
+
+static const TypeInfo mips_trickbox_info = {
+.name  = TYPE_MIPS_TRICKBOX,
+.parent= TYPE_SYS_BUS_DEVICE,
+.instance_size = sizeof(MIPSTrickboxState),
+.instance_init = mips_trickbox_init,
+};
+
+static void mips_trickbox_register_types(void)
+{
+type_register_static(_trickbox_info);
+}
+
+type_init(mips_trickbox_register_types)
diff --git a/hw/misc/trace-events b/hw/misc/trace-events
index c47876a90262..8603cf0d5ad2 100644
--- a/hw/misc/trace-events
+++ b/hw/misc/trace-events
@@ -279,3 +279,7 @@ virt_ctrl_instance_init(void *dev) "ctrl: %p"
 lasi_chip_mem_valid(uint64_t addr, uint32_t val) "access to addr 0x%"PRIx64" 
is %d"
 lasi_chip_read(uint64_t addr, uint32_t val) "addr 0x%"PRIx64" val 0x%08x"
 lasi_chip_write(uint64_t addr, uint32_t val

Re: [PATCH v3 03/20] target/mips: Drop tcg_temp_free from mips16e_translate.c.inc

2023-03-04 Thread Jiaxun Yang



> 2023年3月4日 18:18,Richard Henderson  写道:
> 
> Translators are no longer required to free tcg temporaries.
> 
> Signed-off-by: Richard Henderson 

Reviewed-by: Jiaxun Yang 

Thanks.

> ---
> 2.34.1
> 




[PATCH] hw/mips/gt64xxx_pci: Don't endian-swap GT_PCI0_CFGADDR

2023-02-23 Thread Jiaxun Yang
145e2198d749 ("hw/mips/gt64xxx_pci: Endian-swap using PCI_HOST_BRIDGE
MemoryRegionOps") converted CFGADDR/CFGDATA registers to use PCI_HOST_BRIDGE's
accessor facility and enabled byte swap for both CFGADDR/CFGDATA register.

However CFGADDR as a ISD internal register is not controled by MByteSwap
bit, it follows endian of all other ISD register, which means it ties to
little endian.

Move mapping of CFGADDR out of gt64120_update_pci_cfgdata_mapping to disable
endian-swapping.

This should fix some recent reports about poweroff hang.

Fixes: 145e2198d749 ("hw/mips/gt64xxx_pci: Endian-swap using PCI_HOST_BRIDGE 
MemoryRegionOps")
Signed-off-by: Jiaxun Yang 
---
 hw/pci-host/gt64120.c | 18 ++
 1 file changed, 6 insertions(+), 12 deletions(-)

diff --git a/hw/pci-host/gt64120.c b/hw/pci-host/gt64120.c
index f226d0342039..82c15edb4698 100644
--- a/hw/pci-host/gt64120.c
+++ b/hw/pci-host/gt64120.c
@@ -321,9 +321,6 @@ static void gt64120_isd_mapping(GT64120State *s)
 static void gt64120_update_pci_cfgdata_mapping(GT64120State *s)
 {
 /* Indexed on MByteSwap bit, see Table 158: PCI_0 Command, Offset: 0xc00 */
-static const MemoryRegionOps *pci_host_conf_ops[] = {
-_host_conf_be_ops, _host_conf_le_ops
-};
 static const MemoryRegionOps *pci_host_data_ops[] = {
 _host_data_be_ops, _host_data_le_ops
 };
@@ -339,15 +336,6 @@ static void 
gt64120_update_pci_cfgdata_mapping(GT64120State *s)
  * - Table 16: 32-bit PCI Transaction Endianess
  * - Table 158: PCI_0 Command, Offset: 0xc00
  */
-if (memory_region_is_mapped(>conf_mem)) {
-memory_region_del_subregion(>ISD_mem, >conf_mem);
-object_unparent(OBJECT(>conf_mem));
-}
-memory_region_init_io(>conf_mem, OBJECT(phb),
-  pci_host_conf_ops[s->regs[GT_PCI0_CMD] & 1],
-  s, "pci-conf-idx", 4);
-memory_region_add_subregion_overlap(>ISD_mem, GT_PCI0_CFGADDR << 2,
->conf_mem, 1);
 
 if (memory_region_is_mapped(>data_mem)) {
 memory_region_del_subregion(>ISD_mem, >data_mem);
@@ -1208,6 +1196,12 @@ static void gt64120_realize(DeviceState *dev, Error 
**errp)
 PCI_DEVFN(18, 0), TYPE_PCI_BUS);
 
 pci_create_simple(phb->bus, PCI_DEVFN(0, 0), "gt64120_pci");
+memory_region_init_io(>conf_mem, OBJECT(phb),
+  _host_conf_le_ops,
+  s, "pci-conf-idx", 4);
+memory_region_add_subregion_overlap(>ISD_mem, GT_PCI0_CFGADDR << 2,
+>conf_mem, 1);
+
 
 /*
  * The whole address space decoded by the GT-64120A doesn't generate
-- 
2.37.1 (Apple Git-137.1)




Re: [PATCH 3/3] hw/mips: Add MIPS virt board

2023-02-22 Thread Jiaxun Yang
Ping?

> 2023年2月6日 01:08,Jiaxun Yang  写道:
> 
> 
> 
>> 2023年2月5日 11:48,Philippe Mathieu-Daudé  写道:
>> 
>> Hi Jiaxun,
>> 
>> On 2/2/23 14:21, Jiaxun Yang wrote:
>>> MIPS virt board is design to utilize existing VirtIO infrastures
>>> but also comptitable with MIPS's existing internal simulation tools.
>>> It includes virtio-mmio, pcie gpex, flash rom, fw_cfg, goldfish-rtc,
>>> and optional goldfish_pic in case MIPS GIC is not present.
>> 
>> Is it worth using the CPS/GIC? Can't we using the goldfish PIC
>> regardless CPS availability? Did you run performance comparison?
> 
> goldfish_pic don’t have IPI infra so we must reinvent another SMP mechanism 
> :-(
> 
> The interrupt performance should be close as the interrupt handling flow is 
> almost
> the same.
> 
> Also it can help us prepare for I6400 vGIC support.
> 
> Thanks.
> - Jiaxun
> 
> 
>> 
>>> It should be able to cooperate with any MIPS CPU cores.
>>> Signed-off-by: Jiaxun Yang 
>>> ---
>>> v1:
>>> - Rename to virt board
>>> - Convert BIOS flash to ROM
>>> - Cleanups
>>> ---
>>> MAINTAINERS |7 +
>>> configs/devices/mips-softmmu/common.mak |1 +
>>> docs/system/target-mips.rst |   24 +
>>> hw/mips/Kconfig |   18 +
>>> hw/mips/meson.build |1 +
>>> hw/mips/virt.c  | 1015 +++
>>> 6 files changed, 1066 insertions(+)
>>> create mode 100644 hw/mips/virt.c
>> 
> 
> 




Re: [PATCH] linux-user/mips: Low down switchable NaN2008 requirement

2023-02-22 Thread Jiaxun Yang
Ping?

> 2023年2月11日 17:34,Jiaxun Yang  写道:
> 
> Previously switchable NaN2008 requires fcsr31.nan2008 to be writable
> for guest. However as per MIPS arch spec this bit can never be writable.
> This cause NaN2008 ELF to be rejected by QEMU.
> 
> NaN2008 can be enabled on R2~R5 processors, just make it available
> unconditionally.
> 
> Signed-off-by: Jiaxun Yang 
> ---
> linux-user/mips/cpu_loop.c | 3 +--
> 1 file changed, 1 insertion(+), 2 deletions(-)
> 
> diff --git a/linux-user/mips/cpu_loop.c b/linux-user/mips/cpu_loop.c
> index d5c1c7941d..b5c2ca4a3e 100644
> --- a/linux-user/mips/cpu_loop.c
> +++ b/linux-user/mips/cpu_loop.c
> @@ -301,8 +301,7 @@ void target_cpu_copy_regs(CPUArchState *env, struct 
> target_pt_regs *regs)
> }
> if (((info->elf_flags & EF_MIPS_NAN2008) != 0) !=
> ((env->active_fpu.fcr31 & (1 << FCR31_NAN2008)) != 0)) {
> -if ((env->active_fpu.fcr31_rw_bitmask &
> -  (1 << FCR31_NAN2008)) == 0) {
> +if (!(env->insn_flags & ISA_MIPS_R2)) {
> fprintf(stderr, "ELF binary's NaN mode not supported by CPU\n");
> exit(1);
> }
> -- 
> 2.37.1 (Apple Git-137.1)
> 




Re: [RFC PATCH] docs/about/deprecated: Deprecate 32-bit host systems

2023-02-18 Thread Jiaxun Yang



在2023年2月17日二月 下午6:57,Thomas Huth写道:
> On 17/02/2023 18.43, Philippe Mathieu-Daudé wrote:
>> (Cc'ing Huacai & Jiaxun).
>> 
>> On 17/2/23 17:38, Paolo Bonzini wrote:
>>> On 2/17/23 11:47, Daniel P. Berrangé wrote:
 On Fri, Feb 17, 2023 at 11:36:41AM +0100, Markus Armbruster wrote:
> I feel the discussion petered out without a conclusion.
>
> I don't think letting the status quo win by inertia is a good outcome
> here.
>
> Which 32-bit hosts are still useful, and why?

 Which 32-bit hosts does Linux still provide KVM  support for.
>>>
>>> All except ARM: MIPS, x86, PPC and RISC-V.
>>>
>>> I would like to remove x86, but encountered some objections.
>>>
>>> MIPS, nobody is really using it I think.
>> 
>> 32-bit was added in 2014, commit 222e7d11e7 ("target-mips: Enable KVM
>> support in build system"). I'm not aware of anybody using it (even
>> testing it). I don't have hardware to test it (neither time).
>
> Could you maybe suggest a kernel patch to remove it, to see what happens? 
> ... if nobody objects to the removal of the 32-bit MIPS KVM kernel support 
> and the patch gets merged, that would help us in the long run, I think.

I’m still occasionally testing 32-bit MIPS KVM support with MIPS P5600.

It works just fine so there is no need for further maintenance work.

I’d be sad to see the support go but I can live with it.

There are commercial users for MIPS 32 KVM but they’re all running customized 
downstream QEMU so I guess it’s fine.

Thanks
- Jiaxun

>
>   Thanks,
>Thomas

-- 
- Jiaxun



Re: [PATCH 1/3] target/mips: fix JALS32/J32 instruction handling for microMIPS

2023-02-15 Thread Jiaxun Yang



在2023年2月15日二月 下午8:50,Philippe Mathieu-Daudé写道:
> On 15/2/23 21:21, Richard Henderson wrote:
>> On 2/14/23 22:47, Marcin Nowakowski wrote:
>>> @@ -4860,6 +4860,7 @@ static void gen_compute_branch(DisasContext 
>>> *ctx, uint32_t opc,
>>>   target_ulong btgt = -1;
>>>   int blink = 0;
>>>   int bcond_compute = 0;
>>> +    int jal_mask = 0;
>> 
>> Better to limit the scope of the variable to the block below.
>> 
>>> @@ -4917,6 +4918,11 @@ static void gen_compute_branch(DisasContext 
>>> *ctx, uint32_t opc,
>>>   break;
>>>   case OPC_J:
>>>   case OPC_JAL:
>>> +    /* Jump to immediate */
>>> +    jal_mask = ctx->hflags & MIPS_HFLAG_M16 ? 0xF800 : 
>>> 0xF000;
>>> +    btgt = ((ctx->base.pc_next + insn_bytes) & jal_mask) |
>>> +    (uint32_t)offset;
>> 
>> Ideally we wouldn't have one huge helper function, and could pass down 
>> the mask from the translator.  But that's on-going cleanup.
>
> Yes, this is the approach taken in decodetree conversion.
>
> I hope to rebase / respin incorporating Jiaxun patches some day...

Which series are you referring?
Just caught some time so I might able to help.

>
>> Reviewed-by: Richard Henderson 
>> 
>> 
>> r~

-- 
- Jiaxun



Re: [RFC PATCH 9/9] hw/mips/itu: Pass SAAR using QOM link property

2023-02-13 Thread Jiaxun Yang



> 2023年2月3日 11:36,Philippe Mathieu-Daudé  写道:
> 
> QOM objects shouldn't access each other internals fields
> except using the QOM API.
> 
> mips_cps_realize() instantiates a TYPE_MIPS_ITU object, and
> directly sets the 'saar' pointer:
> 
>   if (saar_present) {
>   s->itu.saar = >CP0_SAAR;
>   }
> 
> In order to avoid that, pass the MIPS_CPU object via a QOM
> link property, and set the 'saar' pointer in mips_itu_realize().
> 
> Signed-off-by: Philippe Mathieu-Daudé 

Tested-by: Jiaxun Yang 
Reviewed-by: Jiaxun Yang 

Tested with ITU cases.

> ---
> RFC because not tested.
> ---
> hw/mips/cps.c  | 23 ++-
> hw/misc/mips_itu.c | 26 ++
> include/hw/misc/mips_itu.h |  5 ++---
> 3 files changed, 26 insertions(+), 28 deletions(-)
> 
> diff --git a/hw/mips/cps.c b/hw/mips/cps.c
> index 38acc57468..2b5269ebf1 100644
> --- a/hw/mips/cps.c
> +++ b/hw/mips/cps.c
> @@ -66,20 +66,17 @@ static bool cpu_mips_itu_supported(CPUMIPSState *env)
> static void mips_cps_realize(DeviceState *dev, Error **errp)
> {
> MIPSCPSState *s = MIPS_CPS(dev);
> -CPUMIPSState *env;
> -MIPSCPU *cpu;
> -int i;
> target_ulong gcr_base;
> bool itu_present = false;
> -bool saar_present = false;
> 
> if (!clock_get(s->clock)) {
> error_setg(errp, "CPS input clock is not connected to an output 
> clock");
> return;
> }
> 
> -for (i = 0; i < s->num_vp; i++) {
> -cpu = MIPS_CPU(object_new(s->cpu_type));
> +for (int i = 0; i < s->num_vp; i++) {
> +MIPSCPU *cpu = MIPS_CPU(object_new(s->cpu_type));
> +CPUMIPSState *env = >env;
> 
> /* All VPs are halted on reset. Leave powering up to CPC. */
> if (!object_property_set_bool(OBJECT(cpu), "start-powered-off", true,
> @@ -97,7 +94,6 @@ static void mips_cps_realize(DeviceState *dev, Error **errp)
> cpu_mips_irq_init_cpu(cpu);
> cpu_mips_clock_init(cpu);
> 
> -env = >env;
> if (cpu_mips_itu_supported(env)) {
> itu_present = true;
> /* Attach ITC Tag to the VP */
> @@ -107,22 +103,15 @@ static void mips_cps_realize(DeviceState *dev, Error 
> **errp)
> qemu_register_reset(main_cpu_reset, cpu);
> }
> 
> -cpu = MIPS_CPU(first_cpu);
> -env = >env;
> -saar_present = (bool)env->saarp;
> -
> /* Inter-Thread Communication Unit */
> if (itu_present) {
> object_initialize_child(OBJECT(dev), "itu", >itu, TYPE_MIPS_ITU);
> +object_property_set_link(OBJECT(>itu), "cpu[0]",
> + OBJECT(first_cpu), _abort);
> object_property_set_uint(OBJECT(>itu), "num-fifo", 16,
> _abort);
> object_property_set_uint(OBJECT(>itu), "num-semaphores", 16,
> _abort);
> -object_property_set_bool(OBJECT(>itu), "saar-present", 
> saar_present,
> - _abort);
> -if (saar_present) {
> -s->itu.saar = >CP0_SAAR;
> -}
> if (!sysbus_realize(SYS_BUS_DEVICE(>itu), errp)) {
> return;
> }
> @@ -158,7 +147,7 @@ static void mips_cps_realize(DeviceState *dev, Error 
> **errp)
> sysbus_mmio_get_region(SYS_BUS_DEVICE(>gic), 
> 0));
> 
> /* Global Configuration Registers */
> -gcr_base = env->CP0_CMGCRBase << 4;
> +gcr_base = MIPS_CPU(first_cpu)->env.CP0_CMGCRBase << 4;
> 
> object_initialize_child(OBJECT(dev), "gcr", >gcr, TYPE_MIPS_GCR);
> object_property_set_uint(OBJECT(>gcr), "num-vp", s->num_vp,
> diff --git a/hw/misc/mips_itu.c b/hw/misc/mips_itu.c
> index a06cdd10ea..0eda302db4 100644
> --- a/hw/misc/mips_itu.c
> +++ b/hw/misc/mips_itu.c
> @@ -93,10 +93,10 @@ void itc_reconfigure(MIPSITUState *tag)
> uint64_t size = (1 * KiB) + (am[1] & ITC_AM1_ADDR_MASK_MASK);
> bool is_enabled = (am[0] & ITC_AM0_EN_MASK) != 0;
> 
> -if (tag->saar_present) {
> -address = ((*(uint64_t *) tag->saar) & 0xE000ULL) << 4;
> -size = 1ULL << ((*(uint64_t *) tag->saar >> 1) & 0x1f);
> -is_enabled = *(uint64_t *) tag->saar & 1;
> +if (tag->saar) {
> +address = (tag->saar[0] & 0xE000ULL) << 4;
> +size = 1ULL << ((tag->saar[0] >> 1) & 0x1f);
> +is_enabled = tag->saar[0] 

[PATCH] linux-user/mips: Low down switchable NaN2008 requirement

2023-02-11 Thread Jiaxun Yang
Previously switchable NaN2008 requires fcsr31.nan2008 to be writable
for guest. However as per MIPS arch spec this bit can never be writable.
This cause NaN2008 ELF to be rejected by QEMU.

NaN2008 can be enabled on R2~R5 processors, just make it available
unconditionally.

Signed-off-by: Jiaxun Yang 
---
 linux-user/mips/cpu_loop.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/linux-user/mips/cpu_loop.c b/linux-user/mips/cpu_loop.c
index d5c1c7941d..b5c2ca4a3e 100644
--- a/linux-user/mips/cpu_loop.c
+++ b/linux-user/mips/cpu_loop.c
@@ -301,8 +301,7 @@ void target_cpu_copy_regs(CPUArchState *env, struct 
target_pt_regs *regs)
 }
 if (((info->elf_flags & EF_MIPS_NAN2008) != 0) !=
 ((env->active_fpu.fcr31 & (1 << FCR31_NAN2008)) != 0)) {
-if ((env->active_fpu.fcr31_rw_bitmask &
-  (1 << FCR31_NAN2008)) == 0) {
+if (!(env->insn_flags & ISA_MIPS_R2)) {
 fprintf(stderr, "ELF binary's NaN mode not supported by CPU\n");
 exit(1);
 }
-- 
2.37.1 (Apple Git-137.1)




Re: [PATCH 3/3] hw/mips: Add MIPS virt board

2023-02-05 Thread Jiaxun Yang



> 2023年2月5日 11:48,Philippe Mathieu-Daudé  写道:
> 
> Hi Jiaxun,
> 
> On 2/2/23 14:21, Jiaxun Yang wrote:
>> MIPS virt board is design to utilize existing VirtIO infrastures
>> but also comptitable with MIPS's existing internal simulation tools.
>> It includes virtio-mmio, pcie gpex, flash rom, fw_cfg, goldfish-rtc,
>> and optional goldfish_pic in case MIPS GIC is not present.
> 
> Is it worth using the CPS/GIC? Can't we using the goldfish PIC
> regardless CPS availability? Did you run performance comparison?

goldfish_pic don’t have IPI infra so we must reinvent another SMP mechanism :-(

The interrupt performance should be close as the interrupt handling flow is 
almost
the same.

Also it can help us prepare for I6400 vGIC support.

Thanks.
- Jiaxun


> 
>> It should be able to cooperate with any MIPS CPU cores.
>> Signed-off-by: Jiaxun Yang 
>> ---
>> v1:
>>  - Rename to virt board
>>  - Convert BIOS flash to ROM
>>  - Cleanups
>> ---
>>  MAINTAINERS |7 +
>>  configs/devices/mips-softmmu/common.mak |1 +
>>  docs/system/target-mips.rst |   24 +
>>  hw/mips/Kconfig |   18 +
>>  hw/mips/meson.build |1 +
>>  hw/mips/virt.c  | 1015 +++
>>  6 files changed, 1066 insertions(+)
>>  create mode 100644 hw/mips/virt.c
> 




[PATCH 1/3] docs/system: Remove "mips" board from target-mips.rst

2023-02-02 Thread Jiaxun Yang
This board had been deprecated long ago.

Signed-off-by: Jiaxun Yang 
---
 docs/system/target-mips.rst | 14 --
 1 file changed, 14 deletions(-)

diff --git a/docs/system/target-mips.rst b/docs/system/target-mips.rst
index 138441bdec..83239fb9df 100644
--- a/docs/system/target-mips.rst
+++ b/docs/system/target-mips.rst
@@ -8,8 +8,6 @@ endian options, ``qemu-system-mips``, ``qemu-system-mipsel``
 ``qemu-system-mips64`` and ``qemu-system-mips64el``. Five different
 machine types are emulated:
 
--  A generic ISA PC-like machine \"mips\"
-
 -  The MIPS Malta prototype board \"malta\"
 
 -  An ACER Pica \"pica61\". This machine needs the 64-bit emulator.
@@ -19,18 +17,6 @@ machine types are emulated:
 -  A MIPS Magnum R4000 machine \"magnum\". This machine needs the
64-bit emulator.
 
-The generic emulation is supported by Debian 'Etch' and is able to
-install Debian into a virtual disk image. The following devices are
-emulated:
-
--  A range of MIPS CPUs, default is the 24Kf
-
--  PC style serial port
-
--  PC style IDE disk
-
--  NE2000 network card
-
 The Malta emulation supports the following devices:
 
 -  Core board with MIPS 24Kf CPU and Galileo system controller
-- 
2.37.1 (Apple Git-137.1)




[PATCH 3/3] hw/mips: Add MIPS virt board

2023-02-02 Thread Jiaxun Yang
MIPS virt board is design to utilize existing VirtIO infrastures
but also comptitable with MIPS's existing internal simulation tools.

It includes virtio-mmio, pcie gpex, flash rom, fw_cfg, goldfish-rtc,
and optional goldfish_pic in case MIPS GIC is not present.

It should be able to cooperate with any MIPS CPU cores.

Signed-off-by: Jiaxun Yang 
---
v1:
 - Rename to virt board
 - Convert BIOS flash to ROM
 - Cleanups
---
 MAINTAINERS |7 +
 configs/devices/mips-softmmu/common.mak |1 +
 docs/system/target-mips.rst |   24 +
 hw/mips/Kconfig |   18 +
 hw/mips/meson.build |1 +
 hw/mips/virt.c  | 1015 +++
 6 files changed, 1066 insertions(+)
 create mode 100644 hw/mips/virt.c

diff --git a/MAINTAINERS b/MAINTAINERS
index c581c11a64..eb6b748786 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1291,6 +1291,13 @@ F: hw/mips/boston.c
 F: hw/pci-host/xilinx-pcie.c
 F: include/hw/pci-host/xilinx-pcie.h
 
+Virt
+M: Jiaxun Yang 
+S: Maintained
+F: hw/mips/virt.c
+F: hw/misc/mips_trickbox.c
+F: include/hw/misc/mips_trickbox.h
+
 OpenRISC Machines
 -
 or1k-sim
diff --git a/configs/devices/mips-softmmu/common.mak 
b/configs/devices/mips-softmmu/common.mak
index 7da99327a7..eb2c32b7c1 100644
--- a/configs/devices/mips-softmmu/common.mak
+++ b/configs/devices/mips-softmmu/common.mak
@@ -24,6 +24,7 @@ CONFIG_I8259=y
 CONFIG_MC146818RTC=y
 CONFIG_MIPS_CPS=y
 CONFIG_MIPS_ITU=y
+CONFIG_MIPS_VIRT=y
 CONFIG_MALTA=y
 CONFIG_PCNET_PCI=y
 CONFIG_MIPSSIM=y
diff --git a/docs/system/target-mips.rst b/docs/system/target-mips.rst
index 83239fb9df..8755a21bf4 100644
--- a/docs/system/target-mips.rst
+++ b/docs/system/target-mips.rst
@@ -8,6 +8,8 @@ endian options, ``qemu-system-mips``, ``qemu-system-mipsel``
 ``qemu-system-mips64`` and ``qemu-system-mips64el``. Five different
 machine types are emulated:
 
+- Generic Virtual Platform \"virt\"
+
 -  The MIPS Malta prototype board \"malta\"
 
 -  An ACER Pica \"pica61\". This machine needs the 64-bit emulator.
@@ -17,6 +19,28 @@ machine types are emulated:
 -  A MIPS Magnum R4000 machine \"magnum\". This machine needs the
64-bit emulator.
 
+The virt machine supports the following devices:
+
+- A range of MIPS CPUs, default is the P5600 (32-bit) or I6400 (64-bit)
+
+- MIPS CM (Coherence Manager) for SMP system with supported CPU
+
+- Google Goldfish PIC Interrupt Controller for system without CM
+
+- CFI parallel NOR flash memory
+
+- 1 NS16550 compatible UART
+
+- 1 Google Goldfish RTC
+
+- 1 MIPS Trickbox device
+
+- 8 virtio-mmio transport devices
+
+- 1 generic PCIe host bridge
+
+- The fw_cfg device that allows a guest to obtain data from QEMU
+
 The Malta emulation supports the following devices:
 
 -  Core board with MIPS 24Kf CPU and Galileo system controller
diff --git a/hw/mips/Kconfig b/hw/mips/Kconfig
index da3a37e215..0790ec55c3 100644
--- a/hw/mips/Kconfig
+++ b/hw/mips/Kconfig
@@ -59,5 +59,23 @@ config MIPS_BOSTON
 select AHCI_ICH9
 select SERIAL
 
+config MIPS_VIRT
+bool
+imply PCI_DEVICES
+imply VIRTIO_VGA
+imply TEST_DEVICES
+select MIPS_CPS
+select MIPS_TRICKBOX
+select SERIAL
+select FW_CFG_MIPS
+select GOLDFISH_RTC
+select GOLDFISH_PIC
+select PCI
+select PCI_EXPRESS_GENERIC_BRIDGE
+select PFLASH_CFI01
+select VIRTIO_MMIO
+select FW_CFG_DMA
+select PLATFORM_BUS
+
 config FW_CFG_MIPS
 bool
diff --git a/hw/mips/meson.build b/hw/mips/meson.build
index 900613fc08..5670c939fa 100644
--- a/hw/mips/meson.build
+++ b/hw/mips/meson.build
@@ -1,6 +1,7 @@
 mips_ss = ss.source_set()
 mips_ss.add(files('bootloader.c', 'mips_int.c'))
 mips_ss.add(when: 'CONFIG_FW_CFG_MIPS', if_true: files('fw_cfg.c'))
+mips_ss.add(when: 'CONFIG_MIPS_VIRT', if_true: files('virt.c'))
 mips_ss.add(when: 'CONFIG_LOONGSON3V', if_true: files('loongson3_bootp.c', 
'loongson3_virt.c'))
 mips_ss.add(when: 'CONFIG_MALTA', if_true: files('malta.c'))
 mips_ss.add(when: 'CONFIG_MIPS_CPS', if_true: files('cps.c'))
diff --git a/hw/mips/virt.c b/hw/mips/virt.c
new file mode 100644
index 00..e13b2c731b
--- /dev/null
+++ b/hw/mips/virt.c
@@ -0,0 +1,1015 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+/*
+ * QEMU MIPS Virt Board
+ * Copyright (C) 2022 Jiaxun Yang 
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/units.h"
+#include "qemu/datadir.h"
+
+#include "chardev/char.h"
+#include "hw/block/flash.h"
+#include "hw/boards.h"
+#include "hw/char/serial.h"
+#include "hw/core/sysbus-fdt.h"
+#include "hw/display/ramfb.h"
+#include "hw/intc/goldfish_pic.h"
+#include "hw/loader-fit.h"
+#include "hw/loader.h"
+#include "hw/mips/bootloader.h"
+#include "hw/mips/cps.h"
+#include "hw/mips/cpudevs.h"

[PATCH 2/3] hw/misc: Add MIPS Trickbox device

2023-02-02 Thread Jiaxun Yang
MIPS Trickbox is a emulated device present in MIPS's IASIM simulator
for decades. It's capable of managing simulator status, signaling
interrupts, doing DMA and EJTAG signal stimulations.

For now we just use definition of this device and implement power
management related functions.

Signed-off-by: Jiaxun Yang 
---
v1: Rewording commit message
---
 hw/misc/Kconfig |  3 +
 hw/misc/meson.build |  1 +
 hw/misc/mips_trickbox.c | 97 +
 hw/misc/trace-events|  4 ++
 include/hw/misc/mips_trickbox.h | 41 ++
 5 files changed, 146 insertions(+)
 create mode 100644 hw/misc/mips_trickbox.c
 create mode 100644 include/hw/misc/mips_trickbox.h

diff --git a/hw/misc/Kconfig b/hw/misc/Kconfig
index eaeddca277..a9637e6494 100644
--- a/hw/misc/Kconfig
+++ b/hw/misc/Kconfig
@@ -89,6 +89,9 @@ config STM32F4XX_EXTI
 config MIPS_ITU
 bool
 
+config MIPS_TRICKBOX
+bool
+
 config MPS2_FPGAIO
 bool
 select LED
diff --git a/hw/misc/meson.build b/hw/misc/meson.build
index 448e14b531..1ea92b266d 100644
--- a/hw/misc/meson.build
+++ b/hw/misc/meson.build
@@ -135,6 +135,7 @@ specific_ss.add(when: 'CONFIG_MAC_VIA', if_true: 
files('mac_via.c'))
 
 specific_ss.add(when: 'CONFIG_MIPS_CPS', if_true: files('mips_cmgcr.c', 
'mips_cpc.c'))
 specific_ss.add(when: 'CONFIG_MIPS_ITU', if_true: files('mips_itu.c'))
+specific_ss.add(when: 'CONFIG_MIPS_TRICKBOX', if_true: 
files('mips_trickbox.c'))
 
 softmmu_ss.add(when: 'CONFIG_SBSA_REF', if_true: files('sbsa_ec.c'))
 
diff --git a/hw/misc/mips_trickbox.c b/hw/misc/mips_trickbox.c
new file mode 100644
index 00..20349b774b
--- /dev/null
+++ b/hw/misc/mips_trickbox.c
@@ -0,0 +1,97 @@
+/*
+ * SPDX-License-Identifier: LGPL-2.0-or-later
+ *
+ * MIPS Trickbox
+ */
+
+#include "qemu/osdep.h"
+#include "hw/sysbus.h"
+#include "qapi/error.h"
+#include "qemu/log.h"
+#include "qemu/module.h"
+#include "trace.h"
+#include "sysemu/runstate.h"
+#include "hw/misc/mips_trickbox.h"
+
+static uint64_t mips_trickbox_read(void *opaque, hwaddr addr, unsigned int 
size)
+{
+uint64_t value = 0;
+
+qemu_log_mask(LOG_UNIMP,
+"%s: unimplemented register read 0x%02"HWADDR_PRIx"\n",
+__func__, addr);
+trace_mips_trickbox_read(size, value);
+
+return 0;
+}
+
+static void mips_trickbox_write(void *opaque, hwaddr addr,
+   uint64_t val64, unsigned int size)
+{
+trace_mips_trickbox_write(size, val64);
+
+switch (addr) {
+case REG_SIM_CMD:
+switch (val64 & 0x) {
+case TRICK_PANIC:
+qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_PANIC);
+break;
+case TRICK_HALT:
+qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
+break;
+case TRICK_SUSPEND:
+qemu_system_suspend_request();
+break;
+case TRICK_RESET:
+qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
+break;
+case TRICK_PASS_MIPS:
+case TRICK_PASS_NANOMIPS:
+exit(EXIT_SUCCESS);
+break;
+case TRICK_FAIL_MIPS:
+case TRICK_FAIL_NANOMIPS:
+exit(EXIT_FAILURE);
+break;
+}
+break;
+default:
+qemu_log_mask(LOG_UNIMP,
+  "%s: unimplemented register write 0x%02"HWADDR_PRIx"\n",
+  __func__, addr);
+break;
+}
+}
+
+static const MemoryRegionOps mips_trickbox_ops = {
+.read = mips_trickbox_read,
+.write = mips_trickbox_write,
+.endianness = DEVICE_NATIVE_ENDIAN,
+.valid = {
+.min_access_size = 2,
+.max_access_size = 4
+}
+};
+
+static void mips_trickbox_init(Object *obj)
+{
+MIPSTrickboxState *s = MIPS_TRICKBOX(obj);
+
+memory_region_init_io(>mmio, obj, _trickbox_ops, s,
+  TYPE_MIPS_TRICKBOX, 0x100);
+sysbus_init_mmio(SYS_BUS_DEVICE(obj), >mmio);
+}
+
+static const TypeInfo mips_trickbox_info = {
+.name  = TYPE_MIPS_TRICKBOX,
+.parent= TYPE_SYS_BUS_DEVICE,
+.instance_size = sizeof(MIPSTrickboxState),
+.instance_init = mips_trickbox_init,
+};
+
+static void mips_trickbox_register_types(void)
+{
+type_register_static(_trickbox_info);
+}
+
+type_init(mips_trickbox_register_types)
diff --git a/hw/misc/trace-events b/hw/misc/trace-events
index c47876a902..8603cf0d5a 100644
--- a/hw/misc/trace-events
+++ b/hw/misc/trace-events
@@ -279,3 +279,7 @@ virt_ctrl_instance_init(void *dev) "ctrl: %p"
 lasi_chip_mem_valid(uint64_t addr, uint32_t val) "access to addr 0x%"PRIx64" 
is %d"
 lasi_chip_read(uint64_t addr, uint32_t val) "addr 0x%"PRIx64" val 0x%08x"
 lasi_chip_write(uint64_t addr, uint32_t val) "addr 0x%&q

[PATCH 0/3] MIPS Virt machine

2023-02-02 Thread Jiaxun Yang
Hi there,

This patchset is to add a new machine type for MIPS architecture, which
is purely a VirtIO machine.

It is design to utilize existing VirtIO infrastures but also comptitable
with MIPS's existing internal simulation tools.

It should be able to cooperate with any MIPS core and boot Generic MIPS
kernel.

For testing purpose I've built little endian kernel[1] to work with this
machine with R4X00, loongson2f, octeon, mips32r2, mips64r2 and mips64r6. 

TODO:
- Documentation
- Test against big endian kernel
- nanoMIPS options

Thanks

Jiaxun Yang (3):
  docs/system: Remove "mips" board from target-mips.rst
  hw/misc: Add MIPS Trickbox device
  hw/mips: Add MIPS virt board

 MAINTAINERS |7 +
 configs/devices/mips-softmmu/common.mak |1 +
 docs/system/target-mips.rst |   26 +-
 hw/mips/Kconfig |   18 +
 hw/mips/meson.build |1 +
 hw/mips/virt.c  | 1015 +++
 hw/misc/Kconfig |3 +
 hw/misc/meson.build |1 +
 hw/misc/mips_trickbox.c |   97 +++
 hw/misc/trace-events|4 +
 include/hw/misc/mips_trickbox.h |   41 +
 11 files changed, 1206 insertions(+), 8 deletions(-)
 create mode 100644 hw/mips/virt.c
 create mode 100644 hw/misc/mips_trickbox.c
 create mode 100644 include/hw/misc/mips_trickbox.h

-- 
2.37.1 (Apple Git-137.1)




Re: [PATCH-for-8.0 6/7] hw/mips/bootloader: Implement nanoMIPS SW opcode

2022-12-11 Thread Jiaxun Yang



> 2022年12月10日 15:55,Philippe Mathieu-Daudé  写道:
> 
> Signed-off-by: Philippe Mathieu-Daudé 
> ---
> hw/mips/bootloader.c | 25 -
> 1 file changed, 24 insertions(+), 1 deletion(-)
> 
> diff --git a/hw/mips/bootloader.c b/hw/mips/bootloader.c
> index cc3df385df..541b59bf84 100644
> --- a/hw/mips/bootloader.c
> +++ b/hw/mips/bootloader.c
> @@ -177,9 +177,32 @@ static void bl_gen_ori(void **p, bl_reg rt, bl_reg rs, 
> uint16_t imm)
> }
> }
> 
> +static void bl_gen_sw_nm(void **ptr, bl_reg rt, uint8_t rs, uint16_t offset)
> +{
> +uint16_t *p = (uint16_t *)*ptr;
> +uint32_t insn = 0;
> +
> +insn = deposit32(insn, 26, 6, 0b11);
> +insn = deposit32(insn, 21, 5, rt);
> +insn = deposit32(insn, 16, 5, rs);
> +insn = deposit32(insn, 12, 4, 0b1001);
> +insn = deposit32(insn, 0, 12, offset);
> +
> +stw_p(p, insn >> 16);
> +p++;
> +stw_p(p, insn >> 0);
> +p++;

Think we can have a helper function like st_nm32_p.

Thanks
- Jiaxun

> +
> +*ptr = p;
> +}
> +
> static void bl_gen_sw(void **p, bl_reg rt, uint8_t base, uint16_t offset)
> {
> -bl_gen_i_type(p, 0x2b, base, rt, offset);
> +if (bootcpu_supports_isa(ISA_NANOMIPS32)) {
> +bl_gen_sw_nm(p, rt, base, offset);
> +} else {
> +bl_gen_i_type(p, 0x2b, base, rt, offset);
> +}
> }
> 
> static void bl_gen_sd(void **p, bl_reg rt, uint8_t base, uint16_t offset)
> -- 
> 2.38.1
> 




Re: [PATCH-for-8.0 4/7] hw/mips/bootloader: Implement nanoMIPS LUI opcode

2022-12-11 Thread Jiaxun Yang



> 2022年12月10日 16:01,Philippe Mathieu-Daudé  写道:
> 
> On 10/12/22 16:54, Philippe Mathieu-Daudé wrote:
>> Signed-off-by: Philippe Mathieu-Daudé 
>> ---
>>  hw/mips/bootloader.c | 29 ++---
>>  1 file changed, 26 insertions(+), 3 deletions(-)
>> diff --git a/hw/mips/bootloader.c b/hw/mips/bootloader.c
>> index 7f7d938f2e..997e74ee52 100644
>> --- a/hw/mips/bootloader.c
>> +++ b/hw/mips/bootloader.c
>> @@ -120,11 +120,34 @@ static void bl_gen_jalr(void **p, bl_reg rs)
>>  bl_gen_r_type(p, 0, rs, 0, BL_REG_RA, 0, 0x09);
>>  }
>>  +static void bl_gen_lui_nm(void **ptr, bl_reg rt, uint32_t imm20)
>> +{
>> +uint16_t *p = (uint16_t *)*ptr;
>> +uint32_t insn = 0;
> 
> Hmm we should check if imm20 fits in 20-bit.

Perhaps it will be easier to use 48bit addiu instruction to generate LI?

Thanks
- Jiaxun

> 
>> +insn = deposit32(insn, 26, 6, 0b111000);
>> +insn = deposit32(insn, 21, 5, rt);
>> +insn = deposit32(insn, 12, 9, extract32(imm20, 12, 9));
>> +insn = deposit32(insn, 2, 10, extract32(imm20, 21, 10));
>> +insn = deposit32(insn, 0, 1, sextract32(imm20, 31, 1));
>> +
>> +stw_p(p, insn >> 16);
>> +p++;
>> +stw_p(p, insn >> 0);
>> +p++;
>> +
>> +*ptr = p;
>> +}





Re: CVMSEG Emulation

2022-12-09 Thread Jiaxun Yang



> 2022年12月9日 17:44,Christopher Wrogg  写道:
> 
> I tried both.
> 
> Option 1 
> What I did:
> #undef TARGET_VIRT_ADDR_SPACE_BITS and #define 
> TARGET_VIRT_ADDR_SPACE_BITS 64
> The Result:
> perror reports "Cannot allocate memory"
> Option 2: 
> What I did:
> TARGET_VIRT_ADDR_SPACE_BITS for me is 30 so I masked by 0x3FFF
> The Result:
> The segfault persists and gdb reports the memory as inaccessible.

Hmm this looks wired for me, by no chance TARGET_VIRT_ADDR_SPACE_BITS for MIPS
can be 30, on N64 ABI build it should be 48 and 32 for N32 or O32 build.

It is defined in target/mips/cpu-param.h .

Thanks.

> 
> On Thu, Dec 8, 2022 at 4:55 PM Jiaxun Yang  wrote:
> 
> Hi,
> 
> This address range is located in KSEG3… Doesn’t seems to be a good location
> for userspace program.
> 
> I think you have two options to make target_mmap work, the first would be 
> rising
> TARGET_VIRT_ADDR_SPACE_BITS to 64 bit. That may break some user space
> applications storing pointer tags on higher bits.
> 
> The second would be mask CVMSEG base with TARGET_VIRT_ADDR_SPACE_BITS
> before mmap, As higher VM address bits will be dropped when addressing guest 
> VM,
> that should provide a similar behaviour. Though you’ll have multiple alias 
> for CVMSEG in
> memory and application will be able to access CVMSEG with bits higher than
> TARGET_VIRT_ADDR_SPACE_BITS set to any value. Don’t know if it will break 
> anything,
> AFAIK normal applications won't use this range.
> 
> Thanks
> - Jiaxun 
> 
> 
> > 2022年12月8日 15:08,Christopher Wrogg  写道:
> > 
> > In userspace emulation how do I make a set of addresses always valid and 
> > initialized to 0 even though the process does not map it in? In particular 
> > I want to map the CVMSEG for Cavium qemu-mips64 and qemu-mipsn32. The 
> > addresses would be 0x8000 - 0xBFFF. I've looked at 
> > target_mmap but it can't handle addresses that large. The lack of an 
> > emulated mmu for 64 bit guests is going to be a problem.
> 




Re: CVMSEG Emulation

2022-12-08 Thread Jiaxun Yang


Hi,

This address range is located in KSEG3… Doesn’t seems to be a good location
for userspace program.

I think you have two options to make target_mmap work, the first would be rising
TARGET_VIRT_ADDR_SPACE_BITS to 64 bit. That may break some user space
applications storing pointer tags on higher bits.

The second would be mask CVMSEG base with TARGET_VIRT_ADDR_SPACE_BITS
before mmap, As higher VM address bits will be dropped when addressing guest VM,
that should provide a similar behaviour. Though you’ll have multiple alias for 
CVMSEG in
memory and application will be able to access CVMSEG with bits higher than
TARGET_VIRT_ADDR_SPACE_BITS set to any value. Don’t know if it will break 
anything,
AFAIK normal applications won't use this range.

Thanks
- Jiaxun 


> 2022年12月8日 15:08,Christopher Wrogg  写道:
> 
> In userspace emulation how do I make a set of addresses always valid and 
> initialized to 0 even though the process does not map it in? In particular I 
> want to map the CVMSEG for Cavium qemu-mips64 and qemu-mipsn32. The addresses 
> would be 0x8000 - 0xBFFF. I've looked at target_mmap 
> but it can't handle addresses that large. The lack of an emulated mmu for 64 
> bit guests is going to be a problem.




Re: [RFC PATCH 3/3] hw/mips: Add MIPS VirtIO board

2022-11-25 Thread Jiaxun Yang



> 2022年11月25日 13:25,Philippe Mathieu-Daudé  写道:
> 
> On 24/11/22 22:29, Jiaxun Yang wrote:
>> MIPS VirtIO board is design to utilize existing VirtIO infrastures
>> but also comptitable with MIPS's existing internal simulation tools.
>> It includes virtio-mmio, pcie gpex, flash rom, fw_cfg, goldfish-rtc,
>> and optional goldfish_pic in case MIPS GIC is not present.
>> It should be able to cooperate with any MIPS CPU cores.
>> Signed-off-by: Jiaxun Yang 
>> ---
>>  configs/devices/mips-softmmu/common.mak |1 +
>>  hw/mips/Kconfig |   18 +
>>  hw/mips/meson.build |1 +
>>  hw/mips/virt.c  | 1039 +++
>>  4 files changed, 1059 insertions(+)
>>  create mode 100644 hw/mips/virt.c
>> diff --git a/configs/devices/mips-softmmu/common.mak 
>> b/configs/devices/mips-softmmu/common.mak
>> index 416161f833..534b7843eb 100644
>> --- a/configs/devices/mips-softmmu/common.mak
>> +++ b/configs/devices/mips-softmmu/common.mak
>> @@ -29,6 +29,7 @@ CONFIG_MC146818RTC=y
>>  CONFIG_EMPTY_SLOT=y
>>  CONFIG_MIPS_CPS=y
>>  CONFIG_MIPS_ITU=y
>> +CONFIG_MIPS_VIRT=y
> 
> Is there any value adding the 32-bit machine, or can we just add it as 64-bit?

Well because it can boot with generic kernel so people can still test it again 
various
32bit cores like old 4K / 24K / and newer P5600 / Ingenic XBurst / I7200.

There will be some new 32-bit nanoMIPS products,  though they will run highly 
customised
software instead of Linux stuff :-(

> 
>> +struct MIPSVirtState {
>> +MachineState parent;
>> +
>> +Notifier machine_done;
>> +Clock *cpuclk;
>> +DeviceState *platform_bus_dev;
>> +MIPSCPSState *cps;
>> +DeviceState *pic;
>> +PFlashCFI01 *flash[2];
> 
> We should be fine with 1 ROM for CODE and 1 flash for VARS,
> see my previous comments on the LoongArch virt machine:
> 
> https://lore.kernel.org/qemu-devel/2f381d06-842f-ac8b-085c-0419675a4...@linaro.org/
> https://lore.kernel.org/qemu-devel/b62401b2-3a12-e89d-6953-b40dd170b...@linaro.org/

Will use use this scheme, thanks.
Any recommendation on size of those two regions?

Thanks
- Jiaxun

> 
>> +FWCfgState *fw_cfg;
>> +
>> +MIPSVirtPlatType plat_type;
>> +int fdt_size;
>> +};





[RFC PATCH 3/3] hw/mips: Add MIPS VirtIO board

2022-11-24 Thread Jiaxun Yang
MIPS VirtIO board is design to utilize existing VirtIO infrastures
but also comptitable with MIPS's existing internal simulation tools.

It includes virtio-mmio, pcie gpex, flash rom, fw_cfg, goldfish-rtc,
and optional goldfish_pic in case MIPS GIC is not present.

It should be able to cooperate with any MIPS CPU cores.

Signed-off-by: Jiaxun Yang 
---
 configs/devices/mips-softmmu/common.mak |1 +
 hw/mips/Kconfig |   18 +
 hw/mips/meson.build |1 +
 hw/mips/virt.c  | 1039 +++
 4 files changed, 1059 insertions(+)
 create mode 100644 hw/mips/virt.c

diff --git a/configs/devices/mips-softmmu/common.mak 
b/configs/devices/mips-softmmu/common.mak
index 416161f833..534b7843eb 100644
--- a/configs/devices/mips-softmmu/common.mak
+++ b/configs/devices/mips-softmmu/common.mak
@@ -29,6 +29,7 @@ CONFIG_MC146818RTC=y
 CONFIG_EMPTY_SLOT=y
 CONFIG_MIPS_CPS=y
 CONFIG_MIPS_ITU=y
+CONFIG_MIPS_VIRT=y
 CONFIG_MALTA=y
 CONFIG_PCNET_PCI=y
 CONFIG_MIPSSIM=y
diff --git a/hw/mips/Kconfig b/hw/mips/Kconfig
index 725525358d..419a729479 100644
--- a/hw/mips/Kconfig
+++ b/hw/mips/Kconfig
@@ -57,5 +57,23 @@ config MIPS_BOSTON
 select AHCI_ICH9
 select SERIAL
 
+config MIPS_VIRT
+bool
+imply PCI_DEVICES
+imply VIRTIO_VGA
+imply TEST_DEVICES
+select MIPS_CPS
+select MIPS_TRICKBOX
+select SERIAL
+select FW_CFG_MIPS
+select GOLDFISH_RTC
+select GOLDFISH_PIC
+select PCI
+select PCI_EXPRESS_GENERIC_BRIDGE
+select PFLASH_CFI01
+select VIRTIO_MMIO
+select FW_CFG_DMA
+select PLATFORM_BUS
+
 config FW_CFG_MIPS
 bool
diff --git a/hw/mips/meson.build b/hw/mips/meson.build
index dd0101ad4d..287425cb10 100644
--- a/hw/mips/meson.build
+++ b/hw/mips/meson.build
@@ -1,6 +1,7 @@
 mips_ss = ss.source_set()
 mips_ss.add(files('bootloader.c', 'mips_int.c'))
 mips_ss.add(when: 'CONFIG_FW_CFG_MIPS', if_true: files('fw_cfg.c'))
+mips_ss.add(when: 'CONFIG_MIPS_VIRT', if_true: files('virt.c'))
 mips_ss.add(when: 'CONFIG_LOONGSON3V', if_true: files('loongson3_bootp.c', 
'loongson3_virt.c'))
 mips_ss.add(when: 'CONFIG_MALTA', if_true: files('gt64xxx_pci.c', 'malta.c'))
 mips_ss.add(when: 'CONFIG_MIPS_CPS', if_true: files('cps.c'))
diff --git a/hw/mips/virt.c b/hw/mips/virt.c
new file mode 100644
index 00..d7a1d211ac
--- /dev/null
+++ b/hw/mips/virt.c
@@ -0,0 +1,1039 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+/*
+ * QEMU MIPS VirtIO Board
+ * Copyright (C) 2022 Jiaxun Yang 
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/units.h"
+#include "qemu/datadir.h"
+
+#include "chardev/char.h"
+#include "hw/block/flash.h"
+#include "hw/boards.h"
+#include "hw/char/serial.h"
+#include "hw/core/sysbus-fdt.h"
+#include "hw/display/ramfb.h"
+#include "hw/intc/goldfish_pic.h"
+#include "hw/loader-fit.h"
+#include "hw/loader.h"
+#include "hw/mips/bootloader.h"
+#include "hw/mips/cps.h"
+#include "hw/mips/cpudevs.h"
+#include "hw/mips/mips.h"
+#include "hw/misc/mips_trickbox.h"
+#include "hw/pci-host/gpex.h"
+#include "hw/pci/pci.h"
+#include "hw/platform-bus.h"
+#include "hw/qdev-clock.h"
+#include "hw/qdev-properties.h"
+#include "hw/rtc/goldfish_rtc.h"
+#include "hw/sysbus.h"
+#include "qapi/error.h"
+#include "qemu/error-report.h"
+#include "qemu/guest-random.h"
+#include "qemu/log.h"
+#include "sysemu/device_tree.h"
+#include "sysemu/qtest.h"
+#include "sysemu/reset.h"
+#include "sysemu/runstate.h"
+#include "sysemu/sysemu.h"
+#include "elf.h"
+
+#include "qom/object.h"
+#include 
+
+#define TYPE_MIPS_VIRT_MACHINE MACHINE_TYPE_NAME("virt")
+typedef struct MIPSVirtState MIPSVirtState;
+DECLARE_INSTANCE_CHECKER(MIPSVirtState, MIPS_VIRT_MACHINE,
+ TYPE_MIPS_VIRT_MACHINE)
+
+#define FDT_IRQ_TYPE_NONE 0
+#define FDT_IRQ_TYPE_LEVEL_HIGH 4
+#define FDT_GIC_SHARED 0
+#define FDT_GIC_LOCAL 1
+#define FDT_VIRT_CLK_SYS 1
+#define FDT_VIRT_CLK_CPU 2
+#define FDT_PCI_IRQ_MAP_PINS 4
+#define FDT_PCI_IRQ_MAP_DESCS 6
+
+#define FDT_PCI_ADDR_CELLS 3
+#define FDT_PCI_INT_CELLS 1
+#define FDT_MAX_INT_CELLS 3
+#define FDT_MAX_INT_MAP_WIDTH \
+(FDT_PCI_ADDR_CELLS + FDT_PCI_INT_CELLS + 1 + FDT_MAX_INT_CELLS)
+
+#define VIRT_CPU_REF_CLK_FREQ 1
+
+typedef enum MIPSVirtPlatType {
+VIRT_PLAT_UP = 0,
+VIRT_PLAT_CPS = 1
+} MIPSVirtPlatType;
+
+struct MIPSVirtState {
+MachineState parent;
+
+Notifier machine_done;
+Clock *cpuclk;
+DeviceState *platform_bus_dev;
+MIPSCPSState *cps;
+DeviceState *pic;
+PFlashCFI01 *flash[2];
+FWCfgState *fw_cfg;
+
+MIPSVirtPlatType plat_type;
+int 

[RFC PATCH 0/3] MIPS VirtIO Machine

2022-11-24 Thread Jiaxun Yang
Hi there,

This patchset is to add a new machine type for MIPS architecture, which
is purely a VirtIO machine.

It is design to utilize existing VirtIO infrastures but also comptitable
with MIPS's existing internal simulation tools.

It should be able to cooperate with any MIPS core and boot Generic MIPS
kernel.

For testing purpose I've built little endian kernel[1] to work with this
machine with R4X00, loongson2f, octeon, mips32r2, mips64r2 and mips64r6. 

TODO:
- Documentation
- Test against big endian kernel
- nanoMIPS options

Thanks

[1]: https://github.com/FlyGoat/qemu-testing-blob/tree/main/kernel

Jiaxun Yang (3):
  hw/intc: Add missing include for goldfish_pic.h
  hw/misc: Add MIPS Trickbox device
  hw/mips: Add MIPS VirtIO board

 configs/devices/mips-softmmu/common.mak |1 +
 hw/mips/Kconfig |   18 +
 hw/mips/meson.build |1 +
 hw/mips/virt.c  | 1039 +++
 hw/misc/Kconfig |3 +
 hw/misc/meson.build |1 +
 hw/misc/mips_trickbox.c |   97 +++
 hw/misc/trace-events|4 +
 include/hw/intc/goldfish_pic.h  |2 +
 include/hw/misc/mips_trickbox.h |   41 +
 10 files changed, 1207 insertions(+)
 create mode 100644 hw/mips/virt.c
 create mode 100644 hw/misc/mips_trickbox.c
 create mode 100644 include/hw/misc/mips_trickbox.h

-- 
2.37.1 (Apple Git-137.1)




[RFC PATCH 1/3] hw/intc: Add missing include for goldfish_pic.h

2022-11-24 Thread Jiaxun Yang
hw/sysbus.h is missed in goldfish_pic.h.

Signed-off-by: Jiaxun Yang 
---
 include/hw/intc/goldfish_pic.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/include/hw/intc/goldfish_pic.h b/include/hw/intc/goldfish_pic.h
index e9d552f796..3e79580367 100644
--- a/include/hw/intc/goldfish_pic.h
+++ b/include/hw/intc/goldfish_pic.h
@@ -10,6 +10,8 @@
 #ifndef HW_INTC_GOLDFISH_PIC_H
 #define HW_INTC_GOLDFISH_PIC_H
 
+#include "hw/sysbus.h"
+
 #define TYPE_GOLDFISH_PIC "goldfish_pic"
 OBJECT_DECLARE_SIMPLE_TYPE(GoldfishPICState, GOLDFISH_PIC)
 
-- 
2.37.1 (Apple Git-137.1)




[RFC PATCH 2/3] hw/misc: Add MIPS Trickbox device

2022-11-24 Thread Jiaxun Yang
MIPS Trickbox is a emulated device present in MIPS's proprietary
simulators for decadeds. It's capable for managing simulator status,
signaling interrupts, doing DMA and EJTAG stimulations.

For now we just borrow this device and implement power management
related functions.

Signed-off-by: Jiaxun Yang 
---
 hw/misc/Kconfig |  3 +
 hw/misc/meson.build |  1 +
 hw/misc/mips_trickbox.c | 97 +
 hw/misc/trace-events|  4 ++
 include/hw/misc/mips_trickbox.h | 41 ++
 5 files changed, 146 insertions(+)
 create mode 100644 hw/misc/mips_trickbox.c
 create mode 100644 include/hw/misc/mips_trickbox.h

diff --git a/hw/misc/Kconfig b/hw/misc/Kconfig
index cbabe9f78c..fa92c439ec 100644
--- a/hw/misc/Kconfig
+++ b/hw/misc/Kconfig
@@ -89,6 +89,9 @@ config STM32F4XX_EXTI
 config MIPS_ITU
 bool
 
+config MIPS_TRICKBOX
+bool
+
 config MPS2_FPGAIO
 bool
 select LED
diff --git a/hw/misc/meson.build b/hw/misc/meson.build
index 95268eddc0..116eff8890 100644
--- a/hw/misc/meson.build
+++ b/hw/misc/meson.build
@@ -133,6 +133,7 @@ specific_ss.add(when: 'CONFIG_MAC_VIA', if_true: 
files('mac_via.c'))
 
 specific_ss.add(when: 'CONFIG_MIPS_CPS', if_true: files('mips_cmgcr.c', 
'mips_cpc.c'))
 specific_ss.add(when: 'CONFIG_MIPS_ITU', if_true: files('mips_itu.c'))
+specific_ss.add(when: 'CONFIG_MIPS_TRICKBOX', if_true: 
files('mips_trickbox.c'))
 
 specific_ss.add(when: 'CONFIG_SBSA_REF', if_true: files('sbsa_ec.c'))
 
diff --git a/hw/misc/mips_trickbox.c b/hw/misc/mips_trickbox.c
new file mode 100644
index 00..20349b774b
--- /dev/null
+++ b/hw/misc/mips_trickbox.c
@@ -0,0 +1,97 @@
+/*
+ * SPDX-License-Identifier: LGPL-2.0-or-later
+ *
+ * MIPS Trickbox
+ */
+
+#include "qemu/osdep.h"
+#include "hw/sysbus.h"
+#include "qapi/error.h"
+#include "qemu/log.h"
+#include "qemu/module.h"
+#include "trace.h"
+#include "sysemu/runstate.h"
+#include "hw/misc/mips_trickbox.h"
+
+static uint64_t mips_trickbox_read(void *opaque, hwaddr addr, unsigned int 
size)
+{
+uint64_t value = 0;
+
+qemu_log_mask(LOG_UNIMP,
+"%s: unimplemented register read 0x%02"HWADDR_PRIx"\n",
+__func__, addr);
+trace_mips_trickbox_read(size, value);
+
+return 0;
+}
+
+static void mips_trickbox_write(void *opaque, hwaddr addr,
+   uint64_t val64, unsigned int size)
+{
+trace_mips_trickbox_write(size, val64);
+
+switch (addr) {
+case REG_SIM_CMD:
+switch (val64 & 0x) {
+case TRICK_PANIC:
+qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_PANIC);
+break;
+case TRICK_HALT:
+qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
+break;
+case TRICK_SUSPEND:
+qemu_system_suspend_request();
+break;
+case TRICK_RESET:
+qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
+break;
+case TRICK_PASS_MIPS:
+case TRICK_PASS_NANOMIPS:
+exit(EXIT_SUCCESS);
+break;
+case TRICK_FAIL_MIPS:
+case TRICK_FAIL_NANOMIPS:
+exit(EXIT_FAILURE);
+break;
+}
+break;
+default:
+qemu_log_mask(LOG_UNIMP,
+  "%s: unimplemented register write 0x%02"HWADDR_PRIx"\n",
+  __func__, addr);
+break;
+}
+}
+
+static const MemoryRegionOps mips_trickbox_ops = {
+.read = mips_trickbox_read,
+.write = mips_trickbox_write,
+.endianness = DEVICE_NATIVE_ENDIAN,
+.valid = {
+.min_access_size = 2,
+.max_access_size = 4
+}
+};
+
+static void mips_trickbox_init(Object *obj)
+{
+MIPSTrickboxState *s = MIPS_TRICKBOX(obj);
+
+memory_region_init_io(>mmio, obj, _trickbox_ops, s,
+  TYPE_MIPS_TRICKBOX, 0x100);
+sysbus_init_mmio(SYS_BUS_DEVICE(obj), >mmio);
+}
+
+static const TypeInfo mips_trickbox_info = {
+.name  = TYPE_MIPS_TRICKBOX,
+.parent= TYPE_SYS_BUS_DEVICE,
+.instance_size = sizeof(MIPSTrickboxState),
+.instance_init = mips_trickbox_init,
+};
+
+static void mips_trickbox_register_types(void)
+{
+type_register_static(_trickbox_info);
+}
+
+type_init(mips_trickbox_register_types)
diff --git a/hw/misc/trace-events b/hw/misc/trace-events
index c18bc0605e..6df0e42450 100644
--- a/hw/misc/trace-events
+++ b/hw/misc/trace-events
@@ -274,3 +274,7 @@ virt_ctrl_instance_init(void *dev) "ctrl: %p"
 lasi_chip_mem_valid(uint64_t addr, uint32_t val) "access to addr 0x%"PRIx64" 
is %d"
 lasi_chip_read(uint64_t addr, uint32_t val) "addr 0x%"PRIx64" val 0x%08x"
 lasi_chip_write(uint64_t addr, uint32_t val) "addr 0x%"PRIx64" val 0x%08x"
+
+# mip

Re: [PATCH v2 2/3] hw/mips/malta: Set PIIX4 IRQ routes in embedded bootloader

2022-11-23 Thread Jiaxun Yang



> 2022年11月22日 12:37,BALATON Zoltan  写道:
> 
> Hello,
> 
> On Mon, 21 Nov 2022, Bernhard Beschow wrote:
>> Am 21. November 2022 22:43:50 UTC schrieb "Philippe Mathieu-Daudé" 
>> :
>>> On 21/11/22 16:34, Bernhard Beschow wrote:
 Am 27. Oktober 2022 20:47:19 UTC schrieb "Philippe Mathieu-Daudé" 
 :
> Linux kernel expects the northbridge & southbridge chipsets
> configured by the BIOS firmware. We emulate that by writing
> a tiny bootloader code in write_bootloader().
> 
> Upon introduction in commit 5c2b87e34d ("PIIX4 support"),
> the PIIX4 configuration space included values specific to
> the Malta board.
> 
> Set the Malta-specific IRQ routing values in the embedded
> bootloader, so the next commit can remove the Malta specific
> bits from the PIIX4 PCI-ISA bridge and make it generic
> (matching the real hardware).
> 
> Signed-off-by: Philippe Mathieu-Daudé 
> ---
> FIXME: Missing the nanoMIPS counter-part!
 
 Who will be taking care of this? I have absolutely no clue how the 
 write_bootloader functions work, so I don't see how to fix it.
>>> 
>>> Oh actually I wrote that and tested it but context switched and forgot
>>> about it... I'll look back when I get some time, probably around the
>>> release.

I can try to adopt existing boot loader helper functions, just a matter of 
opcodes I think.

> 
> Unrelated to this but found it while looking at malta.c now: another possible 
> clean up is to replace the local generate_eeprom_spd() func with 
> spd_data_generate() from hw/i2c/smbus_eeprom.c that other boards use already 
> but I did not change malta because I could not test it. If you can test malta 
> then it should be an easy change and simplify malta.c a bit.
> 
 Couldn't we just do it like in pegasos2_init() where the registers are 
 initialized by QEMU directly if there is no bootloader binary configured? 
 I could do that.
>>> I rather mimic bootloaders... maybe a matter of taste?
> 
> Is that a bootloader or a replacement firmware? To me bootloader is some OS 
> specific binary that is loaded by firware to boot an OS. But there are OS 
> independent bootloaders like grub so maybe you could emulate something like 
> that, I don't know what malta does.

YAMON is a OS-dependent and HW-dependent firmware like u-boot.

> 
> If there's no firmware binary QEMU should provide something to replace it to 
> give the expected environment for the binary loaded by -kernel. In case of 
> pegasos2 the init method sets up regs to init devices as done by the firmware 
> and the rest is implemented by VOF (loaded from pc-bios) that provices the 
> OpenFirmware client interface. The device setup in init is needed because VOF 
> does not do that.
> 
>> I don't mind either way. I meant that I could help with the second approach 
>> but not with the current one since I have no clue whatsoever how it works. 
>> There are just too many magic constants that don't make any sense to me, and 
>> too many layers of indirection, for example.
> 
> If malta has a replacement firmware for this case maybe it could be stored in 
> a binary in pc-bios and loaded from there instead of writing it in hex to 
> guest memory. That binary could even be assembled from source which should 
> make it simpler to write and change. Or is YAMON open source? According to 
> this page it is: https://www.mips.com/develop/tools/boot-loaders/ so maybe it 
> could be included as a firmware binary instead of being emulated?

Hmm, YAMON was a open source software but I’m unable to find a copy of source 
for Malta board comes with GT chipset that QEMU emulated.
So nowadays we mainly use -kernel feature to do direct kernel boot.

Direct kernel boot is really a brilliant function that I don’t want to lose :-)

Thanks
- Jiaxun


> 
> Regards,
> BALATON Zoltan
> 
>> Anyway, I'm asking for the current state because I'm pretty much ready for 
>> posting a v3 of my PIIX consolidation series which now depends on this 
>> series.
>> 
>> Best regards,
>> Bernhard
>> 
>>> 
>>> Regards,
>>> 
>>> Phil.
>> 




Re: [PATCH] target/mips: Properly set C0_CMGCRBase after CPU reset

2022-11-23 Thread Jiaxun Yang



> 2022年11月14日 16:25,Jiaxun Yang  写道:
> 
> Value of C0_CMGCRBase will be reseted to default when cpu reset
> happens. In some cases software may move GCR base and then initiate
> a CPU reset, this will leave C0_CMGCRBase of reseted core incorrect.
> 
> Implement a callback in CMGCR device to allow C0_CMGCRBase and other
> global states to be overriden after CPU reset.
> 
> Signed-off-by: Jiaxun Yang 
> ---
> This fixes SMP boot for Boston board.
> I'm not sure if it's the best palce to make such a callback,
> but we can add more global states such as BEV here in future.

Ping :-)

Any comments?

> ---
> hw/mips/cps.c| 3 ++-
> hw/misc/mips_cmgcr.c | 5 +
> target/mips/cpu.c| 4 +++-
> target/mips/cpu.h| 4 
> 4 files changed, 14 insertions(+), 2 deletions(-)
> 
> diff --git a/hw/mips/cps.c b/hw/mips/cps.c
> index 2b436700ce..29b10ff8d0 100644
> --- a/hw/mips/cps.c
> +++ b/hw/mips/cps.c
> @@ -98,6 +98,7 @@ static void mips_cps_realize(DeviceState *dev, Error **errp)
> cpu_mips_clock_init(cpu);
> 
> env = >env;
> +env->gcr = >gcr;
> if (cpu_mips_itu_supported(env)) {
> itu_present = true;
> /* Attach ITC Tag to the VP */
> @@ -158,7 +159,7 @@ static void mips_cps_realize(DeviceState *dev, Error 
> **errp)
> sysbus_mmio_get_region(SYS_BUS_DEVICE(>gic), 
> 0));
> 
> /* Global Configuration Registers */
> -gcr_base = env->CP0_CMGCRBase << 4;
> +gcr_base = GCR_BASE_ADDR;
> 
> object_initialize_child(OBJECT(dev), "gcr", >gcr, TYPE_MIPS_GCR);
> object_property_set_int(OBJECT(>gcr), "num-vp", s->num_vp,
> diff --git a/hw/misc/mips_cmgcr.c b/hw/misc/mips_cmgcr.c
> index 3c8b37f700..f2108b7d32 100644
> --- a/hw/misc/mips_cmgcr.c
> +++ b/hw/misc/mips_cmgcr.c
> @@ -19,6 +19,11 @@
> #include "hw/qdev-properties.h"
> #include "hw/intc/mips_gic.h"
> 
> +void gcr_cpu_reset(struct MIPSGCRState *s, CPUMIPSState *env)
> +{
> +env->CP0_CMGCRBase = s->gcr_base >> 4;
> +}
> +
> static inline bool is_cpc_connected(MIPSGCRState *s)
> {
> return s->cpc_mr != NULL;
> diff --git a/target/mips/cpu.c b/target/mips/cpu.c
> index e997c1b9cb..d0a76b95f7 100644
> --- a/target/mips/cpu.c
> +++ b/target/mips/cpu.c
> @@ -297,7 +297,9 @@ static void mips_cpu_reset(DeviceState *dev)
> env->CP0_EBase |= (int32_t)0x8000;
> }
> if (env->CP0_Config3 & (1 << CP0C3_CMGCR)) {
> -env->CP0_CMGCRBase = 0x1fbf8000 >> 4;
> +if (env->gcr) {
> +gcr_cpu_reset(env->gcr, env);
> +}
> }
> env->CP0_EntryHi_ASID_mask = (env->CP0_Config5 & (1 << CP0C5_MI)) ?
> 0x0 : (env->CP0_Config4 & (1 << CP0C4_AE)) ? 0x3ff : 0xff;
> diff --git a/target/mips/cpu.h b/target/mips/cpu.h
> index 0a085643a3..c345e6b1c7 100644
> --- a/target/mips/cpu.h
> +++ b/target/mips/cpu.h
> @@ -1154,6 +1154,7 @@ typedef struct CPUArchState {
> CPUMIPSTLBContext *tlb;
> void *irq[8];
> struct MIPSITUState *itu;
> +struct MIPSGCRState *gcr;
> MemoryRegion *itc_tag; /* ITC Configuration Tags */
> #endif
> 
> @@ -1310,6 +1311,9 @@ void cpu_mips_soft_irq(CPUMIPSState *env, int irq, int 
> level);
> /* mips_itu.c */
> void itc_reconfigure(struct MIPSITUState *tag);
> 
> +/* mips_cmgcr.c */
> +void gcr_cpu_reset(struct MIPSGCRState *s, CPUMIPSState *env);
> +
> #endif /* !CONFIG_USER_ONLY */
> 
> /* helper.c */
> -- 
> 2.37.4
> 




[PATCH] target/mips: Properly set C0_CMGCRBase after CPU reset

2022-11-14 Thread Jiaxun Yang
Value of C0_CMGCRBase will be reseted to default when cpu reset
happens. In some cases software may move GCR base and then initiate
a CPU reset, this will leave C0_CMGCRBase of reseted core incorrect.

Implement a callback in CMGCR device to allow C0_CMGCRBase and other
global states to be overriden after CPU reset.

Signed-off-by: Jiaxun Yang 
---
This fixes SMP boot for Boston board.
I'm not sure if it's the best palce to make such a callback,
but we can add more global states such as BEV here in future.
---
 hw/mips/cps.c| 3 ++-
 hw/misc/mips_cmgcr.c | 5 +
 target/mips/cpu.c| 4 +++-
 target/mips/cpu.h| 4 
 4 files changed, 14 insertions(+), 2 deletions(-)

diff --git a/hw/mips/cps.c b/hw/mips/cps.c
index 2b436700ce..29b10ff8d0 100644
--- a/hw/mips/cps.c
+++ b/hw/mips/cps.c
@@ -98,6 +98,7 @@ static void mips_cps_realize(DeviceState *dev, Error **errp)
 cpu_mips_clock_init(cpu);
 
 env = >env;
+env->gcr = >gcr;
 if (cpu_mips_itu_supported(env)) {
 itu_present = true;
 /* Attach ITC Tag to the VP */
@@ -158,7 +159,7 @@ static void mips_cps_realize(DeviceState *dev, Error **errp)
 sysbus_mmio_get_region(SYS_BUS_DEVICE(>gic), 
0));
 
 /* Global Configuration Registers */
-gcr_base = env->CP0_CMGCRBase << 4;
+gcr_base = GCR_BASE_ADDR;
 
 object_initialize_child(OBJECT(dev), "gcr", >gcr, TYPE_MIPS_GCR);
 object_property_set_int(OBJECT(>gcr), "num-vp", s->num_vp,
diff --git a/hw/misc/mips_cmgcr.c b/hw/misc/mips_cmgcr.c
index 3c8b37f700..f2108b7d32 100644
--- a/hw/misc/mips_cmgcr.c
+++ b/hw/misc/mips_cmgcr.c
@@ -19,6 +19,11 @@
 #include "hw/qdev-properties.h"
 #include "hw/intc/mips_gic.h"
 
+void gcr_cpu_reset(struct MIPSGCRState *s, CPUMIPSState *env)
+{
+env->CP0_CMGCRBase = s->gcr_base >> 4;
+}
+
 static inline bool is_cpc_connected(MIPSGCRState *s)
 {
 return s->cpc_mr != NULL;
diff --git a/target/mips/cpu.c b/target/mips/cpu.c
index e997c1b9cb..d0a76b95f7 100644
--- a/target/mips/cpu.c
+++ b/target/mips/cpu.c
@@ -297,7 +297,9 @@ static void mips_cpu_reset(DeviceState *dev)
 env->CP0_EBase |= (int32_t)0x8000;
 }
 if (env->CP0_Config3 & (1 << CP0C3_CMGCR)) {
-env->CP0_CMGCRBase = 0x1fbf8000 >> 4;
+if (env->gcr) {
+gcr_cpu_reset(env->gcr, env);
+}
 }
 env->CP0_EntryHi_ASID_mask = (env->CP0_Config5 & (1 << CP0C5_MI)) ?
 0x0 : (env->CP0_Config4 & (1 << CP0C4_AE)) ? 0x3ff : 0xff;
diff --git a/target/mips/cpu.h b/target/mips/cpu.h
index 0a085643a3..c345e6b1c7 100644
--- a/target/mips/cpu.h
+++ b/target/mips/cpu.h
@@ -1154,6 +1154,7 @@ typedef struct CPUArchState {
 CPUMIPSTLBContext *tlb;
 void *irq[8];
 struct MIPSITUState *itu;
+struct MIPSGCRState *gcr;
 MemoryRegion *itc_tag; /* ITC Configuration Tags */
 #endif
 
@@ -1310,6 +1311,9 @@ void cpu_mips_soft_irq(CPUMIPSState *env, int irq, int 
level);
 /* mips_itu.c */
 void itc_reconfigure(struct MIPSITUState *tag);
 
+/* mips_cmgcr.c */
+void gcr_cpu_reset(struct MIPSGCRState *s, CPUMIPSState *env);
+
 #endif /* !CONFIG_USER_ONLY */
 
 /* helper.c */
-- 
2.37.4




Re: [PATCH 1/2] target/mips: Don't check COP1X for 64 bit FP mode

2022-11-08 Thread Jiaxun Yang




在 2022/11/7 23:29, Philippe Mathieu-Daudé 写道:

On 7/11/22 23:47, Philippe Mathieu-Daudé wrote:

On 2/11/22 17:57, Jiaxun Yang wrote:
Some implementations (i.e. Loongson-2F) may decide to implement a 64 
bit

FPU without implmenting COP1X instructions.

As the eligibility of 64 bit FP instructions is already determined by
CP0St_FR, there is no need to check for COP1X again.

Signed-off-by: Jiaxun Yang 
---
  target/mips/tcg/translate.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/mips/tcg/translate.c b/target/mips/tcg/translate.c
index 2f2d707a12..e49d2a25a8 100644
--- a/target/mips/tcg/translate.c
+++ b/target/mips/tcg/translate.c
@@ -1545,7 +1545,7 @@ void check_cop1x(DisasContext *ctx)
   */
  void check_cp1_64bitmode(DisasContext *ctx)
  {
-    if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | 
MIPS_HFLAG_COP1X))) {

+    if (unlikely(~ctx->hflags & MIPS_HFLAG_F64) {
  gen_reserved_instruction(ctx);
  }
  }


Did you test your patch? I'm getting:

../../target/mips/tcg/translate.c:1548:49: error: expected ')'
    if (unlikely(~ctx->hflags & MIPS_HFLAG_F64) {
    ^
../../target/mips/tcg/translate.c:1548:8: note: to match this '('
    if (unlikely(~ctx->hflags & MIPS_HFLAG_F64) {
   ^
../../target/mips/tcg/translate.c:1551:1: error: expected statement
}


Woah, typo when copy changes back from test machine...
Will use git publish next time.

Thanks
- Jiaxun



^






Re: [PATCH 2/2] target/mips: Correct check for CABS instructions

2022-11-08 Thread Jiaxun Yang




在 2022/11/7 22:35, Philippe Mathieu-Daudé 写道:

On 2/11/22 17:57, Jiaxun Yang wrote:

Accroading to "MIPS Architecture for Programmers Volume IV-c:
The MIPS-3D Application-Specific Extension to the MIPS64 Architecture"
(MD00099). CABS.cond.fmt belongs to MIPS-3D ASE, and it has nothing 
to do

with COP1X opcode.

Remove all unnecessary COP1X checks and check for MIPS3D availability
in decoding code path.

Signed-off-by: Jiaxun Yang 
---
  target/mips/tcg/translate.c | 9 +
  1 file changed, 1 insertion(+), 8 deletions(-)

diff --git a/target/mips/tcg/translate.c b/target/mips/tcg/translate.c
index e49d2a25a8..23e575ad95 100644
--- a/target/mips/tcg/translate.c
+++ b/target/mips/tcg/translate.c
@@ -1788,16 +1788,8 @@ static inline void gen_cmp ## type ## _ ## 
fmt(DisasContext *ctx, int n,  \

check_ps(ctx); \
break; \
  case FMT_D: \
-    if (abs) 
{    \

- check_cop1x(ctx); \
- } \
  check_cp1_registers(ctx, fs | 
ft);    \

break; \
-    case FMT_S: \
-    if (abs) 
{    \

- check_cop1x(ctx); \
- } \
- break; \


I'm not sure we want to remove this check on all opcodes handled by
the FOP_CONDS() macro, and for all architecture variants. Maybe we
need to special-case CABS.cond.fmt?


Hmm if I read the code correctly COP1X check is only ran when abs is
set, and the only case abs is set is for CABS.cond.fmt.




} \
  gen_ldcmp_fpr##bits(ctx, fp0, 
fs);    \
  gen_ldcmp_fpr##bits(ctx, fp1, 
ft);    \
@@ -10424,6 +10416,7 @@ static void gen_farith(DisasContext *ctx, 
enum fopcode op1,

  case OPC_CMP_NGT_S:
  check_insn_opc_removed(ctx, ISA_MIPS_R6);
  if (ctx->opcode & (1 << 6)) {
+    check_insn(ctx, ASE_MIPS3D);


You somehow revert commit b8aa4598e2 ("MIPS COP1X (and related)
instructions") which is in use since 15 years.


Still no idea about why it is here in first place
CABS.cond.fmt is even not mentioned in MIPS IV manual. So it's unlikely 
to have

anything to do with COP1X.

Thanks
- Jiaxun




  gen_cmpabs_s(ctx, func - 48, ft, fs, cc);
  } else {
  gen_cmp_s(ctx, func - 48, ft, fs, cc);







[PATCH 1/2] target/mips: Don't check COP1X for 64 bit FP mode

2022-11-02 Thread Jiaxun Yang
Some implementations (i.e. Loongson-2F) may decide to implement a 64 bit
FPU without implmenting COP1X instructions.

As the eligibility of 64 bit FP instructions is already determined by
CP0St_FR, there is no need to check for COP1X again.

Signed-off-by: Jiaxun Yang 
---
 target/mips/tcg/translate.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/mips/tcg/translate.c b/target/mips/tcg/translate.c
index 2f2d707a12..e49d2a25a8 100644
--- a/target/mips/tcg/translate.c
+++ b/target/mips/tcg/translate.c
@@ -1545,7 +1545,7 @@ void check_cop1x(DisasContext *ctx)
  */
 void check_cp1_64bitmode(DisasContext *ctx)
 {
-if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X))) {
+if (unlikely(~ctx->hflags & MIPS_HFLAG_F64) {
 gen_reserved_instruction(ctx);
 }
 }
-- 
2.34.1




[PATCH 2/2] target/mips: Correct check for CABS instructions

2022-11-02 Thread Jiaxun Yang
Accroading to "MIPS Architecture for Programmers Volume IV-c:
The MIPS-3D Application-Specific Extension to the MIPS64 Architecture"
(MD00099). CABS.cond.fmt belongs to MIPS-3D ASE, and it has nothing to do
with COP1X opcode.

Remove all unnecessary COP1X checks and check for MIPS3D availability
in decoding code path.

Signed-off-by: Jiaxun Yang 
---
 target/mips/tcg/translate.c | 9 +
 1 file changed, 1 insertion(+), 8 deletions(-)

diff --git a/target/mips/tcg/translate.c b/target/mips/tcg/translate.c
index e49d2a25a8..23e575ad95 100644
--- a/target/mips/tcg/translate.c
+++ b/target/mips/tcg/translate.c
@@ -1788,16 +1788,8 @@ static inline void gen_cmp ## type ## _ ## 
fmt(DisasContext *ctx, int n,  \
 check_ps(ctx);\
 break;\
 case FMT_D:   \
-if (abs) {\
-check_cop1x(ctx); \
-} \
 check_cp1_registers(ctx, fs | ft);\
 break;\
-case FMT_S:   \
-if (abs) {\
-check_cop1x(ctx); \
-} \
-break;\
 } \
 gen_ldcmp_fpr##bits(ctx, fp0, fs);\
 gen_ldcmp_fpr##bits(ctx, fp1, ft);\
@@ -10424,6 +10416,7 @@ static void gen_farith(DisasContext *ctx, enum fopcode 
op1,
 case OPC_CMP_NGT_S:
 check_insn_opc_removed(ctx, ISA_MIPS_R6);
 if (ctx->opcode & (1 << 6)) {
+check_insn(ctx, ASE_MIPS3D);
 gen_cmpabs_s(ctx, func - 48, ft, fs, cc);
 } else {
 gen_cmp_s(ctx, func - 48, ft, fs, cc);
-- 
2.34.1




[PATCH v2 3/3] target/mips: Disable DSP ASE for Octeon68XX

2022-10-31 Thread Jiaxun Yang
I don't have access to Octeon68XX hardware but accroading to
my investigation Octeon never had DSP ASE support.

As per "Cavium Networks OCTEON Plus CN50XX Hardware Reference
Manual" CP0C3_DSPP is reserved bit and read as 0. Also I do have
access to a Ubiquiti Edgerouter 4 which has Octeon CN7130 processor
and I can confirm CP0C3_DSPP is read as 0 on that processor.

Further more, in linux kernel:
arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h
cpu_has_dsp is overridden as 0.

So I believe we shouldn't emulate DSP in QEMU as well.

Signed-off-by: Jiaxun Yang 
Acked-by: Richard Henderson 
---
 target/mips/cpu-defs.c.inc | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/target/mips/cpu-defs.c.inc b/target/mips/cpu-defs.c.inc
index 7f53c94ec8..480e60aeec 100644
--- a/target/mips/cpu-defs.c.inc
+++ b/target/mips/cpu-defs.c.inc
@@ -934,7 +934,7 @@ const mips_def_t mips_defs[] =
(1 << CP0C1_DS) | (4 << CP0C1_DL) | (1 << CP0C1_DA) |
(1 << CP0C1_PC) | (1 << CP0C1_WR) | (1 << CP0C1_EP),
 .CP0_Config2 = MIPS_CONFIG2,
-.CP0_Config3 = MIPS_CONFIG3 | (1 << CP0C3_LPA) | (1 << CP0C3_DSPP) ,
+.CP0_Config3 = MIPS_CONFIG3 | (1 << CP0C3_LPA),
 .CP0_Config4 = MIPS_CONFIG4 | (1U << CP0C4_M) |
(0x3c << CP0C4_KScrExist) | (1U << CP0C4_MMUExtDef) |
(3U << CP0C4_MMUSizeExt),
@@ -946,7 +946,7 @@ const mips_def_t mips_defs[] =
 .CP0_Status_rw_bitmask = 0x12F8,
 .SEGBITS = 42,
 .PABITS = 49,
-.insn_flags = CPU_MIPS64R2 | INSN_OCTEON | ASE_DSP,
+.insn_flags = CPU_MIPS64R2 | INSN_OCTEON,
 .mmu_type = MMU_TYPE_R4000,
 },
 
-- 
2.34.1




[PATCH v2 2/3] target/mips: Cast offset field of Octeon BBIT to int16_t

2022-10-31 Thread Jiaxun Yang
As per "Cavium Networks OCTEON Plus CN50XX Hardware Reference
Manual" offset field is signed 16 bit value. However arg_BBIT.offset
is unsigned. We need to cast it as signed to do address calculation.

Signed-off-by: Jiaxun Yang 
---
v2:
Do casting in decodetree. (philmd)
---
 target/mips/tcg/octeon.decode | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/mips/tcg/octeon.decode b/target/mips/tcg/octeon.decode
index 8929ad088e..0c787cb498 100644
--- a/target/mips/tcg/octeon.decode
+++ b/target/mips/tcg/octeon.decode
@@ -12,7 +12,7 @@
 # BBIT13210 . . 
 
 %bbit_p  28:1 16:5
-BBIT 11 set:1 . 10 rs:5 . offset:16 p=%bbit_p
+BBIT 11 set:1 . 10 rs:5 . offset:s16 p=%bbit_p
 
 # Arithmetic
 # BADDU rd, rs, rt
-- 
2.34.1




[PATCH v2 1/3] target/mips: Set CP0St_{KX, SX, UX} for Loongson-2F

2022-10-31 Thread Jiaxun Yang
As per an unpublished document, in later reversion of chips
CP0St_{KX, SX, UX} is not writeable and hardcoded to 1.

Without those bits set, kernel is unable to access XKPHYS address
segmant. So just set them up on CPU reset.

Signed-off-by: Jiaxun Yang 
Acked-by: Richard Henderson 
---
v2:
Rewording to point out the document is unpublished
---
 target/mips/cpu.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/target/mips/cpu.c b/target/mips/cpu.c
index d0a76b95f7..a870901bfa 100644
--- a/target/mips/cpu.c
+++ b/target/mips/cpu.c
@@ -304,6 +304,12 @@ static void mips_cpu_reset(DeviceState *dev)
 env->CP0_EntryHi_ASID_mask = (env->CP0_Config5 & (1 << CP0C5_MI)) ?
 0x0 : (env->CP0_Config4 & (1 << CP0C4_AE)) ? 0x3ff : 0xff;
 env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
+if (env->insn_flags & INSN_LOONGSON2F) {
+/* Loongson-2F has those bits hardcoded to 1 */
+env->CP0_Status |= (1 << CP0St_KX) | (1 << CP0St_SX) |
+(1 << CP0St_UX);
+}
+
 /*
  * Vectored interrupts not implemented, timer on int 7,
  * no performance counters.
-- 
2.34.1




[PATCH v2 0/3] MIPS system emulation miscellaneous fixes

2022-10-31 Thread Jiaxun Yang
Hi all,

I was trying to build a MIPS VirtIO board[1] for QEMU that is able
to work with all processors we support.

When I was bring up varoius CPUs on that board I noticed some issues
with the system emulation code that I'm fixing in this series.

Thanks.

- Jiaxun
[1]: https://gitlab.com/FlyGoat/qemu/-/tree/mips-virt

v2: Address review comments

Jiaxun Yang (3):
  target/mips: Set CP0St_{KX, SX, UX} for Loongson-2F
  target/mips: Cast offset field of Octeon BBIT to int16_t
  target/mips: Disable DSP ASE for Octeon68XX

 target/mips/cpu-defs.c.inc| 4 ++--
 target/mips/cpu.c | 6 ++
 target/mips/tcg/octeon.decode | 2 +-
 3 files changed, 9 insertions(+), 3 deletions(-)

-- 
2.34.1




Re: [PATCH 1/3] target/mips: Set CP0St_{KX, SX, UX} for Loongson-2F

2022-10-29 Thread Jiaxun Yang



> 2022年10月30日 00:19,Philippe Mathieu-Daudé  写道:
> 
> On 29/10/22 21:50, Jiaxun Yang wrote:
>>> 2022年10月29日 18:44,Philippe Mathieu-Daudé  写道:
>>> 
>>> On 29/10/22 04:00, Jiaxun Yang wrote:
>>>> As per "Loongson-2F processor user manual", CP0St_{KX, SX, UX}
>>>> should is not writeable and hardcoded to 1.
>>>> Without those bits set, kernel is unable to access XKPHYS address
>>>> segmant. So just set them up on CPU reset.
>>>> Signed-off-by: Jiaxun Yang 
>>>> ---
>>>>  target/mips/cpu.c | 6 ++
>>>>  1 file changed, 6 insertions(+)
>>>> diff --git a/target/mips/cpu.c b/target/mips/cpu.c
>>>> index d0a76b95f7..a870901bfa 100644
>>>> --- a/target/mips/cpu.c
>>>> +++ b/target/mips/cpu.c
>>>> @@ -304,6 +304,12 @@ static void mips_cpu_reset(DeviceState *dev)
>>>>  env->CP0_EntryHi_ASID_mask = (env->CP0_Config5 & (1 << CP0C5_MI)) ?
>>>>  0x0 : (env->CP0_Config4 & (1 << CP0C4_AE)) ? 0x3ff : 0xff;
>>>>  env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
>>>> +if (env->insn_flags & INSN_LOONGSON2F) {
>>>> +/* Loongson-2F has those bits hardcoded to 1 */
>>>> +env->CP0_Status |= (1 << CP0St_KX) | (1 << CP0St_SX) |
>>>> +(1 << CP0St_UX);
>>>> +}
>>> 
>>> Don't we want to update CP0_Status_rw_bitmask in Loongson-2F
>>> entry in mips_defs[] instead?
>> Write to those bits is already disabled by CP0_Status_rw_bitmask. However 
>> real hardware
>> had those bits set to 1 but QEMU default them to 0…
>> Enable writing to those bits can also make kernel work but it mismatches 
>> actual hardware
>> behavior.
> 
> On "龙芯 2F 处理器用户手册 (0.1 版, 2007 年 8 月)"
> Section 5.10 Status 寄存器(12) (page 57),
> CP0_Status bits 5..7 are 0.
> 
> Can you share your "Loongson-2F processor user manual" doc?

Ah sorry the document was marked as “company confidential” so I’m not sure if I 
can share
the whole doc. It was updated in 2016 with version 1.8. The latest document I 
can find in wild
Is version 1.5 [1] but it didn’t cover newer chip reversions.

There is a footnote saying value of those bits was changed in later chips, to 
translate it says:

"Since LS2F04 those bits was refined to 1. As in LS2F we had implemented a 
single 64 bit addressing
model and it is mostly compatible with MIPS64 64 bit addressing model.”

It is obvious that without KX and UX bit 64 bit kernel won’t work but my Lemote 
Fuloong box is running
64 bit kernel along with n64 AOSC/Retro [2] user-space rootfs. For SX bit as 
LS2F supports XSSEG it
should work as well, though nobody take MIPS supervisor mode serious :-)

[1]: https://github.com/loongson-community/docs/tree/master/2F
[2]: https://wiki.aosc.io/aosc-os/retro/intro/
---
Jiaxun Yang




Re: [PATCH 1/3] target/mips: Set CP0St_{KX, SX, UX} for Loongson-2F

2022-10-29 Thread Jiaxun Yang



> 2022年10月29日 18:44,Philippe Mathieu-Daudé  写道:
> 
> On 29/10/22 04:00, Jiaxun Yang wrote:
>> As per "Loongson-2F processor user manual", CP0St_{KX, SX, UX}
>> should is not writeable and hardcoded to 1.
>> Without those bits set, kernel is unable to access XKPHYS address
>> segmant. So just set them up on CPU reset.
>> Signed-off-by: Jiaxun Yang 
>> ---
>>  target/mips/cpu.c | 6 ++
>>  1 file changed, 6 insertions(+)
>> diff --git a/target/mips/cpu.c b/target/mips/cpu.c
>> index d0a76b95f7..a870901bfa 100644
>> --- a/target/mips/cpu.c
>> +++ b/target/mips/cpu.c
>> @@ -304,6 +304,12 @@ static void mips_cpu_reset(DeviceState *dev)
>>  env->CP0_EntryHi_ASID_mask = (env->CP0_Config5 & (1 << CP0C5_MI)) ?
>>  0x0 : (env->CP0_Config4 & (1 << CP0C4_AE)) ? 0x3ff : 0xff;
>>  env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
>> +if (env->insn_flags & INSN_LOONGSON2F) {
>> +/* Loongson-2F has those bits hardcoded to 1 */
>> +env->CP0_Status |= (1 << CP0St_KX) | (1 << CP0St_SX) |
>> +(1 << CP0St_UX);
>> +}
> 
> Don't we want to update CP0_Status_rw_bitmask in Loongson-2F
> entry in mips_defs[] instead?

Write to those bits is already disabled by CP0_Status_rw_bitmask. However real 
hardware
had those bits set to 1 but QEMU default them to 0…

Enable writing to those bits can also make kernel work but it mismatches actual 
hardware
behavior.

Thanks.
---
Jiaxun Yang




[PATCH 0/3] MIPS system emulation miscellaneous fixes

2022-10-28 Thread Jiaxun Yang
Hi all,

I was trying to build a MIPS VirtIO board[1] for QEMU that is able
to work with all processors we support.

When I was bring up varoius CPUs on that board I noticed some issues
with the system emulation code that I'm fixing in this series.

Thanks.

- Jiaxun
[1]: https://gitlab.com/FlyGoat/qemu/-/tree/mips-virt

Jiaxun Yang (3):
  target/mips: Set CP0St_{KX, SX, UX} for Loongson-2F
  target/mips: Cast offset field of Octeon BBIT to int16_t
  target/mips: Disable DSP ASE for Octeon68XX

 target/mips/cpu-defs.c.inc | 4 ++--
 target/mips/cpu.c  | 6 ++
 target/mips/tcg/octeon_translate.c | 2 +-
 3 files changed, 9 insertions(+), 3 deletions(-)

-- 
2.37.1 (Apple Git-137.1)




[PATCH 1/3] target/mips: Set CP0St_{KX, SX, UX} for Loongson-2F

2022-10-28 Thread Jiaxun Yang
As per "Loongson-2F processor user manual", CP0St_{KX, SX, UX}
should is not writeable and hardcoded to 1.

Without those bits set, kernel is unable to access XKPHYS address
segmant. So just set them up on CPU reset.

Signed-off-by: Jiaxun Yang 
---
 target/mips/cpu.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/target/mips/cpu.c b/target/mips/cpu.c
index d0a76b95f7..a870901bfa 100644
--- a/target/mips/cpu.c
+++ b/target/mips/cpu.c
@@ -304,6 +304,12 @@ static void mips_cpu_reset(DeviceState *dev)
 env->CP0_EntryHi_ASID_mask = (env->CP0_Config5 & (1 << CP0C5_MI)) ?
 0x0 : (env->CP0_Config4 & (1 << CP0C4_AE)) ? 0x3ff : 0xff;
 env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
+if (env->insn_flags & INSN_LOONGSON2F) {
+/* Loongson-2F has those bits hardcoded to 1 */
+env->CP0_Status |= (1 << CP0St_KX) | (1 << CP0St_SX) |
+(1 << CP0St_UX);
+}
+
 /*
  * Vectored interrupts not implemented, timer on int 7,
  * no performance counters.
-- 
2.37.1 (Apple Git-137.1)




[PATCH 3/3] target/mips: Disable DSP ASE for Octeon68XX

2022-10-28 Thread Jiaxun Yang
I don't have access to Octeon68XX hardware but accroading to
my investigation Octeon never had DSP ASE support.

As per "Cavium Networks OCTEON Plus CN50XX Hardware Reference
Manual" CP0C3_DSPP is reserved bit and read as 0. Also I do have
access to a Ubiquiti Edgerouter 4 which has Octeon CN7130 processor
and I can confirm CP0C3_DSPP is read as 0 on that processor.

Further more, in linux kernel:
arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h
cpu_has_dsp is overridden as 0.

So I believe we shouldn't emulate DSP in QEMU as well.

Signed-off-by: Jiaxun Yang 
---
 target/mips/cpu-defs.c.inc | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/target/mips/cpu-defs.c.inc b/target/mips/cpu-defs.c.inc
index 7f53c94ec8..480e60aeec 100644
--- a/target/mips/cpu-defs.c.inc
+++ b/target/mips/cpu-defs.c.inc
@@ -934,7 +934,7 @@ const mips_def_t mips_defs[] =
(1 << CP0C1_DS) | (4 << CP0C1_DL) | (1 << CP0C1_DA) |
(1 << CP0C1_PC) | (1 << CP0C1_WR) | (1 << CP0C1_EP),
 .CP0_Config2 = MIPS_CONFIG2,
-.CP0_Config3 = MIPS_CONFIG3 | (1 << CP0C3_LPA) | (1 << CP0C3_DSPP) ,
+.CP0_Config3 = MIPS_CONFIG3 | (1 << CP0C3_LPA),
 .CP0_Config4 = MIPS_CONFIG4 | (1U << CP0C4_M) |
(0x3c << CP0C4_KScrExist) | (1U << CP0C4_MMUExtDef) |
(3U << CP0C4_MMUSizeExt),
@@ -946,7 +946,7 @@ const mips_def_t mips_defs[] =
 .CP0_Status_rw_bitmask = 0x12F8,
 .SEGBITS = 42,
 .PABITS = 49,
-.insn_flags = CPU_MIPS64R2 | INSN_OCTEON | ASE_DSP,
+.insn_flags = CPU_MIPS64R2 | INSN_OCTEON,
 .mmu_type = MMU_TYPE_R4000,
 },
 
-- 
2.37.1 (Apple Git-137.1)




[PATCH 2/3] target/mips: Cast offset field of Octeon BBIT to int16_t

2022-10-28 Thread Jiaxun Yang
As per "Cavium Networks OCTEON Plus CN50XX Hardware Reference
Manual" offset field is signed 16 bit value. However arg_BBIT.offset
is unsigned. We need to cast it as signed to do address calculation.

Signed-off-by: Jiaxun Yang 
---
 target/mips/tcg/octeon_translate.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/mips/tcg/octeon_translate.c 
b/target/mips/tcg/octeon_translate.c
index 6a207d2e7e..e8f2277c51 100644
--- a/target/mips/tcg/octeon_translate.c
+++ b/target/mips/tcg/octeon_translate.c
@@ -38,7 +38,7 @@ static bool trans_BBIT(DisasContext *ctx, arg_BBIT *a)
 }
 
 ctx->hflags |= MIPS_HFLAG_BC;
-ctx->btarget = ctx->base.pc_next + 4 + a->offset * 4;
+ctx->btarget = ctx->base.pc_next + 4 + (int16_t)a->offset * 4;
 ctx->hflags |= MIPS_HFLAG_BDS32;
 
 tcg_temp_free(t0);
-- 
2.37.1 (Apple Git-137.1)




Re: [PATCH v4 0/3] MIPS Bootloader helper

2022-10-27 Thread Jiaxun Yang



> 2022年10月26日 20:18,Philippe Mathieu-Daudé  写道:
> 
> This is a respin of Jiaxun v3 [1] addressing the semihosting review
> comment [2].
> 
> [1] 
> https://lore.kernel.org/qemu-devel/20210127065424.114125-1-jiaxun.y...@flygoat.com/
> [2] 
> https://lore.kernel.org/qemu-devel/5a22bbe1-5023-6fc3-a41b-8d72ec2bb...@flygoat.com/

For the series:

Tested-by: Jiaxun Yang 
Reviewed-by: Jiaxun Yang 

I thought this series was committed in whole.. Just forgot that there are still 
something remaining :-)

Thanks
- Jiaxun


> 
> *** BLURB HERE ***
> 
> Jiaxun Yang (2):
>  hw/mips: Use bl_gen_kernel_jump to generate bootloaders
>  hw/mips/malta: Use bootloader helper to set BAR registers
> 
> Philippe Mathieu-Daudé (1):
>  hw/mips/bootloader: Allow bl_gen_jump_kernel to optionally set
>register
> 
> hw/mips/bootloader.c |  28 ++--
> hw/mips/boston.c |   5 +-
> hw/mips/fuloong2e.c  |   8 ++-
> hw/mips/malta.c  | 122 ++-
> include/hw/mips/bootloader.h |   8 ++-
> 5 files changed, 86 insertions(+), 85 deletions(-)
> 
> -- 
> 2.37.3
> 

---
Jiaxun Yang




[PATCH 4/6] target/mips: Split Loongson extention translation into standalone file

2022-10-24 Thread Jiaxun Yang
So we can do decodetree translation for those exts alone.

Signed-off-by: Jiaxun Yang 
---
 target/mips/tcg/loongson_translate.c | 1290 +
 target/mips/tcg/meson.build  |1 +
 target/mips/tcg/translate.c  | 1577 --
 target/mips/tcg/translate.h  |6 +
 4 files changed, 1493 insertions(+), 1381 deletions(-)
 create mode 100644 target/mips/tcg/loongson_translate.c

diff --git a/target/mips/tcg/loongson_translate.c 
b/target/mips/tcg/loongson_translate.c
new file mode 100644
index 00..efeb1d6e28
--- /dev/null
+++ b/target/mips/tcg/loongson_translate.c
@@ -0,0 +1,1290 @@
+/*
+ * Loongson EXT and MMI translation routines.
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ *
+ * This code is licensed under the LGPL v2.1 or later.
+ */
+
+#include "qemu/osdep.h"
+#include "tcg/tcg-op.h"
+#include "tcg/tcg-op-gvec.h"
+#include "exec/helper-gen.h"
+#include "translate.h"
+
+enum {
+OPC_CP2  = (0x12 << 26),
+OPC_SPECIAL2 = (0x1C << 26),
+OPC_SPECIAL3 = (0x1F << 26),
+OPC_LWC2 = (0x32 << 26),
+OPC_LDC2 = (0x36 << 26),
+OPC_SWC2 = (0x3A << 26),
+OPC_SDC2 = (0x3E << 26),
+};
+
+/* Special2 opcodes */
+#define MASK_2F_SPECIAL2(op)(MASK_OP_MAJOR(op) | (op & 0x3F))
+
+enum {
+OPC_MULT_G_2F   = 0x10 | OPC_SPECIAL2,
+OPC_DMULT_G_2F  = 0x11 | OPC_SPECIAL2,
+OPC_MULTU_G_2F  = 0x12 | OPC_SPECIAL2,
+OPC_DMULTU_G_2F = 0x13 | OPC_SPECIAL2,
+OPC_DIV_G_2F= 0x14 | OPC_SPECIAL2,
+OPC_DDIV_G_2F   = 0x15 | OPC_SPECIAL2,
+OPC_DIVU_G_2F   = 0x16 | OPC_SPECIAL2,
+OPC_DDIVU_G_2F  = 0x17 | OPC_SPECIAL2,
+OPC_MOD_G_2F= 0x1c | OPC_SPECIAL2,
+OPC_DMOD_G_2F   = 0x1d | OPC_SPECIAL2,
+OPC_MODU_G_2F   = 0x1e | OPC_SPECIAL2,
+OPC_DMODU_G_2F  = 0x1f | OPC_SPECIAL2,
+};
+
+/* Special3 opcodes */
+#define MASK_2E_SPECIAL3(op)(MASK_OP_MAJOR(op) | (op & 0x3F))
+enum {
+/* Loongson 2E */
+OPC_MULT_G_2E   = 0x18 | OPC_SPECIAL3,
+OPC_MULTU_G_2E  = 0x19 | OPC_SPECIAL3,
+OPC_DIV_G_2E= 0x1A | OPC_SPECIAL3,
+OPC_DIVU_G_2E   = 0x1B | OPC_SPECIAL3,
+OPC_DMULT_G_2E  = 0x1C | OPC_SPECIAL3,
+OPC_DMULTU_G_2E = 0x1D | OPC_SPECIAL3,
+OPC_DDIV_G_2E   = 0x1E | OPC_SPECIAL3,
+OPC_DDIVU_G_2E  = 0x1F | OPC_SPECIAL3,
+OPC_MOD_G_2E= 0x22 | OPC_SPECIAL3,
+OPC_MODU_G_2E   = 0x23 | OPC_SPECIAL3,
+OPC_DMOD_G_2E   = 0x26 | OPC_SPECIAL3,
+OPC_DMODU_G_2E  = 0x27 | OPC_SPECIAL3,
+};
+
+/* Loongson EXT load/store quad word opcodes */
+#define MASK_LOONGSON_GSLSQ(op)   (MASK_OP_MAJOR(op) | (op & 0x8020))
+enum {
+OPC_GSLQ= 0x0020 | OPC_LWC2,
+OPC_GSLQC1  = 0x8020 | OPC_LWC2,
+OPC_GSSHFL  = OPC_LWC2,
+OPC_GSSQ= 0x0020 | OPC_SWC2,
+OPC_GSSQC1  = 0x8020 | OPC_SWC2,
+OPC_GSSHFS  = OPC_SWC2,
+};
+
+/* Loongson EXT shifted load/store opcodes */
+#define MASK_LOONGSON_GSSHFLS(op) (MASK_OP_MAJOR(op) | (op & 0xc03f))
+enum {
+OPC_GSLWLC1 = 0x4 | OPC_GSSHFL,
+OPC_GSLWRC1 = 0x5 | OPC_GSSHFL,
+OPC_GSLDLC1 = 0x6 | OPC_GSSHFL,
+OPC_GSLDRC1 = 0x7 | OPC_GSSHFL,
+OPC_GSSWLC1 = 0x4 | OPC_GSSHFS,
+OPC_GSSWRC1 = 0x5 | OPC_GSSHFS,
+OPC_GSSDLC1 = 0x6 | OPC_GSSHFS,
+OPC_GSSDRC1 = 0x7 | OPC_GSSHFS,
+};
+
+/* Loongson EXT LDC2/SDC2 opcodes */
+#define MASK_LOONGSON_LSDC2(op)   (MASK_OP_MAJOR(op) | (op & 0x7))
+
+enum {
+OPC_GSLBX  = 0x0 | OPC_LDC2,
+OPC_GSLHX  = 0x1 | OPC_LDC2,
+OPC_GSLWX  = 0x2 | OPC_LDC2,
+OPC_GSLDX  = 0x3 | OPC_LDC2,
+OPC_GSLWXC1= 0x6 | OPC_LDC2,
+OPC_GSLDXC1= 0x7 | OPC_LDC2,
+OPC_GSSBX  = 0x0 | OPC_SDC2,
+OPC_GSSHX  = 0x1 | OPC_SDC2,
+OPC_GSSWX  = 0x2 | OPC_SDC2,
+OPC_GSSDX  = 0x3 | OPC_SDC2,
+OPC_GSSWXC1= 0x6 | OPC_SDC2,
+OPC_GSSDXC1= 0x7 | OPC_SDC2,
+};
+
+#define MASK_LMMI(op)(MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 
0x1F))
+
+enum {
+OPC_PADDSH  = (24 << 21) | (0x00) | OPC_CP2,
+OPC_PADDUSH = (25 << 21) | (0x00) | OPC_CP2,
+OPC_PADDH   = (26 << 21) | (0x00) | OPC_CP2,
+OPC_PADDW   = (27 << 21) | (0x00) | OPC_CP2,
+OPC_PADDSB  = (28 << 21) | (0x00) | OPC_CP2,
+OPC_PADDUSB = (29 << 21) | (0x00) | OPC_CP2,
+OPC_PADDB   = (30 << 21) | (0x00) | OPC_CP2,
+OPC_PADDD   = (31 << 21) | (0x00) | OPC_CP2,
+
+OPC_PSUBSH  = (24 << 21) | (0x01) | OPC_CP2,
+OPC_PSUBUSH = (25 << 21) | (0x01) | OPC_CP2,
+OPC_PSUBH   = (26 << 21) | (0x01) | OPC_CP2,
+OPC_PSUBW   = (27 << 21) | (0x01) | OPC_CP2,
+OPC_PSUBSB  = (28 << 21) | (0x01) | OPC_CP2,
+OPC_PSUBUSB = (29 << 21) | (0x01) | OPC_

[PATCH 1/6] target/mips: Introduce register access helper functions

2022-10-24 Thread Jiaxun Yang
Introduce register access functions with value extend capability
to prepare for decodetree based translation implmentation.

Signed-off-by: Jiaxun Yang 
---
 target/mips/tcg/translate.c | 143 +++-
 target/mips/tcg/translate.h |  54 ++
 2 files changed, 196 insertions(+), 1 deletion(-)

diff --git a/target/mips/tcg/translate.c b/target/mips/tcg/translate.c
index de1511baaf..b5d595ef34 100644
--- a/target/mips/tcg/translate.c
+++ b/target/mips/tcg/translate.c
@@ -1196,6 +1196,17 @@ enum {
 MMI_OPC_MADDU1 = 0x21 | MMI_OPC_CLASS_MMI,
 };
 
+/*
+ * If an operation is being performed on less than TARGET_LONG_BITS,
+ * it may require the inputs to be sign- or zero-extended; which will
+ * depend on the exact operation being performed.
+ */
+typedef enum {
+EXT_NONE,
+EXT_SIGN,
+EXT_ZERO
+} DisasExtend;
+
 /* global register indices */
 TCGv cpu_gpr[32], cpu_PC;
 /*
@@ -1221,6 +1232,18 @@ static const char regnames_LO[][4] = {
 "LO0", "LO1", "LO2", "LO3",
 };
 
+static TCGv ctx_temp_new(DisasContext *ctx)
+{
+assert(ctx->ntemp < ARRAY_SIZE(ctx->temp));
+return ctx->temp[ctx->ntemp++] = tcg_temp_new();
+}
+
+static TCGv_i64 ctx_temp_new_i64(DisasContext *ctx)
+{
+assert(ctx->ntemp64 < ARRAY_SIZE(ctx->temp64));
+return ctx->temp64[ctx->ntemp64++] = tcg_temp_new_i64();
+}
+
 /* General purpose registers moves. */
 void gen_load_gpr(TCGv t, int reg)
 {
@@ -1238,6 +1261,106 @@ void gen_store_gpr(TCGv t, int reg)
 }
 }
 
+void gen_extend(TCGv dst, TCGv src, DisasExtend src_ext)
+{
+switch (src_ext) {
+case EXT_NONE:
+tcg_gen_mov_tl(dst, src);
+return;
+case EXT_SIGN:
+tcg_gen_ext32s_tl(dst, src);
+return;
+case EXT_ZERO:
+tcg_gen_ext32u_tl(dst, src);
+return;
+}
+g_assert_not_reached();
+}
+
+TCGv get_gpr(DisasContext *ctx, int reg_num, DisasExtend src_ext)
+{
+TCGv t;
+
+if (reg_num == 0) {
+return ctx->zero;
+}
+
+switch (src_ext) {
+case EXT_NONE:
+return cpu_gpr[reg_num];
+default:
+t = ctx_temp_new(ctx);
+gen_extend(t, cpu_gpr[reg_num], src_ext);
+return t;
+}
+}
+
+TCGv_i64 get_hilo(DisasContext *ctx, int acc)
+{
+TCGv_i64 t = ctx_temp_new_i64(ctx);
+/* acc must be 0 when DSP is not implemented */
+g_assert(acc == 0 || ctx->insn_flags & ASE_DSP);
+tcg_gen_concat_tl_i64(t, cpu_LO[acc], cpu_HI[acc]);
+
+return t;
+}
+
+TCGv dest_gpr(DisasContext *ctx, int reg_num)
+{
+if (reg_num == 0) {
+return ctx_temp_new(ctx);
+}
+return cpu_gpr[reg_num];
+}
+
+TCGv dest_lo(DisasContext *ctx, int acc)
+{
+/* acc must be 0 when DSP is not implemented */
+g_assert(acc == 0 || ctx->insn_flags & ASE_DSP);
+
+return cpu_LO[acc];
+}
+
+TCGv dest_hi(DisasContext *ctx, int acc)
+{
+/* acc must be 0 when DSP is not implemented */
+g_assert(acc == 0 || ctx->insn_flags & ASE_DSP);
+
+return cpu_HI[acc];
+}
+
+/* For 32 bit hilo pair */
+TCGv_i64 dest_hilo(DisasContext *ctx, int acc)
+{
+/* acc must be 0 when DSP is not implemented */
+g_assert(acc == 0 || ctx->insn_flags & ASE_DSP);
+return ctx_temp_new_i64(ctx);
+}
+
+void gen_set_gpr(int reg_num, TCGv t, DisasExtend dst_ext)
+{
+if (reg_num != 0) {
+gen_extend(cpu_gpr[reg_num], t, dst_ext);
+}
+}
+
+void gen_set_lo(int acc, TCGv t, DisasExtend dst_ext)
+{
+gen_extend(cpu_LO[acc], t, dst_ext);
+}
+
+void gen_set_hi(int acc, TCGv t, DisasExtend dst_ext)
+{
+gen_extend(cpu_HI[acc], t, dst_ext);
+}
+
+/* For 32 bit hilo pair */
+void gen_set_hilo(int acc, TCGv_i64 t)
+{
+gen_move_low32(cpu_LO[acc], t);
+gen_move_high32(cpu_HI[acc], t);
+}
+
 #if defined(TARGET_MIPS64)
 void gen_load_gpr_hi(TCGv_i64 t, int reg)
 {
@@ -2615,7 +2738,6 @@ static void gen_shift_imm(DisasContext *ctx, uint32_t opc,
 tcg_temp_free(t0);
 }
 
-/* Arithmetic */
 static void gen_arith(DisasContext *ctx, uint32_t opc,
   int rd, int rs, int rt)
 {
@@ -16031,6 +16153,12 @@ static void 
mips_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
 ctx->base.max_insns = 2;
 }
 
+ctx->ntemp = 0;
+ctx->ntemp64 = 0;
+memset(ctx->temp, 0, sizeof(ctx->temp));
+memset(ctx->temp64, 0, sizeof(ctx->temp));
+ctx->zero = tcg_constant_tl(0);
+
 LOG_DISAS("\ntb %p idx %d hflags %04x\n", ctx->base.tb, ctx->mem_idx,
   ctx->hflags);
 }
@@ -16053,6 +16181,7 @@ static void mips_tr_translate_insn(DisasContextBase 
*dcbase, CPUState *cs)
 DisasContext *ctx = container_of(dcbase, DisasContext, base);
 int insn_bytes;
 int is_slot;
+int i;
 
 is_slot = ctx->hflags & MIPS_HFLAG_BMASK;
 if (ctx->insn_flags & ISA_NANOMIPS32) {
@@ -16074,

[PATCH 0/6] MIPS decodetree conversion

2022-10-24 Thread Jiaxun Yang
Currently only MIPS I to MIPS Release 5 arithmatic functions are converted.
Old decoding functions are perserved in codebase for now due to dependencies
from microMIPS/nanoMIPS translation code. Will remove them after dealing with
release 6.

Both instruction encoding and test cases are generated form MIPS's internal
architecture validation tools so they are gureented to be correct.

Note:
There are some checkpatch warning/error on test cases but I'm not going to
touch them as they are generated code.

Thanks.

RFC->v1:
 - Tidy up test cases
 - Convert TX79 as well

- Jiaxun
Jiaxun Yang (6):
  target/mips: Introduce register access helper functions
  target/mips: Convert legacy arithmatic instructions to decodetree
  tests/tcg/mips: Add mips32 arithmatic instruction test cases
  target/mips: Split Loongson extention translation into standalone file
  target/mips: Move all tx79 instructions to decodetree
  target/mips: Make MXU decoder standalone

 target/mips/tcg/insn_trans/trans_arith.c.inc  |  352 +++
 target/mips/tcg/legacy.decode |   62 +
 target/mips/tcg/loongson_translate.c  | 1290 +++
 target/mips/tcg/meson.build   |2 +
 target/mips/tcg/mxu_translate.c   |   98 +-
 target/mips/tcg/translate.c   | 1917 ++---
 target/mips/tcg/translate.h   |   60 +
 target/mips/tcg/tx79.decode   |   14 +
 target/mips/tcg/tx79_translate.c  |  205 +-
 tests/tcg/mips/include/test_utils_32.h|   75 +
 .../tcg/mips/user/isa/mips32/arithmatic/add.c |   99 +
 .../mips/user/isa/mips32/arithmatic/addi.c|   70 +
 .../mips/user/isa/mips32/arithmatic/addiu.c   |   90 +
 .../mips/user/isa/mips32/arithmatic/addu.c|  125 ++
 .../tcg/mips/user/isa/mips32/arithmatic/div.c |   81 +
 .../mips/user/isa/mips32/arithmatic/divu.c|   78 +
 .../mips/user/isa/mips32/arithmatic/madd.c|   79 +
 .../mips/user/isa/mips32/arithmatic/maddu.c   |   78 +
 .../mips/user/isa/mips32/arithmatic/msub.c|   78 +
 .../mips/user/isa/mips32/arithmatic/msubu.c   |   78 +
 .../tcg/mips/user/isa/mips32/arithmatic/mul.c |   78 +
 .../mips/user/isa/mips32/arithmatic/mult.c|   78 +
 .../mips/user/isa/mips32/arithmatic/multu.c   |   78 +
 .../tcg/mips/user/isa/mips32/arithmatic/slt.c |   61 +
 .../mips/user/isa/mips32/arithmatic/slti.c|   48 +
 .../mips/user/isa/mips32/arithmatic/sltiu.c   |   48 +
 .../mips/user/isa/mips32/arithmatic/sltu.c|   61 +
 .../tcg/mips/user/isa/mips32/arithmatic/sub.c |  104 +
 .../mips/user/isa/mips32/arithmatic/subu.c|  108 +
 29 files changed, 3865 insertions(+), 1730 deletions(-)
 create mode 100644 target/mips/tcg/insn_trans/trans_arith.c.inc
 create mode 100644 target/mips/tcg/legacy.decode
 create mode 100644 target/mips/tcg/loongson_translate.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/add.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/addi.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/addiu.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/addu.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/div.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/divu.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/madd.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/maddu.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/msub.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/msubu.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/mul.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/mult.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/multu.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/slt.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/slti.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/sltiu.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/sltu.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/sub.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/subu.c

-- 
2.34.1




[PATCH 5/6] target/mips: Move all tx79 instructions to decodetree

2022-10-24 Thread Jiaxun Yang
Move MUL family instructions into decodetree.
Also implement RDHWR emulation for user instructions in decodetree
SQ translation.

Signed-off-by: Jiaxun Yang 
---
 target/mips/tcg/translate.c  | 410 +--
 target/mips/tcg/tx79.decode  |  14 ++
 target/mips/tcg/tx79_translate.c | 205 +++-
 3 files changed, 219 insertions(+), 410 deletions(-)

diff --git a/target/mips/tcg/translate.c b/target/mips/tcg/translate.c
index d398b2f44d..c8a3f63203 100644
--- a/target/mips/tcg/translate.c
+++ b/target/mips/tcg/translate.c
@@ -956,82 +956,6 @@ enum {
 OPC_NMSUB_PS= 0x3E | OPC_CP3,
 };
 
-/*
- * MMI (MultiMedia Instruction) encodings
- * ==
- *
- * MMI instructions encoding table keys:
- *
- * *   This code is reserved for future use. An attempt to execute it
- * causes a Reserved Instruction exception.
- * %   This code indicates an instruction class. The instruction word
- * must be further decoded by examining additional tables that show
- * the values for other instruction fields.
- * #   This code is reserved for the unsupported instructions DMULT,
- * DMULTU, DDIV, DDIVU, LL, LLD, SC, SCD, LWC2 and SWC2. An attempt
- * to execute it causes a Reserved Instruction exception.
- *
- * MMI instructions encoded by opcode field (MMI, LQ, SQ):
- *
- *  31260
- * +++
- * | opcode ||
- * +++
- *
- *   opcode  bits 28..26
- * bits |   0   |   1   |   2   |   3   |   4   |   5   |   6   |   7
- *   31..29 |  000  |  001  |  010  |  011  |  100  |  101  |  110  |  111
- *   ---+---+---+---+---+---+---+---+---
- *0 000 |SPECIAL| REGIMM|   J   |  JAL  |  BEQ  |  BNE  |  BLEZ |  BGTZ
- *1 001 |  ADDI | ADDIU |  SLTI | SLTIU |  ANDI |  ORI  |  XORI |  LUI
- *2 010 |  COP0 |  COP1 |   *   |   *   |  BEQL |  BNEL | BLEZL | BGTZL
- *3 011 | DADDI | DADDIU|  LDL  |  LDR  |  MMI% |   *   |   LQ  |   SQ
- *4 100 |   LB  |   LH  |  LWL  |   LW  |  LBU  |  LHU  |  LWR  |  LWU
- *5 101 |   SB  |   SH  |  SWL  |   SW  |  SDL  |  SDR  |  SWR  | CACHE
- *6 110 |   #   |  LWC1 |   #   |  PREF |   #   |  LDC1 |   #   |   LD
- *7 111 |   #   |  SWC1 |   #   |   *   |   #   |  SDC1 |   #   |   SD
- */
-
-enum {
-MMI_OPC_CLASS_MMI = 0x1C << 26,/* Same as OPC_SPECIAL2 */
-MMI_OPC_SQ= 0x1F << 26,/* Same as OPC_SPECIAL3 */
-};
-
-/*
- * MMI instructions with opcode field = MMI:
- *
- *  3126 5  0
- * ++---++
- * |   MMI  |   |function|
- * ++---++
- *
- * function  bits 2..0
- * bits |   0   |   1   |   2   |   3   |   4   |   5   |   6   |   7
- * 5..3 |  000  |  001  |  010  |  011  |  100  |  101  |  110  |  111
- *   ---+---+---+---+---+---+---+---+---
- *0 000 |  MADD | MADDU |   *   |   *   | PLZCW |   *   |   *   |   *
- *1 001 | MMI0% | MMI2% |   *   |   *   |   *   |   *   |   *   |   *
- *2 010 | MFHI1 | MTHI1 | MFLO1 | MTLO1 |   *   |   *   |   *   |   *
- *3 011 | MULT1 | MULTU1|  DIV1 | DIVU1 |   *   |   *   |   *   |   *
- *4 100 | MADD1 | MADDU1|   *   |   *   |   *   |   *   |   *   |   *
- *5 101 | MMI1% | MMI3% |   *   |   *   |   *   |   *   |   *   |   *
- *6 110 | PMFHL | PMTHL |   *   |   *   | PSLLH |   *   | PSRLH | PSRAH
- *7 111 |   *   |   *   |   *   |   *   | PSLLW |   *   | PSRLW | PSRAW
- */
-
-#define MASK_MMI(op) (MASK_OP_MAJOR(op) | ((op) & 0x3F))
-enum {
-MMI_OPC_MADD   = 0x00 | MMI_OPC_CLASS_MMI, /* Same as OPC_MADD */
-MMI_OPC_MADDU  = 0x01 | MMI_OPC_CLASS_MMI, /* Same as OPC_MADDU */
-MMI_OPC_MULT1  = 0x18 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MULT */
-MMI_OPC_MULTU1 = 0x19 | MMI_OPC_CLASS_MMI, /* Same min. as OPC_MULTU */
-MMI_OPC_DIV1   = 0x1A | MMI_OPC_CLASS_MMI, /* Same minor as OPC_DIV  */
-MMI_OPC_DIVU1  = 0x1B | MMI_OPC_CLASS_MMI, /* Same minor as OPC_DIVU */
-MMI_OPC_MADD1  = 0x20 | MMI_OPC_CLASS_MMI,
-MMI_OPC_MADDU1 = 0x21 | MMI_OPC_CLASS_MMI,
-};
-
-
 /* global register indices */
 TCGv cpu_gpr[32], cpu_PC;
 /*
@@ -3270,65 +3194,6 @@ static void gen_r6_muldiv(DisasContext *ctx, int opc, 
int rd, int rs, int rt)
 tcg_temp_free(t1);
 }
 
-#if defined(TARGET_MIPS64)
-static void gen_div1_tx79(DisasContext *ctx, uint32_t opc, int rs, int rt)
-{
-TCGv t0, t1;
-
-t0 = tcg_temp_new();
-t1 = tcg_temp_new();
-
-gen_load_gpr(t0, rs);
-gen_load_gpr(t1, rt);
-
-switch (opc) {
-case MMI_OPC_DIV1:
-{
-TCGv t2 = tcg_temp_new();
-   

[PATCH 6/6] target/mips: Make MXU decoder standalone

2022-10-24 Thread Jiaxun Yang
MXU is treated as an ISA extension for now.

Signed-off-by: Jiaxun Yang 
---
 target/mips/tcg/mxu_translate.c | 98 ++---
 target/mips/tcg/translate.c | 13 ++---
 2 files changed, 60 insertions(+), 51 deletions(-)

diff --git a/target/mips/tcg/mxu_translate.c b/target/mips/tcg/mxu_translate.c
index f52244e1b2..9be37da620 100644
--- a/target/mips/tcg/mxu_translate.c
+++ b/target/mips/tcg/mxu_translate.c
@@ -354,6 +354,8 @@
  *   Programming Manual", Ingenic Semiconductor Co, Ltd., revision June 2, 2017
  */
 
+#define OPC_SPECIAL2 (0x1C << 26)
+
 enum {
 OPC_MXU__POOL00  = 0x03,
 OPC_MXU_D16MUL   = 0x08,
@@ -1552,54 +1554,64 @@ bool decode_ase_mxu(DisasContext *ctx, uint32_t insn)
 {
 uint32_t opcode = extract32(insn, 0, 6);
 
-if (opcode == OPC_MXU_S32M2I) {
-gen_mxu_s32m2i(ctx);
-return true;
+if (MASK_OP_MAJOR(insn) != OPC_SPECIAL2) {
+return false;
 }
 
-if (opcode == OPC_MXU_S32I2M) {
+switch (opcode) {
+case OPC_MXU_S32M2I:
+gen_mxu_s32m2i(ctx);
+return true;
+case OPC_MXU_S32I2M:
 gen_mxu_s32i2m(ctx);
 return true;
-}
-
-{
-TCGv t_mxu_cr = tcg_temp_new();
-TCGLabel *l_exit = gen_new_label();
-
-gen_load_mxu_cr(t_mxu_cr);
-tcg_gen_andi_tl(t_mxu_cr, t_mxu_cr, MXU_CR_MXU_EN);
-tcg_gen_brcondi_tl(TCG_COND_NE, t_mxu_cr, MXU_CR_MXU_EN, l_exit);
+case OPC_MXU__POOL00:
+case OPC_MXU_D16MUL:
+case OPC_MXU_D16MAC:
+case OPC_MXU__POOL04:
+case OPC_MXU_S8LDD:
+case OPC_MXU__POOL16:
+case OPC_MXU__POOL19:
+{
+TCGv t_mxu_cr = tcg_temp_new();
+TCGLabel *l_exit = gen_new_label();
+
+gen_load_mxu_cr(t_mxu_cr);
+tcg_gen_andi_tl(t_mxu_cr, t_mxu_cr, MXU_CR_MXU_EN);
+tcg_gen_brcondi_tl(TCG_COND_NE, t_mxu_cr, MXU_CR_MXU_EN, l_exit);
+
+switch (opcode) {
+case OPC_MXU__POOL00:
+decode_opc_mxu__pool00(ctx);
+break;
+case OPC_MXU_D16MUL:
+gen_mxu_d16mul(ctx);
+break;
+case OPC_MXU_D16MAC:
+gen_mxu_d16mac(ctx);
+break;
+case OPC_MXU__POOL04:
+decode_opc_mxu__pool04(ctx);
+break;
+case OPC_MXU_S8LDD:
+gen_mxu_s8ldd(ctx);
+break;
+case OPC_MXU__POOL16:
+decode_opc_mxu__pool16(ctx);
+break;
+case OPC_MXU__POOL19:
+decode_opc_mxu__pool19(ctx);
+break;
+default:
+MIPS_INVAL("decode_opc_mxu");
+gen_reserved_instruction(ctx);
+}
 
-switch (opcode) {
-case OPC_MXU__POOL00:
-decode_opc_mxu__pool00(ctx);
-break;
-case OPC_MXU_D16MUL:
-gen_mxu_d16mul(ctx);
-break;
-case OPC_MXU_D16MAC:
-gen_mxu_d16mac(ctx);
-break;
-case OPC_MXU__POOL04:
-decode_opc_mxu__pool04(ctx);
-break;
-case OPC_MXU_S8LDD:
-gen_mxu_s8ldd(ctx);
-break;
-case OPC_MXU__POOL16:
-decode_opc_mxu__pool16(ctx);
-break;
-case OPC_MXU__POOL19:
-decode_opc_mxu__pool19(ctx);
-break;
-default:
-MIPS_INVAL("decode_opc_mxu");
-gen_reserved_instruction(ctx);
+gen_set_label(l_exit);
+tcg_temp_free(t_mxu_cr);
 }
-
-gen_set_label(l_exit);
-tcg_temp_free(t_mxu_cr);
+return true;
+default:
+return false;
 }
-
-return true;
 }
diff --git a/target/mips/tcg/translate.c b/target/mips/tcg/translate.c
index c8a3f63203..a5e89c528d 100644
--- a/target/mips/tcg/translate.c
+++ b/target/mips/tcg/translate.c
@@ -13766,14 +13766,6 @@ static bool decode_opc_legacy(CPUMIPSState *env, 
DisasContext *ctx)
 decode_opc_special(env, ctx);
 break;
 case OPC_SPECIAL2:
-if (TARGET_LONG_BITS == 32 && (ctx->insn_flags & ASE_MXU)) {
-if (MASK_SPECIAL2(ctx->opcode) == OPC_MUL) {
-gen_arith(ctx, OPC_MUL, rd, rs, rt);
-} else {
-decode_ase_mxu(ctx, ctx->opcode);
-}
-break;
-}
 decode_opc_special2_legacy(env, ctx);
 break;
 case OPC_SPECIAL3:
@@ -14484,6 +14476,11 @@ static void decode_opc(CPUMIPSState *env, DisasContext 
*ctx)
 if (cpu_supports_isa(env, ASE_LMMI) && decode_ase_lmmi(ctx, ctx->opcode)) {
 return;
 }
+if (TARGET_LONG_BITS == 32) {
+if (cpu_supports_isa(env, ASE_MXU) && decode_ase_mxu(ctx, 
ctx->opcode)) {
+return;
+}
+}
 if (ase_msa_available(env) && decode_ase_msa(ctx, ctx->opcode)) {
 return;
 }
-- 
2.34.1




[PATCH 2/6] target/mips: Convert legacy arithmatic instructions to decodetree

2022-10-24 Thread Jiaxun Yang
Mostly copy paste from translate.c, with some simplification
based on newly introduced register access functions.

Signed-off-by: Jiaxun Yang 
---
 target/mips/tcg/insn_trans/trans_arith.c.inc | 352 +++
 target/mips/tcg/legacy.decode|  62 
 target/mips/tcg/meson.build  |   1 +
 target/mips/tcg/translate.c  |  20 +-
 4 files changed, 425 insertions(+), 10 deletions(-)
 create mode 100644 target/mips/tcg/insn_trans/trans_arith.c.inc
 create mode 100644 target/mips/tcg/legacy.decode

diff --git a/target/mips/tcg/insn_trans/trans_arith.c.inc 
b/target/mips/tcg/insn_trans/trans_arith.c.inc
new file mode 100644
index 00..3de9722939
--- /dev/null
+++ b/target/mips/tcg/insn_trans/trans_arith.c.inc
@@ -0,0 +1,352 @@
+static bool gen_arith_notrap(DisasContext *ctx, arg_r *a,
+ DisasExtend ext, void (*func)(TCGv, TCGv, TCGv))
+{
+TCGv dest = dest_gpr(ctx, a->rd);
+TCGv src1 = get_gpr(ctx, a->rs, ext);
+TCGv src2 = get_gpr(ctx, a->rt, ext);
+
+func(dest, src1, src2);
+gen_set_gpr(a->rd, dest, ext);
+
+return true;
+}
+
+static bool gen_add(DisasContext *ctx, arg_r *a, DisasExtend ext)
+{
+TCGv t0 = tcg_temp_local_new();
+TCGv t1 = get_gpr(ctx, a->rs, ext);
+TCGv t2 = get_gpr(ctx, a->rt, ext);
+TCGLabel *l1 = gen_new_label();
+
+tcg_gen_add_tl(t0, t1, t2);
+gen_extend(t0, t0, ext);
+tcg_gen_xor_tl(t1, t1, t2);
+tcg_gen_xor_tl(t2, t0, t2);
+tcg_gen_andc_tl(t1, t2, t1);
+tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
+/* operands of same sign, result different sign */
+generate_exception(ctx, EXCP_OVERFLOW);
+gen_set_label(l1);
+gen_store_gpr(t0, a->rd);
+tcg_temp_free(t0);
+
+return true;
+}
+
+static bool gen_sub(DisasContext *ctx, arg_r *a, DisasExtend ext)
+{
+TCGv src1 = get_gpr(ctx, a->rs, ext);
+TCGv src2 = get_gpr(ctx, a->rt, ext);
+TCGv t0 = tcg_temp_local_new();
+TCGv t1 = tcg_temp_local_new();
+TCGv t2 = tcg_temp_local_new();
+TCGLabel *l1 = gen_new_label();
+
+tcg_gen_sub_tl(t0, src1, src2);
+gen_extend(t0, t0, ext);
+tcg_gen_xor_tl(t2, src1, src2);
+tcg_gen_xor_tl(t1, t0, src1);
+tcg_gen_and_tl(t1, t1, t2);
+tcg_temp_free(t2);
+tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
+tcg_temp_free(t1);
+/*
+ * operands of different sign, first operand and the result
+ * of different sign
+ */
+generate_exception(ctx, EXCP_OVERFLOW);
+gen_set_label(l1);
+gen_store_gpr(t0, a->rd);
+tcg_temp_free(t0);
+
+return true;
+}
+
+static bool gen_arith_imm_notrap(DisasContext *ctx, arg_i *a, DisasExtend ext,
+ void (*func)(TCGv, TCGv, target_long))
+{
+TCGv dest = dest_gpr(ctx, a->rt);
+TCGv src1 = get_gpr(ctx, a->rs, ext);
+
+func(dest, src1, a->imm);
+gen_set_gpr(a->rt, dest, ext);
+
+return true;
+}
+
+static bool gen_add_imm(DisasContext *ctx, arg_i *a, DisasExtend ext)
+{
+TCGv t0 = tcg_temp_local_new();
+TCGv t1 = get_gpr(ctx, a->rs, ext);
+TCGv t2 = tcg_temp_new();
+TCGLabel *l1 = gen_new_label();
+target_ulong uimm = (target_long)a->imm; /* Sign extend to 32/64 bits */
+
+gen_load_gpr(t1, a->rs);
+tcg_gen_addi_tl(t0, t1, uimm);
+tcg_gen_ext32s_tl(t0, t0);
+
+tcg_gen_xori_tl(t1, t1, ~uimm);
+tcg_gen_xori_tl(t2, t0, uimm);
+tcg_gen_and_tl(t1, t1, t2);
+tcg_temp_free(t2);
+tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
+/* operands of same sign, result different sign */
+generate_exception(ctx, EXCP_OVERFLOW);
+gen_set_label(l1);
+tcg_gen_ext32s_tl(t0, t0);
+gen_store_gpr(t0, a->rt);
+tcg_temp_free(t0);
+
+return true;
+}
+
+#define DECLEAR_GEN_CL(suffix, arg_type)\
+static bool gen_cl_##suffix(DisasContext *ctx, arg_type * a, bool zero) \
+{   \
+TCGv dest = dest_gpr(ctx, a->rd);   \
+TCGv src = get_gpr(ctx, a->rs, EXT_NONE);   \
+if (!zero) {\
+tcg_gen_not_tl(dest, src);  \
+}   \
+tcg_gen_ext32u_tl(dest, dest);  \
+tcg_gen_clzi_tl(dest, dest, TARGET_LONG_BITS);  \
+tcg_gen_subi_tl(dest, dest, TARGET_LONG_BITS - 32); \
+gen_set_gpr(a->rd, dest, EXT_NONE); \
+return true;\
+}   \
+
+DECLEAR_GEN_CL(legacy, arg_r)
+#undef DECLEAR

[PATCH 3/6] tests/tcg/mips: Add mips32 arithmatic instruction test cases

2022-10-24 Thread Jiaxun Yang
Those cases are delivered from MIPS internal architecture validation
tools.

Signed-off-by: Jiaxun Yang 
---
 tests/tcg/mips/include/test_utils_32.h|  75 +++
 .../tcg/mips/user/isa/mips32/arithmatic/add.c |  99 ++
 .../mips/user/isa/mips32/arithmatic/addi.c|  70 ++
 .../mips/user/isa/mips32/arithmatic/addiu.c   |  90 +
 .../mips/user/isa/mips32/arithmatic/addu.c| 125 ++
 .../tcg/mips/user/isa/mips32/arithmatic/div.c |  81 
 .../mips/user/isa/mips32/arithmatic/divu.c|  78 +++
 .../mips/user/isa/mips32/arithmatic/madd.c|  79 +++
 .../mips/user/isa/mips32/arithmatic/maddu.c   |  78 +++
 .../mips/user/isa/mips32/arithmatic/msub.c|  78 +++
 .../mips/user/isa/mips32/arithmatic/msubu.c   |  78 +++
 .../tcg/mips/user/isa/mips32/arithmatic/mul.c |  78 +++
 .../mips/user/isa/mips32/arithmatic/mult.c|  78 +++
 .../mips/user/isa/mips32/arithmatic/multu.c   |  78 +++
 .../tcg/mips/user/isa/mips32/arithmatic/slt.c |  61 +
 .../mips/user/isa/mips32/arithmatic/slti.c|  48 +++
 .../mips/user/isa/mips32/arithmatic/sltiu.c   |  48 +++
 .../mips/user/isa/mips32/arithmatic/sltu.c|  61 +
 .../tcg/mips/user/isa/mips32/arithmatic/sub.c | 104 +++
 .../mips/user/isa/mips32/arithmatic/subu.c| 108 +++
 20 files changed, 1595 insertions(+)
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/add.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/addi.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/addiu.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/addu.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/div.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/divu.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/madd.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/maddu.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/msub.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/msubu.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/mul.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/mult.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/multu.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/slt.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/slti.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/sltiu.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/sltu.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/sub.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/subu.c

diff --git a/tests/tcg/mips/include/test_utils_32.h 
b/tests/tcg/mips/include/test_utils_32.h
index c33990c0c5..00480e3283 100644
--- a/tests/tcg/mips/include/test_utils_32.h
+++ b/tests/tcg/mips/include/test_utils_32.h
@@ -29,6 +29,81 @@
 
 #define PRINT_RESULTS 0
 
+#define DO_MIPS32_r(mnemonic, id, input1, input2, expect)  \
+{  \
+uint32_t output;   \
+uint32_t expect_val = expect;  \
+__asm__ volatile ( \
+  "li $t1, " #input1 "\n\t"\
+  "li $t2, " #input2 "\n\t"\
+  #mnemonic " $t0, $t1, $t2\n\t"   \
+  "sw $t0, 0(%0)\n\t"  \
+  :\
+  : "r" ()  \
+  : "t0", "t1", "t2", "memory" \
+); \
+check_single_insn_32(id, _count, _count, 1, _val, 
); \
+}
+
+#define DO_MIPS32_i(mnemonic, id, imm, input1, expect) \
+{  \
+uint32_t output;   \
+uint32_t expect_val = expect;  \
+__asm__ volatile ( \
+  "li $t1, " #input1 "\n\t"\
+  #mnemonic " $t0, $t1, " #imm "\n\t"  \
+  "sw $t0, 0(%0)\n\t"  \
+  :\
+  : "r" ()  \
+  : "t0", "

[PATCH] hw/mips/boston: Don't set link_up for xilinx-pcie

2022-10-24 Thread Jiaxun Yang
PCIe port 0 and 1 had link_up set as false previously,
that makes those two ports effectively useless. It can
be annoying for users to find that the device they plug
on those buses won't work at all.

As link_up is true by default, just don't set it again in
boston platform code.

Signed-off-by: Jiaxun Yang 
---
 hw/mips/boston.c | 9 -
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/hw/mips/boston.c b/hw/mips/boston.c
index d2ab9da1a0..aa7942bbc0 100644
--- a/hw/mips/boston.c
+++ b/hw/mips/boston.c
@@ -424,7 +424,7 @@ static inline XilinxPCIEHost *
 xilinx_pcie_init(MemoryRegion *sys_mem, uint32_t bus_nr,
  hwaddr cfg_base, uint64_t cfg_size,
  hwaddr mmio_base, uint64_t mmio_size,
- qemu_irq irq, bool link_up)
+ qemu_irq irq)
 {
 DeviceState *dev;
 MemoryRegion *cfg, *mmio;
@@ -436,7 +436,6 @@ xilinx_pcie_init(MemoryRegion *sys_mem, uint32_t bus_nr,
 qdev_prop_set_uint64(dev, "cfg_size", cfg_size);
 qdev_prop_set_uint64(dev, "mmio_base", mmio_base);
 qdev_prop_set_uint64(dev, "mmio_size", mmio_size);
-qdev_prop_set_bit(dev, "link_up", link_up);
 
 sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), _fatal);
 
@@ -729,21 +728,21 @@ static void boston_mach_init(MachineState *machine)
  boston_memmap[BOSTON_PCIE0].size,
  boston_memmap[BOSTON_PCIE0_MMIO].base,
  boston_memmap[BOSTON_PCIE0_MMIO].size,
- get_cps_irq(>cps, 2), false);
+ get_cps_irq(>cps, 2));
 
 xilinx_pcie_init(sys_mem, 1,
  boston_memmap[BOSTON_PCIE1].base,
  boston_memmap[BOSTON_PCIE1].size,
  boston_memmap[BOSTON_PCIE1_MMIO].base,
  boston_memmap[BOSTON_PCIE1_MMIO].size,
- get_cps_irq(>cps, 1), false);
+ get_cps_irq(>cps, 1));
 
 pcie2 = xilinx_pcie_init(sys_mem, 2,
  boston_memmap[BOSTON_PCIE2].base,
  boston_memmap[BOSTON_PCIE2].size,
  boston_memmap[BOSTON_PCIE2_MMIO].base,
  boston_memmap[BOSTON_PCIE2_MMIO].size,
- get_cps_irq(>cps, 0), true);
+ get_cps_irq(>cps, 0));
 
 platreg = g_new(MemoryRegion, 1);
 memory_region_init_io(platreg, NULL, _platreg_ops, s,
-- 
2.37.1 (Apple Git-137.1)




Re: [PATCH 0/2] hw/mips/boston: Initrd support

2022-10-24 Thread Jiaxun Yang
Please ignore this mail.
Sorry for the noise.


Thanks.

> 2022年10月24日 15:35,Jiaxun Yang  写道:
> 
> Hi all,
> 
> Just a small addition to make boston board easier to use :-)
> 
> Thanks
> - Jiaxun
> 
> Jiaxun Yang (2):
>  mips/boston: Support initrd for ELF kernel
>  hw/mips/boston: Pack fdt in fdt filter
> 
> hw/mips/boston.c | 40 
> 1 file changed, 40 insertions(+)
> 
> -- 
> 2.32.1 (Apple Git-133)
> 

---
Jiaxun Yang




[PATCH 0/2] hw/mips/boston: Initrd support

2022-10-24 Thread Jiaxun Yang
Hi all,

Just a small addition to make boston board easier to use :-)

Thanks
- Jiaxun

Jiaxun Yang (2):
  mips/boston: Support initrd for ELF kernel
  hw/mips/boston: Pack fdt in fdt filter

 hw/mips/boston.c | 40 
 1 file changed, 40 insertions(+)

-- 
2.32.1 (Apple Git-133)




Re: [PATCH] linux-user: Fix more MIPS n32 syscall ABI issues

2022-10-06 Thread Jiaxun Yang



> 2022年10月6日 09:55,WANG Xuerui  写道:
> 
> In commit 80f0fe3a85 ("linux-user: Fix syscall parameter handling for
> MIPS n32") the ABI problem regarding offset64 on MIPS n32 was fixed,
> but still some cases remain where the n32 is incorrectly treated as any
> other 32-bit ABI that passes 64-bit arguments in pairs of GPRs. Fix by
> excluding TARGET_ABI_MIPSN32 from various TARGET_ABI_BITS == 32 checks.
> 
> Closes: https://gitlab.com/qemu-project/qemu/-/issues/1238
> Signed-off-by: WANG Xuerui 
> Cc: Philippe Mathieu-Daudé 
> Cc: Jiaxun Yang 
> Cc: Andreas K. Hüttel 
> Cc: Joshua Kinard 

Good catch.

Reviewed-by: Jiaxun Yang 
Tested-by: Jiaxun Yang 

Managed to chroot into a n32 “共创 Linux” rootfs and ran some test.
Looks good.

Thanks
- Jiaxun


> ---
> 
> Note: I can't reproduce the crash with neither MIPS n32 sysroot at my hand
> (a self-built one for Loongson-2F, and 
> stage3-mips64_n32-openrc-20221001T170527Z),
> so I can only verify by looking at the (host and qemu) strace outputs, and
> would have to ask you to review/test this harder. Thanks.
> 
> linux-user/syscall.c | 10 +-
> 1 file changed, 5 insertions(+), 5 deletions(-)
> 
> diff --git a/linux-user/syscall.c b/linux-user/syscall.c
> index 2e954d8dbd..8b2d39fe73 100644
> --- a/linux-user/syscall.c
> +++ b/linux-user/syscall.c
> @@ -11793,7 +11793,7 @@ static abi_long do_syscall1(CPUArchState *cpu_env, 
> int num, abi_long arg1,
> return -host_to_target_errno(ret);
> #endif
> 
> -#if TARGET_ABI_BITS == 32
> +#if TARGET_ABI_BITS == 32 && !defined(TARGET_ABI_MIPSN32)
> 
> #ifdef TARGET_NR_fadvise64_64
> case TARGET_NR_fadvise64_64:
> @@ -11920,7 +11920,7 @@ static abi_long do_syscall1(CPUArchState *cpu_env, 
> int num, abi_long arg1,
> return get_errno(sys_gettid());
> #ifdef TARGET_NR_readahead
> case TARGET_NR_readahead:
> -#if TARGET_ABI_BITS == 32
> +#if TARGET_ABI_BITS == 32 && !defined(TARGET_ABI_MIPSN32)
> if (regpairs_aligned(cpu_env, num)) {
> arg2 = arg3;
> arg3 = arg4;
> @@ -12612,7 +12612,7 @@ static abi_long do_syscall1(CPUArchState *cpu_env, 
> int num, abi_long arg1,
> #endif /* CONFIG_EVENTFD  */
> #if defined(CONFIG_FALLOCATE) && defined(TARGET_NR_fallocate)
> case TARGET_NR_fallocate:
> -#if TARGET_ABI_BITS == 32
> +#if TARGET_ABI_BITS == 32 && !defined(TARGET_ABI_MIPSN32)
> ret = get_errno(fallocate(arg1, arg2, target_offset64(arg3, arg4),
>   target_offset64(arg5, arg6)));
> #else
> @@ -12623,7 +12623,7 @@ static abi_long do_syscall1(CPUArchState *cpu_env, 
> int num, abi_long arg1,
> #if defined(CONFIG_SYNC_FILE_RANGE)
> #if defined(TARGET_NR_sync_file_range)
> case TARGET_NR_sync_file_range:
> -#if TARGET_ABI_BITS == 32
> +#if TARGET_ABI_BITS == 32 && !defined(TARGET_ABI_MIPSN32)
> #if defined(TARGET_MIPS)
> ret = get_errno(sync_file_range(arg1, target_offset64(arg3, arg4),
> target_offset64(arg5, arg6), arg7));
> @@ -12645,7 +12645,7 @@ static abi_long do_syscall1(CPUArchState *cpu_env, 
> int num, abi_long arg1,
> case TARGET_NR_arm_sync_file_range:
> #endif
> /* This is like sync_file_range but the arguments are reordered */
> -#if TARGET_ABI_BITS == 32
> +#if TARGET_ABI_BITS == 32 && !defined(TARGET_ABI_MIPSN32)
> ret = get_errno(sync_file_range(arg1, target_offset64(arg3, arg4),
> target_offset64(arg5, arg6), arg2));
> #else
> -- 
> 2.38.0
> 

---
Jiaxun Yang




Re: [RFC PATCH 0/3] MIPS decodetree conversion attempt

2022-10-06 Thread Jiaxun Yang



> 2022年9月27日 11:33,Jiaxun Yang  写道:
> 
> 
> 
>> 2022年9月26日 22:35,Philippe Mathieu-Daudé  写道:
>> 
>> Hi Jiaxun,
>> 
>> On Mon, Sep 26, 2022 at 4:44 PM Jiaxun Yang  wrote:
>>>> 2022年9月21日 13:41,Jiaxun Yang  写道:
>>>> 
>>>> Hi,
>>>> 
>>>> This is my attempt of converting MIPS translation code into decodetree.
>>>> 
>>>> Currently only MIPS I to MIPS Release 5 arithmatic functions are converted.
>>>> Old decoding functions are perserved in codebase for now due to 
>>>> dependencies
>>>> from microMIPS/nanoMIPS translation code. Will remove them after dealing 
>>>> with
>>>> release 6.
>>>> 
>>>> Both instruction encoding and test cases are generated form MIPS's internal
>>>> architecture validation tools so they are gureented to be correct.
>>> 
>>> A kindly ping :-)
>>> 
>>> Will send v1 tomorrow if no objection.
>> 
>> Thanks for this work! On a first pass it looks good, but I'd like to
>> spend more time reviewing in the next few days. What did you change
>> between RFC->v1?
> 
> Nothing much, just tidy up test cases a little bit.

Any inputs?

Thanks.

> 
> Thanks.
> ---
> Jiaxun Yang
> 
> 

---
Jiaxun Yang




Re: [RFC PATCH 0/3] MIPS decodetree conversion attempt

2022-09-27 Thread Jiaxun Yang



> 2022年9月26日 22:35,Philippe Mathieu-Daudé  写道:
> 
> Hi Jiaxun,
> 
> On Mon, Sep 26, 2022 at 4:44 PM Jiaxun Yang  wrote:
>>> 2022年9月21日 13:41,Jiaxun Yang  写道:
>>> 
>>> Hi,
>>> 
>>> This is my attempt of converting MIPS translation code into decodetree.
>>> 
>>> Currently only MIPS I to MIPS Release 5 arithmatic functions are converted.
>>> Old decoding functions are perserved in codebase for now due to dependencies
>>> from microMIPS/nanoMIPS translation code. Will remove them after dealing 
>>> with
>>> release 6.
>>> 
>>> Both instruction encoding and test cases are generated form MIPS's internal
>>> architecture validation tools so they are gureented to be correct.
>> 
>> A kindly ping :-)
>> 
>> Will send v1 tomorrow if no objection.
> 
> Thanks for this work! On a first pass it looks good, but I'd like to
> spend more time reviewing in the next few days. What did you change
> between RFC->v1?

Nothing much, just tidy up test cases a little bit.

Thanks.
---
Jiaxun Yang




Re: [RFC PATCH 0/3] MIPS decodetree conversion attempt

2022-09-26 Thread Jiaxun Yang



> 2022年9月21日 13:41,Jiaxun Yang  写道:
> 
> Hi,
> 
> This is my attempt of converting MIPS translation code into decodetree.
> 
> Currently only MIPS I to MIPS Release 5 arithmatic functions are converted.
> Old decoding functions are perserved in codebase for now due to dependencies
> from microMIPS/nanoMIPS translation code. Will remove them after dealing with
> release 6.
> 
> Both instruction encoding and test cases are generated form MIPS's internal
> architecture validation tools so they are gureented to be correct.

A kindly ping :-)

Will send v1 tomorrow if no objection.

Thanks
- Jiaxun

> 
> Thanks.
> 
> - Jiaxun
> 
> Jiaxun Yang (3):
>  target/mips: Introduce register access helper functions
>  target/mips: Convert legacy arithmatic instructions to decodetree
>  tests/tcg/mips: Add mips32 arithmatic instruction test cases
> 
> target/mips/tcg/insn_trans/trans_arith.c.inc  | 352 ++
> target/mips/tcg/legacy.decode |  62 +++
> target/mips/tcg/meson.build   |   1 +
> target/mips/tcg/translate.c   | 143 ++-
> target/mips/tcg/translate.h   |  54 +++
> tests/tcg/mips/include/test_utils_32.h|  75 
> .../tcg/mips/user/isa/mips32/arithmatic/add.c |  99 +
> .../mips/user/isa/mips32/arithmatic/addi.c|  70 
> .../mips/user/isa/mips32/arithmatic/addiu.c   |  90 +
> .../mips/user/isa/mips32/arithmatic/addu.c| 125 +++
> .../tcg/mips/user/isa/mips32/arithmatic/div.c |  81 
> .../mips/user/isa/mips32/arithmatic/divu.c|  78 
> .../mips/user/isa/mips32/arithmatic/madd.c|  79 
> .../mips/user/isa/mips32/arithmatic/maddu.c   |  78 
> .../mips/user/isa/mips32/arithmatic/msub.c|  78 
> .../mips/user/isa/mips32/arithmatic/msubu.c   |  78 
> .../tcg/mips/user/isa/mips32/arithmatic/mul.c |  78 
> .../mips/user/isa/mips32/arithmatic/mult.c|  78 
> .../mips/user/isa/mips32/arithmatic/multu.c   |  78 
> .../tcg/mips/user/isa/mips32/arithmatic/slt.c |  61 +++
> .../mips/user/isa/mips32/arithmatic/slti.c|  48 +++
> .../mips/user/isa/mips32/arithmatic/sltiu.c   |  48 +++
> .../mips/user/isa/mips32/arithmatic/sltu.c|  61 +++
> .../tcg/mips/user/isa/mips32/arithmatic/sub.c | 104 ++
> .../mips/user/isa/mips32/arithmatic/subu.c| 108 ++
> 25 files changed, 2206 insertions(+), 1 deletion(-)
> create mode 100644 target/mips/tcg/insn_trans/trans_arith.c.inc
> create mode 100644 target/mips/tcg/legacy.decode
> create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/add.c
> create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/addi.c
> create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/addiu.c
> create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/addu.c
> create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/div.c
> create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/divu.c
> create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/madd.c
> create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/maddu.c
> create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/msub.c
> create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/msubu.c
> create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/mul.c
> create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/mult.c
> create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/multu.c
> create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/slt.c
> create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/slti.c
> create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/sltiu.c
> create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/sltu.c
> create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/sub.c
> create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/subu.c
> 
> -- 
> 2.34.1
> 

---
Jiaxun Yang




[RFC PATCH 0/3] MIPS decodetree conversion attempt

2022-09-21 Thread Jiaxun Yang
Hi,

This is my attempt of converting MIPS translation code into decodetree.

Currently only MIPS I to MIPS Release 5 arithmatic functions are converted.
Old decoding functions are perserved in codebase for now due to dependencies
from microMIPS/nanoMIPS translation code. Will remove them after dealing with
release 6.

Both instruction encoding and test cases are generated form MIPS's internal
architecture validation tools so they are gureented to be correct.

Thanks.

- Jiaxun

Jiaxun Yang (3):
  target/mips: Introduce register access helper functions
  target/mips: Convert legacy arithmatic instructions to decodetree
  tests/tcg/mips: Add mips32 arithmatic instruction test cases

 target/mips/tcg/insn_trans/trans_arith.c.inc  | 352 ++
 target/mips/tcg/legacy.decode |  62 +++
 target/mips/tcg/meson.build   |   1 +
 target/mips/tcg/translate.c   | 143 ++-
 target/mips/tcg/translate.h   |  54 +++
 tests/tcg/mips/include/test_utils_32.h|  75 
 .../tcg/mips/user/isa/mips32/arithmatic/add.c |  99 +
 .../mips/user/isa/mips32/arithmatic/addi.c|  70 
 .../mips/user/isa/mips32/arithmatic/addiu.c   |  90 +
 .../mips/user/isa/mips32/arithmatic/addu.c| 125 +++
 .../tcg/mips/user/isa/mips32/arithmatic/div.c |  81 
 .../mips/user/isa/mips32/arithmatic/divu.c|  78 
 .../mips/user/isa/mips32/arithmatic/madd.c|  79 
 .../mips/user/isa/mips32/arithmatic/maddu.c   |  78 
 .../mips/user/isa/mips32/arithmatic/msub.c|  78 
 .../mips/user/isa/mips32/arithmatic/msubu.c   |  78 
 .../tcg/mips/user/isa/mips32/arithmatic/mul.c |  78 
 .../mips/user/isa/mips32/arithmatic/mult.c|  78 
 .../mips/user/isa/mips32/arithmatic/multu.c   |  78 
 .../tcg/mips/user/isa/mips32/arithmatic/slt.c |  61 +++
 .../mips/user/isa/mips32/arithmatic/slti.c|  48 +++
 .../mips/user/isa/mips32/arithmatic/sltiu.c   |  48 +++
 .../mips/user/isa/mips32/arithmatic/sltu.c|  61 +++
 .../tcg/mips/user/isa/mips32/arithmatic/sub.c | 104 ++
 .../mips/user/isa/mips32/arithmatic/subu.c| 108 ++
 25 files changed, 2206 insertions(+), 1 deletion(-)
 create mode 100644 target/mips/tcg/insn_trans/trans_arith.c.inc
 create mode 100644 target/mips/tcg/legacy.decode
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/add.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/addi.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/addiu.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/addu.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/div.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/divu.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/madd.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/maddu.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/msub.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/msubu.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/mul.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/mult.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/multu.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/slt.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/slti.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/sltiu.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/sltu.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/sub.c
 create mode 100644 tests/tcg/mips/user/isa/mips32/arithmatic/subu.c

-- 
2.34.1




[RFC PATCH 2/3] target/mips: Convert legacy arithmatic instructions to decodetree

2022-09-21 Thread Jiaxun Yang
Mostly copy paste from translate.c, with some simplification
based on newly introduced register access functions.

Signed-off-by: Jiaxun Yang 
---
 target/mips/tcg/insn_trans/trans_arith.c.inc | 352 +++
 target/mips/tcg/legacy.decode|  62 
 target/mips/tcg/meson.build  |   1 +
 target/mips/tcg/translate.c  |  20 +-
 4 files changed, 425 insertions(+), 10 deletions(-)
 create mode 100644 target/mips/tcg/insn_trans/trans_arith.c.inc
 create mode 100644 target/mips/tcg/legacy.decode

diff --git a/target/mips/tcg/insn_trans/trans_arith.c.inc 
b/target/mips/tcg/insn_trans/trans_arith.c.inc
new file mode 100644
index 00..3de9722939
--- /dev/null
+++ b/target/mips/tcg/insn_trans/trans_arith.c.inc
@@ -0,0 +1,352 @@
+static bool gen_arith_notrap(DisasContext *ctx, arg_r *a,
+ DisasExtend ext, void (*func)(TCGv, TCGv, TCGv))
+{
+TCGv dest = dest_gpr(ctx, a->rd);
+TCGv src1 = get_gpr(ctx, a->rs, ext);
+TCGv src2 = get_gpr(ctx, a->rt, ext);
+
+func(dest, src1, src2);
+gen_set_gpr(a->rd, dest, ext);
+
+return true;
+}
+
+static bool gen_add(DisasContext *ctx, arg_r *a, DisasExtend ext)
+{
+TCGv t0 = tcg_temp_local_new();
+TCGv t1 = get_gpr(ctx, a->rs, ext);
+TCGv t2 = get_gpr(ctx, a->rt, ext);
+TCGLabel *l1 = gen_new_label();
+
+tcg_gen_add_tl(t0, t1, t2);
+gen_extend(t0, t0, ext);
+tcg_gen_xor_tl(t1, t1, t2);
+tcg_gen_xor_tl(t2, t0, t2);
+tcg_gen_andc_tl(t1, t2, t1);
+tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
+/* operands of same sign, result different sign */
+generate_exception(ctx, EXCP_OVERFLOW);
+gen_set_label(l1);
+gen_store_gpr(t0, a->rd);
+tcg_temp_free(t0);
+
+return true;
+}
+
+static bool gen_sub(DisasContext *ctx, arg_r *a, DisasExtend ext)
+{
+TCGv src1 = get_gpr(ctx, a->rs, ext);
+TCGv src2 = get_gpr(ctx, a->rt, ext);
+TCGv t0 = tcg_temp_local_new();
+TCGv t1 = tcg_temp_local_new();
+TCGv t2 = tcg_temp_local_new();
+TCGLabel *l1 = gen_new_label();
+
+tcg_gen_sub_tl(t0, src1, src2);
+gen_extend(t0, t0, ext);
+tcg_gen_xor_tl(t2, src1, src2);
+tcg_gen_xor_tl(t1, t0, src1);
+tcg_gen_and_tl(t1, t1, t2);
+tcg_temp_free(t2);
+tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
+tcg_temp_free(t1);
+/*
+ * operands of different sign, first operand and the result
+ * of different sign
+ */
+generate_exception(ctx, EXCP_OVERFLOW);
+gen_set_label(l1);
+gen_store_gpr(t0, a->rd);
+tcg_temp_free(t0);
+
+return true;
+}
+
+static bool gen_arith_imm_notrap(DisasContext *ctx, arg_i *a, DisasExtend ext,
+ void (*func)(TCGv, TCGv, target_long))
+{
+TCGv dest = dest_gpr(ctx, a->rt);
+TCGv src1 = get_gpr(ctx, a->rs, ext);
+
+func(dest, src1, a->imm);
+gen_set_gpr(a->rt, dest, ext);
+
+return true;
+}
+
+static bool gen_add_imm(DisasContext *ctx, arg_i *a, DisasExtend ext)
+{
+TCGv t0 = tcg_temp_local_new();
+TCGv t1 = get_gpr(ctx, a->rs, ext);
+TCGv t2 = tcg_temp_new();
+TCGLabel *l1 = gen_new_label();
+target_ulong uimm = (target_long)a->imm; /* Sign extend to 32/64 bits */
+
+gen_load_gpr(t1, a->rs);
+tcg_gen_addi_tl(t0, t1, uimm);
+tcg_gen_ext32s_tl(t0, t0);
+
+tcg_gen_xori_tl(t1, t1, ~uimm);
+tcg_gen_xori_tl(t2, t0, uimm);
+tcg_gen_and_tl(t1, t1, t2);
+tcg_temp_free(t2);
+tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
+/* operands of same sign, result different sign */
+generate_exception(ctx, EXCP_OVERFLOW);
+gen_set_label(l1);
+tcg_gen_ext32s_tl(t0, t0);
+gen_store_gpr(t0, a->rt);
+tcg_temp_free(t0);
+
+return true;
+}
+
+#define DECLEAR_GEN_CL(suffix, arg_type)\
+static bool gen_cl_##suffix(DisasContext *ctx, arg_type * a, bool zero) \
+{   \
+TCGv dest = dest_gpr(ctx, a->rd);   \
+TCGv src = get_gpr(ctx, a->rs, EXT_NONE);   \
+if (!zero) {\
+tcg_gen_not_tl(dest, src);  \
+}   \
+tcg_gen_ext32u_tl(dest, dest);  \
+tcg_gen_clzi_tl(dest, dest, TARGET_LONG_BITS);  \
+tcg_gen_subi_tl(dest, dest, TARGET_LONG_BITS - 32); \
+gen_set_gpr(a->rd, dest, EXT_NONE); \
+return true;\
+}   \
+
+DECLEAR_GEN_CL(legacy, arg_r)
+#undef DECLEAR

  1   2   3   4   >