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_amd.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_amd.c')
-rw-r--r-- | arch/x86/kernel/microcode_amd.c | 72 |
1 files changed, 43 insertions, 29 deletions
diff --git a/arch/x86/kernel/microcode_amd.c b/arch/x86/kernel/microcode_amd.c index 48aec9f48e4f..03ea4e52e87a 100644 --- a/arch/x86/kernel/microcode_amd.c +++ b/arch/x86/kernel/microcode_amd.c | |||
@@ -46,6 +46,35 @@ MODULE_LICENSE("GPL v2"); | |||
46 | #define UCODE_EQUIV_CPU_TABLE_TYPE 0x00000000 | 46 | #define UCODE_EQUIV_CPU_TABLE_TYPE 0x00000000 |
47 | #define UCODE_UCODE_TYPE 0x00000001 | 47 | #define UCODE_UCODE_TYPE 0x00000001 |
48 | 48 | ||
49 | struct equiv_cpu_entry { | ||
50 | unsigned int installed_cpu; | ||
51 | unsigned int fixed_errata_mask; | ||
52 | unsigned int fixed_errata_compare; | ||
53 | unsigned int equiv_cpu; | ||
54 | }; | ||
55 | |||
56 | struct microcode_header_amd { | ||
57 | unsigned int data_code; | ||
58 | unsigned int patch_id; | ||
59 | unsigned char mc_patch_data_id[2]; | ||
60 | unsigned char mc_patch_data_len; | ||
61 | unsigned char init_flag; | ||
62 | unsigned int mc_patch_data_checksum; | ||
63 | unsigned int nb_dev_id; | ||
64 | unsigned int sb_dev_id; | ||
65 | unsigned char processor_rev_id[2]; | ||
66 | unsigned char nb_rev_id; | ||
67 | unsigned char sb_rev_id; | ||
68 | unsigned char bios_api_rev; | ||
69 | unsigned char reserved1[3]; | ||
70 | unsigned int match_reg[8]; | ||
71 | }; | ||
72 | |||
73 | struct microcode_amd { | ||
74 | struct microcode_header_amd hdr; | ||
75 | unsigned int mpb[0]; | ||
76 | }; | ||
77 | |||
49 | #define UCODE_MAX_SIZE (2048) | 78 | #define UCODE_MAX_SIZE (2048) |
50 | #define DEFAULT_UCODE_DATASIZE (896) | 79 | #define DEFAULT_UCODE_DATASIZE (896) |
51 | #define MC_HEADER_SIZE (sizeof(struct microcode_header_amd)) | 80 | #define MC_HEADER_SIZE (sizeof(struct microcode_header_amd)) |
@@ -189,17 +218,18 @@ static void apply_microcode_amd(int cpu) | |||
189 | unsigned int rev; | 218 | unsigned int rev; |
190 | int cpu_num = raw_smp_processor_id(); | 219 | int cpu_num = raw_smp_processor_id(); |
191 | struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num; | 220 | struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num; |
221 | struct microcode_amd *mc_amd = uci->mc; | ||
192 | unsigned long addr; | 222 | unsigned long addr; |
193 | 223 | ||
194 | /* We should bind the task to the CPU */ | 224 | /* We should bind the task to the CPU */ |
195 | BUG_ON(cpu_num != cpu); | 225 | BUG_ON(cpu_num != cpu); |
196 | 226 | ||
197 | if (uci->mc.mc_amd == NULL) | 227 | if (mc_amd == NULL) |
198 | return; | 228 | return; |
199 | 229 | ||
200 | spin_lock_irqsave(µcode_update_lock, flags); | 230 | spin_lock_irqsave(µcode_update_lock, flags); |
201 | 231 | ||
202 | addr = (unsigned long)&uci->mc.mc_amd->hdr.data_code; | 232 | addr = (unsigned long)&mc_amd->hdr.data_code; |
203 | edx = (unsigned int)(((unsigned long)upper_32_bits(addr))); | 233 | edx = (unsigned int)(((unsigned long)upper_32_bits(addr))); |
204 | eax = (unsigned int)(((unsigned long)lower_32_bits(addr))); | 234 | eax = (unsigned int)(((unsigned long)lower_32_bits(addr))); |
205 | 235 | ||
@@ -214,16 +244,16 @@ static void apply_microcode_amd(int cpu) | |||
214 | spin_unlock_irqrestore(µcode_update_lock, flags); | 244 | spin_unlock_irqrestore(µcode_update_lock, flags); |
215 | 245 | ||
216 | /* check current patch id and patch's id for match */ | 246 | /* check current patch id and patch's id for match */ |
217 | if (rev != uci->mc.mc_amd->hdr.patch_id) { | 247 | if (rev != mc_amd->hdr.patch_id) { |
218 | printk(KERN_ERR "microcode: CPU%d update from revision " | 248 | printk(KERN_ERR "microcode: CPU%d update from revision " |
219 | "0x%x to 0x%x failed\n", cpu_num, | 249 | "0x%x to 0x%x failed\n", cpu_num, |
220 | uci->mc.mc_amd->hdr.patch_id, rev); | 250 | mc_amd->hdr.patch_id, rev); |
221 | return; | 251 | return; |
222 | } | 252 | } |
223 | 253 | ||
224 | printk(KERN_INFO "microcode: CPU%d updated from revision " | 254 | printk(KERN_INFO "microcode: CPU%d updated from revision " |
225 | "0x%x to 0x%x \n", | 255 | "0x%x to 0x%x \n", |
226 | cpu_num, uci->cpu_sig.rev, uci->mc.mc_amd->hdr.patch_id); | 256 | cpu_num, uci->cpu_sig.rev, mc_amd->hdr.patch_id); |
227 | 257 | ||
228 | uci->cpu_sig.rev = rev; | 258 | uci->cpu_sig.rev = rev; |
229 | } | 259 | } |
@@ -355,12 +385,12 @@ static int generic_load_microcode(int cpu, void *data, size_t size, | |||
355 | 385 | ||
356 | if (new_mc) { | 386 | if (new_mc) { |
357 | if (!leftover) { | 387 | if (!leftover) { |
358 | if (uci->mc.mc_amd) | 388 | if (uci->mc) |
359 | vfree(uci->mc.mc_amd); | 389 | vfree(uci->mc); |
360 | uci->mc.mc_amd = (struct microcode_amd *)new_mc; | 390 | uci->mc = new_mc; |
361 | pr_debug("microcode: CPU%d found a matching microcode update with" | 391 | pr_debug("microcode: CPU%d found a matching microcode update with" |
362 | " version 0x%x (current=0x%x)\n", | 392 | " version 0x%x (current=0x%x)\n", |
363 | cpu, uci->mc.mc_amd->hdr.patch_id, uci->cpu_sig.rev); | 393 | cpu, new_rev, uci->cpu_sig.rev); |
364 | } else | 394 | } else |
365 | vfree(new_mc); | 395 | vfree(new_mc); |
366 | } | 396 | } |
@@ -416,8 +446,8 @@ static void microcode_fini_cpu_amd(int cpu) | |||
416 | { | 446 | { |
417 | struct ucode_cpu_info *uci = ucode_cpu_info + cpu; | 447 | struct ucode_cpu_info *uci = ucode_cpu_info + cpu; |
418 | 448 | ||
419 | vfree(uci->mc.mc_amd); | 449 | vfree(uci->mc); |
420 | uci->mc.mc_amd = NULL; | 450 | uci->mc = NULL; |
421 | } | 451 | } |
422 | 452 | ||
423 | static struct microcode_ops microcode_amd_ops = { | 453 | static struct microcode_ops microcode_amd_ops = { |
@@ -428,23 +458,7 @@ static struct microcode_ops microcode_amd_ops = { | |||
428 | .microcode_fini_cpu = microcode_fini_cpu_amd, | 458 | .microcode_fini_cpu = microcode_fini_cpu_amd, |
429 | }; | 459 | }; |
430 | 460 | ||
431 | static int __init microcode_amd_module_init(void) | 461 | struct microcode_ops * __init init_amd_microcode(void) |
432 | { | 462 | { |
433 | struct cpuinfo_x86 *c = &cpu_data(0); | 463 | return µcode_amd_ops; |
434 | |||
435 | equiv_cpu_table = NULL; | ||
436 | if (c->x86_vendor != X86_VENDOR_AMD) { | ||
437 | printk(KERN_ERR "microcode: CPU platform is not AMD-capable\n"); | ||
438 | return -ENODEV; | ||
439 | } | ||
440 | |||
441 | return microcode_init(µcode_amd_ops, THIS_MODULE); | ||
442 | } | ||
443 | |||
444 | static void __exit microcode_amd_module_exit(void) | ||
445 | { | ||
446 | microcode_exit(); | ||
447 | } | 464 | } |
448 | |||
449 | module_init(microcode_amd_module_init) | ||
450 | module_exit(microcode_amd_module_exit) | ||