diff options
author | 2011-04-03 15:46:30 +0000 | |
---|---|---|
committer | 2011-04-03 15:46:30 +0000 | |
commit | 6dd23c8821eecebeb9ca486a17add8f4260e9528 (patch) | |
tree | ef37553633d81ce4ee16e39c64f0440c29c8f6f4 | |
parent | use nitems(); no binary change for drivers that are compiled on amd64. (diff) | |
download | wireguard-openbsd-6dd23c8821eecebeb9ca486a17add8f4260e9528.tar.xz wireguard-openbsd-6dd23c8821eecebeb9ca486a17add8f4260e9528.zip |
Sprinkle spltty around code which plays with either the video memory or
the backing store. The state of a VT is only coherent if both the active
flag and the backing store are in order, which is not the case during VT
switches.
This fixes display glitches occuring during VT switches if one of the
VT involved is doing a lot of tty updates.
Noticed by deraadt@ on a machine too fast for mere mortals.
-rw-r--r-- | sys/dev/ic/pcdisplay_subr.c | 29 | ||||
-rw-r--r-- | sys/dev/ic/vga.c | 27 |
2 files changed, 43 insertions, 13 deletions
diff --git a/sys/dev/ic/pcdisplay_subr.c b/sys/dev/ic/pcdisplay_subr.c index d743fcaac7d..dba0ea9229e 100644 --- a/sys/dev/ic/pcdisplay_subr.c +++ b/sys/dev/ic/pcdisplay_subr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pcdisplay_subr.c,v 1.9 2010/08/28 12:48:14 miod Exp $ */ +/* $OpenBSD: pcdisplay_subr.c,v 1.10 2011/04/03 15:46:30 miod Exp $ */ /* $NetBSD: pcdisplay_subr.c,v 1.16 2000/06/08 07:01:19 cgd Exp $ */ /* @@ -88,6 +88,7 @@ pcdisplay_cursor(void *id, int on, int row, int col) bus_space_tag_t memt = scr->hdl->ph_memt; bus_space_handle_t memh = scr->hdl->ph_memh; int off; + int s = spltty(); /* Remove old cursor image */ if (scr->cursoron) { @@ -103,7 +104,7 @@ pcdisplay_cursor(void *id, int on, int row, int col) scr->vc_ccol = col; if ((scr->cursoron = on) == 0) - return 0; + goto done; off = (scr->vc_crow * scr->type->ncols + scr->vc_ccol); if (scr->active) { @@ -115,10 +116,13 @@ pcdisplay_cursor(void *id, int on, int row, int col) scr->mem[off] = scr->cursortmp ^ 0x7700; } + splx(s); +done: return 0; #else /* PCDISPLAY_SOFTCURSOR */ struct pcdisplayscreen *scr = id; int pos; + int s = spltty(); scr->vc_crow = row; scr->vc_ccol = col; @@ -135,6 +139,7 @@ pcdisplay_cursor(void *id, int on, int row, int col) pcdisplay_6845_write(scr->hdl, cursorl, pos); } + splx(s); return 0; #endif /* PCDISPLAY_SOFTCURSOR */ } @@ -157,14 +162,17 @@ pcdisplay_putchar(void *id, int row, int col, u_int c, long attr) bus_space_tag_t memt = scr->hdl->ph_memt; bus_space_handle_t memh = scr->hdl->ph_memh; int off; + int s; off = row * scr->type->ncols + col; + s = spltty(); if (scr->active) bus_space_write_2(memt, memh, scr->dispoffset + off * 2, c | (attr << 8)); else scr->mem[off] = c | (attr << 8); + splx(s); return 0; } @@ -176,16 +184,19 @@ pcdisplay_getchar(void *id, int row, int col, struct wsdisplay_charcell *cell) bus_space_tag_t memt = scr->hdl->ph_memt; bus_space_handle_t memh = scr->hdl->ph_memh; int off; + int s; u_int16_t data; off = row * scr->type->ncols + col; /* XXX bounds check? */ + s = spltty(); if (scr->active) data = (bus_space_read_2(memt, memh, scr->dispoffset + off * 2)); else data = (scr->mem[off]); + splx(s); cell->uc = data & 0xff; cell->attr = data >> 8; @@ -200,11 +211,13 @@ pcdisplay_copycols(void *id, int row, int srccol, int dstcol, int ncols) bus_space_tag_t memt = scr->hdl->ph_memt; bus_space_handle_t memh = scr->hdl->ph_memh; bus_size_t srcoff, dstoff; + int s; srcoff = dstoff = row * scr->type->ncols; srcoff += srccol; dstoff += dstcol; + s = spltty(); if (scr->active) bus_space_copy_2(memt, memh, scr->dispoffset + srcoff * 2, @@ -212,6 +225,7 @@ pcdisplay_copycols(void *id, int row, int srccol, int dstcol, int ncols) ncols); else bcopy(&scr->mem[srcoff], &scr->mem[dstoff], ncols * 2); + splx(s); return 0; } @@ -225,17 +239,19 @@ pcdisplay_erasecols(void *id, int row, int startcol, int ncols, long fillattr) bus_size_t off; u_int16_t val; int i; + int s; off = row * scr->type->ncols + startcol; - val = (fillattr << 8) | ' '; + s = spltty(); if (scr->active) bus_space_set_region_2(memt, memh, scr->dispoffset + off * 2, val, ncols); else for (i = 0; i < ncols; i++) scr->mem[off + i] = val; + splx(s); return 0; } @@ -248,10 +264,12 @@ pcdisplay_copyrows(void *id, int srcrow, int dstrow, int nrows) bus_space_handle_t memh = scr->hdl->ph_memh; int ncols = scr->type->ncols; bus_size_t srcoff, dstoff; + int s; srcoff = srcrow * ncols + 0; dstoff = dstrow * ncols + 0; + s = spltty(); if (scr->active) bus_space_copy_2(memt, memh, scr->dispoffset + srcoff * 2, @@ -260,6 +278,7 @@ pcdisplay_copyrows(void *id, int srcrow, int dstrow, int nrows) else bcopy(&scr->mem[srcoff], &scr->mem[dstoff], nrows * ncols * 2); + splx(s); return 0; } @@ -272,18 +291,20 @@ pcdisplay_eraserows(void *id, int startrow, int nrows, long fillattr) bus_space_handle_t memh = scr->hdl->ph_memh; bus_size_t off, count, n; u_int16_t val; + int s; off = startrow * scr->type->ncols; count = nrows * scr->type->ncols; - val = (fillattr << 8) | ' '; + s = spltty(); if (scr->active) bus_space_set_region_2(memt, memh, scr->dispoffset + off * 2, val, count); else for (n = 0; n < count; n++) scr->mem[off + n] = val; + splx(s); return 0; } diff --git a/sys/dev/ic/vga.c b/sys/dev/ic/vga.c index b71a16c5fcc..ce40fc657c4 100644 --- a/sys/dev/ic/vga.c +++ b/sys/dev/ic/vga.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vga.c,v 1.54 2010/08/28 12:48:14 miod Exp $ */ +/* $OpenBSD: vga.c,v 1.55 2011/04/03 15:46:30 miod Exp $ */ /* $NetBSD: vga.c,v 1.28.2.1 2000/06/30 16:27:47 simonb Exp $ */ /*- @@ -770,6 +770,7 @@ vga_doswitch(struct vga_config *vc) struct vgascreen *scr, *oldscr; struct vga_handle *vh = &vc->hdl; const struct wsscreen_descr *type; + int s; scr = vc->wantedscreen; if (!scr) { @@ -777,8 +778,12 @@ vga_doswitch(struct vga_config *vc) (*vc->switchcb)(vc->switchcbarg, EIO, 0); return; } + type = scr->pcs.type; oldscr = vc->active; /* can be NULL! */ + if (scr == oldscr) + return; + s = spltty(); #ifdef DIAGNOSTIC if (oldscr) { if (!oldscr->pcs.active) @@ -786,11 +791,6 @@ vga_doswitch(struct vga_config *vc) if (oldscr->pcs.type != vc->currenttype) panic("vga_show_screen: bad type"); } -#endif - if (scr == oldscr) { - return; - } -#ifdef DIAGNOSTIC if (scr->pcs.active) panic("vga_show_screen: active"); #endif @@ -824,6 +824,7 @@ vga_doswitch(struct vga_config *vc) scr->pcs.dispoffset, scr->pcs.mem, type->ncols * type->nrows); scr->pcs.active = 1; + splx(s); vc->active = scr; @@ -1007,10 +1008,12 @@ vga_copyrows(void *id, int srcrow, int dstrow, int nrows) bus_space_handle_t memh = scr->pcs.hdl->ph_memh; int ncols = scr->pcs.type->ncols; bus_size_t srcoff, dstoff; + int s; srcoff = srcrow * ncols + 0; dstoff = dstrow * ncols + 0; + s = spltty(); if (scr->pcs.active) { if (dstrow == 0 && (srcrow + nrows == scr->pcs.type->nrows)) { #ifdef PCDISPLAY_SOFTCURSOR @@ -1053,6 +1056,7 @@ vga_copyrows(void *id, int srcrow, int dstrow, int nrows) } else bcopy(&scr->pcs.mem[srcoff], &scr->pcs.mem[dstoff], nrows * ncols * 2); + splx(s); return 0; } @@ -1251,11 +1255,16 @@ int vga_putchar(void *c, int row, int col, u_int uc, long attr) { struct vgascreen *scr = c; - - if (scr->pcs.visibleoffset != scr->pcs.dispoffset) + int rc; + int s; + + s = spltty(); + if (scr->pcs.active && scr->pcs.visibleoffset != scr->pcs.dispoffset) vga_scrollback(scr->cfg, scr, 0); + rc = pcdisplay_putchar(c, row, col, uc, attr); + splx(s); - return pcdisplay_putchar(c, row, col, uc, attr); + return rc; } void |