summaryrefslogtreecommitdiffstats
path: root/hw
diff options
context:
space:
mode:
Diffstat (limited to 'hw')
-rw-r--r--hw/arm/boot.c5
-rw-r--r--hw/intc/loongarch_extioi.c41
-rw-r--r--hw/intc/trace-events3
-rw-r--r--hw/loongarch/acpi-build.c51
-rw-r--r--hw/loongarch/virt.c53
5 files changed, 125 insertions, 28 deletions
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
index b106f31468..15c2bf1867 100644
--- a/hw/arm/boot.c
+++ b/hw/arm/boot.c
@@ -764,10 +764,15 @@ static void do_cpu_reset(void *opaque)
}
if (cpu_isar_feature(aa64_sve, cpu)) {
env->cp15.cptr_el[3] |= R_CPTR_EL3_EZ_MASK;
+ env->vfp.zcr_el[3] = 0xf;
}
if (cpu_isar_feature(aa64_sme, cpu)) {
env->cp15.cptr_el[3] |= R_CPTR_EL3_ESM_MASK;
env->cp15.scr_el3 |= SCR_ENTP2;
+ env->vfp.smcr_el[3] = 0xf;
+ }
+ if (cpu_isar_feature(aa64_hcx, cpu)) {
+ env->cp15.scr_el3 |= SCR_HXEN;
}
/* AArch64 kernels never boot in secure mode */
assert(!info->secure_boot);
diff --git a/hw/intc/loongarch_extioi.c b/hw/intc/loongarch_extioi.c
index 22803969bc..4b8ec3f28a 100644
--- a/hw/intc/loongarch_extioi.c
+++ b/hw/intc/loongarch_extioi.c
@@ -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,\
@@ -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;
@@ -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 */
@@ -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,
diff --git a/hw/intc/trace-events b/hw/intc/trace-events
index 0a90c1cdec..6fbc2045e6 100644
--- a/hw/intc/trace-events
+++ b/hw/intc/trace-events
@@ -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
-
diff --git a/hw/loongarch/acpi-build.c b/hw/loongarch/acpi-build.c
index 378a6d9d38..68dfb9f88a 100644
--- a/hw/loongarch/acpi-build.c
+++ b/hw/loongarch/acpi-build.c
@@ -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
@@ -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)
@@ -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);
@@ -359,6 +399,15 @@ static void acpi_build(AcpiBuildTables *tables, MachineState *machine)
lams->oem_table_id);
}
+#ifdef CONFIG_TPM
+ /* 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);
+ }
+#endif
/* Add tables supplied by user (if any) */
for (u = acpi_table_first(); u; u = acpi_table_next(u)) {
unsigned len = acpi_table_len(u);
diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
index 4b595a9ea4..5e4c2790bf 100644
--- a/hw/loongarch/virt.c
+++ b/hw/loongarch/virt.c
@@ -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)
{
@@ -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)
@@ -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++) {
@@ -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,
@@ -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");
@@ -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)
@@ -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[] = {