diff options
author | Yinghai Lu <Yinghai.Lu@Sun.COM> | 2008-01-30 07:33:32 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-01-30 07:33:32 -0500 |
commit | 093af8d7f0ba3c6be1485973508584ef081e9f93 (patch) | |
tree | 0a2db2401e09764e654efafbea60f6d5d6894dcd /arch/x86/kernel/cpu/common.c | |
parent | 11201e603d28a1cb7a4bb1d65f39e61629c97a28 (diff) |
x86_32: trim memory by updating e820
when MTRRs are not covering the whole e820 table, we need to trim the
RAM and need to update e820.
reuse some code on 64-bit as well.
here need to add early_get_cap and use it in early_cpu_detect, and move
mtrr_bp_init early.
The code successfully trimmed the memory map on Justin's system:
from:
[ 0.000000] BIOS-e820: 0000000100000000 - 000000022c000000 (usable)
to:
[ 0.000000] modified: 0000000100000000 - 0000000228000000 (usable)
[ 0.000000] modified: 0000000228000000 - 000000022c000000 (reserved)
According to Justin it makes quite a difference:
| When I boot the box without any trimming it acts like a 286 or 386,
| takes about 10 minutes to boot (using raptor disks).
Signed-off-by: Yinghai Lu <yinghai.lu@sun.com>
Tested-by: Justin Piszcz <jpiszcz@lucidpixels.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'arch/x86/kernel/cpu/common.c')
-rw-r--r-- | arch/x86/kernel/cpu/common.c | 30 |
1 files changed, 29 insertions, 1 deletions
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index 56cc341cc586..bba850b05d0e 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c | |||
@@ -278,6 +278,33 @@ void __init cpu_detect(struct cpuinfo_x86 *c) | |||
278 | c->x86_cache_alignment = ((misc >> 8) & 0xff) * 8; | 278 | c->x86_cache_alignment = ((misc >> 8) & 0xff) * 8; |
279 | } | 279 | } |
280 | } | 280 | } |
281 | static void __cpuinit early_get_cap(struct cpuinfo_x86 *c) | ||
282 | { | ||
283 | u32 tfms, xlvl; | ||
284 | int ebx; | ||
285 | |||
286 | memset(&c->x86_capability, 0, sizeof c->x86_capability); | ||
287 | if (have_cpuid_p()) { | ||
288 | /* Intel-defined flags: level 0x00000001 */ | ||
289 | if (c->cpuid_level >= 0x00000001) { | ||
290 | u32 capability, excap; | ||
291 | cpuid(0x00000001, &tfms, &ebx, &excap, &capability); | ||
292 | c->x86_capability[0] = capability; | ||
293 | c->x86_capability[4] = excap; | ||
294 | } | ||
295 | |||
296 | /* AMD-defined flags: level 0x80000001 */ | ||
297 | xlvl = cpuid_eax(0x80000000); | ||
298 | if ((xlvl & 0xffff0000) == 0x80000000) { | ||
299 | if (xlvl >= 0x80000001) { | ||
300 | c->x86_capability[1] = cpuid_edx(0x80000001); | ||
301 | c->x86_capability[6] = cpuid_ecx(0x80000001); | ||
302 | } | ||
303 | } | ||
304 | |||
305 | } | ||
306 | |||
307 | } | ||
281 | 308 | ||
282 | /* Do minimum CPU detection early. | 309 | /* Do minimum CPU detection early. |
283 | Fields really needed: vendor, cpuid_level, family, model, mask, cache alignment. | 310 | Fields really needed: vendor, cpuid_level, family, model, mask, cache alignment. |
@@ -306,6 +333,8 @@ static void __init early_cpu_detect(void) | |||
306 | early_init_intel(c); | 333 | early_init_intel(c); |
307 | break; | 334 | break; |
308 | } | 335 | } |
336 | |||
337 | early_get_cap(c); | ||
309 | } | 338 | } |
310 | 339 | ||
311 | static void __cpuinit generic_identify(struct cpuinfo_x86 * c) | 340 | static void __cpuinit generic_identify(struct cpuinfo_x86 * c) |
@@ -485,7 +514,6 @@ void __init identify_boot_cpu(void) | |||
485 | identify_cpu(&boot_cpu_data); | 514 | identify_cpu(&boot_cpu_data); |
486 | sysenter_setup(); | 515 | sysenter_setup(); |
487 | enable_sep_cpu(); | 516 | enable_sep_cpu(); |
488 | mtrr_bp_init(); | ||
489 | } | 517 | } |
490 | 518 | ||
491 | void __cpuinit identify_secondary_cpu(struct cpuinfo_x86 *c) | 519 | void __cpuinit identify_secondary_cpu(struct cpuinfo_x86 *c) |