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 e3d4a0daff57..60d2b2db0bc5 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 ca93638ba430..4a411450dfa0 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 f89141982702..0a6e94ab8339 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 | */ |