diff options
Diffstat (limited to 'arch/sh/kernel')
25 files changed, 557 insertions, 606 deletions
diff --git a/arch/sh/kernel/Makefile b/arch/sh/kernel/Makefile index 2f6d2bcb1c9..ff30d7f5804 100644 --- a/arch/sh/kernel/Makefile +++ b/arch/sh/kernel/Makefile @@ -6,7 +6,8 @@ extra-y := head.o init_task.o vmlinux.lds obj-y := process.o signal.o traps.o irq.o \ ptrace.o setup.o time.o sys_sh.o semaphore.o \ - io.o io_generic.o sh_ksyms.o syscalls.o + io.o io_generic.o sh_ksyms.o syscalls.o \ + debugtraps.o obj-y += cpu/ timers/ obj-$(CONFIG_VSYSCALL) += vsyscall/ diff --git a/arch/sh/kernel/cpu/init.c b/arch/sh/kernel/cpu/init.c index 48121766e8d..4b339a640b1 100644 --- a/arch/sh/kernel/cpu/init.c +++ b/arch/sh/kernel/cpu/init.c @@ -3,7 +3,7 @@ * * CPU init code * - * Copyright (C) 2002, 2003 Paul Mundt + * Copyright (C) 2002 - 2006 Paul Mundt * Copyright (C) 2003 Richard Curnow * * This file is subject to the terms and conditions of the GNU General Public @@ -12,6 +12,8 @@ */ #include <linux/init.h> #include <linux/kernel.h> +#include <linux/mm.h> +#include <asm/mmu_context.h> #include <asm/processor.h> #include <asm/uaccess.h> #include <asm/page.h> @@ -46,7 +48,7 @@ static void __init cache_init(void) { unsigned long ccr, flags; - if (cpu_data->type == CPU_SH_NONE) + if (current_cpu_data.type == CPU_SH_NONE) panic("Unknown CPU"); jump_to_P2(); @@ -66,7 +68,7 @@ static void __init cache_init(void) if (ccr & CCR_CACHE_ENABLE) { unsigned long ways, waysize, addrstart; - waysize = cpu_data->dcache.sets; + waysize = current_cpu_data.dcache.sets; #ifdef CCR_CACHE_ORA /* @@ -77,7 +79,7 @@ static void __init cache_init(void) waysize >>= 1; #endif - waysize <<= cpu_data->dcache.entry_shift; + waysize <<= current_cpu_data.dcache.entry_shift; #ifdef CCR_CACHE_EMODE /* If EMODE is not set, we only have 1 way to flush. */ @@ -85,7 +87,7 @@ static void __init cache_init(void) ways = 1; else #endif - ways = cpu_data->dcache.ways; + ways = current_cpu_data.dcache.ways; addrstart = CACHE_OC_ADDRESS_ARRAY; do { @@ -93,10 +95,10 @@ static void __init cache_init(void) for (addr = addrstart; addr < addrstart + waysize; - addr += cpu_data->dcache.linesz) + addr += current_cpu_data.dcache.linesz) ctrl_outl(0, addr); - addrstart += cpu_data->dcache.way_incr; + addrstart += current_cpu_data.dcache.way_incr; } while (--ways); } @@ -108,7 +110,7 @@ static void __init cache_init(void) #ifdef CCR_CACHE_EMODE /* Force EMODE if possible */ - if (cpu_data->dcache.ways > 1) + if (current_cpu_data.dcache.ways > 1) flags |= CCR_CACHE_EMODE; else flags &= ~CCR_CACHE_EMODE; @@ -125,10 +127,10 @@ static void __init cache_init(void) #ifdef CONFIG_SH_OCRAM /* Turn on OCRAM -- halve the OC */ flags |= CCR_CACHE_ORA; - cpu_data->dcache.sets >>= 1; + current_cpu_data.dcache.sets >>= 1; - cpu_data->dcache.way_size = cpu_data->dcache.sets * - cpu_data->dcache.linesz; + current_cpu_data.dcache.way_size = current_cpu_data.dcache.sets * + current_cpu_data.dcache.linesz; #endif ctrl_outl(flags, CCR); @@ -170,7 +172,7 @@ static void __init dsp_init(void) /* If the DSP bit is still set, this CPU has a DSP */ if (sr & SR_DSP) - cpu_data->flags |= CPU_HAS_DSP; + current_cpu_data.flags |= CPU_HAS_DSP; /* Now that we've determined the DSP status, clear the DSP bit. */ release_dsp(); @@ -202,22 +204,28 @@ asmlinkage void __init sh_cpu_init(void) cache_init(); shm_align_mask = max_t(unsigned long, - cpu_data->dcache.way_size - 1, + current_cpu_data.dcache.way_size - 1, PAGE_SIZE - 1); /* Disable the FPU */ if (fpu_disabled) { printk("FPU Disabled\n"); - cpu_data->flags &= ~CPU_HAS_FPU; + current_cpu_data.flags &= ~CPU_HAS_FPU; disable_fpu(); } /* FPU initialization */ - if ((cpu_data->flags & CPU_HAS_FPU)) { + if ((current_cpu_data.flags & CPU_HAS_FPU)) { clear_thread_flag(TIF_USEDFPU); clear_used_math(); } + /* + * Initialize the per-CPU ASID cache very early, since the + * TLB flushing routines depend on this being setup. + */ + current_cpu_data.asid_cache = NO_CONTEXT; + #ifdef CONFIG_SH_DSP /* Probe for DSP */ dsp_init(); @@ -225,7 +233,7 @@ asmlinkage void __init sh_cpu_init(void) /* Disable the DSP */ if (dsp_disabled) { printk("DSP Disabled\n"); - cpu_data->flags &= ~CPU_HAS_DSP; + current_cpu_data.flags &= ~CPU_HAS_DSP; release_dsp(); } #endif @@ -240,4 +248,3 @@ asmlinkage void __init sh_cpu_init(void) ubc_wakeup(); #endif } - diff --git a/arch/sh/kernel/cpu/irq/ipr.c b/arch/sh/kernel/cpu/irq/ipr.c index 35eb5751a3a..210280b6fdd 100644 --- a/arch/sh/kernel/cpu/irq/ipr.c +++ b/arch/sh/kernel/cpu/irq/ipr.c @@ -43,16 +43,29 @@ static struct irq_chip ipr_irq_chip = { .mask_ack = disable_ipr_irq, }; +unsigned int map_ipridx_to_addr(int idx) __attribute__ ((weak)); +unsigned int map_ipridx_to_addr(int idx) +{ + return 0; +} + void make_ipr_irq(struct ipr_data *table, unsigned int nr_irqs) { int i; for (i = 0; i < nr_irqs; i++) { unsigned int irq = table[i].irq; - table[i].addr = map_ipridx_to_addr(table[i].ipr_idx); + + if (!irq) + irq = table[i].irq = i; + /* could the IPR index be mapped, if not we ignore this */ - if (table[i].addr == 0) - continue; + if (!table[i].addr) { + table[i].addr = map_ipridx_to_addr(table[i].ipr_idx); + if (!table[i].addr) + continue; + } + disable_irq_nosync(irq); set_irq_chip_and_handler_name(irq, &ipr_irq_chip, handle_level_irq, "level"); diff --git a/arch/sh/kernel/cpu/sh2/entry.S b/arch/sh/kernel/cpu/sh2/entry.S index d51fa5e9904..7f7d292f36e 100644 --- a/arch/sh/kernel/cpu/sh2/entry.S +++ b/arch/sh/kernel/cpu/sh2/entry.S @@ -178,12 +178,10 @@ interrupt_entry: 8: .long do_exception_error trap_entry: - /* verbose BUG trapa entry check */ - mov #0x3e,r8 - cmp/ge r8,r9 - bf/s 1f - add #-0x10,r9 - add #0x10,r9 + mov #0x30,r8 + cmp/ge r8,r9 ! vector 0x20-0x2f is systemcall + bt 1f + add #-0x10,r9 ! convert SH2 to SH3/4 ABI 1: shll2 r9 ! TRA mov #OFF_TRA,r8 @@ -206,7 +204,7 @@ trap_entry: #if defined(CONFIG_SH_STANDARD_BIOS) /* Unwind the stack and jmp to the debug entry */ -debug_kernel_fw: +ENTRY(sh_bios_handler) mov r15,r0 add #(22-4)*4-4,r0 ldc.l @r0+,gbr diff --git a/arch/sh/kernel/cpu/sh2/probe.c b/arch/sh/kernel/cpu/sh2/probe.c index ba527d9b502..108e81b682e 100644 --- a/arch/sh/kernel/cpu/sh2/probe.c +++ b/arch/sh/kernel/cpu/sh2/probe.c @@ -18,27 +18,27 @@ int __init detect_cpu_and_cache_system(void) { #if defined(CONFIG_CPU_SUBTYPE_SH7604) - cpu_data->type = CPU_SH7604; - cpu_data->dcache.ways = 4; - cpu_data->dcache.way_incr = (1<<10); - cpu_data->dcache.sets = 64; - cpu_data->dcache.entry_shift = 4; - cpu_data->dcache.linesz = L1_CACHE_BYTES; - cpu_data->dcache.flags = 0; + current_cpu_data.type = CPU_SH7604; + current_cpu_data.dcache.ways = 4; + current_cpu_data.dcache.way_incr = (1<<10); + current_cpu_data.dcache.sets = 64; + current_cpu_data.dcache.entry_shift = 4; + current_cpu_data.dcache.linesz = L1_CACHE_BYTES; + current_cpu_data.dcache.flags = 0; #elif defined(CONFIG_CPU_SUBTYPE_SH7619) - cpu_data->type = CPU_SH7619; - cpu_data->dcache.ways = 4; - cpu_data->dcache.way_incr = (1<<12); - cpu_data->dcache.sets = 256; - cpu_data->dcache.entry_shift = 4; - cpu_data->dcache.linesz = L1_CACHE_BYTES; - cpu_data->dcache.flags = 0; + current_cpu_data.type = CPU_SH7619; + current_cpu_data.dcache.ways = 4; + current_cpu_data.dcache.way_incr = (1<<12); + current_cpu_data.dcache.sets = 256; + current_cpu_data.dcache.entry_shift = 4; + current_cpu_data.dcache.linesz = L1_CACHE_BYTES; + current_cpu_data.dcache.flags = 0; #endif /* * SH-2 doesn't have separate caches */ - cpu_data->dcache.flags |= SH_CACHE_COMBINED; - cpu_data->icache = cpu_data->dcache; + current_cpu_data.dcache.flags |= SH_CACHE_COMBINED; + current_cpu_data.icache = current_cpu_data.dcache; return 0; } diff --git a/arch/sh/kernel/cpu/sh2/setup-sh7619.c b/arch/sh/kernel/cpu/sh2/setup-sh7619.c index 79283e6c1d8..f83ff8a68f3 100644 --- a/arch/sh/kernel/cpu/sh2/setup-sh7619.c +++ b/arch/sh/kernel/cpu/sh2/setup-sh7619.c @@ -52,42 +52,38 @@ static int __init sh7619_devices_setup(void) } __initcall(sh7619_devices_setup); -#define INTC_IPRC 0xf8080000UL -#define INTC_IPRD 0xf8080002UL - -#define CMI0_IRQ 86 - -#define SCIF0_ERI_IRQ 88 -#define SCIF0_RXI_IRQ 89 -#define SCIF0_BRI_IRQ 90 -#define SCIF0_TXI_IRQ 91 - -#define SCIF1_ERI_IRQ 92 -#define SCIF1_RXI_IRQ 93 -#define SCIF1_BRI_IRQ 94 -#define SCIF1_TXI_IRQ 95 - -#define SCIF2_BRI_IRQ 96 -#define SCIF2_ERI_IRQ 97 -#define SCIF2_RXI_IRQ 98 -#define SCIF2_TXI_IRQ 99 - static struct ipr_data sh7619_ipr_map[] = { - { CMI0_IRQ, INTC_IPRC, 1, 2 }, - { SCIF0_ERI_IRQ, INTC_IPRD, 3, 3 }, - { SCIF0_RXI_IRQ, INTC_IPRD, 3, 3 }, - { SCIF0_BRI_IRQ, INTC_IPRD, 3, 3 }, - { SCIF0_TXI_IRQ, INTC_IPRD, 3, 3 }, - { SCIF1_ERI_IRQ, INTC_IPRD, 2, 3 }, - { SCIF1_RXI_IRQ, INTC_IPRD, 2, 3 }, - { SCIF1_BRI_IRQ, INTC_IPRD, 2, 3 }, - { SCIF1_TXI_IRQ, INTC_IPRD, 2, 3 }, - { SCIF2_ERI_IRQ, INTC_IPRD, 1, 3 }, - { SCIF2_RXI_IRQ, INTC_IPRD, 1, 3 }, - { SCIF2_BRI_IRQ, INTC_IPRD, 1, 3 }, - { SCIF2_TXI_IRQ, INTC_IPRD, 1, 3 }, + { 86, 0, 4, 2 }, /* CMI0 */ + { 88, 1, 12, 3 }, /* SCIF0_ERI */ + { 89, 1, 12, 3 }, /* SCIF0_RXI */ + { 90, 1, 12, 3 }, /* SCIF0_BRI */ + { 91, 1, 12, 3 }, /* SCIF0_TXI */ + { 92, 1, 8, 3 }, /* SCIF1_ERI */ + { 93, 1, 8, 3 }, /* SCIF1_RXI */ + { 94, 1, 8, 3 }, /* SCIF1_BRI */ + { 95, 1, 8, 3 }, /* SCIF1_TXI */ + { 96, 1, 4, 3 }, /* SCIF2_ERI */ + { 97, 1, 4, 3 }, /* SCIF2_RXI */ + { 98, 1, 4, 3 }, /* SCIF2_BRI */ + { 99, 1, 4, 3 }, /* SCIF2_TXI */ }; +static unsigned int ipr_offsets[] = { + 0xf8080000, /* IPRC */ + 0xf8080002, /* IPRD */ + 0xf8080004, /* IPRE */ + 0xf8080006, /* IPRF */ + 0xf8080008, /* IPRG */ +}; + +/* given the IPR index return the address of the IPR register */ +unsigned int map_ipridx_to_addr(int idx) +{ + if (unlikely(idx >= ARRAY_SIZE(ipr_offsets))) + return 0; + return ipr_offsets[idx]; +} + void __init init_IRQ_ipr(void) { make_ipr_irq(sh7619_ipr_map, ARRAY_SIZE(sh7619_ipr_map)); diff --git a/arch/sh/kernel/cpu/sh2a/probe.c b/arch/sh/kernel/cpu/sh2a/probe.c index 87c6c054208..426f6db01fc 100644 --- a/arch/sh/kernel/cpu/sh2a/probe.c +++ b/arch/sh/kernel/cpu/sh2a/probe.c @@ -17,14 +17,14 @@ int __init detect_cpu_and_cache_system(void) { /* Just SH7206 for now .. */ - cpu_data->type = CPU_SH7206; + current_cpu_data.type = CPU_SH7206; - cpu_data->dcache.ways = 4; - cpu_data->dcache.way_incr = (1 << 11); - cpu_data->dcache.sets = 128; - cpu_data->dcache.entry_shift = 4; - cpu_data->dcache.linesz = L1_CACHE_BYTES; - cpu_data->dcache.flags = 0; + current_cpu_data.dcache.ways = 4; + current_cpu_data.dcache.way_incr = (1 << 11); + current_cpu_data.dcache.sets = 128; + current_cpu_data.dcache.entry_shift = 4; + current_cpu_data.dcache.linesz = L1_CACHE_BYTES; + current_cpu_data.dcache.flags = 0; /* * The icache is the same as the dcache as far as this setup is @@ -32,7 +32,7 @@ int __init detect_cpu_and_cache_system(void) * lacks the U bit that the dcache has, none of this has any bearing * on the cache info. */ - cpu_data->icache = cpu_data->dcache; + current_cpu_data.icache = current_cpu_data.dcache; return 0; } diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7206.c b/arch/sh/kernel/cpu/sh2a/setup-sh7206.c index 4b60fcc7d66..4ed9110632b 100644 --- a/arch/sh/kernel/cpu/sh2a/setup-sh7206.c +++ b/arch/sh/kernel/cpu/sh2a/setup-sh7206.c @@ -57,55 +57,52 @@ static int __init sh7206_devices_setup(void) } __initcall(sh7206_devices_setup); -#define INTC_IPR08 0xfffe0c04UL -#define INTC_IPR09 0xfffe0c06UL -#define INTC_IPR14 0xfffe0c10UL - -#define CMI0_IRQ 140 - -#define MTU1_TGI1A 164 - -#define SCIF0_BRI_IRQ 240 -#define SCIF0_ERI_IRQ 241 -#define SCIF0_RXI_IRQ 242 -#define SCIF0_TXI_IRQ 243 - -#define SCIF1_BRI_IRQ 244 -#define SCIF1_ERI_IRQ 245 -#define SCIF1_RXI_IRQ 246 -#define SCIF1_TXI_IRQ 247 - -#define SCIF2_BRI_IRQ 248 -#define SCIF2_ERI_IRQ 249 -#define SCIF2_RXI_IRQ 250 -#define SCIF2_TXI_IRQ 251 - -#define SCIF3_BRI_IRQ 252 -#define SCIF3_ERI_IRQ 253 -#define SCIF3_RXI_IRQ 254 -#define SCIF3_TXI_IRQ 255 - static struct ipr_data sh7206_ipr_map[] = { - { CMI0_IRQ, INTC_IPR08, 3, 2 }, - { MTU2_TGI1A, INTC_IPR09, 1, 2 }, - { SCIF0_ERI_IRQ, INTC_IPR14, 3, 3 }, - { SCIF0_RXI_IRQ, INTC_IPR14, 3, 3 }, - { SCIF0_BRI_IRQ, INTC_IPR14, 3, 3 }, - { SCIF0_TXI_IRQ, INTC_IPR14, 3, 3 }, - { SCIF1_ERI_IRQ, INTC_IPR14, 2, 3 }, - { SCIF1_RXI_IRQ, INTC_IPR14, 2, 3 }, - { SCIF1_BRI_IRQ, INTC_IPR14, 2, 3 }, - { SCIF1_TXI_IRQ, INTC_IPR14, 2, 3 }, - { SCIF2_ERI_IRQ, INTC_IPR14, 1, 3 }, - { SCIF2_RXI_IRQ, INTC_IPR14, 1, 3 }, - { SCIF2_BRI_IRQ, INTC_IPR14, 1, 3 }, - { SCIF2_TXI_IRQ, INTC_IPR14, 1, 3 }, - { SCIF3_ERI_IRQ, INTC_IPR14, 0, 3 }, - { SCIF3_RXI_IRQ, INTC_IPR14, 0, 3 }, - { SCIF3_BRI_IRQ, INTC_IPR14, 0, 3 }, - { SCIF3_TXI_IRQ, INTC_IPR14, 0, 3 }, + { 140, 7, 12, 2 }, /* CMI0 */ + { 164, 8, 4, 2 }, /* MTU2_TGI1A */ + { 240, 13, 12, 3 }, /* SCIF0_BRI */ + { 241, 13, 12, 3 }, /* SCIF0_ERI */ + { 242, 13, 12, 3 }, /* SCIF0_RXI */ + { 243, 13, 12, 3 }, /* SCIF0_TXI */ + { 244, 13, 8, 3 }, /* SCIF1_BRI */ + { 245, 13, 8, 3 }, /* SCIF1_ERI */ + { 246, 13, 8, 3 }, /* SCIF1_RXI */ + { 247, 13, 8, 3 }, /* SCIF1_TXI */ + { 248, 13, 4, 3 }, /* SCIF2_BRI */ + { 249, 13, 4, 3 }, /* SCIF2_ERI */ + { 250, 13, 4, 3 }, /* SCIF2_RXI */ + { 251, 13, 4, 3 }, /* SCIF2_TXI */ + { 252, 13, 0, 3 }, /* SCIF3_BRI */ + { 253, 13, 0, 3 }, /* SCIF3_ERI */ + { 254, 13, 0, 3 }, /* SCIF3_RXI */ + { 255, 13, 0, 3 }, /* SCIF3_TXI */ +}; + +static unsigned int ipr_offsets[] = { + 0xfffe0818, /* IPR01 */ + 0xfffe081a, /* IPR02 */ + 0, /* unused */ + 0, /* unused */ + 0xfffe0820, /* IPR05 */ + 0xfffe0c00, /* IPR06 */ + 0xfffe0c02, /* IPR07 */ + 0xfffe0c04, /* IPR08 */ + 0xfffe0c06, /* IPR09 */ + 0xfffe0c08, /* IPR10 */ + 0xfffe0c0a, /* IPR11 */ + 0xfffe0c0c, /* IPR12 */ + 0xfffe0c0e, /* IPR13 */ + 0xfffe0c10, /* IPR14 */ }; +/* given the IPR index return the address of the IPR register */ +unsigned int map_ipridx_to_addr(int idx) +{ + if (unlikely(idx >= ARRAY_SIZE(ipr_offsets))) + return 0; + return ipr_offsets[idx]; +} + void __init init_IRQ_ipr(void) { make_ipr_irq(sh7206_ipr_map, ARRAY_SIZE(sh7206_ipr_map)); diff --git a/arch/sh/kernel/cpu/sh3/entry.S b/arch/sh/kernel/cpu/sh3/entry.S index 8c0dc2700c6..c19205b0f2c 100644 --- a/arch/sh/kernel/cpu/sh3/entry.S +++ b/arch/sh/kernel/cpu/sh3/entry.S @@ -13,10 +13,8 @@ #include <linux/linkage.h> #include <asm/asm-offsets.h> #include <asm/thread_info.h> -#include <asm/unistd.h> #include <asm/cpu/mmu_context.h> -#include <asm/pgtable.h> -#include <asm/page.h> +#include <asm/unistd.h> ! NOTE: ! GNU as (as of 2.9.1) changes bf/s into bt/s and bra, when the address @@ -138,14 +136,29 @@ ENTRY(tlb_protection_violation_store) call_dpf: mov.l 1f, r0 - mov.l @r0, r6 ! address + mov r5, r8 + mov.l @r0, r6 + mov r6, r9 + mov.l 2f, r0 + sts pr, r10 + jsr @r0 + mov r15, r4 + ! + tst r0, r0 + bf/s 0f + lds r10, pr + rts + nop +0: sti mov.l 3f, r0 - + mov r9, r6 + mov r8, r5 jmp @r0 - mov r15, r4 ! regs + mov r15, r4 .align 2 1: .long MMU_TEA +2: .long __do_page_fault 3: .long do_page_fault .align 2 @@ -173,7 +186,7 @@ call_dae: #if defined(CONFIG_SH_STANDARD_BIOS) /* Unwind the stack and jmp to the debug entry */ -debug_kernel_fw: +ENTRY(sh_bios_handler) mov.l @r15+, r0 mov.l @r15+, r1 mov.l @r15+, r2 @@ -332,175 +345,9 @@ general_exception: ! ! -/* This code makes some assumptions to improve performance. - * Make sure they are stil true. */ -#if PTRS_PER_PGD != PTRS_PER_PTE -#error PGD and PTE sizes don't match -#endif - -/* gas doesn't flag impossible values for mov #immediate as an error */ -#if (_PAGE_PRESENT >> 2) > 0x7f -#error cannot load PAGE_PRESENT as an immediate -#endif -#if _PAGE_DIRTY > 0x7f -#error cannot load PAGE_DIRTY as an immediate -#endif -#if (_PAGE_PRESENT << 2) != _PAGE_ACCESSED -#error cannot derive PAGE_ACCESSED from PAGE_PRESENT -#endif - -#if defined(CONFIG_CPU_SH4) -#define ldmmupteh(r) mov.l 8f, r -#else -#define ldmmupteh(r) mov #MMU_PTEH, r -#endif - .balign 1024,0,1024 tlb_miss: -#ifdef COUNT_EXCEPTIONS - ! Increment the counts - mov.l 9f, k1 - mov.l @k1, k2 - add #1, k2 - mov.l k2, @k1 -#endif - - ! k0 scratch - ! k1 pgd and pte pointers - ! k2 faulting address - ! k3 pgd and pte index masks - ! k4 shift - - ! Load up the pgd entry (k1) - - ldmmupteh(k0) ! 9 LS (latency=2) MMU_PTEH - - mov.w 4f, k3 ! 8 LS (latency=2) (PTRS_PER_PGD-1) << 2 - mov #-(PGDIR_SHIFT-2), k4 ! 6 EX - - mov.l @(MMU_TEA-MMU_PTEH,k0), k2 ! 18 LS (latency=2) - - mov.l @(MMU_TTB-MMU_PTEH,k0), k1 ! 18 LS (latency=2) - - mov k2, k0 ! 5 MT (latency=0) - shld k4, k0 ! 99 EX - - and k3, k0 ! 78 EX - - mov.l @(k0, k1), k1 ! 21 LS (latency=2) - mov #-(PAGE_SHIFT-2), k4 ! 6 EX - - ! Load up the pte entry (k2) - - mov k2, k0 ! 5 MT (latency=0) - shld k4, k0 ! 99 EX - - tst k1, k1 ! 86 MT - - bt 20f ! 110 BR - - and k3, k0 ! 78 EX - mov.w 5f, k4 ! 8 LS (latency=2) _PAGE_PRESENT - - mov.l @(k0, k1), k2 ! 21 LS (latency=2) - add k0, k1 ! 49 EX - -#ifdef CONFIG_CPU_HAS_PTEA - ! Test the entry for present and _PAGE_ACCESSED - - mov #-28, k3 ! 6 EX - mov k2, k0 ! 5 MT (latency=0) - - tst k4, k2 ! 68 MT - shld k3, k0 ! 99 EX - - bt 20f ! 110 BR - - ! Set PTEA register - ! MMU_PTEA = ((pteval >> 28) & 0xe) | (pteval & 0x1) - ! - ! k0=pte>>28, k1=pte*, k2=pte, k3=<unused>, k4=_PAGE_PRESENT - - and #0xe, k0 ! 79 EX - - mov k0, k3 ! 5 MT (latency=0) - mov k2, k0 ! 5 MT (latency=0) - - and #1, k0 ! 79 EX - - or k0, k3 ! 82 EX - - ldmmupteh(k0) ! 9 LS (latency=2) - shll2 k4 ! 101 EX _PAGE_ACCESSED - - tst k4, k2 ! 68 MT - - mov.l k3, @(MMU_PTEA-MMU_PTEH,k0) ! 27 LS - - mov.l 7f, k3 ! 9 LS (latency=2) _PAGE_FLAGS_HARDWARE_MASK - - ! k0=MMU_PTEH, k1=pte*, k2=pte, k3=_PAGE_FLAGS_HARDWARE, k4=_PAGE_ACCESSED -#else - - ! Test the entry for present and _PAGE_ACCESSED - - mov.l 7f, k3 ! 9 LS (latency=2) _PAGE_FLAGS_HARDWARE_MASK - tst k4, k2 ! 68 MT - - shll2 k4 ! 101 EX _PAGE_ACCESSED - ldmmupteh(k0) ! 9 LS (latency=2) - - bt 20f ! 110 BR - tst k4, k2 ! 68 MT - - ! k0=MMU_PTEH, k1=pte*, k2=pte, k3=_PAGE_FLAGS_HARDWARE, k4=_PAGE_ACCESSED - -#endif - - ! Set up the entry - - and k2, k3 ! 78 EX - bt/s 10f ! 108 BR - - mov.l k3, @(MMU_PTEL-MMU_PTEH,k0) ! 27 LS - - ldtlb ! 128 CO - - ! At least one instruction between ldtlb and rte - nop ! 119 NOP - - rte ! 126 CO - - nop ! 119 NOP - - -10: or k4, k2 ! 82 EX - - ldtlb ! 128 CO - - ! At least one instruction between ldtlb and rte - mov.l k2, @k1 ! 27 LS - - rte ! 126 CO - - ! Note we cannot execute mov here, because it is executed after - ! restoring SSR, so would be executed in user space. - nop ! 119 NOP - - - .align 5 - ! Once cache line if possible... -1: .long swapper_pg_dir -4: .short (PTRS_PER_PGD-1) << 2 -5: .short _PAGE_PRESENT -7: .long _PAGE_FLAGS_HARDWARE_MASK -8: .long MMU_PTEH -#ifdef COUNT_EXCEPTIONS -9: .long exception_count_miss -#endif - - ! Either pgd or pte not present -20: mov.l 1f, k2 + mov.l 1f, k2 mov.l 4f, k3 bra handle_exception mov.l @k2, k2 @@ -651,15 +498,6 @@ skip_save: bf interrupt_exception shlr2 r8 shlr r8 - -#ifdef COUNT_EXCEPTIONS - mov.l 5f, r9 - add r8, r9 - mov.l @r9, r10 - add #1, r10 - mov.l r10, @r9 -#endif - mov.l 4f, r9 add r8, r9 mov.l @r9, r9 @@ -673,9 +511,6 @@ skip_save: 2: .long 0x000080f0 ! FD=1, IMASK=15 3: .long 0xcfffffff ! RB=0, BL=0 4: .long exception_handling_table -#ifdef COUNT_EXCEPTIONS -5: .long exception_count_table -#endif interrupt_exception: mov.l 1f, r9 diff --git a/arch/sh/kernel/cpu/sh3/probe.c b/arch/sh/kernel/cpu/sh3/probe.c index e6709883629..821b0ab7b52 100644 --- a/arch/sh/kernel/cpu/sh3/probe.c +++ b/arch/sh/kernel/cpu/sh3/probe.c @@ -50,41 +50,41 @@ int __init detect_cpu_and_cache_system(void) back_to_P1(); - cpu_data->dcache.ways = 4; - cpu_data->dcache.entry_shift = 4; - cpu_data->dcache.linesz = L1_CACHE_BYTES; - cpu_data->dcache.flags = 0; + current_cpu_data.dcache.ways = 4; + current_cpu_data.dcache.entry_shift = 4; + current_cpu_data.dcache.linesz = L1_CACHE_BYTES; + current_cpu_data.dcache.flags = 0; /* * 7709A/7729 has 16K cache (256-entry), while 7702 has only * 2K(direct) 7702 is not supported (yet) */ if (data0 == data1 && data2 == data3) { /* Shadow */ - cpu_data->dcache.way_incr = (1 << 11); - cpu_data->dcache.entry_mask = 0x7f0; - cpu_data->dcache.sets = 128; - cpu_data->type = CPU_SH7708; + current_cpu_data.dcache.way_incr = (1 << 11); + current_cpu_data.dcache.entry_mask = 0x7f0; + current_cpu_data.dcache.sets = 128; + current_cpu_data.type = CPU_SH7708; - cpu_data->flags |= CPU_HAS_MMU_PAGE_ASSOC; + current_cpu_data.flags |= CPU_HAS_MMU_PAGE_ASSOC; } else { /* 7709A or 7729 */ - cpu_data->dcache.way_incr = (1 << 12); - cpu_data->dcache.entry_mask = 0xff0; - cpu_data->dcache.sets = 256; - cpu_data->type = CPU_SH7729; + current_cpu_data.dcache.way_incr = (1 << 12); + current_cpu_data.dcache.entry_mask = 0xff0; + current_cpu_data.dcache.sets = 256; + current_cpu_data.type = CPU_SH7729; #if defined(CONFIG_CPU_SUBTYPE_SH7706) - cpu_data->type = CPU_SH7706; + current_cpu_data.type = CPU_SH7706; #endif #if defined(CONFIG_CPU_SUBTYPE_SH7710) - cpu_data->type = CPU_SH7710; + current_cpu_data.type = CPU_SH7710; #endif #if defined(CONFIG_CPU_SUBTYPE_SH7705) - cpu_data->type = CPU_SH7705; + current_cpu_data.type = CPU_SH7705; #if defined(CONFIG_SH7705_CACHE_32KB) - cpu_data->dcache.way_incr = (1 << 13); - cpu_data->dcache.entry_mask = 0x1ff0; - cpu_data->dcache.sets = 512; + current_cpu_data.dcache.way_incr = (1 << 13); + current_cpu_data.dcache.entry_mask = 0x1ff0; + current_cpu_data.dcache.sets = 512; ctrl_outl(CCR_CACHE_32KB, CCR3); #else ctrl_outl(CCR_CACHE_16KB, CCR3); @@ -95,8 +95,8 @@ int __init detect_cpu_and_cache_system(void) /* * SH-3 doesn't have separate caches */ - cpu_data->dcache.flags |= SH_CACHE_COMBINED; - cpu_data->icache = cpu_data->dcache; + current_cpu_data.dcache.flags |= SH_CACHE_COMBINED; + current_cpu_data.icache = current_cpu_data.dcache; return 0; } diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7709.c b/arch/sh/kernel/cpu/sh3/setup-sh7709.c index ff43ef2a1f0..dc9b211cf87 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh7709.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh7709.c @@ -51,3 +51,24 @@ static int __init sh7709_devices_setup(void) ARRAY_SIZE(sh7709_devices)); } __initcall(sh7709_devices_setup); + +#define IPRx(A,N) .addr=A, .shift=0*N*-1 +#define IPRA(N) IPRx(0xfffffee2UL,N) +#define IPRB(N) IPRx(0xfffffee4UL,N) +#define IPRE(N) IPRx(0xa400001aUL,N) + +static struct ipr_data sh7709_ipr_map[] = { + [16] = { IPRA(15-12), 2 }, /* TMU TUNI0 */ + [17] = { IPRA(11-8), 4 }, /* TMU TUNI1 */ + [22] = { IPRA(3-0), 2 }, /* RTC CUI */ + [23 ... 26] = { IPRB(7-4), 3 }, /* SCI */ + [27] = { IPRB(15-12), 2 }, /* WDT ITI */ + [48 ... 51] = { IPRE(15-12), 7 }, /* DMA */ + [52 ... 55] = { IPRE(11-8), 3 }, /* IRDA */ + [56 ... 59] = { IPRE(7-4), 3 }, /* SCIF */ +}; + +void __init init_IRQ_ipr() +{ + make_ipr_irq(sh7709_ipr_map, ARRAY_SIZE(sh7709_ipr_map)); +} diff --git a/arch/sh/kernel/cpu/sh4/probe.c b/arch/sh/kernel/cpu/sh4/probe.c index 9031a22a2ce..9d28c88d2f9 100644 --- a/arch/sh/kernel/cpu/sh4/probe.c +++ b/arch/sh/kernel/cpu/sh4/probe.c @@ -10,11 +10,10 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. */ - #include <linux/init.h> +#include <linux/io.h> #include <asm/processor.h> #include <asm/cache.h> -#include <asm/io.h> int __init detect_cpu_and_cache_system(void) { @@ -36,20 +35,20 @@ int __init detect_cpu_and_cache_system(void) /* * Setup some sane SH-4 defaults for the icache */ - cpu_data->icache.way_incr = (1 << 13); - cpu_data->icache.entry_shift = 5; - cpu_data->icache.sets = 256; - cpu_data->icache.ways = 1; - cpu_data->icache.linesz = L1_CACHE_BYTES; + current_cpu_data.icache.way_incr = (1 << 13); + current_cpu_data.icache.entry_shift = 5; + current_cpu_data.icache.sets = 256; + current_cpu_data.icache.ways = 1; + current_cpu_data.icache.linesz = L1_CACHE_BYTES; /* * And again for the dcache .. */ - cpu_data->dcache.way_incr = (1 << 14); - cpu_data->dcache.entry_shift = 5; - cpu_data->dcache.sets = 512; - cpu_data->dcache.ways = 1; - cpu_data->dcache.linesz = L1_CACHE_BYTES; + current_cpu_data.dcache.way_incr = (1 << 14); + current_cpu_data.dcache.entry_shift = 5; + current_cpu_data.dcache.sets = 512; + current_cpu_data.dcache.ways = 1; + current_cpu_data.dcache.linesz = L1_CACHE_BYTES; /* * Setup some generic flags we can probe @@ -57,16 +56,16 @@ int __init detect_cpu_and_cache_system(void) */ if (((pvr >> 16) & 0xff) == 0x10) { if ((cvr & 0x02000000) == 0) - cpu_data->flags |= CPU_HAS_L2_CACHE; + current_cpu_data.flags |= CPU_HAS_L2_CACHE; if ((cvr & 0x10000000) == 0) - cpu_data->flags |= CPU_HAS_DSP; + current_cpu_data.flags |= CPU_HAS_DSP; - cpu_data->flags |= CPU_HAS_LLSC; + current_cpu_data.flags |= CPU_HAS_LLSC; } /* FPU detection works for everyone */ if ((cvr & 0x20000000) == 1) - cpu_data->flags |= CPU_HAS_FPU; + current_cpu_data.flags |= CPU_HAS_FPU; /* Mask off the upper chip ID */ pvr &= 0xffff; @@ -77,151 +76,151 @@ int __init detect_cpu_and_cache_system(void) */ switch (pvr) { case 0x205: - cpu_data->type = CPU_SH7750; - cpu_data->flags |= CPU_HAS_P2_FLUSH_BUG | CPU_HAS_FPU | + current_cpu_data.type = CPU_SH7750; + current_cpu_data.flags |= CPU_HAS_P2_FLUSH_BUG | CPU_HAS_FPU | CPU_HAS_PERF_COUNTER; break; case 0x206: - cpu_data->type = CPU_SH7750S; - cpu_data->flags |= CPU_HAS_P2_FLUSH_BUG | CPU_HAS_FPU | + current_cpu_data.type = CPU_SH7750S; + current_cpu_data.flags |= CPU_HAS_P2_FLUSH_BUG | CPU_HAS_FPU | CPU_HAS_PERF_COUNTER; break; case 0x1100: - cpu_data->type = CPU_SH7751; - cpu_data->flags |= CPU_HAS_FPU; + current_cpu_data.type = CPU_SH7751; + current_cpu_data.flags |= CPU_HAS_FPU; break; case 0x2000: - cpu_data->type = CPU_SH73180; - cpu_data->icache.ways = 4; - cpu_data->dcache.ways = 4; - cpu_data->flags |= CPU_HAS_LLSC; + current_cpu_data.type = CPU_SH73180; + current_cpu_data.icache.ways = 4; + current_cpu_data.dcache.ways = 4; + current_cpu_data.flags |= CPU_HAS_LLSC; break; case 0x2001: case 0x2004: - cpu_data->type = CPU_SH7770; - cpu_data->icache.ways = 4; - cpu_data->dcache.ways = 4; + current_cpu_data.type = CPU_SH7770; + current_cpu_data.icache.ways = 4; + current_cpu_data.dcache.ways = 4; - cpu_data->flags |= CPU_HAS_FPU | CPU_HAS_LLSC; + current_cpu_data.flags |= CPU_HAS_FPU | CPU_HAS_LLSC; break; case 0x2006: case 0x200A: if (prr == 0x61) - cpu_data->type = CPU_SH7781; + current_cpu_data.type = CPU_SH7781; else - cpu_data->type = CPU_SH7780; + current_cpu_data.type = CPU_SH7780; - cpu_data->icache.ways = 4; - cpu_data->dcache.ways = 4; + current_cpu_data.icache.ways = 4; + current_cpu_data.dcache.ways = 4; - cpu_data->flags |= CPU_HAS_FPU | CPU_HAS_PERF_COUNTER | + current_cpu_data.flags |= CPU_HAS_FPU | CPU_HAS_PERF_COUNTER | CPU_HAS_LLSC; break; case 0x3000: case 0x3003: case 0x3009: - cpu_data->type = CPU_SH7343; - cpu_data->icache.ways = 4; - cpu_data->dcache.ways = 4; - cpu_data->flags |= CPU_HAS_LLSC; + current_cpu_data.type = CPU_SH7343; + current_cpu_data.icache.ways = 4; + current_cpu_data.dcache.ways = 4; + current_cpu_data.flags |= CPU_HAS_LLSC; break; case 0x3008: if (prr == 0xa0) { - cpu_data->type = CPU_SH7722; - cpu_data->icache.ways = 4; - cpu_data->dcache.ways = 4; - cpu_data->flags |= CPU_HAS_LLSC; + current_cpu_data.type = CPU_SH7722; + current_cpu_data.icache.ways = 4; + current_cpu_data.dcache.ways = 4; + current_cpu_data.flags |= CPU_HAS_LLSC; } break; case 0x8000: - cpu_data->type = CPU_ST40RA; - cpu_data->flags |= CPU_HAS_FPU; + current_cpu_data.type = CPU_ST40RA; + current_cpu_data.flags |= CPU_HAS_FPU; break; case 0x8100: - cpu_data->type = CPU_ST40GX1; - cpu_data->flags |= CPU_HAS_FPU; + current_cpu_data.type = CPU_ST40GX1; + current_cpu_data.flags |= CPU_HAS_FPU; break; case 0x700: - cpu_data->type = CPU_SH4_501; - cpu_data->icache.ways = 2; - cpu_data->dcache.ways = 2; + current_cpu_data.type = CPU_SH4_501; + current_cpu_data.icache.ways = 2; + current_cpu_data.dcache.ways = 2; break; case 0x600: - cpu_data->type = CPU_SH4_202; - cpu_data->icache.ways = 2; - cpu_data->dcache.ways = 2; - cpu_data->flags |= CPU_HAS_FPU; + current_cpu_data.type = CPU_SH4_202; + current_cpu_data.icache.ways = 2; + current_cpu_data.dcache.ways = 2; + current_cpu_data.flags |= CPU_HAS_FPU; break; case 0x500 ... 0x501: switch (prr) { case 0x10: - cpu_data->type = CPU_SH7750R; + current_cpu_data.type = CPU_SH7750R; break; case 0x11: - cpu_data->type = CPU_SH7751R; + current_cpu_data.type = CPU_SH7751R; break; case 0x50 ... 0x5f: - cpu_data->type = CPU_SH7760; + current_cpu_data.type = CPU_SH7760; break; } - cpu_data->icache.ways = 2; - cpu_data->dcache.ways = 2; + current_cpu_data.icache.ways = 2; + current_cpu_data.dcache.ways = 2; - cpu_data->flags |= CPU_HAS_FPU; + current_cpu_data.flags |= CPU_HAS_FPU; break; default: - cpu_data->type = CPU_SH_NONE; + current_cpu_data.type = CPU_SH_NONE; break; } #ifdef CONFIG_SH_DIRECT_MAPPED - cpu_data->icache.ways = 1; - cpu_data->dcache.ways = 1; + current_cpu_data.icache.ways = 1; + current_cpu_data.dcache.ways = 1; #endif #ifdef CONFIG_CPU_HAS_PTEA - cpu_data->flags |= CPU_HAS_PTEA; + current_cpu_data.flags |= CPU_HAS_PTEA; #endif /* * On anything that's not a direct-mapped cache, look to the CVR * for I/D-cache specifics. */ - if (cpu_data->icache.ways > 1) { + if (current_cpu_data.icache.ways > 1) { size = sizes[(cvr >> 20) & 0xf]; - cpu_data->icache.way_incr = (size >> 1); - cpu_data->icache.sets = (size >> 6); + current_cpu_data.icache.way_incr = (size >> 1); + current_cpu_data.icache.sets = (size >> 6); } /* Setup the rest of the I-cache info */ - cpu_data->icache.entry_mask = cpu_data->icache.way_incr - - cpu_data->icache.linesz; + current_cpu_data.icache.entry_mask = current_cpu_data.icache.way_incr - + current_cpu_data.icache.linesz; - cpu_data->icache.way_size = cpu_data->icache.sets * - cpu_data->icache.linesz; + current_cpu_data.icache.way_size = current_cpu_data.icache.sets * + current_cpu_data.icache.linesz; /* And the rest of the D-cache */ - if (cpu_data->dcache.ways > 1) { + if (current_cpu_data.dcache.ways > 1) { size = sizes[(cvr >> 16) & 0xf]; - cpu_data->dcache.way_incr = (size >> 1); - cpu_data->dcache.sets = (size >> 6); + current_cpu_data.dcache.way_incr = (size >> 1); + current_cpu_data.dcache.sets = (size >> 6); } - cpu_data->dcache.entry_mask = cpu_data->dcache.way_incr - - cpu_data->dcache.linesz; + current_cpu_data.dcache.entry_mask = current_cpu_data.dcache.way_incr - + current_cpu_data.dcache.linesz; - cpu_data->dcache.way_size = cpu_data->dcache.sets * - cpu_data->dcache.linesz; + current_cpu_data.dcache.way_size = current_cpu_data.dcache.sets * + current_cpu_data.dcache.linesz; /* * Setup the L2 cache desc * * SH-4A's have an optional PIPT L2. */ - if (cpu_data->flags & CPU_HAS_L2_CACHE) { + if (current_cpu_data.flags & CPU_HAS_L2_CACHE) { /* * Size calculation is much more sensible * than it is for the L1. @@ -232,16 +231,22 @@ int __init detect_cpu_and_cache_system(void) BUG_ON(!size); - cpu_data->scache.way_incr = (1 << 16); - cpu_data->scache.entry_shift = 5; - cpu_data->scache.ways = 4; - cpu_data->scache.linesz = L1_CACHE_BYTES; - cpu_data->scache.entry_mask = - (cpu_data->scache.way_incr - cpu_data->scache.linesz); - cpu_data->scache.sets = size / - (cpu_data->scache.linesz * cpu_data->scache.ways); - cpu_data->scache.way_size = - (cpu_data->scache.sets * cpu_data->scache.linesz); + current_cpu_data.scache.way_incr = (1 << 16); + current_cpu_data.scache.entry_shift = 5; + current_cpu_data.scache.ways = 4; + current_cpu_data.scache.linesz = L1_CACHE_BYTES; + + current_cpu_data.scache.entry_mask = + (current_cpu_data.scache.way_incr - + current_cpu_data.scache.linesz); + + current_cpu_data.scache.sets = size / + (current_cpu_data.scache.linesz * + current_cpu_data.scache.ways); + + current_cpu_data.scache.way_size = + (current_cpu_data.scache.sets * + current_cpu_data.scache.linesz); } return 0; diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7750.c b/arch/sh/kernel/cpu/sh4/setup-sh7750.c index cbac27634c0..6f8f458912c 100644 --- a/arch/sh/kernel/cpu/sh4/setup-sh7750.c +++ b/arch/sh/kernel/cpu/sh4/setup-sh7750.c @@ -46,11 +46,13 @@ static struct platform_device rtc_device = { static struct plat_sci_port sci_platform_data[] = { { +#ifndef CONFIG_SH_RTS7751R2D .mapbase = 0xffe00000, .flags = UPF_BOOT_AUTOCONF, .type = PORT_SCI, .irqs = { 23, 24, 25, 0 }, }, { +#endif .mapbase = 0xffe80000, .flags = UPF_BOOT_AUTOCONF, .type = PORT_SCIF, @@ -101,7 +103,7 @@ static struct ipr_data sh7750_ipr_map[] = { { 35, 2, 8, 7 }, /* DMAC DMTE1 */ { 36, 2, 8, 7 }, /* DMAC DMTE2 */ { 37, 2, 8, 7 }, /* DMAC DMTE3 */ - { 28, 2, 8, 7 }, /* DMAC DMAE */ + { 38, 2, 8, 7 }, /* DMAC DMAE */ }; static struct ipr_data sh7751_ipr_map[] = { diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7760.c b/arch/sh/kernel/cpu/sh4/setup-sh7760.c index 07e5377bf55..b7c702821e6 100644 --- a/arch/sh/kernel/cpu/sh4/setup-sh7760.c +++ b/arch/sh/kernel/cpu/sh4/setup-sh7760.c @@ -52,17 +52,11 @@ static int __init sh7760_devices_setup(void) } __initcall(sh7760_devices_setup); -/* - * SH7760 INTC2-Style interrupts, vectors IRQ48-111 INTEVT 0x800-0xFE0 - */ static struct intc2_data intc2_irq_table[] = { - /* INTPRIO0 | INTMSK0 */ {48, 0, 28, 0, 31, 3}, /* IRQ 4 */ {49, 0, 24, 0, 30, 3}, /* IRQ 3 */ {50, 0, 20, 0, 29, 3}, /* IRQ 2 */ {51, 0, 16, 0, 28, 3}, /* IRQ 1 */ - /* 52-55 (INTEVT 0x880-0x8E0) unused/reserved */ - /* INTPRIO4 | INTMSK0 */ {56, 4, 28, 0, 25, 3}, /* HCAN2_CHAN0 */ {57, 4, 24, 0, 24, 3}, /* HCAN2_CHAN1 */ {58, 4, 20, 0, 23, 3}, /* I2S_CHAN0 */ @@ -71,18 +65,15 @@ static struct intc2_data intc2_irq_table[] = { {61, 4, 8, 0, 20, 3}, /* AC97_CHAN1 */ {62, 4, 4, 0, 19, 3}, /* I2C_CHAN0 */ {63, 4, 0, 0, 18, 3}, /* I2C_CHAN1 */ - /* INTPRIO8 | INTMSK0 */ {52, 8, 16, 0, 11, 3}, /* SCIF0_ERI_IRQ */ {53, 8, 16, 0, 10, 3}, /* SCIF0_RXI_IRQ */ {54, 8, 16, 0, 9, 3}, /* SCIF0_BRI_IRQ */ {55, 8, 16, 0, 8, 3}, /* SCIF0_TXI_IRQ */ {64, 8, 28, 0, 17, 3}, /* USBHI_IRQ */ {65, 8, 24, 0, 16, 3}, /* LCDC */ - /* 66, 67 unused */ {68, 8, 20, 0, 14, 13}, /* DMABRGI0_IRQ */ {69, 8, 20, 0, 13, 13}, /* DMABRGI1_IRQ */ {70, 8, 20, 0, 12, 13}, /* DMABRGI2_IRQ */ - /* 71 unused */ {72, 8, 12, 0, 7, 3}, /* SCIF1_ERI_IRQ */ {73, 8, 12, 0, 6, 3}, /* SCIF1_RXI_IRQ */ {74, 8, 12, 0, 5, 3}, /* SCIF1_BRI_IRQ */ @@ -91,26 +82,71 @@ static struct intc2_data intc2_irq_table[] = { {77, 8, 8, 0, 2, 3}, /* SCIF2_RXI_IRQ */ {78, 8, 8, 0, 1, 3}, /* SCIF2_BRI_IRQ */ {79, 8, 8, 0, 0, 3}, /* SCIF2_TXI_IRQ */ - /* | INTMSK4 */ {80, 8, 4, 4, 23, 3}, /* SIM_ERI */ {81, 8, 4, 4, 22, 3}, /* SIM_RXI */ {82, 8, 4, 4, 21, 3}, /* SIM_TXI */ {83, 8, 4, 4, 20, 3}, /* SIM_TEI */ {84, 8, 0, 4, 19, 3}, /* HSPII */ - /* INTPRIOC | INTMSK4 */ - /* 85-87 unused/reserved */ {88, 12, 20, 4, 18, 3}, /* MMCI0 */ {89, 12, 20, 4, 17, 3}, /* MMCI1 */ {90, 12, 20, 4, 16, 3}, /* MMCI2 */ {91, 12, 20, 4, 15, 3}, /* MMCI3 */ - {92, 12, 12, 4, 6, 3}, /* MFI (unsure, bug? in my 7760 manual*/ - /* 93-107 reserved/undocumented */ + {92, 12, 12, 4, 6, 3}, /* MFI */ {108,12, 4, 4, 1, 3}, /* ADC */ {109,12, 0, 4, 0, 3}, /* CMTI */ - /* 110-111 reserved/unused */ }; +static struct ipr_data sh7760_ipr_map[] = { + /* IRQ, IPR-idx, shift, priority */ + { 16, 0, 12, 2 }, /* TMU0 TUNI*/ + { 17, 0, 8, 2 }, /* TMU1 TUNI */ + { 18, 0, 4, 2 }, /* TMU2 TUNI */ + { 19, 0, 4, 2 }, /* TMU2 TIPCI */ + { 27, 1, 12, 2 }, /* WDT ITI */ + { 28, 1, 8, 2 }, /* REF RCMI */ + { 29, 1, 8, 2 }, /* REF ROVI */ + { 32, 2, 0, 7 }, /* HUDI */ + { 33, 2, 12, 7 }, /* GPIOI */ + { 34, 2, 8, 7 }, /* DMAC DMTE0 */ + { 35, 2, 8, 7 }, /* DMAC DMTE1 */ + { 36, 2, 8, 7 }, /* DMAC DMTE2 */ + { 37, 2, 8, 7 }, /* DMAC DMTE3 */ + { 38, 2, 8, 7 }, /* DMAC DMAE */ + { 44, 2, 8, 7 }, /* DMAC DMTE4 */ + { 45, 2, 8, 7 }, /* DMAC DMTE5 */ + { 46, 2, 8, 7 }, /* DMAC DMTE6 */ + { 47, 2, 8, 7 }, /* DMAC DMTE7 */ +/* these here are only valid if INTC_ICR bit 7 is set to 1! + * XXX: maybe CONFIG_SH_IRLMODE symbol? SH7751 could use it too */ +#if 0 + { 2, 3, 12, 3 }, /* IRL0 */ + { 5, 3, 8, 3 }, /* IRL1 */ + { 8, 3, 4, 3 }, /* IRL2 */ + { 11, 3, 0, 3 }, /* IRL3 */ +#endif +}; + +static unsigned long ipr_offsets[] = { + 0xffd00004UL, /* 0: IPRA */ + 0xffd00008UL, /* 1: IPRB */ + 0xffd0000cUL, /* 2: IPRC */ + 0xffd00010UL, /* 3: IPRD */ +}; + +/* given the IPR index return the address of the IPR register */ +unsigned int map_ipridx_to_addr(int idx) +{ + if (idx >= ARRAY_SIZE(ipr_offsets)) + return 0; + return ipr_offsets[idx]; +} + void __init init_IRQ_intc2(void) { make_intc2_irq(intc2_irq_table, ARRAY_SIZE(intc2_irq_table)); } + +void __init init_IRQ_ipr(void) +{ + make_ipr_irq(sh7760_ipr_map, ARRAY_SIZE(sh7760_ipr_map)); +} diff --git a/arch/sh/kernel/debugtraps.S b/arch/sh/kernel/debugtraps.S new file mode 100644 index 00000000000..13b66746410 --- /dev/null +++ b/arch/sh/kernel/debugtraps.S @@ -0,0 +1,41 @@ +/* + * arch/sh/kernel/debugtraps.S + * + * Debug trap jump tables for SuperH + * + * Copyright (C) 2006 Paul Mundt + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#include <linux/sys.h> +#include <linux/linkage.h> + +#if !defined(CONFIG_SH_KGDB) +#define kgdb_handle_exception debug_trap_handler +#endif + +#if !defined(CONFIG_SH_STANDARD_BIOS) +#define sh_bios_handler debug_trap_handler +#endif + + .data + +ENTRY(debug_trap_table) + .long debug_trap_handler /* 0x30 */ + .long debug_trap_handler /* 0x31 */ + .long debug_trap_handler /* 0x32 */ + .long debug_trap_handler /* 0x33 */ + .long debug_trap_handler /* 0x34 */ + .long debug_trap_handler /* 0x35 */ + .long debug_trap_handler /* 0x36 */ + .long debug_trap_handler /* 0x37 */ + .long debug_trap_handler /* 0x38 */ + .long debug_trap_handler /* 0x39 */ + .long debug_trap_handler /* 0x3a */ + .long debug_trap_handler /* 0x3b */ + .long kgdb_handle_exception /* 0x3c */ + .long debug_trap_handler /* 0x3d */ + .long bug_trap_handler /* 0x3e */ + .long sh_bios_handler /* 0x3f */ diff --git a/arch/sh/kernel/early_printk.c b/arch/sh/kernel/early_printk.c index 560b91cdd15..9048c0326d8 100644 --- a/arch/sh/kernel/early_printk.c +++ b/arch/sh/kernel/early_printk.c @@ -106,12 +106,32 @@ static struct console scif_console = { }; #if defined(CONFIG_CPU_SH4) && !defined(CONFIG_SH_STANDARD_BIOS) +#define DEFAULT_BAUD 115200 /* * Simple SCIF init, primarily aimed at SH7750 and other similar SH-4 * devices that aren't using sh-ipl+g. */ -static void scif_sercon_init(int baud) +static void scif_sercon_init(char *s) { + unsigned baud = DEFAULT_BAUD; + char *e; + + if (*s == ',') + ++s; + + if (*s) { + /* ignore ioport/device name */ + s += strcspn(s, ","); + if (*s == ',') + s++; + } + + if (*s) { + baud = simple_strtoul(s, &e, 0); + if (baud == 0 || s == e) + baud = DEFAULT_BAUD; + } + ctrl_outw(0, scif_port.mapbase + 8); ctrl_outw(0, scif_port.mapbase); @@ -167,7 +187,7 @@ int __init setup_early_printk(char *buf) early_console = &scif_console; #if defined(CONFIG_CPU_SH4) && !defined(CONFIG_SH_STANDARD_BIOS) - scif_sercon_init(115200); + scif_sercon_init(buf + 6); #endif } #endif diff --git a/arch/sh/kernel/entry-common.S b/arch/sh/kernel/entry-common.S index fc279aeb73a..ab4ebb856c2 100644 --- a/arch/sh/kernel/entry-common.S +++ b/arch/sh/kernel/entry-common.S @@ -54,79 +54,24 @@ # define resume_kernel __restore_all #endif -#if defined(CONFIG_SH_STANDARD_BIOS) || defined(CONFIG_SH_KGDB) -! Handle kernel debug if either kgdb (SW) or gdb-stub (FW) is present. -! If both are configured, handle the debug traps (breakpoints) in SW, -! but still allow BIOS traps to FW. - - .align 2 -debug_kernel: -#if defined(CONFIG_SH_STANDARD_BIOS) && defined(CONFIG_SH_KGDB) - /* Force BIOS call to FW (debug_trap put TRA in r8) */ - mov r8,r0 - shlr2 r0 - cmp/eq #0x3f,r0 - bt debug_kernel_fw -#endif /* CONFIG_SH_STANDARD_BIOS && CONFIG_SH_KGDB */ - -debug_enter: -#if defined(CONFIG_SH_KGDB) - /* Jump to kgdb, pass stacked regs as arg */ -debug_kernel_sw: - mov.l 3f, r0 - jmp @r0 - mov r15, r4 - .align 2 -3: .long kgdb_handle_exception -#endif /* CONFIG_SH_KGDB */ -#ifdef CONFIG_SH_STANDARD_BIOS - bra debug_kernel_fw - nop -#endif -#endif /* CONFIG_SH_STANDARD_BIOS || CONFIG_SH_KGDB */ - - .align 2 -debug_trap: -#if defined(CONFIG_SH_STANDARD_BIOS) || defined(CONFIG_SH_KGDB) - mov r8, r0 - shlr2 r0 - cmp/eq #0x3f, r0 ! sh_bios() trap - bf 1f -#ifdef CONFIG_SH_KGDB - cmp/eq #0xff, r0 ! XXX: KGDB trap, fix for SH-2. - bf 1f -#endif - mov #OFF_SR, r0 - mov.l @(r0,r15), r0 ! get status register - shll r0 - shll r0 ! kernel space? - bt/s debug_kernel -1: -#endif - mov.l @r15, r0 ! Restore R0 value - mov.l 1f, r8 - jmp @r8 - nop .align 2 ENTRY(exception_error) ! #ifdef CONFIG_TRACE_IRQFLAGS - mov.l 3f, r0 + mov.l 2f, r0 jsr @r0 nop #endif sti - mov.l 2f, r0 + mov.l 1f, r0 jmp @r0 nop -! .align 2 -1: .long break_point_trap_software -2: .long do_exception_error +1: .long do_exception_error #ifdef CONFIG_TRACE_IRQFLAGS -3: .long trace_hardirqs_on +2: .long trace_hardirqs_on #endif .align 2 @@ -331,16 +276,31 @@ __restore_all: 1: .long restore_all .align 2 -not_syscall_tra: - bra debug_trap - nop - - .align 2 syscall_badsys: ! Bad syscall number mov #-ENOSYS, r0 bra resume_userspace mov.l r0, @(OFF_R0,r15) ! Return value - + +/* + * The main debug trap handler. + * + * r8=TRA (not the trap number!) + * + * Note: This assumes that the trapa value is left in its original + * form (without the shlr2 shift) so the calculation for the jump + * call table offset remains a simple in place mask. + */ +debug_trap: + mov r8, r0 + and #(0xf << 2), r0 + mov.l 1f, r8 + add r0, r8 + mov.l @r8, r8 + jmp @r8 + nop + + .align 2 +1: .long debug_trap_table /* * Syscall interface: @@ -348,17 +308,19 @@ syscall_badsys: ! Bad syscall number * Syscall #: R3 * Arguments #0 to #3: R4--R7 * Arguments #4 to #6: R0, R1, R2 - * TRA: (number of arguments + 0x10) x 4 + * TRA: (number of arguments + ABI revision) x 4 * * This code also handles delegating other traps to the BIOS/gdb stub * according to: * * Trap number - * (TRA>>2) Purpose - * -------- ------- - * 0x0-0xf old syscall ABI - * 0x10-0x1f new syscall ABI - * 0x20-0xff delegated through debug_trap to BIOS/gdb stub. + * (TRA>>2) Purpose + * -------- ------- + * 0x00-0x0f original SH-3/4 syscall ABI (not in general use). + * 0x10-0x1f general SH-3/4 syscall ABI. + * 0x20-0x2f syscall ABI for SH-2 parts. + * 0x30-0x3f debug traps used by the kernel. + * 0x40-0xff Not supported by all parts, so left unhandled. * * Note: When we're first called, the TRA value must be shifted * right 2 bits in order to get the value that was used as the "trapa" @@ -375,17 +337,22 @@ ret_from_fork: nop .align 2 1: .long schedule_tail - ! + +/* + * The poorly named main trapa decode and dispatch routine, for + * system calls and debug traps through their respective jump tables. + */ ENTRY(system_call) #if !defined(CONFIG_CPU_SH2) mov.l 1f, r9 mov.l @r9, r8 ! Read from TRA (Trap Address) Register #endif - ! - ! Is the trap argument >= 0x20? (TRA will be >= 0x80) - mov #0x7f, r9 + /* + * Check the trap type + */ + mov #((0x20 << 2) - 1), r9 cmp/hi r9, r8 - bt/s not_syscall_tra + bt/s debug_trap ! it's a debug trap.. mov #OFF_TRA, r9 add r15, r9 mov.l r8, @r9 ! set TRA value to tra diff --git a/arch/sh/kernel/io_generic.c b/arch/sh/kernel/io_generic.c index 28ec7487de8..66626c03e1e 100644 --- a/arch/sh/kernel/io_generic.c +++ b/arch/sh/kernel/io_generic.c @@ -1,9 +1,8 @@ -/* $Id: io_generic.c,v 1.2 2003/05/04 19:29:53 lethal Exp $ - * - * linux/arch/sh/kernel/io_generic.c +/* + * arch/sh/kernel/io_generic.c * * Copyright (C) 2000 Niibe Yutaka - * Copyright (C) 2005 Paul Mundt + * Copyright (C) 2005 - 2007 Paul Mundt * * Generic I/O routine. These can be used where a machine specific version * is not required. @@ -13,8 +12,9 @@ * for more details. */ #include <linux/module.h> -#include <asm/io.h> +#include <linux/io.h> #include <asm/machvec.h> +#include <asm/cacheflush.h> #ifdef CONFIG_CPU_SH3 /* SH3 has a PCMCIA bug that needs a dummy read from area 6 for a @@ -96,6 +96,7 @@ void generic_insw(unsigned long port, void *dst, unsigned long count) while (count--) *buf++ = *port_addr; + flush_dcache_all(); dummy_read(); } @@ -170,6 +171,7 @@ void generic_outsw(unsigned long port, const void *src, unsigned long count) while (count--) *port_addr = *buf++; + flush_dcache_all(); dummy_read(); } diff --git a/arch/sh/kernel/kgdb_stub.c b/arch/sh/kernel/kgdb_stub.c index 9c6315f0335..d8927d85492 100644 --- a/arch/sh/kernel/kgdb_stub.c +++ b/arch/sh/kernel/kgdb_stub.c @@ -1323,8 +1323,11 @@ static void kgdb_command_loop(const int excep_code, const int trapa_value) } /* There has been an exception, most likely a breakpoint. */ -void kgdb_handle_exception(struct pt_regs *regs) +asmlinkage void kgdb_handle_exception(unsigned long r4, unsigned long r5, + unsigned long r6, unsigned long r7, + struct pt_regs __regs) { + struct pt_regs *regs = RELOC_HIDE(&__regs, 0); int excep_code, vbr_val; int count; int trapa_value = ctrl_inl(TRA); @@ -1368,8 +1371,6 @@ void kgdb_handle_exception(struct pt_regs *regs) vbr_val = trap_registers.vbr; asm("ldc %0, vbr": :"r"(vbr_val)); - - return; } /* Trigger a breakpoint by function */ diff --git a/arch/sh/kernel/process.c b/arch/sh/kernel/process.c index 486c06e1803..9d6a438b3ea 100644 --- a/arch/sh/kernel/process.c +++ b/arch/sh/kernel/process.c @@ -1,42 +1,30 @@ -/* $Id: process.c,v 1.28 2004/05/05 16:54:23 lethal Exp $ +/* + * arch/sh/kernel/process.c * - * linux/arch/sh/kernel/process.c + * This file handles the architecture-dependent parts of process handling.. * * Copyright (C) 1995 Linus Torvalds * * SuperH version: Copyright (C) 1999, 2000 Niibe Yutaka & Kaz Kojima * Copyright (C) 2006 Lineo Solutions Inc. support SH4A UBC + * Copyright (C) 2002 - 2006 Paul Mundt */ - -/* - * This file handles the architecture-dependent parts of process handling.. - */ - #include <linux/module.h> -#include <linux/unistd.h> #include <linux/mm.h> #include <linux/elfcore.h> -#include <linux/a.out.h> -#include <linux/slab.h> #include <linux/pm.h> -#include <linux/ptrace.h> #include <linux/kallsyms.h> #include <linux/kexec.h> - -#include <asm/io.h> #include <asm/uaccess.h> #include <asm/mmu_context.h> -#include <asm/elf.h> #include <asm/ubc.h> -static int hlt_counter=0; - +static int hlt_counter; int ubc_usercnt = 0; #define HARD_IDLE_TIMEOUT (HZ / 3) void (*pm_idle)(void); - void (*pm_power_off)(void); EXPORT_SYMBOL(pm_power_off); @@ -44,14 +32,12 @@ void disable_hlt(void) { hlt_counter++; } - EXPORT_SYMBOL(disable_hlt); void enable_hlt(void) { hlt_counter--; } - EXPORT_SYMBOL(enable_hlt); void default_idle(void) @@ -152,19 +138,21 @@ __asm__(".align 5\n" ".align 2\n\t" "1:.long do_exit"); +/* Don't use this in BL=1(cli). Or else, CPU resets! */ int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) -{ /* Don't use this in BL=1(cli). Or else, CPU resets! */ +{ struct pt_regs regs; memset(®s, 0, sizeof(regs)); - regs.regs[4] = (unsigned long) arg; - regs.regs[5] = (unsigned long) fn; + regs.regs[4] = (unsigned long)arg; + regs.regs[5] = (unsigned long)fn; - regs.pc = (unsigned long) kernel_thread_helper; + regs.pc = (unsigned long)kernel_thread_helper; regs.sr = (1 << 30); /* Ok, create the new process.. */ - return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, ®s, 0, NULL, NULL); + return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, + ®s, 0, NULL, NULL); } /* @@ -211,21 +199,20 @@ int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu) return fpvalid; } -/* +/* * Capture the user space registers if the task is not running (in user space) */ int dump_task_regs(struct task_struct *tsk, elf_gregset_t *regs) { struct pt_regs ptregs; - + ptregs = *task_pt_regs(tsk); elf_core_copy_regs(regs, &ptregs); return 1; } -int -dump_task_fpu (struct task_struct *tsk, elf_fpregset_t *fpu) +int dump_task_fpu(struct task_struct *tsk, elf_fpregset_t *fpu) { int fpvalid = 0; @@ -263,12 +250,14 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long usp, childregs->regs[15] = usp; ti->addr_limit = USER_DS; } else { - childregs->regs[15] = (unsigned long)task_stack_page(p) + THREAD_SIZE; + childregs->regs[15] = (unsigned long)task_stack_page(p) + + THREAD_SIZE; ti->addr_limit = KERNEL_DS; } - if (clone_flags & CLONE_SETTLS) { + + if (clone_flags & CLONE_SETTLS) childregs->gbr = childregs->regs[0]; - } + childregs->regs[0] = 0; /* Set return value for child */ p->thread.sp = (unsigned long) childregs; @@ -280,8 +269,7 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long usp, } /* Tracing by user break controller. */ -static void -ubc_set_tracing(int asid, unsigned long pc) +static void ubc_set_tracing(int asid, unsigned long pc) { #if defined(CONFIG_CPU_SH4A) unsigned long val; @@ -297,7 +285,7 @@ ubc_set_tracing(int asid, unsigned long pc) val = (UBC_CRR_RES | UBC_CRR_PCB | UBC_CRR_BIE); ctrl_outl(val, UBC_CRR0); - /* Read UBC register that we writed last. For chekking UBC Register changed */ + /* Read UBC register that we wrote last, for checking update */ val = ctrl_inl(UBC_CRR0); #else /* CONFIG_CPU_SH4A */ @@ -305,13 +293,14 @@ ubc_set_tracing(int asid, unsigned long pc) #ifdef CONFIG_MMU /* We don't have any ASID settings for the SH-2! */ - if (cpu_data->type != CPU_SH7604) + if (current_cpu_data.type != CPU_SH7604) ctrl_outb(asid, UBC_BASRA); #endif ctrl_outl(0, UBC_BAMRA); - if (cpu_data->type == CPU_SH7729 || cpu_data->type == CPU_SH7710) { + if (current_cpu_data.type == CPU_SH7729 || + current_cpu_data.type == CPU_SH7710) { ctrl_outw(BBR_INST | BBR_READ | BBR_CPU, UBC_BBRA); ctrl_outl(BRCR_PCBA | BRCR_PCTE, UBC_BRCR); } else { @@ -325,7 +314,8 @@ ubc_set_tracing(int asid, unsigned long pc) * switch_to(x,y) should switch tasks from x to y. * */ -struct task_struct *__switch_to(struct task_struct *prev, struct task_struct *next) +struct task_struct *__switch_to(struct task_struct *prev, + struct task_struct *next) { #if defined(CONFIG_SH_FPU) unlazy_fpu(prev, task_pt_regs(prev)); @@ -354,7 +344,7 @@ struct task_struct *__switch_to(struct task_struct *prev, struct task_struct *ne #ifdef CONFIG_MMU /* * Restore the kernel mode register - * k7 (r7_bank1) + * k7 (r7_bank1) */ asm volatile("ldc %0, r7_bank" : /* no output */ @@ -367,7 +357,7 @@ struct task_struct *__switch_to(struct task_struct *prev, struct task_struct *ne else if (next->thread.ubc_pc && next->mm) { int asid = 0; #ifdef CONFIG_MMU - asid |= next->mm->context.id & MMU_CONTEXT_ASID_MASK; + asid |= cpu_asid(smp_processor_id(), next->mm); #endif ubc_set_tracing(asid, next->thread.ubc_pc); } else { @@ -405,7 +395,8 @@ asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp, if (!newsp) newsp = regs->regs[15]; return do_fork(clone_flags, newsp, regs, 0, - (int __user *)parent_tidptr, (int __user *)child_tidptr); + (int __user *)parent_tidptr, + (int __user *)child_tidptr); } /* @@ -493,9 +484,27 @@ asmlinkage void break_point_trap(void) force_sig(SIGTRAP, current); } -asmlinkage void break_point_trap_software(unsigned long r4, unsigned long r5, - unsigned long r6, unsigned long r7, - struct pt_regs __regs) +/* + * Generic trap handler. + */ +asmlinkage void debug_trap_handler(unsigned long r4, unsigned long r5, + unsigned long r6, unsigned long r7, + struct pt_regs __regs) +{ + struct pt_regs *regs = RELOC_HIDE(&__regs, 0); + + /* Rewind */ + regs->pc -= 2; + + force_sig(SIGTRAP, current); +} + +/* + * Special handler for BUG() traps. + */ +asmlinkage void bug_trap_handler(unsigned long r4, unsigned long r5, + unsigned long r6, unsigned long r7, + struct pt_regs __regs) { struct pt_regs *regs = RELOC_HIDE(&__regs, 0); diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c index d6b817aa568..98802ab2821 100644 --- a/arch/sh/kernel/setup.c +++ b/arch/sh/kernel/setup.c @@ -1,14 +1,11 @@ /* - * linux/arch/sh/kernel/setup.c + * arch/sh/kernel/setup.c * - * Copyright (C) 1999 Niibe Yutaka - * Copyright (C) 2002, 2003 Paul Mundt - */ - -/* * This file handles the architecture-dependent parts of initialization + * + * Copyright (C) 1999 Niibe Yutaka + * Copyright (C) 2002 - 2006 Paul Mundt */ - #include <linux/screen_info.h> #include <linux/ioport.h> #include <linux/init.h> @@ -395,9 +392,9 @@ static const char *cpu_name[] = { [CPU_SH_NONE] = "Unknown" }; -const char *get_cpu_subtype(void) +const char *get_cpu_subtype(struct sh_cpuinfo *c) { - return cpu_name[boot_cpu_data.type]; + return cpu_name[c->type]; } #ifdef CONFIG_PROC_FS @@ -407,19 +404,19 @@ static const char *cpu_flags[] = { "ptea", "llsc", "l2", NULL }; -static void show_cpuflags(struct seq_file *m) +static void show_cpuflags(struct seq_file *m, struct sh_cpuinfo *c) { unsigned long i; seq_printf(m, "cpu flags\t:"); - if (!cpu_data->flags) { + if (!c->flags) { seq_printf(m, " %s\n", cpu_flags[0]); return; } for (i = 0; cpu_flags[i]; i++) - if ((cpu_data->flags & (1 << i))) + if ((c->flags & (1 << i))) seq_printf(m, " %s", cpu_flags[i+1]); seq_printf(m, "\n"); @@ -441,16 +438,20 @@ static void show_cacheinfo(struct seq_file *m, const char *type, */ static int show_cpuinfo(struct seq_file *m, void *v) { - unsigned int cpu = smp_processor_id(); + struct sh_cpuinfo *c = v; + unsigned int cpu = c - cpu_data; + + if (!cpu_online(cpu)) + return 0; - if (!cpu && cpu_online(cpu)) + if (cpu == 0) seq_printf(m, "machine\t\t: %s\n", get_system_type()); seq_printf(m, "processor\t: %d\n", cpu); seq_printf(m, "cpu family\t: %s\n", init_utsname()->machine); - seq_printf(m, "cpu type\t: %s\n", get_cpu_subtype()); + seq_printf(m, "cpu type\t: %s\n", get_cpu_subtype(c)); - show_cpuflags(m); + show_cpuflags(m, c); seq_printf(m, "cache type\t: "); @@ -459,22 +460,22 @@ static int show_cpuinfo(struct seq_file *m, void *v) * unified cache on the SH-2 and SH-3, as well as the harvard * style cache on the SH-4. */ - if (boot_cpu_data.icache.flags & SH_CACHE_COMBINED) { + if (c->icache.flags & SH_CACHE_COMBINED) { seq_printf(m, "unified\n"); - show_cacheinfo(m, "cache", boot_cpu_data.icache); + show_cacheinfo(m, "cache", c->icache); } else { seq_printf(m, "split (harvard)\n"); - show_cacheinfo(m, "icache", boot_cpu_data.icache); - show_cacheinfo(m, "dcache", boot_cpu_data.dcache); + show_cacheinfo(m, "icache", c->icache); + show_cacheinfo(m, "dcache", c->dcache); } /* Optional secondary cache */ - if (boot_cpu_data.flags & CPU_HAS_L2_CACHE) - show_cacheinfo(m, "scache", boot_cpu_data.scache); + if (c->flags & CPU_HAS_L2_CACHE) + show_cacheinfo(m, "scache", c->scache); seq_printf(m, "bogomips\t: %lu.%02lu\n", - boot_cpu_data.loops_per_jiffy/(500000/HZ), - (boot_cpu_data.loops_per_jiffy/(5000/HZ)) % 100); + c->loops_per_jiffy/(500000/HZ), + (c->loops_per_jiffy/(5000/HZ)) % 100); return show_clocks(m); } diff --git a/arch/sh/kernel/sh_ksyms.c b/arch/sh/kernel/sh_ksyms.c index e6106239a0f..fe1b276c97c 100644 --- a/arch/sh/kernel/sh_ksyms.c +++ b/arch/sh/kernel/sh_ksyms.c @@ -105,7 +105,6 @@ EXPORT_SYMBOL(__flush_purge_region); EXPORT_SYMBOL(clear_user_page); #endif -EXPORT_SYMBOL(flush_tlb_page); EXPORT_SYMBOL(__down_trylock); #ifdef CONFIG_SMP diff --git a/arch/sh/kernel/signal.c b/arch/sh/kernel/signal.c index 379c88bf5d9..32f10a03fbb 100644 --- a/arch/sh/kernel/signal.c +++ b/arch/sh/kernel/signal.c @@ -127,7 +127,7 @@ static inline int restore_sigcontext_fpu(struct sigcontext __user *sc) { struct task_struct *tsk = current; - if (!(cpu_data->flags & CPU_HAS_FPU)) + if (!(current_cpu_data.flags & CPU_HAS_FPU)) return 0; set_used_math(); @@ -140,7 +140,7 @@ static inline int save_sigcontext_fpu(struct sigcontext __user *sc, { struct task_struct *tsk = current; - if (!(cpu_data->flags & CPU_HAS_FPU)) + if (!(current_cpu_data.flags & CPU_HAS_FPU)) return 0; if (!used_math()) { @@ -181,7 +181,7 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc, int *r0_p #undef COPY #ifdef CONFIG_SH_FPU - if (cpu_data->flags & CPU_HAS_FPU) { + if (current_cpu_data.flags & CPU_HAS_FPU) { int owned_fp; struct task_struct *tsk = current; diff --git a/arch/sh/kernel/syscalls.S b/arch/sh/kernel/syscalls.S index ca81976e9e3..38fc8cd3ea3 100644 --- a/arch/sh/kernel/syscalls.S +++ b/arch/sh/kernel/syscalls.S @@ -319,15 +319,15 @@ ENTRY(sys_call_table) .long sys_mq_getsetattr .long sys_kexec_load .long sys_waitid - .long sys_ni_syscall /* 285 */ - .long sys_add_key + .long sys_add_key /* 285 */ .long sys_request_key .long sys_keyctl .long sys_ioprio_set - .long sys_ioprio_get /* 290 */ - .long sys_inotify_init + .long sys_ioprio_get + .long sys_inotify_init /* 290 */ .long sys_inotify_add_watch .long sys_inotify_rm_watch + .long sys_ni_syscall .long sys_migrate_pages .long sys_openat /* 295 */ .long sys_mkdirat diff --git a/arch/sh/kernel/traps.c b/arch/sh/kernel/traps.c index ec110157992..e9f168f60f9 100644 --- a/arch/sh/kernel/traps.c +++ b/arch/sh/kernel/traps.c @@ -156,13 +156,13 @@ static inline void do_bug_verbose(struct pt_regs *regs) { } #endif /* CONFIG_DEBUG_BUGVERBOSE */ -#endif /* CONFIG_BUG */ void handle_BUG(struct pt_regs *regs) { do_bug_verbose(regs); die("Kernel BUG", regs, TRAPA_BUG_OPCODE & 0xff); } +#endif /* CONFIG_BUG */ /* * handle an instruction that does an unaligned memory access by emulating the @@ -641,7 +641,7 @@ int is_dsp_inst(struct pt_regs *regs) * Safe guard if DSP mode is already enabled or we're lacking * the DSP altogether. */ - if (!(cpu_data->flags & CPU_HAS_DSP) || (regs->sr & SR_DSP)) + if (!(current_cpu_data.flags & CPU_HAS_DSP) || (regs->sr & SR_DSP)) return 0; get_user(inst, ((unsigned short *) regs->pc)); |