summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authorMiod Vallat <miod@cvs.openbsd.org>2006-12-02 15:55:19 +0000
committerMiod Vallat <miod@cvs.openbsd.org>2006-12-02 15:55:19 +0000
commitcc6f15397de00ac4c73efcf550971680b9dabfff (patch)
tree426d787b5e35e7bb7fbdf8c0e66cd6fb7002814d /sys/dev
parentd2c8d56da6a0b1f99fd3b3e9fed1871cf1cfc577 (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.rasops4
-rw-r--r--sys/dev/rasops/rasops.c71
-rw-r--r--sys/dev/rasops/rasops8.c4
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
}
}