loongarch queue

-----BEGIN PGP SIGNATURE-----
 
 iHUEABYKAB0WIQQNhkKjomWfgLCz0aQfewwSUazn0QUCaBljTgAKCRAfewwSUazn
 0cSzAPoCbqppm5lUPgFAacD4m1sUI6jLk5pJGMsQTQHkMZ34yQD7BswZhMWPL44Z
 LmrZgO7NfqAv96AF1mpRawV9ZXSOGAQ=
 =3itp
 -----END PGP SIGNATURE-----

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

loongarch queue

# -----BEGIN PGP SIGNATURE-----
#
# iHUEABYKAB0WIQQNhkKjomWfgLCz0aQfewwSUazn0QUCaBljTgAKCRAfewwSUazn
# 0cSzAPoCbqppm5lUPgFAacD4m1sUI6jLk5pJGMsQTQHkMZ34yQD7BswZhMWPL44Z
# LmrZgO7NfqAv96AF1mpRawV9ZXSOGAQ=
# =3itp
# -----END PGP SIGNATURE-----
# gpg: Signature made Mon 05 May 2025 21:18:06 EDT
# 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-20250506' of https://github.com/bibo-mao/qemu:
  hw/loongarch/virt: Allow user to customize OEM ID and OEM table ID
  hw/loongarch/virt: Replace RSDT with XSDT table
  hw/loongarch/virt: Get physical entry address with elf file
  hw/intc/loongarch_pch: Replace legacy reset callback with new api
  hw/intc/loongarch_pch: Add reset support
  hw/intc/loongarch_extioi: Replace legacy reset callback with new api
  hw/intc/loongarch_extioi: Add reset support
  hw/intc/loongarch_ipi: Add reset support

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
This commit is contained in:
Stefan Hajnoczi 2025-05-06 11:03:45 -04:00
commit c5e2c4042e
14 changed files with 181 additions and 28 deletions

View file

@ -377,11 +377,13 @@ static void loongarch_extioi_unrealize(DeviceState *dev)
g_free(s->cpu);
}
static void loongarch_extioi_reset(DeviceState *d)
static void loongarch_extioi_reset_hold(Object *obj, ResetType type)
{
LoongArchExtIOICommonState *s = LOONGARCH_EXTIOI_COMMON(d);
LoongArchExtIOIClass *lec = LOONGARCH_EXTIOI_GET_CLASS(obj);
s->status = 0;
if (lec->parent_phases.hold) {
lec->parent_phases.hold(obj, type);
}
}
static int vmstate_extioi_post_load(void *opaque, int version_id)
@ -406,12 +408,14 @@ static void loongarch_extioi_class_init(ObjectClass *klass, const void *data)
DeviceClass *dc = DEVICE_CLASS(klass);
LoongArchExtIOIClass *lec = LOONGARCH_EXTIOI_CLASS(klass);
LoongArchExtIOICommonClass *lecc = LOONGARCH_EXTIOI_COMMON_CLASS(klass);
ResettableClass *rc = RESETTABLE_CLASS(klass);
device_class_set_parent_realize(dc, loongarch_extioi_realize,
&lec->parent_realize);
device_class_set_parent_unrealize(dc, loongarch_extioi_unrealize,
&lec->parent_unrealize);
device_class_set_legacy_reset(dc, loongarch_extioi_reset);
resettable_class_set_parent_phases(rc, NULL, loongarch_extioi_reset_hold,
NULL, &lec->parent_phases);
lecc->post_load = vmstate_extioi_post_load;
}

View file

@ -108,6 +108,43 @@ static void loongarch_extioi_common_realize(DeviceState *dev, Error **errp)
}
}
static void loongarch_extioi_common_reset_hold(Object *obj, ResetType type)
{
LoongArchExtIOICommonClass *lecc = LOONGARCH_EXTIOI_COMMON_GET_CLASS(obj);
LoongArchExtIOICommonState *s = LOONGARCH_EXTIOI_COMMON(obj);
ExtIOICore *core;
int i;
if (lecc->parent_phases.hold) {
lecc->parent_phases.hold(obj, type);
}
/* Clear HW registers for the board */
memset(s->nodetype, 0, sizeof(s->nodetype));
memset(s->bounce, 0, sizeof(s->bounce));
memset(s->isr, 0, sizeof(s->isr));
memset(s->enable, 0, sizeof(s->enable));
memset(s->ipmap, 0, sizeof(s->ipmap));
memset(s->coremap, 0, sizeof(s->coremap));
memset(s->sw_pending, 0, sizeof(s->sw_pending));
memset(s->sw_ipmap, 0, sizeof(s->sw_ipmap));
memset(s->sw_coremap, 0, sizeof(s->sw_coremap));
for (i = 0; i < s->num_cpu; i++) {
core = s->cpu + i;
/* EXTIOI with targeted CPU available however not present */
if (!core->cpu) {
continue;
}
/* Clear HW registers for CPUs */
memset(core->coreisr, 0, sizeof(core->coreisr));
memset(core->sw_isr, 0, sizeof(core->sw_isr));
}
s->status = 0;
}
static int loongarch_extioi_common_pre_save(void *opaque)
{
LoongArchExtIOICommonState *s = (LoongArchExtIOICommonState *)opaque;
@ -180,9 +217,13 @@ static void loongarch_extioi_common_class_init(ObjectClass *klass,
DeviceClass *dc = DEVICE_CLASS(klass);
LoongArchExtIOICommonClass *lecc = LOONGARCH_EXTIOI_COMMON_CLASS(klass);
HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(klass);
ResettableClass *rc = RESETTABLE_CLASS(klass);
device_class_set_parent_realize(dc, loongarch_extioi_common_realize,
&lecc->parent_realize);
resettable_class_set_parent_phases(rc, NULL,
loongarch_extioi_common_reset_hold,
NULL, &lecc->parent_phases);
device_class_set_props(dc, extioi_properties);
dc->vmsd = &vmstate_loongarch_extioi;
hc->plug = loongarch_extioi_cpu_plug;

View file

@ -93,6 +93,32 @@ static void loongarch_ipi_realize(DeviceState *dev, Error **errp)
}
}
static void loongarch_ipi_reset_hold(Object *obj, ResetType type)
{
int i;
LoongarchIPIClass *lic = LOONGARCH_IPI_GET_CLASS(obj);
LoongsonIPICommonState *lics = LOONGSON_IPI_COMMON(obj);
IPICore *core;
if (lic->parent_phases.hold) {
lic->parent_phases.hold(obj, type);
}
for (i = 0; i < lics->num_cpu; i++) {
core = lics->cpu + i;
/* IPI with targeted CPU available however not present */
if (!core->cpu) {
continue;
}
core->status = 0;
core->en = 0;
core->set = 0;
core->clear = 0;
memset(core->buf, 0, sizeof(core->buf));
}
}
static void loongarch_ipi_cpu_plug(HotplugHandler *hotplug_dev,
DeviceState *dev, Error **errp)
{
@ -145,10 +171,13 @@ static void loongarch_ipi_class_init(ObjectClass *klass, const void *data)
LoongsonIPICommonClass *licc = LOONGSON_IPI_COMMON_CLASS(klass);
HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(klass);
LoongarchIPIClass *lic = LOONGARCH_IPI_CLASS(klass);
ResettableClass *rc = RESETTABLE_CLASS(klass);
DeviceClass *dc = DEVICE_CLASS(klass);
device_class_set_parent_realize(dc, loongarch_ipi_realize,
&lic->parent_realize);
resettable_class_set_parent_phases(rc, NULL, loongarch_ipi_reset_hold,
NULL, &lic->parent_phases);
licc->get_iocsr_as = get_iocsr_as;
licc->cpu_by_arch_id = loongarch_cpu_by_arch_id;
hc->plug = loongarch_ipi_cpu_plug;

View file

@ -354,25 +354,13 @@ static const MemoryRegionOps loongarch_pch_pic_reg8_ops = {
.endianness = DEVICE_LITTLE_ENDIAN,
};
static void loongarch_pch_pic_reset(DeviceState *d)
static void loongarch_pic_reset_hold(Object *obj, ResetType type)
{
LoongArchPICCommonState *s = LOONGARCH_PIC_COMMON(d);
int i;
LoongarchPICClass *lpc = LOONGARCH_PIC_GET_CLASS(obj);
s->int_mask = -1;
s->htmsi_en = 0x0;
s->intedge = 0x0;
s->intclr = 0x0;
s->auto_crtl0 = 0x0;
s->auto_crtl1 = 0x0;
for (i = 0; i < 64; i++) {
s->route_entry[i] = 0x1;
s->htmsi_vector[i] = 0x0;
if (lpc->parent_phases.hold) {
lpc->parent_phases.hold(obj, type);
}
s->intirr = 0x0;
s->intisr = 0x0;
s->last_intirr = 0x0;
s->int_polarity = 0x0;
}
static void loongarch_pic_realize(DeviceState *dev, Error **errp)
@ -408,8 +396,10 @@ static void loongarch_pic_class_init(ObjectClass *klass, const void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
LoongarchPICClass *lpc = LOONGARCH_PIC_CLASS(klass);
ResettableClass *rc = RESETTABLE_CLASS(klass);
device_class_set_legacy_reset(dc, loongarch_pch_pic_reset);
resettable_class_set_parent_phases(rc, NULL, loongarch_pic_reset_hold,
NULL, &lpc->parent_phases);
device_class_set_parent_realize(dc, loongarch_pic_realize,
&lpc->parent_realize);
}

View file

@ -44,6 +44,27 @@ static void loongarch_pic_common_realize(DeviceState *dev, Error **errp)
}
}
static void loongarch_pic_common_reset_hold(Object *obj, ResetType type)
{
LoongArchPICCommonState *s = LOONGARCH_PIC_COMMON(obj);
int i;
s->int_mask = UINT64_MAX;
s->htmsi_en = 0x0;
s->intedge = 0x0;
s->intclr = 0x0;
s->auto_crtl0 = 0x0;
s->auto_crtl1 = 0x0;
for (i = 0; i < 64; i++) {
s->route_entry[i] = 0x1;
s->htmsi_vector[i] = 0x0;
}
s->intirr = 0x0;
s->intisr = 0x0;
s->last_intirr = 0x0;
s->int_polarity = 0x0;
}
static const Property loongarch_pic_common_properties[] = {
DEFINE_PROP_UINT32("pch_pic_irq_num", LoongArchPICCommonState, irq_num, 0),
};
@ -76,9 +97,13 @@ static void loongarch_pic_common_class_init(ObjectClass *klass,
{
DeviceClass *dc = DEVICE_CLASS(klass);
LoongArchPICCommonClass *lpcc = LOONGARCH_PIC_COMMON_CLASS(klass);
ResettableClass *rc = RESETTABLE_CLASS(klass);
device_class_set_parent_realize(dc, loongarch_pic_common_realize,
&lpcc->parent_realize);
resettable_class_set_parent_phases(rc, NULL,
loongarch_pic_common_reset_hold,
NULL, &lpcc->parent_phases);
device_class_set_props(dc, loongarch_pic_common_properties);
dc->vmsd = &vmstate_loongarch_pic_common;
}

View file

@ -245,6 +245,7 @@ static int64_t load_kernel_info(struct loongarch_boot_info *info)
&kernel_entry, &kernel_low,
&kernel_high, NULL, ELFDATA2LSB,
EM_LOONGARCH, 1, 0);
kernel_entry = cpu_loongarch_virt_to_phys(NULL, kernel_entry);
if (kernel_size < 0) {
kernel_size = load_loongarch_linux_image(info->kernel_filename,
&kernel_entry, &kernel_low,

View file

@ -514,7 +514,7 @@ static void acpi_build(AcpiBuildTables *tables, MachineState *machine)
LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(machine);
GArray *table_offsets;
AcpiFadtData fadt_data;
unsigned facs, rsdt, dsdt;
unsigned facs, xsdt, dsdt;
uint8_t *u;
GArray *tables_blob = tables->table_data;
@ -600,17 +600,17 @@ static void acpi_build(AcpiBuildTables *tables, MachineState *machine)
}
/* RSDT is pointed to by RSDP */
rsdt = tables_blob->len;
build_rsdt(tables_blob, tables->linker, table_offsets,
xsdt = tables_blob->len;
build_xsdt(tables_blob, tables->linker, table_offsets,
lvms->oem_id, lvms->oem_table_id);
/* RSDP is in FSEG memory, so allocate it separately */
{
AcpiRsdpData rsdp_data = {
.revision = 0,
.revision = 2,
.oem_id = lvms->oem_id,
.xsdt_tbl_offset = NULL,
.rsdt_tbl_offset = &rsdt,
.xsdt_tbl_offset = &xsdt,
.rsdt_tbl_offset = NULL,
};
build_rsdp(tables->rsdp, tables->linker, &rsdp_data);
}

View file

@ -773,6 +773,48 @@ static void virt_set_acpi(Object *obj, Visitor *v, const char *name,
visit_type_OnOffAuto(v, name, &lvms->acpi, errp);
}
static char *virt_get_oem_id(Object *obj, Error **errp)
{
LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(obj);
return g_strdup(lvms->oem_id);
}
static void virt_set_oem_id(Object *obj, const char *value, Error **errp)
{
LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(obj);
size_t len = strlen(value);
if (len > 6) {
error_setg(errp,
"User specified oem-id value is bigger than 6 bytes in size");
return;
}
strncpy(lvms->oem_id, value, 6);
}
static char *virt_get_oem_table_id(Object *obj, Error **errp)
{
LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(obj);
return g_strdup(lvms->oem_table_id);
}
static void virt_set_oem_table_id(Object *obj, const char *value,
Error **errp)
{
LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(obj);
size_t len = strlen(value);
if (len > 8) {
error_setg(errp,
"User specified oem-table-id value is bigger than 8 bytes in size");
return;
}
strncpy(lvms->oem_table_id, value, 8);
}
static void virt_initfn(Object *obj)
{
LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(obj);
@ -1177,6 +1219,22 @@ static void virt_class_init(ObjectClass *oc, const void *data)
#ifdef CONFIG_TPM
machine_class_allow_dynamic_sysbus_dev(mc, TYPE_TPM_TIS_SYSBUS);
#endif
object_class_property_add_str(oc, "x-oem-id",
virt_get_oem_id,
virt_set_oem_id);
object_class_property_set_description(oc, "x-oem-id",
"Override the default value of field OEMID "
"in ACPI table header."
"The string may be up to 6 bytes in size");
object_class_property_add_str(oc, "x-oem-table-id",
virt_get_oem_table_id,
virt_set_oem_table_id);
object_class_property_set_description(oc, "x-oem-table-id",
"Override the default value of field OEM Table ID "
"in ACPI table header."
"The string may be up to 8 bytes in size");
}
static const TypeInfo virt_machine_types[] = {

View file

@ -22,6 +22,7 @@ struct LoongArchExtIOIClass {
DeviceRealize parent_realize;
DeviceUnrealize parent_unrealize;
ResettablePhases parent_phases;
};
#endif /* LOONGARCH_EXTIOI_H */

View file

@ -94,6 +94,7 @@ struct LoongArchExtIOICommonClass {
SysBusDeviceClass parent_class;
DeviceRealize parent_realize;
ResettablePhases parent_phases;
int (*pre_save)(void *s);
int (*post_load)(void *s, int version_id);
};

View file

@ -21,6 +21,7 @@ struct LoongarchIPIState {
struct LoongarchIPIClass {
LoongsonIPICommonClass parent_class;
DeviceRealize parent_realize;
ResettablePhases parent_phases;
};
#endif

View file

@ -22,6 +22,7 @@ struct LoongarchPICClass {
LoongArchPICCommonClass parent_class;
DeviceRealize parent_realize;
ResettablePhases parent_phases;
};
#endif /* HW_LOONGARCH_PCH_PIC_H */

View file

@ -76,6 +76,7 @@ struct LoongArchPICCommonClass {
SysBusDeviceClass parent_class;
DeviceRealize parent_realize;
ResettablePhases parent_phases;
int (*pre_save)(LoongArchPICCommonState *s);
int (*post_load)(LoongArchPICCommonState *s, int version_id);
};

View file

@ -3,7 +3,7 @@ ENTRY(_start)
SECTIONS
{
/* Linux kernel legacy start address. */
. = 0x9000000000200000;
. = 0x200000;
_text = .;
.text : {
*(.text)