diff options
author | Jason Wright <jason@cvs.openbsd.org> | 2002-01-04 01:13:30 +0000 |
---|---|---|
committer | Jason Wright <jason@cvs.openbsd.org> | 2002-01-04 01:13:30 +0000 |
commit | d2bf9720f54c59bb872fe05f29bd558c50af7939 (patch) | |
tree | 780c59a2a93ea7ae18503c21b8beb032859e6551 /sys/dev/sbus/cgsix.c | |
parent | 13d29f577b332c6fbda97311126e6ac3c00536ef (diff) |
add mmap functionality (most from NetBSD)
Diffstat (limited to 'sys/dev/sbus/cgsix.c')
-rw-r--r-- | sys/dev/sbus/cgsix.c | 75 |
1 files changed, 68 insertions, 7 deletions
diff --git a/sys/dev/sbus/cgsix.c b/sys/dev/sbus/cgsix.c index dafc090e68f..6153a596e6a 100644 --- a/sys/dev/sbus/cgsix.c +++ b/sys/dev/sbus/cgsix.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cgsix.c,v 1.2 2001/12/05 05:38:28 jason Exp $ */ +/* $OpenBSD: cgsix.c,v 1.3 2002/01/04 01:13:29 jason Exp $ */ /* * Copyright (c) 2001 Jason L. Wright (jason@thought.net) @@ -50,12 +50,17 @@ #include <dev/wscons/wscons_raster.h> #include <dev/rcons/raster.h> +#define CGSIX_ROM_OFFSET 0x000000 #define CGSIX_BT_OFFSET 0x200000 #define CGSIX_BT_SIZE (sizeof(u_int32_t) * 4) +#define CGSIX_DHC_OFFSET 0x240000 +#define CGSIX_ALT_OFFSET 0x280000 #define CGSIX_FHC_OFFSET 0x300000 #define CGSIX_FHC_SIZE (sizeof(u_int32_t) * 1) #define CGSIX_THC_OFFSET 0x301000 #define CGSIX_THC_SIZE (sizeof(u_int32_t) * 640) +#define CGSIX_FBC_OFFSET 0x700000 +#define CGSIX_TEC_OFFSET 0x701000 #define CGSIX_VID_OFFSET 0x800000 #define CGSIX_VID_SIZE (1024 * 1024) @@ -63,6 +68,8 @@ struct cgsix_softc { struct device sc_dev; struct sbusdev sc_sd; bus_space_tag_t sc_bustag; + bus_addr_t sc_paddr; + bus_type_t sc_btype; bus_space_handle_t sc_bt_regs; bus_space_handle_t sc_fhc_regs; bus_space_handle_t sc_thc_regs; @@ -73,6 +80,21 @@ struct cgsix_softc { struct raster sc_raster; }; +#define CG6_USER_FBC 0x70000000 +#define CG6_USER_TEC 0x70001000 +#define CG6_USER_BTREGS 0x70002000 +#define CG6_USER_FHC 0x70004000 +#define CG6_USER_THC 0x70005000 +#define CG6_USER_ROM 0x70006000 +#define CG6_USER_RAM 0x70016000 +#define CG6_USER_DHC 0x80000000 + +struct mmo { + u_long mo_uaddr; /* user (virtual address */ + u_long mo_size; /* size, or 0 for video ram size */ + u_long mo_physoff; /* offset from sc_physadr */ +}; + struct wsdisplay_emulops cgsix_emulops = { rcons_cursor, rcons_mapchar, @@ -155,6 +177,8 @@ cgsixattach(parent, self, aux) long defattr; sc->sc_bustag = sa->sa_bustag; + sc->sc_btype = (bus_type_t)sa->sa_slot; + sc->sc_paddr = sbus_bus_addr(sa->sa_bustag, sa->sa_slot, sa->sa_offset); if (sa->sa_nreg != 1) { printf(": expected %d registers, got %d\n", 1, sa->sa_nreg); @@ -353,17 +377,54 @@ cgsix_show_screen(v, cookie, waitok, cb, cbarg) } paddr_t -cgsix_mmap(v, offset, prot) +cgsix_mmap(v, off, prot) void *v; - off_t offset; + off_t off; int prot; { -#if 0 struct cgsix_softc *sc = v; -#endif - - if (offset & PGOFSET) + struct mmo *mo; + u_int u, sz; + + static struct mmo mmo[] = { + { CG6_USER_RAM, 0, CGSIX_VID_OFFSET }, + { CG6_USER_FBC, 1, CGSIX_FBC_OFFSET }, + { CG6_USER_TEC, 1, CGSIX_TEC_OFFSET }, + { CG6_USER_BTREGS, 8192 /* XXX */, CGSIX_BT_OFFSET }, + { CG6_USER_FHC, 1, CGSIX_FHC_OFFSET }, + { CG6_USER_THC, 1, CGSIX_THC_OFFSET }, + { CG6_USER_ROM, 1, CGSIX_ROM_OFFSET }, + { CG6_USER_DHC, 1, CGSIX_DHC_OFFSET }, + }; +#define NMMO (sizeof(mmo) / sizeof(*mmo)) + + if (off & PGOFSET) return (-1); + + /* + * Entries with size 0 map video RAM (i.e., the size in fb data). + * + * Since we work in pages, the fact that the map offset table's + * sizes are sometimes bizarre (e.g., 1) is effectively ignored: + * one byte is as good as one page. + */ + for (mo = mmo; mo < &mmo[NMMO]; mo++) { + if ((u_long)off < mo->mo_uaddr) + continue; + u = off - mo->mo_uaddr; + sz = mo->mo_size ? mo->mo_size : + sc->sc_linebytes * sc->sc_height; + if (u < sz) { + bus_space_handle_t bh; + + if (bus_space_mmap(sc->sc_bustag, sc->sc_btype, + sc->sc_paddr + u + mo->mo_physoff, + BUS_SPACE_MAP_LINEAR, &bh)) + return (-1); + return ((paddr_t)bh); + } + } + return (-1); } |