diff options
author | Miod Vallat <miod@cvs.openbsd.org> | 2009-02-06 22:51:05 +0000 |
---|---|---|
committer | Miod Vallat <miod@cvs.openbsd.org> | 2009-02-06 22:51:05 +0000 |
commit | d3d361a2d3be481e649cb5db5bb377125c6685b7 (patch) | |
tree | 43b8dfcc550c09e3fd40baa6b96a3bddbedf73f8 | |
parent | 4ea92572c6bf8090d5a1aa27720c960a9373971a (diff) |
Split sti structures into rom-related information and screen-related
information. This is preliminary work to help eventually supporting the
dual-head ELK model.
Also split the initialization code in several routines, this makes the
code easier to read, and makes it easier to release resources upon failure.
Finally, don't forget to clear the text planes on non-console displays
when initializing.
-rw-r--r-- | sys/arch/hp300/dev/sti_sgc.c | 37 | ||||
-rw-r--r-- | sys/arch/hppa/dev/sti_sgc.c | 24 | ||||
-rw-r--r-- | sys/dev/ic/sti.c | 845 | ||||
-rw-r--r-- | sys/dev/ic/stivar.h | 146 | ||||
-rw-r--r-- | sys/dev/pci/sti_pci.c | 15 |
5 files changed, 593 insertions, 474 deletions
diff --git a/sys/arch/hp300/dev/sti_sgc.c b/sys/arch/hp300/dev/sti_sgc.c index 5b0806b0e31..089dde3b9a4 100644 --- a/sys/arch/hp300/dev/sti_sgc.c +++ b/sys/arch/hp300/dev/sti_sgc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sti_sgc.c,v 1.14 2007/05/26 00:36:03 krw Exp $ */ +/* $OpenBSD: sti_sgc.c,v 1.15 2009/02/06 22:51:03 miod Exp $ */ /* * Copyright (c) 2005, Miodrag Vallat @@ -55,8 +55,9 @@ struct cfattach sti_sgc_ca = { }; /* Console data */ -struct sti_screen stifb_cn; -bus_addr_t stifb_cn_bases[STI_REGION_MAX]; +struct sti_rom sticn_rom; +struct sti_screen sticn_scr; +bus_addr_t sticn_bases[STI_REGION_MAX]; int sti_sgc_match(struct device *parent, void *match, void *aux) @@ -79,7 +80,7 @@ sti_sgc_attach(struct device *parent, struct device *self, void *aux) struct sti_softc *sc = (void *)self; struct sgc_attach_args *saa = aux; bus_addr_t base; - bus_space_handle_t ioh; + bus_space_handle_t romh; u_int romend; int i; @@ -89,14 +90,15 @@ sti_sgc_attach(struct device *parent, struct device *self, void *aux) */ if (SGC_SLOT_TO_CONSCODE(saa->saa_slot) == conscode) { sc->sc_flags |= STI_CONSOLE | STI_ATTACHED; - sc->sc_scr = &stifb_cn; - bcopy(stifb_cn_bases, sc->bases, sizeof(sc->bases)); + sc->sc_rom = &sticn_rom; + sc->sc_scr = &sticn_scr; + bcopy(sticn_bases, sc->bases, sizeof(sc->bases)); sti_describe(sc); } else { base = (bus_addr_t)sgc_slottopa(saa->saa_slot); - if (bus_space_map(saa->saa_iot, base, PAGE_SIZE, 0, &ioh)) { + if (bus_space_map(saa->saa_iot, base, PAGE_SIZE, 0, &romh)) { printf(": can't map frame buffer"); return; } @@ -104,22 +106,21 @@ sti_sgc_attach(struct device *parent, struct device *self, void *aux) /* * Compute real PROM size */ - romend = sti_rom_size(saa->saa_iot, ioh); + romend = sti_rom_size(saa->saa_iot, romh); - bus_space_unmap(saa->saa_iot, ioh, PAGE_SIZE); + bus_space_unmap(saa->saa_iot, romh, PAGE_SIZE); - if (bus_space_map(saa->saa_iot, base, romend, 0, &ioh)) { + if (bus_space_map(saa->saa_iot, base, romend, 0, &romh)) { printf(": can't map frame buffer"); return; } - sc->memt = sc->iot = saa->saa_iot; - sc->romh = ioh; - sc->bases[0] = sc->romh; + sc->bases[0] = romh; for (i = 1; i < STI_REGION_MAX; i++) sc->bases[i] = base; - if (sti_attach_common(sc, STI_CODEBASE_M68K) != 0) + if (sti_attach_common(sc, saa->saa_iot, saa->saa_iot, romh, + STI_CODEBASE_M68K) != 0) return; } @@ -186,12 +187,12 @@ sticninit() iot = &hp300_mem_tag; base = (bus_addr_t)sgc_slottopa(CONSCODE_TO_SGC_SLOT(conscode)); - /* stifb_cn_bases[0] will be fixed in sti_cnattach() */ + /* sticn_bases[0] will be fixed in sti_cnattach() */ for (i = 0; i < STI_REGION_MAX; i++) - stifb_cn_bases[i] = base; + sticn_bases[i] = base; - sti_cnattach(&stifb_cn, iot, stifb_cn_bases, STI_CODEBASE_M68K); - sti_clear(&stifb_cn); + sti_cnattach(&sticn_rom, &sticn_scr, iot, sticn_bases, + STI_CODEBASE_M68K); /* * Since the copyright notice could not be displayed before, diff --git a/sys/arch/hppa/dev/sti_sgc.c b/sys/arch/hppa/dev/sti_sgc.c index bfe294bf753..c04c51819bb 100644 --- a/sys/arch/hppa/dev/sti_sgc.c +++ b/sys/arch/hppa/dev/sti_sgc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sti_sgc.c,v 1.37 2007/09/15 14:28:17 krw Exp $ */ +/* $OpenBSD: sti_sgc.c,v 1.38 2009/02/06 22:51:04 miod Exp $ */ /* * Copyright (c) 2000-2003 Michael Shalayeff @@ -55,7 +55,7 @@ #define STI_ID_FDDI 0x280b31af /* Medusa FDDI ROM id */ /* gecko optional graphics (these share the onboard's prom) */ -char sti_sgc_opt[] = { 0x17, 0x20, 0x30, 0x40, 0x70, 0xc0, 0xd0 }; +const char sti_sgc_opt[] = { 0x17, 0x20, 0x30, 0x40, 0x70, 0xc0, 0xd0 }; extern struct cfdriver sti_cd; @@ -98,9 +98,7 @@ sti_sgc_getrom(int unit, struct confargs *ca) } int -sti_sgc_probe(parent, match, aux) - struct device *parent; - void *match, *aux; +sti_sgc_probe(struct device *parent, void *match, void *aux) { struct cfdata *cf = match; struct confargs *ca = aux; @@ -187,32 +185,29 @@ sti_sgc_probe(parent, match, aux) } void -sti_sgc_attach(parent, self, aux) - struct device *parent, *self; - void *aux; +sti_sgc_attach(struct device *parent, struct device *self, void *aux) { struct sti_softc *sc = (void *)self; struct confargs *ca = aux; + bus_space_handle_t romh; paddr_t rom; u_int32_t romlen; int rv; int i; - sc->memt = sc->iot = ca->ca_iot; - /* we stashed rom addr/len into the last slot during probe */ rom = ca->ca_addrs[ca->ca_naddrs - 1].addr; romlen = ca->ca_addrs[ca->ca_naddrs - 1].size; - if ((rv = bus_space_map(ca->ca_iot, rom, romlen, 0, &sc->romh))) { + if ((rv = bus_space_map(ca->ca_iot, rom, romlen, 0, &romh))) { if ((rom & HPPA_IOBEGIN) == HPPA_IOBEGIN) - sc->romh = rom; + romh = rom; else { printf (": cannot map rom space (%d)\n", rv); return; } } - sc->bases[0] = sc->romh; + sc->bases[0] = romh; for (i = 1; i < STI_REGION_MAX; i++) sc->bases[i] = ca->ca_hpa; @@ -224,6 +219,7 @@ sti_sgc_attach(parent, self, aux) if (ca->ca_hpa == (hppa_hpa_t)PAGE0->mem_cons.pz_hpa) sc->sc_flags |= STI_CONSOLE; - if (sti_attach_common(sc, STI_CODEBASE_PA) == 0) + if (sti_attach_common(sc, ca->ca_iot, ca->ca_iot, romh, + STI_CODEBASE_PA) == 0) startuphook_establish(sti_end_attach, sc); } diff --git a/sys/dev/ic/sti.c b/sys/dev/ic/sti.c index 12bff05e056..a3e377ba00e 100644 --- a/sys/dev/ic/sti.c +++ b/sys/dev/ic/sti.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sti.c,v 1.59 2009/02/06 20:27:40 miod Exp $ */ +/* $OpenBSD: sti.c,v 1.60 2009/02/06 22:51:04 miod Exp $ */ /* * Copyright (c) 2000-2003 Michael Shalayeff @@ -53,15 +53,15 @@ struct cfdriver sti_cd = { NULL, "sti", DV_DULL }; -void sti_cursor(void *v, int on, int row, int col); -int sti_mapchar(void *v, int uni, u_int *index); -void sti_putchar(void *v, int row, int col, u_int uc, long attr); -void sti_copycols(void *v, int row, int srccol, int dstcol, int ncols); -void sti_erasecols(void *v, int row, int startcol, int ncols, long attr); -void sti_copyrows(void *v, int srcrow, int dstrow, int nrows); -void sti_eraserows(void *v, int row, int nrows, long attr); -int sti_alloc_attr(void *v, int fg, int bg, int flags, long *pattr); -void sti_unpack_attr(void *v, long attr, int *fg, int *bg, int *ul); +int sti_alloc_attr(void *, int, int, int, long *); +void sti_copycols(void *, int, int, int, int); +void sti_copyrows(void *, int, int, int); +void sti_cursor(void *, int, int, int); +void sti_erasecols(void *, int, int, int, long); +void sti_eraserows(void *, int, int, long); +int sti_mapchar(void *, int, u_int *); +void sti_putchar(void *, int, int, u_int, long); +void sti_unpack_attr(void *, long, int *, int *, int *); struct wsdisplay_emulops sti_emulops = { sti_cursor, @@ -75,14 +75,13 @@ struct wsdisplay_emulops sti_emulops = { sti_unpack_attr }; -int sti_ioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p); -paddr_t sti_mmap(void *v, off_t offset, int prot); -int sti_alloc_screen(void *v, const struct wsscreen_descr *type, - void **cookiep, int *cxp, int *cyp, long *defattr); - void sti_free_screen(void *v, void *cookie); -int sti_show_screen(void *v, void *cookie, int waitok, - void (*cb)(void *, int, int), void *cbarg); -int sti_load_font(void *v, void *cookie, struct wsdisplay_font *); +int sti_alloc_screen(void *, const struct wsscreen_descr *, void **, int *, + int *, long *); +void sti_free_screen(void *, void *); +int sti_ioctl(void *, u_long, caddr_t, int, struct proc *); +paddr_t sti_mmap(void *, off_t, int); +int sti_show_screen(void *, void *, int, void (*)(void *, int, int), + void *); const struct wsdisplay_accessops sti_accessops = { sti_ioctl, @@ -90,23 +89,31 @@ const struct wsdisplay_accessops sti_accessops = { sti_alloc_screen, sti_free_screen, sti_show_screen, - sti_load_font + NULL /* load_font */ }; enum sti_bmove_funcs { bmf_clear, bmf_copy, bmf_invert, bmf_underline }; -int sti_init(struct sti_screen *scr, int mode); -int sti_inqcfg(struct sti_screen *scr, struct sti_inqconfout *out); -void sti_bmove(struct sti_screen *scr, int, int, int, int, int, int, - enum sti_bmove_funcs); -int sti_setcment(struct sti_screen *scr, u_int i, u_char r, u_char g, u_char b); -int sti_fetchfonts(struct sti_screen *scr, struct sti_inqconfout *cfg, - u_int32_t baseaddr, u_int fontindex); -int sti_screen_setup(struct sti_screen *scr, bus_space_tag_t iot, - bus_space_tag_t memt, bus_space_handle_t romh, bus_addr_t *bases, - u_int codebase); +void sti_bmove(struct sti_screen *, int, int, int, int, int, int, + enum sti_bmove_funcs); +int sti_init(struct sti_screen *, int); +#define STI_TEXTMODE 0x01 +#define STI_CLEARSCR 0x02 +int sti_inqcfg(struct sti_screen *, struct sti_inqconfout *); +int sti_setcment(struct sti_screen *, u_int, u_char, u_char, u_char); + +struct sti_screen * + sti_attach_screen(struct sti_softc *, int); +void sti_describe_screen(struct sti_softc *, struct sti_screen *); +void sti_end_attach_screen(struct sti_softc *, struct sti_screen *, int); +int sti_fetchfonts(struct sti_screen *, struct sti_inqconfout *, u_int32_t, + u_int); +void sti_region_setup(struct sti_screen *); +int sti_rom_setup(struct sti_rom *, bus_space_tag_t, bus_space_tag_t, + bus_space_handle_t, bus_addr_t *, u_int); +int sti_screen_setup(struct sti_screen *, int); #if NSTI_PCI > 0 #define STI_ENABLE_ROM(sc) \ @@ -124,92 +131,119 @@ do { \ #define STI_DISABLE_ROM(sc) do { /* nothing */ } while (0) #endif +/* Macros to read larger than 8 bit values from byte roms */ +#define parseshort(o) \ + ((bus_space_read_1(memt, romh, (o) + 3) << 8) | \ + (bus_space_read_1(memt, romh, (o) + 7))) +#define parseword(o) \ + ((bus_space_read_1(memt, romh, (o) + 3) << 24) | \ + (bus_space_read_1(memt, romh, (o) + 7) << 16) | \ + (bus_space_read_1(memt, romh, (o) + 11) << 8) | \ + (bus_space_read_1(memt, romh, (o) + 15))) + int -sti_attach_common(sc, codebase) - struct sti_softc *sc; - u_int codebase; +sti_attach_common(struct sti_softc *sc, bus_space_tag_t iot, + bus_space_tag_t memt, bus_space_handle_t romh, u_int codebase) +{ + struct sti_rom *rom; + int rc; + + rom = (struct sti_rom *)malloc(sizeof(*rom), M_DEVBUF, + M_NOWAIT | M_ZERO); + if (rom == NULL) { + printf("cannot allocate rom data\n"); + return (ENOMEM); + } + + rom->rom_softc = sc; + rc = sti_rom_setup(rom, iot, memt, romh, sc->bases, codebase); + if (rc != 0) { + free(rom, M_DEVBUF); + return (rc); + } + + sc->sc_rom = rom; + + sti_describe(sc); + + sc->sc_scr = sti_attach_screen(sc, + sc->sc_flags & STI_CONSOLE ? 0 : STI_CLEARSCR); + if (sc->sc_scr == NULL) + rc = ENOMEM; + + return (rc); +} + +struct sti_screen * +sti_attach_screen(struct sti_softc *sc, int flags) { struct sti_screen *scr; int rc; - scr = malloc(sizeof(*scr), M_DEVBUF, M_NOWAIT | M_ZERO); + scr = (struct sti_screen *)malloc(sizeof(*scr), M_DEVBUF, + M_NOWAIT | M_ZERO); if (scr == NULL) { printf("cannot allocate screen data\n"); - return (ENOMEM); + return (NULL); } - sc->sc_scr = scr; - scr->scr_main = sc; - - if ((rc = sti_screen_setup(scr, sc->iot, sc->memt, sc->romh, sc->bases, - codebase)) != 0) { + scr->scr_rom = sc->sc_rom; + rc = sti_screen_setup(scr, flags); + if (rc != 0) { free(scr, M_DEVBUF); - sc->sc_scr = NULL; - return (rc); + return (NULL); } - sti_describe(sc); - return (0); + sti_describe_screen(sc, scr); + + return (scr); } int -sti_screen_setup(struct sti_screen *scr, bus_space_tag_t iot, - bus_space_tag_t memt, bus_space_handle_t romh, bus_addr_t *bases, - u_int codebase) +sti_rom_setup(struct sti_rom *rom, bus_space_tag_t iot, bus_space_tag_t memt, + bus_space_handle_t romh, bus_addr_t *bases, u_int codebase) { - struct sti_inqconfout cfg; - struct sti_einqconfout ecfg; - bus_space_handle_t fbh; struct sti_dd *dd; - struct sti_cfg *cc; int error, size, i; - int geometry_kluge = 0; - u_int fontindex = 0; - STI_ENABLE_ROM(scr->scr_main); + STI_ENABLE_ROM(rom->rom_softc); - scr->iot = iot; - scr->memt = memt; - scr->romh = romh; - scr->bases = bases; - scr->scr_devtype = bus_space_read_1(memt, romh, 3); + rom->iot = iot; + rom->memt = memt; + rom->romh = romh; + rom->bases = bases; - /* { extern int pmapdebug; pmapdebug = 0xfffff; } */ - dd = &scr->scr_dd; - if (scr->scr_devtype == STI_DEVTYPE1) { -#define parseshort(o) \ - ((bus_space_read_1(memt, romh, (o) + 3) << 8) | \ - (bus_space_read_1(memt, romh, (o) + 7))) -#define parseword(o) \ - ((bus_space_read_1(memt, romh, (o) + 3) << 24) | \ - (bus_space_read_1(memt, romh, (o) + 7) << 16) | \ - (bus_space_read_1(memt, romh, (o) + 11) << 8) | \ - (bus_space_read_1(memt, romh, (o) + 15))) + /* + * Get ROM header and code function pointers. + */ - dd->dd_type = bus_space_read_1(memt, romh, 0x03); - dd->dd_nmon = bus_space_read_1(memt, romh, 0x07); - dd->dd_grrev = bus_space_read_1(memt, romh, 0x0b); - dd->dd_lrrev = bus_space_read_1(memt, romh, 0x0f); - dd->dd_grid[0] = parseword(0x10); - dd->dd_grid[1] = parseword(0x20); - dd->dd_fntaddr = parseword(0x30) & ~3; - dd->dd_maxst = parseword(0x40); - dd->dd_romend = parseword(0x50) & ~3; - dd->dd_reglst = parseword(0x60) & ~3; - dd->dd_maxreent= parseshort(0x70); - dd->dd_maxtimo = parseshort(0x78); - dd->dd_montbl = parseword(0x80) & ~3; - dd->dd_udaddr = parseword(0x90) & ~3; - dd->dd_stimemreq=parseword(0xa0); - dd->dd_udsize = parseword(0xb0); - dd->dd_pwruse = parseshort(0xc0); - dd->dd_bussup = bus_space_read_1(memt, romh, 0xcb); - dd->dd_ebussup = bus_space_read_1(memt, romh, 0xcf); - dd->dd_altcodet= bus_space_read_1(memt, romh, 0xd3); - dd->dd_eddst[0]= bus_space_read_1(memt, romh, 0xd7); - dd->dd_eddst[1]= bus_space_read_1(memt, romh, 0xdb); - dd->dd_eddst[2]= bus_space_read_1(memt, romh, 0xdf); - dd->dd_cfbaddr = parseword(0xe0) & ~3; + dd = &rom->rom_dd; + rom->rom_devtype = bus_space_read_1(memt, romh, 3); + if (rom->rom_devtype == STI_DEVTYPE1) { + dd->dd_type = bus_space_read_1(memt, romh, 0x03); + dd->dd_nmon = bus_space_read_1(memt, romh, 0x07); + dd->dd_grrev = bus_space_read_1(memt, romh, 0x0b); + dd->dd_lrrev = bus_space_read_1(memt, romh, 0x0f); + dd->dd_grid[0] = parseword(0x10); + dd->dd_grid[1] = parseword(0x20); + dd->dd_fntaddr = parseword(0x30) & ~3; + dd->dd_maxst = parseword(0x40); + dd->dd_romend = parseword(0x50) & ~3; + dd->dd_reglst = parseword(0x60) & ~3; + dd->dd_maxreent = parseshort(0x70); + dd->dd_maxtimo = parseshort(0x78); + dd->dd_montbl = parseword(0x80) & ~3; + dd->dd_udaddr = parseword(0x90) & ~3; + dd->dd_stimemreq = parseword(0xa0); + dd->dd_udsize = parseword(0xb0); + dd->dd_pwruse = parseshort(0xc0); + dd->dd_bussup = bus_space_read_1(memt, romh, 0xcb); + dd->dd_ebussup = bus_space_read_1(memt, romh, 0xcf); + dd->dd_altcodet = bus_space_read_1(memt, romh, 0xd3); + dd->dd_eddst[0] = bus_space_read_1(memt, romh, 0xd7); + dd->dd_eddst[1] = bus_space_read_1(memt, romh, 0xdb); + dd->dd_eddst[2] = bus_space_read_1(memt, romh, 0xdf); + dd->dd_cfbaddr = parseword(0xe0) & ~3; codebase <<= 2; dd->dd_pacode[0x0] = parseword(codebase + 0x000) & ~3; @@ -236,16 +270,16 @@ sti_screen_setup(struct sti_screen *scr, bus_space_tag_t iot, (u_int8_t *)dd->dd_pacode, sizeof(dd->dd_pacode)); } - STI_DISABLE_ROM(scr->scr_main); + STI_DISABLE_ROM(rom->rom_softc); #ifdef STIDEBUG printf("dd:\n" - "devtype=%x, rev=%x;%d, altt=%x, gid=%016llx, font=%x, mss=%x\n" + "devtype=%x, rev=%x;%d, altt=%x, gid=%08x%08x, font=%x, mss=%x\n" "end=%x, regions=%x, msto=%x, timo=%d, mont=%x, user=%x[%x]\n" "memrq=%x, pwr=%d, bus=%x, ebus=%x, cfb=%x\n" "code=", dd->dd_type & 0xff, dd->dd_grrev, dd->dd_lrrev, dd->dd_altcodet, - *(u_int64_t *)dd->dd_grid, dd->dd_fntaddr, dd->dd_maxst, + dd->dd_grid[0], dd->dd_grid[1], dd->dd_fntaddr, dd->dd_maxst, dd->dd_romend, dd->dd_reglst, dd->dd_maxreent, dd->dd_maxtimo, dd->dd_montbl, dd->dd_udaddr, dd->dd_udsize, dd->dd_stimemreq, dd->dd_pwruse, dd->dd_bussup, dd->dd_ebussup, dd->dd_cfbaddr); @@ -257,28 +291,39 @@ sti_screen_setup(struct sti_screen *scr, bus_space_tag_t iot, dd->dd_pacode[0xc], dd->dd_pacode[0xd], dd->dd_pacode[0xe], dd->dd_pacode[0xf]); #endif - /* devise code size, could be less than STI_END entries */ - for (i = STI_END; !dd->dd_pacode[i]; i--); + + /* + * Figure out how much bytes we need for the STI code. + * Note there could be fewer than STI_END entries pointer + * entries populated, especially on older devices. + */ + + for (i = STI_END; !dd->dd_pacode[i]; i--) + ; size = dd->dd_pacode[i] - dd->dd_pacode[STI_BEGIN]; - if (scr->scr_devtype == STI_DEVTYPE1) + if (rom->rom_devtype == STI_DEVTYPE1) size = (size + 3) / 4; if (size == 0) { printf(": no code for the requested platform\n"); return (EINVAL); } - if (!(scr->scr_code = uvm_km_alloc(kernel_map, round_page(size)))) { + + if (!(rom->rom_code = uvm_km_alloc(kernel_map, round_page(size)))) { printf(": cannot allocate %u bytes for code\n", size); return (ENOMEM); } #ifdef STIDEBUG - printf("code=0x%x[%x]\n", scr->scr_code, size); + printf("code=0x%x[%x]\n", rom->rom_code, size); #endif - STI_ENABLE_ROM(scr->scr_main); + /* + * Copy code into memory and make it executable. + */ + + STI_ENABLE_ROM(rom->rom_softc); - /* copy code into memory */ - if (scr->scr_devtype == STI_DEVTYPE1) { - u_int8_t *p = (u_int8_t *)scr->scr_code; + if (rom->rom_devtype == STI_DEVTYPE1) { + u_int8_t *p = (u_int8_t *)rom->rom_code; u_int32_t addr, eaddr; for (addr = dd->dd_pacode[STI_BEGIN], eaddr = addr + size * 4; @@ -287,120 +332,191 @@ sti_screen_setup(struct sti_screen *scr, bus_space_tag_t iot, } else /* STI_DEVTYPE4 */ bus_space_read_raw_region_4(memt, romh, - dd->dd_pacode[STI_BEGIN], (u_int8_t *)scr->scr_code, + dd->dd_pacode[STI_BEGIN], (u_int8_t *)rom->rom_code, size); - STI_DISABLE_ROM(scr->scr_main); - -#define O(i) (dd->dd_pacode[(i)]? (scr->scr_code + \ - (dd->dd_pacode[(i)] - dd->dd_pacode[0]) / \ - (scr->scr_devtype == STI_DEVTYPE1? 4 : 1)) : NULL) - - scr->init = (sti_init_t) O(STI_INIT_GRAPH); - scr->mgmt = (sti_mgmt_t) O(STI_STATE_MGMT); - scr->unpmv = (sti_unpmv_t) O(STI_FONT_UNPMV); - scr->blkmv = (sti_blkmv_t) O(STI_BLOCK_MOVE); - scr->test = (sti_test_t) O(STI_SELF_TEST); - scr->exhdl = (sti_exhdl_t) O(STI_EXCEP_HDLR); - scr->inqconf = (sti_inqconf_t)O(STI_INQ_CONF); - scr->scment = (sti_scment_t)O(STI_SCM_ENT); - scr->dmac = (sti_dmac_t) O(STI_DMA_CTRL); - scr->flowc = (sti_flowc_t) O(STI_FLOW_CTRL); - scr->utiming = (sti_utiming_t)O(STI_UTIMING); - scr->pmgr = (sti_pmgr_t) O(STI_PROC_MGR); - scr->util = (sti_util_t) O(STI_UTIL); + STI_DISABLE_ROM(rom->rom_softc); + + if ((error = uvm_map_protect(kernel_map, rom->rom_code, + rom->rom_code + round_page(size), UVM_PROT_RX, FALSE))) { + printf(": uvm_map_protect failed (%d)\n", error); + uvm_km_free(kernel_map, rom->rom_code, round_page(size)); + return (error); + } + + /* + * Setup code function pointers. + */ + +#define O(i) \ + (dd->dd_pacode[(i)] == 0 ? NULL : \ + (rom->rom_code + (dd->dd_pacode[(i)] - dd->dd_pacode[0]) / \ + (rom->rom_devtype == STI_DEVTYPE1? 4 : 1))) + + rom->init = (sti_init_t) O(STI_INIT_GRAPH); + rom->mgmt = (sti_mgmt_t) O(STI_STATE_MGMT); + rom->unpmv = (sti_unpmv_t) O(STI_FONT_UNPMV); + rom->blkmv = (sti_blkmv_t) O(STI_BLOCK_MOVE); + rom->test = (sti_test_t) O(STI_SELF_TEST); + rom->exhdl = (sti_exhdl_t) O(STI_EXCEP_HDLR); + rom->inqconf = (sti_inqconf_t)O(STI_INQ_CONF); + rom->scment = (sti_scment_t)O(STI_SCM_ENT); + rom->dmac = (sti_dmac_t) O(STI_DMA_CTRL); + rom->flowc = (sti_flowc_t) O(STI_FLOW_CTRL); + rom->utiming = (sti_utiming_t)O(STI_UTIMING); + rom->pmgr = (sti_pmgr_t) O(STI_PROC_MGR); + rom->util = (sti_util_t) O(STI_UTIL); + +#undef O /* * Set colormap entry is not implemented until 8.04, so force * a NULL pointer here. */ if (dd->dd_grrev < STI_REVISION(8,4)) { - scr->scment = NULL; + rom->scment = NULL; } - if ((error = uvm_map_protect(kernel_map, scr->scr_code, - scr->scr_code + round_page(size), UVM_PROT_RX, FALSE))) { - printf(": uvm_map_protect failed (%d)\n", error); - uvm_km_free(kernel_map, scr->scr_code, round_page(size)); - return (error); - } + return (0); +} - cc = &scr->scr_cfg; - bzero(cc, sizeof (*cc)); - cc->ext_cfg = &scr->scr_ecfg; - bzero(cc->ext_cfg, sizeof(*cc->ext_cfg)); - if (dd->dd_stimemreq) { - scr->scr_ecfg.addr = - malloc(dd->dd_stimemreq, M_DEVBUF, M_NOWAIT); - if (!scr->scr_ecfg.addr) { - printf("cannot allocate %d bytes for STI\n", - dd->dd_stimemreq); - uvm_km_free(kernel_map, scr->scr_code, - round_page(size)); - return (ENOMEM); - } - } - { - int i = dd->dd_reglst; - u_int32_t *p; - struct sti_region r; +/* + * Map all regions. + */ +void +sti_region_setup(struct sti_screen *scr) +{ + struct sti_rom *rom = scr->scr_rom; + bus_space_tag_t memt = rom->memt; + bus_space_handle_t romh = rom->romh; + bus_addr_t *bases = rom->bases; + struct sti_dd *dd = &rom->rom_dd; + struct sti_cfg *cc = &scr->scr_cfg; + bus_space_handle_t bh; + struct sti_region regions[STI_REGION_MAX], *r; + u_int regno, regcnt; + bus_addr_t addr; #ifdef STIDEBUG - printf("stiregions @%p:\n", i); + printf("stiregions @%p:\n", dd->dd_reglst); #endif - STI_ENABLE_ROM(scr->scr_main); + /* + * Read the region information. + */ - r.last = 0; - for (p = cc->regions; !r.last && - p < &cc->regions[STI_REGION_MAX]; p++) { + STI_ENABLE_ROM(rom->rom_softc); - if (scr->scr_devtype == STI_DEVTYPE1) { - *(u_int *)&r = parseword(i); - i += 16; - } else { - bus_space_read_raw_region_4(memt, romh, i, - (u_int8_t *)&r, 4); - i += 4; - } + if (rom->rom_devtype == STI_DEVTYPE1) { + for (regno = 0; regno < STI_REGION_MAX; regno++) + *(u_int *)(regions + regno) = + parseword(dd->dd_reglst + regno * 0x10); + } else { + bus_space_read_raw_region_4(memt, romh, dd->dd_reglst, + (u_int8_t *)regions, sizeof regions); + } + + STI_DISABLE_ROM(rom->rom_softc); + + /* + * Count them. + */ + + for (regcnt = 0, r = regions; regcnt < STI_REGION_MAX; regcnt++, r++) + if (r->last) + break; + regcnt++; + + /* + * Map them. + */ + + for (regno = 0, r = regions; regno < regcnt; regno++, r++) { + if (r->length == 0) + continue; + + /* + * Assume an existing mapping exists. + */ + addr = bases[regno] + (r->offset << PGSHIFT); - *p = bases[p - cc->regions] + (r.offset << PGSHIFT); #ifdef STIDEBUG - STI_DISABLE_ROM(scr->scr_main); - printf("%08x @ 0x%08x%s%s%s%s\n", - r.length << PGSHIFT, *p, r.sys_only? " sys" : "", - r.cache? " cache" : "", r.btlb? " btlb" : "", - r.last? " last" : ""); - STI_ENABLE_ROM(scr->scr_main); + printf("%08x @ 0x%08x%s%s%s%s\n", + r->length << PGSHIFT, addr, r->sys_only ? " sys" : "", + r->cache ? " cache" : "", r->btlb ? " btlb" : "", + r->last ? " last" : ""); #endif - /* skip rom if it has already been mapped */ - if (p == cc->regions && romh == bases[0]) - continue; + /* + * Region #0 is always the rom, and it should have been + * mapped already. + * XXX This expects a 1:1 mapping... + */ + if (regno == 0 && romh == bases[0]) { + cc->regions[0] = addr; + continue; + } - if (bus_space_map(memt, *p, r.length << PGSHIFT, - r.cache ? BUS_SPACE_MAP_CACHEABLE : 0, &fbh)) { + if (bus_space_map(memt, addr, r->length << PGSHIFT, + r->cache ? BUS_SPACE_MAP_CACHEABLE : 0, &bh)) { #ifdef STIDEBUG - STI_DISABLE_ROM(scr->scr_main); - printf("already mapped region\n"); - STI_ENABLE_ROM(scr->scr_main); + printf("already mapped region\n"); #endif - } else { - if (p - cc->regions == 1) { - scr->fbaddr = *p; - scr->fblen = r.length << PGSHIFT; - } - *p = fbh; + } else { + /* XXX should use bus_space_vaddr */ + addr = (bus_addr_t)bh; + if (regno == 1) { + scr->fbaddr = addr; + scr->fblen = r->length << PGSHIFT; } } - STI_DISABLE_ROM(scr->scr_main); + cc->regions[regno] = addr; } +#ifdef STIDEBUG + /* + * Make sure we'll trap accessing unmapped regions + */ + for (regno = 0; regno < STI_REGION_MAX; regno++) + if (cc->regions[regno] == 0) + cc->regions[regno] = 0x81234567; +#endif +} + +int +sti_screen_setup(struct sti_screen *scr, int flags) +{ + struct sti_rom *rom = scr->scr_rom; + bus_space_tag_t memt = rom->memt; + bus_space_handle_t romh = rom->romh; + struct sti_dd *dd = &rom->rom_dd; + struct sti_cfg *cc = &scr->scr_cfg; + struct sti_inqconfout cfg; + struct sti_einqconfout ecfg; + int error, i; + int geometry_kluge = 0; + u_int fontindex = 0; + + bzero(cc, sizeof (*cc)); + cc->ext_cfg = &scr->scr_ecfg; + bzero(cc->ext_cfg, sizeof(*cc->ext_cfg)); + + if (dd->dd_stimemreq) { + scr->scr_ecfg.addr = + malloc(dd->dd_stimemreq, M_DEVBUF, M_NOWAIT); + if (!scr->scr_ecfg.addr) { + printf("cannot allocate %d bytes for STI\n", + dd->dd_stimemreq); + return (ENOMEM); + } + } + + sti_region_setup(scr); + if ((error = sti_init(scr, 0))) { printf(": can not initialize (%d)\n", error); - /* XXX free resources */ - return (ENXIO); + goto fail; } bzero(&cfg, sizeof(cfg)); @@ -408,8 +524,7 @@ sti_screen_setup(struct sti_screen *scr, bus_space_tag_t iot, cfg.ext = &ecfg; if ((error = sti_inqcfg(scr, &cfg))) { printf(": error %d inquiring config\n", error); - /* XXX free resources */ - return (ENXIO); + goto fail; } /* @@ -429,7 +544,7 @@ sti_screen_setup(struct sti_screen *scr, bus_space_tag_t iot, } /* - * Save a few fields for sti_describe() later + * Save a few fields for sti_describe_screen() later */ scr->fbheight = cfg.fbheight; scr->fbwidth = cfg.fbwidth; @@ -437,12 +552,10 @@ sti_screen_setup(struct sti_screen *scr, bus_space_tag_t iot, scr->owidth = cfg.owidth; bcopy(cfg.name, scr->name, sizeof(scr->name)); - if ((error = sti_init(scr, STI_TEXTMODE))) { + if ((error = sti_init(scr, STI_TEXTMODE | flags))) { printf(": can not initialize (%d)\n", error); - /* XXX free resources */ - return (ENXIO); + goto fail; } - #ifdef STIDEBUG printf("conf: bpp=%d planes=%d attr=%b\n" "crt=0x%x:0x%x:0x%x hw=0x%x:0x%x:0x%x\n", cfg.bpp, @@ -459,13 +572,13 @@ sti_screen_setup(struct sti_screen *scr, bus_space_tag_t iot, * resolution, pick its font index. */ if (dd->dd_montbl != 0) { - STI_ENABLE_ROM(scr->scr_main); + STI_ENABLE_ROM(rom->rom_softc); for (i = 0; i < dd->dd_nmon; i++) { u_int offs = dd->dd_montbl + 8 * i; u_int32_t m[2]; sti_mon_t mon = (void *)m; - if (scr->scr_devtype == STI_DEVTYPE1) { + if (rom->rom_devtype == STI_DEVTYPE1) { m[0] = parseword(4 * offs); m[1] = parseword(4 * (offs + 4)); } else { @@ -476,22 +589,20 @@ sti_screen_setup(struct sti_screen *scr, bus_space_tag_t iot, if (mon->width == scr->scr_cfg.scr_width && mon->height == scr->scr_cfg.scr_height) { fontindex = mon->font; -#ifdef STIDEBUG - STI_DISABLE_ROM(scr->scr_main); - printf("font index: %d\n", fontindex); - STI_ENABLE_ROM(scr->scr_main); -#endif break; } } - STI_DISABLE_ROM(scr->scr_main); + STI_DISABLE_ROM(rom->rom_softc); + +#ifdef STIDEBUG + printf("font index: %d\n", fontindex); +#endif } if ((error = sti_fetchfonts(scr, &cfg, dd->dd_fntaddr, fontindex))) { printf(": cannot fetch fonts (%d)\n", error); - /* XXX free resources */ - return (ENXIO); + goto fail; } /* @@ -514,26 +625,26 @@ sti_screen_setup(struct sti_screen *scr, bus_space_tag_t iot, scr->scr_screenlist.screens = (const struct wsscreen_descr **)scr->scr_scrlist; - /* { extern int pmapdebug; pmapdebug = 0; } */ - return (0); + +fail: + /* XXX free resources */ + if (scr->scr_ecfg.addr != NULL) { + free(scr->scr_ecfg.addr, M_DEVBUF); + scr->scr_ecfg.addr = NULL; + } + + return (ENXIO); } void -sti_describe(struct sti_softc *sc) +sti_describe_screen(struct sti_softc *sc, struct sti_screen *scr) { - struct sti_screen *scr = sc->sc_scr; - struct sti_dd *dd = &scr->scr_dd; struct sti_font *fp = &scr->scr_curfont; - printf(": %s rev %d.%02d;%d, ID 0x%016llX\n", - scr->name, dd->dd_grrev >> 4, dd->dd_grrev & 0xf, - dd->dd_lrrev, *(u_int64_t *)dd->dd_grid); - - printf("%s: %dx%d frame buffer, %dx%dx%d display, offset %dx%d\n", - sc->sc_dev.dv_xname, scr->fbwidth, scr->fbheight, - scr->scr_cfg.scr_width, scr->scr_cfg.scr_height, scr->scr_bpp, - scr->owidth, scr->oheight); + printf("%s: %s, %dx%d frame buffer, %dx%dx%d display\n", + sc->sc_dev.dv_xname, scr->name, scr->fbwidth, scr->fbheight, + scr->scr_cfg.scr_width, scr->scr_cfg.scr_height, scr->scr_bpp); printf("%s: %dx%d font type %d, %d bpc, charset %d-%d\n", sc->sc_dev.dv_xname, fp->width, fp->height, @@ -541,26 +652,54 @@ sti_describe(struct sti_softc *sc) } void +sti_describe(struct sti_softc *sc) +{ + struct sti_rom *rom = sc->sc_rom; + struct sti_dd *dd = &rom->rom_dd; + + printf(": rev %d.%02d;%d, ID 0x%08X%08X\n", + dd->dd_grrev >> 4, dd->dd_grrev & 0xf, + dd->dd_lrrev, dd->dd_grid[0], dd->dd_grid[1]); + + if (sc->sc_scr != NULL) + sti_describe_screen(sc, sc->sc_scr); +} + +/* + * Final part of attachment. On hppa where we use the PDC console + * during autoconf, this has to be postponed until autoconf has + * completed. + */ +void sti_end_attach(void *v) { - struct sti_softc *sc = v; + struct sti_softc *sc = (struct sti_softc *)v; + + if (sc->sc_scr != NULL) + sti_end_attach_screen(sc, sc->sc_scr, + sc->sc_flags & STI_CONSOLE ? 1 : 0); +} + +void +sti_end_attach_screen(struct sti_softc *sc, struct sti_screen *scr, int console) +{ struct wsemuldisplaydev_attach_args waa; - sc->sc_wsmode = WSDISPLAYIO_MODE_EMUL; + scr->scr_wsmode = WSDISPLAYIO_MODE_EMUL; - waa.console = sc->sc_flags & STI_CONSOLE ? 1 : 0; - waa.scrdata = &sc->sc_scr->scr_screenlist; + waa.console = console; + waa.scrdata = &scr->scr_screenlist; waa.accessops = &sti_accessops; - waa.accesscookie = sc; + waa.accesscookie = scr; waa.defaultscreens = 0; /* attach as console if required */ - if (waa.console && !ISSET(sc->sc_flags, STI_ATTACHED)) { + if (console && !ISSET(sc->sc_flags, STI_ATTACHED)) { long defattr; - sti_alloc_attr(sc, 0, 0, 0, &defattr); - wsdisplay_cnattach(&sc->sc_scr->scr_wsd, sc->sc_scr, - 0, sc->sc_scr->scr_wsd.nrows - 1, defattr); + sti_alloc_attr(scr, 0, 0, 0, &defattr); + wsdisplay_cnattach(&scr->scr_wsd, scr, + 0, scr->scr_wsd.nrows - 1, defattr); sc->sc_flags |= STI_ATTACHED; } @@ -568,21 +707,17 @@ sti_end_attach(void *v) } u_int -sti_rom_size(bus_space_tag_t iot, bus_space_handle_t ioh) +sti_rom_size(bus_space_tag_t memt, bus_space_handle_t romh) { int devtype; u_int romend; - devtype = bus_space_read_1(iot, ioh, 3); + devtype = bus_space_read_1(memt, romh, 3); if (devtype == STI_DEVTYPE4) { - bus_space_read_raw_region_4(iot, ioh, 0x18, + bus_space_read_raw_region_4(memt, romh, 0x18, (u_int8_t *)&romend, 4); } else { - romend = - (bus_space_read_1(iot, ioh, 0x50 + 3) << 24) | - (bus_space_read_1(iot, ioh, 0x50 + 7) << 16) | - (bus_space_read_1(iot, ioh, 0x50 + 11) << 8) | - (bus_space_read_1(iot, ioh, 0x50 + 15)); + romend = parseword(0x50); } return (round_page(romend)); @@ -592,11 +727,12 @@ int sti_fetchfonts(struct sti_screen *scr, struct sti_inqconfout *cfg, u_int32_t baseaddr, u_int fontindex) { + struct sti_rom *rom = scr->scr_rom; + bus_space_tag_t memt = rom->memt; + bus_space_handle_t romh = rom->romh; struct sti_font *fp = &scr->scr_curfont; u_int32_t addr; int size; - bus_space_tag_t memt; - bus_space_handle_t romh; #ifdef notyet int uc; struct { @@ -606,19 +742,16 @@ sti_fetchfonts(struct sti_screen *scr, struct sti_inqconfout *cfg, } a; #endif - memt = scr->memt; - romh = scr->romh; - /* * Get the first PROM font in memory */ - STI_ENABLE_ROM(scr->scr_main); + STI_ENABLE_ROM(rom->rom_softc); rescan: addr = baseaddr; do { - if (scr->scr_devtype == STI_DEVTYPE1) { + if (rom->rom_devtype == STI_DEVTYPE1) { fp->first = parseshort(addr + 0x00); fp->last = parseshort(addr + 0x08); fp->width = bus_space_read_1(memt, romh, @@ -640,17 +773,17 @@ rescan: } #ifdef STIDEBUG - STI_DISABLE_ROM(scr->scr_main); + STI_DISABLE_ROM(rom->rom_softc); printf("font@%p: %d-%d, %dx%d, type %d, next %x\n", addr, fp->first, fp->last, fp->width, fp->height, fp->type, fp->next); - STI_ENABLE_ROM(scr->scr_main); + STI_ENABLE_ROM(rom->rom_softc); #endif if (fontindex == 0) { size = sizeof(struct sti_font) + (fp->last - fp->first + 1) * fp->bpc; - if (scr->scr_devtype == STI_DEVTYPE1) + if (rom->rom_devtype == STI_DEVTYPE1) size *= 4; scr->scr_romfont = malloc(size, M_DEVBUF, M_NOWAIT); if (scr->scr_romfont == NULL) @@ -675,7 +808,7 @@ rescan: goto rescan; } - STI_DISABLE_ROM(scr->scr_main); + STI_DISABLE_ROM(rom->rom_softc); #ifdef notyet /* @@ -718,11 +851,14 @@ rescan: return (0); } +/* + * Wrappers around STI code pointers + */ + int -sti_init(scr, mode) - struct sti_screen *scr; - int mode; +sti_init(struct sti_screen *scr, int mode) { + struct sti_rom *rom = scr->scr_rom; struct { struct sti_initflags flags; struct sti_initin in; @@ -733,15 +869,16 @@ sti_init(scr, mode) bzero(&a, sizeof(a)); a.flags.flags = STI_INITF_WAIT | STI_INITF_CMB | STI_INITF_EBET | - (mode & STI_TEXTMODE? STI_INITF_TEXT | STI_INITF_PBET | - STI_INITF_PBETI | STI_INITF_ICMT : 0); + (mode & STI_TEXTMODE ? STI_INITF_TEXT | STI_INITF_PBET | + STI_INITF_PBETI | STI_INITF_ICMT : 0) | + (mode & STI_CLEARSCR ? STI_INITF_CLEAR : 0); a.in.text_planes = 1; a.in.ext_in = &a.ein; #ifdef STIDEBUG printf("sti_init,%p(%x, %p, %p, %p)\n", - scr->init, a.flags.flags, &a.in, &a.out, &scr->scr_cfg); + rom->init, a.flags.flags, &a.in, &a.out, &scr->scr_cfg); #endif - (*scr->init)(&a.flags, &a.in, &a.out, &scr->scr_cfg); + (*rom->init)(&a.flags, &a.in, &a.out, &scr->scr_cfg); if (a.out.text_planes != a.in.text_planes) return (-1); /* not colliding with sti errno values */ return (a.out.errno); @@ -750,6 +887,7 @@ sti_init(scr, mode) int sti_inqcfg(struct sti_screen *scr, struct sti_inqconfout *out) { + struct sti_rom *rom = scr->scr_rom; struct { struct sti_inqconfflags flags; struct sti_inqconfin in; @@ -758,17 +896,16 @@ sti_inqcfg(struct sti_screen *scr, struct sti_inqconfout *out) bzero(&a, sizeof(a)); a.flags.flags = STI_INQCONFF_WAIT; - (*scr->inqconf)(&a.flags, &a.in, out, &scr->scr_cfg); + (*rom->inqconf)(&a.flags, &a.in, out, &scr->scr_cfg); return out->errno; } void -sti_bmove(scr, x1, y1, x2, y2, h, w, f) - struct sti_screen *scr; - int x1, y1, x2, y2, h, w; - enum sti_bmove_funcs f; +sti_bmove(struct sti_screen *scr, int x1, int y1, int x2, int y2, int h, int w, + enum sti_bmove_funcs f) { + struct sti_rom *rom = scr->scr_rom; struct { struct sti_blkmvflags flags; struct sti_blkmvin in; @@ -801,7 +938,7 @@ sti_bmove(scr, x1, y1, x2, y2, h, w, f) a.in.height = h; a.in.width = w; - (*scr->blkmv)(&a.flags, &a.in, &a.out, &scr->scr_cfg); + (*rom->blkmv)(&a.flags, &a.in, &a.out, &scr->scr_cfg); #ifdef STIDEBUG if (a.out.errno) printf("sti_blkmv returned %d\n", a.out.errno); @@ -811,6 +948,7 @@ sti_bmove(scr, x1, y1, x2, y2, h, w, f) int sti_setcment(struct sti_screen *scr, u_int i, u_char r, u_char g, u_char b) { + struct sti_rom *rom = scr->scr_rom; struct { struct sti_scmentflags flags; struct sti_scmentin in; @@ -823,21 +961,20 @@ sti_setcment(struct sti_screen *scr, u_int i, u_char r, u_char g, u_char b) a.in.entry = i; a.in.value = (r << 16) | (g << 8) | b; - (*scr->scment)(&a.flags, &a.in, &a.out, &scr->scr_cfg); + (*rom->scment)(&a.flags, &a.in, &a.out, &scr->scr_cfg); return a.out.errno; } +/* + * wsdisplay accessops + */ + int -sti_ioctl(v, cmd, data, flag, p) - void *v; - u_long cmd; - caddr_t data; - int flag; - struct proc *p; +sti_ioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p) { - struct sti_softc *sc = v; - struct sti_screen *scr = sc->sc_scr; + struct sti_screen *scr = (struct sti_screen *)v; + struct sti_rom *rom = scr->scr_rom; struct wsdisplay_fbinfo *wdf; struct wsdisplay_cmap *cmapp; u_int mode, idx, count; @@ -847,13 +984,13 @@ sti_ioctl(v, cmd, data, flag, p) switch (cmd) { case WSDISPLAYIO_SMODE: mode = *(u_int *)data; - if (sc->sc_wsmode == WSDISPLAYIO_MODE_EMUL && + if (scr->scr_wsmode == WSDISPLAYIO_MODE_EMUL && mode == WSDISPLAYIO_MODE_DUMBFB) ret = sti_init(scr, 0); - else if (sc->sc_wsmode == WSDISPLAYIO_MODE_DUMBFB && + else if (scr->scr_wsmode == WSDISPLAYIO_MODE_DUMBFB && mode == WSDISPLAYIO_MODE_EMUL) ret = sti_init(scr, STI_TEXTMODE); - sc->sc_wsmode = mode; + scr->scr_wsmode = mode; break; case WSDISPLAYIO_GTYPE: @@ -865,7 +1002,7 @@ sti_ioctl(v, cmd, data, flag, p) wdf->height = scr->scr_cfg.scr_height; wdf->width = scr->scr_cfg.scr_width; wdf->depth = scr->scr_bpp; - if (scr->scment == NULL) + if (rom->scment == NULL) wdf->cmsize = 0; else wdf->cmsize = STI_NCMAP; @@ -876,7 +1013,7 @@ sti_ioctl(v, cmd, data, flag, p) break; case WSDISPLAYIO_GETCMAP: - if (scr->scment == NULL) + if (rom->scment == NULL) return ENODEV; cmapp = (struct wsdisplay_cmap *)data; idx = cmapp->index; @@ -892,7 +1029,7 @@ sti_ioctl(v, cmd, data, flag, p) break; case WSDISPLAYIO_PUTCMAP: - if (scr->scment == NULL) + if (rom->scment == NULL) return ENODEV; cmapp = (struct wsdisplay_cmap *)data; idx = cmapp->index; @@ -924,11 +1061,6 @@ sti_ioctl(v, cmd, data, flag, p) case WSDISPLAYIO_GVIDEO: break; - case WSDISPLAYIO_GCURPOS: - case WSDISPLAYIO_SCURPOS: - case WSDISPLAYIO_GCURMAX: - case WSDISPLAYIO_GCURSOR: - case WSDISPLAYIO_SCURSOR: default: return (-1); /* not supported yet */ } @@ -937,72 +1069,60 @@ sti_ioctl(v, cmd, data, flag, p) } paddr_t -sti_mmap(v, offset, prot) - void *v; - off_t offset; - int prot; +sti_mmap(void *v, off_t offset, int prot) { +#if 0 + struct sti_screen *scr = (struct sti_screen *)v; +#endif + /* XXX not finished */ return -1; } int -sti_alloc_screen(v, type, cookiep, cxp, cyp, defattr) - void *v; - const struct wsscreen_descr *type; - void **cookiep; - int *cxp, *cyp; - long *defattr; +sti_alloc_screen(void *v, const struct wsscreen_descr *type, void **cookiep, + int *cxp, int *cyp, long *defattr) { - struct sti_softc *sc = v; + struct sti_screen *scr = (struct sti_screen *)v; - if (sc->sc_nscreens > 0) + if (scr->scr_nscreens > 0) return ENOMEM; - *cookiep = sc->sc_scr; + *cookiep = scr; *cxp = 0; *cyp = 0; - sti_alloc_attr(sc, 0, 0, 0, defattr); - sc->sc_nscreens++; + sti_alloc_attr(scr, 0, 0, 0, defattr); + scr->scr_nscreens++; return 0; } void -sti_free_screen(v, cookie) - void *v; - void *cookie; +sti_free_screen(void *v, void *cookie) { - struct sti_softc *sc = v; + struct sti_screen *scr = (struct sti_screen *)v; - sc->sc_nscreens--; + scr->scr_nscreens--; } int -sti_show_screen(v, cookie, waitok, cb, cbarg) - void *v; - void *cookie; - int waitok; - void (*cb)(void *, int, int); - void *cbarg; +sti_show_screen(void *v, void *cookie, int waitok, + void (*cb)(void *, int, int), void *cbarg) { +#if 0 + struct sti_screen *scr = (struct sti_screen *)v; +#endif + return 0; } -int -sti_load_font(v, cookie, font) - void *v; - void *cookie; - struct wsdisplay_font *font; -{ - return -1; -} +/* + * wsdisplay emulops + */ void -sti_cursor(v, on, row, col) - void *v; - int on, row, col; +sti_cursor(void *v, int on, int row, int col) { - struct sti_screen *scr = v; + struct sti_screen *scr = (struct sti_screen *)v; struct sti_font *fp = &scr->scr_curfont; sti_bmove(scr, @@ -1036,12 +1156,9 @@ sti_unitoroman[0x100 - 0xa0] = { }; int -sti_mapchar(v, uni, index) - void *v; - int uni; - u_int *index; +sti_mapchar(void *v, int uni, u_int *index) { - struct sti_screen *scr = v; + struct sti_screen *scr = (struct sti_screen *)v; struct sti_font *fp = &scr->scr_curfont; int c; @@ -1071,13 +1188,10 @@ sti_mapchar(v, uni, index) } void -sti_putchar(v, row, col, uc, attr) - void *v; - int row, col; - u_int uc; - long attr; +sti_putchar(void *v, int row, int col, u_int uc, long attr) { - struct sti_screen *scr = v; + struct sti_screen *scr = (struct sti_screen *)v; + struct sti_rom *rom = scr->scr_rom; struct sti_font *fp = &scr->scr_curfont; if (scr->scr_romfont != NULL) { @@ -1101,7 +1215,7 @@ sti_putchar(v, row, col, uc, attr) a.in.font_addr = scr->scr_romfont; a.in.index = uc; - (*scr->unpmv)(&a.flags, &a.in, &a.out, &scr->scr_cfg); + (*rom->unpmv)(&a.flags, &a.in, &a.out, &scr->scr_cfg); } else { /* * Font is in frame buffer, use blkmv @@ -1128,16 +1242,14 @@ sti_putchar(v, row, col, uc, attr) a.in.height = fp->height; a.in.width = fp->width; - (*scr->blkmv)(&a.flags, &a.in, &a.out, &scr->scr_cfg); + (*rom->blkmv)(&a.flags, &a.in, &a.out, &scr->scr_cfg); } } void -sti_copycols(v, row, srccol, dstcol, ncols) - void *v; - int row, srccol, dstcol, ncols; +sti_copycols(void *v, int row, int srccol, int dstcol, int ncols) { - struct sti_screen *scr = v; + struct sti_screen *scr = (struct sti_screen *)v; struct sti_font *fp = &scr->scr_curfont; sti_bmove(scr, @@ -1147,12 +1259,9 @@ sti_copycols(v, row, srccol, dstcol, ncols) } void -sti_erasecols(v, row, startcol, ncols, attr) - void *v; - int row, startcol, ncols; - long attr; +sti_erasecols(void *v, int row, int startcol, int ncols, long attr) { - struct sti_screen *scr = v; + struct sti_screen *scr = (struct sti_screen *)v; struct sti_font *fp = &scr->scr_curfont; sti_bmove(scr, @@ -1162,11 +1271,9 @@ sti_erasecols(v, row, startcol, ncols, attr) } void -sti_copyrows(v, srcrow, dstrow, nrows) - void *v; - int srcrow, dstrow, nrows; +sti_copyrows(void *v, int srcrow, int dstrow, int nrows) { - struct sti_screen *scr = v; + struct sti_screen *scr = (struct sti_screen *)v; struct sti_font *fp = &scr->scr_curfont; sti_bmove(scr, 0, srcrow * fp->height, 0, dstrow * fp->height, @@ -1174,12 +1281,9 @@ sti_copyrows(v, srcrow, dstrow, nrows) } void -sti_eraserows(v, srcrow, nrows, attr) - void *v; - int srcrow, nrows; - long attr; +sti_eraserows(void *v, int srcrow, int nrows, long attr) { - struct sti_screen *scr = v; + struct sti_screen *scr = (struct sti_screen *)v; struct sti_font *fp = &scr->scr_curfont; sti_bmove(scr, 0, srcrow * fp->height, 0, srcrow * fp->height, @@ -1187,21 +1291,23 @@ sti_eraserows(v, srcrow, nrows, attr) } int -sti_alloc_attr(v, fg, bg, flags, pattr) - void *v; - int fg, bg, flags; - long *pattr; +sti_alloc_attr(void *v, int fg, int bg, int flags, long *pattr) { - /* struct sti_screen *scr = v; */ +#if 0 + struct sti_screen *scr = (struct sti_screen *)v; +#endif *pattr = 0; - return 0; } void sti_unpack_attr(void *v, long attr, int *fg, int *bg, int *ul) { +#if 0 + struct sti_screen *scr = (struct sti_screen *)v; +#endif + *fg = WSCOL_WHITE; *bg = WSCOL_BLACK; if (ul != NULL) @@ -1211,40 +1317,37 @@ sti_unpack_attr(void *v, long attr, int *fg, int *bg, int *ul) #if NSTI_SGC > 0 /* - * Early console support + * Early console support. + * Only used on hp300 with unique sti@sgc attachment. */ -void -sti_clear(struct sti_screen *scr) -{ - sti_bmove(scr, 0, 0, 0, 0, - scr->scr_cfg.scr_height, scr->scr_cfg.scr_width, bmf_clear); -} - int -sti_cnattach(struct sti_screen *scr, bus_space_tag_t iot, bus_addr_t *bases, - u_int codebase) +sti_cnattach(struct sti_rom *rom, struct sti_screen *scr, bus_space_tag_t memt, + bus_addr_t *bases, u_int codebase) { - bus_space_handle_t ioh; + bus_space_handle_t romh; u_int romend; int error; long defattr; - if ((error = bus_space_map(iot, bases[0], PAGE_SIZE, 0, &ioh)) != 0) + if ((error = bus_space_map(memt, bases[0], PAGE_SIZE, 0, &romh)) != 0) return (error); /* * Compute real PROM size */ - romend = sti_rom_size(iot, ioh); + romend = sti_rom_size(memt, romh); - bus_space_unmap(iot, ioh, PAGE_SIZE); + bus_space_unmap(memt, romh, PAGE_SIZE); - if ((error = bus_space_map(iot, bases[0], romend, 0, &ioh)) != 0) + if ((error = bus_space_map(memt, bases[0], romend, 0, &romh)) != 0) return (error); - bases[0] = ioh; - if (sti_screen_setup(scr, iot, iot, ioh, bases, codebase) != 0) + bases[0] = romh; + if (sti_rom_setup(rom, memt, memt, romh, bases, codebase) != 0) + panic(__func__); + scr->scr_rom = rom; + if (sti_screen_setup(scr, STI_CLEARSCR) != 0) panic(__func__); sti_alloc_attr(scr, 0, 0, 0, &defattr); diff --git a/sys/dev/ic/stivar.h b/sys/dev/ic/stivar.h index b45cbfb0d58..c7a6e200b06 100644 --- a/sys/dev/ic/stivar.h +++ b/sys/dev/ic/stivar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: stivar.h,v 1.23 2007/01/12 22:02:33 miod Exp $ */ +/* $OpenBSD: stivar.h,v 1.24 2009/02/06 22:51:04 miod Exp $ */ /* * Copyright (c) 2000-2003 Michael Shalayeff @@ -31,82 +31,100 @@ struct sti_softc; +/* + * STI ROM information - one per device + */ +struct sti_rom { + struct sti_softc *rom_softc; /* backpointer to device */ + int rom_devtype; + + bus_space_tag_t iot, memt; /* XXX iot unused */ + bus_space_handle_t romh; + bus_addr_t *bases; + + struct sti_dd rom_dd; /* in word format */ + + vaddr_t rom_code; + sti_init_t init; + sti_mgmt_t mgmt; + sti_unpmv_t unpmv; + sti_blkmv_t blkmv; + sti_test_t test; + sti_exhdl_t exhdl; + sti_inqconf_t inqconf; + sti_scment_t scment; + sti_dmac_t dmac; + sti_flowc_t flowc; + sti_utiming_t utiming; + sti_pmgr_t pmgr; + sti_util_t util; +}; + +/* + * STI screen information - one per head + */ struct sti_screen { - struct sti_softc *scr_main; /* may be NULL if early console */ - int scr_devtype; - - bus_space_tag_t iot, memt; - bus_space_handle_t romh; - bus_addr_t *bases; - bus_addr_t fbaddr; - bus_size_t fblen; - - int scr_bpp; - - struct sti_dd scr_dd; /* in word format */ - struct sti_font scr_curfont; - struct sti_cfg scr_cfg; - struct sti_ecfg scr_ecfg; - - void *scr_romfont; /* ROM font copy, either in memory... */ - u_int scr_fontmaxcol; /* ...or in off-screen frame buffer */ - u_int scr_fontbase; - - u_int8_t scr_rcmap[STI_NCMAP], - scr_gcmap[STI_NCMAP], - scr_bcmap[STI_NCMAP]; - - vaddr_t scr_code; - sti_init_t init; - sti_mgmt_t mgmt; - sti_unpmv_t unpmv; - sti_blkmv_t blkmv; - sti_test_t test; - sti_exhdl_t exhdl; - sti_inqconf_t inqconf; - sti_scment_t scment; - sti_dmac_t dmac; - sti_flowc_t flowc; - sti_utiming_t utiming; - sti_pmgr_t pmgr; - sti_util_t util; - - u_int16_t fbheight, fbwidth, oheight, owidth; - u_int8_t name[STI_DEVNAME_LEN]; + struct sti_rom *scr_rom; + +#ifdef notyet + u_int scr_flags; +#endif + + int scr_bpp; + + struct sti_font scr_curfont; + struct sti_cfg scr_cfg; + struct sti_ecfg scr_ecfg; + u_int8_t name[STI_DEVNAME_LEN]; + + void *scr_romfont; /* ROM font copy in memory... */ + u_int scr_fontmaxcol;/* ...or in off-screen area */ + u_int scr_fontbase; + + u_int8_t scr_rcmap[STI_NCMAP], + scr_gcmap[STI_NCMAP], + scr_bcmap[STI_NCMAP]; + + u_int16_t fbheight, fbwidth; + u_int16_t oheight, owidth; /* offscreen size */ + bus_addr_t fbaddr; + bus_size_t fblen; /* wsdisplay information */ - struct wsscreen_descr scr_wsd; + int scr_nscreens; + u_int scr_wsmode; + struct wsscreen_descr scr_wsd; struct wsscreen_descr *scr_scrlist[1]; - struct wsscreen_list scr_screenlist; + struct wsscreen_list scr_screenlist; }; +/* + * STI device state + */ struct sti_softc { - struct device sc_dev; - void *sc_ih; - - u_int sc_flags; -#define STI_TEXTMODE 0x0001 -#define STI_CLEARSCR 0x0002 -#define STI_CONSOLE 0x0004 -#define STI_ATTACHED 0x0008 -#define STI_ROM_ENABLED 0x0010 - int sc_nscreens; + struct device sc_dev; +#ifdef notyet + void *sc_ih; +#endif - bus_space_tag_t iot, memt; - bus_space_handle_t romh; - bus_addr_t bases[STI_REGION_MAX]; + u_int sc_flags; +#define STI_CONSOLE 0x0001 /* first head is console... */ +#define STI_ATTACHED 0x0002 /* ... and wsdisplay_cnattach() has been done */ +#define STI_ROM_ENABLED 0x0004 /* PCI ROM is enabled */ - struct sti_screen *sc_scr; - u_int sc_wsmode; + bus_addr_t bases[STI_REGION_MAX]; + struct sti_rom *sc_rom; + struct sti_screen *sc_scr; /* optional, required for PCI */ - void (*sc_enable_rom)(struct sti_softc *); - void (*sc_disable_rom)(struct sti_softc *); + void (*sc_enable_rom)(struct sti_softc *); + void (*sc_disable_rom)(struct sti_softc *); }; -int sti_attach_common(struct sti_softc *sc, u_int codebase); -void sti_clear(struct sti_screen *); -int sti_cnattach(struct sti_screen *, bus_space_tag_t, bus_addr_t *, u_int); +int sti_attach_common(struct sti_softc *, bus_space_tag_t, bus_space_tag_t, + bus_space_handle_t, u_int); +int sti_cnattach(struct sti_rom *, struct sti_screen *, bus_space_tag_t, + bus_addr_t *, u_int); void sti_describe(struct sti_softc *); void sti_end_attach(void *); u_int sti_rom_size(bus_space_tag_t, bus_space_handle_t); diff --git a/sys/dev/pci/sti_pci.c b/sys/dev/pci/sti_pci.c index 894f9f67d37..ce6af45162e 100644 --- a/sys/dev/pci/sti_pci.c +++ b/sys/dev/pci/sti_pci.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sti_pci.c,v 1.6 2007/06/17 12:07:10 miod Exp $ */ +/* $OpenBSD: sti_pci.c,v 1.7 2009/02/06 22:51:04 miod Exp $ */ /* * Copyright (c) 2006, 2007 Miodrag Vallat. @@ -38,6 +38,8 @@ struct sti_pci_softc { pci_chipset_tag_t sc_pc; pcitag_t sc_tag; + + bus_space_handle_t sc_romh; }; struct cfattach sti_pci_ca = { @@ -85,11 +87,11 @@ sti_pci_attach(struct device *parent, struct device *self, void *aux) return; printf("%s", self->dv_xname); - if (sti_attach_common(&spc->sc_base, STI_CODEBASE_MAIN) == 0) { - if (sti_pci_is_console(paa, spc->sc_base.bases) != 0) - spc->sc_base.sc_flags |= STI_CONSOLE; + if (sti_pci_is_console(paa, spc->sc_base.bases) != 0) + spc->sc_base.sc_flags |= STI_CONSOLE; + if (sti_attach_common(&spc->sc_base, paa->pa_iot, paa->pa_memt, + spc->sc_romh, STI_CODEBASE_MAIN) == 0) startuphook_establish(sti_end_attach, spc); - } } /* @@ -278,13 +280,12 @@ sti_check_rom(struct sti_pci_softc *spc, struct pci_attach_args *pa) bus_space_unmap(pa->pa_memt, romh, romsize); rc = bus_space_map(pa->pa_memt, PCI_ROM_ADDR(address) + offs, - stiromsize, 0, &sc->romh); + stiromsize, 0, &spc->sc_romh); if (rc != 0) { printf("%s: can't map STI ROM (%d)\n", sc->sc_dev.dv_xname, rc); goto fail2; } - sc->memt = pa->pa_memt; return (0); |