aboutsummaryrefslogtreecommitdiff
path: root/arch/openrisc/mm/cache.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2017-11-13 12:12:00 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2017-11-13 12:12:00 -0800
commitf3573b8f902c507c721999cc669fbb7e045081b8 (patch)
tree703d1d7e58d50dfbf7a9c4810710acf393166a57 /arch/openrisc/mm/cache.c
parent9e09d05cfe7df9efa7bbca7d679af534a616026e (diff)
parent610f01b9a88a9ef8b506709a825c17395c56a62a (diff)
Merge tag 'for-linus' of git://github.com/openrisc/linux
Pull OpenRISC updates from Stafford Horne: "The OpenRISC work is a bit more interesting this time, adding SMP support and a few general cleanups. Small Things: - Move OpenRISC docs into Documentation and clean them up - Document previously undocumented devicetree bindings - Update the or1ksim dts to use stdout-path OpenRISC SMP support details: - First the "use shadow registers" and "define CPU_BIG_ENDIAN as true" get the architecture ready for SMP. - The "add 1 and 2 byte cmpxchg support" and "use qspinlocks and qrwlocks" add the SMP locking infrastructure as needed. Using the qspinlocks and qrwlocks as suggested by Peter Z while reviewing the original spinlocks implementation. - The "support for ompic" adds a new irqchip device which is used for IPI communication to support SMP. - The "initial SMP support" adds smp.c and makes changes to all of the necessary data-structures to be per-cpu. The remaining patches are bug fixes and debug helpers which I wanted to keep separate from the "initial SMP support" in order to allow them to be reviewed on their own. This includes: - add cacheflush support to fix icache aliasing - fix initial preempt state for secondary cpu tasks - sleep instead of spin on secondary wait - support framepointers and STACKTRACE_SUPPORT - enable LOCKDEP_SUPPORT and irqflags tracing - timer sync: Add tick timer sync logic - fix possible deadlock in timer sync, pointed out by mips guys Note: the irqchip patch was reviewed with Marc and we agreed to push it together with these patches" * tag 'for-linus' of git://github.com/openrisc/linux: openrisc: fix possible deadlock scenario during timer sync openrisc: pass endianness info to sparse openrisc: add tick timer multi-core sync logic openrisc: enable LOCKDEP_SUPPORT and irqflags tracing openrisc: support framepointers and STACKTRACE_SUPPORT openrisc: add simple_smp dts and defconfig for simulators openrisc: add cacheflush support to fix icache aliasing openrisc: sleep instead of spin on secondary wait openrisc: fix initial preempt state for secondary cpu tasks openrisc: initial SMP support irqchip: add initial support for ompic dt-bindings: add openrisc to vendor prefixes list openrisc: use qspinlocks and qrwlocks openrisc: add 1 and 2 byte cmpxchg support openrisc: use shadow registers to save regs on exception dt-bindings: openrisc: Add OpenRISC platform SoC Documentation: openrisc: Updates to README Documentation: Move OpenRISC docs out of arch/ MAINTAINERS: Add OpenRISC pic maintainer openrisc: dts: or1ksim: Add stdout-path
Diffstat (limited to 'arch/openrisc/mm/cache.c')
-rw-r--r--arch/openrisc/mm/cache.c61
1 files changed, 61 insertions, 0 deletions
diff --git a/arch/openrisc/mm/cache.c b/arch/openrisc/mm/cache.c
new file mode 100644
index 000000000000..b747bf1fc1b6
--- /dev/null
+++ b/arch/openrisc/mm/cache.c
@@ -0,0 +1,61 @@
+/*
+ * OpenRISC cache.c
+ *
+ * Linux architectural port borrowing liberally from similar works of
+ * others. All original copyrights apply as per the original source
+ * declaration.
+ *
+ * Modifications for the OpenRISC architecture:
+ * Copyright (C) 2015 Jan Henrik Weinstock <jan.weinstock@rwth-aachen.de>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <asm/spr.h>
+#include <asm/spr_defs.h>
+#include <asm/cache.h>
+#include <asm/cacheflush.h>
+#include <asm/tlbflush.h>
+
+static void cache_loop(struct page *page, const unsigned int reg)
+{
+ unsigned long paddr = page_to_pfn(page) << PAGE_SHIFT;
+ unsigned long line = paddr & ~(L1_CACHE_BYTES - 1);
+
+ while (line < paddr + PAGE_SIZE) {
+ mtspr(reg, line);
+ line += L1_CACHE_BYTES;
+ }
+}
+
+void local_dcache_page_flush(struct page *page)
+{
+ cache_loop(page, SPR_DCBFR);
+}
+EXPORT_SYMBOL(local_dcache_page_flush);
+
+void local_icache_page_inv(struct page *page)
+{
+ cache_loop(page, SPR_ICBIR);
+}
+EXPORT_SYMBOL(local_icache_page_inv);
+
+void update_cache(struct vm_area_struct *vma, unsigned long address,
+ pte_t *pte)
+{
+ unsigned long pfn = pte_val(*pte) >> PAGE_SHIFT;
+ struct page *page = pfn_to_page(pfn);
+ int dirty = !test_and_set_bit(PG_dc_clean, &page->flags);
+
+ /*
+ * Since icaches do not snoop for updated data on OpenRISC, we
+ * must write back and invalidate any dirty pages manually. We
+ * can skip data pages, since they will not end up in icaches.
+ */
+ if ((vma->vm_flags & VM_EXEC) && dirty)
+ sync_icache_dcache(page);
+}
+