1 /* $NetBSD: promdev.c,v 1.19 2006/06/20 05:41:59 jdc Exp $ */ 2 3 /* 4 * Copyright (c) 1993 Paul Kranenburg 5 * Copyright (c) 1995 Gordon W. Ross 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. All advertising materials mentioning features or use of this software 17 * must display the following acknowledgement: 18 * This product includes software developed by Paul Kranenburg. 19 * 4. The name of the author may not be used to endorse or promote products 20 * derived from this software without specific prior written permission 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 25 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 /* 35 * Note: the `#ifndef BOOTXX' in here serve to queeze the code size 36 * of the 1st-stage boot program. 37 */ 38 #include <sys/param.h> 39 #include <sys/reboot.h> 40 #include <sys/systm.h> 41 #include <machine/oldmon.h> 42 #include <machine/promlib.h> 43 #include <machine/ctlreg.h> 44 #include <sparc/sparc/asm.h> 45 #include <machine/pte.h> 46 47 #include <lib/libsa/stand.h> 48 #include <lib/libkern/libkern.h> 49 #include <sparc/stand/common/promdev.h> 50 51 #ifndef BOOTXX 52 #include <sys/disklabel.h> 53 #include <dev/sun/disklabel.h> 54 #include <dev/raidframe/raidframevar.h> 55 #endif 56 57 /* OBP V0-3 PROM vector */ 58 #define obpvec ((struct promvec *)romp) 59 60 int obp_close __P((struct open_file *)); 61 int obp_strategy __P((void *, int, daddr_t, size_t, void *, size_t *)); 62 int obp_v0_strategy __P((void *, int, daddr_t, size_t, void *, size_t *)); 63 ssize_t obp_v0_xmit __P((struct promdata *, void *, size_t)); 64 ssize_t obp_v0_recv __P((struct promdata *, void *, size_t)); 65 int obp_v2_strategy __P((void *, int, daddr_t, size_t, void *, size_t *)); 66 ssize_t obp_v2_xmit __P((struct promdata *, void *, size_t)); 67 ssize_t obp_v2_recv __P((struct promdata *, void *, size_t)); 68 int oldmon_close __P((struct open_file *)); 69 int oldmon_strategy __P((void *, int, daddr_t, size_t, void *, size_t *)); 70 void oldmon_iclose __P((struct saioreq *)); 71 int oldmon_iopen __P((struct promdata *)); 72 ssize_t oldmon_xmit __P((struct promdata *, void *, size_t)); 73 ssize_t oldmon_recv __P((struct promdata *, void *, size_t)); 74 75 static char *oldmon_mapin __P((u_long, int, int)); 76 #ifndef BOOTXX 77 static char *mygetpropstring __P((int, char *)); 78 static int getdevtype __P((int, char *)); 79 #endif 80 81 extern struct fs_ops file_system_nfs[]; 82 extern struct fs_ops file_system_ufs[]; 83 84 #define null_devopen (void *)sparc_noop 85 #define null_devioctl (void *)sparc_noop 86 87 #if 0 88 struct devsw devsw[]; 89 int ndevs = (sizeof(devsw)/sizeof(devsw[0])); 90 #endif 91 92 struct devsw oldmon_devsw = 93 { "oldmon", oldmon_strategy, null_devopen, oldmon_close, null_devioctl }; 94 struct devsw obp_v0_devsw = 95 { "obp v0", obp_v0_strategy, null_devopen, obp_close, null_devioctl }; 96 struct devsw obp_v2_devsw = 97 { "obp v2", obp_v2_strategy, null_devopen, obp_close, null_devioctl }; 98 99 100 char prom_bootdevice[MAX_PROM_PATH]; 101 static int saveecho; 102 103 #ifndef BOOTXX 104 static daddr_t doffset = 0; 105 #endif 106 107 108 void 109 putchar(c) 110 int c; 111 { 112 113 if (c == '\n') 114 prom_putchar('\r'); 115 prom_putchar(c); 116 } 117 118 void 119 _rtt() 120 { 121 prom_halt(); 122 } 123 124 int 125 devopen(f, fname, file) 126 struct open_file *f; 127 const char *fname; 128 char **file; 129 { 130 int error = 0, fd = 0; 131 struct promdata *pd; 132 #ifndef BOOTXX 133 char *partition; 134 int part = 0; 135 char rawpart[MAX_PROM_PATH]; 136 struct promdata *disk_pd; 137 char buf[DEV_BSIZE]; 138 struct disklabel *dlp; 139 size_t read; 140 #endif 141 142 pd = (struct promdata *)alloc(sizeof *pd); 143 f->f_devdata = (void *)pd; 144 145 switch (prom_version()) { 146 case PROM_OLDMON: 147 error = oldmon_iopen(pd); 148 #ifndef BOOTXX 149 pd->xmit = oldmon_xmit; 150 pd->recv = oldmon_recv; 151 #endif 152 f->f_dev = &oldmon_devsw; 153 saveecho = *romVectorPtr->echo; 154 *romVectorPtr->echo = 0; 155 break; 156 157 case PROM_OBP_V0: 158 case PROM_OBP_V2: 159 case PROM_OBP_V3: 160 case PROM_OPENFIRM: 161 if (*prom_bootdevice == '\0') { 162 error = ENXIO; 163 break; 164 } 165 fd = prom_open(prom_bootdevice); 166 if (fd == 0) { 167 error = ENXIO; 168 break; 169 } 170 pd->fd = fd; 171 switch (prom_version()) { 172 case PROM_OBP_V0: 173 #ifndef BOOTXX 174 pd->xmit = obp_v0_xmit; 175 pd->recv = obp_v0_recv; 176 #endif 177 f->f_dev = &obp_v0_devsw; 178 break; 179 case PROM_OBP_V2: 180 case PROM_OBP_V3: 181 case PROM_OPENFIRM: 182 #ifndef BOOTXX 183 pd->xmit = obp_v2_xmit; 184 pd->recv = obp_v2_recv; 185 #endif 186 f->f_dev = &obp_v2_devsw; 187 } 188 } 189 190 if (error) { 191 printf("Can't open device `%s'\n", prom_bootdevice); 192 return (error); 193 } 194 195 #ifdef BOOTXX 196 pd->devtype = DT_BLOCK; 197 #else /* BOOTXX */ 198 pd->devtype = getdevtype(fd, prom_bootdevice); 199 /* Assume type BYTE is a raw device */ 200 if (pd->devtype != DT_BYTE) 201 *file = (char *)fname; 202 203 if (pd->devtype == DT_NET) { 204 bcopy(file_system_nfs, file_system, sizeof(struct fs_ops)); 205 if ((error = net_open(pd)) != 0) { 206 printf("Can't open NFS network connection on `%s'\n", 207 prom_bootdevice); 208 return (error); 209 } 210 } else { 211 bcopy(file_system_ufs, file_system, sizeof(struct fs_ops)); 212 213 #ifdef NOTDEF_DEBUG 214 printf("devopen: Checking disklabel for RAID partition\n"); 215 #endif 216 217 /* 218 * We need to read from the raw partition (i.e. the 219 * beginning of the disk in order to check the NetBSD 220 * disklabel to see if the boot partition is type RAID. 221 * 222 * For machines with prom_version() == PROM_OLDMON, we 223 * only handle boot from RAID for the first disk partition. 224 */ 225 disk_pd = (struct promdata *)alloc(sizeof *disk_pd); 226 memcpy(disk_pd, pd, sizeof(struct promdata)); 227 if (prom_version() != PROM_OLDMON) { 228 strcpy(rawpart, prom_bootdevice); 229 if ((partition = strchr(rawpart, ':')) != '\0' && 230 *++partition >= 'a' && 231 *partition <= 'a' + MAXPARTITIONS) { 232 part = *partition - 'a'; 233 *partition = RAW_PART + 'a'; 234 } else 235 strcat(rawpart, ":c"); 236 if ((disk_pd->fd = prom_open(rawpart)) == 0) 237 return 0; 238 } 239 error = f->f_dev->dv_strategy(disk_pd, F_READ, LABELSECTOR, 240 DEV_BSIZE, &buf, &read); 241 if (prom_version() != PROM_OLDMON) 242 prom_close(disk_pd->fd); 243 if (error || (read != DEV_BSIZE)) 244 return 0; 245 #ifdef NOTDEF_DEBUG 246 { 247 int x = 0; 248 char *p = (char *) buf; 249 250 printf(" Sector %d:\n", LABELSECTOR); 251 printf("00000000 "); 252 while (x < DEV_BSIZE) { 253 if (*p >= 0x00 && *p < 0x10) 254 printf("0%x ", *p & 0xff); 255 else 256 printf("%x ", *p & 0xff); 257 x++; 258 if (x && !(x % 8)) 259 printf(" "); 260 if (x && !(x % 16)) { 261 if(x < 0x100) 262 printf("\n000000%x ", x); 263 else 264 printf("\n00000%x ", x); 265 } 266 p++; 267 } 268 printf("\n"); 269 } 270 #endif 271 /* Check for NetBSD disk label. */ 272 dlp = (struct disklabel *) (buf + LABELOFFSET); 273 if (dlp->d_magic == DISKMAGIC && !dkcksum(dlp) && 274 dlp->d_partitions[part].p_fstype == FS_RAID) { 275 #ifdef NOTDEF_DEBUG 276 printf("devopen: found RAID partition, " 277 "adjusting offset to %d\n", RF_PROTECTED_SECTORS); 278 #endif 279 doffset = RF_PROTECTED_SECTORS; 280 } 281 } 282 #endif /* BOOTXX */ 283 return (0); 284 } 285 286 287 int 288 obp_v0_strategy(devdata, flag, dblk, size, buf, rsize) 289 void *devdata; 290 int flag; 291 daddr_t dblk; 292 size_t size; 293 void *buf; 294 size_t *rsize; 295 { 296 int n, error = 0; 297 struct promdata *pd = (struct promdata *)devdata; 298 int fd = pd->fd; 299 300 #ifndef BOOTXX 301 dblk += doffset; 302 #endif 303 #ifdef DEBUG_PROM 304 printf("promstrategy: size=%d dblk=%d\n", size, dblk); 305 #endif 306 307 #define prom_bread(fd, nblk, dblk, buf) \ 308 (*obpvec->pv_v0devops.v0_rbdev)(fd, nblk, dblk, buf) 309 #define prom_bwrite(fd, nblk, dblk, buf) \ 310 (*obpvec->pv_v0devops.v0_wbdev)(fd, nblk, dblk, buf) 311 312 #ifndef BOOTXX /* We know it's a block device, so save some space */ 313 if (pd->devtype != DT_BLOCK) { 314 printf("promstrategy: non-block device not supported\n"); 315 error = EINVAL; 316 } 317 #endif 318 319 n = (flag == F_READ) 320 ? prom_bread(fd, btodb(size), dblk, buf) 321 : prom_bwrite(fd, btodb(size), dblk, buf); 322 323 *rsize = dbtob(n); 324 325 #ifdef DEBUG_PROM 326 printf("rsize = %x\n", *rsize); 327 #endif 328 return (error); 329 } 330 331 int 332 obp_v2_strategy(devdata, flag, dblk, size, buf, rsize) 333 void *devdata; 334 int flag; 335 daddr_t dblk; 336 size_t size; 337 void *buf; 338 size_t *rsize; 339 { 340 int error = 0; 341 struct promdata *pd = (struct promdata *)devdata; 342 int fd = pd->fd; 343 344 #ifndef BOOTXX 345 dblk += doffset; 346 #endif 347 #ifdef DEBUG_PROM 348 printf("promstrategy: size=%d dblk=%d\n", size, dblk); 349 #endif 350 351 #ifndef BOOTXX /* We know it's a block device, so save some space */ 352 if (pd->devtype == DT_BLOCK) 353 #endif 354 prom_seek(fd, dbtob(dblk)); 355 356 *rsize = (flag == F_READ) 357 ? prom_read(fd, buf, size) 358 : prom_write(fd, buf, size); 359 360 #ifdef DEBUG_PROM 361 printf("rsize = %x\n", *rsize); 362 #endif 363 return (error); 364 } 365 366 /* 367 * On old-monitor machines, things work differently. 368 */ 369 int 370 oldmon_strategy(devdata, flag, dblk, size, buf, rsize) 371 void *devdata; 372 int flag; 373 daddr_t dblk; 374 size_t size; 375 void *buf; 376 size_t *rsize; 377 { 378 struct promdata *pd = devdata; 379 struct saioreq *si; 380 struct om_boottable *ops; 381 char *dmabuf; 382 int si_flag; 383 size_t xcnt; 384 385 si = pd->si; 386 ops = si->si_boottab; 387 388 #ifndef BOOTXX 389 dblk += doffset; 390 #endif 391 #ifdef DEBUG_PROM 392 printf("prom_strategy: size=%d dblk=%d\n", size, dblk); 393 #endif 394 395 dmabuf = dvma_mapin(buf, size); 396 397 si->si_bn = dblk; 398 si->si_ma = dmabuf; 399 si->si_cc = size; 400 401 si_flag = (flag == F_READ) ? SAIO_F_READ : SAIO_F_WRITE; 402 xcnt = (*ops->b_strategy)(si, si_flag); 403 dvma_mapout(dmabuf, size); 404 405 #ifdef DEBUG_PROM 406 printf("disk_strategy: xcnt = %x\n", xcnt); 407 #endif 408 409 if (xcnt <= 0) 410 return (EIO); 411 412 *rsize = xcnt; 413 return (0); 414 } 415 416 int 417 obp_close(f) 418 struct open_file *f; 419 { 420 struct promdata *pd = f->f_devdata; 421 register int fd = pd->fd; 422 423 #ifndef BOOTXX 424 if (pd->devtype == DT_NET) 425 net_close(pd); 426 #endif 427 prom_close(fd); 428 return 0; 429 } 430 431 int 432 oldmon_close(f) 433 struct open_file *f; 434 { 435 struct promdata *pd = f->f_devdata; 436 437 #ifndef BOOTXX 438 if (pd->devtype == DT_NET) 439 net_close(pd); 440 #endif 441 oldmon_iclose(pd->si); 442 pd->si = NULL; 443 *romVectorPtr->echo = saveecho; /* Hmm, probably must go somewhere else */ 444 return 0; 445 } 446 447 #ifndef BOOTXX 448 ssize_t 449 obp_v0_xmit(pd, buf, len) 450 struct promdata *pd; 451 void *buf; 452 size_t len; 453 { 454 455 return ((*obpvec->pv_v0devops.v0_wnet)(pd->fd, len, buf)); 456 } 457 458 ssize_t 459 obp_v2_xmit(pd, buf, len) 460 struct promdata *pd; 461 void *buf; 462 size_t len; 463 { 464 465 return (prom_write(pd->fd, buf, len)); 466 } 467 468 ssize_t 469 obp_v0_recv(pd, buf, len) 470 struct promdata *pd; 471 void *buf; 472 size_t len; 473 { 474 475 return ((*obpvec->pv_v0devops.v0_rnet)(pd->fd, len, buf)); 476 } 477 478 ssize_t 479 obp_v2_recv(pd, buf, len) 480 struct promdata *pd; 481 void *buf; 482 size_t len; 483 { 484 int n; 485 486 n = prom_read(pd->fd, buf, len); 487 488 /* OBP V2 & V3 may return -2 */ 489 return (n == -2 ? 0 : n); 490 } 491 492 ssize_t 493 oldmon_xmit(pd, buf, len) 494 struct promdata *pd; 495 void *buf; 496 size_t len; 497 { 498 struct saioreq *si; 499 struct saif *sif; 500 char *dmabuf; 501 int rv; 502 503 si = pd->si; 504 sif = si->si_sif; 505 if (sif == NULL) { 506 printf("xmit: not a network device\n"); 507 return (-1); 508 } 509 dmabuf = dvma_mapin(buf, len); 510 rv = sif->sif_xmit(si->si_devdata, dmabuf, len); 511 dvma_mapout(dmabuf, len); 512 513 return (ssize_t)(rv ? -1 : len); 514 } 515 516 ssize_t 517 oldmon_recv(pd, buf, len) 518 struct promdata *pd; 519 void *buf; 520 size_t len; 521 { 522 struct saioreq *si; 523 struct saif *sif; 524 char *dmabuf; 525 int rv; 526 527 si = pd->si; 528 sif = si->si_sif; 529 dmabuf = dvma_mapin(buf, len); 530 rv = sif->sif_poll(si->si_devdata, dmabuf); 531 dvma_mapout(dmabuf, len); 532 533 return (ssize_t)rv; 534 } 535 536 int 537 getchar() 538 { 539 return (prom_getchar()); 540 } 541 542 time_t 543 getsecs() 544 { 545 (void)prom_peekchar(); 546 return (prom_ticks() / 1000); 547 } 548 549 /* 550 * A number of well-known devices on sun4s. 551 */ 552 static struct dtab { 553 char *name; 554 int type; 555 } dtab[] = { 556 { "sd", DT_BLOCK }, 557 { "st", DT_BLOCK }, 558 { "xd", DT_BLOCK }, 559 { "xy", DT_BLOCK }, 560 { "fd", DT_BLOCK }, 561 { "le", DT_NET }, 562 { "ie", DT_NET }, 563 { NULL, 0 } 564 }; 565 566 int 567 getdevtype(fd, name) 568 int fd; 569 char *name; 570 { 571 struct dtab *dp; 572 int node; 573 char *cp; 574 575 switch (prom_version()) { 576 case PROM_OLDMON: 577 case PROM_OBP_V0: 578 for (dp = dtab; dp->name; dp++) { 579 if (name[0] == dp->name[0] && 580 name[1] == dp->name[1]) 581 return (dp->type); 582 } 583 break; 584 585 case PROM_OBP_V2: 586 case PROM_OBP_V3: 587 case PROM_OPENFIRM: 588 node = prom_instance_to_package(fd); 589 cp = mygetpropstring(node, "device_type"); 590 if (strcmp(cp, "block") == 0) 591 return (DT_BLOCK); 592 else if (strcmp(cp, "network") == 0) 593 return (DT_NET); 594 else if (strcmp(cp, "byte") == 0) 595 return (DT_BYTE); 596 break; 597 } 598 return (0); 599 } 600 601 /* 602 * Return a string property. There is a (small) limit on the length; 603 * the string is fetched into a static buffer which is overwritten on 604 * subsequent calls. 605 */ 606 char * 607 mygetpropstring(node, name) 608 int node; 609 char *name; 610 { 611 int len; 612 static char buf[64]; 613 614 len = prom_proplen(node, name); 615 if (len > 0) 616 _prom_getprop(node, name, buf, len); 617 else 618 len = 0; 619 620 buf[len] = '\0'; /* usually unnecessary */ 621 return (buf); 622 } 623 #endif /* BOOTXX */ 624 625 /* 626 * Old monitor routines 627 */ 628 629 struct saioreq prom_si; 630 static int promdev_inuse; 631 632 int 633 oldmon_iopen(pd) 634 struct promdata *pd; 635 { 636 struct om_bootparam *bp; 637 struct om_boottable *ops; 638 struct devinfo *dip; 639 struct saioreq *si; 640 int error; 641 642 if (promdev_inuse) 643 return (EMFILE); 644 645 bp = *romVectorPtr->bootParam; 646 ops = bp->bootTable; 647 dip = ops->b_devinfo; 648 649 #ifdef DEBUG_PROM 650 printf("Boot device type: %s\n", ops->b_desc); 651 printf("d_devbytes=%d\n", dip->d_devbytes); 652 printf("d_dmabytes=%d\n", dip->d_dmabytes); 653 printf("d_localbytes=%d\n", dip->d_localbytes); 654 printf("d_stdcount=%d\n", dip->d_stdcount); 655 printf("d_stdaddrs[%d]=%x\n", bp->ctlrNum, dip->d_stdaddrs[bp->ctlrNum]); 656 printf("d_devtype=%d\n", dip->d_devtype); 657 printf("d_maxiobytes=%d\n", dip->d_maxiobytes); 658 #endif 659 660 dvma_init(); 661 662 si = &prom_si; 663 memset(si, 0, sizeof(*si)); 664 si->si_boottab = ops; 665 si->si_ctlr = bp->ctlrNum; 666 si->si_unit = bp->unitNum; 667 si->si_boff = bp->partNum; 668 669 if (si->si_ctlr > dip->d_stdcount) 670 return (ECTLR); 671 672 if (dip->d_devbytes) { 673 si->si_devaddr = oldmon_mapin(dip->d_stdaddrs[si->si_ctlr], 674 dip->d_devbytes, dip->d_devtype); 675 #ifdef DEBUG_PROM 676 printf("prom_iopen: devaddr=0x%x pte=0x%x\n", 677 si->si_devaddr, 678 getpte4((u_long)si->si_devaddr & ~PGOFSET)); 679 #endif 680 } 681 682 if (dip->d_dmabytes) { 683 si->si_dmaaddr = dvma_alloc(dip->d_dmabytes); 684 #ifdef DEBUG_PROM 685 printf("prom_iopen: dmaaddr=0x%x\n", si->si_dmaaddr); 686 #endif 687 } 688 689 if (dip->d_localbytes) { 690 si->si_devdata = alloc(dip->d_localbytes); 691 #ifdef DEBUG_PROM 692 printf("prom_iopen: devdata=0x%x\n", si->si_devdata); 693 #endif 694 } 695 696 /* OK, call the PROM device open routine. */ 697 error = (*ops->b_open)(si); 698 if (error != 0) { 699 printf("prom_iopen: \"%s\" error=%d\n", ops->b_desc, error); 700 return (ENXIO); 701 } 702 #ifdef DEBUG_PROM 703 printf("prom_iopen: succeeded, error=%d\n", error); 704 #endif 705 706 pd->si = si; 707 promdev_inuse++; 708 return (0); 709 } 710 711 void 712 oldmon_iclose(si) 713 struct saioreq *si; 714 { 715 struct om_boottable *ops; 716 struct devinfo *dip; 717 718 if (promdev_inuse == 0) 719 return; 720 721 ops = si->si_boottab; 722 dip = ops->b_devinfo; 723 724 (*ops->b_close)(si); 725 726 if (si->si_dmaaddr) { 727 dvma_free(si->si_dmaaddr, dip->d_dmabytes); 728 si->si_dmaaddr = NULL; 729 } 730 731 promdev_inuse = 0; 732 } 733 734 static struct mapinfo { 735 int maptype; 736 int pgtype; 737 int base; 738 } oldmon_mapinfo[] = { 739 #define PG_COMMON (PG_V|PG_W|PG_S|PG_NC) 740 { MAP_MAINMEM, PG_OBMEM | PG_COMMON, 0 }, 741 { MAP_OBIO, PG_OBIO | PG_COMMON, 0 }, 742 { MAP_MBMEM, PG_VME16 | PG_COMMON, 0xFF000000 }, 743 { MAP_MBIO, PG_VME16 | PG_COMMON, 0xFFFF0000 }, 744 { MAP_VME16A16D, PG_VME16 | PG_COMMON, 0xFFFF0000 }, 745 { MAP_VME16A32D, PG_VME32 | PG_COMMON, 0xFFFF0000 }, 746 { MAP_VME24A16D, PG_VME16 | PG_COMMON, 0xFF000000 }, 747 { MAP_VME24A32D, PG_VME32 | PG_COMMON, 0xFF000000 }, 748 { MAP_VME32A16D, PG_VME16 | PG_COMMON, 0 }, 749 { MAP_VME32A32D, PG_VME32 | PG_COMMON, 0 }, 750 }; 751 static int oldmon_mapinfo_cnt = 752 sizeof(oldmon_mapinfo) / sizeof(oldmon_mapinfo[0]); 753 754 /* The virtual address we will use for PROM device mappings. */ 755 static u_long prom_devmap = MONSHORTSEG; 756 757 static char * 758 oldmon_mapin(physaddr, length, maptype) 759 u_long physaddr; 760 int length, maptype; 761 { 762 int i, pa, pte, va; 763 764 if (length > (4*NBPG)) 765 panic("oldmon_mapin: length=%d", length); 766 767 for (i = 0; i < oldmon_mapinfo_cnt; i++) 768 if (oldmon_mapinfo[i].maptype == maptype) 769 goto found; 770 panic("oldmon_mapin: invalid maptype %d", maptype); 771 772 found: 773 pte = oldmon_mapinfo[i].pgtype; 774 pa = oldmon_mapinfo[i].base; 775 pa += physaddr; 776 pte |= ((pa >> SUN4_PGSHIFT) & PG_PFNUM); 777 778 va = prom_devmap; 779 do { 780 setpte4(va, pte); 781 va += NBPG; 782 pte += 1; 783 length -= NBPG; 784 } while (length > 0); 785 return ((char*)(prom_devmap | (pa & PGOFSET))); 786 } 787