slightly ping :) 在 2023/7/17 10:22, Bibo Mao 写道: > With ACPI Spec 6.5 chapter 5.2.12.20, each processor in LoongArch > system has a Core Programmable Interrupt Controller in MADT table, > value of its type is 0x11 in the spec and defined as enum variable > ACPI_MADT_TYPE_CORE_PIC in Linux kernel. Physical id can be parsed > from MADT table for LoongArch system, also it can be parsed from > MAT table for hotplug cpu. This patch adds physical id parsing for > LoongArch system. > > Signed-off-by: Bibo Mao <maobibo@xxxxxxxxxxx> > --- > Changes in v2: > Refresh the changelog and add detailed description of acpi spec > about MADT table for LoongArch system. > > Add comments in function map_core_pic_id. > > --- > drivers/acpi/processor_core.c | 29 +++++++++++++++++++++++++++++ > 1 file changed, 29 insertions(+) > > diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c > index d6606a9f2da6..7dd6dbaa98c3 100644 > --- a/drivers/acpi/processor_core.c > +++ b/drivers/acpi/processor_core.c > @@ -132,6 +132,30 @@ static int map_rintc_hartid(struct acpi_subtable_header *entry, > return -EINVAL; > } > > +/* > + * Retrieve LoongArch CPU physical id > + */ > +static int map_core_pic_id(struct acpi_subtable_header *entry, > + int device_declaration, u32 acpi_id, phys_cpuid_t *phys_id) > +{ > + struct acpi_madt_core_pic *core_pic = > + container_of(entry, struct acpi_madt_core_pic, header); > + > + if (!(core_pic->flags & ACPI_MADT_ENABLED)) > + return -ENODEV; > + > + /* device_declaration means Device object in DSDT, in LoongArch > + * system, logical processor acpi_id is required in _UID property > + * of DSDT table, so we should check device_declaration here > + */ > + if (device_declaration && (core_pic->processor_id == acpi_id)) { > + *phys_id = core_pic->core_id; > + return 0; > + } > + > + return -EINVAL; > +} > + > static phys_cpuid_t map_madt_entry(struct acpi_table_madt *madt, > int type, u32 acpi_id) > { > @@ -165,6 +189,9 @@ static phys_cpuid_t map_madt_entry(struct acpi_table_madt *madt, > } else if (header->type == ACPI_MADT_TYPE_RINTC) { > if (!map_rintc_hartid(header, type, acpi_id, &phys_id)) > break; > + } else if (header->type == ACPI_MADT_TYPE_CORE_PIC) { > + if (!map_core_pic_id(header, type, acpi_id, &phys_id)) > + break; > } > entry += header->length; > } > @@ -216,6 +243,8 @@ static phys_cpuid_t map_mat_entry(acpi_handle handle, int type, u32 acpi_id) > map_x2apic_id(header, type, acpi_id, &phys_id); > else if (header->type == ACPI_MADT_TYPE_GENERIC_INTERRUPT) > map_gicc_mpidr(header, type, acpi_id, &phys_id); > + else if (header->type == ACPI_MADT_TYPE_CORE_PIC) > + map_core_pic_id(header, type, acpi_id, &phys_id); > > exit: > kfree(buffer.pointer);