1 /* 2 * Copyright (c) 1988 University of Utah. 3 * Copyright (c) 1992, 1993 4 * The Regents of the University of California. All rights reserved. 5 * 6 * This code is derived from software contributed to Berkeley by 7 * the Systems Programming Group of the University of Utah Computer 8 * Science Department, The Mach Operating System project at 9 * Carnegie-Mellon University and Ralph Campbell. 10 * 11 * %sccs.include.redist.c% 12 * 13 * @(#)machdep.c 8.1 (Berkeley) 06/16/93 14 */ 15 16 /* from: Utah $Hdr: machdep.c 1.63 91/04/24$ */ 17 18 #include <sys/param.h> 19 #include <sys/systm.h> 20 #include <sys/signalvar.h> 21 #include <sys/kernel.h> 22 #include <sys/map.h> 23 #include <sys/proc.h> 24 #include <sys/buf.h> 25 #include <sys/reboot.h> 26 #include <sys/conf.h> 27 #include <sys/file.h> 28 #include <sys/clist.h> 29 #include <sys/callout.h> 30 #include <sys/malloc.h> 31 #include <sys/mbuf.h> 32 #include <sys/msgbuf.h> 33 #include <sys/ioctl.h> 34 #include <sys/tty.h> 35 #include <sys/user.h> 36 #include <sys/exec.h> 37 #include <sys/sysctl.h> 38 #ifdef SYSVSHM 39 #include <sys/shm.h> 40 #endif 41 42 #include <vm/vm_kern.h> 43 44 #include <machine/cpu.h> 45 #include <machine/reg.h> 46 #include <machine/psl.h> 47 #include <machine/pte.h> 48 #include <machine/dc7085cons.h> 49 50 #include <pmax/stand/dec_prom.h> 51 52 #include <pmax/dev/device.h> 53 #include <pmax/dev/sccreg.h> 54 #include <pmax/dev/ascreg.h> 55 56 #include <pmax/pmax/clockreg.h> 57 #include <pmax/pmax/kn01.h> 58 #include <pmax/pmax/kn02.h> 59 #include <pmax/pmax/kmin.h> 60 #include <pmax/pmax/maxine.h> 61 #include <pmax/pmax/kn03.h> 62 #include <pmax/pmax/asic.h> 63 #include <pmax/pmax/turbochannel.h> 64 #include <pmax/pmax/pmaxtype.h> 65 #include <pmax/pmax/cons.h> 66 67 #include <pm.h> 68 #include <cfb.h> 69 #include <mfb.h> 70 #include <xcfb.h> 71 #include <dc.h> 72 #include <dtop.h> 73 #include <scc.h> 74 #include <le.h> 75 #include <asc.h> 76 77 #if NDC > 0 78 extern int dcGetc(), dcparam(); 79 extern void dcPutc(); 80 #endif 81 #if NDTOP > 0 82 extern int dtopKBDGetc(); 83 #endif 84 #if NSCC > 0 85 extern int sccGetc(), sccparam(); 86 extern void sccPutc(); 87 #endif 88 extern int KBDGetc(); 89 extern void fbPutc(); 90 extern struct consdev cn_tab; 91 92 /* Will scan from max to min, inclusive */ 93 static int tc_max_slot = KN02_TC_MAX; 94 static int tc_min_slot = KN02_TC_MIN; 95 static u_int tc_slot_phys_base [TC_MAX_SLOTS] = { 96 /* use 3max for default values */ 97 KN02_PHYS_TC_0_START, KN02_PHYS_TC_1_START, 98 KN02_PHYS_TC_2_START, KN02_PHYS_TC_3_START, 99 KN02_PHYS_TC_4_START, KN02_PHYS_TC_5_START, 100 KN02_PHYS_TC_6_START, KN02_PHYS_TC_7_START 101 }; 102 103 /* the following is used externally (sysctl_hw) */ 104 char machine[] = "DEC"; /* cpu "architecture" */ 105 char cpu_model[30]; 106 107 vm_map_t buffer_map; 108 109 /* 110 * Declare these as initialized data so we can patch them. 111 */ 112 int nswbuf = 0; 113 #ifdef NBUF 114 int nbuf = NBUF; 115 #else 116 int nbuf = 0; 117 #endif 118 #ifdef BUFPAGES 119 int bufpages = BUFPAGES; 120 #else 121 int bufpages = 0; 122 #endif 123 int msgbufmapped = 0; /* set when safe to use msgbuf */ 124 int maxmem; /* max memory per process */ 125 int physmem; /* max supported memory, changes to actual */ 126 int pmax_boardtype; /* Mother board type */ 127 u_long le_iomem; /* 128K for lance chip via. ASIC */ 128 u_long asc_iomem; /* and 7 * 8K buffers for the scsi */ 129 u_long asic_base; /* Base address of I/O asic */ 130 const struct callback *callv; /* pointer to PROM entry points */ 131 132 void (*tc_enable_interrupt)(); 133 extern int (*pmax_hardware_intr)(); 134 void pmax_slot_hand_fill(); 135 int kn02_intr(), kmin_intr(), xine_intr(), pmax_intr(); 136 #ifdef DS5000_240 137 int kn03_intr(); 138 #endif 139 extern int Mach_spl0(), Mach_spl1(), Mach_spl2(), Mach_spl3(), splhigh(); 140 int (*Mach_splnet)() = splhigh; 141 int (*Mach_splbio)() = splhigh; 142 int (*Mach_splimp)() = splhigh; 143 int (*Mach_spltty)() = splhigh; 144 int (*Mach_splclock)() = splhigh; 145 int (*Mach_splstatclock)() = splhigh; 146 void (*tc_slot_hand_fill)(); 147 extern volatile struct chiptime *Mach_clock_addr; 148 u_long kmin_tc3_imask, xine_tc3_imask; 149 #ifdef DS5000_240 150 u_long kn03_tc3_imask; 151 #endif 152 tc_option_t tc_slot_info[TC_MAX_LOGICAL_SLOTS]; 153 static void asic_init(); 154 extern void RemconsInit(); 155 #ifdef DS5000 156 void kn02_enable_intr(), kn02_slot_hand_fill(), 157 kmin_enable_intr(), kmin_slot_hand_fill(), 158 xine_enable_intr(), xine_slot_hand_fill(), 159 tc_find_all_options(); 160 #ifdef DS5000_240 161 void kn03_enable_intr(), kn03_slot_hand_fill(); 162 #endif 163 #endif /* DS5000 */ 164 165 /* 166 * safepri is a safe priority for sleep to set for a spin-wait 167 * during autoconfiguration or after a panic. 168 */ 169 int safepri = PSL_LOWIPL; 170 171 struct user *proc0paddr; 172 struct proc nullproc; /* for use by swtch_exit() */ 173 174 /* 175 * Do all the stuff that locore normally does before calling main(). 176 * Process arguments passed to us by the prom monitor. 177 * Return the first page address following the system. 178 */ 179 mach_init(argc, argv, code, cv) 180 int argc; 181 char *argv[]; 182 u_int code; 183 const struct callback *cv; 184 { 185 register char *cp; 186 register int i; 187 register unsigned firstaddr; 188 register caddr_t v; 189 caddr_t start; 190 extern char edata[], end[]; 191 extern char MachUTLBMiss[], MachUTLBMissEnd[]; 192 extern char MachException[], MachExceptionEnd[]; 193 194 /* clear the BSS segment */ 195 v = (caddr_t)pmax_round_page(end); 196 bzero(edata, v - edata); 197 198 /* check for direct boot from DS5000 PROM */ 199 if (argc > 0 && strcmp(argv[0], "boot") == 0) { 200 argc--; 201 argv++; 202 } 203 204 /* look at argv[0] and compute bootdev */ 205 makebootdev(argv[0]); 206 207 /* 208 * Look at arguments passed to us and compute boothowto. 209 */ 210 #ifdef GENERIC 211 boothowto = RB_SINGLE | RB_ASKNAME; 212 #else 213 boothowto = RB_SINGLE; 214 #endif 215 #ifdef KADB 216 boothowto |= RB_KDB; 217 #endif 218 if (argc > 1) { 219 for (i = 1; i < argc; i++) { 220 for (cp = argv[i]; *cp; cp++) { 221 switch (*cp) { 222 case 'a': /* autoboot */ 223 boothowto &= ~RB_SINGLE; 224 break; 225 226 case 'd': /* use compiled in default root */ 227 boothowto |= RB_DFLTROOT; 228 break; 229 230 case 'm': /* mini root present in memory */ 231 boothowto |= RB_MINIROOT; 232 break; 233 234 case 'n': /* ask for names */ 235 boothowto |= RB_ASKNAME; 236 break; 237 238 case 'N': /* don't ask for names */ 239 boothowto &= ~RB_ASKNAME; 240 } 241 } 242 } 243 } 244 245 #ifdef MFS 246 /* 247 * Check to see if a mini-root was loaded into memory. It resides 248 * at the start of the next page just after the end of BSS. 249 */ 250 if (boothowto & RB_MINIROOT) { 251 boothowto |= RB_DFLTROOT; 252 v += mfs_initminiroot(v); 253 } 254 #endif 255 256 /* 257 * Init mapping for u page(s) for proc[0], pm_tlbpid 1. 258 */ 259 start = v; 260 curproc->p_addr = proc0paddr = (struct user *)v; 261 curproc->p_md.md_regs = proc0paddr->u_pcb.pcb_regs; 262 firstaddr = MACH_CACHED_TO_PHYS(v); 263 for (i = 0; i < UPAGES; i++) { 264 MachTLBWriteIndexed(i, 265 (UADDR + (i << PGSHIFT)) | (1 << VMMACH_TLB_PID_SHIFT), 266 curproc->p_md.md_upte[i] = firstaddr | PG_V | PG_M); 267 firstaddr += NBPG; 268 } 269 v += UPAGES * NBPG; 270 MachSetPID(1); 271 272 /* 273 * init nullproc for swtch_exit(). 274 * init mapping for u page(s), pm_tlbpid 0 275 * This could be used for an idle process. 276 */ 277 nullproc.p_addr = (struct user *)v; 278 nullproc.p_md.md_regs = nullproc.p_addr->u_pcb.pcb_regs; 279 bcopy("nullproc", nullproc.p_comm, sizeof("nullproc")); 280 for (i = 0; i < UPAGES; i++) { 281 nullproc.p_md.md_upte[i] = firstaddr | PG_V | PG_M; 282 firstaddr += NBPG; 283 } 284 v += UPAGES * NBPG; 285 286 /* clear pages for u areas */ 287 bzero(start, v - start); 288 289 /* 290 * Copy down exception vector code. 291 */ 292 if (MachUTLBMissEnd - MachUTLBMiss > 0x80) 293 panic("startup: UTLB code too large"); 294 bcopy(MachUTLBMiss, (char *)MACH_UTLB_MISS_EXC_VEC, 295 MachUTLBMissEnd - MachUTLBMiss); 296 bcopy(MachException, (char *)MACH_GEN_EXC_VEC, 297 MachExceptionEnd - MachException); 298 299 /* 300 * Clear out the I and D caches. 301 */ 302 MachConfigCache(); 303 MachFlushCache(); 304 305 /* 306 * Determine what model of computer we are running on. 307 */ 308 if (code == DEC_PROM_MAGIC) { 309 callv = cv; 310 i = (*cv->getsysid)(); 311 cp = ""; 312 } else { 313 callv = &callvec; 314 if (cp = (*callv->getenv)("systype")) 315 i = atoi(cp); 316 else { 317 cp = ""; 318 i = 0; 319 } 320 } 321 /* check for MIPS based platform */ 322 if (((i >> 24) & 0xFF) != 0x82) { 323 printf("Unknown System type '%s' 0x%x\n", cp, i); 324 boot(RB_HALT | RB_NOSYNC); 325 } 326 327 /* check what model platform we are running on */ 328 pmax_boardtype = ((i >> 16) & 0xff); 329 switch (pmax_boardtype) { 330 case DS_PMAX: /* DS3100 Pmax */ 331 /* 332 * Set up interrupt handling and I/O addresses. 333 */ 334 pmax_hardware_intr = pmax_intr; 335 Mach_splnet = Mach_spl1; 336 Mach_splbio = Mach_spl0; 337 Mach_splimp = Mach_spl1; 338 Mach_spltty = Mach_spl2; 339 Mach_splclock = Mach_spl3; 340 Mach_splstatclock = Mach_spl3; 341 Mach_clock_addr = (volatile struct chiptime *) 342 MACH_PHYS_TO_UNCACHED(KN01_SYS_CLOCK); 343 pmax_slot_hand_fill(); 344 strcpy(cpu_model, "3100"); 345 break; 346 347 #ifdef DS5000 348 case DS_3MAX: /* DS5000/200 3max */ 349 { 350 volatile int *csr_addr = 351 (volatile int *)MACH_PHYS_TO_UNCACHED(KN02_SYS_CSR); 352 353 /* disable all TURBOchannel interrupts */ 354 i = *csr_addr; 355 *csr_addr = i & ~(KN02_CSR_WRESERVED | 0xFF); 356 357 tc_slot_hand_fill = kn02_slot_hand_fill; 358 pmax_hardware_intr = kn02_intr; 359 tc_enable_interrupt = kn02_enable_intr; 360 Mach_splnet = Mach_spl0; 361 Mach_splbio = Mach_spl0; 362 Mach_splimp = Mach_spl0; 363 Mach_spltty = Mach_spl0; 364 Mach_splclock = Mach_spl1; 365 Mach_splstatclock = Mach_spl1; 366 Mach_clock_addr = (volatile struct chiptime *) 367 MACH_PHYS_TO_UNCACHED(KN02_SYS_CLOCK); 368 369 /* 370 * Probe the TURBOchannel to see what controllers are present. 371 */ 372 tc_find_all_options(); 373 374 /* clear any memory errors from probes */ 375 *(unsigned *)MACH_PHYS_TO_UNCACHED(KN02_SYS_ERRADR) = 0; 376 } 377 strcpy(cpu_model, "5000/200"); 378 break; 379 380 case DS_3MIN: /* DS5000/1xx 3min */ 381 tc_max_slot = KMIN_TC_MAX; 382 tc_min_slot = KMIN_TC_MIN; 383 tc_slot_phys_base[0] = KMIN_PHYS_TC_0_START; 384 tc_slot_phys_base[1] = KMIN_PHYS_TC_1_START; 385 tc_slot_phys_base[2] = KMIN_PHYS_TC_2_START; 386 asic_base = MACH_PHYS_TO_UNCACHED(KMIN_SYS_ASIC); 387 tc_slot_hand_fill = kmin_slot_hand_fill; 388 pmax_hardware_intr = kmin_intr; 389 tc_enable_interrupt = kmin_enable_intr; 390 kmin_tc3_imask = (KMIN_INTR_CLOCK | KMIN_INTR_PSWARN | 391 KMIN_INTR_TIMEOUT); 392 393 /* 394 * Since all the motherboard interrupts come through the 395 * I/O ASIC, it has to be turned off for all the spls and 396 * since we don't know what kinds of devices are in the 397 * turbochannel option slots, just splhigh(). 398 */ 399 Mach_splnet = splhigh; 400 Mach_splbio = splhigh; 401 Mach_splimp = splhigh; 402 Mach_spltty = splhigh; 403 Mach_splclock = splhigh; 404 Mach_splstatclock = splhigh; 405 Mach_clock_addr = (volatile struct chiptime *) 406 MACH_PHYS_TO_UNCACHED(KMIN_SYS_CLOCK); 407 408 /* 409 * Probe the TURBOchannel to see what controllers are present. 410 */ 411 tc_find_all_options(); 412 413 /* 414 * Initialize interrupts. 415 */ 416 *(u_int *)ASIC_REG_IMSK(asic_base) = KMIN_IM0; 417 *(u_int *)ASIC_REG_INTR(asic_base) = 0; 418 /* clear any memory errors from probes */ 419 *(unsigned *)MACH_PHYS_TO_UNCACHED(KMIN_REG_TIMEOUT) = 0; 420 strcpy(cpu_model, "5000/1xx"); 421 break; 422 423 case DS_MAXINE: /* DS5000/xx maxine */ 424 tc_max_slot = XINE_TC_MAX; 425 tc_min_slot = XINE_TC_MIN; 426 tc_slot_phys_base[0] = XINE_PHYS_TC_0_START; 427 tc_slot_phys_base[1] = XINE_PHYS_TC_1_START; 428 asic_base = MACH_PHYS_TO_UNCACHED(XINE_SYS_ASIC); 429 tc_slot_hand_fill = xine_slot_hand_fill; 430 pmax_hardware_intr = xine_intr; 431 tc_enable_interrupt = xine_enable_intr; 432 Mach_splnet = Mach_spl3; 433 Mach_splbio = Mach_spl3; 434 Mach_splimp = Mach_spl3; 435 Mach_spltty = Mach_spl3; 436 Mach_splclock = Mach_spl1; 437 Mach_splstatclock = Mach_spl1; 438 Mach_clock_addr = (volatile struct chiptime *) 439 MACH_PHYS_TO_UNCACHED(XINE_SYS_CLOCK); 440 441 /* 442 * Probe the TURBOchannel to see what controllers are present. 443 */ 444 tc_find_all_options(); 445 446 /* 447 * Initialize interrupts. 448 */ 449 *(u_int *)ASIC_REG_IMSK(asic_base) = XINE_IM0; 450 *(u_int *)ASIC_REG_INTR(asic_base) = 0; 451 /* clear any memory errors from probes */ 452 *(unsigned *)MACH_PHYS_TO_UNCACHED(XINE_REG_TIMEOUT) = 0; 453 strcpy(cpu_model, "5000/25"); 454 break; 455 456 #ifdef DS5000_240 457 case DS_3MAXPLUS: /* DS5000/240 3max+ UNTESTED!! */ 458 tc_max_slot = KN03_TC_MAX; 459 tc_min_slot = KN03_TC_MIN; 460 tc_slot_phys_base[0] = KN03_PHYS_TC_0_START; 461 tc_slot_phys_base[1] = KN03_PHYS_TC_1_START; 462 tc_slot_phys_base[2] = KN03_PHYS_TC_2_START; 463 asic_base = MACH_PHYS_TO_UNCACHED(KN03_SYS_ASIC); 464 tc_slot_hand_fill = kn03_slot_hand_fill; 465 pmax_hardware_intr = kn03_intr; 466 tc_enable_interrupt = kn03_enable_intr; 467 kn03_tc3_imask = KN03_INTR_PSWARN; 468 469 Mach_splnet = Mach_spl0; 470 Mach_splbio = Mach_spl0; 471 Mach_splimp = Mach_spl0; 472 Mach_spltty = Mach_spl0; 473 Mach_splclock = Mach_spl1; 474 Mach_splstatclock = Mach_spl1; 475 Mach_clock_addr = (volatile struct chiptime *) 476 MACH_PHYS_TO_UNCACHED(KN03_SYS_CLOCK); 477 478 /* 479 * Probe the TURBOchannel to see what controllers are present. 480 */ 481 tc_find_all_options(); 482 483 /* 484 * Initialize interrupts. 485 */ 486 *(u_int *)ASIC_REG_IMSK(asic_base) = KN03_IM0; 487 *(u_int *)ASIC_REG_INTR(asic_base) = 0; 488 /* clear any memory errors from probes */ 489 *(unsigned *)MACH_PHYS_TO_UNCACHED(KN03_SYS_ERRADR) = 0; 490 strcpy(cpu_model, "5000/240"); 491 break; 492 #endif /* DS5000_240 */ 493 #endif /* DS5000 */ 494 495 default: 496 printf("kernel not configured for systype 0x%x\n", i); 497 boot(RB_HALT | RB_NOSYNC); 498 } 499 500 /* 501 * Find out how much memory is available. 502 */ 503 physmem = btoc(v - KERNBASE); 504 cp = (char *)MACH_PHYS_TO_UNCACHED(physmem << PGSHIFT); 505 while (cp < (char *)MACH_MAX_MEM_ADDR) { 506 if (badaddr(cp, 4)) 507 break; 508 *(int *)cp = 0xa5a5a5a5; 509 /* 510 * Data will persist on the bus if we read it right 511 * away. Have to be tricky here. 512 */ 513 ((int *)cp)[4] = 0x5a5a5a5a; 514 MachEmptyWriteBuffer(); 515 if (*(int *)cp != 0xa5a5a5a5) 516 break; 517 cp += NBPG; 518 physmem++; 519 } 520 521 maxmem = physmem; 522 523 #if NLE > 0 524 /* 525 * Grab 128K at the top of physical memory for the lance chip 526 * on machines where it does dma through the I/O ASIC. 527 * It must be physically contiguous and aligned on a 128K boundary. 528 */ 529 if (pmax_boardtype == DS_3MIN || pmax_boardtype == DS_MAXINE || 530 pmax_boardtype == DS_3MAXPLUS) { 531 maxmem -= btoc(128 * 1024); 532 le_iomem = (maxmem << PGSHIFT); 533 } 534 #endif /* NLE */ 535 #if NASC > 0 536 /* 537 * Ditto for the scsi chip. There is probably a way to make asc.c 538 * do dma without these buffers, but it would require major 539 * re-engineering of the asc driver. 540 * They must be 8K in size and page aligned. 541 */ 542 if (pmax_boardtype == DS_3MIN || pmax_boardtype == DS_MAXINE || 543 pmax_boardtype == DS_3MAXPLUS) { 544 maxmem -= btoc(ASC_NCMD * 8192); 545 asc_iomem = (maxmem << PGSHIFT); 546 } 547 #endif /* NASC */ 548 549 /* 550 * Initialize error message buffer (at end of core). 551 */ 552 maxmem -= btoc(sizeof (struct msgbuf)); 553 msgbufp = (struct msgbuf *)(MACH_PHYS_TO_CACHED(maxmem << PGSHIFT)); 554 msgbufmapped = 1; 555 556 /* 557 * Allocate space for system data structures. 558 * The first available kernel virtual address is in "v". 559 * As pages of kernel virtual memory are allocated, "v" is incremented. 560 * 561 * These data structures are allocated here instead of cpu_startup() 562 * because physical memory is directly addressable. We don't have 563 * to map these into virtual address space. 564 */ 565 start = v; 566 567 #define valloc(name, type, num) \ 568 (name) = (type *)v; v = (caddr_t)((name)+(num)) 569 #define valloclim(name, type, num, lim) \ 570 (name) = (type *)v; v = (caddr_t)((lim) = ((name)+(num))) 571 valloc(cfree, struct cblock, nclist); 572 valloc(callout, struct callout, ncallout); 573 valloc(swapmap, struct map, nswapmap = maxproc * 2); 574 #ifdef SYSVSHM 575 valloc(shmsegs, struct shmid_ds, shminfo.shmmni); 576 #endif 577 578 /* 579 * Determine how many buffers to allocate. 580 * We allocate more buffer space than the BSD standard of 581 * using 10% of memory for the first 2 Meg, 5% of remaining. 582 * We just allocate a flat 10%. Insure a minimum of 16 buffers. 583 * We allocate 1/2 as many swap buffer headers as file i/o buffers. 584 */ 585 if (bufpages == 0) 586 bufpages = physmem / 10 / CLSIZE; 587 if (nbuf == 0) { 588 nbuf = bufpages; 589 if (nbuf < 16) 590 nbuf = 16; 591 } 592 if (nswbuf == 0) { 593 nswbuf = (nbuf / 2) &~ 1; /* force even */ 594 if (nswbuf > 256) 595 nswbuf = 256; /* sanity */ 596 } 597 valloc(swbuf, struct buf, nswbuf); 598 valloc(buf, struct buf, nbuf); 599 600 /* 601 * Clear allocated memory. 602 */ 603 bzero(start, v - start); 604 605 /* 606 * Initialize the virtual memory system. 607 */ 608 pmap_bootstrap((vm_offset_t)v); 609 } 610 611 /* 612 * Console initialization: called early on from main, 613 * before vm init or startup. Do enough configuration 614 * to choose and initialize a console. 615 */ 616 consinit() 617 { 618 register int kbd, crt; 619 register char *oscon; 620 621 /* 622 * First get the "osconsole" environment variable. 623 */ 624 oscon = (*callv->getenv)("osconsole"); 625 crt = kbd = -1; 626 if (oscon && *oscon >= '0' && *oscon <= '9') { 627 kbd = *oscon - '0'; 628 cn_tab.cn_screen = 0; 629 while (*++oscon) { 630 if (*oscon == ',') 631 cn_tab.cn_screen = 1; 632 else if (cn_tab.cn_screen && 633 *oscon >= '0' && *oscon <= '9') { 634 crt = kbd; 635 kbd = *oscon - '0'; 636 break; 637 } 638 } 639 } 640 if (pmax_boardtype == DS_PMAX && kbd == 1) 641 cn_tab.cn_screen = 1; 642 /* 643 * The boot program uses PMAX ROM entrypoints so the ROM sets 644 * osconsole to '1' like the PMAX. 645 */ 646 if (pmax_boardtype == DS_3MAX && crt == -1 && kbd == 1) { 647 cn_tab.cn_screen = 1; 648 crt = 0; 649 kbd = 7; 650 } 651 652 /* 653 * First try the keyboard/crt cases then fall through to the 654 * remote serial lines. 655 */ 656 if (cn_tab.cn_screen) { 657 switch (pmax_boardtype) { 658 case DS_PMAX: 659 #if NDC > 0 && NPM > 0 660 if (pminit()) { 661 cn_tab.cn_dev = makedev(DCDEV, DCKBD_PORT); 662 cn_tab.cn_getc = KBDGetc; 663 cn_tab.cn_kbdgetc = dcGetc; 664 cn_tab.cn_putc = fbPutc; 665 cn_tab.cn_disabled = 0; 666 return; 667 } 668 #endif /* NDC and NPM */ 669 goto remcons; 670 671 case DS_MAXINE: 672 #if NDTOP > 0 673 if (kbd == 3) { 674 cn_tab.cn_dev = makedev(DTOPDEV, 0); 675 cn_tab.cn_getc = dtopKBDGetc; 676 cn_tab.cn_putc = fbPutc; 677 } else 678 #endif /* NDTOP */ 679 goto remcons; 680 #if NXCFB > 0 681 if (crt == 3 && xcfbinit()) { 682 cn_tab.cn_disabled = 0; 683 return; 684 } 685 #endif /* XCFB */ 686 break; 687 688 case DS_3MAX: 689 #if NDC > 0 690 if (kbd == 7) { 691 cn_tab.cn_dev = makedev(DCDEV, DCKBD_PORT); 692 cn_tab.cn_getc = KBDGetc; 693 cn_tab.cn_kbdgetc = dcGetc; 694 cn_tab.cn_putc = fbPutc; 695 } else 696 #endif /* NDC */ 697 goto remcons; 698 break; 699 700 case DS_3MIN: 701 case DS_3MAXPLUS: 702 #if NSCC > 0 703 if (kbd == 3) { 704 cn_tab.cn_dev = makedev(SCCDEV, SCCKBD_PORT); 705 cn_tab.cn_getc = KBDGetc; 706 cn_tab.cn_kbdgetc = sccGetc; 707 cn_tab.cn_putc = fbPutc; 708 } else 709 #endif /* NSCC */ 710 goto remcons; 711 break; 712 713 default: 714 goto remcons; 715 }; 716 717 /* 718 * Check for a suitable turbochannel frame buffer. 719 */ 720 if (tc_slot_info[crt].driver_name) { 721 #if NMFB > 0 722 if (strcmp(tc_slot_info[crt].driver_name, "mfb") == 0 && 723 mfbinit(tc_slot_info[crt].k1seg_address)) { 724 cn_tab.cn_disabled = 0; 725 return; 726 } 727 #endif /* NMFB */ 728 #if NCFB > 0 729 if (strcmp(tc_slot_info[crt].driver_name, "cfb") == 0 && 730 cfbinit(tc_slot_info[crt].k1seg_address)) { 731 cn_tab.cn_disabled = 0; 732 return; 733 } 734 #endif /* NCFB */ 735 printf("crt: %s not supported as console device\n", 736 tc_slot_info[crt].driver_name); 737 } else 738 printf("No crt console device in slot %d\n", crt); 739 } 740 remcons: 741 /* 742 * Configure a serial port as a remote console. 743 */ 744 cn_tab.cn_screen = 0; 745 switch (pmax_boardtype) { 746 case DS_PMAX: 747 #if NDC > 0 748 if (kbd == 4) 749 cn_tab.cn_dev = makedev(DCDEV, DCCOMM_PORT); 750 else 751 cn_tab.cn_dev = makedev(DCDEV, DCPRINTER_PORT); 752 cn_tab.cn_getc = dcGetc; 753 cn_tab.cn_putc = dcPutc; 754 #endif /* NDC */ 755 break; 756 757 case DS_3MAX: 758 #if NDC > 0 759 cn_tab.cn_dev = makedev(DCDEV, DCPRINTER_PORT); 760 cn_tab.cn_getc = dcGetc; 761 cn_tab.cn_putc = dcPutc; 762 #endif /* NDC */ 763 break; 764 765 case DS_3MIN: 766 case DS_3MAXPLUS: 767 #if NSCC > 0 768 cn_tab.cn_dev = makedev(SCCDEV, SCCCOMM3_PORT); 769 cn_tab.cn_getc = sccGetc; 770 cn_tab.cn_putc = sccPutc; 771 #endif /* NSCC */ 772 break; 773 774 case DS_MAXINE: 775 #if NSCC > 0 776 cn_tab.cn_dev = makedev(SCCDEV, SCCCOMM2_PORT); 777 cn_tab.cn_getc = sccGetc; 778 cn_tab.cn_putc = sccPutc; 779 #endif /* NSCC */ 780 break; 781 }; 782 if (cn_tab.cn_dev == NODEV) 783 printf("Can't configure console!\n"); 784 } 785 786 /* 787 * cpu_startup: allocate memory for variable-sized tables, 788 * initialize cpu, and do autoconfiguration. 789 */ 790 cpu_startup() 791 { 792 register unsigned i; 793 register caddr_t v; 794 int base, residual; 795 vm_offset_t minaddr, maxaddr; 796 vm_size_t size; 797 #ifdef DEBUG 798 extern int pmapdebug; 799 int opmapdebug = pmapdebug; 800 801 pmapdebug = 0; 802 #endif 803 804 /* 805 * Good {morning,afternoon,evening,night}. 806 */ 807 printf(version); 808 printf("real mem = %d\n", ctob(physmem)); 809 810 /* 811 * Allocate virtual address space for file I/O buffers. 812 * Note they are different than the array of headers, 'buf', 813 * and usually occupy more virtual memory than physical. 814 */ 815 size = MAXBSIZE * nbuf; 816 buffer_map = kmem_suballoc(kernel_map, (vm_offset_t *)&buffers, 817 &maxaddr, size, FALSE); 818 minaddr = (vm_offset_t)buffers; 819 if (vm_map_find(buffer_map, vm_object_allocate(size), (vm_offset_t)0, 820 &minaddr, size, FALSE) != KERN_SUCCESS) 821 panic("startup: cannot allocate buffers"); 822 base = bufpages / nbuf; 823 residual = bufpages % nbuf; 824 for (i = 0; i < nbuf; i++) { 825 vm_size_t curbufsize; 826 vm_offset_t curbuf; 827 828 /* 829 * First <residual> buffers get (base+1) physical pages 830 * allocated for them. The rest get (base) physical pages. 831 * 832 * The rest of each buffer occupies virtual space, 833 * but has no physical memory allocated for it. 834 */ 835 curbuf = (vm_offset_t)buffers + i * MAXBSIZE; 836 curbufsize = CLBYTES * (i < residual ? base+1 : base); 837 vm_map_pageable(buffer_map, curbuf, curbuf+curbufsize, FALSE); 838 vm_map_simplify(buffer_map, curbuf); 839 } 840 /* 841 * Allocate a submap for exec arguments. This map effectively 842 * limits the number of processes exec'ing at any time. 843 */ 844 exec_map = kmem_suballoc(kernel_map, &minaddr, &maxaddr, 845 16 * NCARGS, TRUE); 846 /* 847 * Allocate a submap for physio 848 */ 849 phys_map = kmem_suballoc(kernel_map, &minaddr, &maxaddr, 850 VM_PHYS_SIZE, TRUE); 851 852 /* 853 * Finally, allocate mbuf pool. Since mclrefcnt is an off-size 854 * we use the more space efficient malloc in place of kmem_alloc. 855 */ 856 mclrefcnt = (char *)malloc(NMBCLUSTERS+CLBYTES/MCLBYTES, 857 M_MBUF, M_NOWAIT); 858 bzero(mclrefcnt, NMBCLUSTERS+CLBYTES/MCLBYTES); 859 mb_map = kmem_suballoc(kernel_map, (vm_offset_t *)&mbutl, &maxaddr, 860 VM_MBUF_SIZE, FALSE); 861 /* 862 * Initialize callouts 863 */ 864 callfree = callout; 865 for (i = 1; i < ncallout; i++) 866 callout[i-1].c_next = &callout[i]; 867 callout[i-1].c_next = NULL; 868 869 #ifdef DEBUG 870 pmapdebug = opmapdebug; 871 #endif 872 printf("avail mem = %d\n", ptoa(cnt.v_free_count)); 873 printf("using %d buffers containing %d bytes of memory\n", 874 nbuf, bufpages * CLBYTES); 875 /* 876 * Set up CPU-specific registers, cache, etc. 877 */ 878 initcpu(); 879 880 /* 881 * Set up buffers, so they can be used to read disk labels. 882 */ 883 bufinit(); 884 885 /* 886 * Configure the system. 887 */ 888 configure(); 889 } 890 891 /* 892 * machine dependent system variables. 893 */ 894 cpu_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p) 895 int *name; 896 u_int namelen; 897 void *oldp; 898 size_t *oldlenp; 899 void *newp; 900 size_t newlen; 901 struct proc *p; 902 { 903 904 /* all sysctl names at this level are terminal */ 905 if (namelen != 1) 906 return (ENOTDIR); /* overloaded */ 907 908 switch (name[0]) { 909 case CPU_CONSDEV: 910 return (sysctl_rdstruct(oldp, oldlenp, newp, &cn_tab.cn_dev, 911 sizeof cn_tab.cn_dev)); 912 default: 913 return (EOPNOTSUPP); 914 } 915 /* NOTREACHED */ 916 } 917 918 /* 919 * Set registers on exec. 920 * Clear all registers except sp, pc. 921 */ 922 setregs(p, entry, retval) 923 register struct proc *p; 924 u_long entry; 925 int retval[2]; 926 { 927 int sp = p->p_md.md_regs[SP]; 928 extern struct proc *machFPCurProcPtr; 929 930 bzero((caddr_t)p->p_md.md_regs, (FSR + 1) * sizeof(int)); 931 p->p_md.md_regs[SP] = sp; 932 p->p_md.md_regs[PC] = entry & ~3; 933 p->p_md.md_regs[PS] = PSL_USERSET; 934 p->p_md.md_flags & ~MDP_FPUSED; 935 if (machFPCurProcPtr == p) 936 machFPCurProcPtr = (struct proc *)0; 937 } 938 939 /* 940 * WARNING: code in locore.s assumes the layout shown for sf_signum 941 * thru sf_handler so... don't screw with them! 942 */ 943 struct sigframe { 944 int sf_signum; /* signo for handler */ 945 int sf_code; /* additional info for handler */ 946 struct sigcontext *sf_scp; /* context ptr for handler */ 947 sig_t sf_handler; /* handler addr for u_sigc */ 948 struct sigcontext sf_sc; /* actual context */ 949 }; 950 951 #ifdef DEBUG 952 int sigdebug = 0; 953 int sigpid = 0; 954 #define SDB_FOLLOW 0x01 955 #define SDB_KSTACK 0x02 956 #define SDB_FPSTATE 0x04 957 #endif 958 959 /* 960 * Send an interrupt to process. 961 */ 962 void 963 sendsig(catcher, sig, mask, code) 964 sig_t catcher; 965 int sig, mask; 966 unsigned code; 967 { 968 register struct proc *p = curproc; 969 register struct sigframe *fp; 970 register int *regs; 971 register struct sigacts *psp = p->p_sigacts; 972 int oonstack, fsize; 973 struct sigcontext ksc; 974 extern char sigcode[], esigcode[]; 975 976 regs = p->p_md.md_regs; 977 oonstack = psp->ps_sigstk.ss_flags & SA_ONSTACK; 978 /* 979 * Allocate and validate space for the signal handler 980 * context. Note that if the stack is in data space, the 981 * call to grow() is a nop, and the copyout() 982 * will fail if the process has not already allocated 983 * the space with a `brk'. 984 */ 985 fsize = sizeof(struct sigframe); 986 if ((psp->ps_flags & SAS_ALTSTACK) && 987 (psp->ps_sigstk.ss_flags & SA_ONSTACK) == 0 && 988 (psp->ps_sigonstack & sigmask(sig))) { 989 fp = (struct sigframe *)(psp->ps_sigstk.ss_base + 990 psp->ps_sigstk.ss_size - fsize); 991 psp->ps_sigstk.ss_flags |= SA_ONSTACK; 992 } else 993 fp = (struct sigframe *)(regs[SP] - fsize); 994 if ((unsigned)fp <= USRSTACK - ctob(p->p_vmspace->vm_ssize)) 995 (void)grow(p, (unsigned)fp); 996 #ifdef DEBUG 997 if ((sigdebug & SDB_FOLLOW) || 998 (sigdebug & SDB_KSTACK) && p->p_pid == sigpid) 999 printf("sendsig(%d): sig %d ssp %x usp %x scp %x\n", 1000 p->p_pid, sig, &oonstack, fp, &fp->sf_sc); 1001 #endif 1002 /* 1003 * Build the signal context to be used by sigreturn. 1004 */ 1005 ksc.sc_onstack = oonstack; 1006 ksc.sc_mask = mask; 1007 ksc.sc_pc = regs[PC]; 1008 ksc.sc_regs[ZERO] = 0xACEDBADE; /* magic number */ 1009 bcopy((caddr_t)®s[1], (caddr_t)&ksc.sc_regs[1], 1010 sizeof(ksc.sc_regs) - sizeof(int)); 1011 ksc.sc_fpused = p->p_md.md_flags & MDP_FPUSED; 1012 if (ksc.sc_fpused) { 1013 extern struct proc *machFPCurProcPtr; 1014 1015 /* if FPU has current state, save it first */ 1016 if (p == machFPCurProcPtr) 1017 MachSaveCurFPState(p); 1018 bcopy((caddr_t)&p->p_md.md_regs[F0], (caddr_t)ksc.sc_fpregs, 1019 sizeof(ksc.sc_fpregs)); 1020 } 1021 if (copyout((caddr_t)&ksc, (caddr_t)&fp->sf_sc, sizeof(ksc))) { 1022 /* 1023 * Process has trashed its stack; give it an illegal 1024 * instruction to halt it in its tracks. 1025 */ 1026 SIGACTION(p, SIGILL) = SIG_DFL; 1027 sig = sigmask(SIGILL); 1028 p->p_sigignore &= ~sig; 1029 p->p_sigcatch &= ~sig; 1030 p->p_sigmask &= ~sig; 1031 psignal(p, SIGILL); 1032 return; 1033 } 1034 /* 1035 * Build the argument list for the signal handler. 1036 */ 1037 regs[A0] = sig; 1038 regs[A1] = code; 1039 regs[A2] = (int)&fp->sf_sc; 1040 regs[A3] = (int)catcher; 1041 1042 regs[PC] = (int)catcher; 1043 regs[SP] = (int)fp; 1044 /* 1045 * Signal trampoline code is at base of user stack. 1046 */ 1047 regs[RA] = (int)PS_STRINGS - (esigcode - sigcode); 1048 #ifdef DEBUG 1049 if ((sigdebug & SDB_FOLLOW) || 1050 (sigdebug & SDB_KSTACK) && p->p_pid == sigpid) 1051 printf("sendsig(%d): sig %d returns\n", 1052 p->p_pid, sig); 1053 #endif 1054 } 1055 1056 /* 1057 * System call to cleanup state after a signal 1058 * has been taken. Reset signal mask and 1059 * stack state from context left by sendsig (above). 1060 * Return to previous pc and psl as specified by 1061 * context left by sendsig. Check carefully to 1062 * make sure that the user has not modified the 1063 * psl to gain improper priviledges or to cause 1064 * a machine fault. 1065 */ 1066 struct sigreturn_args { 1067 struct sigcontext *sigcntxp; 1068 }; 1069 /* ARGSUSED */ 1070 sigreturn(p, uap, retval) 1071 struct proc *p; 1072 struct sigreturn_args *uap; 1073 int *retval; 1074 { 1075 register struct sigcontext *scp; 1076 register int *regs; 1077 struct sigcontext ksc; 1078 int error; 1079 1080 scp = uap->sigcntxp; 1081 #ifdef DEBUG 1082 if (sigdebug & SDB_FOLLOW) 1083 printf("sigreturn: pid %d, scp %x\n", p->p_pid, scp); 1084 #endif 1085 regs = p->p_md.md_regs; 1086 /* 1087 * Test and fetch the context structure. 1088 * We grab it all at once for speed. 1089 */ 1090 error = copyin((caddr_t)scp, (caddr_t)&ksc, sizeof(ksc)); 1091 if (error || ksc.sc_regs[ZERO] != 0xACEDBADE) { 1092 #ifdef DEBUG 1093 if (!(sigdebug & SDB_FOLLOW)) 1094 printf("sigreturn: pid %d, scp %x\n", p->p_pid, scp); 1095 printf(" old sp %x ra %x pc %x\n", 1096 regs[SP], regs[RA], regs[PC]); 1097 printf(" new sp %x ra %x pc %x err %d z %x\n", 1098 ksc.sc_regs[SP], ksc.sc_regs[RA], ksc.sc_regs[PC], 1099 error, ksc.sc_regs[ZERO]); 1100 #endif 1101 return (EINVAL); 1102 } 1103 scp = &ksc; 1104 /* 1105 * Restore the user supplied information 1106 */ 1107 if (scp->sc_onstack & 01) 1108 p->p_sigacts->ps_sigstk.ss_flags |= SA_ONSTACK; 1109 else 1110 p->p_sigacts->ps_sigstk.ss_flags &= ~SA_ONSTACK; 1111 p->p_sigmask = scp->sc_mask &~ sigcantmask; 1112 regs[PC] = scp->sc_pc; 1113 bcopy((caddr_t)&scp->sc_regs[1], (caddr_t)®s[1], 1114 sizeof(scp->sc_regs) - sizeof(int)); 1115 if (scp->sc_fpused) 1116 bcopy((caddr_t)scp->sc_fpregs, (caddr_t)&p->p_md.md_regs[F0], 1117 sizeof(scp->sc_fpregs)); 1118 return (EJUSTRETURN); 1119 } 1120 1121 int waittime = -1; 1122 1123 boot(howto) 1124 register int howto; 1125 { 1126 1127 /* take a snap shot before clobbering any registers */ 1128 if (curproc) 1129 savectx(curproc->p_addr, 0); 1130 1131 #ifdef DEBUG 1132 if (panicstr) 1133 stacktrace(); 1134 #endif 1135 1136 boothowto = howto; 1137 if ((howto & RB_NOSYNC) == 0 && waittime < 0) { 1138 register struct buf *bp; 1139 int iter, nbusy; 1140 1141 waittime = 0; 1142 (void) spl0(); 1143 printf("syncing disks... "); 1144 /* 1145 * Release vnodes held by texts before sync. 1146 */ 1147 if (panicstr == 0) 1148 vnode_pager_umount(NULL); 1149 #ifdef notdef 1150 #include "fd.h" 1151 #if NFD > 0 1152 fdshutdown(); 1153 #endif 1154 #endif 1155 sync(&proc0, (void *)NULL, (int *)NULL); 1156 1157 for (iter = 0; iter < 20; iter++) { 1158 nbusy = 0; 1159 for (bp = &buf[nbuf]; --bp >= buf; ) 1160 if ((bp->b_flags & (B_BUSY|B_INVAL)) == B_BUSY) 1161 nbusy++; 1162 if (nbusy == 0) 1163 break; 1164 printf("%d ", nbusy); 1165 DELAY(40000 * iter); 1166 } 1167 if (nbusy) 1168 printf("giving up\n"); 1169 else 1170 printf("done\n"); 1171 /* 1172 * If we've been adjusting the clock, the todr 1173 * will be out of synch; adjust it now. 1174 */ 1175 resettodr(); 1176 } 1177 (void) splhigh(); /* extreme priority */ 1178 if (callv != &callvec) { 1179 if (howto & RB_HALT) 1180 (*callv->rex)('h'); 1181 else { 1182 if (howto & RB_DUMP) 1183 dumpsys(); 1184 (*callv->rex)('b'); 1185 } 1186 } else if (howto & RB_HALT) { 1187 volatile void (*f)() = (volatile void (*)())DEC_PROM_REINIT; 1188 1189 (*f)(); /* jump back to prom monitor */ 1190 } else { 1191 volatile void (*f)() = (volatile void (*)())DEC_PROM_AUTOBOOT; 1192 1193 if (howto & RB_DUMP) 1194 dumpsys(); 1195 (*f)(); /* jump back to prom monitor and do 'auto' cmd */ 1196 } 1197 /*NOTREACHED*/ 1198 } 1199 1200 int dumpmag = (int)0x8fca0101; /* magic number for savecore */ 1201 int dumpsize = 0; /* also for savecore */ 1202 long dumplo = 0; 1203 1204 dumpconf() 1205 { 1206 int nblks; 1207 1208 dumpsize = physmem; 1209 if (dumpdev != NODEV && bdevsw[major(dumpdev)].d_psize) { 1210 nblks = (*bdevsw[major(dumpdev)].d_psize)(dumpdev); 1211 if (dumpsize > btoc(dbtob(nblks - dumplo))) 1212 dumpsize = btoc(dbtob(nblks - dumplo)); 1213 else if (dumplo == 0) 1214 dumplo = nblks - btodb(ctob(physmem)); 1215 } 1216 /* 1217 * Don't dump on the first CLBYTES (why CLBYTES?) 1218 * in case the dump device includes a disk label. 1219 */ 1220 if (dumplo < btodb(CLBYTES)) 1221 dumplo = btodb(CLBYTES); 1222 } 1223 1224 /* 1225 * Doadump comes here after turning off memory management and 1226 * getting on the dump stack, either when called above, or by 1227 * the auto-restart code. 1228 */ 1229 dumpsys() 1230 { 1231 int error; 1232 1233 msgbufmapped = 0; 1234 if (dumpdev == NODEV) 1235 return; 1236 /* 1237 * For dumps during autoconfiguration, 1238 * if dump device has already configured... 1239 */ 1240 if (dumpsize == 0) 1241 dumpconf(); 1242 if (dumplo < 0) 1243 return; 1244 printf("\ndumping to dev %x, offset %d\n", dumpdev, dumplo); 1245 printf("dump "); 1246 switch (error = (*bdevsw[major(dumpdev)].d_dump)(dumpdev)) { 1247 1248 case ENXIO: 1249 printf("device bad\n"); 1250 break; 1251 1252 case EFAULT: 1253 printf("device not ready\n"); 1254 break; 1255 1256 case EINVAL: 1257 printf("area improper\n"); 1258 break; 1259 1260 case EIO: 1261 printf("i/o error\n"); 1262 break; 1263 1264 default: 1265 printf("error %d\n", error); 1266 break; 1267 1268 case 0: 1269 printf("succeeded\n"); 1270 } 1271 } 1272 1273 /* 1274 * Return the best possible estimate of the time in the timeval 1275 * to which tvp points. Unfortunately, we can't read the hardware registers. 1276 * We guarantee that the time will be greater than the value obtained by a 1277 * previous call. 1278 */ 1279 microtime(tvp) 1280 register struct timeval *tvp; 1281 { 1282 int s = splclock(); 1283 static struct timeval lasttime; 1284 1285 *tvp = time; 1286 #ifdef notdef 1287 tvp->tv_usec += clkread(); 1288 while (tvp->tv_usec > 1000000) { 1289 tvp->tv_sec++; 1290 tvp->tv_usec -= 1000000; 1291 } 1292 #endif 1293 if (tvp->tv_sec == lasttime.tv_sec && 1294 tvp->tv_usec <= lasttime.tv_usec && 1295 (tvp->tv_usec = lasttime.tv_usec + 1) > 1000000) { 1296 tvp->tv_sec++; 1297 tvp->tv_usec -= 1000000; 1298 } 1299 lasttime = *tvp; 1300 splx(s); 1301 } 1302 1303 initcpu() 1304 { 1305 register volatile struct chiptime *c; 1306 int i; 1307 1308 /* disable clock interrupts (until startrtclock()) */ 1309 c = Mach_clock_addr; 1310 c->regb = REGB_DATA_MODE | REGB_HOURS_FORMAT; 1311 i = c->regc; 1312 spl0(); /* safe to turn interrupts on now */ 1313 return (i); 1314 } 1315 1316 /* 1317 * Convert an ASCII string into an integer. 1318 */ 1319 int 1320 atoi(s) 1321 char *s; 1322 { 1323 int c; 1324 unsigned base = 10, d; 1325 int neg = 0, val = 0; 1326 1327 if (s == 0 || (c = *s++) == 0) 1328 goto out; 1329 1330 /* skip spaces if any */ 1331 while (c == ' ' || c == '\t') 1332 c = *s++; 1333 1334 /* parse sign, allow more than one (compat) */ 1335 while (c == '-') { 1336 neg = !neg; 1337 c = *s++; 1338 } 1339 1340 /* parse base specification, if any */ 1341 if (c == '0') { 1342 c = *s++; 1343 switch (c) { 1344 case 'X': 1345 case 'x': 1346 base = 16; 1347 break; 1348 case 'B': 1349 case 'b': 1350 base = 2; 1351 break; 1352 default: 1353 base = 8; 1354 } 1355 } 1356 1357 /* parse number proper */ 1358 for (;;) { 1359 if (c >= '0' && c <= '9') 1360 d = c - '0'; 1361 else if (c >= 'a' && c <= 'z') 1362 d = c - 'a' + 10; 1363 else if (c >= 'A' && c <= 'Z') 1364 d = c - 'A' + 10; 1365 else 1366 break; 1367 val *= base; 1368 val += d; 1369 c = *s++; 1370 } 1371 if (neg) 1372 val = -val; 1373 out: 1374 return val; 1375 } 1376 1377 /* 1378 * Fill in the pmax addresses by hand. 1379 */ 1380 static struct pmax_address { 1381 char *pmax_name; 1382 char *pmax_addr; 1383 int pmax_pri; 1384 } pmax_addresses[] = { 1385 { "pm", (char *)MACH_PHYS_TO_CACHED(KN01_PHYS_FBUF_START), 3 }, 1386 { "dc", (char *)MACH_PHYS_TO_UNCACHED(KN01_SYS_DZ), 2 }, 1387 { "le", (char *)MACH_PHYS_TO_UNCACHED(KN01_SYS_LANCE), 1 }, 1388 { "sii",(char *)MACH_PHYS_TO_UNCACHED(KN01_SYS_SII), 0 }, 1389 { (char *)0, }, 1390 }; 1391 1392 void 1393 pmax_slot_hand_fill() 1394 { 1395 register struct pmax_ctlr *cp; 1396 register struct driver *drp; 1397 register struct pmax_address *pmap; 1398 1399 /* 1400 * Find the device driver entry and fill in the address. 1401 */ 1402 for (cp = pmax_cinit; drp = cp->pmax_driver; cp++) { 1403 for (pmap = pmax_addresses; pmap->pmax_name; pmap++) { 1404 if (strcmp(drp->d_name, pmap->pmax_name)) 1405 continue; 1406 if (cp->pmax_addr == (char *)QUES) { 1407 cp->pmax_addr = pmap->pmax_addr; 1408 cp->pmax_pri = pmap->pmax_pri; 1409 continue; 1410 } 1411 } 1412 } 1413 } 1414 1415 #ifdef DS5000 1416 /* 1417 * Mach Operating System 1418 * Copyright (c) 1991,1990,1989 Carnegie Mellon University 1419 * All Rights Reserved. 1420 * 1421 * Permission to use, copy, modify and distribute this software and its 1422 * documentation is hereby granted, provided that both the copyright 1423 * notice and this permission notice appear in all copies of the 1424 * software, derivative works or modified versions, and any portions 1425 * thereof, and that both notices appear in supporting documentation. 1426 * 1427 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS 1428 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR 1429 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 1430 * 1431 * Carnegie Mellon requests users of this software to return to 1432 * 1433 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 1434 * School of Computer Science 1435 * Carnegie Mellon University 1436 * Pittsburgh PA 15213-3890 1437 * 1438 * any improvements or extensions that they make and grant Carnegie the 1439 * rights to redistribute these changes. 1440 */ 1441 1442 1443 /* 1444 * Driver map: associates a device driver to an option type. 1445 * Drivers name are (arbitrarily) defined in each driver and 1446 * used in the various config tables. 1447 */ 1448 struct drivers_map { 1449 char module_name[TC_ROM_LLEN]; /* from ROM, literally! */ 1450 char *driver_name; /* in bus_??_init[] tables */ 1451 } tc_drivers_map[] = { 1452 { "KN02 ", "dc"}, /* (*) 3max system board (with DC) */ 1453 { "PMAD-AA ", "le"}, /* Ether */ 1454 { "PMAZ-AA ", "asc"}, /* SCSI */ 1455 { "PMAG-AA ", "mfb"}, /* Mono Frame Buffer */ 1456 { "PMAG-BA ", "cfb"}, /* Color Frame Buffer */ 1457 { "PMAG-CA ", "ga"}, /* 2D graphic board */ 1458 { "PMAG-DA ", "gq"}, /* 3D graphic board (LM) */ 1459 { "PMAG-FA ", "gq"}, /* 3D graphic board (HE) */ 1460 { "PMAG-DV ", "xcfb"}, /* (*) maxine Color Frame Buffer */ 1461 { "Z8530 ", "scc"}, /* (*) 3min/maxine serial lines */ 1462 { "ASIC ", "asic"}, /* (*) 3min/maxine DMA controller */ 1463 { "XINE-FDC", "fdc"}, /* (*) maxine floppy controller */ 1464 { "DTOP ", "dtop"}, /* (*) maxine desktop bus */ 1465 { "AMD79c30", "isdn"}, /* (*) maxine ISDN chip */ 1466 { "XINE-FRC", "frc"}, /* (*) maxine free-running counter */ 1467 { "", 0} /* list end */ 1468 }; 1469 1470 /* 1471 * Identify an option on the TC. Looks at the mandatory 1472 * info in the option's ROM and checks it. 1473 */ 1474 #ifdef DEBUG 1475 int tc_verbose = 0; 1476 #endif 1477 1478 static int 1479 tc_identify_option(addr, slot, complain) 1480 tc_rommap_t *addr; 1481 tc_option_t *slot; 1482 int complain; 1483 { 1484 register int i; 1485 unsigned char width; 1486 char firmwr[TC_ROM_LLEN+1], vendor[TC_ROM_LLEN+1], 1487 module[TC_ROM_LLEN+1], host_type[TC_ROM_SLEN+1]; 1488 1489 /* 1490 * We do not really use the 'width' info, but take advantage 1491 * of the restriction that the spec impose on the portion 1492 * of the ROM that maps between +0x3e0 and +0x470, which 1493 * is the only piece we need to look at. 1494 */ 1495 width = addr->rom_width.value; 1496 switch (width) { 1497 case 1: 1498 case 2: 1499 case 4: 1500 break; 1501 1502 default: 1503 #ifdef DEBUG 1504 if (tc_verbose && complain) 1505 printf("%s (x%x) at x%x\n", "Invalid ROM width", 1506 width, addr); 1507 #endif 1508 return (0); 1509 } 1510 1511 if (addr->rom_stride.value != 4) { 1512 #ifdef DEBUG 1513 if (tc_verbose && complain) 1514 printf("%s (x%x) at x%x\n", "Invalid ROM stride", 1515 addr->rom_stride.value, addr); 1516 #endif 1517 return (0); 1518 } 1519 1520 if ((addr->test_data[0] != 0x55) || 1521 (addr->test_data[4] != 0x00) || 1522 (addr->test_data[8] != 0xaa) || 1523 (addr->test_data[12] != 0xff)) { 1524 #ifdef DEBUG 1525 if (tc_verbose && complain) 1526 printf("%s x%x\n", "Test pattern failed, option at", 1527 addr); 1528 #endif 1529 return (0); 1530 } 1531 1532 for (i = 0; i < TC_ROM_LLEN; i++) { 1533 firmwr[i] = addr->firmware_rev[i].value; 1534 vendor[i] = addr->vendor_name[i].value; 1535 module[i] = addr->module_name[i].value; 1536 if (i >= TC_ROM_SLEN) 1537 continue; 1538 host_type[i] = addr->host_firmware_type[i].value; 1539 } 1540 firmwr[TC_ROM_LLEN] = vendor[TC_ROM_LLEN] = 1541 module[TC_ROM_LLEN] = host_type[TC_ROM_SLEN] = '\0'; 1542 1543 #ifdef DEBUG 1544 if (tc_verbose) 1545 printf("%s %s '%s' at 0x%x\n %s %s %s '%s'\n %s %d %s %d %s\n", 1546 "Found a", vendor, module, addr, 1547 "Firmware rev.", firmwr, 1548 "diagnostics for a", host_type, 1549 "ROM size is", addr->rom_size.value << 3, 1550 "Kbytes, uses", addr->slot_size.value, "TC slot(s)"); 1551 #endif 1552 1553 bcopy(module, slot->module_name, TC_ROM_LLEN); 1554 bcopy(vendor, slot->module_id, TC_ROM_LLEN); 1555 bcopy(firmwr, &slot->module_id[TC_ROM_LLEN], TC_ROM_LLEN); 1556 slot->slot_size = addr->slot_size.value; 1557 slot->rom_width = width; 1558 1559 return (1); 1560 } 1561 1562 /* 1563 * TURBOchannel autoconf procedure. Finds in one sweep what is 1564 * hanging on the bus and fills in the tc_slot_info array. 1565 * This is only the first part of the autoconf scheme, at this 1566 * time we are basically only looking for a graphics board to 1567 * use as system console (all workstations). 1568 */ 1569 1570 void 1571 tc_find_all_options() 1572 { 1573 register int i; 1574 u_long addr; 1575 int found; 1576 register tc_option_t *sl; 1577 struct drivers_map *map; 1578 register struct pmax_ctlr *cp; 1579 register struct driver *drp; 1580 1581 /* 1582 * Take a look at the bus 1583 */ 1584 bzero(tc_slot_info, sizeof(tc_slot_info)); 1585 for (i = tc_max_slot; i >= tc_min_slot;) { 1586 addr = MACH_PHYS_TO_UNCACHED(tc_slot_phys_base[i]); 1587 found = tc_probe_slot(addr, &tc_slot_info[i]); 1588 1589 if (found) { 1590 /* 1591 * Found a slot, make a note of it 1592 */ 1593 tc_slot_info[i].present = 1; 1594 tc_slot_info[i].k1seg_address = addr; 1595 } 1596 1597 i -= tc_slot_info[i].slot_size; 1598 } 1599 1600 /* 1601 * Some slots (e.g. the system slot on 3max) might require 1602 * hand-filling. If so, do it now. 1603 */ 1604 if (tc_slot_hand_fill) 1605 (*tc_slot_hand_fill) (tc_slot_info); 1606 1607 /* 1608 * Now for each alive slot see if we have a device driver that 1609 * handles it. This is done in "priority order", meaning that 1610 * always present devices are at higher slot numbers on all 1611 * current TC machines, and option slots are at lowest numbers. 1612 */ 1613 for (i = TC_MAX_LOGICAL_SLOTS - 1; i >= 0; i--) { 1614 sl = &tc_slot_info[i]; 1615 if (!sl->present) 1616 continue; 1617 found = FALSE; 1618 for (map = tc_drivers_map; map->driver_name; map++) { 1619 if (bcmp(sl->module_name, map->module_name, TC_ROM_LLEN)) 1620 continue; 1621 sl->driver_name = map->driver_name; 1622 found = TRUE; 1623 break; 1624 } 1625 if (!found) { 1626 printf("%s %s %s\n", 1627 "Cannot associate a device driver to", 1628 sl->module_name, ". Will (try to) ignore it."); 1629 sl->present = 0; 1630 continue; 1631 } 1632 1633 /* 1634 * Find the device driver entry and fill in the address. 1635 */ 1636 for (cp = pmax_cinit; drp = cp->pmax_driver; cp++) { 1637 if (strcmp(drp->d_name, map->driver_name)) 1638 continue; 1639 if (cp->pmax_alive) 1640 continue; 1641 if (cp->pmax_addr == (char *)QUES) { 1642 cp->pmax_addr = (char *)sl->k1seg_address; 1643 cp->pmax_pri = i; 1644 /* 1645 * Only enable interrupts if there is an 1646 * interrupt handler for it. (e.g., PMAG-BA 1647 * can't disable the vertical retrace interrupt 1648 * and we might want to ignore it). 1649 */ 1650 if (drp->d_intr) 1651 (*tc_enable_interrupt)(i, 1); 1652 cp->pmax_alive = 1; 1653 break; 1654 } 1655 if (cp->pmax_addr != (char *)sl->k1seg_address) { 1656 cp->pmax_addr = (char *)QUES; 1657 printf("%s: device not at configued address (expected at %x, found at %x)\n", 1658 drp->d_name, 1659 cp->pmax_addr, sl->k1seg_address); 1660 } 1661 } 1662 } 1663 } 1664 1665 /* 1666 * Probe a slot in the TURBOchannel. Return TRUE if a valid option 1667 * is present, FALSE otherwise. A side-effect is to fill the slot 1668 * descriptor with the size of the option, whether it is 1669 * recognized or not. 1670 */ 1671 int 1672 tc_probe_slot(addr, slot) 1673 caddr_t addr; 1674 tc_option_t *slot; 1675 { 1676 int i; 1677 static unsigned tc_offset_rom[] = { 1678 TC_OFF_PROTO_ROM, TC_OFF_ROM 1679 }; 1680 #define TC_N_OFFSETS sizeof(tc_offset_rom)/sizeof(unsigned) 1681 1682 slot->slot_size = 1; 1683 1684 for (i = 0; i < TC_N_OFFSETS; i++) { 1685 if (badaddr(addr + tc_offset_rom[i], 4)) 1686 continue; 1687 /* complain only on last chance */ 1688 if (tc_identify_option((tc_rommap_t *)(addr + tc_offset_rom[i]), 1689 slot, i == (TC_N_OFFSETS-1))) 1690 return (1); 1691 } 1692 return (0); 1693 #undef TC_N_OFFSETS 1694 } 1695 1696 /* 1697 * Enable/Disable interrupts for a TURBOchannel slot. 1698 */ 1699 void 1700 kn02_enable_intr(slotno, on) 1701 register int slotno; 1702 int on; 1703 { 1704 register volatile int *p_csr = 1705 (volatile int *)MACH_PHYS_TO_UNCACHED(KN02_SYS_CSR); 1706 int csr; 1707 int s; 1708 1709 slotno = 1 << (slotno + KN02_CSR_IOINTEN_SHIFT); 1710 s = Mach_spl0(); 1711 csr = *p_csr & ~(KN02_CSR_WRESERVED | 0xFF); 1712 if (on) 1713 *p_csr = csr | slotno; 1714 else 1715 *p_csr = csr & ~slotno; 1716 splx(s); 1717 } 1718 1719 /* 1720 * Object: 1721 * kmin_enable_intr EXPORTED function 1722 * 1723 * Enable/Disable interrupts from a TURBOchannel slot. 1724 * 1725 * We pretend we actually have 8 slots even if we really have 1726 * only 4: TCslots 0-2 maps to slots 0-2, TCslot3 maps to 1727 * slots 3-7 (see kmin_slot_hand_fill). 1728 */ 1729 void 1730 kmin_enable_intr(slotno, on) 1731 register unsigned int slotno; 1732 int on; 1733 { 1734 register unsigned mask; 1735 1736 switch (slotno) { 1737 case 0: 1738 case 1: 1739 case 2: 1740 return; 1741 case KMIN_SCSI_SLOT: 1742 mask = (KMIN_INTR_SCSI | KMIN_INTR_SCSI_PTR_LOAD | 1743 KMIN_INTR_SCSI_OVRUN | KMIN_INTR_SCSI_READ_E); 1744 break; 1745 case KMIN_LANCE_SLOT: 1746 mask = KMIN_INTR_LANCE; 1747 break; 1748 case KMIN_SCC0_SLOT: 1749 mask = KMIN_INTR_SCC_0; 1750 break; 1751 case KMIN_SCC1_SLOT: 1752 mask = KMIN_INTR_SCC_1; 1753 break; 1754 case KMIN_ASIC_SLOT: 1755 mask = KMIN_INTR_ASIC; 1756 break; 1757 default: 1758 return; 1759 } 1760 if (on) 1761 kmin_tc3_imask |= mask; 1762 else 1763 kmin_tc3_imask &= ~mask; 1764 } 1765 1766 /* 1767 * Object: 1768 * xine_enable_intr EXPORTED function 1769 * 1770 * Enable/Disable interrupts from a TURBOchannel slot. 1771 * 1772 * We pretend we actually have 11 slots even if we really have 1773 * only 3: TCslots 0-1 maps to slots 0-1, TCslot 2 is used for 1774 * the system (TCslot3), TCslot3 maps to slots 3-10 1775 * (see xine_slot_hand_fill). 1776 * Note that all these interrupts come in via the IMR. 1777 */ 1778 void 1779 xine_enable_intr(slotno, on) 1780 register unsigned int slotno; 1781 int on; 1782 { 1783 register unsigned mask; 1784 1785 switch (slotno) { 1786 case 0: /* a real slot, but */ 1787 mask = XINE_INTR_TC_0; 1788 break; 1789 case 1: /* a real slot, but */ 1790 mask = XINE_INTR_TC_1; 1791 break; 1792 case XINE_FLOPPY_SLOT: 1793 mask = XINE_INTR_FLOPPY; 1794 break; 1795 case XINE_SCSI_SLOT: 1796 mask = (XINE_INTR_SCSI | XINE_INTR_SCSI_PTR_LOAD | 1797 XINE_INTR_SCSI_OVRUN | XINE_INTR_SCSI_READ_E); 1798 break; 1799 case XINE_LANCE_SLOT: 1800 mask = XINE_INTR_LANCE; 1801 break; 1802 case XINE_SCC0_SLOT: 1803 mask = XINE_INTR_SCC_0; 1804 break; 1805 case XINE_DTOP_SLOT: 1806 mask = XINE_INTR_DTOP_RX; 1807 break; 1808 case XINE_ISDN_SLOT: 1809 mask = XINE_INTR_ISDN; 1810 break; 1811 case XINE_ASIC_SLOT: 1812 mask = XINE_INTR_ASIC; 1813 break; 1814 default: 1815 return;/* ignore */ 1816 } 1817 if (on) 1818 xine_tc3_imask |= mask; 1819 else 1820 xine_tc3_imask &= ~mask; 1821 } 1822 1823 #ifdef DS5000_240 1824 /* 1825 * UNTESTED!! 1826 * Object: 1827 * kn03_enable_intr EXPORTED function 1828 * 1829 * Enable/Disable interrupts from a TURBOchannel slot. 1830 * 1831 * We pretend we actually have 8 slots even if we really have 1832 * only 4: TCslots 0-2 maps to slots 0-2, TCslot3 maps to 1833 * slots 3-7 (see kn03_slot_hand_fill). 1834 */ 1835 void 1836 kn03_enable_intr(slotno, on) 1837 register unsigned int slotno; 1838 int on; 1839 { 1840 register unsigned mask; 1841 1842 switch (slotno) { 1843 case 0: 1844 mask = KN03_INTR_TC_0; 1845 break; 1846 case 1: 1847 mask = KN03_INTR_TC_1; 1848 break; 1849 case 2: 1850 mask = KN03_INTR_TC_2; 1851 break; 1852 case KN03_SCSI_SLOT: 1853 mask = (KN03_INTR_SCSI | KN03_INTR_SCSI_PTR_LOAD | 1854 KN03_INTR_SCSI_OVRUN | KN03_INTR_SCSI_READ_E); 1855 break; 1856 case KN03_LANCE_SLOT: 1857 mask = KN03_INTR_LANCE; 1858 break; 1859 case KN03_SCC0_SLOT: 1860 mask = KN03_INTR_SCC_0; 1861 break; 1862 case KN03_SCC1_SLOT: 1863 mask = KN03_INTR_SCC_1; 1864 break; 1865 case KN03_ASIC_SLOT: 1866 mask = KN03_INTR_ASIC; 1867 break; 1868 default: 1869 return; 1870 } 1871 if (on) 1872 kn03_tc3_imask |= mask; 1873 else 1874 kn03_tc3_imask &= ~mask; 1875 } 1876 #endif /* DS5000_240 */ 1877 1878 /* 1879 * Object: 1880 * kn02_slot_hand_fill EXPORTED function 1881 * 1882 * Fill in by hand the info for TC slots that are non-standard. 1883 * This is basically just the system slot on a 3max, it does not 1884 * look to me like it follows the TC rules although some of the 1885 * required info is indeed there. 1886 * 1887 */ 1888 void 1889 kn02_slot_hand_fill(slot) 1890 tc_option_t *slot; 1891 { 1892 slot[7].present = 1; 1893 slot[7].slot_size = 1; 1894 slot[7].rom_width = 1; 1895 #if unsafe 1896 bcopy(0xbffc0410, slot[7].module_name, TC_ROM_LLEN+1); 1897 #endif 1898 bcopy("KN02 ", slot[7].module_name, TC_ROM_LLEN+1); 1899 bcopy("DEC xxxx", slot[7].module_id, TC_ROM_LLEN+1); 1900 slot[7].k1seg_address = MACH_PHYS_TO_UNCACHED(KN02_SYS_DZ); 1901 } 1902 1903 /* 1904 * Object: 1905 * kmin_slot_hand_fill EXPORTED function 1906 * 1907 * Fill in by hand the info for TC slots that are non-standard. 1908 * This is the system slot on a 3min, which we think of as a 1909 * set of non-regular size TC slots. 1910 * 1911 */ 1912 void 1913 kmin_slot_hand_fill(slot) 1914 tc_option_t *slot; 1915 { 1916 register int i; 1917 1918 for (i = KMIN_SCSI_SLOT; i < KMIN_ASIC_SLOT+1; i++) { 1919 slot[i].present = 1; 1920 slot[i].slot_size = 1; 1921 slot[i].rom_width = 1; 1922 slot[i].unit = 0; 1923 bcopy("DEC KMIN", slot[i].module_id, TC_ROM_LLEN+1); 1924 } 1925 1926 /* scsi */ 1927 bcopy("PMAZ-AA ", slot[KMIN_SCSI_SLOT].module_name, TC_ROM_LLEN+1); 1928 slot[KMIN_SCSI_SLOT].k1seg_address = 1929 MACH_PHYS_TO_UNCACHED(KMIN_SYS_SCSI); 1930 1931 /* lance */ 1932 bcopy("PMAD-AA ", slot[KMIN_LANCE_SLOT].module_name, TC_ROM_LLEN+1); 1933 slot[KMIN_LANCE_SLOT].k1seg_address = 0; 1934 1935 /* scc */ 1936 bcopy("Z8530 ", slot[KMIN_SCC0_SLOT].module_name, TC_ROM_LLEN+1); 1937 slot[KMIN_SCC0_SLOT].k1seg_address = 1938 MACH_PHYS_TO_UNCACHED(KMIN_SYS_SCC_0); 1939 1940 slot[KMIN_SCC1_SLOT].unit = 1; 1941 bcopy("Z8530 ", slot[KMIN_SCC1_SLOT].module_name, TC_ROM_LLEN+1); 1942 slot[KMIN_SCC1_SLOT].k1seg_address = 1943 MACH_PHYS_TO_UNCACHED(KMIN_SYS_SCC_1); 1944 1945 /* asic */ 1946 bcopy("ASIC ", slot[KMIN_ASIC_SLOT].module_name, TC_ROM_LLEN+1); 1947 slot[KMIN_ASIC_SLOT].k1seg_address = 1948 MACH_PHYS_TO_UNCACHED(KMIN_SYS_ASIC); 1949 asic_init(0); 1950 } 1951 1952 /* 1953 * Object: 1954 * xine_slot_hand_fill EXPORTED function 1955 * 1956 * Fill in by hand the info for TC slots that are non-standard. 1957 * This is the system slot on a 3min, which we think of as a 1958 * set of non-regular size TC slots. 1959 * 1960 */ 1961 void 1962 xine_slot_hand_fill(slot) 1963 tc_option_t *slot; 1964 { 1965 register int i; 1966 1967 for (i = XINE_FLOPPY_SLOT; i < XINE_FRC_SLOT+1; i++) { 1968 slot[i].present = 1; 1969 slot[i].slot_size = 1; 1970 slot[i].rom_width = 1; 1971 slot[i].unit = 0; 1972 bcopy("DEC XINE", slot[i].module_id, TC_ROM_LLEN+1); 1973 } 1974 1975 /* floppy */ 1976 bcopy("XINE-FDC", slot[XINE_FLOPPY_SLOT].module_name, TC_ROM_LLEN+1); 1977 slot[XINE_FLOPPY_SLOT].k1seg_address = 1978 MACH_PHYS_TO_UNCACHED(XINE_SYS_FLOPPY); 1979 1980 /* scsi */ 1981 bcopy("PMAZ-AA ", slot[XINE_SCSI_SLOT].module_name, TC_ROM_LLEN+1); 1982 slot[XINE_SCSI_SLOT].k1seg_address = 1983 MACH_PHYS_TO_UNCACHED(XINE_SYS_SCSI); 1984 1985 /* lance */ 1986 bcopy("PMAD-AA ", slot[XINE_LANCE_SLOT].module_name, TC_ROM_LLEN+1); 1987 slot[XINE_LANCE_SLOT].k1seg_address = 1988 MACH_PHYS_TO_UNCACHED(XINE_SYS_LANCE); 1989 1990 /* scc */ 1991 bcopy("Z8530 ", slot[XINE_SCC0_SLOT].module_name, TC_ROM_LLEN+1); 1992 slot[XINE_SCC0_SLOT].k1seg_address = 1993 MACH_PHYS_TO_UNCACHED(XINE_SYS_SCC_0); 1994 1995 /* Desktop */ 1996 bcopy("DTOP ", slot[XINE_DTOP_SLOT].module_name, TC_ROM_LLEN+1); 1997 slot[XINE_DTOP_SLOT].k1seg_address = 1998 MACH_PHYS_TO_UNCACHED(XINE_SYS_DTOP+0x20000); /* why? */ 1999 2000 /* ISDN */ 2001 bcopy("AMD79c30", slot[XINE_ISDN_SLOT].module_name, TC_ROM_LLEN+1); 2002 slot[XINE_ISDN_SLOT].k1seg_address = 2003 MACH_PHYS_TO_UNCACHED(XINE_SYS_ISDN); 2004 2005 /* Video */ 2006 bcopy("PMAG-DV ", slot[XINE_CFB_SLOT].module_name, TC_ROM_LLEN+1); 2007 slot[XINE_CFB_SLOT].k1seg_address = 2008 MACH_PHYS_TO_CACHED(XINE_PHYS_CFB_START); 2009 2010 /* asic */ 2011 bcopy("ASIC ", slot[XINE_ASIC_SLOT].module_name, TC_ROM_LLEN+1); 2012 slot[XINE_ASIC_SLOT].k1seg_address = 2013 MACH_PHYS_TO_UNCACHED(XINE_SYS_ASIC); 2014 2015 /* free-running counter (high resolution mapped time) */ 2016 bcopy("XINE-FRC", slot[XINE_FRC_SLOT].module_name, TC_ROM_LLEN+1); 2017 slot[XINE_FRC_SLOT].k1seg_address = 2018 MACH_PHYS_TO_UNCACHED(XINE_REG_FCTR); 2019 asic_init(1); 2020 } 2021 2022 #ifdef DS5000_240 2023 /* 2024 * UNTESTED!! 2025 * Object: 2026 * kn03_slot_hand_fill EXPORTED function 2027 * 2028 * Fill in by hand the info for TC slots that are non-standard. 2029 * This is the system slot on a 3max+, which we think of as a 2030 * set of non-regular size TC slots. 2031 * 2032 */ 2033 void 2034 kn03_slot_hand_fill(slot) 2035 tc_option_t *slot; 2036 { 2037 register int i; 2038 2039 for (i = KN03_SCSI_SLOT; i < KN03_ASIC_SLOT+1; i++) { 2040 slot[i].present = 1; 2041 slot[i].slot_size = 1; 2042 slot[i].rom_width = 1; 2043 slot[i].unit = 0; 2044 bcopy("DEC KN03", slot[i].module_id, TC_ROM_LLEN+1); 2045 } 2046 2047 /* scsi */ 2048 bcopy("PMAZ-AA ", slot[KN03_SCSI_SLOT].module_name, TC_ROM_LLEN+1); 2049 slot[KN03_SCSI_SLOT].k1seg_address = 2050 MACH_PHYS_TO_UNCACHED(KN03_SYS_SCSI); 2051 2052 /* lance */ 2053 bcopy("PMAD-AA ", slot[KN03_LANCE_SLOT].module_name, TC_ROM_LLEN+1); 2054 slot[KN03_LANCE_SLOT].k1seg_address = 0; 2055 2056 /* scc */ 2057 bcopy("Z8530 ", slot[KN03_SCC0_SLOT].module_name, TC_ROM_LLEN+1); 2058 slot[KN03_SCC0_SLOT].k1seg_address = 2059 MACH_PHYS_TO_UNCACHED(KN03_SYS_SCC_0); 2060 2061 slot[KN03_SCC1_SLOT].unit = 1; 2062 bcopy("Z8530 ", slot[KN03_SCC1_SLOT].module_name, TC_ROM_LLEN+1); 2063 slot[KN03_SCC1_SLOT].k1seg_address = 2064 MACH_PHYS_TO_UNCACHED(KN03_SYS_SCC_1); 2065 2066 /* asic */ 2067 bcopy("ASIC ", slot[KN03_ASIC_SLOT].module_name, TC_ROM_LLEN+1); 2068 slot[KN03_ASIC_SLOT].k1seg_address = 2069 MACH_PHYS_TO_UNCACHED(KN03_SYS_ASIC); 2070 asic_init(0); 2071 } 2072 #endif /* DS5000_240 */ 2073 2074 /* 2075 * Initialize the I/O asic 2076 */ 2077 static void 2078 asic_init(isa_maxine) 2079 int isa_maxine; 2080 { 2081 volatile u_int *decoder; 2082 2083 /* These are common between 3min and maxine */ 2084 decoder = (volatile u_int *)ASIC_REG_LANCE_DECODE(asic_base); 2085 *decoder = KMIN_LANCE_CONFIG; 2086 } 2087 #endif /* DS5000 */ 2088