1 /* autoconf.c 6.3 83/08/11 */ 2 3 /* 4 * Setup the system to run on the current machine. 5 * 6 * Configure() is called at boot time and initializes the uba and mba 7 * device tables and the memory controller monitoring. Available 8 * devices are determined (from possibilities mentioned in ioconf.c), 9 * and the drivers are initialized. 10 * 11 * N.B.: A lot of the conditionals based on processor type say 12 * #if VAX780 13 * and 14 * #if VAX750 15 * which may be incorrect after more processors are introduced if they 16 * are like either of these machines. 17 * 18 * TODO: 19 * use pcpu info about whether a ubasr exists 20 */ 21 22 #include "mba.h" 23 #include "uba.h" 24 25 #include "../machine/pte.h" 26 27 #include "../h/param.h" 28 #include "../h/systm.h" 29 #include "../h/map.h" 30 #include "../h/buf.h" 31 #include "../h/dk.h" 32 #include "../h/vm.h" 33 #include "../h/conf.h" 34 #include "../h/dmap.h" 35 36 #include "../vax/cpu.h" 37 #include "../vax/mem.h" 38 #include "../vax/mtpr.h" 39 #include "../vax/nexus.h" 40 #include "../vax/scb.h" 41 #include "../vaxmba/mbareg.h" 42 #include "../vaxmba/mbavar.h" 43 #include "../vaxuba/ubareg.h" 44 #include "../vaxuba/ubavar.h" 45 46 /* 47 * The following several variables are related to 48 * the configuration process, and are used in initializing 49 * the machine. 50 */ 51 int cold; /* if 1, still working on cold-start */ 52 int nexnum; /* current nexus number */ 53 int dkn; /* number of iostat dk numbers assigned so far */ 54 55 /* 56 * Addresses of the (locore) routines which bootstrap us from 57 * hardware traps to C code. Filled into the system control block 58 * as necessary. 59 */ 60 #if NMBA > 0 61 int (*mbaintv[4])() = { Xmba0int, Xmba1int, Xmba2int, Xmba3int }; 62 #endif 63 #if VAX780 64 int (*ubaintv[4])() = { Xua0int, Xua1int, Xua2int, Xua3int }; 65 #endif 66 67 /* 68 * This allocates the space for the per-uba information, 69 * such as buffered data path usage. 70 */ 71 struct uba_hd uba_hd[MAXNUBA]; 72 73 /* 74 * Determine mass storage and memory configuration for a machine. 75 * Get cpu type, and then switch out to machine specific procedures 76 * which will probe adaptors to see what is out there. 77 */ 78 configure() 79 { 80 union cpusid cpusid; 81 register struct percpu *ocp; 82 register int *ip; 83 extern char Sysbase[]; 84 85 cpusid.cpusid = mfpr(SID); 86 for (ocp = percpu; ocp->pc_cputype; ocp++) 87 if (ocp->pc_cputype == cpusid.cpuany.cp_type) { 88 probenexus(ocp); 89 /* 90 * Write protect the scb and UNIBUS interrupt vectors. 91 * It is strange that this code is here, but this is 92 * as soon as we are done mucking with it, and the 93 * write-enable was done in assembly language 94 * to which we will never return. 95 */ 96 ip = (int *)Sysmap + 1; *ip &= ~PG_PROT; *ip |= PG_KR; 97 ip++; *ip &= ~PG_PROT; *ip |= PG_KR; 98 #if NUBA > 1 99 ip++; *ip &= ~PG_PROT; *ip |= PG_KR; 100 #endif 101 mtpr(TBIS, Sysbase); 102 #if GENERIC 103 setconf(); 104 #endif 105 /* 106 * Configure swap area and related system 107 * parameter based on device(s) used. 108 */ 109 swapconf(); 110 cold = 0; 111 memenable(); 112 return; 113 } 114 printf("cpu type %d not configured\n", cpusid.cpuany.cp_type); 115 asm("halt"); 116 } 117 118 /* 119 * Probe nexus space, finding the interconnects 120 * and setting up and probing mba's and uba's for devices. 121 */ 122 /*ARGSUSED*/ 123 probenexus(pcpu) 124 register struct percpu *pcpu; 125 { 126 register struct nexus *nxv; 127 struct nexus *nxp = pcpu->pc_nexbase; 128 union nexcsr nexcsr; 129 int i; 130 131 nexnum = 0, nxv = nexus; 132 for (; nexnum < pcpu->pc_nnexus; nexnum++, nxp++, nxv++) { 133 nxaccess(nxp, Nexmap[nexnum]); 134 if (badaddr((caddr_t)nxv, 4)) 135 continue; 136 if (pcpu->pc_nextype && pcpu->pc_nextype[nexnum] != NEX_ANY) 137 nexcsr.nex_csr = pcpu->pc_nextype[nexnum]; 138 else 139 nexcsr = nxv->nexcsr; 140 if (nexcsr.nex_csr&NEX_APD) 141 continue; 142 switch (nexcsr.nex_type) { 143 144 case NEX_MBA: 145 printf("mba%d at tr%d\n", nummba, nexnum); 146 if (nummba >= NMBA) { 147 printf("%d mba's", nummba); 148 goto unconfig; 149 } 150 #if NMBA > 0 151 mbafind(nxv, nxp); 152 nummba++; 153 #endif 154 break; 155 156 case NEX_UBA0: 157 case NEX_UBA1: 158 case NEX_UBA2: 159 case NEX_UBA3: 160 printf("uba%d at tr%d\n", numuba, nexnum); 161 if (numuba >= 4) { 162 printf("5 uba's"); 163 goto unsupp; 164 } 165 #if VAX780 166 if (cpu == VAX_780) 167 setscbnex(ubaintv[numuba]); 168 #endif 169 i = nexcsr.nex_type - NEX_UBA0; 170 unifind((struct uba_regs *)nxv, (struct uba_regs *)nxp, 171 umem[i], pcpu->pc_umaddr[i], UMEMmap[i]); 172 #if VAX780 173 if (cpu == VAX_780) 174 ((struct uba_regs *)nxv)->uba_cr = 175 UBACR_IFS|UBACR_BRIE| 176 UBACR_USEFIE|UBACR_SUEFIE| 177 (((struct uba_regs *)nxv)->uba_cr&0x7c000000); 178 #endif 179 numuba++; 180 break; 181 182 case NEX_DR32: 183 /* there can be more than one... are there other codes??? */ 184 printf("dr32"); 185 goto unsupp; 186 187 case NEX_MEM4: 188 case NEX_MEM4I: 189 case NEX_MEM16: 190 case NEX_MEM16I: 191 case NEX_MEM64L: 192 case NEX_MEM64LI: 193 case NEX_MEM64U: 194 case NEX_MEM64UI: 195 case NEX_MEM64I: 196 printf("mcr%d at tr%d\n", nmcr, nexnum); 197 if (nmcr >= 4) { 198 printf("5 mcr's"); 199 goto unsupp; 200 } 201 mcraddr[nmcr++] = (struct mcr *)nxv; 202 break; 203 204 case NEX_MPM0: 205 case NEX_MPM1: 206 case NEX_MPM2: 207 case NEX_MPM3: 208 printf("mpm"); 209 goto unsupp; 210 211 case NEX_CI: 212 printf("ci"); 213 goto unsupp; 214 215 default: 216 printf("nexus type %x", nexcsr.nex_type); 217 unsupp: 218 printf(" unsupported (at tr %d)\n", nexnum); 219 continue; 220 unconfig: 221 printf(" not configured\n"); 222 continue; 223 } 224 } 225 } 226 227 #if NMBA > 0 228 struct mba_device *mbaconfig(); 229 /* 230 * Find devices attached to a particular mba 231 * and look for each device found in the massbus 232 * initialization tables. 233 */ 234 mbafind(nxv, nxp) 235 struct nexus *nxv, *nxp; 236 { 237 register struct mba_regs *mdp; 238 register struct mba_drv *mbd; 239 register struct mba_device *mi; 240 register struct mba_slave *ms; 241 int dn, dt, sn; 242 struct mba_device fnd; 243 244 mdp = (struct mba_regs *)nxv; 245 mba_hd[nummba].mh_mba = mdp; 246 mba_hd[nummba].mh_physmba = (struct mba_regs *)nxp; 247 setscbnex(mbaintv[nummba]); 248 fnd.mi_mba = mdp; 249 fnd.mi_mbanum = nummba; 250 for (mbd = mdp->mba_drv, dn = 0; mbd < &mdp->mba_drv[8]; mbd++, dn++) { 251 if ((mbd->mbd_ds&MBDS_DPR) == 0) 252 continue; 253 mdp->mba_sr |= MBSR_NED; /* si kludge */ 254 dt = mbd->mbd_dt & 0xffff; 255 if (dt == 0) 256 continue; 257 if (mdp->mba_sr&MBSR_NED) 258 continue; /* si kludge */ 259 if (dt == MBDT_MOH) 260 continue; 261 fnd.mi_drive = dn; 262 #define qeq(a, b) ( a == b || a == '?' ) 263 if ((mi = mbaconfig(&fnd, dt)) && (dt & MBDT_TAP)) 264 for (sn = 0; sn < 8; sn++) { 265 mbd->mbd_tc = sn; 266 for (ms = mbsinit; ms->ms_driver; ms++) 267 if (ms->ms_driver == mi->mi_driver && 268 ms->ms_alive == 0 && 269 qeq(ms->ms_ctlr, mi->mi_unit) && 270 qeq(ms->ms_slave, sn) && 271 (*ms->ms_driver->md_slave)(mi, ms, sn)) { 272 printf("%s%d at %s%d slave %d\n" 273 , ms->ms_driver->md_sname 274 , ms->ms_unit 275 , mi->mi_driver->md_dname 276 , mi->mi_unit 277 , sn 278 ); 279 ms->ms_alive = 1; 280 ms->ms_ctlr = mi->mi_unit; 281 ms->ms_slave = sn; 282 } 283 } 284 } 285 mdp->mba_cr = MBCR_INIT; 286 mdp->mba_cr = MBCR_IE; 287 } 288 289 /* 290 * Have found a massbus device; 291 * see if it is in the configuration table. 292 * If so, fill in its data. 293 */ 294 struct mba_device * 295 mbaconfig(ni, type) 296 register struct mba_device *ni; 297 register int type; 298 { 299 register struct mba_device *mi; 300 register short *tp; 301 register struct mba_hd *mh; 302 303 for (mi = mbdinit; mi->mi_driver; mi++) { 304 if (mi->mi_alive) 305 continue; 306 tp = mi->mi_driver->md_type; 307 for (mi->mi_type = 0; *tp; tp++, mi->mi_type++) 308 if (*tp == (type&MBDT_TYPE)) 309 goto found; 310 continue; 311 found: 312 #define match(fld) (ni->fld == mi->fld || mi->fld == '?') 313 if (!match(mi_drive) || !match(mi_mbanum)) 314 continue; 315 printf("%s%d at mba%d drive %d\n", 316 mi->mi_driver->md_dname, mi->mi_unit, 317 ni->mi_mbanum, ni->mi_drive); 318 mi->mi_alive = 1; 319 mh = &mba_hd[ni->mi_mbanum]; 320 mi->mi_hd = mh; 321 mh->mh_mbip[ni->mi_drive] = mi; 322 mh->mh_ndrive++; 323 mi->mi_mba = ni->mi_mba; 324 mi->mi_drv = &mi->mi_mba->mba_drv[ni->mi_drive]; 325 mi->mi_mbanum = ni->mi_mbanum; 326 mi->mi_drive = ni->mi_drive; 327 /* 328 * If drive has never been seen before, 329 * give it a dkn for statistics. 330 */ 331 if (mi->mi_driver->md_info[mi->mi_unit] == 0) { 332 mi->mi_driver->md_info[mi->mi_unit] = mi; 333 if (mi->mi_dk && dkn < DK_NDRIVE) 334 mi->mi_dk = dkn++; 335 else 336 mi->mi_dk = -1; 337 } 338 (*mi->mi_driver->md_attach)(mi); 339 return (mi); 340 } 341 return (0); 342 } 343 #endif 344 345 /* 346 * Fixctlrmask fixes the masks of the driver ctlr routines 347 * which otherwise save r10 and r11 where the interrupt and br 348 * level are passed through. 349 */ 350 fixctlrmask() 351 { 352 register struct uba_ctlr *um; 353 register struct uba_device *ui; 354 register struct uba_driver *ud; 355 #define phys(a,b) ((b)(((int)(a))&0x7fffffff)) 356 357 for (um = ubminit; ud = phys(um->um_driver, struct uba_driver *); um++) 358 *phys(ud->ud_probe, short *) &= ~0xc00; 359 for (ui = ubdinit; ud = phys(ui->ui_driver, struct uba_driver *); ui++) 360 *phys(ud->ud_probe, short *) &= ~0xc00; 361 } 362 363 /* 364 * Find devices on a UNIBUS. 365 * Uses per-driver routine to set <br,cvec> into <r11,r10>, 366 * and then fills in the tables, with help from a per-driver 367 * slave initialization routine. 368 */ 369 unifind(vubp, pubp, vumem, pumem, memmap) 370 struct uba_regs *vubp, *pubp; 371 caddr_t vumem, pumem; 372 struct pte *memmap; 373 { 374 #ifndef lint 375 register int br, cvec; /* MUST BE r11, r10 */ 376 #else 377 /* 378 * Lint doesn't realize that these 379 * can be initialized asynchronously 380 * when devices interrupt. 381 */ 382 register int br = 0, cvec = 0; 383 #endif 384 register struct uba_device *ui; 385 register struct uba_ctlr *um; 386 u_short *reg, *ap, addr; 387 struct uba_hd *uhp; 388 struct uba_driver *udp; 389 int i, (**ivec)(), haveubasr; 390 caddr_t ualloc, zmemall(); 391 extern int catcher[256]; 392 393 /* 394 * Initialize the UNIBUS, by freeing the map 395 * registers and the buffered data path registers 396 */ 397 uhp = &uba_hd[numuba]; 398 uhp->uh_map = (struct map *)calloc(UAMSIZ * sizeof (struct map)); 399 ubainitmaps(uhp); 400 haveubasr = cpu == VAX_780; 401 402 /* 403 * Save virtual and physical addresses 404 * of adaptor, and allocate and initialize 405 * the UNIBUS interrupt vector. 406 */ 407 uhp->uh_uba = vubp; 408 uhp->uh_physuba = pubp; 409 if (numuba == 0) 410 uhp->uh_vec = UNIvec; 411 #if NUBA > 1 412 else if (numuba == 1) 413 uhp->uh_vec = UNI1vec; 414 else { 415 #if defined(VAX_750) 416 if (cpu == VAX_750) 417 printf("More than 2 UBA's not supported\n"); 418 else 419 #endif 420 uhp->uh_vec = (int(**)())calloc(512); 421 } 422 #endif 423 for (i = 0; i < 128; i++) 424 uhp->uh_vec[i] = 425 scbentry(&catcher[i*2], SCB_ISTACK); 426 /* 427 * Set last free interrupt vector for devices with 428 * programmable interrupt vectors. Use is to decrement 429 * this number and use result as interrupt vector. 430 */ 431 uhp->uh_lastiv = 0x200; 432 433 ubaaccess(pumem, memmap); 434 #if VAX780 435 if (haveubasr) { 436 vubp->uba_sr = vubp->uba_sr; 437 vubp->uba_cr = UBACR_IFS|UBACR_BRIE; 438 } 439 #endif 440 /* 441 * Grab some memory to record the umem address space we allocate, 442 * so we can be sure not to place two devices at the same address. 443 * 444 * We could use just 1/8 of this (we only want a 1 bit flag) but 445 * we are going to give it back anyway, and that would make the 446 * code here bigger (which we can't give back), so ... 447 * 448 * One day, someone will make a unibus with something other than 449 * an 8K i/o address space, & screw this totally. 450 */ 451 ualloc = zmemall(memall, 8*1024); 452 if (ualloc == (caddr_t)0) 453 panic("no mem for unifind"); 454 455 /* 456 * Map the first page of UNIBUS i/o 457 * space to the first page of memory 458 * for devices which will need to dma 459 * output to produce an interrupt. 460 */ 461 *(int *)(&vubp->uba_map[0]) = UBAMR_MRV; 462 463 #define ubaoff(off) ((off)&0x1fff) 464 #define ubaddr(off) (u_short *)((int)vumem + (ubaoff(off)|0x3e000)) 465 /* 466 * Check each unibus mass storage controller. 467 * For each one which is potentially on this uba, 468 * see if it is really there, and if it is record it and 469 * then go looking for slaves. 470 */ 471 for (um = ubminit; udp = um->um_driver; um++) { 472 if (um->um_ubanum != numuba && um->um_ubanum != '?') 473 continue; 474 addr = (u_short)um->um_addr; 475 /* 476 * use the particular address specified first, 477 * or if it is given as "0", of there is no device 478 * at that address, try all the standard addresses 479 * in the driver til we find it 480 */ 481 for (ap = udp->ud_addr; addr || (addr = *ap++); addr = 0) { 482 483 if (ualloc[ubaoff(addr)]) 484 continue; 485 reg = ubaddr(addr); 486 if (badaddr((caddr_t)reg, 2)) 487 continue; 488 #if VAX780 489 if (haveubasr && vubp->uba_sr) { 490 vubp->uba_sr = vubp->uba_sr; 491 continue; 492 } 493 #endif 494 cvec = 0x200; 495 i = (*udp->ud_probe)(reg, um->um_ctlr); 496 #if VAX780 497 if (haveubasr && vubp->uba_sr) { 498 vubp->uba_sr = vubp->uba_sr; 499 continue; 500 } 501 #endif 502 if (i == 0) 503 continue; 504 printf("%s%d at uba%d csr %o ", 505 udp->ud_mname, um->um_ctlr, numuba, addr); 506 if (cvec == 0) { 507 printf("zero vector\n"); 508 continue; 509 } 510 if (cvec == 0x200) { 511 printf("didn't interrupt\n"); 512 continue; 513 } 514 printf("vec %o, ipl %x\n", cvec, br); 515 um->um_alive = 1; 516 um->um_ubanum = numuba; 517 um->um_hd = &uba_hd[numuba]; 518 um->um_addr = (caddr_t)reg; 519 udp->ud_minfo[um->um_ctlr] = um; 520 for (ivec = um->um_intr; *ivec; ivec++) { 521 um->um_hd->uh_vec[cvec/4] = 522 scbentry(*ivec, SCB_ISTACK); 523 cvec += 4; 524 } 525 for (ui = ubdinit; ui->ui_driver; ui++) { 526 if (ui->ui_driver != udp || ui->ui_alive || 527 ui->ui_ctlr != um->um_ctlr && ui->ui_ctlr != '?' || 528 ui->ui_ubanum != numuba && ui->ui_ubanum != '?') 529 continue; 530 if ((*udp->ud_slave)(ui, reg)) { 531 ui->ui_alive = 1; 532 ui->ui_ctlr = um->um_ctlr; 533 ui->ui_ubanum = numuba; 534 ui->ui_hd = &uba_hd[numuba]; 535 ui->ui_addr = (caddr_t)reg; 536 ui->ui_physaddr = pumem + ubdevreg(addr); 537 if (ui->ui_dk && dkn < DK_NDRIVE) 538 ui->ui_dk = dkn++; 539 else 540 ui->ui_dk = -1; 541 ui->ui_mi = um; 542 /* ui_type comes from driver */ 543 udp->ud_dinfo[ui->ui_unit] = ui; 544 printf("%s%d at %s%d slave %d\n", 545 udp->ud_dname, ui->ui_unit, 546 udp->ud_mname, um->um_ctlr, ui->ui_slave); 547 (*udp->ud_attach)(ui); 548 } 549 } 550 break; 551 } 552 } 553 /* 554 * Now look for non-mass storage peripherals. 555 */ 556 for (ui = ubdinit; udp = ui->ui_driver; ui++) { 557 if (ui->ui_ubanum != numuba && ui->ui_ubanum != '?' || 558 ui->ui_alive || ui->ui_slave != -1) 559 continue; 560 addr = (u_short)ui->ui_addr; 561 562 for (ap = udp->ud_addr; addr || (addr = *ap++); addr = 0) { 563 564 if (ualloc[ubaoff(addr)]) 565 continue; 566 reg = ubaddr(addr); 567 if (badaddr((caddr_t)reg, 2)) 568 continue; 569 #if VAX780 570 if (haveubasr && vubp->uba_sr) { 571 vubp->uba_sr = vubp->uba_sr; 572 continue; 573 } 574 #endif 575 cvec = 0x200; 576 i = (*udp->ud_probe)(reg); 577 #if VAX780 578 if (haveubasr && vubp->uba_sr) { 579 vubp->uba_sr = vubp->uba_sr; 580 continue; 581 } 582 #endif 583 if (i == 0) 584 continue; 585 printf("%s%d at uba%d csr %o ", 586 ui->ui_driver->ud_dname, ui->ui_unit, numuba, addr); 587 if (cvec == 0) { 588 printf("zero vector\n"); 589 continue; 590 } 591 if (cvec == 0x200) { 592 printf("didn't interrupt\n"); 593 continue; 594 } 595 printf("vec %o, ipl %x\n", cvec, br); 596 while (--i >= 0) 597 ualloc[ubaoff(addr+i)] = 1; 598 ui->ui_hd = &uba_hd[numuba]; 599 for (ivec = ui->ui_intr; *ivec; ivec++) { 600 ui->ui_hd->uh_vec[cvec/4] = 601 scbentry(*ivec, SCB_ISTACK); 602 cvec += 4; 603 } 604 ui->ui_alive = 1; 605 ui->ui_ubanum = numuba; 606 ui->ui_addr = (caddr_t)reg; 607 ui->ui_physaddr = pumem + ubdevreg(addr); 608 ui->ui_dk = -1; 609 /* ui_type comes from driver */ 610 udp->ud_dinfo[ui->ui_unit] = ui; 611 (*udp->ud_attach)(ui); 612 break; 613 } 614 } 615 616 #ifdef AUTO_DEBUG 617 printf("Unibus allocation map"); 618 for (i = 0; i < 8*1024; ) { 619 register n, m; 620 621 if ((i % 128) == 0) { 622 printf("\n%6o:", i); 623 for (n = 0; n < 128; n++) 624 if (ualloc[i+n]) 625 break; 626 if (n == 128) { 627 i += 128; 628 continue; 629 } 630 } 631 632 for (n = m = 0; n < 16; n++) { 633 m <<= 1; 634 m |= ualloc[i++]; 635 } 636 637 printf(" %4x", m); 638 } 639 printf("\n"); 640 #endif 641 642 wmemfree(ualloc, 8*1024); 643 } 644 645 setscbnex(fn) 646 int (*fn)(); 647 { 648 register struct scb *scbp = &scb; 649 650 scbp->scb_ipl14[nexnum] = scbp->scb_ipl15[nexnum] = 651 scbp->scb_ipl16[nexnum] = scbp->scb_ipl17[nexnum] = 652 scbentry(fn, SCB_ISTACK); 653 } 654 655 /* 656 * Make a nexus accessible at physical address phys 657 * by mapping kernel ptes starting at pte. 658 * 659 * WE LEAVE ALL NEXI MAPPED; THIS IS PERHAPS UNWISE 660 * SINCE MISSING NEXI DONT RESPOND. BUT THEN AGAIN 661 * PRESENT NEXI DONT RESPOND TO ALL OF THEIR ADDRESS SPACE. 662 */ 663 nxaccess(physa, pte) 664 struct nexus *physa; 665 register struct pte *pte; 666 { 667 register int i = btop(sizeof (struct nexus)); 668 register unsigned v = btop(physa); 669 670 do 671 *(int *)pte++ = PG_V|PG_KW|v++; 672 while (--i > 0); 673 mtpr(TBIA, 0); 674 } 675 676 ubaaccess(pumem, pte) 677 caddr_t pumem; 678 register struct pte *pte; 679 { 680 register int i = 512; 681 register unsigned v = btop(pumem); 682 683 do 684 *(int *)pte++ = PG_V|PG_KW|v++; 685 while (--i > 0); 686 mtpr(TBIA, 0); 687 } 688 689 #define DMMIN 32 690 #define DMMAX 1024 691 #define DMTEXT 1024 692 #define MAXDUMP (10*2048) 693 /* 694 * Configure swap space and related parameters. 695 */ 696 swapconf() 697 { 698 register struct swdevt *swp; 699 register int nblks; 700 701 for (swp = swdevt; swp->sw_dev; swp++) { 702 if (bdevsw[major(swp->sw_dev)].d_psize) 703 nblks = 704 (*bdevsw[major(swp->sw_dev)].d_psize)(swp->sw_dev); 705 if (swp->sw_nblks == 0 || swp->sw_nblks > nblks) 706 swp->sw_nblks = nblks; 707 } 708 if (!cold) /* in case called for mba device */ 709 return; 710 if (dumplo == 0) 711 dumplo = swdevt[0].sw_nblks - MAXDUMP; 712 if (dumplo < 0) 713 dumplo = 0; 714 if (dmmin == 0) 715 dmmin = DMMIN; 716 if (dmmax == 0) 717 dmmax = DMMAX; 718 if (dmtext == 0) 719 dmtext = DMTEXT; 720 if (dmtext > dmmax) 721 dmtext = dmmax; 722 } 723