diff options
author | Miod Vallat <miod@cvs.openbsd.org> | 2006-12-02 15:55:19 +0000 |
---|---|---|
committer | Miod Vallat <miod@cvs.openbsd.org> | 2006-12-02 15:55:19 +0000 |
commit | cc6f15397de00ac4c73efcf550971680b9dabfff (patch) | |
tree | 426d787b5e35e7bb7fbdf8c0e66cd6fb7002814d /sys/dev | |
parent | d2c8d56da6a0b1f99fd3b3e9fed1871cf1cfc577 (diff) |
On frame buffers which endianness differs from the host CPU, we can not afford
using ovbcopy() in the erasecols emulop, as the ovbcopy implementation might
do larger-than-byte loads and store, which will not have the expected result
if the source and destination addresses are not similarly aligned.
Instead, roll our own byte-only ovbcopy() in this case. This is made dependent
on a config(8) attribute to avoid bloating platforms which do not need this,
thus frame buffers which may set RI_BSWAP in ri_flg need to depend on this
attribute.
Problem spotted by matthieu@ using tcsh on sparc64 console.
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/rasops/files.rasops | 4 | ||||
-rw-r--r-- | sys/dev/rasops/rasops.c | 71 | ||||
-rw-r--r-- | sys/dev/rasops/rasops8.c | 4 |
3 files changed, 67 insertions, 12 deletions
diff --git a/sys/dev/rasops/files.rasops b/sys/dev/rasops/files.rasops index 53136074b5a..7bd131d8c3d 100644 --- a/sys/dev/rasops/files.rasops +++ b/sys/dev/rasops/files.rasops @@ -1,11 +1,11 @@ -# $OpenBSD: files.rasops,v 1.5 2005/09/15 20:23:10 miod Exp $ +# $OpenBSD: files.rasops,v 1.6 2006/12/02 15:55:18 miod Exp $ # $NetBSD: files.rasops,v 1.7 2001/01/21 13:50:59 takemura Exp $ # Note: `rasops_glue' is only here to force the header file's name # hence it must be mentioned first (shudder...) file dev/rasops/rasops.c ((rasops_glue | rasops1 | rasops2 | rasops4 | rasops8 | rasops15 | rasops16 | rasops24 | - rasops32 | rasops_rotation) & + rasops32 | rasops_bswap | rasops_rotation) & wsdisplay) needs-flag file dev/rasops/rasops_masks.c wsdisplay & (rasops1 | rasops2 | rasops4) diff --git a/sys/dev/rasops/rasops.c b/sys/dev/rasops/rasops.c index 7e2ca53c5ac..78c02107db7 100644 --- a/sys/dev/rasops/rasops.c +++ b/sys/dev/rasops/rasops.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rasops.c,v 1.15 2006/11/29 19:08:22 miod Exp $ */ +/* $OpenBSD: rasops.c,v 1.16 2006/12/02 15:55:18 miod Exp $ */ /* $NetBSD: rasops.c,v 1.35 2001/02/02 06:01:01 marcus Exp $ */ /*- @@ -147,6 +147,7 @@ int rasops_alloc_mattr(void *, int, int, int, long *); void rasops_do_cursor(struct rasops_info *); void rasops_init_devcmap(struct rasops_info *); void rasops_unpack_attr(void *, long, int *, int *, int *); +static void slow_ovbcopy(void *, void *, size_t); #if NRASOPS_ROTATION > 0 void rasops_copychar(void *, int, int, int, int); @@ -663,10 +664,21 @@ rasops_copycols(cookie, row, src, dst, num) sp = ri->ri_bits + row + src * ri->ri_xscale; dp = ri->ri_bits + row + dst * ri->ri_xscale; - while (height--) { - ovbcopy(sp, dp, num); - dp += ri->ri_stride; - sp += ri->ri_stride; +#if NRASOPS_BSWAP > 0 + if (ri->ri_flg & RI_BSWAP) { + while (height--) { + slow_ovbcopy(sp, dp, num); + dp += ri->ri_stride; + sp += ri->ri_stride; + } + } else +#endif + { + while (height--) { + ovbcopy(sp, dp, num); + dp += ri->ri_stride; + sp += ri->ri_stride; + } } } @@ -794,6 +806,7 @@ rasops_init_devcmap(ri) c = c | (c << 16); /* 24bpp does bswap on the fly. {32,16,15}bpp do it here. */ +#if NRASOPS_BSWAP > 0 if ((ri->ri_flg & RI_BSWAP) == 0) ri->ri_devcmap[i] = c; else if (ri->ri_depth == 32) @@ -802,6 +815,9 @@ rasops_init_devcmap(ri) ri->ri_devcmap[i] = swap16(c); else ri->ri_devcmap[i] = c; +#else + ri->ri_devcmap[i] = c; +#endif } #endif } @@ -1158,10 +1174,21 @@ rasops_copychar(cookie, srcrow, dstrow, srccol, dstcol) sp = ri->ri_bits + r_srcrow + r_srccol * ri->ri_xscale; dp = ri->ri_bits + r_dstrow + r_dstcol * ri->ri_xscale; - while (height--) { - ovbcopy(sp, dp, ri->ri_xscale); - dp += ri->ri_stride; - sp += ri->ri_stride; +#if NRASOPS_BSWAP > 0 + if (ri->ri_flg & RI_BSWAP) { + while (height--) { + slow_ovbcopy(sp, dp, ri->ri_xscale); + dp += ri->ri_stride; + sp += ri->ri_stride; + } + } else +#endif + { + while (height--) { + ovbcopy(sp, dp, ri->ri_xscale); + dp += ri->ri_stride; + sp += ri->ri_stride; + } } } @@ -1265,3 +1292,29 @@ rasops_eraserows_rotated(cookie, row, num, attr) ri->ri_ops.putchar(cookie, rn, col, ' ', attr); } #endif /* NRASOPS_ROTATION */ + +#if NRASOPS_BSWAP > 0 +/* + * Strictly byte-only ovbcopy() version, to be used with RI_BSWAP, as the + * regular ovbcopy() may want to optimize things by doing larger-than-byte + * reads or write. This may confuse things if src and dst have different + * alignments. + */ +void +slow_ovbcopy(void *s, void *d, size_t len) +{ + u_int8_t *src = s; + u_int8_t *dst = d; + + if ((vaddr_t)dst <= (vaddr_t)src) { + while (len-- != 0) + *dst++ = *src++; + } else { + src += len; + dst += len; + if (len != 0) + while (--len != 0) + *--dst = *--src; + } +} +#endif /* NRASOPS_BSWAP */ diff --git a/sys/dev/rasops/rasops8.c b/sys/dev/rasops/rasops8.c index 9d45f66e45d..2d9933a2084 100644 --- a/sys/dev/rasops/rasops8.c +++ b/sys/dev/rasops/rasops8.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rasops8.c,v 1.6 2002/07/27 22:17:49 miod Exp $ */ +/* $OpenBSD: rasops8.c,v 1.7 2006/12/02 15:55:18 miod Exp $ */ /* $NetBSD: rasops8.c,v 1.8 2000/04/12 14:22:29 pk Exp $ */ /*- @@ -195,8 +195,10 @@ rasops8_makestamp(ri, attr) stamp[i] |= ((i & 4 ? fg : bg) << 16); stamp[i] |= ((i & 8 ? fg : bg) << 24); #endif +#if NRASOPS_BSWAP > 0 if (ri->ri_flg & RI_BSWAP) stamp[i] = swap32(stamp[i]); +#endif } } |