diff options
Diffstat (limited to 'arch/sh/kernel')
-rw-r--r-- | arch/sh/kernel/cpu/init.c | 2 | ||||
-rw-r--r-- | arch/sh/kernel/cpu/sh2/probe.c | 1 | ||||
-rw-r--r-- | arch/sh/kernel/cpu/sh2a/probe.c | 2 | ||||
-rw-r--r-- | arch/sh/kernel/cpu/sh3/entry.S | 32 | ||||
-rw-r--r-- | arch/sh/kernel/cpu/sh3/probe.c | 2 | ||||
-rw-r--r-- | arch/sh/kernel/cpu/sh4/probe.c | 10 | ||||
-rw-r--r-- | arch/sh/kernel/cpu/sh4a/smp-shx3.c | 2 | ||||
-rw-r--r-- | arch/sh/kernel/cpu/sh5/probe.c | 2 | ||||
-rw-r--r-- | arch/sh/kernel/localtimer.c | 9 | ||||
-rw-r--r-- | arch/sh/kernel/process_64.c | 24 | ||||
-rw-r--r-- | arch/sh/kernel/setup.c | 1 | ||||
-rw-r--r-- | arch/sh/kernel/sh_ksyms_32.c | 6 | ||||
-rw-r--r-- | arch/sh/kernel/sh_ksyms_64.c | 9 | ||||
-rw-r--r-- | arch/sh/kernel/signal_64.c | 38 | ||||
-rw-r--r-- | arch/sh/kernel/time.c | 4 |
15 files changed, 66 insertions, 78 deletions
diff --git a/arch/sh/kernel/cpu/init.c b/arch/sh/kernel/cpu/init.c index d40b9db5be0..e932ebef473 100644 --- a/arch/sh/kernel/cpu/init.c +++ b/arch/sh/kernel/cpu/init.c @@ -299,11 +299,9 @@ asmlinkage void __init sh_cpu_init(void) cache_init(); if (raw_smp_processor_id() == 0) { -#ifdef CONFIG_MMU shm_align_mask = max_t(unsigned long, current_cpu_data.dcache.way_size - 1, PAGE_SIZE - 1); -#endif /* Boot CPU sets the cache shape */ detect_cache_shape(); diff --git a/arch/sh/kernel/cpu/sh2/probe.c b/arch/sh/kernel/cpu/sh2/probe.c index 5916d9096b9..1db6d888388 100644 --- a/arch/sh/kernel/cpu/sh2/probe.c +++ b/arch/sh/kernel/cpu/sh2/probe.c @@ -29,6 +29,7 @@ int __init detect_cpu_and_cache_system(void) */ boot_cpu_data.dcache.flags |= SH_CACHE_COMBINED; boot_cpu_data.icache = boot_cpu_data.dcache; + boot_cpu_data.family = CPU_FAMILY_SH2; return 0; } diff --git a/arch/sh/kernel/cpu/sh2a/probe.c b/arch/sh/kernel/cpu/sh2a/probe.c index e098e2f6aa0..6825d650716 100644 --- a/arch/sh/kernel/cpu/sh2a/probe.c +++ b/arch/sh/kernel/cpu/sh2a/probe.c @@ -15,6 +15,8 @@ int __init detect_cpu_and_cache_system(void) { + boot_cpu_data.family = CPU_FAMILY_SH2A; + /* All SH-2A CPUs have support for 16 and 32-bit opcodes.. */ boot_cpu_data.flags |= CPU_HAS_OP32; diff --git a/arch/sh/kernel/cpu/sh3/entry.S b/arch/sh/kernel/cpu/sh3/entry.S index 9421ec715fd..aebd33d18ff 100644 --- a/arch/sh/kernel/cpu/sh3/entry.S +++ b/arch/sh/kernel/cpu/sh3/entry.S @@ -113,35 +113,34 @@ OFF_TRA = (16*4+6*4) #if defined(CONFIG_MMU) .align 2 ENTRY(tlb_miss_load) - bra call_dpf + bra call_handle_tlbmiss mov #0, r5 .align 2 ENTRY(tlb_miss_store) - bra call_dpf + bra call_handle_tlbmiss mov #1, r5 .align 2 ENTRY(initial_page_write) - bra call_dpf - mov #1, r5 + bra call_handle_tlbmiss + mov #2, r5 .align 2 ENTRY(tlb_protection_violation_load) - bra call_dpf + bra call_do_page_fault mov #0, r5 .align 2 ENTRY(tlb_protection_violation_store) - bra call_dpf + bra call_do_page_fault mov #1, r5 -call_dpf: +call_handle_tlbmiss: setup_frame_reg mov.l 1f, r0 mov r5, r8 mov.l @r0, r6 - mov r6, r9 mov.l 2f, r0 sts pr, r10 jsr @r0 @@ -152,16 +151,25 @@ call_dpf: lds r10, pr rts nop -0: mov.l 3f, r0 - mov r9, r6 +0: mov r8, r5 +call_do_page_fault: + mov.l 1f, r0 + mov.l @r0, r6 + + sti + + mov.l 3f, r0 + mov.l 4f, r1 + mov r15, r4 jmp @r0 - mov r15, r4 + lds r1, pr .align 2 1: .long MMU_TEA -2: .long __do_page_fault +2: .long handle_tlbmiss 3: .long do_page_fault +4: .long ret_from_exception .align 2 ENTRY(address_error_load) diff --git a/arch/sh/kernel/cpu/sh3/probe.c b/arch/sh/kernel/cpu/sh3/probe.c index 10f2a760c5e..f9c7df64eb0 100644 --- a/arch/sh/kernel/cpu/sh3/probe.c +++ b/arch/sh/kernel/cpu/sh3/probe.c @@ -107,5 +107,7 @@ int __uses_jump_to_uncached detect_cpu_and_cache_system(void) boot_cpu_data.dcache.flags |= SH_CACHE_COMBINED; boot_cpu_data.icache = boot_cpu_data.dcache; + boot_cpu_data.family = CPU_FAMILY_SH3; + return 0; } diff --git a/arch/sh/kernel/cpu/sh4/probe.c b/arch/sh/kernel/cpu/sh4/probe.c index afd3e73d5ad..d36f0c45f55 100644 --- a/arch/sh/kernel/cpu/sh4/probe.c +++ b/arch/sh/kernel/cpu/sh4/probe.c @@ -57,8 +57,12 @@ int __init detect_cpu_and_cache_system(void) * Setup some generic flags we can probe on SH-4A parts */ if (((pvr >> 16) & 0xff) == 0x10) { - if ((cvr & 0x10000000) == 0) + boot_cpu_data.family = CPU_FAMILY_SH4A; + + if ((cvr & 0x10000000) == 0) { boot_cpu_data.flags |= CPU_HAS_DSP; + boot_cpu_data.family = CPU_FAMILY_SH4AL_DSP; + } boot_cpu_data.flags |= CPU_HAS_LLSC | CPU_HAS_PERF_COUNTER; boot_cpu_data.cut_major = pvr & 0x7f; @@ -68,6 +72,7 @@ int __init detect_cpu_and_cache_system(void) } else { /* And some SH-4 defaults.. */ boot_cpu_data.flags |= CPU_HAS_PTEA; + boot_cpu_data.family = CPU_FAMILY_SH4; } /* FPU detection works for everyone */ @@ -180,9 +185,6 @@ int __init detect_cpu_and_cache_system(void) boot_cpu_data.dcache.ways = 2; break; - default: - boot_cpu_data.type = CPU_SH_NONE; - break; } /* diff --git a/arch/sh/kernel/cpu/sh4a/smp-shx3.c b/arch/sh/kernel/cpu/sh4a/smp-shx3.c index 2b6b0d50c57..185ec3976a2 100644 --- a/arch/sh/kernel/cpu/sh4a/smp-shx3.c +++ b/arch/sh/kernel/cpu/sh4a/smp-shx3.c @@ -57,6 +57,8 @@ void __init plat_prepare_cpus(unsigned int max_cpus) { int i; + local_timer_setup(0); + BUILD_BUG_ON(SMP_MSG_NR >= 8); for (i = 0; i < SMP_MSG_NR; i++) diff --git a/arch/sh/kernel/cpu/sh5/probe.c b/arch/sh/kernel/cpu/sh5/probe.c index 92ad844b5c1..521d05b3f7b 100644 --- a/arch/sh/kernel/cpu/sh5/probe.c +++ b/arch/sh/kernel/cpu/sh5/probe.c @@ -34,6 +34,8 @@ int __init detect_cpu_and_cache_system(void) /* CPU.VCR aliased at CIR address on SH5-101 */ boot_cpu_data.type = CPU_SH5_101; + boot_cpu_data.family = CPU_FAMILY_SH5; + /* * First, setup some sane values for the I-cache. */ diff --git a/arch/sh/kernel/localtimer.c b/arch/sh/kernel/localtimer.c index 96e8eaea1e6..0b04e7d4a9b 100644 --- a/arch/sh/kernel/localtimer.c +++ b/arch/sh/kernel/localtimer.c @@ -22,6 +22,7 @@ #include <linux/jiffies.h> #include <linux/percpu.h> #include <linux/clockchips.h> +#include <linux/hardirq.h> #include <linux/irq.h> static DEFINE_PER_CPU(struct clock_event_device, local_clockevent); @@ -33,7 +34,9 @@ void local_timer_interrupt(void) { struct clock_event_device *clk = &__get_cpu_var(local_clockevent); + irq_enter(); clk->event_handler(clk); + irq_exit(); } static void dummy_timer_set_mode(enum clock_event_mode mode, @@ -46,8 +49,10 @@ void __cpuinit local_timer_setup(unsigned int cpu) struct clock_event_device *clk = &per_cpu(local_clockevent, cpu); clk->name = "dummy_timer"; - clk->features = CLOCK_EVT_FEAT_DUMMY; - clk->rating = 200; + clk->features = CLOCK_EVT_FEAT_ONESHOT | + CLOCK_EVT_FEAT_PERIODIC | + CLOCK_EVT_FEAT_DUMMY; + clk->rating = 400; clk->mult = 1; clk->set_mode = dummy_timer_set_mode; clk->broadcast = smp_timer_broadcast; diff --git a/arch/sh/kernel/process_64.c b/arch/sh/kernel/process_64.c index 24de7421494..1192398ef58 100644 --- a/arch/sh/kernel/process_64.c +++ b/arch/sh/kernel/process_64.c @@ -425,7 +425,6 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, struct task_struct *p, struct pt_regs *regs) { struct pt_regs *childregs; - unsigned long long se; /* Sign extension */ #ifdef CONFIG_SH_FPU if(last_task_used_math == current) { @@ -441,11 +440,19 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, *childregs = *regs; + /* + * Sign extend the edited stack. + * Note that thread.pc and thread.pc will stay + * 32-bit wide and context switch must take care + * of NEFF sign extension. + */ if (user_mode(regs)) { - childregs->regs[15] = usp; + childregs->regs[15] = neff_sign_extend(usp); p->thread.uregs = childregs; } else { - childregs->regs[15] = (unsigned long)task_stack_page(p) + THREAD_SIZE; + childregs->regs[15] = + neff_sign_extend((unsigned long)task_stack_page(p) + + THREAD_SIZE); } childregs->regs[9] = 0; /* Set return value for child */ @@ -454,17 +461,6 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, p->thread.sp = (unsigned long) childregs; p->thread.pc = (unsigned long) ret_from_fork; - /* - * Sign extend the edited stack. - * Note that thread.pc and thread.pc will stay - * 32-bit wide and context switch must take care - * of NEFF sign extension. - */ - - se = childregs->regs[15]; - se = (se & NEFF_SIGN) ? (se | NEFF_MASK) : se; - childregs->regs[15] = se; - return 0; } diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c index d13bbafb4e1..f9d44f8e0df 100644 --- a/arch/sh/kernel/setup.c +++ b/arch/sh/kernel/setup.c @@ -49,6 +49,7 @@ struct sh_cpuinfo cpu_data[NR_CPUS] __read_mostly = { [0] = { .type = CPU_SH_NONE, + .family = CPU_FAMILY_UNKNOWN, .loops_per_jiffy = 10000000, }, }; diff --git a/arch/sh/kernel/sh_ksyms_32.c b/arch/sh/kernel/sh_ksyms_32.c index cec610888e2..8dbe26b17c4 100644 --- a/arch/sh/kernel/sh_ksyms_32.c +++ b/arch/sh/kernel/sh_ksyms_32.c @@ -101,11 +101,6 @@ EXPORT_SYMBOL(flush_cache_range); EXPORT_SYMBOL(flush_dcache_page); #endif -#if !defined(CONFIG_CACHE_OFF) && defined(CONFIG_MMU) && \ - (defined(CONFIG_CPU_SH4) || defined(CONFIG_SH7705_CACHE_32KB)) -EXPORT_SYMBOL(clear_user_page); -#endif - #ifdef CONFIG_MCOUNT DECLARE_EXPORT(mcount); #endif @@ -114,7 +109,6 @@ EXPORT_SYMBOL(csum_partial_copy_generic); #ifdef CONFIG_IPV6 EXPORT_SYMBOL(csum_ipv6_magic); #endif -EXPORT_SYMBOL(clear_page); EXPORT_SYMBOL(copy_page); EXPORT_SYMBOL(__clear_user); EXPORT_SYMBOL(_ebss); diff --git a/arch/sh/kernel/sh_ksyms_64.c b/arch/sh/kernel/sh_ksyms_64.c index f5bd156ea50..d008e17eb25 100644 --- a/arch/sh/kernel/sh_ksyms_64.c +++ b/arch/sh/kernel/sh_ksyms_64.c @@ -30,14 +30,6 @@ extern int dump_fpu(struct pt_regs *, elf_fpregset_t *); EXPORT_SYMBOL(dump_fpu); EXPORT_SYMBOL(kernel_thread); -#if !defined(CONFIG_CACHE_OFF) && defined(CONFIG_MMU) -EXPORT_SYMBOL(clear_user_page); -#endif - -#ifndef CONFIG_CACHE_OFF -EXPORT_SYMBOL(flush_dcache_page); -#endif - #ifdef CONFIG_VT EXPORT_SYMBOL(screen_info); #endif @@ -52,7 +44,6 @@ EXPORT_SYMBOL(__get_user_asm_l); EXPORT_SYMBOL(__get_user_asm_q); EXPORT_SYMBOL(__strnlen_user); EXPORT_SYMBOL(__strncpy_from_user); -EXPORT_SYMBOL(clear_page); EXPORT_SYMBOL(__clear_user); EXPORT_SYMBOL(copy_page); EXPORT_SYMBOL(__copy_user); diff --git a/arch/sh/kernel/signal_64.c b/arch/sh/kernel/signal_64.c index 0663a0ee602..026fd1cfe17 100644 --- a/arch/sh/kernel/signal_64.c +++ b/arch/sh/kernel/signal_64.c @@ -561,13 +561,11 @@ static int setup_frame(int sig, struct k_sigaction *ka, /* Set up to return from userspace. If provided, use a stub already in userspace. */ if (ka->sa.sa_flags & SA_RESTORER) { - DEREF_REG_PR = (unsigned long) ka->sa.sa_restorer | 0x1; - /* * On SH5 all edited pointers are subject to NEFF */ - DEREF_REG_PR = (DEREF_REG_PR & NEFF_SIGN) ? - (DEREF_REG_PR | NEFF_MASK) : DEREF_REG_PR; + DEREF_REG_PR = neff_sign_extend((unsigned long) + ka->sa.sa_restorer | 0x1); } else { /* * Different approach on SH5. @@ -580,9 +578,8 @@ static int setup_frame(int sig, struct k_sigaction *ka, * . being code, linker turns ShMedia bit on, always * dereference index -1. */ - DEREF_REG_PR = (unsigned long) frame->retcode | 0x01; - DEREF_REG_PR = (DEREF_REG_PR & NEFF_SIGN) ? - (DEREF_REG_PR | NEFF_MASK) : DEREF_REG_PR; + DEREF_REG_PR = neff_sign_extend((unsigned long) + frame->retcode | 0x01); if (__copy_to_user(frame->retcode, (void *)((unsigned long)sa_default_restorer & (~1)), 16) != 0) @@ -596,9 +593,7 @@ static int setup_frame(int sig, struct k_sigaction *ka, * Set up registers for signal handler. * All edited pointers are subject to NEFF. */ - regs->regs[REG_SP] = (unsigned long) frame; - regs->regs[REG_SP] = (regs->regs[REG_SP] & NEFF_SIGN) ? - (regs->regs[REG_SP] | NEFF_MASK) : regs->regs[REG_SP]; + regs->regs[REG_SP] = neff_sign_extend((unsigned long)frame); regs->regs[REG_ARG1] = signal; /* Arg for signal handler */ /* FIXME: @@ -613,8 +608,7 @@ static int setup_frame(int sig, struct k_sigaction *ka, regs->regs[REG_ARG2] = (unsigned long long)(unsigned long)(signed long)&frame->sc; regs->regs[REG_ARG3] = (unsigned long long)(unsigned long)(signed long)&frame->sc; - regs->pc = (unsigned long) ka->sa.sa_handler; - regs->pc = (regs->pc & NEFF_SIGN) ? (regs->pc | NEFF_MASK) : regs->pc; + regs->pc = neff_sign_extend((unsigned long)ka->sa.sa_handler); set_fs(USER_DS); @@ -676,13 +670,11 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, /* Set up to return from userspace. If provided, use a stub already in userspace. */ if (ka->sa.sa_flags & SA_RESTORER) { - DEREF_REG_PR = (unsigned long) ka->sa.sa_restorer | 0x1; - /* * On SH5 all edited pointers are subject to NEFF */ - DEREF_REG_PR = (DEREF_REG_PR & NEFF_SIGN) ? - (DEREF_REG_PR | NEFF_MASK) : DEREF_REG_PR; + DEREF_REG_PR = neff_sign_extend((unsigned long) + ka->sa.sa_restorer | 0x1); } else { /* * Different approach on SH5. @@ -695,15 +687,14 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, * . being code, linker turns ShMedia bit on, always * dereference index -1. */ - - DEREF_REG_PR = (unsigned long) frame->retcode | 0x01; - DEREF_REG_PR = (DEREF_REG_PR & NEFF_SIGN) ? - (DEREF_REG_PR | NEFF_MASK) : DEREF_REG_PR; + DEREF_REG_PR = neff_sign_extend((unsigned long) + frame->retcode | 0x01); if (__copy_to_user(frame->retcode, (void *)((unsigned long)sa_default_rt_restorer & (~1)), 16) != 0) goto give_sigsegv; + /* Cohere the trampoline with the I-cache. */ flush_icache_range(DEREF_REG_PR-1, DEREF_REG_PR-1+15); } @@ -711,14 +702,11 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, * Set up registers for signal handler. * All edited pointers are subject to NEFF. */ - regs->regs[REG_SP] = (unsigned long) frame; - regs->regs[REG_SP] = (regs->regs[REG_SP] & NEFF_SIGN) ? - (regs->regs[REG_SP] | NEFF_MASK) : regs->regs[REG_SP]; + regs->regs[REG_SP] = neff_sign_extend((unsigned long)frame); regs->regs[REG_ARG1] = signal; /* Arg for signal handler */ regs->regs[REG_ARG2] = (unsigned long long)(unsigned long)(signed long)&frame->info; regs->regs[REG_ARG3] = (unsigned long long)(unsigned long)(signed long)&frame->uc.uc_mcontext; - regs->pc = (unsigned long) ka->sa.sa_handler; - regs->pc = (regs->pc & NEFF_SIGN) ? (regs->pc | NEFF_MASK) : regs->pc; + regs->pc = neff_sign_extend((unsigned long)ka->sa.sa_handler); set_fs(USER_DS); diff --git a/arch/sh/kernel/time.c b/arch/sh/kernel/time.c index 7f95f479060..632aff53328 100644 --- a/arch/sh/kernel/time.c +++ b/arch/sh/kernel/time.c @@ -119,9 +119,5 @@ void __init time_init(void) set_normalized_timespec(&wall_to_monotonic, -xtime.tv_sec, -xtime.tv_nsec); -#ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST - local_timer_setup(smp_processor_id()); -#endif - late_time_init = sh_late_time_init; } |