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.3 (Berkeley) 01/12/94 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 for (iter = 0; iter < 20; iter++) { 1165 nbusy = 0; 1166 for (bp = &buf[nbuf]; --bp >= buf; ) 1167 if ((bp->b_flags & (B_BUSY|B_INVAL)) == B_BUSY) 1168 nbusy++; 1169 if (nbusy == 0) 1170 break; 1171 printf("%d ", nbusy); 1172 DELAY(40000 * iter); 1173 } 1174 if (nbusy) 1175 printf("giving up\n"); 1176 else 1177 printf("done\n"); 1178 /* 1179 * If we've been adjusting the clock, the todr 1180 * will be out of synch; adjust it now. 1181 */ 1182 resettodr(); 1183 } 1184 (void) splhigh(); /* extreme priority */ 1185 if (callv != &callvec) { 1186 if (howto & RB_HALT) 1187 (*callv->rex)('h'); 1188 else { 1189 if (howto & RB_DUMP) 1190 dumpsys(); 1191 (*callv->rex)('b'); 1192 } 1193 } else if (howto & RB_HALT) { 1194 volatile void (*f)() = (volatile void (*)())DEC_PROM_REINIT; 1195 1196 (*f)(); /* jump back to prom monitor */ 1197 } else { 1198 volatile void (*f)() = (volatile void (*)())DEC_PROM_AUTOBOOT; 1199 1200 if (howto & RB_DUMP) 1201 dumpsys(); 1202 (*f)(); /* jump back to prom monitor and do 'auto' cmd */ 1203 } 1204 /*NOTREACHED*/ 1205 } 1206 1207 int dumpmag = (int)0x8fca0101; /* magic number for savecore */ 1208 int dumpsize = 0; /* also for savecore */ 1209 long dumplo = 0; 1210 1211 dumpconf() 1212 { 1213 int nblks; 1214 1215 dumpsize = physmem; 1216 if (dumpdev != NODEV && bdevsw[major(dumpdev)].d_psize) { 1217 nblks = (*bdevsw[major(dumpdev)].d_psize)(dumpdev); 1218 if (dumpsize > btoc(dbtob(nblks - dumplo))) 1219 dumpsize = btoc(dbtob(nblks - dumplo)); 1220 else if (dumplo == 0) 1221 dumplo = nblks - btodb(ctob(physmem)); 1222 } 1223 /* 1224 * Don't dump on the first CLBYTES (why CLBYTES?) 1225 * in case the dump device includes a disk label. 1226 */ 1227 if (dumplo < btodb(CLBYTES)) 1228 dumplo = btodb(CLBYTES); 1229 } 1230 1231 /* 1232 * Doadump comes here after turning off memory management and 1233 * getting on the dump stack, either when called above, or by 1234 * the auto-restart code. 1235 */ 1236 dumpsys() 1237 { 1238 int error; 1239 1240 msgbufmapped = 0; 1241 if (dumpdev == NODEV) 1242 return; 1243 /* 1244 * For dumps during autoconfiguration, 1245 * if dump device has already configured... 1246 */ 1247 if (dumpsize == 0) 1248 dumpconf(); 1249 if (dumplo < 0) 1250 return; 1251 printf("\ndumping to dev %x, offset %d\n", dumpdev, dumplo); 1252 printf("dump "); 1253 switch (error = (*bdevsw[major(dumpdev)].d_dump)(dumpdev)) { 1254 1255 case ENXIO: 1256 printf("device bad\n"); 1257 break; 1258 1259 case EFAULT: 1260 printf("device not ready\n"); 1261 break; 1262 1263 case EINVAL: 1264 printf("area improper\n"); 1265 break; 1266 1267 case EIO: 1268 printf("i/o error\n"); 1269 break; 1270 1271 default: 1272 printf("error %d\n", error); 1273 break; 1274 1275 case 0: 1276 printf("succeeded\n"); 1277 } 1278 } 1279 1280 /* 1281 * Return the best possible estimate of the time in the timeval 1282 * to which tvp points. Unfortunately, we can't read the hardware registers. 1283 * We guarantee that the time will be greater than the value obtained by a 1284 * previous call. 1285 */ 1286 microtime(tvp) 1287 register struct timeval *tvp; 1288 { 1289 int s = splclock(); 1290 static struct timeval lasttime; 1291 1292 *tvp = time; 1293 #ifdef notdef 1294 tvp->tv_usec += clkread(); 1295 while (tvp->tv_usec > 1000000) { 1296 tvp->tv_sec++; 1297 tvp->tv_usec -= 1000000; 1298 } 1299 #endif 1300 if (tvp->tv_sec == lasttime.tv_sec && 1301 tvp->tv_usec <= lasttime.tv_usec && 1302 (tvp->tv_usec = lasttime.tv_usec + 1) > 1000000) { 1303 tvp->tv_sec++; 1304 tvp->tv_usec -= 1000000; 1305 } 1306 lasttime = *tvp; 1307 splx(s); 1308 } 1309 1310 initcpu() 1311 { 1312 register volatile struct chiptime *c; 1313 int i; 1314 1315 /* disable clock interrupts (until startrtclock()) */ 1316 c = Mach_clock_addr; 1317 c->regb = REGB_DATA_MODE | REGB_HOURS_FORMAT; 1318 i = c->regc; 1319 spl0(); /* safe to turn interrupts on now */ 1320 return (i); 1321 } 1322 1323 /* 1324 * Convert an ASCII string into an integer. 1325 */ 1326 int 1327 atoi(s) 1328 char *s; 1329 { 1330 int c; 1331 unsigned base = 10, d; 1332 int neg = 0, val = 0; 1333 1334 if (s == 0 || (c = *s++) == 0) 1335 goto out; 1336 1337 /* skip spaces if any */ 1338 while (c == ' ' || c == '\t') 1339 c = *s++; 1340 1341 /* parse sign, allow more than one (compat) */ 1342 while (c == '-') { 1343 neg = !neg; 1344 c = *s++; 1345 } 1346 1347 /* parse base specification, if any */ 1348 if (c == '0') { 1349 c = *s++; 1350 switch (c) { 1351 case 'X': 1352 case 'x': 1353 base = 16; 1354 break; 1355 case 'B': 1356 case 'b': 1357 base = 2; 1358 break; 1359 default: 1360 base = 8; 1361 } 1362 } 1363 1364 /* parse number proper */ 1365 for (;;) { 1366 if (c >= '0' && c <= '9') 1367 d = c - '0'; 1368 else if (c >= 'a' && c <= 'z') 1369 d = c - 'a' + 10; 1370 else if (c >= 'A' && c <= 'Z') 1371 d = c - 'A' + 10; 1372 else 1373 break; 1374 val *= base; 1375 val += d; 1376 c = *s++; 1377 } 1378 if (neg) 1379 val = -val; 1380 out: 1381 return val; 1382 } 1383 1384 /* 1385 * Fill in the pmax addresses by hand. 1386 */ 1387 static struct pmax_address { 1388 char *pmax_name; 1389 char *pmax_addr; 1390 int pmax_pri; 1391 } pmax_addresses[] = { 1392 { "pm", (char *)MACH_PHYS_TO_CACHED(KN01_PHYS_FBUF_START), 3 }, 1393 { "dc", (char *)MACH_PHYS_TO_UNCACHED(KN01_SYS_DZ), 2 }, 1394 { "le", (char *)MACH_PHYS_TO_UNCACHED(KN01_SYS_LANCE), 1 }, 1395 { "sii",(char *)MACH_PHYS_TO_UNCACHED(KN01_SYS_SII), 0 }, 1396 { (char *)0, }, 1397 }; 1398 1399 void 1400 pmax_slot_hand_fill() 1401 { 1402 register struct pmax_ctlr *cp; 1403 register struct driver *drp; 1404 register struct pmax_address *pmap; 1405 1406 /* 1407 * Find the device driver entry and fill in the address. 1408 */ 1409 for (cp = pmax_cinit; drp = cp->pmax_driver; cp++) { 1410 for (pmap = pmax_addresses; pmap->pmax_name; pmap++) { 1411 if (strcmp(drp->d_name, pmap->pmax_name)) 1412 continue; 1413 if (cp->pmax_addr == (char *)QUES) { 1414 cp->pmax_addr = pmap->pmax_addr; 1415 cp->pmax_pri = pmap->pmax_pri; 1416 continue; 1417 } 1418 } 1419 } 1420 } 1421 1422 #ifdef DS5000 1423 /* 1424 * Mach Operating System 1425 * Copyright (c) 1991,1990,1989 Carnegie Mellon University 1426 * All Rights Reserved. 1427 * 1428 * Permission to use, copy, modify and distribute this software and its 1429 * documentation is hereby granted, provided that both the copyright 1430 * notice and this permission notice appear in all copies of the 1431 * software, derivative works or modified versions, and any portions 1432 * thereof, and that both notices appear in supporting documentation. 1433 * 1434 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS 1435 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR 1436 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 1437 * 1438 * Carnegie Mellon requests users of this software to return to 1439 * 1440 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 1441 * School of Computer Science 1442 * Carnegie Mellon University 1443 * Pittsburgh PA 15213-3890 1444 * 1445 * any improvements or extensions that they make and grant Carnegie the 1446 * rights to redistribute these changes. 1447 */ 1448 1449 1450 /* 1451 * Driver map: associates a device driver to an option type. 1452 * Drivers name are (arbitrarily) defined in each driver and 1453 * used in the various config tables. 1454 */ 1455 struct drivers_map { 1456 char module_name[TC_ROM_LLEN]; /* from ROM, literally! */ 1457 char *driver_name; /* in bus_??_init[] tables */ 1458 } tc_drivers_map[] = { 1459 { "KN02 ", "dc"}, /* (*) 3max system board (with DC) */ 1460 { "PMAD-AA ", "le"}, /* Ether */ 1461 { "PMAZ-AA ", "asc"}, /* SCSI */ 1462 { "PMAG-AA ", "mfb"}, /* Mono Frame Buffer */ 1463 { "PMAG-BA ", "cfb"}, /* Color Frame Buffer */ 1464 { "PMAG-CA ", "ga"}, /* 2D graphic board */ 1465 { "PMAG-DA ", "gq"}, /* 3D graphic board (LM) */ 1466 { "PMAG-FA ", "gq"}, /* 3D graphic board (HE) */ 1467 { "PMAG-DV ", "xcfb"}, /* (*) maxine Color Frame Buffer */ 1468 { "Z8530 ", "scc"}, /* (*) 3min/maxine serial lines */ 1469 { "ASIC ", "asic"}, /* (*) 3min/maxine DMA controller */ 1470 { "XINE-FDC", "fdc"}, /* (*) maxine floppy controller */ 1471 { "DTOP ", "dtop"}, /* (*) maxine desktop bus */ 1472 { "AMD79c30", "isdn"}, /* (*) maxine ISDN chip */ 1473 { "XINE-FRC", "frc"}, /* (*) maxine free-running counter */ 1474 { "", 0} /* list end */ 1475 }; 1476 1477 /* 1478 * Identify an option on the TC. Looks at the mandatory 1479 * info in the option's ROM and checks it. 1480 */ 1481 #ifdef DEBUG 1482 int tc_verbose = 0; 1483 #endif 1484 1485 static int 1486 tc_identify_option(addr, slot, complain) 1487 tc_rommap_t *addr; 1488 tc_option_t *slot; 1489 int complain; 1490 { 1491 register int i; 1492 unsigned char width; 1493 char firmwr[TC_ROM_LLEN+1], vendor[TC_ROM_LLEN+1], 1494 module[TC_ROM_LLEN+1], host_type[TC_ROM_SLEN+1]; 1495 1496 /* 1497 * We do not really use the 'width' info, but take advantage 1498 * of the restriction that the spec impose on the portion 1499 * of the ROM that maps between +0x3e0 and +0x470, which 1500 * is the only piece we need to look at. 1501 */ 1502 width = addr->rom_width.value; 1503 switch (width) { 1504 case 1: 1505 case 2: 1506 case 4: 1507 break; 1508 1509 default: 1510 #ifdef DEBUG 1511 if (tc_verbose && complain) 1512 printf("%s (x%x) at x%x\n", "Invalid ROM width", 1513 width, addr); 1514 #endif 1515 return (0); 1516 } 1517 1518 if (addr->rom_stride.value != 4) { 1519 #ifdef DEBUG 1520 if (tc_verbose && complain) 1521 printf("%s (x%x) at x%x\n", "Invalid ROM stride", 1522 addr->rom_stride.value, addr); 1523 #endif 1524 return (0); 1525 } 1526 1527 if ((addr->test_data[0] != 0x55) || 1528 (addr->test_data[4] != 0x00) || 1529 (addr->test_data[8] != 0xaa) || 1530 (addr->test_data[12] != 0xff)) { 1531 #ifdef DEBUG 1532 if (tc_verbose && complain) 1533 printf("%s x%x\n", "Test pattern failed, option at", 1534 addr); 1535 #endif 1536 return (0); 1537 } 1538 1539 for (i = 0; i < TC_ROM_LLEN; i++) { 1540 firmwr[i] = addr->firmware_rev[i].value; 1541 vendor[i] = addr->vendor_name[i].value; 1542 module[i] = addr->module_name[i].value; 1543 if (i >= TC_ROM_SLEN) 1544 continue; 1545 host_type[i] = addr->host_firmware_type[i].value; 1546 } 1547 firmwr[TC_ROM_LLEN] = vendor[TC_ROM_LLEN] = 1548 module[TC_ROM_LLEN] = host_type[TC_ROM_SLEN] = '\0'; 1549 1550 #ifdef DEBUG 1551 if (tc_verbose) 1552 printf("%s %s '%s' at 0x%x\n %s %s %s '%s'\n %s %d %s %d %s\n", 1553 "Found a", vendor, module, addr, 1554 "Firmware rev.", firmwr, 1555 "diagnostics for a", host_type, 1556 "ROM size is", addr->rom_size.value << 3, 1557 "Kbytes, uses", addr->slot_size.value, "TC slot(s)"); 1558 #endif 1559 1560 bcopy(module, slot->module_name, TC_ROM_LLEN); 1561 bcopy(vendor, slot->module_id, TC_ROM_LLEN); 1562 bcopy(firmwr, &slot->module_id[TC_ROM_LLEN], TC_ROM_LLEN); 1563 slot->slot_size = addr->slot_size.value; 1564 slot->rom_width = width; 1565 1566 return (1); 1567 } 1568 1569 /* 1570 * TURBOchannel autoconf procedure. Finds in one sweep what is 1571 * hanging on the bus and fills in the tc_slot_info array. 1572 * This is only the first part of the autoconf scheme, at this 1573 * time we are basically only looking for a graphics board to 1574 * use as system console (all workstations). 1575 */ 1576 1577 void 1578 tc_find_all_options() 1579 { 1580 register int i; 1581 u_long addr; 1582 int found; 1583 register tc_option_t *sl; 1584 struct drivers_map *map; 1585 register struct pmax_ctlr *cp; 1586 register struct driver *drp; 1587 1588 /* 1589 * Take a look at the bus 1590 */ 1591 bzero(tc_slot_info, sizeof(tc_slot_info)); 1592 for (i = tc_max_slot; i >= tc_min_slot;) { 1593 addr = MACH_PHYS_TO_UNCACHED(tc_slot_phys_base[i]); 1594 found = tc_probe_slot(addr, &tc_slot_info[i]); 1595 1596 if (found) { 1597 /* 1598 * Found a slot, make a note of it 1599 */ 1600 tc_slot_info[i].present = 1; 1601 tc_slot_info[i].k1seg_address = addr; 1602 } 1603 1604 i -= tc_slot_info[i].slot_size; 1605 } 1606 1607 /* 1608 * Some slots (e.g. the system slot on 3max) might require 1609 * hand-filling. If so, do it now. 1610 */ 1611 if (tc_slot_hand_fill) 1612 (*tc_slot_hand_fill) (tc_slot_info); 1613 1614 /* 1615 * Now for each alive slot see if we have a device driver that 1616 * handles it. This is done in "priority order", meaning that 1617 * always present devices are at higher slot numbers on all 1618 * current TC machines, and option slots are at lowest numbers. 1619 */ 1620 for (i = TC_MAX_LOGICAL_SLOTS - 1; i >= 0; i--) { 1621 sl = &tc_slot_info[i]; 1622 if (!sl->present) 1623 continue; 1624 found = FALSE; 1625 for (map = tc_drivers_map; map->driver_name; map++) { 1626 if (bcmp(sl->module_name, map->module_name, TC_ROM_LLEN)) 1627 continue; 1628 sl->driver_name = map->driver_name; 1629 found = TRUE; 1630 break; 1631 } 1632 if (!found) { 1633 printf("%s %s %s\n", 1634 "Cannot associate a device driver to", 1635 sl->module_name, ". Will (try to) ignore it."); 1636 sl->present = 0; 1637 continue; 1638 } 1639 1640 /* 1641 * Find the device driver entry and fill in the address. 1642 */ 1643 for (cp = pmax_cinit; drp = cp->pmax_driver; cp++) { 1644 if (strcmp(drp->d_name, map->driver_name)) 1645 continue; 1646 if (cp->pmax_alive) 1647 continue; 1648 if (cp->pmax_addr == (char *)QUES) { 1649 cp->pmax_addr = (char *)sl->k1seg_address; 1650 cp->pmax_pri = i; 1651 /* 1652 * Only enable interrupts if there is an 1653 * interrupt handler for it. (e.g., PMAG-BA 1654 * can't disable the vertical retrace interrupt 1655 * and we might want to ignore it). 1656 */ 1657 if (drp->d_intr) 1658 (*tc_enable_interrupt)(i, 1); 1659 cp->pmax_alive = 1; 1660 break; 1661 } 1662 if (cp->pmax_addr != (char *)sl->k1seg_address) { 1663 cp->pmax_addr = (char *)QUES; 1664 printf("%s: device not at configued address (expected at %x, found at %x)\n", 1665 drp->d_name, 1666 cp->pmax_addr, sl->k1seg_address); 1667 } 1668 } 1669 } 1670 } 1671 1672 /* 1673 * Probe a slot in the TURBOchannel. Return TRUE if a valid option 1674 * is present, FALSE otherwise. A side-effect is to fill the slot 1675 * descriptor with the size of the option, whether it is 1676 * recognized or not. 1677 */ 1678 int 1679 tc_probe_slot(addr, slot) 1680 caddr_t addr; 1681 tc_option_t *slot; 1682 { 1683 int i; 1684 static unsigned tc_offset_rom[] = { 1685 TC_OFF_PROTO_ROM, TC_OFF_ROM 1686 }; 1687 #define TC_N_OFFSETS sizeof(tc_offset_rom)/sizeof(unsigned) 1688 1689 slot->slot_size = 1; 1690 1691 for (i = 0; i < TC_N_OFFSETS; i++) { 1692 if (badaddr(addr + tc_offset_rom[i], 4)) 1693 continue; 1694 /* complain only on last chance */ 1695 if (tc_identify_option((tc_rommap_t *)(addr + tc_offset_rom[i]), 1696 slot, i == (TC_N_OFFSETS-1))) 1697 return (1); 1698 } 1699 return (0); 1700 #undef TC_N_OFFSETS 1701 } 1702 1703 /* 1704 * Enable/Disable interrupts for a TURBOchannel slot. 1705 */ 1706 void 1707 kn02_enable_intr(slotno, on) 1708 register int slotno; 1709 int on; 1710 { 1711 register volatile int *p_csr = 1712 (volatile int *)MACH_PHYS_TO_UNCACHED(KN02_SYS_CSR); 1713 int csr; 1714 int s; 1715 1716 slotno = 1 << (slotno + KN02_CSR_IOINTEN_SHIFT); 1717 s = Mach_spl0(); 1718 csr = *p_csr & ~(KN02_CSR_WRESERVED | 0xFF); 1719 if (on) 1720 *p_csr = csr | slotno; 1721 else 1722 *p_csr = csr & ~slotno; 1723 splx(s); 1724 } 1725 1726 /* 1727 * Object: 1728 * kmin_enable_intr EXPORTED function 1729 * 1730 * Enable/Disable interrupts from a TURBOchannel slot. 1731 * 1732 * We pretend we actually have 8 slots even if we really have 1733 * only 4: TCslots 0-2 maps to slots 0-2, TCslot3 maps to 1734 * slots 3-7 (see kmin_slot_hand_fill). 1735 */ 1736 void 1737 kmin_enable_intr(slotno, on) 1738 register unsigned int slotno; 1739 int on; 1740 { 1741 register unsigned mask; 1742 1743 switch (slotno) { 1744 case 0: 1745 case 1: 1746 case 2: 1747 return; 1748 case KMIN_SCSI_SLOT: 1749 mask = (KMIN_INTR_SCSI | KMIN_INTR_SCSI_PTR_LOAD | 1750 KMIN_INTR_SCSI_OVRUN | KMIN_INTR_SCSI_READ_E); 1751 break; 1752 case KMIN_LANCE_SLOT: 1753 mask = KMIN_INTR_LANCE; 1754 break; 1755 case KMIN_SCC0_SLOT: 1756 mask = KMIN_INTR_SCC_0; 1757 break; 1758 case KMIN_SCC1_SLOT: 1759 mask = KMIN_INTR_SCC_1; 1760 break; 1761 case KMIN_ASIC_SLOT: 1762 mask = KMIN_INTR_ASIC; 1763 break; 1764 default: 1765 return; 1766 } 1767 if (on) 1768 kmin_tc3_imask |= mask; 1769 else 1770 kmin_tc3_imask &= ~mask; 1771 } 1772 1773 /* 1774 * Object: 1775 * xine_enable_intr EXPORTED function 1776 * 1777 * Enable/Disable interrupts from a TURBOchannel slot. 1778 * 1779 * We pretend we actually have 11 slots even if we really have 1780 * only 3: TCslots 0-1 maps to slots 0-1, TCslot 2 is used for 1781 * the system (TCslot3), TCslot3 maps to slots 3-10 1782 * (see xine_slot_hand_fill). 1783 * Note that all these interrupts come in via the IMR. 1784 */ 1785 void 1786 xine_enable_intr(slotno, on) 1787 register unsigned int slotno; 1788 int on; 1789 { 1790 register unsigned mask; 1791 1792 switch (slotno) { 1793 case 0: /* a real slot, but */ 1794 mask = XINE_INTR_TC_0; 1795 break; 1796 case 1: /* a real slot, but */ 1797 mask = XINE_INTR_TC_1; 1798 break; 1799 case XINE_FLOPPY_SLOT: 1800 mask = XINE_INTR_FLOPPY; 1801 break; 1802 case XINE_SCSI_SLOT: 1803 mask = (XINE_INTR_SCSI | XINE_INTR_SCSI_PTR_LOAD | 1804 XINE_INTR_SCSI_OVRUN | XINE_INTR_SCSI_READ_E); 1805 break; 1806 case XINE_LANCE_SLOT: 1807 mask = XINE_INTR_LANCE; 1808 break; 1809 case XINE_SCC0_SLOT: 1810 mask = XINE_INTR_SCC_0; 1811 break; 1812 case XINE_DTOP_SLOT: 1813 mask = XINE_INTR_DTOP_RX; 1814 break; 1815 case XINE_ISDN_SLOT: 1816 mask = XINE_INTR_ISDN; 1817 break; 1818 case XINE_ASIC_SLOT: 1819 mask = XINE_INTR_ASIC; 1820 break; 1821 default: 1822 return;/* ignore */ 1823 } 1824 if (on) 1825 xine_tc3_imask |= mask; 1826 else 1827 xine_tc3_imask &= ~mask; 1828 } 1829 1830 #ifdef DS5000_240 1831 /* 1832 * UNTESTED!! 1833 * Object: 1834 * kn03_enable_intr EXPORTED function 1835 * 1836 * Enable/Disable interrupts from a TURBOchannel slot. 1837 * 1838 * We pretend we actually have 8 slots even if we really have 1839 * only 4: TCslots 0-2 maps to slots 0-2, TCslot3 maps to 1840 * slots 3-7 (see kn03_slot_hand_fill). 1841 */ 1842 void 1843 kn03_enable_intr(slotno, on) 1844 register unsigned int slotno; 1845 int on; 1846 { 1847 register unsigned mask; 1848 1849 switch (slotno) { 1850 case 0: 1851 mask = KN03_INTR_TC_0; 1852 break; 1853 case 1: 1854 mask = KN03_INTR_TC_1; 1855 break; 1856 case 2: 1857 mask = KN03_INTR_TC_2; 1858 break; 1859 case KN03_SCSI_SLOT: 1860 mask = (KN03_INTR_SCSI | KN03_INTR_SCSI_PTR_LOAD | 1861 KN03_INTR_SCSI_OVRUN | KN03_INTR_SCSI_READ_E); 1862 break; 1863 case KN03_LANCE_SLOT: 1864 mask = KN03_INTR_LANCE; 1865 break; 1866 case KN03_SCC0_SLOT: 1867 mask = KN03_INTR_SCC_0; 1868 break; 1869 case KN03_SCC1_SLOT: 1870 mask = KN03_INTR_SCC_1; 1871 break; 1872 case KN03_ASIC_SLOT: 1873 mask = KN03_INTR_ASIC; 1874 break; 1875 default: 1876 return; 1877 } 1878 if (on) 1879 kn03_tc3_imask |= mask; 1880 else 1881 kn03_tc3_imask &= ~mask; 1882 } 1883 #endif /* DS5000_240 */ 1884 1885 /* 1886 * Object: 1887 * kn02_slot_hand_fill EXPORTED function 1888 * 1889 * Fill in by hand the info for TC slots that are non-standard. 1890 * This is basically just the system slot on a 3max, it does not 1891 * look to me like it follows the TC rules although some of the 1892 * required info is indeed there. 1893 * 1894 */ 1895 void 1896 kn02_slot_hand_fill(slot) 1897 tc_option_t *slot; 1898 { 1899 slot[7].present = 1; 1900 slot[7].slot_size = 1; 1901 slot[7].rom_width = 1; 1902 #if unsafe 1903 bcopy(0xbffc0410, slot[7].module_name, TC_ROM_LLEN+1); 1904 #endif 1905 bcopy("KN02 ", slot[7].module_name, TC_ROM_LLEN+1); 1906 bcopy("DEC xxxx", slot[7].module_id, TC_ROM_LLEN+1); 1907 slot[7].k1seg_address = MACH_PHYS_TO_UNCACHED(KN02_SYS_DZ); 1908 } 1909 1910 /* 1911 * Object: 1912 * kmin_slot_hand_fill EXPORTED function 1913 * 1914 * Fill in by hand the info for TC slots that are non-standard. 1915 * This is the system slot on a 3min, which we think of as a 1916 * set of non-regular size TC slots. 1917 * 1918 */ 1919 void 1920 kmin_slot_hand_fill(slot) 1921 tc_option_t *slot; 1922 { 1923 register int i; 1924 1925 for (i = KMIN_SCSI_SLOT; i < KMIN_ASIC_SLOT+1; i++) { 1926 slot[i].present = 1; 1927 slot[i].slot_size = 1; 1928 slot[i].rom_width = 1; 1929 slot[i].unit = 0; 1930 bcopy("DEC KMIN", slot[i].module_id, TC_ROM_LLEN+1); 1931 } 1932 1933 /* scsi */ 1934 bcopy("PMAZ-AA ", slot[KMIN_SCSI_SLOT].module_name, TC_ROM_LLEN+1); 1935 slot[KMIN_SCSI_SLOT].k1seg_address = 1936 MACH_PHYS_TO_UNCACHED(KMIN_SYS_SCSI); 1937 1938 /* lance */ 1939 bcopy("PMAD-AA ", slot[KMIN_LANCE_SLOT].module_name, TC_ROM_LLEN+1); 1940 slot[KMIN_LANCE_SLOT].k1seg_address = 0; 1941 1942 /* scc */ 1943 bcopy("Z8530 ", slot[KMIN_SCC0_SLOT].module_name, TC_ROM_LLEN+1); 1944 slot[KMIN_SCC0_SLOT].k1seg_address = 1945 MACH_PHYS_TO_UNCACHED(KMIN_SYS_SCC_0); 1946 1947 slot[KMIN_SCC1_SLOT].unit = 1; 1948 bcopy("Z8530 ", slot[KMIN_SCC1_SLOT].module_name, TC_ROM_LLEN+1); 1949 slot[KMIN_SCC1_SLOT].k1seg_address = 1950 MACH_PHYS_TO_UNCACHED(KMIN_SYS_SCC_1); 1951 1952 /* asic */ 1953 bcopy("ASIC ", slot[KMIN_ASIC_SLOT].module_name, TC_ROM_LLEN+1); 1954 slot[KMIN_ASIC_SLOT].k1seg_address = 1955 MACH_PHYS_TO_UNCACHED(KMIN_SYS_ASIC); 1956 asic_init(0); 1957 } 1958 1959 /* 1960 * Object: 1961 * xine_slot_hand_fill EXPORTED function 1962 * 1963 * Fill in by hand the info for TC slots that are non-standard. 1964 * This is the system slot on a 3min, which we think of as a 1965 * set of non-regular size TC slots. 1966 * 1967 */ 1968 void 1969 xine_slot_hand_fill(slot) 1970 tc_option_t *slot; 1971 { 1972 register int i; 1973 1974 for (i = XINE_FLOPPY_SLOT; i < XINE_FRC_SLOT+1; i++) { 1975 slot[i].present = 1; 1976 slot[i].slot_size = 1; 1977 slot[i].rom_width = 1; 1978 slot[i].unit = 0; 1979 bcopy("DEC XINE", slot[i].module_id, TC_ROM_LLEN+1); 1980 } 1981 1982 /* floppy */ 1983 bcopy("XINE-FDC", slot[XINE_FLOPPY_SLOT].module_name, TC_ROM_LLEN+1); 1984 slot[XINE_FLOPPY_SLOT].k1seg_address = 1985 MACH_PHYS_TO_UNCACHED(XINE_SYS_FLOPPY); 1986 1987 /* scsi */ 1988 bcopy("PMAZ-AA ", slot[XINE_SCSI_SLOT].module_name, TC_ROM_LLEN+1); 1989 slot[XINE_SCSI_SLOT].k1seg_address = 1990 MACH_PHYS_TO_UNCACHED(XINE_SYS_SCSI); 1991 1992 /* lance */ 1993 bcopy("PMAD-AA ", slot[XINE_LANCE_SLOT].module_name, TC_ROM_LLEN+1); 1994 slot[XINE_LANCE_SLOT].k1seg_address = 1995 MACH_PHYS_TO_UNCACHED(XINE_SYS_LANCE); 1996 1997 /* scc */ 1998 bcopy("Z8530 ", slot[XINE_SCC0_SLOT].module_name, TC_ROM_LLEN+1); 1999 slot[XINE_SCC0_SLOT].k1seg_address = 2000 MACH_PHYS_TO_UNCACHED(XINE_SYS_SCC_0); 2001 2002 /* Desktop */ 2003 bcopy("DTOP ", slot[XINE_DTOP_SLOT].module_name, TC_ROM_LLEN+1); 2004 slot[XINE_DTOP_SLOT].k1seg_address = 2005 MACH_PHYS_TO_UNCACHED(XINE_SYS_DTOP+0x20000); /* why? */ 2006 2007 /* ISDN */ 2008 bcopy("AMD79c30", slot[XINE_ISDN_SLOT].module_name, TC_ROM_LLEN+1); 2009 slot[XINE_ISDN_SLOT].k1seg_address = 2010 MACH_PHYS_TO_UNCACHED(XINE_SYS_ISDN); 2011 2012 /* Video */ 2013 bcopy("PMAG-DV ", slot[XINE_CFB_SLOT].module_name, TC_ROM_LLEN+1); 2014 slot[XINE_CFB_SLOT].k1seg_address = 2015 MACH_PHYS_TO_CACHED(XINE_PHYS_CFB_START); 2016 2017 /* asic */ 2018 bcopy("ASIC ", slot[XINE_ASIC_SLOT].module_name, TC_ROM_LLEN+1); 2019 slot[XINE_ASIC_SLOT].k1seg_address = 2020 MACH_PHYS_TO_UNCACHED(XINE_SYS_ASIC); 2021 2022 /* free-running counter (high resolution mapped time) */ 2023 bcopy("XINE-FRC", slot[XINE_FRC_SLOT].module_name, TC_ROM_LLEN+1); 2024 slot[XINE_FRC_SLOT].k1seg_address = 2025 MACH_PHYS_TO_UNCACHED(XINE_REG_FCTR); 2026 asic_init(1); 2027 } 2028 2029 #ifdef DS5000_240 2030 /* 2031 * UNTESTED!! 2032 * Object: 2033 * kn03_slot_hand_fill EXPORTED function 2034 * 2035 * Fill in by hand the info for TC slots that are non-standard. 2036 * This is the system slot on a 3max+, which we think of as a 2037 * set of non-regular size TC slots. 2038 * 2039 */ 2040 void 2041 kn03_slot_hand_fill(slot) 2042 tc_option_t *slot; 2043 { 2044 register int i; 2045 2046 for (i = KN03_SCSI_SLOT; i < KN03_ASIC_SLOT+1; i++) { 2047 slot[i].present = 1; 2048 slot[i].slot_size = 1; 2049 slot[i].rom_width = 1; 2050 slot[i].unit = 0; 2051 bcopy("DEC KN03", slot[i].module_id, TC_ROM_LLEN+1); 2052 } 2053 2054 /* scsi */ 2055 bcopy("PMAZ-AA ", slot[KN03_SCSI_SLOT].module_name, TC_ROM_LLEN+1); 2056 slot[KN03_SCSI_SLOT].k1seg_address = 2057 MACH_PHYS_TO_UNCACHED(KN03_SYS_SCSI); 2058 2059 /* lance */ 2060 bcopy("PMAD-AA ", slot[KN03_LANCE_SLOT].module_name, TC_ROM_LLEN+1); 2061 slot[KN03_LANCE_SLOT].k1seg_address = 0; 2062 2063 /* scc */ 2064 bcopy("Z8530 ", slot[KN03_SCC0_SLOT].module_name, TC_ROM_LLEN+1); 2065 slot[KN03_SCC0_SLOT].k1seg_address = 2066 MACH_PHYS_TO_UNCACHED(KN03_SYS_SCC_0); 2067 2068 slot[KN03_SCC1_SLOT].unit = 1; 2069 bcopy("Z8530 ", slot[KN03_SCC1_SLOT].module_name, TC_ROM_LLEN+1); 2070 slot[KN03_SCC1_SLOT].k1seg_address = 2071 MACH_PHYS_TO_UNCACHED(KN03_SYS_SCC_1); 2072 2073 /* asic */ 2074 bcopy("ASIC ", slot[KN03_ASIC_SLOT].module_name, TC_ROM_LLEN+1); 2075 slot[KN03_ASIC_SLOT].k1seg_address = 2076 MACH_PHYS_TO_UNCACHED(KN03_SYS_ASIC); 2077 asic_init(0); 2078 } 2079 #endif /* DS5000_240 */ 2080 2081 /* 2082 * Initialize the I/O asic 2083 */ 2084 static void 2085 asic_init(isa_maxine) 2086 int isa_maxine; 2087 { 2088 volatile u_int *decoder; 2089 2090 /* These are common between 3min and maxine */ 2091 decoder = (volatile u_int *)ASIC_REG_LANCE_DECODE(asic_base); 2092 *decoder = KMIN_LANCE_CONFIG; 2093 } 2094 #endif /* DS5000 */ 2095