[BACK]Return to xboxfb.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / arch / i386 / xbox

Annotation of src/sys/arch/i386/xbox/xboxfb.c, Revision 1.4

1.4     ! jmcneill    1: /* $NetBSD: xboxfb.c,v 1.3 2007/01/05 04:13:09 jmcneill Exp $ */
1.1       jmcneill    2:
                      3: /*
                      4:  * Copyright (c) 2006 Andrew Gillham
                      5:  * All rights reserved.
                      6:  *
                      7:  * Redistribution and use in source and binary forms, with or without
                      8:  * modification, are permitted provided that the following conditions
                      9:  * are met:
                     10:  * 1. Redistributions of source code must retain the above copyright
                     11:  *    notice, this list of conditions and the following disclaimer.
                     12:  * 2. Redistributions in binary form must reproduce the above copyright
                     13:  *    notice, this list of conditions and the following disclaimer in the
                     14:  *    documentation and/or other materials provided with the distribution.
                     15:  * 3. The name of the author may not be used to endorse or promote products
                     16:  *    derived from this software without specific prior written permission.
                     17:  *
                     18:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
                     19:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
                     20:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
                     21:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
                     22:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
                     23:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
                     24:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
                     25:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
                     26:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
                     27:  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
                     28:  */
                     29:
                     30: /*
                     31:  * A console driver for the Xbox.
                     32:  */
                     33:
                     34: #include <sys/cdefs.h>
                     35: #include <sys/param.h>
                     36: #include <sys/systm.h>
                     37: #include <sys/kernel.h>
                     38: #include <sys/device.h>
                     39: #include <sys/malloc.h>
                     40: #include <sys/callout.h>
                     41: #include <sys/lwp.h>
                     42: #include <sys/kauth.h>
                     43:
                     44: #include <uvm/uvm_extern.h>
                     45: /* #include <machine/autoconf.h> */
                     46: #include <machine/bus.h>
                     47: #include <machine/xbox.h>
                     48:
                     49: #include <dev/pci/pcivar.h>
                     50: #include <dev/pci/pcireg.h>
                     51: #include <dev/pci/pcidevs.h>
                     52: #include <dev/pci/pciio.h>
                     53:
                     54: #include <dev/wscons/wsdisplayvar.h>
                     55: #include <dev/wscons/wsconsio.h>
                     56: #include <dev/wsfont/wsfont.h>
                     57: #include <dev/rasops/rasops.h>
                     58: #include <dev/wscons/wsdisplay_vconsvar.h>
                     59:
                     60: #include "opt_wsemul.h"
                     61:
1.2       jmcneill   62: MALLOC_DEFINE(M_XBOXFB, "xboxfb", "xboxfb shadow framebuffer");
                     63:
1.1       jmcneill   64: #define SCREEN_WIDTH   640
                     65: #define SCREEN_HEIGHT  480
                     66: #define SCREEN_BPP     32
                     67: #define SCREEN_SIZE    (SCREEN_WIDTH*SCREEN_HEIGHT*SCREEN_BPP)
                     68:
                     69: #define FONT_HEIGHT    16
                     70: #define FONT_WIDTH     8
                     71:
                     72: #define CHAR_HEIGHT    16
                     73: #define CHAR_WIDTH     10
                     74:
                     75: /*
                     76: #define XBOX_RAM_SIZE          (arch_i386_xbox_memsize * 1024 * 1024)
                     77: #define XBOX_FB_SIZE           (0x400000)
                     78: #define XBOX_FB_START          (0xF0000000 | (XBOX_RAM_SIZE - XBOX_FB_SIZE))
                     79: #define XBOX_FB_START_PTR      (0xFD600800)
                     80: */
                     81:
1.3       jmcneill   82: static char *xboxfb_console_shadowbits;
                     83: static bus_space_handle_t xboxfb_console_memh;
                     84:
1.1       jmcneill   85: struct xboxfb_softc {
                     86:        struct device sc_dev;
                     87:        struct vcons_data vd;
                     88:
                     89:        bus_space_tag_t sc_memt;
                     90:        bus_space_handle_t sc_memh;
                     91:
                     92:        vaddr_t fbva;
                     93:        paddr_t fbpa;
                     94:
                     95:        void *sc_ih;
                     96:
                     97:        size_t memsize;
                     98:
                     99:        int bits_per_pixel;
                    100:        int width, height, linebytes;
                    101:
                    102:        int sc_mode;
                    103:        uint32_t sc_bg;
1.2       jmcneill  104:
                    105:        char *sc_shadowbits;
1.1       jmcneill  106: };
                    107:
                    108: static struct vcons_screen xboxfb_console_screen;
                    109:
                    110: static int     xboxfb_match(struct device *, struct cfdata *, void *);
                    111: static void    xboxfb_attach(struct device *, struct device *, void *);
                    112:
                    113: CFATTACH_DECL(xboxfb, sizeof(struct xboxfb_softc), xboxfb_match,
                    114:        xboxfb_attach, NULL, NULL);
                    115:
                    116: /* static void xboxfb_init(struct xboxfb_softc *); */
                    117:
                    118: /* static void xboxfb_cursor(void *, int, int, int); */
                    119: /* static void xboxfb_copycols(void *, int, int, int, int); */
                    120: /* static void xboxfb_erasecols(void *, int, int, int, long); */
                    121: /* static void xboxfb_copyrows(void *, int, int, int); */
                    122: /* static void xboxfb_eraserows(void *, int, int, long); */
                    123:
                    124: struct wsscreen_descr xboxfb_defaultscreen = {
                    125:        "default",
                    126:        0, 0,
                    127:        NULL,
                    128:        8, 16,
                    129:        WSSCREEN_WSCOLORS,
                    130:        NULL,
                    131: };
                    132:
                    133: const struct wsscreen_descr *_xboxfb_scrlist[] = {
                    134:        &xboxfb_defaultscreen,
                    135: };
                    136:
                    137: struct wsscreen_list xboxfb_screenlist = {
                    138:        sizeof(_xboxfb_scrlist) / sizeof(struct wsscreen_descr *),
                    139:                _xboxfb_scrlist
                    140: };
                    141:
                    142: static int     xboxfb_ioctl(void *, void *, u_long, caddr_t, int,
                    143:                        struct lwp *);
                    144: static paddr_t xboxfb_mmap(void *, void *, off_t, int);
                    145: static void    xboxfb_init_screen(void *, struct vcons_screen *, int,
                    146:                        long *);
                    147:
                    148: struct wsdisplay_accessops xboxfb_accessops = {
                    149:        xboxfb_ioctl,
                    150:        xboxfb_mmap,
                    151:        NULL,   /* alloc_screen */
                    152:        NULL,   /* free_screen */
                    153:        NULL,   /* show_screen */
                    154:        NULL,   /* load_font */
                    155:        NULL,   /* pollc */
                    156:        NULL,   /* scroll */
                    157: };
                    158:
                    159: static int
                    160: xboxfb_match(struct device *parent, struct cfdata *match, void *aux)
                    161: {
                    162:        struct pci_attach_args *pa = (struct pci_attach_args *)aux;
                    163:
                    164:        /* Don't match on non-Xbox i386 */
                    165:        if (!arch_i386_is_xbox) {
                    166:                return (0);
                    167:        }
                    168:
                    169:        if (PCI_CLASS(pa->pa_class) != PCI_CLASS_DISPLAY ||
                    170:            PCI_SUBCLASS(pa->pa_class) != PCI_SUBCLASS_DISPLAY_VGA)
                    171:                return 0;
                    172:        if ((PCI_VENDOR(pa->pa_id) == PCI_VENDOR_NVIDIA) &&
                    173:            (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_NVIDIA_XBOXFB))
                    174:                return 100;
                    175:        return 0;
                    176: };
                    177:
                    178: static void
                    179: xboxfb_attach(struct device *parent, struct device *self, void *aux)
                    180: {
                    181:        struct xboxfb_softc *sc = (void *)self;
                    182:        struct wsemuldisplaydev_attach_args aa;
                    183:        struct rasops_info *ri;
                    184:        int console;
                    185:        ulong defattr = 0;
                    186:        uint32_t bg, fg, ul;
                    187:
1.3       jmcneill  188:        sc->sc_memt = X86_BUS_SPACE_MEM;
                    189:        sc->sc_memh = xboxfb_console_memh;
1.1       jmcneill  190:        sc->sc_mode = WSDISPLAYIO_MODE_EMUL;
                    191:        sc->width = SCREEN_WIDTH;
                    192:        sc->height = SCREEN_HEIGHT;
                    193:        sc->bits_per_pixel = SCREEN_BPP;
                    194:        sc->fbpa = XBOX_FB_START;
                    195:
1.3       jmcneill  196:        aprint_normal(": %dx%d, %d bit framebuffer console\n",
1.1       jmcneill  197:                sc->width, sc->height, sc->bits_per_pixel);
                    198:
                    199:        sc->fbva = (vaddr_t)bus_space_vaddr(sc->sc_memt, sc->sc_memh);
                    200:        if (sc->fbva == 0)
                    201:                return;
                    202:
1.3       jmcneill  203:        sc->sc_shadowbits = xboxfb_console_shadowbits;
1.2       jmcneill  204:        if (sc->sc_shadowbits == NULL) {
                    205:                aprint_error(": unable to allocate %d bytes for shadowfb\n",
                    206:                    XBOX_FB_SIZE);
                    207:                return;
                    208:        }
                    209:
                    210:        ri = &xboxfb_console_screen.scr_ri;
                    211:
1.1       jmcneill  212:        vcons_init(&sc->vd, sc, &xboxfb_defaultscreen, &xboxfb_accessops);
                    213:        sc->vd.init_screen = xboxfb_init_screen;
                    214:
                    215:        /* yes, we're the console */
                    216:        console = 1;
                    217:
                    218:        if (console) {
                    219:                vcons_init_screen(&sc->vd, &xboxfb_console_screen, 1,
                    220:                        &defattr);
1.3       jmcneill  221:                xboxfb_console_screen.scr_flags |= VCONS_SCREEN_IS_STATIC;
                    222:        }
1.1       jmcneill  223:
                    224:        rasops_unpack_attr(defattr, &fg, &bg, &ul);
                    225:        sc->sc_bg = ri->ri_devcmap[bg];
                    226:
                    227:        aa.console = console;
                    228:        aa.scrdata = &xboxfb_screenlist;
                    229:        aa.accessops = &xboxfb_accessops;
                    230:        aa.accesscookie = &sc->vd;
                    231:
                    232:        config_found(self, &aa, wsemuldisplaydevprint);
                    233: }
                    234:
                    235: /*
                    236:  * respond to ioctl requests
                    237:  */
                    238:
                    239: static int
                    240: xboxfb_ioctl(void *v, void*vs, u_long cmd, caddr_t data, int flag,
                    241:        struct lwp *l)
                    242: {
                    243:        struct vcons_data *vd = v;
1.4     ! jmcneill  244:        struct xboxfb_softc *sc = vd->cookie;
1.1       jmcneill  245:        struct wsdisplay_fbinfo *wdf;
                    246:        struct vcons_screen *ms = vd->active;
                    247:
                    248:        switch (cmd) {
                    249:                case WSDISPLAYIO_GTYPE:
                    250:                        *(u_int *)data = WSDISPLAY_TYPE_PCIMISC;
1.4     ! jmcneill  251:                        return 0;
1.1       jmcneill  252:
                    253:                case WSDISPLAYIO_GINFO:
                    254:                        wdf = (void *)data;
                    255:                        wdf->height = ms->scr_ri.ri_height;
                    256:                        wdf->width = ms->scr_ri.ri_width;
                    257:                        wdf->depth = ms->scr_ri.ri_depth;
                    258:                        wdf->cmsize = 256;
1.4     ! jmcneill  259:                        return 0;
1.1       jmcneill  260:
                    261:                case WSDISPLAYIO_GETCMAP:
1.4     ! jmcneill  262:                        return EINVAL;
1.1       jmcneill  263:
                    264:                case WSDISPLAYIO_PUTCMAP:
1.4     ! jmcneill  265:                        return EINVAL;
        !           266:
        !           267:                case WSDISPLAYIO_LINEBYTES:
        !           268:                        *(u_int *)data = SCREEN_WIDTH * 4;
        !           269:                        return 0;
1.1       jmcneill  270:
                    271:                case WSDISPLAYIO_SMODE:
1.4     ! jmcneill  272:                        {
        !           273:                                int new_mode = *(int *)data;
        !           274:                                if (new_mode != sc->sc_mode) {
        !           275:                                        sc->sc_mode = new_mode;
        !           276:                                        if (new_mode == WSDISPLAYIO_MODE_EMUL)
        !           277:                                                vcons_redraw_screen(vd->active);
        !           278:                                }
        !           279:                        }
        !           280:                        return 0;
1.1       jmcneill  281:        }
                    282:        return EPASSTHROUGH;
                    283: }
                    284:
                    285: static paddr_t
                    286: xboxfb_mmap(void *v, void *vs, off_t offset, int prot)
                    287: {
1.4     ! jmcneill  288:        struct vcons_data *vd;
        !           289:        struct xboxfb_softc *sc;
        !           290:        paddr_t pa;
        !           291:
        !           292:        vd = (struct vcons_data *)v;
        !           293:        sc = (struct xboxfb_softc *)vd->cookie;
        !           294:
        !           295:        if (offset >= 0 && offset < XBOX_FB_SIZE) {
        !           296:                pa = bus_space_mmap(X86_BUS_SPACE_MEM, XBOX_FB_START,
        !           297:                    offset, prot, BUS_SPACE_MAP_LINEAR);
        !           298:                return pa;
        !           299:        }
        !           300:
1.1       jmcneill  301:        return (-1);
                    302: }
                    303:
                    304: static void
                    305: xboxfb_init_screen(void *cookie, struct vcons_screen *scr,
                    306:        int existing, long *defattr)
                    307: {
                    308:        struct xboxfb_softc *sc = cookie;
                    309:        struct rasops_info *ri = &scr->scr_ri;
                    310:
1.3       jmcneill  311:        if (scr == &xboxfb_console_screen)
                    312:                return;
                    313:
1.1       jmcneill  314:        ri->ri_depth = sc->bits_per_pixel;
                    315:        ri->ri_width = sc->width;
                    316:        ri->ri_height = sc->height;
                    317:        ri->ri_stride = sc->width * (sc->bits_per_pixel / 8);
1.2       jmcneill  318:        ri->ri_flg = RI_CENTER;
1.1       jmcneill  319:
1.3       jmcneill  320:        if (xboxfb_console_shadowbits != NULL) {
                    321:                ri->ri_hwbits = bus_space_vaddr(sc->sc_memt, sc->sc_memh);
                    322:                ri->ri_bits = sc->sc_shadowbits;
                    323:        } else
                    324:                ri->ri_bits = bus_space_vaddr(sc->sc_memt, sc->sc_memh);
1.1       jmcneill  325:
                    326:        if (existing) {
                    327:                ri->ri_flg |= RI_CLEAR;
                    328:        }
                    329:
                    330:        rasops_init(ri, sc->height/8, sc->width/8);
                    331:        ri->ri_caps = WSSCREEN_WSCOLORS;
                    332:
                    333:        rasops_reconfig(ri, sc->height / ri->ri_font->fontheight,
                    334:                sc->width / ri->ri_font->fontwidth);
                    335:
                    336:        ri->ri_hw = scr;
                    337: }
                    338:
                    339: int
                    340: xboxfb_cnattach(void)
                    341: {
1.3       jmcneill  342:        static int ncalls = 0;
                    343:        struct rasops_info *ri = &xboxfb_console_screen.scr_ri;
                    344:        long defattr;
                    345:
                    346:        /* We can't attach if we're not running on an Xbox... */
                    347:        if (!arch_i386_is_xbox)
                    348:                return 1;
                    349:
                    350:        /* XXX jmcneill
                    351:         *  Console initialization is called multiple times on i386; the first
                    352:         *  two being too early for us to use malloc or bus_space_map. Defer
                    353:         *  initialization under these subsystems are ready.
                    354:         */
                    355:        ++ncalls;
                    356:        if (ncalls < 3)
                    357:                return -1;
                    358:
                    359:        xboxfb_console_shadowbits = malloc(XBOX_FB_SIZE, M_XBOXFB, M_NOWAIT);
                    360:
                    361:        if (xboxfb_console_shadowbits == NULL)
                    362:                aprint_error("xboxfb_cnattach: failed to allocate shadowfb\n");
                    363:
                    364:        if (bus_space_map(X86_BUS_SPACE_MEM, XBOX_FB_START, XBOX_FB_SIZE,
                    365:            BUS_SPACE_MAP_LINEAR, &xboxfb_console_memh)) {
                    366:                aprint_error("xboxfb_cnattach: failed to map memory.\n");
                    367:                return 1;
                    368:        }
                    369:
                    370:        wsfont_init();
                    371:        ri->ri_width = SCREEN_WIDTH;
                    372:        ri->ri_height = SCREEN_HEIGHT;
                    373:        ri->ri_depth = SCREEN_BPP;
                    374:        ri->ri_stride = ri->ri_width * ri->ri_depth / 8;
                    375:        ri->ri_flg = RI_CENTER;
                    376:        ri->ri_bits = xboxfb_console_shadowbits;
                    377:        ri->ri_hwbits = bus_space_vaddr(X86_BUS_SPACE_MEM,
                    378:            xboxfb_console_memh);
                    379:        if (ri->ri_hwbits == NULL) {
                    380:                aprint_error("xboxfb_cnattach: bus_space_vaddr failed\n");
                    381:                return 1;
                    382:        }
                    383:
                    384:        /* clear screen */
                    385:        memset(ri->ri_bits, 0, XBOX_FB_SIZE);
                    386:        memset(ri->ri_hwbits, 0, XBOX_FB_SIZE);
                    387:
                    388:        rasops_init(ri, ri->ri_height / 8, ri->ri_width / 8);
                    389:        ri->ri_caps = WSSCREEN_WSCOLORS;
                    390:        rasops_reconfig(ri, ri->ri_height / ri->ri_font->fontheight,
                    391:            ri->ri_width / ri->ri_font->fontwidth);
                    392:
                    393:        xboxfb_defaultscreen.nrows = ri->ri_rows;
                    394:        xboxfb_defaultscreen.ncols = ri->ri_cols;
                    395:        xboxfb_defaultscreen.textops = &ri->ri_ops;
                    396:        xboxfb_defaultscreen.capabilities = ri->ri_caps;
                    397:        ri->ri_ops.allocattr(ri, 0, 0, 0, &defattr);
                    398:
                    399:        wsdisplay_preattach(&xboxfb_defaultscreen, ri, 0, 0, defattr);
                    400:
                    401:        return 0;
1.1       jmcneill  402: }

CVSweb <webmaster@jp.NetBSD.org>