From 09a072947791088b88ae15111cf68fc5aaaf758d Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 9 Nov 2009 16:27:40 +0900 Subject: sh: hw-breakpoints: Add preliminary support for SH-4A UBC. This adds preliminary support for the SH-4A UBC to the hw-breakpoints API. Presently only a single channel is implemented, and the ptrace interface still needs to be converted. This is the first step to cleaning up the long-standing UBC mess, making the UBC more generally accessible, and finally making it SMP safe. An additional abstraction will be layered on top of this as with the perf events code to permit the various CPU families to wire up support for their own specific UBCs, as many variations exist. Signed-off-by: Paul Mundt --- arch/sh/include/asm/Kbuild | 4 ++- arch/sh/include/asm/hw_breakpoint.h | 53 +++++++++++++++++++++++++++++++++++++ arch/sh/include/asm/kdebug.h | 2 ++ arch/sh/include/asm/processor_32.h | 8 +++--- arch/sh/include/asm/system.h | 2 -- arch/sh/include/asm/thread_info.h | 2 ++ arch/sh/include/asm/ubc.h | 8 +++++- 7 files changed, 70 insertions(+), 9 deletions(-) create mode 100644 arch/sh/include/asm/hw_breakpoint.h (limited to 'arch/sh/include/asm') diff --git a/arch/sh/include/asm/Kbuild b/arch/sh/include/asm/Kbuild index e121c30f797d..46cb93477bcb 100644 --- a/arch/sh/include/asm/Kbuild +++ b/arch/sh/include/asm/Kbuild @@ -1,6 +1,8 @@ include include/asm-generic/Kbuild.asm -header-y += cachectl.h cpu-features.h +header-y += cachectl.h +header-y += cpu-features.h +header-y += hw_breakpoint.h unifdef-y += unistd_32.h unifdef-y += unistd_64.h diff --git a/arch/sh/include/asm/hw_breakpoint.h b/arch/sh/include/asm/hw_breakpoint.h new file mode 100644 index 000000000000..0f4a00f60058 --- /dev/null +++ b/arch/sh/include/asm/hw_breakpoint.h @@ -0,0 +1,53 @@ +#ifndef __ASM_SH_HW_BREAKPOINT_H +#define __ASM_SH_HW_BREAKPOINT_H + +#include +#include +#include + +#ifdef __KERNEL__ +#define __ARCH_HW_BREAKPOINT_H + +struct arch_hw_breakpoint { + char *name; /* Contains name of the symbol to set bkpt */ + unsigned long address; + unsigned long asid; + u16 len; + u16 type; +}; + +enum { + SH_BREAKPOINT_READ = (1 << 1), + SH_BREAKPOINT_WRITE = (1 << 2), + SH_BREAKPOINT_RW = SH_BREAKPOINT_READ | SH_BREAKPOINT_WRITE, + + SH_BREAKPOINT_LEN_1 = (1 << 12), + SH_BREAKPOINT_LEN_2 = (1 << 13), + SH_BREAKPOINT_LEN_4 = SH_BREAKPOINT_LEN_1 | SH_BREAKPOINT_LEN_2, + SH_BREAKPOINT_LEN_8 = (1 << 14), +}; + +/* Total number of available UBC channels */ +#define HBP_NUM 1 /* XXX */ + +struct perf_event; +struct task_struct; +struct pmu; + +extern int arch_check_va_in_userspace(unsigned long va, u16 hbp_len); +extern int arch_validate_hwbkpt_settings(struct perf_event *bp, + struct task_struct *tsk); +extern int hw_breakpoint_exceptions_notify(struct notifier_block *unused, + unsigned long val, void *data); + +int arch_install_hw_breakpoint(struct perf_event *bp); +void arch_uninstall_hw_breakpoint(struct perf_event *bp); +void hw_breakpoint_pmu_read(struct perf_event *bp); +void hw_breakpoint_pmu_unthrottle(struct perf_event *bp); + +extern void arch_fill_perf_breakpoint(struct perf_event *bp); + +extern struct pmu perf_ops_bp; + +#endif /* __KERNEL__ */ +#endif /* __ASM_SH_HW_BREAKPOINT_H */ diff --git a/arch/sh/include/asm/kdebug.h b/arch/sh/include/asm/kdebug.h index 985219f9759e..5f6d2e9ccb7c 100644 --- a/arch/sh/include/asm/kdebug.h +++ b/arch/sh/include/asm/kdebug.h @@ -6,6 +6,8 @@ enum die_val { DIE_TRAP, DIE_NMI, DIE_OOPS, + DIE_BREAKPOINT, + DIE_SSTEP, }; #endif /* __ASM_SH_KDEBUG_H */ diff --git a/arch/sh/include/asm/processor_32.h b/arch/sh/include/asm/processor_32.h index 9a8714945dc9..f4b54040dbc3 100644 --- a/arch/sh/include/asm/processor_32.h +++ b/arch/sh/include/asm/processor_32.h @@ -14,6 +14,7 @@ #include #include #include +#include /* * Default implementation of macro that returns current @@ -99,8 +100,8 @@ struct thread_struct { unsigned long sp; unsigned long pc; - /* Hardware debugging registers */ - unsigned long ubc_pc; + /* Save middle states of ptrace breakpoints */ + struct perf_event *ptrace_bps[NR_UBC_CHANNELS]; /* floating point info */ union sh_fpu_union fpu; @@ -111,9 +112,6 @@ struct thread_struct { #endif }; -/* Count of active tasks with UBC settings */ -extern int ubc_usercnt; - #define INIT_THREAD { \ .sp = sizeof(init_stack) + (long) &init_stack, \ } diff --git a/arch/sh/include/asm/system.h b/arch/sh/include/asm/system.h index b5c5acdc8c0e..1014da8b3ed3 100644 --- a/arch/sh/include/asm/system.h +++ b/arch/sh/include/asm/system.h @@ -144,8 +144,6 @@ void per_cpu_trap_init(void); void default_idle(void); void cpu_idle_wait(void); -asmlinkage void break_point_trap(void); - #ifdef CONFIG_SUPERH32 #define BUILD_TRAP_HANDLER(name) \ asmlinkage void name##_trap_handler(unsigned long r4, unsigned long r5, \ diff --git a/arch/sh/include/asm/thread_info.h b/arch/sh/include/asm/thread_info.h index bdeb9d46d17d..8ab9145bf50b 100644 --- a/arch/sh/include/asm/thread_info.h +++ b/arch/sh/include/asm/thread_info.h @@ -117,6 +117,7 @@ extern void free_thread_info(struct thread_info *ti); #define TIF_SECCOMP 6 /* secure computing */ #define TIF_NOTIFY_RESUME 7 /* callback before returning to user */ #define TIF_SYSCALL_TRACEPOINT 8 /* for ftrace syscall instrumentation */ +#define TIF_DEBUG 9 /* uses UBC */ #define TIF_USEDFPU 16 /* FPU was used by this task this quantum (SMP) */ #define TIF_POLLING_NRFLAG 17 /* true if poll_idle() is polling TIF_NEED_RESCHED */ #define TIF_MEMDIE 18 @@ -131,6 +132,7 @@ extern void free_thread_info(struct thread_info *ti); #define _TIF_SECCOMP (1 << TIF_SECCOMP) #define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME) #define _TIF_SYSCALL_TRACEPOINT (1 << TIF_SYSCALL_TRACEPOINT) +#define _TIF_DEBUG (1 << TIF_DEBUG) #define _TIF_USEDFPU (1 << TIF_USEDFPU) #define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG) #define _TIF_FREEZE (1 << TIF_FREEZE) diff --git a/arch/sh/include/asm/ubc.h b/arch/sh/include/asm/ubc.h index 4ca4b7717371..dd7878197b6e 100644 --- a/arch/sh/include/asm/ubc.h +++ b/arch/sh/include/asm/ubc.h @@ -10,8 +10,8 @@ */ #ifndef __ASM_SH_UBC_H #define __ASM_SH_UBC_H -#ifdef __KERNEL__ +#ifdef __KERNEL__ #include /* User Break Controller */ @@ -60,6 +60,12 @@ #define BRCR_UBDE (1 << 0) #endif +/* + * All SH parts have 2 UBC channels. I defy any hardware designer to + * invalidate this assertion. + */ +#define NR_UBC_CHANNELS 2 + #ifndef __ASSEMBLY__ /* arch/sh/kernel/cpu/ubc.S */ extern void ubc_sleep(void); -- cgit v1.2.3 From b73c806341cfc7492ede6a2ce713cb579547d0ab Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Wed, 25 Nov 2009 22:00:08 +0000 Subject: sh: Abstract the number of page table levels Keep the dimensions of the page tables in a separate header file in preparation for allowing a three level page table structure. Signed-off-by: Matt Fleming Signed-off-by: Paul Mundt --- arch/sh/include/asm/pgalloc.h | 24 +++--------------------- arch/sh/include/asm/pgalloc_nopmd.h | 30 ++++++++++++++++++++++++++++++ arch/sh/include/asm/pgtable.h | 18 +----------------- arch/sh/include/asm/pgtable_nopmd.h | 22 ++++++++++++++++++++++ 4 files changed, 56 insertions(+), 38 deletions(-) create mode 100644 arch/sh/include/asm/pgalloc_nopmd.h create mode 100644 arch/sh/include/asm/pgtable_nopmd.h (limited to 'arch/sh/include/asm') diff --git a/arch/sh/include/asm/pgalloc.h b/arch/sh/include/asm/pgalloc.h index 63ca37bd9a95..fe9f037ac5fd 100644 --- a/arch/sh/include/asm/pgalloc.h +++ b/arch/sh/include/asm/pgalloc.h @@ -4,9 +4,10 @@ #include #include -#define QUICK_PGD 0 /* We preserve special mappings over free */ #define QUICK_PT 1 /* Other page table pages that are zero on free */ +#include + static inline void pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd, pte_t *pte) { @@ -20,28 +21,9 @@ static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd, } #define pmd_pgtable(pmd) pmd_page(pmd) -static inline void pgd_ctor(void *x) -{ - pgd_t *pgd = x; - - memcpy(pgd + USER_PTRS_PER_PGD, - swapper_pg_dir + USER_PTRS_PER_PGD, - (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t)); -} - /* * Allocate and free page tables. */ -static inline pgd_t *pgd_alloc(struct mm_struct *mm) -{ - return quicklist_alloc(QUICK_PGD, GFP_KERNEL | __GFP_REPEAT, pgd_ctor); -} - -static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd) -{ - quicklist_free(QUICK_PGD, NULL, pgd); -} - static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address) { @@ -81,7 +63,7 @@ do { \ static inline void check_pgt_cache(void) { - quicklist_trim(QUICK_PGD, NULL, 25, 16); + __check_pgt_cache(); quicklist_trim(QUICK_PT, NULL, 25, 16); } diff --git a/arch/sh/include/asm/pgalloc_nopmd.h b/arch/sh/include/asm/pgalloc_nopmd.h new file mode 100644 index 000000000000..e4b344c37e74 --- /dev/null +++ b/arch/sh/include/asm/pgalloc_nopmd.h @@ -0,0 +1,30 @@ +#ifndef __ASM_SH_PGALLOC_NOPMD_H +#define __ASM_SH_PGALLOC_NOPMD_H + +#define QUICK_PGD 0 /* We preserve special mappings over free */ + +static inline void pgd_ctor(void *x) +{ + pgd_t *pgd = x; + + memcpy(pgd + USER_PTRS_PER_PGD, + swapper_pg_dir + USER_PTRS_PER_PGD, + (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t)); +} + +static inline pgd_t *pgd_alloc(struct mm_struct *mm) +{ + return quicklist_alloc(QUICK_PGD, GFP_KERNEL | __GFP_REPEAT, pgd_ctor); +} + +static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd) +{ + quicklist_free(QUICK_PGD, NULL, pgd); +} + +static inline void __check_pgt_cache(void) +{ + quicklist_trim(QUICK_PGD, NULL, 25, 16); +} + +#endif /* __ASM_SH_PGALLOC_NOPMD_H */ diff --git a/arch/sh/include/asm/pgtable.h b/arch/sh/include/asm/pgtable.h index ba3046e4f06f..9a0f66c1134c 100644 --- a/arch/sh/include/asm/pgtable.h +++ b/arch/sh/include/asm/pgtable.h @@ -12,7 +12,7 @@ #ifndef __ASM_SH_PGTABLE_H #define __ASM_SH_PGTABLE_H -#include +#include #include #ifndef __ASSEMBLY__ @@ -51,28 +51,12 @@ static inline unsigned long long neff_sign_extend(unsigned long val) #define NPHYS_SIGN (1LL << (NPHYS - 1)) #define NPHYS_MASK (-1LL << NPHYS) -/* - * traditional two-level paging structure - */ -/* PTE bits */ -#if defined(CONFIG_X2TLB) || defined(CONFIG_SUPERH64) -# define PTE_MAGNITUDE 3 /* 64-bit PTEs on extended mode SH-X2 TLB */ -#else -# define PTE_MAGNITUDE 2 /* 32-bit PTEs */ -#endif -#define PTE_SHIFT PAGE_SHIFT -#define PTE_BITS (PTE_SHIFT - PTE_MAGNITUDE) - -/* PGD bits */ -#define PGDIR_SHIFT (PTE_SHIFT + PTE_BITS) #define PGDIR_SIZE (1UL << PGDIR_SHIFT) #define PGDIR_MASK (~(PGDIR_SIZE-1)) /* Entries per level */ #define PTRS_PER_PTE (PAGE_SIZE / (1 << PTE_MAGNITUDE)) -#define PTRS_PER_PGD (PAGE_SIZE / sizeof(pgd_t)) -#define USER_PTRS_PER_PGD (TASK_SIZE/PGDIR_SIZE) #define FIRST_USER_ADDRESS 0 #define PHYS_ADDR_MASK29 0x1fffffff diff --git a/arch/sh/include/asm/pgtable_nopmd.h b/arch/sh/include/asm/pgtable_nopmd.h new file mode 100644 index 000000000000..f0b525b3cb4a --- /dev/null +++ b/arch/sh/include/asm/pgtable_nopmd.h @@ -0,0 +1,22 @@ +#ifndef __ASM_SH_PGTABLE_NOPMD_H +#define __ASM_SH_PGTABLE_NOPMD_H + +#include + +/* + * traditional two-level paging structure + */ + +/* PTE bits */ +#define PTE_MAGNITUDE 2 /* 32-bit PTEs */ + +#define PTE_SHIFT PAGE_SHIFT +#define PTE_BITS (PTE_SHIFT - PTE_MAGNITUDE) + +/* PGD bits */ +#define PGDIR_SHIFT (PTE_SHIFT + PTE_BITS) + +#define PTRS_PER_PGD (PAGE_SIZE / (1 << PTE_MAGNITUDE)) +#define USER_PTRS_PER_PGD (TASK_SIZE/PGDIR_SIZE) + +#endif /* __ASM_SH_PGTABLE_NOPMD_H */ -- cgit v1.2.3 From 5d9b4b19f118abfb75e352841f7bf74580d7e427 Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Sun, 13 Dec 2009 14:38:50 +0000 Subject: sh: Definitions for 3-level page table layout If using 64-bit PTEs and 4K pages then each page table has 512 entries (as opposed to 1024 entries with 32-bit PTEs). Unlike MIPS, SH follows the convention that all structures in the page table (pgd_t, pmd_t, pgprot_t, etc) must be the same size. Therefore, 64-bit PTEs require 64-bit PGD entries, etc. Using 2-levels of page tables and 64-bit PTEs it is only possible to map 1GB of virtual address space. In order to map all 4GB of virtual address space we need to adopt a 3-level page table layout. This actually works out better for CONFIG_SUPERH32 because we only waste 2 PGD entries on the P1 and P2 areas (which are untranslated) instead of 256. Signed-off-by: Matt Fleming Signed-off-by: Paul Mundt --- arch/sh/include/asm/pgalloc.h | 4 +++ arch/sh/include/asm/pgalloc_pmd.h | 41 +++++++++++++++++++++++++++++ arch/sh/include/asm/pgtable.h | 4 +++ arch/sh/include/asm/pgtable_pmd.h | 55 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 104 insertions(+) create mode 100644 arch/sh/include/asm/pgalloc_pmd.h create mode 100644 arch/sh/include/asm/pgtable_pmd.h (limited to 'arch/sh/include/asm') diff --git a/arch/sh/include/asm/pgalloc.h b/arch/sh/include/asm/pgalloc.h index fe9f037ac5fd..4ea27855c3b5 100644 --- a/arch/sh/include/asm/pgalloc.h +++ b/arch/sh/include/asm/pgalloc.h @@ -6,7 +6,11 @@ #define QUICK_PT 1 /* Other page table pages that are zero on free */ +#ifdef CONFIG_PGTABLE_LEVELS_3 +#include +#else #include +#endif static inline void pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd, pte_t *pte) diff --git a/arch/sh/include/asm/pgalloc_pmd.h b/arch/sh/include/asm/pgalloc_pmd.h new file mode 100644 index 000000000000..20f75cc4eb09 --- /dev/null +++ b/arch/sh/include/asm/pgalloc_pmd.h @@ -0,0 +1,41 @@ +#ifndef __ASM_SH_PGALLOC_PMD_H +#define __ASM_SH_PGALLOC_PMD_H + +static inline pgd_t *pgd_alloc(struct mm_struct *mm) +{ + pgd_t *pgd; + int i; + + pgd = kzalloc(sizeof(*pgd) * PTRS_PER_PGD, GFP_KERNEL | __GFP_REPEAT); + + for (i = USER_PTRS_PER_PGD; i < PTRS_PER_PGD; i++) + pgd[i] = swapper_pg_dir[i]; + + return pgd; +} + +static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd) +{ + kfree(pgd); +} + +static inline void __check_pgt_cache(void) +{ +} + +static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd) +{ + set_pud(pud, __pud((unsigned long)pmd)); +} + +static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address) +{ + return quicklist_alloc(QUICK_PT, GFP_KERNEL | __GFP_REPEAT, NULL); +} + +static inline void pmd_free(struct mm_struct *mm, pmd_t *pmd) +{ + quicklist_free(QUICK_PT, NULL, pmd); +} + +#endif /* __ASM_SH_PGALLOC_PMD_H */ diff --git a/arch/sh/include/asm/pgtable.h b/arch/sh/include/asm/pgtable.h index 9a0f66c1134c..9effcc3b0d10 100644 --- a/arch/sh/include/asm/pgtable.h +++ b/arch/sh/include/asm/pgtable.h @@ -12,7 +12,11 @@ #ifndef __ASM_SH_PGTABLE_H #define __ASM_SH_PGTABLE_H +#ifdef CONFIG_PGTABLE_LEVELS_3 +#include +#else #include +#endif #include #ifndef __ASSEMBLY__ diff --git a/arch/sh/include/asm/pgtable_pmd.h b/arch/sh/include/asm/pgtable_pmd.h new file mode 100644 index 000000000000..78dc36e1c2dd --- /dev/null +++ b/arch/sh/include/asm/pgtable_pmd.h @@ -0,0 +1,55 @@ +#ifndef __ASM_SH_PGTABLE_PMD_H +#define __ASM_SH_PGTABLE_PMD_H + +#include + +/* + * Some cores need a 3-level page table layout, for example when using + * 64-bit PTEs and 4K pages. + */ + +#define PTE_MAGNITUDE 3 /* 64-bit PTEs on extended mode SH-X2 TLB */ + +/* PGD bits */ +#define PGDIR_SHIFT 30 + +#define PTRS_PER_PGD 4 +#define USER_PTRS_PER_PGD 2 + +/* PMD bits */ +#define PMD_SHIFT (PAGE_SHIFT + (PAGE_SHIFT - 3)) +#define PMD_SIZE (1UL << PMD_SHIFT) +#define PMD_MASK (~(PMD_SIZE-1)) + +#define PTRS_PER_PMD (PAGE_SIZE / sizeof(pmd_t)) + +#define pmd_ERROR(e) \ + printk("%s:%d: bad pmd %016llx.\n", __FILE__, __LINE__, pmd_val(e)) + +typedef struct { unsigned long long pmd; } pmd_t; +#define pmd_val(x) ((x).pmd) +#define __pmd(x) ((pmd_t) { (x) } ) + +static inline unsigned long pud_page_vaddr(pud_t pud) +{ + return pud_val(pud); +} + +#define pmd_index(address) (((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1)) +static inline pmd_t *pmd_offset(pud_t *pud, unsigned long address) +{ + return (pmd_t *)pud_page_vaddr(*pud) + pmd_index(address); +} + +#define pud_none(x) (!pud_val(x)) +#define pud_present(x) (pud_val(x)) +#define pud_clear(xp) do { set_pud(xp, __pud(0)); } while (0) +#define pud_bad(x) (pud_val(x) & ~PAGE_MASK) + +/* + * (puds are folded into pgds so this doesn't get actually called, + * but the define is needed for a generic inline function.) + */ +#define set_pud(pudptr, pudval) do { *(pudptr) = (pudval); } while(0) + +#endif /* __ASM_SH_PGTABLE_PMD_H */ -- cgit v1.2.3 From 34d0b5af50a063cded842716633501b38ff815fb Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 28 Dec 2009 17:53:47 +0900 Subject: sh: Convert ptrace to hw_breakpoint API. This is the initial step for converting singlestep handling via ptrace over to hw_breakpoints. Signed-off-by: Paul Mundt --- arch/sh/include/asm/ptrace.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'arch/sh/include/asm') diff --git a/arch/sh/include/asm/ptrace.h b/arch/sh/include/asm/ptrace.h index 1dc12cb44a2d..201d11ef211f 100644 --- a/arch/sh/include/asm/ptrace.h +++ b/arch/sh/include/asm/ptrace.h @@ -124,6 +124,12 @@ struct task_struct; extern void user_enable_single_step(struct task_struct *); extern void user_disable_single_step(struct task_struct *); +struct perf_event; +struct perf_sample_data; + +extern void ptrace_triggered(struct perf_event *bp, int nmi, + struct perf_sample_data *data, struct pt_regs *regs); + #define task_pt_regs(task) \ ((struct pt_regs *) (task_stack_page(task) + THREAD_SIZE) - 1) -- cgit v1.2.3 From e591a517230a97e93f5edd19e7bef7ec8d22ac2b Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Sun, 13 Dec 2009 22:18:09 +0000 Subject: sh: Remove unused functions Apply some TLC to the SH64 header files and remove some functions that are not used anymore. Signed-off-by: Matt Fleming --- arch/sh/include/asm/pgtable_64.h | 11 ----------- 1 file changed, 11 deletions(-) (limited to 'arch/sh/include/asm') diff --git a/arch/sh/include/asm/pgtable_64.h b/arch/sh/include/asm/pgtable_64.h index 17cdbecc3adc..dd381588c695 100644 --- a/arch/sh/include/asm/pgtable_64.h +++ b/arch/sh/include/asm/pgtable_64.h @@ -43,11 +43,6 @@ static __inline__ void set_pte(pte_t *pteptr, pte_t pteval) } #define set_pte_at(mm,addr,ptep,pteval) set_pte(ptep,pteval) -static __inline__ void pmd_set(pmd_t *pmdp,pte_t *ptep) -{ - pmd_val(*pmdp) = (unsigned long) ptep; -} - /* * PGD defines. Top level. */ @@ -202,12 +197,6 @@ static __inline__ void pmd_set(pmd_t *pmdp,pte_t *ptep) #define pgprot_noncached(x) __pgprot(((x).pgprot & ~(_PAGE_CACHABLE)) | _PAGE_DEVICE) #define pgprot_writecombine(prot) __pgprot(pgprot_val(prot) & ~_PAGE_CACHABLE) -/* - * Handling allocation failures during page table setup. - */ -extern void __handle_bad_pmd_kernel(pmd_t * pmd); -#define __handle_bad_pmd(x) __handle_bad_pmd_kernel(x) - /* * PTE level access routines. * -- cgit v1.2.3 From 3f5ab768164df9a44721660b96e0accb92eb2c24 Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Thu, 24 Dec 2009 20:38:45 +0000 Subject: sh: Correct the PTRS_PER_PMD and PMD_SHIFT values The previous expressions were wrong which made free_pmd_range() explode when using anything other than 4KB pages (which is why 8KB and 64KB pages were disabled with the 3-level page table layout). The problem was that pmd_offset() was returning an index of non-zero when it should have been returning 0. This non-zero offset was used to calculate the address of the pmd table to free in free_pmd_range(), which ended up trying to free an object that was not aligned on a page boundary. Now 3-level page tables should work with 4KB, 8KB and 64KB pages. Signed-off-by: Matt Fleming --- arch/sh/include/asm/pgtable_pmd.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch/sh/include/asm') diff --git a/arch/sh/include/asm/pgtable_pmd.h b/arch/sh/include/asm/pgtable_pmd.h index 78dc36e1c2dd..42a180e534a8 100644 --- a/arch/sh/include/asm/pgtable_pmd.h +++ b/arch/sh/include/asm/pgtable_pmd.h @@ -17,11 +17,11 @@ #define USER_PTRS_PER_PGD 2 /* PMD bits */ -#define PMD_SHIFT (PAGE_SHIFT + (PAGE_SHIFT - 3)) +#define PMD_SHIFT (PAGE_SHIFT + (PAGE_SHIFT - PTE_MAGNITUDE)) #define PMD_SIZE (1UL << PMD_SHIFT) #define PMD_MASK (~(PMD_SIZE-1)) -#define PTRS_PER_PMD (PAGE_SIZE / sizeof(pmd_t)) +#define PTRS_PER_PMD ((1 << PGDIR_SHIFT) / PMD_SIZE) #define pmd_ERROR(e) \ printk("%s:%d: bad pmd %016llx.\n", __FILE__, __LINE__, pmd_val(e)) -- cgit v1.2.3 From 2a5eacca85d39d8b6dffae821d7d260f05584dc7 Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Thu, 31 Dec 2009 12:19:24 +0000 Subject: sh: Move page table allocation out of line We also switched away from quicklists and instead moved to slab caches. After benchmarking both implementations the difference is negligible. The slab caches suit us better though because the size of a pgd table is just 4 entries when we're using a 3-level page table layout and quicklists always deal with pages. Signed-off-by: Matt Fleming --- arch/sh/include/asm/pgalloc.h | 10 +++++---- arch/sh/include/asm/pgalloc_nopmd.h | 30 --------------------------- arch/sh/include/asm/pgalloc_pmd.h | 41 ------------------------------------- arch/sh/include/asm/pgtable.h | 4 ++-- 4 files changed, 8 insertions(+), 77 deletions(-) delete mode 100644 arch/sh/include/asm/pgalloc_nopmd.h delete mode 100644 arch/sh/include/asm/pgalloc_pmd.h (limited to 'arch/sh/include/asm') diff --git a/arch/sh/include/asm/pgalloc.h b/arch/sh/include/asm/pgalloc.h index 4ea27855c3b5..e106474996b2 100644 --- a/arch/sh/include/asm/pgalloc.h +++ b/arch/sh/include/asm/pgalloc.h @@ -6,10 +6,13 @@ #define QUICK_PT 1 /* Other page table pages that are zero on free */ +extern pgd_t *pgd_alloc(struct mm_struct *); +extern void pgd_free(struct mm_struct *mm, pgd_t *pgd); + #ifdef CONFIG_PGTABLE_LEVELS_3 -#include -#else -#include +extern void pud_populate(struct mm_struct *mm, pud_t *pudp, pmd_t *pmd); +extern pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address); +extern void pmd_free(struct mm_struct *mm, pmd_t *pmd); #endif static inline void pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd, @@ -67,7 +70,6 @@ do { \ static inline void check_pgt_cache(void) { - __check_pgt_cache(); quicklist_trim(QUICK_PT, NULL, 25, 16); } diff --git a/arch/sh/include/asm/pgalloc_nopmd.h b/arch/sh/include/asm/pgalloc_nopmd.h deleted file mode 100644 index e4b344c37e74..000000000000 --- a/arch/sh/include/asm/pgalloc_nopmd.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef __ASM_SH_PGALLOC_NOPMD_H -#define __ASM_SH_PGALLOC_NOPMD_H - -#define QUICK_PGD 0 /* We preserve special mappings over free */ - -static inline void pgd_ctor(void *x) -{ - pgd_t *pgd = x; - - memcpy(pgd + USER_PTRS_PER_PGD, - swapper_pg_dir + USER_PTRS_PER_PGD, - (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t)); -} - -static inline pgd_t *pgd_alloc(struct mm_struct *mm) -{ - return quicklist_alloc(QUICK_PGD, GFP_KERNEL | __GFP_REPEAT, pgd_ctor); -} - -static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd) -{ - quicklist_free(QUICK_PGD, NULL, pgd); -} - -static inline void __check_pgt_cache(void) -{ - quicklist_trim(QUICK_PGD, NULL, 25, 16); -} - -#endif /* __ASM_SH_PGALLOC_NOPMD_H */ diff --git a/arch/sh/include/asm/pgalloc_pmd.h b/arch/sh/include/asm/pgalloc_pmd.h deleted file mode 100644 index 20f75cc4eb09..000000000000 --- a/arch/sh/include/asm/pgalloc_pmd.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef __ASM_SH_PGALLOC_PMD_H -#define __ASM_SH_PGALLOC_PMD_H - -static inline pgd_t *pgd_alloc(struct mm_struct *mm) -{ - pgd_t *pgd; - int i; - - pgd = kzalloc(sizeof(*pgd) * PTRS_PER_PGD, GFP_KERNEL | __GFP_REPEAT); - - for (i = USER_PTRS_PER_PGD; i < PTRS_PER_PGD; i++) - pgd[i] = swapper_pg_dir[i]; - - return pgd; -} - -static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd) -{ - kfree(pgd); -} - -static inline void __check_pgt_cache(void) -{ -} - -static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd) -{ - set_pud(pud, __pud((unsigned long)pmd)); -} - -static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address) -{ - return quicklist_alloc(QUICK_PT, GFP_KERNEL | __GFP_REPEAT, NULL); -} - -static inline void pmd_free(struct mm_struct *mm, pmd_t *pmd) -{ - quicklist_free(QUICK_PT, NULL, pmd); -} - -#endif /* __ASM_SH_PGALLOC_PMD_H */ diff --git a/arch/sh/include/asm/pgtable.h b/arch/sh/include/asm/pgtable.h index 9effcc3b0d10..78598ec33d0a 100644 --- a/arch/sh/include/asm/pgtable.h +++ b/arch/sh/include/asm/pgtable.h @@ -141,9 +141,9 @@ typedef pte_t *pte_addr_t; #define pte_pfn(x) ((unsigned long)(((x).pte_low >> PAGE_SHIFT))) /* - * No page table caches to initialise + * Initialise the page table caches */ -#define pgtable_cache_init() do { } while (0) +extern void pgtable_cache_init(void); struct vm_area_struct; -- cgit v1.2.3 From 0176bd3dab4fe522bfb6ceab9e3c441fe0305738 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 5 Jan 2010 12:35:00 +0900 Subject: sh: Drop down to a single quicklist. We previously had 2 quicklists, one for the PGD case and one for PTEs. Now that the PGD/PMD cases are handled through slab caches due to the multi-level configurability, only the PTE quicklist remains. As such, reduce NR_QUICK to its appropriate size and bump down the PTE quicklist index. Signed-off-by: Paul Mundt --- arch/sh/include/asm/pgalloc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/sh/include/asm') diff --git a/arch/sh/include/asm/pgalloc.h b/arch/sh/include/asm/pgalloc.h index e106474996b2..f8982f4e0405 100644 --- a/arch/sh/include/asm/pgalloc.h +++ b/arch/sh/include/asm/pgalloc.h @@ -4,7 +4,7 @@ #include #include -#define QUICK_PT 1 /* Other page table pages that are zero on free */ +#define QUICK_PT 0 /* Other page table pages that are zero on free */ extern pgd_t *pgd_alloc(struct mm_struct *); extern void pgd_free(struct mm_struct *mm, pgd_t *pgd); -- cgit v1.2.3 From 4352fc1b12fae4c753a063a2f162ddf9277af774 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 5 Jan 2010 19:06:45 +0900 Subject: sh: Abstracted SH-4A UBC support on hw-breakpoint core. This is the next big chunk of hw_breakpoint support. This decouples the SH-4A support from the core and moves it out in to its own stub, following many of the conventions established with the perf events layering. In addition to extending SH-4A support to encapsulate the remainder of the UBC channels, clock framework support for handling the UBC interface clock is added as well, allowing for dynamic clock gating. This also fixes up a regression introduced by the SIGTRAP handling that broke the ksym_tracer, to the extent that the current support works well with all of the ksym_tracer/ptrace/kgdb. The kprobes singlestep code will follow in turn. With this in place, the remaining UBC variants (SH-2A and SH-4) can now be trivially plugged in. Signed-off-by: Paul Mundt --- arch/sh/include/asm/hw_breakpoint.h | 22 ++++++++++++++++++---- arch/sh/include/asm/processor_32.h | 4 ++-- 2 files changed, 20 insertions(+), 6 deletions(-) (limited to 'arch/sh/include/asm') diff --git a/arch/sh/include/asm/hw_breakpoint.h b/arch/sh/include/asm/hw_breakpoint.h index 0f4a00f60058..7295d6290249 100644 --- a/arch/sh/include/asm/hw_breakpoint.h +++ b/arch/sh/include/asm/hw_breakpoint.h @@ -3,7 +3,6 @@ #include #include -#include #ifdef __KERNEL__ #define __ARCH_HW_BREAKPOINT_H @@ -11,7 +10,6 @@ struct arch_hw_breakpoint { char *name; /* Contains name of the symbol to set bkpt */ unsigned long address; - unsigned long asid; u16 len; u16 type; }; @@ -27,13 +25,28 @@ enum { SH_BREAKPOINT_LEN_8 = (1 << 14), }; -/* Total number of available UBC channels */ -#define HBP_NUM 1 /* XXX */ +struct sh_ubc { + const char *name; + unsigned int num_events; + unsigned int trap_nr; + void (*enable)(struct arch_hw_breakpoint *, int); + void (*disable)(struct arch_hw_breakpoint *, int); + void (*enable_all)(unsigned long); + void (*disable_all)(void); + unsigned long (*active_mask)(void); + unsigned long (*triggered_mask)(void); + void (*clear_triggered_mask)(unsigned long); + struct clk *clk; /* optional interface clock / MSTP bit */ +}; struct perf_event; struct task_struct; struct pmu; +/* Maximum number of UBC channels */ +#define HBP_NUM 2 + +/* arch/sh/kernel/hw_breakpoint.c */ extern int arch_check_va_in_userspace(unsigned long va, u16 hbp_len); extern int arch_validate_hwbkpt_settings(struct perf_event *bp, struct task_struct *tsk); @@ -46,6 +59,7 @@ void hw_breakpoint_pmu_read(struct perf_event *bp); void hw_breakpoint_pmu_unthrottle(struct perf_event *bp); extern void arch_fill_perf_breakpoint(struct perf_event *bp); +extern int register_sh_ubc(struct sh_ubc *); extern struct pmu perf_ops_bp; diff --git a/arch/sh/include/asm/processor_32.h b/arch/sh/include/asm/processor_32.h index d60b28271a05..259112cecbdf 100644 --- a/arch/sh/include/asm/processor_32.h +++ b/arch/sh/include/asm/processor_32.h @@ -14,7 +14,7 @@ #include #include #include -#include +#include /* * Default implementation of macro that returns current @@ -102,7 +102,7 @@ struct thread_struct { unsigned long pc; /* Save middle states of ptrace breakpoints */ - struct perf_event *ptrace_bps[NR_UBC_CHANNELS]; + struct perf_event *ptrace_bps[HBP_NUM]; /* floating point info */ union sh_fpu_union fpu; -- cgit v1.2.3 From 7025bec9125b0a02edcaf22c2dce753bf2c95480 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 5 Jan 2010 19:16:35 +0900 Subject: sh: Kill off dead UBC headers. Nothing is using these now, so kill them all off. Signed-off-by: Paul Mundt --- arch/sh/include/asm/ubc.h | 70 ----------------------------------------------- 1 file changed, 70 deletions(-) delete mode 100644 arch/sh/include/asm/ubc.h (limited to 'arch/sh/include/asm') diff --git a/arch/sh/include/asm/ubc.h b/arch/sh/include/asm/ubc.h deleted file mode 100644 index e3c2968b04d3..000000000000 --- a/arch/sh/include/asm/ubc.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - * include/asm-sh/ubc.h - * - * Copyright (C) 1999 Niibe Yutaka - * Copyright (C) 2002, 2003 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. - */ -#ifndef __ASM_SH_UBC_H -#define __ASM_SH_UBC_H - -#ifdef __KERNEL__ -#include - -/* User Break Controller */ -#if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709) -#define UBC_TYPE_SH7729 (current_cpu_data.type == CPU_SH7729) -#else -#define UBC_TYPE_SH7729 0 -#endif - -#define BAMR_ASID (1 << 2) -#define BAMR_NONE 0 -#define BAMR_10 0x1 -#define BAMR_12 0x2 -#define BAMR_ALL 0x3 -#define BAMR_16 0x8 -#define BAMR_20 0x9 - -#define BBR_INST (1 << 4) -#define BBR_DATA (2 << 4) -#define BBR_READ (1 << 2) -#define BBR_WRITE (2 << 2) -#define BBR_BYTE 0x1 -#define BBR_HALF 0x2 -#define BBR_LONG 0x3 -#define BBR_QUAD (1 << 6) /* SH7750 */ -#define BBR_CPU (1 << 6) /* SH7709A,SH7729 */ -#define BBR_DMA (2 << 6) /* SH7709A,SH7729 */ - -#define BRCR_CMFA (1 << 15) -#define BRCR_CMFB (1 << 14) - -#if defined CONFIG_CPU_SH2A -#define BRCR_CMFCA (1 << 15) -#define BRCR_CMFCB (1 << 14) -#define BRCR_CMFDA (1 << 13) -#define BRCR_CMFDB (1 << 12) -#define BRCR_PCBB (1 << 6) /* 1: after execution */ -#define BRCR_PCBA (1 << 5) /* 1: after execution */ -#define BRCR_PCTE 0 -#else -#define BRCR_PCTE (1 << 11) -#define BRCR_PCBA (1 << 10) /* 1: after execution */ -#define BRCR_DBEB (1 << 7) -#define BRCR_PCBB (1 << 6) -#define BRCR_SEQ (1 << 3) -#define BRCR_UBDE (1 << 0) -#endif - -/* - * All SH parts have 2 UBC channels. I defy any hardware designer to - * invalidate this assertion. - */ -#define NR_UBC_CHANNELS 2 - -#endif /* __KERNEL__ */ -#endif /* __ASM_SH_UBC_H */ -- cgit v1.2.3 From 9fae4fb3ce38cc657ff0aba570ae875aae2806d4 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 5 Jan 2010 19:30:18 +0900 Subject: sh: Reclaim TIF_DEBUG. This was used by the old hw-breakpoints API, but now there is nothing is using it anymore, so just kill it off. Signed-off-by: Paul Mundt --- arch/sh/include/asm/thread_info.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'arch/sh/include/asm') diff --git a/arch/sh/include/asm/thread_info.h b/arch/sh/include/asm/thread_info.h index e0856b205c4e..1f3d927e2265 100644 --- a/arch/sh/include/asm/thread_info.h +++ b/arch/sh/include/asm/thread_info.h @@ -118,7 +118,6 @@ extern void free_thread_info(struct thread_info *ti); #define TIF_SECCOMP 6 /* secure computing */ #define TIF_NOTIFY_RESUME 7 /* callback before returning to user */ #define TIF_SYSCALL_TRACEPOINT 8 /* for ftrace syscall instrumentation */ -#define TIF_DEBUG 9 /* uses UBC */ #define TIF_POLLING_NRFLAG 17 /* true if poll_idle() is polling TIF_NEED_RESCHED */ #define TIF_MEMDIE 18 #define TIF_FREEZE 19 /* Freezing for suspend */ @@ -131,7 +130,6 @@ extern void free_thread_info(struct thread_info *ti); #define _TIF_SECCOMP (1 << TIF_SECCOMP) #define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME) #define _TIF_SYSCALL_TRACEPOINT (1 << TIF_SYSCALL_TRACEPOINT) -#define _TIF_DEBUG (1 << TIF_DEBUG) #define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG) #define _TIF_FREEZE (1 << TIF_FREEZE) -- cgit v1.2.3 From 8c0b8139c87cfe8b95c6e763b4ca3190aa9b1ad0 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Fri, 8 Jan 2010 17:02:17 +0900 Subject: sh: consolidate atomic_cmpxchg()/atomic_add_unless() definitions. The LL/SC and IRQ versions were using generic stubs while the GRB version was just reimplementing what it already had for the standard cmpxchg() code. As we have optimized cmpxchg() implementations that are decoupled from the atomic code, simply falling back on the generic wrapper does the right thing. With this in place the GRB case is unaffected while the LL/SC case gets to use its optimized cmpxchg(). Signed-off-by: Paul Mundt --- arch/sh/include/asm/atomic-grb.h | 46 ------------------------ arch/sh/include/asm/atomic-llsc.h | 27 --------------- arch/sh/include/asm/atomic.h | 73 ++++++++++++++++----------------------- 3 files changed, 29 insertions(+), 117 deletions(-) (limited to 'arch/sh/include/asm') diff --git a/arch/sh/include/asm/atomic-grb.h b/arch/sh/include/asm/atomic-grb.h index 4c5b7dbfcedb..a273c88578fc 100644 --- a/arch/sh/include/asm/atomic-grb.h +++ b/arch/sh/include/asm/atomic-grb.h @@ -120,50 +120,4 @@ static inline void atomic_set_mask(unsigned int mask, atomic_t *v) : "memory" , "r0", "r1"); } -static inline int atomic_cmpxchg(atomic_t *v, int old, int new) -{ - int ret; - - __asm__ __volatile__ ( - " .align 2 \n\t" - " mova 1f, r0 \n\t" - " nop \n\t" - " mov r15, r1 \n\t" - " mov #-8, r15 \n\t" - " mov.l @%1, %0 \n\t" - " cmp/eq %2, %0 \n\t" - " bf 1f \n\t" - " mov.l %3, @%1 \n\t" - "1: mov r1, r15 \n\t" - : "=&r" (ret) - : "r" (v), "r" (old), "r" (new) - : "memory" , "r0", "r1" , "t"); - - return ret; -} - -static inline int atomic_add_unless(atomic_t *v, int a, int u) -{ - int ret; - unsigned long tmp; - - __asm__ __volatile__ ( - " .align 2 \n\t" - " mova 1f, r0 \n\t" - " nop \n\t" - " mov r15, r1 \n\t" - " mov #-12, r15 \n\t" - " mov.l @%2, %1 \n\t" - " mov %1, %0 \n\t" - " cmp/eq %4, %0 \n\t" - " bt/s 1f \n\t" - " add %3, %1 \n\t" - " mov.l %1, @%2 \n\t" - "1: mov r1, r15 \n\t" - : "=&r" (ret), "=&r" (tmp) - : "r" (v), "r" (a), "r" (u) - : "memory" , "r0", "r1" , "t"); - - return ret != u; -} #endif /* __ASM_SH_ATOMIC_GRB_H */ diff --git a/arch/sh/include/asm/atomic-llsc.h b/arch/sh/include/asm/atomic-llsc.h index b040e1e08610..4b00b78e3f4f 100644 --- a/arch/sh/include/asm/atomic-llsc.h +++ b/arch/sh/include/asm/atomic-llsc.h @@ -104,31 +104,4 @@ static inline void atomic_set_mask(unsigned int mask, atomic_t *v) : "t"); } -#define atomic_cmpxchg(v, o, n) (cmpxchg(&((v)->counter), (o), (n))) - -/** - * atomic_add_unless - add unless the number is a given value - * @v: pointer of type atomic_t - * @a: the amount to add to v... - * @u: ...unless v is equal to u. - * - * Atomically adds @a to @v, so long as it was not @u. - * Returns non-zero if @v was not @u, and zero otherwise. - */ -static inline int atomic_add_unless(atomic_t *v, int a, int u) -{ - int c, old; - c = atomic_read(v); - for (;;) { - if (unlikely(c == (u))) - break; - old = atomic_cmpxchg((v), c, c + (a)); - if (likely(old == c)) - break; - c = old; - } - - return c != (u); -} - #endif /* __ASM_SH_ATOMIC_LLSC_H */ diff --git a/arch/sh/include/asm/atomic.h b/arch/sh/include/asm/atomic.h index b16388d71954..275a448ae8c2 100644 --- a/arch/sh/include/asm/atomic.h +++ b/arch/sh/include/asm/atomic.h @@ -25,58 +25,43 @@ #endif #define atomic_add_negative(a, v) (atomic_add_return((a), (v)) < 0) +#define atomic_dec_return(v) atomic_sub_return(1, (v)) +#define atomic_inc_return(v) atomic_add_return(1, (v)) +#define atomic_inc_and_test(v) (atomic_inc_return(v) == 0) +#define atomic_sub_and_test(i,v) (atomic_sub_return((i), (v)) == 0) +#define atomic_dec_and_test(v) (atomic_sub_return(1, (v)) == 0) +#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0) -#define atomic_dec_return(v) atomic_sub_return(1,(v)) -#define atomic_inc_return(v) atomic_add_return(1,(v)) +#define atomic_inc(v) atomic_add(1, (v)) +#define atomic_dec(v) atomic_sub(1, (v)) -/* - * atomic_inc_and_test - increment and test +#define atomic_xchg(v, new) (xchg(&((v)->counter), new)) +#define atomic_cmpxchg(v, o, n) (cmpxchg(&((v)->counter), (o), (n))) + +/** + * atomic_add_unless - add unless the number is a given value * @v: pointer of type atomic_t + * @a: the amount to add to v... + * @u: ...unless v is equal to u. * - * Atomically increments @v by 1 - * and returns true if the result is zero, or false for all - * other cases. + * Atomically adds @a to @v, so long as it was not @u. + * Returns non-zero if @v was not @u, and zero otherwise. */ -#define atomic_inc_and_test(v) (atomic_inc_return(v) == 0) - -#define atomic_sub_and_test(i,v) (atomic_sub_return((i), (v)) == 0) -#define atomic_dec_and_test(v) (atomic_sub_return(1, (v)) == 0) - -#define atomic_inc(v) atomic_add(1,(v)) -#define atomic_dec(v) atomic_sub(1,(v)) - -#if !defined(CONFIG_GUSA_RB) && !defined(CONFIG_CPU_SH4A) -static inline int atomic_cmpxchg(atomic_t *v, int old, int new) -{ - int ret; - unsigned long flags; - - local_irq_save(flags); - ret = v->counter; - if (likely(ret == old)) - v->counter = new; - local_irq_restore(flags); - - return ret; -} - static inline int atomic_add_unless(atomic_t *v, int a, int u) { - int ret; - unsigned long flags; - - local_irq_save(flags); - ret = v->counter; - if (ret != u) - v->counter += a; - local_irq_restore(flags); - - return ret != u; + int c, old; + c = atomic_read(v); + for (;;) { + if (unlikely(c == (u))) + break; + old = atomic_cmpxchg((v), c, c + (a)); + if (likely(old == c)) + break; + c = old; + } + + return c != (u); } -#endif /* !CONFIG_GUSA_RB && !CONFIG_CPU_SH4A */ - -#define atomic_xchg(v, new) (xchg(&((v)->counter), new)) -#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0) #define smp_mb__before_atomic_dec() smp_mb() #define smp_mb__after_atomic_dec() smp_mb() -- cgit v1.2.3 From 191d0d24b632eb69767705acded5cbf7449ad457 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 12 Jan 2010 14:50:43 +0900 Subject: sh: Tidy up the sh bios VBR handling. This moves the VBR handling out of the main trap handling code and in to the sh-bios helper code. A couple of accessors are added in order to permit other kernel code to get at the VBR value for state save/restore paths. Signed-off-by: Paul Mundt --- arch/sh/include/asm/sh_bios.h | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'arch/sh/include/asm') diff --git a/arch/sh/include/asm/sh_bios.h b/arch/sh/include/asm/sh_bios.h index d9c96d7cf6c7..d8a67a17777c 100644 --- a/arch/sh/include/asm/sh_bios.h +++ b/arch/sh/include/asm/sh_bios.h @@ -1,13 +1,13 @@ #ifndef __ASM_SH_BIOS_H #define __ASM_SH_BIOS_H +#ifdef CONFIG_SH_STANDARD_BIOS + /* * Copyright (C) 2000 Greg Banks, Mitch Davis * C API to interface to the standard LinuxSH BIOS * usually from within the early stages of kernel boot. */ - - extern void sh_bios_console_write(const char *buf, unsigned int len); extern void sh_bios_char_out(char ch); extern void sh_bios_gdb_detach(void); @@ -15,4 +15,14 @@ extern void sh_bios_gdb_detach(void); extern void sh_bios_get_node_addr(unsigned char *node_addr); extern void sh_bios_shutdown(unsigned int how); +extern void sh_bios_vbr_init(void); +extern void sh_bios_vbr_reload(void); + +#else + +static inline void sh_bios_vbr_init(void) { } +static inline void sh_bios_vbr_reload(void) { } + +#endif /* CONFIG_SH_STANDARD_BIOS */ + #endif /* __ASM_SH_BIOS_H */ -- cgit v1.2.3 From b9303a79567d4a45b015dff7e71dd24923332d8d Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 12 Jan 2010 15:26:11 +0900 Subject: sh: Kill off more unused sh_bios callbacks. sh_bios_char_out() is not used by anything in-tree these days, so just get rid of it. Signed-off-by: Paul Mundt --- arch/sh/include/asm/sh_bios.h | 1 - 1 file changed, 1 deletion(-) (limited to 'arch/sh/include/asm') diff --git a/arch/sh/include/asm/sh_bios.h b/arch/sh/include/asm/sh_bios.h index d8a67a17777c..95714c28422b 100644 --- a/arch/sh/include/asm/sh_bios.h +++ b/arch/sh/include/asm/sh_bios.h @@ -9,7 +9,6 @@ * usually from within the early stages of kernel boot. */ extern void sh_bios_console_write(const char *buf, unsigned int len); -extern void sh_bios_char_out(char ch); extern void sh_bios_gdb_detach(void); extern void sh_bios_get_node_addr(unsigned char *node_addr); -- cgit v1.2.3 From 776258df925acd0563f471ee4b3f19bbffb3c04f Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 12 Jan 2010 15:31:20 +0900 Subject: sh: Consolidate the sh_bios earlyprintk code. Now that the sh-sci earlyprintk is taken care of by the sh-sci driver directly, there's no longer any reason for having a split-out early_printk framework. sh_bios is the only other thing that uses it, so we just migrate the leftovers in to there. As it's possible to have multiple early_param()'s for the same string, there's not much point in having this split out anymore anyways, particularly since the sh_bios dependencies are still special-cased within sh-sci itself. Signed-off-by: Paul Mundt --- arch/sh/include/asm/setup.h | 1 - 1 file changed, 1 deletion(-) (limited to 'arch/sh/include/asm') diff --git a/arch/sh/include/asm/setup.h b/arch/sh/include/asm/setup.h index ce3743599b27..4758325bb24a 100644 --- a/arch/sh/include/asm/setup.h +++ b/arch/sh/include/asm/setup.h @@ -18,7 +18,6 @@ /* ... */ #define COMMAND_LINE ((char *) (PARAM+0x100)) -int setup_early_printk(char *); void sh_mv_setup(void); #endif /* __KERNEL__ */ -- cgit v1.2.3 From a99eae5417a09e0be66bf574a9a79a2a7388c967 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 12 Jan 2010 16:12:25 +0900 Subject: sh: Split out the unaligned counters and user bits. This splits out the unaligned access counters and userspace bits in to their own generic interface, which will allow them to be wired up on sh64 too. Signed-off-by: Paul Mundt --- arch/sh/include/asm/alignment.h | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 arch/sh/include/asm/alignment.h (limited to 'arch/sh/include/asm') diff --git a/arch/sh/include/asm/alignment.h b/arch/sh/include/asm/alignment.h new file mode 100644 index 000000000000..b12efecf5294 --- /dev/null +++ b/arch/sh/include/asm/alignment.h @@ -0,0 +1,21 @@ +#ifndef __ASM_SH_ALIGNMENT_H +#define __ASM_SH_ALIGNMENT_H + +#include + +extern void inc_unaligned_byte_access(void); +extern void inc_unaligned_word_access(void); +extern void inc_unaligned_dword_access(void); +extern void inc_unaligned_multi_access(void); +extern void inc_unaligned_user_access(void); +extern void inc_unaligned_kernel_access(void); + +#define UM_WARN (1 << 0) +#define UM_FIXUP (1 << 1) +#define UM_SIGNAL (1 << 2) + +extern unsigned int unaligned_user_action(void); + +extern void unaligned_fixups_notify(struct task_struct *, insn_size_t, struct pt_regs *); + +#endif /* __ASM_SH_ALIGNMENT_H */ -- cgit v1.2.3 From 70e068eef97d05c97c3512f82352f39fdadfa8cb Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 12 Jan 2010 18:52:00 +0900 Subject: sh: Move start_thread() out of line. start_thread() will become a bit heavier with the xstate freeing to be added in, so move it out-of-line in preparation. Signed-off-by: Paul Mundt --- arch/sh/include/asm/processor_32.h | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) (limited to 'arch/sh/include/asm') diff --git a/arch/sh/include/asm/processor_32.h b/arch/sh/include/asm/processor_32.h index 1f3d6fab660c..50b8c9c3fa4c 100644 --- a/arch/sh/include/asm/processor_32.h +++ b/arch/sh/include/asm/processor_32.h @@ -119,19 +119,10 @@ extern int ubc_usercnt; .sp = sizeof(init_stack) + (long) &init_stack, \ } -/* - * Do necessary setup to start up a newly executed thread. - */ -#define start_thread(_regs, new_pc, new_sp) \ - set_fs(USER_DS); \ - _regs->pr = 0; \ - _regs->sr = SR_FD; /* User mode. */ \ - _regs->pc = new_pc; \ - _regs->regs[15] = new_sp - /* Forward declaration, a strange C thing */ struct task_struct; -struct mm_struct; + +extern void start_thread(struct pt_regs *regs, unsigned long new_pc, unsigned long new_sp); /* Free all resources held by a thread. */ extern void release_thread(struct task_struct *); -- cgit v1.2.3 From cbf6b1ba7ae12b3f7cb6b0d060b88d44649f9eda Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 12 Jan 2010 19:01:11 +0900 Subject: sh: Always provide thread_info allocators. Presently the thread_info allocators are special cased, depending on THREAD_SHIFT < PAGE_SHIFT. This provides a sensible definition for them regardless of configuration, in preparation for extended CPU state. Signed-off-by: Paul Mundt --- arch/sh/include/asm/thread_info.h | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'arch/sh/include/asm') diff --git a/arch/sh/include/asm/thread_info.h b/arch/sh/include/asm/thread_info.h index 1f3d927e2265..2c5b48edeab9 100644 --- a/arch/sh/include/asm/thread_info.h +++ b/arch/sh/include/asm/thread_info.h @@ -93,14 +93,12 @@ static inline struct thread_info *current_thread_info(void) #define THREAD_SIZE_ORDER (THREAD_SHIFT - PAGE_SHIFT) -#else /* THREAD_SHIFT < PAGE_SHIFT */ - -#define __HAVE_ARCH_THREAD_INFO_ALLOCATOR +#endif extern struct thread_info *alloc_thread_info(struct task_struct *tsk); extern void free_thread_info(struct thread_info *ti); -#endif /* THREAD_SHIFT < PAGE_SHIFT */ +#define __HAVE_ARCH_THREAD_INFO_ALLOCATOR #endif /* __ASSEMBLY__ */ -- cgit v1.2.3 From 0ea820cf9bf58f735ed40ec67947159c4f170012 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 13 Jan 2010 12:51:40 +0900 Subject: sh: Move over to dynamically allocated FPU context. This follows the x86 xstate changes and implements a task_xstate slab cache that is dynamically sized to match one of hard FP/soft FP/FPU-less. This also tidies up and consolidates some of the SH-2A/SH-4 FPU fragmentation. Now fpu state restorers are commonly defined, with the init_fpu()/fpu_init() mess reworked to follow the x86 convention. The fpu_init() register initialization has been replaced by xstate setup followed by writing out to hardware via the standard restore path. As init_fpu() now performs a slab allocation a secondary lighterweight restorer is also introduced for the context switch. In the future the DSP state will be rolled in here, too. More work remains for math emulation and the SH-5 FPU, which presently uses its own special (UP-only) interfaces. Signed-off-by: Paul Mundt --- arch/sh/include/asm/fpu.h | 35 ++++++++++++----------------------- arch/sh/include/asm/processor_32.h | 16 ++++++++++------ arch/sh/include/asm/thread_info.h | 4 ++++ 3 files changed, 26 insertions(+), 29 deletions(-) (limited to 'arch/sh/include/asm') diff --git a/arch/sh/include/asm/fpu.h b/arch/sh/include/asm/fpu.h index fb6bbb9b1cc8..06c4281aab65 100644 --- a/arch/sh/include/asm/fpu.h +++ b/arch/sh/include/asm/fpu.h @@ -2,8 +2,8 @@ #define __ASM_SH_FPU_H #ifndef __ASSEMBLY__ -#include -#include + +struct task_struct; #ifdef CONFIG_SH_FPU static inline void release_fpu(struct pt_regs *regs) @@ -16,22 +16,23 @@ static inline void grab_fpu(struct pt_regs *regs) regs->sr &= ~SR_FD; } -struct task_struct; - extern void save_fpu(struct task_struct *__tsk); -void fpu_state_restore(struct pt_regs *regs); +extern void restore_fpu(struct task_struct *__tsk); +extern void fpu_state_restore(struct pt_regs *regs); +extern void __fpu_state_restore(void); #else - -#define save_fpu(tsk) do { } while (0) -#define release_fpu(regs) do { } while (0) -#define grab_fpu(regs) do { } while (0) -#define fpu_state_restore(regs) do { } while (0) - +#define save_fpu(tsk) do { } while (0) +#define restore_fpu(tsk) do { } while (0) +#define release_fpu(regs) do { } while (0) +#define grab_fpu(regs) do { } while (0) +#define fpu_state_restore(regs) do { } while (0) +#define __fpu_state_restore(regs) do { } while (0) #endif struct user_regset; extern int do_fpu_inst(unsigned short, struct pt_regs *); +extern int init_fpu(struct task_struct *); extern int fpregs_get(struct task_struct *target, const struct user_regset *regset, @@ -65,18 +66,6 @@ static inline void clear_fpu(struct task_struct *tsk, struct pt_regs *regs) preempt_enable(); } -static inline int init_fpu(struct task_struct *tsk) -{ - if (tsk_used_math(tsk)) { - if ((boot_cpu_data.flags & CPU_HAS_FPU) && tsk == current) - unlazy_fpu(tsk, task_pt_regs(tsk)); - return 0; - } - - set_stopped_child_used_math(tsk); - return 0; -} - #endif /* __ASSEMBLY__ */ #endif /* __ASM_SH_FPU_H */ diff --git a/arch/sh/include/asm/processor_32.h b/arch/sh/include/asm/processor_32.h index 50b8c9c3fa4c..a359898206e8 100644 --- a/arch/sh/include/asm/processor_32.h +++ b/arch/sh/include/asm/processor_32.h @@ -90,11 +90,15 @@ struct sh_fpu_soft_struct { unsigned long entry_pc; }; -union sh_fpu_union { - struct sh_fpu_hard_struct hard; - struct sh_fpu_soft_struct soft; +union thread_xstate { + struct sh_fpu_hard_struct hardfpu; + struct sh_fpu_soft_struct softfpu; }; +extern unsigned int xstate_size; +extern void free_thread_xstate(struct task_struct *); +extern struct kmem_cache *task_xstate_cachep; + struct thread_struct { /* Saved registers when thread is descheduled */ unsigned long sp; @@ -103,13 +107,13 @@ struct thread_struct { /* Hardware debugging registers */ unsigned long ubc_pc; - /* floating point info */ - union sh_fpu_union fpu; - #ifdef CONFIG_SH_DSP /* Dsp status information */ struct sh_dsp_struct dsp_status; #endif + + /* Extended processor state */ + union thread_xstate *xstate; }; /* Count of active tasks with UBC settings */ diff --git a/arch/sh/include/asm/thread_info.h b/arch/sh/include/asm/thread_info.h index 2c5b48edeab9..55a36fef6875 100644 --- a/arch/sh/include/asm/thread_info.h +++ b/arch/sh/include/asm/thread_info.h @@ -97,6 +97,10 @@ static inline struct thread_info *current_thread_info(void) extern struct thread_info *alloc_thread_info(struct task_struct *tsk); extern void free_thread_info(struct thread_info *ti); +extern void arch_task_cache_init(void); +#define arch_task_cache_init arch_task_cache_init +extern int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src); +extern void init_thread_xstate(void); #define __HAVE_ARCH_THREAD_INFO_ALLOCATOR -- cgit v1.2.3 From 6430a5987f8bb9a7c5187b343956aa8ef404d571 Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Wed, 13 Jan 2010 12:59:24 +0900 Subject: sh: Don't perform an icbi on a P2 address The legacy P2 area may not always be mapped (for example when using PMB). So perform an icbi on an address that we know will always be mapped. Signed-off-by: Matt Fleming Signed-off-by: Paul Mundt --- arch/sh/include/asm/system.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/sh/include/asm') diff --git a/arch/sh/include/asm/system.h b/arch/sh/include/asm/system.h index c15415b4b169..b74d2532cc27 100644 --- a/arch/sh/include/asm/system.h +++ b/arch/sh/include/asm/system.h @@ -32,7 +32,7 @@ #define mb() __asm__ __volatile__ ("synco": : :"memory") #define rmb() mb() #define wmb() __asm__ __volatile__ ("synco": : :"memory") -#define ctrl_barrier() __icbi(0xa8000000) +#define ctrl_barrier() __icbi(PAGE_OFFSET) #define read_barrier_depends() do { } while(0) #else #define mb() __asm__ __volatile__ ("": : :"memory") -- cgit v1.2.3 From a0ab36689a36e583b6e736f1c99ac8c9aebdad59 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 13 Jan 2010 18:31:48 +0900 Subject: sh: fixed PMB mode refactoring. This introduces some much overdue chainsawing of the fixed PMB support. fixed PMB was introduced initially to work around the fact that dynamic PMB mode was relatively broken, though they were never intended to converge. The main areas where there are differences are whether the system is booted in 29-bit mode or 32-bit mode, and whether legacy mappings are to be preserved. Any system booting in true 32-bit mode will not care about legacy mappings, so these are roughly decoupled. Regardless of the entry point, PMB and 32BIT are directly related as far as the kernel is concerned, so we also switch back to having one select the other. With legacy mappings iterated through and applied in the initialization path it's now possible to finally merge the two implementations and permit dynamic remapping overtop of remaining entries regardless of whether boot mappings are crafted by hand or inherited from the boot loader. Signed-off-by: Paul Mundt --- arch/sh/include/asm/addrspace.h | 4 ++-- arch/sh/include/asm/io.h | 27 ++++++++++++++++++--------- arch/sh/include/asm/mmu.h | 18 ++++++++++++++++++ arch/sh/include/asm/page.h | 2 +- 4 files changed, 39 insertions(+), 12 deletions(-) (limited to 'arch/sh/include/asm') diff --git a/arch/sh/include/asm/addrspace.h b/arch/sh/include/asm/addrspace.h index 99d6b3ecbe22..bcd7d4d78f6b 100644 --- a/arch/sh/include/asm/addrspace.h +++ b/arch/sh/include/asm/addrspace.h @@ -28,7 +28,7 @@ /* Returns the privileged segment base of a given address */ #define PXSEG(a) (((unsigned long)(a)) & 0xe0000000) -#if defined(CONFIG_29BIT) || defined(CONFIG_PMB_FIXED) +#ifdef CONFIG_29BIT /* * Map an address to a certain privileged segment */ @@ -40,7 +40,7 @@ ((__typeof__(a))(((unsigned long)(a) & 0x1fffffff) | P3SEG)) #define P4SEGADDR(a) \ ((__typeof__(a))(((unsigned long)(a) & 0x1fffffff) | P4SEG)) -#endif /* 29BIT || PMB_FIXED */ +#endif /* 29BIT */ #endif /* P1SEG */ /* Check if an address can be reached in 29 bits */ diff --git a/arch/sh/include/asm/io.h b/arch/sh/include/asm/io.h index 026dd659a640..f4314d8b05b8 100644 --- a/arch/sh/include/asm/io.h +++ b/arch/sh/include/asm/io.h @@ -244,18 +244,11 @@ __ioremap(unsigned long offset, unsigned long size, unsigned long flags) } static inline void __iomem * -__ioremap_mode(unsigned long offset, unsigned long size, unsigned long flags) +__ioremap_29bit(unsigned long offset, unsigned long size, unsigned long flags) { -#if defined(CONFIG_SUPERH32) && !defined(CONFIG_PMB_FIXED) && !defined(CONFIG_PMB) +#ifdef CONFIG_29BIT unsigned long last_addr = offset + size - 1; -#endif - void __iomem *ret; - ret = __ioremap_trapped(offset, size); - if (ret) - return ret; - -#if defined(CONFIG_SUPERH32) && !defined(CONFIG_PMB_FIXED) && !defined(CONFIG_PMB) /* * For P1 and P2 space this is trivial, as everything is already * mapped. Uncached access for P1 addresses are done through P2. @@ -274,6 +267,22 @@ __ioremap_mode(unsigned long offset, unsigned long size, unsigned long flags) return (void __iomem *)P4SEGADDR(offset); #endif + return NULL; +} + +static inline void __iomem * +__ioremap_mode(unsigned long offset, unsigned long size, unsigned long flags) +{ + void __iomem *ret; + + ret = __ioremap_trapped(offset, size); + if (ret) + return ret; + + ret = __ioremap_29bit(offset, size, flags); + if (ret) + return ret; + return __ioremap(offset, size, flags); } #else diff --git a/arch/sh/include/asm/mmu.h b/arch/sh/include/asm/mmu.h index c7426ad9926e..4b0882bf5183 100644 --- a/arch/sh/include/asm/mmu.h +++ b/arch/sh/include/asm/mmu.h @@ -65,11 +65,29 @@ struct pmb_entry { struct pmb_entry *link; }; +#ifdef CONFIG_PMB /* arch/sh/mm/pmb.c */ long pmb_remap(unsigned long virt, unsigned long phys, unsigned long size, unsigned long flags); void pmb_unmap(unsigned long addr); int pmb_init(void); +#else +static inline long pmb_remap(unsigned long virt, unsigned long phys, + unsigned long size, unsigned long flags) +{ + return -EINVAL +} + +static inline void pmb_unmap(unsigned long addr) +{ +} + +static inline int pmb_init(void) +{ + return -ENODEV; +} +#endif /* CONFIG_PMB */ + #endif /* __ASSEMBLY__ */ #endif /* __MMU_H */ diff --git a/arch/sh/include/asm/page.h b/arch/sh/include/asm/page.h index 81bffc0d6860..a86c0f1d05d4 100644 --- a/arch/sh/include/asm/page.h +++ b/arch/sh/include/asm/page.h @@ -127,7 +127,7 @@ typedef struct page *pgtable_t; * is not visible (it is part of the PMB mapping) and so needs to be * added or subtracted as required. */ -#if defined(CONFIG_PMB_FIXED) +#if defined(CONFIG_PMB_LEGACY) /* phys = virt - PAGE_OFFSET - (__MEMORY_START & 0xe0000000) */ #define PMB_OFFSET (PAGE_OFFSET - PXSEG(__MEMORY_START)) #define __pa(x) ((unsigned long)(x) - PMB_OFFSET) -- cgit v1.2.3 From 206582c3161f165f5bf49ececa962c5f95fdf0a3 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 13 Jan 2010 18:45:12 +0900 Subject: sh: Make all PxSEGADDR() calls fatal for non-legacy configs. This stubs out all of the PxSEGADDR() wrappers for non-legacy code. 29-bit will continue to work with these, while 32-bit code will now blow up on compile rather than at runtime. The vast majority of the in-tree offenders are gone, with the only remaining culprits being unable to support 32-bit mode. Hopefully this will prevent anyone from ever using these again. Signed-off-by: Paul Mundt --- arch/sh/include/asm/addrspace.h | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'arch/sh/include/asm') diff --git a/arch/sh/include/asm/addrspace.h b/arch/sh/include/asm/addrspace.h index bcd7d4d78f6b..268efd62ed21 100644 --- a/arch/sh/include/asm/addrspace.h +++ b/arch/sh/include/asm/addrspace.h @@ -40,7 +40,15 @@ ((__typeof__(a))(((unsigned long)(a) & 0x1fffffff) | P3SEG)) #define P4SEGADDR(a) \ ((__typeof__(a))(((unsigned long)(a) & 0x1fffffff) | P4SEG)) -#endif /* 29BIT */ +#else +/* + * These will never work in 32-bit, don't even bother. + */ +#define P1SEGADDR(a) __futile_remapping_attempt +#define P2SEGADDR(a) __futile_remapping_attempt +#define P3SEGADDR(a) __futile_remapping_attempt +#define P4SEGADDR(a) __futile_remapping_attempt +#endif #endif /* P1SEG */ /* Check if an address can be reached in 29 bits */ -- cgit v1.2.3 From 782bb5a532f883540bf403afb19f735a4eefd95b Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 13 Jan 2010 19:11:14 +0900 Subject: sh: default to extended TLB support. All SH-X2 and SH-X3 parts support an extended TLB mode, which has been left as experimental since support was originally merged. Now that it's had some time to stabilize and get some exposure to various platforms, we can drop it as an option and default enable it across the board. This is also good future proofing for newer parts that will drop support for the legacy TLB mode completely. This will also force 3-level page tables for all newer parts, which is necessary both for the varying page sizes and larger memories. Signed-off-by: Paul Mundt --- arch/sh/include/asm/pgalloc.h | 2 +- arch/sh/include/asm/pgtable.h | 2 +- arch/sh/include/asm/pgtable_nopmd.h | 11 ++++++----- arch/sh/include/asm/pgtable_pmd.h | 5 +++-- 4 files changed, 11 insertions(+), 9 deletions(-) (limited to 'arch/sh/include/asm') diff --git a/arch/sh/include/asm/pgalloc.h b/arch/sh/include/asm/pgalloc.h index f8982f4e0405..8c00785c60d5 100644 --- a/arch/sh/include/asm/pgalloc.h +++ b/arch/sh/include/asm/pgalloc.h @@ -9,7 +9,7 @@ extern pgd_t *pgd_alloc(struct mm_struct *); extern void pgd_free(struct mm_struct *mm, pgd_t *pgd); -#ifdef CONFIG_PGTABLE_LEVELS_3 +#if PAGETABLE_LEVELS > 2 extern void pud_populate(struct mm_struct *mm, pud_t *pudp, pmd_t *pmd); extern pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address); extern void pmd_free(struct mm_struct *mm, pmd_t *pmd); diff --git a/arch/sh/include/asm/pgtable.h b/arch/sh/include/asm/pgtable.h index 78598ec33d0a..856ece07d31b 100644 --- a/arch/sh/include/asm/pgtable.h +++ b/arch/sh/include/asm/pgtable.h @@ -12,7 +12,7 @@ #ifndef __ASM_SH_PGTABLE_H #define __ASM_SH_PGTABLE_H -#ifdef CONFIG_PGTABLE_LEVELS_3 +#ifdef CONFIG_X2TLB #include #else #include diff --git a/arch/sh/include/asm/pgtable_nopmd.h b/arch/sh/include/asm/pgtable_nopmd.h index f0b525b3cb4a..b8355e4057cf 100644 --- a/arch/sh/include/asm/pgtable_nopmd.h +++ b/arch/sh/include/asm/pgtable_nopmd.h @@ -6,17 +6,18 @@ /* * traditional two-level paging structure */ +#define PAGETABLE_LEVELS 2 /* PTE bits */ -#define PTE_MAGNITUDE 2 /* 32-bit PTEs */ +#define PTE_MAGNITUDE 2 /* 32-bit PTEs */ -#define PTE_SHIFT PAGE_SHIFT -#define PTE_BITS (PTE_SHIFT - PTE_MAGNITUDE) +#define PTE_SHIFT PAGE_SHIFT +#define PTE_BITS (PTE_SHIFT - PTE_MAGNITUDE) /* PGD bits */ -#define PGDIR_SHIFT (PTE_SHIFT + PTE_BITS) +#define PGDIR_SHIFT (PTE_SHIFT + PTE_BITS) -#define PTRS_PER_PGD (PAGE_SIZE / (1 << PTE_MAGNITUDE)) +#define PTRS_PER_PGD (PAGE_SIZE / (1 << PTE_MAGNITUDE)) #define USER_PTRS_PER_PGD (TASK_SIZE/PGDIR_SIZE) #endif /* __ASM_SH_PGTABLE_NOPMD_H */ diff --git a/arch/sh/include/asm/pgtable_pmd.h b/arch/sh/include/asm/pgtable_pmd.h index 42a180e534a8..587b05e1d04f 100644 --- a/arch/sh/include/asm/pgtable_pmd.h +++ b/arch/sh/include/asm/pgtable_pmd.h @@ -7,11 +7,12 @@ * Some cores need a 3-level page table layout, for example when using * 64-bit PTEs and 4K pages. */ +#define PAGETABLE_LEVELS 3 -#define PTE_MAGNITUDE 3 /* 64-bit PTEs on extended mode SH-X2 TLB */ +#define PTE_MAGNITUDE 3 /* 64-bit PTEs on SH-X2 TLB */ /* PGD bits */ -#define PGDIR_SHIFT 30 +#define PGDIR_SHIFT 30 #define PTRS_PER_PGD 4 #define USER_PTRS_PER_PGD 2 -- cgit v1.2.3 From e44d6c4010a4c84369013932eea4721d16cbc08d Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 13 Jan 2010 19:18:39 +0900 Subject: sh: Rename split-level pgtable headers. These were originally named _nopmd and _pmd to follow their asm-generic counterparts, but we rename them to -2level and -3level for general consistency. Signed-off-by: Paul Mundt --- arch/sh/include/asm/pgtable-2level.h | 23 +++++++++++++++ arch/sh/include/asm/pgtable-3level.h | 56 ++++++++++++++++++++++++++++++++++++ arch/sh/include/asm/pgtable.h | 4 +-- arch/sh/include/asm/pgtable_nopmd.h | 23 --------------- arch/sh/include/asm/pgtable_pmd.h | 56 ------------------------------------ 5 files changed, 81 insertions(+), 81 deletions(-) create mode 100644 arch/sh/include/asm/pgtable-2level.h create mode 100644 arch/sh/include/asm/pgtable-3level.h delete mode 100644 arch/sh/include/asm/pgtable_nopmd.h delete mode 100644 arch/sh/include/asm/pgtable_pmd.h (limited to 'arch/sh/include/asm') diff --git a/arch/sh/include/asm/pgtable-2level.h b/arch/sh/include/asm/pgtable-2level.h new file mode 100644 index 000000000000..19bd89db17e7 --- /dev/null +++ b/arch/sh/include/asm/pgtable-2level.h @@ -0,0 +1,23 @@ +#ifndef __ASM_SH_PGTABLE_2LEVEL_H +#define __ASM_SH_PGTABLE_2LEVEL_H + +#include + +/* + * traditional two-level paging structure + */ +#define PAGETABLE_LEVELS 2 + +/* PTE bits */ +#define PTE_MAGNITUDE 2 /* 32-bit PTEs */ + +#define PTE_SHIFT PAGE_SHIFT +#define PTE_BITS (PTE_SHIFT - PTE_MAGNITUDE) + +/* PGD bits */ +#define PGDIR_SHIFT (PTE_SHIFT + PTE_BITS) + +#define PTRS_PER_PGD (PAGE_SIZE / (1 << PTE_MAGNITUDE)) +#define USER_PTRS_PER_PGD (TASK_SIZE/PGDIR_SIZE) + +#endif /* __ASM_SH_PGTABLE_2LEVEL_H */ diff --git a/arch/sh/include/asm/pgtable-3level.h b/arch/sh/include/asm/pgtable-3level.h new file mode 100644 index 000000000000..249a985d9648 --- /dev/null +++ b/arch/sh/include/asm/pgtable-3level.h @@ -0,0 +1,56 @@ +#ifndef __ASM_SH_PGTABLE_3LEVEL_H +#define __ASM_SH_PGTABLE_3LEVEL_H + +#include + +/* + * Some cores need a 3-level page table layout, for example when using + * 64-bit PTEs and 4K pages. + */ +#define PAGETABLE_LEVELS 3 + +#define PTE_MAGNITUDE 3 /* 64-bit PTEs on SH-X2 TLB */ + +/* PGD bits */ +#define PGDIR_SHIFT 30 + +#define PTRS_PER_PGD 4 +#define USER_PTRS_PER_PGD 2 + +/* PMD bits */ +#define PMD_SHIFT (PAGE_SHIFT + (PAGE_SHIFT - PTE_MAGNITUDE)) +#define PMD_SIZE (1UL << PMD_SHIFT) +#define PMD_MASK (~(PMD_SIZE-1)) + +#define PTRS_PER_PMD ((1 << PGDIR_SHIFT) / PMD_SIZE) + +#define pmd_ERROR(e) \ + printk("%s:%d: bad pmd %016llx.\n", __FILE__, __LINE__, pmd_val(e)) + +typedef struct { unsigned long long pmd; } pmd_t; +#define pmd_val(x) ((x).pmd) +#define __pmd(x) ((pmd_t) { (x) } ) + +static inline unsigned long pud_page_vaddr(pud_t pud) +{ + return pud_val(pud); +} + +#define pmd_index(address) (((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1)) +static inline pmd_t *pmd_offset(pud_t *pud, unsigned long address) +{ + return (pmd_t *)pud_page_vaddr(*pud) + pmd_index(address); +} + +#define pud_none(x) (!pud_val(x)) +#define pud_present(x) (pud_val(x)) +#define pud_clear(xp) do { set_pud(xp, __pud(0)); } while (0) +#define pud_bad(x) (pud_val(x) & ~PAGE_MASK) + +/* + * (puds are folded into pgds so this doesn't get actually called, + * but the define is needed for a generic inline function.) + */ +#define set_pud(pudptr, pudval) do { *(pudptr) = (pudval); } while(0) + +#endif /* __ASM_SH_PGTABLE_3LEVEL_H */ diff --git a/arch/sh/include/asm/pgtable.h b/arch/sh/include/asm/pgtable.h index 856ece07d31b..aab76528abb9 100644 --- a/arch/sh/include/asm/pgtable.h +++ b/arch/sh/include/asm/pgtable.h @@ -13,9 +13,9 @@ #define __ASM_SH_PGTABLE_H #ifdef CONFIG_X2TLB -#include +#include #else -#include +#include #endif #include diff --git a/arch/sh/include/asm/pgtable_nopmd.h b/arch/sh/include/asm/pgtable_nopmd.h deleted file mode 100644 index b8355e4057cf..000000000000 --- a/arch/sh/include/asm/pgtable_nopmd.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef __ASM_SH_PGTABLE_NOPMD_H -#define __ASM_SH_PGTABLE_NOPMD_H - -#include - -/* - * traditional two-level paging structure - */ -#define PAGETABLE_LEVELS 2 - -/* PTE bits */ -#define PTE_MAGNITUDE 2 /* 32-bit PTEs */ - -#define PTE_SHIFT PAGE_SHIFT -#define PTE_BITS (PTE_SHIFT - PTE_MAGNITUDE) - -/* PGD bits */ -#define PGDIR_SHIFT (PTE_SHIFT + PTE_BITS) - -#define PTRS_PER_PGD (PAGE_SIZE / (1 << PTE_MAGNITUDE)) -#define USER_PTRS_PER_PGD (TASK_SIZE/PGDIR_SIZE) - -#endif /* __ASM_SH_PGTABLE_NOPMD_H */ diff --git a/arch/sh/include/asm/pgtable_pmd.h b/arch/sh/include/asm/pgtable_pmd.h deleted file mode 100644 index 587b05e1d04f..000000000000 --- a/arch/sh/include/asm/pgtable_pmd.h +++ /dev/null @@ -1,56 +0,0 @@ -#ifndef __ASM_SH_PGTABLE_PMD_H -#define __ASM_SH_PGTABLE_PMD_H - -#include - -/* - * Some cores need a 3-level page table layout, for example when using - * 64-bit PTEs and 4K pages. - */ -#define PAGETABLE_LEVELS 3 - -#define PTE_MAGNITUDE 3 /* 64-bit PTEs on SH-X2 TLB */ - -/* PGD bits */ -#define PGDIR_SHIFT 30 - -#define PTRS_PER_PGD 4 -#define USER_PTRS_PER_PGD 2 - -/* PMD bits */ -#define PMD_SHIFT (PAGE_SHIFT + (PAGE_SHIFT - PTE_MAGNITUDE)) -#define PMD_SIZE (1UL << PMD_SHIFT) -#define PMD_MASK (~(PMD_SIZE-1)) - -#define PTRS_PER_PMD ((1 << PGDIR_SHIFT) / PMD_SIZE) - -#define pmd_ERROR(e) \ - printk("%s:%d: bad pmd %016llx.\n", __FILE__, __LINE__, pmd_val(e)) - -typedef struct { unsigned long long pmd; } pmd_t; -#define pmd_val(x) ((x).pmd) -#define __pmd(x) ((pmd_t) { (x) } ) - -static inline unsigned long pud_page_vaddr(pud_t pud) -{ - return pud_val(pud); -} - -#define pmd_index(address) (((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1)) -static inline pmd_t *pmd_offset(pud_t *pud, unsigned long address) -{ - return (pmd_t *)pud_page_vaddr(*pud) + pmd_index(address); -} - -#define pud_none(x) (!pud_val(x)) -#define pud_present(x) (pud_val(x)) -#define pud_clear(xp) do { set_pud(xp, __pud(0)); } while (0) -#define pud_bad(x) (pud_val(x) & ~PAGE_MASK) - -/* - * (puds are folded into pgds so this doesn't get actually called, - * but the define is needed for a generic inline function.) - */ -#define set_pud(pudptr, pudval) do { *(pudptr) = (pudval); } while(0) - -#endif /* __ASM_SH_PGTABLE_PMD_H */ -- cgit v1.2.3 From 46c4e5daea3d5df06e27bf5a49a0c42274db6725 Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Fri, 15 Jan 2010 08:00:45 +0900 Subject: sh: Fix CONFIG_PMB=n build. The last commit introduced the following breakage arch/sh/include/asm/mmu.h: In function 'pmb_remap': arch/sh/include/asm/mmu.h:79: error: expected ';' before '}' token and... arch/sh/include/asm/mmu.h:78: error: 'EINVAL' undeclared (first use in this function) arch/sh/include/asm/mmu.h:78: error: (Each undeclared identifier is reported only once arch/sh/include/asm/mmu.h:78: error: for each function it appears in.) arch/sh/include/asm/mmu.h: In function 'pmb_init': arch/sh/include/asm/mmu.h:87: error: 'ENODEV' undeclared (first use in this function) Signed-off-by: Matt Fleming Signed-off-by: Paul Mundt --- arch/sh/include/asm/mmu.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'arch/sh/include/asm') diff --git a/arch/sh/include/asm/mmu.h b/arch/sh/include/asm/mmu.h index 4b0882bf5183..e5e8f48830ef 100644 --- a/arch/sh/include/asm/mmu.h +++ b/arch/sh/include/asm/mmu.h @@ -30,6 +30,7 @@ #define PMB_NO_ENTRY (-1) #ifndef __ASSEMBLY__ +#include /* Default "unsigned long" context */ typedef unsigned long mm_context_id_t[NR_CPUS]; @@ -75,7 +76,7 @@ int pmb_init(void); static inline long pmb_remap(unsigned long virt, unsigned long phys, unsigned long size, unsigned long flags) { - return -EINVAL + return -EINVAL; } static inline void pmb_unmap(unsigned long addr) -- cgit v1.2.3 From 8eda55142080f0373b1f0268fe6d6807f193e713 Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Tue, 17 Nov 2009 21:05:31 +0000 Subject: sh: New extended page flag to wire/unwire TLB entries Provide a new extended page flag, _PAGE_WIRED and an SH4 implementation for wiring TLB entries and use it in the fixmap code path so that we can wire the fixmap TLB entry. Signed-off-by: Matt Fleming --- arch/sh/include/asm/pgtable_32.h | 4 ++++ arch/sh/include/asm/tlb.h | 16 ++++++++++++++++ 2 files changed, 20 insertions(+) (limited to 'arch/sh/include/asm') diff --git a/arch/sh/include/asm/pgtable_32.h b/arch/sh/include/asm/pgtable_32.h index 5003ee86f67b..c573d45f1286 100644 --- a/arch/sh/include/asm/pgtable_32.h +++ b/arch/sh/include/asm/pgtable_32.h @@ -71,6 +71,8 @@ #define _PAGE_EXT_KERN_WRITE 0x1000 /* EPR4-bit: Kernel space writable */ #define _PAGE_EXT_KERN_READ 0x2000 /* EPR5-bit: Kernel space readable */ +#define _PAGE_EXT_WIRED 0x4000 /* software: Wire TLB entry */ + /* Wrapper for extended mode pgprot twiddling */ #define _PAGE_EXT(x) ((unsigned long long)(x) << 32) @@ -164,6 +166,8 @@ static inline unsigned long copy_ptea_attributes(unsigned long x) (PTE_MASK | _PAGE_ACCESSED | _PAGE_CACHABLE | \ _PAGE_DIRTY | _PAGE_SPECIAL) +#define _PAGE_WIRED (_PAGE_EXT(_PAGE_EXT_WIRED)) + #ifndef __ASSEMBLY__ #if defined(CONFIG_X2TLB) /* SH-X2 TLB */ diff --git a/arch/sh/include/asm/tlb.h b/arch/sh/include/asm/tlb.h index da8fe7ab8728..3ed2f7a05416 100644 --- a/arch/sh/include/asm/tlb.h +++ b/arch/sh/include/asm/tlb.h @@ -97,6 +97,22 @@ tlb_end_vma(struct mmu_gather *tlb, struct vm_area_struct *vma) #define tlb_migrate_finish(mm) do { } while (0) +#ifdef CONFIG_CPU_SH4 +extern void tlb_wire_entry(struct vm_area_struct *, unsigned long, pte_t); +extern void tlb_unwire_entry(void); +#else +static inline void tlb_wire_entry(struct vm_area_struct *vma , + unsigned long addr, pte_t pte) +{ + BUG(); +} + +static inline void tlb_unwire_entry(void) +{ + BUG(); +} +#endif /* CONFIG_CPU_SH4 */ + #else /* CONFIG_MMU */ #define tlb_start_vma(tlb, vma) do { } while (0) -- cgit v1.2.3 From 24ef7fc4dcc57afa0c33166c25bfe7676ffd4296 Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Thu, 19 Nov 2009 21:11:05 +0000 Subject: sh: Acquire some more page flags for SH-5. We need some more page flags to hook up _PAGE_WIRED (and eventually other things). So use the unused PTE bits above the PPN field as no implementations use these for anything currently. Now that we have _PAGE_WIRED let's provide the SH-5 functions for wiring up TLB entries. Signed-off-by: Matt Fleming --- arch/sh/include/asm/page.h | 2 +- arch/sh/include/asm/pgtable_64.h | 15 ++++++++++++++- arch/sh/include/asm/tlb.h | 41 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 56 insertions(+), 2 deletions(-) (limited to 'arch/sh/include/asm') diff --git a/arch/sh/include/asm/page.h b/arch/sh/include/asm/page.h index a86c0f1d05d4..61e58105adc3 100644 --- a/arch/sh/include/asm/page.h +++ b/arch/sh/include/asm/page.h @@ -88,7 +88,7 @@ typedef struct { unsigned long pgd; } pgd_t; #define __pte(x) ((pte_t) { (x) } ) #else typedef struct { unsigned long long pte_low; } pte_t; -typedef struct { unsigned long pgprot; } pgprot_t; +typedef struct { unsigned long long pgprot; } pgprot_t; typedef struct { unsigned long pgd; } pgd_t; #define pte_val(x) ((x).pte_low) #define __pte(x) ((pte_t) { (x) } ) diff --git a/arch/sh/include/asm/pgtable_64.h b/arch/sh/include/asm/pgtable_64.h index dd381588c695..0ee46776dad6 100644 --- a/arch/sh/include/asm/pgtable_64.h +++ b/arch/sh/include/asm/pgtable_64.h @@ -123,8 +123,21 @@ static __inline__ void set_pte(pte_t *pteptr, pte_t pteval) #define _PAGE_DIRTY 0x400 /* software: page accessed in write */ #define _PAGE_ACCESSED 0x800 /* software: page referenced */ +/* Wrapper for extended mode pgprot twiddling */ +#define _PAGE_EXT(x) ((unsigned long long)(x) << 32) + +/* + * We can use the sign-extended bits in the PTEL to get 32 bits of + * software flags. This works for now because no implementations uses + * anything above the PPN field. + */ +#define _PAGE_WIRED _PAGE_EXT(0x001) /* software: wire the tlb entry */ + +#define _PAGE_CLEAR_FLAGS (_PAGE_PRESENT | _PAGE_FILE | _PAGE_SHARED | \ + _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_WIRED) + /* Mask which drops software flags */ -#define _PAGE_FLAGS_HARDWARE_MASK 0xfffffffffffff3dbLL +#define _PAGE_FLAGS_HARDWARE_MASK (NEFF_MASK & ~(_PAGE_CLEAR_FLAGS)) /* * HugeTLB support diff --git a/arch/sh/include/asm/tlb.h b/arch/sh/include/asm/tlb.h index 3ed2f7a05416..dfc8fcd8ee50 100644 --- a/arch/sh/include/asm/tlb.h +++ b/arch/sh/include/asm/tlb.h @@ -11,6 +11,7 @@ #ifdef CONFIG_MMU #include #include +#include /* * TLB handling. This allows us to remove pages from the page @@ -100,6 +101,46 @@ tlb_end_vma(struct mmu_gather *tlb, struct vm_area_struct *vma) #ifdef CONFIG_CPU_SH4 extern void tlb_wire_entry(struct vm_area_struct *, unsigned long, pte_t); extern void tlb_unwire_entry(void); +#elif defined(CONFIG_SUPERH64) +static int dtlb_entry; +static unsigned long long dtlb_entries[64]; + +static inline void tlb_wire_entry(struct vm_area_struct *vma, + unsigned long addr, pte_t pte) +{ + unsigned long long entry; + unsigned long paddr, flags; + + BUG_ON(dtlb_entry == 64); + + local_irq_save(flags); + + entry = sh64_get_wired_dtlb_entry(); + dtlb_entries[dtlb_entry++] = entry; + + paddr = pte_val(pte) & _PAGE_FLAGS_HARDWARE_MASK; + paddr &= ~PAGE_MASK; + + sh64_setup_tlb_slot(entry, addr, get_asid(), paddr); + + local_irq_restore(flags); +} + +static inline void tlb_unwire_entry(void) +{ + unsigned long long entry; + unsigned long flags; + + BUG_ON(!dtlb_entry); + + local_irq_save(flags); + entry = dtlb_entries[dtlb_entry--]; + + sh64_teardown_tlb_slot(entry); + sh64_put_wired_dtlb_entry(entry); + + local_irq_restore(flags); +} #else static inline void tlb_wire_entry(struct vm_area_struct *vma , unsigned long addr, pte_t pte) -- cgit v1.2.3 From 07cad4dc1bfdaefd20c6329e9d8179ad1c600e92 Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Tue, 17 Nov 2009 22:03:41 +0000 Subject: sh: Generalise the pte handling code for the fixmap path Generalise the code for setting and clearing pte's and allow TLB entries to be pinned and unpinned if the _PAGE_WIRED flag is present. Signed-off-by: Matt Fleming --- arch/sh/include/asm/fixmap.h | 1 + 1 file changed, 1 insertion(+) (limited to 'arch/sh/include/asm') diff --git a/arch/sh/include/asm/fixmap.h b/arch/sh/include/asm/fixmap.h index 5ac1e40a511c..1566d3361ca4 100644 --- a/arch/sh/include/asm/fixmap.h +++ b/arch/sh/include/asm/fixmap.h @@ -65,6 +65,7 @@ enum fixed_addresses { extern void __set_fixmap(enum fixed_addresses idx, unsigned long phys, pgprot_t flags); +extern void __clear_fixmap(enum fixed_addresses idx, pgprot_t flags); #define set_fixmap(idx, phys) \ __set_fixmap(idx, phys, PAGE_KERNEL) -- cgit v1.2.3 From 4d35b93a66e9b87df20784fcf130d2e8760be53f Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Thu, 5 Nov 2009 07:54:17 +0000 Subject: sh: Add fixed ioremap support Some devices need to be ioremap'd and accessed very early in the boot process. It is not possible to use the standard ioremap() function in this case because that requires kmalloc()'ing some virtual address space and kmalloc() may not be available so early in boot. This patch provides fixmap mappings that allow physical address ranges to be remapped into the kernel address space during the early boot stages. Signed-off-by: Matt Fleming --- arch/sh/include/asm/fixmap.h | 8 ++++++++ arch/sh/include/asm/io.h | 6 ++++++ 2 files changed, 14 insertions(+) (limited to 'arch/sh/include/asm') diff --git a/arch/sh/include/asm/fixmap.h b/arch/sh/include/asm/fixmap.h index 1566d3361ca4..38a1de866873 100644 --- a/arch/sh/include/asm/fixmap.h +++ b/arch/sh/include/asm/fixmap.h @@ -60,6 +60,14 @@ enum fixed_addresses { FIX_KMAP_BEGIN, /* reserved pte's for temporary kernel mappings */ FIX_KMAP_END = FIX_KMAP_BEGIN+(KM_TYPE_NR*NR_CPUS)-1, #endif + /* + * FIX_IOREMAP entries are useful for mapping physical address + * space before ioremap() is useable, e.g. really early in boot + * before kmalloc() is working. + */ +#define FIX_N_IOREMAPS 32 + FIX_IOREMAP_BEGIN, + FIX_IOREMAP_END = FIX_IOREMAP_BEGIN + FIX_N_IOREMAPS, __end_of_fixed_addresses }; diff --git a/arch/sh/include/asm/io.h b/arch/sh/include/asm/io.h index f4314d8b05b8..bee5965e0a82 100644 --- a/arch/sh/include/asm/io.h +++ b/arch/sh/include/asm/io.h @@ -237,6 +237,12 @@ void __iomem *__ioremap_caller(unsigned long offset, unsigned long size, unsigned long flags, void *caller); void __iounmap(void __iomem *addr); +#ifdef CONFIG_IOREMAP_FIXED +extern void __iomem *ioremap_fixed(resource_size_t, unsigned long, pgprot_t); +extern void iounmap_fixed(void __iomem *); +extern void ioremap_fixed_init(void); +#endif + static inline void __iomem * __ioremap(unsigned long offset, unsigned long size, unsigned long flags) { -- cgit v1.2.3 From d9b9487af79955a8e8fcddc963f56697e020cfed Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 18 Jan 2010 21:08:32 +0900 Subject: sh: Handle early ioremaps through fixed mappings. This adds in a mem_init_done to work out when a standard ioremap() is possible, falling back to the fixmap based ioremap otherwise. Signed-off-by: Paul Mundt --- arch/sh/include/asm/processor.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'arch/sh/include/asm') diff --git a/arch/sh/include/asm/processor.h b/arch/sh/include/asm/processor.h index 017e0c1807b2..a522e5d8f44f 100644 --- a/arch/sh/include/asm/processor.h +++ b/arch/sh/include/asm/processor.h @@ -101,6 +101,9 @@ struct seq_operations; extern struct pt_regs fake_swapper_regs; +/* arch/sh/mm/init.c */ +extern unsigned int mem_init_done; + /* arch/sh/kernel/setup.c */ const char *get_cpu_subtype(struct sh_cpuinfo *c); extern const struct seq_operations cpuinfo_op; -- cgit v1.2.3 From edf711b66f2a8a9629aa253ad8b3a5a03b5d7af5 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 18 Jan 2010 21:20:13 +0900 Subject: sh: Fixup the IOREMAP_FIXED=n build. Presently the fixed ioremap API is only defined when CONFIG_IOREMAP_FIXED is set. As we want to call in to it unconditionally, provide a stubbed out interface. Signed-off-by: Paul Mundt --- arch/sh/include/asm/io.h | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'arch/sh/include/asm') diff --git a/arch/sh/include/asm/io.h b/arch/sh/include/asm/io.h index bee5965e0a82..9aa9438c66c3 100644 --- a/arch/sh/include/asm/io.h +++ b/arch/sh/include/asm/io.h @@ -241,6 +241,15 @@ void __iounmap(void __iomem *addr); extern void __iomem *ioremap_fixed(resource_size_t, unsigned long, pgprot_t); extern void iounmap_fixed(void __iomem *); extern void ioremap_fixed_init(void); +#else +static inline void __iomem * +ioremap_fixed(resource_size t phys_addr, unsigned long size, pgprot_t prot) +{ + BUG(); +} + +static inline void ioremap_fixed_init(void) { } +static inline void iounmap_fixed(void __iomem *addr) { } #endif static inline void __iomem * -- cgit v1.2.3 From 4f744affc345f8b158615e0cdd01d1f4985837c3 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 18 Jan 2010 21:30:29 +0900 Subject: sh: Make iounmap_fixed() return success/failure for iounmap() path. This converts iounmap_fixed() to return success/error if it handled the unmap request or not. At the same time, drop the __init label, as this can be called in to later. Signed-off-by: Paul Mundt --- arch/sh/include/asm/io.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'arch/sh/include/asm') diff --git a/arch/sh/include/asm/io.h b/arch/sh/include/asm/io.h index 9aa9438c66c3..6a0dd8c1e0a9 100644 --- a/arch/sh/include/asm/io.h +++ b/arch/sh/include/asm/io.h @@ -22,6 +22,7 @@ * for old compat code for I/O offseting to SuperIOs, all of which are * better handled through the machvec ioport mapping routines these days. */ +#include #include #include #include @@ -239,7 +240,7 @@ void __iounmap(void __iomem *addr); #ifdef CONFIG_IOREMAP_FIXED extern void __iomem *ioremap_fixed(resource_size_t, unsigned long, pgprot_t); -extern void iounmap_fixed(void __iomem *); +extern int iounmap_fixed(void __iomem *); extern void ioremap_fixed_init(void); #else static inline void __iomem * @@ -249,7 +250,7 @@ ioremap_fixed(resource_size t phys_addr, unsigned long size, pgprot_t prot) } static inline void ioremap_fixed_init(void) { } -static inline void iounmap_fixed(void __iomem *addr) { } +static inline int iounmap_fixed(void __iomem *addr) { return -EINVAL; } #endif static inline void __iomem * -- cgit v1.2.3 From d57d64080ddc0ff13fcffc898b6251074a482ba1 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 19 Jan 2010 13:34:38 +0900 Subject: sh: Prevent 64-bit pgprot clobbering across ioremap implementations. Presently 'flags' gets passed around a lot between the various ioremap helpers and implementations, which is only 32-bits. In the X2TLB case we use 64-bit pgprots which presently results in the upper 32bits being chopped off (which handily include our read/write/exec permissions). As such, we convert everything internally to using pgprot_t directly and simply convert over with pgprot_val() where needed. With this in place, transparent fixmap utilization for early ioremap works as expected. Signed-off-by: Paul Mundt --- arch/sh/include/asm/io.h | 53 ++++++++++++++++++++++++++++-------------------- 1 file changed, 31 insertions(+), 22 deletions(-) (limited to 'arch/sh/include/asm') diff --git a/arch/sh/include/asm/io.h b/arch/sh/include/asm/io.h index 6a0dd8c1e0a9..13696dfccc16 100644 --- a/arch/sh/include/asm/io.h +++ b/arch/sh/include/asm/io.h @@ -235,7 +235,7 @@ unsigned long long poke_real_address_q(unsigned long long addr, */ #ifdef CONFIG_MMU void __iomem *__ioremap_caller(unsigned long offset, unsigned long size, - unsigned long flags, void *caller); + pgprot_t prot, void *caller); void __iounmap(void __iomem *addr); #ifdef CONFIG_IOREMAP_FIXED @@ -254,13 +254,13 @@ static inline int iounmap_fixed(void __iomem *addr) { return -EINVAL; } #endif static inline void __iomem * -__ioremap(unsigned long offset, unsigned long size, unsigned long flags) +__ioremap(unsigned long offset, unsigned long size, pgprot_t prot) { - return __ioremap_caller(offset, size, flags, __builtin_return_address(0)); + return __ioremap_caller(offset, size, prot, __builtin_return_address(0)); } static inline void __iomem * -__ioremap_29bit(unsigned long offset, unsigned long size, unsigned long flags) +__ioremap_29bit(unsigned long offset, unsigned long size, pgprot_t prot) { #ifdef CONFIG_29BIT unsigned long last_addr = offset + size - 1; @@ -272,7 +272,7 @@ __ioremap_29bit(unsigned long offset, unsigned long size, unsigned long flags) * mapping must be done by the PMB or by using page tables. */ if (likely(PXSEG(offset) < P3SEG && PXSEG(last_addr) < P3SEG)) { - if (unlikely(flags & _PAGE_CACHABLE)) + if (unlikely(pgprot_val(prot) & _PAGE_CACHABLE)) return (void __iomem *)P1SEGADDR(offset); return (void __iomem *)P2SEGADDR(offset); @@ -287,7 +287,7 @@ __ioremap_29bit(unsigned long offset, unsigned long size, unsigned long flags) } static inline void __iomem * -__ioremap_mode(unsigned long offset, unsigned long size, unsigned long flags) +__ioremap_mode(unsigned long offset, unsigned long size, pgprot_t prot) { void __iomem *ret; @@ -295,30 +295,39 @@ __ioremap_mode(unsigned long offset, unsigned long size, unsigned long flags) if (ret) return ret; - ret = __ioremap_29bit(offset, size, flags); + ret = __ioremap_29bit(offset, size, prot); if (ret) return ret; - return __ioremap(offset, size, flags); + return __ioremap(offset, size, prot); } #else -#define __ioremap(offset, size, flags) ((void __iomem *)(offset)) -#define __ioremap_mode(offset, size, flags) ((void __iomem *)(offset)) +#define __ioremap(offset, size, prot) ((void __iomem *)(offset)) +#define __ioremap_mode(offset, size, prot) ((void __iomem *)(offset)) #define __iounmap(addr) do { } while (0) #endif /* CONFIG_MMU */ -#define ioremap(offset, size) \ - __ioremap_mode((offset), (size), 0) -#define ioremap_nocache(offset, size) \ - __ioremap_mode((offset), (size), 0) -#define ioremap_cache(offset, size) \ - __ioremap_mode((offset), (size), _PAGE_CACHABLE) -#define p3_ioremap(offset, size, flags) \ - __ioremap((offset), (size), (flags)) -#define ioremap_prot(offset, size, flags) \ - __ioremap_mode((offset), (size), (flags)) -#define iounmap(addr) \ - __iounmap((addr)) +static inline void __iomem * +ioremap(unsigned long offset, unsigned long size) +{ + return __ioremap_mode(offset, size, PAGE_KERNEL_NOCACHE); +} + +static inline void __iomem * +ioremap_cache(unsigned long offset, unsigned long size) +{ + return __ioremap_mode(offset, size, PAGE_KERNEL); +} + +static inline void __iomem * +ioremap_prot(resource_size_t offset, unsigned long size, unsigned long flags) +{ + return __ioremap_mode(offset, size, __pgprot(flags)); +} + +#define ioremap_nocache ioremap +#define p3_ioremap __ioremap +#define iounmap __iounmap #define maybebadio(port) \ printk(KERN_ERR "bad PC-like io %s:%u for port 0x%lx at 0x%08x\n", \ -- cgit v1.2.3 From acf2c9685fb8295cb62a623d7358a1cfde8b07ea Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 19 Jan 2010 13:49:19 +0900 Subject: sh: Kill off duplicate address alignment in ioremap_fixed(). This is already taken care of in the top-level ioremap, and now that no one should be calling ioremap_fixed() directly we can simply throw the mapping displacement in as an additional argument. Signed-off-by: Paul Mundt --- arch/sh/include/asm/io.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'arch/sh/include/asm') diff --git a/arch/sh/include/asm/io.h b/arch/sh/include/asm/io.h index 13696dfccc16..70269813cef1 100644 --- a/arch/sh/include/asm/io.h +++ b/arch/sh/include/asm/io.h @@ -239,12 +239,14 @@ void __iomem *__ioremap_caller(unsigned long offset, unsigned long size, void __iounmap(void __iomem *addr); #ifdef CONFIG_IOREMAP_FIXED -extern void __iomem *ioremap_fixed(resource_size_t, unsigned long, pgprot_t); +extern void __iomem *ioremap_fixed(resource_size_t, unsigned long, + unsigned long, pgprot_t); extern int iounmap_fixed(void __iomem *); extern void ioremap_fixed_init(void); #else static inline void __iomem * -ioremap_fixed(resource_size t phys_addr, unsigned long size, pgprot_t prot) +ioremap_fixed(resource_size t phys_addr, unsigned long offset, + unsigned long size, pgprot_t prot) { BUG(); } -- cgit v1.2.3 From f33609344acfdde1c1acedf6de3efe6b80af93a6 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 19 Jan 2010 13:55:41 +0900 Subject: sh: Convert p3_ioremap() users to ioremap_prot(). This kills off the ancient p3_ioremap(), converting over to the more generic ioremap_prot() instead. Signed-off-by: Paul Mundt --- arch/sh/include/asm/io.h | 1 - 1 file changed, 1 deletion(-) (limited to 'arch/sh/include/asm') diff --git a/arch/sh/include/asm/io.h b/arch/sh/include/asm/io.h index 70269813cef1..c32a55601d01 100644 --- a/arch/sh/include/asm/io.h +++ b/arch/sh/include/asm/io.h @@ -328,7 +328,6 @@ ioremap_prot(resource_size_t offset, unsigned long size, unsigned long flags) } #define ioremap_nocache ioremap -#define p3_ioremap __ioremap #define iounmap __iounmap #define maybebadio(port) \ -- cgit v1.2.3 From 6d63e73d520b690e4378cef3003eb5f01f7d128c Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 19 Jan 2010 14:00:14 +0900 Subject: sh: Limit ioremap_prot() to 32bit pgprot parts. Presently ioremap_prot() uses an unsigned long to pass the pgprot value around. This results in the upper half of the pgprot being chomped when using 64-bit pgprots on a 32-bit ABI (X2TLB and SH-5). As the only users of ioremap_prot() are presently legacy parts, this doesn't cause too much of an issue. In the future when the interface is converted to use pgprot_t directly this can be re-enabled for the other parts, too. Signed-off-by: Paul Mundt --- arch/sh/include/asm/io.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch/sh/include/asm') diff --git a/arch/sh/include/asm/io.h b/arch/sh/include/asm/io.h index c32a55601d01..4bad72a1b39e 100644 --- a/arch/sh/include/asm/io.h +++ b/arch/sh/include/asm/io.h @@ -321,11 +321,13 @@ ioremap_cache(unsigned long offset, unsigned long size) return __ioremap_mode(offset, size, PAGE_KERNEL); } +#ifdef CONFIG_HAVE_IOREMAP_PROT static inline void __iomem * ioremap_prot(resource_size_t offset, unsigned long size, unsigned long flags) { return __ioremap_mode(offset, size, __pgprot(flags)); } +#endif #define ioremap_nocache ioremap #define iounmap __iounmap -- cgit v1.2.3 From 046581f9623b53f551a93864bb74e15ad2514f0c Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 19 Jan 2010 14:23:39 +0900 Subject: sh: Provide a dummy _PAGE_WIRED flag for non-X2TLB parts. This provides a dummy value for legacy parts which permits the entry wiring to be open-coded. The compiler takes care of optimizing the entry wiring away in these cases. Signed-off-by: Paul Mundt --- arch/sh/include/asm/pgtable_32.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch/sh/include/asm') diff --git a/arch/sh/include/asm/pgtable_32.h b/arch/sh/include/asm/pgtable_32.h index c573d45f1286..e172d696e52b 100644 --- a/arch/sh/include/asm/pgtable_32.h +++ b/arch/sh/include/asm/pgtable_32.h @@ -143,12 +143,14 @@ static inline unsigned long copy_ptea_attributes(unsigned long x) # elif defined(CONFIG_HUGETLB_PAGE_SIZE_64MB) # define _PAGE_SZHUGE (_PAGE_EXT_ESZ2 | _PAGE_EXT_ESZ3) # endif +# define _PAGE_WIRED (_PAGE_EXT(_PAGE_EXT_WIRED)) #else # if defined(CONFIG_HUGETLB_PAGE_SIZE_64K) # define _PAGE_SZHUGE (_PAGE_SZ1) # elif defined(CONFIG_HUGETLB_PAGE_SIZE_1MB) # define _PAGE_SZHUGE (_PAGE_SZ0 | _PAGE_SZ1) # endif +# define _PAGE_WIRED (0) #endif /* @@ -166,8 +168,6 @@ static inline unsigned long copy_ptea_attributes(unsigned long x) (PTE_MASK | _PAGE_ACCESSED | _PAGE_CACHABLE | \ _PAGE_DIRTY | _PAGE_SPECIAL) -#define _PAGE_WIRED (_PAGE_EXT(_PAGE_EXT_WIRED)) - #ifndef __ASSEMBLY__ #if defined(CONFIG_X2TLB) /* SH-X2 TLB */ -- cgit v1.2.3 From bb29c677b366fdf4f6522cd82228a32567aa98c7 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 19 Jan 2010 15:20:35 +0900 Subject: sh: Split out MMUCR.URB based entry wiring in to shared helper. Presently this is duplicated between tlb-sh4 and tlb-pteaex. Split the helpers out in to a generic tlb-urb that can be used by any parts equipped with MMUCR.URB. At the same time, move the SH-5 code out-of-line, as we require single global state for DTLB entry wiring. Signed-off-by: Paul Mundt --- arch/sh/include/asm/tlb.h | 44 ++------------------------------------------ 1 file changed, 2 insertions(+), 42 deletions(-) (limited to 'arch/sh/include/asm') diff --git a/arch/sh/include/asm/tlb.h b/arch/sh/include/asm/tlb.h index dfc8fcd8ee50..75abb38dffd5 100644 --- a/arch/sh/include/asm/tlb.h +++ b/arch/sh/include/asm/tlb.h @@ -98,49 +98,9 @@ tlb_end_vma(struct mmu_gather *tlb, struct vm_area_struct *vma) #define tlb_migrate_finish(mm) do { } while (0) -#ifdef CONFIG_CPU_SH4 +#if defined(CONFIG_CPU_SH4) || defined(CONFIG_SUPERH64) extern void tlb_wire_entry(struct vm_area_struct *, unsigned long, pte_t); extern void tlb_unwire_entry(void); -#elif defined(CONFIG_SUPERH64) -static int dtlb_entry; -static unsigned long long dtlb_entries[64]; - -static inline void tlb_wire_entry(struct vm_area_struct *vma, - unsigned long addr, pte_t pte) -{ - unsigned long long entry; - unsigned long paddr, flags; - - BUG_ON(dtlb_entry == 64); - - local_irq_save(flags); - - entry = sh64_get_wired_dtlb_entry(); - dtlb_entries[dtlb_entry++] = entry; - - paddr = pte_val(pte) & _PAGE_FLAGS_HARDWARE_MASK; - paddr &= ~PAGE_MASK; - - sh64_setup_tlb_slot(entry, addr, get_asid(), paddr); - - local_irq_restore(flags); -} - -static inline void tlb_unwire_entry(void) -{ - unsigned long long entry; - unsigned long flags; - - BUG_ON(!dtlb_entry); - - local_irq_save(flags); - entry = dtlb_entries[dtlb_entry--]; - - sh64_teardown_tlb_slot(entry); - sh64_put_wired_dtlb_entry(entry); - - local_irq_restore(flags); -} #else static inline void tlb_wire_entry(struct vm_area_struct *vma , unsigned long addr, pte_t pte) @@ -152,7 +112,7 @@ static inline void tlb_unwire_entry(void) { BUG(); } -#endif /* CONFIG_CPU_SH4 */ +#endif #else /* CONFIG_MMU */ -- cgit v1.2.3 From 3ef2932b8c1fc89408ef1fd4b1e1c2caabc7f07d Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 19 Jan 2010 15:40:03 +0900 Subject: sh64: Fix up the build for the thread_xstate changes. This updates the sh64 processor info with the sh32 changes in order to tie in to the generic task_xstate management code. Signed-off-by: Paul Mundt --- arch/sh/include/asm/processor.h | 6 ++++++ arch/sh/include/asm/processor_32.h | 4 ---- arch/sh/include/asm/processor_64.h | 18 +++++++++--------- 3 files changed, 15 insertions(+), 13 deletions(-) (limited to 'arch/sh/include/asm') diff --git a/arch/sh/include/asm/processor.h b/arch/sh/include/asm/processor.h index a522e5d8f44f..87a8d1ef64e4 100644 --- a/arch/sh/include/asm/processor.h +++ b/arch/sh/include/asm/processor.h @@ -98,9 +98,15 @@ extern struct sh_cpuinfo cpu_data[]; /* Forward decl */ struct seq_operations; +struct task_struct; extern struct pt_regs fake_swapper_regs; +/* arch/sh/kernel/process.c */ +extern unsigned int xstate_size; +extern void free_thread_xstate(struct task_struct *); +extern struct kmem_cache *task_xstate_cachep; + /* arch/sh/mm/init.c */ extern unsigned int mem_init_done; diff --git a/arch/sh/include/asm/processor_32.h b/arch/sh/include/asm/processor_32.h index 5fd83125fb89..488f0a906a41 100644 --- a/arch/sh/include/asm/processor_32.h +++ b/arch/sh/include/asm/processor_32.h @@ -96,10 +96,6 @@ union thread_xstate { struct sh_fpu_soft_struct softfpu; }; -extern unsigned int xstate_size; -extern void free_thread_xstate(struct task_struct *); -extern struct kmem_cache *task_xstate_cachep; - struct thread_struct { /* Saved registers when thread is descheduled */ unsigned long sp; diff --git a/arch/sh/include/asm/processor_64.h b/arch/sh/include/asm/processor_64.h index 5727d31b0ccf..7b1560f03d14 100644 --- a/arch/sh/include/asm/processor_64.h +++ b/arch/sh/include/asm/processor_64.h @@ -87,20 +87,21 @@ struct sh_fpu_hard_struct { /* long status; * software status information */ }; -#if 0 /* Dummy fpu emulator */ struct sh_fpu_soft_struct { - unsigned long long fp_regs[32]; + unsigned long fp_regs[64]; unsigned int fpscr; unsigned char lookahead; unsigned long entry_pc; }; -#endif -union sh_fpu_union { - struct sh_fpu_hard_struct hard; - /* 'hard' itself only produces 32 bit alignment, yet we need - to access it using 64 bit load/store as well. */ +union thread_xstate { + struct sh_fpu_hard_struct hardfpu; + struct sh_fpu_soft_struct softfpu; + /* + * The structure definitions only produce 32 bit alignment, yet we need + * to access them using 64 bit load/store as well. + */ unsigned long long alignment_dummy; }; @@ -122,7 +123,7 @@ struct thread_struct { /* Hardware debugging registers may come here */ /* floating point info */ - union sh_fpu_union fpu; + union thread_xstate *xstate; }; #define INIT_MMAP \ @@ -137,7 +138,6 @@ struct thread_struct { .trap_no = 0, \ .error_code = 0, \ .address = 0, \ - .fpu = { { { 0, } }, } \ } /* -- cgit v1.2.3 From 31c3af503eb75488aafb7a3d292b9e00962f2cee Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Tue, 19 Jan 2010 11:14:31 +0000 Subject: sh: support SIU sourcing from external clock on sh7722 Implement .set_rate() for all SH "div4 clocks," .enable(), .disable(), and .set_parent() for those, that support them. This allows, among other uses, reparenting of SIU clocks to the external source, and enabling and disabling of the IrDA clock on sh7722. Signed-off-by: Guennadi Liakhovetski Signed-off-by: Paul Mundt --- arch/sh/include/asm/clock.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'arch/sh/include/asm') diff --git a/arch/sh/include/asm/clock.h b/arch/sh/include/asm/clock.h index 9fe7d7f8af40..501d0b076283 100644 --- a/arch/sh/include/asm/clock.h +++ b/arch/sh/include/asm/clock.h @@ -148,6 +148,10 @@ int sh_clk_mstp32_register(struct clk *clks, int nr); int sh_clk_div4_register(struct clk *clks, int nr, struct clk_div_mult_table *table); +int sh_clk_div4_enable_register(struct clk *clks, int nr, + struct clk_div_mult_table *table); +int sh_clk_div4_reparent_register(struct clk *clks, int nr, + struct clk_div_mult_table *table); #define SH_CLK_DIV6(_name, _parent, _reg, _flags) \ { \ -- cgit v1.2.3 From 70911b861bfbba1851cbb3497635030f34703c7a Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 20 Jan 2010 02:45:05 +0900 Subject: sh: Shut up noisy IOREMAP_FIXED=n build. The ioremap_fixed() stub neglected to provide a return value, resulting in a fairly noisy build. Signed-off-by: Paul Mundt --- arch/sh/include/asm/io.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'arch/sh/include/asm') diff --git a/arch/sh/include/asm/io.h b/arch/sh/include/asm/io.h index 4bad72a1b39e..e4f563f472eb 100644 --- a/arch/sh/include/asm/io.h +++ b/arch/sh/include/asm/io.h @@ -245,10 +245,11 @@ extern int iounmap_fixed(void __iomem *); extern void ioremap_fixed_init(void); #else static inline void __iomem * -ioremap_fixed(resource_size t phys_addr, unsigned long offset, +ioremap_fixed(resource_size_t phys_addr, unsigned long offset, unsigned long size, pgprot_t prot) { BUG(); + return NULL; } static inline void ioremap_fixed_init(void) { } -- cgit v1.2.3 From 2efa53b269ec1e9289a108e1506f53f6f1de440b Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 20 Jan 2010 16:40:48 +0900 Subject: sh: Make 29/32-bit mode check helper generally available. Presently __in_29bit_mode() is only defined for the PMB case, but it's also easily derived from the CONFIG_29BIT and CONFIG_32BIT && CONFIG_PMB=n cases. Signed-off-by: Paul Mundt --- arch/sh/include/asm/addrspace.h | 6 ------ arch/sh/include/asm/mmu.h | 10 +++++++++- 2 files changed, 9 insertions(+), 7 deletions(-) (limited to 'arch/sh/include/asm') diff --git a/arch/sh/include/asm/addrspace.h b/arch/sh/include/asm/addrspace.h index 268efd62ed21..446b3831c214 100644 --- a/arch/sh/include/asm/addrspace.h +++ b/arch/sh/include/asm/addrspace.h @@ -65,11 +65,5 @@ #define P3_ADDR_MAX P4SEG #endif -#ifndef __ASSEMBLY__ -#ifdef CONFIG_PMB -extern int __in_29bit_mode(void); -#endif /* CONFIG_PMB */ -#endif /* __ASSEMBLY__ */ - #endif /* __KERNEL__ */ #endif /* __ASM_SH_ADDRSPACE_H */ diff --git a/arch/sh/include/asm/mmu.h b/arch/sh/include/asm/mmu.h index e5e8f48830ef..ca7d91e8aa72 100644 --- a/arch/sh/include/asm/mmu.h +++ b/arch/sh/include/asm/mmu.h @@ -31,6 +31,7 @@ #ifndef __ASSEMBLY__ #include +#include /* Default "unsigned long" context */ typedef unsigned long mm_context_id_t[NR_CPUS]; @@ -72,6 +73,7 @@ long pmb_remap(unsigned long virt, unsigned long phys, unsigned long size, unsigned long flags); void pmb_unmap(unsigned long addr); int pmb_init(void); +bool __in_29bit_mode(void); #else static inline long pmb_remap(unsigned long virt, unsigned long phys, unsigned long size, unsigned long flags) @@ -87,8 +89,14 @@ static inline int pmb_init(void) { return -ENODEV; } -#endif /* CONFIG_PMB */ +#ifdef CONFIG_29BIT +#define __in_29bit_mode() (1) +#else +#define __in_29bit_mode() (0) +#endif + +#endif /* CONFIG_PMB */ #endif /* __ASSEMBLY__ */ #endif /* __MMU_H */ -- cgit v1.2.3 From fbb82b03653cdb7fd1863b911e7540011259d2ce Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 20 Jan 2010 16:42:52 +0900 Subject: sh: machine_ops based reboot support. This provides a machine_ops-based reboot interface loosely cloned from x86, and converts the native sh32 and sh64 cases over to it. Necessary both for tying in SMP support and also enabling platforms like SDK7786 to add support for their microcontroller-based power managers. Signed-off-by: Paul Mundt --- arch/sh/include/asm/reboot.h | 21 +++++++++++++++++++++ arch/sh/include/asm/system.h | 1 + arch/sh/include/asm/system_32.h | 12 ++++++++++++ arch/sh/include/asm/system_64.h | 7 +++++++ 4 files changed, 41 insertions(+) create mode 100644 arch/sh/include/asm/reboot.h (limited to 'arch/sh/include/asm') diff --git a/arch/sh/include/asm/reboot.h b/arch/sh/include/asm/reboot.h new file mode 100644 index 000000000000..b3da0c63fc3d --- /dev/null +++ b/arch/sh/include/asm/reboot.h @@ -0,0 +1,21 @@ +#ifndef __ASM_SH_REBOOT_H +#define __ASM_SH_REBOOT_H + +#include + +struct pt_regs; + +struct machine_ops { + void (*restart)(char *cmd); + void (*halt)(void); + void (*power_off)(void); + void (*shutdown)(void); + void (*crash_shutdown)(struct pt_regs *); +}; + +extern struct machine_ops machine_ops; + +/* arch/sh/kernel/machine_kexec.c */ +void native_machine_crash_shutdown(struct pt_regs *regs); + +#endif /* __ASM_SH_REBOOT_H */ diff --git a/arch/sh/include/asm/system.h b/arch/sh/include/asm/system.h index 62e4fc1e4409..de2fc3963c12 100644 --- a/arch/sh/include/asm/system.h +++ b/arch/sh/include/asm/system.h @@ -143,6 +143,7 @@ extern struct dentry *sh_debugfs_root; void per_cpu_trap_init(void); void default_idle(void); void cpu_idle_wait(void); +void stop_this_cpu(void *); #ifdef CONFIG_SUPERH32 #define BUILD_TRAP_HANDLER(name) \ diff --git a/arch/sh/include/asm/system_32.h b/arch/sh/include/asm/system_32.h index 06814f5b59c7..34bd2bac9a5f 100644 --- a/arch/sh/include/asm/system_32.h +++ b/arch/sh/include/asm/system_32.h @@ -2,6 +2,7 @@ #define __ASM_SH_SYSTEM_32_H #include +#include #ifdef CONFIG_SH_DSP @@ -216,6 +217,17 @@ static inline reg_size_t register_align(void *val) int handle_unaligned_access(insn_size_t instruction, struct pt_regs *regs, struct mem_access *ma, int); +static inline void trigger_address_error(void) +{ + if (__in_29bit_mode()) + __asm__ __volatile__ ( + "ldc %0, sr\n\t" + "mov.l @%1, %0" + : + : "r" (0x10000000), "r" (0x80000001) + ); +} + asmlinkage void do_address_error(struct pt_regs *regs, unsigned long writeaccess, unsigned long address); diff --git a/arch/sh/include/asm/system_64.h b/arch/sh/include/asm/system_64.h index ab1dd917ea87..604ba7802cc2 100644 --- a/arch/sh/include/asm/system_64.h +++ b/arch/sh/include/asm/system_64.h @@ -48,6 +48,13 @@ static inline reg_size_t register_align(void *val) return (unsigned long long)(signed long long)(signed long)val; } +extern void phys_stext(void); + +static inline void trigger_address_error(void) +{ + phys_stext(); +} + #define SR_BL_LL 0x0000000010000000LL static inline void set_bl_bit(void) -- cgit v1.2.3 From 3125ee72dca25fc2157dcddd07e2d740db921fc4 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Thu, 21 Jan 2010 15:54:31 +0900 Subject: sh: Track the uncached mapping size. This provides a variable for tracking the uncached mapping size, and uses it for pretty printing the uncached lowmem range. Beyond this, we'll also be building on top of this for figuring out from where the remainder of P2 becomes usable when constructing unrelated mappings. Signed-off-by: Paul Mundt --- arch/sh/include/asm/system.h | 1 + 1 file changed, 1 insertion(+) (limited to 'arch/sh/include/asm') diff --git a/arch/sh/include/asm/system.h b/arch/sh/include/asm/system.h index de2fc3963c12..6442f1783fe0 100644 --- a/arch/sh/include/asm/system.h +++ b/arch/sh/include/asm/system.h @@ -137,6 +137,7 @@ extern unsigned int instruction_size(unsigned int insn); #endif extern unsigned long cached_to_uncached; +extern unsigned long uncached_size; extern struct dentry *sh_debugfs_root; -- cgit v1.2.3 From 2dc2f8e0c46864e2a3722c84eaa96513d4cf8b2f Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Thu, 21 Jan 2010 16:05:25 +0900 Subject: sh: Kill off the special uncached section and fixmap. Now that cached_to_uncached works as advertized in 32-bit mode and we're never going to be able to map < 16MB anyways, there's no need for the special uncached section. Kill it off. Signed-off-by: Paul Mundt --- arch/sh/include/asm/fixmap.h | 4 +++- arch/sh/include/asm/system_32.h | 3 --- arch/sh/include/asm/system_64.h | 2 -- 3 files changed, 3 insertions(+), 6 deletions(-) (limited to 'arch/sh/include/asm') diff --git a/arch/sh/include/asm/fixmap.h b/arch/sh/include/asm/fixmap.h index 38a1de866873..17b22b6c1001 100644 --- a/arch/sh/include/asm/fixmap.h +++ b/arch/sh/include/asm/fixmap.h @@ -55,11 +55,12 @@ enum fixed_addresses { #define FIX_N_COLOURS 8 FIX_CMAP_BEGIN, FIX_CMAP_END = FIX_CMAP_BEGIN + (FIX_N_COLOURS * NR_CPUS) - 1, - FIX_UNCACHED, + #ifdef CONFIG_HIGHMEM FIX_KMAP_BEGIN, /* reserved pte's for temporary kernel mappings */ FIX_KMAP_END = FIX_KMAP_BEGIN+(KM_TYPE_NR*NR_CPUS)-1, #endif + /* * FIX_IOREMAP entries are useful for mapping physical address * space before ioremap() is useable, e.g. really early in boot @@ -68,6 +69,7 @@ enum fixed_addresses { #define FIX_N_IOREMAPS 32 FIX_IOREMAP_BEGIN, FIX_IOREMAP_END = FIX_IOREMAP_BEGIN + FIX_N_IOREMAPS, + __end_of_fixed_addresses }; diff --git a/arch/sh/include/asm/system_32.h b/arch/sh/include/asm/system_32.h index 34bd2bac9a5f..51296b36770e 100644 --- a/arch/sh/include/asm/system_32.h +++ b/arch/sh/include/asm/system_32.h @@ -145,9 +145,6 @@ do { \ __restore_dsp(prev); \ } while (0) -#define __uses_jump_to_uncached \ - noinline __attribute__ ((__section__ (".uncached.text"))) - /* * Jump to uncached area. * When handling TLB or caches, we need to do it from an uncached area. diff --git a/arch/sh/include/asm/system_64.h b/arch/sh/include/asm/system_64.h index 604ba7802cc2..3391bb6b21d8 100644 --- a/arch/sh/include/asm/system_64.h +++ b/arch/sh/include/asm/system_64.h @@ -33,8 +33,6 @@ do { \ &next->thread); \ } while (0) -#define __uses_jump_to_uncached - #define jump_to_uncached() do { } while (0) #define back_to_cached() do { } while (0) -- cgit v1.2.3 From a077e91690fb32a1453423b2cf1df3492fd30c3a Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Thu, 21 Jan 2010 16:16:36 +0900 Subject: sh: Conserve fixmap slots when IOREMAP_FIXED=n. Presently the IOREMAP_FIXED fixmaps are always defined, even if the platform isn't capable of supporting it. Since we already have an ifdef for it, ifdef the entries, too. Signed-off-by: Paul Mundt --- arch/sh/include/asm/fixmap.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch/sh/include/asm') diff --git a/arch/sh/include/asm/fixmap.h b/arch/sh/include/asm/fixmap.h index 17b22b6c1001..6e7cea453895 100644 --- a/arch/sh/include/asm/fixmap.h +++ b/arch/sh/include/asm/fixmap.h @@ -61,6 +61,7 @@ enum fixed_addresses { FIX_KMAP_END = FIX_KMAP_BEGIN+(KM_TYPE_NR*NR_CPUS)-1, #endif +#ifdef CONFIG_IOREMAP_FIXED /* * FIX_IOREMAP entries are useful for mapping physical address * space before ioremap() is useable, e.g. really early in boot @@ -69,6 +70,7 @@ enum fixed_addresses { #define FIX_N_IOREMAPS 32 FIX_IOREMAP_BEGIN, FIX_IOREMAP_END = FIX_IOREMAP_BEGIN + FIX_N_IOREMAPS, +#endif __end_of_fixed_addresses }; -- cgit v1.2.3 From 9d56dd3b083a3bec56e9da35ce07baca81030b03 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 26 Jan 2010 12:58:40 +0900 Subject: sh: Mass ctrl_in/outX to __raw_read/writeX conversion. The old ctrl in/out routines are non-portable and unsuitable for cross-platform use. While drivers/sh has already been sanitized, there is still quite a lot of code that is not. This converts the arch/sh/ bits over, which permits us to flag the routines as deprecated whilst still building with -Werror for the architecture code, and to ensure that future users are not added. Signed-off-by: Paul Mundt --- arch/sh/include/asm/dma-sh.h | 12 ++++++------ arch/sh/include/asm/mmu_context.h | 6 +++--- arch/sh/include/asm/mmu_context_32.h | 4 ++-- arch/sh/include/asm/watchdog.h | 18 +++++++++--------- 4 files changed, 20 insertions(+), 20 deletions(-) (limited to 'arch/sh/include/asm') diff --git a/arch/sh/include/asm/dma-sh.h b/arch/sh/include/asm/dma-sh.h index 78eed3e0bdf5..47de10976991 100644 --- a/arch/sh/include/asm/dma-sh.h +++ b/arch/sh/include/asm/dma-sh.h @@ -20,14 +20,14 @@ defined(CONFIG_CPU_SUBTYPE_SH7780) || \ defined(CONFIG_CPU_SUBTYPE_SH7785) #define dmaor_read_reg(n) \ - (n ? ctrl_inw(SH_DMAC_BASE1 + DMAOR) \ - : ctrl_inw(SH_DMAC_BASE0 + DMAOR)) + (n ? __raw_readw(SH_DMAC_BASE1 + DMAOR) \ + : __raw_readw(SH_DMAC_BASE0 + DMAOR)) #define dmaor_write_reg(n, data) \ - (n ? ctrl_outw(data, SH_DMAC_BASE1 + DMAOR) \ - : ctrl_outw(data, SH_DMAC_BASE0 + DMAOR)) + (n ? __raw_writew(data, SH_DMAC_BASE1 + DMAOR) \ + : __raw_writew(data, SH_DMAC_BASE0 + DMAOR)) #else /* Other CPU */ -#define dmaor_read_reg(n) ctrl_inw(SH_DMAC_BASE0 + DMAOR) -#define dmaor_write_reg(n, data) ctrl_outw(data, SH_DMAC_BASE0 + DMAOR) +#define dmaor_read_reg(n) __raw_readw(SH_DMAC_BASE0 + DMAOR) +#define dmaor_write_reg(n, data) __raw_writew(data, SH_DMAC_BASE0 + DMAOR) #endif static int dmte_irq_map[] __maybe_unused = { diff --git a/arch/sh/include/asm/mmu_context.h b/arch/sh/include/asm/mmu_context.h index 41080b173a7a..384c7471a374 100644 --- a/arch/sh/include/asm/mmu_context.h +++ b/arch/sh/include/asm/mmu_context.h @@ -158,7 +158,7 @@ static inline void enable_mmu(void) unsigned int cpu = smp_processor_id(); /* Enable MMU */ - ctrl_outl(MMU_CONTROL_INIT, MMUCR); + __raw_writel(MMU_CONTROL_INIT, MMUCR); ctrl_barrier(); if (asid_cache(cpu) == NO_CONTEXT) @@ -171,9 +171,9 @@ static inline void disable_mmu(void) { unsigned long cr; - cr = ctrl_inl(MMUCR); + cr = __raw_readl(MMUCR); cr &= ~MMU_CONTROL_INIT; - ctrl_outl(cr, MMUCR); + __raw_writel(cr, MMUCR); ctrl_barrier(); } diff --git a/arch/sh/include/asm/mmu_context_32.h b/arch/sh/include/asm/mmu_context_32.h index 8ef800c549ab..10e2e17210d2 100644 --- a/arch/sh/include/asm/mmu_context_32.h +++ b/arch/sh/include/asm/mmu_context_32.h @@ -49,11 +49,11 @@ static inline unsigned long get_asid(void) /* MMU_TTB is used for optimizing the fault handling. */ static inline void set_TTB(pgd_t *pgd) { - ctrl_outl((unsigned long)pgd, MMU_TTB); + __raw_writel((unsigned long)pgd, MMU_TTB); } static inline pgd_t *get_TTB(void) { - return (pgd_t *)ctrl_inl(MMU_TTB); + return (pgd_t *)__raw_readl(MMU_TTB); } #endif /* __ASM_SH_MMU_CONTEXT_32_H */ diff --git a/arch/sh/include/asm/watchdog.h b/arch/sh/include/asm/watchdog.h index 19dfff5c8511..85a7aca7fb8f 100644 --- a/arch/sh/include/asm/watchdog.h +++ b/arch/sh/include/asm/watchdog.h @@ -70,7 +70,7 @@ */ static inline __u32 sh_wdt_read_cnt(void) { - return ctrl_inl(WTCNT_R); + return __raw_readl(WTCNT_R); } /** @@ -82,7 +82,7 @@ static inline __u32 sh_wdt_read_cnt(void) */ static inline void sh_wdt_write_cnt(__u32 val) { - ctrl_outl((WTCNT_HIGH << 24) | (__u32)val, WTCNT); + __raw_writel((WTCNT_HIGH << 24) | (__u32)val, WTCNT); } /** @@ -94,7 +94,7 @@ static inline void sh_wdt_write_cnt(__u32 val) */ static inline void sh_wdt_write_bst(__u32 val) { - ctrl_outl((WTBST_HIGH << 24) | (__u32)val, WTBST); + __raw_writel((WTBST_HIGH << 24) | (__u32)val, WTBST); } /** * sh_wdt_read_csr - Read from Control/Status Register @@ -103,7 +103,7 @@ static inline void sh_wdt_write_bst(__u32 val) */ static inline __u32 sh_wdt_read_csr(void) { - return ctrl_inl(WTCSR_R); + return __raw_readl(WTCSR_R); } /** @@ -115,7 +115,7 @@ static inline __u32 sh_wdt_read_csr(void) */ static inline void sh_wdt_write_csr(__u32 val) { - ctrl_outl((WTCSR_HIGH << 24) | (__u32)val, WTCSR); + __raw_writel((WTCSR_HIGH << 24) | (__u32)val, WTCSR); } #else /** @@ -124,7 +124,7 @@ static inline void sh_wdt_write_csr(__u32 val) */ static inline __u8 sh_wdt_read_cnt(void) { - return ctrl_inb(WTCNT_R); + return __raw_readb(WTCNT_R); } /** @@ -136,7 +136,7 @@ static inline __u8 sh_wdt_read_cnt(void) */ static inline void sh_wdt_write_cnt(__u8 val) { - ctrl_outw((WTCNT_HIGH << 8) | (__u16)val, WTCNT); + __raw_writew((WTCNT_HIGH << 8) | (__u16)val, WTCNT); } /** @@ -146,7 +146,7 @@ static inline void sh_wdt_write_cnt(__u8 val) */ static inline __u8 sh_wdt_read_csr(void) { - return ctrl_inb(WTCSR_R); + return __raw_readb(WTCSR_R); } /** @@ -158,7 +158,7 @@ static inline __u8 sh_wdt_read_csr(void) */ static inline void sh_wdt_write_csr(__u8 val) { - ctrl_outw((WTCSR_HIGH << 8) | (__u16)val, WTCSR); + __raw_writew((WTCSR_HIGH << 8) | (__u16)val, WTCSR); } #endif /* CONFIG_CPU_SUBTYPE_SH7785 || CONFIG_CPU_SUBTYPE_SH7780 */ #endif /* __KERNEL__ */ -- cgit v1.2.3 From 485773f3e401fca31c112c1ff24797e42ff87afd Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 26 Jan 2010 13:02:10 +0900 Subject: sh: flag ctrl_in/outX as __deprecated. These routines are unsuitable for cross-platform use and no new code should be using them, flag them as deprecated in order to give drivers sufficient time to migrate over. Signed-off-by: Paul Mundt --- arch/sh/include/asm/io.h | 55 +++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 45 insertions(+), 10 deletions(-) (limited to 'arch/sh/include/asm') diff --git a/arch/sh/include/asm/io.h b/arch/sh/include/asm/io.h index e4f563f472eb..98c62fa168c2 100644 --- a/arch/sh/include/asm/io.h +++ b/arch/sh/include/asm/io.h @@ -80,16 +80,51 @@ #define writel(v,a) ({ __raw_writel((v),(a)); mb(); }) #define writeq(v,a) ({ __raw_writeq((v),(a)); mb(); }) -/* SuperH on-chip I/O functions */ -#define ctrl_inb __raw_readb -#define ctrl_inw __raw_readw -#define ctrl_inl __raw_readl -#define ctrl_inq __raw_readq - -#define ctrl_outb __raw_writeb -#define ctrl_outw __raw_writew -#define ctrl_outl __raw_writel -#define ctrl_outq __raw_writeq +/* + * Legacy SuperH on-chip I/O functions + * + * These are all deprecated, all new (and especially cross-platform) code + * should be using the __raw_xxx() routines directly. + */ +static inline u8 __deprecated ctrl_inb(unsigned long addr) +{ + return __raw_readb(addr); +} + +static inline u16 __deprecated ctrl_inw(unsigned long addr) +{ + return __raw_readw(addr); +} + +static inline u32 __deprecated ctrl_inl(unsigned long addr) +{ + return __raw_readl(addr); +} + +static inline u64 __deprecated ctrl_inq(unsigned long addr) +{ + return __raw_readq(addr); +} + +static inline void __deprecated ctrl_outb(u8 v, unsigned long addr) +{ + __raw_writeb(v, addr); +} + +static inline void __deprecated ctrl_outw(u16 v, unsigned long addr) +{ + __raw_writew(v, addr); +} + +static inline void __deprecated ctrl_outl(u32 v, unsigned long addr) +{ + __raw_writel(v, addr); +} + +static inline void __deprecated ctrl_outq(u64 v, unsigned long addr) +{ + __raw_writeq(v, addr); +} extern unsigned long generic_io_base; -- cgit v1.2.3 From 7013109f52ff38ad9ea38952cedc144c8e8b9636 Mon Sep 17 00:00:00 2001 From: Giuseppe CAVALLARO Date: Mon, 25 Jan 2010 16:12:07 +0100 Subject: sh: fixed cmpxchg gRB version This patch fixes a bug within the cmpxchg GRB version. A problem was notices while running some tests to stress the priority inheritance, for example pi_stress (http://rt.wiki.kernel.org/index.php/PI_Mutex_Test). Also, without this patch, after applying the latest work to consolidate atomic_cmpxchg() definitions (commit: 8c0b8139c87cfe8b95c6e763b4ca3190aa9b1ad0) the Kernel doesn't boot at all. Signed-off-by: Giuseppe Cavallaro Signed-off-by: Stuart Menefy Signed-off-by: Paul Mundt --- arch/sh/include/asm/cmpxchg-grb.h | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'arch/sh/include/asm') diff --git a/arch/sh/include/asm/cmpxchg-grb.h b/arch/sh/include/asm/cmpxchg-grb.h index e2681abe764f..4676bf57693a 100644 --- a/arch/sh/include/asm/cmpxchg-grb.h +++ b/arch/sh/include/asm/cmpxchg-grb.h @@ -57,11 +57,10 @@ static inline unsigned long __cmpxchg_u32(volatile int *m, unsigned long old, " mov.l @%1, %0 \n\t" /* load old value */ " cmp/eq %0, %2 \n\t" " bf 1f \n\t" /* if not equal */ - " mov.l %2, @%1 \n\t" /* store new value */ + " mov.l %3, @%1 \n\t" /* store new value */ "1: mov r1, r15 \n\t" /* LOGOUT */ - : "=&r" (retval), - "+r" (m) - : "r" (new) + : "=&r" (retval) + : "r" (m), "r" (old), "r" (new) : "memory" , "r0", "r1", "t"); return retval; -- cgit v1.2.3 From 621266bdf4b78fa92f7eabd7688b86f0dbd61d64 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Thu, 28 Jan 2010 15:55:37 +0900 Subject: sh: Quiet noisy coherent DMA unmapping on R2D. IRQs are re-enabled at a later stage when doing the unmapping on R2D via the sm501 USB coherent DMA, resulting in the irqs_disabled() check producing considerable noise for this configuration. Just kill off the check, which was blindly copied from x86 anyways. Signed-off-by: Paul Mundt --- arch/sh/include/asm/dma-mapping.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'arch/sh/include/asm') diff --git a/arch/sh/include/asm/dma-mapping.h b/arch/sh/include/asm/dma-mapping.h index 87ced133a363..bea3337a426a 100644 --- a/arch/sh/include/asm/dma-mapping.h +++ b/arch/sh/include/asm/dma-mapping.h @@ -89,8 +89,6 @@ static inline void dma_free_coherent(struct device *dev, size_t size, { struct dma_map_ops *ops = get_dma_ops(dev); - WARN_ON(irqs_disabled()); /* for portability */ - if (dma_release_from_coherent(dev, get_order(size), vaddr)) return; -- cgit v1.2.3 From d627a2ebd1a303aa4ac1962c553d1e8738735d01 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Thu, 28 Jan 2010 18:17:29 +0900 Subject: sh: Fix up the ioremap_fixed() build for nommu. arch/sh/kernel/setup.c:455: error: implicit declaration of function 'ioremap_fixed_init' Signed-off-by: Paul Mundt --- arch/sh/include/asm/io.h | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) (limited to 'arch/sh/include/asm') diff --git a/arch/sh/include/asm/io.h b/arch/sh/include/asm/io.h index 98c62fa168c2..bd5fafa23eb4 100644 --- a/arch/sh/include/asm/io.h +++ b/arch/sh/include/asm/io.h @@ -273,24 +273,6 @@ void __iomem *__ioremap_caller(unsigned long offset, unsigned long size, pgprot_t prot, void *caller); void __iounmap(void __iomem *addr); -#ifdef CONFIG_IOREMAP_FIXED -extern void __iomem *ioremap_fixed(resource_size_t, unsigned long, - unsigned long, pgprot_t); -extern int iounmap_fixed(void __iomem *); -extern void ioremap_fixed_init(void); -#else -static inline void __iomem * -ioremap_fixed(resource_size_t phys_addr, unsigned long offset, - unsigned long size, pgprot_t prot) -{ - BUG(); - return NULL; -} - -static inline void ioremap_fixed_init(void) { } -static inline int iounmap_fixed(void __iomem *addr) { return -EINVAL; } -#endif - static inline void __iomem * __ioremap(unsigned long offset, unsigned long size, pgprot_t prot) { @@ -365,6 +347,24 @@ ioremap_prot(resource_size_t offset, unsigned long size, unsigned long flags) } #endif +#ifdef CONFIG_IOREMAP_FIXED +extern void __iomem *ioremap_fixed(resource_size_t, unsigned long, + unsigned long, pgprot_t); +extern int iounmap_fixed(void __iomem *); +extern void ioremap_fixed_init(void); +#else +static inline void __iomem * +ioremap_fixed(resource_size_t phys_addr, unsigned long offset, + unsigned long size, pgprot_t prot) +{ + BUG(); + return NULL; +} + +static inline void ioremap_fixed_init(void) { } +static inline int iounmap_fixed(void __iomem *addr) { return -EINVAL; } +#endif + #define ioremap_nocache ioremap #define iounmap __iounmap -- cgit v1.2.3 From 9762528f37ddc7071509dddb10e7b4b3b957fd01 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Fri, 29 Jan 2010 16:14:29 +0900 Subject: sh: Kill off deprecated fixed PCI memory window accessors. This kills off the deprected fixed memory range accessors for the cases of non-translatable ioremapping. Signed-off-by: Paul Mundt --- arch/sh/include/asm/pci.h | 14 -------------- 1 file changed, 14 deletions(-) (limited to 'arch/sh/include/asm') diff --git a/arch/sh/include/asm/pci.h b/arch/sh/include/asm/pci.h index 67f3999b544e..f362d8a045e7 100644 --- a/arch/sh/include/asm/pci.h +++ b/arch/sh/include/asm/pci.h @@ -99,20 +99,6 @@ static inline void pci_dma_burst_advice(struct pci_dev *pdev, } #endif -#ifdef CONFIG_SUPERH32 -/* - * If we're on an SH7751 or SH7780 PCI controller, PCI memory is mapped - * at the end of the address space in a special non-translatable area. - */ -#define PCI_MEM_FIXED_START 0xfd000000 -#define PCI_MEM_FIXED_END (PCI_MEM_FIXED_START + 0x01000000) - -#define is_pci_memory_fixed_range(s, e) \ - ((s) >= PCI_MEM_FIXED_START && (e) < PCI_MEM_FIXED_END) -#else -#define is_pci_memory_fixed_range(s, e) (0) -#endif - /* Board-specific fixup routines. */ int pcibios_map_platform_irq(struct pci_dev *dev, u8 slot, u8 pin); -- cgit v1.2.3 From 320e68da59353fe6ad51b81f6865c4b674ad66ea Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Fri, 29 Jan 2010 22:38:13 +0900 Subject: sh: support PCI domains. Newer SH parts are now commonly shipping with multiple controllers, so we wire up PCI domain support to deal with them. Shamelessly cloned from the MIPS implementation. Signed-off-by: Paul Mundt --- arch/sh/include/asm/pci.h | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'arch/sh/include/asm') diff --git a/arch/sh/include/asm/pci.h b/arch/sh/include/asm/pci.h index f362d8a045e7..d124a009889f 100644 --- a/arch/sh/include/asm/pci.h +++ b/arch/sh/include/asm/pci.h @@ -15,6 +15,7 @@ */ struct pci_channel { struct pci_channel *next; + struct pci_bus *bus; struct pci_ops *pci_ops; struct resource *io_resource; @@ -24,8 +25,10 @@ struct pci_channel { unsigned long mem_offset; unsigned long reg_base; - unsigned long io_map_base; + + unsigned int index; + unsigned int need_domain_info; }; extern void register_pci_controller(struct pci_channel *hose); @@ -108,6 +111,14 @@ extern void pcibios_resource_to_bus(struct pci_dev *dev, extern void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, struct pci_bus_region *region); +#define pci_domain_nr(bus) ((struct pci_channel *)(bus)->sysdata)->index + +static inline int pci_proc_domain(struct pci_bus *bus) +{ + struct pci_channel *hose = bus->sysdata; + return hose->need_domain_info; +} + /* Chances are this interrupt is wired PC-style ... */ static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel) { -- cgit v1.2.3 From 31a090ae0693af189fc7a8ad16cece4878acad33 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Sat, 30 Jan 2010 11:29:56 +0900 Subject: sh: Fix up asm/hw_breakpoint.h header check. Presently headers_check complains about linux/kdebug.h being unexported, so just bump the __KERNEL__ ifdef up, as per the x86 change. Signed-off-by: Paul Mundt --- arch/sh/include/asm/hw_breakpoint.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'arch/sh/include/asm') diff --git a/arch/sh/include/asm/hw_breakpoint.h b/arch/sh/include/asm/hw_breakpoint.h index 7295d6290249..965dd780d51b 100644 --- a/arch/sh/include/asm/hw_breakpoint.h +++ b/arch/sh/include/asm/hw_breakpoint.h @@ -1,12 +1,12 @@ #ifndef __ASM_SH_HW_BREAKPOINT_H #define __ASM_SH_HW_BREAKPOINT_H -#include -#include - #ifdef __KERNEL__ #define __ARCH_HW_BREAKPOINT_H +#include +#include + struct arch_hw_breakpoint { char *name; /* Contains name of the symbol to set bkpt */ unsigned long address; -- cgit v1.2.3 From 85b59f5bb24aeca1a987cbb206e228bf630c8327 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 1 Feb 2010 13:01:42 +0900 Subject: sh: Enable PCI66 support for SH7780 host controller. This adds some helper glue for scanning the bus and determining if all of the devices are 66MHz capable or not before flipping on 66MHz mode. This isn't quite to spec, but it's fairly consistent with what other embedded controllers end up having to do. Scanning code cribbed from the MIPS txx9 PCI code. Signed-off-by: Paul Mundt --- arch/sh/include/asm/pci.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch/sh/include/asm') diff --git a/arch/sh/include/asm/pci.h b/arch/sh/include/asm/pci.h index d124a009889f..5849d435c441 100644 --- a/arch/sh/include/asm/pci.h +++ b/arch/sh/include/asm/pci.h @@ -32,6 +32,8 @@ struct pci_channel { }; extern void register_pci_controller(struct pci_channel *hose); +extern int pci_is_66mhz_capable(struct pci_channel *hose, + int top_bus, int current_bus); extern unsigned long PCIBIOS_MIN_IO, PCIBIOS_MIN_MEM; -- cgit v1.2.3 From bcf39352eb9e9026f7a1028d4bce3707b65f104b Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 1 Feb 2010 13:11:25 +0900 Subject: sh: Handle PCI controller resource conflicts. register_pci_controller() can fail, but presently is a void function. Change this over to an int so that we can bail early before continuing on with post-registration initialization (such as throwing the controller in to 66MHz mode in the case of the SH7780 host controller). Signed-off-by: Paul Mundt --- arch/sh/include/asm/pci.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/sh/include/asm') diff --git a/arch/sh/include/asm/pci.h b/arch/sh/include/asm/pci.h index 5849d435c441..bbd10cf79825 100644 --- a/arch/sh/include/asm/pci.h +++ b/arch/sh/include/asm/pci.h @@ -31,7 +31,7 @@ struct pci_channel { unsigned int need_domain_info; }; -extern void register_pci_controller(struct pci_channel *hose); +extern int register_pci_controller(struct pci_channel *hose); extern int pci_is_66mhz_capable(struct pci_channel *hose, int top_bus, int current_bus); -- cgit v1.2.3 From ef407beefbd9928792ccc93857e408e0057bc17b Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 1 Feb 2010 16:39:46 +0900 Subject: sh: Hook up ERR/PERR/SERR detection for SH7780 PCI host controllers. These were never handled before, so implement some common infrastructure to support them, then make use of that in the SH7780-specific code. In practice there is little here that can not be generalized for SH4 parts, which will be an incremental change as the 7780/7751 code is gradually unified. Signed-off-by: Paul Mundt --- arch/sh/include/asm/pci.h | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'arch/sh/include/asm') diff --git a/arch/sh/include/asm/pci.h b/arch/sh/include/asm/pci.h index bbd10cf79825..1de83f2161f7 100644 --- a/arch/sh/include/asm/pci.h +++ b/arch/sh/include/asm/pci.h @@ -29,9 +29,20 @@ struct pci_channel { unsigned int index; unsigned int need_domain_info; + + /* Optional error handling */ + struct timer_list err_timer, serr_timer; + unsigned int err_irq, serr_irq; }; +/* arch/sh/drivers/pci/pci.c */ extern int register_pci_controller(struct pci_channel *hose); +extern void pcibios_report_status(unsigned int status_mask, int warn); + +/* arch/sh/drivers/pci/common.c */ +extern void pcibios_enable_timers(struct pci_channel *hose); +extern unsigned int pcibios_handle_status_errors(unsigned long addr, + unsigned int status, struct pci_channel *hose); extern int pci_is_66mhz_capable(struct pci_channel *hose, int top_bus, int current_bus); -- cgit v1.2.3 From b6c58b1d987a5795086c5c2babd8c7367d2fdb8c Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 1 Feb 2010 20:01:50 +0900 Subject: sh: Improved multi-resource handling for SH7780 PCI. The SH7780 PCI controller supports 3 different ranges of PCI memory in addition to its PCI I/O window. In the case of 29-bit mode, only 2 memory windows are supported, while in 32-bit mode all 3 are visible. This attempts to make the resource handling completely dynamic and to permit platforms to map in as many apertures as they can handle. Signed-off-by: Paul Mundt --- arch/sh/include/asm/pci.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'arch/sh/include/asm') diff --git a/arch/sh/include/asm/pci.h b/arch/sh/include/asm/pci.h index 1de83f2161f7..6d762cca2312 100644 --- a/arch/sh/include/asm/pci.h +++ b/arch/sh/include/asm/pci.h @@ -18,8 +18,9 @@ struct pci_channel { struct pci_bus *bus; struct pci_ops *pci_ops; - struct resource *io_resource; - struct resource *mem_resource; + + struct resource *resources; + unsigned int nr_resources; unsigned long io_offset; unsigned long mem_offset; -- cgit v1.2.3 From 9ad62ec4f752c82b39aa5927f23d894b46ae10b9 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 3 Feb 2010 16:46:20 +0900 Subject: sh: Fix up early PCI PERR/SERR IRQ handling. This adds support for handling early PERR/SERR triggering in between controller registration and the initial bus scan. Buggy cards end up asserting these as soon as the M66EN scan is undertaken, resulting in an early crash. Signed-off-by: Paul Mundt --- arch/sh/include/asm/pci.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'arch/sh/include/asm') diff --git a/arch/sh/include/asm/pci.h b/arch/sh/include/asm/pci.h index 6d762cca2312..1042f7f0a48b 100644 --- a/arch/sh/include/asm/pci.h +++ b/arch/sh/include/asm/pci.h @@ -41,6 +41,18 @@ extern int register_pci_controller(struct pci_channel *hose); extern void pcibios_report_status(unsigned int status_mask, int warn); /* arch/sh/drivers/pci/common.c */ +extern int early_read_config_byte(struct pci_channel *hose, int top_bus, + int bus, int devfn, int offset, u8 *value); +extern int early_read_config_word(struct pci_channel *hose, int top_bus, + int bus, int devfn, int offset, u16 *value); +extern int early_read_config_dword(struct pci_channel *hose, int top_bus, + int bus, int devfn, int offset, u32 *value); +extern int early_write_config_byte(struct pci_channel *hose, int top_bus, + int bus, int devfn, int offset, u8 value); +extern int early_write_config_word(struct pci_channel *hose, int top_bus, + int bus, int devfn, int offset, u16 value); +extern int early_write_config_dword(struct pci_channel *hose, int top_bus, + int bus, int devfn, int offset, u32 value); extern void pcibios_enable_timers(struct pci_channel *hose); extern unsigned int pcibios_handle_status_errors(unsigned long addr, unsigned int status, struct pci_channel *hose); -- cgit v1.2.3 From 623b4ac4bf9e767991c66e29b47dd4b19458fb42 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Wed, 3 Feb 2010 14:44:12 +0000 Subject: sh: fix Transfer Size calculation in both DMA drivers Both the original arch/sh/drivers/dma/dma-sh.c and the new SH dmaengine drivers do not take into account bits 3:2 of the Transfer Size field in the CHCR register, besides, bit-field defines set bit 2, but the mask only passes bits 1:0 through. TS_16BLK and TS_32BLK macros are bogus too. This patch fixes all these issues for sh7722 and sh7724, other CPUs stay unchanged and might need to be fixed too. Signed-off-by: Guennadi Liakhovetski Acked-by: Dan Williams Signed-off-by: Paul Mundt --- arch/sh/include/asm/dma-sh.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/sh/include/asm') diff --git a/arch/sh/include/asm/dma-sh.h b/arch/sh/include/asm/dma-sh.h index 78eed3e0bdf5..01d2fc72551b 100644 --- a/arch/sh/include/asm/dma-sh.h +++ b/arch/sh/include/asm/dma-sh.h @@ -83,7 +83,7 @@ static int dmte_irq_map[] __maybe_unused = { * Define the default configuration for dual address memory-memory transfer. * The 0x400 value represents auto-request, external->external. */ -#define RS_DUAL (DM_INC | SM_INC | 0x400 | TS_32) +#define RS_DUAL (DM_INC | SM_INC | 0x400 | TS_INDEX2VAL(XMIT_SZ_32BIT)) /* DMA base address */ static u32 dma_base_addr[] __maybe_unused = { -- cgit v1.2.3 From cfefe99795251d76d92e8457f4152f532a961ec5 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Wed, 3 Feb 2010 14:46:41 +0000 Subject: sh: implement DMA_SLAVE capability in SH dmaengine driver Tested to work with a SIU ASoC driver on sh7722 (migor). Signed-off-by: Guennadi Liakhovetski Acked-by: Dan Williams Signed-off-by: Paul Mundt --- arch/sh/include/asm/dma-sh.h | 41 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) (limited to 'arch/sh/include/asm') diff --git a/arch/sh/include/asm/dma-sh.h b/arch/sh/include/asm/dma-sh.h index 01d2fc72551b..c8d8ce78f346 100644 --- a/arch/sh/include/asm/dma-sh.h +++ b/arch/sh/include/asm/dma-sh.h @@ -64,8 +64,10 @@ static int dmte_irq_map[] __maybe_unused = { #define ACK_L 0x00010000 #define DM_INC 0x00004000 #define DM_DEC 0x00008000 +#define DM_FIX 0x0000c000 #define SM_INC 0x00001000 #define SM_DEC 0x00002000 +#define SM_FIX 0x00003000 #define RS_IN 0x00000200 #define RS_OUT 0x00000300 #define TS_BLK 0x00000040 @@ -123,10 +125,47 @@ static u32 dma_base_addr[] __maybe_unused = { */ #define SHDMA_MIX_IRQ (1 << 1) #define SHDMA_DMAOR1 (1 << 2) -#define SHDMA_DMAE1 (1 << 3) +#define SHDMA_DMAE1 (1 << 3) + +enum sh_dmae_slave_chan_id { + SHDMA_SLAVE_SCIF0_TX, + SHDMA_SLAVE_SCIF0_RX, + SHDMA_SLAVE_SCIF1_TX, + SHDMA_SLAVE_SCIF1_RX, + SHDMA_SLAVE_SCIF2_TX, + SHDMA_SLAVE_SCIF2_RX, + SHDMA_SLAVE_SCIF3_TX, + SHDMA_SLAVE_SCIF3_RX, + SHDMA_SLAVE_SCIF4_TX, + SHDMA_SLAVE_SCIF4_RX, + SHDMA_SLAVE_SCIF5_TX, + SHDMA_SLAVE_SCIF5_RX, + SHDMA_SLAVE_SIUA_TX, + SHDMA_SLAVE_SIUA_RX, + SHDMA_SLAVE_SIUB_TX, + SHDMA_SLAVE_SIUB_RX, + SHDMA_SLAVE_NUMBER, /* Must stay last */ +}; + +struct sh_dmae_slave_config { + enum sh_dmae_slave_chan_id slave_id; + dma_addr_t addr; + u32 chcr; + char mid_rid; +}; struct sh_dmae_pdata { unsigned int mode; + struct sh_dmae_slave_config *config; + int config_num; +}; + +struct device; + +struct sh_dmae_slave { + enum sh_dmae_slave_chan_id slave_id; /* Set by the platform */ + struct device *dma_dev; /* Set by the platform */ + struct sh_dmae_slave_config *config; /* Set by the driver */ }; #endif /* __DMA_SH_H */ -- cgit v1.2.3 From 858918b77b29d0e9ce7f524d1b57d602d85f5d64 Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Sun, 7 Feb 2010 12:40:36 +0000 Subject: sh: Optimise FDE/CIE lookup by using red-black trees Now that the DWARF unwinder is being used to provide perf callstacks unwinding speed is an issue. It is no longer being used in exceptional circumstances where we don't care about runtime performance, e.g. when panicing, so it makes sense improve performance is possible. With this patch I saw a 42% improvement in unwind time when calling return_address(1). Greater improvements will be seen as the number of levels unwound increases as each unwind is now cheaper. Note that insertion time has doubled but that's just the price we pay for keeping the trees balanced. However, this is a one-time cost for kernel boot/module load and so the improvements in lookup time dominate the extra time we spend keeping the trees balanced. Signed-off-by: Matt Fleming Signed-off-by: Paul Mundt --- arch/sh/include/asm/dwarf.h | 19 +++++++------------ arch/sh/include/asm/module.h | 17 ++++++++++++++++- 2 files changed, 23 insertions(+), 13 deletions(-) (limited to 'arch/sh/include/asm') diff --git a/arch/sh/include/asm/dwarf.h b/arch/sh/include/asm/dwarf.h index bdccbbfdc0bd..d62abd1d0c05 100644 --- a/arch/sh/include/asm/dwarf.h +++ b/arch/sh/include/asm/dwarf.h @@ -243,16 +243,13 @@ struct dwarf_cie { unsigned long cie_pointer; - struct list_head link; - unsigned long flags; #define DWARF_CIE_Z_AUGMENTATION (1 << 0) - /* - * 'mod' will be non-NULL if this CIE came from a module's - * .eh_frame section. - */ - struct module *mod; + /* linked-list entry if this CIE is from a module */ + struct list_head link; + + struct rb_node node; }; /** @@ -266,13 +263,11 @@ struct dwarf_fde { unsigned long address_range; unsigned char *instructions; unsigned char *end; + + /* linked-list entry if this FDE is from a module */ struct list_head link; - /* - * 'mod' will be non-NULL if this FDE came from a module's - * .eh_frame section. - */ - struct module *mod; + struct rb_node node; }; /** diff --git a/arch/sh/include/asm/module.h b/arch/sh/include/asm/module.h index 068bf1659750..b7927de86f9f 100644 --- a/arch/sh/include/asm/module.h +++ b/arch/sh/include/asm/module.h @@ -1,7 +1,22 @@ #ifndef _ASM_SH_MODULE_H #define _ASM_SH_MODULE_H -#include +struct mod_arch_specific { +#ifdef CONFIG_DWARF_UNWINDER + struct list_head fde_list; + struct list_head cie_list; +#endif +}; + +#ifdef CONFIG_64BIT +#define Elf_Shdr Elf64_Shdr +#define Elf_Sym Elf64_Sym +#define Elf_Ehdr Elf64_Ehdr +#else +#define Elf_Shdr Elf32_Shdr +#define Elf_Sym Elf32_Sym +#define Elf_Ehdr Elf32_Ehdr +#endif #ifdef CONFIG_CPU_LITTLE_ENDIAN # ifdef CONFIG_CPU_SH2 -- cgit v1.2.3 From b0f3ae03aca0f331b851ae94bc066124e7f104df Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Fri, 12 Feb 2010 15:40:00 +0900 Subject: sh: Isolate uncached mapping support. This splits out the uncached mapping support under its own config option, presently only used by 29-bit mode and 32-bit + PMB. This will make it possible to optionally add an uncached mapping on sh64 as well as booting without an uncached mapping for 32-bit. Signed-off-by: Paul Mundt --- arch/sh/include/asm/ptrace.h | 19 +++++++++++++------ arch/sh/include/asm/system.h | 3 ++- arch/sh/include/asm/system_64.h | 1 + 3 files changed, 16 insertions(+), 7 deletions(-) (limited to 'arch/sh/include/asm') diff --git a/arch/sh/include/asm/ptrace.h b/arch/sh/include/asm/ptrace.h index 201d11ef211f..e879dffa324b 100644 --- a/arch/sh/include/asm/ptrace.h +++ b/arch/sh/include/asm/ptrace.h @@ -102,13 +102,15 @@ struct pt_dspregs { #define PTRACE_GETDSPREGS 55 /* DSP registers */ #define PTRACE_SETDSPREGS 56 -#define PT_TEXT_END_ADDR 240 -#define PT_TEXT_ADDR 244 /* &(struct user)->start_code */ -#define PT_DATA_ADDR 248 /* &(struct user)->start_data */ +#define PT_TEXT_END_ADDR 240 +#define PT_TEXT_ADDR 244 /* &(struct user)->start_code */ +#define PT_DATA_ADDR 248 /* &(struct user)->start_data */ #define PT_TEXT_LEN 252 #ifdef __KERNEL__ #include +#include +#include #define user_mode(regs) (((regs)->sr & 0x40000000)==0) #define instruction_pointer(regs) ((unsigned long)(regs)->pc) @@ -137,9 +139,14 @@ static inline unsigned long profile_pc(struct pt_regs *regs) { unsigned long pc = instruction_pointer(regs); -#ifdef P2SEG - if (pc >= P2SEG && pc < P3SEG) - pc -= 0x20000000; +#ifdef CONFIG_UNCACHED_MAPPING + /* + * If PC points in to the uncached mapping, fix it up and hand + * back the cached equivalent. + */ + if ((pc >= (memory_start + cached_to_uncached)) && + (pc < (memory_start + cached_to_uncached + uncached_size))) + pc -= cached_to_uncached; #endif return pc; diff --git a/arch/sh/include/asm/system.h b/arch/sh/include/asm/system.h index 6442f1783fe0..0bd7a17d5e1a 100644 --- a/arch/sh/include/asm/system.h +++ b/arch/sh/include/asm/system.h @@ -10,7 +10,6 @@ #include #include #include -#include #define AT_VECTOR_SIZE_ARCH 5 /* entries in ARCH_DLINFO */ @@ -114,6 +113,8 @@ static inline unsigned long __cmpxchg(volatile void * ptr, unsigned long old, (unsigned long)_n_, sizeof(*(ptr))); \ }) +struct pt_regs; + extern void die(const char *str, struct pt_regs *regs, long err) __attribute__ ((noreturn)); void free_initmem(void); void free_initrd_mem(unsigned long start, unsigned long end); diff --git a/arch/sh/include/asm/system_64.h b/arch/sh/include/asm/system_64.h index 3391bb6b21d8..36338646dfc8 100644 --- a/arch/sh/include/asm/system_64.h +++ b/arch/sh/include/asm/system_64.h @@ -18,6 +18,7 @@ /* * switch_to() should switch tasks to task nr n, first */ +struct thread_struct; struct task_struct *sh64_switch_to(struct task_struct *prev, struct thread_struct *prev_thread, struct task_struct *next, -- cgit v1.2.3 From 19f6b8b44e3f633d5d7d1ed68848b1eb89a1e800 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Fri, 12 Feb 2010 15:41:45 +0900 Subject: sh64: fix up memory offset calculation. The linker script offsets were broken by the recent 29/32-bit integration, so this fixes it up for sh64. Signed-off-by: Paul Mundt --- arch/sh/include/asm/vmlinux.lds.h | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'arch/sh/include/asm') diff --git a/arch/sh/include/asm/vmlinux.lds.h b/arch/sh/include/asm/vmlinux.lds.h index 244ec4ad9a79..d58ad493b3a6 100644 --- a/arch/sh/include/asm/vmlinux.lds.h +++ b/arch/sh/include/asm/vmlinux.lds.h @@ -14,4 +14,12 @@ #define DWARF_EH_FRAME #endif +#ifdef CONFIG_SUPERH64 +#define EXTRA_TEXT \ + *(.text64) \ + *(.text..SHmedia32) +#else +#define EXTRA_TEXT +#endif + #endif /* __ASM_SH_VMLINUX_LDS_H */ -- cgit v1.2.3 From efd54ea315f645ef318708aab5714a5f1f432d03 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 16 Feb 2010 18:39:30 +0900 Subject: sh: Merge the legacy PMB mapping and entry synchronization code. This merges the code for iterating over the legacy PMB mappings and the code for synchronizing software state with the hardware mappings. There's really no reason to do the same iteration twice, and this also buys us the legacy entry logging facility for the dynamic PMB case. Signed-off-by: Paul Mundt --- arch/sh/include/asm/mmu.h | 1 + 1 file changed, 1 insertion(+) (limited to 'arch/sh/include/asm') diff --git a/arch/sh/include/asm/mmu.h b/arch/sh/include/asm/mmu.h index ca7d91e8aa72..2fcbedb55002 100644 --- a/arch/sh/include/asm/mmu.h +++ b/arch/sh/include/asm/mmu.h @@ -25,6 +25,7 @@ #define PMB_C 0x00000008 #define PMB_WT 0x00000001 #define PMB_UB 0x00000200 +#define PMB_CACHE_MASK (PMB_C | PMB_WT | PMB_UB) #define PMB_V 0x00000100 #define PMB_NO_ENTRY (-1) -- cgit v1.2.3 From 1d5cfcdff793e2f34ec61d902fa5ee0c7e4a2208 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 16 Feb 2010 21:43:38 +0900 Subject: sh: Kill off some superfluous legacy PMB special casing. The __va()/__pa() offsets and the boot memory offsets are consistent for all PMB users, so there is no need to special case these for legacy PMB. Kill the special casing off and depend on CONFIG_PMB across the board. This also fixes up yet another addressing bug for sh64. Signed-off-by: Paul Mundt --- arch/sh/include/asm/page.h | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'arch/sh/include/asm') diff --git a/arch/sh/include/asm/page.h b/arch/sh/include/asm/page.h index 61e58105adc3..3accdc5ab122 100644 --- a/arch/sh/include/asm/page.h +++ b/arch/sh/include/asm/page.h @@ -127,12 +127,7 @@ typedef struct page *pgtable_t; * is not visible (it is part of the PMB mapping) and so needs to be * added or subtracted as required. */ -#if defined(CONFIG_PMB_LEGACY) -/* phys = virt - PAGE_OFFSET - (__MEMORY_START & 0xe0000000) */ -#define PMB_OFFSET (PAGE_OFFSET - PXSEG(__MEMORY_START)) -#define __pa(x) ((unsigned long)(x) - PMB_OFFSET) -#define __va(x) ((void *)((unsigned long)(x) + PMB_OFFSET)) -#elif defined(CONFIG_32BIT) +#ifdef CONFIG_PMB #define __pa(x) ((unsigned long)(x)-PAGE_OFFSET+__MEMORY_START) #define __va(x) ((void *)((unsigned long)(x)+PAGE_OFFSET-__MEMORY_START)) #else -- cgit v1.2.3 From 7bdda6209f224aa784a036df54b22cb338d2e859 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 17 Feb 2010 13:23:00 +0900 Subject: sh: Fix up more 64-bit pgprot truncation on SH-X2 TLB. Both the store queue API and the PMB remapping take unsigned long for their pgprot flags, which cuts off the extended protection bits. In the case of the PMB this isn't really a problem since the cache attribute bits that we care about are all in the lower 32-bits, but we do it just to be safe. The store queue remapping on the other hand depends on the extended prot bits for enabling userspace access to the mappings. Signed-off-by: Paul Mundt --- arch/sh/include/asm/mmu.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'arch/sh/include/asm') diff --git a/arch/sh/include/asm/mmu.h b/arch/sh/include/asm/mmu.h index 2fcbedb55002..151bc922701b 100644 --- a/arch/sh/include/asm/mmu.h +++ b/arch/sh/include/asm/mmu.h @@ -33,6 +33,7 @@ #ifndef __ASSEMBLY__ #include #include +#include /* Default "unsigned long" context */ typedef unsigned long mm_context_id_t[NR_CPUS]; @@ -71,13 +72,13 @@ struct pmb_entry { #ifdef CONFIG_PMB /* arch/sh/mm/pmb.c */ long pmb_remap(unsigned long virt, unsigned long phys, - unsigned long size, unsigned long flags); + unsigned long size, pgprot_t prot); void pmb_unmap(unsigned long addr); int pmb_init(void); bool __in_29bit_mode(void); #else static inline long pmb_remap(unsigned long virt, unsigned long phys, - unsigned long size, unsigned long flags) + unsigned long size, pgprot_t prot) { return -EINVAL; } -- cgit v1.2.3 From 51becfd96287b3913b13075699433730984e2f4f Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 17 Feb 2010 15:33:30 +0900 Subject: sh: PMB tidying. Some overdue cleanup of the PMB code, killing off unused functionality and duplication sprinkled about the tree. Signed-off-by: Paul Mundt --- arch/sh/include/asm/mmu.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'arch/sh/include/asm') diff --git a/arch/sh/include/asm/mmu.h b/arch/sh/include/asm/mmu.h index 151bc922701b..44c904341414 100644 --- a/arch/sh/include/asm/mmu.h +++ b/arch/sh/include/asm/mmu.h @@ -11,7 +11,9 @@ #define PMB_ADDR 0xf6100000 #define PMB_DATA 0xf7100000 -#define PMB_ENTRY_MAX 16 + +#define NR_PMB_ENTRIES 16 + #define PMB_E_MASK 0x0000000f #define PMB_E_SHIFT 8 -- cgit v1.2.3 From 9edef28653a519bf0a48250f36cce96b1736ec4e Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 17 Feb 2010 16:28:00 +0900 Subject: sh: uncached mapping helpers. This adds some helper routines for uncached mapping support. This simplifies some of the cases where we need to check the uncached mapping boundaries in addition to giving us a centralized location for building more complex manipulation on top of. Signed-off-by: Paul Mundt --- arch/sh/include/asm/page.h | 19 ++++++++++++++++++- arch/sh/include/asm/ptrace.h | 11 ++--------- 2 files changed, 20 insertions(+), 10 deletions(-) (limited to 'arch/sh/include/asm') diff --git a/arch/sh/include/asm/page.h b/arch/sh/include/asm/page.h index 3accdc5ab122..8237d9f53e56 100644 --- a/arch/sh/include/asm/page.h +++ b/arch/sh/include/asm/page.h @@ -50,13 +50,22 @@ extern unsigned long shm_align_mask; extern unsigned long max_low_pfn, min_low_pfn; extern unsigned long memory_start, memory_end; +#ifdef CONFIG_UNCACHED_MAPPING +extern unsigned long uncached_start, uncached_end; + +extern int virt_addr_uncached(unsigned long kaddr); +extern void uncached_init(void); +#else +#define virt_addr_uncached(kaddr) (0) +#define uncached_init() do { } while (0) +#endif + static inline unsigned long pages_do_alias(unsigned long addr1, unsigned long addr2) { return (addr1 ^ addr2) & shm_align_mask; } - #define clear_page(page) memset((void *)(page), 0, PAGE_SIZE) extern void copy_page(void *to, void *from); @@ -135,6 +144,14 @@ typedef struct page *pgtable_t; #define __va(x) ((void *)((unsigned long)(x)+PAGE_OFFSET)) #endif +#ifdef CONFIG_UNCACHED_MAPPING +#define UNCAC_ADDR(addr) ((addr) - PAGE_OFFSET + uncached_start) +#define CAC_ADDR(addr) ((addr) - uncached_start + PAGE_OFFSET) +#else +#define UNCAC_ADDR(addr) ((addr)) +#define CAC_ADDR(addr) ((addr)) +#endif + #define pfn_to_kaddr(pfn) __va((pfn) << PAGE_SHIFT) #define page_to_phys(page) (page_to_pfn(page) << PAGE_SHIFT) diff --git a/arch/sh/include/asm/ptrace.h b/arch/sh/include/asm/ptrace.h index e879dffa324b..e11b14ea2c43 100644 --- a/arch/sh/include/asm/ptrace.h +++ b/arch/sh/include/asm/ptrace.h @@ -139,15 +139,8 @@ static inline unsigned long profile_pc(struct pt_regs *regs) { unsigned long pc = instruction_pointer(regs); -#ifdef CONFIG_UNCACHED_MAPPING - /* - * If PC points in to the uncached mapping, fix it up and hand - * back the cached equivalent. - */ - if ((pc >= (memory_start + cached_to_uncached)) && - (pc < (memory_start + cached_to_uncached + uncached_size))) - pc -= cached_to_uncached; -#endif + if (virt_addr_uncached(pc)) + return CAC_ADDR(pc); return pc; } -- cgit v1.2.3 From d7813bc9e8e384f5a293b05c095c799d41af3668 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 17 Feb 2010 17:56:38 +0900 Subject: sh: Build PMB entry links for existing contiguous multi-page mappings. This plugs in entry sizing support for existing mappings and then builds on top of that for linking together entries that are mapping contiguous areas. This will ultimately permit us to coalesce mappings and promote head pages while reclaiming PMB slots for dynamic remapping. Signed-off-by: Paul Mundt --- arch/sh/include/asm/mmu.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/sh/include/asm') diff --git a/arch/sh/include/asm/mmu.h b/arch/sh/include/asm/mmu.h index 44c904341414..5453169bf052 100644 --- a/arch/sh/include/asm/mmu.h +++ b/arch/sh/include/asm/mmu.h @@ -59,6 +59,7 @@ struct pmb_entry { unsigned long vpn; unsigned long ppn; unsigned long flags; + unsigned long size; /* * 0 .. NR_PMB_ENTRIES for specific entry selection, or @@ -66,7 +67,6 @@ struct pmb_entry { */ int entry; - struct pmb_entry *next; /* Adjacent entry link for contiguous multi-entry mappings */ struct pmb_entry *link; }; -- cgit v1.2.3 From d53a0d33bc3a50ea0e8dd1680a2e8435770b162a Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 17 Feb 2010 21:17:02 +0900 Subject: sh: PMB locking overhaul. This implements some locking for the PMB code. A high level rwlock is added for dealing with rw accesses on the entry map while a per-entry data structure spinlock is added to deal with the PMB entry changing out from underneath us. Signed-off-by: Paul Mundt --- arch/sh/include/asm/mmu.h | 18 ------------------ 1 file changed, 18 deletions(-) (limited to 'arch/sh/include/asm') diff --git a/arch/sh/include/asm/mmu.h b/arch/sh/include/asm/mmu.h index 5453169bf052..e42c4e2a41df 100644 --- a/arch/sh/include/asm/mmu.h +++ b/arch/sh/include/asm/mmu.h @@ -53,24 +53,6 @@ typedef struct { #endif } mm_context_t; -struct pmb_entry; - -struct pmb_entry { - unsigned long vpn; - unsigned long ppn; - unsigned long flags; - unsigned long size; - - /* - * 0 .. NR_PMB_ENTRIES for specific entry selection, or - * PMB_NO_ENTRY to search for a free one - */ - int entry; - - /* Adjacent entry link for contiguous multi-entry mappings */ - struct pmb_entry *link; -}; - #ifdef CONFIG_PMB /* arch/sh/mm/pmb.c */ long pmb_remap(unsigned long virt, unsigned long phys, -- cgit v1.2.3 From b8f7918f332873a79e4c820e90e7a245ce4d3042 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Thu, 18 Feb 2010 13:23:30 +0900 Subject: sh: Provide uncached I/O helpers. There are lots of registers that can only be updated from the uncached mapping, so we add some helpers for those cases in order to make it easier to ensure that we only make the jump when it's absolutely necessary. Signed-off-by: Paul Mundt --- arch/sh/include/asm/io.h | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'arch/sh/include/asm') diff --git a/arch/sh/include/asm/io.h b/arch/sh/include/asm/io.h index bd5fafa23eb4..7dab7b23a5ec 100644 --- a/arch/sh/include/asm/io.h +++ b/arch/sh/include/asm/io.h @@ -133,6 +133,28 @@ static inline void ctrl_delay(void) __raw_readw(generic_io_base); } +#define __BUILD_UNCACHED_IO(bwlq, type) \ +static inline type read##bwlq##_uncached(unsigned long addr) \ +{ \ + type ret; \ + jump_to_uncached(); \ + ret = __raw_read##bwlq(addr); \ + back_to_cached(); \ + return ret; \ +} \ + \ +static inline void write##bwlq##_uncached(type v, unsigned long addr) \ +{ \ + jump_to_uncached(); \ + __raw_write##bwlq(v, addr); \ + back_to_cached(); \ +} + +__BUILD_UNCACHED_IO(b, u8) +__BUILD_UNCACHED_IO(w, u16) +__BUILD_UNCACHED_IO(l, u32) +__BUILD_UNCACHED_IO(q, u64) + #define __BUILD_MEMORY_STRING(bwlq, type) \ \ static inline void __raw_writes##bwlq(volatile void __iomem *mem, \ -- cgit v1.2.3 From d01447b3197c2c470a14666be2c640407bbbfec7 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Thu, 18 Feb 2010 18:13:51 +0900 Subject: sh: Merge legacy and dynamic PMB modes. This implements a bit of rework for the PMB code, which permits us to kill off the legacy PMB mode completely. Rather than trusting the boot loader to do the right thing, we do a quick verification of the PMB contents to determine whether to have the kernel setup the initial mappings or whether it needs to mangle them later on instead. If we're booting from legacy mappings, the kernel will now take control of them and make them match the kernel's initial mapping configuration. This is accomplished by breaking the initialization phase out in to multiple steps: synchronization, merging, and resizing. With the recent rework, the synchronization code establishes page links for compound mappings already, so we build on top of this for promoting mappings and reclaiming unused slots. At the same time, the changes introduced for the uncached helpers also permit us to dynamically resize the uncached mapping without any particular headaches. The smallest page size is more than sufficient for mapping all of kernel text, and as we're careful not to jump to any far off locations in the setup code the mapping can safely be resized regardless of whether we are executing from it or not. Signed-off-by: Paul Mundt --- arch/sh/include/asm/mmu.h | 12 +++--------- arch/sh/include/asm/page.h | 11 +---------- arch/sh/include/asm/uncached.h | 18 ++++++++++++++++++ 3 files changed, 22 insertions(+), 19 deletions(-) create mode 100644 arch/sh/include/asm/uncached.h (limited to 'arch/sh/include/asm') diff --git a/arch/sh/include/asm/mmu.h b/arch/sh/include/asm/mmu.h index e42c4e2a41df..15a05b615ba7 100644 --- a/arch/sh/include/asm/mmu.h +++ b/arch/sh/include/asm/mmu.h @@ -58,7 +58,7 @@ typedef struct { long pmb_remap(unsigned long virt, unsigned long phys, unsigned long size, pgprot_t prot); void pmb_unmap(unsigned long addr); -int pmb_init(void); +void pmb_init(void); bool __in_29bit_mode(void); #else static inline long pmb_remap(unsigned long virt, unsigned long phys, @@ -67,14 +67,8 @@ static inline long pmb_remap(unsigned long virt, unsigned long phys, return -EINVAL; } -static inline void pmb_unmap(unsigned long addr) -{ -} - -static inline int pmb_init(void) -{ - return -ENODEV; -} +#define pmb_unmap(addr) do { } while (0) +#define pmb_init(addr) do { } while (0) #ifdef CONFIG_29BIT #define __in_29bit_mode() (1) diff --git a/arch/sh/include/asm/page.h b/arch/sh/include/asm/page.h index 8237d9f53e56..d71feb359304 100644 --- a/arch/sh/include/asm/page.h +++ b/arch/sh/include/asm/page.h @@ -45,21 +45,12 @@ #endif #ifndef __ASSEMBLY__ +#include extern unsigned long shm_align_mask; extern unsigned long max_low_pfn, min_low_pfn; extern unsigned long memory_start, memory_end; -#ifdef CONFIG_UNCACHED_MAPPING -extern unsigned long uncached_start, uncached_end; - -extern int virt_addr_uncached(unsigned long kaddr); -extern void uncached_init(void); -#else -#define virt_addr_uncached(kaddr) (0) -#define uncached_init() do { } while (0) -#endif - static inline unsigned long pages_do_alias(unsigned long addr1, unsigned long addr2) { diff --git a/arch/sh/include/asm/uncached.h b/arch/sh/include/asm/uncached.h new file mode 100644 index 000000000000..e3419f96626a --- /dev/null +++ b/arch/sh/include/asm/uncached.h @@ -0,0 +1,18 @@ +#ifndef __ASM_SH_UNCACHED_H +#define __ASM_SH_UNCACHED_H + +#include + +#ifdef CONFIG_UNCACHED_MAPPING +extern unsigned long uncached_start, uncached_end; + +extern int virt_addr_uncached(unsigned long kaddr); +extern void uncached_init(void); +extern void uncached_resize(unsigned long size); +#else +#define virt_addr_uncached(kaddr) (0) +#define uncached_init() do { } while (0) +#define uncached_resize(size) BUG() +#endif + +#endif /* __ASM_SH_UNCACHED_H */ -- cgit v1.2.3 From 0a5f337ecd20e70e84a5cfc0f2c24d0366087026 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Fri, 19 Feb 2010 09:22:25 +0000 Subject: sh: introduce struct clk_div4_table This patch introduces struct clk_div4_table. The structure will be used to keep div4 specific data, and is with this patch replacing the struct clk_div_mult_table pointer arg used by the sh_clk_div4_register() functions. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/include/asm/clock.h | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'arch/sh/include/asm') diff --git a/arch/sh/include/asm/clock.h b/arch/sh/include/asm/clock.h index 501d0b076283..dbb5746e88f6 100644 --- a/arch/sh/include/asm/clock.h +++ b/arch/sh/include/asm/clock.h @@ -146,12 +146,16 @@ int sh_clk_mstp32_register(struct clk *clks, int nr); .flags = _flags, \ } +struct clk_div4_table { + struct clk_div_mult_table *div_mult_table; +}; + int sh_clk_div4_register(struct clk *clks, int nr, - struct clk_div_mult_table *table); + struct clk_div4_table *table); int sh_clk_div4_enable_register(struct clk *clks, int nr, - struct clk_div_mult_table *table); + struct clk_div4_table *table); int sh_clk_div4_reparent_register(struct clk *clks, int nr, - struct clk_div_mult_table *table); + struct clk_div4_table *table); #define SH_CLK_DIV6(_name, _parent, _reg, _flags) \ { \ -- cgit v1.2.3 From 7be85c6eb4462cd973e680d9dcf897a7b5b26165 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Fri, 19 Feb 2010 09:26:56 +0000 Subject: sh: add sh7724 kick callback to clk_div4_table This patch adds a ->kick() callback to clk_div4_table and ties it into sh_clk_div4_set_rate(). A sh7724 specific kick function is also added that updates the KICK bit whenever div4 clocks in FRQCRA and FRQCRB have been set. Allows us to set the VPU clock. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/include/asm/clock.h | 1 + 1 file changed, 1 insertion(+) (limited to 'arch/sh/include/asm') diff --git a/arch/sh/include/asm/clock.h b/arch/sh/include/asm/clock.h index dbb5746e88f6..11da4c5beb68 100644 --- a/arch/sh/include/asm/clock.h +++ b/arch/sh/include/asm/clock.h @@ -148,6 +148,7 @@ int sh_clk_mstp32_register(struct clk *clks, int nr); struct clk_div4_table { struct clk_div_mult_table *div_mult_table; + void (*kick)(struct clk *clk); }; int sh_clk_div4_register(struct clk *clks, int nr, -- cgit v1.2.3 From 94ea5e449ae834af058ef005d16a8ad44fcf13d6 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 23 Feb 2010 12:56:30 +0900 Subject: sh: wire up SET/GET_UNALIGN_CTL. This hooks up the SET/GET_UNALIGN_CTL knobs cribbing the bulk of it from the PPC and ia64 implementations. The thread flags happen to be the logical inverse of what the global fault mode is set to, so this works out pretty cleanly. By default the global fault mode is used, with tasks now being able to override their own settings via prctl(). Signed-off-by: Paul Mundt --- arch/sh/include/asm/processor.h | 12 ++++++++++++ arch/sh/include/asm/processor_32.h | 6 +++++- arch/sh/include/asm/processor_64.h | 5 +++++ 3 files changed, 22 insertions(+), 1 deletion(-) (limited to 'arch/sh/include/asm') diff --git a/arch/sh/include/asm/processor.h b/arch/sh/include/asm/processor.h index 87a8d1ef64e4..9605e062840f 100644 --- a/arch/sh/include/asm/processor.h +++ b/arch/sh/include/asm/processor.h @@ -107,6 +107,13 @@ extern unsigned int xstate_size; extern void free_thread_xstate(struct task_struct *); extern struct kmem_cache *task_xstate_cachep; +/* arch/sh/mm/alignment.c */ +extern int get_unalign_ctl(struct task_struct *, unsigned long addr); +extern int set_unalign_ctl(struct task_struct *, unsigned int val); + +#define GET_UNALIGN_CTL(tsk, addr) get_unalign_ctl((tsk), (addr)) +#define SET_UNALIGN_CTL(tsk, val) set_unalign_ctl((tsk), (val)) + /* arch/sh/mm/init.c */ extern unsigned int mem_init_done; @@ -114,6 +121,11 @@ extern unsigned int mem_init_done; const char *get_cpu_subtype(struct sh_cpuinfo *c); extern const struct seq_operations cpuinfo_op; +/* thread_struct flags */ +#define SH_THREAD_UAC_NOPRINT (1 << 0) +#define SH_THREAD_UAC_SIGBUS (1 << 1) +#define SH_THREAD_UAC_MASK (SH_THREAD_UAC_NOPRINT | SH_THREAD_UAC_SIGBUS) + /* processor boot mode configuration */ #define MODE_PIN0 (1 << 0) #define MODE_PIN1 (1 << 1) diff --git a/arch/sh/include/asm/processor_32.h b/arch/sh/include/asm/processor_32.h index 488f0a906a41..572b4eb09493 100644 --- a/arch/sh/include/asm/processor_32.h +++ b/arch/sh/include/asm/processor_32.h @@ -101,8 +101,11 @@ struct thread_struct { unsigned long sp; unsigned long pc; + /* Various thread flags, see SH_THREAD_xxx */ + unsigned long flags; + /* Save middle states of ptrace breakpoints */ - struct perf_event *ptrace_bps[HBP_NUM]; + struct perf_event *ptrace_bps[HBP_NUM]; #ifdef CONFIG_SH_DSP /* Dsp status information */ @@ -115,6 +118,7 @@ struct thread_struct { #define INIT_THREAD { \ .sp = sizeof(init_stack) + (long) &init_stack, \ + .flags = 0, \ } /* Forward declaration, a strange C thing */ diff --git a/arch/sh/include/asm/processor_64.h b/arch/sh/include/asm/processor_64.h index 7b1560f03d14..621bc4618c6b 100644 --- a/arch/sh/include/asm/processor_64.h +++ b/arch/sh/include/asm/processor_64.h @@ -108,6 +108,10 @@ union thread_xstate { struct thread_struct { unsigned long sp; unsigned long pc; + + /* Various thread flags, see SH_THREAD_xxx */ + unsigned long flags; + /* This stores the address of the pt_regs built during a context switch, or of the register save area built for a kernel mode exception. It is used for backtracing the stack of a sleeping task @@ -138,6 +142,7 @@ struct thread_struct { .trap_no = 0, \ .error_code = 0, \ .address = 0, \ + .flags = 0, \ } /* -- cgit v1.2.3 From 41bfb7d7a6ce3d8dd83112e65f5d97feefde818a Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Thu, 25 Feb 2010 11:03:24 +0000 Subject: sh: SH-Mobile R-standby register save/restore Add code to save/restore registers during R-standby sleep on SH-Mobile processors. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/include/asm/suspend.h | 1 + 1 file changed, 1 insertion(+) (limited to 'arch/sh/include/asm') diff --git a/arch/sh/include/asm/suspend.h b/arch/sh/include/asm/suspend.h index fe9c2a1ad047..64eb41a063e8 100644 --- a/arch/sh/include/asm/suspend.h +++ b/arch/sh/include/asm/suspend.h @@ -92,5 +92,6 @@ extern unsigned long sh_mobile_sleep_supported; #define SUSP_SH_USTANDBY (1 << 3) /* SH-Mobile U-standby mode */ #define SUSP_SH_SF (1 << 4) /* Enable self-refresh */ #define SUSP_SH_MMU (1 << 5) /* Save/restore MMU and cache */ +#define SUSP_SH_REGS (1 << 6) /* Save/restore registers */ #endif /* _ASM_SH_SUSPEND_H */ -- cgit v1.2.3