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. i686model
  5. getmodel
  6. 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 * i686model(unsigned int nr)
     /* [previous][next][first][last][top][bottom][index][help] */
 229 {
 230         static const char *model[] = {
 231                 "PPro A-step", "Pentium Pro"
 232         };
 233         if (nr < sizeof(model)/sizeof(char *))
 234                 return model[nr];
 235         return NULL;
 236 }
 237 
 238 static const char * getmodel(int x86, int model)
     /* [previous][next][first][last][top][bottom][index][help] */
 239 {
 240         const char *p = NULL;
 241         static char nbuf[12];
 242         switch (x86) {
 243                 case 4:
 244                         p = i486model(model);
 245                         break;
 246                 case 5:
 247                         p = i586model(model);
 248                         break;
 249                 case 6:
 250                         p = i686model(model);
 251                         break;
 252         }
 253         if (p)
 254                 return p;
 255 
 256         sprintf(nbuf, "%d", model);
 257         return nbuf;
 258 }
 259 
 260 int get_cpuinfo(char * buffer)
     /* [previous][next][first][last][top][bottom][index][help] */
 261 {
 262         int i, len = 0;
 263         static const char *x86_cap_flags[] = {
 264                 "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce",
 265                 "cx8", "apic", "10", "11", "mtrr", "pge", "mca", "cmov",
 266                 "16", "17", "18", "19", "20", "21", "22", "mmx",
 267                 "24", "25", "26", "27", "28", "29", "30", "31"
 268         };
 269         
 270 #ifdef __SMP__
 271         int n;
 272 
 273 #define CD(X)           (cpu_data[n].X)
 274 /* SMP has the wrong name for loops_per_sec */
 275 #define loops_per_sec   udelay_val
 276 #define CPUN n
 277 
 278         for ( n = 0 ; n < 32 ; n++ ) {
 279                 if ( cpu_present_map & (1<<n) ) {
 280                         if (len) buffer[len++] = '\n'; 
 281 
 282 #else
 283 #define CD(X) (X)
 284 #define CPUN 0
 285 #endif
 286 
 287                         len += sprintf(buffer+len,"processor\t: %d\n"
 288                                        "cpu\t\t: %c86\n"
 289                                        "model\t\t: %s\n"
 290                                        "vendor_id\t: %s\n",
 291                                        CPUN,
 292                                        CD(x86)+'0',
 293                                        CD(have_cpuid) ? 
 294                                          getmodel(CD(x86), CD(x86_model)) :
 295                                          "unknown",
 296                                        CD(x86_vendor_id));
 297         
 298                         if (CD(x86_mask))
 299                                 len += sprintf(buffer+len,
 300                                                "stepping\t: %d\n",
 301                                                CD(x86_mask));
 302                         else
 303                                 len += sprintf(buffer+len, 
 304                                                "stepping\t: unknown\n");
 305         
 306                         len += sprintf(buffer+len,
 307                                        "fdiv_bug\t: %s\n"
 308                                        "hlt_bug\t\t: %s\n"
 309                                        "fpu\t\t: %s\n"
 310                                        "fpu_exception\t: %s\n"
 311                                        "cpuid\t\t: %s\n"
 312                                        "wp\t\t: %s\n"
 313                                        "flags\t\t:",
 314                                        CD(fdiv_bug) ? "yes" : "no",
 315                                        CD(hlt_works_ok) ? "no" : "yes",
 316                                        CD(hard_math) ? "yes" : "no",
 317                                        (CD(hard_math) && ignore_irq13)
 318                                          ? "yes" : "no",
 319                                        CD(have_cpuid) ? "yes" : "no",
 320                                        CD(wp_works_ok) ? "yes" : "no");
 321         
 322                         for ( i = 0 ; i < 32 ; i++ ) {
 323                                 if ( CD(x86_capability) & (1 << i) ) {
 324                                         len += sprintf(buffer+len, " %s",
 325                                                        x86_cap_flags[i]);
 326                                 }
 327                         }
 328                         len += sprintf(buffer+len,
 329                                        "\nbogomips:\t: %lu.%02lu\n",
 330                                        CD(loops_per_sec)/500000,
 331                                        (CD(loops_per_sec)/5000) % 100);
 332 #ifdef __SMP__
 333                 }
 334         }
 335 #endif
 336         return len;
 337 }

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