Browse Source

loongarch queue

-----BEGIN PGP SIGNATURE-----
 
 iHUEABYKAB0WIQQNhkKjomWfgLCz0aQfewwSUazn0QUCaWiLIAAKCRAfewwSUazn
 0cGHAQCVjRn2wPtniAIS6HQ/edTPXQt8Nr83Bv6SHkcOskbexwEA/OmUd4MiftSV
 GJFfJ66Z3i9TCRZJdLqsUZBk9p9W9AQ=
 =Aiem
 -----END PGP SIGNATURE-----

Merge tag 'pull-loongarch-20260115' of https://github.com/bibo-mao/qemu into staging

loongarch queue

# -----BEGIN PGP SIGNATURE-----
#
# iHUEABYKAB0WIQQNhkKjomWfgLCz0aQfewwSUazn0QUCaWiLIAAKCRAfewwSUazn
# 0cGHAQCVjRn2wPtniAIS6HQ/edTPXQt8Nr83Bv6SHkcOskbexwEA/OmUd4MiftSV
# GJFfJ66Z3i9TCRZJdLqsUZBk9p9W9AQ=
# =Aiem
# -----END PGP SIGNATURE-----
# gpg: Signature made Thu 15 Jan 2026 05:37:20 PM AEDT
# gpg:                using EDDSA key 0D8642A3A2659F80B0B3D1A41F7B0C1251ACE7D1
# gpg: Good signature from "bibo mao <maobibo@loongson.cn>" [unknown]
# gpg: WARNING: This key is not certified with a trusted signature!
# gpg:          There is no indication that the signature belongs to the owner.
# Primary key fingerprint: 7044 3A00 19C0 E97A 31C7  13C4 8E86 8FB7 A176 9D4C
#      Subkey fingerprint: 0D86 42A3 A265 9F80 B0B3  D1A4 1F7B 0C12 51AC E7D1

* tag 'pull-loongarch-20260115' of https://github.com/bibo-mao/qemu:
  hw/loongarch/virt: Don't abort on access to unimplemented IOCSR
  target/loongarch: Fix exception ADEF/ADEM missing to update CSR_BADV
  target/loongarch: Fix exception BCE missing to update CSR_BADV
  target/loongach: Fix some exceptions failure in updating CSR_BADV
  hw/loongarch/virt: Fix irq allocation failure with pci device from fdt
  hw/loongarch/virt: Modify the interrupt trigger type in fdt table

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
pull/316/head
Richard Henderson 2 months ago
parent
commit
beaeffb57c
  1. 55
      hw/loongarch/virt-fdt-build.c
  2. 14
      hw/loongarch/virt.c
  3. 7
      target/loongarch/tcg/tcg_cpu.c

55
hw/loongarch/virt-fdt-build.c

@ -16,6 +16,11 @@
#include "system/reset.h"
#include "target/loongarch/cpu.h"
#define FDT_IRQ_TYPE_EDGE_RISING 1
#define FDT_IRQ_TYPE_EDGE_FALLING 2
#define FDT_IRQ_TYPE_LEVEL_HIGH 4
#define FDT_IRQ_TYPE_LEVEL_LOW 8
static void create_fdt(LoongArchVirtMachineState *lvms)
{
MachineState *ms = MACHINE(lvms);
@ -316,6 +321,8 @@ static void fdt_add_pcie_irq_map_node(const LoongArchVirtMachineState *lvms,
uint32_t full_irq_map[PCI_NUM_PINS * PCI_NUM_PINS * 10] = {};
uint32_t *irq_map = full_irq_map;
const MachineState *ms = MACHINE(lvms);
uint32_t pin_mask;
uint32_t devfn_mask;
/*
* This code creates a standard swizzle of interrupts such that
@ -328,37 +335,45 @@ static void fdt_add_pcie_irq_map_node(const LoongArchVirtMachineState *lvms,
*/
for (dev = 0; dev < PCI_NUM_PINS; dev++) {
int devfn = dev * 0x8;
int devfn = PCI_DEVFN(dev, 0);
for (pin = 0; pin < PCI_NUM_PINS; pin++) {
int irq_nr = 16 + ((pin + PCI_SLOT(devfn)) % PCI_NUM_PINS);
int irq_nr = VIRT_DEVICE_IRQS + \
((pin + PCI_SLOT(devfn)) % PCI_NUM_PINS);
int i = 0;
/* Fill PCI address cells */
irq_map[i] = cpu_to_be32(devfn << 8);
i += 3;
/* Fill PCI Interrupt cells */
irq_map[i] = cpu_to_be32(pin + 1);
i += 1;
/* Fill interrupt controller phandle and cells */
irq_map[i++] = cpu_to_be32(*pch_pic_phandle);
irq_map[i++] = cpu_to_be32(irq_nr);
uint32_t map[] = {
devfn << 8, 0, 0, /* devfn */
pin + 1, /* PCI pin */
*pch_pic_phandle, /* interrupt controller handle */
irq_nr, /* irq number */
FDT_IRQ_TYPE_LEVEL_HIGH }; /* irq trigger level */
if (!irq_map_stride) {
irq_map_stride = i;
irq_map_stride = sizeof(map) / sizeof(uint32_t);
}
/* Convert map to big endian */
for (i = 0; i < irq_map_stride; i++) {
irq_map[i] = cpu_to_be32(map[i]);
}
irq_map += irq_map_stride;
}
}
qemu_fdt_setprop(ms->fdt, nodename, "interrupt-map", full_irq_map,
PCI_NUM_PINS * PCI_NUM_PINS *
irq_map_stride * sizeof(uint32_t));
/* Only need to match the pci slot bit */
devfn_mask = PCI_DEVFN((PCI_NUM_PINS - 1), 0) << 8;
/* The pci interrupt only needs to match the specified low bit */
pin_mask = (1 << ((PCI_NUM_PINS - 1))) - 1;
qemu_fdt_setprop_cells(ms->fdt, nodename, "interrupt-map-mask",
0x1800, 0, 0, 0x7);
devfn_mask, 0, 0, /* address cells */
pin_mask);
}
static void fdt_add_pcie_node(const LoongArchVirtMachineState *lvms,
@ -414,6 +429,8 @@ static void fdt_add_pcie_node(const LoongArchVirtMachineState *lvms,
}
qemu_fdt_setprop_cells(ms->fdt, nodename, "msi-map",
0, *pch_msi_phandle, 0, 0x10000);
qemu_fdt_setprop_cell(ms->fdt, nodename, "#interrupt-cells", 1);
fdt_add_pcie_irq_map_node(lvms, nodename, pch_pic_phandle);
g_free(nodename);
}
@ -434,7 +451,8 @@ static void fdt_add_uart_node(LoongArchVirtMachineState *lvms,
if (chosen) {
qemu_fdt_setprop_string(ms->fdt, "/chosen", "stdout-path", nodename);
}
qemu_fdt_setprop_cells(ms->fdt, nodename, "interrupts", irq, 0x4);
qemu_fdt_setprop_cells(ms->fdt, nodename, "interrupts", irq,
FDT_IRQ_TYPE_LEVEL_HIGH);
qemu_fdt_setprop_cell(ms->fdt, nodename, "interrupt-parent",
*pch_pic_phandle);
g_free(nodename);
@ -454,7 +472,8 @@ static void fdt_add_rtc_node(LoongArchVirtMachineState *lvms,
"loongson,ls7a-rtc");
qemu_fdt_setprop_sized_cells(ms->fdt, nodename, "reg", 2, base, 2, size);
qemu_fdt_setprop_cells(ms->fdt, nodename, "interrupts",
VIRT_RTC_IRQ - VIRT_GSI_BASE , 0x4);
VIRT_RTC_IRQ - VIRT_GSI_BASE ,
FDT_IRQ_TYPE_LEVEL_HIGH);
qemu_fdt_setprop_cell(ms->fdt, nodename, "interrupt-parent",
*pch_pic_phandle);
g_free(nodename);

14
hw/loongarch/virt.c

@ -47,6 +47,7 @@
#include "hw/block/flash.h"
#include "hw/virtio/virtio-iommu.h"
#include "qemu/error-report.h"
#include "qemu/log.h"
#include "kvm/kvm_loongarch.h"
static void virt_get_dmsi(Object *obj, Visitor *v, const char *name,
@ -754,8 +755,15 @@ static MemTxResult virt_iocsr_misc_write(void *opaque, hwaddr addr,
EXTIOI_VIRT_BASE + EXTIOI_VIRT_CONFIG,
features, attrs, NULL);
break;
case VERSION_REG:
case FEATURE_REG:
case VENDOR_REG:
case CPUNAME_REG:
break;
default:
g_assert_not_reached();
qemu_log_mask(LOG_UNIMP, "%s: Unimplemented IOCSR 0x%" HWADDR_PRIx "\n",
__func__, addr);
break;
}
return MEMTX_OK;
@ -813,7 +821,9 @@ static MemTxResult virt_iocsr_misc_read(void *opaque, hwaddr addr,
}
break;
default:
g_assert_not_reached();
qemu_log_mask(LOG_UNIMP, "%s: Unimplemented IOCSR 0x%" HWADDR_PRIx "\n",
__func__, addr);
break;
}
*data = ret;

7
target/loongarch/tcg/tcg_cpu.c

@ -113,6 +113,9 @@ static void loongarch_cpu_do_interrupt(CPUState *cs)
cause = cs->exception_index;
update_badinstr = 0;
break;
case EXCCODE_BCE:
env->CSR_BADV = env->pc;
QEMU_FALLTHROUGH;
case EXCCODE_SYS:
case EXCCODE_BRK:
case EXCCODE_INE:
@ -121,9 +124,6 @@ static void loongarch_cpu_do_interrupt(CPUState *cs)
case EXCCODE_FPE:
case EXCCODE_SXD:
case EXCCODE_ASXD:
env->CSR_BADV = env->pc;
QEMU_FALLTHROUGH;
case EXCCODE_BCE:
case EXCCODE_ADEM:
case EXCCODE_PIL:
case EXCCODE_PIS:
@ -227,6 +227,7 @@ static void loongarch_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr,
{
CPULoongArchState *env = cpu_env(cs);
env->CSR_BADV = addr;
if (access_type == MMU_INST_FETCH) {
do_raise_exception(env, EXCCODE_ADEF, retaddr);
} else {

Loading…
Cancel
Save