mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: monstr@monstr.eu
To: monstr@monstr.eu
Cc: linux-kernel@vger.kernel.org, stephen.neuendorffer@xilinx.com,
	john.williams@petalogix.com, microblaze-uclinux@itee.uq.edu.au
Subject: [PATCH 09/52] [microblaze] cache support
Date: Thu, 24 Jan 2008 16:03:34 +0100	[thread overview]
Message-ID: <511c50297cee79a1237479ed1c68c923aed8293f.1201107832.git.monstr@monstr.eu> (raw)
In-Reply-To: <671df2e842f46f829133f893b5388e29a797494d.1201107832.git.monstr@monstr.eu>
In-Reply-To: <8051f6df628e1ff896ec7d580b613da50f718fb4.1201107832.git.monstr@monstr.eu>

From: Michal Simek <monstr@monstr.eu>


Signed-off-by: Michal Simek <monstr@monstr.eu>
---
 arch/microblaze/kernel/cpu/cache.c  |  256 +++++++++++++++++++++++++++++++++++
 include/asm-microblaze/cache.h      |   47 +++++++
 include/asm-microblaze/cacheflush.h |   72 ++++++++++
 3 files changed, 375 insertions(+), 0 deletions(-)
 create mode 100644 arch/microblaze/kernel/cpu/cache.c
 create mode 100644 include/asm-microblaze/cache.h
 create mode 100644 include/asm-microblaze/cacheflush.h

diff --git a/arch/microblaze/kernel/cpu/cache.c b/arch/microblaze/kernel/cpu/cache.c
new file mode 100644
index 0000000..43fff59
--- /dev/null
+++ b/arch/microblaze/kernel/cpu/cache.c
@@ -0,0 +1,256 @@
+/*
+ * arch/microblaze/kernel/cpu/cache.c
+ * Cache control for MicroBlaze cache memories
+ *
+ * Copyright (C) 2007 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2007 PetaLogix
+ * Copyright (C) 2007 John Williams <john.williams@petalogix.com>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License. See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ */
+
+#include <asm/cacheflush.h>
+#include <asm/cache.h>
+#include <asm/cpuinfo.h>
+
+/* Exported functions */
+
+void _enable_icache(void)
+{
+	if (cpuinfo->use_icache) {
+#if CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR
+		__asm__ __volatile__ ("					\
+				msrset	r0, %0;				\
+				nop; "					\
+				:					\
+				: "i" (MSR_ICE)				\
+				: "memory");
+#else
+		__asm__ __volatile__ ("					\
+				mfs	r12, rmsr;			\
+				ori	r12, r12, %0;			\
+				mts	rmsr, r12;			\
+				nop; "					\
+				:					\
+				: "i" (MSR_ICE)				\
+				: "memory", "r12");
+#endif
+	}
+}
+
+void _disable_icache(void)
+{
+	if (cpuinfo->use_icache) {
+#if CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR
+		__asm__ __volatile__ ("					\
+				msrclr r0, %0;				\
+				nop; "					\
+				:					\
+				: "i" (MSR_ICE)				\
+				: "memory");
+#else
+		__asm__ __volatile__ ("					\
+				mfs	r12, rmsr;			\
+				andi	r12, r12, ~%0;			\
+				mts	rmsr, r12;			\
+				nop; "					\
+				:					\
+				: "i" (MSR_ICE)				\
+				: "memory", "r12");
+#endif
+	}
+}
+
+void _invalidate_icache(unsigned int addr)
+{
+	if (cpuinfo->use_icache) {
+		__asm__ __volatile__ ("					\
+				wic	%0, r0"				\
+				:					\
+				: "r" (addr));
+	}
+}
+
+void _enable_dcache(void)
+{
+	if (cpuinfo->use_dcache) {
+#if CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR
+		__asm__ __volatile__ ("					\
+				msrset	r0, %0;				\
+				nop; "					\
+				:					\
+				: "i" (MSR_DCE)				\
+				: "memory");
+#else
+		__asm__ __volatile__ ("					\
+				mfs	r12, rmsr;			\
+				ori	r12, r12, %0;			\
+				mts	rmsr, r12;			\
+				nop; "					\
+				:					\
+				: "i" (MSR_DCE)			\
+				: "memory", "r12");
+#endif
+	}
+}
+
+void _disable_dcache(void)
+{
+	if (cpuinfo->use_dcache) {
+#if CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR
+		__asm__ __volatile__ ("					\
+				msrclr	r0, %0;				\
+				nop; "					\
+				:					\
+				: "i" (MSR_DCE)			\
+				: "memory");
+#else
+		__asm__ __volatile__ ("					\
+				mfs	r12, rmsr;			\
+				andi	r12, r12, ~%0;			\
+				mts	rmsr, r12;			\
+				nop; "					\
+				:					\
+				: "i" (MSR_DCE)			\
+				: "memory", "r12");
+#endif
+	}
+}
+
+void _invalidate_dcache(unsigned int addr)
+{
+	if (cpuinfo->use_dcache)
+		__asm__ __volatile__ ("					\
+				wdc	%0, r0"				\
+				:					\
+				: "r" (addr));
+}
+
+void __flush_icache_all(void)
+{
+	unsigned int i;
+	unsigned flags;
+
+	if (cpuinfo->use_icache) {
+		local_irq_save(flags);
+		__disable_icache();
+
+		/* Just loop through cache size and invalidate, no need to add
+			CACHE_BASE address */
+		for (i = 0; i < cpuinfo->icache_size;
+			i += cpuinfo->icache_line)
+				__invalidate_icache(i);
+
+		__enable_icache();
+		local_irq_restore(flags);
+	}
+}
+
+void __flush_icache_range(unsigned long start, unsigned long end)
+{
+	unsigned int i;
+	unsigned flags;
+	unsigned int align;
+
+	if (cpuinfo->use_icache) {
+		/*
+		 * No need to cover entire cache range,
+		 * just cover cache footprint
+		 */
+		end = min(start + cpuinfo->icache_size, end);
+		align = ~(cpuinfo->icache_line - 1);
+		start &= align; /* Make sure we are aligned */
+		/* Push end up to the next cache line */
+		end = ((end & align) + cpuinfo->icache_line);
+
+		local_irq_save(flags);
+		__disable_icache();
+
+		for (i = start; i < end; i += cpuinfo->icache_line)
+			__invalidate_icache(i);
+
+		__enable_icache();
+		local_irq_restore(flags);
+	}
+}
+
+void __flush_icache_page(struct vm_area_struct *vma, struct page *page)
+{
+	__flush_icache_all();
+}
+
+void __flush_icache_user_range(struct vm_area_struct *vma,
+				struct page *page, unsigned long adr,
+				int len)
+{
+	__flush_icache_all();
+}
+
+void __flush_cache_sigtramp(unsigned long addr)
+{
+	__flush_icache_range(addr, addr + 8);
+}
+
+void __flush_dcache_all(void)
+{
+	unsigned int i;
+	unsigned flags;
+
+	if (cpuinfo->use_dcache) {
+		local_irq_save(flags);
+		__disable_dcache();
+
+		/*
+		 * Just loop through cache size and invalidate,
+		 * no need to add CACHE_BASE address
+		 */
+		for (i = 0; i < cpuinfo->dcache_size;
+			i += cpuinfo->dcache_line)
+				__invalidate_dcache(i);
+
+		__enable_dcache();
+		local_irq_restore(flags);
+	}
+}
+
+void __flush_dcache_range(unsigned long start, unsigned long end)
+{
+	unsigned int i;
+	unsigned flags;
+	unsigned int align;
+
+	if (cpuinfo->use_dcache) {
+		/*
+		 * No need to cover entire cache range,
+		 * just cover cache footprint
+		 */
+		end = min(start + cpuinfo->dcache_size, end);
+		align = ~(cpuinfo->dcache_line - 1);
+		start &= align; /* Make sure we are aligned */
+		/* Push end up to the next cache line */
+		end = ((end & align) + cpuinfo->dcache_line);
+		local_irq_save(flags);
+		__disable_dcache();
+
+		for (i = start; i < end; i += cpuinfo->dcache_line)
+			__invalidate_dcache(i);
+
+		__enable_dcache();
+		local_irq_restore(flags);
+	}
+}
+
+void __flush_dcache_page(struct vm_area_struct *vma, struct page *page)
+{
+	__flush_dcache_all();
+}
+
+void __flush_dcache_user_range(struct vm_area_struct *vma,
+				struct page *page, unsigned long adr,
+				int len)
+{
+	__flush_dcache_all();
+}
diff --git a/include/asm-microblaze/cache.h b/include/asm-microblaze/cache.h
new file mode 100644
index 0000000..e988152
--- /dev/null
+++ b/include/asm-microblaze/cache.h
@@ -0,0 +1,47 @@
+/*
+ * include/asm-microblaze/cache.h
+ *
+ * Cache operations
+ *
+ * Copyright (C) 2007 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2003 John Williams <jwilliams@itee.uq.edu.au>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License. See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ */
+
+#ifndef _MICROBLAZE_CACHE_H
+#define _MICROBLAZE_CACHE_H
+
+#include <asm/registers.h>
+#include <linux/autoconf.h>
+
+#ifndef L1_CACHE_BYTES
+/* word-granular cache in microblaze */
+#define L1_CACHE_BYTES		4
+#endif
+
+void _enable_icache(void);
+void _disable_icache(void);
+void _invalidate_icache(unsigned int addr);
+
+#define __enable_icache()		_enable_icache()
+#define __disable_icache()		_disable_icache()
+#define __invalidate_icache(addr)	_invalidate_icache(addr)
+
+void _enable_dcache(void);
+void _disable_dcache(void);
+void _invalidate_dcache(unsigned int addr);
+
+#define __enable_dcache()		_enable_dcache()
+#define __disable_dcache()		_disable_dcache()
+#define __invalidate_dcache(addr)	_invalidate_dcache(addr)
+
+/* FIXME - I don't think this is right */
+#ifdef CONFIG_XILINX_UNCACHED_SHADOW
+#define UNCACHED_SHADOW_MASK (CONFIG_XILINX_ERAM_SIZE)
+#endif
+
+#endif /* _MICROBLAZE_CACHE_H */
diff --git a/include/asm-microblaze/cacheflush.h b/include/asm-microblaze/cacheflush.h
new file mode 100644
index 0000000..3051690
--- /dev/null
+++ b/include/asm-microblaze/cacheflush.h
@@ -0,0 +1,72 @@
+/*
+ * include/asm-microblaze/cacheflush.h
+ *
+ * Copyright (C) 2007 PetaLogix
+ * Copyright (C) 2007 John Williams <john.williams@petalogix.com>
+ * based on v850 version which was
+ * Copyright (C) 2001,02,03 NEC Electronics Corporation
+ * Copyright (C) 2001,02,03 Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License. See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ */
+
+#ifndef _MICROBLAZE_CACHEFLUSH_H
+#define _MICROBLAZE_CACHEFLUSH_H
+
+/* Somebody depends on this; sigh... */
+#include <linux/mm.h>
+
+#define flush_cache_all()			__flush_cache_all()
+#define flush_cache_mm(mm)			do { } while (0)
+#define flush_cache_range(vma, start, end)	__flush_cache_all()
+#define flush_cache_page(vma, vmaddr, pfn)	do { } while (0)
+
+#define flush_dcache_range(start, end)	__flush_dcache_range(start, end)
+#define flush_dcache_page(page)		do { } while (0)
+#define flush_dcache_mmap_lock(mapping)		do { } while (0)
+#define flush_dcache_mmap_unlock(mapping)	do { } while (0)
+
+#define flush_icache_range(start, len)	__flush_icache_range(start, len)
+#define flush_icache_page(vma, pg)		do { } while (0)
+#define flush_icache_user_range(start, len)	do { } while (0)
+
+#define flush_cache_vmap(start, end)		do { } while (0)
+#define flush_cache_vunmap(start, end)		do { } while (0)
+
+struct page;
+struct mm_struct;
+struct vm_area_struct;
+
+/* see arch/microblaze/kernel/cache.c */
+extern void __flush_icache_all(void);
+extern void __flush_icache_range(unsigned long start, unsigned long end);
+extern void __flush_icache_page(struct vm_area_struct *vma, struct page *page);
+extern void __flush_icache_user_range(struct vm_area_struct *vma,
+				struct page *page,
+				unsigned long adr, int len);
+extern void __flush_cache_sigtramp(unsigned long addr);
+
+extern void __flush_dcache_all(void);
+extern void __flush_dcache_range(unsigned long start, unsigned long end);
+extern void __flush_dcache_page(struct vm_area_struct *vma, struct page *page);
+extern void __flush_dcache_user_range(struct vm_area_struct *vma,
+				struct page *page,
+				unsigned long adr, int len);
+
+extern inline void __flush_cache_all(void)
+{
+	__flush_icache_all();
+	__flush_dcache_all();
+}
+
+#define copy_to_user_page(vma, page, vaddr, dst, src, len) \
+do { memcpy(dst, src, len); \
+	flush_icache_user_range(vma, page, vaddr, len); \
+} while (0)
+#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
+	memcpy(dst, src, len)
+
+#endif /* _MICROBLAZE_CACHEFLUSH_H */
-- 
1.5.4.rc4.14.g6fc74


  parent reply	other threads:[~2008-01-26 16:08 UTC|newest]

Thread overview: 67+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-01-24 15:02 Microblaze init port monstr
2008-01-24 15:05 ` [PATCH 01/52] [microblaze] Kconfig patches monstr
2008-01-24 15:02   ` [PATCH 10/52] [microblaze] Generic dts file for platforms monstr
2008-01-24 15:02   ` [PATCH 11/52] [microblaze] kernel modules support monstr
2008-01-26 16:27     ` Jan Engelhardt
2008-01-24 15:02   ` [PATCH 12/52] [microblaze] lmb support monstr
2008-01-27 12:51     ` Jan Engelhardt
2008-01-24 15:02   ` [PATCH 13/52] [microblaze] PVR support, cpuinfo support monstr
2008-01-24 15:02   ` [PATCH 14/52] [microblaze] defconfig file monstr
2008-01-24 15:02   ` [PATCH 15/52] [microblaze] assembler files head.S, entry.S, monstr
2008-01-24 15:02   ` [PATCH 16/52] [microblaze] supported function for memory - kernel/lib monstr
2008-01-29 21:26     ` Jan Engelhardt
2008-01-24 15:02   ` [PATCH 17/52] [microblaze] checksum support monstr
2008-01-27 11:57     ` Geert Uytterhoeven
2008-01-27 13:41       ` Michal Simek
2008-01-27 15:12         ` Geert Uytterhoeven
2008-01-29 21:30     ` Jan Engelhardt
2008-01-24 15:02   ` [PATCH 18/52] [microblaze] early_printk support monstr
2008-01-24 15:02   ` [PATCH 19/52] [microblaze] uaccess files monstr
2008-01-24 15:02   ` [PATCH 20/52] [microblaze] heartbeat file monstr
2008-01-24 15:02   ` [PATCH 21/52] [microblaze] setup.c - system setting monstr
2008-01-24 15:02   ` [PATCH 22/52] [microblaze] asm-offsets monstr
2008-01-24 15:02   ` [PATCH 23/52] [microblaze] process and init task function monstr
2008-01-24 15:02   ` [PATCH 24/52] [microblaze] time support monstr
     [not found]     ` <47BD86F3.9030400@petalogix.com>
     [not found]       ` <20080221163040.5E9FA6A0056@mail168-sin.bigfish.com>
2008-03-02 19:25         ` [microblaze-uclinux] " Michal Simek
2008-01-24 15:03   ` [PATCH 25/52] [microblaze] ptrace support monstr
2008-01-24 15:03   ` [PATCH 26/52] [microblaze] IPC support monstr
2008-01-24 15:03   ` [PATCH 27/52] [microblaze] traps support monstr
2008-01-24 15:03   ` [PATCH 28/52] [microblaze] support for a.out monstr
2008-01-24 15:03   ` [PATCH 29/52] [microblaze] memory inicialization, MMU, TLB monstr
2008-01-24 15:03   ` [PATCH 30/52] [microblaze] consistent allocation & page.h, monstr
2008-01-24 15:03   ` [PATCH 31/52] [microblaze] pci header files monstr
2008-01-24 15:03   ` [PATCH 32/52] [microblaze] includes SHM*, msgbuf monstr
2008-01-24 15:03   ` [PATCH 33/52] [microblaze] bug headers files monstr
2008-01-24 15:03   ` [PATCH 34/52] [microblaze] definitions of types monstr
2008-01-24 15:03   ` [PATCH 35/52] [microblaze] ioctl support monstr
2008-01-24 15:03   ` [PATCH 36/52] [microblaze] io.h IO operations monstr
2008-01-24 15:03   ` [PATCH 37/52] [microblaze] headers for executables format FLAT, ELF monstr
2008-01-24 15:03   ` [PATCH 38/52] [microblaze] dma support monstr
2008-01-24 15:03   ` [PATCH 39/52] [microblaze] headers for irq monstr
2008-01-24 15:03   ` [PATCH 40/52] [microblaze] atomic.h bitops.h byteorder.h monstr
2008-01-24 15:03   ` [PATCH 41/52] [microblaze] headers pgalloc.h pgtable.h monstr
2008-01-24 15:03   ` [PATCH 42/52] [microblaze] system.h pvr.h processor.h monstr
2008-01-24 15:03   ` [PATCH 43/52] [microblaze] clinkage.h linkage.h sections.h kmap_types.h monstr
2008-01-24 15:03   ` [PATCH 44/52] [microblaze] stats headers monstr
2008-01-24 15:03   ` [PATCH 45/52] [microblaze] termbits.h termios.h monstr
2008-01-24 15:03   ` [PATCH 46/52] [microblaze] sigcontext.h siginfo.h monstr
2008-01-24 15:03   ` [PATCH 47/52] [microblaze] headers simple files monstr
2008-01-24 15:03   ` [PATCH 48/52] [microblaze] headers files entry.h current.h mman.h registers.h sembuf.h monstr
2008-01-24 15:03   ` [PATCH 49/52] [microblaze] device.h param.h topology.h monstr
2008-01-24 15:03   ` [PATCH 50/52] [microblaze] pool.h socket.h monstr
2008-01-24 15:03   ` [PATCH 51/52] [microblaze] fcntl.h sockios.h ucontext.h unistd.h monstr
2008-01-24 15:03   ` [PATCH 52/52] [microblaze] setup.h string.h thread_info.h monstr
2008-01-24 15:03   ` [PATCH 03/52] [microblaze] Cpuinfo handling monstr
2008-01-27 12:55     ` Jan Engelhardt
2008-01-24 15:03   ` [PATCH 04/52] [microblaze] Open firmware files monstr
2008-01-24 15:03   ` [PATCH 05/52] [microblaze] Support for semaphores monstr
2008-01-24 15:03   ` [PATCH 06/52] [microblaze] exception handling monstr
2008-01-24 15:03   ` [PATCH 07/52] [microblaze] Signal support monstr
2008-01-24 15:03   ` [PATCH 08/52] [microblaze] Interrupt handling, timer support, supported function monstr
2008-01-24 15:03   ` monstr [this message]
2008-01-24 15:05   ` [PATCH 02/52] [microblaze] Makefiles for Microblaze cpu monstr
2008-01-26 17:36   ` [PATCH 01/52] [microblaze] Kconfig patches Randy Dunlap
2008-01-27 10:39     ` Michal Simek
2008-01-27 10:41     ` [PATCH 01/52] [microblaze] Kconfig patches v2 Michal Simek
2008-01-27 17:15       ` Randy Dunlap
2008-01-27 11:59 ` Microblaze init port Geert Uytterhoeven

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=511c50297cee79a1237479ed1c68c923aed8293f.1201107832.git.monstr@monstr.eu \
    --to=monstr@monstr.eu \
    --cc=john.williams@petalogix.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=microblaze-uclinux@itee.uq.edu.au \
    --cc=stephen.neuendorffer@xilinx.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®