Skip to content

Commit 9bd0c41

Browse files
committed
Merge branch 'acpi-processor'
Merge ACPI processor driver changes for 6.6-rc1: - Support obtaining physical CPU ID from MADT on LoongArch (Bibo Mao). - Convert ACPI CPU initialization to using _OSC instead of _PDC that has been depreceted since 2018 and dropped from the specification in ACPI 6.5 (Michal Wilczynski, Rafael Wysocki). * acpi-processor: ACPI: processor: LoongArch: Get physical ID from MADT ACPI: processor: Refine messages in acpi_early_processor_control_setup() ACPI: processor: Remove acpi_hwp_native_thermal_lvt_osc() ACPI: processor: Use _OSC to convey OSPM processor support information ACPI: processor: Introduce acpi_processor_osc() ACPI: processor: Set CAP_SMP_T_SWCOORD in arch_acpi_set_proc_cap_bits() ACPI: processor: Clear C_C2C3_FFH and C_C1_FFH in arch_acpi_set_proc_cap_bits() ACPI: processor: Rename ACPI_PDC symbols ACPI: processor: Refactor arch_acpi_set_pdc_bits() ACPI: processor: Move processor_physically_present() to acpi_processor.c ACPI: processor: Move MWAIT quirk out of acpi_processor.c
2 parents e921f8c + f6fcf03 commit 9bd0c41

File tree

11 files changed

+226
-188
lines changed

11 files changed

+226
-188
lines changed

arch/ia64/include/asm/acpi.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
#ifdef __KERNEL__
1313

14-
#include <acpi/pdc_intel.h>
14+
#include <acpi/proc_cap_intel.h>
1515

1616
#include <linux/init.h>
1717
#include <linux/numa.h>
@@ -69,9 +69,9 @@ extern int __initdata nid_to_pxm_map[MAX_NUMNODES];
6969
#endif
7070

7171
static inline bool arch_has_acpi_pdc(void) { return true; }
72-
static inline void arch_acpi_set_pdc_bits(u32 *buf)
72+
static inline void arch_acpi_set_proc_cap_bits(u32 *cap)
7373
{
74-
buf[2] |= ACPI_PDC_EST_CAPABILITY_SMP;
74+
*cap |= ACPI_PROC_CAP_EST_CAPABILITY_SMP;
7575
}
7676

7777
#ifdef CONFIG_ACPI_NUMA

arch/x86/include/asm/acpi.h

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* Copyright (C) 2001 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
77
* Copyright (C) 2001 Patrick Mochel <mochel@osdl.org>
88
*/
9-
#include <acpi/pdc_intel.h>
9+
#include <acpi/proc_cap_intel.h>
1010

1111
#include <asm/numa.h>
1212
#include <asm/fixmap.h>
@@ -102,23 +102,31 @@ static inline bool arch_has_acpi_pdc(void)
102102
c->x86_vendor == X86_VENDOR_CENTAUR);
103103
}
104104

105-
static inline void arch_acpi_set_pdc_bits(u32 *buf)
105+
static inline void arch_acpi_set_proc_cap_bits(u32 *cap)
106106
{
107107
struct cpuinfo_x86 *c = &cpu_data(0);
108108

109-
buf[2] |= ACPI_PDC_C_CAPABILITY_SMP;
109+
*cap |= ACPI_PROC_CAP_C_CAPABILITY_SMP;
110+
111+
/* Enable coordination with firmware's _TSD info */
112+
*cap |= ACPI_PROC_CAP_SMP_T_SWCOORD;
110113

111114
if (cpu_has(c, X86_FEATURE_EST))
112-
buf[2] |= ACPI_PDC_EST_CAPABILITY_SWSMP;
115+
*cap |= ACPI_PROC_CAP_EST_CAPABILITY_SWSMP;
113116

114117
if (cpu_has(c, X86_FEATURE_ACPI))
115-
buf[2] |= ACPI_PDC_T_FFH;
118+
*cap |= ACPI_PROC_CAP_T_FFH;
119+
120+
if (cpu_has(c, X86_FEATURE_HWP))
121+
*cap |= ACPI_PROC_CAP_COLLAB_PROC_PERF;
116122

117123
/*
118-
* If mwait/monitor is unsupported, C2/C3_FFH will be disabled
124+
* If mwait/monitor is unsupported, C_C1_FFH and
125+
* C2/C3_FFH will be disabled.
119126
*/
120-
if (!cpu_has(c, X86_FEATURE_MWAIT))
121-
buf[2] &= ~(ACPI_PDC_C_C2C3_FFH);
127+
if (!cpu_has(c, X86_FEATURE_MWAIT) ||
128+
boot_option_idle_override == IDLE_NOMWAIT)
129+
*cap &= ~(ACPI_PROC_CAP_C_C1_FFH | ACPI_PROC_CAP_C_C2C3_FFH);
122130
}
123131

124132
static inline bool acpi_has_cpu_in_madt(void)

arch/x86/xen/enlighten_pv.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@
7979
#ifdef CONFIG_ACPI
8080
#include <linux/acpi.h>
8181
#include <asm/acpi.h>
82-
#include <acpi/pdc_intel.h>
82+
#include <acpi/proc_cap_intel.h>
8383
#include <acpi/processor.h>
8484
#include <xen/interface/platform.h>
8585
#endif
@@ -288,17 +288,17 @@ static bool __init xen_check_mwait(void)
288288

289289
native_cpuid(&ax, &bx, &cx, &dx);
290290

291-
/* Ask the Hypervisor whether to clear ACPI_PDC_C_C2C3_FFH. If so,
291+
/* Ask the Hypervisor whether to clear ACPI_PROC_CAP_C_C2C3_FFH. If so,
292292
* don't expose MWAIT_LEAF and let ACPI pick the IOPORT version of C3.
293293
*/
294294
buf[0] = ACPI_PDC_REVISION_ID;
295295
buf[1] = 1;
296-
buf[2] = (ACPI_PDC_C_CAPABILITY_SMP | ACPI_PDC_EST_CAPABILITY_SWSMP);
296+
buf[2] = (ACPI_PROC_CAP_C_CAPABILITY_SMP | ACPI_PROC_CAP_EST_CAPABILITY_SWSMP);
297297

298298
set_xen_guest_handle(op.u.set_pminfo.pdc, buf);
299299

300300
if ((HYPERVISOR_platform_op(&op) == 0) &&
301-
(buf[2] & (ACPI_PDC_C_C1_FFH | ACPI_PDC_C_C2C3_FFH))) {
301+
(buf[2] & (ACPI_PROC_CAP_C_C1_FFH | ACPI_PROC_CAP_C_C2C3_FFH))) {
302302
cpuid_leaf5_ecx_val = cx;
303303
cpuid_leaf5_edx_val = dx;
304304
}

drivers/acpi/acpi_processor.c

Lines changed: 92 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,11 @@
99
* Copyright (C) 2013, Intel Corporation
1010
* Rafael J. Wysocki <rafael.j.wysocki@intel.com>
1111
*/
12+
#define pr_fmt(fmt) "ACPI: " fmt
1213

1314
#include <linux/acpi.h>
1415
#include <linux/device.h>
16+
#include <linux/dmi.h>
1517
#include <linux/kernel.h>
1618
#include <linux/module.h>
1719
#include <linux/pci.h>
@@ -21,6 +23,8 @@
2123

2224
#include <asm/cpu.h>
2325

26+
#include <xen/xen.h>
27+
2428
#include "internal.h"
2529

2630
DEFINE_PER_CPU(struct acpi_processor *, processors);
@@ -508,54 +512,110 @@ static void acpi_processor_remove(struct acpi_device *device)
508512
}
509513
#endif /* CONFIG_ACPI_HOTPLUG_CPU */
510514

511-
#ifdef CONFIG_X86
512-
static bool acpi_hwp_native_thermal_lvt_set;
513-
static acpi_status __init acpi_hwp_native_thermal_lvt_osc(acpi_handle handle,
514-
u32 lvl,
515-
void *context,
516-
void **rv)
515+
#ifdef CONFIG_ARCH_MIGHT_HAVE_ACPI_PDC
516+
bool __init processor_physically_present(acpi_handle handle)
517+
{
518+
int cpuid, type;
519+
u32 acpi_id;
520+
acpi_status status;
521+
acpi_object_type acpi_type;
522+
unsigned long long tmp;
523+
union acpi_object object = {};
524+
struct acpi_buffer buffer = { sizeof(union acpi_object), &object };
525+
526+
status = acpi_get_type(handle, &acpi_type);
527+
if (ACPI_FAILURE(status))
528+
return false;
529+
530+
switch (acpi_type) {
531+
case ACPI_TYPE_PROCESSOR:
532+
status = acpi_evaluate_object(handle, NULL, NULL, &buffer);
533+
if (ACPI_FAILURE(status))
534+
return false;
535+
acpi_id = object.processor.proc_id;
536+
break;
537+
case ACPI_TYPE_DEVICE:
538+
status = acpi_evaluate_integer(handle, METHOD_NAME__UID,
539+
NULL, &tmp);
540+
if (ACPI_FAILURE(status))
541+
return false;
542+
acpi_id = tmp;
543+
break;
544+
default:
545+
return false;
546+
}
547+
548+
if (xen_initial_domain())
549+
/*
550+
* When running as a Xen dom0 the number of processors Linux
551+
* sees can be different from the real number of processors on
552+
* the system, and we still need to execute _PDC or _OSC for
553+
* all of them.
554+
*/
555+
return xen_processor_present(acpi_id);
556+
557+
type = (acpi_type == ACPI_TYPE_DEVICE) ? 1 : 0;
558+
cpuid = acpi_get_cpuid(handle, type, acpi_id);
559+
560+
return !invalid_logical_cpuid(cpuid);
561+
}
562+
563+
/* vendor specific UUID indicating an Intel platform */
564+
static u8 sb_uuid_str[] = "4077A616-290C-47BE-9EBD-D87058713953";
565+
566+
static acpi_status __init acpi_processor_osc(acpi_handle handle, u32 lvl,
567+
void *context, void **rv)
517568
{
518-
u8 sb_uuid_str[] = "4077A616-290C-47BE-9EBD-D87058713953";
519-
u32 capbuf[2];
569+
u32 capbuf[2] = {};
520570
struct acpi_osc_context osc_context = {
521571
.uuid_str = sb_uuid_str,
522572
.rev = 1,
523573
.cap.length = 8,
524574
.cap.pointer = capbuf,
525575
};
576+
acpi_status status;
526577

527-
if (acpi_hwp_native_thermal_lvt_set)
528-
return AE_CTRL_TERMINATE;
578+
if (!processor_physically_present(handle))
579+
return AE_OK;
529580

530-
capbuf[0] = 0x0000;
531-
capbuf[1] = 0x1000; /* set bit 12 */
581+
arch_acpi_set_proc_cap_bits(&capbuf[OSC_SUPPORT_DWORD]);
532582

533-
if (ACPI_SUCCESS(acpi_run_osc(handle, &osc_context))) {
534-
if (osc_context.ret.pointer && osc_context.ret.length > 1) {
535-
u32 *capbuf_ret = osc_context.ret.pointer;
583+
status = acpi_run_osc(handle, &osc_context);
584+
if (ACPI_FAILURE(status))
585+
return status;
536586

537-
if (capbuf_ret[1] & 0x1000) {
538-
acpi_handle_info(handle,
539-
"_OSC native thermal LVT Acked\n");
540-
acpi_hwp_native_thermal_lvt_set = true;
541-
}
542-
}
543-
kfree(osc_context.ret.pointer);
544-
}
587+
kfree(osc_context.ret.pointer);
545588

546589
return AE_OK;
547590
}
548591

549-
void __init acpi_early_processor_osc(void)
592+
static bool __init acpi_early_processor_osc(void)
550593
{
551-
if (boot_cpu_has(X86_FEATURE_HWP)) {
552-
acpi_walk_namespace(ACPI_TYPE_PROCESSOR, ACPI_ROOT_OBJECT,
553-
ACPI_UINT32_MAX,
554-
acpi_hwp_native_thermal_lvt_osc,
555-
NULL, NULL, NULL);
556-
acpi_get_devices(ACPI_PROCESSOR_DEVICE_HID,
557-
acpi_hwp_native_thermal_lvt_osc,
558-
NULL, NULL);
594+
acpi_status status;
595+
596+
acpi_proc_quirk_mwait_check();
597+
598+
status = acpi_walk_namespace(ACPI_TYPE_PROCESSOR, ACPI_ROOT_OBJECT,
599+
ACPI_UINT32_MAX, acpi_processor_osc, NULL,
600+
NULL, NULL);
601+
if (ACPI_FAILURE(status))
602+
return false;
603+
604+
status = acpi_get_devices(ACPI_PROCESSOR_DEVICE_HID, acpi_processor_osc,
605+
NULL, NULL);
606+
if (ACPI_FAILURE(status))
607+
return false;
608+
609+
return true;
610+
}
611+
612+
void __init acpi_early_processor_control_setup(void)
613+
{
614+
if (acpi_early_processor_osc()) {
615+
pr_info("_OSC evaluated successfully for all CPUs\n");
616+
} else {
617+
pr_info("_OSC evaluation for CPUs failed, trying _PDC\n");
618+
acpi_early_processor_set_pdc();
559619
}
560620
}
561621
#endif

drivers/acpi/bus.c

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1322,9 +1322,6 @@ static int __init acpi_bus_init(void)
13221322
goto error1;
13231323
}
13241324

1325-
/* Set capability bits for _OSC under processor scope */
1326-
acpi_early_processor_osc();
1327-
13281325
/*
13291326
* _OSC method may exist in module level code,
13301327
* so it must be run after ACPI_FULL_INITIALIZATION
@@ -1340,7 +1337,7 @@ static int __init acpi_bus_init(void)
13401337

13411338
acpi_sysfs_init();
13421339

1343-
acpi_early_processor_set_pdc();
1340+
acpi_early_processor_control_setup();
13441341

13451342
/*
13461343
* Maybe EC region is required at bus_scan/acpi_get_devices. So it

drivers/acpi/internal.h

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -152,15 +152,13 @@ int acpi_wakeup_device_init(void);
152152
Processor
153153
-------------------------------------------------------------------------- */
154154
#ifdef CONFIG_ARCH_MIGHT_HAVE_ACPI_PDC
155+
void acpi_early_processor_control_setup(void);
155156
void acpi_early_processor_set_pdc(void);
156-
#else
157-
static inline void acpi_early_processor_set_pdc(void) {}
158-
#endif
159157

160-
#ifdef CONFIG_X86
161-
void acpi_early_processor_osc(void);
158+
void acpi_proc_quirk_mwait_check(void);
159+
bool processor_physically_present(acpi_handle handle);
162160
#else
163-
static inline void acpi_early_processor_osc(void) {}
161+
static inline void acpi_early_processor_control_setup(void) {}
164162
#endif
165163

166164
/* --------------------------------------------------------------------------

drivers/acpi/processor_core.c

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,30 @@ static int map_rintc_hartid(struct acpi_subtable_header *entry,
132132
return -EINVAL;
133133
}
134134

135+
/*
136+
* Retrieve LoongArch CPU physical id
137+
*/
138+
static int map_core_pic_id(struct acpi_subtable_header *entry,
139+
int device_declaration, u32 acpi_id, phys_cpuid_t *phys_id)
140+
{
141+
struct acpi_madt_core_pic *core_pic =
142+
container_of(entry, struct acpi_madt_core_pic, header);
143+
144+
if (!(core_pic->flags & ACPI_MADT_ENABLED))
145+
return -ENODEV;
146+
147+
/* device_declaration means Device object in DSDT, in LoongArch
148+
* system, logical processor acpi_id is required in _UID property
149+
* of DSDT table, so we should check device_declaration here
150+
*/
151+
if (device_declaration && (core_pic->processor_id == acpi_id)) {
152+
*phys_id = core_pic->core_id;
153+
return 0;
154+
}
155+
156+
return -EINVAL;
157+
}
158+
135159
static phys_cpuid_t map_madt_entry(struct acpi_table_madt *madt,
136160
int type, u32 acpi_id)
137161
{
@@ -165,6 +189,9 @@ static phys_cpuid_t map_madt_entry(struct acpi_table_madt *madt,
165189
} else if (header->type == ACPI_MADT_TYPE_RINTC) {
166190
if (!map_rintc_hartid(header, type, acpi_id, &phys_id))
167191
break;
192+
} else if (header->type == ACPI_MADT_TYPE_CORE_PIC) {
193+
if (!map_core_pic_id(header, type, acpi_id, &phys_id))
194+
break;
168195
}
169196
entry += header->length;
170197
}
@@ -216,6 +243,8 @@ static phys_cpuid_t map_mat_entry(acpi_handle handle, int type, u32 acpi_id)
216243
map_x2apic_id(header, type, acpi_id, &phys_id);
217244
else if (header->type == ACPI_MADT_TYPE_GENERIC_INTERRUPT)
218245
map_gicc_mpidr(header, type, acpi_id, &phys_id);
246+
else if (header->type == ACPI_MADT_TYPE_CORE_PIC)
247+
map_core_pic_id(header, type, acpi_id, &phys_id);
219248

220249
exit:
221250
kfree(buffer.pointer);

0 commit comments

Comments
 (0)