mirror of
git://projects.qi-hardware.com/openwrt-xburst.git
synced 2025-04-21 12:27:27 +03:00
[xburst] Add 2.6.36 patches
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@23421 3c298f89-4303-0410-b956-a3cf2f4a3e73
This commit is contained in:
334
target/linux/xburst/patches-2.6.36/001-xburst-cache-quirks.patch
Normal file
334
target/linux/xburst/patches-2.6.36/001-xburst-cache-quirks.patch
Normal file
@@ -0,0 +1,334 @@
|
||||
From 3679ae9872aef12529b332767e32097aa8233904 Mon Sep 17 00:00:00 2001
|
||||
From: Lars-Peter Clausen <lars@metafoo.de>
|
||||
Date: Sat, 24 Apr 2010 17:34:29 +0200
|
||||
Subject: [PATCH] JZ4740 cache quirks
|
||||
|
||||
---
|
||||
arch/mips/include/asm/r4kcache.h | 231 ++++++++++++++++++++++++++++++++++++++
|
||||
1 files changed, 231 insertions(+), 0 deletions(-)
|
||||
|
||||
--- a/arch/mips/include/asm/r4kcache.h
|
||||
+++ b/arch/mips/include/asm/r4kcache.h
|
||||
@@ -17,6 +17,58 @@
|
||||
#include <asm/cpu-features.h>
|
||||
#include <asm/mipsmtregs.h>
|
||||
|
||||
+#ifdef CONFIG_JZRISC
|
||||
+
|
||||
+#define K0_TO_K1() \
|
||||
+do { \
|
||||
+ unsigned long __k0_addr; \
|
||||
+ \
|
||||
+ __asm__ __volatile__( \
|
||||
+ "la %0, 1f\n\t" \
|
||||
+ "or %0, %0, %1\n\t" \
|
||||
+ "jr %0\n\t" \
|
||||
+ "nop\n\t" \
|
||||
+ "1: nop\n" \
|
||||
+ : "=&r"(__k0_addr) \
|
||||
+ : "r" (0x20000000) ); \
|
||||
+} while(0)
|
||||
+
|
||||
+#define K1_TO_K0() \
|
||||
+do { \
|
||||
+ unsigned long __k0_addr; \
|
||||
+ __asm__ __volatile__( \
|
||||
+ "nop;nop;nop;nop;nop;nop;nop\n\t" \
|
||||
+ "la %0, 1f\n\t" \
|
||||
+ "jr %0\n\t" \
|
||||
+ "nop\n\t" \
|
||||
+ "1: nop\n" \
|
||||
+ : "=&r" (__k0_addr)); \
|
||||
+} while (0)
|
||||
+
|
||||
+#define INVALIDATE_BTB() \
|
||||
+do { \
|
||||
+ unsigned long tmp; \
|
||||
+ __asm__ __volatile__( \
|
||||
+ ".set mips32\n\t" \
|
||||
+ "mfc0 %0, $16, 7\n\t" \
|
||||
+ "nop\n\t" \
|
||||
+ "ori %0, 2\n\t" \
|
||||
+ "mtc0 %0, $16, 7\n\t" \
|
||||
+ "nop\n\t" \
|
||||
+ : "=&r" (tmp)); \
|
||||
+} while (0)
|
||||
+
|
||||
+#define SYNC_WB() __asm__ __volatile__ ("sync")
|
||||
+
|
||||
+#else /* CONFIG_JZRISC */
|
||||
+
|
||||
+#define K0_TO_K1() do { } while (0)
|
||||
+#define K1_TO_K0() do { } while (0)
|
||||
+#define INVALIDATE_BTB() do { } while (0)
|
||||
+#define SYNC_WB() do { } while (0)
|
||||
+
|
||||
+#endif /* CONFIG_JZRISC */
|
||||
+
|
||||
/*
|
||||
* This macro return a properly sign-extended address suitable as base address
|
||||
* for indexed cache operations. Two issues here:
|
||||
@@ -144,6 +196,7 @@ static inline void flush_icache_line_ind
|
||||
{
|
||||
__iflush_prologue
|
||||
cache_op(Index_Invalidate_I, addr);
|
||||
+ INVALIDATE_BTB();
|
||||
__iflush_epilogue
|
||||
}
|
||||
|
||||
@@ -151,6 +204,7 @@ static inline void flush_dcache_line_ind
|
||||
{
|
||||
__dflush_prologue
|
||||
cache_op(Index_Writeback_Inv_D, addr);
|
||||
+ SYNC_WB();
|
||||
__dflush_epilogue
|
||||
}
|
||||
|
||||
@@ -163,6 +217,7 @@ static inline void flush_icache_line(uns
|
||||
{
|
||||
__iflush_prologue
|
||||
cache_op(Hit_Invalidate_I, addr);
|
||||
+ INVALIDATE_BTB();
|
||||
__iflush_epilogue
|
||||
}
|
||||
|
||||
@@ -170,6 +225,7 @@ static inline void flush_dcache_line(uns
|
||||
{
|
||||
__dflush_prologue
|
||||
cache_op(Hit_Writeback_Inv_D, addr);
|
||||
+ SYNC_WB();
|
||||
__dflush_epilogue
|
||||
}
|
||||
|
||||
@@ -177,6 +233,7 @@ static inline void invalidate_dcache_lin
|
||||
{
|
||||
__dflush_prologue
|
||||
cache_op(Hit_Invalidate_D, addr);
|
||||
+ SYNC_WB();
|
||||
__dflush_epilogue
|
||||
}
|
||||
|
||||
@@ -209,6 +266,7 @@ static inline void flush_scache_line(uns
|
||||
static inline void protected_flush_icache_line(unsigned long addr)
|
||||
{
|
||||
protected_cache_op(Hit_Invalidate_I, addr);
|
||||
+ INVALIDATE_BTB();
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -220,6 +278,7 @@ static inline void protected_flush_icach
|
||||
static inline void protected_writeback_dcache_line(unsigned long addr)
|
||||
{
|
||||
protected_cache_op(Hit_Writeback_Inv_D, addr);
|
||||
+ SYNC_WB();
|
||||
}
|
||||
|
||||
static inline void protected_writeback_scache_line(unsigned long addr)
|
||||
@@ -396,8 +455,10 @@ static inline void blast_##pfx##cache##l
|
||||
__BUILD_BLAST_CACHE(d, dcache, Index_Writeback_Inv_D, Hit_Writeback_Inv_D, 16)
|
||||
__BUILD_BLAST_CACHE(i, icache, Index_Invalidate_I, Hit_Invalidate_I, 16)
|
||||
__BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 16)
|
||||
+#ifndef CONFIG_JZRISC
|
||||
__BUILD_BLAST_CACHE(d, dcache, Index_Writeback_Inv_D, Hit_Writeback_Inv_D, 32)
|
||||
__BUILD_BLAST_CACHE(i, icache, Index_Invalidate_I, Hit_Invalidate_I, 32)
|
||||
+#endif
|
||||
__BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 32)
|
||||
__BUILD_BLAST_CACHE(d, dcache, Index_Writeback_Inv_D, Hit_Writeback_Inv_D, 64)
|
||||
__BUILD_BLAST_CACHE(i, icache, Index_Invalidate_I, Hit_Invalidate_I, 64)
|
||||
@@ -405,12 +466,122 @@ __BUILD_BLAST_CACHE(s, scache, Index_Wri
|
||||
__BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 128)
|
||||
|
||||
__BUILD_BLAST_CACHE(inv_d, dcache, Index_Writeback_Inv_D, Hit_Invalidate_D, 16)
|
||||
+#ifndef CONFIG_JZRISC
|
||||
__BUILD_BLAST_CACHE(inv_d, dcache, Index_Writeback_Inv_D, Hit_Invalidate_D, 32)
|
||||
+#endif
|
||||
__BUILD_BLAST_CACHE(inv_s, scache, Index_Writeback_Inv_SD, Hit_Invalidate_SD, 16)
|
||||
__BUILD_BLAST_CACHE(inv_s, scache, Index_Writeback_Inv_SD, Hit_Invalidate_SD, 32)
|
||||
__BUILD_BLAST_CACHE(inv_s, scache, Index_Writeback_Inv_SD, Hit_Invalidate_SD, 64)
|
||||
__BUILD_BLAST_CACHE(inv_s, scache, Index_Writeback_Inv_SD, Hit_Invalidate_SD, 128)
|
||||
|
||||
+#ifdef CONFIG_JZRISC
|
||||
+
|
||||
+static inline void blast_dcache32(void)
|
||||
+{
|
||||
+ unsigned long start = INDEX_BASE;
|
||||
+ unsigned long end = start + current_cpu_data.dcache.waysize;
|
||||
+ unsigned long ws_inc = 1UL << current_cpu_data.dcache.waybit;
|
||||
+ unsigned long ws_end = current_cpu_data.dcache.ways <<
|
||||
+ current_cpu_data.dcache.waybit;
|
||||
+ unsigned long ws, addr;
|
||||
+
|
||||
+ for (ws = 0; ws < ws_end; ws += ws_inc)
|
||||
+ for (addr = start; addr < end; addr += 0x400)
|
||||
+ cache32_unroll32(addr|ws,Index_Writeback_Inv_D);
|
||||
+
|
||||
+ SYNC_WB();
|
||||
+}
|
||||
+
|
||||
+static inline void blast_dcache32_page(unsigned long page)
|
||||
+{
|
||||
+ unsigned long start = page;
|
||||
+ unsigned long end = page + PAGE_SIZE;
|
||||
+
|
||||
+ do {
|
||||
+ cache32_unroll32(start,Hit_Writeback_Inv_D);
|
||||
+ start += 0x400;
|
||||
+ } while (start < end);
|
||||
+
|
||||
+ SYNC_WB();
|
||||
+}
|
||||
+
|
||||
+static inline void blast_dcache32_page_indexed(unsigned long page)
|
||||
+{
|
||||
+ unsigned long indexmask = current_cpu_data.dcache.waysize - 1;
|
||||
+ unsigned long start = INDEX_BASE + (page & indexmask);
|
||||
+ unsigned long end = start + PAGE_SIZE;
|
||||
+ unsigned long ws_inc = 1UL << current_cpu_data.dcache.waybit;
|
||||
+ unsigned long ws_end = current_cpu_data.dcache.ways <<
|
||||
+ current_cpu_data.dcache.waybit;
|
||||
+ unsigned long ws, addr;
|
||||
+
|
||||
+ for (ws = 0; ws < ws_end; ws += ws_inc)
|
||||
+ for (addr = start; addr < end; addr += 0x400)
|
||||
+ cache32_unroll32(addr|ws,Index_Writeback_Inv_D);
|
||||
+
|
||||
+ SYNC_WB();
|
||||
+}
|
||||
+
|
||||
+static inline void blast_icache32(void)
|
||||
+{
|
||||
+ unsigned long start = INDEX_BASE;
|
||||
+ unsigned long end = start + current_cpu_data.icache.waysize;
|
||||
+ unsigned long ws_inc = 1UL << current_cpu_data.icache.waybit;
|
||||
+ unsigned long ws_end = current_cpu_data.icache.ways <<
|
||||
+ current_cpu_data.icache.waybit;
|
||||
+ unsigned long ws, addr;
|
||||
+
|
||||
+ K0_TO_K1();
|
||||
+
|
||||
+ for (ws = 0; ws < ws_end; ws += ws_inc)
|
||||
+ for (addr = start; addr < end; addr += 0x400)
|
||||
+ cache32_unroll32(addr|ws,Index_Invalidate_I);
|
||||
+
|
||||
+ INVALIDATE_BTB();
|
||||
+
|
||||
+ K1_TO_K0();
|
||||
+}
|
||||
+
|
||||
+static inline void blast_icache32_page(unsigned long page)
|
||||
+{
|
||||
+ unsigned long start = page;
|
||||
+ unsigned long end = page + PAGE_SIZE;
|
||||
+
|
||||
+ K0_TO_K1();
|
||||
+
|
||||
+ do {
|
||||
+ cache32_unroll32(start,Hit_Invalidate_I);
|
||||
+ start += 0x400;
|
||||
+ } while (start < end);
|
||||
+
|
||||
+ INVALIDATE_BTB();
|
||||
+
|
||||
+ K1_TO_K0();
|
||||
+}
|
||||
+
|
||||
+static inline void blast_icache32_page_indexed(unsigned long page)
|
||||
+{
|
||||
+ unsigned long indexmask = current_cpu_data.icache.waysize - 1;
|
||||
+ unsigned long start = INDEX_BASE + (page & indexmask);
|
||||
+ unsigned long end = start + PAGE_SIZE;
|
||||
+ unsigned long ws_inc = 1UL << current_cpu_data.icache.waybit;
|
||||
+ unsigned long ws_end = current_cpu_data.icache.ways <<
|
||||
+ current_cpu_data.icache.waybit;
|
||||
+ unsigned long ws, addr;
|
||||
+
|
||||
+ K0_TO_K1();
|
||||
+
|
||||
+ for (ws = 0; ws < ws_end; ws += ws_inc)
|
||||
+ for (addr = start; addr < end; addr += 0x400)
|
||||
+ cache32_unroll32(addr|ws,Index_Invalidate_I);
|
||||
+
|
||||
+ INVALIDATE_BTB();
|
||||
+
|
||||
+ K1_TO_K0();
|
||||
+}
|
||||
+
|
||||
+#endif /* CONFIG_JZRISC */
|
||||
+
|
||||
/* build blast_xxx_range, protected_blast_xxx_range */
|
||||
#define __BUILD_BLAST_CACHE_RANGE(pfx, desc, hitop, prot) \
|
||||
static inline void prot##blast_##pfx##cache##_range(unsigned long start, \
|
||||
@@ -432,13 +603,73 @@ static inline void prot##blast_##pfx##ca
|
||||
__##pfx##flush_epilogue \
|
||||
}
|
||||
|
||||
+#ifndef CONFIG_JZRISC
|
||||
__BUILD_BLAST_CACHE_RANGE(d, dcache, Hit_Writeback_Inv_D, protected_)
|
||||
+#endif
|
||||
__BUILD_BLAST_CACHE_RANGE(s, scache, Hit_Writeback_Inv_SD, protected_)
|
||||
+#ifndef CONFIG_JZRISC
|
||||
__BUILD_BLAST_CACHE_RANGE(i, icache, Hit_Invalidate_I, protected_)
|
||||
__BUILD_BLAST_CACHE_RANGE(d, dcache, Hit_Writeback_Inv_D, )
|
||||
+#endif
|
||||
__BUILD_BLAST_CACHE_RANGE(s, scache, Hit_Writeback_Inv_SD, )
|
||||
/* blast_inv_dcache_range */
|
||||
__BUILD_BLAST_CACHE_RANGE(inv_d, dcache, Hit_Invalidate_D, )
|
||||
__BUILD_BLAST_CACHE_RANGE(inv_s, scache, Hit_Invalidate_SD, )
|
||||
|
||||
+#ifdef CONFIG_JZRISC
|
||||
+
|
||||
+static inline void protected_blast_dcache_range(unsigned long start,
|
||||
+ unsigned long end)
|
||||
+{
|
||||
+ unsigned long lsize = cpu_dcache_line_size();
|
||||
+ unsigned long addr = start & ~(lsize - 1);
|
||||
+ unsigned long aend = (end - 1) & ~(lsize - 1);
|
||||
+
|
||||
+ while (1) {
|
||||
+ protected_cache_op(Hit_Writeback_Inv_D, addr);
|
||||
+ if (addr == aend)
|
||||
+ break;
|
||||
+ addr += lsize;
|
||||
+ }
|
||||
+ SYNC_WB();
|
||||
+}
|
||||
+
|
||||
+static inline void protected_blast_icache_range(unsigned long start,
|
||||
+ unsigned long end)
|
||||
+{
|
||||
+ unsigned long lsize = cpu_icache_line_size();
|
||||
+ unsigned long addr = start & ~(lsize - 1);
|
||||
+ unsigned long aend = (end - 1) & ~(lsize - 1);
|
||||
+
|
||||
+ K0_TO_K1();
|
||||
+
|
||||
+ while (1) {
|
||||
+ protected_cache_op(Hit_Invalidate_I, addr);
|
||||
+ if (addr == aend)
|
||||
+ break;
|
||||
+ addr += lsize;
|
||||
+ }
|
||||
+ INVALIDATE_BTB();
|
||||
+
|
||||
+ K1_TO_K0();
|
||||
+}
|
||||
+
|
||||
+static inline void blast_dcache_range(unsigned long start,
|
||||
+ unsigned long end)
|
||||
+{
|
||||
+ unsigned long lsize = cpu_dcache_line_size();
|
||||
+ unsigned long addr = start & ~(lsize - 1);
|
||||
+ unsigned long aend = (end - 1) & ~(lsize - 1);
|
||||
+
|
||||
+ while (1) {
|
||||
+ cache_op(Hit_Writeback_Inv_D, addr);
|
||||
+ if (addr == aend)
|
||||
+ break;
|
||||
+ addr += lsize;
|
||||
+ }
|
||||
+ SYNC_WB();
|
||||
+}
|
||||
+
|
||||
+#endif /* CONFIG_JZRISC */
|
||||
+
|
||||
#endif /* _ASM_R4KCACHE_H */
|
||||
Reference in New Issue
Block a user