summaryrefslogtreecommitdiffstats
path: root/arch/i386/kernel/setup.c
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>1997-01-07 02:33:00 +0000
committer <ralf@linux-mips.org>1997-01-07 02:33:00 +0000
commitbeb116954b9b7f3bb56412b2494b562f02b864b1 (patch)
tree120e997879884e1b9d93b265221b939d2ef1ade1 /arch/i386/kernel/setup.c
parent908d4681a1dc3792ecafbe64265783a86c4cccb6 (diff)
Import of Linux/MIPS 2.1.14
Diffstat (limited to 'arch/i386/kernel/setup.c')
-rw-r--r--arch/i386/kernel/setup.c308
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;
}