diff options
Diffstat (limited to 'arch/nios2')
-rw-r--r-- | arch/nios2/include/asm/Kbuild | 1 | ||||
-rw-r--r-- | arch/nios2/include/asm/shmparam.h | 21 | ||||
-rw-r--r-- | arch/nios2/include/asm/thread_info.h | 2 | ||||
-rw-r--r-- | arch/nios2/include/uapi/asm/ptrace.h | 2 | ||||
-rw-r--r-- | arch/nios2/kernel/cpuinfo.c | 77 | ||||
-rw-r--r-- | arch/nios2/kernel/entry.S | 71 | ||||
-rw-r--r-- | arch/nios2/kernel/process.c | 1 | ||||
-rw-r--r-- | arch/nios2/kernel/traps.c | 34 | ||||
-rw-r--r-- | arch/nios2/mm/cacheflush.c | 55 |
9 files changed, 166 insertions, 98 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 generic-y += sembuf.h generic-y += serial.h generic-y += shmbuf.h -generic-y += shmparam.h generic-y += siginfo.h generic-y += signal.h generic-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 @@ +/* + * Copyright Altera Corporation (C) <2015>. All rights reserved + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see <http://www.gnu.org/licenses/>. + */ +#ifndef _ASM_NIOS2_SHMPARAM_H +#define _ASM_NIOS2_SHMPARAM_H + +#define SHMLBA CONFIG_NIOS2_DCACHE_SIZE + +#endif /* _ASM_NIOS2_SHMPARAM_H */ diff --git a/arch/nios2/include/asm/thread_info.h b/arch/nios2/include/asm/thread_info.h index a16e55cbd8ad..d69c338bd19c 100644 --- a/arch/nios2/include/asm/thread_info.h +++ b/arch/nios2/include/asm/thread_info.h @@ -39,7 +39,6 @@ typedef struct { */ struct thread_info { struct task_struct *task; /* main task structure */ - struct exec_domain *exec_domain; /* execution domain */ unsigned long flags; /* low level flags */ __u32 cpu; /* current CPU */ int preempt_count; /* 0 => preemptable,<0 => BUG */ @@ -58,7 +57,6 @@ struct thread_info { #define INIT_THREAD_INFO(tsk) \ { \ .task = &tsk, \ - .exec_domain = &default_exec_domain, \ .flags = 0, \ .cpu = 0, \ .preempt_count = INIT_PREEMPT_COUNT, \ 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 @@ #ifndef __ASSEMBLY__ +#include <linux/types.h> + /* * Register numbers used by 'ptrace' system call interface. */ diff --git a/arch/nios2/kernel/cpuinfo.c b/arch/nios2/kernel/cpuinfo.c index a223691dff4f..1d96de0bd4aa 100644 --- a/arch/nios2/kernel/cpuinfo.c +++ b/arch/nios2/kernel/cpuinfo.c @@ -126,47 +126,46 @@ void __init setup_cpuinfo(void) */ static int show_cpuinfo(struct seq_file *m, void *v) { - int count = 0; const u32 clockfreq = cpuinfo.cpu_clock_freq; - count = seq_printf(m, - "CPU:\t\tNios II/%s\n" - "MMU:\t\t%s\n" - "FPU:\t\tnone\n" - "Clocking:\t%u.%02u MHz\n" - "BogoMips:\t%lu.%02lu\n" - "Calibration:\t%lu loops\n", - cpuinfo.cpu_impl, - cpuinfo.mmu ? "present" : "none", - clockfreq / 1000000, (clockfreq / 100000) % 10, - (loops_per_jiffy * HZ) / 500000, - ((loops_per_jiffy * HZ) / 5000) % 100, - (loops_per_jiffy * HZ)); - - count += seq_printf(m, - "HW:\n" - " MUL:\t\t%s\n" - " MULX:\t\t%s\n" - " DIV:\t\t%s\n", - cpuinfo.has_mul ? "yes" : "no", - cpuinfo.has_mulx ? "yes" : "no", - cpuinfo.has_div ? "yes" : "no"); - - count += seq_printf(m, - "Icache:\t\t%ukB, line length: %u\n", - cpuinfo.icache_size >> 10, - cpuinfo.icache_line_size); - - count += seq_printf(m, - "Dcache:\t\t%ukB, line length: %u\n", - cpuinfo.dcache_size >> 10, - cpuinfo.dcache_line_size); - - count += seq_printf(m, - "TLB:\t\t%u ways, %u entries, %u PID bits\n", - cpuinfo.tlb_num_ways, - cpuinfo.tlb_num_entries, - cpuinfo.tlb_pid_num_bits); + seq_printf(m, + "CPU:\t\tNios II/%s\n" + "MMU:\t\t%s\n" + "FPU:\t\tnone\n" + "Clocking:\t%u.%02u MHz\n" + "BogoMips:\t%lu.%02lu\n" + "Calibration:\t%lu loops\n", + cpuinfo.cpu_impl, + cpuinfo.mmu ? "present" : "none", + clockfreq / 1000000, (clockfreq / 100000) % 10, + (loops_per_jiffy * HZ) / 500000, + ((loops_per_jiffy * HZ) / 5000) % 100, + (loops_per_jiffy * HZ)); + + seq_printf(m, + "HW:\n" + " MUL:\t\t%s\n" + " MULX:\t\t%s\n" + " DIV:\t\t%s\n", + cpuinfo.has_mul ? "yes" : "no", + cpuinfo.has_mulx ? "yes" : "no", + cpuinfo.has_div ? "yes" : "no"); + + seq_printf(m, + "Icache:\t\t%ukB, line length: %u\n", + cpuinfo.icache_size >> 10, + cpuinfo.icache_line_size); + + seq_printf(m, + "Dcache:\t\t%ukB, line length: %u\n", + cpuinfo.dcache_size >> 10, + cpuinfo.dcache_line_size); + + seq_printf(m, + "TLB:\t\t%u ways, %u entries, %u PID bits\n", + cpuinfo.tlb_num_ways, + cpuinfo.tlb_num_entries, + cpuinfo.tlb_pid_num_bits); return 0; } 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: trap_table: .word handle_system_call /* 0 */ - .word instruction_trap /* 1 */ - .word instruction_trap /* 2 */ - .word instruction_trap /* 3 */ - .word instruction_trap /* 4 */ - .word instruction_trap /* 5 */ - .word instruction_trap /* 6 */ - .word instruction_trap /* 7 */ - .word instruction_trap /* 8 */ - .word instruction_trap /* 9 */ - .word instruction_trap /* 10 */ - .word instruction_trap /* 11 */ - .word instruction_trap /* 12 */ - .word instruction_trap /* 13 */ - .word instruction_trap /* 14 */ - .word instruction_trap /* 15 */ - .word instruction_trap /* 16 */ - .word instruction_trap /* 17 */ - .word instruction_trap /* 18 */ - .word instruction_trap /* 19 */ - .word instruction_trap /* 20 */ - .word instruction_trap /* 21 */ - .word instruction_trap /* 22 */ - .word instruction_trap /* 23 */ - .word instruction_trap /* 24 */ - .word instruction_trap /* 25 */ - .word instruction_trap /* 26 */ - .word instruction_trap /* 27 */ - .word instruction_trap /* 28 */ - .word instruction_trap /* 29 */ + .word handle_trap_1 /* 1 */ + .word handle_trap_2 /* 2 */ + .word handle_trap_3 /* 3 */ + .word handle_trap_reserved /* 4 */ + .word handle_trap_reserved /* 5 */ + .word handle_trap_reserved /* 6 */ + .word handle_trap_reserved /* 7 */ + .word handle_trap_reserved /* 8 */ + .word handle_trap_reserved /* 9 */ + .word handle_trap_reserved /* 10 */ + .word handle_trap_reserved /* 11 */ + .word handle_trap_reserved /* 12 */ + .word handle_trap_reserved /* 13 */ + .word handle_trap_reserved /* 14 */ + .word handle_trap_reserved /* 15 */ + .word handle_trap_reserved /* 16 */ + .word handle_trap_reserved /* 17 */ + .word handle_trap_reserved /* 18 */ + .word handle_trap_reserved /* 19 */ + .word handle_trap_reserved /* 20 */ + .word handle_trap_reserved /* 21 */ + .word handle_trap_reserved /* 22 */ + .word handle_trap_reserved /* 23 */ + .word handle_trap_reserved /* 24 */ + .word handle_trap_reserved /* 25 */ + .word handle_trap_reserved /* 26 */ + .word handle_trap_reserved /* 27 */ + .word handle_trap_reserved /* 28 */ + .word handle_trap_reserved /* 29 */ #ifdef CONFIG_KGDB .word handle_kgdb_breakpoint /* 30 KGDB breakpoint */ #else @@ -455,6 +455,19 @@ handle_kgdb_breakpoint: br ret_from_exception #endif +handle_trap_1: + call handle_trap_1_c + br ret_from_exception + +handle_trap_2: + call handle_trap_2_c + br ret_from_exception + +handle_trap_3: +handle_trap_reserved: + call handle_trap_3_c + br ret_from_exception + /* * Beware - when entering resume, prev (the current task) is * in r4, next (the new task) is in r5, don't change these diff --git a/arch/nios2/kernel/process.c b/arch/nios2/kernel/process.c index 0e075b5ad2a5..2f8c74f93e70 100644 --- a/arch/nios2/kernel/process.c +++ b/arch/nios2/kernel/process.c @@ -94,7 +94,6 @@ void show_regs(struct pt_regs *regs) void flush_thread(void) { - set_fs(USER_DS); } int copy_thread(unsigned long clone_flags, 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 @@ static DEFINE_SPINLOCK(die_lock); +static void _send_sig(int signo, int code, unsigned long addr) +{ + siginfo_t info; + + info.si_signo = signo; + info.si_errno = 0; + info.si_code = code; + info.si_addr = (void __user *) addr; + force_sig_info(signo, &info, current); +} + void die(const char *str, struct pt_regs *regs, long err) { console_verbose(); @@ -39,16 +50,10 @@ void die(const char *str, struct pt_regs *regs, long err) void _exception(int signo, struct pt_regs *regs, int code, unsigned long addr) { - siginfo_t info; - if (!user_mode(regs)) die("Exception in kernel mode", regs, signo); - info.si_signo = signo; - info.si_errno = 0; - info.si_code = code; - info.si_addr = (void __user *) addr; - force_sig_info(signo, &info, current); + _send_sig(signo, code, addr); } /* @@ -183,3 +188,18 @@ asmlinkage void unhandled_exception(struct pt_regs *regs, int cause) pr_emerg("opcode: 0x%08lx\n", *(unsigned long *)(regs->ea)); } + +asmlinkage void handle_trap_1_c(struct pt_regs *fp) +{ + _send_sig(SIGUSR1, 0, fp->ea); +} + +asmlinkage void handle_trap_2_c(struct pt_regs *fp) +{ + _send_sig(SIGUSR2, 0, fp->ea); +} + +asmlinkage void handle_trap_3_c(struct pt_regs *fp) +{ + _send_sig(SIGILL, ILL_ILLTRP, fp->ea); +} 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) end += (cpuinfo.dcache_line_size - 1); end &= ~(cpuinfo.dcache_line_size - 1); - if (end > start + cpuinfo.dcache_size) - end = start + cpuinfo.dcache_size; - for (addr = start; addr < end; addr += cpuinfo.dcache_line_size) { __asm__ __volatile__ (" initda 0(%0)\n" : /* Outputs */ @@ -131,12 +128,14 @@ void flush_cache_dup_mm(struct mm_struct *mm) void flush_icache_range(unsigned long start, unsigned long end) { + __flush_dcache(start, end); __flush_icache(start, end); } void flush_dcache_range(unsigned long start, unsigned long end) { __flush_dcache(start, end); + __flush_icache(start, end); } EXPORT_SYMBOL(flush_dcache_range); @@ -159,6 +158,7 @@ void flush_icache_page(struct vm_area_struct *vma, struct page *page) unsigned long start = (unsigned long) page_address(page); unsigned long end = start + PAGE_SIZE; + __flush_dcache(start, end); __flush_icache(start, end); } @@ -173,6 +173,18 @@ void flush_cache_page(struct vm_area_struct *vma, unsigned long vmaddr, __flush_icache(start, end); } +void __flush_dcache_page(struct address_space *mapping, struct page *page) +{ + /* + * Writeback any data associated with the kernel mapping of this + * page. This ensures that data in the physical page is mutually + * coherent with the kernels mapping. + */ + unsigned long start = (unsigned long)page_address(page); + + __flush_dcache_all(start, start + PAGE_SIZE); +} + void flush_dcache_page(struct page *page) { struct address_space *mapping; @@ -190,11 +202,12 @@ void flush_dcache_page(struct page *page) if (mapping && !mapping_mapped(mapping)) { clear_bit(PG_dcache_clean, &page->flags); } else { - unsigned long start = (unsigned long)page_address(page); - - __flush_dcache_all(start, start + PAGE_SIZE); - if (mapping) + __flush_dcache_page(mapping, page); + if (mapping) { + unsigned long start = (unsigned long)page_address(page); flush_aliases(mapping, page); + flush_icache_range(start, start + PAGE_SIZE); + } set_bit(PG_dcache_clean, &page->flags); } } @@ -205,6 +218,7 @@ void update_mmu_cache(struct vm_area_struct *vma, { unsigned long pfn = pte_pfn(*pte); struct page *page; + struct address_space *mapping; if (!pfn_valid(pfn)) return; @@ -217,16 +231,15 @@ void update_mmu_cache(struct vm_area_struct *vma, if (page == ZERO_PAGE(0)) return; - if (!PageReserved(page) && - !test_and_set_bit(PG_dcache_clean, &page->flags)) { - unsigned long start = page_to_virt(page); - struct address_space *mapping; - - __flush_dcache(start, start + PAGE_SIZE); - - mapping = page_mapping(page); - if (mapping) - flush_aliases(mapping, page); + mapping = page_mapping(page); + if (!test_and_set_bit(PG_dcache_clean, &page->flags)) + __flush_dcache_page(mapping, page); + + if(mapping) + { + flush_aliases(mapping, page); + if (vma->vm_flags & VM_EXEC) + flush_icache_page(vma, page); } } @@ -234,15 +247,19 @@ void copy_user_page(void *vto, void *vfrom, unsigned long vaddr, struct page *to) { __flush_dcache(vaddr, vaddr + PAGE_SIZE); + __flush_icache(vaddr, vaddr + PAGE_SIZE); copy_page(vto, vfrom); __flush_dcache((unsigned long)vto, (unsigned long)vto + PAGE_SIZE); + __flush_icache((unsigned long)vto, (unsigned long)vto + PAGE_SIZE); } void clear_user_page(void *addr, unsigned long vaddr, struct page *page) { __flush_dcache(vaddr, vaddr + PAGE_SIZE); + __flush_icache(vaddr, vaddr + PAGE_SIZE); clear_page(addr); __flush_dcache((unsigned long)addr, (unsigned long)addr + PAGE_SIZE); + __flush_icache((unsigned long)addr, (unsigned long)addr + PAGE_SIZE); } void 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, { flush_cache_page(vma, user_vaddr, page_to_pfn(page)); memcpy(dst, src, len); - __flush_dcache((unsigned long)src, (unsigned long)src + len); + __flush_dcache_all((unsigned long)src, (unsigned long)src + len); if (vma->vm_flags & VM_EXEC) __flush_icache((unsigned long)src, (unsigned long)src + len); } @@ -262,7 +279,7 @@ void copy_to_user_page(struct vm_area_struct *vma, struct page *page, { flush_cache_page(vma, user_vaddr, page_to_pfn(page)); memcpy(dst, src, len); - __flush_dcache((unsigned long)dst, (unsigned long)dst + len); + __flush_dcache_all((unsigned long)dst, (unsigned long)dst + len); if (vma->vm_flags & VM_EXEC) __flush_icache((unsigned long)dst, (unsigned long)dst + len); } |