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