processor_core.c 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354
  1. /*
  2. * Copyright (C) 2005 Intel Corporation
  3. * Copyright (C) 2009 Hewlett-Packard Development Company, L.P.
  4. *
  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
  9. */
  10. #include <linux/dmi.h>
  11. #include <acpi/acpi_drivers.h>
  12. #include <acpi/processor.h>
  13. #include "internal.h"
  14. #define PREFIX "ACPI: "
  15. #define _COMPONENT ACPI_PROCESSOR_COMPONENT
  16. ACPI_MODULE_NAME("processor_core");
  17. static int set_no_mwait(const struct dmi_system_id *id)
  18. {
  19. printk(KERN_NOTICE PREFIX "%s detected - "
  20. "disabling mwait for CPU C-states\n", id->ident);
  21. idle_nomwait = 1;
  22. return 0;
  23. }
  24. static struct dmi_system_id __cpuinitdata processor_idle_dmi_table[] = {
  25. {
  26. set_no_mwait, "IFL91 board", {
  27. DMI_MATCH(DMI_BIOS_VENDOR, "COMPAL"),
  28. DMI_MATCH(DMI_SYS_VENDOR, "ZEPTO"),
  29. DMI_MATCH(DMI_PRODUCT_VERSION, "3215W"),
  30. DMI_MATCH(DMI_BOARD_NAME, "IFL91") }, NULL},
  31. {
  32. set_no_mwait, "Extensa 5220", {
  33. DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
  34. DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
  35. DMI_MATCH(DMI_PRODUCT_VERSION, "0100"),
  36. DMI_MATCH(DMI_BOARD_NAME, "Columbia") }, NULL},
  37. {},
  38. };
  39. #ifdef CONFIG_SMP
  40. static int map_lapic_id(struct acpi_subtable_header *entry,
  41. u32 acpi_id, int *apic_id)
  42. {
  43. struct acpi_madt_local_apic *lapic =
  44. (struct acpi_madt_local_apic *)entry;
  45. if (!(lapic->lapic_flags & ACPI_MADT_ENABLED))
  46. return 0;
  47. if (lapic->processor_id != acpi_id)
  48. return 0;
  49. *apic_id = lapic->id;
  50. return 1;
  51. }
  52. static int map_x2apic_id(struct acpi_subtable_header *entry,
  53. int device_declaration, u32 acpi_id, int *apic_id)
  54. {
  55. struct acpi_madt_local_x2apic *apic =
  56. (struct acpi_madt_local_x2apic *)entry;
  57. if (!(apic->lapic_flags & ACPI_MADT_ENABLED))
  58. return 0;
  59. if (device_declaration && (apic->uid == acpi_id)) {
  60. *apic_id = apic->local_apic_id;
  61. return 1;
  62. }
  63. return 0;
  64. }
  65. static int map_lsapic_id(struct acpi_subtable_header *entry,
  66. int device_declaration, u32 acpi_id, int *apic_id)
  67. {
  68. struct acpi_madt_local_sapic *lsapic =
  69. (struct acpi_madt_local_sapic *)entry;
  70. if (!(lsapic->lapic_flags & ACPI_MADT_ENABLED))
  71. return 0;
  72. if (device_declaration) {
  73. if ((entry->length < 16) || (lsapic->uid != acpi_id))
  74. return 0;
  75. } else if (lsapic->processor_id != acpi_id)
  76. return 0;
  77. *apic_id = (lsapic->id << 8) | lsapic->eid;
  78. return 1;
  79. }
  80. static int map_madt_entry(int type, u32 acpi_id)
  81. {
  82. unsigned long madt_end, entry;
  83. static struct acpi_table_madt *madt;
  84. static int read_madt;
  85. int apic_id = -1;
  86. if (!read_madt) {
  87. if (ACPI_FAILURE(acpi_get_table(ACPI_SIG_MADT, 0,
  88. (struct acpi_table_header **)&madt)))
  89. madt = NULL;
  90. read_madt++;
  91. }
  92. if (!madt)
  93. return apic_id;
  94. entry = (unsigned long)madt;
  95. madt_end = entry + madt->header.length;
  96. /* Parse all entries looking for a match. */
  97. entry += sizeof(struct acpi_table_madt);
  98. while (entry + sizeof(struct acpi_subtable_header) < madt_end) {
  99. struct acpi_subtable_header *header =
  100. (struct acpi_subtable_header *)entry;
  101. if (header->type == ACPI_MADT_TYPE_LOCAL_APIC) {
  102. if (map_lapic_id(header, acpi_id, &apic_id))
  103. break;
  104. } else if (header->type == ACPI_MADT_TYPE_LOCAL_X2APIC) {
  105. if (map_x2apic_id(header, type, acpi_id, &apic_id))
  106. break;
  107. } else if (header->type == ACPI_MADT_TYPE_LOCAL_SAPIC) {
  108. if (map_lsapic_id(header, type, acpi_id, &apic_id))
  109. break;
  110. }
  111. entry += header->length;
  112. }
  113. return apic_id;
  114. }
  115. static int map_mat_entry(acpi_handle handle, int type, u32 acpi_id)
  116. {
  117. struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
  118. union acpi_object *obj;
  119. struct acpi_subtable_header *header;
  120. int apic_id = -1;
  121. if (ACPI_FAILURE(acpi_evaluate_object(handle, "_MAT", NULL, &buffer)))
  122. goto exit;
  123. if (!buffer.length || !buffer.pointer)
  124. goto exit;
  125. obj = buffer.pointer;
  126. if (obj->type != ACPI_TYPE_BUFFER ||
  127. obj->buffer.length < sizeof(struct acpi_subtable_header)) {
  128. goto exit;
  129. }
  130. header = (struct acpi_subtable_header *)obj->buffer.pointer;
  131. if (header->type == ACPI_MADT_TYPE_LOCAL_APIC) {
  132. map_lapic_id(header, acpi_id, &apic_id);
  133. } else if (header->type == ACPI_MADT_TYPE_LOCAL_SAPIC) {
  134. map_lsapic_id(header, type, acpi_id, &apic_id);
  135. }
  136. exit:
  137. if (buffer.pointer)
  138. kfree(buffer.pointer);
  139. return apic_id;
  140. }
  141. int acpi_get_cpuid(acpi_handle handle, int type, u32 acpi_id)
  142. {
  143. int i;
  144. int apic_id = -1;
  145. apic_id = map_mat_entry(handle, type, acpi_id);
  146. if (apic_id == -1)
  147. apic_id = map_madt_entry(type, acpi_id);
  148. if (apic_id == -1)
  149. return apic_id;
  150. for_each_possible_cpu(i) {
  151. if (cpu_physical_id(i) == apic_id)
  152. return i;
  153. }
  154. return -1;
  155. }
  156. EXPORT_SYMBOL_GPL(acpi_get_cpuid);
  157. #endif
  158. static bool processor_physically_present(acpi_handle handle)
  159. {
  160. int cpuid, type;
  161. u32 acpi_id;
  162. acpi_status status;
  163. acpi_object_type acpi_type;
  164. unsigned long long tmp;
  165. union acpi_object object = { 0 };
  166. struct acpi_buffer buffer = { sizeof(union acpi_object), &object };
  167. status = acpi_get_type(handle, &acpi_type);
  168. if (ACPI_FAILURE(status))
  169. return false;
  170. switch (acpi_type) {
  171. case ACPI_TYPE_PROCESSOR:
  172. status = acpi_evaluate_object(handle, NULL, NULL, &buffer);
  173. if (ACPI_FAILURE(status))
  174. return false;
  175. acpi_id = object.processor.proc_id;
  176. break;
  177. case ACPI_TYPE_DEVICE:
  178. status = acpi_evaluate_integer(handle, "_UID", NULL, &tmp);
  179. if (ACPI_FAILURE(status))
  180. return false;
  181. acpi_id = tmp;
  182. break;
  183. default:
  184. return false;
  185. }
  186. type = (acpi_type == ACPI_TYPE_DEVICE) ? 1 : 0;
  187. cpuid = acpi_get_cpuid(handle, type, acpi_id);
  188. if (cpuid == -1)
  189. return false;
  190. return true;
  191. }
  192. static void acpi_set_pdc_bits(u32 *buf)
  193. {
  194. buf[0] = ACPI_PDC_REVISION_ID;
  195. buf[1] = 1;
  196. /* Enable coordination with firmware's _TSD info */
  197. buf[2] = ACPI_PDC_SMP_T_SWCOORD;
  198. /* Twiddle arch-specific bits needed for _PDC */
  199. arch_acpi_set_pdc_bits(buf);
  200. }
  201. static struct acpi_object_list *acpi_processor_alloc_pdc(void)
  202. {
  203. struct acpi_object_list *obj_list;
  204. union acpi_object *obj;
  205. u32 *buf;
  206. /* allocate and initialize pdc. It will be used later. */
  207. obj_list = kmalloc(sizeof(struct acpi_object_list), GFP_KERNEL);
  208. if (!obj_list) {
  209. printk(KERN_ERR "Memory allocation error\n");
  210. return NULL;
  211. }
  212. obj = kmalloc(sizeof(union acpi_object), GFP_KERNEL);
  213. if (!obj) {
  214. printk(KERN_ERR "Memory allocation error\n");
  215. kfree(obj_list);
  216. return NULL;
  217. }
  218. buf = kmalloc(12, GFP_KERNEL);
  219. if (!buf) {
  220. printk(KERN_ERR "Memory allocation error\n");
  221. kfree(obj);
  222. kfree(obj_list);
  223. return NULL;
  224. }
  225. acpi_set_pdc_bits(buf);
  226. obj->type = ACPI_TYPE_BUFFER;
  227. obj->buffer.length = 12;
  228. obj->buffer.pointer = (u8 *) buf;
  229. obj_list->count = 1;
  230. obj_list->pointer = obj;
  231. return obj_list;
  232. }
  233. /*
  234. * _PDC is required for a BIOS-OS handshake for most of the newer
  235. * ACPI processor features.
  236. */
  237. static int
  238. acpi_processor_eval_pdc(acpi_handle handle, struct acpi_object_list *pdc_in)
  239. {
  240. acpi_status status = AE_OK;
  241. if (idle_nomwait) {
  242. /*
  243. * If mwait is disabled for CPU C-states, the C2C3_FFH access
  244. * mode will be disabled in the parameter of _PDC object.
  245. * Of course C1_FFH access mode will also be disabled.
  246. */
  247. union acpi_object *obj;
  248. u32 *buffer = NULL;
  249. obj = pdc_in->pointer;
  250. buffer = (u32 *)(obj->buffer.pointer);
  251. buffer[2] &= ~(ACPI_PDC_C_C2C3_FFH | ACPI_PDC_C_C1_FFH);
  252. }
  253. status = acpi_evaluate_object(handle, "_PDC", pdc_in, NULL);
  254. if (ACPI_FAILURE(status))
  255. ACPI_DEBUG_PRINT((ACPI_DB_INFO,
  256. "Could not evaluate _PDC, using legacy perf. control.\n"));
  257. return status;
  258. }
  259. void acpi_processor_set_pdc(acpi_handle handle)
  260. {
  261. struct acpi_object_list *obj_list;
  262. if (arch_has_acpi_pdc() == false)
  263. return;
  264. obj_list = acpi_processor_alloc_pdc();
  265. if (!obj_list)
  266. return;
  267. acpi_processor_eval_pdc(handle, obj_list);
  268. kfree(obj_list->pointer->buffer.pointer);
  269. kfree(obj_list->pointer);
  270. kfree(obj_list);
  271. }
  272. EXPORT_SYMBOL_GPL(acpi_processor_set_pdc);
  273. static acpi_status
  274. early_init_pdc(acpi_handle handle, u32 lvl, void *context, void **rv)
  275. {
  276. if (processor_physically_present(handle) == false)
  277. return AE_OK;
  278. acpi_processor_set_pdc(handle);
  279. return AE_OK;
  280. }
  281. void __init acpi_early_processor_set_pdc(void)
  282. {
  283. /*
  284. * Check whether the system is DMI table. If yes, OSPM
  285. * should not use mwait for CPU-states.
  286. */
  287. dmi_check_system(processor_idle_dmi_table);
  288. acpi_walk_namespace(ACPI_TYPE_PROCESSOR, ACPI_ROOT_OBJECT,
  289. ACPI_UINT32_MAX,
  290. early_init_pdc, NULL, NULL, NULL);
  291. }