root/arch/i386/kernel/setup.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. setup_arch
  2. i486model
  3. i586model
  4. getmodel
  5. get_cpuinfo

   1 /*
   2  *  linux/arch/i386/kernel/setup.c
   3  *
   4  *  Copyright (C) 1995  Linus Torvalds
   5  */
   6 
   7 /*
   8  * This file handles the architecture-dependent parts of initialization
   9  */
  10 
  11 #include <linux/errno.h>
  12 #include <linux/sched.h>
  13 #include <linux/kernel.h>
  14 #include <linux/mm.h>
  15 #include <linux/stddef.h>
  16 #include <linux/unistd.h>
  17 #include <linux/ptrace.h>
  18 #include <linux/malloc.h>
  19 #include <linux/ldt.h>
  20 #include <linux/user.h>
  21 #include <linux/a.out.h>
  22 #include <linux/tty.h>
  23 #include <linux/ioport.h>
  24 #include <linux/delay.h>
  25 #include <linux/config.h>
  26 #ifdef CONFIG_APM
  27 #include <linux/apm_bios.h>
  28 #endif
  29 #ifdef CONFIG_BLK_DEV_RAM
  30 #include <linux/blk.h>
  31 #endif
  32 #include <asm/segment.h>
  33 #include <asm/system.h>
  34 #include <asm/smp.h>
  35 
  36 /*
  37  * Tell us the machine setup..
  38  */
  39 char hard_math = 0;             /* set by kernel/head.S */
  40 char x86 = 0;                   /* set by kernel/head.S to 3..6 */
  41 char x86_model = 0;             /* set by kernel/head.S */
  42 char x86_mask = 0;              /* set by kernel/head.S */
  43 int x86_capability = 0;         /* set by kernel/head.S */
  44 int fdiv_bug = 0;               /* set if Pentium(TM) with FP bug */
  45 int have_cpuid = 0;             /* set if CPUID instruction works */
  46 
  47 char x86_vendor_id[13] = "unknown";
  48 
  49 char ignore_irq13 = 0;          /* set if exception 16 works */
  50 char wp_works_ok = -1;          /* set if paging hardware honours WP */ 
  51 char hlt_works_ok = 1;          /* set if the "hlt" instruction works */
  52 
  53 /*
  54  * Bus types ..
  55  */
  56 int EISA_bus = 0;
  57 
  58 /*
  59  * Setup options
  60  */
  61 struct drive_info_struct { char dummy[32]; } drive_info;
  62 struct screen_info screen_info;
  63 #ifdef CONFIG_APM
  64 struct apm_bios_info apm_bios_info;
  65 #endif
  66 
  67 unsigned char aux_device_present;
  68 
  69 #ifdef CONFIG_BLK_DEV_RAM
  70 extern int rd_doload;           /* 1 = load ramdisk, 0 = don't load */
  71 extern int rd_prompt;           /* 1 = prompt for ramdisk, 0 = don't prompt */
  72 extern int rd_image_start;      /* starting block # of image */
  73 #endif
  74 
  75 extern int root_mountflags;
  76 extern int _etext, _edata, _end;
  77 
  78 extern char empty_zero_page[PAGE_SIZE];
  79 
  80 /*
  81  * This is set up by the setup-routine at boot-time
  82  */
  83 #define PARAM   empty_zero_page
  84 #define EXT_MEM_K (*(unsigned short *) (PARAM+2))
  85 #ifdef CONFIG_APM
  86 #define APM_BIOS_INFO (*(struct apm_bios_info *) (PARAM+64))
  87 #endif
  88 #define DRIVE_INFO (*(struct drive_info_struct *) (PARAM+0x80))
  89 #define SCREEN_INFO (*(struct screen_info *) (PARAM+0))
  90 #define MOUNT_ROOT_RDONLY (*(unsigned short *) (PARAM+0x1F2))
  91 #define RAMDISK_FLAGS (*(unsigned short *) (PARAM+0x1F8))
  92 #define ORIG_ROOT_DEV (*(unsigned short *) (PARAM+0x1FC))
  93 #define AUX_DEVICE_INFO (*(unsigned char *) (PARAM+0x1FF))
  94 #define LOADER_TYPE (*(unsigned char *) (PARAM+0x210))
  95 #define KERNEL_START (*(unsigned long *) (PARAM+0x214))
  96 #define INITRD_START (*(unsigned long *) (PARAM+0x218))
  97 #define INITRD_SIZE (*(unsigned long *) (PARAM+0x21c))
  98 #define COMMAND_LINE ((char *) (PARAM+2048))
  99 #define COMMAND_LINE_SIZE 256
 100 
 101 #define RAMDISK_IMAGE_START_MASK        0x07FF
 102 #define RAMDISK_PROMPT_FLAG             0x8000
 103 #define RAMDISK_LOAD_FLAG               0x4000  
 104 
 105 static char command_line[COMMAND_LINE_SIZE] = { 0, };
 106        char saved_command_line[COMMAND_LINE_SIZE];
 107 
 108 void setup_arch(char **cmdline_p,
     /* [previous][next][first][last][top][bottom][index][help] */
 109         unsigned long * memory_start_p, unsigned long * memory_end_p)
 110 {
 111         unsigned long memory_start, memory_end;
 112         char c = ' ', *to = command_line, *from = COMMAND_LINE;
 113         int len = 0;
 114         static unsigned char smptrap=0;
 115 
 116         if(smptrap==1)
 117         {
 118                 return;
 119         }
 120         smptrap=1;
 121 
 122         ROOT_DEV = to_kdev_t(ORIG_ROOT_DEV);
 123         drive_info = DRIVE_INFO;
 124         screen_info = SCREEN_INFO;
 125 #ifdef CONFIG_APM
 126         apm_bios_info = APM_BIOS_INFO;
 127 #endif
 128         aux_device_present = AUX_DEVICE_INFO;
 129         memory_end = (1<<20) + (EXT_MEM_K<<10);
 130         memory_end &= PAGE_MASK;
 131 #ifdef CONFIG_BLK_DEV_RAM
 132         rd_image_start = RAMDISK_FLAGS & RAMDISK_IMAGE_START_MASK;
 133         rd_prompt = ((RAMDISK_FLAGS & RAMDISK_PROMPT_FLAG) != 0);
 134         rd_doload = ((RAMDISK_FLAGS & RAMDISK_LOAD_FLAG) != 0);
 135 #endif
 136 #ifdef CONFIG_MAX_16M
 137         if (memory_end > 16*1024*1024)
 138                 memory_end = 16*1024*1024;
 139 #endif
 140         if (!MOUNT_ROOT_RDONLY)
 141                 root_mountflags &= ~MS_RDONLY;
 142         memory_start = (unsigned long) &_end;
 143         init_task.mm->start_code = TASK_SIZE;
 144         init_task.mm->end_code = TASK_SIZE + (unsigned long) &_etext;
 145         init_task.mm->end_data = TASK_SIZE + (unsigned long) &_edata;
 146         init_task.mm->brk = TASK_SIZE + (unsigned long) &_end;
 147 
 148         /* Save unparsed command line copy for /proc/cmdline */
 149         memcpy(saved_command_line, COMMAND_LINE, COMMAND_LINE_SIZE);
 150         saved_command_line[COMMAND_LINE_SIZE-1] = '\0';
 151 
 152         for (;;) {
 153                 /*
 154                  * "mem=nopentium" disables the 4MB page tables.
 155                  * "mem=XXX[kKmM]" overrides the BIOS-reported
 156                  * memory size
 157                  */
 158                 if (c == ' ' && *(const unsigned long *)from == *(const unsigned long *)"mem=") {
 159                         if (to != command_line) to--;
 160                         if (!memcmp(from+4, "nopentium", 9)) {
 161                                 from += 9+4;
 162                                 x86_capability &= ~8;
 163                         } else {
 164                                 memory_end = simple_strtoul(from+4, &from, 0);
 165                                 if ( *from == 'K' || *from == 'k' ) {
 166                                         memory_end = memory_end << 10;
 167                                         from++;
 168                                 } else if ( *from == 'M' || *from == 'm' ) {
 169                                         memory_end = memory_end << 20;
 170                                         from++;
 171                                 }
 172                         }
 173                 }
 174                 c = *(from++);
 175                 if (!c)
 176                         break;
 177                 if (COMMAND_LINE_SIZE <= ++len)
 178                         break;
 179                 *(to++) = c;
 180         }
 181         *to = '\0';
 182         *cmdline_p = command_line;
 183         *memory_start_p = memory_start;
 184         *memory_end_p = memory_end;
 185 
 186 #ifdef CONFIG_BLK_DEV_INITRD
 187         if (LOADER_TYPE) {
 188                 initrd_start = INITRD_START;
 189                 initrd_end = INITRD_START+INITRD_SIZE;
 190                 if (initrd_end > memory_end) {
 191                         printk("initrd extends beyond end of memory "
 192                             "(0x%08lx > 0x%08lx)\ndisabling initrd\n",
 193                             initrd_end,memory_end);
 194                         initrd_start = 0;
 195                 }
 196         }
 197 #endif
 198 
 199         /* request io space for devices used on all i[345]86 PC'S */
 200         request_region(0x00,0x20,"dma1");
 201         request_region(0x40,0x20,"timer");
 202         request_region(0x70,0x10,"rtc");
 203         request_region(0x80,0x20,"dma page reg");
 204         request_region(0xc0,0x20,"dma2");
 205         request_region(0xf0,0x10,"npu");
 206 }
 207 
 208 static const char * i486model(unsigned int nr)
     /* [previous][next][first][last][top][bottom][index][help] */
 209 {
 210         static const char *model[] = {
 211                 "0", "DX","SX","DX/2","4","SX/2","6","DX/2-WB","DX/4","DX/4-WB"
 212         };
 213         if (nr < sizeof(model)/sizeof(char *))
 214                 return model[nr];
 215         return NULL;
 216 }
 217 
 218 static const char * i586model(unsigned int nr)
     /* [previous][next][first][last][top][bottom][index][help] */
 219 {
 220         static const char *model[] = {
 221                 "0", "Pentium 60/66","Pentium 75+","OverDrive PODP5V83"
 222         };
 223         if (nr < sizeof(model)/sizeof(char *))
 224                 return model[nr];
 225         return NULL;
 226 }
 227 
 228 static const char * getmodel(int x86, int model)
     /* [previous][next][first][last][top][bottom][index][help] */
 229 {
 230         const char *p = NULL;
 231         static char nbuf[12];
 232         switch (x86) {
 233                 case 4:
 234                         p = i486model(model);
 235                         break;
 236                 case 5:
 237                         p = i586model(model);
 238                         break;
 239         }
 240         if (p)
 241                 return p;
 242 
 243         sprintf(nbuf, "%d", model);
 244         return nbuf;
 245 }
 246 
 247 int get_cpuinfo(char * buffer)
     /* [previous][next][first][last][top][bottom][index][help] */
 248 {
 249         int i, len = 0;
 250         static const char *x86_cap_flags[] = {
 251                 "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce",
 252                 "cx8", "apic", "10", "11", "mtrr", "pge", "mca", "cmov",
 253                 "16", "17", "18", "19", "20", "21", "22", "mmx",
 254                 "24", "25", "26", "27", "28", "29", "30", "31"
 255         };
 256         
 257 #ifdef __SMP__
 258         int n;
 259 
 260 #define CD(X)           (cpu_data[n].X)
 261 /* SMP has the wrong name for loops_per_sec */
 262 #define loops_per_sec   udelay_val
 263 #define CPUN n
 264 
 265         for ( n = 0 ; n < 32 ; n++ ) {
 266                 if ( cpu_present_map & (1<<n) ) {
 267                         if (len) buffer[len++] = '\n'; 
 268 
 269 #else
 270 #define CD(X) (X)
 271 #define CPUN 0
 272 #endif
 273 
 274                         len += sprintf(buffer+len,"processor\t: %d\n"
 275                                        "cpu\t\t: %c86\n"
 276                                        "model\t\t: %s\n"
 277                                        "vendor_id\t: %s\n",
 278                                        CPUN,
 279                                        CD(x86)+'0',
 280                                        CD(have_cpuid) ? 
 281                                          getmodel(CD(x86), CD(x86_model)) :
 282                                          "unknown",
 283                                        CD(x86_vendor_id));
 284         
 285                         if (CD(x86_mask))
 286                                 len += sprintf(buffer+len,
 287                                                "stepping\t: %d\n",
 288                                                CD(x86_mask));
 289                         else
 290                                 len += sprintf(buffer+len, 
 291                                                "stepping\t: unknown\n");
 292         
 293                         len += sprintf(buffer+len,
 294                                        "fdiv_bug\t: %s\n"
 295                                        "hlt_bug\t\t: %s\n"
 296                                        "fpu\t\t: %s\n"
 297                                        "cpuid\t\t: %s\n"
 298                                        "wp\t\t: %s\n"
 299                                        "flags\t\t:",
 300                                        CD(fdiv_bug) ? "yes" : "no",
 301                                        CD(hlt_works_ok) ? "no" : "yes",
 302                                        CD(hard_math) ? "yes" : "no",
 303                                        CD(have_cpuid) ? "yes" : "no",
 304                                        CD(wp_works_ok) ? "yes" : "no");
 305         
 306                         for ( i = 0 ; i < 32 ; i++ ) {
 307                                 if ( CD(x86_capability) & (1 << i) ) {
 308                                         len += sprintf(buffer+len, " %s",
 309                                                        x86_cap_flags[i]);
 310                                 }
 311                         }
 312                         len += sprintf(buffer+len,
 313                                        "\nbogomips:\t: %lu.%02lu\n",
 314                                        CD(loops_per_sec)/500000,
 315                                        (CD(loops_per_sec)/5000) % 100);
 316 #ifdef __SMP__
 317                 }
 318         }
 319 #endif
 320         return len;
 321 }

/* [previous][next][first][last][top][bottom][index][help] */