root/arch/sparc/kernel/setup.c

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

DEFINITIONS

This source file includes following definitions.
  1. bios32_init
  2. prom_sync_me
  3. kernel_enter_debugger
  4. obp_system_intr
  5. boot_flags_init
  6. setup_arch
  7. sys_ioperm
  8. get_cpuinfo

   1 /*  $Id: setup.c,v 1.60 1996/04/04 16:30:28 tridge Exp $
   2  *  linux/arch/sparc/kernel/setup.c
   3  *
   4  *  Copyright (C) 1995  David S. Miller (davem@caip.rutgers.edu)
   5  */
   6 
   7 #include <linux/errno.h>
   8 #include <linux/sched.h>
   9 #include <linux/kernel.h>
  10 #include <linux/mm.h>
  11 #include <linux/stddef.h>
  12 #include <linux/unistd.h>
  13 #include <linux/ptrace.h>
  14 #include <linux/malloc.h>
  15 #include <linux/ldt.h>
  16 #include <linux/smp.h>
  17 #include <linux/user.h>
  18 #include <linux/a.out.h>
  19 #include <linux/tty.h>
  20 #include <linux/delay.h>
  21 #include <linux/config.h>
  22 #include <linux/fs.h>
  23 #include <linux/kdev_t.h>
  24 #include <linux/major.h>
  25 
  26 #include <asm/segment.h>
  27 #include <asm/system.h>
  28 #include <asm/io.h>
  29 #include <asm/kgdb.h>
  30 #include <asm/processor.h>
  31 #include <asm/oplib.h>
  32 #include <asm/page.h>
  33 #include <asm/pgtable.h>
  34 #include <asm/traps.h>
  35 #include <asm/vaddrs.h>
  36 #include <asm/kdebug.h>
  37 #include <asm/mbus.h>
  38 
  39 struct screen_info screen_info = {
  40         0, 0,                   /* orig-x, orig-y */
  41         { 0, 0, },              /* unused */
  42         0,                      /* orig-video-page */
  43         0,                      /* orig-video-mode */
  44         128,                    /* orig-video-cols */
  45         0,0,0,                  /* ega_ax, ega_bx, ega_cx */
  46         54,                     /* orig-video-lines */
  47         0,                      /* orig-video-isVGA */
  48         16                      /* orig-video-points */
  49 };
  50 
  51 unsigned int phys_bytes_of_ram, end_of_phys_memory;
  52 
  53 unsigned long bios32_init(unsigned long memory_start, unsigned long memory_end)
     /* [previous][next][first][last][top][bottom][index][help] */
  54 {
  55         return memory_start;
  56 }
  57 
  58 /* Typing sync at the prom prompt calls the function pointed to by
  59  * romvec->pv_synchook which I set to the following function.
  60  * This should sync all filesystems and return, for now it just
  61  * prints out pretty messages and returns.
  62  */
  63 
  64 extern unsigned long trapbase;
  65 extern void breakpoint(void);
  66 #if CONFIG_SUN_CONSOLE
  67 extern void console_restore_palette(void);
  68 #endif
  69 asmlinkage void sys_sync(void); /* it's really int */
  70 
  71 /* Pretty sick eh? */
  72 void prom_sync_me(void)
     /* [previous][next][first][last][top][bottom][index][help] */
  73 {
  74         unsigned long prom_tbr, flags;
  75 
  76         save_flags(flags); cli();
  77         __asm__ __volatile__("rd %%tbr, %0\n\t" : "=r" (prom_tbr));
  78         __asm__ __volatile__("wr %0, 0x0, %%tbr\n\t"
  79                              "nop\n\t"
  80                              "nop\n\t"
  81                              "nop\n\t" : : "r" (&trapbase));
  82 
  83 #if CONFIG_SUN_CONSOLE
  84         console_restore_palette ();
  85 #endif
  86         prom_printf("PROM SYNC COMMAND...\n");
  87         show_free_areas();
  88         if(current->pid != 0) {
  89                 sti();
  90                 sys_sync();
  91                 cli();
  92         }
  93         prom_printf("Returning to prom\n");
  94 
  95         __asm__ __volatile__("wr %0, 0x0, %%tbr\n\t"
  96                              "nop\n\t"
  97                              "nop\n\t"
  98                              "nop\n\t" : : "r" (prom_tbr));
  99         restore_flags(flags);
 100 
 101         return;
 102 }
 103 
 104 extern void rs_kgdb_hook(int tty_num); /* sparc/serial.c */
 105 
 106 unsigned int boot_flags;
 107 #define BOOTME_DEBUG  0x1
 108 #define BOOTME_SINGLE 0x2
 109 #define BOOTME_KGDB   0x4
 110 
 111 void kernel_enter_debugger(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 112 {
 113         if (boot_flags & BOOTME_KGDB) {
 114                 printk("KGDB: Entered\n");
 115                 breakpoint();
 116         }
 117 }
 118 
 119 int obp_system_intr(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 120 {
 121         if (boot_flags & BOOTME_KGDB) {
 122                 printk("KGDB: system interrupted\n");
 123                 breakpoint();
 124                 return 1;
 125         }
 126         if (boot_flags & BOOTME_DEBUG) {
 127                 printk("OBP: system interrupted\n");
 128                 prom_halt();
 129                 return 1;
 130         }
 131         return 0;
 132 }
 133 
 134 /* This routine does no error checking, make sure your string is sane
 135  * before calling this!
 136  * XXX This is cheese, make generic and better.
 137  */
 138 void
 139 boot_flags_init(char *commands)
     /* [previous][next][first][last][top][bottom][index][help] */
 140 {
 141         int i;
 142         for(i=0; i<strlen(commands); i++) {
 143                 if(commands[i]=='-') {
 144                         switch(commands[i+1]) {
 145                         case 'd':
 146                                 boot_flags |= BOOTME_DEBUG;
 147                                 break;
 148                         case 's':
 149                                 boot_flags |= BOOTME_SINGLE;
 150                                 break;
 151                         case 'h':
 152                                 prom_printf("boot_flags_init: Found halt flag, doing so now...\n");
 153                                 halt();
 154                                 break;
 155                         default:
 156                                 printk("boot_flags_init: Unknown boot arg (-%c)\n",
 157                                        commands[i+1]);
 158                                 break;
 159                         };
 160                 } else {
 161                         if(commands[i]=='k' && commands[i+1]=='g' &&
 162                            commands[i+2]=='d' && commands[i+3]=='b' &&
 163                            commands[i+4]=='=' && commands[i+5]=='t' &&
 164                            commands[i+6]=='t' && commands[i+7]=='y') {
 165                                 printk("KGDB: Using serial line /dev/tty%c for "
 166                                        "session\n", commands[i+8]);
 167                                 boot_flags |= BOOTME_KGDB;
 168 #if CONFIG_SUN_SERIAL
 169                                 if(commands[i+8]=='a')
 170                                         rs_kgdb_hook(0);
 171                                 else if(commands[i+8]=='b')
 172                                         rs_kgdb_hook(1);
 173                                 else
 174 #endif
 175 #if CONFIG_AP1000
 176                                 if(commands[i+8]=='c')
 177                                   printk("KGDB: ap1000+ debugging\n");
 178                                 else
 179 #endif
 180                                 {
 181                                         printk("KGDB: whoops bogon tty line "
 182                                                "requested, disabling session\n");
 183                                         boot_flags &= (~BOOTME_KGDB);
 184                                 }
 185                         }
 186                 }
 187         }
 188         return;
 189 }
 190 
 191 /* This routine will in the future do all the nasty prom stuff
 192  * to probe for the mmu type and its parameters, etc. This will
 193  * also be where SMP things happen plus the Sparc specific memory
 194  * physical memory probe as on the alpha.
 195  */
 196 
 197 extern void load_mmu(void);
 198 extern int prom_probe_memory(void);
 199 extern void sun4c_probe_vac(void);
 200 extern void get_idprom(void);
 201 extern char cputypval;
 202 extern unsigned long start, end;
 203 extern void panic_setup(char *, int *);
 204 
 205 char saved_command_line[256];
 206 enum sparc_cpu sparc_cpu_model;
 207 
 208 struct tt_entry *sparc_ttable;
 209 
 210 static struct pt_regs fake_swapper_regs = { 0, 0, 0, 0, { 0, } };
 211 
 212 void setup_arch(char **cmdline_p,
     /* [previous][next][first][last][top][bottom][index][help] */
 213         unsigned long * memory_start_p, unsigned long * memory_end_p)
 214 {
 215         int total, i, panic_stuff[2], packed;
 216 
 217 #if CONFIG_AP1000
 218         register_console(prom_printf);
 219         ((char *)(&cputypval))[4] = 'm'; /* ugly :-( */
 220 #endif
 221 
 222 #if 0
 223         /* Always reboot on panic, but give 5 seconds to hit L1-A
 224          * and look at debugging info if desired.
 225          */
 226         panic_stuff[0] = 1;
 227         panic_stuff[1] = 5;
 228         panic_setup(0, panic_stuff);
 229 #endif
 230 
 231         sparc_ttable = (struct tt_entry *) &start;
 232 
 233         /* Initialize PROM console and command line. */
 234         *cmdline_p = prom_getbootargs();
 235         strcpy(saved_command_line, *cmdline_p);
 236 
 237         /* Set sparc_cpu_model */
 238         sparc_cpu_model = sun_unknown;
 239         if(!strcmp(&cputypval,"sun4c")) { sparc_cpu_model=sun4c; }
 240         if(!strcmp(&cputypval,"sun4m")) { sparc_cpu_model=sun4m; }
 241         if(!strcmp(&cputypval,"sun4d")) { sparc_cpu_model=sun4d; }
 242         if(!strcmp(&cputypval,"sun4e")) { sparc_cpu_model=sun4e; }
 243         if(!strcmp(&cputypval,"sun4u")) { sparc_cpu_model=sun4u; }
 244         printk("ARCH: ");
 245         packed = 0;
 246         switch(sparc_cpu_model)
 247           {
 248           case sun4c:
 249                   printk("SUN4C\n");
 250                   sun4c_probe_vac();
 251                   packed = 0;
 252                   break;
 253           case sun4m:
 254                   printk("SUN4M\n");
 255                   packed = 1;
 256                   break;
 257           case sun4d:
 258                   printk("SUN4D\n");
 259                   packed = 1;
 260                   break;
 261           case sun4e:
 262                   printk("SUN4E\n");
 263                   packed = 0;
 264                   break;
 265           case sun4u:
 266                   printk("SUN4U\n");
 267                   break;
 268           default:
 269                   printk("UNKNOWN!\n");
 270                   break;
 271           };
 272 
 273         boot_flags_init(*cmdline_p);
 274         if((boot_flags&BOOTME_DEBUG) && (linux_dbvec!=0) && 
 275            ((*(short *)linux_dbvec) != -1)) {
 276                 printk("Booted under KADB. Syncing trap table.\n");
 277                 (*(linux_dbvec->teach_debugger))();
 278         }
 279         if((boot_flags & BOOTME_KGDB)) {
 280                 set_debug_traps();
 281                 breakpoint();
 282         }
 283 
 284         get_idprom();
 285         load_mmu();
 286         total = prom_probe_memory();
 287         *memory_start_p = (((unsigned long) &end));
 288 
 289         if(!packed) {
 290                 for(i=0; sp_banks[i].num_bytes != 0; i++)
 291                         end_of_phys_memory = sp_banks[i].base_addr +
 292                                 sp_banks[i].num_bytes;
 293         } else {
 294                 unsigned int sum = 0;
 295 
 296                 for(i = 0; sp_banks[i].num_bytes != 0; i++)
 297                         sum += sp_banks[i].num_bytes;
 298 
 299                 end_of_phys_memory = sum;
 300         }
 301 
 302         prom_setsync(prom_sync_me);
 303 
 304         *memory_end_p = (end_of_phys_memory + PAGE_OFFSET);
 305         if(*memory_end_p > IOBASE_VADDR)
 306                 *memory_end_p = IOBASE_VADDR;
 307 
 308         /* Due to stack alignment restrictions and assumptions... */
 309         init_task.mm->mmap->vm_page_prot = PAGE_SHARED;
 310         init_task.mm->mmap->vm_start = KERNBASE;
 311         init_task.mm->mmap->vm_end = *memory_end_p;
 312         init_task.tss.kregs = &fake_swapper_regs;
 313 
 314         {
 315                 extern int serial_console;  /* in console.c, of course */
 316 #if !CONFIG_SUN_SERIAL
 317                 serial_console = 0;
 318 #else
 319                 int idev = prom_query_input_device();
 320                 int odev = prom_query_output_device();
 321                 if (idev == PROMDEV_IKBD && odev == PROMDEV_OSCREEN) {
 322                         serial_console = 0;
 323                 } else if (idev == PROMDEV_ITTYA && odev == PROMDEV_OTTYA) {
 324                         serial_console = 1;
 325                 } else if (idev == PROMDEV_ITTYB && odev == PROMDEV_OTTYB) {
 326                         prom_printf("Console on ttyb is not supported\n");
 327                         prom_halt();
 328                 } else {
 329                         prom_printf("Inconsistent console\n");
 330                         prom_halt();
 331                 }
 332 #endif
 333         }
 334 #if 1
 335         /* XXX ROOT_DEV hack for kgdb - davem XXX */
 336 #if 1
 337         ROOT_DEV = MKDEV(UNNAMED_MAJOR, 255); /* NFS */
 338 #else
 339         ROOT_DEV = 0x801; /* SCSI DISK */
 340 #endif
 341 
 342 #endif
 343 }
 344 
 345 asmlinkage int sys_ioperm(unsigned long from, unsigned long num, int on)
     /* [previous][next][first][last][top][bottom][index][help] */
 346 {
 347         return -EIO;
 348 }
 349 
 350 /* BUFFER is PAGE_SIZE bytes long. */
 351 
 352 extern char *sparc_cpu_type[];
 353 extern char *sparc_fpu_type[];
 354 
 355 extern char *smp_info(void);
 356 
 357 int get_cpuinfo(char *buffer)
     /* [previous][next][first][last][top][bottom][index][help] */
 358 {
 359         int cpuid=get_cpuid();
 360 
 361         return sprintf(buffer, "cpu\t\t: %s\n"
 362             "fpu\t\t: %s\n"
 363             "promlib\t\t: Version %d Revision %d\n"
 364             "type\t\t: %s\n"
 365             "Elf Support\t: %s\n"   /* I can't remember when I do --ralp */
 366 #ifndef __SMP__
 367             "BogoMips\t: %lu.%02lu\n"
 368 #else
 369             "Cpu0Bogo\t: %lu.%02lu\n"
 370             "Cpu1Bogo\t: %lu.%02lu\n"
 371             "Cpu2Bogo\t: %lu.%02lu\n"
 372             "Cpu3Bogo\t: %lu.%02lu\n"
 373 #endif
 374             "%s"
 375 #ifdef __SMP__
 376             "%s"
 377 #endif
 378             ,
 379             sparc_cpu_type[cpuid],
 380             sparc_fpu_type[cpuid],
 381 #if CONFIG_AP1000
 382             0, 0,
 383 #else
 384             romvec->pv_romvers, prom_rev,
 385 #endif
 386             &cputypval,
 387 #if CONFIG_BINFMT_ELF
 388             "yes",
 389 #else
 390             "no",
 391 #endif
 392 #ifndef __SMP__
 393             loops_per_sec/500000, (loops_per_sec/5000) % 100,
 394 #else
 395             cpu_data[0].udelay_val/500000, (cpu_data[0].udelay_val/5000)%100,
 396             cpu_data[1].udelay_val/500000, (cpu_data[1].udelay_val/5000)%100,
 397             cpu_data[2].udelay_val/500000, (cpu_data[2].udelay_val/5000)%100,
 398             cpu_data[3].udelay_val/500000, (cpu_data[3].udelay_val/5000)%100,
 399 #endif
 400             mmu_info()
 401 #ifdef __SMP__
 402             , smp_info()
 403 #endif
 404             );
 405 
 406 }

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