diff options
author | Dmitry Adamushko <dmitry.adamushko@gmail.com> | 2008-09-23 06:08:44 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-09-23 06:21:42 -0400 |
commit | 18dbc9160507dc7df998e00cd1dcd7889557307b (patch) | |
tree | 81262b57db5de63267762083a54a37558d8555f0 /arch/x86/kernel/microcode_intel.c | |
parent | a1c75cc5018f17ff6d80ce45a13435b1536f76db (diff) |
x86: moved microcode.c to microcode_intel.c
Combine both generic and arch-specific parts of microcode into a
single module (arch-specific parts are config-dependent).
Also while we are at it, move arch-specific parts from microcode.h
into their respective arch-specific .c files.
Signed-off-by: Dmitry Adamushko <dmitry.adamushko@gmail.com>
Cc: "Peter Oruba" <peter.oruba@amd.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/kernel/microcode_intel.c')
-rw-r--r-- | arch/x86/kernel/microcode_intel.c | 79 |
1 files changed, 49 insertions, 30 deletions
diff --git a/arch/x86/kernel/microcode_intel.c b/arch/x86/kernel/microcode_intel.c index 48ed3cef58c1..622dc4a21784 100644 --- a/arch/x86/kernel/microcode_intel.c +++ b/arch/x86/kernel/microcode_intel.c | |||
@@ -97,6 +97,38 @@ MODULE_DESCRIPTION("Microcode Update Driver"); | |||
97 | MODULE_AUTHOR("Tigran Aivazian <tigran@aivazian.fsnet.co.uk>"); | 97 | MODULE_AUTHOR("Tigran Aivazian <tigran@aivazian.fsnet.co.uk>"); |
98 | MODULE_LICENSE("GPL"); | 98 | MODULE_LICENSE("GPL"); |
99 | 99 | ||
100 | struct microcode_header_intel { | ||
101 | unsigned int hdrver; | ||
102 | unsigned int rev; | ||
103 | unsigned int date; | ||
104 | unsigned int sig; | ||
105 | unsigned int cksum; | ||
106 | unsigned int ldrver; | ||
107 | unsigned int pf; | ||
108 | unsigned int datasize; | ||
109 | unsigned int totalsize; | ||
110 | unsigned int reserved[3]; | ||
111 | }; | ||
112 | |||
113 | struct microcode_intel { | ||
114 | struct microcode_header_intel hdr; | ||
115 | unsigned int bits[0]; | ||
116 | }; | ||
117 | |||
118 | /* microcode format is extended from prescott processors */ | ||
119 | struct extended_signature { | ||
120 | unsigned int sig; | ||
121 | unsigned int pf; | ||
122 | unsigned int cksum; | ||
123 | }; | ||
124 | |||
125 | struct extended_sigtable { | ||
126 | unsigned int count; | ||
127 | unsigned int cksum; | ||
128 | unsigned int reserved[3]; | ||
129 | struct extended_signature sigs[0]; | ||
130 | }; | ||
131 | |||
100 | #define DEFAULT_UCODE_DATASIZE (2000) | 132 | #define DEFAULT_UCODE_DATASIZE (2000) |
101 | #define MC_HEADER_SIZE (sizeof(struct microcode_header_intel)) | 133 | #define MC_HEADER_SIZE (sizeof(struct microcode_header_intel)) |
102 | #define DEFAULT_UCODE_TOTALSIZE (DEFAULT_UCODE_DATASIZE + MC_HEADER_SIZE) | 134 | #define DEFAULT_UCODE_TOTALSIZE (DEFAULT_UCODE_DATASIZE + MC_HEADER_SIZE) |
@@ -284,11 +316,12 @@ static void apply_microcode(int cpu) | |||
284 | unsigned int val[2]; | 316 | unsigned int val[2]; |
285 | int cpu_num = raw_smp_processor_id(); | 317 | int cpu_num = raw_smp_processor_id(); |
286 | struct ucode_cpu_info *uci = ucode_cpu_info + cpu; | 318 | struct ucode_cpu_info *uci = ucode_cpu_info + cpu; |
319 | struct microcode_intel *mc_intel = uci->mc; | ||
287 | 320 | ||
288 | /* We should bind the task to the CPU */ | 321 | /* We should bind the task to the CPU */ |
289 | BUG_ON(cpu_num != cpu); | 322 | BUG_ON(cpu_num != cpu); |
290 | 323 | ||
291 | if (uci->mc.mc_intel == NULL) | 324 | if (mc_intel == NULL) |
292 | return; | 325 | return; |
293 | 326 | ||
294 | /* serialize access to the physical write to MSR 0x79 */ | 327 | /* serialize access to the physical write to MSR 0x79 */ |
@@ -296,8 +329,8 @@ static void apply_microcode(int cpu) | |||
296 | 329 | ||
297 | /* write microcode via MSR 0x79 */ | 330 | /* write microcode via MSR 0x79 */ |
298 | wrmsr(MSR_IA32_UCODE_WRITE, | 331 | wrmsr(MSR_IA32_UCODE_WRITE, |
299 | (unsigned long) uci->mc.mc_intel->bits, | 332 | (unsigned long) mc_intel->bits, |
300 | (unsigned long) uci->mc.mc_intel->bits >> 16 >> 16); | 333 | (unsigned long) mc_intel->bits >> 16 >> 16); |
301 | wrmsr(MSR_IA32_UCODE_REV, 0, 0); | 334 | wrmsr(MSR_IA32_UCODE_REV, 0, 0); |
302 | 335 | ||
303 | /* see notes above for revision 1.07. Apparent chip bug */ | 336 | /* see notes above for revision 1.07. Apparent chip bug */ |
@@ -307,7 +340,7 @@ static void apply_microcode(int cpu) | |||
307 | rdmsr(MSR_IA32_UCODE_REV, val[0], val[1]); | 340 | rdmsr(MSR_IA32_UCODE_REV, val[0], val[1]); |
308 | 341 | ||
309 | spin_unlock_irqrestore(µcode_update_lock, flags); | 342 | spin_unlock_irqrestore(µcode_update_lock, flags); |
310 | if (val[1] != uci->mc.mc_intel->hdr.rev) { | 343 | if (val[1] != mc_intel->hdr.rev) { |
311 | printk(KERN_ERR "microcode: CPU%d update from revision " | 344 | printk(KERN_ERR "microcode: CPU%d update from revision " |
312 | "0x%x to 0x%x failed\n", cpu_num, uci->cpu_sig.rev, val[1]); | 345 | "0x%x to 0x%x failed\n", cpu_num, uci->cpu_sig.rev, val[1]); |
313 | return; | 346 | return; |
@@ -315,9 +348,9 @@ static void apply_microcode(int cpu) | |||
315 | printk(KERN_INFO "microcode: CPU%d updated from revision " | 348 | printk(KERN_INFO "microcode: CPU%d updated from revision " |
316 | "0x%x to 0x%x, date = %04x-%02x-%02x \n", | 349 | "0x%x to 0x%x, date = %04x-%02x-%02x \n", |
317 | cpu_num, uci->cpu_sig.rev, val[1], | 350 | cpu_num, uci->cpu_sig.rev, val[1], |
318 | uci->mc.mc_intel->hdr.date & 0xffff, | 351 | mc_intel->hdr.date & 0xffff, |
319 | uci->mc.mc_intel->hdr.date >> 24, | 352 | mc_intel->hdr.date >> 24, |
320 | (uci->mc.mc_intel->hdr.date >> 16) & 0xff); | 353 | (mc_intel->hdr.date >> 16) & 0xff); |
321 | uci->cpu_sig.rev = val[1]; | 354 | uci->cpu_sig.rev = val[1]; |
322 | } | 355 | } |
323 | 356 | ||
@@ -367,12 +400,12 @@ static int generic_load_microcode(int cpu, void *data, size_t size, | |||
367 | 400 | ||
368 | if (new_mc) { | 401 | if (new_mc) { |
369 | if (!leftover) { | 402 | if (!leftover) { |
370 | if (uci->mc.mc_intel) | 403 | if (uci->mc) |
371 | vfree(uci->mc.mc_intel); | 404 | vfree(uci->mc); |
372 | uci->mc.mc_intel = (struct microcode_intel *)new_mc; | 405 | uci->mc = (struct microcode_intel *)new_mc; |
373 | pr_debug("microcode: CPU%d found a matching microcode update with" | 406 | pr_debug("microcode: CPU%d found a matching microcode update with" |
374 | " version 0x%x (current=0x%x)\n", | 407 | " version 0x%x (current=0x%x)\n", |
375 | cpu, uci->mc.mc_intel->hdr.rev, uci->cpu_sig.rev); | 408 | cpu, new_rev, uci->cpu_sig.rev); |
376 | } else | 409 | } else |
377 | vfree(new_mc); | 410 | vfree(new_mc); |
378 | } | 411 | } |
@@ -428,11 +461,11 @@ static void microcode_fini_cpu(int cpu) | |||
428 | { | 461 | { |
429 | struct ucode_cpu_info *uci = ucode_cpu_info + cpu; | 462 | struct ucode_cpu_info *uci = ucode_cpu_info + cpu; |
430 | 463 | ||
431 | vfree(uci->mc.mc_intel); | 464 | vfree(uci->mc); |
432 | uci->mc.mc_intel = NULL; | 465 | uci->mc = NULL; |
433 | } | 466 | } |
434 | 467 | ||
435 | static struct microcode_ops microcode_intel_ops = { | 468 | struct microcode_ops microcode_intel_ops = { |
436 | .request_microcode_user = request_microcode_user, | 469 | .request_microcode_user = request_microcode_user, |
437 | .request_microcode_fw = request_microcode_fw, | 470 | .request_microcode_fw = request_microcode_fw, |
438 | .collect_cpu_info = collect_cpu_info, | 471 | .collect_cpu_info = collect_cpu_info, |
@@ -440,22 +473,8 @@ static struct microcode_ops microcode_intel_ops = { | |||
440 | .microcode_fini_cpu = microcode_fini_cpu, | 473 | .microcode_fini_cpu = microcode_fini_cpu, |
441 | }; | 474 | }; |
442 | 475 | ||
443 | static int __init microcode_intel_module_init(void) | 476 | struct microcode_ops * __init init_intel_microcode(void) |
444 | { | ||
445 | struct cpuinfo_x86 *c = &cpu_data(0); | ||
446 | |||
447 | if (c->x86_vendor != X86_VENDOR_INTEL) { | ||
448 | printk(KERN_ERR "microcode: CPU platform is not Intel-capable\n"); | ||
449 | return -ENODEV; | ||
450 | } | ||
451 | |||
452 | return microcode_init(µcode_intel_ops, THIS_MODULE); | ||
453 | } | ||
454 | |||
455 | static void __exit microcode_intel_module_exit(void) | ||
456 | { | 477 | { |
457 | microcode_exit(); | 478 | return µcode_intel_ops; |
458 | } | 479 | } |
459 | 480 | ||
460 | module_init(microcode_intel_module_init) | ||
461 | module_exit(microcode_intel_module_exit) | ||