diff options
author | Ralf Baechle <ralf@linux-mips.org> | 1997-01-07 02:33:00 +0000 |
---|---|---|
committer | <ralf@linux-mips.org> | 1997-01-07 02:33:00 +0000 |
commit | beb116954b9b7f3bb56412b2494b562f02b864b1 (patch) | |
tree | 120e997879884e1b9d93b265221b939d2ef1ade1 /arch/i386/kernel/setup.c | |
parent | 908d4681a1dc3792ecafbe64265783a86c4cccb6 (diff) |
Import of Linux/MIPS 2.1.14
Diffstat (limited to 'arch/i386/kernel/setup.c')
-rw-r--r-- | arch/i386/kernel/setup.c | 308 |
1 files changed, 232 insertions, 76 deletions
diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c index 5cc4c5d7d..3dae50628 100644 --- a/arch/i386/kernel/setup.c +++ b/arch/i386/kernel/setup.c @@ -5,7 +5,7 @@ */ /* - * This file handles the architecture-dependent parts of process handling.. + * This file handles the architecture-dependent parts of initialization */ #include <linux/errno.h> @@ -16,30 +16,37 @@ #include <linux/unistd.h> #include <linux/ptrace.h> #include <linux/malloc.h> -#include <linux/ldt.h> #include <linux/user.h> #include <linux/a.out.h> #include <linux/tty.h> #include <linux/ioport.h> #include <linux/delay.h> - -#include <asm/segment.h> +#include <linux/config.h> +#ifdef CONFIG_APM +#include <linux/apm_bios.h> +#endif +#ifdef CONFIG_BLK_DEV_RAM +#include <linux/blk.h> +#endif +#include <asm/uaccess.h> #include <asm/system.h> +#include <asm/smp.h> /* * Tell us the machine setup.. */ -char hard_math = 0; /* set by boot/head.S */ -char x86 = 0; /* set by boot/head.S to 3 or 4 */ -char x86_model = 0; /* set by boot/head.S */ -char x86_mask = 0; /* set by boot/head.S */ -int x86_capability = 0; /* set by boot/head.S */ +char hard_math = 0; /* set by kernel/head.S */ +char x86 = 0; /* set by kernel/head.S to 3..6 */ +char x86_model = 0; /* set by kernel/head.S */ +char x86_mask = 0; /* set by kernel/head.S */ +int x86_capability = 0; /* set by kernel/head.S */ int fdiv_bug = 0; /* set if Pentium(TM) with FP bug */ +int have_cpuid = 0; /* set if CPUID instruction works */ -char x86_vendor_id[13] = "Unknown"; +char x86_vendor_id[13] = "unknown"; char ignore_irq13 = 0; /* set if exception 16 works */ -char wp_works_ok = 0; /* set if paging hardware honours WP */ +char wp_works_ok = -1; /* set if paging hardware honours WP */ char hlt_works_ok = 1; /* set if the "hlt" instruction works */ /* @@ -52,11 +59,20 @@ int EISA_bus = 0; */ struct drive_info_struct { char dummy[32]; } drive_info; struct screen_info screen_info; +#ifdef CONFIG_APM +struct apm_bios_info apm_bios_info; +#endif unsigned char aux_device_present; -extern int ramdisk_size; + +#ifdef CONFIG_BLK_DEV_RAM +extern int rd_doload; /* 1 = load ramdisk, 0 = don't load */ +extern int rd_prompt; /* 1 = prompt for ramdisk, 0 = don't prompt */ +extern int rd_image_start; /* starting block # of image */ +#endif + extern int root_mountflags; -extern int etext, edata, end; +extern int _etext, _edata, _end; extern char empty_zero_page[PAGE_SIZE]; @@ -65,16 +81,28 @@ extern char empty_zero_page[PAGE_SIZE]; */ #define PARAM empty_zero_page #define EXT_MEM_K (*(unsigned short *) (PARAM+2)) +#ifdef CONFIG_APM +#define APM_BIOS_INFO (*(struct apm_bios_info *) (PARAM+64)) +#endif #define DRIVE_INFO (*(struct drive_info_struct *) (PARAM+0x80)) #define SCREEN_INFO (*(struct screen_info *) (PARAM+0)) #define MOUNT_ROOT_RDONLY (*(unsigned short *) (PARAM+0x1F2)) -#define RAMDISK_SIZE (*(unsigned short *) (PARAM+0x1F8)) +#define RAMDISK_FLAGS (*(unsigned short *) (PARAM+0x1F8)) #define ORIG_ROOT_DEV (*(unsigned short *) (PARAM+0x1FC)) #define AUX_DEVICE_INFO (*(unsigned char *) (PARAM+0x1FF)) +#define LOADER_TYPE (*(unsigned char *) (PARAM+0x210)) +#define KERNEL_START (*(unsigned long *) (PARAM+0x214)) +#define INITRD_START (*(unsigned long *) (PARAM+0x218)) +#define INITRD_SIZE (*(unsigned long *) (PARAM+0x21c)) #define COMMAND_LINE ((char *) (PARAM+2048)) #define COMMAND_LINE_SIZE 256 +#define RAMDISK_IMAGE_START_MASK 0x07FF +#define RAMDISK_PROMPT_FLAG 0x8000 +#define RAMDISK_LOAD_FLAG 0x4000 + static char command_line[COMMAND_LINE_SIZE] = { 0, }; + char saved_command_line[COMMAND_LINE_SIZE]; void setup_arch(char **cmdline_p, unsigned long * memory_start_p, unsigned long * memory_end_p) @@ -82,35 +110,64 @@ void setup_arch(char **cmdline_p, unsigned long memory_start, memory_end; char c = ' ', *to = command_line, *from = COMMAND_LINE; int len = 0; + static unsigned char smptrap=0; + + if(smptrap==1) + { + return; + } + smptrap=1; - ROOT_DEV = ORIG_ROOT_DEV; + ROOT_DEV = to_kdev_t(ORIG_ROOT_DEV); drive_info = DRIVE_INFO; screen_info = SCREEN_INFO; +#ifdef CONFIG_APM + apm_bios_info = APM_BIOS_INFO; +#endif aux_device_present = AUX_DEVICE_INFO; memory_end = (1<<20) + (EXT_MEM_K<<10); memory_end &= PAGE_MASK; - ramdisk_size = RAMDISK_SIZE; +#ifdef CONFIG_BLK_DEV_RAM + rd_image_start = RAMDISK_FLAGS & RAMDISK_IMAGE_START_MASK; + rd_prompt = ((RAMDISK_FLAGS & RAMDISK_PROMPT_FLAG) != 0); + rd_doload = ((RAMDISK_FLAGS & RAMDISK_LOAD_FLAG) != 0); +#endif #ifdef CONFIG_MAX_16M if (memory_end > 16*1024*1024) memory_end = 16*1024*1024; #endif - if (MOUNT_ROOT_RDONLY) - root_mountflags |= MS_RDONLY; - memory_start = (unsigned long) &end; - init_task.mm->start_code = TASK_SIZE; - init_task.mm->end_code = TASK_SIZE + (unsigned long) &etext; - init_task.mm->end_data = TASK_SIZE + (unsigned long) &edata; - init_task.mm->brk = TASK_SIZE + (unsigned long) &end; + if (!MOUNT_ROOT_RDONLY) + root_mountflags &= ~MS_RDONLY; + memory_start = (unsigned long) &_end; + init_task.mm->start_code = PAGE_OFFSET; + init_task.mm->end_code = (unsigned long) &_etext; + init_task.mm->end_data = (unsigned long) &_edata; + init_task.mm->brk = (unsigned long) &_end; + + /* Save unparsed command line copy for /proc/cmdline */ + memcpy(saved_command_line, COMMAND_LINE, COMMAND_LINE_SIZE); + saved_command_line[COMMAND_LINE_SIZE-1] = '\0'; for (;;) { - if (c == ' ' && *(unsigned long *)from == *(unsigned long *)"mem=") { - memory_end = simple_strtoul(from+4, &from, 0); - if ( *from == 'K' || *from == 'k' ) { - memory_end = memory_end << 10; - from++; - } else if ( *from == 'M' || *from == 'm' ) { - memory_end = memory_end << 20; - from++; + /* + * "mem=nopentium" disables the 4MB page tables. + * "mem=XXX[kKmM]" overrides the BIOS-reported + * memory size + */ + if (c == ' ' && *(const unsigned long *)from == *(const unsigned long *)"mem=") { + if (to != command_line) to--; + if (!memcmp(from+4, "nopentium", 9)) { + from += 9+4; + x86_capability &= ~8; + } else { + memory_end = simple_strtoul(from+4, &from, 0); + if ( *from == 'K' || *from == 'k' ) { + memory_end = memory_end << 10; + from++; + } else if ( *from == 'M' || *from == 'm' ) { + memory_end = memory_end << 20; + from++; + } } } c = *(from++); @@ -122,60 +179,159 @@ void setup_arch(char **cmdline_p, } *to = '\0'; *cmdline_p = command_line; + memory_end += PAGE_OFFSET; *memory_start_p = memory_start; *memory_end_p = memory_end; + +#ifdef CONFIG_BLK_DEV_INITRD + if (LOADER_TYPE) { + initrd_start = INITRD_START ? INITRD_START + PAGE_OFFSET : 0; + initrd_end = initrd_start+INITRD_SIZE; + if (initrd_end > memory_end) { + printk("initrd extends beyond end of memory " + "(0x%08lx > 0x%08lx)\ndisabling initrd\n", + initrd_end,memory_end); + initrd_start = 0; + } + } +#endif + /* request io space for devices used on all i[345]86 PC'S */ request_region(0x00,0x20,"dma1"); request_region(0x40,0x20,"timer"); - request_region(0x70,0x10,"rtc"); request_region(0x80,0x20,"dma page reg"); request_region(0xc0,0x20,"dma2"); - request_region(0xf0,0x2,"npu"); - request_region(0xf8,0x8,"npu"); + request_region(0xf0,0x10,"npu"); +} + +static const char * i486model(unsigned int nr) +{ + static const char *model[] = { + "0","DX","SX","DX/2","4","SX/2","6","DX/2-WB","DX/4","DX/4-WB", + "10","11","12","13","Am5x86-WT","Am5x86-WB" + }; + if (nr < sizeof(model)/sizeof(char *)) + return model[nr]; + return NULL; +} + +static const char * i586model(unsigned int nr) +{ + static const char *model[] = { + "0", "Pentium 60/66","Pentium 75+","OverDrive PODP5V83" + }; + if (nr < sizeof(model)/sizeof(char *)) + return model[nr]; + return NULL; +} + +static const char * i686model(unsigned int nr) +{ + static const char *model[] = { + "PPro A-step", "Pentium Pro" + }; + if (nr < sizeof(model)/sizeof(char *)) + return model[nr]; + return NULL; +} + +static const char * getmodel(int x86, int model) +{ + const char *p = NULL; + static char nbuf[12]; + switch (x86) { + case 4: + p = i486model(model); + break; + case 5: + p = i586model(model); + break; + case 6: + p = i686model(model); + break; + } + if (p) + return p; + + sprintf(nbuf, "%d", model); + return nbuf; } int get_cpuinfo(char * buffer) { - char *model[2][9]={{"DX","SX","DX/2","4","SX/2","6", - "DX/2-WB","DX/4"}, - {"Pentium 60/66","Pentium 90/100","3", - "4","5","6","7","8"}}; - char mask[2]; - mask[0] = x86_mask+'@'; - mask[1] = '\0'; - return sprintf(buffer,"cpu\t\t: %c86\n" - "model\t\t: %s\n" - "mask\t\t: %s\n" - "vid\t\t: %s\n" - "fdiv_bug\t: %s\n" - "math\t\t: %s\n" - "hlt\t\t: %s\n" - "wp\t\t: %s\n" - "Integrated NPU\t: %s\n" - "Enhanced VM86\t: %s\n" - "IO Breakpoints\t: %s\n" - "4MB Pages\t: %s\n" - "TS Counters\t: %s\n" - "Pentium MSR\t: %s\n" - "Mach. Ch. Exep.\t: %s\n" - "CMPXCHGB8B\t: %s\n" - "BogoMips\t: %lu.%02lu\n", - x86+'0', - x86_model ? model[x86-4][x86_model-1] : "Unknown", - x86_mask ? mask : "Unknown", - x86_vendor_id, - fdiv_bug ? "yes" : "no", - hard_math ? "yes" : "no", - hlt_works_ok ? "yes" : "no", - wp_works_ok ? "yes" : "no", - x86_capability & 1 ? "yes" : "no", - x86_capability & 2 ? "yes" : "no", - x86_capability & 4 ? "yes" : "no", - x86_capability & 8 ? "yes" : "no", - x86_capability & 16 ? "yes" : "no", - x86_capability & 32 ? "yes" : "no", - x86_capability & 128 ? "yes" : "no", - x86_capability & 256 ? "yes" : "no", - loops_per_sec/500000, (loops_per_sec/5000) % 100 - ); + int i, len = 0; + static const char *x86_cap_flags[] = { + "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce", + "cx8", "apic", "10", "11", "mtrr", "pge", "mca", "cmov", + "16", "17", "18", "19", "20", "21", "22", "mmx", + "24", "25", "26", "27", "28", "29", "30", "31" + }; + +#ifdef __SMP__ + int n; + +#define CD(X) (cpu_data[n].X) +/* SMP has the wrong name for loops_per_sec */ +#define loops_per_sec udelay_val +#define CPUN n + + for ( n = 0 ; n < 32 ; n++ ) { + if ( cpu_present_map & (1<<n) ) { + if (len) buffer[len++] = '\n'; + +#else +#define CD(X) (X) +#define CPUN 0 +#endif + + len += sprintf(buffer+len,"processor\t: %d\n" + "cpu\t\t: %c86\n" + "model\t\t: %s\n" + "vendor_id\t: %s\n", + CPUN, + CD(x86)+'0', + CD(have_cpuid) ? + getmodel(CD(x86), CD(x86_model)) : + "unknown", + CD(x86_vendor_id)); + + if (CD(x86_mask)) + len += sprintf(buffer+len, + "stepping\t: %d\n", + CD(x86_mask)); + else + len += sprintf(buffer+len, + "stepping\t: unknown\n"); + + len += sprintf(buffer+len, + "fdiv_bug\t: %s\n" + "hlt_bug\t\t: %s\n" + "fpu\t\t: %s\n" + "fpu_exception\t: %s\n" + "cpuid\t\t: %s\n" + "wp\t\t: %s\n" + "flags\t\t:", + CD(fdiv_bug) ? "yes" : "no", + CD(hlt_works_ok) ? "no" : "yes", + CD(hard_math) ? "yes" : "no", + (CD(hard_math) && ignore_irq13) + ? "yes" : "no", + CD(have_cpuid) ? "yes" : "no", + CD(wp_works_ok) ? "yes" : "no"); + + for ( i = 0 ; i < 32 ; i++ ) { + if ( CD(x86_capability) & (1 << i) ) { + len += sprintf(buffer+len, " %s", + x86_cap_flags[i]); + } + } + len += sprintf(buffer+len, + "\nbogomips\t: %lu.%02lu\n", + CD(loops_per_sec+2500)/500000, + (CD(loops_per_sec+2500)/5000) % 100); +#ifdef __SMP__ + } + } +#endif + return len; } |