1 /* $NetBSD: smg.c,v 1.57 2017/05/22 17:17:25 ragge Exp $ */ 2 /* 3 * Copyright (c) 1998 Ludd, University of Lule}, Sweden. 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 */ 26 27 #include <sys/cdefs.h> 28 __KERNEL_RCSID(0, "$NetBSD: smg.c,v 1.57 2017/05/22 17:17:25 ragge Exp $"); 29 30 #include <sys/param.h> 31 #include <sys/systm.h> 32 #include <sys/callout.h> 33 #include <sys/conf.h> 34 #include <sys/cpu.h> 35 #include <sys/device.h> 36 #include <sys/kernel.h> 37 #include <sys/malloc.h> 38 #include <sys/time.h> 39 40 #include <machine/vsbus.h> 41 #include <machine/sid.h> 42 #include <machine/ka420.h> 43 44 #include <dev/cons.h> 45 46 #include <dev/dec/dzreg.h> 47 #include <dev/dec/dzvar.h> 48 #include <dev/dec/dzkbdvar.h> 49 50 #include <dev/wscons/wsdisplayvar.h> 51 #include <dev/wscons/wsconsio.h> 52 #include <dev/wscons/wscons_callbacks.h> 53 #include <dev/wsfont/wsfont.h> 54 55 #include "dzkbd.h" 56 #include "opt_wsfont.h" 57 58 /* Screen hardware defs */ 59 #define SM_COLS 128 /* char width of screen */ 60 #define SM_ROWS 57 /* rows of char on screen */ 61 #define SM_CHEIGHT 15 /* lines a char consists of */ 62 #define SM_NEXTROW (SM_COLS * SM_CHEIGHT) 63 #define SM_YWIDTH 864 64 #define SM_XWIDTH 1024 65 66 /* Cursor register definitions */ 67 #define CUR_CMD 0 68 #define CUR_XPOS 4 69 #define CUR_YPOS 8 70 #define CUR_XMIN_1 12 71 #define CUR_XMAX_1 16 72 #define CUR_YMIN_1 20 73 #define CUR_YMAX_1 24 74 #define CUR_XMIN_2 28 75 #define CUR_XMAX_2 32 76 #define CUR_YMIN_2 36 77 #define CUR_YMAX_2 40 78 #define CUR_LOAD 44 79 80 #define CUR_CMD_TEST 0x8000 81 #define CUR_CMD_HSHI 0x4000 82 #define CUR_CMD_VBHI 0x2000 83 #define CUR_CMD_LODSA 0x1000 84 #define CUR_CMD_FORG2 0x0800 85 #define CUR_CMD_ENRG2 0x0400 86 #define CUR_CMD_FORG1 0x0200 87 #define CUR_CMD_ENRG1 0x0100 88 #define CUR_CMD_XHWID 0x0080 89 #define CUR_CMD_XHCL1 0x0040 90 #define CUR_CMD_XHCLP 0x0020 91 #define CUR_CMD_XHAIR 0x0010 92 #define CUR_CMD_FOPB 0x0008 93 #define CUR_CMD_ENPB 0x0004 94 #define CUR_CMD_FOPA 0x0002 95 #define CUR_CMD_ENPA 0x0001 96 97 #define CUR_XBIAS 216 /* Add to cursor position */ 98 #define CUR_YBIAS 33 99 100 #define WRITECUR(addr, val) *(volatile uint16_t *)(curaddr + (addr)) = (val) 101 static char *curaddr; 102 static uint16_t curcmd, curx, cury, hotX, hotY; 103 static int bgmask, fgmask; 104 105 static int smg_match(device_t, cfdata_t, void *); 106 static void smg_attach(device_t, device_t, void *); 107 108 CFATTACH_DECL_NEW(smg, 0, 109 smg_match, smg_attach, NULL, NULL); 110 111 static void smg_cursor(void *, int, int, int); 112 static int smg_mapchar(void *, int, unsigned int *); 113 static void smg_putchar(void *, int, int, u_int, long); 114 static void smg_copycols(void *, int, int, int,int); 115 static void smg_erasecols(void *, int, int, int, long); 116 static void smg_copyrows(void *, int, int, int); 117 static void smg_eraserows(void *, int, int, long); 118 static int smg_allocattr(void *, int, int, int, long *); 119 120 const struct wsdisplay_emulops smg_emulops = { 121 .cursor = smg_cursor, 122 .mapchar = smg_mapchar, 123 .putchar = smg_putchar, 124 .copycols = smg_copycols, 125 .erasecols = smg_erasecols, 126 .copyrows = smg_copyrows, 127 .eraserows = smg_eraserows, 128 .allocattr = smg_allocattr 129 }; 130 131 const struct wsscreen_descr smg_stdscreen = { 132 .name = "128x57", 133 .ncols = SM_COLS, 134 .nrows = SM_ROWS, 135 .textops = &smg_emulops, 136 .fontwidth = 8, 137 .fontheight = SM_CHEIGHT, 138 .capabilities = WSSCREEN_UNDERLINE|WSSCREEN_REVERSE, 139 }; 140 141 const struct wsscreen_descr *_smg_scrlist[] = { 142 &smg_stdscreen, 143 }; 144 145 const struct wsscreen_list smg_screenlist = { 146 .nscreens = __arraycount(_smg_scrlist), 147 .screens = _smg_scrlist, 148 }; 149 150 static char *sm_addr; 151 152 static u_char *qf; 153 154 #define QCHAR(c) (c < 32 ? 32 : (c > 127 ? c - 66 : c - 32)) 155 #define QFONT(c,line) qf[QCHAR(c) * 15 + line] 156 #define SM_ADDR(row, col, line) \ 157 sm_addr[col + (row * SM_CHEIGHT * SM_COLS) + line * SM_COLS] 158 159 160 static int smg_ioctl(void *, void *, u_long, void *, int, struct lwp *); 161 static paddr_t smg_mmap(void *, void *, off_t, int); 162 static int smg_alloc_screen(void *, const struct wsscreen_descr *, 163 void **, int *, int *, long *); 164 static void smg_free_screen(void *, void *); 165 static int smg_show_screen(void *, void *, int, 166 void (*) (void *, int, int), void *); 167 static void smg_crsr_blink(void *); 168 169 const struct wsdisplay_accessops smg_accessops = { 170 .ioctl = smg_ioctl, 171 .mmap = smg_mmap, 172 .alloc_screen = smg_alloc_screen, 173 .free_screen = smg_free_screen, 174 .show_screen = smg_show_screen, 175 }; 176 177 struct smg_screen { 178 int ss_curx; 179 int ss_cury; 180 u_char ss_image[SM_ROWS][SM_COLS]; /* Image of current screen */ 181 u_char ss_attr[SM_ROWS][SM_COLS]; /* Reversed etc... */ 182 }; 183 184 static struct smg_screen smg_conscreen; 185 static struct smg_screen *curscr; 186 187 static callout_t smg_cursor_ch; 188 189 int 190 smg_match(device_t parent, cfdata_t match, void *aux) 191 { 192 struct vsbus_attach_args * const va = aux; 193 volatile uint16_t *ccmd; 194 volatile uint16_t *cfgtst; 195 uint16_t tmp, tmp2; 196 197 if (vax_boardtype == VAX_BTYP_49 || vax_boardtype == VAX_BTYP_53) 198 return 0; 199 200 ccmd = (uint16_t *)va->va_addr; 201 cfgtst = (uint16_t *)vax_map_physmem(VS_CFGTST, 1); 202 /* 203 * Try to find the cursor chip by testing the flip-flop. 204 * If nonexistent, no glass tty. 205 */ 206 ccmd[0] = CUR_CMD_HSHI|CUR_CMD_FOPB; 207 DELAY(300000); 208 tmp = cfgtst[0]; 209 ccmd[0] = CUR_CMD_TEST|CUR_CMD_HSHI; 210 DELAY(300000); 211 tmp2 = cfgtst[0]; 212 vax_unmap_physmem((vaddr_t)cfgtst, 1); 213 214 if (tmp2 != tmp) 215 return 20; /* Using periodic interrupt */ 216 else 217 return 0; 218 } 219 220 void 221 smg_attach(device_t parent, device_t self, void *aux) 222 { 223 struct wsemuldisplaydev_attach_args aa; 224 struct wsdisplay_font *console_font; 225 int fcookie; 226 227 aprint_normal("\n"); 228 sm_addr = (void *)vax_map_physmem(SMADDR, (SMSIZE/VAX_NBPG)); 229 curaddr = (void *)vax_map_physmem(KA420_CUR_BASE, 1); 230 if (sm_addr == 0) { 231 aprint_error_dev(self, "Couldn't alloc graphics memory.\n"); 232 return; 233 } 234 if (curscr == NULL) 235 callout_init(&smg_cursor_ch, 0); 236 curscr = &smg_conscreen; 237 aa.console = (vax_confdata & (KA420_CFG_L3CON|KA420_CFG_MULTU)) == 0; 238 239 aa.scrdata = &smg_screenlist; 240 aa.accessops = &smg_accessops; 241 callout_reset(&smg_cursor_ch, hz / 2, smg_crsr_blink, NULL); 242 curcmd = CUR_CMD_HSHI; 243 WRITECUR(CUR_CMD, curcmd); 244 if ((fcookie = wsfont_find(NULL, 8, 15, 0, WSDISPLAY_FONTORDER_R2L, 245 WSDISPLAY_FONTORDER_L2R, WSFONT_FIND_BITMAP)) < 0) { 246 aprint_error_dev(self, "could not find 8x15 font\n"); 247 return; 248 } 249 if (wsfont_lock(fcookie, &console_font) != 0) { 250 aprint_error_dev(self, "could not lock 8x15 font\n"); 251 return; 252 } 253 qf = console_font->data; 254 255 config_found(self, &aa, wsemuldisplaydevprint); 256 } 257 258 static u_char *cursor; 259 static int cur_on; 260 261 static void 262 smg_crsr_blink(void *arg) 263 { 264 if (cur_on) 265 *cursor ^= 255; 266 callout_reset(&smg_cursor_ch, hz / 2, smg_crsr_blink, NULL); 267 } 268 269 void 270 smg_cursor(void *id, int on, int row, int col) 271 { 272 struct smg_screen * const ss = id; 273 274 if (ss == curscr) { 275 SM_ADDR(ss->ss_cury, ss->ss_curx, 14) = 276 QFONT(ss->ss_image[ss->ss_cury][ss->ss_curx], 14); 277 cursor = &SM_ADDR(row, col, 14); 278 if ((cur_on = on)) 279 *cursor ^= 255; 280 } 281 ss->ss_curx = col; 282 ss->ss_cury = row; 283 } 284 285 int 286 smg_mapchar(void *id, int uni, unsigned int *index) 287 { 288 if (uni < 256) { 289 *index = uni; 290 return (5); 291 } 292 *index = ' '; 293 return (0); 294 } 295 296 static void 297 smg_putchar(void *id, int row, int col, u_int c, long attr) 298 { 299 struct smg_screen * const ss = id; 300 int i; 301 302 c &= 0xff; 303 304 ss->ss_image[row][col] = c; 305 ss->ss_attr[row][col] = attr; 306 if (ss != curscr) 307 return; 308 for (i = 0; i < 15; i++) { 309 unsigned char ch = QFONT(c, i); 310 311 SM_ADDR(row, col, i) = (attr & WSATTR_REVERSE ? ~ch : ch); 312 313 } 314 if (attr & WSATTR_UNDERLINE) 315 SM_ADDR(row, col, 14) ^= SM_ADDR(row, col, 14); 316 } 317 318 /* 319 * copies columns inside a row. 320 */ 321 static void 322 smg_copycols(void *id, int row, int srccol, int dstcol, int ncols) 323 { 324 struct smg_screen * const ss = id; 325 int i; 326 327 memcpy(&ss->ss_image[row][dstcol], &ss->ss_image[row][srccol], ncols); 328 memcpy(&ss->ss_attr[row][dstcol], &ss->ss_attr[row][srccol], ncols); 329 if (ss != curscr) 330 return; 331 for (i = 0; i < SM_CHEIGHT; i++) 332 memcpy(&SM_ADDR(row, dstcol, i), &SM_ADDR(row, srccol, i), ncols); 333 } 334 335 /* 336 * Erases a bunch of chars inside one row. 337 */ 338 static void 339 smg_erasecols(void *id, int row, int startcol, int ncols, long fillattr) 340 { 341 struct smg_screen * const ss = id; 342 int i; 343 344 memset(&ss->ss_image[row][startcol], 0, ncols); 345 memset(&ss->ss_attr[row][startcol], 0, ncols); 346 if (ss != curscr) 347 return; 348 for (i = 0; i < SM_CHEIGHT; i++) 349 memset(&SM_ADDR(row, startcol, i), 0, ncols); 350 } 351 352 static void 353 smg_copyrows(void *id, int srcrow, int dstrow, int nrows) 354 { 355 struct smg_screen * const ss = id; 356 int frows; 357 358 memcpy(&ss->ss_image[dstrow][0], &ss->ss_image[srcrow][0], 359 nrows * SM_COLS); 360 memcpy(&ss->ss_attr[dstrow][0], &ss->ss_attr[srcrow][0], 361 nrows * SM_COLS); 362 if (ss != curscr) 363 return; 364 if (nrows > 25) { 365 frows = nrows >> 1; 366 if (srcrow > dstrow) { 367 bcopy(&sm_addr[(srcrow * SM_NEXTROW)], 368 &sm_addr[(dstrow * SM_NEXTROW)], 369 frows * SM_NEXTROW); 370 bcopy(&sm_addr[((srcrow + frows) * SM_NEXTROW)], 371 &sm_addr[((dstrow + frows) * SM_NEXTROW)], 372 (nrows - frows) * SM_NEXTROW); 373 } else { 374 bcopy(&sm_addr[((srcrow + frows) * SM_NEXTROW)], 375 &sm_addr[((dstrow + frows) * SM_NEXTROW)], 376 (nrows - frows) * SM_NEXTROW); 377 bcopy(&sm_addr[(srcrow * SM_NEXTROW)], 378 &sm_addr[(dstrow * SM_NEXTROW)], 379 frows * SM_NEXTROW); 380 } 381 } else 382 bcopy(&sm_addr[(srcrow * SM_NEXTROW)], 383 &sm_addr[(dstrow * SM_NEXTROW)], nrows * SM_NEXTROW); 384 } 385 386 static void 387 smg_eraserows(void *id, int startrow, int nrows, long fillattr) 388 { 389 struct smg_screen * const ss = id; 390 int frows; 391 392 memset(&ss->ss_image[startrow][0], 0, nrows * SM_COLS); 393 memset(&ss->ss_attr[startrow][0], 0, nrows * SM_COLS); 394 if (ss != curscr) 395 return; 396 if (nrows > 25) { 397 frows = nrows >> 1; 398 memset(&sm_addr[(startrow * SM_NEXTROW)], 0, frows * SM_NEXTROW); 399 memset(&sm_addr[((startrow + frows) * SM_NEXTROW)], 0, 400 (nrows - frows) * SM_NEXTROW); 401 } else 402 memset(&sm_addr[(startrow * SM_NEXTROW)], 0, nrows * SM_NEXTROW); 403 } 404 405 static int 406 smg_allocattr(void *id, int fg, int bg, int flags, long *attrp) 407 { 408 *attrp = flags; 409 return 0; 410 } 411 412 static void 413 setcursor(struct wsdisplay_cursor *v) 414 { 415 uint16_t red, green, blue; 416 uint32_t curfg[16], curmask[16]; 417 int i; 418 419 /* Enable cursor */ 420 if (v->which & WSDISPLAY_CURSOR_DOCUR) { 421 if (v->enable) 422 curcmd |= CUR_CMD_ENPB|CUR_CMD_ENPA; 423 else 424 curcmd &= ~(CUR_CMD_ENPB|CUR_CMD_ENPA); 425 WRITECUR(CUR_CMD, curcmd); 426 } 427 if (v->which & WSDISPLAY_CURSOR_DOHOT) { 428 hotX = v->hot.x; 429 hotY = v->hot.y; 430 } 431 if (v->which & WSDISPLAY_CURSOR_DOCMAP) { 432 /* First background */ 433 red = fusword(v->cmap.red); 434 green = fusword(v->cmap.green); 435 blue = fusword(v->cmap.blue); 436 bgmask = (((30L * red + 59L * green + 11L * blue) >> 8) >= 437 (((1<<8)-1)*50)) ? ~0 : 0; 438 red = fusword(v->cmap.red+2); 439 green = fusword(v->cmap.green+2); 440 blue = fusword(v->cmap.blue+2); 441 fgmask = (((30L * red + 59L * green + 11L * blue) >> 8) >= 442 (((1<<8)-1)*50)) ? ~0 : 0; 443 } 444 if (v->which & WSDISPLAY_CURSOR_DOSHAPE) { 445 WRITECUR(CUR_CMD, curcmd | CUR_CMD_LODSA); 446 copyin(v->image, curfg, sizeof(curfg)); 447 copyin(v->mask, curmask, sizeof(curmask)); 448 for (i = 0; i < sizeof(curfg)/sizeof(curfg[0]); i++) { 449 WRITECUR(CUR_LOAD, ((uint16_t)curfg[i] & fgmask) | 450 (((uint16_t)curmask[i] & (uint16_t)~curfg[i]) 451 & bgmask)); 452 } 453 for (i = 0; i < sizeof(curmask)/sizeof(curmask[0]); i++) { 454 WRITECUR(CUR_LOAD, (uint16_t)curmask[i]); 455 } 456 WRITECUR(CUR_CMD, curcmd); 457 } 458 } 459 460 int 461 smg_ioctl(void *v, void *vs, u_long cmd, void *data, int flag, struct lwp *l) 462 { 463 struct wsdisplay_fbinfo *fb = (void *)data; 464 static uint16_t curc; 465 466 switch (cmd) { 467 case WSDISPLAYIO_GTYPE: 468 *(u_int *)data = WSDISPLAY_TYPE_VAX_MONO; 469 break; 470 471 case WSDISPLAYIO_GINFO: 472 fb->height = SM_YWIDTH; 473 fb->width = SM_XWIDTH; 474 fb->depth = 1; 475 fb->cmsize = 2; 476 break; 477 478 case WSDISPLAYIO_SVIDEO: 479 if (*(u_int *)data == WSDISPLAYIO_VIDEO_ON) { 480 curcmd = curc; 481 } else { 482 curc = curcmd; 483 curcmd &= ~(CUR_CMD_FOPA|CUR_CMD_ENPA); 484 curcmd |= CUR_CMD_FOPB; 485 } 486 WRITECUR(CUR_CMD, curcmd); 487 break; 488 489 case WSDISPLAYIO_GVIDEO: 490 *(u_int *)data = (curcmd & CUR_CMD_FOPB ? 491 WSDISPLAYIO_VIDEO_OFF : WSDISPLAYIO_VIDEO_ON); 492 break; 493 494 case WSDISPLAYIO_SCURSOR: 495 setcursor((struct wsdisplay_cursor *)data); 496 break; 497 498 case WSDISPLAYIO_SCURPOS: 499 curx = ((struct wsdisplay_curpos *)data)->x; 500 cury = ((struct wsdisplay_curpos *)data)->y; 501 WRITECUR(CUR_XPOS, curx + CUR_XBIAS); 502 WRITECUR(CUR_YPOS, cury + CUR_YBIAS); 503 break; 504 505 case WSDISPLAYIO_GCURPOS: 506 ((struct wsdisplay_curpos *)data)->x = curx; 507 ((struct wsdisplay_curpos *)data)->y = cury; 508 break; 509 510 case WSDISPLAYIO_GCURMAX: 511 ((struct wsdisplay_curpos *)data)->x = 16; 512 ((struct wsdisplay_curpos *)data)->y = 16; 513 break; 514 515 default: 516 return EPASSTHROUGH; 517 } 518 return 0; 519 } 520 521 static paddr_t 522 smg_mmap(void *v, void *vs, off_t offset, int prot) 523 { 524 if (offset >= SMSIZE || offset < 0) 525 return -1; 526 return (SMADDR + offset) >> PGSHIFT; 527 } 528 529 int 530 smg_alloc_screen(void *v, const struct wsscreen_descr *type, void **cookiep, 531 int *curxp, int *curyp, long *defattrp) 532 { 533 *cookiep = malloc(sizeof(struct smg_screen), M_DEVBUF, M_WAITOK|M_ZERO); 534 *curxp = *curyp = *defattrp = 0; 535 return 0; 536 } 537 538 void 539 smg_free_screen(void *v, void *cookie) 540 { 541 } 542 543 int 544 smg_show_screen(void *v, void *cookie, int waitok, 545 void (*cb)(void *, int, int), void *cbarg) 546 { 547 struct smg_screen *ss = cookie; 548 int row, col, line; 549 550 if (ss == curscr) 551 return (0); 552 553 for (row = 0; row < SM_ROWS; row++) 554 for (line = 0; line < SM_CHEIGHT; line++) { 555 for (col = 0; col < SM_COLS; col++) { 556 u_char s, c = ss->ss_image[row][col]; 557 558 if (c < 32) 559 c = 32; 560 s = QFONT(c, line); 561 if (ss->ss_attr[row][col] & WSATTR_REVERSE) 562 s ^= 255; 563 SM_ADDR(row, col, line) = s; 564 if (ss->ss_attr[row][col] & WSATTR_UNDERLINE) 565 SM_ADDR(row, col, line) = 255; 566 } 567 } 568 cursor = &sm_addr[(ss->ss_cury * SM_CHEIGHT * SM_COLS) + ss->ss_curx + 569 ((SM_CHEIGHT - 1) * SM_COLS)]; 570 curscr = ss; 571 return (0); 572 } 573 574 cons_decl(smg); 575 576 void 577 smgcninit(struct consdev *cndev) 578 { 579 int fcookie; 580 struct wsdisplay_font *console_font; 581 extern void lkccninit(struct consdev *); 582 extern int lkccngetc(dev_t); 583 extern int dz_vsbus_lk201_cnattach(int); 584 /* Clear screen */ 585 memset(sm_addr, 0, 128*864); 586 587 callout_init(&smg_cursor_ch, 0); 588 589 curscr = &smg_conscreen; 590 wsdisplay_cnattach(&smg_stdscreen, &smg_conscreen, 0, 0, 0); 591 cn_tab->cn_pri = CN_INTERNAL; 592 if ((fcookie = wsfont_find(NULL, 8, 15, 0, WSDISPLAY_FONTORDER_R2L, 593 WSDISPLAY_FONTORDER_L2R, WSFONT_FIND_BITMAP)) < 0) 594 { 595 printf("smg: could not find 8x15 font\n"); 596 return; 597 } 598 if (wsfont_lock(fcookie, &console_font) != 0) { 599 printf("smg: could not lock 8x15 font\n"); 600 return; 601 } 602 qf = console_font->data; 603 604 #if NDZKBD > 0 605 dzkbd_cnattach(0); /* Connect keyboard and screen together */ 606 #endif 607 } 608 609 /* 610 * Called very early to setup the glass tty as console. 611 * Because it's called before the VM system is inited, virtual memory 612 * for the framebuffer can be stolen directly without disturbing anything. 613 */ 614 void 615 smgcnprobe(struct consdev *cndev) 616 { 617 extern vaddr_t virtual_avail; 618 extern const struct cdevsw wsdisplay_cdevsw; 619 620 switch (vax_boardtype) { 621 case VAX_BTYP_410: 622 case VAX_BTYP_420: 623 case VAX_BTYP_43: 624 if ((vax_confdata & KA420_CFG_L3CON) || 625 (vax_confdata & KA420_CFG_MULTU)) 626 break; /* doesn't use graphics console */ 627 sm_addr = (void *)virtual_avail; 628 virtual_avail += SMSIZE; 629 ioaccess((vaddr_t)sm_addr, SMADDR, (SMSIZE/VAX_NBPG)); 630 cndev->cn_pri = CN_INTERNAL; 631 cndev->cn_dev = makedev(cdevsw_lookup_major(&wsdisplay_cdevsw), 632 0); 633 break; 634 635 default: 636 break; 637 } 638 } 639