aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/sh/include/asm/page.h19
-rw-r--r--arch/sh/include/asm/ptrace.h11
-rw-r--r--arch/sh/kernel/head_32.S8
-rw-r--r--arch/sh/mm/Makefile1
-rw-r--r--arch/sh/mm/init.c21
-rw-r--r--arch/sh/mm/uncached.c28
6 files changed, 58 insertions, 30 deletions
diff --git a/arch/sh/include/asm/page.h b/arch/sh/include/asm/page.h
index 3accdc5ab122..8237d9f53e56 100644
--- a/arch/sh/include/asm/page.h
+++ b/arch/sh/include/asm/page.h
@@ -50,13 +50,22 @@ extern unsigned long shm_align_mask;
50extern unsigned long max_low_pfn, min_low_pfn; 50extern unsigned long max_low_pfn, min_low_pfn;
51extern unsigned long memory_start, memory_end; 51extern unsigned long memory_start, memory_end;
52 52
53#ifdef CONFIG_UNCACHED_MAPPING
54extern unsigned long uncached_start, uncached_end;
55
56extern int virt_addr_uncached(unsigned long kaddr);
57extern void uncached_init(void);
58#else
59#define virt_addr_uncached(kaddr) (0)
60#define uncached_init() do { } while (0)
61#endif
62
53static inline unsigned long 63static inline unsigned long
54pages_do_alias(unsigned long addr1, unsigned long addr2) 64pages_do_alias(unsigned long addr1, unsigned long addr2)
55{ 65{
56 return (addr1 ^ addr2) & shm_align_mask; 66 return (addr1 ^ addr2) & shm_align_mask;
57} 67}
58 68
59
60#define clear_page(page) memset((void *)(page), 0, PAGE_SIZE) 69#define clear_page(page) memset((void *)(page), 0, PAGE_SIZE)
61extern void copy_page(void *to, void *from); 70extern void copy_page(void *to, void *from);
62 71
@@ -135,6 +144,14 @@ typedef struct page *pgtable_t;
135#define __va(x) ((void *)((unsigned long)(x)+PAGE_OFFSET)) 144#define __va(x) ((void *)((unsigned long)(x)+PAGE_OFFSET))
136#endif 145#endif
137 146
147#ifdef CONFIG_UNCACHED_MAPPING
148#define UNCAC_ADDR(addr) ((addr) - PAGE_OFFSET + uncached_start)
149#define CAC_ADDR(addr) ((addr) - uncached_start + PAGE_OFFSET)
150#else
151#define UNCAC_ADDR(addr) ((addr))
152#define CAC_ADDR(addr) ((addr))
153#endif
154
138#define pfn_to_kaddr(pfn) __va((pfn) << PAGE_SHIFT) 155#define pfn_to_kaddr(pfn) __va((pfn) << PAGE_SHIFT)
139#define page_to_phys(page) (page_to_pfn(page) << PAGE_SHIFT) 156#define page_to_phys(page) (page_to_pfn(page) << PAGE_SHIFT)
140 157
diff --git a/arch/sh/include/asm/ptrace.h b/arch/sh/include/asm/ptrace.h
index e879dffa324b..e11b14ea2c43 100644
--- a/arch/sh/include/asm/ptrace.h
+++ b/arch/sh/include/asm/ptrace.h
@@ -139,15 +139,8 @@ static inline unsigned long profile_pc(struct pt_regs *regs)
139{ 139{
140 unsigned long pc = instruction_pointer(regs); 140 unsigned long pc = instruction_pointer(regs);
141 141
142#ifdef CONFIG_UNCACHED_MAPPING 142 if (virt_addr_uncached(pc))
143 /* 143 return CAC_ADDR(pc);
144 * If PC points in to the uncached mapping, fix it up and hand
145 * back the cached equivalent.
146 */
147 if ((pc >= (memory_start + cached_to_uncached)) &&
148 (pc < (memory_start + cached_to_uncached + uncached_size)))
149 pc -= cached_to_uncached;
150#endif
151 144
152 return pc; 145 return pc;
153} 146}
diff --git a/arch/sh/kernel/head_32.S b/arch/sh/kernel/head_32.S
index 91ae76277d8f..79ff39517f8e 100644
--- a/arch/sh/kernel/head_32.S
+++ b/arch/sh/kernel/head_32.S
@@ -152,6 +152,7 @@ ENTRY(_stext)
152 152
153 mov #0, r10 153 mov #0, r10
154 154
155#ifdef CONFIG_UNCACHED_MAPPING
155 /* 156 /*
156 * Uncached mapping 157 * Uncached mapping
157 */ 158 */
@@ -171,6 +172,7 @@ ENTRY(_stext)
171 add r4, r1 172 add r4, r1
172 add r4, r3 173 add r4, r3
173 add #1, r10 174 add #1, r10
175#endif
174 176
175/* 177/*
176 * Iterate over all of the available sizes from largest to 178 * Iterate over all of the available sizes from largest to
@@ -216,6 +218,7 @@ ENTRY(_stext)
216 __PMB_ITER_BY_SIZE(64) 218 __PMB_ITER_BY_SIZE(64)
217 __PMB_ITER_BY_SIZE(16) 219 __PMB_ITER_BY_SIZE(16)
218 220
221#ifdef CONFIG_UNCACHED_MAPPING
219 /* 222 /*
220 * Now that we can access it, update cached_to_uncached and 223 * Now that we can access it, update cached_to_uncached and
221 * uncached_size. 224 * uncached_size.
@@ -228,6 +231,7 @@ ENTRY(_stext)
228 shll16 r7 231 shll16 r7
229 shll8 r7 232 shll8 r7
230 mov.l r7, @r0 233 mov.l r7, @r0
234#endif
231 235
232 /* 236 /*
233 * Clear the remaining PMB entries. 237 * Clear the remaining PMB entries.
@@ -306,7 +310,9 @@ ENTRY(stack_start)
306.LFIRST_ADDR_ENTRY: .long PAGE_OFFSET | PMB_V 310.LFIRST_ADDR_ENTRY: .long PAGE_OFFSET | PMB_V
307.LFIRST_DATA_ENTRY: .long __MEMORY_START | PMB_V 311.LFIRST_DATA_ENTRY: .long __MEMORY_START | PMB_V
308.LMMUCR: .long MMUCR 312.LMMUCR: .long MMUCR
313.LMEMORY_SIZE: .long __MEMORY_SIZE
314#ifdef CONFIG_UNCACHED_MAPPING
309.Lcached_to_uncached: .long cached_to_uncached 315.Lcached_to_uncached: .long cached_to_uncached
310.Luncached_size: .long uncached_size 316.Luncached_size: .long uncached_size
311.LMEMORY_SIZE: .long __MEMORY_SIZE 317#endif
312#endif 318#endif
diff --git a/arch/sh/mm/Makefile b/arch/sh/mm/Makefile
index de714cbd961a..3dc8a8a63822 100644
--- a/arch/sh/mm/Makefile
+++ b/arch/sh/mm/Makefile
@@ -36,6 +36,7 @@ obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
36obj-$(CONFIG_PMB) += pmb.o 36obj-$(CONFIG_PMB) += pmb.o
37obj-$(CONFIG_NUMA) += numa.o 37obj-$(CONFIG_NUMA) += numa.o
38obj-$(CONFIG_IOREMAP_FIXED) += ioremap_fixed.o 38obj-$(CONFIG_IOREMAP_FIXED) += ioremap_fixed.o
39obj-$(CONFIG_UNCACHED_MAPPING) += uncached.o
39 40
40# Special flags for fault_64.o. This puts restrictions on the number of 41# Special flags for fault_64.o. This puts restrictions on the number of
41# caller-save registers that the compiler can target when building this file. 42# caller-save registers that the compiler can target when building this file.
diff --git a/arch/sh/mm/init.c b/arch/sh/mm/init.c
index 58012b6bbe76..08e280d7cc7e 100644
--- a/arch/sh/mm/init.c
+++ b/arch/sh/mm/init.c
@@ -26,21 +26,6 @@
26DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); 26DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
27pgd_t swapper_pg_dir[PTRS_PER_PGD]; 27pgd_t swapper_pg_dir[PTRS_PER_PGD];
28 28
29#ifdef CONFIG_UNCACHED_MAPPING
30/*
31 * This is the offset of the uncached section from its cached alias.
32 *
33 * Legacy platforms handle trivial transitions between cached and
34 * uncached segments by making use of the 1:1 mapping relationship in
35 * 512MB lowmem, others via a special uncached mapping.
36 *
37 * Default value only valid in 29 bit mode, in 32bit mode this will be
38 * updated by the early PMB initialization code.
39 */
40unsigned long cached_to_uncached = 0x20000000;
41unsigned long uncached_size = SZ_512M;
42#endif
43
44#ifdef CONFIG_MMU 29#ifdef CONFIG_MMU
45static pte_t *__get_pte_phys(unsigned long addr) 30static pte_t *__get_pte_phys(unsigned long addr)
46{ 31{
@@ -260,7 +245,7 @@ void __init mem_init(void)
260 memset(empty_zero_page, 0, PAGE_SIZE); 245 memset(empty_zero_page, 0, PAGE_SIZE);
261 __flush_wback_region(empty_zero_page, PAGE_SIZE); 246 __flush_wback_region(empty_zero_page, PAGE_SIZE);
262 247
263 /* Initialize the vDSO */ 248 uncached_init();
264 vsyscall_init(); 249 vsyscall_init();
265 250
266 codesize = (unsigned long) &_etext - (unsigned long) &_text; 251 codesize = (unsigned long) &_etext - (unsigned long) &_text;
@@ -303,9 +288,7 @@ void __init mem_init(void)
303 ((unsigned long)high_memory - (unsigned long)memory_start) >> 20, 288 ((unsigned long)high_memory - (unsigned long)memory_start) >> 20,
304 289
305#ifdef CONFIG_UNCACHED_MAPPING 290#ifdef CONFIG_UNCACHED_MAPPING
306 (unsigned long)memory_start + cached_to_uncached, 291 uncached_start, uncached_end, uncached_size >> 20,
307 (unsigned long)memory_start + cached_to_uncached + uncached_size,
308 uncached_size >> 20,
309#endif 292#endif
310 293
311 (unsigned long)&__init_begin, (unsigned long)&__init_end, 294 (unsigned long)&__init_begin, (unsigned long)&__init_end,
diff --git a/arch/sh/mm/uncached.c b/arch/sh/mm/uncached.c
new file mode 100644
index 000000000000..807906981d9d
--- /dev/null
+++ b/arch/sh/mm/uncached.c
@@ -0,0 +1,28 @@
1#include <linux/init.h>
2#include <asm/sizes.h>
3#include <asm/page.h>
4
5/*
6 * This is the offset of the uncached section from its cached alias.
7 *
8 * Legacy platforms handle trivial transitions between cached and
9 * uncached segments by making use of the 1:1 mapping relationship in
10 * 512MB lowmem, others via a special uncached mapping.
11 *
12 * Default value only valid in 29 bit mode, in 32bit mode this will be
13 * updated by the early PMB initialization code.
14 */
15unsigned long cached_to_uncached = SZ_512M;
16unsigned long uncached_size = SZ_512M;
17unsigned long uncached_start, uncached_end;
18
19int virt_addr_uncached(unsigned long kaddr)
20{
21 return (kaddr >= uncached_start) && (kaddr < uncached_end);
22}
23
24void __init uncached_init(void)
25{
26 uncached_start = memory_end;
27 uncached_end = uncached_start + uncached_size;
28}