2 * Copyright (C) 2005 Intel Corporation
3 * Copyright (C) 2009 Hewlett-Packard Development Company, L.P.
5 * Alex Chiang <achiang@hp.com>
6 * - Unified x86/ia64 implementations
7 * Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
8 * - Added _PDC for platforms with Intel CPUs
10 #include <linux/export.h>
11 #include <linux/dmi.h>
12 #include <linux/slab.h>
13 #include <linux/acpi.h>
14 #include <acpi/processor.h>
18 #define PREFIX "ACPI: "
19 #define _COMPONENT ACPI_PROCESSOR_COMPONENT
20 ACPI_MODULE_NAME("processor_core");
22 static int map_lapic_id(struct acpi_subtable_header
*entry
,
23 u32 acpi_id
, int *apic_id
)
25 struct acpi_madt_local_apic
*lapic
=
26 (struct acpi_madt_local_apic
*)entry
;
28 if (!(lapic
->lapic_flags
& ACPI_MADT_ENABLED
))
31 if (lapic
->processor_id
!= acpi_id
)
38 static int map_x2apic_id(struct acpi_subtable_header
*entry
,
39 int device_declaration
, u32 acpi_id
, int *apic_id
)
41 struct acpi_madt_local_x2apic
*apic
=
42 (struct acpi_madt_local_x2apic
*)entry
;
44 if (!(apic
->lapic_flags
& ACPI_MADT_ENABLED
))
47 if (device_declaration
&& (apic
->uid
== acpi_id
)) {
48 *apic_id
= apic
->local_apic_id
;
55 static int map_lsapic_id(struct acpi_subtable_header
*entry
,
56 int device_declaration
, u32 acpi_id
, int *apic_id
)
58 struct acpi_madt_local_sapic
*lsapic
=
59 (struct acpi_madt_local_sapic
*)entry
;
61 if (!(lsapic
->lapic_flags
& ACPI_MADT_ENABLED
))
64 if (device_declaration
) {
65 if ((entry
->length
< 16) || (lsapic
->uid
!= acpi_id
))
67 } else if (lsapic
->processor_id
!= acpi_id
)
70 *apic_id
= (lsapic
->id
<< 8) | lsapic
->eid
;
74 static int map_madt_entry(int type
, u32 acpi_id
)
76 unsigned long madt_end
, entry
;
77 static struct acpi_table_madt
*madt
;
82 if (ACPI_FAILURE(acpi_get_table(ACPI_SIG_MADT
, 0,
83 (struct acpi_table_header
**)&madt
)))
91 entry
= (unsigned long)madt
;
92 madt_end
= entry
+ madt
->header
.length
;
94 /* Parse all entries looking for a match. */
96 entry
+= sizeof(struct acpi_table_madt
);
97 while (entry
+ sizeof(struct acpi_subtable_header
) < madt_end
) {
98 struct acpi_subtable_header
*header
=
99 (struct acpi_subtable_header
*)entry
;
100 if (header
->type
== ACPI_MADT_TYPE_LOCAL_APIC
) {
101 if (!map_lapic_id(header
, acpi_id
, &apic_id
))
103 } else if (header
->type
== ACPI_MADT_TYPE_LOCAL_X2APIC
) {
104 if (!map_x2apic_id(header
, type
, acpi_id
, &apic_id
))
106 } else if (header
->type
== ACPI_MADT_TYPE_LOCAL_SAPIC
) {
107 if (!map_lsapic_id(header
, type
, acpi_id
, &apic_id
))
110 entry
+= header
->length
;
115 static int map_mat_entry(acpi_handle handle
, int type
, u32 acpi_id
)
117 struct acpi_buffer buffer
= { ACPI_ALLOCATE_BUFFER
, NULL
};
118 union acpi_object
*obj
;
119 struct acpi_subtable_header
*header
;
122 if (ACPI_FAILURE(acpi_evaluate_object(handle
, "_MAT", NULL
, &buffer
)))
125 if (!buffer
.length
|| !buffer
.pointer
)
128 obj
= buffer
.pointer
;
129 if (obj
->type
!= ACPI_TYPE_BUFFER
||
130 obj
->buffer
.length
< sizeof(struct acpi_subtable_header
)) {
134 header
= (struct acpi_subtable_header
*)obj
->buffer
.pointer
;
135 if (header
->type
== ACPI_MADT_TYPE_LOCAL_APIC
) {
136 map_lapic_id(header
, acpi_id
, &apic_id
);
137 } else if (header
->type
== ACPI_MADT_TYPE_LOCAL_SAPIC
) {
138 map_lsapic_id(header
, type
, acpi_id
, &apic_id
);
142 kfree(buffer
.pointer
);
146 int acpi_get_apicid(acpi_handle handle
, int type
, u32 acpi_id
)
150 apic_id
= map_mat_entry(handle
, type
, acpi_id
);
152 apic_id
= map_madt_entry(type
, acpi_id
);
157 int acpi_map_cpuid(int apic_id
, u32 acpi_id
)
165 * On UP processor, there is no _MAT or MADT table.
166 * So above apic_id is always set to -1.
168 * BIOS may define multiple CPU handles even for UP processor.
173 * Processor (CPU0, 0x00, 0x00000410, 0x06) {}
174 * Processor (CPU1, 0x01, 0x00000410, 0x06) {}
175 * Processor (CPU2, 0x02, 0x00000410, 0x06) {}
176 * Processor (CPU3, 0x03, 0x00000410, 0x06) {}
179 * Ignores apic_id and always returns 0 for the processor
180 * handle with acpi id 0 if nr_cpu_ids is 1.
181 * This should be the case if SMP tables are not found.
182 * Return -1 for other CPU's handle.
184 if (nr_cpu_ids
<= 1 && acpi_id
== 0)
191 for_each_possible_cpu(i
) {
192 if (cpu_physical_id(i
) == apic_id
)
196 /* In UP kernel, only processor 0 is valid */
203 int acpi_get_cpuid(acpi_handle handle
, int type
, u32 acpi_id
)
207 apic_id
= acpi_get_apicid(handle
, type
, acpi_id
);
209 return acpi_map_cpuid(apic_id
, acpi_id
);
211 EXPORT_SYMBOL_GPL(acpi_get_cpuid
);
213 static bool __init
processor_physically_present(acpi_handle handle
)
218 acpi_object_type acpi_type
;
219 unsigned long long tmp
;
220 union acpi_object object
= { 0 };
221 struct acpi_buffer buffer
= { sizeof(union acpi_object
), &object
};
223 status
= acpi_get_type(handle
, &acpi_type
);
224 if (ACPI_FAILURE(status
))
228 case ACPI_TYPE_PROCESSOR
:
229 status
= acpi_evaluate_object(handle
, NULL
, NULL
, &buffer
);
230 if (ACPI_FAILURE(status
))
232 acpi_id
= object
.processor
.proc_id
;
234 case ACPI_TYPE_DEVICE
:
235 status
= acpi_evaluate_integer(handle
, "_UID", NULL
, &tmp
);
236 if (ACPI_FAILURE(status
))
244 type
= (acpi_type
== ACPI_TYPE_DEVICE
) ? 1 : 0;
245 cpuid
= acpi_get_cpuid(handle
, type
, acpi_id
);
253 static void acpi_set_pdc_bits(u32
*buf
)
255 buf
[0] = ACPI_PDC_REVISION_ID
;
258 /* Enable coordination with firmware's _TSD info */
259 buf
[2] = ACPI_PDC_SMP_T_SWCOORD
;
261 /* Twiddle arch-specific bits needed for _PDC */
262 arch_acpi_set_pdc_bits(buf
);
265 static struct acpi_object_list
*acpi_processor_alloc_pdc(void)
267 struct acpi_object_list
*obj_list
;
268 union acpi_object
*obj
;
271 /* allocate and initialize pdc. It will be used later. */
272 obj_list
= kmalloc(sizeof(struct acpi_object_list
), GFP_KERNEL
);
274 printk(KERN_ERR
"Memory allocation error\n");
278 obj
= kmalloc(sizeof(union acpi_object
), GFP_KERNEL
);
280 printk(KERN_ERR
"Memory allocation error\n");
285 buf
= kmalloc(12, GFP_KERNEL
);
287 printk(KERN_ERR
"Memory allocation error\n");
293 acpi_set_pdc_bits(buf
);
295 obj
->type
= ACPI_TYPE_BUFFER
;
296 obj
->buffer
.length
= 12;
297 obj
->buffer
.pointer
= (u8
*) buf
;
299 obj_list
->pointer
= obj
;
305 * _PDC is required for a BIOS-OS handshake for most of the newer
306 * ACPI processor features.
309 acpi_processor_eval_pdc(acpi_handle handle
, struct acpi_object_list
*pdc_in
)
311 acpi_status status
= AE_OK
;
313 if (boot_option_idle_override
== IDLE_NOMWAIT
) {
315 * If mwait is disabled for CPU C-states, the C2C3_FFH access
316 * mode will be disabled in the parameter of _PDC object.
317 * Of course C1_FFH access mode will also be disabled.
319 union acpi_object
*obj
;
322 obj
= pdc_in
->pointer
;
323 buffer
= (u32
*)(obj
->buffer
.pointer
);
324 buffer
[2] &= ~(ACPI_PDC_C_C2C3_FFH
| ACPI_PDC_C_C1_FFH
);
327 status
= acpi_evaluate_object(handle
, "_PDC", pdc_in
, NULL
);
329 if (ACPI_FAILURE(status
))
330 ACPI_DEBUG_PRINT((ACPI_DB_INFO
,
331 "Could not evaluate _PDC, using legacy perf. control.\n"));
336 void acpi_processor_set_pdc(acpi_handle handle
)
338 struct acpi_object_list
*obj_list
;
340 if (arch_has_acpi_pdc() == false)
343 obj_list
= acpi_processor_alloc_pdc();
347 acpi_processor_eval_pdc(handle
, obj_list
);
349 kfree(obj_list
->pointer
->buffer
.pointer
);
350 kfree(obj_list
->pointer
);
354 static acpi_status __init
355 early_init_pdc(acpi_handle handle
, u32 lvl
, void *context
, void **rv
)
357 if (processor_physically_present(handle
) == false)
360 acpi_processor_set_pdc(handle
);
364 #if defined(CONFIG_X86) || defined(CONFIG_IA64)
365 static int __init
set_no_mwait(const struct dmi_system_id
*id
)
367 pr_notice(PREFIX
"%s detected - disabling mwait for CPU C-states\n",
369 boot_option_idle_override
= IDLE_NOMWAIT
;
373 static struct dmi_system_id processor_idle_dmi_table
[] __initdata
= {
375 set_no_mwait
, "Extensa 5220", {
376 DMI_MATCH(DMI_BIOS_VENDOR
, "Phoenix Technologies LTD"),
377 DMI_MATCH(DMI_SYS_VENDOR
, "Acer"),
378 DMI_MATCH(DMI_PRODUCT_VERSION
, "0100"),
379 DMI_MATCH(DMI_BOARD_NAME
, "Columbia") }, NULL
},
383 static void __init
processor_dmi_check(void)
386 * Check whether the system is DMI table. If yes, OSPM
387 * should not use mwait for CPU-states.
389 dmi_check_system(processor_idle_dmi_table
);
392 static inline void processor_dmi_check(void) {}
395 void __init
acpi_early_processor_set_pdc(void)
397 processor_dmi_check();
399 acpi_walk_namespace(ACPI_TYPE_PROCESSOR
, ACPI_ROOT_OBJECT
,
401 early_init_pdc
, NULL
, NULL
, NULL
);
402 acpi_get_devices(ACPI_PROCESSOR_DEVICE_HID
, early_init_pdc
, NULL
, NULL
);