summaryrefslogtreecommitdiff
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
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.
-rw-r--r--sys/arch/sparc64/conf/files.sparc644
-rw-r--r--sys/conf/files3
-rw-r--r--sys/dev/rasops/files.rasops4
-rw-r--r--sys/dev/rasops/rasops.c71
-rw-r--r--sys/dev/rasops/rasops8.c4
5 files changed, 71 insertions, 15 deletions
diff --git a/sys/arch/sparc64/conf/files.sparc64 b/sys/arch/sparc64/conf/files.sparc64
index b781ef385cb..0b8585f8497 100644
--- a/sys/arch/sparc64/conf/files.sparc64
+++ b/sys/arch/sparc64/conf/files.sparc64
@@ -1,4 +1,4 @@
-# $OpenBSD: files.sparc64,v 1.73 2006/09/27 06:33:03 grange Exp $
+# $OpenBSD: files.sparc64,v 1.74 2006/12/02 15:55:16 miod Exp $
# $NetBSD: files.sparc64,v 1.50 2001/08/10 20:53:50 eeh Exp $
# maxpartitions must be first item in files.${ARCH}
@@ -92,7 +92,7 @@ file arch/sparc64/dev/pci_machdep.c psycho | schizo
attach hme at pci with hme_pci
file dev/pci/if_hme_pci.c hme_pci
-device vgafb: wsemuldisplaydev, rasops8, rasops16, rasops32, wsemul_sun
+device vgafb: wsemuldisplaydev, rasops_bswap, rasops8, rasops16, rasops32, wsemul_sun
attach vgafb at pci
file arch/sparc64/dev/vgafb.c vgafb
diff --git a/sys/conf/files b/sys/conf/files
index 8352ee615c1..4969b16c42e 100644
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -1,4 +1,4 @@
-# $OpenBSD: files,v 1.390 2006/11/25 18:10:29 uwe Exp $
+# $OpenBSD: files,v 1.391 2006/12/02 15:55:18 miod Exp $
# $NetBSD: files,v 1.87 1996/05/19 17:17:50 jonathan Exp $
# @(#)files.newconf 7.5 (Berkeley) 5/10/93
@@ -48,6 +48,7 @@ define rasops15
define rasops16
define rasops24
define rasops32
+define rasops_bswap
define rasops_rotation
# net device attributes - we have generic code for ether(net),
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
}
}