diff options
author | Miod Vallat <miod@cvs.openbsd.org> | 2009-01-28 17:37:41 +0000 |
---|---|---|
committer | Miod Vallat <miod@cvs.openbsd.org> | 2009-01-28 17:37:41 +0000 |
commit | 8b9efb273c5ec82bdb0a1aff73776f3f649e7481 (patch) | |
tree | 1a40168eef8abde59c1b23bcd3eb1404caeadfb9 | |
parent | a83fc87b13095d2ab8b05bb05e8bff472c6f91cd (diff) |
If the rom contains a monitor table, look for an entry matching our
display resolution, and if one is found, pick the built-in font it points
to, instead of the first font from the list. If the index is wrong and the
font list is shorter, revert to the previous behaviour of using the first
ROM font.
This fixes the font discrepency on my B132L (INTERNAL_EG_1280) where PDC
would use the 10x20 font, which is third in the list, and OpenBSD would
use the 8x16 font instead.
Tested on byte- and word- roms, gsc and pci cards.
-rw-r--r-- | sys/dev/ic/sti.c | 110 | ||||
-rw-r--r-- | sys/dev/ic/stireg.h | 21 |
2 files changed, 103 insertions, 28 deletions
diff --git a/sys/dev/ic/sti.c b/sys/dev/ic/sti.c index 1dfc7169ef7..aba46b0d775 100644 --- a/sys/dev/ic/sti.c +++ b/sys/dev/ic/sti.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sti.c,v 1.56 2007/10/01 04:03:51 krw Exp $ */ +/* $OpenBSD: sti.c,v 1.57 2009/01/28 17:37:40 miod Exp $ */ /* * Copyright (c) 2000-2003 Michael Shalayeff @@ -103,7 +103,7 @@ 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 addr); + 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); @@ -164,6 +164,7 @@ sti_screen_setup(struct sti_screen *scr, bus_space_tag_t iot, struct sti_cfg *cc; int error, size, i; int geometry_kluge = 0; + u_int fontindex = 0; STI_ENABLE_ROM(scr->scr_main); @@ -256,7 +257,7 @@ 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 - /* divise code size, could be less than STI_END entries */ + /* devise code size, could be less than STI_END entries */ 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) @@ -354,9 +355,10 @@ sti_screen_setup(struct sti_screen *scr, bus_space_tag_t iot, for (p = cc->regions; !r.last && p < &cc->regions[STI_REGION_MAX]; p++) { - if (scr->scr_devtype == STI_DEVTYPE1) - *(u_int *)&r = parseword(i), i+= 16; - else { + 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; @@ -450,7 +452,43 @@ sti_screen_setup(struct sti_screen *scr, bus_space_tag_t iot, #endif scr->scr_bpp = cfg.bppu; - if ((error = sti_fetchfonts(scr, &cfg, dd->dd_fntaddr))) { + /* + * Although scr->scr_ecfg.current_monitor is not filled by + * sti_init() as expected, we can nevertheless walk the monitor + * list, if there is any, and if we find a mode matching our + * resolution, pick its font index. + */ + if (dd->dd_montbl != 0) { + STI_ENABLE_ROM(scr->scr_main); + + 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) { + m[0] = parseword(4 * offs); + m[1] = parseword(4 * (offs + 4)); + } else { + bus_space_read_raw_region_4(memt, romh, offs, + (u_int8_t *)mon, sizeof(*mon)); + } + + 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); + } + + if ((error = sti_fetchfonts(scr, &cfg, dd->dd_fntaddr, fontindex))) { printf(": cannot fetch fonts (%d)\n", error); /* XXX free resources */ return (ENXIO); @@ -552,9 +590,10 @@ sti_rom_size(bus_space_tag_t iot, bus_space_handle_t ioh) int sti_fetchfonts(struct sti_screen *scr, struct sti_inqconfout *cfg, - u_int32_t addr) + u_int32_t baseaddr, u_int fontindex) { struct sti_font *fp = &scr->scr_curfont; + u_int32_t addr; int size; bus_space_tag_t memt; bus_space_handle_t romh; @@ -576,6 +615,8 @@ sti_fetchfonts(struct sti_screen *scr, struct sti_inqconfout *cfg, STI_ENABLE_ROM(scr->scr_main); +rescan: + addr = baseaddr; do { if (scr->scr_devtype == STI_DEVTYPE1) { fp->first = parseshort(addr + 0x00); @@ -588,28 +629,51 @@ sti_fetchfonts(struct sti_screen *scr, struct sti_inqconfout *cfg, addr + 0x1b); fp->bpc = bus_space_read_1(memt, romh, addr + 0x1f); - fp->next = parseword(addr + 0x23); + fp->next = parseword(addr + 0x20); fp->uheight= bus_space_read_1(memt, romh, addr + 0x33); fp->uoffset= bus_space_read_1(memt, romh, addr + 0x37); - } else /* STI_DEVTYPE4 */ + } else { /* STI_DEVTYPE4 */ bus_space_read_raw_region_4(memt, romh, addr, (u_int8_t *)fp, sizeof(struct sti_font)); + } - size = sizeof(struct sti_font) + - (fp->last - fp->first + 1) * fp->bpc; - if (scr->scr_devtype == STI_DEVTYPE1) - size *= 4; - scr->scr_romfont = malloc(size, M_DEVBUF, M_NOWAIT); - if (scr->scr_romfont == NULL) - return (ENOMEM); +#ifdef STIDEBUG + STI_DISABLE_ROM(scr->scr_main); + 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); +#endif - bus_space_read_raw_region_4(memt, romh, addr, - (u_int8_t *)scr->scr_romfont, size); + if (fontindex == 0) { + size = sizeof(struct sti_font) + + (fp->last - fp->first + 1) * fp->bpc; + if (scr->scr_devtype == STI_DEVTYPE1) + size *= 4; + scr->scr_romfont = malloc(size, M_DEVBUF, M_NOWAIT); + if (scr->scr_romfont == NULL) + return (ENOMEM); - addr = NULL; /* fp->next */ - } while (addr); + bus_space_read_raw_region_4(memt, romh, addr, + (u_int8_t *)scr->scr_romfont, size); + + break; + } + + addr = baseaddr + fp->next; + fontindex--; + } while (fp->next != 0); + + /* + * If our font index was bogus, we did not find the expected font. + * In this case, pick the first one and be done with it. + */ + if (addr == 0) { + fontindex = 0; + goto rescan; + } STI_DISABLE_ROM(scr->scr_main); @@ -781,10 +845,6 @@ sti_ioctl(v, cmd, data, flag, p) ret = 0; switch (cmd) { - case WSDISPLAYIO_GMODE: - *(u_int *)data = sc->sc_wsmode; - break; - case WSDISPLAYIO_SMODE: mode = *(u_int *)data; if (sc->sc_wsmode == WSDISPLAYIO_MODE_EMUL && diff --git a/sys/dev/ic/stireg.h b/sys/dev/ic/stireg.h index e9c83b7eced..da06995fb3e 100644 --- a/sys/dev/ic/stireg.h +++ b/sys/dev/ic/stireg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: stireg.h,v 1.12 2008/09/01 17:30:56 deraadt Exp $ */ +/* $OpenBSD: stireg.h,v 1.13 2009/01/28 17:37:40 miod Exp $ */ /* * Copyright (c) 2000 Michael Shalayeff @@ -127,8 +127,7 @@ struct sti_dd { u_int32_t dd_reglst; /* 0x1c device region list */ u_int16_t dd_maxreent; /* 0x20 max reent storage */ u_int16_t dd_maxtimo; /* 0x22 max execution timeout .1 sec */ - u_int32_t dd_montbl; /* 0x24 mon table address, array of - names num of dd_nmon */ + u_int32_t dd_montbl; /* 0x24 monitor table address */ u_int32_t dd_udaddr; /* 0x28 user data address */ u_int32_t dd_stimemreq; /* 0x2c sti memory request */ u_int32_t dd_udsize; /* 0x30 user data size */ @@ -194,6 +193,22 @@ struct sti_fontcfg { u_int8_t uoffset; } __packed; +typedef struct sti_mon { + u_int32_t width: 12; + u_int32_t height: 12; + u_int32_t hz: 7; /* low 7 bits of refresh rate */ + u_int32_t flat: 1; /* flatpanel */ + u_int32_t vesa: 1; /* vesa mode */ + u_int32_t grey: 1; /* greyscale */ + u_int32_t dblbuf: 1; /* double buffered */ + u_int32_t user: 1; /* user-defined mode */ + u_int32_t stereo: 1; /* stereo display */ + u_int32_t sam: 1; /* ? */ + u_int32_t : 15; + u_int32_t hz_upper: 3; /* upper 3 bits of refresh rate */ + u_int32_t font: 8; /* rom font index */ +} __packed *sti_mon_t; + typedef struct sti_ecfg { u_int8_t current_monitor; u_int8_t uf_boot; |