summaryrefslogtreecommitdiffstats
path: root/sys/arch/arm/cortex/arml2cc.c
diff options
context:
space:
mode:
authorjsg <jsg@openbsd.org>2016-08-22 01:41:59 +0000
committerjsg <jsg@openbsd.org>2016-08-22 01:41:59 +0000
commitc4f21f07e9a891ad3b6dfe433d8847ae6615a538 (patch)
treec98cf330adf4111eb8ccb1facd87f0a2fe58f237 /sys/arch/arm/cortex/arml2cc.c
parentUse generic clock API to enable the module clock. (diff)
downloadwireguard-openbsd-c4f21f07e9a891ad3b6dfe433d8847ae6615a538.tar.xz
wireguard-openbsd-c4f21f07e9a891ad3b6dfe433d8847ae6615a538.zip
Before pmap7.c rev 1.35 and pmap.h rev 1.44 DMA'able memory with the
BUS_DMA_COHERENT flag was mapped as device memory which does not use the store buffer. It is now mapped as normal inner and outer non-cacheable which does. While we drain the cpu store buffer for this case, on cortex a9 systems we also need to explicitly drain the PL310 L2's store buffer. With PL310 revisions r3p2 and later this is done automatically after being present in the store buffer for 256 cycles. On i.MX6 PL310 is rev r3p1 which does not have this behaviour. This issue is i.MX6 errata ERR055199 and PL310 errata 769419. This change restores io performance with a usb flash drive attached to my cubox. Raw reads go from 3 MB/s to 19 MB/s for example. Based on code written by patrick@ some time ago. ok kettenis@ patrick@
Diffstat (limited to 'sys/arch/arm/cortex/arml2cc.c')
-rw-r--r--sys/arch/arm/cortex/arml2cc.c14
1 files changed, 13 insertions, 1 deletions
diff --git a/sys/arch/arm/cortex/arml2cc.c b/sys/arch/arm/cortex/arml2cc.c
index 1ce135469d4..8c75cbba511 100644
--- a/sys/arch/arm/cortex/arml2cc.c
+++ b/sys/arch/arm/cortex/arml2cc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: arml2cc.c,v 1.4 2015/05/20 00:39:16 jsg Exp $ */
+/* $OpenBSD: arml2cc.c,v 1.5 2016/08/22 01:42:00 jsg Exp $ */
/*
* Copyright (c) 2013 Patrick Wildt <patrick@blueri.se>
*
@@ -114,6 +114,7 @@ void arml2cc_cache_range_op(paddr_t, psize_t, bus_size_t);
void arml2cc_cache_way_op(struct arml2cc_softc *, bus_size_t, uint32_t);
void arml2cc_cache_op(struct arml2cc_softc *, bus_size_t, uint32_t);
void arml2cc_cache_sync(struct arml2cc_softc *);
+void arml2cc_sdcache_drain_writebuf(void);
struct cfattach armliicc_ca = {
sizeof (struct arml2cc_softc), arml2cc_match, arml2cc_attach
@@ -165,6 +166,7 @@ arml2cc_attach(struct device *parent, struct device *self, void *args)
cpufuncs.cf_sdcache_wbinv_range = arml2cc_sdcache_wbinv_range;
cpufuncs.cf_sdcache_inv_range = arml2cc_sdcache_inv_range;
cpufuncs.cf_sdcache_wb_range = arml2cc_sdcache_wb_range;
+ cpufuncs.cf_sdcache_drain_writebuf = arml2cc_sdcache_drain_writebuf;
}
void
@@ -222,6 +224,16 @@ arml2cc_cache_sync(struct arml2cc_softc *sc)
}
void
+arml2cc_sdcache_drain_writebuf(void)
+{
+ struct arml2cc_softc * const sc = arml2cc_sc;
+ if (sc == NULL || !sc->sc_enabled)
+ return;
+
+ arml2cc_cache_sync(sc);
+}
+
+void
arml2cc_cache_range_op(paddr_t pa, psize_t len, bus_size_t cache_op)
{
struct arml2cc_softc * const sc = arml2cc_sc;