Skip to content

Commit

Permalink
Merge tag 'pull-loongarch-20221103' of https://gitlab.com/gaosong/qemu
Browse files Browse the repository at this point in the history
…into staging

pull-loongarch-20221103

# -----BEGIN PGP SIGNATURE-----
#
# iLMEAAEIAB0WIQS4/x2g0v3LLaCcbCxAov/yOSY+3wUCY2OiRwAKCRBAov/yOSY+
# 3/NuA/9wCor5Z4wqkRsQXXC3Od3catqpowCW/0v4ZgEtYVv1gHduxXkN/z3UTv4B
# cKJh/ZeyN7dCAogsLQR9dllGsM3gOzJmR7aDks6120K5A3RVFhspCrifgpXlevfS
# B4/i07UwDmxYc2ToCb2Gpw6YHZFT/9+gK3e+N691LOm7PpqxBQ==
# =EhwX
# -----END PGP SIGNATURE-----
# gpg: Signature made Thu 03 Nov 2022 07:13:11 EDT
# gpg:                using RSA key B8FF1DA0D2FDCB2DA09C6C2C40A2FFF239263EDF
# gpg: Good signature from "Song Gao <m17746591750@163.com>" [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: B8FF 1DA0 D2FD CB2D A09C  6C2C 40A2 FFF2 3926 3EDF

* tag 'pull-loongarch-20221103' of https://gitlab.com/gaosong/qemu:
  target/loongarch: Fix raise_mmu_exception() set wrong exception_index
  target/loongarch: Add exception subcode
  hw/loongarch: Add TPM device for LoongArch virt machine
  hw/loongarch: Improve fdt for LoongArch virt machine
  hw/loongarch: Load FDT table into dram memory space
  hw/intc: Fix LoongArch extioi coreisr accessing
  hw/intc: Convert the memops to with_attrs in LoongArch extioi

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
  • Loading branch information
stefanhaRH committed Nov 3, 2022
2 parents ece5f83 + d31e2b1 commit 6418794
Show file tree
Hide file tree
Showing 10 changed files with 170 additions and 71 deletions.
41 changes: 23 additions & 18 deletions hw/intc/loongarch_extioi.c
Expand Up @@ -68,44 +68,46 @@ static void extioi_setirq(void *opaque, int irq, int level)
extioi_update_irq(s, irq, level);
}

static uint64_t extioi_readw(void *opaque, hwaddr addr, unsigned size)
static MemTxResult extioi_readw(void *opaque, hwaddr addr, uint64_t *data,
unsigned size, MemTxAttrs attrs)
{
LoongArchExtIOI *s = LOONGARCH_EXTIOI(opaque);
unsigned long offset = addr & 0xffff;
uint32_t index, cpu, ret = 0;
uint32_t index, cpu;

switch (offset) {
case EXTIOI_NODETYPE_START ... EXTIOI_NODETYPE_END - 1:
index = (offset - EXTIOI_NODETYPE_START) >> 2;
ret = s->nodetype[index];
*data = s->nodetype[index];
break;
case EXTIOI_IPMAP_START ... EXTIOI_IPMAP_END - 1:
index = (offset - EXTIOI_IPMAP_START) >> 2;
ret = s->ipmap[index];
*data = s->ipmap[index];
break;
case EXTIOI_ENABLE_START ... EXTIOI_ENABLE_END - 1:
index = (offset - EXTIOI_ENABLE_START) >> 2;
ret = s->enable[index];
*data = s->enable[index];
break;
case EXTIOI_BOUNCE_START ... EXTIOI_BOUNCE_END - 1:
index = (offset - EXTIOI_BOUNCE_START) >> 2;
ret = s->bounce[index];
*data = s->bounce[index];
break;
case EXTIOI_COREISR_START ... EXTIOI_COREISR_END - 1:
index = ((offset - EXTIOI_COREISR_START) & 0x1f) >> 2;
cpu = ((offset - EXTIOI_COREISR_START) >> 8) & 0x3;
ret = s->coreisr[cpu][index];
index = (offset - EXTIOI_COREISR_START) >> 2;
/* using attrs to get current cpu index */
cpu = attrs.requester_id;
*data = s->coreisr[cpu][index];
break;
case EXTIOI_COREMAP_START ... EXTIOI_COREMAP_END - 1:
index = (offset - EXTIOI_COREMAP_START) >> 2;
ret = s->coremap[index];
*data = s->coremap[index];
break;
default:
break;
}

trace_loongarch_extioi_readw(addr, ret);
return ret;
trace_loongarch_extioi_readw(addr, *data);
return MEMTX_OK;
}

static inline void extioi_enable_irq(LoongArchExtIOI *s, int index,\
Expand All @@ -127,8 +129,9 @@ static inline void extioi_enable_irq(LoongArchExtIOI *s, int index,\
}
}

static void extioi_writew(void *opaque, hwaddr addr,
uint64_t val, unsigned size)
static MemTxResult extioi_writew(void *opaque, hwaddr addr,
uint64_t val, unsigned size,
MemTxAttrs attrs)
{
LoongArchExtIOI *s = LOONGARCH_EXTIOI(opaque);
int i, cpu, index, old_data, irq;
Expand Down Expand Up @@ -183,8 +186,9 @@ static void extioi_writew(void *opaque, hwaddr addr,
s->bounce[index] = val;
break;
case EXTIOI_COREISR_START ... EXTIOI_COREISR_END - 1:
index = ((offset - EXTIOI_COREISR_START) & 0x1f) >> 2;
cpu = ((offset - EXTIOI_COREISR_START) >> 8) & 0x3;
index = (offset - EXTIOI_COREISR_START) >> 2;
/* using attrs to get current cpu index */
cpu = attrs.requester_id;
old_data = s->coreisr[cpu][index];
s->coreisr[cpu][index] = old_data & ~val;
/* write 1 to clear interrrupt */
Expand Down Expand Up @@ -231,11 +235,12 @@ static void extioi_writew(void *opaque, hwaddr addr,
default:
break;
}
return MEMTX_OK;
}

static const MemoryRegionOps extioi_ops = {
.read = extioi_readw,
.write = extioi_writew,
.read_with_attrs = extioi_readw,
.write_with_attrs = extioi_writew,
.impl.min_access_size = 4,
.impl.max_access_size = 4,
.valid.min_access_size = 4,
Expand Down
3 changes: 1 addition & 2 deletions hw/intc/trace-events
Expand Up @@ -306,6 +306,5 @@ loongarch_msi_set_irq(int irq_num) "set msi irq %d"

# loongarch_extioi.c
loongarch_extioi_setirq(int irq, int level) "set extirq irq %d level %d"
loongarch_extioi_readw(uint64_t addr, uint32_t val) "addr: 0x%"PRIx64 "val: 0x%x"
loongarch_extioi_readw(uint64_t addr, uint64_t val) "addr: 0x%"PRIx64 "val: 0x%" PRIx64
loongarch_extioi_writew(uint64_t addr, uint64_t val) "addr: 0x%"PRIx64 "val: 0x%" PRIx64

50 changes: 48 additions & 2 deletions hw/loongarch/acpi-build.c
Expand Up @@ -31,6 +31,9 @@

#include "hw/acpi/generic_event_device.h"
#include "hw/pci-host/gpex.h"
#include "sysemu/tpm.h"
#include "hw/platform-bus.h"
#include "hw/acpi/aml-build.h"

#define ACPI_BUILD_ALIGN_SIZE 0x1000
#define ACPI_BUILD_TABLE_SIZE 0x20000
Expand Down Expand Up @@ -275,6 +278,41 @@ static void build_pci_device_aml(Aml *scope, LoongArchMachineState *lams)
acpi_dsdt_add_gpex(scope, &cfg);
}

#ifdef CONFIG_TPM
static void acpi_dsdt_add_tpm(Aml *scope, LoongArchMachineState *vms)
{
PlatformBusDevice *pbus = PLATFORM_BUS_DEVICE(vms->platform_bus_dev);
hwaddr pbus_base = VIRT_PLATFORM_BUS_BASEADDRESS;
SysBusDevice *sbdev = SYS_BUS_DEVICE(tpm_find());
MemoryRegion *sbdev_mr;
hwaddr tpm_base;

if (!sbdev) {
return;
}

tpm_base = platform_bus_get_mmio_addr(pbus, sbdev, 0);
assert(tpm_base != -1);

tpm_base += pbus_base;

sbdev_mr = sysbus_mmio_get_region(sbdev, 0);

Aml *dev = aml_device("TPM0");
aml_append(dev, aml_name_decl("_HID", aml_string("MSFT0101")));
aml_append(dev, aml_name_decl("_STR", aml_string("TPM 2.0 Device")));
aml_append(dev, aml_name_decl("_UID", aml_int(0)));

Aml *crs = aml_resource_template();
aml_append(crs,
aml_memory32_fixed(tpm_base,
(uint32_t)memory_region_size(sbdev_mr),
AML_READ_WRITE));
aml_append(dev, aml_name_decl("_CRS", crs));
aml_append(scope, dev);
}
#endif

/* build DSDT */
static void
build_dsdt(GArray *table_data, BIOSLinker *linker, MachineState *machine)
Expand All @@ -289,7 +327,9 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, MachineState *machine)
build_uart_device_aml(dsdt);
build_pci_device_aml(dsdt, lams);
build_la_ged_aml(dsdt, machine);

#ifdef CONFIG_TPM
acpi_dsdt_add_tpm(dsdt, lams);
#endif
/* System State Package */
scope = aml_scope("\\");
pkg = aml_package(4);
Expand Down Expand Up @@ -358,7 +398,13 @@ static void acpi_build(AcpiBuildTables *tables, MachineState *machine)
build_mcfg(tables_blob, tables->linker, &mcfg, lams->oem_id,
lams->oem_table_id);
}

/* TPM info */
if (tpm_get_version(tpm_find()) == TPM_VERSION_2_0) {
acpi_add_table(table_offsets, tables_blob);
build_tpm2(tables_blob, tables->linker,
tables->tcpalog, lams->oem_id,
lams->oem_table_id);
}
/* Add tables supplied by user (if any) */
for (u = acpi_table_first(); u; u = acpi_table_next(u)) {
unsigned len = acpi_table_len(u);
Expand Down
53 changes: 46 additions & 7 deletions hw/loongarch/virt.c
Expand Up @@ -41,6 +41,36 @@
#include "hw/platform-bus.h"
#include "hw/display/ramfb.h"
#include "hw/mem/pc-dimm.h"
#include "sysemu/tpm.h"

static void fdt_add_rtc_node(LoongArchMachineState *lams)
{
char *nodename;
hwaddr base = VIRT_RTC_REG_BASE;
hwaddr size = VIRT_RTC_LEN;
MachineState *ms = MACHINE(lams);

nodename = g_strdup_printf("/rtc@%" PRIx64, base);
qemu_fdt_add_subnode(ms->fdt, nodename);
qemu_fdt_setprop_string(ms->fdt, nodename, "compatible", "loongson,ls7a-rtc");
qemu_fdt_setprop_sized_cells(ms->fdt, nodename, "reg", 0x0, base, size);
g_free(nodename);
}

static void fdt_add_uart_node(LoongArchMachineState *lams)
{
char *nodename;
hwaddr base = VIRT_UART_BASE;
hwaddr size = VIRT_UART_SIZE;
MachineState *ms = MACHINE(lams);

nodename = g_strdup_printf("/serial@%" PRIx64, base);
qemu_fdt_add_subnode(ms->fdt, nodename);
qemu_fdt_setprop_string(ms->fdt, nodename, "compatible", "ns16550a");
qemu_fdt_setprop_cells(ms->fdt, nodename, "reg", 0x0, base, 0x0, size);
qemu_fdt_setprop_cell(ms->fdt, nodename, "clock-frequency", 100000000);
g_free(nodename);
}

static void create_fdt(LoongArchMachineState *lams)
{
Expand Down Expand Up @@ -159,7 +189,6 @@ static void fdt_add_pcie_node(const LoongArchMachineState *lams)
1, FDT_PCI_RANGE_MMIO, 2, base_mmio,
2, base_mmio, 2, size_mmio);
g_free(nodename);
qemu_fdt_dumpdtb(ms->fdt, lams->fdt_size);
}

static void fdt_add_irqchip_node(LoongArchMachineState *lams)
Expand Down Expand Up @@ -423,6 +452,7 @@ static void loongarch_devices_init(DeviceState *pch_pic, LoongArchMachineState *
qdev_get_gpio_in(pch_pic,
VIRT_UART_IRQ - PCH_PIC_IRQ_OFFSET),
115200, serial_hd(0), DEVICE_LITTLE_ENDIAN);
fdt_add_uart_node(lams);

/* Network init */
for (i = 0; i < nb_nics; i++) {
Expand All @@ -443,6 +473,7 @@ static void loongarch_devices_init(DeviceState *pch_pic, LoongArchMachineState *
sysbus_create_simple("ls7a_rtc", VIRT_RTC_REG_BASE,
qdev_get_gpio_in(pch_pic,
VIRT_RTC_IRQ - PCH_PIC_IRQ_OFFSET));
fdt_add_rtc_node(lams);

pm_mem = g_new(MemoryRegion, 1);
memory_region_init_io(pm_mem, NULL, &loongarch_virt_pm_ops,
Expand Down Expand Up @@ -656,6 +687,7 @@ static void loongarch_init(MachineState *machine)
MemoryRegion *address_space_mem = get_system_memory();
LoongArchMachineState *lams = LOONGARCH_MACHINE(machine);
int i;
hwaddr fdt_base;

if (!cpu_model) {
cpu_model = LOONGARCH_CPU_TYPE_NAME("la464");
Expand Down Expand Up @@ -760,12 +792,16 @@ static void loongarch_init(MachineState *machine)
lams->machine_done.notify = virt_machine_done;
qemu_add_machine_init_done_notifier(&lams->machine_done);
fdt_add_pcie_node(lams);

/* load fdt */
MemoryRegion *fdt_rom = g_new(MemoryRegion, 1);
memory_region_init_rom(fdt_rom, NULL, "fdt", VIRT_FDT_SIZE, &error_fatal);
memory_region_add_subregion(get_system_memory(), VIRT_FDT_BASE, fdt_rom);
rom_add_blob_fixed("fdt", machine->fdt, lams->fdt_size, VIRT_FDT_BASE);
/*
* Since lowmem region starts from 0, FDT base address is located
* at 2 MiB to avoid NULL pointer access.
*
* Put the FDT into the memory map as a ROM image: this will ensure
* the FDT is copied again upon reset, even if addr points into RAM.
*/
fdt_base = 2 * MiB;
qemu_fdt_dumpdtb(machine->fdt, lams->fdt_size);
rom_add_blob_fixed("fdt", machine->fdt, lams->fdt_size, fdt_base);
}

bool loongarch_is_acpi_enabled(LoongArchMachineState *lams)
Expand Down Expand Up @@ -925,6 +961,9 @@ static void loongarch_class_init(ObjectClass *oc, void *data)
object_class_property_set_description(oc, "acpi",
"Enable ACPI");
machine_class_allow_dynamic_sysbus_dev(mc, TYPE_RAMFB_DEVICE);
#ifdef CONFIG_TPM
machine_class_allow_dynamic_sysbus_dev(mc, TYPE_TPM_TIS_SYSBUS);
#endif
}

static const TypeInfo loongarch_machine_types[] = {
Expand Down
3 changes: 0 additions & 3 deletions include/hw/loongarch/virt.h
Expand Up @@ -28,9 +28,6 @@
#define VIRT_GED_MEM_ADDR (VIRT_GED_EVT_ADDR + ACPI_GED_EVT_SEL_LEN)
#define VIRT_GED_REG_ADDR (VIRT_GED_MEM_ADDR + MEMORY_HOTPLUG_IO_LEN)

#define VIRT_FDT_BASE 0x1c400000
#define VIRT_FDT_SIZE 0x100000

struct LoongArchMachineState {
/*< private >*/
MachineState parent_obj;
Expand Down
1 change: 1 addition & 0 deletions include/hw/pci-host/ls7a.h
Expand Up @@ -37,6 +37,7 @@
#define VIRT_PCI_IRQS 48
#define VIRT_UART_IRQ (PCH_PIC_IRQ_OFFSET + 2)
#define VIRT_UART_BASE 0x1fe001e0
#define VIRT_UART_SIZE 0X100
#define VIRT_RTC_IRQ (PCH_PIC_IRQ_OFFSET + 3)
#define VIRT_MISC_REG_BASE (VIRT_PCH_REG_BASE + 0x00080000)
#define VIRT_RTC_REG_BASE (VIRT_MISC_REG_BASE + 0x00050100)
Expand Down
8 changes: 6 additions & 2 deletions target/loongarch/cpu.c
Expand Up @@ -177,6 +177,7 @@ static void loongarch_cpu_do_interrupt(CPUState *cs)
}
QEMU_FALLTHROUGH;
case EXCCODE_PIF:
case EXCCODE_ADEF:
cause = cs->exception_index;
update_badinstr = 0;
break;
Expand Down Expand Up @@ -220,7 +221,10 @@ static void loongarch_cpu_do_interrupt(CPUState *cs)
env->CSR_TLBRERA = FIELD_DP64(env->CSR_TLBRERA, CSR_TLBRERA,
PC, (env->pc >> 2));
} else {
env->CSR_ESTAT = FIELD_DP64(env->CSR_ESTAT, CSR_ESTAT, ECODE, cause);
env->CSR_ESTAT = FIELD_DP64(env->CSR_ESTAT, CSR_ESTAT, ECODE,
EXCODE_MCODE(cause));
env->CSR_ESTAT = FIELD_DP64(env->CSR_ESTAT, CSR_ESTAT, ESUBCODE,
EXCODE_SUBCODE(cause));
env->CSR_PRMD = FIELD_DP64(env->CSR_PRMD, CSR_PRMD, PPLV,
FIELD_EX64(env->CSR_CRMD, CSR_CRMD, PLV));
env->CSR_PRMD = FIELD_DP64(env->CSR_PRMD, CSR_PRMD, PIE,
Expand Down Expand Up @@ -257,7 +261,7 @@ static void loongarch_cpu_do_interrupt(CPUState *cs)
env->pc = env->CSR_TLBRENTRY;
} else {
env->pc = env->CSR_EENTRY;
env->pc += cause * vec_size;
env->pc += EXCODE_MCODE(cause) * vec_size;
}
qemu_log_mask(CPU_LOG_INT,
"%s: PC " TARGET_FMT_lx " ERA " TARGET_FMT_lx
Expand Down
58 changes: 31 additions & 27 deletions target/loongarch/cpu.h
Expand Up @@ -75,33 +75,37 @@ FIELD(FCSR0, CAUSE, 24, 5)
#define FP_DIV0 8
#define FP_INVALID 16

#define EXCCODE_EXTERNAL_INT 64 /* plus external interrupt number */
#define EXCCODE_INT 0
#define EXCCODE_PIL 1
#define EXCCODE_PIS 2
#define EXCCODE_PIF 3
#define EXCCODE_PME 4
#define EXCCODE_PNR 5
#define EXCCODE_PNX 6
#define EXCCODE_PPI 7
#define EXCCODE_ADEF 8 /* Different exception subcode */
#define EXCCODE_ADEM 8
#define EXCCODE_ALE 9
#define EXCCODE_BCE 10
#define EXCCODE_SYS 11
#define EXCCODE_BRK 12
#define EXCCODE_INE 13
#define EXCCODE_IPE 14
#define EXCCODE_FPD 15
#define EXCCODE_SXD 16
#define EXCCODE_ASXD 17
#define EXCCODE_FPE 18 /* Different exception subcode */
#define EXCCODE_VFPE 18
#define EXCCODE_WPEF 19 /* Different exception subcode */
#define EXCCODE_WPEM 19
#define EXCCODE_BTD 20
#define EXCCODE_BTE 21
#define EXCCODE_DBP 26 /* Reserved subcode used for debug */
#define EXCODE(code, subcode) ( ((subcode) << 6) | (code) )
#define EXCODE_MCODE(code) ( (code) & 0x3f )
#define EXCODE_SUBCODE(code) ( (code) >> 6 )

#define EXCCODE_EXTERNAL_INT 64 /* plus external interrupt number */
#define EXCCODE_INT EXCODE(0, 0)
#define EXCCODE_PIL EXCODE(1, 0)
#define EXCCODE_PIS EXCODE(2, 0)
#define EXCCODE_PIF EXCODE(3, 0)
#define EXCCODE_PME EXCODE(4, 0)
#define EXCCODE_PNR EXCODE(5, 0)
#define EXCCODE_PNX EXCODE(6, 0)
#define EXCCODE_PPI EXCODE(7, 0)
#define EXCCODE_ADEF EXCODE(8, 0) /* Different exception subcode */
#define EXCCODE_ADEM EXCODE(8, 1)
#define EXCCODE_ALE EXCODE(9, 0)
#define EXCCODE_BCE EXCODE(10, 0)
#define EXCCODE_SYS EXCODE(11, 0)
#define EXCCODE_BRK EXCODE(12, 0)
#define EXCCODE_INE EXCODE(13, 0)
#define EXCCODE_IPE EXCODE(14, 0)
#define EXCCODE_FPD EXCODE(15, 0)
#define EXCCODE_SXD EXCODE(16, 0)
#define EXCCODE_ASXD EXCODE(17, 0)
#define EXCCODE_FPE EXCODE(18, 0) /* Different exception subcode */
#define EXCCODE_VFPE EXCODE(18, 1)
#define EXCCODE_WPEF EXCODE(19, 0) /* Different exception subcode */
#define EXCCODE_WPEM EXCODE(19, 1)
#define EXCCODE_BTD EXCODE(20, 0)
#define EXCCODE_BTE EXCODE(21, 0)
#define EXCCODE_DBP EXCODE(26, 0) /* Reserved subcode used for debug */

/* cpucfg[0] bits */
FIELD(CPUCFG0, PRID, 0, 32)
Expand Down

0 comments on commit 6418794

Please sign in to comment.