summaryrefslogtreecommitdiffstats
path: root/arch/nios2
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2015-06-19 10:07:07 -0400
committerHerbert Xu <herbert@gondor.apana.org.au>2015-06-19 10:07:07 -0400
commitc0b59fafe31bf91f589736be304d739b13952fdd (patch)
tree0088a41c6b68132739294643be06734e3af67677 /arch/nios2
parent28bceeaaf81140d69647acd0eb7dc9312f27844a (diff)
parentbfa1ce5f38938cc9e6c7f2d1011f88eba2b9e2b2 (diff)
Merge branch 'mvebu/drivers' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
Merge the mvebu/drivers branch of the arm-soc tree which contains just a single patch bfa1ce5f38938cc9e6c7f2d1011f88eba2b9e2b2 ("bus: mvebu-mbus: add mv_mbus_dram_info_nooverlap()") that happens to be a prerequisite of the new marvell/cesa crypto driver.
Diffstat (limited to 'arch/nios2')
-rw-r--r--arch/nios2/include/asm/Kbuild1
-rw-r--r--arch/nios2/include/asm/shmparam.h21
-rw-r--r--arch/nios2/include/uapi/asm/ptrace.h2
-rw-r--r--arch/nios2/kernel/entry.S71
-rw-r--r--arch/nios2/kernel/traps.c34
-rw-r--r--arch/nios2/mm/cacheflush.c55
6 files changed, 128 insertions, 56 deletions
diff --git a/arch/nios2/include/asm/Kbuild b/arch/nios2/include/asm/Kbuild
index 01c75f36e8b3..24b3d8999ac7 100644
--- a/arch/nios2/include/asm/Kbuild
+++ b/arch/nios2/include/asm/Kbuild
@@ -46,7 +46,6 @@ generic-y += segment.h
46generic-y += sembuf.h 46generic-y += sembuf.h
47generic-y += serial.h 47generic-y += serial.h
48generic-y += shmbuf.h 48generic-y += shmbuf.h
49generic-y += shmparam.h
50generic-y += siginfo.h 49generic-y += siginfo.h
51generic-y += signal.h 50generic-y += signal.h
52generic-y += socket.h 51generic-y += socket.h
diff --git a/arch/nios2/include/asm/shmparam.h b/arch/nios2/include/asm/shmparam.h
new file mode 100644
index 000000000000..60784294e407
--- /dev/null
+++ b/arch/nios2/include/asm/shmparam.h
@@ -0,0 +1,21 @@
1/*
2 * Copyright Altera Corporation (C) <2015>. All rights reserved
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License along with
14 * this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16#ifndef _ASM_NIOS2_SHMPARAM_H
17#define _ASM_NIOS2_SHMPARAM_H
18
19#define SHMLBA CONFIG_NIOS2_DCACHE_SIZE
20
21#endif /* _ASM_NIOS2_SHMPARAM_H */
diff --git a/arch/nios2/include/uapi/asm/ptrace.h b/arch/nios2/include/uapi/asm/ptrace.h
index eff00e67c0a2..1d35de90a977 100644
--- a/arch/nios2/include/uapi/asm/ptrace.h
+++ b/arch/nios2/include/uapi/asm/ptrace.h
@@ -14,6 +14,8 @@
14 14
15#ifndef __ASSEMBLY__ 15#ifndef __ASSEMBLY__
16 16
17#include <linux/types.h>
18
17/* 19/*
18 * Register numbers used by 'ptrace' system call interface. 20 * Register numbers used by 'ptrace' system call interface.
19 */ 21 */
diff --git a/arch/nios2/kernel/entry.S b/arch/nios2/kernel/entry.S
index 27b006c52e12..1e515ccd698e 100644
--- a/arch/nios2/kernel/entry.S
+++ b/arch/nios2/kernel/entry.S
@@ -92,35 +92,35 @@ exception_table:
92 92
93trap_table: 93trap_table:
94 .word handle_system_call /* 0 */ 94 .word handle_system_call /* 0 */
95 .word instruction_trap /* 1 */ 95 .word handle_trap_1 /* 1 */
96 .word instruction_trap /* 2 */ 96 .word handle_trap_2 /* 2 */
97 .word instruction_trap /* 3 */ 97 .word handle_trap_3 /* 3 */
98 .word instruction_trap /* 4 */ 98 .word handle_trap_reserved /* 4 */
99 .word instruction_trap /* 5 */ 99 .word handle_trap_reserved /* 5 */
100 .word instruction_trap /* 6 */ 100 .word handle_trap_reserved /* 6 */
101 .word instruction_trap /* 7 */ 101 .word handle_trap_reserved /* 7 */
102 .word instruction_trap /* 8 */ 102 .word handle_trap_reserved /* 8 */
103 .word instruction_trap /* 9 */ 103 .word handle_trap_reserved /* 9 */
104 .word instruction_trap /* 10 */ 104 .word handle_trap_reserved /* 10 */
105 .word instruction_trap /* 11 */ 105 .word handle_trap_reserved /* 11 */
106 .word instruction_trap /* 12 */ 106 .word handle_trap_reserved /* 12 */
107 .word instruction_trap /* 13 */ 107 .word handle_trap_reserved /* 13 */
108 .word instruction_trap /* 14 */ 108 .word handle_trap_reserved /* 14 */
109 .word instruction_trap /* 15 */ 109 .word handle_trap_reserved /* 15 */
110 .word instruction_trap /* 16 */ 110 .word handle_trap_reserved /* 16 */
111 .word instruction_trap /* 17 */ 111 .word handle_trap_reserved /* 17 */
112 .word instruction_trap /* 18 */ 112 .word handle_trap_reserved /* 18 */
113 .word instruction_trap /* 19 */ 113 .word handle_trap_reserved /* 19 */
114 .word instruction_trap /* 20 */ 114 .word handle_trap_reserved /* 20 */
115 .word instruction_trap /* 21 */ 115 .word handle_trap_reserved /* 21 */
116 .word instruction_trap /* 22 */ 116 .word handle_trap_reserved /* 22 */
117 .word instruction_trap /* 23 */ 117 .word handle_trap_reserved /* 23 */
118 .word instruction_trap /* 24 */ 118 .word handle_trap_reserved /* 24 */
119 .word instruction_trap /* 25 */ 119 .word handle_trap_reserved /* 25 */
120 .word instruction_trap /* 26 */ 120 .word handle_trap_reserved /* 26 */
121 .word instruction_trap /* 27 */ 121 .word handle_trap_reserved /* 27 */
122 .word instruction_trap /* 28 */ 122 .word handle_trap_reserved /* 28 */
123 .word instruction_trap /* 29 */ 123 .word handle_trap_reserved /* 29 */
124#ifdef CONFIG_KGDB 124#ifdef CONFIG_KGDB
125 .word handle_kgdb_breakpoint /* 30 KGDB breakpoint */ 125 .word handle_kgdb_breakpoint /* 30 KGDB breakpoint */
126#else 126#else
@@ -455,6 +455,19 @@ handle_kgdb_breakpoint:
455 br ret_from_exception 455 br ret_from_exception
456#endif 456#endif
457 457
458handle_trap_1:
459 call handle_trap_1_c
460 br ret_from_exception
461
462handle_trap_2:
463 call handle_trap_2_c
464 br ret_from_exception
465
466handle_trap_3:
467handle_trap_reserved:
468 call handle_trap_3_c
469 br ret_from_exception
470
458/* 471/*
459 * Beware - when entering resume, prev (the current task) is 472 * Beware - when entering resume, prev (the current task) is
460 * in r4, next (the new task) is in r5, don't change these 473 * in r4, next (the new task) is in r5, don't change these
diff --git a/arch/nios2/kernel/traps.c b/arch/nios2/kernel/traps.c
index b7b97641a9a6..81f7da7b1d55 100644
--- a/arch/nios2/kernel/traps.c
+++ b/arch/nios2/kernel/traps.c
@@ -23,6 +23,17 @@
23 23
24static DEFINE_SPINLOCK(die_lock); 24static DEFINE_SPINLOCK(die_lock);
25 25
26static void _send_sig(int signo, int code, unsigned long addr)
27{
28 siginfo_t info;
29
30 info.si_signo = signo;
31 info.si_errno = 0;
32 info.si_code = code;
33 info.si_addr = (void __user *) addr;
34 force_sig_info(signo, &info, current);
35}
36
26void die(const char *str, struct pt_regs *regs, long err) 37void die(const char *str, struct pt_regs *regs, long err)
27{ 38{
28 console_verbose(); 39 console_verbose();
@@ -39,16 +50,10 @@ void die(const char *str, struct pt_regs *regs, long err)
39 50
40void _exception(int signo, struct pt_regs *regs, int code, unsigned long addr) 51void _exception(int signo, struct pt_regs *regs, int code, unsigned long addr)
41{ 52{
42 siginfo_t info;
43
44 if (!user_mode(regs)) 53 if (!user_mode(regs))
45 die("Exception in kernel mode", regs, signo); 54 die("Exception in kernel mode", regs, signo);
46 55
47 info.si_signo = signo; 56 _send_sig(signo, code, addr);
48 info.si_errno = 0;
49 info.si_code = code;
50 info.si_addr = (void __user *) addr;
51 force_sig_info(signo, &info, current);
52} 57}
53 58
54/* 59/*
@@ -183,3 +188,18 @@ asmlinkage void unhandled_exception(struct pt_regs *regs, int cause)
183 188
184 pr_emerg("opcode: 0x%08lx\n", *(unsigned long *)(regs->ea)); 189 pr_emerg("opcode: 0x%08lx\n", *(unsigned long *)(regs->ea));
185} 190}
191
192asmlinkage void handle_trap_1_c(struct pt_regs *fp)
193{
194 _send_sig(SIGUSR1, 0, fp->ea);
195}
196
197asmlinkage void handle_trap_2_c(struct pt_regs *fp)
198{
199 _send_sig(SIGUSR2, 0, fp->ea);
200}
201
202asmlinkage void handle_trap_3_c(struct pt_regs *fp)
203{
204 _send_sig(SIGILL, ILL_ILLTRP, fp->ea);
205}
diff --git a/arch/nios2/mm/cacheflush.c b/arch/nios2/mm/cacheflush.c
index 796642932e2e..223cdcc8203f 100644
--- a/arch/nios2/mm/cacheflush.c
+++ b/arch/nios2/mm/cacheflush.c
@@ -58,9 +58,6 @@ static void __invalidate_dcache(unsigned long start, unsigned long end)
58 end += (cpuinfo.dcache_line_size - 1); 58 end += (cpuinfo.dcache_line_size - 1);
59 end &= ~(cpuinfo.dcache_line_size - 1); 59 end &= ~(cpuinfo.dcache_line_size - 1);
60 60
61 if (end > start + cpuinfo.dcache_size)
62 end = start + cpuinfo.dcache_size;
63
64 for (addr = start; addr < end; addr += cpuinfo.dcache_line_size) { 61 for (addr = start; addr < end; addr += cpuinfo.dcache_line_size) {
65 __asm__ __volatile__ (" initda 0(%0)\n" 62 __asm__ __volatile__ (" initda 0(%0)\n"
66 : /* Outputs */ 63 : /* Outputs */
@@ -131,12 +128,14 @@ void flush_cache_dup_mm(struct mm_struct *mm)
131 128
132void flush_icache_range(unsigned long start, unsigned long end) 129void flush_icache_range(unsigned long start, unsigned long end)
133{ 130{
131 __flush_dcache(start, end);
134 __flush_icache(start, end); 132 __flush_icache(start, end);
135} 133}
136 134
137void flush_dcache_range(unsigned long start, unsigned long end) 135void flush_dcache_range(unsigned long start, unsigned long end)
138{ 136{
139 __flush_dcache(start, end); 137 __flush_dcache(start, end);
138 __flush_icache(start, end);
140} 139}
141EXPORT_SYMBOL(flush_dcache_range); 140EXPORT_SYMBOL(flush_dcache_range);
142 141
@@ -159,6 +158,7 @@ void flush_icache_page(struct vm_area_struct *vma, struct page *page)
159 unsigned long start = (unsigned long) page_address(page); 158 unsigned long start = (unsigned long) page_address(page);
160 unsigned long end = start + PAGE_SIZE; 159 unsigned long end = start + PAGE_SIZE;
161 160
161 __flush_dcache(start, end);
162 __flush_icache(start, end); 162 __flush_icache(start, end);
163} 163}
164 164
@@ -173,6 +173,18 @@ void flush_cache_page(struct vm_area_struct *vma, unsigned long vmaddr,
173 __flush_icache(start, end); 173 __flush_icache(start, end);
174} 174}
175 175
176void __flush_dcache_page(struct address_space *mapping, struct page *page)
177{
178 /*
179 * Writeback any data associated with the kernel mapping of this
180 * page. This ensures that data in the physical page is mutually
181 * coherent with the kernels mapping.
182 */
183 unsigned long start = (unsigned long)page_address(page);
184
185 __flush_dcache_all(start, start + PAGE_SIZE);
186}
187
176void flush_dcache_page(struct page *page) 188void flush_dcache_page(struct page *page)
177{ 189{
178 struct address_space *mapping; 190 struct address_space *mapping;
@@ -190,11 +202,12 @@ void flush_dcache_page(struct page *page)
190 if (mapping && !mapping_mapped(mapping)) { 202 if (mapping && !mapping_mapped(mapping)) {
191 clear_bit(PG_dcache_clean, &page->flags); 203 clear_bit(PG_dcache_clean, &page->flags);
192 } else { 204 } else {
193 unsigned long start = (unsigned long)page_address(page); 205 __flush_dcache_page(mapping, page);
194 206 if (mapping) {
195 __flush_dcache_all(start, start + PAGE_SIZE); 207 unsigned long start = (unsigned long)page_address(page);
196 if (mapping)
197 flush_aliases(mapping, page); 208 flush_aliases(mapping, page);
209 flush_icache_range(start, start + PAGE_SIZE);
210 }
198 set_bit(PG_dcache_clean, &page->flags); 211 set_bit(PG_dcache_clean, &page->flags);
199 } 212 }
200} 213}
@@ -205,6 +218,7 @@ void update_mmu_cache(struct vm_area_struct *vma,
205{ 218{
206 unsigned long pfn = pte_pfn(*pte); 219 unsigned long pfn = pte_pfn(*pte);
207 struct page *page; 220 struct page *page;
221 struct address_space *mapping;
208 222
209 if (!pfn_valid(pfn)) 223 if (!pfn_valid(pfn))
210 return; 224 return;
@@ -217,16 +231,15 @@ void update_mmu_cache(struct vm_area_struct *vma,
217 if (page == ZERO_PAGE(0)) 231 if (page == ZERO_PAGE(0))
218 return; 232 return;
219 233
220 if (!PageReserved(page) && 234 mapping = page_mapping(page);
221 !test_and_set_bit(PG_dcache_clean, &page->flags)) { 235 if (!test_and_set_bit(PG_dcache_clean, &page->flags))
222 unsigned long start = page_to_virt(page); 236 __flush_dcache_page(mapping, page);
223 struct address_space *mapping; 237
224 238 if(mapping)
225 __flush_dcache(start, start + PAGE_SIZE); 239 {
226 240 flush_aliases(mapping, page);
227 mapping = page_mapping(page); 241 if (vma->vm_flags & VM_EXEC)
228 if (mapping) 242 flush_icache_page(vma, page);
229 flush_aliases(mapping, page);
230 } 243 }
231} 244}
232 245
@@ -234,15 +247,19 @@ void copy_user_page(void *vto, void *vfrom, unsigned long vaddr,
234 struct page *to) 247 struct page *to)
235{ 248{
236 __flush_dcache(vaddr, vaddr + PAGE_SIZE); 249 __flush_dcache(vaddr, vaddr + PAGE_SIZE);
250 __flush_icache(vaddr, vaddr + PAGE_SIZE);
237 copy_page(vto, vfrom); 251 copy_page(vto, vfrom);
238 __flush_dcache((unsigned long)vto, (unsigned long)vto + PAGE_SIZE); 252 __flush_dcache((unsigned long)vto, (unsigned long)vto + PAGE_SIZE);
253 __flush_icache((unsigned long)vto, (unsigned long)vto + PAGE_SIZE);
239} 254}
240 255
241void clear_user_page(void *addr, unsigned long vaddr, struct page *page) 256void clear_user_page(void *addr, unsigned long vaddr, struct page *page)
242{ 257{
243 __flush_dcache(vaddr, vaddr + PAGE_SIZE); 258 __flush_dcache(vaddr, vaddr + PAGE_SIZE);
259 __flush_icache(vaddr, vaddr + PAGE_SIZE);
244 clear_page(addr); 260 clear_page(addr);
245 __flush_dcache((unsigned long)addr, (unsigned long)addr + PAGE_SIZE); 261 __flush_dcache((unsigned long)addr, (unsigned long)addr + PAGE_SIZE);
262 __flush_icache((unsigned long)addr, (unsigned long)addr + PAGE_SIZE);
246} 263}
247 264
248void copy_from_user_page(struct vm_area_struct *vma, struct page *page, 265void copy_from_user_page(struct vm_area_struct *vma, struct page *page,
@@ -251,7 +268,7 @@ void copy_from_user_page(struct vm_area_struct *vma, struct page *page,
251{ 268{
252 flush_cache_page(vma, user_vaddr, page_to_pfn(page)); 269 flush_cache_page(vma, user_vaddr, page_to_pfn(page));
253 memcpy(dst, src, len); 270 memcpy(dst, src, len);
254 __flush_dcache((unsigned long)src, (unsigned long)src + len); 271 __flush_dcache_all((unsigned long)src, (unsigned long)src + len);
255 if (vma->vm_flags & VM_EXEC) 272 if (vma->vm_flags & VM_EXEC)
256 __flush_icache((unsigned long)src, (unsigned long)src + len); 273 __flush_icache((unsigned long)src, (unsigned long)src + len);
257} 274}
@@ -262,7 +279,7 @@ void copy_to_user_page(struct vm_area_struct *vma, struct page *page,
262{ 279{
263 flush_cache_page(vma, user_vaddr, page_to_pfn(page)); 280 flush_cache_page(vma, user_vaddr, page_to_pfn(page));
264 memcpy(dst, src, len); 281 memcpy(dst, src, len);
265 __flush_dcache((unsigned long)dst, (unsigned long)dst + len); 282 __flush_dcache_all((unsigned long)dst, (unsigned long)dst + len);
266 if (vma->vm_flags & VM_EXEC) 283 if (vma->vm_flags & VM_EXEC)
267 __flush_icache((unsigned long)dst, (unsigned long)dst + len); 284 __flush_icache((unsigned long)dst, (unsigned long)dst + len);
268} 285}