diff options
author | Stephen Rothwell <sfr@canb.auug.org.au> | 2008-06-30 15:06:36 +1000 |
---|---|---|
committer | Stephen Rothwell <sfr@canb.auug.org.au> | 2008-06-30 15:06:36 +1000 |
commit | 0a465d76e491e5a7e774b07416495a0feb9d4c92 (patch) | |
tree | 3685c183720ccab6f426e16a180b6156423a6e98 /include | |
parent | 9452ef7f839735d0dab666cf275f1115beaaf4ee (diff) | |
parent | 8cf5861fee48e37bd3288124476c33e699da64a9 (diff) |
Merge commit 'sh/master'
Diffstat (limited to 'include')
-rw-r--r-- | include/asm-sh/clock.h | 3 | ||||
-rw-r--r-- | include/asm-sh/elf.h | 53 | ||||
-rw-r--r-- | include/asm-sh/mmu.h | 4 | ||||
-rw-r--r-- | include/asm-sh/page.h | 2 | ||||
-rw-r--r-- | include/asm-sh/pgtable_32.h | 4 | ||||
-rw-r--r-- | include/asm-sh/processor.h | 1 | ||||
-rw-r--r-- | include/asm-sh/processor_32.h | 4 | ||||
-rw-r--r-- | include/asm-sh/processor_64.h | 4 | ||||
-rw-r--r-- | include/asm-sh/ptrace.h | 5 | ||||
-rw-r--r-- | include/asm-sh/se.h | 17 | ||||
-rw-r--r-- | include/asm-sh/segment.h | 30 | ||||
-rw-r--r-- | include/asm-sh/sh7763rdp.h | 54 | ||||
-rw-r--r-- | include/asm-sh/system.h | 8 | ||||
-rw-r--r-- | include/asm-sh/thread_info.h | 2 | ||||
-rw-r--r-- | include/asm-sh/timer.h | 1 | ||||
-rw-r--r-- | include/asm-sh/uaccess.h | 222 | ||||
-rw-r--r-- | include/asm-sh/uaccess_32.h | 341 | ||||
-rw-r--r-- | include/asm-sh/uaccess_64.h | 206 | ||||
-rw-r--r-- | include/linux/maple.h | 2 |
19 files changed, 441 insertions, 522 deletions
diff --git a/include/asm-sh/clock.h b/include/asm-sh/clock.h index b550a27a7042..608fda55c0ea 100644 --- a/include/asm-sh/clock.h +++ b/include/asm-sh/clock.h @@ -41,9 +41,6 @@ void arch_init_clk_ops(struct clk_ops **, int type); /* arch/sh/kernel/cpu/clock.c */ int clk_init(void); -int __clk_enable(struct clk *); -void __clk_disable(struct clk *); - void clk_recalc_rate(struct clk *); int clk_register(struct clk *); diff --git a/include/asm-sh/elf.h b/include/asm-sh/elf.h index 05092da1aa59..f01449a8d378 100644 --- a/include/asm-sh/elf.h +++ b/include/asm-sh/elf.h @@ -1,10 +1,15 @@ #ifndef __ASM_SH_ELF_H #define __ASM_SH_ELF_H +#include <linux/utsname.h> #include <asm/auxvec.h> #include <asm/ptrace.h> #include <asm/user.h> +/* ELF header e_flags defines */ +#define EF_SH_PIC 0x100 /* -fpic */ +#define EF_SH_FDPIC 0x8000 /* -mfdpic */ + /* SH (particularly SHcompact) relocation types */ #define R_SH_NONE 0 #define R_SH_DIR32 1 @@ -43,6 +48,28 @@ #define R_SH_RELATIVE 165 #define R_SH_GOTOFF 166 #define R_SH_GOTPC 167 + +/* FDPIC relocs */ +#define R_SH_GOT20 70 +#define R_SH_GOTOFF20 71 +#define R_SH_GOTFUNCDESC 72 +#define R_SH_GOTFUNCDESC20 73 +#define R_SH_GOTOFFFUNCDESC 74 +#define R_SH_GOTOFFFUNCDESC20 75 +#define R_SH_FUNCDESC 76 +#define R_SH_FUNCDESC_VALUE 77 + +#if 0 /* XXX - later .. */ +#define R_SH_GOT20 198 +#define R_SH_GOTOFF20 199 +#define R_SH_GOTFUNCDESC 200 +#define R_SH_GOTFUNCDESC20 201 +#define R_SH_GOTOFFFUNCDESC 202 +#define R_SH_GOTOFFFUNCDESC20 203 +#define R_SH_FUNCDESC 204 +#define R_SH_FUNCDESC_VALUE 205 +#endif + /* SHmedia relocs */ #define R_SH_IMM_LOW16 246 #define R_SH_IMM_LOW16_PCREL 247 @@ -77,9 +104,12 @@ typedef struct user_fpu_struct elf_fpregset_t; /* * This is used to ensure we don't load something for the wrong architecture. */ -#define elf_check_arch(x) ( (x)->e_machine == EM_SH ) +#define elf_check_arch(x) ((x)->e_machine == EM_SH) +#define elf_check_fdpic(x) ((x)->e_flags & EF_SH_FDPIC) +#define elf_check_const_displacement(x) ((x)->e_flags & EF_SH_PIC) #define USE_ELF_CORE_DUMP +#define ELF_FDPIC_CORE_EFLAGS EF_SH_FDPIC #define ELF_EXEC_PAGESIZE PAGE_SIZE /* This is the location that an ET_DYN program is loaded if exec'ed. Typical @@ -136,6 +166,27 @@ typedef struct user_fpu_struct elf_fpregset_t; _r->regs[8]=0; _r->regs[9]=0; _r->regs[10]=0; _r->regs[11]=0; \ _r->regs[12]=0; _r->regs[13]=0; _r->regs[14]=0; \ _r->sr = SR_FD; } while (0) + +#define ELF_FDPIC_PLAT_INIT(_r, _exec_map_addr, _interp_map_addr, \ + _dynamic_addr) \ +do { \ + _r->regs[0] = 0; \ + _r->regs[1] = 0; \ + _r->regs[2] = 0; \ + _r->regs[3] = 0; \ + _r->regs[4] = 0; \ + _r->regs[5] = 0; \ + _r->regs[6] = 0; \ + _r->regs[7] = 0; \ + _r->regs[8] = _exec_map_addr; \ + _r->regs[9] = _interp_map_addr; \ + _r->regs[10] = _dynamic_addr; \ + _r->regs[11] = 0; \ + _r->regs[12] = 0; \ + _r->regs[13] = 0; \ + _r->regs[14] = 0; \ + _r->sr = SR_FD; \ +} while (0) #endif #define SET_PERSONALITY(ex, ibcs2) set_personality(PER_LINUX_32BIT) diff --git a/include/asm-sh/mmu.h b/include/asm-sh/mmu.h index eb0358c097d0..fdcb93bc6d11 100644 --- a/include/asm-sh/mmu.h +++ b/include/asm-sh/mmu.h @@ -12,6 +12,10 @@ typedef struct { struct vm_list_struct *vmlist; unsigned long end_brk; #endif +#ifdef CONFIG_BINFMT_ELF_FDPIC + unsigned long exec_fdpic_loadmap; + unsigned long interp_fdpic_loadmap; +#endif } mm_context_t; /* diff --git a/include/asm-sh/page.h b/include/asm-sh/page.h index 304c30b5d947..3b305ca9a00f 100644 --- a/include/asm-sh/page.h +++ b/include/asm-sh/page.h @@ -12,6 +12,8 @@ # define PAGE_SHIFT 12 #elif defined(CONFIG_PAGE_SIZE_8KB) # define PAGE_SHIFT 13 +#elif defined(CONFIG_PAGE_SIZE_16KB) +# define PAGE_SHIFT 14 #elif defined(CONFIG_PAGE_SIZE_64KB) # define PAGE_SHIFT 16 #else diff --git a/include/asm-sh/pgtable_32.h b/include/asm-sh/pgtable_32.h index cbc731d35c25..72ea209195bd 100644 --- a/include/asm-sh/pgtable_32.h +++ b/include/asm-sh/pgtable_32.h @@ -102,7 +102,9 @@ #define _PAGE_FLAGS_HARDWARE_MASK (PHYS_ADDR_MASK & ~(_PAGE_CLEAR_FLAGS)) /* Hardware flags, page size encoding */ -#if defined(CONFIG_X2TLB) +#if !defined(CONFIG_MMU) +# define _PAGE_FLAGS_HARD 0ULL +#elif defined(CONFIG_X2TLB) # if defined(CONFIG_PAGE_SIZE_4KB) # define _PAGE_FLAGS_HARD _PAGE_EXT(_PAGE_EXT_ESZ0) # elif defined(CONFIG_PAGE_SIZE_8KB) diff --git a/include/asm-sh/processor.h b/include/asm-sh/processor.h index b7c7ce80f03e..15d9f92ca383 100644 --- a/include/asm-sh/processor.h +++ b/include/asm-sh/processor.h @@ -2,6 +2,7 @@ #define __ASM_SH_PROCESSOR_H #include <asm/cpu-features.h> +#include <asm/segment.h> #ifndef __ASSEMBLY__ /* diff --git a/include/asm-sh/processor_32.h b/include/asm-sh/processor_32.h index c09305d6a9d9..81628f144faf 100644 --- a/include/asm-sh/processor_32.h +++ b/include/asm-sh/processor_32.h @@ -113,10 +113,6 @@ struct thread_struct { union sh_fpu_union fpu; }; -typedef struct { - unsigned long seg; -} mm_segment_t; - /* Count of active tasks with UBC settings */ extern int ubc_usercnt; diff --git a/include/asm-sh/processor_64.h b/include/asm-sh/processor_64.h index 88a2edf8fa5d..fc7fc685ba27 100644 --- a/include/asm-sh/processor_64.h +++ b/include/asm-sh/processor_64.h @@ -166,10 +166,6 @@ struct thread_struct { union sh_fpu_union fpu; }; -typedef struct { - unsigned long seg; -} mm_segment_t; - #define INIT_MMAP \ { &init_mm, 0, 0, NULL, PAGE_SHARED, VM_READ | VM_WRITE | VM_EXEC, 1, NULL, NULL } diff --git a/include/asm-sh/ptrace.h b/include/asm-sh/ptrace.h index 8d6c92b3e770..a9f0c3f67f4a 100644 --- a/include/asm-sh/ptrace.h +++ b/include/asm-sh/ptrace.h @@ -87,6 +87,11 @@ struct pt_dspregs { unsigned long mod; }; +#define PTRACE_GETFDPIC 31 /* get the ELF fdpic loadmap address */ + +#define PTRACE_GETFDPIC_EXEC 0 /* [addr] request the executable loadmap */ +#define PTRACE_GETFDPIC_INTERP 1 /* [addr] request the interpreter loadmap */ + #define PTRACE_GETDSPREGS 55 #define PTRACE_SETDSPREGS 56 #endif diff --git a/include/asm-sh/se.h b/include/asm-sh/se.h index bd2596c014a9..eb23000e1bbe 100644 --- a/include/asm-sh/se.h +++ b/include/asm-sh/se.h @@ -76,6 +76,23 @@ #define IRQ_CFCARD 7 #endif +/* SH Ether support (SH7710/SH7712) */ +/* Base address */ +#define SH_ETH0_BASE 0xA7000000 +#define SH_ETH1_BASE 0xA7000400 +/* PHY ID */ +#if defined(CONFIG_CPU_SUBTYPE_SH7710) +# define PHY_ID 0x00 +#elif defined(CONFIG_CPU_SUBTYPE_SH7712) +# define PHY_ID 0x01 +#endif +/* Ether IRQ */ +#define SH_ETH0_IRQ 80 +#define SH_ETH1_IRQ 81 +#define SH_TSU_IRQ 82 + +void init_se_IRQ(void); + #define __IO_PREFIX se #include <asm/io_generic.h> diff --git a/include/asm-sh/segment.h b/include/asm-sh/segment.h index e417eab4c7d7..5e2725f4ac49 100644 --- a/include/asm-sh/segment.h +++ b/include/asm-sh/segment.h @@ -1,6 +1,34 @@ #ifndef __ASM_SH_SEGMENT_H #define __ASM_SH_SEGMENT_H -/* Only here because we have some old header files that expect it.. */ +#ifndef __ASSEMBLY__ +typedef struct { + unsigned long seg; +} mm_segment_t; + +#define MAKE_MM_SEG(s) ((mm_segment_t) { (s) }) + +/* + * The fs value determines whether argument validity checking should be + * performed or not. If get_fs() == USER_DS, checking is performed, with + * get_fs() == KERNEL_DS, checking is bypassed. + * + * For historical reasons, these macros are grossly misnamed. + */ +#define KERNEL_DS MAKE_MM_SEG(0xFFFFFFFFUL) +#ifdef CONFIG_MMU +#define USER_DS MAKE_MM_SEG(PAGE_OFFSET) +#else +#define USER_DS KERNEL_DS +#endif + +#define segment_eq(a,b) ((a).seg == (b).seg) + +#define get_ds() (KERNEL_DS) + +#define get_fs() (current_thread_info()->addr_limit) +#define set_fs(x) (current_thread_info()->addr_limit = (x)) + +#endif /* __ASSEMBLY__ */ #endif /* __ASM_SH_SEGMENT_H */ diff --git a/include/asm-sh/sh7763rdp.h b/include/asm-sh/sh7763rdp.h new file mode 100644 index 000000000000..8750cc852977 --- /dev/null +++ b/include/asm-sh/sh7763rdp.h @@ -0,0 +1,54 @@ +#ifndef __ASM_SH_SH7763RDP_H +#define __ASM_SH_SH7763RDP_H + +/* + * linux/include/asm-sh/sh7763drp.h + * + * Copyright (C) 2008 Renesas Solutions + * Copyright (C) 2008 Nobuhiro Iwamatsu <iwamatsu.nobuhiro@renesas.com> + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + */ +#include <asm/addrspace.h> + +/* clock control */ +#define MSTPCR1 0xFFC80038 + +/* PORT */ +#define PORT_PSEL0 0xFFEF0070 +#define PORT_PSEL1 0xFFEF0072 +#define PORT_PSEL2 0xFFEF0074 +#define PORT_PSEL3 0xFFEF0076 +#define PORT_PSEL4 0xFFEF0078 + +#define PORT_PACR 0xFFEF0000 +#define PORT_PCCR 0xFFEF0004 +#define PORT_PFCR 0xFFEF000A +#define PORT_PGCR 0xFFEF000C +#define PORT_PHCR 0xFFEF000E +#define PORT_PICR 0xFFEF0010 +#define PORT_PJCR 0xFFEF0012 +#define PORT_PKCR 0xFFEF0014 +#define PORT_PLCR 0xFFEF0016 +#define PORT_PMCR 0xFFEF0018 +#define PORT_PNCR 0xFFEF001A + +/* FPGA */ +#define CPLD_BOARD_ID_ERV_REG 0xB1000000 +#define CPLD_CPLD_CMD_REG 0xB1000006 + +/* + * USB SH7763RDP board can use Host only. + */ +#define USB_USBHSC 0xFFEC80f0 + +/* arch/sh/boards/renesas/sh7763rdp/irq.c */ +void init_sh7763rdp_IRQ(void); +int sh7763rdp_irq_demux(int irq); +#define __IO_PREFIX sh7763rdp +#include <asm/io_generic.h> + +#endif /* __ASM_SH_SH7763RDP_H */ diff --git a/include/asm-sh/system.h b/include/asm-sh/system.h index e65b6b822cb3..056d68cd2108 100644 --- a/include/asm-sh/system.h +++ b/include/asm-sh/system.h @@ -148,14 +148,6 @@ extern unsigned long cached_to_uncached; extern struct dentry *sh_debugfs_root; -/* XXX - * disable hlt during certain critical i/o operations - */ -#define HAVE_DISABLE_HLT -void disable_hlt(void); -void enable_hlt(void); - -void default_idle(void); void per_cpu_trap_init(void); asmlinkage void break_point_trap(void); diff --git a/include/asm-sh/thread_info.h b/include/asm-sh/thread_info.h index c50e5d35fe84..0f69b4899309 100644 --- a/include/asm-sh/thread_info.h +++ b/include/asm-sh/thread_info.h @@ -38,6 +38,8 @@ struct thread_info { #define THREAD_SIZE_ORDER (1) #elif defined(CONFIG_PAGE_SIZE_8KB) #define THREAD_SIZE_ORDER (1) +#elif defined(CONFIG_PAGE_SIZE_16KB) +#define THREAD_SIZE_ORDER (0) #elif defined(CONFIG_PAGE_SIZE_64KB) #define THREAD_SIZE_ORDER (0) #else diff --git a/include/asm-sh/timer.h b/include/asm-sh/timer.h index 701ba84c7049..327f7eb8976a 100644 --- a/include/asm-sh/timer.h +++ b/include/asm-sh/timer.h @@ -40,6 +40,5 @@ struct sys_timer *get_sys_timer(void); /* arch/sh/kernel/time.c */ void handle_timer_tick(void); extern unsigned long sh_hpt_frequency; -extern struct clocksource clocksource_sh; #endif /* __ASM_SH_TIMER_H */ diff --git a/include/asm-sh/uaccess.h b/include/asm-sh/uaccess.h index b3440c305b5d..45c2c9b2993d 100644 --- a/include/asm-sh/uaccess.h +++ b/include/asm-sh/uaccess.h @@ -1,12 +1,171 @@ #ifndef __ASM_SH_UACCESS_H #define __ASM_SH_UACCESS_H +#include <linux/errno.h> +#include <linux/sched.h> +#include <asm/segment.h> + +#define VERIFY_READ 0 +#define VERIFY_WRITE 1 + +#define __addr_ok(addr) \ + ((unsigned long __force)(addr) < current_thread_info()->addr_limit.seg) + +/* + * __access_ok: Check if address with size is OK or not. + * + * Uhhuh, this needs 33-bit arithmetic. We have a carry.. + * + * sum := addr + size; carry? --> flag = true; + * if (sum >= addr_limit) flag = true; + */ +#define __access_ok(addr, size) \ + (__addr_ok((addr) + (size))) +#define access_ok(type, addr, size) \ + (__chk_user_ptr(addr), \ + __access_ok((unsigned long __force)(addr), (size))) + +/* + * Uh, these should become the main single-value transfer routines ... + * They automatically use the right size if we just have the right + * pointer type ... + * + * As SuperH uses the same address space for kernel and user data, we + * can just do these as direct assignments. + * + * Careful to not + * (a) re-use the arguments for side effects (sizeof is ok) + * (b) require any knowledge of processes at this stage + */ +#define put_user(x,ptr) __put_user_check((x), (ptr), sizeof(*(ptr))) +#define get_user(x,ptr) __get_user_check((x), (ptr), sizeof(*(ptr))) + +/* + * The "__xxx" versions do not do address space checking, useful when + * doing multiple accesses to the same area (the user has to do the + * checks by hand with "access_ok()") + */ +#define __put_user(x,ptr) __put_user_nocheck((x), (ptr), sizeof(*(ptr))) +#define __get_user(x,ptr) __get_user_nocheck((x), (ptr), sizeof(*(ptr))) + +struct __large_struct { unsigned long buf[100]; }; +#define __m(x) (*(struct __large_struct __user *)(x)) + +#define __get_user_nocheck(x,ptr,size) \ +({ \ + long __gu_err; \ + unsigned long __gu_val; \ + const __typeof__(*(ptr)) __user *__gu_addr = (ptr); \ + __chk_user_ptr(ptr); \ + __get_user_size(__gu_val, __gu_addr, (size), __gu_err); \ + (x) = (__typeof__(*(ptr)))__gu_val; \ + __gu_err; \ +}) + +#define __get_user_check(x,ptr,size) \ +({ \ + long __gu_err = -EFAULT; \ + unsigned long __gu_val = 0; \ + const __typeof__(*(ptr)) *__gu_addr = (ptr); \ + if (likely(access_ok(VERIFY_READ, __gu_addr, (size)))) \ + __get_user_size(__gu_val, __gu_addr, (size), __gu_err); \ + (x) = (__typeof__(*(ptr)))__gu_val; \ + __gu_err; \ +}) + +#define __put_user_nocheck(x,ptr,size) \ +({ \ + long __pu_err; \ + __typeof__(*(ptr)) __user *__pu_addr = (ptr); \ + __chk_user_ptr(ptr); \ + __put_user_size((x), __pu_addr, (size), __pu_err); \ + __pu_err; \ +}) + +#define __put_user_check(x,ptr,size) \ +({ \ + long __pu_err = -EFAULT; \ + __typeof__(*(ptr)) __user *__pu_addr = (ptr); \ + if (likely(access_ok(VERIFY_WRITE, __pu_addr, size))) \ + __put_user_size((x), __pu_addr, (size), \ + __pu_err); \ + __pu_err; \ +}) + #ifdef CONFIG_SUPERH32 # include "uaccess_32.h" #else # include "uaccess_64.h" #endif +/* Generic arbitrary sized copy. */ +/* Return the number of bytes NOT copied */ +__kernel_size_t __copy_user(void *to, const void *from, __kernel_size_t n); + +static __always_inline unsigned long +__copy_from_user(void *to, const void __user *from, unsigned long n) +{ + return __copy_user(to, (__force void *)from, n); +} + +static __always_inline unsigned long __must_check +__copy_to_user(void __user *to, const void *from, unsigned long n) +{ + return __copy_user((__force void *)to, from, n); +} + +#define __copy_to_user_inatomic __copy_to_user +#define __copy_from_user_inatomic __copy_from_user + +/* + * Clear the area and return remaining number of bytes + * (on failure. Usually it's 0.) + */ +__kernel_size_t __clear_user(void *addr, __kernel_size_t size); + +#define clear_user(addr,n) \ +({ \ + void __user * __cl_addr = (addr); \ + unsigned long __cl_size = (n); \ + \ + if (__cl_size && access_ok(VERIFY_WRITE, \ + ((unsigned long)(__cl_addr)), __cl_size)) \ + __cl_size = __clear_user(__cl_addr, __cl_size); \ + \ + __cl_size; \ +}) + +/** + * strncpy_from_user: - Copy a NUL terminated string from userspace. + * @dst: Destination address, in kernel space. This buffer must be at + * least @count bytes long. + * @src: Source address, in user space. + * @count: Maximum number of bytes to copy, including the trailing NUL. + * + * Copies a NUL-terminated string from userspace to kernel space. + * + * On success, returns the length of the string (not including the trailing + * NUL). + * + * If access to userspace fails, returns -EFAULT (some data may have been + * copied). + * + * If @count is smaller than the length of the string, copies @count bytes + * and returns @count. + */ +#define strncpy_from_user(dest,src,count) \ +({ \ + unsigned long __sfu_src = (unsigned long)(src); \ + int __sfu_count = (int)(count); \ + long __sfu_res = -EFAULT; \ + \ + if (__access_ok(__sfu_src, __sfu_count)) \ + __sfu_res = __strncpy_from_user((unsigned long)(dest), \ + __sfu_src, __sfu_count); \ + \ + __sfu_res; \ +}) + static inline unsigned long copy_from_user(void *to, const void __user *from, unsigned long n) { @@ -31,4 +190,67 @@ copy_to_user(void __user *to, const void *from, unsigned long n) return __copy_size; } +/** + * strnlen_user: - Get the size of a string in user space. + * @s: The string to measure. + * @n: The maximum valid length + * + * Context: User context only. This function may sleep. + * + * Get the size of a NUL-terminated string in user space. + * + * Returns the size of the string INCLUDING the terminating NUL. + * On exception, returns 0. + * If the string is too long, returns a value greater than @n. + */ +static inline long strnlen_user(const char __user *s, long n) +{ + if (!__addr_ok(s)) + return 0; + else + return __strnlen_user(s, n); +} + +/** + * strlen_user: - Get the size of a string in user space. + * @str: The string to measure. + * + * Context: User context only. This function may sleep. + * + * Get the size of a NUL-terminated string in user space. + * + * Returns the size of the string INCLUDING the terminating NUL. + * On exception, returns 0. + * + * If there is a limit on the length of a valid string, you may wish to + * consider using strnlen_user() instead. + */ +#define strlen_user(str) strnlen_user(str, ~0UL >> 1) + +/* + * The exception table consists of pairs of addresses: the first is the + * address of an instruction that is allowed to fault, and the second is + * the address at which the program should continue. No registers are + * modified, so it is entirely up to the continuation code to figure out + * what to do. + * + * All the routines below use bits of fixup code that are out of line + * with the main instruction path. This means when everything is well, + * we don't even have to jump over them. Further, they do not intrude + * on our cache or tlb entries. + */ +struct exception_table_entry { + unsigned long insn, fixup; +}; + +#if defined(CONFIG_SUPERH64) && defined(CONFIG_MMU) +#define ARCH_HAS_SEARCH_EXTABLE +#endif + +int fixup_exception(struct pt_regs *regs); +/* Returns 0 if exception not found and fixup.unit otherwise. */ +unsigned long search_exception_table(unsigned long addr); +const struct exception_table_entry *search_exception_tables(unsigned long addr); + + #endif /* __ASM_SH_UACCESS_H */ diff --git a/include/asm-sh/uaccess_32.h b/include/asm-sh/uaccess_32.h index 1e41fda74bd3..ae0d24f6653f 100644 --- a/include/asm-sh/uaccess_32.h +++ b/include/asm-sh/uaccess_32.h @@ -1,9 +1,8 @@ -/* $Id: uaccess.h,v 1.11 2003/10/13 07:21:20 lethal Exp $ - * +/* * User space memory access functions * * Copyright (C) 1999, 2002 Niibe Yutaka - * Copyright (C) 2003 Paul Mundt + * Copyright (C) 2003 - 2008 Paul Mundt * * Based on: * MIPS implementation version 1.15 by @@ -13,115 +12,6 @@ #ifndef __ASM_SH_UACCESS_32_H #define __ASM_SH_UACCESS_32_H -#include <linux/errno.h> -#include <linux/sched.h> - -#define VERIFY_READ 0 -#define VERIFY_WRITE 1 - -/* - * The fs value determines whether argument validity checking should be - * performed or not. If get_fs() == USER_DS, checking is performed, with - * get_fs() == KERNEL_DS, checking is bypassed. - * - * For historical reasons (Data Segment Register?), these macros are misnamed. - */ - -#define MAKE_MM_SEG(s) ((mm_segment_t) { (s) }) - -#define KERNEL_DS MAKE_MM_SEG(0xFFFFFFFFUL) -#define USER_DS MAKE_MM_SEG(PAGE_OFFSET) - -#define segment_eq(a,b) ((a).seg == (b).seg) - -#define get_ds() (KERNEL_DS) - -#if !defined(CONFIG_MMU) -/* NOMMU is always true */ -#define __addr_ok(addr) (1) - -static inline mm_segment_t get_fs(void) -{ - return USER_DS; -} - -static inline void set_fs(mm_segment_t s) -{ -} - -/* - * __access_ok: Check if address with size is OK or not. - * - * If we don't have an MMU (or if its disabled) the only thing we really have - * to look out for is if the address resides somewhere outside of what - * available RAM we have. - */ -static inline int __access_ok(unsigned long addr, unsigned long size) -{ - return 1; -} -#else /* CONFIG_MMU */ -#define __addr_ok(addr) \ - ((unsigned long)(addr) < (current_thread_info()->addr_limit.seg)) - -#define get_fs() (current_thread_info()->addr_limit) -#define set_fs(x) (current_thread_info()->addr_limit = (x)) - -/* - * __access_ok: Check if address with size is OK or not. - * - * Uhhuh, this needs 33-bit arithmetic. We have a carry.. - * - * sum := addr + size; carry? --> flag = true; - * if (sum >= addr_limit) flag = true; - */ -static inline int __access_ok(unsigned long addr, unsigned long size) -{ - unsigned long flag, sum; - - __asm__("clrt\n\t" - "addc %3, %1\n\t" - "movt %0\n\t" - "cmp/hi %4, %1\n\t" - "rotcl %0" - :"=&r" (flag), "=r" (sum) - :"1" (addr), "r" (size), - "r" (current_thread_info()->addr_limit.seg) - :"t"); - return flag == 0; -} -#endif /* CONFIG_MMU */ - -#define access_ok(type, addr, size) \ - (__chk_user_ptr(addr), \ - __access_ok((unsigned long __force)(addr), (size))) - -/* - * Uh, these should become the main single-value transfer routines ... - * They automatically use the right size if we just have the right - * pointer type ... - * - * As SuperH uses the same address space for kernel and user data, we - * can just do these as direct assignments. - * - * Careful to not - * (a) re-use the arguments for side effects (sizeof is ok) - * (b) require any knowledge of processes at this stage - */ -#define put_user(x,ptr) __put_user_check((x), (ptr), sizeof(*(ptr))) -#define get_user(x,ptr) __get_user_check((x), (ptr), sizeof(*(ptr))) - -/* - * The "__xxx" versions do not do address space checking, useful when - * doing multiple accesses to the same area (the user has to do the - * checks by hand with "access_ok()") - */ -#define __put_user(x,ptr) __put_user_nocheck((x), (ptr), sizeof(*(ptr))) -#define __get_user(x,ptr) __get_user_nocheck((x), (ptr), sizeof(*(ptr))) - -struct __large_struct { unsigned long buf[100]; }; -#define __m(x) (*(struct __large_struct __user *)(x)) - #define __get_user_size(x,ptr,size,retval) \ do { \ retval = 0; \ @@ -141,28 +31,7 @@ do { \ } \ } while (0) -#define __get_user_nocheck(x,ptr,size) \ -({ \ - long __gu_err; \ - unsigned long __gu_val; \ - const __typeof__(*(ptr)) __user *__gu_addr = (ptr); \ - __chk_user_ptr(ptr); \ - __get_user_size(__gu_val, __gu_addr, (size), __gu_err); \ - (x) = (__typeof__(*(ptr)))__gu_val; \ - __gu_err; \ -}) - -#define __get_user_check(x,ptr,size) \ -({ \ - long __gu_err = -EFAULT; \ - unsigned long __gu_val = 0; \ - const __typeof__(*(ptr)) *__gu_addr = (ptr); \ - if (likely(access_ok(VERIFY_READ, __gu_addr, (size)))) \ - __get_user_size(__gu_val, __gu_addr, (size), __gu_err); \ - (x) = (__typeof__(*(ptr)))__gu_val; \ - __gu_err; \ -}) - +#ifdef CONFIG_MMU #define __get_user_asm(x, addr, err, insn) \ ({ \ __asm__ __volatile__( \ @@ -183,6 +52,16 @@ __asm__ __volatile__( \ ".previous" \ :"=&r" (err), "=&r" (x) \ :"m" (__m(addr)), "i" (-EFAULT), "0" (err)); }) +#else +#define __get_user_asm(x, addr, err, insn) \ +do { \ + __asm__ __volatile__ ( \ + "mov." insn " %1, %0\n\t" \ + : "=&r" (x) \ + : "m" (__m(addr)) \ + ); \ +} while (0) +#endif /* CONFIG_MMU */ extern void __get_user_unknown(void); @@ -207,45 +86,41 @@ do { \ } \ } while (0) -#define __put_user_nocheck(x,ptr,size) \ -({ \ - long __pu_err; \ - __typeof__(*(ptr)) __user *__pu_addr = (ptr); \ - __chk_user_ptr(ptr); \ - __put_user_size((x), __pu_addr, (size), __pu_err); \ - __pu_err; \ -}) - -#define __put_user_check(x,ptr,size) \ -({ \ - long __pu_err = -EFAULT; \ - __typeof__(*(ptr)) __user *__pu_addr = (ptr); \ - if (likely(access_ok(VERIFY_WRITE, __pu_addr, size))) \ - __put_user_size((x), __pu_addr, (size), \ - __pu_err); \ - __pu_err; \ -}) - -#define __put_user_asm(x, addr, err, insn) \ -({ \ -__asm__ __volatile__( \ - "1:\n\t" \ - "mov." insn " %1, %2\n\t" \ - "2:\n" \ - ".section .fixup,\"ax\"\n" \ - "3:\n\t" \ - "mov.l 4f, %0\n\t" \ - "jmp @%0\n\t" \ - " mov %3, %0\n\t" \ - ".balign 4\n" \ - "4: .long 2b\n\t" \ - ".previous\n" \ - ".section __ex_table,\"a\"\n\t" \ - ".long 1b, 3b\n\t" \ - ".previous" \ - :"=&r" (err) \ - :"r" (x), "m" (__m(addr)), "i" (-EFAULT), "0" (err) \ - :"memory"); }) +#ifdef CONFIG_MMU +#define __put_user_asm(x, addr, err, insn) \ +do { \ + __asm__ __volatile__ ( \ + "1:\n\t" \ + "mov." insn " %1, %2\n\t" \ + "2:\n" \ + ".section .fixup,\"ax\"\n" \ + "3:\n\t" \ + "mov.l 4f, %0\n\t" \ + "jmp @%0\n\t" \ + " mov %3, %0\n\t" \ + ".balign 4\n" \ + "4: .long 2b\n\t" \ + ".previous\n" \ + ".section __ex_table,\"a\"\n\t" \ + ".long 1b, 3b\n\t" \ + ".previous" \ + : "=&r" (err) \ + : "r" (x), "m" (__m(addr)), "i" (-EFAULT), \ + "0" (err) \ + : "memory" \ + ); \ +} while (0) +#else +#define __put_user_asm(x, addr, err, insn) \ +do { \ + __asm__ __volatile__ ( \ + "mov." insn " %0, %1\n\t" \ + : /* no outputs */ \ + : "r" (x), "m" (__m(addr)) \ + : "memory" \ + ); \ +} while (0) +#endif /* CONFIG_MMU */ #if defined(CONFIG_CPU_LITTLE_ENDIAN) #define __put_user_u64(val,addr,retval) \ @@ -295,40 +170,7 @@ __asm__ __volatile__( \ extern void __put_user_unknown(void); -/* Generic arbitrary sized copy. */ -/* Return the number of bytes NOT copied */ -__kernel_size_t __copy_user(void *to, const void *from, __kernel_size_t n); - - -static __always_inline unsigned long -__copy_from_user(void *to, const void __user *from, unsigned long n) -{ - return __copy_user(to, (__force void *)from, n); -} - -static __always_inline unsigned long __must_check -__copy_to_user(void __user *to, const void *from, unsigned long n) -{ - return __copy_user((__force void *)to, from, n); -} - -#define __copy_to_user_inatomic __copy_to_user -#define __copy_from_user_inatomic __copy_from_user - -/* - * Clear the area and return remaining number of bytes - * (on failure. Usually it's 0.) - */ -extern __kernel_size_t __clear_user(void *addr, __kernel_size_t size); - -#define clear_user(addr,n) ({ \ -void * __cl_addr = (addr); \ -unsigned long __cl_size = (n); \ -if (__cl_size && __access_ok(((unsigned long)(__cl_addr)), __cl_size)) \ -__cl_size = __clear_user(__cl_addr, __cl_size); \ -__cl_size; }) - -static __inline__ int +static inline int __strncpy_from_user(unsigned long __dest, unsigned long __user __src, int __count) { __kernel_size_t res; @@ -367,37 +209,11 @@ __strncpy_from_user(unsigned long __dest, unsigned long __user __src, int __coun return res; } -/** - * strncpy_from_user: - Copy a NUL terminated string from userspace. - * @dst: Destination address, in kernel space. This buffer must be at - * least @count bytes long. - * @src: Source address, in user space. - * @count: Maximum number of bytes to copy, including the trailing NUL. - * - * Copies a NUL-terminated string from userspace to kernel space. - * - * On success, returns the length of the string (not including the trailing - * NUL). - * - * If access to userspace fails, returns -EFAULT (some data may have been - * copied). - * - * If @count is smaller than the length of the string, copies @count bytes - * and returns @count. - */ -#define strncpy_from_user(dest,src,count) ({ \ -unsigned long __sfu_src = (unsigned long) (src); \ -int __sfu_count = (int) (count); \ -long __sfu_res = -EFAULT; \ -if(__access_ok(__sfu_src, __sfu_count)) { \ -__sfu_res = __strncpy_from_user((unsigned long) (dest), __sfu_src, __sfu_count); \ -} __sfu_res; }) - /* * Return the size of a string (including the ending 0 even when we have * exceeded the maximum string length). */ -static __inline__ long __strnlen_user(const char __user *__s, long __n) +static inline long __strnlen_user(const char __user *__s, long __n) { unsigned long res; unsigned long __dummy; @@ -429,61 +245,4 @@ static __inline__ long __strnlen_user(const char __user *__s, long __n) return res; } -/** - * strnlen_user: - Get the size of a string in user space. - * @s: The string to measure. - * @n: The maximum valid length - * - * Context: User context only. This function may sleep. - * - * Get the size of a NUL-terminated string in user space. - * - * Returns the size of the string INCLUDING the terminating NUL. - * On exception, returns 0. - * If the string is too long, returns a value greater than @n. - */ -static __inline__ long strnlen_user(const char __user *s, long n) -{ - if (!__addr_ok(s)) - return 0; - else - return __strnlen_user(s, n); -} - -/** - * strlen_user: - Get the size of a string in user space. - * @str: The string to measure. - * - * Context: User context only. This function may sleep. - * - * Get the size of a NUL-terminated string in user space. - * - * Returns the size of the string INCLUDING the terminating NUL. - * On exception, returns 0. - * - * If there is a limit on the length of a valid string, you may wish to - * consider using strnlen_user() instead. - */ -#define strlen_user(str) strnlen_user(str, ~0UL >> 1) - -/* - * The exception table consists of pairs of addresses: the first is the - * address of an instruction that is allowed to fault, and the second is - * the address at which the program should continue. No registers are - * modified, so it is entirely up to the continuation code to figure out - * what to do. - * - * All the routines below use bits of fixup code that are out of line - * with the main instruction path. This means when everything is well, - * we don't even have to jump over them. Further, they do not intrude - * on our cache or tlb entries. - */ - -struct exception_table_entry -{ - unsigned long insn, fixup; -}; - -extern int fixup_exception(struct pt_regs *regs); - #endif /* __ASM_SH_UACCESS_32_H */ diff --git a/include/asm-sh/uaccess_64.h b/include/asm-sh/uaccess_64.h index a9b68d094844..81b3d515fcb3 100644 --- a/include/asm-sh/uaccess_64.h +++ b/include/asm-sh/uaccess_64.h @@ -20,87 +20,6 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. */ -#include <linux/errno.h> -#include <linux/sched.h> - -#define VERIFY_READ 0 -#define VERIFY_WRITE 1 - -/* - * The fs value determines whether argument validity checking should be - * performed or not. If get_fs() == USER_DS, checking is performed, with - * get_fs() == KERNEL_DS, checking is bypassed. - * - * For historical reasons (Data Segment Register?), these macros are misnamed. - */ - -#define MAKE_MM_SEG(s) ((mm_segment_t) { (s) }) - -#define KERNEL_DS MAKE_MM_SEG(0xFFFFFFFF) -#define USER_DS MAKE_MM_SEG(0x80000000) - -#define get_ds() (KERNEL_DS) -#define get_fs() (current_thread_info()->addr_limit) -#define set_fs(x) (current_thread_info()->addr_limit=(x)) - -#define segment_eq(a,b) ((a).seg == (b).seg) - -#define __addr_ok(addr) ((unsigned long)(addr) < (current_thread_info()->addr_limit.seg)) - -/* - * Uhhuh, this needs 33-bit arithmetic. We have a carry.. - * - * sum := addr + size; carry? --> flag = true; - * if (sum >= addr_limit) flag = true; - */ -#define __range_ok(addr,size) (((unsigned long) (addr) + (size) < (current_thread_info()->addr_limit.seg)) ? 0 : 1) - -#define access_ok(type,addr,size) (__range_ok(addr,size) == 0) -#define __access_ok(addr,size) (__range_ok(addr,size) == 0) - -/* - * Uh, these should become the main single-value transfer routines ... - * They automatically use the right size if we just have the right - * pointer type ... - * - * As MIPS uses the same address space for kernel and user data, we - * can just do these as direct assignments. - * - * Careful to not - * (a) re-use the arguments for side effects (sizeof is ok) - * (b) require any knowledge of processes at this stage - */ -#define put_user(x,ptr) __put_user_check((x),(ptr),sizeof(*(ptr))) -#define get_user(x,ptr) __get_user_check((x),(ptr),sizeof(*(ptr))) - -/* - * The "__xxx" versions do not do address space checking, useful when - * doing multiple accesses to the same area (the user has to do the - * checks by hand with "access_ok()") - */ -#define __put_user(x,ptr) __put_user_nocheck((x),(ptr),sizeof(*(ptr))) -#define __get_user(x,ptr) __get_user_nocheck((x),(ptr),sizeof(*(ptr))) - -/* - * The "xxx_ret" versions return constant specified in third argument, if - * something bad happens. These macros can be optimized for the - * case of just returning from the function xxx_ret is used. - */ - -#define put_user_ret(x,ptr,ret) ({ \ -if (put_user(x,ptr)) return ret; }) - -#define get_user_ret(x,ptr,ret) ({ \ -if (get_user(x,ptr)) return ret; }) - -#define __put_user_ret(x,ptr,ret) ({ \ -if (__put_user(x,ptr)) return ret; }) - -#define __get_user_ret(x,ptr,ret) ({ \ -if (__get_user(x,ptr)) return ret; }) - -struct __large_struct { unsigned long buf[100]; }; -#define __m(x) (*(struct __large_struct *)(x)) #define __get_user_size(x,ptr,size,retval) \ do { \ @@ -124,26 +43,6 @@ do { \ } \ } while (0) -#define __get_user_nocheck(x,ptr,size) \ -({ \ - long __gu_err, __gu_val; \ - __get_user_size((void *)&__gu_val, (long)(ptr), \ - (size), __gu_err); \ - (x) = (__typeof__(*(ptr)))__gu_val; \ - __gu_err; \ -}) - -#define __get_user_check(x,ptr,size) \ -({ \ - long __gu_addr = (long)(ptr); \ - long __gu_err = -EFAULT, __gu_val; \ - if (__access_ok(__gu_addr, (size))) \ - __get_user_size((void *)&__gu_val, __gu_addr, \ - (size), __gu_err); \ - (x) = (__typeof__(*(ptr))) __gu_val; \ - __gu_err; \ -}) - extern long __get_user_asm_b(void *, long); extern long __get_user_asm_w(void *, long); extern long __get_user_asm_l(void *, long); @@ -171,115 +70,10 @@ do { \ } \ } while (0) -#define __put_user_nocheck(x,ptr,size) \ -({ \ - long __pu_err; \ - __typeof__(*(ptr)) __pu_val = (x); \ - __put_user_size((void *)&__pu_val, (long)(ptr), (size), __pu_err); \ - __pu_err; \ -}) - -#define __put_user_check(x,ptr,size) \ -({ \ - long __pu_err = -EFAULT; \ - long __pu_addr = (long)(ptr); \ - __typeof__(*(ptr)) __pu_val = (x); \ - \ - if (__access_ok(__pu_addr, (size))) \ - __put_user_size((void *)&__pu_val, __pu_addr, (size), __pu_err);\ - __pu_err; \ -}) - extern long __put_user_asm_b(void *, long); extern long __put_user_asm_w(void *, long); extern long __put_user_asm_l(void *, long); extern long __put_user_asm_q(void *, long); extern void __put_user_unknown(void); - -/* Generic arbitrary sized copy. */ -/* Return the number of bytes NOT copied */ -/* XXX: should be such that: 4byte and the rest. */ -extern __kernel_size_t __copy_user(void *__to, const void *__from, __kernel_size_t __n); - -#define copy_to_user_ret(to,from,n,retval) ({ \ -if (copy_to_user(to,from,n)) \ - return retval; \ -}) - -#define __copy_to_user(to,from,n) \ - __copy_user((void *)(to), \ - (void *)(from), n) - -#define __copy_to_user_ret(to,from,n,retval) ({ \ -if (__copy_to_user(to,from,n)) \ - return retval; \ -}) - -#define copy_from_user_ret(to,from,n,retval) ({ \ -if (copy_from_user(to,from,n)) \ - return retval; \ -}) - -#define __copy_from_user(to,from,n) \ - __copy_user((void *)(to), \ - (void *)(from), n) - -#define __copy_from_user_ret(to,from,n,retval) ({ \ -if (__copy_from_user(to,from,n)) \ - return retval; \ -}) - -#define __copy_to_user_inatomic __copy_to_user -#define __copy_from_user_inatomic __copy_from_user - -/* XXX: Not sure it works well.. - should be such that: 4byte clear and the rest. */ -extern __kernel_size_t __clear_user(void *addr, __kernel_size_t size); - -#define clear_user(addr,n) ({ \ -void * __cl_addr = (addr); \ -unsigned long __cl_size = (n); \ -if (__cl_size && __access_ok(((unsigned long)(__cl_addr)), __cl_size)) \ -__cl_size = __clear_user(__cl_addr, __cl_size); \ -__cl_size; }) - -extern int __strncpy_from_user(unsigned long __dest, unsigned long __src, int __count); - -#define strncpy_from_user(dest,src,count) ({ \ -unsigned long __sfu_src = (unsigned long) (src); \ -int __sfu_count = (int) (count); \ -long __sfu_res = -EFAULT; \ -if(__access_ok(__sfu_src, __sfu_count)) { \ -__sfu_res = __strncpy_from_user((unsigned long) (dest), __sfu_src, __sfu_count); \ -} __sfu_res; }) - -#define strlen_user(str) strnlen_user(str, ~0UL >> 1) - -/* - * Return the size of a string (including the ending 0!) - */ -extern long __strnlen_user(const char *__s, long __n); - -static inline long strnlen_user(const char *s, long n) -{ - if (!__addr_ok(s)) - return 0; - else - return __strnlen_user(s, n); -} - -struct exception_table_entry -{ - unsigned long insn, fixup; -}; - -#ifdef CONFIG_MMU -#define ARCH_HAS_SEARCH_EXTABLE -#endif - -/* Returns 0 if exception not found and fixup.unit otherwise. */ -extern unsigned long search_exception_table(unsigned long addr); -extern const struct exception_table_entry *search_exception_tables (unsigned long addr); - #endif /* __ASM_SH_UACCESS_64_H */ diff --git a/include/linux/maple.h b/include/linux/maple.h index d31e36ebb436..523a286bb477 100644 --- a/include/linux/maple.h +++ b/include/linux/maple.h @@ -61,8 +61,6 @@ struct maple_device { struct maple_driver { unsigned long function; - int (*connect) (struct maple_device * dev); - void (*disconnect) (struct maple_device * dev); struct device_driver drv; }; |