aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/microcode_intel.c
diff options
context:
space:
mode:
authorDmitry Adamushko <dmitry.adamushko@gmail.com>2008-09-23 06:08:44 -0400
committerIngo Molnar <mingo@elte.hu>2008-09-23 06:21:42 -0400
commit18dbc9160507dc7df998e00cd1dcd7889557307b (patch)
tree81262b57db5de63267762083a54a37558d8555f0 /arch/x86/kernel/microcode_intel.c
parenta1c75cc5018f17ff6d80ce45a13435b1536f76db (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.c79
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");
97MODULE_AUTHOR("Tigran Aivazian <tigran@aivazian.fsnet.co.uk>"); 97MODULE_AUTHOR("Tigran Aivazian <tigran@aivazian.fsnet.co.uk>");
98MODULE_LICENSE("GPL"); 98MODULE_LICENSE("GPL");
99 99
100struct 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
113struct microcode_intel {
114 struct microcode_header_intel hdr;
115 unsigned int bits[0];
116};
117
118/* microcode format is extended from prescott processors */
119struct extended_signature {
120 unsigned int sig;
121 unsigned int pf;
122 unsigned int cksum;
123};
124
125struct 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(&microcode_update_lock, flags); 342 spin_unlock_irqrestore(&microcode_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
435static struct microcode_ops microcode_intel_ops = { 468struct 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
443static int __init microcode_intel_module_init(void) 476struct 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(&microcode_intel_ops, THIS_MODULE);
453}
454
455static void __exit microcode_intel_module_exit(void)
456{ 477{
457 microcode_exit(); 478 return &microcode_intel_ops;
458} 479}
459 480
460module_init(microcode_intel_module_init)
461module_exit(microcode_intel_module_exit)