Add the rt linux 4.1.3-rt3 as base
[kvmfornfv.git] / kernel / arch / mn10300 / mm / cache-dbg-flush-by-reg.S
diff --git a/kernel/arch/mn10300/mm/cache-dbg-flush-by-reg.S b/kernel/arch/mn10300/mm/cache-dbg-flush-by-reg.S
new file mode 100644 (file)
index 0000000..a775ea5
--- /dev/null
@@ -0,0 +1,160 @@
+/* MN10300 CPU cache invalidation routines, using automatic purge registers
+ *
+ * Copyright (C) 2011 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+#include <linux/sys.h>
+#include <linux/linkage.h>
+#include <asm/smp.h>
+#include <asm/page.h>
+#include <asm/cache.h>
+#include <asm/irqflags.h>
+#include <asm/cacheflush.h>
+#include "cache.inc"
+
+       .am33_2
+
+###############################################################################
+#
+# void debugger_local_cache_flushinv(void)
+# Flush the entire data cache back to RAM and invalidate the icache
+#
+###############################################################################
+       ALIGN
+       .globl  debugger_local_cache_flushinv
+        .type  debugger_local_cache_flushinv,@function
+debugger_local_cache_flushinv:
+       #
+       # firstly flush the dcache
+       #
+       movhu   (CHCTR),d0
+       btst    CHCTR_DCEN|CHCTR_ICEN,d0
+       beq     debugger_local_cache_flushinv_end
+
+       mov     DCPGCR,a0
+
+       mov     epsw,d1
+       and     ~EPSW_IE,epsw
+       or      EPSW_NMID,epsw
+       nop
+
+       btst    CHCTR_DCEN,d0
+       beq     debugger_local_cache_flushinv_no_dcache
+
+       # wait for busy bit of area purge
+       setlb
+       mov     (a0),d0
+       btst    DCPGCR_DCPGBSY,d0
+       lne
+
+       # set mask
+       clr     d0
+       mov     d0,(DCPGMR)
+
+       # area purge
+       #
+       # DCPGCR = DCPGCR_DCP
+       #
+       mov     DCPGCR_DCP,d0
+       mov     d0,(a0)
+
+       # wait for busy bit of area purge
+       setlb
+       mov     (a0),d0
+       btst    DCPGCR_DCPGBSY,d0
+       lne
+
+debugger_local_cache_flushinv_no_dcache:
+       #
+       # secondly, invalidate the icache if it is enabled
+       #
+       mov     CHCTR,a0
+       movhu   (a0),d0
+       btst    CHCTR_ICEN,d0
+       beq     debugger_local_cache_flushinv_done
+
+       invalidate_icache 0
+
+debugger_local_cache_flushinv_done:
+       mov     d1,epsw
+
+debugger_local_cache_flushinv_end:
+       ret     [],0
+       .size   debugger_local_cache_flushinv,.-debugger_local_cache_flushinv
+
+###############################################################################
+#
+# void debugger_local_cache_flushinv_one(u8 *addr)
+#
+# Invalidate one particular cacheline if it's in the icache
+#
+###############################################################################
+       ALIGN
+       .globl  debugger_local_cache_flushinv_one
+       .type   debugger_local_cache_flushinv_one,@function
+debugger_local_cache_flushinv_one:
+       movhu   (CHCTR),d1
+       btst    CHCTR_DCEN|CHCTR_ICEN,d1
+       beq     debugger_local_cache_flushinv_one_end
+       btst    CHCTR_DCEN,d1
+       beq     debugger_local_cache_flushinv_one_no_dcache
+
+       # round cacheline addr down
+       and     L1_CACHE_TAG_MASK,d0
+       mov     d0,a1
+       mov     d0,d1
+
+       # determine the dcache purge control reg address
+       mov     DCACHE_PURGE(0,0),a0
+       and     L1_CACHE_TAG_ENTRY,d0
+       add     d0,a0
+
+       # retain valid entries in the cache
+       or      L1_CACHE_TAG_VALID,d1
+
+       # conditionally purge this line in all ways
+       mov     d1,(L1_CACHE_WAYDISP*0,a0)
+
+debugger_local_cache_flushinv_one_no_dcache:
+       #
+       # now try to flush the icache
+       #
+       mov     CHCTR,a0
+       movhu   (a0),d0
+       btst    CHCTR_ICEN,d0
+       beq     debugger_local_cache_flushinv_one_end
+
+       LOCAL_CLI_SAVE(d1)
+
+       mov     ICIVCR,a0
+
+       # wait for the invalidator to quiesce
+       setlb
+       mov     (a0),d0
+       btst    ICIVCR_ICIVBSY,d0
+       lne
+
+       # set the mask
+       mov     L1_CACHE_TAG_MASK,d0
+       mov     d0,(ICIVMR)
+
+       # invalidate the cache line at the given address
+       or      ICIVCR_ICI,a1
+       mov     a1,(a0)
+
+       # wait for the invalidator to quiesce again
+       setlb
+       mov     (a0),d0
+       btst    ICIVCR_ICIVBSY,d0
+       lne
+
+       LOCAL_IRQ_RESTORE(d1)
+
+debugger_local_cache_flushinv_one_end:
+       ret     [],0
+       .size   debugger_local_cache_flushinv_one,.-debugger_local_cache_flushinv_one