diff options
author | Jeremy Fitzhardinge <jeremy@xensource.com> | 2006-06-25 05:46:50 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-06-25 10:00:55 -0700 |
commit | e75eac33b5c7f797e4b2ddcb39183cf268e26822 (patch) | |
tree | 3c87328055c5975ca9d69df56dcc4a1d9066352c /arch | |
parent | e6a1530d692d6a60cdf15dfbcfea07f5324d7b9f (diff) | |
download | linux-e75eac33b5c7f797e4b2ddcb39183cf268e26822.tar.gz linux-e75eac33b5c7f797e4b2ddcb39183cf268e26822.tar.bz2 linux-e75eac33b5c7f797e4b2ddcb39183cf268e26822.zip |
[PATCH] Clean up and refactor i386 sub-architecture setup
Clean up and refactor i386 sub-architecture setup.
This change moves all the code from the
asm-i386/mach-*/setup_arch_pre/post.h headers, into
arch/i386/mach-*/setup.c. mach-*/setup_arch_pre.h is renamed to
setup_arch.h, and contains only things which should be in header files. It
is purely code-motion; there should be no functional changes at all.
Several functions in arch/i386/kernel/setup.c needed to be made non-static
so that they're visible to the code in mach-*/setup.c. asm-i386/setup.h is
used to hold the prototypes for these functions.
Signed-off-by: Jeremy Fitzhardinge <jeremy@xensource.com>
Signed-off-by: Chris Wright <chrisw@sous-sol.org>
Cc: Zachary Amsden <zach@vmware.com>
Cc: Chris Wright <chrisw@sous-sol.org>
Cc: Christian Limpach <Christian.Limpach@cl.cam.ac.uk>
Cc: Martin Bligh <mbligh@google.com>
Cc: James Bottomley <James.Bottomley@steeleye.com>
Cc: Andrey Panin <pazke@donpac.ru>
Cc: Dave Hansen <haveblue@us.ibm.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/i386/kernel/setup.c | 19 | ||||
-rw-r--r-- | arch/i386/mach-default/setup.c | 43 | ||||
-rw-r--r-- | arch/i386/mach-visws/setup.c | 49 | ||||
-rw-r--r-- | arch/i386/mach-voyager/setup.c | 74 |
4 files changed, 171 insertions, 14 deletions
diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c index e6023970aa40..6c1639836e06 100644 --- a/arch/i386/kernel/setup.c +++ b/arch/i386/kernel/setup.c @@ -61,7 +61,7 @@ #include <asm/io_apic.h> #include <asm/ist.h> #include <asm/io.h> -#include "setup_arch_pre.h" +#include <setup_arch.h> #include <bios_ebda.h> /* Forward Declaration. */ @@ -411,8 +411,8 @@ static void __init limit_regions(unsigned long long size) } } -static void __init add_memory_region(unsigned long long start, - unsigned long long size, int type) +void __init add_memory_region(unsigned long long start, + unsigned long long size, int type) { int x; @@ -475,7 +475,7 @@ static struct change_member *change_point[2*E820MAX] __initdata; static struct e820entry *overlap_list[E820MAX] __initdata; static struct e820entry new_bios[E820MAX] __initdata; -static int __init sanitize_e820_map(struct e820entry * biosmap, char * pnr_map) +int __init sanitize_e820_map(struct e820entry * biosmap, char * pnr_map) { struct change_member *change_tmp; unsigned long current_type, last_type; @@ -644,7 +644,7 @@ static int __init sanitize_e820_map(struct e820entry * biosmap, char * pnr_map) * thinkpad 560x, for example, does not cooperate with the memory * detection code.) */ -static int __init copy_e820_map(struct e820entry * biosmap, int nr_map) +int __init copy_e820_map(struct e820entry * biosmap, int nr_map) { /* Only one memory region (or negative)? Ignore it */ if (nr_map < 2) @@ -702,12 +702,6 @@ static inline void copy_edd(void) } #endif -/* - * Do NOT EVER look at the BIOS memory size location. - * It does not work on many machines. - */ -#define LOWMEMSIZE() (0x9f000) - static void __init parse_cmdline_early (char ** cmdline_p) { char c = ' ', *to = command_line, *from = saved_command_line; @@ -1424,8 +1418,6 @@ static void __init register_memory(void) pci_mem_start, gapstart, gapsize); } -static char * __init machine_specific_memory_setup(void); - #ifdef CONFIG_MCA static void set_mca_bus(int x) { @@ -1708,7 +1700,6 @@ static __init int add_pcspkr(void) } device_initcall(add_pcspkr); -#include "setup_arch_post.h" /* * Local Variables: * mode:c diff --git a/arch/i386/mach-default/setup.c b/arch/i386/mach-default/setup.c index b4a7455c6993..004837c58793 100644 --- a/arch/i386/mach-default/setup.c +++ b/arch/i386/mach-default/setup.c @@ -8,6 +8,8 @@ #include <linux/interrupt.h> #include <asm/acpi.h> #include <asm/arch_hooks.h> +#include <asm/e820.h> +#include <asm/setup.h> #ifdef CONFIG_HOTPLUG_CPU #define DEFAULT_SEND_IPI (1) @@ -130,3 +132,44 @@ static int __init print_ipi_mode(void) } late_initcall(print_ipi_mode); + +/** + * machine_specific_memory_setup - Hook for machine specific memory setup. + * + * Description: + * This is included late in kernel/setup.c so that it can make + * use of all of the static functions. + **/ + +char * __init machine_specific_memory_setup(void) +{ + char *who; + + + who = "BIOS-e820"; + + /* + * Try to copy the BIOS-supplied E820-map. + * + * Otherwise fake a memory map; one section from 0k->640k, + * the next section from 1mb->appropriate_mem_k + */ + sanitize_e820_map(E820_MAP, &E820_MAP_NR); + if (copy_e820_map(E820_MAP, E820_MAP_NR) < 0) { + unsigned long mem_size; + + /* compare results from other methods and take the greater */ + if (ALT_MEM_K < EXT_MEM_K) { + mem_size = EXT_MEM_K; + who = "BIOS-88"; + } else { + mem_size = ALT_MEM_K; + who = "BIOS-e801"; + } + + e820.nr_map = 0; + add_memory_region(0, LOWMEMSIZE(), E820_RAM); + add_memory_region(HIGH_MEMORY, mem_size << 10, E820_RAM); + } + return who; +} diff --git a/arch/i386/mach-visws/setup.c b/arch/i386/mach-visws/setup.c index 07fac7e749c7..8a9e1a6f745d 100644 --- a/arch/i386/mach-visws/setup.c +++ b/arch/i386/mach-visws/setup.c @@ -10,6 +10,8 @@ #include <asm/fixmap.h> #include <asm/arch_hooks.h> #include <asm/io.h> +#include <asm/e820.h> +#include <asm/setup.h> #include "cobalt.h" #include "piix4.h" @@ -133,3 +135,50 @@ void __init time_init_hook(void) /* Wire cpu IDT entry to s/w handler (and Cobalt APIC to IDT) */ setup_irq(0, &irq0); } + +/* Hook for machine specific memory setup. */ + +#define MB (1024 * 1024) + +static unsigned long sgivwfb_mem_phys; +static unsigned long sgivwfb_mem_size; + +long long mem_size __initdata = 0; + +char * __init machine_specific_memory_setup(void) +{ + long long gfx_mem_size = 8 * MB; + + mem_size = ALT_MEM_K; + + if (!mem_size) { + printk(KERN_WARNING "Bootloader didn't set memory size, upgrade it !\n"); + mem_size = 128 * MB; + } + + /* + * this hardcodes the graphics memory to 8 MB + * it really should be sized dynamically (or at least + * set as a boot param) + */ + if (!sgivwfb_mem_size) { + printk(KERN_WARNING "Defaulting to 8 MB framebuffer size\n"); + sgivwfb_mem_size = 8 * MB; + } + + /* + * Trim to nearest MB + */ + sgivwfb_mem_size &= ~((1 << 20) - 1); + sgivwfb_mem_phys = mem_size - gfx_mem_size; + + add_memory_region(0, LOWMEMSIZE(), E820_RAM); + add_memory_region(HIGH_MEMORY, mem_size - sgivwfb_mem_size - HIGH_MEMORY, E820_RAM); + add_memory_region(sgivwfb_mem_phys, sgivwfb_mem_size, E820_RESERVED); + + return "PROM"; + + /* Remove gcc warnings */ + (void) sanitize_e820_map(NULL, NULL); + (void) copy_e820_map(NULL, 0); +} diff --git a/arch/i386/mach-voyager/setup.c b/arch/i386/mach-voyager/setup.c index 7d8a3acb9441..0e225054e222 100644 --- a/arch/i386/mach-voyager/setup.c +++ b/arch/i386/mach-voyager/setup.c @@ -7,6 +7,9 @@ #include <linux/interrupt.h> #include <asm/acpi.h> #include <asm/arch_hooks.h> +#include <asm/voyager.h> +#include <asm/e820.h> +#include <asm/setup.h> void __init pre_intr_init_hook(void) { @@ -45,3 +48,74 @@ void __init time_init_hook(void) { setup_irq(0, &irq0); } + +/* Hook for machine specific memory setup. */ + +char * __init machine_specific_memory_setup(void) +{ + char *who; + + who = "NOT VOYAGER"; + + if(voyager_level == 5) { + __u32 addr, length; + int i; + + who = "Voyager-SUS"; + + e820.nr_map = 0; + for(i=0; voyager_memory_detect(i, &addr, &length); i++) { + add_memory_region(addr, length, E820_RAM); + } + return who; + } else if(voyager_level == 4) { + __u32 tom; + __u16 catbase = inb(VOYAGER_SSPB_RELOCATION_PORT)<<8; + /* select the DINO config space */ + outb(VOYAGER_DINO, VOYAGER_CAT_CONFIG_PORT); + /* Read DINO top of memory register */ + tom = ((inb(catbase + 0x4) & 0xf0) << 16) + + ((inb(catbase + 0x5) & 0x7f) << 24); + + if(inb(catbase) != VOYAGER_DINO) { + printk(KERN_ERR "Voyager: Failed to get DINO for L4, setting tom to EXT_MEM_K\n"); + tom = (EXT_MEM_K)<<10; + } + who = "Voyager-TOM"; + add_memory_region(0, 0x9f000, E820_RAM); + /* map from 1M to top of memory */ + add_memory_region(1*1024*1024, tom - 1*1024*1024, E820_RAM); + /* FIXME: Should check the ASICs to see if I need to + * take out the 8M window. Just do it at the moment + * */ + add_memory_region(8*1024*1024, 8*1024*1024, E820_RESERVED); + return who; + } + + who = "BIOS-e820"; + + /* + * Try to copy the BIOS-supplied E820-map. + * + * Otherwise fake a memory map; one section from 0k->640k, + * the next section from 1mb->appropriate_mem_k + */ + sanitize_e820_map(E820_MAP, &E820_MAP_NR); + if (copy_e820_map(E820_MAP, E820_MAP_NR) < 0) { + unsigned long mem_size; + + /* compare results from other methods and take the greater */ + if (ALT_MEM_K < EXT_MEM_K) { + mem_size = EXT_MEM_K; + who = "BIOS-88"; + } else { + mem_size = ALT_MEM_K; + who = "BIOS-e801"; + } + + e820.nr_map = 0; + add_memory_region(0, LOWMEMSIZE(), E820_RAM); + add_memory_region(HIGH_MEMORY, mem_size << 10, E820_RAM); + } + return who; +} |