diff options
author | Peter Oruba <peter.oruba@amd.com> | 2008-07-28 12:44:21 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-07-28 13:57:57 -0400 |
commit | 8d86f390d9bb5b39f0a315838d1616de6363e1b9 (patch) | |
tree | f3857d76d029b87571ac5cb4e3c1bd9965c859f8 /arch/x86/kernel/microcode_intel.c | |
parent | 26bf7a48c33906cc3415a4492aa9ead7a75f1353 (diff) |
x86: major refactoring
Refactored code by introducing a two-module solution.
There is one general module in which vendor specific modules can hook into.
However, that is exclusive, there is only one vendor specific module
allowed at a time. A CPU vendor check makes sure only the correct
module for the underlying system gets called.
Functinally in terms of patch loading itself there are no changes. This
refactoring provides a basis for future implementations of other vendors'
patch loaders.
Signed-off-by: Peter Oruba <peter.oruba@amd.com>
Cc: Tigran Aivazian <tigran@aivazian.fsnet.co.uk>
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 | 50 |
1 files changed, 40 insertions, 10 deletions
diff --git a/arch/x86/kernel/microcode_intel.c b/arch/x86/kernel/microcode_intel.c index ca9861bf067e..831db5363dba 100644 --- a/arch/x86/kernel/microcode_intel.c +++ b/arch/x86/kernel/microcode_intel.c | |||
@@ -127,7 +127,7 @@ extern struct mutex microcode_mutex; | |||
127 | 127 | ||
128 | extern struct ucode_cpu_info ucode_cpu_info[NR_CPUS]; | 128 | extern struct ucode_cpu_info ucode_cpu_info[NR_CPUS]; |
129 | 129 | ||
130 | void collect_cpu_info(int cpu_num) | 130 | static void collect_cpu_info(int cpu_num) |
131 | { | 131 | { |
132 | struct cpuinfo_x86 *c = &cpu_data(cpu_num); | 132 | struct cpuinfo_x86 *c = &cpu_data(cpu_num); |
133 | struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num; | 133 | struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num; |
@@ -175,7 +175,7 @@ static inline int microcode_update_match(int cpu_num, | |||
175 | return 1; | 175 | return 1; |
176 | } | 176 | } |
177 | 177 | ||
178 | int microcode_sanity_check(void *mc) | 178 | static int microcode_sanity_check(void *mc) |
179 | { | 179 | { |
180 | struct microcode_header_intel *mc_header = mc; | 180 | struct microcode_header_intel *mc_header = mc; |
181 | struct extended_sigtable *ext_header = NULL; | 181 | struct extended_sigtable *ext_header = NULL; |
@@ -259,7 +259,7 @@ int microcode_sanity_check(void *mc) | |||
259 | * return 1 - found update | 259 | * return 1 - found update |
260 | * return < 0 - error | 260 | * return < 0 - error |
261 | */ | 261 | */ |
262 | int get_matching_microcode(void *mc, int cpu) | 262 | static int get_matching_microcode(void *mc, int cpu) |
263 | { | 263 | { |
264 | struct ucode_cpu_info *uci = ucode_cpu_info + cpu; | 264 | struct ucode_cpu_info *uci = ucode_cpu_info + cpu; |
265 | struct microcode_header_intel *mc_header = mc; | 265 | struct microcode_header_intel *mc_header = mc; |
@@ -288,7 +288,8 @@ int get_matching_microcode(void *mc, int cpu) | |||
288 | return 0; | 288 | return 0; |
289 | find: | 289 | find: |
290 | pr_debug("microcode: CPU%d found a matching microcode update with" | 290 | pr_debug("microcode: CPU%d found a matching microcode update with" |
291 | " version 0x%x (current=0x%x)\n", cpu, mc_header->rev, uci->rev); | 291 | " version 0x%x (current=0x%x)\n", |
292 | cpu, mc_header->rev, uci->rev); | ||
292 | new_mc = vmalloc(total_size); | 293 | new_mc = vmalloc(total_size); |
293 | if (!new_mc) { | 294 | if (!new_mc) { |
294 | printk(KERN_ERR "microcode: error! Can not allocate memory\n"); | 295 | printk(KERN_ERR "microcode: error! Can not allocate memory\n"); |
@@ -303,7 +304,7 @@ find: | |||
303 | return 1; | 304 | return 1; |
304 | } | 305 | } |
305 | 306 | ||
306 | void apply_microcode(int cpu) | 307 | static void apply_microcode(int cpu) |
307 | { | 308 | { |
308 | unsigned long flags; | 309 | unsigned long flags; |
309 | unsigned int val[2]; | 310 | unsigned int val[2]; |
@@ -347,7 +348,7 @@ void apply_microcode(int cpu) | |||
347 | extern void __user *user_buffer; /* user area microcode data buffer */ | 348 | extern void __user *user_buffer; /* user area microcode data buffer */ |
348 | extern unsigned int user_buffer_size; /* it's size */ | 349 | extern unsigned int user_buffer_size; /* it's size */ |
349 | 350 | ||
350 | long get_next_ucode(void **mc, long offset) | 351 | static long get_next_ucode(void **mc, long offset) |
351 | { | 352 | { |
352 | struct microcode_header_intel mc_header; | 353 | struct microcode_header_intel mc_header; |
353 | unsigned long total_size; | 354 | unsigned long total_size; |
@@ -406,7 +407,7 @@ static long get_next_ucode_from_buffer(void **mc, const u8 *buf, | |||
406 | /* fake device for request_firmware */ | 407 | /* fake device for request_firmware */ |
407 | extern struct platform_device *microcode_pdev; | 408 | extern struct platform_device *microcode_pdev; |
408 | 409 | ||
409 | int cpu_request_microcode(int cpu) | 410 | static int cpu_request_microcode(int cpu) |
410 | { | 411 | { |
411 | char name[30]; | 412 | char name[30]; |
412 | struct cpuinfo_x86 *c = &cpu_data(cpu); | 413 | struct cpuinfo_x86 *c = &cpu_data(cpu); |
@@ -455,7 +456,7 @@ int cpu_request_microcode(int cpu) | |||
455 | return error; | 456 | return error; |
456 | } | 457 | } |
457 | 458 | ||
458 | int apply_microcode_check_cpu(int cpu) | 459 | static int apply_microcode_check_cpu(int cpu) |
459 | { | 460 | { |
460 | struct cpuinfo_x86 *c = &cpu_data(cpu); | 461 | struct cpuinfo_x86 *c = &cpu_data(cpu); |
461 | struct ucode_cpu_info *uci = ucode_cpu_info + cpu; | 462 | struct ucode_cpu_info *uci = ucode_cpu_info + cpu; |
@@ -504,13 +505,42 @@ int apply_microcode_check_cpu(int cpu) | |||
504 | return err; | 505 | return err; |
505 | } | 506 | } |
506 | 507 | ||
507 | void microcode_fini_cpu(int cpu) | 508 | static void microcode_fini_cpu(int cpu) |
508 | { | 509 | { |
509 | struct ucode_cpu_info *uci = ucode_cpu_info + cpu; | 510 | struct ucode_cpu_info *uci = ucode_cpu_info + cpu; |
510 | 511 | ||
511 | mutex_lock(µcode_mutex); | 512 | mutex_lock(µcode_mutex); |
512 | uci->valid = 0; | 513 | uci->valid = 0; |
513 | kfree(uci->mc.mc_intel); | 514 | vfree(uci->mc.mc_intel); |
514 | uci->mc.mc_intel = NULL; | 515 | uci->mc.mc_intel = NULL; |
515 | mutex_unlock(µcode_mutex); | 516 | mutex_unlock(µcode_mutex); |
516 | } | 517 | } |
518 | |||
519 | static struct microcode_ops microcode_intel_ops = { | ||
520 | .get_next_ucode = get_next_ucode, | ||
521 | .get_matching_microcode = get_matching_microcode, | ||
522 | .microcode_sanity_check = microcode_sanity_check, | ||
523 | .apply_microcode_check_cpu = apply_microcode_check_cpu, | ||
524 | .cpu_request_microcode = cpu_request_microcode, | ||
525 | .collect_cpu_info = collect_cpu_info, | ||
526 | .apply_microcode = apply_microcode, | ||
527 | .microcode_fini_cpu = microcode_fini_cpu, | ||
528 | }; | ||
529 | |||
530 | static int __init microcode_intel_module_init(void) | ||
531 | { | ||
532 | struct cpuinfo_x86 *c = &cpu_data(get_cpu()); | ||
533 | |||
534 | if (c->x86_vendor == X86_VENDOR_INTEL) | ||
535 | return microcode_init(µcode_intel_ops, THIS_MODULE); | ||
536 | else | ||
537 | return -ENODEV; | ||
538 | } | ||
539 | |||
540 | static void __exit microcode_intel_module_exit(void) | ||
541 | { | ||
542 | microcode_exit(); | ||
543 | } | ||
544 | |||
545 | module_init(microcode_intel_module_init) | ||
546 | module_exit(microcode_intel_module_exit) | ||