diff options
| author | Yinghai Lu <yinghai@kernel.org> | 2009-11-10 21:27:23 -0500 |
|---|---|---|
| committer | Ingo Molnar <mingo@elte.hu> | 2009-11-11 14:14:32 -0500 |
| commit | 196cf0d67acad70ebb2572da489d5cc7066cdd05 (patch) | |
| tree | ba475e8afc56aeb6392d146a7cb9bdae7ff65279 /arch/x86 | |
| parent | 0420101c075530c65ba00b6fe7291b126fbfc5d2 (diff) | |
x86: Make sure wakeup trampoline code is below 1MB
Instead of using bootmem, try find_e820_area()/reserve_early(),
and call acpi_reserve_memory() early, to allocate the wakeup
trampoline code area below 1M.
This is more reliable, and it also removes a dependency on
bootmem.
-v2: change function name to acpi_reserve_wakeup_memory(),
as suggested by Rafael.
Signed-off-by: Yinghai Lu <yinghai@kernel.org>
Acked-by: H. Peter Anvin <hpa@zytor.com>
Acked-by: Rafael J. Wysocki <rjw@sisk.pl>
Cc: pm list <linux-pm@lists.linux-foundation.org>
Cc: Len Brown <lenb@kernel.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
LKML-Reference: <4AFA210B.3020207@kernel.org>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86')
| -rw-r--r-- | arch/x86/include/asm/acpi.h | 2 | ||||
| -rw-r--r-- | arch/x86/kernel/acpi/sleep.c | 15 | ||||
| -rw-r--r-- | arch/x86/kernel/setup.c | 13 |
3 files changed, 17 insertions, 13 deletions
diff --git a/arch/x86/include/asm/acpi.h b/arch/x86/include/asm/acpi.h index e3d4a0daff5..60d2b2db0bc 100644 --- a/arch/x86/include/asm/acpi.h +++ b/arch/x86/include/asm/acpi.h | |||
| @@ -118,7 +118,7 @@ extern void acpi_restore_state_mem(void); | |||
| 118 | extern unsigned long acpi_wakeup_address; | 118 | extern unsigned long acpi_wakeup_address; |
| 119 | 119 | ||
| 120 | /* early initialization routine */ | 120 | /* early initialization routine */ |
| 121 | extern void acpi_reserve_bootmem(void); | 121 | extern void acpi_reserve_wakeup_memory(void); |
| 122 | 122 | ||
| 123 | /* | 123 | /* |
| 124 | * Check if the CPU can handle C2 and deeper | 124 | * Check if the CPU can handle C2 and deeper |
diff --git a/arch/x86/kernel/acpi/sleep.c b/arch/x86/kernel/acpi/sleep.c index ca93638ba43..4a411450dfa 100644 --- a/arch/x86/kernel/acpi/sleep.c +++ b/arch/x86/kernel/acpi/sleep.c | |||
| @@ -119,29 +119,32 @@ void acpi_restore_state_mem(void) | |||
| 119 | 119 | ||
| 120 | 120 | ||
| 121 | /** | 121 | /** |
| 122 | * acpi_reserve_bootmem - do _very_ early ACPI initialisation | 122 | * acpi_reserve_wakeup_memory - do _very_ early ACPI initialisation |
| 123 | * | 123 | * |
| 124 | * We allocate a page from the first 1MB of memory for the wakeup | 124 | * We allocate a page from the first 1MB of memory for the wakeup |
| 125 | * routine for when we come back from a sleep state. The | 125 | * routine for when we come back from a sleep state. The |
| 126 | * runtime allocator allows specification of <16MB pages, but not | 126 | * runtime allocator allows specification of <16MB pages, but not |
| 127 | * <1MB pages. | 127 | * <1MB pages. |
| 128 | */ | 128 | */ |
| 129 | void __init acpi_reserve_bootmem(void) | 129 | void __init acpi_reserve_wakeup_memory(void) |
| 130 | { | 130 | { |
| 131 | unsigned long mem; | ||
| 132 | |||
| 131 | if ((&wakeup_code_end - &wakeup_code_start) > WAKEUP_SIZE) { | 133 | if ((&wakeup_code_end - &wakeup_code_start) > WAKEUP_SIZE) { |
| 132 | printk(KERN_ERR | 134 | printk(KERN_ERR |
| 133 | "ACPI: Wakeup code way too big, S3 disabled.\n"); | 135 | "ACPI: Wakeup code way too big, S3 disabled.\n"); |
| 134 | return; | 136 | return; |
| 135 | } | 137 | } |
| 136 | 138 | ||
| 137 | acpi_realmode = (unsigned long)alloc_bootmem_low(WAKEUP_SIZE); | 139 | mem = find_e820_area(0, 1<<20, WAKEUP_SIZE, PAGE_SIZE); |
| 138 | 140 | ||
| 139 | if (!acpi_realmode) { | 141 | if (mem == -1L) { |
| 140 | printk(KERN_ERR "ACPI: Cannot allocate lowmem, S3 disabled.\n"); | 142 | printk(KERN_ERR "ACPI: Cannot allocate lowmem, S3 disabled.\n"); |
| 141 | return; | 143 | return; |
| 142 | } | 144 | } |
| 143 | 145 | acpi_realmode = (unsigned long) phys_to_virt(mem); | |
| 144 | acpi_wakeup_address = virt_to_phys((void *)acpi_realmode); | 146 | acpi_wakeup_address = mem; |
| 147 | reserve_early(mem, mem + WAKEUP_SIZE, "ACPI WAKEUP"); | ||
| 145 | } | 148 | } |
| 146 | 149 | ||
| 147 | 150 | ||
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index f8914198270..0a6e94ab833 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c | |||
| @@ -897,6 +897,13 @@ void __init setup_arch(char **cmdline_p) | |||
| 897 | 897 | ||
| 898 | reserve_brk(); | 898 | reserve_brk(); |
| 899 | 899 | ||
| 900 | #ifdef CONFIG_ACPI_SLEEP | ||
| 901 | /* | ||
| 902 | * Reserve low memory region for sleep support. | ||
| 903 | * even before init_memory_mapping | ||
| 904 | */ | ||
| 905 | acpi_reserve_wakeup_memory(); | ||
| 906 | #endif | ||
| 900 | init_gbpages(); | 907 | init_gbpages(); |
| 901 | 908 | ||
| 902 | /* max_pfn_mapped is updated here */ | 909 | /* max_pfn_mapped is updated here */ |
| @@ -948,12 +955,6 @@ void __init setup_arch(char **cmdline_p) | |||
| 948 | 955 | ||
| 949 | initmem_init(0, max_pfn, acpi, k8); | 956 | initmem_init(0, max_pfn, acpi, k8); |
| 950 | 957 | ||
| 951 | #ifdef CONFIG_ACPI_SLEEP | ||
| 952 | /* | ||
| 953 | * Reserve low memory region for sleep support. | ||
| 954 | */ | ||
| 955 | acpi_reserve_bootmem(); | ||
| 956 | #endif | ||
| 957 | /* | 958 | /* |
| 958 | * Find and reserve possible boot-time SMP configuration: | 959 | * Find and reserve possible boot-time SMP configuration: |
| 959 | */ | 960 | */ |
