diff options
author | marcel <marcel@FreeBSD.org> | 2009-05-18 18:37:18 +0000 |
---|---|---|
committer | marcel <marcel@FreeBSD.org> | 2009-05-18 18:37:18 +0000 |
commit | 8b09116a5afc11ad02ed3d58dc2619303aeca12b (patch) | |
tree | cf3c716dbc38984e19bd613ced4f6b9f8d4ca6b7 /sys/ia64 | |
parent | c6c278457529c585668914f3ccc199e9c40165ac (diff) | |
download | FreeBSD-src-8b09116a5afc11ad02ed3d58dc2619303aeca12b.zip FreeBSD-src-8b09116a5afc11ad02ed3d58dc2619303aeca12b.tar.gz |
Add cpu_flush_dcache() for use after non-DMA based I/O so that a
possible future I-cache coherency operation can succeed. On ARM
for example the L1 cache can be (is) virtually mapped, which
means that any I/O that uses temporary mappings will not see the
I-cache made coherent. On ia64 a similar behaviour has been
observed. By flushing the D-cache, execution of binaries backed
by md(4) and/or NFS work reliably.
For Book-E (powerpc), execution over NFS exhibits SIGILL once in
a while as well, though cpu_flush_dcache() hasn't been implemented
yet.
Doing an explicit D-cache flush as part of the non-DMA based I/O
read operation eliminates the need to do it as part of the
I-cache coherency operation itself and as such avoids pessimizing
the DMA-based I/O read operations for which D-cache are already
flushed/invalidated. It also allows future optimizations whereby
the bcopy() followed by the D-cache flush can be integrated in a
single operation, which could be implemented using on-chips DMA
engines, by-passing the D-cache altogether.
Diffstat (limited to 'sys/ia64')
-rw-r--r-- | sys/ia64/ia64/machdep.c | 15 |
1 files changed, 15 insertions, 0 deletions
diff --git a/sys/ia64/ia64/machdep.c b/sys/ia64/ia64/machdep.c index 3c6e61d..8ffdcf2 100644 --- a/sys/ia64/ia64/machdep.c +++ b/sys/ia64/ia64/machdep.c @@ -311,6 +311,21 @@ cpu_boot(int howto) efi_reset_system(); } +void +cpu_flush_dcache(void *ptr, size_t len) +{ + vm_offset_t lim, va; + + va = (uintptr_t)ptr & ~31; + lim = (uintptr_t)ptr + len; + while (va < lim) { + ia64_fc(va); + va += 32; + } + + ia64_srlz_d(); +} + /* Get current clock frequency for the given cpu id. */ int cpu_est_clockrate(int cpu_id, uint64_t *rate) |