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 boot/head.S */
  40 char x86 = 0;                   /* set by boot/head.S to 3 or 4 */
  41 char x86_model = 0;             /* set by boot/head.S */
  42 char x86_mask = 0;              /* set by boot/head.S */
  43 int x86_capability = 0;         /* set by boot/head.S */
  44 int fdiv_bug = 0;               /* set if Pentium(TM) with FP bug */
  45 
  46 char x86_vendor_id[13] = "Unknown";
  47 
  48 char ignore_irq13 = 0;          /* set if exception 16 works */
  49 char wp_works_ok = -1;          /* set if paging hardware honours WP */ 
  50 char hlt_works_ok = 1;          /* set if the "hlt" instruction works */
  51 
  52 /*
  53  * Bus types ..
  54  */
  55 int EISA_bus = 0;
  56 
  57 /*
  58  * Setup options
  59  */
  60 struct drive_info_struct { char dummy[32]; } drive_info;
  61 struct screen_info screen_info;
  62 #ifdef CONFIG_APM
  63 struct apm_bios_info apm_bios_info;
  64 #endif
  65 
  66 unsigned char aux_device_present;
  67 
  68 #ifdef CONFIG_BLK_DEV_RAM
  69 extern int rd_doload;           /* 1 = load ramdisk, 0 = don't load */
  70 extern int rd_prompt;           /* 1 = prompt for ramdisk, 0 = don't prompt */
  71 extern int rd_image_start;      /* starting block # of image */
  72 #endif
  73 
  74 extern int root_mountflags;
  75 extern int _etext, _edata, _end;
  76 
  77 extern char empty_zero_page[PAGE_SIZE];
  78 
  79 /*
  80  * This is set up by the setup-routine at boot-time
  81  */
  82 #define PARAM   empty_zero_page
  83 #define EXT_MEM_K (*(unsigned short *) (PARAM+2))
  84 #ifdef CONFIG_APM
  85 #define APM_BIOS_INFO (*(struct apm_bios_info *) (PARAM+64))
  86 #endif
  87 #define DRIVE_INFO (*(struct drive_info_struct *) (PARAM+0x80))
  88 #define SCREEN_INFO (*(struct screen_info *) (PARAM+0))
  89 #define MOUNT_ROOT_RDONLY (*(unsigned short *) (PARAM+0x1F2))
  90 #define RAMDISK_FLAGS (*(unsigned short *) (PARAM+0x1F8))
  91 #define ORIG_ROOT_DEV (*(unsigned short *) (PARAM+0x1FC))
  92 #define AUX_DEVICE_INFO (*(unsigned char *) (PARAM+0x1FF))
  93 #define LOADER_TYPE (*(unsigned char *) (PARAM+0x210))
  94 #define KERNEL_START (*(unsigned long *) (PARAM+0x214))
  95 #define INITRD_START (*(unsigned long *) (PARAM+0x218))
  96 #define INITRD_SIZE (*(unsigned long *) (PARAM+0x21c))
  97 #define COMMAND_LINE ((char *) (PARAM+2048))
  98 #define COMMAND_LINE_SIZE 256
  99 
 100 #define RAMDISK_IMAGE_START_MASK        0x07FF
 101 #define RAMDISK_PROMPT_FLAG             0x8000
 102 #define RAMDISK_LOAD_FLAG               0x4000  
 103 
 104 static char command_line[COMMAND_LINE_SIZE] = { 0, };
 105        char saved_command_line[COMMAND_LINE_SIZE];
 106 
 107 void setup_arch(char **cmdline_p,
     /* [previous][next][first][last][top][bottom][index][help] */
 108         unsigned long * memory_start_p, unsigned long * memory_end_p)
 109 {
 110         unsigned long memory_start, memory_end;
 111         char c = ' ', *to = command_line, *from = COMMAND_LINE;
 112         int len = 0;
 113         static unsigned char smptrap=0;
 114 
 115         if(smptrap==1)
 116         {
 117                 return;
 118         }
 119         smptrap=1;
 120 
 121         ROOT_DEV = to_kdev_t(ORIG_ROOT_DEV);
 122         drive_info = DRIVE_INFO;
 123         screen_info = SCREEN_INFO;
 124 #ifdef CONFIG_APM
 125         apm_bios_info = APM_BIOS_INFO;
 126 #endif
 127         aux_device_present = AUX_DEVICE_INFO;
 128         memory_end = (1<<20) + (EXT_MEM_K<<10);
 129         memory_end &= PAGE_MASK;
 130 #ifdef CONFIG_BLK_DEV_RAM
 131         rd_image_start = RAMDISK_FLAGS & RAMDISK_IMAGE_START_MASK;
 132         rd_prompt = ((RAMDISK_FLAGS & RAMDISK_PROMPT_FLAG) != 0);
 133         rd_doload = ((RAMDISK_FLAGS & RAMDISK_LOAD_FLAG) != 0);
 134 #endif
 135 #ifdef CONFIG_MAX_16M
 136         if (memory_end > 16*1024*1024)
 137                 memory_end = 16*1024*1024;
 138 #endif
 139         if (!MOUNT_ROOT_RDONLY)
 140                 root_mountflags &= ~MS_RDONLY;
 141         memory_start = (unsigned long) &_end;
 142         init_task.mm->start_code = TASK_SIZE;
 143         init_task.mm->end_code = TASK_SIZE + (unsigned long) &_etext;
 144         init_task.mm->end_data = TASK_SIZE + (unsigned long) &_edata;
 145         init_task.mm->brk = TASK_SIZE + (unsigned long) &_end;
 146 
 147         /* Save unparsed command line copy for /proc/cmdline */
 148         memcpy(saved_command_line, COMMAND_LINE, COMMAND_LINE_SIZE);
 149         saved_command_line[COMMAND_LINE_SIZE-1] = '\0';
 150 
 151         for (;;) {
 152                 /*
 153                  * "mem=nopentium" disables the 4MB page tables.
 154                  * "mem=XXX[kKmM]" overrides the BIOS-reported
 155                  * memory size
 156                  */
 157                 if (c == ' ' && *(const unsigned long *)from == *(const unsigned long *)"mem=") {
 158                         if (to != command_line) to--;
 159                         if (!memcmp(from+4, "nopentium", 9)) {
 160                                 from += 9+4;
 161                                 x86_capability &= ~8;
 162                         } else {
 163                                 memory_end = simple_strtoul(from+4, &from, 0);
 164                                 if ( *from == 'K' || *from == 'k' ) {
 165                                         memory_end = memory_end << 10;
 166                                         from++;
 167                                 } else if ( *from == 'M' || *from == 'm' ) {
 168                                         memory_end = memory_end << 20;
 169                                         from++;
 170                                 }
 171                         }
 172                 }
 173                 c = *(from++);
 174                 if (!c)
 175                         break;
 176                 if (COMMAND_LINE_SIZE <= ++len)
 177                         break;
 178                 *(to++) = c;
 179         }
 180         *to = '\0';
 181         *cmdline_p = command_line;
 182         *memory_start_p = memory_start;
 183         *memory_end_p = memory_end;
 184 
 185 #ifdef CONFIG_BLK_DEV_INITRD
 186         if (LOADER_TYPE) {
 187                 initrd_start = INITRD_START;
 188                 initrd_end = INITRD_START+INITRD_SIZE;
 189                 if (initrd_end > memory_end) {
 190                         printk("initrd extends beyond end of memory "
 191                             "(0x%08lx > 0x%08lx)\ndisabling initrd\n",
 192                             initrd_end,memory_end);
 193                         initrd_start = 0;
 194                 }
 195         }
 196 #endif
 197 
 198         /* request io space for devices used on all i[345]86 PC'S */
 199         request_region(0x00,0x20,"dma1");
 200         request_region(0x40,0x20,"timer");
 201         request_region(0x70,0x10,"rtc");
 202         request_region(0x80,0x20,"dma page reg");
 203         request_region(0xc0,0x20,"dma2");
 204         request_region(0xf0,0x10,"npu");
 205 }
 206 
 207 static const char * i486model(unsigned int nr)
     /* [previous][next][first][last][top][bottom][index][help] */
 208 {
 209         static const char *model[] = {
 210                 "0", "DX","SX","DX/2","4","SX/2","6","DX/2-WB","DX/4","DX/4-WB"
 211         };
 212         if (nr < sizeof(model)/sizeof(char *))
 213                 return model[nr];
 214         return "Unknown";
 215 }
 216 
 217 static const char * i586model(unsigned int nr)
     /* [previous][next][first][last][top][bottom][index][help] */
 218 {
 219         static const char *model[] = {
 220                 "0", "Pentium 60/66","Pentium 75+","OverDrive PODP5V83"
 221         };
 222         if (nr < sizeof(model)/sizeof(char *))
 223                 return model[nr];
 224         return "Unknown";
 225 }
 226 
 227 static const char * getmodel(int x86, int model)
     /* [previous][next][first][last][top][bottom][index][help] */
 228 {
 229         switch (x86) {
 230                 case 4:
 231                         return i486model(model);
 232                 case 5:
 233                         return i586model(model);
 234         }
 235         return "Unknown";
 236 }
 237 
 238 int get_cpuinfo(char * buffer)
     /* [previous][next][first][last][top][bottom][index][help] */
 239 {
 240         char mask[2];
 241 #ifndef __SMP__ 
 242         mask[0] = x86_mask+'@';
 243         mask[1] = '\0';
 244         return sprintf(buffer,"cpu\t\t: %c86\n"
 245                               "model\t\t: %s\n"
 246                               "mask\t\t: %s\n"
 247                               "vid\t\t: %s\n"
 248                               "fdiv_bug\t: %s\n"
 249                               "math\t\t: %s\n"
 250                               "hlt\t\t: %s\n"
 251                               "wp\t\t: %s\n"
 252                               "Integrated NPU\t: %s\n"
 253                               "Enhanced VM86\t: %s\n"
 254                               "IO Breakpoints\t: %s\n"
 255                               "4MB Pages\t: %s\n"
 256                               "TS Counters\t: %s\n"
 257                               "Pentium MSR\t: %s\n"
 258                               "Mach. Ch. Exep.\t: %s\n"
 259                               "CMPXCHGB8B\t: %s\n"
 260                               "BogoMips\t: %lu.%02lu\n",
 261                               x86+'0', 
 262                               getmodel(x86, x86_model),
 263                               x86_mask ? mask : "Unknown",
 264                               x86_vendor_id,
 265                               fdiv_bug ? "yes" : "no",
 266                               hard_math ? "yes" : "no",
 267                               hlt_works_ok ? "yes" : "no",
 268                               wp_works_ok ? "yes" : "no",
 269                               x86_capability & 1 ? "yes" : "no",
 270                               x86_capability & 2 ? "yes" : "no",
 271                               x86_capability & 4 ? "yes" : "no",
 272                               x86_capability & 8 ? "yes" : "no",
 273                               x86_capability & 16 ? "yes" : "no",
 274                               x86_capability & 32 ? "yes" : "no",
 275                               x86_capability & 128 ? "yes" : "no",
 276                               x86_capability & 256 ? "yes" : "no",
 277                               loops_per_sec/500000, (loops_per_sec/5000) % 100
 278                               );
 279 #else
 280         char *bp=buffer;
 281         int i;  
 282         bp+=sprintf(bp,"cpu\t\t: ");
 283         for(i=0;i<32;i++)
 284                 if(cpu_present_map&(1<<i))
 285                         bp+=sprintf(bp,"%c86             ",cpu_data[i].x86+'0');
 286         bp+=sprintf(bp,"\nmodel\t\t: ");
 287         for(i=0;i<32;i++)
 288                 if(cpu_present_map&(1<<i))
 289                         bp+=sprintf(bp,"%-16s",getmodel(cpu_data[i].x86,cpu_data[i].x86_model));
 290         bp+=sprintf(bp,"\nmask\t\t: ");
 291         for(i=0;i<32;i++)
 292                 if(cpu_present_map&(1<<i))
 293                 {
 294                         mask[0] = cpu_data[i].x86_mask+'@';
 295                         mask[1] = '\0';         
 296                         bp+=sprintf(bp,"%-16s", cpu_data[i].x86_mask ? mask : "Unknown");
 297                 }
 298         bp+=sprintf(bp,"\nvid\t\t: ");
 299         for(i=0;i<32;i++)
 300                 if(cpu_present_map&(1<<i))
 301                         bp+=sprintf(bp,"%-16s", cpu_data[i].x86_vendor_id);
 302         bp+=sprintf(bp,"\nfdiv_bug\t: ");
 303         for(i=0;i<32;i++)
 304                 if(cpu_present_map&(1<<i))
 305                         bp+=sprintf(bp,"%-16s", cpu_data[i].fdiv_bug?"yes":"no");
 306         bp+=sprintf(bp,"\nmath\t\t: ");
 307         for(i=0;i<32;i++)
 308                 if(cpu_present_map&(1<<i))
 309                         bp+=sprintf(bp,"%-16s", cpu_data[i].hard_math?"yes":"no");
 310         bp+=sprintf(bp,"\nhlt\t\t: ");
 311         for(i=0;i<32;i++)
 312                 if(cpu_present_map&(1<<i))
 313                         bp+=sprintf(bp,"%-16s", cpu_data[i].hlt_works_ok?"yes":"no");
 314         bp+=sprintf(bp,"\nwp\t\t: ");
 315         for(i=0;i<32;i++)
 316                 if(cpu_present_map&(1<<i))
 317                         bp+=sprintf(bp,"%-16s", cpu_data[i].wp_works_ok?"yes":"no");
 318         bp+=sprintf(bp,"\nIntegrated NPU\t: ");
 319         for(i=0;i<32;i++)
 320                 if(cpu_present_map&(1<<i))
 321                         bp+=sprintf(bp,"%-16s", cpu_data[i].x86_capability&1?"yes":"no");
 322         bp+=sprintf(bp,"\nEnhanced VM86\t: ");
 323         for(i=0;i<32;i++)
 324                 if(cpu_present_map&(1<<i))
 325                         bp+=sprintf(bp,"%-16s", cpu_data[i].x86_capability&2?"yes":"no");
 326         bp+=sprintf(bp,"\nIO Breakpoints\t: ");
 327         for(i=0;i<32;i++)
 328                 if(cpu_present_map&(1<<i))
 329                         bp+=sprintf(bp,"%-16s", (cpu_data[i].x86_capability&4)?"yes":"no");
 330         bp+=sprintf(bp,"\n4MB Pages\t: ");
 331         for(i=0;i<32;i++)
 332                 if(cpu_present_map&(1<<i))
 333                         bp+=sprintf(bp,"%-16s", (cpu_data[i].x86_capability)&8?"yes":"no");
 334         bp+=sprintf(bp,"\nTS Counters\t: ");
 335         for(i=0;i<32;i++)
 336                 if(cpu_present_map&(1<<i))
 337                         bp+=sprintf(bp,"%-16s", (cpu_data[i].x86_capability&16)?"yes":"no");
 338         bp+=sprintf(bp,"\nPentium MSR\t: ");
 339         for(i=0;i<32;i++)
 340                 if(cpu_present_map&(1<<i))
 341                         bp+=sprintf(bp,"%-16s", (cpu_data[i].x86_capability&32)?"yes":"no");
 342         bp+=sprintf(bp,"\nMach. Ch. Exep.\t: ");
 343         for(i=0;i<32;i++)
 344                 if(cpu_present_map&(1<<i))
 345                         bp+=sprintf(bp,"%-16s", (cpu_data[i].x86_capability&128)?"yes":"no");
 346         bp+=sprintf(bp,"\nCMPXCHG8B\t: ");
 347         for(i=0;i<32;i++)
 348                 if(cpu_present_map&(1<<i))
 349                         bp+=sprintf(bp,"%-16s", (cpu_data[i].x86_capability&256)?"yes":"no");
 350         bp+=sprintf(bp,"\nBogoMips\t: ");
 351         for(i=0;i<32;i++)
 352         {
 353                 char tmp[17];
 354                 if(cpu_present_map&(1<<i))
 355                 {
 356                         sprintf(tmp,"%lu.%02lu",cpu_data[i].udelay_val/500000L,
 357                                                    (cpu_data[i].udelay_val/5000L)%100);
 358                         bp+=sprintf(bp,"%-16s",tmp);
 359                 }
 360         }
 361         *bp++='\n';
 362         return bp-buffer;
 363 #endif                        
 364 }

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