Annotation of sys/arch/vax/vsa/lcspx.c, Revision 1.1
1.1 ! nbrk 1: /* $OpenBSD: lcspx.c,v 1.11 2006/11/29 12:13:54 miod Exp $ */
! 2: /*
! 3: * Copyright (c) 2006 Miodrag Vallat.
! 4: *
! 5: * Permission to use, copy, modify, and distribute this software for any
! 6: * purpose with or without fee is hereby granted, provided that the above
! 7: * copyright notice, this permission notice, and the disclaimer below
! 8: * appear in all copies.
! 9: *
! 10: * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
! 11: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
! 12: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
! 13: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
! 14: * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
! 15: * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
! 16: * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
! 17: */
! 18: /*
! 19: * Copyright (c) 2004 Blaz Antonic
! 20: * All rights reserved.
! 21: *
! 22: * This software contains code written by Michael L. Hitch.
! 23: *
! 24: * Redistribution and use in source and binary forms, with or without
! 25: * modification, are permitted provided that the following conditions
! 26: * are met:
! 27: * 1. Redistributions of source code must retain the above copyright
! 28: * notice, this list of conditions and the following disclaimer.
! 29: * 2. Redistributions in binary form must reproduce the above copyright
! 30: * notice, this list of conditions and the following disclaimer in the
! 31: * documentation and/or other materials provided with the distribution.
! 32: * 3. All advertising materials mentioning features or use of this software
! 33: * must display the abovementioned copyrights
! 34: * 4. The name of the author may not be used to endorse or promote products
! 35: * derived from this software without specific prior written permission
! 36: *
! 37: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
! 38: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
! 39: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
! 40: * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
! 41: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
! 42: * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
! 43: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
! 44: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
! 45: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
! 46: * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
! 47: */
! 48:
! 49: #include <sys/param.h>
! 50: #include <sys/device.h>
! 51: #include <sys/systm.h>
! 52: #include <sys/malloc.h>
! 53: #include <sys/conf.h>
! 54: #include <sys/kernel.h>
! 55:
! 56: #include <machine/nexus.h>
! 57: #include <machine/vsbus.h>
! 58: #include <machine/scb.h>
! 59: #include <machine/sid.h>
! 60: #include <machine/cpu.h>
! 61:
! 62: #include <uvm/uvm_extern.h>
! 63:
! 64: #include <dev/cons.h>
! 65:
! 66: #include <dev/wscons/wsconsio.h>
! 67: #include <dev/wscons/wsdisplayvar.h>
! 68: #include <dev/rasops/rasops.h>
! 69:
! 70: #include <dev/ic/bt463reg.h> /* actually it's a 459 here... */
! 71:
! 72: #define LCSPX_REG_ADDR 0x39302000 /* registers */
! 73: #define LCSPX_REG_SIZE 0x2000
! 74: #define LCSPX_REG1_ADDR 0x39b00000 /* more registers */
! 75: #define LCSPX_RAMDAC_ADDR 0x39b10000 /* RAMDAC */
! 76: #define LCSPX_RAMDAC_INTERLEAVE 0x00004000
! 77: #define LCSPX_FB_ADDR 0x38000000 /* frame buffer */
! 78:
! 79: #define LCSPX_WIDTH 1280
! 80: #define LCSPX_HEIGHT 1024
! 81: #define LCSPX_FBSIZE (LCSPX_WIDTH * LCSPX_HEIGHT)
! 82:
! 83: void lcspx_attach(struct device *, struct device *, void *);
! 84: int lcspx_vsbus_match(struct device *, void *, void *);
! 85: int lcspx_vxtbus_match(struct device *, void *, void *);
! 86:
! 87: struct lcspx_screen {
! 88: struct rasops_info ss_ri;
! 89: caddr_t ss_addr; /* frame buffer address */
! 90: volatile u_int8_t *ss_ramdac[4];
! 91: vaddr_t ss_reg;
! 92: u_int8_t ss_cmap[256 * 3];
! 93: };
! 94:
! 95: #define lcspx_reg_read(ss, reg) \
! 96: *(volatile u_int32_t *)((ss)->ss_reg + (reg))
! 97: #define lcspx_reg_write(ss, reg, val) \
! 98: *(volatile u_int32_t *)((ss)->ss_reg + (reg)) = (val)
! 99:
! 100: /* for console */
! 101: struct lcspx_screen lcspx_consscr;
! 102:
! 103: struct lcspx_softc {
! 104: struct device sc_dev;
! 105: struct lcspx_screen *sc_scr;
! 106: int sc_nscreens;
! 107: };
! 108:
! 109: struct cfattach lcspx_vsbus_ca = {
! 110: sizeof(struct lcspx_softc), lcspx_vsbus_match, lcspx_attach,
! 111: };
! 112:
! 113: struct cfattach lcspx_vxtbus_ca = {
! 114: sizeof(struct lcspx_softc), lcspx_vxtbus_match, lcspx_attach,
! 115: };
! 116:
! 117: struct cfdriver lcspx_cd = {
! 118: NULL, "lcspx", DV_DULL
! 119: };
! 120:
! 121: struct wsscreen_descr lcspx_stdscreen = {
! 122: "std",
! 123: };
! 124:
! 125: const struct wsscreen_descr *_lcspx_scrlist[] = {
! 126: &lcspx_stdscreen,
! 127: };
! 128:
! 129: const struct wsscreen_list lcspx_screenlist = {
! 130: sizeof(_lcspx_scrlist) / sizeof(struct wsscreen_descr *),
! 131: _lcspx_scrlist,
! 132: };
! 133:
! 134: int lcspx_ioctl(void *, u_long, caddr_t, int, struct proc *);
! 135: paddr_t lcspx_mmap(void *, off_t, int);
! 136: int lcspx_alloc_screen(void *, const struct wsscreen_descr *,
! 137: void **, int *, int *, long *);
! 138: void lcspx_free_screen(void *, void *);
! 139: int lcspx_show_screen(void *, void *, int,
! 140: void (*) (void *, int, int), void *);
! 141:
! 142: const struct wsdisplay_accessops lcspx_accessops = {
! 143: lcspx_ioctl,
! 144: lcspx_mmap,
! 145: lcspx_alloc_screen,
! 146: lcspx_free_screen,
! 147: lcspx_show_screen,
! 148: NULL, /* load_font */
! 149: NULL, /* scrollback */
! 150: NULL, /* getchar */
! 151: NULL /* burner */
! 152: };
! 153:
! 154: int lcspx_getcmap(struct lcspx_screen *, struct wsdisplay_cmap *);
! 155: void lcspx_loadcmap(struct lcspx_screen *, int, int);
! 156: int lcspx_putcmap(struct lcspx_screen *, struct wsdisplay_cmap *);
! 157: static __inline__
! 158: void lcspx_ramdac_wraddr(struct lcspx_screen *, u_int);
! 159: void lcspx_resetcmap(struct lcspx_screen *);
! 160: int lcspx_setup_screen(struct lcspx_screen *);
! 161:
! 162: int
! 163: lcspx_vsbus_match(struct device *parent, void *vcf, void *aux)
! 164: {
! 165: struct vsbus_softc *sc = (void *)parent;
! 166: struct vsbus_attach_args *va = aux;
! 167:
! 168: switch (vax_boardtype) {
! 169: default:
! 170: return (0);
! 171:
! 172: case VAX_BTYP_49:
! 173: if (va->va_paddr != LCSPX_REG_ADDR)
! 174: return (0);
! 175:
! 176: if ((vax_confdata & 0x12) != 0x02)
! 177: return (0);
! 178:
! 179: break;
! 180: }
! 181:
! 182: sc->sc_mask = 0x04; /* XXX - should be generated */
! 183: scb_fake(0x120, 0x15);
! 184: return (20);
! 185: }
! 186:
! 187: int
! 188: lcspx_vxtbus_match(struct device *parent, void *vcf, void *aux)
! 189: {
! 190: struct bp_conf *bp = aux;
! 191: int missing;
! 192: volatile u_int8_t *ch;
! 193:
! 194: if (strcmp(bp->type, lcspx_cd.cd_name) != 0)
! 195: return (0);
! 196:
! 197: /*
! 198: * Check for video memory at SPX address.
! 199: */
! 200: missing = 0;
! 201: ch = (volatile u_int8_t *)vax_map_physmem(LCSPX_FB_ADDR, 1);
! 202: *ch = 0x01;
! 203: if ((*ch & 0x01) == 0)
! 204: missing = 1;
! 205: else {
! 206: *ch = 0x00;
! 207: if ((*ch & 0x01) != 0)
! 208: missing = 1;
! 209: }
! 210: vax_unmap_physmem((vaddr_t)ch, 1);
! 211:
! 212: return (missing ? 0 : 1);
! 213: }
! 214:
! 215: void
! 216: lcspx_attach(struct device *parent, struct device *self, void *aux)
! 217: {
! 218: struct lcspx_softc *sc = (struct lcspx_softc *)self;
! 219: struct lcspx_screen *ss;
! 220: struct wsemuldisplaydev_attach_args aa;
! 221: int i, console;
! 222: extern struct consdev wsdisplay_cons;
! 223:
! 224: if (cn_tab == &wsdisplay_cons) {
! 225: if (vax_boardtype == VAX_BTYP_49)
! 226: console = (vax_confdata & 8) == 0;
! 227: else /* VXT2000 */
! 228: console = (vax_confdata & 2) != 0;
! 229: } else
! 230: console = 0;
! 231: if (console) {
! 232: ss = &lcspx_consscr;
! 233: sc->sc_nscreens = 1;
! 234: } else {
! 235: ss = malloc(sizeof(struct lcspx_screen), M_DEVBUF, M_NOWAIT);
! 236: if (ss == NULL) {
! 237: printf(": can not allocate memory\n");
! 238: return;
! 239: }
! 240: bzero(ss, sizeof(struct lcspx_screen));
! 241:
! 242: ss->ss_addr = (caddr_t)vax_map_physmem(LCSPX_FB_ADDR,
! 243: LCSPX_FBSIZE / VAX_NBPG);
! 244: if (ss->ss_addr == NULL) {
! 245: printf(": can not map frame buffer\n");
! 246: goto fail1;
! 247: }
! 248:
! 249: ss->ss_reg = vax_map_physmem(LCSPX_REG_ADDR,
! 250: LCSPX_REG_SIZE / VAX_NBPG);
! 251: if (ss->ss_reg == 0L) {
! 252: printf(": can not map registers\n");
! 253: goto fail2;
! 254: }
! 255:
! 256: for (i = 0; i < 4; i++) {
! 257: ss->ss_ramdac[i] = (volatile u_int8_t *)vax_map_physmem(
! 258: LCSPX_RAMDAC_ADDR + i * LCSPX_RAMDAC_INTERLEAVE, 1);
! 259: if (ss->ss_ramdac[i] == NULL) {
! 260: printf(": can not map RAMDAC registers\n");
! 261: goto fail3;
! 262: }
! 263: }
! 264:
! 265: if (lcspx_setup_screen(ss) != 0) {
! 266: printf(": initialization failed\n");
! 267: goto fail3;
! 268: }
! 269: }
! 270: sc->sc_scr = ss;
! 271:
! 272: printf("\n%s: 1280x1024x8 frame buffer\n", self->dv_xname);
! 273:
! 274: aa.console = console;
! 275: aa.scrdata = &lcspx_screenlist;
! 276: aa.accessops = &lcspx_accessops;
! 277: aa.accesscookie = sc;
! 278: aa.defaultscreens = 0;
! 279:
! 280: config_found(self, &aa, wsemuldisplaydevprint);
! 281: return;
! 282:
! 283: fail3:
! 284: for (i = 0; i < 4; i++)
! 285: if (ss->ss_ramdac[i] != NULL)
! 286: vax_unmap_physmem((vaddr_t)ss->ss_ramdac[i], 1);
! 287: vax_unmap_physmem(ss->ss_reg, LCSPX_REG_SIZE / VAX_NBPG);
! 288: fail2:
! 289: vax_unmap_physmem((vaddr_t)ss->ss_addr, LCSPX_FBSIZE / VAX_NBPG);
! 290: fail1:
! 291: free(ss, M_DEVBUF);
! 292: }
! 293:
! 294: static __inline__ void
! 295: lcspx_ramdac_wraddr(struct lcspx_screen *ss, u_int addr)
! 296: {
! 297: *(ss->ss_ramdac[BT463_REG_ADDR_LOW]) = addr & 0xff;
! 298: *(ss->ss_ramdac[BT463_REG_ADDR_HIGH]) = (addr >> 8) & 0xff;
! 299: }
! 300:
! 301: /*
! 302: * Initialize anything necessary for an emulating wsdisplay to work (i.e.
! 303: * pick a font, initialize a rasops structure, setup the accessops callbacks.)
! 304: */
! 305: int
! 306: lcspx_setup_screen(struct lcspx_screen *ss)
! 307: {
! 308: struct rasops_info *ri = &ss->ss_ri;
! 309:
! 310: bzero(ri, sizeof(*ri));
! 311: ri->ri_depth = 8;
! 312: ri->ri_width = LCSPX_WIDTH;
! 313: ri->ri_height = LCSPX_HEIGHT;
! 314: ri->ri_stride = LCSPX_WIDTH;
! 315: ri->ri_flg = RI_CLEAR | RI_CENTER;
! 316: ri->ri_bits = (void *)ss->ss_addr;
! 317: ri->ri_hw = ss;
! 318:
! 319: /*
! 320: * Enable all planes for reading and writing
! 321: */
! 322: lcspx_reg_write(ss, 0x1170, 0xffffffff);
! 323: lcspx_reg_write(ss, 0x1174, 0xffffffff);
! 324: lcspx_ramdac_wraddr(ss, 0x0204); /* plane mask */
! 325: *(ss->ss_ramdac[BT463_REG_IREG_DATA]) = 0xff;
! 326:
! 327: /*
! 328: * Ask for an unholy big display, rasops will trim this to more
! 329: * reasonable values.
! 330: */
! 331: if (rasops_init(ri, 160, 160) != 0)
! 332: return (-1);
! 333:
! 334: lcspx_resetcmap(ss);
! 335:
! 336: lcspx_stdscreen.ncols = ri->ri_cols;
! 337: lcspx_stdscreen.nrows = ri->ri_rows;
! 338: lcspx_stdscreen.textops = &ri->ri_ops;
! 339: lcspx_stdscreen.fontwidth = ri->ri_font->fontwidth;
! 340: lcspx_stdscreen.fontheight = ri->ri_font->fontheight;
! 341: lcspx_stdscreen.capabilities = ri->ri_caps;
! 342:
! 343: return (0);
! 344: }
! 345:
! 346: int
! 347: lcspx_ioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p)
! 348: {
! 349: struct lcspx_softc *sc = v;
! 350: struct lcspx_screen *ss = sc->sc_scr;
! 351: struct wsdisplay_fbinfo *wdf;
! 352: struct wsdisplay_cmap *cm;
! 353: int error;
! 354:
! 355: switch (cmd) {
! 356: case WSDISPLAYIO_GTYPE:
! 357: *(u_int *)data = WSDISPLAY_TYPE_LCSPX;
! 358: break;
! 359:
! 360: case WSDISPLAYIO_GINFO:
! 361: wdf = (struct wsdisplay_fbinfo *)data;
! 362: wdf->height = LCSPX_HEIGHT;
! 363: wdf->width = LCSPX_WIDTH;
! 364: wdf->depth = 8;
! 365: wdf->cmsize = 256;
! 366: break;
! 367:
! 368: case WSDISPLAYIO_LINEBYTES:
! 369: *(u_int *)data = ss->ss_ri.ri_stride;
! 370: break;
! 371:
! 372: case WSDISPLAYIO_GETCMAP:
! 373: cm = (struct wsdisplay_cmap *)data;
! 374: error = lcspx_getcmap(ss, cm);
! 375: if (error != 0)
! 376: return (error);
! 377: break;
! 378: case WSDISPLAYIO_PUTCMAP:
! 379: cm = (struct wsdisplay_cmap *)data;
! 380: error = lcspx_putcmap(ss, cm);
! 381: if (error != 0)
! 382: return (error);
! 383: lcspx_loadcmap(ss, cm->index, cm->count);
! 384: break;
! 385:
! 386: case WSDISPLAYIO_GVIDEO:
! 387: case WSDISPLAYIO_SVIDEO:
! 388: break;
! 389:
! 390: default:
! 391: return (-1);
! 392: }
! 393:
! 394: return (0);
! 395: }
! 396:
! 397: paddr_t
! 398: lcspx_mmap(void *v, off_t offset, int prot)
! 399: {
! 400: if (offset >= LCSPX_FBSIZE || offset < 0)
! 401: return (-1);
! 402:
! 403: return (LCSPX_FB_ADDR + offset) >> PGSHIFT;
! 404: }
! 405:
! 406: int
! 407: lcspx_alloc_screen(void *v, const struct wsscreen_descr *type, void **cookiep,
! 408: int *curxp, int *curyp, long *defattrp)
! 409: {
! 410: struct lcspx_softc *sc = v;
! 411: struct lcspx_screen *ss = sc->sc_scr;
! 412: struct rasops_info *ri = &ss->ss_ri;
! 413:
! 414: if (sc->sc_nscreens > 0)
! 415: return (ENOMEM);
! 416:
! 417: *cookiep = ri;
! 418: *curxp = *curyp = 0;
! 419: ri->ri_ops.alloc_attr(ri, 0, 0, 0, defattrp);
! 420: sc->sc_nscreens++;
! 421:
! 422: return (0);
! 423: }
! 424:
! 425: void
! 426: lcspx_free_screen(void *v, void *cookie)
! 427: {
! 428: struct lcspx_softc *sc = v;
! 429:
! 430: sc->sc_nscreens--;
! 431: }
! 432:
! 433: int
! 434: lcspx_show_screen(void *v, void *cookie, int waitok,
! 435: void (*cb)(void *, int, int), void *cbarg)
! 436: {
! 437: return (0);
! 438: }
! 439:
! 440: /*
! 441: * Colormap handling routines
! 442: */
! 443:
! 444: int
! 445: lcspx_getcmap(struct lcspx_screen *ss, struct wsdisplay_cmap *cm)
! 446: {
! 447: u_int index = cm->index, count = cm->count, i;
! 448: int error;
! 449: u_int8_t ramp[256], *c, *r;
! 450:
! 451: if (index >= 256 || count > 256 - index)
! 452: return (EINVAL);
! 453:
! 454: /* extract reds */
! 455: c = ss->ss_cmap + 0 + index * 3;
! 456: for (i = count, r = ramp; i != 0; i--)
! 457: *r++ = *c, c += 3;
! 458: if ((error = copyout(ramp, cm->red, count)) != 0)
! 459: return (error);
! 460:
! 461: /* extract greens */
! 462: c = ss->ss_cmap + 1 + index * 3;
! 463: for (i = count, r = ramp; i != 0; i--)
! 464: *r++ = *c, c += 3;
! 465: if ((error = copyout(ramp, cm->green, count)) != 0)
! 466: return (error);
! 467:
! 468: /* extract blues */
! 469: c = ss->ss_cmap + 2 + index * 3;
! 470: for (i = count, r = ramp; i != 0; i--)
! 471: *r++ = *c, c += 3;
! 472: if ((error = copyout(ramp, cm->blue, count)) != 0)
! 473: return (error);
! 474:
! 475: return (0);
! 476: }
! 477:
! 478: int
! 479: lcspx_putcmap(struct lcspx_screen *ss, struct wsdisplay_cmap *cm)
! 480: {
! 481: u_int index = cm->index, count = cm->count;
! 482: int i, error;
! 483: u_int8_t r[256], g[256], b[256], *nr, *ng, *nb, *c;
! 484:
! 485: if (index >= 256 || count > 256 - index)
! 486: return (EINVAL);
! 487:
! 488: if ((error = copyin(cm->red, r, count)) != 0)
! 489: return (error);
! 490: if ((error = copyin(cm->green, g, count)) != 0)
! 491: return (error);
! 492: if ((error = copyin(cm->blue, b, count)) != 0)
! 493: return (error);
! 494:
! 495: nr = r, ng = g, nb = b;
! 496: c = ss->ss_cmap + index * 3;
! 497: for (i = count; i != 0; i--) {
! 498: *c++ = *nr++;
! 499: *c++ = *ng++;
! 500: *c++ = *nb++;
! 501: }
! 502:
! 503: return (0);
! 504: }
! 505:
! 506: void
! 507: lcspx_loadcmap(struct lcspx_screen *ss, int from, int count)
! 508: {
! 509: u_int8_t *cmap = ss->ss_cmap;
! 510: int i;
! 511:
! 512: cmap += from * 3;
! 513: for (i = from; i < from + count; i++) {
! 514: /*
! 515: * Reprogram the index every iteration, because the RAMDAC
! 516: * may not be in autoincrement mode. XXX fix this
! 517: */
! 518: lcspx_ramdac_wraddr(ss, i);
! 519: *(ss->ss_ramdac[BT463_REG_CMAP_DATA]) = *cmap++;
! 520: *(ss->ss_ramdac[BT463_REG_CMAP_DATA]) = *cmap++;
! 521: *(ss->ss_ramdac[BT463_REG_CMAP_DATA]) = *cmap++;
! 522: }
! 523: }
! 524:
! 525: void
! 526: lcspx_resetcmap(struct lcspx_screen *ss)
! 527: {
! 528: bcopy(rasops_cmap, ss->ss_cmap, sizeof(ss->ss_cmap));
! 529: lcspx_loadcmap(ss, 0, 256);
! 530: }
! 531:
! 532: /*
! 533: * Console support code
! 534: */
! 535:
! 536: int lcspxcnprobe(void);
! 537: void lcspxcninit(void);
! 538:
! 539: int
! 540: lcspxcnprobe()
! 541: {
! 542: extern vaddr_t virtual_avail;
! 543: volatile u_int8_t *ch;
! 544:
! 545: switch (vax_boardtype) {
! 546: case VAX_BTYP_49:
! 547: if ((vax_confdata & 8) != 0)
! 548: break; /* doesn't use graphics console */
! 549:
! 550: if ((vax_confdata & 0x12) != 0x02)
! 551: return (0);
! 552:
! 553: return (1);
! 554:
! 555: case VAX_BTYP_VXT:
! 556: if ((vax_confdata & 2) == 0)
! 557: break; /* doesn't use graphics console */
! 558:
! 559: /*
! 560: * Check for video memory at SPX address.
! 561: */
! 562: ioaccess(virtual_avail, LCSPX_FB_ADDR, 1);
! 563: ch = (volatile u_int8_t *)virtual_avail;
! 564: *ch = 0x01;
! 565: if ((*ch & 0x01) == 0)
! 566: break;
! 567: *ch = 0x00;
! 568: if ((*ch & 0x01) != 0)
! 569: break;
! 570:
! 571: return (1);
! 572:
! 573: default:
! 574: break;
! 575: }
! 576:
! 577: return (0);
! 578: }
! 579:
! 580: /*
! 581: * Called very early to setup the glass tty as console.
! 582: * Because it's called before the VM system is initialized, virtual memory
! 583: * for the framebuffer can be stolen directly without disturbing anything.
! 584: */
! 585: void
! 586: lcspxcninit()
! 587: {
! 588: struct lcspx_screen *ss = &lcspx_consscr;
! 589: extern vaddr_t virtual_avail;
! 590: int i;
! 591: long defattr;
! 592: struct rasops_info *ri;
! 593:
! 594: ss->ss_addr = (caddr_t)virtual_avail;
! 595: virtual_avail += LCSPX_FBSIZE;
! 596: ioaccess((vaddr_t)ss->ss_addr, LCSPX_FB_ADDR, LCSPX_FBSIZE / VAX_NBPG);
! 597:
! 598: ss->ss_reg = virtual_avail;
! 599: virtual_avail += LCSPX_REG_SIZE;
! 600: ioaccess(ss->ss_reg, LCSPX_REG_ADDR, LCSPX_REG_SIZE / VAX_NBPG);
! 601:
! 602: for (i = 0; i < 4; i++) {
! 603: ss->ss_ramdac[i] = (volatile u_int8_t *)virtual_avail;
! 604: virtual_avail += VAX_NBPG;
! 605: ioaccess((vaddr_t)ss->ss_ramdac[i],
! 606: LCSPX_RAMDAC_ADDR + i * LCSPX_RAMDAC_INTERLEAVE, 1);
! 607: }
! 608:
! 609: virtual_avail = round_page(virtual_avail);
! 610:
! 611: /* this had better not fail as we can't recover there */
! 612: if (lcspx_setup_screen(ss) != 0)
! 613: panic(__func__);
! 614:
! 615: ri = &ss->ss_ri;
! 616: ri->ri_ops.alloc_attr(ri, 0, 0, 0, &defattr);
! 617: wsdisplay_cnattach(&lcspx_stdscreen, ri, 0, 0, defattr);
! 618: }
CVSweb