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:
commit
c5e2c4042e
14 changed files with 181 additions and 28 deletions
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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[] = {
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ struct LoongArchExtIOIClass {
|
|||
|
||||
DeviceRealize parent_realize;
|
||||
DeviceUnrealize parent_unrealize;
|
||||
ResettablePhases parent_phases;
|
||||
};
|
||||
|
||||
#endif /* LOONGARCH_EXTIOI_H */
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ struct LoongarchIPIState {
|
|||
struct LoongarchIPIClass {
|
||||
LoongsonIPICommonClass parent_class;
|
||||
DeviceRealize parent_realize;
|
||||
ResettablePhases parent_phases;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ struct LoongarchPICClass {
|
|||
LoongArchPICCommonClass parent_class;
|
||||
|
||||
DeviceRealize parent_realize;
|
||||
ResettablePhases parent_phases;
|
||||
};
|
||||
|
||||
#endif /* HW_LOONGARCH_PCH_PIC_H */
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ ENTRY(_start)
|
|||
SECTIONS
|
||||
{
|
||||
/* Linux kernel legacy start address. */
|
||||
. = 0x9000000000200000;
|
||||
. = 0x200000;
|
||||
_text = .;
|
||||
.text : {
|
||||
*(.text)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue