diff mbox series

[v2] ACPI: processor_core: LoongArch: Get physical id from MADT table

Message ID 20230717022258.2579631-1-maobibo@loongson.cn
State Accepted
Commit f6fcf03ce8a9b8c135cf47f4978617bdf2829711
Headers show
Series [v2] ACPI: processor_core: LoongArch: Get physical id from MADT table | expand

Commit Message

maobibo July 17, 2023, 2:22 a.m. UTC
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@loongson.cn>
---
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(+)

Comments

maobibo July 25, 2023, 12:32 a.m. UTC | #1
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@loongson.cn>
> ---
> 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);
diff mbox series

Patch

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);