diff options
Diffstat (limited to 'arch/arm/kernel/setup.c')
-rw-r--r-- | arch/arm/kernel/setup.c | 363 |
1 files changed, 205 insertions, 158 deletions
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index 8258bd767..b09b3798b 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c @@ -10,36 +10,27 @@ */ #include <linux/config.h> -#include <linux/errno.h> -#include <linux/sched.h> #include <linux/kernel.h> #include <linux/mm.h> #include <linux/stddef.h> -#include <linux/unistd.h> -#include <linux/ptrace.h> -#include <linux/malloc.h> -#include <linux/user.h> -#include <linux/a.out.h> #include <linux/tty.h> #include <linux/ioport.h> #include <linux/delay.h> -#include <linux/major.h> #include <linux/utsname.h> #include <linux/blk.h> -#include <linux/init.h> #include <linux/console.h> +#include <linux/init.h> #include <asm/elf.h> #include <asm/hardware.h> #include <asm/io.h> -#include <asm/pgtable.h> #include <asm/procinfo.h> -#include <asm/segment.h> #include <asm/setup.h> #include <asm/system.h> +#ifndef MEM_SIZE #define MEM_SIZE (16*1024*1024) -#define COMMAND_LINE_SIZE 256 +#endif #ifndef CONFIG_CMDLINE #define CONFIG_CMDLINE "" @@ -50,7 +41,6 @@ #endif extern void reboot_setup(char *str, int *ints); -extern void fpe_init(void); extern void disable_hlt(void); struct drive_info_struct { char dummy[32]; } drive_info; @@ -64,10 +54,9 @@ struct screen_info screen_info = { }; extern int root_mountflags; -extern int _etext, _edata, _end; +extern int _text, _etext, _edata, _end; unsigned char aux_device_present; - char elf_platform[ELF_PLATFORM_SIZE]; unsigned int elf_hwcap; @@ -76,13 +65,16 @@ unsigned int elf_hwcap; */ unsigned int processor_id; unsigned int __machine_arch_type; +unsigned int vram_size; +unsigned int system_rev; +unsigned int system_serial_low; +unsigned int system_serial_high; #ifdef MULTI_CPU struct processor processor; #endif #ifdef CONFIG_ARCH_ACORN -int memc_ctrl_reg; -int number_mfm_drives; -unsigned int vram_size; +unsigned int memc_ctrl_reg; +unsigned int number_mfm_drives; #endif static struct proc_info_item proc_info; @@ -95,39 +87,41 @@ static union { char c[4]; unsigned long l; } endian_test __initdata = { { 'l', ' * symbol to be empty if not configured. */ -/* - * initial ram disk - */ -#ifdef CONFIG_BLK_DEV_INITRD -static void __init -check_initrd(unsigned long mem_start, unsigned long mem_end) +static void __init setup_processor(void) { - if (initrd_end > mem_end) { - printk ("initrd extends beyond end of memory " - "(0x%08lx > 0x%08lx) - disabling initrd\n", - initrd_end, mem_end); - initrd_start = 0; - } -} + extern struct proc_info_list __proc_info_begin, __proc_info_end; + struct proc_info_list *list; -#else -#define check_initrd(ms,me) -#endif + /* + * locate processor in the list of supported processor + * types. The linker builds this table for us from the + * entries in arch/arm/mm/proc-*.S + */ + for (list = &__proc_info_begin; list < &__proc_info_end ; list++) + if ((processor_id & list->cpu_mask) == list->cpu_val) + break; -void __init -setup_processor(void) -{ - armidindex = 0; + /* + * If processor type is unrecognised, then we + * can do nothing... + */ + if (list >= &__proc_info_end) { + printk("CPU configuration botched (ID %08x), unable " + "to continue.\n", processor_id); + while (1); + } - while ((armidlist[armidindex].id ^ processor_id) & - armidlist[armidindex].mask) - armidindex += 1; + proc_info = *list->info; - if (armidlist[armidindex].id == 0) - while (1); +#ifdef MULTI_CPU + processor = *list->proc; +#endif - processor = *armidlist[armidindex].proc; - processor._proc_init(); + sprintf(system_utsname.machine, "%s%c", list->arch_name, ENDIANNESS); + sprintf(elf_platform, "%s%c", list->elf_name, ENDIANNESS); + elf_hwcap = list->elf_hwcap; + + cpu_proc_init(); } static char default_command_line[COMMAND_LINE_SIZE] __initdata = CONFIG_CMDLINE; @@ -135,12 +129,13 @@ static char command_line[COMMAND_LINE_SIZE] = { 0, }; char saved_command_line[COMMAND_LINE_SIZE]; static void __init -setup_mem(char *cmd_line, unsigned long *mem_start, unsigned long *mem_sz) +setup_mem(char *cmd_line, unsigned long *mem_sz) { char c = ' ', *to = command_line; int len = 0; - *mem_start = (unsigned long)&_end; + if (!*mem_sz) + *mem_sz = MEM_SIZE; for (;;) { if (c == ' ') { @@ -181,24 +176,27 @@ setup_mem(char *cmd_line, unsigned long *mem_start, unsigned long *mem_sz) } static void __init -setup_ram(int doload, int prompt, int image_start) +setup_ramdisk(int doload, int prompt, int image_start, unsigned int rd_sz) { #ifdef CONFIG_BLK_DEV_RAM extern int rd_doload; extern int rd_prompt; extern int rd_image_start; + extern int rd_size; rd_image_start = image_start; rd_prompt = prompt; rd_doload = doload; + + if (rd_sz) + rd_size = rd_sz; #endif } /* * initial ram disk */ -static void __init -setup_initrd(unsigned int start, unsigned int size) +static void __init setup_initrd(unsigned int start, unsigned int size) { #ifdef CONFIG_BLK_DEV_INITRD if (start) { @@ -211,30 +209,62 @@ setup_initrd(unsigned int start, unsigned int size) #endif } -#ifdef CONFIG_ARCH_ACORN -int memc_ctrl_reg; -int number_mfm_drives; -unsigned int vram_size; +static void __init check_initrd(unsigned long mem_end) +{ +#ifdef CONFIG_BLK_DEV_INITRD + if (initrd_end > mem_end) { + printk ("initrd extends beyond end of memory " + "(0x%08lx > 0x%08lx) - disabling initrd\n", + initrd_end, mem_end); + initrd_start = 0; + } #endif +} -#ifndef PARAMS_BASE -#define PARAMS_BASE NULL -#endif +/* + * Standard memory resources + */ +static struct resource system_ram = { "System RAM", 0, 0, IORESOURCE_MEM | IORESOURCE_BUSY }; +static struct resource video_ram = { "Video RAM", 0, 0, IORESOURCE_MEM }; +static struct resource kernel_code = { "Kernel code", 0, 0, IORESOURCE_MEM }; +static struct resource kernel_data = { "Kernel data", 0, 0, IORESOURCE_MEM }; +static struct resource lpt1 = { "reserved", 0x3bc, 0x3be, IORESOURCE_IO | IORESOURCE_BUSY }; +static struct resource lpt2 = { "reserved", 0x378, 0x37f, IORESOURCE_IO | IORESOURCE_BUSY }; +static struct resource lpt3 = { "reserved", 0x278, 0x27f, IORESOURCE_IO | IORESOURCE_BUSY }; + +static void __init request_standard_resources(unsigned long end) +{ + kernel_code.start = __virt_to_bus((unsigned long) &_text); + kernel_code.end = __virt_to_bus((unsigned long) &_etext - 1); + kernel_data.start = __virt_to_bus((unsigned long) &_etext); + kernel_data.end = __virt_to_bus((unsigned long) &_edata - 1); + system_ram.start = __virt_to_bus(PAGE_OFFSET); + system_ram.end = __virt_to_bus(end - 1); + + request_resource(&iomem_resource, &system_ram); + request_resource(&system_ram, &kernel_code); + request_resource(&system_ram, &kernel_data); + if (video_ram.start != video_ram.end) + request_resource(&iomem_resource, &video_ram); -static union { char c[4]; unsigned long l; } endian_test __initdata = { { 'l', '?', '?', 'b' } }; -#define ENDIANNESS ((char)endian_test.l) + /* + * Some machines don't have the possibility of ever + * possessing LPT1 (lp0) and LPT3 (lp2) + */ + if (machine_is_ebsa110() || machine_is_riscpc() || + machine_is_netwinder()) + request_resource(&ioport_resource, &lpt1); + if (machine_is_riscpc()) + request_resource(&ioport_resource, &lpt2); + if (machine_is_ebsa110() || machine_is_netwinder()) + request_resource(&ioport_resource, &lpt3); +} -void __init -setup_arch(char **cmdline_p, unsigned long * memory_start_p, unsigned long * memory_end_p) +void __init setup_arch(char **cmdline_p, unsigned long * memory_start_p, unsigned long * memory_end_p) { struct param_struct *params = (struct param_struct *)PARAMS_BASE; - static unsigned char smptrap; unsigned long memory_end = 0; - char *from = NULL; - - if (smptrap == 1) - return; - smptrap = 1; + char *from = default_command_line; #if defined(CONFIG_ARCH_ARC) __machine_arch_type = MACH_TYPE_ARCHIMEDES; @@ -244,10 +274,11 @@ setup_arch(char **cmdline_p, unsigned long * memory_start_p, unsigned long * mem setup_processor(); - init_mm.start_code = TASK_SIZE; - init_mm.end_code = TASK_SIZE + (unsigned long) &_etext; - init_mm.end_data = TASK_SIZE + (unsigned long) &_edata; - init_mm.brk = TASK_SIZE + (unsigned long) &_end; + /* + * Defaults + */ + ROOT_DEV = MKDEV(0, 255); + setup_ramdisk(1, 1, 0, 0); /* * Add your machine dependencies here @@ -256,14 +287,35 @@ setup_arch(char **cmdline_p, unsigned long * memory_start_p, unsigned long * mem case MACH_TYPE_EBSA110: /* EBSA110 locks if we execute 'wait for interrupt' */ disable_hlt(); - if (params && params->u1.s.page_size != 4096) + if (params && params->u1.s.page_size != PAGE_SIZE) params = NULL; break; +#ifdef CONFIG_ARCH_ACORN +#ifdef CONFIG_ARCH_RPC case MACH_TYPE_RISCPC: /* RiscPC can't handle half-word loads and stores */ elf_hwcap &= ~HWCAP_HALF; + { + extern void init_dram_banks(struct param_struct *); + init_dram_banks(params); + } + + switch (params->u1.s.pages_in_vram) { + case 512: + vram_size += PAGE_SIZE * 256; + case 256: + vram_size += PAGE_SIZE * 256; + default: + break; + } +#endif + case MACH_TYPE_ARCHIMEDES: + case MACH_TYPE_A5K: + memc_ctrl_reg = params->u1.s.memc_control_reg; + number_mfm_drives = (params->u1.s.adfsdrives >> 3) & 3; break; +#endif case MACH_TYPE_EBSA285: if (params) { @@ -271,6 +323,8 @@ setup_arch(char **cmdline_p, unsigned long * memory_start_p, unsigned long * mem ORIG_Y = params->u1.s.video_y; ORIG_VIDEO_COLS = params->u1.s.video_num_cols; ORIG_VIDEO_LINES = params->u1.s.video_num_rows; + video_ram.start = 0x0a0000; + video_ram.end = 0x0bffff; } break; @@ -288,53 +342,67 @@ setup_arch(char **cmdline_p, unsigned long * memory_start_p, unsigned long * mem break; case MACH_TYPE_CATS: - /* CATS must use soft-reboot */ + /* CATS uses soft-reboot by default, since hard reboots + * fail on early boards. + */ reboot_setup("s", NULL); + params = NULL; + ORIG_VIDEO_LINES = 25; + ORIG_VIDEO_POINTS = 16; + ORIG_Y = 24; + video_ram.start = 0x0a0000; + video_ram.end = 0x0bffff; break; case MACH_TYPE_NETWINDER: /* * to be fixed in a future NeTTrom */ - if (params->u1.s.page_size == 4096) { + if (params->u1.s.page_size == PAGE_SIZE) { if (params->u1.s.nr_pages != 0x2000 && params->u1.s.nr_pages != 0x4000) { printk("Warning: bad NeTTrom parameters detected, using defaults\n"); - /* - * This stuff doesn't appear to be initialised - * properly by NeTTrom 2.0.6 and 2.0.7 - */ + /* + * This stuff doesn't appear to be initialised + * properly by NeTTrom 2.0.6 and 2.0.7 + */ params->u1.s.nr_pages = 0x2000; /* 32MB */ params->u1.s.ramdisk_size = 0; params->u1.s.flags = FLAG_READONLY; params->u1.s.initrd_start = 0; params->u1.s.initrd_size = 0; params->u1.s.rd_start = 0; - params->u1.s.video_x = 0; - params->u1.s.video_y = 0; - params->u1.s.video_num_cols = 80; - params->u1.s.video_num_rows = 30; } } else { printk("Warning: no NeTTrom parameter page detected, using " "compiled-in settings\n"); params = NULL; } + video_ram.start = 0x0a0000; + video_ram.end = 0x0bffff; break; default: break; } - if (params) { - memory_end = params->u1.s.page_size * - params->u1.s.nr_pages; + if (params && params->u1.s.page_size != PAGE_SIZE) { + printk("Warning: wrong page size configuration, " + "trying to continue\n"); + params = NULL; + } - ROOT_DEV = to_kdev_t(params->u1.s.rootdev); + if (params) { + memory_end = PAGE_SIZE * params->u1.s.nr_pages; + ROOT_DEV = to_kdev_t(params->u1.s.rootdev); + system_rev = params->u1.s.system_rev; + system_serial_low = params->u1.s.system_serial_low; + system_serial_high = params->u1.s.system_serial_high; - setup_ram((params->u1.s.flags & FLAG_RDLOAD) == 0, - (params->u1.s.flags & FLAG_RDPROMPT) == 0, - params->u1.s.rd_start); + setup_ramdisk((params->u1.s.flags & FLAG_RDLOAD) == 0, + (params->u1.s.flags & FLAG_RDPROMPT) == 0, + params->u1.s.rd_start, + params->u1.s.ramdisk_size); setup_initrd(params->u1.s.initrd_start, params->u1.s.initrd_size); @@ -342,57 +410,27 @@ setup_arch(char **cmdline_p, unsigned long * memory_start_p, unsigned long * mem if (!(params->u1.s.flags & FLAG_READONLY)) root_mountflags &= ~MS_RDONLY; -#ifdef CONFIG_ARCH_ACORN -#ifdef CONFIG_ARCH_RPC - { - extern void init_dram_banks(struct param_struct *); - init_dram_banks(params); - } -#endif - - memc_ctrl_reg = params->u1.s.memc_control_reg; - number_mfm_drives = (params->u1.s.adfsdrives >> 3) & 3; - vram_size = 0; - - switch (params->u1.s.pages_in_vram) { - case 512: - vram_size += PAGE_SIZE * 256; - case 256: - vram_size += PAGE_SIZE * 256; - default: - break; - } - - memory_end -= vram_size; -#endif - from = params->commandline; - } else { - ROOT_DEV = to_kdev_t(0x00ff); - - setup_ram(1, 1, 0); - setup_initrd(0, 0); } - if (!memory_end) - memory_end = MEM_SIZE; - - if (!from) - from = default_command_line; - -#ifdef CONFIG_NWFPE - fpe_init(); -#endif - /* Save unparsed command line copy for /proc/cmdline */ memcpy(saved_command_line, from, COMMAND_LINE_SIZE); saved_command_line[COMMAND_LINE_SIZE-1] = '\0'; - setup_mem(from, memory_start_p, &memory_end); + setup_mem(from, &memory_end); memory_end += PAGE_OFFSET; - check_initrd(*memory_start_p, memory_end); + *cmdline_p = command_line; + init_mm.start_code = (unsigned long) &_text; + init_mm.end_code = (unsigned long) &_etext; + init_mm.end_data = (unsigned long) &_edata; + init_mm.brk = (unsigned long) &_end; + *memory_start_p = (unsigned long) &_end; + *memory_end_p = memory_end; + + request_standard_resources(memory_end); + check_initrd(memory_end); #ifdef CONFIG_VT #if defined(CONFIG_VGA_CONSOLE) @@ -401,40 +439,49 @@ setup_arch(char **cmdline_p, unsigned long * memory_start_p, unsigned long * mem conswitchp = &dummy_con; #endif #endif - - *cmdline_p = command_line; - *memory_end_p = memory_end; } static const char *machine_desc[] = { - "EBSA110", - "Acorn-RiscPC", + /* Machine name Allocater */ + "EBSA110", /* RMK */ + "Acorn-RiscPC", /* RMK */ "unknown", - "Nexus-FTV/PCI", - "EBSA285", - "Rebel-NetWinder", - "Chalice-CATS", - "unknown-TBOX", - "co-EBSA285", - "CL-PS7110", - "Acorn-Archimedes", - "Acorn-A5000" + "Nexus-FTV/PCI", /* Philip Blundell */ + "EBSA285", /* RMK */ + "Rebel-NetWinder", /* RMK */ + "Chalice-CATS", /* Philip Blundell */ + "unknown-TBOX", /* Philip Blundell */ + "co-EBSA285", /* Mark van Doesburg */ + "CL-PS7110", /* Werner Almesberger */ + "Acorn-Archimedes", /* RMK/DAG */ + "Acorn-A5000", /* RMK/PB */ + "Etoile", /* Alex de Vries */ + "LaCie_NAS", /* Benjamin Herrenschmidt */ + "CL-PS7500", /* Philip Blundell */ + "Shark" /* Alexander Schulz */ }; int get_cpuinfo(char * buffer) { - int len; - - len = sprintf(buffer, - "Processor\t: %s %s rev %d (%s)\n" - "BogoMips\t: %lu.%02lu\n" - "Hardware\t: %s\n", - proc_info.manufacturer, - proc_info.cpu_name, - (int)processor_id & 15, - elf_platform, - (loops_per_sec+2500) / 500000, - ((loops_per_sec+2500) / 5000) % 100, - machine_desc[machine_arch_type]); - return len; + char *p = buffer; + + p += sprintf(p, "Processor\t: %s %s rev %d (%s)\n", + proc_info.manufacturer, proc_info.cpu_name, + (int)processor_id & 15, elf_platform); + + p += sprintf(p, "BogoMIPS\t: %lu.%02lu\n", + (loops_per_sec+2500) / 500000, + ((loops_per_sec+2500) / 5000) % 100); + + p += sprintf(p, "Hardware\t: %s\n", + machine_desc[machine_arch_type]); + + p += sprintf(p, "Revision\t: %04x\n", + system_rev); + + p += sprintf(p, "Serial\t\t: %08x%08x\n", + system_serial_high, + system_serial_low); + + return p - buffer; } |