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
next prev 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®