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