1 /* $NetBSD: smg.c,v 1.58 2019/03/14 23:49:38 thorpej 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.58 2019/03/14 23:49:38 thorpej 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 if (copyin(v->cmap.red, &red, sizeof(red)) == 0 && 434 copyin(v->cmap.green, &green, sizeof(green)) == 0 && 435 copyin(v->cmap.blue, &blue, sizeof(blue)) == 0) { 436 bgmask = (((30L * red + 59L * green + 11L * blue) >> 8) 437 >= (((1<<8)-1)*50)) ? ~0 : 0; 438 } 439 if (copyin(v->cmap.red + 2, &red, sizeof(red)) == 0 && 440 copyin(v->cmap.green + 2, &green, sizeof(green)) == 0 && 441 copyin(v->cmap.blue + 2, &blue, sizeof(blue)) == 0) { 442 fgmask = (((30L * red + 59L * green + 11L * blue) >> 8) 443 >= (((1<<8)-1)*50)) ? ~0 : 0; 444 } 445 } 446 if (v->which & WSDISPLAY_CURSOR_DOSHAPE) { 447 WRITECUR(CUR_CMD, curcmd | CUR_CMD_LODSA); 448 copyin(v->image, curfg, sizeof(curfg)); 449 copyin(v->mask, curmask, sizeof(curmask)); 450 for (i = 0; i < sizeof(curfg)/sizeof(curfg[0]); i++) { 451 WRITECUR(CUR_LOAD, ((uint16_t)curfg[i] & fgmask) | 452 (((uint16_t)curmask[i] & (uint16_t)~curfg[i]) 453 & bgmask)); 454 } 455 for (i = 0; i < sizeof(curmask)/sizeof(curmask[0]); i++) { 456 WRITECUR(CUR_LOAD, (uint16_t)curmask[i]); 457 } 458 WRITECUR(CUR_CMD, curcmd); 459 } 460 } 461 462 int 463 smg_ioctl(void *v, void *vs, u_long cmd, void *data, int flag, struct lwp *l) 464 { 465 struct wsdisplay_fbinfo *fb = (void *)data; 466 static uint16_t curc; 467 468 switch (cmd) { 469 case WSDISPLAYIO_GTYPE: 470 *(u_int *)data = WSDISPLAY_TYPE_VAX_MONO; 471 break; 472 473 case WSDISPLAYIO_GINFO: 474 fb->height = SM_YWIDTH; 475 fb->width = SM_XWIDTH; 476 fb->depth = 1; 477 fb->cmsize = 2; 478 break; 479 480 case WSDISPLAYIO_SVIDEO: 481 if (*(u_int *)data == WSDISPLAYIO_VIDEO_ON) { 482 curcmd = curc; 483 } else { 484 curc = curcmd; 485 curcmd &= ~(CUR_CMD_FOPA|CUR_CMD_ENPA); 486 curcmd |= CUR_CMD_FOPB; 487 } 488 WRITECUR(CUR_CMD, curcmd); 489 break; 490 491 case WSDISPLAYIO_GVIDEO: 492 *(u_int *)data = (curcmd & CUR_CMD_FOPB ? 493 WSDISPLAYIO_VIDEO_OFF : WSDISPLAYIO_VIDEO_ON); 494 break; 495 496 case WSDISPLAYIO_SCURSOR: 497 setcursor((struct wsdisplay_cursor *)data); 498 break; 499 500 case WSDISPLAYIO_SCURPOS: 501 curx = ((struct wsdisplay_curpos *)data)->x; 502 cury = ((struct wsdisplay_curpos *)data)->y; 503 WRITECUR(CUR_XPOS, curx + CUR_XBIAS); 504 WRITECUR(CUR_YPOS, cury + CUR_YBIAS); 505 break; 506 507 case WSDISPLAYIO_GCURPOS: 508 ((struct wsdisplay_curpos *)data)->x = curx; 509 ((struct wsdisplay_curpos *)data)->y = cury; 510 break; 511 512 case WSDISPLAYIO_GCURMAX: 513 ((struct wsdisplay_curpos *)data)->x = 16; 514 ((struct wsdisplay_curpos *)data)->y = 16; 515 break; 516 517 default: 518 return EPASSTHROUGH; 519 } 520 return 0; 521 } 522 523 static paddr_t 524 smg_mmap(void *v, void *vs, off_t offset, int prot) 525 { 526 if (offset >= SMSIZE || offset < 0) 527 return -1; 528 return (SMADDR + offset) >> PGSHIFT; 529 } 530 531 int 532 smg_alloc_screen(void *v, const struct wsscreen_descr *type, void **cookiep, 533 int *curxp, int *curyp, long *defattrp) 534 { 535 *cookiep = malloc(sizeof(struct smg_screen), M_DEVBUF, M_WAITOK|M_ZERO); 536 *curxp = *curyp = *defattrp = 0; 537 return 0; 538 } 539 540 void 541 smg_free_screen(void *v, void *cookie) 542 { 543 } 544 545 int 546 smg_show_screen(void *v, void *cookie, int waitok, 547 void (*cb)(void *, int, int), void *cbarg) 548 { 549 struct smg_screen *ss = cookie; 550 int row, col, line; 551 552 if (ss == curscr) 553 return (0); 554 555 for (row = 0; row < SM_ROWS; row++) 556 for (line = 0; line < SM_CHEIGHT; line++) { 557 for (col = 0; col < SM_COLS; col++) { 558 u_char s, c = ss->ss_image[row][col]; 559 560 if (c < 32) 561 c = 32; 562 s = QFONT(c, line); 563 if (ss->ss_attr[row][col] & WSATTR_REVERSE) 564 s ^= 255; 565 SM_ADDR(row, col, line) = s; 566 if (ss->ss_attr[row][col] & WSATTR_UNDERLINE) 567 SM_ADDR(row, col, line) = 255; 568 } 569 } 570 cursor = &sm_addr[(ss->ss_cury * SM_CHEIGHT * SM_COLS) + ss->ss_curx + 571 ((SM_CHEIGHT - 1) * SM_COLS)]; 572 curscr = ss; 573 return (0); 574 } 575 576 cons_decl(smg); 577 578 void 579 smgcninit(struct consdev *cndev) 580 { 581 int fcookie; 582 struct wsdisplay_font *console_font; 583 extern void lkccninit(struct consdev *); 584 extern int lkccngetc(dev_t); 585 extern int dz_vsbus_lk201_cnattach(int); 586 /* Clear screen */ 587 memset(sm_addr, 0, 128*864); 588 589 callout_init(&smg_cursor_ch, 0); 590 591 curscr = &smg_conscreen; 592 wsdisplay_cnattach(&smg_stdscreen, &smg_conscreen, 0, 0, 0); 593 cn_tab->cn_pri = CN_INTERNAL; 594 if ((fcookie = wsfont_find(NULL, 8, 15, 0, WSDISPLAY_FONTORDER_R2L, 595 WSDISPLAY_FONTORDER_L2R, WSFONT_FIND_BITMAP)) < 0) 596 { 597 printf("smg: could not find 8x15 font\n"); 598 return; 599 } 600 if (wsfont_lock(fcookie, &console_font) != 0) { 601 printf("smg: could not lock 8x15 font\n"); 602 return; 603 } 604 qf = console_font->data; 605 606 #if NDZKBD > 0 607 dzkbd_cnattach(0); /* Connect keyboard and screen together */ 608 #endif 609 } 610 611 /* 612 * Called very early to setup the glass tty as console. 613 * Because it's called before the VM system is inited, virtual memory 614 * for the framebuffer can be stolen directly without disturbing anything. 615 */ 616 void 617 smgcnprobe(struct consdev *cndev) 618 { 619 extern vaddr_t virtual_avail; 620 extern const struct cdevsw wsdisplay_cdevsw; 621 622 switch (vax_boardtype) { 623 case VAX_BTYP_410: 624 case VAX_BTYP_420: 625 case VAX_BTYP_43: 626 if ((vax_confdata & KA420_CFG_L3CON) || 627 (vax_confdata & KA420_CFG_MULTU)) 628 break; /* doesn't use graphics console */ 629 sm_addr = (void *)virtual_avail; 630 virtual_avail += SMSIZE; 631 ioaccess((vaddr_t)sm_addr, SMADDR, (SMSIZE/VAX_NBPG)); 632 cndev->cn_pri = CN_INTERNAL; 633 cndev->cn_dev = makedev(cdevsw_lookup_major(&wsdisplay_cdevsw), 634 0); 635 break; 636 637 default: 638 break; 639 } 640 } 641