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

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