diff options
Diffstat (limited to 'include/asm-sh')
109 files changed, 5966 insertions, 3176 deletions
diff --git a/include/asm-sh/Kbuild b/include/asm-sh/Kbuild index 76a8ccf254a..43910cdf78a 100644 --- a/include/asm-sh/Kbuild +++ b/include/asm-sh/Kbuild @@ -1,3 +1,8 @@ include include/asm-generic/Kbuild.asm header-y += cpu-features.h + +unifdef-y += unistd_32.h +unifdef-y += unistd_64.h +unifdef-y += posix_types_32.h +unifdef-y += posix_types_64.h diff --git a/include/asm-sh/addrspace.h b/include/asm-sh/addrspace.h index b860218e402..fa544fc38c2 100644 --- a/include/asm-sh/addrspace.h +++ b/include/asm-sh/addrspace.h @@ -9,24 +9,21 @@ */ #ifndef __ASM_SH_ADDRSPACE_H #define __ASM_SH_ADDRSPACE_H + #ifdef __KERNEL__ #include <asm/cpu/addrspace.h> -/* Memory segments (32bit Privileged mode addresses) */ -#ifndef CONFIG_CPU_SH2A -#define P0SEG 0x00000000 -#define P1SEG 0x80000000 -#define P2SEG 0xa0000000 -#define P3SEG 0xc0000000 -#define P4SEG 0xe0000000 -#else -#define P0SEG 0x00000000 -#define P1SEG 0x00000000 -#define P2SEG 0x20000000 -#define P3SEG 0x00000000 -#define P4SEG 0x80000000 -#endif +/* If this CPU supports segmentation, hook up the helpers */ +#ifdef P1SEG + +/* + [ P0/U0 (virtual) ] 0x00000000 <------ User space + [ P1 (fixed) cached ] 0x80000000 <------ Kernel space + [ P2 (fixed) non-cachable] 0xA0000000 <------ Physical access + [ P3 (virtual) cached] 0xC0000000 <------ vmalloced area + [ P4 control ] 0xE0000000 + */ /* Returns the privileged segment base of a given address */ #define PXSEG(a) (((unsigned long)(a)) & 0xe0000000) @@ -34,13 +31,23 @@ /* Returns the physical address of a PnSEG (n=1,2) address */ #define PHYSADDR(a) (((unsigned long)(a)) & 0x1fffffff) +#ifdef CONFIG_29BIT /* * Map an address to a certain privileged segment */ -#define P1SEGADDR(a) ((__typeof__(a))(((unsigned long)(a) & 0x1fffffff) | P1SEG)) -#define P2SEGADDR(a) ((__typeof__(a))(((unsigned long)(a) & 0x1fffffff) | P2SEG)) -#define P3SEGADDR(a) ((__typeof__(a))(((unsigned long)(a) & 0x1fffffff) | P3SEG)) -#define P4SEGADDR(a) ((__typeof__(a))(((unsigned long)(a) & 0x1fffffff) | P4SEG)) +#define P1SEGADDR(a) \ + ((__typeof__(a))(((unsigned long)(a) & 0x1fffffff) | P1SEG)) +#define P2SEGADDR(a) \ + ((__typeof__(a))(((unsigned long)(a) & 0x1fffffff) | P2SEG)) +#define P3SEGADDR(a) \ + ((__typeof__(a))(((unsigned long)(a) & 0x1fffffff) | P3SEG)) +#define P4SEGADDR(a) \ + ((__typeof__(a))(((unsigned long)(a) & 0x1fffffff) | P4SEG)) +#endif /* 29BIT */ +#endif /* P1SEG */ + +/* Check if an address can be reached in 29 bits */ +#define IS_29BIT(a) (((unsigned long)(a)) < 0x20000000) #endif /* __KERNEL__ */ #endif /* __ASM_SH_ADDRSPACE_H */ diff --git a/include/asm-sh/atomic-grb.h b/include/asm-sh/atomic-grb.h new file mode 100644 index 00000000000..4c5b7dbfced --- /dev/null +++ b/include/asm-sh/atomic-grb.h @@ -0,0 +1,169 @@ +#ifndef __ASM_SH_ATOMIC_GRB_H +#define __ASM_SH_ATOMIC_GRB_H + +static inline void atomic_add(int i, atomic_t *v) +{ + int tmp; + + __asm__ __volatile__ ( + " .align 2 \n\t" + " mova 1f, r0 \n\t" /* r0 = end point */ + " mov r15, r1 \n\t" /* r1 = saved sp */ + " mov #-6, r15 \n\t" /* LOGIN: r15 = size */ + " mov.l @%1, %0 \n\t" /* load old value */ + " add %2, %0 \n\t" /* add */ + " mov.l %0, @%1 \n\t" /* store new value */ + "1: mov r1, r15 \n\t" /* LOGOUT */ + : "=&r" (tmp), + "+r" (v) + : "r" (i) + : "memory" , "r0", "r1"); +} + +static inline void atomic_sub(int i, atomic_t *v) +{ + int tmp; + + __asm__ __volatile__ ( + " .align 2 \n\t" + " mova 1f, r0 \n\t" /* r0 = end point */ + " mov r15, r1 \n\t" /* r1 = saved sp */ + " mov #-6, r15 \n\t" /* LOGIN: r15 = size */ + " mov.l @%1, %0 \n\t" /* load old value */ + " sub %2, %0 \n\t" /* sub */ + " mov.l %0, @%1 \n\t" /* store new value */ + "1: mov r1, r15 \n\t" /* LOGOUT */ + : "=&r" (tmp), + "+r" (v) + : "r" (i) + : "memory" , "r0", "r1"); +} + +static inline int atomic_add_return(int i, atomic_t *v) +{ + int tmp; + + __asm__ __volatile__ ( + " .align 2 \n\t" + " mova 1f, r0 \n\t" /* r0 = end point */ + " mov r15, r1 \n\t" /* r1 = saved sp */ + " mov #-6, r15 \n\t" /* LOGIN: r15 = size */ + " mov.l @%1, %0 \n\t" /* load old value */ + " add %2, %0 \n\t" /* add */ + " mov.l %0, @%1 \n\t" /* store new value */ + "1: mov r1, r15 \n\t" /* LOGOUT */ + : "=&r" (tmp), + "+r" (v) + : "r" (i) + : "memory" , "r0", "r1"); + + return tmp; +} + +static inline int atomic_sub_return(int i, atomic_t *v) +{ + int tmp; + + __asm__ __volatile__ ( + " .align 2 \n\t" + " mova 1f, r0 \n\t" /* r0 = end point */ + " mov r15, r1 \n\t" /* r1 = saved sp */ + " mov #-6, r15 \n\t" /* LOGIN: r15 = size */ + " mov.l @%1, %0 \n\t" /* load old value */ + " sub %2, %0 \n\t" /* sub */ + " mov.l %0, @%1 \n\t" /* store new value */ + "1: mov r1, r15 \n\t" /* LOGOUT */ + : "=&r" (tmp), + "+r" (v) + : "r" (i) + : "memory", "r0", "r1"); + + return tmp; +} + +static inline void atomic_clear_mask(unsigned int mask, atomic_t *v) +{ + int tmp; + unsigned int _mask = ~mask; + + __asm__ __volatile__ ( + " .align 2 \n\t" + " mova 1f, r0 \n\t" /* r0 = end point */ + " mov r15, r1 \n\t" /* r1 = saved sp */ + " mov #-6, r15 \n\t" /* LOGIN: r15 = size */ + " mov.l @%1, %0 \n\t" /* load old value */ + " and %2, %0 \n\t" /* add */ + " mov.l %0, @%1 \n\t" /* store new value */ + "1: mov r1, r15 \n\t" /* LOGOUT */ + : "=&r" (tmp), + "+r" (v) + : "r" (_mask) + : "memory" , "r0", "r1"); +} + +static inline void atomic_set_mask(unsigned int mask, atomic_t *v) +{ + int tmp; + + __asm__ __volatile__ ( + " .align 2 \n\t" + " mova 1f, r0 \n\t" /* r0 = end point */ + " mov r15, r1 \n\t" /* r1 = saved sp */ + " mov #-6, r15 \n\t" /* LOGIN: r15 = size */ + " mov.l @%1, %0 \n\t" /* load old value */ + " or %2, %0 \n\t" /* or */ + " mov.l %0, @%1 \n\t" /* store new value */ + "1: mov r1, r15 \n\t" /* LOGOUT */ + : "=&r" (tmp), + "+r" (v) + : "r" (mask) + : "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/include/asm-sh/atomic.h b/include/asm-sh/atomic.h index e12570b9339..c043ef00302 100644 --- a/include/asm-sh/atomic.h +++ b/include/asm-sh/atomic.h @@ -17,7 +17,9 @@ typedef struct { volatile int counter; } atomic_t; #include <linux/compiler.h> #include <asm/system.h> -#ifdef CONFIG_CPU_SH4A +#if defined(CONFIG_GUSA_RB) +#include <asm/atomic-grb.h> +#elif defined(CONFIG_CPU_SH4A) #include <asm/atomic-llsc.h> #else #include <asm/atomic-irq.h> @@ -44,6 +46,7 @@ typedef struct { volatile int counter; } atomic_t; #define atomic_inc(v) atomic_add(1,(v)) #define atomic_dec(v) atomic_sub(1,(v)) +#ifndef CONFIG_GUSA_RB static inline int atomic_cmpxchg(atomic_t *v, int old, int new) { int ret; @@ -58,8 +61,6 @@ static inline int atomic_cmpxchg(atomic_t *v, int old, int new) return ret; } -#define atomic_xchg(v, new) (xchg(&((v)->counter), new)) - static inline int atomic_add_unless(atomic_t *v, int a, int u) { int ret; @@ -73,6 +74,9 @@ static inline int atomic_add_unless(atomic_t *v, int a, int u) return ret != u; } +#endif + +#define atomic_xchg(v, new) (xchg(&((v)->counter), new)) #define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0) /* Atomic operations are already serializing on SH */ diff --git a/include/asm-sh/auxvec.h b/include/asm-sh/auxvec.h index 1b6916e63e9..a6b9d4f4859 100644 --- a/include/asm-sh/auxvec.h +++ b/include/asm-sh/auxvec.h @@ -6,6 +6,12 @@ * for more of them. */ +/* + * This entry gives some information about the FPU initialization + * performed by the kernel. + */ +#define AT_FPUCW 18 /* Used FPU control word. */ + #ifdef CONFIG_VSYSCALL /* * Only define this in the vsyscall case, the entry point to @@ -15,4 +21,16 @@ #define AT_SYSINFO_EHDR 33 #endif +/* + * More complete cache descriptions than AT_[DIU]CACHEBSIZE. If the + * value is -1, then the cache doesn't exist. Otherwise: + * + * bit 0-3: Cache set-associativity; 0 means fully associative. + * bit 4-7: Log2 of cacheline size. + * bit 8-31: Size of the entire cache >> 8. + */ +#define AT_L1I_CACHESHAPE 34 +#define AT_L1D_CACHESHAPE 35 +#define AT_L2_CACHESHAPE 36 + #endif /* __ASM_SH_AUXVEC_H */ diff --git a/include/asm-sh/bitops-grb.h b/include/asm-sh/bitops-grb.h new file mode 100644 index 00000000000..a5907b94395 --- /dev/null +++ b/include/asm-sh/bitops-grb.h @@ -0,0 +1,169 @@ +#ifndef __ASM_SH_BITOPS_GRB_H +#define __ASM_SH_BITOPS_GRB_H + +static inline void set_bit(int nr, volatile void * addr) +{ + int mask; + volatile unsigned int *a = addr; + unsigned long tmp; + + a += nr >> 5; + mask = 1 << (nr & 0x1f); + + __asm__ __volatile__ ( + " .align 2 \n\t" + " mova 1f, r0 \n\t" /* r0 = end point */ + " mov r15, r1 \n\t" /* r1 = saved sp */ + " mov #-6, r15 \n\t" /* LOGIN: r15 = size */ + " mov.l @%1, %0 \n\t" /* load old value */ + " or %2, %0 \n\t" /* or */ + " mov.l %0, @%1 \n\t" /* store new value */ + "1: mov r1, r15 \n\t" /* LOGOUT */ + : "=&r" (tmp), + "+r" (a) + : "r" (mask) + : "memory" , "r0", "r1"); +} + +static inline void clear_bit(int nr, volatile void * addr) +{ + int mask; + volatile unsigned int *a = addr; + unsigned long tmp; + + a += nr >> 5; + mask = ~(1 << (nr & 0x1f)); + __asm__ __volatile__ ( + " .align 2 \n\t" + " mova 1f, r0 \n\t" /* r0 = end point */ + " mov r15, r1 \n\t" /* r1 = saved sp */ + " mov #-6, r15 \n\t" /* LOGIN: r15 = size */ + " mov.l @%1, %0 \n\t" /* load old value */ + " and %2, %0 \n\t" /* and */ + " mov.l %0, @%1 \n\t" /* store new value */ + "1: mov r1, r15 \n\t" /* LOGOUT */ + : "=&r" (tmp), + "+r" (a) + : "r" (mask) + : "memory" , "r0", "r1"); +} + +static inline void change_bit(int nr, volatile void * addr) +{ + int mask; + volatile unsigned int *a = addr; + unsigned long tmp; + + a += nr >> 5; + mask = 1 << (nr & 0x1f); + __asm__ __volatile__ ( + " .align 2 \n\t" + " mova 1f, r0 \n\t" /* r0 = end point */ + " mov r15, r1 \n\t" /* r1 = saved sp */ + " mov #-6, r15 \n\t" /* LOGIN: r15 = size */ + " mov.l @%1, %0 \n\t" /* load old value */ + " xor %2, %0 \n\t" /* xor */ + " mov.l %0, @%1 \n\t" /* store new value */ + "1: mov r1, r15 \n\t" /* LOGOUT */ + : "=&r" (tmp), + "+r" (a) + : "r" (mask) + : "memory" , "r0", "r1"); +} + +static inline int test_and_set_bit(int nr, volatile void * addr) +{ + int mask, retval; + volatile unsigned int *a = addr; + unsigned long tmp; + + a += nr >> 5; + mask = 1 << (nr & 0x1f); + + __asm__ __volatile__ ( + " .align 2 \n\t" + " mova 1f, r0 \n\t" /* r0 = end point */ + " mov r15, r1 \n\t" /* r1 = saved sp */ + " mov #-14, r15 \n\t" /* LOGIN: r15 = size */ + " mov.l @%2, %0 \n\t" /* load old value */ + " mov %0, %1 \n\t" + " tst %1, %3 \n\t" /* T = ((*a & mask) == 0) */ + " mov #-1, %1 \n\t" /* retvat = -1 */ + " negc %1, %1 \n\t" /* retval = (mask & *a) != 0 */ + " or %3, %0 \n\t" + " mov.l %0, @%2 \n\t" /* store new value */ + "1: mov r1, r15 \n\t" /* LOGOUT */ + : "=&r" (tmp), + "=&r" (retval), + "+r" (a) + : "r" (mask) + : "memory" , "r0", "r1" ,"t"); + + return retval; +} + +static inline int test_and_clear_bit(int nr, volatile void * addr) +{ + int mask, retval,not_mask; + volatile unsigned int *a = addr; + unsigned long tmp; + + a += nr >> 5; + mask = 1 << (nr & 0x1f); + + not_mask = ~mask; + + __asm__ __volatile__ ( + " .align 2 \n\t" + " mova 1f, r0 \n\t" /* r0 = end point */ + " mov r15, r1 \n\t" /* r1 = saved sp */ + " mov #-14, r15 \n\t" /* LOGIN */ + " mov.l @%2, %0 \n\t" /* load old value */ + " mov %0, %1 \n\t" /* %1 = *a */ + " tst %1, %3 \n\t" /* T = ((*a & mask) == 0) */ + " mov #-1, %1 \n\t" /* retvat = -1 */ + " negc %1, %1 \n\t" /* retval = (mask & *a) != 0 */ + " and %4, %0 \n\t" + " mov.l %0, @%2 \n\t" /* store new value */ + "1: mov r1, r15 \n\t" /* LOGOUT */ + : "=&r" (tmp), + "=&r" (retval), + "+r" (a) + : "r" (mask), + "r" (not_mask) + : "memory" , "r0", "r1", "t"); + + return retval; +} + +static inline int test_and_change_bit(int nr, volatile void * addr) +{ + int mask, retval; + volatile unsigned int *a = addr; + unsigned long tmp; + + a += nr >> 5; + mask = 1 << (nr & 0x1f); + + __asm__ __volatile__ ( + " .align 2 \n\t" + " mova 1f, r0 \n\t" /* r0 = end point */ + " mov r15, r1 \n\t" /* r1 = saved sp */ + " mov #-14, r15 \n\t" /* LOGIN */ + " mov.l @%2, %0 \n\t" /* load old value */ + " mov %0, %1 \n\t" /* %1 = *a */ + " tst %1, %3 \n\t" /* T = ((*a & mask) == 0) */ + " mov #-1, %1 \n\t" /* retvat = -1 */ + " negc %1, %1 \n\t" /* retval = (mask & *a) != 0 */ + " xor %3, %0 \n\t" + " mov.l %0, @%2 \n\t" /* store new value */ + "1: mov r1, r15 \n\t" /* LOGOUT */ + : "=&r" (tmp), + "=&r" (retval), + "+r" (a) + : "r" (mask) + : "memory" , "r0", "r1", "t"); + + return retval; +} +#endif /* __ASM_SH_BITOPS_GRB_H */ diff --git a/include/asm-sh/bitops-irq.h b/include/asm-sh/bitops-irq.h new file mode 100644 index 00000000000..653a1275058 --- /dev/null +++ b/include/asm-sh/bitops-irq.h @@ -0,0 +1,91 @@ +#ifndef __ASM_SH_BITOPS_IRQ_H +#define __ASM_SH_BITOPS_IRQ_H + +static inline void set_bit(int nr, volatile void *addr) +{ + int mask; + volatile unsigned int *a = addr; + unsigned long flags; + + a += nr >> 5; + mask = 1 << (nr & 0x1f); + local_irq_save(flags); + *a |= mask; + local_irq_restore(flags); +} + +static inline void clear_bit(int nr, volatile void *addr) +{ + int mask; + volatile unsigned int *a = addr; + unsigned long flags; + + a += nr >> 5; + mask = 1 << (nr & 0x1f); + local_irq_save(flags); + *a &= ~mask; + local_irq_restore(flags); +} + +static inline void change_bit(int nr, volatile void *addr) +{ + int mask; + volatile unsigned int *a = addr; + unsigned long flags; + + a += nr >> 5; + mask = 1 << (nr & 0x1f); + local_irq_save(flags); + *a ^= mask; + local_irq_restore(flags); +} + +static inline int test_and_set_bit(int nr, volatile void *addr) +{ + int mask, retval; + volatile unsigned int *a = addr; + unsigned long flags; + + a += nr >> 5; + mask = 1 << (nr & 0x1f); + local_irq_save(flags); + retval = (mask & *a) != 0; + *a |= mask; + local_irq_restore(flags); + + return retval; +} + +static inline int test_and_clear_bit(int nr, volatile void *addr) +{ + int mask, retval; + volatile unsigned int *a = addr; + unsigned long flags; + + a += nr >> 5; + mask = 1 << (nr & 0x1f); + local_irq_save(flags); + retval = (mask & *a) != 0; + *a &= ~mask; + local_irq_restore(flags); + + return retval; +} + +static inline int test_and_change_bit(int nr, volatile void *addr) +{ + int mask, retval; + volatile unsigned int *a = addr; + unsigned long flags; + + a += nr >> 5; + mask = 1 << (nr & 0x1f); + local_irq_save(flags); + retval = (mask & *a) != 0; + *a ^= mask; + local_irq_restore(flags); + + return retval; +} + +#endif /* __ASM_SH_BITOPS_IRQ_H */ diff --git a/include/asm-sh/bitops.h b/include/asm-sh/bitops.h index df805f20b26..b6ba5a60dec 100644 --- a/include/asm-sh/bitops.h +++ b/include/asm-sh/bitops.h @@ -11,100 +11,22 @@ /* For __swab32 */ #include <asm/byteorder.h> -static inline void set_bit(int nr, volatile void * addr) -{ - int mask; - volatile unsigned int *a = addr; - unsigned long flags; - - a += nr >> 5; - mask = 1 << (nr & 0x1f); - local_irq_save(flags); - *a |= mask; - local_irq_restore(flags); -} +#ifdef CONFIG_GUSA_RB +#include <asm/bitops-grb.h> +#else +#include <asm/bitops-irq.h> +#endif + /* * clear_bit() doesn't provide any barrier for the compiler. */ #define smp_mb__before_clear_bit() barrier() #define smp_mb__after_clear_bit() barrier() -static inline void clear_bit(int nr, volatile void * addr) -{ - int mask; - volatile unsigned int *a = addr; - unsigned long flags; - - a += nr >> 5; - mask = 1 << (nr & 0x1f); - local_irq_save(flags); - *a &= ~mask; - local_irq_restore(flags); -} - -static inline void change_bit(int nr, volatile void * addr) -{ - int mask; - volatile unsigned int *a = addr; - unsigned long flags; - - a += nr >> 5; - mask = 1 << (nr & 0x1f); - local_irq_save(flags); - *a ^= mask; - local_irq_restore(flags); -} - -static inline int test_and_set_bit(int nr, volatile void * addr) -{ - int mask, retval; - volatile unsigned int *a = addr; - unsigned long flags; - - a += nr >> 5; - mask = 1 << (nr & 0x1f); - local_irq_save(flags); - retval = (mask & *a) != 0; - *a |= mask; - local_irq_restore(flags); - - return retval; -} - -static inline int test_and_clear_bit(int nr, volatile void * addr) -{ - int mask, retval; - volatile unsigned int *a = addr; - unsigned long flags; - - a += nr >> 5; - mask = 1 << (nr & 0x1f); - local_irq_save(flags); - retval = (mask & *a) != 0; - *a &= ~mask; - local_irq_restore(flags); - - return retval; -} - -static inline int test_and_change_bit(int nr, volatile void * addr) -{ - int mask, retval; - volatile unsigned int *a = addr; - unsigned long flags; - - a += nr >> 5; - mask = 1 << (nr & 0x1f); - local_irq_save(flags); - retval = (mask & *a) != 0; - *a ^= mask; - local_irq_restore(flags); - - return retval; -} #include <asm-generic/bitops/non-atomic.h> +#ifdef CONFIG_SUPERH32 static inline unsigned long ffz(unsigned long word) { unsigned long result; @@ -138,6 +60,31 @@ static inline unsigned long __ffs(unsigned long word) : "t"); return result; } +#else +static inline unsigned long ffz(unsigned long word) +{ + unsigned long result, __d2, __d3; + + __asm__("gettr tr0, %2\n\t" + "pta $+32, tr0\n\t" + "andi %1, 1, %3\n\t" + "beq %3, r63, tr0\n\t" + "pta $+4, tr0\n" + "0:\n\t" + "shlri.l %1, 1, %1\n\t" + "addi %0, 1, %0\n\t" + "andi %1, 1, %3\n\t" + "beqi %3, 1, tr0\n" + "1:\n\t" + "ptabs %2, tr0\n\t" + : "=r" (result), "=r" (word), "=r" (__d2), "=r" (__d3) + : "0" (0L), "1" (word)); + + return result; +} + +#include <asm-generic/bitops/__ffs.h> +#endif #include <asm-generic/bitops/find.h> #include <asm-generic/bitops/ffs.h> diff --git a/include/asm-sh/bug.h b/include/asm-sh/bug.h index a78d482e8b2..c0171804016 100644 --- a/include/asm-sh/bug.h +++ b/include/asm-sh/bug.h @@ -3,7 +3,7 @@ #define TRAPA_BUG_OPCODE 0xc33e /* trapa #0x3e */ -#ifdef CONFIG_BUG +#ifdef CONFIG_GENERIC_BUG #define HAVE_ARCH_BUG #define HAVE_ARCH_WARN_ON @@ -72,12 +72,7 @@ do { \ unlikely(__ret_warn_on); \ }) -struct pt_regs; - -/* arch/sh/kernel/traps.c */ -void handle_BUG(struct pt_regs *); - -#endif /* CONFIG_BUG */ +#endif /* CONFIG_GENERIC_BUG */ #include <asm-generic/bug.h> diff --git a/include/asm-sh/bugs.h b/include/asm-sh/bugs.h index b66139ff73f..def8128b8b7 100644 --- a/include/asm-sh/bugs.h +++ b/include/asm-sh/bugs.h @@ -25,7 +25,7 @@ static void __init check_bugs(void) case CPU_SH7619: *p++ = '2'; break; - case CPU_SH7206: + case CPU_SH7203 ... CPU_SH7263: *p++ = '2'; *p++ = 'a'; break; @@ -35,7 +35,7 @@ static void __init check_bugs(void) case CPU_SH7750 ... CPU_SH4_501: *p++ = '4'; break; - case CPU_SH7770 ... CPU_SHX3: + case CPU_SH7763 ... CPU_SHX3: *p++ = '4'; *p++ = 'a'; break; @@ -48,9 +48,16 @@ static void __init check_bugs(void) *p++ = 's'; *p++ = 'p'; break; - default: - *p++ = '?'; - *p++ = '!'; + case CPU_SH5_101 ... CPU_SH5_103: + *p++ = '6'; + *p++ = '4'; + break; + case CPU_SH_NONE: + /* + * Specifically use CPU_SH_NONE rather than default:, + * so we're able to have the compiler whine about + * unhandled enumerations. + */ break; } diff --git a/include/asm-sh/byteorder.h b/include/asm-sh/byteorder.h index bff2b1382e0..0eb9904b654 100644 --- a/include/asm-sh/byteorder.h +++ b/include/asm-sh/byteorder.h @@ -3,40 +3,55 @@ /* * Copyright (C) 1999 Niibe Yutaka + * Copyright (C) 2000, 2001 Paolo Alberelli */ - -#include <asm/types.h> #include <linux/compiler.h> +#include <linux/types.h> -static __inline__ __attribute_const__ __u32 ___arch__swab32(__u32 x) +static inline __attribute_const__ __u32 ___arch__swab32(__u32 x) { - __asm__("swap.b %0, %0\n\t" - "swap.w %0, %0\n\t" - "swap.b %0, %0" + __asm__( +#ifdef CONFIG_SUPERH32 + "swap.b %0, %0\n\t" + "swap.w %0, %0\n\t" + "swap.b %0, %0" +#else + "byterev %0, %0\n\t" + "shari %0, 32, %0" +#endif : "=r" (x) : "0" (x)); + return x; } -static __inline__ __attribute_const__ __u16 ___arch__swab16(__u16 x) +static inline __attribute_const__ __u16 ___arch__swab16(__u16 x) { - __asm__("swap.b %0, %0" + __asm__( +#ifdef CONFIG_SUPERH32 + "swap.b %0, %0" +#else + "byterev %0, %0\n\t" + "shari %0, 32, %0" + +#endif : "=r" (x) : "0" (x)); + return x; } -static inline __u64 ___arch__swab64(__u64 val) -{ - union { +static inline __u64 ___arch__swab64(__u64 val) +{ + union { struct { __u32 a,b; } s; __u64 u; } v, w; v.u = val; - w.s.b = ___arch__swab32(v.s.a); - w.s.a = ___arch__swab32(v.s.b); - return w.u; -} + w.s.b = ___arch__swab32(v.s.a); + w.s.a = ___arch__swab32(v.s.b); + return w.u; +} #define __arch__swab64(x) ___arch__swab64(x) #define __arch__swab32(x) ___arch__swab32(x) diff --git a/include/asm-sh/cache.h b/include/asm-sh/cache.h index 01e5cf51ba9..083419f47c6 100644 --- a/include/asm-sh/cache.h +++ b/include/asm-sh/cache.h @@ -12,11 +12,6 @@ #include <linux/init.h> #include <asm/cpu/cache.h> -#define SH_CACHE_VALID 1 -#define SH_CACHE_UPDATED 2 -#define SH_CACHE_COMBINED 4 -#define SH_CACHE_ASSOC 8 - #define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT) #define __read_mostly __attribute__((__section__(".data.read_mostly"))) diff --git a/include/asm-sh/cacheflush.h b/include/asm-sh/cacheflush.h index 9d528ada3c1..e034c360411 100644 --- a/include/asm-sh/cacheflush.h +++ b/include/asm-sh/cacheflush.h @@ -43,6 +43,12 @@ extern void __flush_purge_region(void *start, int size); extern void __flush_invalidate_region(void *start, int size); #endif +#define ARCH_HAS_FLUSH_KERNEL_DCACHE_PAGE +static inline void flush_kernel_dcache_page(struct page *page) +{ + flush_dcache_page(page); +} + #if defined(CONFIG_CPU_SH4) && !defined(CONFIG_CACHE_OFF) extern void copy_to_user_page(struct vm_area_struct *vma, struct page *page, unsigned long vaddr, void *dst, const void *src, diff --git a/include/asm-sh/checksum.h b/include/asm-sh/checksum.h index 4bc8357e889..67496ab0ef0 100644 --- a/include/asm-sh/checksum.h +++ b/include/asm-sh/checksum.h @@ -1,215 +1,5 @@ -#ifndef __ASM_SH_CHECKSUM_H -#define __ASM_SH_CHECKSUM_H - -/* - * 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. - * - * Copyright (C) 1999 by Kaz Kojima & Niibe Yutaka - */ - -#include <linux/in6.h> - -/* - * computes the checksum of a memory block at buff, length len, - * and adds in "sum" (32-bit) - * - * returns a 32-bit number suitable for feeding into itself - * or csum_tcpudp_magic - * - * this function must be called with even lengths, except - * for the last fragment, which may be odd - * - * it's best to have buff aligned on a 32-bit boundary - */ -asmlinkage __wsum csum_partial(const void *buff, int len, __wsum sum); - -/* - * the same as csum_partial, but copies from src while it - * checksums, and handles user-space pointer exceptions correctly, when needed. - * - * here even more important to align src and dst on a 32-bit (or even - * better 64-bit) boundary - */ - -asmlinkage __wsum csum_partial_copy_generic(const void *src, void *dst, - int len, __wsum sum, - int *src_err_ptr, int *dst_err_ptr); - -/* - * Note: when you get a NULL pointer exception here this means someone - * passed in an incorrect kernel address to one of these functions. - * - * If you use these functions directly please don't forget the - * access_ok(). - */ -static inline -__wsum csum_partial_copy_nocheck(const void *src, void *dst, - int len, __wsum sum) -{ - return csum_partial_copy_generic(src, dst, len, sum, NULL, NULL); -} - -static inline -__wsum csum_partial_copy_from_user(const void __user *src, void *dst, - int len, __wsum sum, int *err_ptr) -{ - return csum_partial_copy_generic((__force const void *)src, dst, - len, sum, err_ptr, NULL); -} - -/* - * Fold a partial checksum - */ - -static inline __sum16 csum_fold(__wsum sum) -{ - unsigned int __dummy; - __asm__("swap.w %0, %1\n\t" - "extu.w %0, %0\n\t" - "extu.w %1, %1\n\t" - "add %1, %0\n\t" - "swap.w %0, %1\n\t" - "add %1, %0\n\t" - "not %0, %0\n\t" - : "=r" (sum), "=&r" (__dummy) - : "0" (sum) - : "t"); - return (__force __sum16)sum; -} - -/* - * This is a version of ip_compute_csum() optimized for IP headers, - * which always checksum on 4 octet boundaries. - * - * i386 version by Jorge Cwik <jorge@laser.satlink.net>, adapted - * for linux by * Arnt Gulbrandsen. - */ -static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl) -{ - unsigned int sum, __dummy0, __dummy1; - - __asm__ __volatile__( - "mov.l @%1+, %0\n\t" - "mov.l @%1+, %3\n\t" - "add #-2, %2\n\t" - "clrt\n\t" - "1:\t" - "addc %3, %0\n\t" - "movt %4\n\t" - "mov.l @%1+, %3\n\t" - "dt %2\n\t" - "bf/s 1b\n\t" - " cmp/eq #1, %4\n\t" - "addc %3, %0\n\t" - "addc %2, %0" /* Here %2 is 0, add carry-bit */ - /* Since the input registers which are loaded with iph and ihl - are modified, we must also specify them as outputs, or gcc - will assume they contain their original values. */ - : "=r" (sum), "=r" (iph), "=r" (ihl), "=&r" (__dummy0), "=&z" (__dummy1) - : "1" (iph), "2" (ihl) - : "t"); - - return csum_fold(sum); -} - -static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr, - unsigned short len, - unsigned short proto, - __wsum sum) -{ -#ifdef __LITTLE_ENDIAN__ - unsigned long len_proto = (proto + len) << 8; +#ifdef CONFIG_SUPERH32 +# include "checksum_32.h" #else - unsigned long len_proto = proto + len; +# include "checksum_64.h" #endif - __asm__("clrt\n\t" - "addc %0, %1\n\t" - "addc %2, %1\n\t" - "addc %3, %1\n\t" - "movt %0\n\t" - "add %1, %0" - : "=r" (sum), "=r" (len_proto) - : "r" (daddr), "r" (saddr), "1" (len_proto), "0" (sum) - : "t"); - - return sum; -} - -/* - * computes the checksum of the TCP/UDP pseudo-header - * returns a 16-bit checksum, already complemented - */ -static inline __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr, - unsigned short len, - unsigned short proto, - __wsum sum) -{ - return csum_fold(csum_tcpudp_nofold(saddr, daddr, len, proto, sum)); -} - -/* - * this routine is used for miscellaneous IP-like checksums, mainly - * in icmp.c - */ -static inline __sum16 ip_compute_csum(const void *buff, int len) -{ - return csum_fold(csum_partial(buff, len, 0)); -} - -#define _HAVE_ARCH_IPV6_CSUM -static inline __sum16 csum_ipv6_magic(const struct in6_addr *saddr, - const struct in6_addr *daddr, - __u32 len, unsigned short proto, - __wsum sum) -{ - unsigned int __dummy; - __asm__("clrt\n\t" - "mov.l @(0,%2), %1\n\t" - "addc %1, %0\n\t" - "mov.l @(4,%2), %1\n\t" - "addc %1, %0\n\t" - "mov.l @(8,%2), %1\n\t" - "addc %1, %0\n\t" - "mov.l @(12,%2), %1\n\t" - "addc %1, %0\n\t" - "mov.l @(0,%3), %1\n\t" - "addc %1, %0\n\t" - "mov.l @(4,%3), %1\n\t" - "addc %1, %0\n\t" - "mov.l @(8,%3), %1\n\t" - "addc %1, %0\n\t" - "mov.l @(12,%3), %1\n\t" - "addc %1, %0\n\t" - "addc %4, %0\n\t" - "addc %5, %0\n\t" - "movt %1\n\t" - "add %1, %0\n" - : "=r" (sum), "=&r" (__dummy) - : "r" (saddr), "r" (daddr), - "r" (htonl(len)), "r" (htonl(proto)), "0" (sum) - : "t"); - - return csum_fold(sum); -} - -/* - * Copy and checksum to user - */ -#define HAVE_CSUM_COPY_USER -static inline __wsum csum_and_copy_to_user(const void *src, - void __user *dst, - int len, __wsum sum, - int *err_ptr) -{ - if (access_ok(VERIFY_WRITE, dst, len)) - return csum_partial_copy_generic((__force const void *)src, - dst, len, sum, NULL, err_ptr); - - if (len) - *err_ptr = -EFAULT; - - return (__force __wsum)-1; /* invalid checksum */ -} -#endif /* __ASM_SH_CHECKSUM_H */ diff --git a/include/asm-sh/checksum_32.h b/include/asm-sh/checksum_32.h new file mode 100644 index 00000000000..4bc8357e889 --- /dev/null +++ b/include/asm-sh/checksum_32.h @@ -0,0 +1,215 @@ +#ifndef __ASM_SH_CHECKSUM_H +#define __ASM_SH_CHECKSUM_H + +/* + * 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. + * + * Copyright (C) 1999 by Kaz Kojima & Niibe Yutaka + */ + +#include <linux/in6.h> + +/* + * computes the checksum of a memory block at buff, length len, + * and adds in "sum" (32-bit) + * + * returns a 32-bit number suitable for feeding into itself + * or csum_tcpudp_magic + * + * this function must be called with even lengths, except + * for the last fragment, which may be odd + * + * it's best to have buff aligned on a 32-bit boundary + */ +asmlinkage __wsum csum_partial(const void *buff, int len, __wsum sum); + +/* + * the same as csum_partial, but copies from src while it + * checksums, and handles user-space pointer exceptions correctly, when needed. + * + * here even more important to align src and dst on a 32-bit (or even + * better 64-bit) boundary + */ + +asmlinkage __wsum csum_partial_copy_generic(const void *src, void *dst, + int len, __wsum sum, + int *src_err_ptr, int *dst_err_ptr); + +/* + * Note: when you get a NULL pointer exception here this means someone + * passed in an incorrect kernel address to one of these functions. + * + * If you use these functions directly please don't forget the + * access_ok(). + */ +static inline +__wsum csum_partial_copy_nocheck(const void *src, void *dst, + int len, __wsum sum) +{ + return csum_partial_copy_generic(src, dst, len, sum, NULL, NULL); +} + +static inline +__wsum csum_partial_copy_from_user(const void __user *src, void *dst, + int len, __wsum sum, int *err_ptr) +{ + return csum_partial_copy_generic((__force const void *)src, dst, + len, sum, err_ptr, NULL); +} + +/* + * Fold a partial checksum + */ + +static inline __sum16 csum_fold(__wsum sum) +{ + unsigned int __dummy; + __asm__("swap.w %0, %1\n\t" + "extu.w %0, %0\n\t" + "extu.w %1, %1\n\t" + "add %1, %0\n\t" + "swap.w %0, %1\n\t" + "add %1, %0\n\t" + "not %0, %0\n\t" + : "=r" (sum), "=&r" (__dummy) + : "0" (sum) + : "t"); + return (__force __sum16)sum; +} + +/* + * This is a version of ip_compute_csum() optimized for IP headers, + * which always checksum on 4 octet boundaries. + * + * i386 version by Jorge Cwik <jorge@laser.satlink.net>, adapted + * for linux by * Arnt Gulbrandsen. + */ +static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl) +{ + unsigned int sum, __dummy0, __dummy1; + + __asm__ __volatile__( + "mov.l @%1+, %0\n\t" + "mov.l @%1+, %3\n\t" + "add #-2, %2\n\t" + "clrt\n\t" + "1:\t" + "addc %3, %0\n\t" + "movt %4\n\t" + "mov.l @%1+, %3\n\t" + "dt %2\n\t" + "bf/s 1b\n\t" + " cmp/eq #1, %4\n\t" + "addc %3, %0\n\t" + "addc %2, %0" /* Here %2 is 0, add carry-bit */ + /* Since the input registers which are loaded with iph and ihl + are modified, we must also specify them as outputs, or gcc + will assume they contain their original values. */ + : "=r" (sum), "=r" (iph), "=r" (ihl), "=&r" (__dummy0), "=&z" (__dummy1) + : "1" (iph), "2" (ihl) + : "t"); + + return csum_fold(sum); +} + +static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr, + unsigned short len, + unsigned short proto, + __wsum sum) +{ +#ifdef __LITTLE_ENDIAN__ + unsigned long len_proto = (proto + len) << 8; +#else + unsigned long len_proto = proto + len; +#endif + __asm__("clrt\n\t" + "addc %0, %1\n\t" + "addc %2, %1\n\t" + "addc %3, %1\n\t" + "movt %0\n\t" + "add %1, %0" + : "=r" (sum), "=r" (len_proto) + : "r" (daddr), "r" (saddr), "1" (len_proto), "0" (sum) + : "t"); + + return sum; +} + +/* + * computes the checksum of the TCP/UDP pseudo-header + * returns a 16-bit checksum, already complemented + */ +static inline __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr, + unsigned short len, + unsigned short proto, + __wsum sum) +{ + return csum_fold(csum_tcpudp_nofold(saddr, daddr, len, proto, sum)); +} + +/* + * this routine is used for miscellaneous IP-like checksums, mainly + * in icmp.c + */ +static inline __sum16 ip_compute_csum(const void *buff, int len) +{ + return csum_fold(csum_partial(buff, len, 0)); +} + +#define _HAVE_ARCH_IPV6_CSUM +static inline __sum16 csum_ipv6_magic(const struct in6_addr *saddr, + const struct in6_addr *daddr, + __u32 len, unsigned short proto, + __wsum sum) +{ + unsigned int __dummy; + __asm__("clrt\n\t" + "mov.l @(0,%2), %1\n\t" + "addc %1, %0\n\t" + "mov.l @(4,%2), %1\n\t" + "addc %1, %0\n\t" + "mov.l @(8,%2), %1\n\t" + "addc %1, %0\n\t" + "mov.l @(12,%2), %1\n\t" + "addc %1, %0\n\t" + "mov.l @(0,%3), %1\n\t" + "addc %1, %0\n\t" + "mov.l @(4,%3), %1\n\t" + "addc %1, %0\n\t" + "mov.l @(8,%3), %1\n\t" + "addc %1, %0\n\t" + "mov.l @(12,%3), %1\n\t" + "addc %1, %0\n\t" + "addc %4, %0\n\t" + "addc %5, %0\n\t" + "movt %1\n\t" + "add %1, %0\n" + : "=r" (sum), "=&r" (__dummy) + : "r" (saddr), "r" (daddr), + "r" (htonl(len)), "r" (htonl(proto)), "0" (sum) + : "t"); + + return csum_fold(sum); +} + +/* + * Copy and checksum to user + */ +#define HAVE_CSUM_COPY_USER +static inline __wsum csum_and_copy_to_user(const void *src, + void __user *dst, + int len, __wsum sum, + int *err_ptr) +{ + if (access_ok(VERIFY_WRITE, dst, len)) + return csum_partial_copy_generic((__force const void *)src, + dst, len, sum, NULL, err_ptr); + + if (len) + *err_ptr = -EFAULT; + + return (__force __wsum)-1; /* invalid checksum */ +} +#endif /* __ASM_SH_CHECKSUM_H */ diff --git a/include/asm-sh/checksum_64.h b/include/asm-sh/checksum_64.h new file mode 100644 index 00000000000..9c62a031a8f --- /dev/null +++ b/include/asm-sh/checksum_64.h @@ -0,0 +1,78 @@ +#ifndef __ASM_SH_CHECKSUM_64_H +#define __ASM_SH_CHECKSUM_64_H + +/* + * include/asm-sh/checksum_64.h + * + * Copyright (C) 2000, 2001 Paolo Alberelli + * + * 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. + */ + +/* + * computes the checksum of a memory block at buff, length len, + * and adds in "sum" (32-bit) + * + * returns a 32-bit number suitable for feeding into itself + * or csum_tcpudp_magic + * + * this function must be called with even lengths, except + * for the last fragment, which may be odd + * + * it's best to have buff aligned on a 32-bit boundary + */ +asmlinkage __wsum csum_partial(const void *buff, int len, __wsum sum); + +/* + * Note: when you get a NULL pointer exception here this means someone + * passed in an incorrect kernel address to one of these functions. + * + * If you use these functions directly please don't forget the + * access_ok(). + */ + + +__wsum csum_partial_copy_nocheck(const void *src, void *dst, int len, + __wsum sum); + +__wsum csum_partial_copy_from_user(const void __user *src, void *dst, + int len, __wsum sum, int *err_ptr); + +static inline __sum16 csum_fold(__wsum csum) +{ + u32 sum = (__force u32)csum; + sum = (sum & 0xffff) + (sum >> 16); + sum = (sum & 0xffff) + (sum >> 16); + return (__force __sum16)~sum; +} + +__sum16 ip_fast_csum(const void *iph, unsigned int ihl); + +__wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr, + unsigned short len, unsigned short proto, + __wsum sum); + +/* + * computes the checksum of the TCP/UDP pseudo-header + * returns a 16-bit checksum, already complemented + */ +static inline __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr, + unsigned short len, + unsigned short proto, + __wsum sum) +{ + return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum)); +} + +/* + * this routine is used for miscellaneous IP-like checksums, mainly + * in icmp.c + */ +static inline __sum16 ip_compute_csum(const void *buff, int len) +{ + return csum_fold(csum_partial(buff, len, 0)); +} + +#endif /* __ASM_SH_CHECKSUM_64_H */ diff --git a/include/asm-sh/cmpxchg-grb.h b/include/asm-sh/cmpxchg-grb.h new file mode 100644 index 00000000000..e2681abe764 --- /dev/null +++ b/include/asm-sh/cmpxchg-grb.h @@ -0,0 +1,70 @@ +#ifndef __ASM_SH_CMPXCHG_GRB_H +#define __ASM_SH_CMPXCHG_GRB_H + +static inline unsigned long xchg_u32(volatile u32 *m, unsigned long val) +{ + unsigned long retval; + + __asm__ __volatile__ ( + " .align 2 \n\t" + " mova 1f, r0 \n\t" /* r0 = end point */ + " nop \n\t" + " mov r15, r1 \n\t" /* r1 = saved sp */ + " mov #-4, r15 \n\t" /* LOGIN */ + " mov.l @%1, %0 \n\t" /* load old value */ + " mov.l %2, @%1 \n\t" /* store new value */ + "1: mov r1, r15 \n\t" /* LOGOUT */ + : "=&r" (retval), + "+r" (m) + : "r" (val) + : "memory", "r0", "r1"); + + return retval; +} + +static inline unsigned long xchg_u8(volatile u8 *m, unsigned long val) +{ + unsigned long retval; + + __asm__ __volatile__ ( + " .align 2 \n\t" + " mova 1f, r0 \n\t" /* r0 = end point */ + " mov r15, r1 \n\t" /* r1 = saved sp */ + " mov #-6, r15 \n\t" /* LOGIN */ + " mov.b @%1, %0 \n\t" /* load old value */ + " extu.b %0, %0 \n\t" /* extend as unsigned */ + " mov.b %2, @%1 \n\t" /* store new value */ + "1: mov r1, r15 \n\t" /* LOGOUT */ + : "=&r" (retval), + "+r" (m) + : "r" (val) + : "memory" , "r0", "r1"); + + return retval; +} + +static inline unsigned long __cmpxchg_u32(volatile int *m, unsigned long old, + unsigned long new) +{ + unsigned long retval; + + __asm__ __volatile__ ( + " .align 2 \n\t" + " mova 1f, r0 \n\t" /* r0 = end point */ + " nop \n\t" + " mov r15, r1 \n\t" /* r1 = saved sp */ + " mov #-8, r15 \n\t" /* LOGIN */ + " 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 */ + "1: mov r1, r15 \n\t" /* LOGOUT */ + : "=&r" (retval), + "+r" (m) + : "r" (new) + : "memory" , "r0", "r1", "t"); + + return retval; +} + +#endif /* __ASM_SH_CMPXCHG_GRB_H */ diff --git a/include/asm-sh/cmpxchg-irq.h b/include/asm-sh/cmpxchg-irq.h new file mode 100644 index 00000000000..43049ec0554 --- /dev/null +++ b/include/asm-sh/cmpxchg-irq.h @@ -0,0 +1,40 @@ +#ifndef __ASM_SH_CMPXCHG_IRQ_H +#define __ASM_SH_CMPXCHG_IRQ_H + +static inline unsigned long xchg_u32(volatile u32 *m, unsigned long val) +{ + unsigned long flags, retval; + + local_irq_save(flags); + retval = *m; + *m = val; + local_irq_restore(flags); + return retval; +} + +static inline unsigned long xchg_u8(volatile u8 *m, unsigned long val) +{ + unsigned long flags, retval; + + local_irq_save(flags); + retval = *m; + *m = val & 0xff; + local_irq_restore(flags); + return retval; +} + +static inline unsigned long __cmpxchg_u32(volatile int *m, unsigned long old, + unsigned long new) +{ + __u32 retval; + unsigned long flags; + + local_irq_save(flags); + retval = *m; + if (retval == old) + *m = new; + local_irq_restore(flags); /* implies memory barrier */ + return retval; +} + +#endif /* __ASM_SH_CMPXCHG_IRQ_H */ diff --git a/include/asm-sh/cpu-sh2/addrspace.h b/include/asm-sh/cpu-sh2/addrspace.h index 8706c903c5a..2b9ab93efa4 100644 --- a/include/asm-sh/cpu-sh2/addrspace.h +++ b/include/asm-sh/cpu-sh2/addrspace.h @@ -10,7 +10,10 @@ #ifndef __ASM_CPU_SH2_ADDRSPACE_H #define __ASM_CPU_SH2_ADDRSPACE_H -/* Should fill here */ +#define P0SEG 0x00000000 +#define P1SEG 0x80000000 +#define P2SEG 0xa0000000 +#define P3SEG 0xc0000000 +#define P4SEG 0xe0000000 #endif /* __ASM_CPU_SH2_ADDRSPACE_H */ - diff --git a/include/asm-sh/cpu-sh2/cache.h b/include/asm-sh/cpu-sh2/cache.h index f02ba7a672b..4e0b1650068 100644 --- a/include/asm-sh/cpu-sh2/cache.h +++ b/include/asm-sh/cpu-sh2/cache.h @@ -12,9 +12,13 @@ #define L1_CACHE_SHIFT 4 +#define SH_CACHE_VALID 1 +#define SH_CACHE_UPDATED 2 +#define SH_CACHE_COMBINED 4 +#define SH_CACHE_ASSOC 8 + #if defined(CONFIG_CPU_SUBTYPE_SH7619) -#define CCR1 0xffffffec -#define CCR CCR1 +#define CCR 0xffffffec #define CCR_CACHE_CE 0x01 /* Cache enable */ #define CCR_CACHE_WT 0x06 /* CCR[bit1=1,bit2=1] */ diff --git a/include/asm-sh/cpu-sh2/rtc.h b/include/asm-sh/cpu-sh2/rtc.h new file mode 100644 index 00000000000..39e2d6e9478 --- /dev/null +++ b/include/asm-sh/cpu-sh2/rtc.h @@ -0,0 +1,8 @@ +#ifndef __ASM_SH_CPU_SH2_RTC_H +#define __ASM_SH_CPU_SH2_RTC_H + +#define rtc_reg_size sizeof(u16) +#define RTC_BIT_INVERTED 0 +#define RTC_DEF_CAPABILITIES 0UL + +#endif /* __ASM_SH_CPU_SH2_RTC_H */ diff --git a/include/asm-sh/cpu-sh2a/addrspace.h b/include/asm-sh/cpu-sh2a/addrspace.h index 3d2e9aa2152..795ddd6856a 100644 --- a/include/asm-sh/cpu-sh2a/addrspace.h +++ b/include/asm-sh/cpu-sh2a/addrspace.h @@ -1 +1,10 @@ -#include <asm/cpu-sh2/addrspace.h> +#ifndef __ASM_SH_CPU_SH2A_ADDRSPACE_H +#define __ASM_SH_CPU_SH2A_ADDRSPACE_H + +#define P0SEG 0x00000000 +#define P1SEG 0x00000000 +#define P2SEG 0x20000000 +#define P3SEG 0x00000000 +#define P4SEG 0x80000000 + +#endif /* __ASM_SH_CPU_SH2A_ADDRSPACE_H */ diff --git a/include/asm-sh/cpu-sh2a/cache.h b/include/asm-sh/cpu-sh2a/cache.h index 3e4b9e48098..afe228b3f49 100644 --- a/include/asm-sh/cpu-sh2a/cache.h +++ b/include/asm-sh/cpu-sh2a/cache.h @@ -12,11 +12,13 @@ #define L1_CACHE_SHIFT 4 -#define CCR1 0xfffc1000 -#define CCR2 0xfffc1004 +#define SH_CACHE_VALID 1 +#define SH_CACHE_UPDATED 2 +#define SH_CACHE_COMBINED 4 +#define SH_CACHE_ASSOC 8 -/* CCR1 behaves more like the traditional CCR */ -#define CCR CCR1 +#define CCR 0xfffc1000 /* CCR1 */ +#define CCR2 0xfffc1004 /* * Most of the SH-2A CCR1 definitions resemble the SH-4 ones. All others not @@ -36,4 +38,3 @@ #define CCR_CACHE_INVALIDATE (CCR_CACHE_OCI | CCR_CACHE_ICI) #endif /* __ASM_CPU_SH2A_CACHE_H */ - diff --git a/include/asm-sh/cpu-sh2a/freq.h b/include/asm-sh/cpu-sh2a/freq.h index e518fff6d10..830fd43b6cd 100644 --- a/include/asm-sh/cpu-sh2a/freq.h +++ b/include/asm-sh/cpu-sh2a/freq.h @@ -10,9 +10,7 @@ #ifndef __ASM_CPU_SH2A_FREQ_H #define __ASM_CPU_SH2A_FREQ_H -#if defined(CONFIG_CPU_SUBTYPE_SH7206) #define FREQCR 0xfffe0010 -#endif #endif /* __ASM_CPU_SH2A_FREQ_H */ diff --git a/include/asm-sh/cpu-sh2a/rtc.h b/include/asm-sh/cpu-sh2a/rtc.h new file mode 100644 index 00000000000..afb511e2bed --- /dev/null +++ b/include/asm-sh/cpu-sh2a/rtc.h @@ -0,0 +1,8 @@ +#ifndef __ASM_SH_CPU_SH2A_RTC_H +#define __ASM_SH_CPU_SH2A_RTC_H + +#define rtc_reg_size sizeof(u16) +#define RTC_BIT_INVERTED 0 +#define RTC_DEF_CAPABILITIES RTC_CAP_4_DIGIT_YEAR + +#endif /* __ASM_SH_CPU_SH2A_RTC_H */ diff --git a/include/asm-sh/cpu-sh3/addrspace.h b/include/asm-sh/cpu-sh3/addrspace.h index 872e9e1b548..0f94726c7d6 100644 --- a/include/asm-sh/cpu-sh3/addrspace.h +++ b/include/asm-sh/cpu-sh3/addrspace.h @@ -10,7 +10,10 @@ #ifndef __ASM_CPU_SH3_ADDRSPACE_H #define __ASM_CPU_SH3_ADDRSPACE_H -/* Should fill here */ +#define P0SEG 0x00000000 +#define P1SEG 0x80000000 +#define P2SEG 0xa0000000 +#define P3SEG 0xc0000000 +#define P4SEG 0xe0000000 #endif /* __ASM_CPU_SH3_ADDRSPACE_H */ - diff --git a/include/asm-sh/cpu-sh3/cache.h b/include/asm-sh/cpu-sh3/cache.h index 255016fc91f..56bd838b7db 100644 --- a/include/asm-sh/cpu-sh3/cache.h +++ b/include/asm-sh/cpu-sh3/cache.h @@ -12,6 +12,11 @@ #define L1_CACHE_SHIFT 4 +#define SH_CACHE_VALID 1 +#define SH_CACHE_UPDATED 2 +#define SH_CACHE_COMBINED 4 +#define SH_CACHE_ASSOC 8 + #define CCR 0xffffffec /* Address of Cache Control Register */ #define CCR_CACHE_CE 0x01 /* Cache Enable */ @@ -28,7 +33,8 @@ #if defined(CONFIG_CPU_SUBTYPE_SH7705) || \ defined(CONFIG_CPU_SUBTYPE_SH7710) || \ - defined(CONFIG_CPU_SUBTYPE_SH7720) + defined(CONFIG_CPU_SUBTYPE_SH7720) || \ + defined(CONFIG_CPU_SUBTYPE_SH7721) #define CCR3 0xa40000b4 #define CCR_CACHE_16KB 0x00010000 #define CCR_CACHE_32KB 0x00020000 diff --git a/include/asm-sh/cpu-sh3/dma.h b/include/asm-sh/cpu-sh3/dma.h index 54bfece328c..092ff9d872c 100644 --- a/include/asm-sh/cpu-sh3/dma.h +++ b/include/asm-sh/cpu-sh3/dma.h @@ -2,7 +2,9 @@ #define __ASM_CPU_SH3_DMA_H -#if defined(CONFIG_CPU_SUBTYPE_SH7720) || defined(CONFIG_CPU_SUBTYPE_SH7709) +#if defined(CONFIG_CPU_SUBTYPE_SH7720) || \ + defined(CONFIG_CPU_SUBTYPE_SH7721) || \ + defined(CONFIG_CPU_SUBTYPE_SH7709) #define SH_DMAC_BASE 0xa4010020 #define DMTE0_IRQ 48 diff --git a/include/asm-sh/cpu-sh3/freq.h b/include/asm-sh/cpu-sh3/freq.h index 0a054b53b9d..53c62302b2e 100644 --- a/include/asm-sh/cpu-sh3/freq.h +++ b/include/asm-sh/cpu-sh3/freq.h @@ -10,7 +10,12 @@ #ifndef __ASM_CPU_SH3_FREQ_H #define __ASM_CPU_SH3_FREQ_H +#ifdef CONFIG_CPU_SUBTYPE_SH7712 +#define FRQCR 0xA415FF80 +#else #define FRQCR 0xffffff80 +#endif + #define MIN_DIVISOR_NR 0 #define MAX_DIVISOR_NR 4 diff --git a/include/asm-sh/cpu-sh3/gpio.h b/include/asm-sh/cpu-sh3/gpio.h index 48770c1c7bd..4e53eb314b8 100644 --- a/include/asm-sh/cpu-sh3/gpio.h +++ b/include/asm-sh/cpu-sh3/gpio.h @@ -12,7 +12,8 @@ #ifndef _CPU_SH3_GPIO_H #define _CPU_SH3_GPIO_H -#if defined(CONFIG_CPU_SUBTYPE_SH7720) +#if defined(CONFIG_CPU_SUBTYPE_SH7720) || \ + defined(CONFIG_CPU_SUBTYPE_SH7721) /* Control registers */ #define PORT_PACR 0xA4050100UL diff --git a/include/asm-sh/cpu-sh3/mmu_context.h b/include/asm-sh/cpu-sh3/mmu_context.h index 16c2d63b7e3..ab09da73ce7 100644 --- a/include/asm-sh/cpu-sh3/mmu_context.h +++ b/include/asm-sh/cpu-sh3/mmu_context.h @@ -33,7 +33,8 @@ defined(CONFIG_CPU_SUBTYPE_SH7709) || \ defined(CONFIG_CPU_SUBTYPE_SH7710) || \ defined(CONFIG_CPU_SUBTYPE_SH7712) || \ - defined(CONFIG_CPU_SUBTYPE_SH7720) + defined(CONFIG_CPU_SUBTYPE_SH7720) || \ + defined(CONFIG_CPU_SUBTYPE_SH7721) #define INTEVT 0xa4000000 /* INTEVTE2(0xa4000000) */ #else #define INTEVT 0xffffffd8 diff --git a/include/asm-sh/cpu-sh3/rtc.h b/include/asm-sh/cpu-sh3/rtc.h new file mode 100644 index 00000000000..319404aaee3 --- /dev/null +++ b/include/asm-sh/cpu-sh3/rtc.h @@ -0,0 +1,8 @@ +#ifndef __ASM_SH_CPU_SH3_RTC_H +#define __ASM_SH_CPU_SH3_RTC_H + +#define rtc_reg_size sizeof(u16) +#define RTC_BIT_INVERTED 0 /* No bug on SH7708, SH7709A */ +#define RTC_DEF_CAPABILITIES 0UL + +#endif /* __ASM_SH_CPU_SH3_RTC_H */ diff --git a/include/asm-sh/cpu-sh3/timer.h b/include/asm-sh/cpu-sh3/timer.h index 7b795ac5477..793acf12aa0 100644 --- a/include/asm-sh/cpu-sh3/timer.h +++ b/include/asm-sh/cpu-sh3/timer.h @@ -23,12 +23,13 @@ * --------------------------------------------------------------------------- */ -#if !defined(CONFIG_CPU_SUBTYPE_SH7720) +#if !defined(CONFIG_CPU_SUBTYPE_SH7720) && !defined(CONFIG_CPU_SUBTYPE_SH7721) #define TMU_TOCR 0xfffffe90 /* Byte access */ #endif #if defined(CONFIG_CPU_SUBTYPE_SH7710) || \ - defined(CONFIG_CPU_SUBTYPE_SH7720) + defined(CONFIG_CPU_SUBTYPE_SH7720) || \ + defined(CONFIG_CPU_SUBTYPE_SH7721) #define TMU_012_TSTR 0xa412fe92 /* Byte access */ #define TMU0_TCOR 0xa412fe94 /* Long access */ @@ -57,7 +58,7 @@ #define TMU2_TCOR 0xfffffeac /* Long access */ #define TMU2_TCNT 0xfffffeb0 /* Long access */ #define TMU2_TCR 0xfffffeb4 /* Word access */ -#if !defined(CONFIG_CPU_SUBTYPE_SH7720) +#if !defined(CONFIG_CPU_SUBTYPE_SH7720) && !defined(CONFIG_CPU_SUBTYPE_SH7721) #define TMU2_TCPR2 0xfffffeb8 /* Long access */ #endif #endif diff --git a/include/asm-sh/cpu-sh3/ubc.h b/include/asm-sh/cpu-sh3/ubc.h index 18467c57453..4e6381d5ff7 100644 --- a/include/asm-sh/cpu-sh3/ubc.h +++ b/include/asm-sh/cpu-sh3/ubc.h @@ -12,7 +12,8 @@ #define __ASM_CPU_SH3_UBC_H #if defined(CONFIG_CPU_SUBTYPE_SH7710) || \ - defined(CONFIG_CPU_SUBTYPE_SH7720) + defined(CONFIG_CPU_SUBTYPE_SH7720) || \ + defined(CONFIG_CPU_SUBTYPE_SH7721) #define UBC_BARA 0xa4ffffb0 #define UBC_BAMRA 0xa4ffffb4 #define UBC_BBRA 0xa4ffffb8 diff --git a/include/asm-sh/cpu-sh4/addrspace.h b/include/asm-sh/cpu-sh4/addrspace.h index bb2e1b03060..a3fa733c1c7 100644 --- a/include/asm-sh/cpu-sh4/addrspace.h +++ b/include/asm-sh/cpu-sh4/addrspace.h @@ -10,6 +10,12 @@ #ifndef __ASM_CPU_SH4_ADDRSPACE_H #define __ASM_CPU_SH4_ADDRSPACE_H +#define P0SEG 0x00000000 +#define P1SEG 0x80000000 +#define P2SEG 0xa0000000 +#define P3SEG 0xc0000000 +#define P4SEG 0xe0000000 + /* Detailed P4SEG */ #define P4SEG_STORE_QUE (P4SEG) #define P4SEG_IC_ADDR 0xf0000000 diff --git a/include/asm-sh/cpu-sh4/cache.h b/include/asm-sh/cpu-sh4/cache.h index f92b20a0983..1c61ebf5c8e 100644 --- a/include/asm-sh/cpu-sh4/cache.h +++ b/include/asm-sh/cpu-sh4/cache.h @@ -12,6 +12,11 @@ #define L1_CACHE_SHIFT 5 +#define SH_CACHE_VALID 1 +#define SH_CACHE_UPDATED 2 +#define SH_CACHE_COMBINED 4 +#define SH_CACHE_ASSOC 8 + #define CCR 0xff00001c /* Address of Cache Control Register */ #define CCR_CACHE_OCE 0x0001 /* Operand Cache Enable */ #define CCR_CACHE_WT 0x0002 /* Write-Through (for P0,U0,P3) (else writeback)*/ diff --git a/include/asm-sh/cpu-sh4/fpu.h b/include/asm-sh/cpu-sh4/fpu.h new file mode 100644 index 00000000000..febef734252 --- /dev/null +++ b/include/asm-sh/cpu-sh4/fpu.h @@ -0,0 +1,32 @@ +/* + * linux/arch/sh/kernel/cpu/sh4/sh4_fpu.h + * + * Copyright (C) 2006 STMicroelectronics Limited + * Author: Carl Shaw <carl.shaw@st.com> + * + * May be copied or modified under the terms of the GNU General Public + * License Version 2. See linux/COPYING for more information. + * + * Definitions for SH4 FPU operations + */ + +#ifndef __CPU_SH4_FPU_H +#define __CPU_SH4_FPU_H + +#define FPSCR_ENABLE_MASK 0x00000f80UL + +#define FPSCR_FMOV_DOUBLE (1<<1) + +#define FPSCR_CAUSE_INEXACT (1<<12) +#define FPSCR_CAUSE_UNDERFLOW (1<<13) +#define FPSCR_CAUSE_OVERFLOW (1<<14) +#define FPSCR_CAUSE_DIVZERO (1<<15) +#define FPSCR_CAUSE_INVALID (1<<16) +#define FPSCR_CAUSE_ERROR (1<<17) + +#define FPSCR_DBL_PRECISION (1<<19) +#define FPSCR_ROUNDING_MODE(x) ((x >> 20) & 3) +#define FPSCR_RM_NEAREST (0) +#define FPSCR_RM_ZERO (1) + +#endif diff --git a/include/asm-sh/cpu-sh4/freq.h b/include/asm-sh/cpu-sh4/freq.h index dc1d32a8637..1ac10b9a078 100644 --- a/include/asm-sh/cpu-sh4/freq.h +++ b/include/asm-sh/cpu-sh4/freq.h @@ -16,7 +16,8 @@ #define SCLKACR 0xa4150008 #define SCLKBCR 0xa415000c #define IrDACLKCR 0xa4150010 -#elif defined(CONFIG_CPU_SUBTYPE_SH7780) +#elif defined(CONFIG_CPU_SUBTYPE_SH7763) || \ + defined(CONFIG_CPU_SUBTYPE_SH7780) #define FRQCR 0xffc80000 #elif defined(CONFIG_CPU_SUBTYPE_SH7785) #define FRQCR0 0xffc80000 diff --git a/include/asm-sh/cpu-sh4/mmu_context.h b/include/asm-sh/cpu-sh4/mmu_context.h index 979acddc0f8..9ea8eb27b18 100644 --- a/include/asm-sh/cpu-sh4/mmu_context.h +++ b/include/asm-sh/cpu-sh4/mmu_context.h @@ -22,12 +22,20 @@ #define MMU_UTLB_ADDRESS_ARRAY 0xF6000000 #define MMU_PAGE_ASSOC_BIT 0x80 +#define MMUCR_TI (1<<2) + #ifdef CONFIG_X2TLB #define MMUCR_ME (1 << 7) #else #define MMUCR_ME (0) #endif +#if defined(CONFIG_32BIT) && defined(CONFIG_CPU_SUBTYPE_ST40) +#define MMUCR_SE (1 << 4) +#else +#define MMUCR_SE (0) +#endif + #ifdef CONFIG_SH_STORE_QUEUES #define MMUCR_SQMD (1 << 9) #else @@ -35,7 +43,7 @@ #endif #define MMU_NTLB_ENTRIES 64 -#define MMU_CONTROL_INIT (0x05|MMUCR_SQMD|MMUCR_ME) +#define MMU_CONTROL_INIT (0x05|MMUCR_SQMD|MMUCR_ME|MMUCR_SE) #define MMU_ITLB_DATA_ARRAY 0xF3000000 #define MMU_UTLB_DATA_ARRAY 0xF7000000 diff --git a/include/asm-sh/cpu-sh4/rtc.h b/include/asm-sh/cpu-sh4/rtc.h new file mode 100644 index 00000000000..f3d0f53275e --- /dev/null +++ b/include/asm-sh/cpu-sh4/rtc.h @@ -0,0 +1,8 @@ +#ifndef __ASM_SH_CPU_SH4_RTC_H +#define __ASM_SH_CPU_SH4_RTC_H + +#define rtc_reg_size sizeof(u32) +#define RTC_BIT_INVERTED 0x40 /* bug on SH7750, SH7750S */ +#define RTC_DEF_CAPABILITIES RTC_CAP_4_DIGIT_YEAR + +#endif /* __ASM_SH_CPU_SH4_RTC_H */ diff --git a/include/asm-sh/cpu-sh5/addrspace.h b/include/asm-sh/cpu-sh5/addrspace.h new file mode 100644 index 00000000000..dc36b9a03af --- /dev/null +++ b/include/asm-sh/cpu-sh5/addrspace.h @@ -0,0 +1,11 @@ +#ifndef __ASM_SH_CPU_SH5_ADDRSPACE_H +#define __ASM_SH_CPU_SH5_ADDRSPACE_H + +#define PHYS_PERIPHERAL_BLOCK 0x09000000 +#define PHYS_DMAC_BLOCK 0x0e000000 +#define PHYS_PCI_BLOCK 0x60000000 +#define PHYS_EMI_BLOCK 0xff000000 + +/* No segmentation.. */ + +#endif /* __ASM_SH_CPU_SH5_ADDRSPACE_H */ diff --git a/include/asm-sh/cpu-sh5/cache.h b/include/asm-sh/cpu-sh5/cache.h new file mode 100644 index 00000000000..ed050ab526f --- /dev/null +++ b/include/asm-sh/cpu-sh5/cache.h @@ -0,0 +1,97 @@ +#ifndef __ASM_SH_CPU_SH5_CACHE_H +#define __ASM_SH_CPU_SH5_CACHE_H + +/* + * include/asm-sh/cpu-sh5/cache.h + * + * Copyright (C) 2000, 2001 Paolo Alberelli + * Copyright (C) 2003, 2004 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. + */ + +#define L1_CACHE_SHIFT 5 + +/* Valid and Dirty bits */ +#define SH_CACHE_VALID (1LL<<0) +#define SH_CACHE_UPDATED (1LL<<57) + +/* Unimplemented compat bits.. */ +#define SH_CACHE_COMBINED 0 +#define SH_CACHE_ASSOC 0 + +/* Cache flags */ +#define SH_CACHE_MODE_WT (1LL<<0) +#define SH_CACHE_MODE_WB (1LL<<1) + +/* + * Control Registers. + */ +#define ICCR_BASE 0x01600000 /* Instruction Cache Control Register */ +#define ICCR_REG0 0 /* Register 0 offset */ +#define ICCR_REG1 1 /* Register 1 offset */ +#define ICCR0 ICCR_BASE+ICCR_REG0 +#define ICCR1 ICCR_BASE+ICCR_REG1 + +#define ICCR0_OFF 0x0 /* Set ICACHE off */ +#define ICCR0_ON 0x1 /* Set ICACHE on */ +#define ICCR0_ICI 0x2 /* Invalidate all in IC */ + +#define ICCR1_NOLOCK 0x0 /* Set No Locking */ + +#define OCCR_BASE 0x01E00000 /* Operand Cache Control Register */ +#define OCCR_REG0 0 /* Register 0 offset */ +#define OCCR_REG1 1 /* Register 1 offset */ +#define OCCR0 OCCR_BASE+OCCR_REG0 +#define OCCR1 OCCR_BASE+OCCR_REG1 + +#define OCCR0_OFF 0x0 /* Set OCACHE off */ +#define OCCR0_ON 0x1 /* Set OCACHE on */ +#define OCCR0_OCI 0x2 /* Invalidate all in OC */ +#define OCCR0_WT 0x4 /* Set OCACHE in WT Mode */ +#define OCCR0_WB 0x0 /* Set OCACHE in WB Mode */ + +#define OCCR1_NOLOCK 0x0 /* Set No Locking */ + +/* + * SH-5 + * A bit of description here, for neff=32. + * + * |<--- tag (19 bits) --->| + * +-----------------------------+-----------------+------+----------+------+ + * | | | ways |set index |offset| + * +-----------------------------+-----------------+------+----------+------+ + * ^ 2 bits 8 bits 5 bits + * +- Bit 31 + * + * Cacheline size is based on offset: 5 bits = 32 bytes per line + * A cache line is identified by a tag + set but OCACHETAG/ICACHETAG + * have a broader space for registers. These are outlined by + * CACHE_?C_*_STEP below. + * + */ + +/* Instruction cache */ +#define CACHE_IC_ADDRESS_ARRAY 0x01000000 + +/* Operand Cache */ +#define CACHE_OC_ADDRESS_ARRAY 0x01800000 + +/* These declarations relate to cache 'synonyms' in the operand cache. A + 'synonym' occurs where effective address bits overlap between those used for + indexing the cache sets and those passed to the MMU for translation. In the + case of SH5-101 & SH5-103, only bit 12 is affected for 4k pages. */ + +#define CACHE_OC_N_SYNBITS 1 /* Number of synonym bits */ +#define CACHE_OC_SYN_SHIFT 12 +/* Mask to select synonym bit(s) */ +#define CACHE_OC_SYN_MASK (((1UL<<CACHE_OC_N_SYNBITS)-1)<<CACHE_OC_SYN_SHIFT) + +/* + * Instruction cache can't be invalidated based on physical addresses. + * No Instruction Cache defines required, then. + */ + +#endif /* __ASM_SH_CPU_SH5_CACHE_H */ diff --git a/include/asm-sh/cpu-sh5/cacheflush.h b/include/asm-sh/cpu-sh5/cacheflush.h new file mode 100644 index 00000000000..98edb5b1da3 --- /dev/null +++ b/include/asm-sh/cpu-sh5/cacheflush.h @@ -0,0 +1,35 @@ +#ifndef __ASM_SH_CPU_SH5_CACHEFLUSH_H +#define __ASM_SH_CPU_SH5_CACHEFLUSH_H + +#ifndef __ASSEMBLY__ + +#include <asm/page.h> + +struct vm_area_struct; +struct page; +struct mm_struct; + +extern void flush_cache_all(void); +extern void flush_cache_mm(struct mm_struct *mm); +extern void flush_cache_sigtramp(unsigned long start, unsigned long end); +extern void flush_cache_range(struct vm_area_struct *vma, unsigned long start, + unsigned long end); +extern void flush_cache_page(struct vm_area_struct *vma, unsigned long addr, unsigned long pfn); +extern void flush_dcache_page(struct page *pg); +extern void flush_icache_range(unsigned long start, unsigned long end); +extern void flush_icache_user_range(struct vm_area_struct *vma, + struct page *page, unsigned long addr, + int len); + +#define flush_cache_dup_mm(mm) flush_cache_mm(mm) + +#define flush_dcache_mmap_lock(mapping) do { } while (0) +#define flush_dcache_mmap_unlock(mapping) do { } while (0) + +#define flush_icache_page(vma, page) do { } while (0) +#define p3_cache_init() do { } while (0) + +#endif /* __ASSEMBLY__ */ + +#endif /* __ASM_SH_CPU_SH5_CACHEFLUSH_H */ + diff --git a/include/asm-sh/cpu-sh5/dma.h b/include/asm-sh/cpu-sh5/dma.h new file mode 100644 index 00000000000..7bf6bb3d35e --- /dev/null +++ b/include/asm-sh/cpu-sh5/dma.h @@ -0,0 +1,6 @@ +#ifndef __ASM_SH_CPU_SH5_DMA_H +#define __ASM_SH_CPU_SH5_DMA_H + +/* Nothing yet */ + +#endif /* __ASM_SH_CPU_SH5_DMA_H */ diff --git a/include/asm-sh/cpu-sh5/irq.h b/include/asm-sh/cpu-sh5/irq.h new file mode 100644 index 00000000000..f0f0756e6e8 --- /dev/null +++ b/include/asm-sh/cpu-sh5/irq.h @@ -0,0 +1,117 @@ +#ifndef __ASM_SH_CPU_SH5_IRQ_H +#define __ASM_SH_CPU_SH5_IRQ_H + +/* + * include/asm-sh/cpu-sh5/irq.h + * + * Copyright (C) 2000, 2001 Paolo Alberelli + * + * 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. + */ + + +/* + * Encoded IRQs are not considered worth to be supported. + * Main reason is that there's no per-encoded-interrupt + * enable/disable mechanism (as there was in SH3/4). + * An all enabled/all disabled is worth only if there's + * a cascaded IC to disable/enable/ack on. Until such + * IC is available there's no such support. + * + * Presumably Encoded IRQs may use extra IRQs beyond 64, + * below. Some logic must be added to cope with IRQ_IRL? + * in an exclusive way. + * + * Priorities are set at Platform level, when IRQ_IRL0-3 + * are set to 0 Encoding is allowed. Otherwise it's not + * allowed. + */ + +/* Independent IRQs */ +#define IRQ_IRL0 0 +#define IRQ_IRL1 1 +#define IRQ_IRL2 2 +#define IRQ_IRL3 3 + +#define IRQ_INTA 4 +#define IRQ_INTB 5 +#define IRQ_INTC 6 +#define IRQ_INTD 7 + +#define IRQ_SERR 12 +#define IRQ_ERR 13 +#define IRQ_PWR3 14 +#define IRQ_PWR2 15 +#define IRQ_PWR1 16 +#define IRQ_PWR0 17 + +#define IRQ_DMTE0 18 +#define IRQ_DMTE1 19 +#define IRQ_DMTE2 20 +#define IRQ_DMTE3 21 +#define IRQ_DAERR 22 + +#define IRQ_TUNI0 32 +#define IRQ_TUNI1 33 +#define IRQ_TUNI2 34 +#define IRQ_TICPI2 35 + +#define IRQ_ATI 36 +#define IRQ_PRI 37 +#define IRQ_CUI 38 + +#define IRQ_ERI 39 +#define IRQ_RXI 40 +#define IRQ_BRI 41 +#define IRQ_TXI 42 + +#define IRQ_ITI 63 + +#define NR_INTC_IRQS 64 + +#ifdef CONFIG_SH_CAYMAN +#define NR_EXT_IRQS 32 +#define START_EXT_IRQS 64 + +/* PCI bus 2 uses encoded external interrupts on the Cayman board */ +#define IRQ_P2INTA (START_EXT_IRQS + (3*8) + 0) +#define IRQ_P2INTB (START_EXT_IRQS + (3*8) + 1) +#define IRQ_P2INTC (START_EXT_IRQS + (3*8) + 2) +#define IRQ_P2INTD (START_EXT_IRQS + (3*8) + 3) + +#define I8042_KBD_IRQ (START_EXT_IRQS + 2) +#define I8042_AUX_IRQ (START_EXT_IRQS + 6) + +#define IRQ_CFCARD (START_EXT_IRQS + 7) +#define IRQ_PCMCIA (0) + +#else +#define NR_EXT_IRQS 0 +#endif + +/* Default IRQs, fixed */ +#define TIMER_IRQ IRQ_TUNI0 +#define RTC_IRQ IRQ_CUI + +/* Default Priorities, Platform may choose differently */ +#define NO_PRIORITY 0 /* Disabled */ +#define TIMER_PRIORITY 2 +#define RTC_PRIORITY TIMER_PRIORITY +#define SCIF_PRIORITY 3 +#define INTD_PRIORITY 3 +#define IRL3_PRIORITY 4 +#define INTC_PRIORITY 6 +#define IRL2_PRIORITY 7 +#define INTB_PRIORITY 9 +#define IRL1_PRIORITY 10 +#define INTA_PRIORITY 12 +#define IRL0_PRIORITY 13 +#define TOP_PRIORITY 15 + +extern int intc_evt_to_irq[(0xE20/0x20)+1]; +int intc_irq_describe(char* p, int irq); +extern int platform_int_priority[NR_INTC_IRQS]; + +#endif /* __ASM_SH_CPU_SH5_IRQ_H */ diff --git a/include/asm-sh/cpu-sh5/mmu_context.h b/include/asm-sh/cpu-sh5/mmu_context.h new file mode 100644 index 00000000000..df857fc0996 --- /dev/null +++ b/include/asm-sh/cpu-sh5/mmu_context.h @@ -0,0 +1,27 @@ +#ifndef __ASM_SH_CPU_SH5_MMU_CONTEXT_H +#define __ASM_SH_CPU_SH5_MMU_CONTEXT_H + +/* Common defines */ +#define TLB_STEP 0x00000010 +#define TLB_PTEH 0x00000000 +#define TLB_PTEL 0x00000008 + +/* PTEH defines */ +#define PTEH_ASID_SHIFT 2 +#define PTEH_VALID 0x0000000000000001 +#define PTEH_SHARED 0x0000000000000002 +#define PTEH_MATCH_ASID 0x00000000000003ff + +#ifndef __ASSEMBLY__ +/* This has to be a common function because the next location to fill + * information is shared. */ +extern void __do_tlb_refill(unsigned long address, unsigned long long is_text_not_data, pte_t *pte); + +/* Profiling counter. */ +#ifdef CONFIG_SH64_PROC_TLB +extern unsigned long long calls_to_do_fast_page_fault; +#endif + +#endif /* __ASSEMBLY__ */ + +#endif /* __ASM_SH_CPU_SH5_MMU_CONTEXT_H */ diff --git a/include/asm-sh/cpu-sh5/registers.h b/include/asm-sh/cpu-sh5/registers.h new file mode 100644 index 00000000000..6664ea6f156 --- /dev/null +++ b/include/asm-sh/cpu-sh5/registers.h @@ -0,0 +1,106 @@ +#ifndef __ASM_SH_CPU_SH5_REGISTERS_H +#define __ASM_SH_CPU_SH5_REGISTERS_H + +/* + * include/asm-sh/cpu-sh5/registers.h + * + * Copyright (C) 2000, 2001 Paolo Alberelli + * Copyright (C) 2004 Richard Curnow + * + * 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. + */ + +#ifdef __ASSEMBLY__ +/* ===================================================================== +** +** Section 1: acts on assembly sources pre-processed by GPP ( <source.S>). +** Assigns symbolic names to control & target registers. +*/ + +/* + * Define some useful aliases for control registers. + */ +#define SR cr0 +#define SSR cr1 +#define PSSR cr2 + /* cr3 UNDEFINED */ +#define INTEVT cr4 +#define EXPEVT cr5 +#define PEXPEVT cr6 +#define TRA cr7 +#define SPC cr8 +#define PSPC cr9 +#define RESVEC cr10 +#define VBR cr11 + /* cr12 UNDEFINED */ +#define TEA cr13 + /* cr14-cr15 UNDEFINED */ +#define DCR cr16 +#define KCR0 cr17 +#define KCR1 cr18 + /* cr19-cr31 UNDEFINED */ + /* cr32-cr61 RESERVED */ +#define CTC cr62 +#define USR cr63 + +/* + * ABI dependent registers (general purpose set) + */ +#define RET r2 +#define ARG1 r2 +#define ARG2 r3 +#define ARG3 r4 +#define ARG4 r5 +#define ARG5 r6 +#define ARG6 r7 +#define SP r15 +#define LINK r18 +#define ZERO r63 + +/* + * Status register defines: used only by assembly sources (and + * syntax independednt) + */ +#define SR_RESET_VAL 0x0000000050008000 +#define SR_HARMLESS 0x00000000500080f0 /* Write ignores for most */ +#define SR_ENABLE_FPU 0xffffffffffff7fff /* AND with this */ + +#if defined (CONFIG_SH64_SR_WATCH) +#define SR_ENABLE_MMU 0x0000000084000000 /* OR with this */ +#else +#define SR_ENABLE_MMU 0x0000000080000000 /* OR with this */ +#endif + +#define SR_UNBLOCK_EXC 0xffffffffefffffff /* AND with this */ +#define SR_BLOCK_EXC 0x0000000010000000 /* OR with this */ + +#else /* Not __ASSEMBLY__ syntax */ + +/* +** Stringify reg. name +*/ +#define __str(x) #x + +/* Stringify control register names for use in inline assembly */ +#define __SR __str(SR) +#define __SSR __str(SSR) +#define __PSSR __str(PSSR) +#define __INTEVT __str(INTEVT) +#define __EXPEVT __str(EXPEVT) +#define __PEXPEVT __str(PEXPEVT) +#define __TRA __str(TRA) +#define __SPC __str(SPC) +#define __PSPC __str(PSPC) +#define __RESVEC __str(RESVEC) +#define __VBR __str(VBR) +#define __TEA __str(TEA) +#define __DCR __str(DCR) +#define __KCR0 __str(KCR0) +#define __KCR1 __str(KCR1) +#define __CTC __str(CTC) +#define __USR __str(USR) + +#endif /* __ASSEMBLY__ */ +#endif /* __ASM_SH_CPU_SH5_REGISTERS_H */ diff --git a/include/asm-sh/cpu-sh5/rtc.h b/include/asm-sh/cpu-sh5/rtc.h new file mode 100644 index 00000000000..12ea0ed144e --- /dev/null +++ b/include/asm-sh/cpu-sh5/rtc.h @@ -0,0 +1,8 @@ +#ifndef __ASM_SH_CPU_SH5_RTC_H +#define __ASM_SH_CPU_SH5_RTC_H + +#define rtc_reg_size sizeof(u32) +#define RTC_BIT_INVERTED 0 /* The SH-5 RTC is surprisingly sane! */ +#define RTC_DEF_CAPABILITIES RTC_CAP_4_DIGIT_YEAR + +#endif /* __ASM_SH_CPU_SH5_RTC_H */ diff --git a/include/asm-sh/cpu-sh5/timer.h b/include/asm-sh/cpu-sh5/timer.h new file mode 100644 index 00000000000..88da9b341a3 --- /dev/null +++ b/include/asm-sh/cpu-sh5/timer.h @@ -0,0 +1,4 @@ +#ifndef __ASM_SH_CPU_SH5_TIMER_H +#define __ASM_SH_CPU_SH5_TIMER_H + +#endif /* __ASM_SH_CPU_SH5_TIMER_H */ diff --git a/include/asm-sh/delay.h b/include/asm-sh/delay.h index db599b2a5a9..d5d46404100 100644 --- a/include/asm-sh/delay.h +++ b/include/asm-sh/delay.h @@ -6,22 +6,26 @@ * * Delay routines calling functions in arch/sh/lib/delay.c */ - + extern void __bad_udelay(void); extern void __bad_ndelay(void); extern void __udelay(unsigned long usecs); extern void __ndelay(unsigned long nsecs); -extern void __const_udelay(unsigned long usecs); +extern void __const_udelay(unsigned long xloops); extern void __delay(unsigned long loops); +#ifdef CONFIG_SUPERH32 #define udelay(n) (__builtin_constant_p(n) ? \ ((n) > 20000 ? __bad_udelay() : __const_udelay((n) * 0x10c6ul)) : \ __udelay(n)) - #define ndelay(n) (__builtin_constant_p(n) ? \ ((n) > 20000 ? __bad_ndelay() : __const_udelay((n) * 5ul)) : \ __ndelay(n)) +#else +extern void udelay(unsigned long usecs); +extern void ndelay(unsigned long nsecs); +#endif #endif /* __ASM_SH_DELAY_H */ diff --git a/include/asm-sh/dma-mapping.h b/include/asm-sh/dma-mapping.h index fcea067f7a9..22cc419389f 100644 --- a/include/asm-sh/dma-mapping.h +++ b/include/asm-sh/dma-mapping.h @@ -8,11 +8,6 @@ extern struct bus_type pci_bus_type; -/* arch/sh/mm/consistent.c */ -extern void *consistent_alloc(gfp_t gfp, size_t size, dma_addr_t *handle); -extern void consistent_free(void *vaddr, size_t size); -extern void consistent_sync(void *vaddr, size_t size, int direction); - #define dma_supported(dev, mask) (1) static inline int dma_set_mask(struct device *dev, u64 mask) @@ -25,44 +20,19 @@ static inline int dma_set_mask(struct device *dev, u64 mask) return 0; } -static inline void *dma_alloc_coherent(struct device *dev, size_t size, - dma_addr_t *dma_handle, gfp_t flag) -{ - if (sh_mv.mv_consistent_alloc) { - void *ret; +void *dma_alloc_coherent(struct device *dev, size_t size, + dma_addr_t *dma_handle, gfp_t flag); - ret = sh_mv.mv_consistent_alloc(dev, size, dma_handle, flag); - if (ret != NULL) - return ret; - } - - return consistent_alloc(flag, size, dma_handle); -} - -static inline void dma_free_coherent(struct device *dev, size_t size, - void *vaddr, dma_addr_t dma_handle) -{ - if (sh_mv.mv_consistent_free) { - int ret; - - ret = sh_mv.mv_consistent_free(dev, size, vaddr, dma_handle); - if (ret == 0) - return; - } +void dma_free_coherent(struct device *dev, size_t size, + void *vaddr, dma_addr_t dma_handle); - consistent_free(vaddr, size); -} +void dma_cache_sync(struct device *dev, void *vaddr, size_t size, + enum dma_data_direction dir); #define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f) #define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h) #define dma_is_consistent(d, h) (1) -static inline void dma_cache_sync(struct device *dev, void *vaddr, size_t size, - enum dma_data_direction dir) -{ - consistent_sync(vaddr, size, (int)dir); -} - static inline dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size, enum dma_data_direction dir) @@ -205,4 +175,18 @@ static inline int dma_mapping_error(dma_addr_t dma_addr) { return dma_addr == 0; } + +#define ARCH_HAS_DMA_DECLARE_COHERENT_MEMORY + +extern int +dma_declare_coherent_memory(struct device *dev, dma_addr_t bus_addr, + dma_addr_t device_addr, size_t size, int flags); + +extern void +dma_release_declared_memory(struct device *dev); + +extern void * +dma_mark_declared_memory_occupied(struct device *dev, + dma_addr_t device_addr, size_t size); + #endif /* __ASM_SH_DMA_MAPPING_H */ diff --git a/include/asm-sh/elf.h b/include/asm-sh/elf.h index 12cc4b392bf..05092da1aa5 100644 --- a/include/asm-sh/elf.h +++ b/include/asm-sh/elf.h @@ -5,7 +5,7 @@ #include <asm/ptrace.h> #include <asm/user.h> -/* SH relocation types */ +/* SH (particularly SHcompact) relocation types */ #define R_SH_NONE 0 #define R_SH_DIR32 1 #define R_SH_REL32 2 @@ -43,6 +43,11 @@ #define R_SH_RELATIVE 165 #define R_SH_GOTOFF 166 #define R_SH_GOTPC 167 +/* SHmedia relocs */ +#define R_SH_IMM_LOW16 246 +#define R_SH_IMM_LOW16_PCREL 247 +#define R_SH_IMM_MEDLOW16 248 +#define R_SH_IMM_MEDLOW16_PCREL 249 /* Keep this the last entry. */ #define R_SH_NUM 256 @@ -58,11 +63,6 @@ typedef elf_greg_t elf_gregset_t[ELF_NGREG]; 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 ) - -/* * These are used to set parameters in the core dumps. */ #define ELF_CLASS ELFCLASS32 @@ -73,6 +73,12 @@ typedef struct user_fpu_struct elf_fpregset_t; #endif #define ELF_ARCH EM_SH +#ifdef __KERNEL__ +/* + * 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 USE_ELF_CORE_DUMP #define ELF_EXEC_PAGESIZE PAGE_SIZE @@ -83,7 +89,6 @@ typedef struct user_fpu_struct elf_fpregset_t; #define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3) - #define ELF_CORE_COPY_REGS(_dest,_regs) \ memcpy((char *) &_dest, (char *) _regs, \ sizeof(struct pt_regs)); @@ -101,16 +106,38 @@ typedef struct user_fpu_struct elf_fpregset_t; For the moment, we have only optimizations for the Intel generations, but that could change... */ -#define ELF_PLATFORM (NULL) +#define ELF_PLATFORM (utsname()->machine) +#ifdef __SH5__ +#define ELF_PLAT_INIT(_r, load_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]=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->regs[15]=0; \ + _r->regs[16]=0; _r->regs[17]=0; _r->regs[18]=0; _r->regs[19]=0; \ + _r->regs[20]=0; _r->regs[21]=0; _r->regs[22]=0; _r->regs[23]=0; \ + _r->regs[24]=0; _r->regs[25]=0; _r->regs[26]=0; _r->regs[27]=0; \ + _r->regs[28]=0; _r->regs[29]=0; _r->regs[30]=0; _r->regs[31]=0; \ + _r->regs[32]=0; _r->regs[33]=0; _r->regs[34]=0; _r->regs[35]=0; \ + _r->regs[36]=0; _r->regs[37]=0; _r->regs[38]=0; _r->regs[39]=0; \ + _r->regs[40]=0; _r->regs[41]=0; _r->regs[42]=0; _r->regs[43]=0; \ + _r->regs[44]=0; _r->regs[45]=0; _r->regs[46]=0; _r->regs[47]=0; \ + _r->regs[48]=0; _r->regs[49]=0; _r->regs[50]=0; _r->regs[51]=0; \ + _r->regs[52]=0; _r->regs[53]=0; _r->regs[54]=0; _r->regs[55]=0; \ + _r->regs[56]=0; _r->regs[57]=0; _r->regs[58]=0; _r->regs[59]=0; \ + _r->regs[60]=0; _r->regs[61]=0; _r->regs[62]=0; \ + _r->tregs[0]=0; _r->tregs[1]=0; _r->tregs[2]=0; _r->tregs[3]=0; \ + _r->tregs[4]=0; _r->tregs[5]=0; _r->tregs[6]=0; _r->tregs[7]=0; \ + _r->sr = SR_FD | SR_MMU; } while (0) +#else #define ELF_PLAT_INIT(_r, load_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]=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) +#endif -#ifdef __KERNEL__ #define SET_PERSONALITY(ex, ibcs2) set_personality(PER_LINUX_32BIT) struct task_struct; extern int dump_task_regs (struct task_struct *, elf_gregset_t *); @@ -118,7 +145,6 @@ extern int dump_task_fpu (struct task_struct *, elf_fpregset_t *); #define ELF_CORE_COPY_TASK_REGS(tsk, elf_regs) dump_task_regs(tsk, elf_regs) #define ELF_CORE_COPY_FPREGS(tsk, elf_fpregs) dump_task_fpu(tsk, elf_fpregs) -#endif #ifdef CONFIG_VSYSCALL /* vDSO has arch_setup_additional_pages */ @@ -133,12 +159,35 @@ extern void __kernel_vsyscall; #define VDSO_BASE ((unsigned long)current->mm->context.vdso) #define VDSO_SYM(x) (VDSO_BASE + (unsigned long)(x)) +#define VSYSCALL_AUX_ENT \ + if (vdso_enabled) \ + NEW_AUX_ENT(AT_SYSINFO_EHDR, VDSO_BASE); +#else +#define VSYSCALL_AUX_ENT +#endif /* CONFIG_VSYSCALL */ + +#ifdef CONFIG_SH_FPU +#define FPU_AUX_ENT NEW_AUX_ENT(AT_FPUCW, FPSCR_INIT) +#else +#define FPU_AUX_ENT +#endif + +extern int l1i_cache_shape, l1d_cache_shape, l2_cache_shape; + /* update AT_VECTOR_SIZE_ARCH if the number of NEW_AUX_ENT entries changes */ #define ARCH_DLINFO \ do { \ - if (vdso_enabled) \ - NEW_AUX_ENT(AT_SYSINFO_EHDR, VDSO_BASE); \ + /* Optional FPU initialization */ \ + FPU_AUX_ENT; \ + \ + /* Optional vsyscall entry */ \ + VSYSCALL_AUX_ENT; \ + \ + /* Cache desc */ \ + NEW_AUX_ENT(AT_L1I_CACHESHAPE, l1i_cache_shape); \ + NEW_AUX_ENT(AT_L1D_CACHESHAPE, l1d_cache_shape); \ + NEW_AUX_ENT(AT_L2_CACHESHAPE, l2_cache_shape); \ } while (0) -#endif /* CONFIG_VSYSCALL */ +#endif /* __KERNEL__ */ #endif /* __ASM_SH_ELF_H */ diff --git a/include/asm-sh/fixmap.h b/include/asm-sh/fixmap.h index 8a566177ad9..721fcc4d5e9 100644 --- a/include/asm-sh/fixmap.h +++ b/include/asm-sh/fixmap.h @@ -49,6 +49,7 @@ enum fixed_addresses { #define FIX_N_COLOURS 16 FIX_CMAP_BEGIN, FIX_CMAP_END = FIX_CMAP_BEGIN + FIX_N_COLOURS, + 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, @@ -73,7 +74,11 @@ extern void __set_fixmap(enum fixed_addresses idx, * the start of the fixmap, and leave one page empty * at the top of mem.. */ +#ifdef CONFIG_SUPERH32 #define FIXADDR_TOP (P4SEG - PAGE_SIZE) +#else +#define FIXADDR_TOP (0xff000000 - PAGE_SIZE) +#endif #define FIXADDR_SIZE (__end_of_fixed_addresses << PAGE_SHIFT) #define FIXADDR_START (FIXADDR_TOP - FIXADDR_SIZE) diff --git a/include/asm-sh/flat.h b/include/asm-sh/flat.h index dc4f5950daf..0cc800299e0 100644 --- a/include/asm-sh/flat.h +++ b/include/asm-sh/flat.h @@ -19,6 +19,6 @@ #define flat_get_addr_from_rp(rp, relval, flags, p) get_unaligned(rp) #define flat_put_addr_at_rp(rp, val, relval) put_unaligned(val,rp) #define flat_get_relocate_addr(rel) (rel) -#define flat_set_persistent(relval, p) 0 +#define flat_set_persistent(relval, p) ({ (void)p; 0; }) #endif /* __ASM_SH_FLAT_H */ diff --git a/include/asm-sh/fpu.h b/include/asm-sh/fpu.h new file mode 100644 index 00000000000..f8429880a27 --- /dev/null +++ b/include/asm-sh/fpu.h @@ -0,0 +1,46 @@ +#ifndef __ASM_SH_FPU_H +#define __ASM_SH_FPU_H + +#define SR_FD 0x00008000 + +#ifndef __ASSEMBLY__ +#include <asm/ptrace.h> + +#ifdef CONFIG_SH_FPU +static inline void release_fpu(struct pt_regs *regs) +{ + regs->sr |= SR_FD; +} + +static inline void grab_fpu(struct pt_regs *regs) +{ + regs->sr &= ~SR_FD; +} + +struct task_struct; + +extern void save_fpu(struct task_struct *__tsk, struct pt_regs *regs); +#else +#define release_fpu(regs) do { } while (0) +#define grab_fpu(regs) do { } while (0) +#define save_fpu(tsk, regs) do { } while (0) +#endif + +extern int do_fpu_inst(unsigned short, struct pt_regs *); + +#define unlazy_fpu(tsk, regs) do { \ + if (test_tsk_thread_flag(tsk, TIF_USEDFPU)) { \ + save_fpu(tsk, regs); \ + } \ +} while (0) + +#define clear_fpu(tsk, regs) do { \ + if (test_tsk_thread_flag(tsk, TIF_USEDFPU)) { \ + clear_tsk_thread_flag(tsk, TIF_USEDFPU); \ + release_fpu(regs); \ + } \ +} while (0) + +#endif /* __ASSEMBLY__ */ + +#endif /* __ASM_SH_FPU_H */ diff --git a/include/asm-sh/hd64461.h b/include/asm-sh/hd64461.h index 342ca55a266..8c1353baf00 100644 --- a/include/asm-sh/hd64461.h +++ b/include/asm-sh/hd64461.h @@ -46,10 +46,10 @@ /* CPU Data Bus Control Register */ #define HD64461_SCPUCR (CONFIG_HD64461_IOBASE + 0x04) -/* Base Adress Register */ +/* Base Address Register */ #define HD64461_LCDCBAR (CONFIG_HD64461_IOBASE + 0x1000) -/* Line increment adress */ +/* Line increment address */ #define HD64461_LCDCLOR (CONFIG_HD64461_IOBASE + 0x1002) /* Controls LCD controller */ @@ -80,9 +80,9 @@ #define HD64461_LDR3 (CONFIG_HD64461_IOBASE + 0x101e) /* Palette Registers */ -#define HD64461_CPTWAR (CONFIG_HD64461_IOBASE + 0x1030) /* Color Palette Write Adress Register */ +#define HD64461_CPTWAR (CONFIG_HD64461_IOBASE + 0x1030) /* Color Palette Write Address Register */ #define HD64461_CPTWDR (CONFIG_HD64461_IOBASE + 0x1032) /* Color Palette Write Data Register */ -#define HD64461_CPTRAR (CONFIG_HD64461_IOBASE + 0x1034) /* Color Palette Read Adress Register */ +#define HD64461_CPTRAR (CONFIG_HD64461_IOBASE + 0x1034) /* Color Palette Read Address Register */ #define HD64461_CPTRDR (CONFIG_HD64461_IOBASE + 0x1036) /* Color Palette Read Data Register */ #define HD64461_GRDOR (CONFIG_HD64461_IOBASE + 0x1040) /* Display Resolution Offset Register */ @@ -97,8 +97,8 @@ #define HD64461_GRCFGR_COLORDEPTH8 0x01 /* Sets Colordepth 8 for Accelerator */ /* Line Drawing Registers */ -#define HD64461_LNSARH (CONFIG_HD64461_IOBASE + 0x1046) /* Line Start Adress Register (H) */ -#define HD64461_LNSARL (CONFIG_HD64461_IOBASE + 0x1048) /* Line Start Adress Register (L) */ +#define HD64461_LNSARH (CONFIG_HD64461_IOBASE + 0x1046) /* Line Start Address Register (H) */ +#define HD64461_LNSARL (CONFIG_HD64461_IOBASE + 0x1048) /* Line Start Address Register (L) */ #define HD64461_LNAXLR (CONFIG_HD64461_IOBASE + 0x104a) /* Axis Pixel Length Register */ #define HD64461_LNDGR (CONFIG_HD64461_IOBASE + 0x104c) /* Diagonal Register */ #define HD64461_LNAXR (CONFIG_HD64461_IOBASE + 0x104e) /* Axial Register */ @@ -106,16 +106,16 @@ #define HD64461_LNMDR (CONFIG_HD64461_IOBASE + 0x1052) /* Line Mode Register */ /* BitBLT Registers */ -#define HD64461_BBTSSARH (CONFIG_HD64461_IOBASE + 0x1054) /* Source Start Adress Register (H) */ -#define HD64461_BBTSSARL (CONFIG_HD64461_IOBASE + 0x1056) /* Source Start Adress Register (L) */ -#define HD64461_BBTDSARH (CONFIG_HD64461_IOBASE + 0x1058) /* Destination Start Adress Register (H) */ -#define HD64461_BBTDSARL (CONFIG_HD64461_IOBASE + 0x105a) /* Destination Start Adress Register (L) */ +#define HD64461_BBTSSARH (CONFIG_HD64461_IOBASE + 0x1054) /* Source Start Address Register (H) */ +#define HD64461_BBTSSARL (CONFIG_HD64461_IOBASE + 0x1056) /* Source Start Address Register (L) */ +#define HD64461_BBTDSARH (CONFIG_HD64461_IOBASE + 0x1058) /* Destination Start Address Register (H) */ +#define HD64461_BBTDSARL (CONFIG_HD64461_IOBASE + 0x105a) /* Destination Start Address Register (L) */ #define HD64461_BBTDWR (CONFIG_HD64461_IOBASE + 0x105c) /* Destination Block Width Register */ #define HD64461_BBTDHR (CONFIG_HD64461_IOBASE + 0x105e) /* Destination Block Height Register */ -#define HD64461_BBTPARH (CONFIG_HD64461_IOBASE + 0x1060) /* Pattern Start Adress Register (H) */ -#define HD64461_BBTPARL (CONFIG_HD64461_IOBASE + 0x1062) /* Pattern Start Adress Register (L) */ -#define HD64461_BBTMARH (CONFIG_HD64461_IOBASE + 0x1064) /* Mask Start Adress Register (H) */ -#define HD64461_BBTMARL (CONFIG_HD64461_IOBASE + 0x1066) /* Mask Start Adress Register (L) */ +#define HD64461_BBTPARH (CONFIG_HD64461_IOBASE + 0x1060) /* Pattern Start Address Register (H) */ +#define HD64461_BBTPARL (CONFIG_HD64461_IOBASE + 0x1062) /* Pattern Start Address Register (L) */ +#define HD64461_BBTMARH (CONFIG_HD64461_IOBASE + 0x1064) /* Mask Start Address Register (H) */ +#define HD64461_BBTMARL (CONFIG_HD64461_IOBASE + 0x1066) /* Mask Start Address Register (L) */ #define HD64461_BBTROPR (CONFIG_HD64461_IOBASE + 0x1068) /* ROP Register */ #define HD64461_BBTMDR (CONFIG_HD64461_IOBASE + 0x106a) /* BitBLT Mode Register */ diff --git a/include/asm-sh/hs7751rvoip.h b/include/asm-sh/hs7751rvoip.h deleted file mode 100644 index c4cff9d3392..00000000000 --- a/include/asm-sh/hs7751rvoip.h +++ /dev/null @@ -1,54 +0,0 @@ -#ifndef __ASM_SH_RENESAS_HS7751RVOIP_H -#define __ASM_SH_RENESAS_HS7751RVOIP_H - -/* - * linux/include/asm-sh/hs7751rvoip/hs7751rvoip.h - * - * Copyright (C) 2000 Atom Create Engineering Co., Ltd. - * - * Renesas Technology Sales HS7751RVoIP support - */ - -/* Box specific addresses. */ - -#define PA_BCR 0xa4000000 /* FPGA */ -#define PA_SLICCNTR1 0xa4000006 /* SLIC PIO Control 1 */ -#define PA_SLICCNTR2 0xa4000008 /* SLIC PIO Control 2 */ -#define PA_DMACNTR 0xa400000a /* USB DMA Control */ -#define PA_INPORTR 0xa400000c /* Input Port Register */ -#define PA_OUTPORTR 0xa400000e /* Output Port Reguster */ -#define PA_VERREG 0xa4000014 /* FPGA Version Register */ - -#define PA_IDE_OFFSET 0x1f0 /* CF IDE Offset */ - -#define IRLCNTR1 (PA_BCR + 0) /* Interrupt Control Register1 */ -#define IRLCNTR2 (PA_BCR + 2) /* Interrupt Control Register2 */ -#define IRLCNTR3 (PA_BCR + 4) /* Interrupt Control Register3 */ -#define IRLCNTR4 (PA_BCR + 16) /* Interrupt Control Register4 */ -#define IRLCNTR5 (PA_BCR + 18) /* Interrupt Control Register5 */ - -#define IRQ_PCIETH 6 /* PCI Ethernet IRQ */ -#define IRQ_PCIHUB 7 /* PCI Ethernet Hub IRQ */ -#define IRQ_USBCOM 8 /* USB Comunication IRQ */ -#define IRQ_USBCON 9 /* USB Connect IRQ */ -#define IRQ_USBDMA 10 /* USB DMA IRQ */ -#define IRQ_CFCARD 11 /* CF Card IRQ */ -#define IRQ_PCMCIA 12 /* PCMCIA IRQ */ -#define IRQ_PCISLOT 13 /* PCI Slot #1 IRQ */ -#define IRQ_ONHOOK1 0 /* ON HOOK1 IRQ */ -#define IRQ_OFFHOOK1 1 /* OFF HOOK1 IRQ */ -#define IRQ_ONHOOK2 2 /* ON HOOK2 IRQ */ -#define IRQ_OFFHOOK2 3 /* OFF HOOK2 IRQ */ -#define IRQ_RINGING 4 /* Ringing IRQ */ -#define IRQ_CODEC 5 /* CODEC IRQ */ - -#define __IO_PREFIX hs7751rvoip -#include <asm/io_generic.h> - -/* arch/sh/boards/renesas/hs7751rvoip/irq.c */ -void init_hs7751rvoip_IRQ(void); - -/* arch/sh/boards/renesas/hs7751rvoip/io.c */ -void *hs7751rvoip_ioremap(unsigned long, unsigned long); - -#endif /* __ASM_SH_RENESAS_HS7751RVOIP */ diff --git a/include/asm-sh/hw_irq.h b/include/asm-sh/hw_irq.h index cb0b6c9f702..c958fdaa009 100644 --- a/include/asm-sh/hw_irq.h +++ b/include/asm-sh/hw_irq.h @@ -33,13 +33,6 @@ struct intc_vect { #define INTC_VECT(enum_id, vect) { enum_id, vect } #define INTC_IRQ(enum_id, irq) INTC_VECT(enum_id, irq2evt(irq)) -struct intc_prio { - intc_enum enum_id; - unsigned char priority; -}; - -#define INTC_PRIO(enum_id, prio) { enum_id, prio } - struct intc_group { intc_enum enum_id; intc_enum enum_ids[32]; @@ -79,8 +72,6 @@ struct intc_desc { unsigned int nr_vectors; struct intc_group *groups; unsigned int nr_groups; - struct intc_prio *priorities; - unsigned int nr_priorities; struct intc_mask_reg *mask_regs; unsigned int nr_mask_regs; struct intc_prio_reg *prio_regs; @@ -92,10 +83,9 @@ struct intc_desc { #define _INTC_ARRAY(a) a, sizeof(a)/sizeof(*a) #define DECLARE_INTC_DESC(symbol, chipname, vectors, groups, \ - priorities, mask_regs, prio_regs, sense_regs) \ + mask_regs, prio_regs, sense_regs) \ struct intc_desc symbol __initdata = { \ _INTC_ARRAY(vectors), _INTC_ARRAY(groups), \ - _INTC_ARRAY(priorities), \ _INTC_ARRAY(mask_regs), _INTC_ARRAY(prio_regs), \ _INTC_ARRAY(sense_regs), \ chipname, \ diff --git a/include/asm-sh/io.h b/include/asm-sh/io.h index 6ed34d8eac5..94900c08951 100644 --- a/include/asm-sh/io.h +++ b/include/asm-sh/io.h @@ -191,6 +191,8 @@ __BUILD_MEMORY_STRING(w, u16) #define mmiowb() wmb() /* synco on SH-4A, otherwise a nop */ +#define IO_SPACE_LIMIT 0xffffffff + /* * This function provides a method for the generic case where a board-specific * ioport_map simply needs to return the port + some arbitrary port base. @@ -226,6 +228,11 @@ static inline unsigned int ctrl_inl(unsigned long addr) return *(volatile unsigned long*)addr; } +static inline unsigned long long ctrl_inq(unsigned long addr) +{ + return *(volatile unsigned long long*)addr; +} + static inline void ctrl_outb(unsigned char b, unsigned long addr) { *(volatile unsigned char*)addr = b; @@ -241,49 +248,52 @@ static inline void ctrl_outl(unsigned int b, unsigned long addr) *(volatile unsigned long*)addr = b; } +static inline void ctrl_outq(unsigned long long b, unsigned long addr) +{ + *(volatile unsigned long long*)addr = b; +} + static inline void ctrl_delay(void) { +#ifdef P2SEG ctrl_inw(P2SEG); +#endif } -#define IO_SPACE_LIMIT 0xffffffff +/* Quad-word real-mode I/O, don't ask.. */ +unsigned long long peek_real_address_q(unsigned long long addr); +unsigned long long poke_real_address_q(unsigned long long addr, + unsigned long long val); -#ifdef CONFIG_MMU -/* - * Change virtual addresses to physical addresses and vv. - * These are trivial on the 1:1 Linux/SuperH mapping - */ -static inline unsigned long virt_to_phys(volatile void *address) -{ - return PHYSADDR(address); -} +/* arch/sh/mm/ioremap_64.c */ +unsigned long onchip_remap(unsigned long addr, unsigned long size, + const char *name); +extern void onchip_unmap(unsigned long vaddr); -static inline void *phys_to_virt(unsigned long address) -{ - return (void *)P1SEGADDR(address); -} -#else -#define phys_to_virt(address) ((void *)(address)) +#if !defined(CONFIG_MMU) #define virt_to_phys(address) ((unsigned long)(address)) +#define phys_to_virt(address) ((void *)(address)) +#else +#define virt_to_phys(address) (__pa(address)) +#define phys_to_virt(address) (__va(address)) #endif /* - * readX/writeX() are used to access memory mapped devices. On some - * architectures the memory mapped IO stuff needs to be accessed - * differently. On the x86 architecture, we just read/write the - * memory location directly. + * On 32-bit SH, we traditionally have the whole physical address space + * mapped at all times (as MIPS does), so "ioremap()" and "iounmap()" do + * not need to do anything but place the address in the proper segment. + * This is true for P1 and P2 addresses, as well as some P3 ones. + * However, most of the P3 addresses and newer cores using extended + * addressing need to map through page tables, so the ioremap() + * implementation becomes a bit more complicated. * - * On SH, we traditionally have the whole physical address space mapped - * at all times (as MIPS does), so "ioremap()" and "iounmap()" do not - * need to do anything but place the address in the proper segment. This - * is true for P1 and P2 addresses, as well as some P3 ones. However, - * most of the P3 addresses and newer cores using extended addressing - * need to map through page tables, so the ioremap() implementation - * becomes a bit more complicated. See arch/sh/mm/ioremap.c for - * additional notes on this. + * See arch/sh/mm/ioremap.c for additional notes on this. * * We cheat a bit and always return uncachable areas until we've fixed * the drivers to handle caching properly. + * + * On the SH-5 the concept of segmentation in the 1:1 PXSEG sense simply + * doesn't exist, so everything must go through page tables. */ #ifdef CONFIG_MMU void __iomem *__ioremap(unsigned long offset, unsigned long size, @@ -297,6 +307,7 @@ void __iounmap(void __iomem *addr); static inline void __iomem * __ioremap_mode(unsigned long offset, unsigned long size, unsigned long flags) { +#ifdef CONFIG_SUPERH32 unsigned long last_addr = offset + size - 1; /* @@ -311,6 +322,7 @@ __ioremap_mode(unsigned long offset, unsigned long size, unsigned long flags) return (void __iomem *)P2SEGADDR(offset); } +#endif return __ioremap(offset, size, flags); } diff --git a/include/asm-sh/irqflags.h b/include/asm-sh/irqflags.h index 9dedc1b693e..46e71da5be6 100644 --- a/include/asm-sh/irqflags.h +++ b/include/asm-sh/irqflags.h @@ -1,81 +1,11 @@ #ifndef __ASM_SH_IRQFLAGS_H #define __ASM_SH_IRQFLAGS_H -static inline void raw_local_irq_enable(void) -{ - unsigned long __dummy0, __dummy1; - - __asm__ __volatile__ ( - "stc sr, %0\n\t" - "and %1, %0\n\t" -#ifdef CONFIG_CPU_HAS_SR_RB - "stc r6_bank, %1\n\t" - "or %1, %0\n\t" +#ifdef CONFIG_SUPERH32 +#include "irqflags_32.h" +#else +#include "irqflags_64.h" #endif - "ldc %0, sr\n\t" - : "=&r" (__dummy0), "=r" (__dummy1) - : "1" (~0x000000f0) - : "memory" - ); -} - -static inline void raw_local_irq_disable(void) -{ - unsigned long flags; - - __asm__ __volatile__ ( - "stc sr, %0\n\t" - "or #0xf0, %0\n\t" - "ldc %0, sr\n\t" - : "=&z" (flags) - : /* no inputs */ - : "memory" - ); -} - -static inline void set_bl_bit(void) -{ - unsigned long __dummy0, __dummy1; - - __asm__ __volatile__ ( - "stc sr, %0\n\t" - "or %2, %0\n\t" - "and %3, %0\n\t" - "ldc %0, sr\n\t" - : "=&r" (__dummy0), "=r" (__dummy1) - : "r" (0x10000000), "r" (0xffffff0f) - : "memory" - ); -} - -static inline void clear_bl_bit(void) -{ - unsigned long __dummy0, __dummy1; - - __asm__ __volatile__ ( - "stc sr, %0\n\t" - "and %2, %0\n\t" - "ldc %0, sr\n\t" - : "=&r" (__dummy0), "=r" (__dummy1) - : "1" (~0x10000000) - : "memory" - ); -} - -static inline unsigned long __raw_local_save_flags(void) -{ - unsigned long flags; - - __asm__ __volatile__ ( - "stc sr, %0\n\t" - "and #0xf0, %0\n\t" - : "=&z" (flags) - : /* no inputs */ - : "memory" - ); - - return flags; -} #define raw_local_save_flags(flags) \ do { (flags) = __raw_local_save_flags(); } while (0) @@ -92,25 +22,6 @@ static inline int raw_irqs_disabled(void) return raw_irqs_disabled_flags(flags); } -static inline unsigned long __raw_local_irq_save(void) -{ - unsigned long flags, __dummy; - - __asm__ __volatile__ ( - "stc sr, %1\n\t" - "mov %1, %0\n\t" - "or #0xf0, %0\n\t" - "ldc %0, sr\n\t" - "mov %1, %0\n\t" - "and #0xf0, %0\n\t" - : "=&z" (flags), "=&r" (__dummy) - : /* no inputs */ - : "memory" - ); - - return flags; -} - #define raw_local_irq_save(flags) \ do { (flags) = __raw_local_irq_save(); } while (0) diff --git a/include/asm-sh/irqflags_32.h b/include/asm-sh/irqflags_32.h new file mode 100644 index 00000000000..60218f54134 --- /dev/null +++ b/include/asm-sh/irqflags_32.h @@ -0,0 +1,99 @@ +#ifndef __ASM_SH_IRQFLAGS_32_H +#define __ASM_SH_IRQFLAGS_32_H + +static inline void raw_local_irq_enable(void) +{ + unsigned long __dummy0, __dummy1; + + __asm__ __volatile__ ( + "stc sr, %0\n\t" + "and %1, %0\n\t" +#ifdef CONFIG_CPU_HAS_SR_RB + "stc r6_bank, %1\n\t" + "or %1, %0\n\t" +#endif + "ldc %0, sr\n\t" + : "=&r" (__dummy0), "=r" (__dummy1) + : "1" (~0x000000f0) + : "memory" + ); +} + +static inline void raw_local_irq_disable(void) +{ + unsigned long flags; + + __asm__ __volatile__ ( + "stc sr, %0\n\t" + "or #0xf0, %0\n\t" + "ldc %0, sr\n\t" + : "=&z" (flags) + : /* no inputs */ + : "memory" + ); +} + +static inline void set_bl_bit(void) +{ + unsigned long __dummy0, __dummy1; + + __asm__ __volatile__ ( + "stc sr, %0\n\t" + "or %2, %0\n\t" + "and %3, %0\n\t" + "ldc %0, sr\n\t" + : "=&r" (__dummy0), "=r" (__dummy1) + : "r" (0x10000000), "r" (0xffffff0f) + : "memory" + ); +} + +static inline void clear_bl_bit(void) +{ + unsigned long __dummy0, __dummy1; + + __asm__ __volatile__ ( + "stc sr, %0\n\t" + "and %2, %0\n\t" + "ldc %0, sr\n\t" + : "=&r" (__dummy0), "=r" (__dummy1) + : "1" (~0x10000000) + : "memory" + ); +} + +static inline unsigned long __raw_local_save_flags(void) +{ + unsigned long flags; + + __asm__ __volatile__ ( + "stc sr, %0\n\t" + "and #0xf0, %0\n\t" + : "=&z" (flags) + : /* no inputs */ + : "memory" + ); + + return flags; +} + +static inline unsigned long __raw_local_irq_save(void) +{ + unsigned long flags, __dummy; + + __asm__ __volatile__ ( + "stc sr, %1\n\t" + "mov %1, %0\n\t" + "or #0xf0, %0\n\t" + "ldc %0, sr\n\t" + "mov %1, %0\n\t" + "and #0xf0, %0\n\t" + : "=&z" (flags), "=&r" (__dummy) + : /* no inputs */ + : "memory" + ); + + return flags; +} + +#endif /* __ASM_SH_IRQFLAGS_32_H */ diff --git a/include/asm-sh/irqflags_64.h b/include/asm-sh/irqflags_64.h new file mode 100644 index 00000000000..4f6b8a56e7b --- /dev/null +++ b/include/asm-sh/irqflags_64.h @@ -0,0 +1,85 @@ +#ifndef __ASM_SH_IRQFLAGS_64_H +#define __ASM_SH_IRQFLAGS_64_H + +#include <asm/cpu/registers.h> + +#define SR_MASK_LL 0x00000000000000f0LL +#define SR_BL_LL 0x0000000010000000LL + +static inline void raw_local_irq_enable(void) +{ + unsigned long long __dummy0, __dummy1 = ~SR_MASK_LL; + + __asm__ __volatile__("getcon " __SR ", %0\n\t" + "and %0, %1, %0\n\t" + "putcon %0, " __SR "\n\t" + : "=&r" (__dummy0) + : "r" (__dummy1)); +} + +static inline void raw_local_irq_disable(void) +{ + unsigned long long __dummy0, __dummy1 = SR_MASK_LL; + + __asm__ __volatile__("getcon " __SR ", %0\n\t" + "or %0, %1, %0\n\t" + "putcon %0, " __SR "\n\t" + : "=&r" (__dummy0) + : "r" (__dummy1)); +} + +static inline void set_bl_bit(void) +{ + unsigned long long __dummy0, __dummy1 = SR_BL_LL; + + __asm__ __volatile__("getcon " __SR ", %0\n\t" + "or %0, %1, %0\n\t" + "putcon %0, " __SR "\n\t" + : "=&r" (__dummy0) + : "r" (__dummy1)); + +} + +static inline void clear_bl_bit(void) +{ + unsigned long long __dummy0, __dummy1 = ~SR_BL_LL; + + __asm__ __volatile__("getcon " __SR ", %0\n\t" + "and %0, %1, %0\n\t" + "putcon %0, " __SR "\n\t" + : "=&r" (__dummy0) + : "r" (__dummy1)); +} + +static inline unsigned long __raw_local_save_flags(void) +{ + unsigned long long __dummy = SR_MASK_LL; + unsigned long flags; + + __asm__ __volatile__ ( + "getcon " __SR ", %0\n\t" + "and %0, %1, %0" + : "=&r" (flags) + : "r" (__dummy)); + + return flags; +} + +static inline unsigned long __raw_local_irq_save(void) +{ + unsigned long long __dummy0, __dummy1 = SR_MASK_LL; + unsigned long flags; + + __asm__ __volatile__ ( + "getcon " __SR ", %1\n\t" + "or %1, r63, %0\n\t" + "or %1, %2, %1\n\t" + "putcon %1, " __SR "\n\t" + "and %0, %2, %0" + : "=&r" (flags), "=&r" (__dummy0) + : "r" (__dummy1)); + + return flags; +} + +#endif /* __ASM_SH_IRQFLAGS_64_H */ diff --git a/include/asm-sh/machvec.h b/include/asm-sh/machvec.h index 088698bacf2..b2e4124070a 100644 --- a/include/asm-sh/machvec.h +++ b/include/asm-sh/machvec.h @@ -56,9 +56,6 @@ struct sh_machine_vector { void (*mv_heartbeat)(void); - void *(*mv_consistent_alloc)(struct device *, size_t, dma_addr_t *, gfp_t); - int (*mv_consistent_free)(struct device *, size_t, void *, dma_addr_t); - void __iomem *(*mv_ioport_map)(unsigned long port, unsigned int size); void (*mv_ioport_unmap)(void __iomem *); }; @@ -68,6 +65,6 @@ extern struct sh_machine_vector sh_mv; #define get_system_type() sh_mv.mv_name #define __initmv \ - __attribute_used__ __attribute__((__section__ (".machvec.init"))) + __used __section(.machvec.init) #endif /* _ASM_SH_MACHVEC_H */ diff --git a/include/asm-sh/microdev.h b/include/asm-sh/microdev.h index 018332a9e59..1aed15856e1 100644 --- a/include/asm-sh/microdev.h +++ b/include/asm-sh/microdev.h @@ -17,7 +17,7 @@ extern void microdev_print_fpga_intc_status(void); /* * The following are useful macros for manipulating the interrupt * controller (INTC) on the CPU-board FPGA. should be noted that there - * is an INTC on the FPGA, and a seperate INTC on the SH4-202 core - + * is an INTC on the FPGA, and a separate INTC on the SH4-202 core - * these are two different things, both of which need to be prorammed to * correctly route - unfortunately, they have the same name and * abbreviations! @@ -25,7 +25,7 @@ extern void microdev_print_fpga_intc_status(void); #define MICRODEV_FPGA_INTC_BASE 0xa6110000ul /* INTC base address on CPU-board FPGA */ #define MICRODEV_FPGA_INTENB_REG (MICRODEV_FPGA_INTC_BASE+0ul) /* Interrupt Enable Register on INTC on CPU-board FPGA */ #define MICRODEV_FPGA_INTDSB_REG (MICRODEV_FPGA_INTC_BASE+8ul) /* Interrupt Disable Register on INTC on CPU-board FPGA */ -#define MICRODEV_FPGA_INTC_MASK(n) (1ul<<(n)) /* Interupt mask to enable/disable INTC in CPU-board FPGA */ +#define MICRODEV_FPGA_INTC_MASK(n) (1ul<<(n)) /* Interrupt mask to enable/disable INTC in CPU-board FPGA */ #define MICRODEV_FPGA_INTPRI_REG(n) (MICRODEV_FPGA_INTC_BASE+0x10+((n)/8)*8)/* Interrupt Priority Register on INTC on CPU-board FPGA */ #define MICRODEV_FPGA_INTPRI_LEVEL(n,x) ((x)<<(((n)%8)*4)) /* MICRODEV_FPGA_INTPRI_LEVEL(int_number, int_level) */ #define MICRODEV_FPGA_INTPRI_MASK(n) (MICRODEV_FPGA_INTPRI_LEVEL((n),0xful)) /* Interrupt Priority Mask on INTC on CPU-board FPGA */ diff --git a/include/asm-sh/mmu_context.h b/include/asm-sh/mmu_context.h index 199662bb35c..fe58d00b250 100644 --- a/include/asm-sh/mmu_context.h +++ b/include/asm-sh/mmu_context.h @@ -1,13 +1,13 @@ /* * Copyright (C) 1999 Niibe Yutaka - * Copyright (C) 2003 - 2006 Paul Mundt + * Copyright (C) 2003 - 2007 Paul Mundt * * ASID handling idea taken from MIPS implementation. */ #ifndef __ASM_SH_MMU_CONTEXT_H #define __ASM_SH_MMU_CONTEXT_H -#ifdef __KERNEL__ +#ifdef __KERNEL__ #include <asm/cpu/mmu_context.h> #include <asm/tlbflush.h> #include <asm/uaccess.h> @@ -19,7 +19,6 @@ * (a) TLB cache version (or round, cycle whatever expression you like) * (b) ASID (Address Space IDentifier) */ - #define MMU_CONTEXT_ASID_MASK 0x000000ff #define MMU_CONTEXT_VERSION_MASK 0xffffff00 #define MMU_CONTEXT_FIRST_VERSION 0x00000100 @@ -28,10 +27,11 @@ /* ASID is 8-bit value, so it can't be 0x100 */ #define MMU_NO_ASID 0x100 -#define cpu_context(cpu, mm) ((mm)->context.id[cpu]) -#define cpu_asid(cpu, mm) (cpu_context((cpu), (mm)) & \ - MMU_CONTEXT_ASID_MASK) #define asid_cache(cpu) (cpu_data[cpu].asid_cache) +#define cpu_context(cpu, mm) ((mm)->context.id[cpu]) + +#define cpu_asid(cpu, mm) \ + (cpu_context((cpu), (mm)) & MMU_CONTEXT_ASID_MASK) /* * Virtual Page Number mask @@ -39,6 +39,12 @@ #define MMU_VPN_MASK 0xfffff000 #ifdef CONFIG_MMU +#if defined(CONFIG_SUPERH32) +#include "mmu_context_32.h" +#else +#include "mmu_context_64.h" +#endif + /* * Get MMU context if needed. */ @@ -59,6 +65,14 @@ static inline void get_mmu_context(struct mm_struct *mm, unsigned int cpu) */ flush_tlb_all(); +#ifdef CONFIG_SUPERH64 + /* + * The SH-5 cache uses the ASIDs, requiring both the I and D + * cache to be flushed when the ASID is exhausted. Weak. + */ + flush_cache_all(); +#endif + /* * Fix version; Note that we avoid version #0 * to distingush NO_CONTEXT. @@ -86,39 +100,6 @@ static inline int init_new_context(struct task_struct *tsk, } /* - * Destroy context related info for an mm_struct that is about - * to be put to rest. - */ -static inline void destroy_context(struct mm_struct *mm) -{ - /* Do nothing */ -} - -static inline void set_asid(unsigned long asid) -{ - unsigned long __dummy; - - __asm__ __volatile__ ("mov.l %2, %0\n\t" - "and %3, %0\n\t" - "or %1, %0\n\t" - "mov.l %0, %2" - : "=&r" (__dummy) - : "r" (asid), "m" (__m(MMU_PTEH)), - "r" (0xffffff00)); -} - -static inline unsigned long get_asid(void) -{ - unsigned long asid; - - __asm__ __volatile__ ("mov.l %1, %0" - : "=r" (asid) - : "m" (__m(MMU_PTEH))); - asid &= MMU_CONTEXT_ASID_MASK; - return asid; -} - -/* * After we have set current->mm to a new value, this activates * the context for the new mm so we see the new mappings. */ @@ -128,17 +109,6 @@ static inline void activate_context(struct mm_struct *mm, unsigned int cpu) set_asid(cpu_asid(cpu, mm)); } -/* MMU_TTB is used for optimizing the fault handling. */ -static inline void set_TTB(pgd_t *pgd) -{ - ctrl_outl((unsigned long)pgd, MMU_TTB); -} - -static inline pgd_t *get_TTB(void) -{ - return (pgd_t *)ctrl_inl(MMU_TTB); -} - static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, struct task_struct *tsk) @@ -153,17 +123,7 @@ static inline void switch_mm(struct mm_struct *prev, if (!cpu_test_and_set(cpu, next->cpu_vm_mask)) activate_context(next, cpu); } - -#define deactivate_mm(tsk,mm) do { } while (0) - -#define activate_mm(prev, next) \ - switch_mm((prev),(next),NULL) - -static inline void -enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk) -{ -} -#else /* !CONFIG_MMU */ +#else #define get_mmu_context(mm) do { } while (0) #define init_new_context(tsk,mm) (0) #define destroy_context(mm) do { } while (0) @@ -173,10 +133,11 @@ enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk) #define get_TTB() (0) #define activate_context(mm,cpu) do { } while (0) #define switch_mm(prev,next,tsk) do { } while (0) +#endif /* CONFIG_MMU */ + +#define activate_mm(prev, next) switch_mm((prev),(next),NULL) #define deactivate_mm(tsk,mm) do { } while (0) -#define activate_mm(prev,next) do { } while (0) #define enter_lazy_tlb(mm,tsk) do { } while (0) -#endif /* CONFIG_MMU */ #if defined(CONFIG_CPU_SH3) || defined(CONFIG_CPU_SH4) /* diff --git a/include/asm-sh/mmu_context_32.h b/include/asm-sh/mmu_context_32.h new file mode 100644 index 00000000000..f4f9aebd68b --- /dev/null +++ b/include/asm-sh/mmu_context_32.h @@ -0,0 +1,47 @@ +#ifndef __ASM_SH_MMU_CONTEXT_32_H +#define __ASM_SH_MMU_CONTEXT_32_H + +/* + * Destroy context related info for an mm_struct that is about + * to be put to rest. + */ +static inline void destroy_context(struct mm_struct *mm) +{ + /* Do nothing */ +} + +static inline void set_asid(unsigned long asid) +{ + unsigned long __dummy; + + __asm__ __volatile__ ("mov.l %2, %0\n\t" + "and %3, %0\n\t" + "or %1, %0\n\t" + "mov.l %0, %2" + : "=&r" (__dummy) + : "r" (asid), "m" (__m(MMU_PTEH)), + "r" (0xffffff00)); +} + +static inline unsigned long get_asid(void) +{ + unsigned long asid; + + __asm__ __volatile__ ("mov.l %1, %0" + : "=r" (asid) + : "m" (__m(MMU_PTEH))); + asid &= MMU_CONTEXT_ASID_MASK; + return asid; +} + +/* MMU_TTB is used for optimizing the fault handling. */ +static inline void set_TTB(pgd_t *pgd) +{ + ctrl_outl((unsigned long)pgd, MMU_TTB); +} + +static inline pgd_t *get_TTB(void) +{ + return (pgd_t *)ctrl_inl(MMU_TTB); +} +#endif /* __ASM_SH_MMU_CONTEXT_32_H */ diff --git a/include/asm-sh/mmu_context_64.h b/include/asm-sh/mmu_context_64.h new file mode 100644 index 00000000000..020be744b08 --- /dev/null +++ b/include/asm-sh/mmu_context_64.h @@ -0,0 +1,75 @@ +#ifndef __ASM_SH_MMU_CONTEXT_64_H +#define __ASM_SH_MMU_CONTEXT_64_H + +/* + * sh64-specific mmu_context interface. + * + * Copyright (C) 2000, 2001 Paolo Alberelli + * Copyright (C) 2003 - 2007 Paul Mundt + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#include <asm/cpu/registers.h> +#include <asm/cacheflush.h> + +#define SR_ASID_MASK 0xffffffffff00ffffULL +#define SR_ASID_SHIFT 16 + +/* + * Destroy context related info for an mm_struct that is about + * to be put to rest. + */ +static inline void destroy_context(struct mm_struct *mm) +{ + /* Well, at least free TLB entries */ + flush_tlb_mm(mm); +} + +static inline unsigned long get_asid(void) +{ + unsigned long long sr; + + asm volatile ("getcon " __SR ", %0\n\t" + : "=r" (sr)); + + sr = (sr >> SR_ASID_SHIFT) & MMU_CONTEXT_ASID_MASK; + return (unsigned long) sr; +} + +/* Set ASID into SR */ +static inline void set_asid(unsigned long asid) +{ + unsigned long long sr, pc; + + asm volatile ("getcon " __SR ", %0" : "=r" (sr)); + + sr = (sr & SR_ASID_MASK) | (asid << SR_ASID_SHIFT); + + /* + * It is possible that this function may be inlined and so to avoid + * the assembler reporting duplicate symbols we make use of the + * gas trick of generating symbols using numerics and forward + * reference. + */ + asm volatile ("movi 1, %1\n\t" + "shlli %1, 28, %1\n\t" + "or %0, %1, %1\n\t" + "putcon %1, " __SR "\n\t" + "putcon %0, " __SSR "\n\t" + "movi 1f, %1\n\t" + "ori %1, 1 , %1\n\t" + "putcon %1, " __SPC "\n\t" + "rte\n" + "1:\n\t" + : "=r" (sr), "=r" (pc) : "0" (sr)); +} + +/* No spare register to twiddle, so use a software cache */ +extern pgd_t *mmu_pdtp_cache; + +#define set_TTB(pgd) (mmu_pdtp_cache = (pgd)) +#define get_TTB() (mmu_pdtp_cache) + +#endif /* __ASM_SH_MMU_CONTEXT_64_H */ diff --git a/include/asm-sh/module.h b/include/asm-sh/module.h index 118d5a2b228..46eccd33166 100644 --- a/include/asm-sh/module.h +++ b/include/asm-sh/module.h @@ -20,6 +20,8 @@ struct mod_arch_specific { # define MODULE_PROC_FAMILY "SH3LE " # elif defined CONFIG_CPU_SH4 # define MODULE_PROC_FAMILY "SH4LE " +# elif defined CONFIG_CPU_SH5 +# define MODULE_PROC_FAMILY "SH5LE " # else # error unknown processor family # endif @@ -30,6 +32,8 @@ struct mod_arch_specific { # define MODULE_PROC_FAMILY "SH3BE " # elif defined CONFIG_CPU_SH4 # define MODULE_PROC_FAMILY "SH4BE " +# elif defined CONFIG_CPU_SH5 +# define MODULE_PROC_FAMILY "SH5BE " # else # error unknown processor family # endif diff --git a/include/asm-sh/page.h b/include/asm-sh/page.h index d00a8fde7c7..002e64a4f04 100644 --- a/include/asm-sh/page.h +++ b/include/asm-sh/page.h @@ -5,13 +5,7 @@ * Copyright (C) 1999 Niibe Yutaka */ -/* - [ P0/U0 (virtual) ] 0x00000000 <------ User space - [ P1 (fixed) cached ] 0x80000000 <------ Kernel space - [ P2 (fixed) non-cachable] 0xA0000000 <------ Physical access - [ P3 (virtual) cached] 0xC0000000 <------ vmalloced area - [ P4 control ] 0xE0000000 - */ +#include <linux/const.h> #ifdef __KERNEL__ @@ -26,15 +20,13 @@ # error "Bogus kernel page size?" #endif -#ifdef __ASSEMBLY__ -#define PAGE_SIZE (1 << PAGE_SHIFT) -#else -#define PAGE_SIZE (1UL << PAGE_SHIFT) -#endif - +#define PAGE_SIZE (_AC(1, UL) << PAGE_SHIFT) #define PAGE_MASK (~(PAGE_SIZE-1)) #define PTE_MASK PAGE_MASK +/* to align the pointer to the (next) page boundary */ +#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK) + #if defined(CONFIG_HUGETLB_PAGE_SIZE_64K) #define HPAGE_SHIFT 16 #elif defined(CONFIG_HUGETLB_PAGE_SIZE_256K) @@ -45,6 +37,8 @@ #define HPAGE_SHIFT 22 #elif defined(CONFIG_HUGETLB_PAGE_SIZE_64MB) #define HPAGE_SHIFT 26 +#elif defined(CONFIG_HUGETLB_PAGE_SIZE_512MB) +#define HPAGE_SHIFT 29 #endif #ifdef CONFIG_HUGETLB_PAGE @@ -55,20 +49,12 @@ #ifndef __ASSEMBLY__ -extern void (*clear_page)(void *to); -extern void (*copy_page)(void *to, void *from); - extern unsigned long shm_align_mask; extern unsigned long max_low_pfn, min_low_pfn; extern unsigned long memory_start, memory_end; -#ifdef CONFIG_MMU -extern void clear_page_slow(void *to); -extern void copy_page_slow(void *to, void *from); -#else -extern void clear_page_nommu(void *to); -extern void copy_page_nommu(void *to, void *from); -#endif +extern void clear_page(void *to); +extern void copy_page(void *to, void *from); #if !defined(CONFIG_CACHE_OFF) && defined(CONFIG_MMU) && \ (defined(CONFIG_CPU_SH4) || defined(CONFIG_SH7705_CACHE_32KB)) @@ -96,12 +82,18 @@ typedef struct { unsigned long long pgd; } pgd_t; ((x).pte_low | ((unsigned long long)(x).pte_high << 32)) #define __pte(x) \ ({ pte_t __pte = {(x), ((unsigned long long)(x)) >> 32}; __pte; }) -#else +#elif defined(CONFIG_SUPERH32) typedef struct { unsigned long pte_low; } pte_t; typedef struct { unsigned long pgprot; } pgprot_t; typedef struct { unsigned long pgd; } pgd_t; #define pte_val(x) ((x).pte_low) -#define __pte(x) ((pte_t) { (x) } ) +#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 pgd; } pgd_t; +#define pte_val(x) ((x).pte_low) +#define __pte(x) ((pte_t) { (x) } ) #endif #define pgd_val(x) ((x).pgd) @@ -112,28 +104,44 @@ typedef struct { unsigned long pgd; } pgd_t; #endif /* !__ASSEMBLY__ */ -/* to align the pointer to the (next) page boundary */ -#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK) - /* - * IF YOU CHANGE THIS, PLEASE ALSO CHANGE - * - * arch/sh/kernel/vmlinux.lds.S - * - * which has the same constant encoded.. + * __MEMORY_START and SIZE are the physical addresses and size of RAM. */ - #define __MEMORY_START CONFIG_MEMORY_START #define __MEMORY_SIZE CONFIG_MEMORY_SIZE +/* + * PAGE_OFFSET is the virtual address of the start of kernel address + * space. + */ #define PAGE_OFFSET CONFIG_PAGE_OFFSET -#define __pa(x) ((unsigned long)(x)-PAGE_OFFSET) -#define __va(x) ((void *)((unsigned long)(x)+PAGE_OFFSET)) -#define pfn_to_kaddr(pfn) __va((pfn) << PAGE_SHIFT) +/* + * Virtual to physical RAM address translation. + * + * In 29 bit mode, the physical offset of RAM from address 0 is visible in + * the kernel virtual address space, and thus we don't have to take + * this into account when translating. However in 32 bit mode this offset + * is not visible (it is part of the PMB mapping) and so needs to be + * added or subtracted as required. + */ +#ifdef CONFIG_32BIT +#define __pa(x) ((unsigned long)(x)-PAGE_OFFSET+__MEMORY_START) +#define __va(x) ((void *)((unsigned long)(x)+PAGE_OFFSET-__MEMORY_START)) +#else +#define __pa(x) ((unsigned long)(x)-PAGE_OFFSET) +#define __va(x) ((void *)((unsigned long)(x)+PAGE_OFFSET)) +#endif + +#define pfn_to_kaddr(pfn) __va((pfn) << PAGE_SHIFT) #define page_to_phys(page) (page_to_pfn(page) << PAGE_SHIFT) -/* PFN start number, because of __MEMORY_START */ +/* + * PFN = physical frame number (ie PFN 0 == physical address 0) + * PFN_START is the PFN of the first page of RAM. By defining this we + * don't have struct page entries for the portion of address space + * between physical address 0 and the start of RAM. + */ #define PFN_START (__MEMORY_START >> PAGE_SHIFT) #define ARCH_PFN_OFFSET (PFN_START) #define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT) @@ -154,11 +162,21 @@ typedef struct { unsigned long pgd; } pgd_t; #endif /* - * Slub defaults to 8-byte alignment, we're only interested in 4. - * Slab defaults to BYTES_PER_WORD, which ends up being the same anyways. + * Some drivers need to perform DMA into kmalloc'ed buffers + * and so we have to increase the kmalloc minalign for this. */ -#define ARCH_KMALLOC_MINALIGN 4 -#define ARCH_SLAB_MINALIGN 4 +#define ARCH_KMALLOC_MINALIGN L1_CACHE_BYTES + +#ifdef CONFIG_SUPERH64 +/* + * While BYTES_PER_WORD == 4 on the current sh64 ABI, GCC will still + * happily generate {ld/st}.q pairs, requiring us to have 8-byte + * alignment to avoid traps. The kmalloc alignment is gauranteed by + * virtue of L1_CACHE_BYTES, requiring this to only be special cased + * for slab caches. + */ +#define ARCH_SLAB_MINALIGN 8 +#endif #endif /* __KERNEL__ */ #endif /* __ASM_SH_PAGE_H */ diff --git a/include/asm-sh/param.h b/include/asm-sh/param.h index 1012296e07a..ae245afdfd6 100644 --- a/include/asm-sh/param.h +++ b/include/asm-sh/param.h @@ -2,11 +2,7 @@ #define __ASM_SH_PARAM_H #ifdef __KERNEL__ -# ifdef CONFIG_SH_WDT -# define HZ 1000 /* Needed for high-res WOVF */ -# else -# define HZ CONFIG_HZ -# endif +# define HZ CONFIG_HZ # define USER_HZ 100 /* User interfaces are in "ticks" */ # define CLOCKS_PER_SEC (USER_HZ) /* frequency at which times() counts */ #endif diff --git a/include/asm-sh/pci.h b/include/asm-sh/pci.h index 2757ce096ff..df1d383e18a 100644 --- a/include/asm-sh/pci.h +++ b/include/asm-sh/pci.h @@ -38,9 +38,12 @@ extern struct pci_channel board_pci_channels[]; #if defined(CONFIG_CPU_SUBTYPE_SH7780) || defined(CONFIG_CPU_SUBTYPE_SH7785) #define PCI_IO_AREA 0xFE400000 #define PCI_IO_SIZE 0x00400000 +#elif defined(CONFIG_CPU_SH5) +extern unsigned long PCI_IO_AREA; +#define PCI_IO_SIZE 0x00010000 #else #define PCI_IO_AREA 0xFE240000 -#define PCI_IO_SIZE 0X00040000 +#define PCI_IO_SIZE 0x00040000 #endif #define PCI_MEM_SIZE 0x01000000 diff --git a/include/asm-sh/pgalloc.h b/include/asm-sh/pgalloc.h index 18b613c57cf..59ca16d77a1 100644 --- a/include/asm-sh/pgalloc.h +++ b/include/asm-sh/pgalloc.h @@ -36,7 +36,7 @@ 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(pgd_t *pgd) +static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd) { quicklist_free(QUICK_PGD, NULL, pgd); } @@ -54,12 +54,12 @@ static inline struct page *pte_alloc_one(struct mm_struct *mm, return pg ? virt_to_page(pg) : NULL; } -static inline void pte_free_kernel(pte_t *pte) +static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte) { quicklist_free(QUICK_PT, NULL, pte); } -static inline void pte_free(struct page *pte) +static inline void pte_free(struct mm_struct *mm, struct page *pte) { quicklist_free_page(QUICK_PT, NULL, pte); } @@ -71,7 +71,7 @@ static inline void pte_free(struct page *pte) * inside the pgd, so has no extra memory associated with it. */ -#define pmd_free(x) do { } while (0) +#define pmd_free(mm, x) do { } while (0) #define __pmd_free_tlb(tlb,x) do { } while (0) static inline void check_pgt_cache(void) diff --git a/include/asm-sh/pgtable.h b/include/asm-sh/pgtable.h index 8f1e8be8d15..a4a8f8b9346 100644 --- a/include/asm-sh/pgtable.h +++ b/include/asm-sh/pgtable.h @@ -3,7 +3,7 @@ * use the SuperH page table tree. * * Copyright (C) 1999 Niibe Yutaka - * Copyright (C) 2002 - 2005 Paul Mundt + * Copyright (C) 2002 - 2007 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 @@ -29,10 +29,27 @@ extern unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)]; #endif /* !__ASSEMBLY__ */ /* + * Effective and physical address definitions, to aid with sign + * extension. + */ +#define NEFF 32 +#define NEFF_SIGN (1LL << (NEFF - 1)) +#define NEFF_MASK (-1LL << NEFF) + +#ifdef CONFIG_29BIT +#define NPHYS 29 +#else +#define NPHYS 32 +#endif + +#define NPHYS_SIGN (1LL << (NPHYS - 1)) +#define NPHYS_MASK (-1LL << NPHYS) + +/* * traditional two-level paging structure */ /* PTE bits */ -#ifdef CONFIG_X2TLB +#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 */ @@ -52,283 +69,27 @@ extern unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)]; #define USER_PTRS_PER_PGD (TASK_SIZE/PGDIR_SIZE) #define FIRST_USER_ADDRESS 0 -#define PTE_PHYS_MASK (0x20000000 - PAGE_SIZE) - -#define VMALLOC_START (P3SEG) -#define VMALLOC_END (FIXADDR_START-2*PAGE_SIZE) - -/* - * Linux PTEL encoding. - * - * Hardware and software bit definitions for the PTEL value (see below for - * notes on SH-X2 MMUs and 64-bit PTEs): - * - * - Bits 0 and 7 are reserved on SH-3 (_PAGE_WT and _PAGE_SZ1 on SH-4). - * - * - Bit 1 is the SH-bit, but is unused on SH-3 due to an MMU bug (the - * hardware PTEL value can't have the SH-bit set when MMUCR.IX is set, - * which is the default in cpu-sh3/mmu_context.h:MMU_CONTROL_INIT). - * - * In order to keep this relatively clean, do not use these for defining - * SH-3 specific flags until all of the other unused bits have been - * exhausted. - * - * - Bit 9 is reserved by everyone and used by _PAGE_PROTNONE. - * - * - Bits 10 and 11 are low bits of the PPN that are reserved on >= 4K pages. - * Bit 10 is used for _PAGE_ACCESSED, bit 11 remains unused. - * - * - Bits 31, 30, and 29 remain unused by everyone and can be used for future - * software flags, although care must be taken to update _PAGE_CLEAR_FLAGS. - * - * XXX: Leave the _PAGE_FILE and _PAGE_WT overhaul for a rainy day. - * - * SH-X2 MMUs and extended PTEs - * - * SH-X2 supports an extended mode TLB with split data arrays due to the - * number of bits needed for PR and SZ (now EPR and ESZ) encodings. The PR and - * SZ bit placeholders still exist in data array 1, but are implemented as - * reserved bits, with the real logic existing in data array 2. - * - * The downside to this is that we can no longer fit everything in to a 32-bit - * PTE encoding, so a 64-bit pte_t is necessary for these parts. On the plus - * side, this gives us quite a few spare bits to play with for future usage. - */ -/* Legacy and compat mode bits */ -#define _PAGE_WT 0x001 /* WT-bit on SH-4, 0 on SH-3 */ -#define _PAGE_HW_SHARED 0x002 /* SH-bit : shared among processes */ -#define _PAGE_DIRTY 0x004 /* D-bit : page changed */ -#define _PAGE_CACHABLE 0x008 /* C-bit : cachable */ -#define _PAGE_SZ0 0x010 /* SZ0-bit : Size of page */ -#define _PAGE_RW 0x020 /* PR0-bit : write access allowed */ -#define _PAGE_USER 0x040 /* PR1-bit : user space access allowed*/ -#define _PAGE_SZ1 0x080 /* SZ1-bit : Size of page (on SH-4) */ -#define _PAGE_PRESENT 0x100 /* V-bit : page is valid */ -#define _PAGE_PROTNONE 0x200 /* software: if not present */ -#define _PAGE_ACCESSED 0x400 /* software: page referenced */ -#define _PAGE_FILE _PAGE_WT /* software: pagecache or swap? */ - -#define _PAGE_SZ_MASK (_PAGE_SZ0 | _PAGE_SZ1) -#define _PAGE_PR_MASK (_PAGE_RW | _PAGE_USER) - -/* Extended mode bits */ -#define _PAGE_EXT_ESZ0 0x0010 /* ESZ0-bit: Size of page */ -#define _PAGE_EXT_ESZ1 0x0020 /* ESZ1-bit: Size of page */ -#define _PAGE_EXT_ESZ2 0x0040 /* ESZ2-bit: Size of page */ -#define _PAGE_EXT_ESZ3 0x0080 /* ESZ3-bit: Size of page */ - -#define _PAGE_EXT_USER_EXEC 0x0100 /* EPR0-bit: User space executable */ -#define _PAGE_EXT_USER_WRITE 0x0200 /* EPR1-bit: User space writable */ -#define _PAGE_EXT_USER_READ 0x0400 /* EPR2-bit: User space readable */ - -#define _PAGE_EXT_KERN_EXEC 0x0800 /* EPR3-bit: Kernel space executable */ -#define _PAGE_EXT_KERN_WRITE 0x1000 /* EPR4-bit: Kernel space writable */ -#define _PAGE_EXT_KERN_READ 0x2000 /* EPR5-bit: Kernel space readable */ - -/* Wrapper for extended mode pgprot twiddling */ -#define _PAGE_EXT(x) ((unsigned long long)(x) << 32) - -/* software: moves to PTEA.TC (Timing Control) */ -#define _PAGE_PCC_AREA5 0x00000000 /* use BSC registers for area5 */ -#define _PAGE_PCC_AREA6 0x80000000 /* use BSC registers for area6 */ - -/* software: moves to PTEA.SA[2:0] (Space Attributes) */ -#define _PAGE_PCC_IODYN 0x00000001 /* IO space, dynamically sized bus */ -#define _PAGE_PCC_IO8 0x20000000 /* IO space, 8 bit bus */ -#define _PAGE_PCC_IO16 0x20000001 /* IO space, 16 bit bus */ -#define _PAGE_PCC_COM8 0x40000000 /* Common Memory space, 8 bit bus */ -#define _PAGE_PCC_COM16 0x40000001 /* Common Memory space, 16 bit bus */ -#define _PAGE_PCC_ATR8 0x60000000 /* Attribute Memory space, 8 bit bus */ -#define _PAGE_PCC_ATR16 0x60000001 /* Attribute Memory space, 6 bit bus */ - -/* Mask which drops unused bits from the PTEL value */ -#if defined(CONFIG_CPU_SH3) -#define _PAGE_CLEAR_FLAGS (_PAGE_PROTNONE | _PAGE_ACCESSED| \ - _PAGE_FILE | _PAGE_SZ1 | \ - _PAGE_HW_SHARED) -#elif defined(CONFIG_X2TLB) -/* Get rid of the legacy PR/SZ bits when using extended mode */ -#define _PAGE_CLEAR_FLAGS (_PAGE_PROTNONE | _PAGE_ACCESSED | \ - _PAGE_FILE | _PAGE_PR_MASK | _PAGE_SZ_MASK) +#ifdef CONFIG_32BIT +#define PHYS_ADDR_MASK 0xffffffff #else -#define _PAGE_CLEAR_FLAGS (_PAGE_PROTNONE | _PAGE_ACCESSED | _PAGE_FILE) +#define PHYS_ADDR_MASK 0x1fffffff #endif -#define _PAGE_FLAGS_HARDWARE_MASK (0x1fffffff & ~(_PAGE_CLEAR_FLAGS)) +#define PTE_PHYS_MASK (PHYS_ADDR_MASK & PAGE_MASK) -/* Hardware flags, page size encoding */ -#if defined(CONFIG_X2TLB) -# if defined(CONFIG_PAGE_SIZE_4KB) -# define _PAGE_FLAGS_HARD _PAGE_EXT(_PAGE_EXT_ESZ0) -# elif defined(CONFIG_PAGE_SIZE_8KB) -# define _PAGE_FLAGS_HARD _PAGE_EXT(_PAGE_EXT_ESZ1) -# elif defined(CONFIG_PAGE_SIZE_64KB) -# define _PAGE_FLAGS_HARD _PAGE_EXT(_PAGE_EXT_ESZ2) -# endif +#ifdef CONFIG_SUPERH32 +#define VMALLOC_START (P3SEG) #else -# if defined(CONFIG_PAGE_SIZE_4KB) -# define _PAGE_FLAGS_HARD _PAGE_SZ0 -# elif defined(CONFIG_PAGE_SIZE_64KB) -# define _PAGE_FLAGS_HARD _PAGE_SZ1 -# endif +#define VMALLOC_START (0xf0000000) #endif +#define VMALLOC_END (FIXADDR_START-2*PAGE_SIZE) -#if defined(CONFIG_X2TLB) -# if defined(CONFIG_HUGETLB_PAGE_SIZE_64K) -# define _PAGE_SZHUGE (_PAGE_EXT_ESZ2) -# elif defined(CONFIG_HUGETLB_PAGE_SIZE_256K) -# define _PAGE_SZHUGE (_PAGE_EXT_ESZ0 | _PAGE_EXT_ESZ2) -# elif defined(CONFIG_HUGETLB_PAGE_SIZE_1MB) -# define _PAGE_SZHUGE (_PAGE_EXT_ESZ0 | _PAGE_EXT_ESZ1 | _PAGE_EXT_ESZ2) -# elif defined(CONFIG_HUGETLB_PAGE_SIZE_4MB) -# define _PAGE_SZHUGE (_PAGE_EXT_ESZ3) -# elif defined(CONFIG_HUGETLB_PAGE_SIZE_64MB) -# define _PAGE_SZHUGE (_PAGE_EXT_ESZ2 | _PAGE_EXT_ESZ3) -# endif +#if defined(CONFIG_SUPERH32) +#include <asm/pgtable_32.h> #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 -#endif - -/* - * Stub out _PAGE_SZHUGE if we don't have a good definition for it, - * to make pte_mkhuge() happy. - */ -#ifndef _PAGE_SZHUGE -# define _PAGE_SZHUGE (_PAGE_FLAGS_HARD) -#endif - -#define _PAGE_CHG_MASK \ - (PTE_MASK | _PAGE_ACCESSED | _PAGE_CACHABLE | _PAGE_DIRTY) - -#ifndef __ASSEMBLY__ - -#if defined(CONFIG_X2TLB) /* SH-X2 TLB */ -#define PAGE_NONE __pgprot(_PAGE_PROTNONE | _PAGE_CACHABLE | \ - _PAGE_ACCESSED | _PAGE_FLAGS_HARD) - -#define PAGE_SHARED __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED | \ - _PAGE_CACHABLE | _PAGE_FLAGS_HARD | \ - _PAGE_EXT(_PAGE_EXT_KERN_READ | \ - _PAGE_EXT_KERN_WRITE | \ - _PAGE_EXT_USER_READ | \ - _PAGE_EXT_USER_WRITE)) - -#define PAGE_EXECREAD __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED | \ - _PAGE_CACHABLE | _PAGE_FLAGS_HARD | \ - _PAGE_EXT(_PAGE_EXT_KERN_EXEC | \ - _PAGE_EXT_KERN_READ | \ - _PAGE_EXT_USER_EXEC | \ - _PAGE_EXT_USER_READ)) - -#define PAGE_COPY PAGE_EXECREAD - -#define PAGE_READONLY __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED | \ - _PAGE_CACHABLE | _PAGE_FLAGS_HARD | \ - _PAGE_EXT(_PAGE_EXT_KERN_READ | \ - _PAGE_EXT_USER_READ)) - -#define PAGE_WRITEONLY __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED | \ - _PAGE_CACHABLE | _PAGE_FLAGS_HARD | \ - _PAGE_EXT(_PAGE_EXT_KERN_WRITE | \ - _PAGE_EXT_USER_WRITE)) - -#define PAGE_RWX __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED | \ - _PAGE_CACHABLE | _PAGE_FLAGS_HARD | \ - _PAGE_EXT(_PAGE_EXT_KERN_WRITE | \ - _PAGE_EXT_KERN_READ | \ - _PAGE_EXT_KERN_EXEC | \ - _PAGE_EXT_USER_WRITE | \ - _PAGE_EXT_USER_READ | \ - _PAGE_EXT_USER_EXEC)) - -#define PAGE_KERNEL __pgprot(_PAGE_PRESENT | _PAGE_CACHABLE | \ - _PAGE_DIRTY | _PAGE_ACCESSED | \ - _PAGE_HW_SHARED | _PAGE_FLAGS_HARD | \ - _PAGE_EXT(_PAGE_EXT_KERN_READ | \ - _PAGE_EXT_KERN_WRITE | \ - _PAGE_EXT_KERN_EXEC)) - -#define PAGE_KERNEL_NOCACHE \ - __pgprot(_PAGE_PRESENT | _PAGE_DIRTY | \ - _PAGE_ACCESSED | _PAGE_HW_SHARED | \ - _PAGE_FLAGS_HARD | \ - _PAGE_EXT(_PAGE_EXT_KERN_READ | \ - _PAGE_EXT_KERN_WRITE | \ - _PAGE_EXT_KERN_EXEC)) - -#define PAGE_KERNEL_RO __pgprot(_PAGE_PRESENT | _PAGE_CACHABLE | \ - _PAGE_DIRTY | _PAGE_ACCESSED | \ - _PAGE_HW_SHARED | _PAGE_FLAGS_HARD | \ - _PAGE_EXT(_PAGE_EXT_KERN_READ | \ - _PAGE_EXT_KERN_EXEC)) - -#define PAGE_KERNEL_PCC(slot, type) \ - __pgprot(_PAGE_PRESENT | _PAGE_DIRTY | \ - _PAGE_ACCESSED | _PAGE_FLAGS_HARD | \ - _PAGE_EXT(_PAGE_EXT_KERN_READ | \ - _PAGE_EXT_KERN_WRITE | \ - _PAGE_EXT_KERN_EXEC) \ - (slot ? _PAGE_PCC_AREA5 : _PAGE_PCC_AREA6) | \ - (type)) - -#elif defined(CONFIG_MMU) /* SH-X TLB */ -#define PAGE_NONE __pgprot(_PAGE_PROTNONE | _PAGE_CACHABLE | \ - _PAGE_ACCESSED | _PAGE_FLAGS_HARD) - -#define PAGE_SHARED __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | \ - _PAGE_CACHABLE | _PAGE_ACCESSED | \ - _PAGE_FLAGS_HARD) - -#define PAGE_COPY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_CACHABLE | \ - _PAGE_ACCESSED | _PAGE_FLAGS_HARD) - -#define PAGE_READONLY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_CACHABLE | \ - _PAGE_ACCESSED | _PAGE_FLAGS_HARD) - -#define PAGE_EXECREAD PAGE_READONLY -#define PAGE_RWX PAGE_SHARED -#define PAGE_WRITEONLY PAGE_SHARED - -#define PAGE_KERNEL __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_CACHABLE | \ - _PAGE_DIRTY | _PAGE_ACCESSED | \ - _PAGE_HW_SHARED | _PAGE_FLAGS_HARD) - -#define PAGE_KERNEL_NOCACHE \ - __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | \ - _PAGE_ACCESSED | _PAGE_HW_SHARED | \ - _PAGE_FLAGS_HARD) - -#define PAGE_KERNEL_RO __pgprot(_PAGE_PRESENT | _PAGE_CACHABLE | \ - _PAGE_DIRTY | _PAGE_ACCESSED | \ - _PAGE_HW_SHARED | _PAGE_FLAGS_HARD) - -#define PAGE_KERNEL_PCC(slot, type) \ - __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | \ - _PAGE_ACCESSED | _PAGE_FLAGS_HARD | \ - (slot ? _PAGE_PCC_AREA5 : _PAGE_PCC_AREA6) | \ - (type)) -#else /* no mmu */ -#define PAGE_NONE __pgprot(0) -#define PAGE_SHARED __pgprot(0) -#define PAGE_COPY __pgprot(0) -#define PAGE_EXECREAD __pgprot(0) -#define PAGE_RWX __pgprot(0) -#define PAGE_READONLY __pgprot(0) -#define PAGE_WRITEONLY __pgprot(0) -#define PAGE_KERNEL __pgprot(0) -#define PAGE_KERNEL_NOCACHE __pgprot(0) -#define PAGE_KERNEL_RO __pgprot(0) - -#define PAGE_KERNEL_PCC(slot, type) \ - __pgprot(0) +#include <asm/pgtable_64.h> #endif -#endif /* __ASSEMBLY__ */ - /* * SH-X and lower (legacy) SuperH parts (SH-3, SH-4, some SH-4A) can't do page * protection for execute, and considers it the same as a read. Also, write @@ -357,208 +118,6 @@ extern unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)]; #define __S110 PAGE_RWX #define __S111 PAGE_RWX -#ifndef __ASSEMBLY__ - -/* - * Certain architectures need to do special things when PTEs - * within a page table are directly modified. Thus, the following - * hook is made available. - */ -#ifdef CONFIG_X2TLB -static inline void set_pte(pte_t *ptep, pte_t pte) -{ - ptep->pte_high = pte.pte_high; - smp_wmb(); - ptep->pte_low = pte.pte_low; -} -#else -#define set_pte(pteptr, pteval) (*(pteptr) = pteval) -#endif - -#define set_pte_at(mm,addr,ptep,pteval) set_pte(ptep,pteval) - -/* - * (pmds are folded into pgds so this doesn't get actually called, - * but the define is needed for a generic inline function.) - */ -#define set_pmd(pmdptr, pmdval) (*(pmdptr) = pmdval) - -#define pte_pfn(x) ((unsigned long)(((x).pte_low >> PAGE_SHIFT))) - -#define pfn_pte(pfn, prot) \ - __pte(((unsigned long long)(pfn) << PAGE_SHIFT) | pgprot_val(prot)) -#define pfn_pmd(pfn, prot) \ - __pmd(((unsigned long long)(pfn) << PAGE_SHIFT) | pgprot_val(prot)) - -#define pte_none(x) (!pte_val(x)) -#define pte_present(x) ((x).pte_low & (_PAGE_PRESENT | _PAGE_PROTNONE)) - -#define pte_clear(mm,addr,xp) do { set_pte_at(mm, addr, xp, __pte(0)); } while (0) - -#define pmd_none(x) (!pmd_val(x)) -#define pmd_present(x) (pmd_val(x)) -#define pmd_clear(xp) do { set_pmd(xp, __pmd(0)); } while (0) -#define pmd_bad(x) (pmd_val(x) & ~PAGE_MASK) - -#define pages_to_mb(x) ((x) >> (20-PAGE_SHIFT)) -#define pte_page(x) pfn_to_page(pte_pfn(x)) - -/* - * The following only work if pte_present() is true. - * Undefined behaviour if not.. - */ -#define pte_not_present(pte) (!((pte).pte_low & _PAGE_PRESENT)) -#define pte_dirty(pte) ((pte).pte_low & _PAGE_DIRTY) -#define pte_young(pte) ((pte).pte_low & _PAGE_ACCESSED) -#define pte_file(pte) ((pte).pte_low & _PAGE_FILE) - -#ifdef CONFIG_X2TLB -#define pte_write(pte) ((pte).pte_high & _PAGE_EXT_USER_WRITE) -#else -#define pte_write(pte) ((pte).pte_low & _PAGE_RW) -#endif - -#define PTE_BIT_FUNC(h,fn,op) \ -static inline pte_t pte_##fn(pte_t pte) { pte.pte_##h op; return pte; } - -#ifdef CONFIG_X2TLB -/* - * We cheat a bit in the SH-X2 TLB case. As the permission bits are - * individually toggled (and user permissions are entirely decoupled from - * kernel permissions), we attempt to couple them a bit more sanely here. - */ -PTE_BIT_FUNC(high, wrprotect, &= ~_PAGE_EXT_USER_WRITE); -PTE_BIT_FUNC(high, mkwrite, |= _PAGE_EXT_USER_WRITE | _PAGE_EXT_KERN_WRITE); -PTE_BIT_FUNC(high, mkhuge, |= _PAGE_SZHUGE); -#else -PTE_BIT_FUNC(low, wrprotect, &= ~_PAGE_RW); -PTE_BIT_FUNC(low, mkwrite, |= _PAGE_RW); -PTE_BIT_FUNC(low, mkhuge, |= _PAGE_SZHUGE); -#endif - -PTE_BIT_FUNC(low, mkclean, &= ~_PAGE_DIRTY); -PTE_BIT_FUNC(low, mkdirty, |= _PAGE_DIRTY); -PTE_BIT_FUNC(low, mkold, &= ~_PAGE_ACCESSED); -PTE_BIT_FUNC(low, mkyoung, |= _PAGE_ACCESSED); - -/* - * Macro and implementation to make a page protection as uncachable. - */ -#define pgprot_writecombine(prot) \ - __pgprot(pgprot_val(prot) & ~_PAGE_CACHABLE) - -#define pgprot_noncached pgprot_writecombine - -/* - * Conversion functions: convert a page and protection to a page entry, - * and a page entry and page directory to the page they refer to. - * - * extern pte_t mk_pte(struct page *page, pgprot_t pgprot) - */ -#define mk_pte(page, pgprot) pfn_pte(page_to_pfn(page), (pgprot)) - -static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) -{ - pte.pte_low &= _PAGE_CHG_MASK; - pte.pte_low |= pgprot_val(newprot); - -#ifdef CONFIG_X2TLB - pte.pte_high |= pgprot_val(newprot) >> 32; -#endif - - return pte; -} - -#define pmd_page_vaddr(pmd) ((unsigned long)pmd_val(pmd)) -#define pmd_page(pmd) (virt_to_page(pmd_val(pmd))) - -/* to find an entry in a page-table-directory. */ -#define pgd_index(address) (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD-1)) -#define pgd_offset(mm, address) ((mm)->pgd+pgd_index(address)) - -/* to find an entry in a kernel page-table-directory */ -#define pgd_offset_k(address) pgd_offset(&init_mm, address) - -/* Find an entry in the third-level page table.. */ -#define pte_index(address) ((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)) -#define pte_offset_kernel(dir, address) \ - ((pte_t *) pmd_page_vaddr(*(dir)) + pte_index(address)) -#define pte_offset_map(dir, address) pte_offset_kernel(dir, address) -#define pte_offset_map_nested(dir, address) pte_offset_kernel(dir, address) - -#define pte_unmap(pte) do { } while (0) -#define pte_unmap_nested(pte) do { } while (0) - -#ifdef CONFIG_X2TLB -#define pte_ERROR(e) \ - printk("%s:%d: bad pte %p(%08lx%08lx).\n", __FILE__, __LINE__, \ - &(e), (e).pte_high, (e).pte_low) -#define pgd_ERROR(e) \ - printk("%s:%d: bad pgd %016llx.\n", __FILE__, __LINE__, pgd_val(e)) -#else -#define pte_ERROR(e) \ - printk("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, pte_val(e)) -#define pgd_ERROR(e) \ - printk("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pgd_val(e)) -#endif - -struct vm_area_struct; -extern void update_mmu_cache(struct vm_area_struct * vma, - unsigned long address, pte_t pte); - -/* - * Encode and de-code a swap entry - * - * Constraints: - * _PAGE_FILE at bit 0 - * _PAGE_PRESENT at bit 8 - * _PAGE_PROTNONE at bit 9 - * - * For the normal case, we encode the swap type into bits 0:7 and the - * swap offset into bits 10:30. For the 64-bit PTE case, we keep the - * preserved bits in the low 32-bits and use the upper 32 as the swap - * offset (along with a 5-bit type), following the same approach as x86 - * PAE. This keeps the logic quite simple, and allows for a full 32 - * PTE_FILE_MAX_BITS, as opposed to the 29-bits we're constrained with - * in the pte_low case. - * - * As is evident by the Alpha code, if we ever get a 64-bit unsigned - * long (swp_entry_t) to match up with the 64-bit PTEs, this all becomes - * much cleaner.. - * - * NOTE: We should set ZEROs at the position of _PAGE_PRESENT - * and _PAGE_PROTNONE bits - */ -#ifdef CONFIG_X2TLB -#define __swp_type(x) ((x).val & 0x1f) -#define __swp_offset(x) ((x).val >> 5) -#define __swp_entry(type, offset) ((swp_entry_t){ (type) | (offset) << 5}) -#define __pte_to_swp_entry(pte) ((swp_entry_t){ (pte).pte_high }) -#define __swp_entry_to_pte(x) ((pte_t){ 0, (x).val }) - -/* - * Encode and decode a nonlinear file mapping entry - */ -#define pte_to_pgoff(pte) ((pte).pte_high) -#define pgoff_to_pte(off) ((pte_t) { _PAGE_FILE, (off) }) - -#define PTE_FILE_MAX_BITS 32 -#else -#define __swp_type(x) ((x).val & 0xff) -#define __swp_offset(x) ((x).val >> 10) -#define __swp_entry(type, offset) ((swp_entry_t){(type) | (offset) <<10}) - -#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) >> 1 }) -#define __swp_entry_to_pte(x) ((pte_t) { (x).val << 1 }) - -/* - * Encode and decode a nonlinear file mapping entry - */ -#define PTE_FILE_MAX_BITS 29 -#define pte_to_pgoff(pte) (pte_val(pte) >> 1) -#define pgoff_to_pte(off) ((pte_t) { ((off) << 1) | _PAGE_FILE }) -#endif - typedef pte_t *pte_addr_t; #define kern_addr_valid(addr) (1) @@ -566,27 +125,28 @@ typedef pte_t *pte_addr_t; #define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \ remap_pfn_range(vma, vaddr, pfn, size, prot) -struct mm_struct; +#define pte_pfn(x) ((unsigned long)(((x).pte_low >> PAGE_SHIFT))) /* * No page table caches to initialise */ #define pgtable_cache_init() do { } while (0) -#ifndef CONFIG_MMU -extern unsigned int kobjsize(const void *objp); -#endif /* !CONFIG_MMU */ - #if !defined(CONFIG_CACHE_OFF) && (defined(CONFIG_CPU_SH4) || \ defined(CONFIG_SH7705_CACHE_32KB)) +struct mm_struct; #define __HAVE_ARCH_PTEP_GET_AND_CLEAR -extern pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep); +pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep); #endif +struct vm_area_struct; +extern void update_mmu_cache(struct vm_area_struct * vma, + unsigned long address, pte_t pte); extern pgd_t swapper_pg_dir[PTRS_PER_PGD]; extern void paging_init(void); +extern void page_table_range_init(unsigned long start, unsigned long end, + pgd_t *pgd); #include <asm-generic/pgtable.h> -#endif /* !__ASSEMBLY__ */ -#endif /* __ASM_SH_PAGE_H */ +#endif /* __ASM_SH_PGTABLE_H */ diff --git a/include/asm-sh/pgtable_32.h b/include/asm-sh/pgtable_32.h new file mode 100644 index 00000000000..3e3557c53c5 --- /dev/null +++ b/include/asm-sh/pgtable_32.h @@ -0,0 +1,474 @@ +#ifndef __ASM_SH_PGTABLE_32_H +#define __ASM_SH_PGTABLE_32_H + +/* + * Linux PTEL encoding. + * + * Hardware and software bit definitions for the PTEL value (see below for + * notes on SH-X2 MMUs and 64-bit PTEs): + * + * - Bits 0 and 7 are reserved on SH-3 (_PAGE_WT and _PAGE_SZ1 on SH-4). + * + * - Bit 1 is the SH-bit, but is unused on SH-3 due to an MMU bug (the + * hardware PTEL value can't have the SH-bit set when MMUCR.IX is set, + * which is the default in cpu-sh3/mmu_context.h:MMU_CONTROL_INIT). + * + * In order to keep this relatively clean, do not use these for defining + * SH-3 specific flags until all of the other unused bits have been + * exhausted. + * + * - Bit 9 is reserved by everyone and used by _PAGE_PROTNONE. + * + * - Bits 10 and 11 are low bits of the PPN that are reserved on >= 4K pages. + * Bit 10 is used for _PAGE_ACCESSED, bit 11 remains unused. + * + * - On 29 bit platforms, bits 31 to 29 are used for the space attributes + * and timing control which (together with bit 0) are moved into the + * old-style PTEA on the parts that support it. + * + * XXX: Leave the _PAGE_FILE and _PAGE_WT overhaul for a rainy day. + * + * SH-X2 MMUs and extended PTEs + * + * SH-X2 supports an extended mode TLB with split data arrays due to the + * number of bits needed for PR and SZ (now EPR and ESZ) encodings. The PR and + * SZ bit placeholders still exist in data array 1, but are implemented as + * reserved bits, with the real logic existing in data array 2. + * + * The downside to this is that we can no longer fit everything in to a 32-bit + * PTE encoding, so a 64-bit pte_t is necessary for these parts. On the plus + * side, this gives us quite a few spare bits to play with for future usage. + */ +/* Legacy and compat mode bits */ +#define _PAGE_WT 0x001 /* WT-bit on SH-4, 0 on SH-3 */ +#define _PAGE_HW_SHARED 0x002 /* SH-bit : shared among processes */ +#define _PAGE_DIRTY 0x004 /* D-bit : page changed */ +#define _PAGE_CACHABLE 0x008 /* C-bit : cachable */ +#define _PAGE_SZ0 0x010 /* SZ0-bit : Size of page */ +#define _PAGE_RW 0x020 /* PR0-bit : write access allowed */ +#define _PAGE_USER 0x040 /* PR1-bit : user space access allowed*/ +#define _PAGE_SZ1 0x080 /* SZ1-bit : Size of page (on SH-4) */ +#define _PAGE_PRESENT 0x100 /* V-bit : page is valid */ +#define _PAGE_PROTNONE 0x200 /* software: if not present */ +#define _PAGE_ACCESSED 0x400 /* software: page referenced */ +#define _PAGE_FILE _PAGE_WT /* software: pagecache or swap? */ + +#define _PAGE_SZ_MASK (_PAGE_SZ0 | _PAGE_SZ1) +#define _PAGE_PR_MASK (_PAGE_RW | _PAGE_USER) + +/* Extended mode bits */ +#define _PAGE_EXT_ESZ0 0x0010 /* ESZ0-bit: Size of page */ +#define _PAGE_EXT_ESZ1 0x0020 /* ESZ1-bit: Size of page */ +#define _PAGE_EXT_ESZ2 0x0040 /* ESZ2-bit: Size of page */ +#define _PAGE_EXT_ESZ3 0x0080 /* ESZ3-bit: Size of page */ + +#define _PAGE_EXT_USER_EXEC 0x0100 /* EPR0-bit: User space executable */ +#define _PAGE_EXT_USER_WRITE 0x0200 /* EPR1-bit: User space writable */ +#define _PAGE_EXT_USER_READ 0x0400 /* EPR2-bit: User space readable */ + +#define _PAGE_EXT_KERN_EXEC 0x0800 /* EPR3-bit: Kernel space executable */ +#define _PAGE_EXT_KERN_WRITE 0x1000 /* EPR4-bit: Kernel space writable */ +#define _PAGE_EXT_KERN_READ 0x2000 /* EPR5-bit: Kernel space readable */ + +/* Wrapper for extended mode pgprot twiddling */ +#define _PAGE_EXT(x) ((unsigned long long)(x) << 32) + +/* software: moves to PTEA.TC (Timing Control) */ +#define _PAGE_PCC_AREA5 0x00000000 /* use BSC registers for area5 */ +#define _PAGE_PCC_AREA6 0x80000000 /* use BSC registers for area6 */ + +/* software: moves to PTEA.SA[2:0] (Space Attributes) */ +#define _PAGE_PCC_IODYN 0x00000001 /* IO space, dynamically sized bus */ +#define _PAGE_PCC_IO8 0x20000000 /* IO space, 8 bit bus */ +#define _PAGE_PCC_IO16 0x20000001 /* IO space, 16 bit bus */ +#define _PAGE_PCC_COM8 0x40000000 /* Common Memory space, 8 bit bus */ +#define _PAGE_PCC_COM16 0x40000001 /* Common Memory space, 16 bit bus */ +#define _PAGE_PCC_ATR8 0x60000000 /* Attribute Memory space, 8 bit bus */ +#define _PAGE_PCC_ATR16 0x60000001 /* Attribute Memory space, 6 bit bus */ + +/* Mask which drops unused bits from the PTEL value */ +#if defined(CONFIG_CPU_SH3) +#define _PAGE_CLEAR_FLAGS (_PAGE_PROTNONE | _PAGE_ACCESSED| \ + _PAGE_FILE | _PAGE_SZ1 | \ + _PAGE_HW_SHARED) +#elif defined(CONFIG_X2TLB) +/* Get rid of the legacy PR/SZ bits when using extended mode */ +#define _PAGE_CLEAR_FLAGS (_PAGE_PROTNONE | _PAGE_ACCESSED | \ + _PAGE_FILE | _PAGE_PR_MASK | _PAGE_SZ_MASK) +#else +#define _PAGE_CLEAR_FLAGS (_PAGE_PROTNONE | _PAGE_ACCESSED | _PAGE_FILE) +#endif + +#define _PAGE_FLAGS_HARDWARE_MASK (PHYS_ADDR_MASK & ~(_PAGE_CLEAR_FLAGS)) + +/* Hardware flags, page size encoding */ +#if defined(CONFIG_X2TLB) +# if defined(CONFIG_PAGE_SIZE_4KB) +# define _PAGE_FLAGS_HARD _PAGE_EXT(_PAGE_EXT_ESZ0) +# elif defined(CONFIG_PAGE_SIZE_8KB) +# define _PAGE_FLAGS_HARD _PAGE_EXT(_PAGE_EXT_ESZ1) +# elif defined(CONFIG_PAGE_SIZE_64KB) +# define _PAGE_FLAGS_HARD _PAGE_EXT(_PAGE_EXT_ESZ2) +# endif +#else +# if defined(CONFIG_PAGE_SIZE_4KB) +# define _PAGE_FLAGS_HARD _PAGE_SZ0 +# elif defined(CONFIG_PAGE_SIZE_64KB) +# define _PAGE_FLAGS_HARD _PAGE_SZ1 +# endif +#endif + +#if defined(CONFIG_X2TLB) +# if defined(CONFIG_HUGETLB_PAGE_SIZE_64K) +# define _PAGE_SZHUGE (_PAGE_EXT_ESZ2) +# elif defined(CONFIG_HUGETLB_PAGE_SIZE_256K) +# define _PAGE_SZHUGE (_PAGE_EXT_ESZ0 | _PAGE_EXT_ESZ2) +# elif defined(CONFIG_HUGETLB_PAGE_SIZE_1MB) +# define _PAGE_SZHUGE (_PAGE_EXT_ESZ0 | _PAGE_EXT_ESZ1 | _PAGE_EXT_ESZ2) +# elif defined(CONFIG_HUGETLB_PAGE_SIZE_4MB) +# define _PAGE_SZHUGE (_PAGE_EXT_ESZ3) +# elif defined(CONFIG_HUGETLB_PAGE_SIZE_64MB) +# define _PAGE_SZHUGE (_PAGE_EXT_ESZ2 | _PAGE_EXT_ESZ3) +# endif +#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 +#endif + +/* + * Stub out _PAGE_SZHUGE if we don't have a good definition for it, + * to make pte_mkhuge() happy. + */ +#ifndef _PAGE_SZHUGE +# define _PAGE_SZHUGE (_PAGE_FLAGS_HARD) +#endif + +#define _PAGE_CHG_MASK \ + (PTE_MASK | _PAGE_ACCESSED | _PAGE_CACHABLE | _PAGE_DIRTY) + +#ifndef __ASSEMBLY__ + +#if defined(CONFIG_X2TLB) /* SH-X2 TLB */ +#define PAGE_NONE __pgprot(_PAGE_PROTNONE | _PAGE_CACHABLE | \ + _PAGE_ACCESSED | _PAGE_FLAGS_HARD) + +#define PAGE_SHARED __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED | \ + _PAGE_CACHABLE | _PAGE_FLAGS_HARD | \ + _PAGE_EXT(_PAGE_EXT_KERN_READ | \ + _PAGE_EXT_KERN_WRITE | \ + _PAGE_EXT_USER_READ | \ + _PAGE_EXT_USER_WRITE)) + +#define PAGE_EXECREAD __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED | \ + _PAGE_CACHABLE | _PAGE_FLAGS_HARD | \ + _PAGE_EXT(_PAGE_EXT_KERN_EXEC | \ + _PAGE_EXT_KERN_READ | \ + _PAGE_EXT_USER_EXEC | \ + _PAGE_EXT_USER_READ)) + +#define PAGE_COPY PAGE_EXECREAD + +#define PAGE_READONLY __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED | \ + _PAGE_CACHABLE | _PAGE_FLAGS_HARD | \ + _PAGE_EXT(_PAGE_EXT_KERN_READ | \ + _PAGE_EXT_USER_READ)) + +#define PAGE_WRITEONLY __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED | \ + _PAGE_CACHABLE | _PAGE_FLAGS_HARD | \ + _PAGE_EXT(_PAGE_EXT_KERN_WRITE | \ + _PAGE_EXT_USER_WRITE)) + +#define PAGE_RWX __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED | \ + _PAGE_CACHABLE | _PAGE_FLAGS_HARD | \ + _PAGE_EXT(_PAGE_EXT_KERN_WRITE | \ + _PAGE_EXT_KERN_READ | \ + _PAGE_EXT_KERN_EXEC | \ + _PAGE_EXT_USER_WRITE | \ + _PAGE_EXT_USER_READ | \ + _PAGE_EXT_USER_EXEC)) + +#define PAGE_KERNEL __pgprot(_PAGE_PRESENT | _PAGE_CACHABLE | \ + _PAGE_DIRTY | _PAGE_ACCESSED | \ + _PAGE_HW_SHARED | _PAGE_FLAGS_HARD | \ + _PAGE_EXT(_PAGE_EXT_KERN_READ | \ + _PAGE_EXT_KERN_WRITE | \ + _PAGE_EXT_KERN_EXEC)) + +#define PAGE_KERNEL_NOCACHE \ + __pgprot(_PAGE_PRESENT | _PAGE_DIRTY | \ + _PAGE_ACCESSED | _PAGE_HW_SHARED | \ + _PAGE_FLAGS_HARD | \ + _PAGE_EXT(_PAGE_EXT_KERN_READ | \ + _PAGE_EXT_KERN_WRITE | \ + _PAGE_EXT_KERN_EXEC)) + +#define PAGE_KERNEL_RO __pgprot(_PAGE_PRESENT | _PAGE_CACHABLE | \ + _PAGE_DIRTY | _PAGE_ACCESSED | \ + _PAGE_HW_SHARED | _PAGE_FLAGS_HARD | \ + _PAGE_EXT(_PAGE_EXT_KERN_READ | \ + _PAGE_EXT_KERN_EXEC)) + +#define PAGE_KERNEL_PCC(slot, type) \ + __pgprot(_PAGE_PRESENT | _PAGE_DIRTY | \ + _PAGE_ACCESSED | _PAGE_FLAGS_HARD | \ + _PAGE_EXT(_PAGE_EXT_KERN_READ | \ + _PAGE_EXT_KERN_WRITE | \ + _PAGE_EXT_KERN_EXEC) \ + (slot ? _PAGE_PCC_AREA5 : _PAGE_PCC_AREA6) | \ + (type)) + +#elif defined(CONFIG_MMU) /* SH-X TLB */ +#define PAGE_NONE __pgprot(_PAGE_PROTNONE | _PAGE_CACHABLE | \ + _PAGE_ACCESSED | _PAGE_FLAGS_HARD) + +#define PAGE_SHARED __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | \ + _PAGE_CACHABLE | _PAGE_ACCESSED | \ + _PAGE_FLAGS_HARD) + +#define PAGE_COPY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_CACHABLE | \ + _PAGE_ACCESSED | _PAGE_FLAGS_HARD) + +#define PAGE_READONLY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_CACHABLE | \ + _PAGE_ACCESSED | _PAGE_FLAGS_HARD) + +#define PAGE_EXECREAD PAGE_READONLY +#define PAGE_RWX PAGE_SHARED +#define PAGE_WRITEONLY PAGE_SHARED + +#define PAGE_KERNEL __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_CACHABLE | \ + _PAGE_DIRTY | _PAGE_ACCESSED | \ + _PAGE_HW_SHARED | _PAGE_FLAGS_HARD) + +#define PAGE_KERNEL_NOCACHE \ + __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | \ + _PAGE_ACCESSED | _PAGE_HW_SHARED | \ + _PAGE_FLAGS_HARD) + +#define PAGE_KERNEL_RO __pgprot(_PAGE_PRESENT | _PAGE_CACHABLE | \ + _PAGE_DIRTY | _PAGE_ACCESSED | \ + _PAGE_HW_SHARED | _PAGE_FLAGS_HARD) + +#define PAGE_KERNEL_PCC(slot, type) \ + __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | \ + _PAGE_ACCESSED | _PAGE_FLAGS_HARD | \ + (slot ? _PAGE_PCC_AREA5 : _PAGE_PCC_AREA6) | \ + (type)) +#else /* no mmu */ +#define PAGE_NONE __pgprot(0) +#define PAGE_SHARED __pgprot(0) +#define PAGE_COPY __pgprot(0) +#define PAGE_EXECREAD __pgprot(0) +#define PAGE_RWX __pgprot(0) +#define PAGE_READONLY __pgprot(0) +#define PAGE_WRITEONLY __pgprot(0) +#define PAGE_KERNEL __pgprot(0) +#define PAGE_KERNEL_NOCACHE __pgprot(0) +#define PAGE_KERNEL_RO __pgprot(0) + +#define PAGE_KERNEL_PCC(slot, type) \ + __pgprot(0) +#endif + +#endif /* __ASSEMBLY__ */ + +#ifndef __ASSEMBLY__ + +/* + * Certain architectures need to do special things when PTEs + * within a page table are directly modified. Thus, the following + * hook is made available. + */ +#ifdef CONFIG_X2TLB +static inline void set_pte(pte_t *ptep, pte_t pte) +{ + ptep->pte_high = pte.pte_high; + smp_wmb(); + ptep->pte_low = pte.pte_low; +} +#else +#define set_pte(pteptr, pteval) (*(pteptr) = pteval) +#endif + +#define set_pte_at(mm,addr,ptep,pteval) set_pte(ptep,pteval) + +/* + * (pmds are folded into pgds so this doesn't get actually called, + * but the define is needed for a generic inline function.) + */ +#define set_pmd(pmdptr, pmdval) (*(pmdptr) = pmdval) + +#define pfn_pte(pfn, prot) \ + __pte(((unsigned long long)(pfn) << PAGE_SHIFT) | pgprot_val(prot)) +#define pfn_pmd(pfn, prot) \ + __pmd(((unsigned long long)(pfn) << PAGE_SHIFT) | pgprot_val(prot)) + +#define pte_none(x) (!pte_val(x)) +#define pte_present(x) ((x).pte_low & (_PAGE_PRESENT | _PAGE_PROTNONE)) + +#define pte_clear(mm,addr,xp) do { set_pte_at(mm, addr, xp, __pte(0)); } while (0) + +#define pmd_none(x) (!pmd_val(x)) +#define pmd_present(x) (pmd_val(x)) +#define pmd_clear(xp) do { set_pmd(xp, __pmd(0)); } while (0) +#define pmd_bad(x) (pmd_val(x) & ~PAGE_MASK) + +#define pages_to_mb(x) ((x) >> (20-PAGE_SHIFT)) +#define pte_page(x) pfn_to_page(pte_pfn(x)) + +/* + * The following only work if pte_present() is true. + * Undefined behaviour if not.. + */ +#define pte_not_present(pte) (!((pte).pte_low & _PAGE_PRESENT)) +#define pte_dirty(pte) ((pte).pte_low & _PAGE_DIRTY) +#define pte_young(pte) ((pte).pte_low & _PAGE_ACCESSED) +#define pte_file(pte) ((pte).pte_low & _PAGE_FILE) + +#ifdef CONFIG_X2TLB +#define pte_write(pte) ((pte).pte_high & _PAGE_EXT_USER_WRITE) +#else +#define pte_write(pte) ((pte).pte_low & _PAGE_RW) +#endif + +#define PTE_BIT_FUNC(h,fn,op) \ +static inline pte_t pte_##fn(pte_t pte) { pte.pte_##h op; return pte; } + +#ifdef CONFIG_X2TLB +/* + * We cheat a bit in the SH-X2 TLB case. As the permission bits are + * individually toggled (and user permissions are entirely decoupled from + * kernel permissions), we attempt to couple them a bit more sanely here. + */ +PTE_BIT_FUNC(high, wrprotect, &= ~_PAGE_EXT_USER_WRITE); +PTE_BIT_FUNC(high, mkwrite, |= _PAGE_EXT_USER_WRITE | _PAGE_EXT_KERN_WRITE); +PTE_BIT_FUNC(high, mkhuge, |= _PAGE_SZHUGE); +#else +PTE_BIT_FUNC(low, wrprotect, &= ~_PAGE_RW); +PTE_BIT_FUNC(low, mkwrite, |= _PAGE_RW); +PTE_BIT_FUNC(low, mkhuge, |= _PAGE_SZHUGE); +#endif + +PTE_BIT_FUNC(low, mkclean, &= ~_PAGE_DIRTY); +PTE_BIT_FUNC(low, mkdirty, |= _PAGE_DIRTY); +PTE_BIT_FUNC(low, mkold, &= ~_PAGE_ACCESSED); +PTE_BIT_FUNC(low, mkyoung, |= _PAGE_ACCESSED); + +/* + * Macro and implementation to make a page protection as uncachable. + */ +#define pgprot_writecombine(prot) \ + __pgprot(pgprot_val(prot) & ~_PAGE_CACHABLE) + +#define pgprot_noncached pgprot_writecombine + +/* + * Conversion functions: convert a page and protection to a page entry, + * and a page entry and page directory to the page they refer to. + * + * extern pte_t mk_pte(struct page *page, pgprot_t pgprot) + */ +#define mk_pte(page, pgprot) pfn_pte(page_to_pfn(page), (pgprot)) + +static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) +{ + pte.pte_low &= _PAGE_CHG_MASK; + pte.pte_low |= pgprot_val(newprot); + +#ifdef CONFIG_X2TLB + pte.pte_high |= pgprot_val(newprot) >> 32; +#endif + + return pte; +} + +#define pmd_page_vaddr(pmd) ((unsigned long)pmd_val(pmd)) +#define pmd_page(pmd) (virt_to_page(pmd_val(pmd))) + +/* to find an entry in a page-table-directory. */ +#define pgd_index(address) (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD-1)) +#define pgd_offset(mm, address) ((mm)->pgd+pgd_index(address)) + +/* to find an entry in a kernel page-table-directory */ +#define pgd_offset_k(address) pgd_offset(&init_mm, address) + +/* Find an entry in the third-level page table.. */ +#define pte_index(address) ((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)) +#define pte_offset_kernel(dir, address) \ + ((pte_t *) pmd_page_vaddr(*(dir)) + pte_index(address)) +#define pte_offset_map(dir, address) pte_offset_kernel(dir, address) +#define pte_offset_map_nested(dir, address) pte_offset_kernel(dir, address) + +#define pte_unmap(pte) do { } while (0) +#define pte_unmap_nested(pte) do { } while (0) + +#ifdef CONFIG_X2TLB +#define pte_ERROR(e) \ + printk("%s:%d: bad pte %p(%08lx%08lx).\n", __FILE__, __LINE__, \ + &(e), (e).pte_high, (e).pte_low) +#define pgd_ERROR(e) \ + printk("%s:%d: bad pgd %016llx.\n", __FILE__, __LINE__, pgd_val(e)) +#else +#define pte_ERROR(e) \ + printk("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, pte_val(e)) +#define pgd_ERROR(e) \ + printk("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pgd_val(e)) +#endif + +/* + * Encode and de-code a swap entry + * + * Constraints: + * _PAGE_FILE at bit 0 + * _PAGE_PRESENT at bit 8 + * _PAGE_PROTNONE at bit 9 + * + * For the normal case, we encode the swap type into bits 0:7 and the + * swap offset into bits 10:30. For the 64-bit PTE case, we keep the + * preserved bits in the low 32-bits and use the upper 32 as the swap + * offset (along with a 5-bit type), following the same approach as x86 + * PAE. This keeps the logic quite simple, and allows for a full 32 + * PTE_FILE_MAX_BITS, as opposed to the 29-bits we're constrained with + * in the pte_low case. + * + * As is evident by the Alpha code, if we ever get a 64-bit unsigned + * long (swp_entry_t) to match up with the 64-bit PTEs, this all becomes + * much cleaner.. + * + * NOTE: We should set ZEROs at the position of _PAGE_PRESENT + * and _PAGE_PROTNONE bits + */ +#ifdef CONFIG_X2TLB +#define __swp_type(x) ((x).val & 0x1f) +#define __swp_offset(x) ((x).val >> 5) +#define __swp_entry(type, offset) ((swp_entry_t){ (type) | (offset) << 5}) +#define __pte_to_swp_entry(pte) ((swp_entry_t){ (pte).pte_high }) +#define __swp_entry_to_pte(x) ((pte_t){ 0, (x).val }) + +/* + * Encode and decode a nonlinear file mapping entry + */ +#define pte_to_pgoff(pte) ((pte).pte_high) +#define pgoff_to_pte(off) ((pte_t) { _PAGE_FILE, (off) }) + +#define PTE_FILE_MAX_BITS 32 +#else +#define __swp_type(x) ((x).val & 0xff) +#define __swp_offset(x) ((x).val >> 10) +#define __swp_entry(type, offset) ((swp_entry_t){(type) | (offset) <<10}) + +#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) >> 1 }) +#define __swp_entry_to_pte(x) ((pte_t) { (x).val << 1 }) + +/* + * Encode and decode a nonlinear file mapping entry + */ +#define PTE_FILE_MAX_BITS 29 +#define pte_to_pgoff(pte) (pte_val(pte) >> 1) +#define pgoff_to_pte(off) ((pte_t) { ((off) << 1) | _PAGE_FILE }) +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ASM_SH_PGTABLE_32_H */ diff --git a/include/asm-sh/pgtable_64.h b/include/asm-sh/pgtable_64.h new file mode 100644 index 00000000000..972211671c9 --- /dev/null +++ b/include/asm-sh/pgtable_64.h @@ -0,0 +1,299 @@ +#ifndef __ASM_SH_PGTABLE_64_H +#define __ASM_SH_PGTABLE_64_H + +/* + * include/asm-sh/pgtable_64.h + * + * This file contains the functions and defines necessary to modify and use + * the SuperH page table tree. + * + * Copyright (C) 2000, 2001 Paolo Alberelli + * Copyright (C) 2003, 2004 Paul Mundt + * Copyright (C) 2003, 2004 Richard Curnow + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#include <linux/threads.h> +#include <asm/processor.h> +#include <asm/page.h> + +/* + * Error outputs. + */ +#define pte_ERROR(e) \ + printk("%s:%d: bad pte %016Lx.\n", __FILE__, __LINE__, pte_val(e)) +#define pgd_ERROR(e) \ + printk("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pgd_val(e)) + +/* + * Table setting routines. Used within arch/mm only. + */ +#define set_pmd(pmdptr, pmdval) (*(pmdptr) = pmdval) + +static __inline__ void set_pte(pte_t *pteptr, pte_t pteval) +{ + unsigned long long x = ((unsigned long long) pteval.pte_low); + unsigned long long *xp = (unsigned long long *) pteptr; + /* + * Sign-extend based on NPHYS. + */ + *(xp) = (x & NPHYS_SIGN) ? (x | NPHYS_MASK) : x; +} +#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. + */ + +/* To find an entry in a generic PGD. */ +#define pgd_index(address) (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD-1)) +#define __pgd_offset(address) pgd_index(address) +#define pgd_offset(mm, address) ((mm)->pgd+pgd_index(address)) + +/* To find an entry in a kernel PGD. */ +#define pgd_offset_k(address) pgd_offset(&init_mm, address) + +/* + * PMD level access routines. Same notes as above. + */ +#define _PMD_EMPTY 0x0 +/* Either the PMD is empty or present, it's not paged out */ +#define pmd_present(pmd_entry) (pmd_val(pmd_entry) & _PAGE_PRESENT) +#define pmd_clear(pmd_entry_p) (set_pmd((pmd_entry_p), __pmd(_PMD_EMPTY))) +#define pmd_none(pmd_entry) (pmd_val((pmd_entry)) == _PMD_EMPTY) +#define pmd_bad(pmd_entry) ((pmd_val(pmd_entry) & (~PAGE_MASK & ~_PAGE_USER)) != _KERNPG_TABLE) + +#define pmd_page_vaddr(pmd_entry) \ + ((unsigned long) __va(pmd_val(pmd_entry) & PAGE_MASK)) + +#define pmd_page(pmd) \ + (virt_to_page(pmd_val(pmd))) + +/* PMD to PTE dereferencing */ +#define pte_index(address) \ + ((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)) + +#define pte_offset_kernel(dir, addr) \ + ((pte_t *) ((pmd_val(*(dir))) & PAGE_MASK) + pte_index((addr))) + +#define pte_offset_map(dir,addr) pte_offset_kernel(dir, addr) +#define pte_offset_map_nested(dir,addr) pte_offset_kernel(dir, addr) +#define pte_unmap(pte) do { } while (0) +#define pte_unmap_nested(pte) do { } while (0) + +#ifndef __ASSEMBLY__ +#define IOBASE_VADDR 0xff000000 +#define IOBASE_END 0xffffffff + +/* + * PTEL coherent flags. + * See Chapter 17 ST50 CPU Core Volume 1, Architecture. + */ +/* The bits that are required in the SH-5 TLB are placed in the h/w-defined + positions, to avoid expensive bit shuffling on every refill. The remaining + bits are used for s/w purposes and masked out on each refill. + + Note, the PTE slots are used to hold data of type swp_entry_t when a page is + swapped out. Only the _PAGE_PRESENT flag is significant when the page is + swapped out, and it must be placed so that it doesn't overlap either the + type or offset fields of swp_entry_t. For x86, offset is at [31:8] and type + at [6:1], with _PAGE_PRESENT at bit 0 for both pte_t and swp_entry_t. This + scheme doesn't map to SH-5 because bit [0] controls cacheability. So bit + [2] is used for _PAGE_PRESENT and the type field of swp_entry_t is split + into 2 pieces. That is handled by SWP_ENTRY and SWP_TYPE below. */ +#define _PAGE_WT 0x001 /* CB0: if cacheable, 1->write-thru, 0->write-back */ +#define _PAGE_DEVICE 0x001 /* CB0: if uncacheable, 1->device (i.e. no write-combining or reordering at bus level) */ +#define _PAGE_CACHABLE 0x002 /* CB1: uncachable/cachable */ +#define _PAGE_PRESENT 0x004 /* software: page referenced */ +#define _PAGE_FILE 0x004 /* software: only when !present */ +#define _PAGE_SIZE0 0x008 /* SZ0-bit : size of page */ +#define _PAGE_SIZE1 0x010 /* SZ1-bit : size of page */ +#define _PAGE_SHARED 0x020 /* software: reflects PTEH's SH */ +#define _PAGE_READ 0x040 /* PR0-bit : read access allowed */ +#define _PAGE_EXECUTE 0x080 /* PR1-bit : execute access allowed */ +#define _PAGE_WRITE 0x100 /* PR2-bit : write access allowed */ +#define _PAGE_USER 0x200 /* PR3-bit : user space access allowed */ +#define _PAGE_DIRTY 0x400 /* software: page accessed in write */ +#define _PAGE_ACCESSED 0x800 /* software: page referenced */ + +/* Mask which drops software flags */ +#define _PAGE_FLAGS_HARDWARE_MASK 0xfffffffffffff3dbLL + +/* + * HugeTLB support + */ +#if defined(CONFIG_HUGETLB_PAGE_SIZE_64K) +#define _PAGE_SZHUGE (_PAGE_SIZE0) +#elif defined(CONFIG_HUGETLB_PAGE_SIZE_1MB) +#define _PAGE_SZHUGE (_PAGE_SIZE1) +#elif defined(CONFIG_HUGETLB_PAGE_SIZE_512MB) +#define _PAGE_SZHUGE (_PAGE_SIZE0 | _PAGE_SIZE1) +#endif + +/* + * Default flags for a Kernel page. + * This is fundametally also SHARED because the main use of this define + * (other than for PGD/PMD entries) is for the VMALLOC pool which is + * contextless. + * + * _PAGE_EXECUTE is required for modules + * + */ +#define _KERNPG_TABLE (_PAGE_PRESENT | _PAGE_READ | _PAGE_WRITE | \ + _PAGE_EXECUTE | \ + _PAGE_CACHABLE | _PAGE_ACCESSED | _PAGE_DIRTY | \ + _PAGE_SHARED) + +/* Default flags for a User page */ +#define _PAGE_TABLE (_KERNPG_TABLE | _PAGE_USER) + +#define _PAGE_CHG_MASK (PTE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY) + +/* + * We have full permissions (Read/Write/Execute/Shared). + */ +#define _PAGE_COMMON (_PAGE_PRESENT | _PAGE_USER | \ + _PAGE_CACHABLE | _PAGE_ACCESSED) + +#define PAGE_NONE __pgprot(_PAGE_CACHABLE | _PAGE_ACCESSED) +#define PAGE_SHARED __pgprot(_PAGE_COMMON | _PAGE_READ | _PAGE_WRITE | \ + _PAGE_SHARED) +#define PAGE_EXECREAD __pgprot(_PAGE_COMMON | _PAGE_READ | _PAGE_EXECUTE) + +/* + * We need to include PAGE_EXECUTE in PAGE_COPY because it is the default + * protection mode for the stack. + */ +#define PAGE_COPY PAGE_EXECREAD + +#define PAGE_READONLY __pgprot(_PAGE_COMMON | _PAGE_READ) +#define PAGE_WRITEONLY __pgprot(_PAGE_COMMON | _PAGE_WRITE) +#define PAGE_RWX __pgprot(_PAGE_COMMON | _PAGE_READ | \ + _PAGE_WRITE | _PAGE_EXECUTE) +#define PAGE_KERNEL __pgprot(_KERNPG_TABLE) + +/* Make it a device mapping for maximum safety (e.g. for mapping device + registers into user-space via /dev/map). */ +#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. + * + * Note1: + * It's the tree walk leaf. This is physical address to be stored. + * + * Note 2: + * Regarding the choice of _PTE_EMPTY: + + We must choose a bit pattern that cannot be valid, whether or not the page + is present. bit[2]==1 => present, bit[2]==0 => swapped out. If swapped + out, bits [31:8], [6:3], [1:0] are under swapper control, so only bit[7] is + left for us to select. If we force bit[7]==0 when swapped out, we could use + the combination bit[7,2]=2'b10 to indicate an empty PTE. Alternatively, if + we force bit[7]==1 when swapped out, we can use all zeroes to indicate + empty. This is convenient, because the page tables get cleared to zero + when they are allocated. + + */ +#define _PTE_EMPTY 0x0 +#define pte_present(x) (pte_val(x) & _PAGE_PRESENT) +#define pte_clear(mm,addr,xp) (set_pte_at(mm, addr, xp, __pte(_PTE_EMPTY))) +#define pte_none(x) (pte_val(x) == _PTE_EMPTY) + +/* + * Some definitions to translate between mem_map, PTEs, and page + * addresses: + */ + +/* + * Given a PTE, return the index of the mem_map[] entry corresponding + * to the page frame the PTE. Get the absolute physical address, make + * a relative physical address and translate it to an index. + */ +#define pte_pagenr(x) (((unsigned long) (pte_val(x)) - \ + __MEMORY_START) >> PAGE_SHIFT) + +/* + * Given a PTE, return the "struct page *". + */ +#define pte_page(x) (mem_map + pte_pagenr(x)) + +/* + * Return number of (down rounded) MB corresponding to x pages. + */ +#define pages_to_mb(x) ((x) >> (20-PAGE_SHIFT)) + + +/* + * The following have defined behavior only work if pte_present() is true. + */ +static inline int pte_dirty(pte_t pte){ return pte_val(pte) & _PAGE_DIRTY; } +static inline int pte_young(pte_t pte){ return pte_val(pte) & _PAGE_ACCESSED; } +static inline int pte_file(pte_t pte) { return pte_val(pte) & _PAGE_FILE; } +static inline int pte_write(pte_t pte){ return pte_val(pte) & _PAGE_WRITE; } + +static inline pte_t pte_wrprotect(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_WRITE)); return pte; } +static inline pte_t pte_mkclean(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_DIRTY)); return pte; } +static inline pte_t pte_mkold(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_ACCESSED)); return pte; } +static inline pte_t pte_mkwrite(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) | _PAGE_WRITE)); return pte; } +static inline pte_t pte_mkdirty(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) | _PAGE_DIRTY)); return pte; } +static inline pte_t pte_mkyoung(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) | _PAGE_ACCESSED)); return pte; } +static inline pte_t pte_mkhuge(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) | _PAGE_SZHUGE)); return pte; } + + +/* + * Conversion functions: convert a page and protection to a page entry. + * + * extern pte_t mk_pte(struct page *page, pgprot_t pgprot) + */ +#define mk_pte(page,pgprot) \ +({ \ + pte_t __pte; \ + \ + set_pte(&__pte, __pte((((page)-mem_map) << PAGE_SHIFT) | \ + __MEMORY_START | pgprot_val((pgprot)))); \ + __pte; \ +}) + +/* + * This takes a (absolute) physical page address that is used + * by the remapping functions + */ +#define mk_pte_phys(physpage, pgprot) \ +({ pte_t __pte; set_pte(&__pte, __pte(physpage | pgprot_val(pgprot))); __pte; }) + +static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) +{ set_pte(&pte, __pte((pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot))); return pte; } + +/* Encode and decode a swap entry */ +#define __swp_type(x) (((x).val & 3) + (((x).val >> 1) & 0x3c)) +#define __swp_offset(x) ((x).val >> 8) +#define __swp_entry(type, offset) ((swp_entry_t) { ((offset << 8) + ((type & 0x3c) << 1) + (type & 3)) }) +#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) }) +#define __swp_entry_to_pte(x) ((pte_t) { (x).val }) + +/* Encode and decode a nonlinear file mapping entry */ +#define PTE_FILE_MAX_BITS 29 +#define pte_to_pgoff(pte) (pte_val(pte)) +#define pgoff_to_pte(off) ((pte_t) { (off) | _PAGE_FILE }) + +#endif /* !__ASSEMBLY__ */ + +#define pfn_pte(pfn, prot) __pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot)) +#define pfn_pmd(pfn, prot) __pmd(((pfn) << PAGE_SHIFT) | pgprot_val(prot)) + +#endif /* __ASM_SH_PGTABLE_64_H */ diff --git a/include/asm-sh/posix_types.h b/include/asm-sh/posix_types.h index 0a3d2f54ab2..4b9d11c9fc7 100644 --- a/include/asm-sh/posix_types.h +++ b/include/asm-sh/posix_types.h @@ -1,122 +1,7 @@ -#ifndef __ASM_SH_POSIX_TYPES_H -#define __ASM_SH_POSIX_TYPES_H - -/* - * This file is generally used by user-level software, so you need to - * be a little careful about namespace pollution etc. Also, we cannot - * assume GCC is being used. - */ - -typedef unsigned long __kernel_ino_t; -typedef unsigned short __kernel_mode_t; -typedef unsigned short __kernel_nlink_t; -typedef long __kernel_off_t; -typedef int __kernel_pid_t; -typedef unsigned short __kernel_ipc_pid_t; -typedef unsigned short __kernel_uid_t; -typedef unsigned short __kernel_gid_t; -typedef unsigned int __kernel_size_t; -typedef int __kernel_ssize_t; -typedef int __kernel_ptrdiff_t; -typedef long __kernel_time_t; -typedef long __kernel_suseconds_t; -typedef long __kernel_clock_t; -typedef int __kernel_timer_t; -typedef int __kernel_clockid_t; -typedef int __kernel_daddr_t; -typedef char * __kernel_caddr_t; -typedef unsigned short __kernel_uid16_t; -typedef unsigned short __kernel_gid16_t; -typedef unsigned int __kernel_uid32_t; -typedef unsigned int __kernel_gid32_t; - -typedef unsigned short __kernel_old_uid_t; -typedef unsigned short __kernel_old_gid_t; -typedef unsigned short __kernel_old_dev_t; - -#ifdef __GNUC__ -typedef long long __kernel_loff_t; -#endif - -typedef struct { -#if defined(__KERNEL__) || defined(__USE_ALL) - int val[2]; -#else /* !defined(__KERNEL__) && !defined(__USE_ALL) */ - int __val[2]; -#endif /* !defined(__KERNEL__) && !defined(__USE_ALL) */ -} __kernel_fsid_t; - -#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) - -#undef __FD_SET -static __inline__ void __FD_SET(unsigned long __fd, __kernel_fd_set *__fdsetp) -{ - unsigned long __tmp = __fd / __NFDBITS; - unsigned long __rem = __fd % __NFDBITS; - __fdsetp->fds_bits[__tmp] |= (1UL<<__rem); -} - -#undef __FD_CLR -static __inline__ void __FD_CLR(unsigned long __fd, __kernel_fd_set *__fdsetp) -{ - unsigned long __tmp = __fd / __NFDBITS; - unsigned long __rem = __fd % __NFDBITS; - __fdsetp->fds_bits[__tmp] &= ~(1UL<<__rem); -} - - -#undef __FD_ISSET -static __inline__ int __FD_ISSET(unsigned long __fd, const __kernel_fd_set *__p) -{ - unsigned long __tmp = __fd / __NFDBITS; - unsigned long __rem = __fd % __NFDBITS; - return (__p->fds_bits[__tmp] & (1UL<<__rem)) != 0; -} - -/* - * This will unroll the loop for the normal constant case (8 ints, - * for a 256-bit fd_set) - */ -#undef __FD_ZERO -static __inline__ void __FD_ZERO(__kernel_fd_set *__p) -{ - unsigned long *__tmp = __p->fds_bits; - int __i; - - if (__builtin_constant_p(__FDSET_LONGS)) { - switch (__FDSET_LONGS) { - case 16: - __tmp[ 0] = 0; __tmp[ 1] = 0; - __tmp[ 2] = 0; __tmp[ 3] = 0; - __tmp[ 4] = 0; __tmp[ 5] = 0; - __tmp[ 6] = 0; __tmp[ 7] = 0; - __tmp[ 8] = 0; __tmp[ 9] = 0; - __tmp[10] = 0; __tmp[11] = 0; - __tmp[12] = 0; __tmp[13] = 0; - __tmp[14] = 0; __tmp[15] = 0; - return; - - case 8: - __tmp[ 0] = 0; __tmp[ 1] = 0; - __tmp[ 2] = 0; __tmp[ 3] = 0; - __tmp[ 4] = 0; __tmp[ 5] = 0; - __tmp[ 6] = 0; __tmp[ 7] = 0; - return; - - case 4: - __tmp[ 0] = 0; __tmp[ 1] = 0; - __tmp[ 2] = 0; __tmp[ 3] = 0; - return; - } - } - __i = __FDSET_LONGS; - while (__i) { - __i--; - *__tmp = 0; - __tmp++; - } -} - -#endif /* defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) */ - -#endif /* __ASM_SH_POSIX_TYPES_H */ +#ifdef __KERNEL__ +# ifdef CONFIG_SUPERH32 +# include "posix_types_32.h" +# else +# include "posix_types_64.h" +# endif +#endif /* __KERNEL__ */ diff --git a/include/asm-sh/posix_types_32.h b/include/asm-sh/posix_types_32.h new file mode 100644 index 00000000000..0a3d2f54ab2 --- /dev/null +++ b/include/asm-sh/posix_types_32.h @@ -0,0 +1,122 @@ +#ifndef __ASM_SH_POSIX_TYPES_H +#define __ASM_SH_POSIX_TYPES_H + +/* + * This file is generally used by user-level software, so you need to + * be a little careful about namespace pollution etc. Also, we cannot + * assume GCC is being used. + */ + +typedef unsigned long __kernel_ino_t; +typedef unsigned short __kernel_mode_t; +typedef unsigned short __kernel_nlink_t; +typedef long __kernel_off_t; +typedef int __kernel_pid_t; +typedef unsigned short __kernel_ipc_pid_t; +typedef unsigned short __kernel_uid_t; +typedef unsigned short __kernel_gid_t; +typedef unsigned int __kernel_size_t; +typedef int __kernel_ssize_t; +typedef int __kernel_ptrdiff_t; +typedef long __kernel_time_t; +typedef long __kernel_suseconds_t; +typedef long __kernel_clock_t; +typedef int __kernel_timer_t; +typedef int __kernel_clockid_t; +typedef int __kernel_daddr_t; +typedef char * __kernel_caddr_t; +typedef unsigned short __kernel_uid16_t; +typedef unsigned short __kernel_gid16_t; +typedef unsigned int __kernel_uid32_t; +typedef unsigned int __kernel_gid32_t; + +typedef unsigned short __kernel_old_uid_t; +typedef unsigned short __kernel_old_gid_t; +typedef unsigned short __kernel_old_dev_t; + +#ifdef __GNUC__ +typedef long long __kernel_loff_t; +#endif + +typedef struct { +#if defined(__KERNEL__) || defined(__USE_ALL) + int val[2]; +#else /* !defined(__KERNEL__) && !defined(__USE_ALL) */ + int __val[2]; +#endif /* !defined(__KERNEL__) && !defined(__USE_ALL) */ +} __kernel_fsid_t; + +#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) + +#undef __FD_SET +static __inline__ void __FD_SET(unsigned long __fd, __kernel_fd_set *__fdsetp) +{ + unsigned long __tmp = __fd / __NFDBITS; + unsigned long __rem = __fd % __NFDBITS; + __fdsetp->fds_bits[__tmp] |= (1UL<<__rem); +} + +#undef __FD_CLR +static __inline__ void __FD_CLR(unsigned long __fd, __kernel_fd_set *__fdsetp) +{ + unsigned long __tmp = __fd / __NFDBITS; + unsigned long __rem = __fd % __NFDBITS; + __fdsetp->fds_bits[__tmp] &= ~(1UL<<__rem); +} + + +#undef __FD_ISSET +static __inline__ int __FD_ISSET(unsigned long __fd, const __kernel_fd_set *__p) +{ + unsigned long __tmp = __fd / __NFDBITS; + unsigned long __rem = __fd % __NFDBITS; + return (__p->fds_bits[__tmp] & (1UL<<__rem)) != 0; +} + +/* + * This will unroll the loop for the normal constant case (8 ints, + * for a 256-bit fd_set) + */ +#undef __FD_ZERO +static __inline__ void __FD_ZERO(__kernel_fd_set *__p) +{ + unsigned long *__tmp = __p->fds_bits; + int __i; + + if (__builtin_constant_p(__FDSET_LONGS)) { + switch (__FDSET_LONGS) { + case 16: + __tmp[ 0] = 0; __tmp[ 1] = 0; + __tmp[ 2] = 0; __tmp[ 3] = 0; + __tmp[ 4] = 0; __tmp[ 5] = 0; + __tmp[ 6] = 0; __tmp[ 7] = 0; + __tmp[ 8] = 0; __tmp[ 9] = 0; + __tmp[10] = 0; __tmp[11] = 0; + __tmp[12] = 0; __tmp[13] = 0; + __tmp[14] = 0; __tmp[15] = 0; + return; + + case 8: + __tmp[ 0] = 0; __tmp[ 1] = 0; + __tmp[ 2] = 0; __tmp[ 3] = 0; + __tmp[ 4] = 0; __tmp[ 5] = 0; + __tmp[ 6] = 0; __tmp[ 7] = 0; + return; + + case 4: + __tmp[ 0] = 0; __tmp[ 1] = 0; + __tmp[ 2] = 0; __tmp[ 3] = 0; + return; + } + } + __i = __FDSET_LONGS; + while (__i) { + __i--; + *__tmp = 0; + __tmp++; + } +} + +#endif /* defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) */ + +#endif /* __ASM_SH_POSIX_TYPES_H */ diff --git a/include/asm-sh/posix_types_64.h b/include/asm-sh/posix_types_64.h new file mode 100644 index 00000000000..0620317a6f0 --- /dev/null +++ b/include/asm-sh/posix_types_64.h @@ -0,0 +1,131 @@ +#ifndef __ASM_SH64_POSIX_TYPES_H +#define __ASM_SH64_POSIX_TYPES_H + +/* + * 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-sh64/posix_types.h + * + * Copyright (C) 2000, 2001 Paolo Alberelli + * Copyright (C) 2003 Paul Mundt + * + * This file is generally used by user-level software, so you need to + * be a little careful about namespace pollution etc. Also, we cannot + * assume GCC is being used. + */ + +typedef unsigned long __kernel_ino_t; +typedef unsigned short __kernel_mode_t; +typedef unsigned short __kernel_nlink_t; +typedef long __kernel_off_t; +typedef int __kernel_pid_t; +typedef unsigned short __kernel_ipc_pid_t; +typedef unsigned short __kernel_uid_t; +typedef unsigned short __kernel_gid_t; +typedef long unsigned int __kernel_size_t; +typedef int __kernel_ssize_t; +typedef int __kernel_ptrdiff_t; +typedef long __kernel_time_t; +typedef long __kernel_suseconds_t; +typedef long __kernel_clock_t; +typedef int __kernel_timer_t; +typedef int __kernel_clockid_t; +typedef int __kernel_daddr_t; +typedef char * __kernel_caddr_t; +typedef unsigned short __kernel_uid16_t; +typedef unsigned short __kernel_gid16_t; +typedef unsigned int __kernel_uid32_t; +typedef unsigned int __kernel_gid32_t; + +typedef unsigned short __kernel_old_uid_t; +typedef unsigned short __kernel_old_gid_t; +typedef unsigned short __kernel_old_dev_t; + +#ifdef __GNUC__ +typedef long long __kernel_loff_t; +#endif + +typedef struct { +#if defined(__KERNEL__) || defined(__USE_ALL) + int val[2]; +#else /* !defined(__KERNEL__) && !defined(__USE_ALL) */ + int __val[2]; +#endif /* !defined(__KERNEL__) && !defined(__USE_ALL) */ +} __kernel_fsid_t; + +#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) + +#undef __FD_SET +static __inline__ void __FD_SET(unsigned long __fd, __kernel_fd_set *__fdsetp) +{ + unsigned long __tmp = __fd / __NFDBITS; + unsigned long __rem = __fd % __NFDBITS; + __fdsetp->fds_bits[__tmp] |= (1UL<<__rem); +} + +#undef __FD_CLR +static __inline__ void __FD_CLR(unsigned long __fd, __kernel_fd_set *__fdsetp) +{ + unsigned long __tmp = __fd / __NFDBITS; + unsigned long __rem = __fd % __NFDBITS; + __fdsetp->fds_bits[__tmp] &= ~(1UL<<__rem); +} + + +#undef __FD_ISSET +static __inline__ int __FD_ISSET(unsigned long __fd, const __kernel_fd_set *__p) +{ + unsigned long __tmp = __fd / __NFDBITS; + unsigned long __rem = __fd % __NFDBITS; + return (__p->fds_bits[__tmp] & (1UL<<__rem)) != 0; +} + +/* + * This will unroll the loop for the normal constant case (8 ints, + * for a 256-bit fd_set) + */ +#undef __FD_ZERO +static __inline__ void __FD_ZERO(__kernel_fd_set *__p) +{ + unsigned long *__tmp = __p->fds_bits; + int __i; + + if (__builtin_constant_p(__FDSET_LONGS)) { + switch (__FDSET_LONGS) { + case 16: + __tmp[ 0] = 0; __tmp[ 1] = 0; + __tmp[ 2] = 0; __tmp[ 3] = 0; + __tmp[ 4] = 0; __tmp[ 5] = 0; + __tmp[ 6] = 0; __tmp[ 7] = 0; + __tmp[ 8] = 0; __tmp[ 9] = 0; + __tmp[10] = 0; __tmp[11] = 0; + __tmp[12] = 0; __tmp[13] = 0; + __tmp[14] = 0; __tmp[15] = 0; + return; + + case 8: + __tmp[ 0] = 0; __tmp[ 1] = 0; + __tmp[ 2] = 0; __tmp[ 3] = 0; + __tmp[ 4] = 0; __tmp[ 5] = 0; + __tmp[ 6] = 0; __tmp[ 7] = 0; + return; + + case 4: + __tmp[ 0] = 0; __tmp[ 1] = 0; + __tmp[ 2] = 0; __tmp[ 3] = 0; + return; + } + } + __i = __FDSET_LONGS; + while (__i) { + __i--; + *__tmp = 0; + __tmp++; + } +} + +#endif /* defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) */ + +#endif /* __ASM_SH64_POSIX_TYPES_H */ diff --git a/include/asm-sh/processor.h b/include/asm-sh/processor.h index fda68480f37..c9b14161f73 100644 --- a/include/asm-sh/processor.h +++ b/include/asm-sh/processor.h @@ -1,32 +1,10 @@ -/* - * include/asm-sh/processor.h - * - * Copyright (C) 1999, 2000 Niibe Yutaka - * Copyright (C) 2002, 2003 Paul Mundt - */ - #ifndef __ASM_SH_PROCESSOR_H #define __ASM_SH_PROCESSOR_H -#ifdef __KERNEL__ -#include <linux/compiler.h> -#include <asm/page.h> -#include <asm/types.h> -#include <asm/cache.h> -#include <asm/ptrace.h> #include <asm/cpu-features.h> +#include <asm/fpu.h> -/* - * Default implementation of macro that returns current - * instruction pointer ("program counter"). - */ -#define current_text_addr() ({ void *pc; __asm__("mova 1f, %0\n1:":"=z" (pc)); pc; }) - -/* Core Processor Version Register */ -#define CCN_PVR 0xff000030 -#define CCN_CVR 0xff000040 -#define CCN_PRR 0xff000044 - +#ifndef __ASSEMBLY__ /* * CPU type and hardware bug flags. Kept separately for each CPU. * @@ -39,247 +17,49 @@ enum cpu_type { CPU_SH7619, /* SH-2A types */ - CPU_SH7206, + CPU_SH7203, CPU_SH7206, CPU_SH7263, /* SH-3 types */ CPU_SH7705, CPU_SH7706, CPU_SH7707, CPU_SH7708, CPU_SH7708S, CPU_SH7708R, CPU_SH7709, CPU_SH7709A, CPU_SH7710, CPU_SH7712, - CPU_SH7720, CPU_SH7729, + CPU_SH7720, CPU_SH7721, CPU_SH7729, /* SH-4 types */ CPU_SH7750, CPU_SH7750S, CPU_SH7750R, CPU_SH7751, CPU_SH7751R, CPU_SH7760, CPU_SH4_202, CPU_SH4_501, /* SH-4A types */ - CPU_SH7770, CPU_SH7780, CPU_SH7781, CPU_SH7785, CPU_SHX3, + CPU_SH7763, CPU_SH7770, CPU_SH7780, CPU_SH7781, CPU_SH7785, CPU_SHX3, /* SH4AL-DSP types */ CPU_SH7343, CPU_SH7722, + /* SH-5 types */ + CPU_SH5_101, CPU_SH5_103, + /* Unknown subtype */ CPU_SH_NONE }; -struct sh_cpuinfo { - unsigned int type; - unsigned long loops_per_jiffy; - unsigned long asid_cache; - - struct cache_info icache; /* Primary I-cache */ - struct cache_info dcache; /* Primary D-cache */ - struct cache_info scache; /* Secondary cache */ - - unsigned long flags; -} __attribute__ ((aligned(L1_CACHE_BYTES))); - -extern struct sh_cpuinfo cpu_data[]; -#define boot_cpu_data cpu_data[0] -#define current_cpu_data cpu_data[smp_processor_id()] -#define raw_current_cpu_data cpu_data[raw_smp_processor_id()] - -/* - * User space process size: 2GB. - * - * Since SH7709 and SH7750 have "area 7", we can't use 0x7c000000--0x7fffffff - */ -#define TASK_SIZE 0x7c000000UL - -/* This decides where the kernel will search for a free chunk of vm - * space during mmap's. - */ -#define TASK_UNMAPPED_BASE (TASK_SIZE / 3) - -/* - * Bit of SR register - * - * FD-bit: - * When it's set, it means the processor doesn't have right to use FPU, - * and it results exception when the floating operation is executed. - * - * IMASK-bit: - * Interrupt level mask - */ -#define SR_FD 0x00008000 -#define SR_DSP 0x00001000 -#define SR_IMASK 0x000000f0 - -/* - * FPU structure and data - */ - -struct sh_fpu_hard_struct { - unsigned long fp_regs[16]; - unsigned long xfp_regs[16]; - unsigned long fpscr; - unsigned long fpul; - - long status; /* software status information */ -}; - -/* Dummy fpu emulator */ -struct sh_fpu_soft_struct { - unsigned long fp_regs[16]; - unsigned long xfp_regs[16]; - unsigned long fpscr; - unsigned long fpul; - - unsigned char lookahead; - unsigned long entry_pc; -}; - -union sh_fpu_union { - struct sh_fpu_hard_struct hard; - struct sh_fpu_soft_struct soft; -}; - -struct thread_struct { - /* Saved registers when thread is descheduled */ - unsigned long sp; - unsigned long pc; - - /* Hardware debugging registers */ - unsigned long ubc_pc; - - /* floating point info */ - union sh_fpu_union fpu; -}; - -typedef struct { - unsigned long seg; -} mm_segment_t; - -/* Count of active tasks with UBC settings */ -extern int ubc_usercnt; +/* Forward decl */ +struct sh_cpuinfo; -#define INIT_THREAD { \ - .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; - -/* Free all resources held by a thread. */ -extern void release_thread(struct task_struct *); - -/* Prepare to copy thread state - unlazy all lazy status */ -#define prepare_to_copy(tsk) do { } while (0) - -/* - * create a kernel thread without removing it from tasklists - */ -extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags); - -/* Copy and release all segment info associated with a VM */ -#define copy_segments(p, mm) do { } while(0) -#define release_segments(mm) do { } while(0) - -/* - * FPU lazy state save handling. - */ - -static __inline__ void disable_fpu(void) -{ - unsigned long __dummy; - - /* Set FD flag in SR */ - __asm__ __volatile__("stc sr, %0\n\t" - "or %1, %0\n\t" - "ldc %0, sr" - : "=&r" (__dummy) - : "r" (SR_FD)); -} - -static __inline__ void enable_fpu(void) -{ - unsigned long __dummy; - - /* Clear out FD flag in SR */ - __asm__ __volatile__("stc sr, %0\n\t" - "and %1, %0\n\t" - "ldc %0, sr" - : "=&r" (__dummy) - : "r" (~SR_FD)); -} - -static __inline__ void release_fpu(struct pt_regs *regs) -{ - regs->sr |= SR_FD; -} - -static __inline__ void grab_fpu(struct pt_regs *regs) -{ - regs->sr &= ~SR_FD; -} - -extern void save_fpu(struct task_struct *__tsk, struct pt_regs *regs); - -#define unlazy_fpu(tsk, regs) do { \ - if (test_tsk_thread_flag(tsk, TIF_USEDFPU)) { \ - save_fpu(tsk, regs); \ - } \ -} while (0) - -#define clear_fpu(tsk, regs) do { \ - if (test_tsk_thread_flag(tsk, TIF_USEDFPU)) { \ - clear_tsk_thread_flag(tsk, TIF_USEDFPU); \ - release_fpu(regs); \ - } \ -} while (0) - -/* Double presision, NANS as NANS, rounding to nearest, no exceptions */ -#define FPSCR_INIT 0x00080000 - -#define FPSCR_CAUSE_MASK 0x0001f000 /* Cause bits */ -#define FPSCR_FLAG_MASK 0x0000007c /* Flag bits */ - -/* - * Return saved PC of a blocked thread. - */ -#define thread_saved_pc(tsk) (tsk->thread.pc) - -void show_trace(struct task_struct *tsk, unsigned long *sp, - struct pt_regs *regs); -extern unsigned long get_wchan(struct task_struct *p); - -#define KSTK_EIP(tsk) (task_pt_regs(tsk)->pc) -#define KSTK_ESP(tsk) (task_pt_regs(tsk)->regs[15]) - -#define cpu_sleep() __asm__ __volatile__ ("sleep" : : : "memory") -#define cpu_relax() barrier() - -#if defined(CONFIG_CPU_SH2A) || defined(CONFIG_CPU_SH3) || \ - defined(CONFIG_CPU_SH4) -#define PREFETCH_STRIDE L1_CACHE_BYTES -#define ARCH_HAS_PREFETCH -#define ARCH_HAS_PREFETCHW -static inline void prefetch(void *x) -{ - __asm__ __volatile__ ("pref @%0\n\t" : : "r" (x) : "memory"); -} - -#define prefetchw(x) prefetch(x) -#endif +/* arch/sh/kernel/setup.c */ +const char *get_cpu_subtype(struct sh_cpuinfo *c); #ifdef CONFIG_VSYSCALL -extern int vsyscall_init(void); +int vsyscall_init(void); #else #define vsyscall_init() do { } while (0) #endif -/* arch/sh/kernel/setup.c */ -const char *get_cpu_subtype(struct sh_cpuinfo *c); +#endif /* __ASSEMBLY__ */ + +#ifdef CONFIG_SUPERH32 +# include "processor_32.h" +#else +# include "processor_64.h" +#endif -#endif /* __KERNEL__ */ #endif /* __ASM_SH_PROCESSOR_H */ diff --git a/include/asm-sh/processor_32.h b/include/asm-sh/processor_32.h new file mode 100644 index 00000000000..a7edaa1a870 --- /dev/null +++ b/include/asm-sh/processor_32.h @@ -0,0 +1,215 @@ +/* + * include/asm-sh/processor.h + * + * Copyright (C) 1999, 2000 Niibe Yutaka + * Copyright (C) 2002, 2003 Paul Mundt + */ + +#ifndef __ASM_SH_PROCESSOR_32_H +#define __ASM_SH_PROCESSOR_32_H +#ifdef __KERNEL__ + +#include <linux/compiler.h> +#include <asm/page.h> +#include <asm/types.h> +#include <asm/cache.h> +#include <asm/ptrace.h> + +/* + * Default implementation of macro that returns current + * instruction pointer ("program counter"). + */ +#define current_text_addr() ({ void *pc; __asm__("mova 1f, %0\n1:":"=z" (pc)); pc; }) + +/* Core Processor Version Register */ +#define CCN_PVR 0xff000030 +#define CCN_CVR 0xff000040 +#define CCN_PRR 0xff000044 + +struct sh_cpuinfo { + unsigned int type; + unsigned long loops_per_jiffy; + unsigned long asid_cache; + + struct cache_info icache; /* Primary I-cache */ + struct cache_info dcache; /* Primary D-cache */ + struct cache_info scache; /* Secondary cache */ + + unsigned long flags; +} __attribute__ ((aligned(L1_CACHE_BYTES))); + +extern struct sh_cpuinfo cpu_data[]; +#define boot_cpu_data cpu_data[0] +#define current_cpu_data cpu_data[smp_processor_id()] +#define raw_current_cpu_data cpu_data[raw_smp_processor_id()] + +/* + * User space process size: 2GB. + * + * Since SH7709 and SH7750 have "area 7", we can't use 0x7c000000--0x7fffffff + */ +#define TASK_SIZE 0x7c000000UL + +/* This decides where the kernel will search for a free chunk of vm + * space during mmap's. + */ +#define TASK_UNMAPPED_BASE (TASK_SIZE / 3) + +/* + * Bit of SR register + * + * FD-bit: + * When it's set, it means the processor doesn't have right to use FPU, + * and it results exception when the floating operation is executed. + * + * IMASK-bit: + * Interrupt level mask + */ +#define SR_DSP 0x00001000 +#define SR_IMASK 0x000000f0 + +/* + * FPU structure and data + */ + +struct sh_fpu_hard_struct { + unsigned long fp_regs[16]; + unsigned long xfp_regs[16]; + unsigned long fpscr; + unsigned long fpul; + + long status; /* software status information */ +}; + +/* Dummy fpu emulator */ +struct sh_fpu_soft_struct { + unsigned long fp_regs[16]; + unsigned long xfp_regs[16]; + unsigned long fpscr; + unsigned long fpul; + + unsigned char lookahead; + unsigned long entry_pc; +}; + +union sh_fpu_union { + struct sh_fpu_hard_struct hard; + struct sh_fpu_soft_struct soft; +}; + +struct thread_struct { + /* Saved registers when thread is descheduled */ + unsigned long sp; + unsigned long pc; + + /* Hardware debugging registers */ + unsigned long ubc_pc; + + /* floating point info */ + union sh_fpu_union fpu; +}; + +typedef struct { + unsigned long seg; +} mm_segment_t; + +/* Count of active tasks with UBC settings */ +extern int ubc_usercnt; + +#define INIT_THREAD { \ + .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; + +/* Free all resources held by a thread. */ +extern void release_thread(struct task_struct *); + +/* Prepare to copy thread state - unlazy all lazy status */ +#define prepare_to_copy(tsk) do { } while (0) + +/* + * create a kernel thread without removing it from tasklists + */ +extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags); + +/* Copy and release all segment info associated with a VM */ +#define copy_segments(p, mm) do { } while(0) +#define release_segments(mm) do { } while(0) + +/* + * FPU lazy state save handling. + */ + +static __inline__ void disable_fpu(void) +{ + unsigned long __dummy; + + /* Set FD flag in SR */ + __asm__ __volatile__("stc sr, %0\n\t" + "or %1, %0\n\t" + "ldc %0, sr" + : "=&r" (__dummy) + : "r" (SR_FD)); +} + +static __inline__ void enable_fpu(void) +{ + unsigned long __dummy; + + /* Clear out FD flag in SR */ + __asm__ __volatile__("stc sr, %0\n\t" + "and %1, %0\n\t" + "ldc %0, sr" + : "=&r" (__dummy) + : "r" (~SR_FD)); +} + +/* Double presision, NANS as NANS, rounding to nearest, no exceptions */ +#define FPSCR_INIT 0x00080000 + +#define FPSCR_CAUSE_MASK 0x0001f000 /* Cause bits */ +#define FPSCR_FLAG_MASK 0x0000007c /* Flag bits */ + +/* + * Return saved PC of a blocked thread. + */ +#define thread_saved_pc(tsk) (tsk->thread.pc) + +void show_trace(struct task_struct *tsk, unsigned long *sp, + struct pt_regs *regs); +extern unsigned long get_wchan(struct task_struct *p); + +#define KSTK_EIP(tsk) (task_pt_regs(tsk)->pc) +#define KSTK_ESP(tsk) (task_pt_regs(tsk)->regs[15]) + +#define cpu_sleep() __asm__ __volatile__ ("sleep" : : : "memory") +#define cpu_relax() barrier() + +#if defined(CONFIG_CPU_SH2A) || defined(CONFIG_CPU_SH3) || \ + defined(CONFIG_CPU_SH4) +#define PREFETCH_STRIDE L1_CACHE_BYTES +#define ARCH_HAS_PREFETCH +#define ARCH_HAS_PREFETCHW +static inline void prefetch(void *x) +{ + __asm__ __volatile__ ("pref @%0\n\t" : : "r" (x) : "memory"); +} + +#define prefetchw(x) prefetch(x) +#endif + +#endif /* __KERNEL__ */ +#endif /* __ASM_SH_PROCESSOR_32_H */ diff --git a/include/asm-sh/processor_64.h b/include/asm-sh/processor_64.h new file mode 100644 index 00000000000..99c22b14a85 --- /dev/null +++ b/include/asm-sh/processor_64.h @@ -0,0 +1,275 @@ +#ifndef __ASM_SH_PROCESSOR_64_H +#define __ASM_SH_PROCESSOR_64_H + +/* + * include/asm-sh/processor_64.h + * + * Copyright (C) 2000, 2001 Paolo Alberelli + * Copyright (C) 2003 Paul Mundt + * Copyright (C) 2004 Richard Curnow + * + * 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 __ASSEMBLY__ + +#include <linux/compiler.h> +#include <asm/page.h> +#include <asm/types.h> +#include <asm/cache.h> +#include <asm/ptrace.h> +#include <asm/cpu/registers.h> + +/* + * Default implementation of macro that returns current + * instruction pointer ("program counter"). + */ +#define current_text_addr() ({ \ +void *pc; \ +unsigned long long __dummy = 0; \ +__asm__("gettr tr0, %1\n\t" \ + "pta 4, tr0\n\t" \ + "gettr tr0, %0\n\t" \ + "ptabs %1, tr0\n\t" \ + :"=r" (pc), "=r" (__dummy) \ + : "1" (__dummy)); \ +pc; }) + +/* + * TLB information structure + * + * Defined for both I and D tlb, per-processor. + */ +struct tlb_info { + unsigned long long next; + unsigned long long first; + unsigned long long last; + + unsigned int entries; + unsigned int step; + + unsigned long flags; +}; + +struct sh_cpuinfo { + enum cpu_type type; + unsigned long loops_per_jiffy; + unsigned long asid_cache; + + unsigned int cpu_clock, master_clock, bus_clock, module_clock; + + /* Cache info */ + struct cache_info icache; + struct cache_info dcache; + struct cache_info scache; + + /* TLB info */ + struct tlb_info itlb; + struct tlb_info dtlb; + + unsigned long flags; +}; + +extern struct sh_cpuinfo cpu_data[]; +#define boot_cpu_data cpu_data[0] +#define current_cpu_data cpu_data[smp_processor_id()] +#define raw_current_cpu_data cpu_data[raw_smp_processor_id()] + +#endif + +/* + * User space process size: 2GB - 4k. + */ +#define TASK_SIZE 0x7ffff000UL + +/* This decides where the kernel will search for a free chunk of vm + * space during mmap's. + */ +#define TASK_UNMAPPED_BASE (TASK_SIZE / 3) + +/* + * Bit of SR register + * + * FD-bit: + * When it's set, it means the processor doesn't have right to use FPU, + * and it results exception when the floating operation is executed. + * + * IMASK-bit: + * Interrupt level mask + * + * STEP-bit: + * Single step bit + * + */ +#if defined(CONFIG_SH64_SR_WATCH) +#define SR_MMU 0x84000000 +#else +#define SR_MMU 0x80000000 +#endif + +#define SR_IMASK 0x000000f0 +#define SR_SSTEP 0x08000000 + +#ifndef __ASSEMBLY__ + +/* + * FPU structure and data : require 8-byte alignment as we need to access it + with fld.p, fst.p + */ + +struct sh_fpu_hard_struct { + unsigned long fp_regs[64]; + unsigned int fpscr; + /* long status; * software status information */ +}; + +#if 0 +/* Dummy fpu emulator */ +struct sh_fpu_soft_struct { + unsigned long long fp_regs[32]; + 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. */ + unsigned long long alignment_dummy; +}; + +struct thread_struct { + unsigned long sp; + unsigned long pc; + /* 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 + or one that traps in kernel mode. */ + struct pt_regs *kregs; + /* This stores the address of the pt_regs constructed on entry from + user mode. It is a fixed value over the lifetime of a process, or + NULL for a kernel thread. */ + struct pt_regs *uregs; + + unsigned long trap_no, error_code; + unsigned long address; + /* Hardware debugging registers may come here */ + + /* floating point info */ + 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 } + +extern struct pt_regs fake_swapper_regs; + +#define INIT_THREAD { \ + .sp = sizeof(init_stack) + \ + (long) &init_stack, \ + .pc = 0, \ + .kregs = &fake_swapper_regs, \ + .uregs = NULL, \ + .trap_no = 0, \ + .error_code = 0, \ + .address = 0, \ + .fpu = { { { 0, } }, } \ +} + +/* + * Do necessary setup to start up a newly executed thread. + */ +#define SR_USER (SR_MMU | SR_FD) + +#define start_thread(regs, new_pc, new_sp) \ + set_fs(USER_DS); \ + regs->sr = SR_USER; /* User mode. */ \ + regs->pc = new_pc - 4; /* Compensate syscall exit */ \ + regs->pc |= 1; /* Set SHmedia ! */ \ + regs->regs[18] = 0; \ + regs->regs[15] = new_sp + +/* Forward declaration, a strange C thing */ +struct task_struct; +struct mm_struct; + +/* Free all resources held by a thread. */ +extern void release_thread(struct task_struct *); +/* + * create a kernel thread without removing it from tasklists + */ +extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags); + + +/* Copy and release all segment info associated with a VM */ +#define copy_segments(p, mm) do { } while (0) +#define release_segments(mm) do { } while (0) +#define forget_segments() do { } while (0) +#define prepare_to_copy(tsk) do { } while (0) +/* + * FPU lazy state save handling. + */ + +static inline void disable_fpu(void) +{ + unsigned long long __dummy; + + /* Set FD flag in SR */ + __asm__ __volatile__("getcon " __SR ", %0\n\t" + "or %0, %1, %0\n\t" + "putcon %0, " __SR "\n\t" + : "=&r" (__dummy) + : "r" (SR_FD)); +} + +static inline void enable_fpu(void) +{ + unsigned long long __dummy; + + /* Clear out FD flag in SR */ + __asm__ __volatile__("getcon " __SR ", %0\n\t" + "and %0, %1, %0\n\t" + "putcon %0, " __SR "\n\t" + : "=&r" (__dummy) + : "r" (~SR_FD)); +} + +/* Round to nearest, no exceptions on inexact, overflow, underflow, + zero-divide, invalid. Configure option for whether to flush denorms to + zero, or except if a denorm is encountered. */ +#if defined(CONFIG_SH64_FPU_DENORM_FLUSH) +#define FPSCR_INIT 0x00040000 +#else +#define FPSCR_INIT 0x00000000 +#endif + +#ifdef CONFIG_SH_FPU +/* Initialise the FP state of a task */ +void fpinit(struct sh_fpu_hard_struct *fpregs); +#else +#define fpinit(fpregs) do { } while (0) +#endif + +extern struct task_struct *last_task_used_math; + +/* + * Return saved PC of a blocked thread. + */ +#define thread_saved_pc(tsk) (tsk->thread.pc) + +extern unsigned long get_wchan(struct task_struct *p); + +#define KSTK_EIP(tsk) ((tsk)->thread.pc) +#define KSTK_ESP(tsk) ((tsk)->thread.sp) + +#define cpu_relax() barrier() + +#endif /* __ASSEMBLY__ */ +#endif /* __ASM_SH_PROCESSOR_64_H */ diff --git a/include/asm-sh/ptrace.h b/include/asm-sh/ptrace.h index b9789c8b4d1..8d6c92b3e77 100644 --- a/include/asm-sh/ptrace.h +++ b/include/asm-sh/ptrace.h @@ -5,7 +5,16 @@ * Copyright (C) 1999, 2000 Niibe Yutaka * */ - +#if defined(__SH5__) || defined(CONFIG_SUPERH64) +struct pt_regs { + unsigned long long pc; + unsigned long long sr; + unsigned long long syscall_nr; + unsigned long long regs[63]; + unsigned long long tregs[8]; + unsigned long long pad[2]; +}; +#else /* * GCC defines register number like this: * ----------------------------- @@ -28,7 +37,7 @@ #define REG_PR 17 #define REG_SR 18 -#define REG_GBR 19 +#define REG_GBR 19 #define REG_MACH 20 #define REG_MACL 21 @@ -80,10 +89,14 @@ struct pt_dspregs { #define PTRACE_GETDSPREGS 55 #define PTRACE_SETDSPREGS 56 +#endif #ifdef __KERNEL__ -#define user_mode(regs) (((regs)->sr & 0x40000000)==0) -#define instruction_pointer(regs) ((regs)->pc) +#include <asm/addrspace.h> + +#define user_mode(regs) (((regs)->sr & 0x40000000)==0) +#define instruction_pointer(regs) ((unsigned long)(regs)->pc) + extern void show_regs(struct pt_regs *); #ifdef CONFIG_SH_DSP @@ -100,10 +113,13 @@ static inline unsigned long profile_pc(struct pt_regs *regs) { unsigned long pc = instruction_pointer(regs); - if (pc >= 0xa0000000UL && pc < 0xc0000000UL) +#ifdef P2SEG + if (pc >= P2SEG && pc < P3SEG) pc -= 0x20000000; +#endif + return pc; } -#endif +#endif /* __KERNEL__ */ #endif /* __ASM_SH_PTRACE_H */ diff --git a/include/asm-sh/r7780rp.h b/include/asm-sh/r7780rp.h index de37f933aa4..bdecea0840a 100644 --- a/include/asm-sh/r7780rp.h +++ b/include/asm-sh/r7780rp.h @@ -121,21 +121,6 @@ #define IRLCNTR1 (PA_BCR + 0) /* Interrupt Control Register1 */ -#define IRQ_PCISLOT1 0 /* PCI Slot #1 IRQ */ -#define IRQ_PCISLOT2 1 /* PCI Slot #2 IRQ */ -#define IRQ_PCISLOT3 2 /* PCI Slot #3 IRQ */ -#define IRQ_PCISLOT4 3 /* PCI Slot #4 IRQ */ -#define IRQ_CFINST 5 /* CF Card Insert IRQ */ -#define IRQ_M66596 6 /* M66596 IRQ */ -#define IRQ_SDCARD 7 /* SD Card IRQ */ -#define IRQ_TUCHPANEL 8 /* Touch Panel IRQ */ -#define IRQ_SCI 9 /* SCI IRQ */ -#define IRQ_2SERIAL 10 /* Serial IRQ */ -#define IRQ_EXTENTION 11 /* EXTn IRQ */ -#define IRQ_ONETH 12 /* On board Ethernet IRQ */ -#define IRQ_PSW 13 /* Push Switch IRQ */ -#define IRQ_ZIGBEE 14 /* Ziggbee IO IRQ */ - #define IVDR_CK_ON 8 /* iVDR Clock ON */ #elif defined(CONFIG_SH_R7785RP) @@ -192,13 +177,19 @@ #define IRQ_AX88796 (HL_FPGA_IRQ_BASE + 0) #define IRQ_CF (HL_FPGA_IRQ_BASE + 1) -#ifndef IRQ_PSW #define IRQ_PSW (HL_FPGA_IRQ_BASE + 2) -#endif -#define IRQ_EXT1 (HL_FPGA_IRQ_BASE + 3) -#define IRQ_EXT4 (HL_FPGA_IRQ_BASE + 4) - -void make_r7780rp_irq(unsigned int irq); +#define IRQ_EXT0 (HL_FPGA_IRQ_BASE + 3) +#define IRQ_EXT1 (HL_FPGA_IRQ_BASE + 4) +#define IRQ_EXT2 (HL_FPGA_IRQ_BASE + 5) +#define IRQ_EXT3 (HL_FPGA_IRQ_BASE + 6) +#define IRQ_EXT4 (HL_FPGA_IRQ_BASE + 7) +#define IRQ_EXT5 (HL_FPGA_IRQ_BASE + 8) +#define IRQ_EXT6 (HL_FPGA_IRQ_BASE + 9) +#define IRQ_EXT7 (HL_FPGA_IRQ_BASE + 10) +#define IRQ_SMBUS (HL_FPGA_IRQ_BASE + 11) +#define IRQ_TP (HL_FPGA_IRQ_BASE + 12) +#define IRQ_RTC (HL_FPGA_IRQ_BASE + 13) +#define IRQ_TH_ALERT (HL_FPGA_IRQ_BASE + 14) unsigned char *highlander_init_irq_r7780mp(void); unsigned char *highlander_init_irq_r7780rp(void); diff --git a/include/asm-sh/rtc.h b/include/asm-sh/rtc.h index 858da99d37e..ec45ba8e11d 100644 --- a/include/asm-sh/rtc.h +++ b/include/asm-sh/rtc.h @@ -11,4 +11,6 @@ struct sh_rtc_platform_info { unsigned long capabilities; }; +#include <asm/cpu/rtc.h> + #endif /* _ASM_RTC_H */ diff --git a/include/asm-sh/scatterlist.h b/include/asm-sh/scatterlist.h index a7d0d1856a9..2084d037369 100644 --- a/include/asm-sh/scatterlist.h +++ b/include/asm-sh/scatterlist.h @@ -13,7 +13,7 @@ struct scatterlist { unsigned int length; }; -#define ISA_DMA_THRESHOLD (0x1fffffff) +#define ISA_DMA_THRESHOLD PHYS_ADDR_MASK /* These macros should be used after a pci_map_sg call has been done * to get bus addresses of each of the SG entries and their lengths. diff --git a/include/asm-sh/sdk7780.h b/include/asm-sh/sdk7780.h new file mode 100644 index 00000000000..697dc865f21 --- /dev/null +++ b/include/asm-sh/sdk7780.h @@ -0,0 +1,81 @@ +#ifndef __ASM_SH_RENESAS_SDK7780_H +#define __ASM_SH_RENESAS_SDK7780_H + +/* + * linux/include/asm-sh/sdk7780.h + * + * Renesas Solutions SH7780 SDK Support + * Copyright (C) 2008 Nicholas Beck <nbeck@mpc-data.co.uk> + * + * 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> + +/* Box specific addresses. */ +#define SE_AREA0_WIDTH 4 /* Area0: 32bit */ +#define PA_ROM 0xa0000000 /* EPROM */ +#define PA_ROM_SIZE 0x00400000 /* EPROM size 4M byte */ +#define PA_FROM 0xa0800000 /* Flash-ROM */ +#define PA_FROM_SIZE 0x00400000 /* Flash-ROM size 4M byte */ +#define PA_EXT1 0xa4000000 +#define PA_EXT1_SIZE 0x04000000 +#define PA_SDRAM 0xa8000000 /* DDR-SDRAM(Area2/3) 128MB */ +#define PA_SDRAM_SIZE 0x08000000 + +#define PA_EXT4 0xb0000000 +#define PA_EXT4_SIZE 0x04000000 +#define PA_EXT_USER PA_EXT4 /* User Expansion Space */ + +#define PA_PERIPHERAL PA_AREA5_IO + +/* SRAM/Reserved */ +#define PA_RESERVED (PA_PERIPHERAL + 0) +/* FPGA base address */ +#define PA_FPGA (PA_PERIPHERAL + 0x01000000) +/* SMC LAN91C111 */ +#define PA_LAN (PA_PERIPHERAL + 0x01800000) + + +#define FPGA_SRSTR (PA_FPGA + 0x000) /* System reset */ +#define FPGA_IRQ0SR (PA_FPGA + 0x010) /* IRQ0 status */ +#define FPGA_IRQ0MR (PA_FPGA + 0x020) /* IRQ0 mask */ +#define FPGA_BDMR (PA_FPGA + 0x030) /* Board operating mode */ +#define FPGA_INTT0PRTR (PA_FPGA + 0x040) /* Interrupt test mode0 port */ +#define FPGA_INTT0SELR (PA_FPGA + 0x050) /* Int. test mode0 select */ +#define FPGA_INTT1POLR (PA_FPGA + 0x060) /* Int. test mode0 polarity */ +#define FPGA_NMIR (PA_FPGA + 0x070) /* NMI source */ +#define FPGA_NMIMR (PA_FPGA + 0x080) /* NMI mask */ +#define FPGA_IRQR (PA_FPGA + 0x090) /* IRQX source */ +#define FPGA_IRQMR (PA_FPGA + 0x0A0) /* IRQX mask */ +#define FPGA_SLEDR (PA_FPGA + 0x0B0) /* LED control */ +#define PA_LED FPGA_SLEDR +#define FPGA_MAPSWR (PA_FPGA + 0x0C0) /* Map switch */ +#define FPGA_FPVERR (PA_FPGA + 0x0D0) /* FPGA version */ +#define FPGA_FPDATER (PA_FPGA + 0x0E0) /* FPGA date */ +#define FPGA_RSE (PA_FPGA + 0x100) /* Reset source */ +#define FPGA_EASR (PA_FPGA + 0x110) /* External area select */ +#define FPGA_SPER (PA_FPGA + 0x120) /* Serial port enable */ +#define FPGA_IMSR (PA_FPGA + 0x130) /* Interrupt mode select */ +#define FPGA_PCIMR (PA_FPGA + 0x140) /* PCI Mode */ +#define FPGA_DIPSWMR (PA_FPGA + 0x150) /* DIPSW monitor */ +#define FPGA_FPODR (PA_FPGA + 0x160) /* Output port data */ +#define FPGA_ATAESR (PA_FPGA + 0x170) /* ATA extended bus status */ +#define FPGA_IRQPOLR (PA_FPGA + 0x180) /* IRQx polarity */ + + +#define SDK7780_NR_IRL 15 +/* IDE/ATA interrupt */ +#define IRQ_CFCARD 14 +/* SMC interrupt */ +#define IRQ_ETHERNET 6 + + +/* arch/sh/boards/renesas/sdk7780/irq.c */ +void init_sdk7780_IRQ(void); + +#define __IO_PREFIX sdk7780 +#include <asm/io_generic.h> + +#endif /* __ASM_SH_RENESAS_SDK7780_H */ diff --git a/include/asm-sh/sections.h b/include/asm-sh/sections.h index bd9cbc967c2..8f8f4ad400d 100644 --- a/include/asm-sh/sections.h +++ b/include/asm-sh/sections.h @@ -4,6 +4,7 @@ #include <asm-generic/sections.h> extern long __machvec_start, __machvec_end; +extern char __uncached_start, __uncached_end; extern char _ebss[]; #endif /* __ASM_SH_SECTIONS_H */ diff --git a/include/asm-sh/sigcontext.h b/include/asm-sh/sigcontext.h index eb8effba2e8..8ce1435bc0b 100644 --- a/include/asm-sh/sigcontext.h +++ b/include/asm-sh/sigcontext.h @@ -4,6 +4,18 @@ struct sigcontext { unsigned long oldmask; +#if defined(__SH5__) || defined(CONFIG_CPU_SH5) + /* CPU registers */ + unsigned long long sc_regs[63]; + unsigned long long sc_tregs[8]; + unsigned long long sc_pc; + unsigned long long sc_sr; + + /* FPU registers */ + unsigned long long sc_fpregs[32]; + unsigned int sc_fpscr; + unsigned int sc_fpvalid; +#else /* CPU registers */ unsigned long sc_regs[16]; unsigned long sc_pc; @@ -13,7 +25,8 @@ struct sigcontext { unsigned long sc_mach; unsigned long sc_macl; -#if defined(__SH4__) || defined(CONFIG_CPU_SH4) +#if defined(__SH4__) || defined(CONFIG_CPU_SH4) || \ + defined(__SH2A__) || defined(CONFIG_CPU_SH2A) /* FPU registers */ unsigned long sc_fpregs[16]; unsigned long sc_xfpregs[16]; @@ -21,6 +34,7 @@ struct sigcontext { unsigned int sc_fpul; unsigned int sc_ownedfp; #endif +#endif }; #endif /* __ASM_SH_SIGCONTEXT_H */ diff --git a/include/asm-sh/socket.h b/include/asm-sh/socket.h index c48d6fc9da3..6d4bf651295 100644 --- a/include/asm-sh/socket.h +++ b/include/asm-sh/socket.h @@ -52,4 +52,6 @@ #define SO_TIMESTAMPNS 35 #define SCM_TIMESTAMPNS SO_TIMESTAMPNS +#define SO_MARK 36 + #endif /* __ASM_SH_SOCKET_H */ diff --git a/include/asm-sh/spi.h b/include/asm-sh/spi.h new file mode 100644 index 00000000000..e96f5b0953c --- /dev/null +++ b/include/asm-sh/spi.h @@ -0,0 +1,13 @@ +#ifndef __ASM_SPI_H__ +#define __ASM_SPI_H__ + +struct sh_spi_info; + +struct sh_spi_info { + int bus_num; + int num_chipselect; + + void (*chip_select)(struct sh_spi_info *spi, int cs, int state); +}; + +#endif /* __ASM_SPI_H__ */ diff --git a/include/asm-sh/stat.h b/include/asm-sh/stat.h index 6d6ad26e3a2..e1810cc6e3d 100644 --- a/include/asm-sh/stat.h +++ b/include/asm-sh/stat.h @@ -15,6 +15,66 @@ struct __old_kernel_stat { unsigned long st_ctime; }; +#if defined(__SH5__) || defined(CONFIG_CPU_SH5) +struct stat { + unsigned short st_dev; + unsigned short __pad1; + unsigned long st_ino; + unsigned short st_mode; + unsigned short st_nlink; + unsigned short st_uid; + unsigned short st_gid; + unsigned short st_rdev; + unsigned short __pad2; + unsigned long st_size; + unsigned long st_blksize; + unsigned long st_blocks; + unsigned long st_atime; + unsigned long st_atime_nsec; + unsigned long st_mtime; + unsigned long st_mtime_nsec; + unsigned long st_ctime; + unsigned long st_ctime_nsec; + unsigned long __unused4; + unsigned long __unused5; +}; + +/* This matches struct stat64 in glibc2.1, hence the absolutely + * insane amounts of padding around dev_t's. + */ +struct stat64 { + unsigned short st_dev; + unsigned char __pad0[10]; + + unsigned long st_ino; + unsigned int st_mode; + unsigned int st_nlink; + + unsigned long st_uid; + unsigned long st_gid; + + unsigned short st_rdev; + unsigned char __pad3[10]; + + long long st_size; + unsigned long st_blksize; + + unsigned long st_blocks; /* Number 512-byte blocks allocated. */ + unsigned long __pad4; /* future possible st_blocks high bits */ + + unsigned long st_atime; + unsigned long st_atime_nsec; + + unsigned long st_mtime; + unsigned long st_mtime_nsec; + + unsigned long st_ctime; + unsigned long st_ctime_nsec; /* will be high 32 bits of ctime someday */ + + unsigned long __unused1; + unsigned long __unused2; +}; +#else struct stat { unsigned long st_dev; unsigned long st_ino; @@ -67,11 +127,12 @@ struct stat64 { unsigned long st_mtime_nsec; unsigned long st_ctime; - unsigned long st_ctime_nsec; + unsigned long st_ctime_nsec; unsigned long long st_ino; }; #define STAT_HAVE_NSEC 1 +#endif #endif /* __ASM_SH_STAT_H */ diff --git a/include/asm-sh/string.h b/include/asm-sh/string.h index 55f8db6bc1d..8c1ea21dc0a 100644 --- a/include/asm-sh/string.h +++ b/include/asm-sh/string.h @@ -1,131 +1,5 @@ -#ifndef __ASM_SH_STRING_H -#define __ASM_SH_STRING_H - -#ifdef __KERNEL__ - -/* - * Copyright (C) 1999 Niibe Yutaka - * But consider these trivial functions to be public domain. - */ - -#define __HAVE_ARCH_STRCPY -static inline char *strcpy(char *__dest, const char *__src) -{ - register char *__xdest = __dest; - unsigned long __dummy; - - __asm__ __volatile__("1:\n\t" - "mov.b @%1+, %2\n\t" - "mov.b %2, @%0\n\t" - "cmp/eq #0, %2\n\t" - "bf/s 1b\n\t" - " add #1, %0\n\t" - : "=r" (__dest), "=r" (__src), "=&z" (__dummy) - : "0" (__dest), "1" (__src) - : "memory", "t"); - - return __xdest; -} - -#define __HAVE_ARCH_STRNCPY -static inline char *strncpy(char *__dest, const char *__src, size_t __n) -{ - register char *__xdest = __dest; - unsigned long __dummy; - - if (__n == 0) - return __xdest; - - __asm__ __volatile__( - "1:\n" - "mov.b @%1+, %2\n\t" - "mov.b %2, @%0\n\t" - "cmp/eq #0, %2\n\t" - "bt/s 2f\n\t" - " cmp/eq %5,%1\n\t" - "bf/s 1b\n\t" - " add #1, %0\n" - "2:" - : "=r" (__dest), "=r" (__src), "=&z" (__dummy) - : "0" (__dest), "1" (__src), "r" (__src+__n) - : "memory", "t"); - - return __xdest; -} - -#define __HAVE_ARCH_STRCMP -static inline int strcmp(const char *__cs, const char *__ct) -{ - register int __res; - unsigned long __dummy; - - __asm__ __volatile__( - "mov.b @%1+, %3\n" - "1:\n\t" - "mov.b @%0+, %2\n\t" - "cmp/eq #0, %3\n\t" - "bt 2f\n\t" - "cmp/eq %2, %3\n\t" - "bt/s 1b\n\t" - " mov.b @%1+, %3\n\t" - "add #-2, %1\n\t" - "mov.b @%1, %3\n\t" - "sub %3, %2\n" - "2:" - : "=r" (__cs), "=r" (__ct), "=&r" (__res), "=&z" (__dummy) - : "0" (__cs), "1" (__ct) - : "t"); - - return __res; -} - -#define __HAVE_ARCH_STRNCMP -static inline int strncmp(const char *__cs, const char *__ct, size_t __n) -{ - register int __res; - unsigned long __dummy; - - if (__n == 0) - return 0; - - __asm__ __volatile__( - "mov.b @%1+, %3\n" - "1:\n\t" - "mov.b @%0+, %2\n\t" - "cmp/eq %6, %0\n\t" - "bt/s 2f\n\t" - " cmp/eq #0, %3\n\t" - "bt/s 3f\n\t" - " cmp/eq %3, %2\n\t" - "bt/s 1b\n\t" - " mov.b @%1+, %3\n\t" - "add #-2, %1\n\t" - "mov.b @%1, %3\n" - "2:\n\t" - "sub %3, %2\n" - "3:" - :"=r" (__cs), "=r" (__ct), "=&r" (__res), "=&z" (__dummy) - : "0" (__cs), "1" (__ct), "r" (__cs+__n) - : "t"); - - return __res; -} - -#define __HAVE_ARCH_MEMSET -extern void *memset(void *__s, int __c, size_t __count); - -#define __HAVE_ARCH_MEMCPY -extern void *memcpy(void *__to, __const__ void *__from, size_t __n); - -#define __HAVE_ARCH_MEMMOVE -extern void *memmove(void *__dest, __const__ void *__src, size_t __n); - -#define __HAVE_ARCH_MEMCHR -extern void *memchr(const void *__s, int __c, size_t __n); - -#define __HAVE_ARCH_STRLEN -extern size_t strlen(const char *); - -#endif /* __KERNEL__ */ - -#endif /* __ASM_SH_STRING_H */ +#ifdef CONFIG_SUPERH32 +# include "string_32.h" +#else +# include "string_64.h" +#endif diff --git a/include/asm-sh/string_32.h b/include/asm-sh/string_32.h new file mode 100644 index 00000000000..55f8db6bc1d --- /dev/null +++ b/include/asm-sh/string_32.h @@ -0,0 +1,131 @@ +#ifndef __ASM_SH_STRING_H +#define __ASM_SH_STRING_H + +#ifdef __KERNEL__ + +/* + * Copyright (C) 1999 Niibe Yutaka + * But consider these trivial functions to be public domain. + */ + +#define __HAVE_ARCH_STRCPY +static inline char *strcpy(char *__dest, const char *__src) +{ + register char *__xdest = __dest; + unsigned long __dummy; + + __asm__ __volatile__("1:\n\t" + "mov.b @%1+, %2\n\t" + "mov.b %2, @%0\n\t" + "cmp/eq #0, %2\n\t" + "bf/s 1b\n\t" + " add #1, %0\n\t" + : "=r" (__dest), "=r" (__src), "=&z" (__dummy) + : "0" (__dest), "1" (__src) + : "memory", "t"); + + return __xdest; +} + +#define __HAVE_ARCH_STRNCPY +static inline char *strncpy(char *__dest, const char *__src, size_t __n) +{ + register char *__xdest = __dest; + unsigned long __dummy; + + if (__n == 0) + return __xdest; + + __asm__ __volatile__( + "1:\n" + "mov.b @%1+, %2\n\t" + "mov.b %2, @%0\n\t" + "cmp/eq #0, %2\n\t" + "bt/s 2f\n\t" + " cmp/eq %5,%1\n\t" + "bf/s 1b\n\t" + " add #1, %0\n" + "2:" + : "=r" (__dest), "=r" (__src), "=&z" (__dummy) + : "0" (__dest), "1" (__src), "r" (__src+__n) + : "memory", "t"); + + return __xdest; +} + +#define __HAVE_ARCH_STRCMP +static inline int strcmp(const char *__cs, const char *__ct) +{ + register int __res; + unsigned long __dummy; + + __asm__ __volatile__( + "mov.b @%1+, %3\n" + "1:\n\t" + "mov.b @%0+, %2\n\t" + "cmp/eq #0, %3\n\t" + "bt 2f\n\t" + "cmp/eq %2, %3\n\t" + "bt/s 1b\n\t" + " mov.b @%1+, %3\n\t" + "add #-2, %1\n\t" + "mov.b @%1, %3\n\t" + "sub %3, %2\n" + "2:" + : "=r" (__cs), "=r" (__ct), "=&r" (__res), "=&z" (__dummy) + : "0" (__cs), "1" (__ct) + : "t"); + + return __res; +} + +#define __HAVE_ARCH_STRNCMP +static inline int strncmp(const char *__cs, const char *__ct, size_t __n) +{ + register int __res; + unsigned long __dummy; + + if (__n == 0) + return 0; + + __asm__ __volatile__( + "mov.b @%1+, %3\n" + "1:\n\t" + "mov.b @%0+, %2\n\t" + "cmp/eq %6, %0\n\t" + "bt/s 2f\n\t" + " cmp/eq #0, %3\n\t" + "bt/s 3f\n\t" + " cmp/eq %3, %2\n\t" + "bt/s 1b\n\t" + " mov.b @%1+, %3\n\t" + "add #-2, %1\n\t" + "mov.b @%1, %3\n" + "2:\n\t" + "sub %3, %2\n" + "3:" + :"=r" (__cs), "=r" (__ct), "=&r" (__res), "=&z" (__dummy) + : "0" (__cs), "1" (__ct), "r" (__cs+__n) + : "t"); + + return __res; +} + +#define __HAVE_ARCH_MEMSET +extern void *memset(void *__s, int __c, size_t __count); + +#define __HAVE_ARCH_MEMCPY +extern void *memcpy(void *__to, __const__ void *__from, size_t __n); + +#define __HAVE_ARCH_MEMMOVE +extern void *memmove(void *__dest, __const__ void *__src, size_t __n); + +#define __HAVE_ARCH_MEMCHR +extern void *memchr(const void *__s, int __c, size_t __n); + +#define __HAVE_ARCH_STRLEN +extern size_t strlen(const char *); + +#endif /* __KERNEL__ */ + +#endif /* __ASM_SH_STRING_H */ diff --git a/include/asm-sh/string_64.h b/include/asm-sh/string_64.h new file mode 100644 index 00000000000..aa1fef229c7 --- /dev/null +++ b/include/asm-sh/string_64.h @@ -0,0 +1,17 @@ +#ifndef __ASM_SH_STRING_64_H +#define __ASM_SH_STRING_64_H + +/* + * include/asm-sh/string_64.h + * + * Copyright (C) 2000, 2001 Paolo Alberelli + * + * 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. + */ + +#define __HAVE_ARCH_MEMCPY +extern void *memcpy(void *dest, const void *src, size_t count); + +#endif /* __ASM_SH_STRING_64_H */ diff --git a/include/asm-sh/system.h b/include/asm-sh/system.h index 4faa2fb8861..772cd1a0a67 100644 --- a/include/asm-sh/system.h +++ b/include/asm-sh/system.h @@ -12,60 +12,9 @@ #include <asm/types.h> #include <asm/ptrace.h> -struct task_struct *__switch_to(struct task_struct *prev, - struct task_struct *next); +#define AT_VECTOR_SIZE_ARCH 5 /* entries in ARCH_DLINFO */ -#define AT_VECTOR_SIZE_ARCH 1 /* entries in ARCH_DLINFO */ -/* - * switch_to() should switch tasks to task nr n, first - */ - -#define switch_to(prev, next, last) do { \ - struct task_struct *__last; \ - register unsigned long *__ts1 __asm__ ("r1") = &prev->thread.sp; \ - register unsigned long *__ts2 __asm__ ("r2") = &prev->thread.pc; \ - register unsigned long *__ts4 __asm__ ("r4") = (unsigned long *)prev; \ - register unsigned long *__ts5 __asm__ ("r5") = (unsigned long *)next; \ - register unsigned long *__ts6 __asm__ ("r6") = &next->thread.sp; \ - register unsigned long __ts7 __asm__ ("r7") = next->thread.pc; \ - __asm__ __volatile__ (".balign 4\n\t" \ - "stc.l gbr, @-r15\n\t" \ - "sts.l pr, @-r15\n\t" \ - "mov.l r8, @-r15\n\t" \ - "mov.l r9, @-r15\n\t" \ - "mov.l r10, @-r15\n\t" \ - "mov.l r11, @-r15\n\t" \ - "mov.l r12, @-r15\n\t" \ - "mov.l r13, @-r15\n\t" \ - "mov.l r14, @-r15\n\t" \ - "mov.l r15, @r1 ! save SP\n\t" \ - "mov.l @r6, r15 ! change to new stack\n\t" \ - "mova 1f, %0\n\t" \ - "mov.l %0, @r2 ! save PC\n\t" \ - "mov.l 2f, %0\n\t" \ - "jmp @%0 ! call __switch_to\n\t" \ - " lds r7, pr ! with return to new PC\n\t" \ - ".balign 4\n" \ - "2:\n\t" \ - ".long __switch_to\n" \ - "1:\n\t" \ - "mov.l @r15+, r14\n\t" \ - "mov.l @r15+, r13\n\t" \ - "mov.l @r15+, r12\n\t" \ - "mov.l @r15+, r11\n\t" \ - "mov.l @r15+, r10\n\t" \ - "mov.l @r15+, r9\n\t" \ - "mov.l @r15+, r8\n\t" \ - "lds.l @r15+, pr\n\t" \ - "ldc.l @r15+, gbr\n\t" \ - : "=z" (__last) \ - : "r" (__ts1), "r" (__ts2), "r" (__ts4), \ - "r" (__ts5), "r" (__ts6), "r" (__ts7) \ - : "r3", "t"); \ - last = __last; \ -} while (0) - -#ifdef CONFIG_CPU_SH4A +#if defined(CONFIG_CPU_SH4A) || defined(CONFIG_CPU_SH5) #define __icbi() \ { \ unsigned long __addr; \ @@ -91,7 +40,7 @@ struct task_struct *__switch_to(struct task_struct *prev, * Historically we have only done this type of barrier for the MMUCR, but * it's also necessary for the CCR, so we make it generic here instead. */ -#ifdef CONFIG_CPU_SH4A +#if defined(CONFIG_CPU_SH4A) || defined(CONFIG_CPU_SH5) #define mb() __asm__ __volatile__ ("synco": : :"memory") #define rmb() mb() #define wmb() __asm__ __volatile__ ("synco": : :"memory") @@ -119,63 +68,11 @@ struct task_struct *__switch_to(struct task_struct *prev, #define set_mb(var, value) do { (void)xchg(&var, value); } while (0) -/* - * Jump to P2 area. - * When handling TLB or caches, we need to do it from P2 area. - */ -#define jump_to_P2() \ -do { \ - unsigned long __dummy; \ - __asm__ __volatile__( \ - "mov.l 1f, %0\n\t" \ - "or %1, %0\n\t" \ - "jmp @%0\n\t" \ - " nop\n\t" \ - ".balign 4\n" \ - "1: .long 2f\n" \ - "2:" \ - : "=&r" (__dummy) \ - : "r" (0x20000000)); \ -} while (0) - -/* - * Back to P1 area. - */ -#define back_to_P1() \ -do { \ - unsigned long __dummy; \ - ctrl_barrier(); \ - __asm__ __volatile__( \ - "mov.l 1f, %0\n\t" \ - "jmp @%0\n\t" \ - " nop\n\t" \ - ".balign 4\n" \ - "1: .long 2f\n" \ - "2:" \ - : "=&r" (__dummy)); \ -} while (0) - -static inline unsigned long xchg_u32(volatile u32 *m, unsigned long val) -{ - unsigned long flags, retval; - - local_irq_save(flags); - retval = *m; - *m = val; - local_irq_restore(flags); - return retval; -} - -static inline unsigned long xchg_u8(volatile u8 *m, unsigned long val) -{ - unsigned long flags, retval; - - local_irq_save(flags); - retval = *m; - *m = val & 0xff; - local_irq_restore(flags); - return retval; -} +#ifdef CONFIG_GUSA_RB +#include <asm/cmpxchg-grb.h> +#else +#include <asm/cmpxchg-irq.h> +#endif extern void __xchg_called_with_bad_pointer(void); @@ -202,20 +99,6 @@ extern void __xchg_called_with_bad_pointer(void); #define xchg(ptr,x) \ ((__typeof__(*(ptr)))__xchg((ptr),(unsigned long)(x), sizeof(*(ptr)))) -static inline unsigned long __cmpxchg_u32(volatile int * m, unsigned long old, - unsigned long new) -{ - __u32 retval; - unsigned long flags; - - local_irq_save(flags); - retval = *m; - if (retval == old) - *m = new; - local_irq_restore(flags); /* implies memory barrier */ - return retval; -} - /* This function doesn't exist, so you'll get a linker error * if something tries to do an invalid cmpxchg(). */ extern void __cmpxchg_called_with_bad_pointer(void); @@ -255,10 +138,14 @@ static inline void *set_exception_table_evt(unsigned int evt, void *handler) */ #ifdef CONFIG_CPU_SH2A extern unsigned int instruction_size(unsigned int insn); -#else +#elif defined(CONFIG_SUPERH32) #define instruction_size(insn) (2) +#else +#define instruction_size(insn) (4) #endif +extern unsigned long cached_to_uncached; + /* XXX * disable hlt during certain critical i/o operations */ @@ -270,13 +157,35 @@ void default_idle(void); void per_cpu_trap_init(void); asmlinkage void break_point_trap(void); -asmlinkage void debug_trap_handler(unsigned long r4, unsigned long r5, - unsigned long r6, unsigned long r7, - struct pt_regs __regs); -asmlinkage void bug_trap_handler(unsigned long r4, unsigned long r5, - unsigned long r6, unsigned long r7, - struct pt_regs __regs); + +#ifdef CONFIG_SUPERH32 +#define BUILD_TRAP_HANDLER(name) \ +asmlinkage void name##_trap_handler(unsigned long r4, unsigned long r5, \ + unsigned long r6, unsigned long r7, \ + struct pt_regs __regs) + +#define TRAP_HANDLER_DECL \ + struct pt_regs *regs = RELOC_HIDE(&__regs, 0); \ + unsigned int vec = regs->tra; \ + (void)vec; +#else +#define BUILD_TRAP_HANDLER(name) \ +asmlinkage void name##_trap_handler(unsigned int vec, struct pt_regs *regs) +#define TRAP_HANDLER_DECL +#endif + +BUILD_TRAP_HANDLER(address_error); +BUILD_TRAP_HANDLER(debug); +BUILD_TRAP_HANDLER(bug); +BUILD_TRAP_HANDLER(fpu_error); +BUILD_TRAP_HANDLER(fpu_state_restore); #define arch_align_stack(x) (x) +#ifdef CONFIG_SUPERH32 +# include "system_32.h" +#else +# include "system_64.h" +#endif + #endif diff --git a/include/asm-sh/system_32.h b/include/asm-sh/system_32.h new file mode 100644 index 00000000000..7ff08d956ba --- /dev/null +++ b/include/asm-sh/system_32.h @@ -0,0 +1,99 @@ +#ifndef __ASM_SH_SYSTEM_32_H +#define __ASM_SH_SYSTEM_32_H + +#include <linux/types.h> + +struct task_struct *__switch_to(struct task_struct *prev, + struct task_struct *next); + +/* + * switch_to() should switch tasks to task nr n, first + */ +#define switch_to(prev, next, last) \ +do { \ + register u32 *__ts1 __asm__ ("r1") = (u32 *)&prev->thread.sp; \ + register u32 *__ts2 __asm__ ("r2") = (u32 *)&prev->thread.pc; \ + register u32 *__ts4 __asm__ ("r4") = (u32 *)prev; \ + register u32 *__ts5 __asm__ ("r5") = (u32 *)next; \ + register u32 *__ts6 __asm__ ("r6") = (u32 *)&next->thread.sp; \ + register u32 __ts7 __asm__ ("r7") = next->thread.pc; \ + struct task_struct *__last; \ + \ + __asm__ __volatile__ ( \ + ".balign 4\n\t" \ + "stc.l gbr, @-r15\n\t" \ + "sts.l pr, @-r15\n\t" \ + "mov.l r8, @-r15\n\t" \ + "mov.l r9, @-r15\n\t" \ + "mov.l r10, @-r15\n\t" \ + "mov.l r11, @-r15\n\t" \ + "mov.l r12, @-r15\n\t" \ + "mov.l r13, @-r15\n\t" \ + "mov.l r14, @-r15\n\t" \ + "mov.l r15, @r1\t! save SP\n\t" \ + "mov.l @r6, r15\t! change to new stack\n\t" \ + "mova 1f, %0\n\t" \ + "mov.l %0, @r2\t! save PC\n\t" \ + "mov.l 2f, %0\n\t" \ + "jmp @%0\t! call __switch_to\n\t" \ + " lds r7, pr\t! with return to new PC\n\t" \ + ".balign 4\n" \ + "2:\n\t" \ + ".long __switch_to\n" \ + "1:\n\t" \ + "mov.l @r15+, r14\n\t" \ + "mov.l @r15+, r13\n\t" \ + "mov.l @r15+, r12\n\t" \ + "mov.l @r15+, r11\n\t" \ + "mov.l @r15+, r10\n\t" \ + "mov.l @r15+, r9\n\t" \ + "mov.l @r15+, r8\n\t" \ + "lds.l @r15+, pr\n\t" \ + "ldc.l @r15+, gbr\n\t" \ + : "=z" (__last) \ + : "r" (__ts1), "r" (__ts2), "r" (__ts4), \ + "r" (__ts5), "r" (__ts6), "r" (__ts7) \ + : "r3", "t"); \ + \ + last = __last; \ +} while (0) + +#define __uses_jump_to_uncached __attribute__ ((__section__ (".uncached.text"))) + +/* + * Jump to uncached area. + * When handling TLB or caches, we need to do it from an uncached area. + */ +#define jump_to_uncached() \ +do { \ + unsigned long __dummy; \ + \ + __asm__ __volatile__( \ + "mova 1f, %0\n\t" \ + "add %1, %0\n\t" \ + "jmp @%0\n\t" \ + " nop\n\t" \ + ".balign 4\n" \ + "1:" \ + : "=&z" (__dummy) \ + : "r" (cached_to_uncached)); \ +} while (0) + +/* + * Back to cached area. + */ +#define back_to_cached() \ +do { \ + unsigned long __dummy; \ + ctrl_barrier(); \ + __asm__ __volatile__( \ + "mov.l 1f, %0\n\t" \ + "jmp @%0\n\t" \ + " nop\n\t" \ + ".balign 4\n" \ + "1: .long 2f\n" \ + "2:" \ + : "=&r" (__dummy)); \ +} while (0) + +#endif /* __ASM_SH_SYSTEM_32_H */ diff --git a/include/asm-sh/system_64.h b/include/asm-sh/system_64.h new file mode 100644 index 00000000000..943acf5ea07 --- /dev/null +++ b/include/asm-sh/system_64.h @@ -0,0 +1,40 @@ +#ifndef __ASM_SH_SYSTEM_64_H +#define __ASM_SH_SYSTEM_64_H + +/* + * include/asm-sh/system_64.h + * + * Copyright (C) 2000, 2001 Paolo Alberelli + * Copyright (C) 2003 Paul Mundt + * Copyright (C) 2004 Richard Curnow + * + * 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/processor.h> + +/* + * switch_to() should switch tasks to task nr n, first + */ +struct task_struct *sh64_switch_to(struct task_struct *prev, + struct thread_struct *prev_thread, + struct task_struct *next, + struct thread_struct *next_thread); + +#define switch_to(prev,next,last) \ +do { \ + if (last_task_used_math != next) { \ + struct pt_regs *regs = next->thread.uregs; \ + if (regs) regs->sr |= SR_FD; \ + } \ + last = sh64_switch_to(prev, &prev->thread, next, \ + &next->thread); \ +} while (0) + +#define __uses_jump_to_uncached + +#define jump_to_uncached() do { } while (0) +#define back_to_cached() do { } while (0) + +#endif /* __ASM_SH_SYSTEM_64_H */ diff --git a/include/asm-sh/thread_info.h b/include/asm-sh/thread_info.h index 1f7e1deb8d9..c50e5d35fe8 100644 --- a/include/asm-sh/thread_info.h +++ b/include/asm-sh/thread_info.h @@ -68,14 +68,16 @@ struct thread_info { #define init_stack (init_thread_union.stack) /* how to get the current stack pointer from C */ -register unsigned long current_stack_pointer asm("r15") __attribute_used__; +register unsigned long current_stack_pointer asm("r15") __used; /* how to get the thread information struct from C */ static inline struct thread_info *current_thread_info(void) { struct thread_info *ti; -#ifdef CONFIG_CPU_HAS_SR_RB - __asm__("stc r7_bank, %0" : "=r" (ti)); +#if defined(CONFIG_SUPERH64) + __asm__ __volatile__ ("getcon cr17, %0" : "=r" (ti)); +#elif defined(CONFIG_CPU_HAS_SR_RB) + __asm__ __volatile__ ("stc r7_bank, %0" : "=r" (ti)); #else unsigned long __dummy; @@ -111,6 +113,7 @@ static inline struct thread_info *current_thread_info(void) #define TIF_NEED_RESCHED 2 /* rescheduling necessary */ #define TIF_RESTORE_SIGMASK 3 /* restore signal mask in do_signal() */ #define TIF_SINGLESTEP 4 /* singlestepping active */ +#define TIF_SYSCALL_AUDIT 5 #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 @@ -121,6 +124,7 @@ static inline struct thread_info *current_thread_info(void) #define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED) #define _TIF_RESTORE_SIGMASK (1<<TIF_RESTORE_SIGMASK) #define _TIF_SINGLESTEP (1<<TIF_SINGLESTEP) +#define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT) #define _TIF_USEDFPU (1<<TIF_USEDFPU) #define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG) #define _TIF_FREEZE (1<<TIF_FREEZE) diff --git a/include/asm-sh/tlb.h b/include/asm-sh/tlb.h index 53d185bcf87..56ad1fb888a 100644 --- a/include/asm-sh/tlb.h +++ b/include/asm-sh/tlb.h @@ -1,6 +1,12 @@ #ifndef __ASM_SH_TLB_H #define __ASM_SH_TLB_H +#ifdef CONFIG_SUPERH64 +# include "tlb_64.h" +#endif + +#ifndef __ASSEMBLY__ + #define tlb_start_vma(tlb, vma) \ flush_cache_range(vma, vma->vm_start, vma->vm_end) @@ -15,4 +21,6 @@ #define tlb_flush(tlb) flush_tlb_mm((tlb)->mm) #include <asm-generic/tlb.h> -#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ASM_SH_TLB_H */ diff --git a/include/asm-sh/tlb_64.h b/include/asm-sh/tlb_64.h new file mode 100644 index 00000000000..0308e05fc57 --- /dev/null +++ b/include/asm-sh/tlb_64.h @@ -0,0 +1,69 @@ +/* + * include/asm-sh/tlb_64.h + * + * Copyright (C) 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_TLB_64_H +#define __ASM_SH_TLB_64_H + +/* ITLB defines */ +#define ITLB_FIXED 0x00000000 /* First fixed ITLB, see head.S */ +#define ITLB_LAST_VAR_UNRESTRICTED 0x000003F0 /* Last ITLB */ + +/* DTLB defines */ +#define DTLB_FIXED 0x00800000 /* First fixed DTLB, see head.S */ +#define DTLB_LAST_VAR_UNRESTRICTED 0x008003F0 /* Last DTLB */ + +#ifndef __ASSEMBLY__ + +/** + * for_each_dtlb_entry + * + * @tlb: TLB entry + * + * Iterate over free (non-wired) DTLB entries + */ +#define for_each_dtlb_entry(tlb) \ + for (tlb = cpu_data->dtlb.first; \ + tlb <= cpu_data->dtlb.last; \ + tlb += cpu_data->dtlb.step) + +/** + * for_each_itlb_entry + * + * @tlb: TLB entry + * + * Iterate over free (non-wired) ITLB entries + */ +#define for_each_itlb_entry(tlb) \ + for (tlb = cpu_data->itlb.first; \ + tlb <= cpu_data->itlb.last; \ + tlb += cpu_data->itlb.step) + +/** + * __flush_tlb_slot + * + * @slot: Address of TLB slot. + * + * Flushes TLB slot @slot. + */ +static inline void __flush_tlb_slot(unsigned long long slot) +{ + __asm__ __volatile__ ("putcfg %0, 0, r63\n" : : "r" (slot)); +} + +/* arch/sh64/mm/tlb.c */ +int sh64_tlb_init(void); +unsigned long long sh64_next_free_dtlb_entry(void); +unsigned long long sh64_get_wired_dtlb_entry(void); +int sh64_put_wired_dtlb_entry(unsigned long long entry); +void sh64_setup_tlb_slot(unsigned long long config_addr, unsigned long eaddr, + unsigned long asid, unsigned long paddr); +void sh64_teardown_tlb_slot(unsigned long long config_addr); + +#endif /* __ASSEMBLY__ */ +#endif /* __ASM_SH_TLB_64_H */ diff --git a/include/asm-sh/types.h b/include/asm-sh/types.h index 7ba69d9707e..a6e1d4126e6 100644 --- a/include/asm-sh/types.h +++ b/include/asm-sh/types.h @@ -52,6 +52,12 @@ typedef unsigned long long u64; typedef u32 dma_addr_t; +#ifdef CONFIG_SUPERH32 +typedef u16 opcode_t; +#else +typedef u32 opcode_t; +#endif + #endif /* __ASSEMBLY__ */ #endif /* __KERNEL__ */ diff --git a/include/asm-sh/uaccess.h b/include/asm-sh/uaccess.h index f18a1a5c95c..ff24ce95b23 100644 --- a/include/asm-sh/uaccess.h +++ b/include/asm-sh/uaccess.h @@ -1,575 +1,5 @@ -/* $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 - * - * Based on: - * MIPS implementation version 1.15 by - * Copyright (C) 1996, 1997, 1998 by Ralf Baechle - * and i386 version. - */ -#ifndef __ASM_SH_UACCESS_H -#define __ASM_SH_UACCESS_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. - * - * TODO: This check could probably also stand to be restricted somewhat more.. - * though it still does the Right Thing(tm) for the time being. - */ -static inline int __access_ok(unsigned long addr, unsigned long size) -{ - return ((addr >= memory_start) && ((addr + size) < memory_end)); -} -#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. - * - * We do three checks: - * (1) is it user space? - * (2) addr + size --> carry? - * (3) addr + size >= 0x80000000 (PAGE_OFFSET) - * - * (1) (2) (3) | RESULT - * 0 0 0 | ok - * 0 0 1 | ok - * 0 1 0 | bad - * 0 1 1 | bad - * 1 0 0 | ok - * 1 0 1 | bad - * 1 1 0 | bad - * 1 1 1 | bad - */ -static inline int __access_ok(unsigned long addr, unsigned long size) -{ - unsigned long flag, tmp; - - __asm__("stc r7_bank, %0\n\t" - "mov.l @(8,%0), %0\n\t" - "clrt\n\t" - "addc %2, %1\n\t" - "and %1, %0\n\t" - "rotcl %0\n\t" - "rotcl %0\n\t" - "and #3, %0" - : "=&z" (flag), "=r" (tmp) - : "r" (addr), "1" (size) - : "t"); - - return flag == 0; -} -#endif /* CONFIG_MMU */ - -static inline int access_ok(int type, const void __user *p, unsigned long size) -{ - unsigned long addr = (unsigned long)p; - return __access_ok(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((__typeof__(*(ptr)))(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; \ - __chk_user_ptr(ptr); \ - switch (size) { \ - case 1: \ - __get_user_asm(x, ptr, retval, "b"); \ - break; \ - case 2: \ - __get_user_asm(x, ptr, retval, "w"); \ - break; \ - case 4: \ - __get_user_asm(x, ptr, retval, "l"); \ - break; \ - default: \ - __get_user_unknown(); \ - break; \ - } \ -} while (0) - -#define __get_user_nocheck(x,ptr,size) \ -({ \ - long __gu_err, __gu_val; \ - __get_user_size(__gu_val, (ptr), (size), __gu_err); \ - (x) = (__typeof__(*(ptr)))__gu_val; \ - __gu_err; \ -}) - -#ifdef CONFIG_MMU -#define __get_user_check(x,ptr,size) \ -({ \ - long __gu_err, __gu_val; \ - __chk_user_ptr(ptr); \ - switch (size) { \ - case 1: \ - __get_user_1(__gu_val, (ptr), __gu_err); \ - break; \ - case 2: \ - __get_user_2(__gu_val, (ptr), __gu_err); \ - break; \ - case 4: \ - __get_user_4(__gu_val, (ptr), __gu_err); \ - break; \ - default: \ - __get_user_unknown(); \ - break; \ - } \ - \ - (x) = (__typeof__(*(ptr)))__gu_val; \ - __gu_err; \ -}) - -#define __get_user_1(x,addr,err) ({ \ -__asm__("stc r7_bank, %1\n\t" \ - "mov.l @(8,%1), %1\n\t" \ - "and %2, %1\n\t" \ - "cmp/pz %1\n\t" \ - "bt/s 1f\n\t" \ - " mov #0, %0\n\t" \ - "0:\n" \ - "mov #-14, %0\n\t" \ - "bra 2f\n\t" \ - " mov #0, %1\n" \ - "1:\n\t" \ - "mov.b @%2, %1\n\t" \ - "extu.b %1, %1\n" \ - "2:\n" \ - ".section __ex_table,\"a\"\n\t" \ - ".long 1b, 0b\n\t" \ - ".previous" \ - : "=&r" (err), "=&r" (x) \ - : "r" (addr) \ - : "t"); \ -}) - -#define __get_user_2(x,addr,err) ({ \ -__asm__("stc r7_bank, %1\n\t" \ - "mov.l @(8,%1), %1\n\t" \ - "and %2, %1\n\t" \ - "cmp/pz %1\n\t" \ - "bt/s 1f\n\t" \ - " mov #0, %0\n\t" \ - "0:\n" \ - "mov #-14, %0\n\t" \ - "bra 2f\n\t" \ - " mov #0, %1\n" \ - "1:\n\t" \ - "mov.w @%2, %1\n\t" \ - "extu.w %1, %1\n" \ - "2:\n" \ - ".section __ex_table,\"a\"\n\t" \ - ".long 1b, 0b\n\t" \ - ".previous" \ - : "=&r" (err), "=&r" (x) \ - : "r" (addr) \ - : "t"); \ -}) - -#define __get_user_4(x,addr,err) ({ \ -__asm__("stc r7_bank, %1\n\t" \ - "mov.l @(8,%1), %1\n\t" \ - "and %2, %1\n\t" \ - "cmp/pz %1\n\t" \ - "bt/s 1f\n\t" \ - " mov #0, %0\n\t" \ - "0:\n" \ - "mov #-14, %0\n\t" \ - "bra 2f\n\t" \ - " mov #0, %1\n" \ - "1:\n\t" \ - "mov.l @%2, %1\n\t" \ - "2:\n" \ - ".section __ex_table,\"a\"\n\t" \ - ".long 1b, 0b\n\t" \ - ".previous" \ - : "=&r" (err), "=&r" (x) \ - : "r" (addr) \ - : "t"); \ -}) -#else /* CONFIG_MMU */ -#define __get_user_check(x,ptr,size) \ -({ \ - long __gu_err, __gu_val; \ - if (__access_ok((unsigned long)(ptr), (size))) { \ - __get_user_size(__gu_val, (ptr), (size), __gu_err); \ - (x) = (__typeof__(*(ptr)))__gu_val; \ - } else \ - __gu_err = -EFAULT; \ - __gu_err; \ -}) -#endif - -#define __get_user_asm(x, addr, err, insn) \ -({ \ -__asm__ __volatile__( \ - "1:\n\t" \ - "mov." insn " %2, %1\n\t" \ - "mov #0, %0\n" \ - "2:\n" \ - ".section .fixup,\"ax\"\n" \ - "3:\n\t" \ - "mov #0, %1\n\t" \ - "mov.l 4f, %0\n\t" \ - "jmp @%0\n\t" \ - " mov %3, %0\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)); }) - -extern void __get_user_unknown(void); - -#define __put_user_size(x,ptr,size,retval) \ -do { \ - retval = 0; \ - __chk_user_ptr(ptr); \ - switch (size) { \ - case 1: \ - __put_user_asm(x, ptr, retval, "b"); \ - break; \ - case 2: \ - __put_user_asm(x, ptr, retval, "w"); \ - break; \ - case 4: \ - __put_user_asm(x, ptr, retval, "l"); \ - break; \ - case 8: \ - __put_user_u64(x, ptr, retval); \ - break; \ - default: \ - __put_user_unknown(); \ - } \ -} while (0) - -#define __put_user_nocheck(x,ptr,size) \ -({ \ - long __pu_err; \ - __put_user_size((x),(ptr),(size),__pu_err); \ - __pu_err; \ -}) - -#define __put_user_check(x,ptr,size) \ -({ \ - long __pu_err = -EFAULT; \ - __typeof__(*(ptr)) __user *__pu_addr = (ptr); \ - \ - if (__access_ok((unsigned long)__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" \ - "mov #0, %0\n" \ - "2:\n" \ - ".section .fixup,\"ax\"\n" \ - "3:\n\t" \ - "nop\n\t" \ - "mov.l 4f, %0\n\t" \ - "jmp @%0\n\t" \ - "mov %3, %0\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) \ - :"memory"); }) - -#if defined(__LITTLE_ENDIAN__) -#define __put_user_u64(val,addr,retval) \ -({ \ -__asm__ __volatile__( \ - "1:\n\t" \ - "mov.l %R1,%2\n\t" \ - "mov.l %S1,%T2\n\t" \ - "mov #0,%0\n" \ - "2:\n" \ - ".section .fixup,\"ax\"\n" \ - "3:\n\t" \ - "nop\n\t" \ - "mov.l 4f,%0\n\t" \ - "jmp @%0\n\t" \ - " mov %3,%0\n" \ - "4: .long 2b\n\t" \ - ".previous\n" \ - ".section __ex_table,\"a\"\n\t" \ - ".long 1b, 3b\n\t" \ - ".previous" \ - : "=r" (retval) \ - : "r" (val), "m" (__m(addr)), "i" (-EFAULT) \ - : "memory"); }) +#ifdef CONFIG_SUPERH32 +# include "uaccess_32.h" #else -#define __put_user_u64(val,addr,retval) \ -({ \ -__asm__ __volatile__( \ - "1:\n\t" \ - "mov.l %S1,%2\n\t" \ - "mov.l %R1,%T2\n\t" \ - "mov #0,%0\n" \ - "2:\n" \ - ".section .fixup,\"ax\"\n" \ - "3:\n\t" \ - "nop\n\t" \ - "mov.l 4f,%0\n\t" \ - "jmp @%0\n\t" \ - " mov %3,%0\n" \ - "4: .long 2b\n\t" \ - ".previous\n" \ - ".section __ex_table,\"a\"\n\t" \ - ".long 1b, 3b\n\t" \ - ".previous" \ - : "=r" (retval) \ - : "r" (val), "m" (__m(addr)), "i" (-EFAULT) \ - : "memory"); }) +# include "uaccess_64.h" #endif - -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); - -#define copy_to_user(to,from,n) ({ \ -void *__copy_to = (void *) (to); \ -__kernel_size_t __copy_size = (__kernel_size_t) (n); \ -__kernel_size_t __copy_res; \ -if(__copy_size && __access_ok((unsigned long)__copy_to, __copy_size)) { \ -__copy_res = __copy_user(__copy_to, (void *) (from), __copy_size); \ -} else __copy_res = __copy_size; \ -__copy_res; }) - -#define copy_from_user(to,from,n) ({ \ -void *__copy_to = (void *) (to); \ -void *__copy_from = (void *) (from); \ -__kernel_size_t __copy_size = (__kernel_size_t) (n); \ -__kernel_size_t __copy_res; \ -if(__copy_size && __access_ok((unsigned long)__copy_from, __copy_size)) { \ -__copy_res = __copy_user(__copy_to, __copy_from, __copy_size); \ -} else __copy_res = __copy_size; \ -__copy_res; }) - -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 -__strncpy_from_user(unsigned long __dest, unsigned long __user __src, int __count) -{ - __kernel_size_t res; - unsigned long __dummy, _d, _s; - - __asm__ __volatile__( - "9:\n" - "mov.b @%2+, %1\n\t" - "cmp/eq #0, %1\n\t" - "bt/s 2f\n" - "1:\n" - "mov.b %1, @%3\n\t" - "dt %7\n\t" - "bf/s 9b\n\t" - " add #1, %3\n\t" - "2:\n\t" - "sub %7, %0\n" - "3:\n" - ".section .fixup,\"ax\"\n" - "4:\n\t" - "mov.l 5f, %1\n\t" - "jmp @%1\n\t" - " mov %8, %0\n\t" - ".balign 4\n" - "5: .long 3b\n" - ".previous\n" - ".section __ex_table,\"a\"\n" - " .balign 4\n" - " .long 9b,4b\n" - ".previous" - : "=r" (res), "=&z" (__dummy), "=r" (_s), "=r" (_d) - : "0" (__count), "2" (__src), "3" (__dest), "r" (__count), - "i" (-EFAULT) - : "memory", "t"); - - return res; -} - -#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!) - */ -static __inline__ long __strnlen_user(const char __user *__s, long __n) -{ - unsigned long res; - unsigned long __dummy; - - __asm__ __volatile__( - "9:\n" - "cmp/eq %4, %0\n\t" - "bt 2f\n" - "1:\t" - "mov.b @(%0,%3), %1\n\t" - "tst %1, %1\n\t" - "bf/s 9b\n\t" - " add #1, %0\n" - "2:\n" - ".section .fixup,\"ax\"\n" - "3:\n\t" - "mov.l 4f, %1\n\t" - "jmp @%1\n\t" - " mov #0, %0\n" - ".balign 4\n" - "4: .long 2b\n" - ".previous\n" - ".section __ex_table,\"a\"\n" - " .balign 4\n" - " .long 1b,3b\n" - ".previous" - : "=z" (res), "=&r" (__dummy) - : "0" (0), "r" (__s), "r" (__n) - : "t"); - return res; -} - -static __inline__ long strnlen_user(const char __user *s, long n) -{ - if (!__addr_ok(s)) - return 0; - else - return __strnlen_user(s, n); -} - -#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_H */ diff --git a/include/asm-sh/uaccess_32.h b/include/asm-sh/uaccess_32.h new file mode 100644 index 00000000000..b6082f3c1dc --- /dev/null +++ b/include/asm-sh/uaccess_32.h @@ -0,0 +1,510 @@ +/* $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 + * + * Based on: + * MIPS implementation version 1.15 by + * Copyright (C) 1996, 1997, 1998 by Ralf Baechle + * and i386 version. + */ +#ifndef __ASM_SH_UACCESS_H +#define __ASM_SH_UACCESS_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. + * + * TODO: This check could probably also stand to be restricted somewhat more.. + * though it still does the Right Thing(tm) for the time being. + */ +static inline int __access_ok(unsigned long addr, unsigned long size) +{ + return ((addr >= memory_start) && ((addr + size) < memory_end)); +} +#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; \ + switch (size) { \ + case 1: \ + __get_user_asm(x, ptr, retval, "b"); \ + break; \ + case 2: \ + __get_user_asm(x, ptr, retval, "w"); \ + break; \ + case 4: \ + __get_user_asm(x, ptr, retval, "l"); \ + break; \ + default: \ + __get_user_unknown(); \ + break; \ + } \ +} 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; \ +}) + +#define __get_user_asm(x, addr, err, insn) \ +({ \ +__asm__ __volatile__( \ + "1:\n\t" \ + "mov." insn " %2, %1\n\t" \ + "2:\n" \ + ".section .fixup,\"ax\"\n" \ + "3:\n\t" \ + "mov #0, %1\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)); }) + +extern void __get_user_unknown(void); + +#define __put_user_size(x,ptr,size,retval) \ +do { \ + retval = 0; \ + switch (size) { \ + case 1: \ + __put_user_asm(x, ptr, retval, "b"); \ + break; \ + case 2: \ + __put_user_asm(x, ptr, retval, "w"); \ + break; \ + case 4: \ + __put_user_asm(x, ptr, retval, "l"); \ + break; \ + case 8: \ + __put_user_u64(x, ptr, retval); \ + break; \ + default: \ + __put_user_unknown(); \ + } \ +} 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"); }) + +#if defined(CONFIG_CPU_LITTLE_ENDIAN) +#define __put_user_u64(val,addr,retval) \ +({ \ +__asm__ __volatile__( \ + "1:\n\t" \ + "mov.l %R1,%2\n\t" \ + "mov.l %S1,%T2\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" (retval) \ + : "r" (val), "m" (__m(addr)), "i" (-EFAULT), "0" (retval) \ + : "memory"); }) +#else +#define __put_user_u64(val,addr,retval) \ +({ \ +__asm__ __volatile__( \ + "1:\n\t" \ + "mov.l %S1,%2\n\t" \ + "mov.l %R1,%T2\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" (retval) \ + : "r" (val), "m" (__m(addr)), "i" (-EFAULT), "0" (retval) \ + : "memory"); }) +#endif + +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); + +#define copy_to_user(to,from,n) ({ \ +void *__copy_to = (void *) (to); \ +__kernel_size_t __copy_size = (__kernel_size_t) (n); \ +__kernel_size_t __copy_res; \ +if(__copy_size && __access_ok((unsigned long)__copy_to, __copy_size)) { \ +__copy_res = __copy_user(__copy_to, (void *) (from), __copy_size); \ +} else __copy_res = __copy_size; \ +__copy_res; }) + +#define copy_from_user(to,from,n) ({ \ +void *__copy_to = (void *) (to); \ +void *__copy_from = (void *) (from); \ +__kernel_size_t __copy_size = (__kernel_size_t) (n); \ +__kernel_size_t __copy_res; \ +if(__copy_size && __access_ok((unsigned long)__copy_from, __copy_size)) { \ +__copy_res = __copy_user(__copy_to, __copy_from, __copy_size); \ +} else __copy_res = __copy_size; \ +__copy_res; }) + +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 +__strncpy_from_user(unsigned long __dest, unsigned long __user __src, int __count) +{ + __kernel_size_t res; + unsigned long __dummy, _d, _s, _c; + + __asm__ __volatile__( + "9:\n" + "mov.b @%2+, %1\n\t" + "cmp/eq #0, %1\n\t" + "bt/s 2f\n" + "1:\n" + "mov.b %1, @%3\n\t" + "dt %4\n\t" + "bf/s 9b\n\t" + " add #1, %3\n\t" + "2:\n\t" + "sub %4, %0\n" + "3:\n" + ".section .fixup,\"ax\"\n" + "4:\n\t" + "mov.l 5f, %1\n\t" + "jmp @%1\n\t" + " mov %9, %0\n\t" + ".balign 4\n" + "5: .long 3b\n" + ".previous\n" + ".section __ex_table,\"a\"\n" + " .balign 4\n" + " .long 9b,4b\n" + ".previous" + : "=r" (res), "=&z" (__dummy), "=r" (_s), "=r" (_d), "=r"(_c) + : "0" (__count), "2" (__src), "3" (__dest), "4" (__count), + "i" (-EFAULT) + : "memory", "t"); + + 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) +{ + unsigned long res; + unsigned long __dummy; + + __asm__ __volatile__( + "1:\t" + "mov.b @(%0,%3), %1\n\t" + "cmp/eq %4, %0\n\t" + "bt/s 2f\n\t" + " add #1, %0\n\t" + "tst %1, %1\n\t" + "bf 1b\n\t" + "2:\n" + ".section .fixup,\"ax\"\n" + "3:\n\t" + "mov.l 4f, %1\n\t" + "jmp @%1\n\t" + " mov #0, %0\n" + ".balign 4\n" + "4: .long 2b\n" + ".previous\n" + ".section __ex_table,\"a\"\n" + " .balign 4\n" + " .long 1b,3b\n" + ".previous" + : "=z" (res), "=&r" (__dummy) + : "0" (0), "r" (__s), "r" (__n) + : "t"); + 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_H */ diff --git a/include/asm-sh/uaccess_64.h b/include/asm-sh/uaccess_64.h new file mode 100644 index 00000000000..d54ec082d25 --- /dev/null +++ b/include/asm-sh/uaccess_64.h @@ -0,0 +1,302 @@ +#ifndef __ASM_SH_UACCESS_64_H +#define __ASM_SH_UACCESS_64_H + +/* + * include/asm-sh/uaccess_64.h + * + * Copyright (C) 2000, 2001 Paolo Alberelli + * Copyright (C) 2003, 2004 Paul Mundt + * + * User space memory access functions + * + * Copyright (C) 1999 Niibe Yutaka + * + * Based on: + * MIPS implementation version 1.15 by + * Copyright (C) 1996, 1997, 1998 by Ralf Baechle + * and i386 version. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#include <linux/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 { \ + retval = 0; \ + switch (size) { \ + case 1: \ + retval = __get_user_asm_b(x, ptr); \ + break; \ + case 2: \ + retval = __get_user_asm_w(x, ptr); \ + break; \ + case 4: \ + retval = __get_user_asm_l(x, ptr); \ + break; \ + case 8: \ + retval = __get_user_asm_q(x, ptr); \ + break; \ + default: \ + __get_user_unknown(); \ + break; \ + } \ +} 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); +extern long __get_user_asm_q(void *, long); +extern void __get_user_unknown(void); + +#define __put_user_size(x,ptr,size,retval) \ +do { \ + retval = 0; \ + switch (size) { \ + case 1: \ + retval = __put_user_asm_b(x, ptr); \ + break; \ + case 2: \ + retval = __put_user_asm_w(x, ptr); \ + break; \ + case 4: \ + retval = __put_user_asm_l(x, ptr); \ + break; \ + case 8: \ + retval = __put_user_asm_q(x, ptr); \ + break; \ + default: \ + __put_user_unknown(); \ + } \ +} 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(to,from,n) ({ \ +void *__copy_to = (void *) (to); \ +__kernel_size_t __copy_size = (__kernel_size_t) (n); \ +__kernel_size_t __copy_res; \ +if(__copy_size && __access_ok((unsigned long)__copy_to, __copy_size)) { \ +__copy_res = __copy_user(__copy_to, (void *) (from), __copy_size); \ +} else __copy_res = __copy_size; \ +__copy_res; }) + +#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(to,from,n) ({ \ +void *__copy_to = (void *) (to); \ +void *__copy_from = (void *) (from); \ +__kernel_size_t __copy_size = (__kernel_size_t) (n); \ +__kernel_size_t __copy_res; \ +if(__copy_size && __access_ok((unsigned long)__copy_from, __copy_size)) { \ +__copy_res = __copy_user(__copy_to, __copy_from, __copy_size); \ +} else __copy_res = __copy_size; \ +__copy_res; }) + +#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; +}; + +#define ARCH_HAS_SEARCH_EXTABLE + +/* 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/asm-sh/unistd.h b/include/asm-sh/unistd.h index b182b1cb05f..4b21f369c28 100644 --- a/include/asm-sh/unistd.h +++ b/include/asm-sh/unistd.h @@ -1,376 +1,5 @@ -#ifndef __ASM_SH_UNISTD_H -#define __ASM_SH_UNISTD_H - -/* - * Copyright (C) 1999 Niibe Yutaka - */ - -/* - * This file contains the system call numbers. - */ - -#define __NR_restart_syscall 0 -#define __NR_exit 1 -#define __NR_fork 2 -#define __NR_read 3 -#define __NR_write 4 -#define __NR_open 5 -#define __NR_close 6 -#define __NR_waitpid 7 -#define __NR_creat 8 -#define __NR_link 9 -#define __NR_unlink 10 -#define __NR_execve 11 -#define __NR_chdir 12 -#define __NR_time 13 -#define __NR_mknod 14 -#define __NR_chmod 15 -#define __NR_lchown 16 -#define __NR_break 17 -#define __NR_oldstat 18 -#define __NR_lseek 19 -#define __NR_getpid 20 -#define __NR_mount 21 -#define __NR_umount 22 -#define __NR_setuid 23 -#define __NR_getuid 24 -#define __NR_stime 25 -#define __NR_ptrace 26 -#define __NR_alarm 27 -#define __NR_oldfstat 28 -#define __NR_pause 29 -#define __NR_utime 30 -#define __NR_stty 31 -#define __NR_gtty 32 -#define __NR_access 33 -#define __NR_nice 34 -#define __NR_ftime 35 -#define __NR_sync 36 -#define __NR_kill 37 -#define __NR_rename 38 -#define __NR_mkdir 39 -#define __NR_rmdir 40 -#define __NR_dup 41 -#define __NR_pipe 42 -#define __NR_times 43 -#define __NR_prof 44 -#define __NR_brk 45 -#define __NR_setgid 46 -#define __NR_getgid 47 -#define __NR_signal 48 -#define __NR_geteuid 49 -#define __NR_getegid 50 -#define __NR_acct 51 -#define __NR_umount2 52 -#define __NR_lock 53 -#define __NR_ioctl 54 -#define __NR_fcntl 55 -#define __NR_mpx 56 -#define __NR_setpgid 57 -#define __NR_ulimit 58 -#define __NR_oldolduname 59 -#define __NR_umask 60 -#define __NR_chroot 61 -#define __NR_ustat 62 -#define __NR_dup2 63 -#define __NR_getppid 64 -#define __NR_getpgrp 65 -#define __NR_setsid 66 -#define __NR_sigaction 67 -#define __NR_sgetmask 68 -#define __NR_ssetmask 69 -#define __NR_setreuid 70 -#define __NR_setregid 71 -#define __NR_sigsuspend 72 -#define __NR_sigpending 73 -#define __NR_sethostname 74 -#define __NR_setrlimit 75 -#define __NR_getrlimit 76 /* Back compatible 2Gig limited rlimit */ -#define __NR_getrusage 77 -#define __NR_gettimeofday 78 -#define __NR_settimeofday 79 -#define __NR_getgroups 80 -#define __NR_setgroups 81 -#define __NR_select 82 -#define __NR_symlink 83 -#define __NR_oldlstat 84 -#define __NR_readlink 85 -#define __NR_uselib 86 -#define __NR_swapon 87 -#define __NR_reboot 88 -#define __NR_readdir 89 -#define __NR_mmap 90 -#define __NR_munmap 91 -#define __NR_truncate 92 -#define __NR_ftruncate 93 -#define __NR_fchmod 94 -#define __NR_fchown 95 -#define __NR_getpriority 96 -#define __NR_setpriority 97 -#define __NR_profil 98 -#define __NR_statfs 99 -#define __NR_fstatfs 100 -#define __NR_ioperm 101 -#define __NR_socketcall 102 -#define __NR_syslog 103 -#define __NR_setitimer 104 -#define __NR_getitimer 105 -#define __NR_stat 106 -#define __NR_lstat 107 -#define __NR_fstat 108 -#define __NR_olduname 109 -#define __NR_iopl 110 -#define __NR_vhangup 111 -#define __NR_idle 112 -#define __NR_vm86old 113 -#define __NR_wait4 114 -#define __NR_swapoff 115 -#define __NR_sysinfo 116 -#define __NR_ipc 117 -#define __NR_fsync 118 -#define __NR_sigreturn 119 -#define __NR_clone 120 -#define __NR_setdomainname 121 -#define __NR_uname 122 -#define __NR_modify_ldt 123 -#define __NR_adjtimex 124 -#define __NR_mprotect 125 -#define __NR_sigprocmask 126 -#define __NR_create_module 127 -#define __NR_init_module 128 -#define __NR_delete_module 129 -#define __NR_get_kernel_syms 130 -#define __NR_quotactl 131 -#define __NR_getpgid 132 -#define __NR_fchdir 133 -#define __NR_bdflush 134 -#define __NR_sysfs 135 -#define __NR_personality 136 -#define __NR_afs_syscall 137 /* Syscall for Andrew File System */ -#define __NR_setfsuid 138 -#define __NR_setfsgid 139 -#define __NR__llseek 140 -#define __NR_getdents 141 -#define __NR__newselect 142 -#define __NR_flock 143 -#define __NR_msync 144 -#define __NR_readv 145 -#define __NR_writev 146 -#define __NR_getsid 147 -#define __NR_fdatasync 148 -#define __NR__sysctl 149 -#define __NR_mlock 150 -#define __NR_munlock 151 -#define __NR_mlockall 152 -#define __NR_munlockall 153 -#define __NR_sched_setparam 154 -#define __NR_sched_getparam 155 -#define __NR_sched_setscheduler 156 -#define __NR_sched_getscheduler 157 -#define __NR_sched_yield 158 -#define __NR_sched_get_priority_max 159 -#define __NR_sched_get_priority_min 160 -#define __NR_sched_rr_get_interval 161 -#define __NR_nanosleep 162 -#define __NR_mremap 163 -#define __NR_setresuid 164 -#define __NR_getresuid 165 -#define __NR_vm86 166 -#define __NR_query_module 167 -#define __NR_poll 168 -#define __NR_nfsservctl 169 -#define __NR_setresgid 170 -#define __NR_getresgid 171 -#define __NR_prctl 172 -#define __NR_rt_sigreturn 173 -#define __NR_rt_sigaction 174 -#define __NR_rt_sigprocmask 175 -#define __NR_rt_sigpending 176 -#define __NR_rt_sigtimedwait 177 -#define __NR_rt_sigqueueinfo 178 -#define __NR_rt_sigsuspend 179 -#define __NR_pread64 180 -#define __NR_pwrite64 181 -#define __NR_chown 182 -#define __NR_getcwd 183 -#define __NR_capget 184 -#define __NR_capset 185 -#define __NR_sigaltstack 186 -#define __NR_sendfile 187 -#define __NR_streams1 188 /* some people actually want it */ -#define __NR_streams2 189 /* some people actually want it */ -#define __NR_vfork 190 -#define __NR_ugetrlimit 191 /* SuS compliant getrlimit */ -#define __NR_mmap2 192 -#define __NR_truncate64 193 -#define __NR_ftruncate64 194 -#define __NR_stat64 195 -#define __NR_lstat64 196 -#define __NR_fstat64 197 -#define __NR_lchown32 198 -#define __NR_getuid32 199 -#define __NR_getgid32 200 -#define __NR_geteuid32 201 -#define __NR_getegid32 202 -#define __NR_setreuid32 203 -#define __NR_setregid32 204 -#define __NR_getgroups32 205 -#define __NR_setgroups32 206 -#define __NR_fchown32 207 -#define __NR_setresuid32 208 -#define __NR_getresuid32 209 -#define __NR_setresgid32 210 -#define __NR_getresgid32 211 -#define __NR_chown32 212 -#define __NR_setuid32 213 -#define __NR_setgid32 214 -#define __NR_setfsuid32 215 -#define __NR_setfsgid32 216 -#define __NR_pivot_root 217 -#define __NR_mincore 218 -#define __NR_madvise 219 -#define __NR_getdents64 220 -#define __NR_fcntl64 221 -/* 223 is unused */ -#define __NR_gettid 224 -#define __NR_readahead 225 -#define __NR_setxattr 226 -#define __NR_lsetxattr 227 -#define __NR_fsetxattr 228 -#define __NR_getxattr 229 -#define __NR_lgetxattr 230 -#define __NR_fgetxattr 231 -#define __NR_listxattr 232 -#define __NR_llistxattr 233 -#define __NR_flistxattr 234 -#define __NR_removexattr 235 -#define __NR_lremovexattr 236 -#define __NR_fremovexattr 237 -#define __NR_tkill 238 -#define __NR_sendfile64 239 -#define __NR_futex 240 -#define __NR_sched_setaffinity 241 -#define __NR_sched_getaffinity 242 -#define __NR_set_thread_area 243 -#define __NR_get_thread_area 244 -#define __NR_io_setup 245 -#define __NR_io_destroy 246 -#define __NR_io_getevents 247 -#define __NR_io_submit 248 -#define __NR_io_cancel 249 -#define __NR_fadvise64 250 - -#define __NR_exit_group 252 -#define __NR_lookup_dcookie 253 -#define __NR_epoll_create 254 -#define __NR_epoll_ctl 255 -#define __NR_epoll_wait 256 -#define __NR_remap_file_pages 257 -#define __NR_set_tid_address 258 -#define __NR_timer_create 259 -#define __NR_timer_settime (__NR_timer_create+1) -#define __NR_timer_gettime (__NR_timer_create+2) -#define __NR_timer_getoverrun (__NR_timer_create+3) -#define __NR_timer_delete (__NR_timer_create+4) -#define __NR_clock_settime (__NR_timer_create+5) -#define __NR_clock_gettime (__NR_timer_create+6) -#define __NR_clock_getres (__NR_timer_create+7) -#define __NR_clock_nanosleep (__NR_timer_create+8) -#define __NR_statfs64 268 -#define __NR_fstatfs64 269 -#define __NR_tgkill 270 -#define __NR_utimes 271 -#define __NR_fadvise64_64 272 -#define __NR_vserver 273 -#define __NR_mbind 274 -#define __NR_get_mempolicy 275 -#define __NR_set_mempolicy 276 -#define __NR_mq_open 277 -#define __NR_mq_unlink (__NR_mq_open+1) -#define __NR_mq_timedsend (__NR_mq_open+2) -#define __NR_mq_timedreceive (__NR_mq_open+3) -#define __NR_mq_notify (__NR_mq_open+4) -#define __NR_mq_getsetattr (__NR_mq_open+5) -#define __NR_kexec_load 283 -#define __NR_waitid 284 -#define __NR_add_key 285 -#define __NR_request_key 286 -#define __NR_keyctl 287 -#define __NR_ioprio_set 288 -#define __NR_ioprio_get 289 -#define __NR_inotify_init 290 -#define __NR_inotify_add_watch 291 -#define __NR_inotify_rm_watch 292 -/* 293 is unused */ -#define __NR_migrate_pages 294 -#define __NR_openat 295 -#define __NR_mkdirat 296 -#define __NR_mknodat 297 -#define __NR_fchownat 298 -#define __NR_futimesat 299 -#define __NR_fstatat64 300 -#define __NR_unlinkat 301 -#define __NR_renameat 302 -#define __NR_linkat 303 -#define __NR_symlinkat 304 -#define __NR_readlinkat 305 -#define __NR_fchmodat 306 -#define __NR_faccessat 307 -#define __NR_pselect6 308 -#define __NR_ppoll 309 -#define __NR_unshare 310 -#define __NR_set_robust_list 311 -#define __NR_get_robust_list 312 -#define __NR_splice 313 -#define __NR_sync_file_range 314 -#define __NR_tee 315 -#define __NR_vmsplice 316 -#define __NR_move_pages 317 -#define __NR_getcpu 318 -#define __NR_epoll_pwait 319 -#define __NR_utimensat 320 -#define __NR_signalfd 321 -#define __NR_timerfd 322 -#define __NR_eventfd 323 -#define __NR_fallocate 324 - -#define NR_syscalls 325 - -#ifdef __KERNEL__ - -#define __ARCH_WANT_IPC_PARSE_VERSION -#define __ARCH_WANT_OLD_READDIR -#define __ARCH_WANT_OLD_STAT -#define __ARCH_WANT_STAT64 -#define __ARCH_WANT_SYS_ALARM -#define __ARCH_WANT_SYS_GETHOSTNAME -#define __ARCH_WANT_SYS_PAUSE -#define __ARCH_WANT_SYS_SGETMASK -#define __ARCH_WANT_SYS_SIGNAL -#define __ARCH_WANT_SYS_TIME -#define __ARCH_WANT_SYS_UTIME -#define __ARCH_WANT_SYS_WAITPID -#define __ARCH_WANT_SYS_SOCKETCALL -#define __ARCH_WANT_SYS_FADVISE64 -#define __ARCH_WANT_SYS_GETPGRP -#define __ARCH_WANT_SYS_LLSEEK -#define __ARCH_WANT_SYS_NICE -#define __ARCH_WANT_SYS_OLD_GETRLIMIT -#define __ARCH_WANT_SYS_OLDUMOUNT -#define __ARCH_WANT_SYS_SIGPENDING -#define __ARCH_WANT_SYS_SIGPROCMASK -#define __ARCH_WANT_SYS_RT_SIGACTION -#define __ARCH_WANT_SYS_RT_SIGSUSPEND - -/* - * "Conditional" syscalls - * - * What we want is __attribute__((weak,alias("sys_ni_syscall"))), - * but it doesn't work on all toolchains, so we just do it by hand - */ -#ifndef cond_syscall -#define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall") +#ifdef CONFIG_SUPERH32 +# include "unistd_32.h" +#else +# include "unistd_64.h" #endif - -#endif /* __KERNEL__ */ -#endif /* __ASM_SH_UNISTD_H */ diff --git a/include/asm-sh/unistd_32.h b/include/asm-sh/unistd_32.h new file mode 100644 index 00000000000..433fd1b48fa --- /dev/null +++ b/include/asm-sh/unistd_32.h @@ -0,0 +1,376 @@ +#ifndef __ASM_SH_UNISTD_H +#define __ASM_SH_UNISTD_H + +/* + * Copyright (C) 1999 Niibe Yutaka + */ + +/* + * This file contains the system call numbers. + */ + +#define __NR_restart_syscall 0 +#define __NR_exit 1 +#define __NR_fork 2 +#define __NR_read 3 +#define __NR_write 4 +#define __NR_open 5 +#define __NR_close 6 +#define __NR_waitpid 7 +#define __NR_creat 8 +#define __NR_link 9 +#define __NR_unlink 10 +#define __NR_execve 11 +#define __NR_chdir 12 +#define __NR_time 13 +#define __NR_mknod 14 +#define __NR_chmod 15 +#define __NR_lchown 16 +#define __NR_break 17 +#define __NR_oldstat 18 +#define __NR_lseek 19 +#define __NR_getpid 20 +#define __NR_mount 21 +#define __NR_umount 22 +#define __NR_setuid 23 +#define __NR_getuid 24 +#define __NR_stime 25 +#define __NR_ptrace 26 +#define __NR_alarm 27 +#define __NR_oldfstat 28 +#define __NR_pause 29 +#define __NR_utime 30 +#define __NR_stty 31 +#define __NR_gtty 32 +#define __NR_access 33 +#define __NR_nice 34 +#define __NR_ftime 35 +#define __NR_sync 36 +#define __NR_kill 37 +#define __NR_rename 38 +#define __NR_mkdir 39 +#define __NR_rmdir 40 +#define __NR_dup 41 +#define __NR_pipe 42 +#define __NR_times 43 +#define __NR_prof 44 +#define __NR_brk 45 +#define __NR_setgid 46 +#define __NR_getgid 47 +#define __NR_signal 48 +#define __NR_geteuid 49 +#define __NR_getegid 50 +#define __NR_acct 51 +#define __NR_umount2 52 +#define __NR_lock 53 +#define __NR_ioctl 54 +#define __NR_fcntl 55 +#define __NR_mpx 56 +#define __NR_setpgid 57 +#define __NR_ulimit 58 +#define __NR_oldolduname 59 +#define __NR_umask 60 +#define __NR_chroot 61 +#define __NR_ustat 62 +#define __NR_dup2 63 +#define __NR_getppid 64 +#define __NR_getpgrp 65 +#define __NR_setsid 66 +#define __NR_sigaction 67 +#define __NR_sgetmask 68 +#define __NR_ssetmask 69 +#define __NR_setreuid 70 +#define __NR_setregid 71 +#define __NR_sigsuspend 72 +#define __NR_sigpending 73 +#define __NR_sethostname 74 +#define __NR_setrlimit 75 +#define __NR_getrlimit 76 /* Back compatible 2Gig limited rlimit */ +#define __NR_getrusage 77 +#define __NR_gettimeofday 78 +#define __NR_settimeofday 79 +#define __NR_getgroups 80 +#define __NR_setgroups 81 +#define __NR_select 82 +#define __NR_symlink 83 +#define __NR_oldlstat 84 +#define __NR_readlink 85 +#define __NR_uselib 86 +#define __NR_swapon 87 +#define __NR_reboot 88 +#define __NR_readdir 89 +#define __NR_mmap 90 +#define __NR_munmap 91 +#define __NR_truncate 92 +#define __NR_ftruncate 93 +#define __NR_fchmod 94 +#define __NR_fchown 95 +#define __NR_getpriority 96 +#define __NR_setpriority 97 +#define __NR_profil 98 +#define __NR_statfs 99 +#define __NR_fstatfs 100 +#define __NR_ioperm 101 +#define __NR_socketcall 102 +#define __NR_syslog 103 +#define __NR_setitimer 104 +#define __NR_getitimer 105 +#define __NR_stat 106 +#define __NR_lstat 107 +#define __NR_fstat 108 +#define __NR_olduname 109 +#define __NR_iopl 110 +#define __NR_vhangup 111 +#define __NR_idle 112 +#define __NR_vm86old 113 +#define __NR_wait4 114 +#define __NR_swapoff 115 +#define __NR_sysinfo 116 +#define __NR_ipc 117 +#define __NR_fsync 118 +#define __NR_sigreturn 119 +#define __NR_clone 120 +#define __NR_setdomainname 121 +#define __NR_uname 122 +#define __NR_modify_ldt 123 +#define __NR_adjtimex 124 +#define __NR_mprotect 125 +#define __NR_sigprocmask 126 +#define __NR_create_module 127 +#define __NR_init_module 128 +#define __NR_delete_module 129 +#define __NR_get_kernel_syms 130 +#define __NR_quotactl 131 +#define __NR_getpgid 132 +#define __NR_fchdir 133 +#define __NR_bdflush 134 +#define __NR_sysfs 135 +#define __NR_personality 136 +#define __NR_afs_syscall 137 /* Syscall for Andrew File System */ +#define __NR_setfsuid 138 +#define __NR_setfsgid 139 +#define __NR__llseek 140 +#define __NR_getdents 141 +#define __NR__newselect 142 +#define __NR_flock 143 +#define __NR_msync 144 +#define __NR_readv 145 +#define __NR_writev 146 +#define __NR_getsid 147 +#define __NR_fdatasync 148 +#define __NR__sysctl 149 +#define __NR_mlock 150 +#define __NR_munlock 151 +#define __NR_mlockall 152 +#define __NR_munlockall 153 +#define __NR_sched_setparam 154 +#define __NR_sched_getparam 155 +#define __NR_sched_setscheduler 156 +#define __NR_sched_getscheduler 157 +#define __NR_sched_yield 158 +#define __NR_sched_get_priority_max 159 +#define __NR_sched_get_priority_min 160 +#define __NR_sched_rr_get_interval 161 +#define __NR_nanosleep 162 +#define __NR_mremap 163 +#define __NR_setresuid 164 +#define __NR_getresuid 165 +#define __NR_vm86 166 +#define __NR_query_module 167 +#define __NR_poll 168 +#define __NR_nfsservctl 169 +#define __NR_setresgid 170 +#define __NR_getresgid 171 +#define __NR_prctl 172 +#define __NR_rt_sigreturn 173 +#define __NR_rt_sigaction 174 +#define __NR_rt_sigprocmask 175 +#define __NR_rt_sigpending 176 +#define __NR_rt_sigtimedwait 177 +#define __NR_rt_sigqueueinfo 178 +#define __NR_rt_sigsuspend 179 +#define __NR_pread64 180 +#define __NR_pwrite64 181 +#define __NR_chown 182 +#define __NR_getcwd 183 +#define __NR_capget 184 +#define __NR_capset 185 +#define __NR_sigaltstack 186 +#define __NR_sendfile 187 +#define __NR_streams1 188 /* some people actually want it */ +#define __NR_streams2 189 /* some people actually want it */ +#define __NR_vfork 190 +#define __NR_ugetrlimit 191 /* SuS compliant getrlimit */ +#define __NR_mmap2 192 +#define __NR_truncate64 193 +#define __NR_ftruncate64 194 +#define __NR_stat64 195 +#define __NR_lstat64 196 +#define __NR_fstat64 197 +#define __NR_lchown32 198 +#define __NR_getuid32 199 +#define __NR_getgid32 200 +#define __NR_geteuid32 201 +#define __NR_getegid32 202 +#define __NR_setreuid32 203 +#define __NR_setregid32 204 +#define __NR_getgroups32 205 +#define __NR_setgroups32 206 +#define __NR_fchown32 207 +#define __NR_setresuid32 208 +#define __NR_getresuid32 209 +#define __NR_setresgid32 210 +#define __NR_getresgid32 211 +#define __NR_chown32 212 +#define __NR_setuid32 213 +#define __NR_setgid32 214 +#define __NR_setfsuid32 215 +#define __NR_setfsgid32 216 +#define __NR_pivot_root 217 +#define __NR_mincore 218 +#define __NR_madvise 219 +#define __NR_getdents64 220 +#define __NR_fcntl64 221 +/* 223 is unused */ +#define __NR_gettid 224 +#define __NR_readahead 225 +#define __NR_setxattr 226 +#define __NR_lsetxattr 227 +#define __NR_fsetxattr 228 +#define __NR_getxattr 229 +#define __NR_lgetxattr 230 +#define __NR_fgetxattr 231 +#define __NR_listxattr 232 +#define __NR_llistxattr 233 +#define __NR_flistxattr 234 +#define __NR_removexattr 235 +#define __NR_lremovexattr 236 +#define __NR_fremovexattr 237 +#define __NR_tkill 238 +#define __NR_sendfile64 239 +#define __NR_futex 240 +#define __NR_sched_setaffinity 241 +#define __NR_sched_getaffinity 242 +#define __NR_set_thread_area 243 +#define __NR_get_thread_area 244 +#define __NR_io_setup 245 +#define __NR_io_destroy 246 +#define __NR_io_getevents 247 +#define __NR_io_submit 248 +#define __NR_io_cancel 249 +#define __NR_fadvise64 250 + +#define __NR_exit_group 252 +#define __NR_lookup_dcookie 253 +#define __NR_epoll_create 254 +#define __NR_epoll_ctl 255 +#define __NR_epoll_wait 256 +#define __NR_remap_file_pages 257 +#define __NR_set_tid_address 258 +#define __NR_timer_create 259 +#define __NR_timer_settime (__NR_timer_create+1) +#define __NR_timer_gettime (__NR_timer_create+2) +#define __NR_timer_getoverrun (__NR_timer_create+3) +#define __NR_timer_delete (__NR_timer_create+4) +#define __NR_clock_settime (__NR_timer_create+5) +#define __NR_clock_gettime (__NR_timer_create+6) +#define __NR_clock_getres (__NR_timer_create+7) +#define __NR_clock_nanosleep (__NR_timer_create+8) +#define __NR_statfs64 268 +#define __NR_fstatfs64 269 +#define __NR_tgkill 270 +#define __NR_utimes 271 +#define __NR_fadvise64_64 272 +#define __NR_vserver 273 +#define __NR_mbind 274 +#define __NR_get_mempolicy 275 +#define __NR_set_mempolicy 276 +#define __NR_mq_open 277 +#define __NR_mq_unlink (__NR_mq_open+1) +#define __NR_mq_timedsend (__NR_mq_open+2) +#define __NR_mq_timedreceive (__NR_mq_open+3) +#define __NR_mq_notify (__NR_mq_open+4) +#define __NR_mq_getsetattr (__NR_mq_open+5) +#define __NR_kexec_load 283 +#define __NR_waitid 284 +#define __NR_add_key 285 +#define __NR_request_key 286 +#define __NR_keyctl 287 +#define __NR_ioprio_set 288 +#define __NR_ioprio_get 289 +#define __NR_inotify_init 290 +#define __NR_inotify_add_watch 291 +#define __NR_inotify_rm_watch 292 +/* 293 is unused */ +#define __NR_migrate_pages 294 +#define __NR_openat 295 +#define __NR_mkdirat 296 +#define __NR_mknodat 297 +#define __NR_fchownat 298 +#define __NR_futimesat 299 +#define __NR_fstatat64 300 +#define __NR_unlinkat 301 +#define __NR_renameat 302 +#define __NR_linkat 303 +#define __NR_symlinkat 304 +#define __NR_readlinkat 305 +#define __NR_fchmodat 306 +#define __NR_faccessat 307 +#define __NR_pselect6 308 +#define __NR_ppoll 309 +#define __NR_unshare 310 +#define __NR_set_robust_list 311 +#define __NR_get_robust_list 312 +#define __NR_splice 313 +#define __NR_sync_file_range 314 +#define __NR_tee 315 +#define __NR_vmsplice 316 +#define __NR_move_pages 317 +#define __NR_getcpu 318 +#define __NR_epoll_pwait 319 +#define __NR_utimensat 320 +#define __NR_signalfd 321 +/* #define __NR_timerfd 322 removed */ +#define __NR_eventfd 323 +#define __NR_fallocate 324 + +#define NR_syscalls 325 + +#ifdef __KERNEL__ + +#define __ARCH_WANT_IPC_PARSE_VERSION +#define __ARCH_WANT_OLD_READDIR +#define __ARCH_WANT_OLD_STAT +#define __ARCH_WANT_STAT64 +#define __ARCH_WANT_SYS_ALARM +#define __ARCH_WANT_SYS_GETHOSTNAME +#define __ARCH_WANT_SYS_PAUSE +#define __ARCH_WANT_SYS_SGETMASK +#define __ARCH_WANT_SYS_SIGNAL +#define __ARCH_WANT_SYS_TIME +#define __ARCH_WANT_SYS_UTIME +#define __ARCH_WANT_SYS_WAITPID +#define __ARCH_WANT_SYS_SOCKETCALL +#define __ARCH_WANT_SYS_FADVISE64 +#define __ARCH_WANT_SYS_GETPGRP +#define __ARCH_WANT_SYS_LLSEEK +#define __ARCH_WANT_SYS_NICE +#define __ARCH_WANT_SYS_OLD_GETRLIMIT +#define __ARCH_WANT_SYS_OLDUMOUNT +#define __ARCH_WANT_SYS_SIGPENDING +#define __ARCH_WANT_SYS_SIGPROCMASK +#define __ARCH_WANT_SYS_RT_SIGACTION +#define __ARCH_WANT_SYS_RT_SIGSUSPEND + +/* + * "Conditional" syscalls + * + * What we want is __attribute__((weak,alias("sys_ni_syscall"))), + * but it doesn't work on all toolchains, so we just do it by hand + */ +#ifndef cond_syscall +#define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall") +#endif + +#endif /* __KERNEL__ */ +#endif /* __ASM_SH_UNISTD_H */ diff --git a/include/asm-sh/unistd_64.h b/include/asm-sh/unistd_64.h new file mode 100644 index 00000000000..108d2ba897f --- /dev/null +++ b/include/asm-sh/unistd_64.h @@ -0,0 +1,415 @@ +#ifndef __ASM_SH_UNISTD_64_H +#define __ASM_SH_UNISTD_64_H + +/* + * include/asm-sh/unistd_64.h + * + * This file contains the system call numbers. + * + * Copyright (C) 2000, 2001 Paolo Alberelli + * Copyright (C) 2003 - 2007 Paul Mundt + * Copyright (C) 2004 Sean McGoogan + * + * 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. + */ +#define __NR_restart_syscall 0 +#define __NR_exit 1 +#define __NR_fork 2 +#define __NR_read 3 +#define __NR_write 4 +#define __NR_open 5 +#define __NR_close 6 +#define __NR_waitpid 7 +#define __NR_creat 8 +#define __NR_link 9 +#define __NR_unlink 10 +#define __NR_execve 11 +#define __NR_chdir 12 +#define __NR_time 13 +#define __NR_mknod 14 +#define __NR_chmod 15 +#define __NR_lchown 16 +#define __NR_break 17 +#define __NR_oldstat 18 +#define __NR_lseek 19 +#define __NR_getpid 20 +#define __NR_mount 21 +#define __NR_umount 22 +#define __NR_setuid 23 +#define __NR_getuid 24 +#define __NR_stime 25 +#define __NR_ptrace 26 +#define __NR_alarm 27 +#define __NR_oldfstat 28 +#define __NR_pause 29 +#define __NR_utime 30 +#define __NR_stty 31 +#define __NR_gtty 32 +#define __NR_access 33 +#define __NR_nice 34 +#define __NR_ftime 35 +#define __NR_sync 36 +#define __NR_kill 37 +#define __NR_rename 38 +#define __NR_mkdir 39 +#define __NR_rmdir 40 +#define __NR_dup 41 +#define __NR_pipe 42 +#define __NR_times 43 +#define __NR_prof 44 +#define __NR_brk 45 +#define __NR_setgid 46 +#define __NR_getgid 47 +#define __NR_signal 48 +#define __NR_geteuid 49 +#define __NR_getegid 50 +#define __NR_acct 51 +#define __NR_umount2 52 +#define __NR_lock 53 +#define __NR_ioctl 54 +#define __NR_fcntl 55 +#define __NR_mpx 56 +#define __NR_setpgid 57 +#define __NR_ulimit 58 +#define __NR_oldolduname 59 +#define __NR_umask 60 +#define __NR_chroot 61 +#define __NR_ustat 62 +#define __NR_dup2 63 +#define __NR_getppid 64 +#define __NR_getpgrp 65 +#define __NR_setsid 66 +#define __NR_sigaction 67 +#define __NR_sgetmask 68 +#define __NR_ssetmask 69 +#define __NR_setreuid 70 +#define __NR_setregid 71 +#define __NR_sigsuspend 72 +#define __NR_sigpending 73 +#define __NR_sethostname 74 +#define __NR_setrlimit 75 +#define __NR_getrlimit 76 /* Back compatible 2Gig limited rlimit */ +#define __NR_getrusage 77 +#define __NR_gettimeofday 78 +#define __NR_settimeofday 79 +#define __NR_getgroups 80 +#define __NR_setgroups 81 +#define __NR_select 82 +#define __NR_symlink 83 +#define __NR_oldlstat 84 +#define __NR_readlink 85 +#define __NR_uselib 86 +#define __NR_swapon 87 +#define __NR_reboot 88 +#define __NR_readdir 89 +#define __NR_mmap 90 +#define __NR_munmap 91 +#define __NR_truncate 92 +#define __NR_ftruncate 93 +#define __NR_fchmod 94 +#define __NR_fchown 95 +#define __NR_getpriority 96 +#define __NR_setpriority 97 +#define __NR_profil 98 +#define __NR_statfs 99 +#define __NR_fstatfs 100 +#define __NR_ioperm 101 +#define __NR_socketcall 102 /* old implementation of socket systemcall */ +#define __NR_syslog 103 +#define __NR_setitimer 104 +#define __NR_getitimer 105 +#define __NR_stat 106 +#define __NR_lstat 107 +#define __NR_fstat 108 +#define __NR_olduname 109 +#define __NR_iopl 110 +#define __NR_vhangup 111 +#define __NR_idle 112 +#define __NR_vm86old 113 +#define __NR_wait4 114 +#define __NR_swapoff 115 +#define __NR_sysinfo 116 +#define __NR_ipc 117 +#define __NR_fsync 118 +#define __NR_sigreturn 119 +#define __NR_clone 120 +#define __NR_setdomainname 121 +#define __NR_uname 122 +#define __NR_modify_ldt 123 +#define __NR_adjtimex 124 +#define __NR_mprotect 125 +#define __NR_sigprocmask 126 +#define __NR_create_module 127 +#define __NR_init_module 128 +#define __NR_delete_module 129 +#define __NR_get_kernel_syms 130 +#define __NR_quotactl 131 +#define __NR_getpgid 132 +#define __NR_fchdir 133 +#define __NR_bdflush 134 +#define __NR_sysfs 135 +#define __NR_personality 136 +#define __NR_afs_syscall 137 /* Syscall for Andrew File System */ +#define __NR_setfsuid 138 +#define __NR_setfsgid 139 +#define __NR__llseek 140 +#define __NR_getdents 141 +#define __NR__newselect 142 +#define __NR_flock 143 +#define __NR_msync 144 +#define __NR_readv 145 +#define __NR_writev 146 +#define __NR_getsid 147 +#define __NR_fdatasync 148 +#define __NR__sysctl 149 +#define __NR_mlock 150 +#define __NR_munlock 151 +#define __NR_mlockall 152 +#define __NR_munlockall 153 +#define __NR_sched_setparam 154 +#define __NR_sched_getparam 155 +#define __NR_sched_setscheduler 156 +#define __NR_sched_getscheduler 157 +#define __NR_sched_yield 158 +#define __NR_sched_get_priority_max 159 +#define __NR_sched_get_priority_min 160 +#define __NR_sched_rr_get_interval 161 +#define __NR_nanosleep 162 +#define __NR_mremap 163 +#define __NR_setresuid 164 +#define __NR_getresuid 165 +#define __NR_vm86 166 +#define __NR_query_module 167 +#define __NR_poll 168 +#define __NR_nfsservctl 169 +#define __NR_setresgid 170 +#define __NR_getresgid 171 +#define __NR_prctl 172 +#define __NR_rt_sigreturn 173 +#define __NR_rt_sigaction 174 +#define __NR_rt_sigprocmask 175 +#define __NR_rt_sigpending 176 +#define __NR_rt_sigtimedwait 177 +#define __NR_rt_sigqueueinfo 178 +#define __NR_rt_sigsuspend 179 +#define __NR_pread64 180 +#define __NR_pwrite64 181 +#define __NR_chown 182 +#define __NR_getcwd 183 +#define __NR_capget 184 +#define __NR_capset 185 +#define __NR_sigaltstack 186 +#define __NR_sendfile 187 +#define __NR_streams1 188 /* some people actually want it */ +#define __NR_streams2 189 /* some people actually want it */ +#define __NR_vfork 190 +#define __NR_ugetrlimit 191 /* SuS compliant getrlimit */ +#define __NR_mmap2 192 +#define __NR_truncate64 193 +#define __NR_ftruncate64 194 +#define __NR_stat64 195 +#define __NR_lstat64 196 +#define __NR_fstat64 197 +#define __NR_lchown32 198 +#define __NR_getuid32 199 +#define __NR_getgid32 200 +#define __NR_geteuid32 201 +#define __NR_getegid32 202 +#define __NR_setreuid32 203 +#define __NR_setregid32 204 +#define __NR_getgroups32 205 +#define __NR_setgroups32 206 +#define __NR_fchown32 207 +#define __NR_setresuid32 208 +#define __NR_getresuid32 209 +#define __NR_setresgid32 210 +#define __NR_getresgid32 211 +#define __NR_chown32 212 +#define __NR_setuid32 213 +#define __NR_setgid32 214 +#define __NR_setfsuid32 215 +#define __NR_setfsgid32 216 +#define __NR_pivot_root 217 +#define __NR_mincore 218 +#define __NR_madvise 219 + +/* Non-multiplexed socket family */ +#define __NR_socket 220 +#define __NR_bind 221 +#define __NR_connect 222 +#define __NR_listen 223 +#define __NR_accept 224 +#define __NR_getsockname 225 +#define __NR_getpeername 226 +#define __NR_socketpair 227 +#define __NR_send 228 +#define __NR_sendto 229 +#define __NR_recv 230 +#define __NR_recvfrom 231 +#define __NR_shutdown 232 +#define __NR_setsockopt 233 +#define __NR_getsockopt 234 +#define __NR_sendmsg 235 +#define __NR_recvmsg 236 + +/* Non-multiplexed IPC family */ +#define __NR_semop 237 +#define __NR_semget 238 +#define __NR_semctl 239 +#define __NR_msgsnd 240 +#define __NR_msgrcv 241 +#define __NR_msgget 242 +#define __NR_msgctl 243 +#if 0 +#define __NR_shmatcall 244 +#endif +#define __NR_shmdt 245 +#define __NR_shmget 246 +#define __NR_shmctl 247 + +#define __NR_getdents64 248 +#define __NR_fcntl64 249 +/* 223 is unused */ +#define __NR_gettid 252 +#define __NR_readahead 253 +#define __NR_setxattr 254 +#define __NR_lsetxattr 255 +#define __NR_fsetxattr 256 +#define __NR_getxattr 257 +#define __NR_lgetxattr 258 +#define __NR_fgetxattr 269 +#define __NR_listxattr 260 +#define __NR_llistxattr 261 +#define __NR_flistxattr 262 +#define __NR_removexattr 263 +#define __NR_lremovexattr 264 +#define __NR_fremovexattr 265 +#define __NR_tkill 266 +#define __NR_sendfile64 267 +#define __NR_futex 268 +#define __NR_sched_setaffinity 269 +#define __NR_sched_getaffinity 270 +#define __NR_set_thread_area 271 +#define __NR_get_thread_area 272 +#define __NR_io_setup 273 +#define __NR_io_destroy 274 +#define __NR_io_getevents 275 +#define __NR_io_submit 276 +#define __NR_io_cancel 277 +#define __NR_fadvise64 278 +#define __NR_exit_group 280 + +#define __NR_lookup_dcookie 281 +#define __NR_epoll_create 282 +#define __NR_epoll_ctl 283 +#define __NR_epoll_wait 284 +#define __NR_remap_file_pages 285 +#define __NR_set_tid_address 286 +#define __NR_timer_create 287 +#define __NR_timer_settime (__NR_timer_create+1) +#define __NR_timer_gettime (__NR_timer_create+2) +#define __NR_timer_getoverrun (__NR_timer_create+3) +#define __NR_timer_delete (__NR_timer_create+4) +#define __NR_clock_settime (__NR_timer_create+5) +#define __NR_clock_gettime (__NR_timer_create+6) +#define __NR_clock_getres (__NR_timer_create+7) +#define __NR_clock_nanosleep (__NR_timer_create+8) +#define __NR_statfs64 296 +#define __NR_fstatfs64 297 +#define __NR_tgkill 298 +#define __NR_utimes 299 +#define __NR_fadvise64_64 300 +#define __NR_vserver 301 +#define __NR_mbind 302 +#define __NR_get_mempolicy 303 +#define __NR_set_mempolicy 304 +#define __NR_mq_open 305 +#define __NR_mq_unlink (__NR_mq_open+1) +#define __NR_mq_timedsend (__NR_mq_open+2) +#define __NR_mq_timedreceive (__NR_mq_open+3) +#define __NR_mq_notify (__NR_mq_open+4) +#define __NR_mq_getsetattr (__NR_mq_open+5) +#define __NR_kexec_load 311 +#define __NR_waitid 312 +#define __NR_add_key 313 +#define __NR_request_key 314 +#define __NR_keyctl 315 +#define __NR_ioprio_set 316 +#define __NR_ioprio_get 317 +#define __NR_inotify_init 318 +#define __NR_inotify_add_watch 319 +#define __NR_inotify_rm_watch 320 +/* 321 is unused */ +#define __NR_migrate_pages 322 +#define __NR_openat 323 +#define __NR_mkdirat 324 +#define __NR_mknodat 325 +#define __NR_fchownat 326 +#define __NR_futimesat 327 +#define __NR_fstatat64 328 +#define __NR_unlinkat 329 +#define __NR_renameat 330 +#define __NR_linkat 331 +#define __NR_symlinkat 332 +#define __NR_readlinkat 333 +#define __NR_fchmodat 334 +#define __NR_faccessat 335 +#define __NR_pselect6 336 +#define __NR_ppoll 337 +#define __NR_unshare 338 +#define __NR_set_robust_list 339 +#define __NR_get_robust_list 340 +#define __NR_splice 341 +#define __NR_sync_file_range 342 +#define __NR_tee 343 +#define __NR_vmsplice 344 +#define __NR_move_pages 345 +#define __NR_getcpu 346 +#define __NR_epoll_pwait 347 +#define __NR_utimensat 348 +#define __NR_signalfd 349 +/* #define __NR_timerfd 350 removed */ +#define __NR_eventfd 351 +#define __NR_fallocate 352 + +#ifdef __KERNEL__ + +#define NR_syscalls 353 + +#define __ARCH_WANT_IPC_PARSE_VERSION +#define __ARCH_WANT_OLD_READDIR +#define __ARCH_WANT_OLD_STAT +#define __ARCH_WANT_STAT64 +#define __ARCH_WANT_SYS_ALARM +#define __ARCH_WANT_SYS_GETHOSTNAME +#define __ARCH_WANT_SYS_PAUSE +#define __ARCH_WANT_SYS_SGETMASK +#define __ARCH_WANT_SYS_SIGNAL +#define __ARCH_WANT_SYS_TIME +#define __ARCH_WANT_SYS_UTIME +#define __ARCH_WANT_SYS_WAITPID +#define __ARCH_WANT_SYS_SOCKETCALL +#define __ARCH_WANT_SYS_FADVISE64 +#define __ARCH_WANT_SYS_GETPGRP +#define __ARCH_WANT_SYS_LLSEEK +#define __ARCH_WANT_SYS_NICE +#define __ARCH_WANT_SYS_OLD_GETRLIMIT +#define __ARCH_WANT_SYS_OLDUMOUNT +#define __ARCH_WANT_SYS_SIGPENDING +#define __ARCH_WANT_SYS_SIGPROCMASK +#define __ARCH_WANT_SYS_RT_SIGACTION + +/* + * "Conditional" syscalls + * + * What we want is __attribute__((weak,alias("sys_ni_syscall"))), + * but it doesn't work on all toolchains, so we just do it by hand + */ +#ifndef cond_syscall +#define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall") +#endif + +#endif /* __KERNEL__ */ +#endif /* __ASM_SH_UNISTD_64_H */ diff --git a/include/asm-sh/user.h b/include/asm-sh/user.h index d1b8511d9d9..1a4f43c7512 100644 --- a/include/asm-sh/user.h +++ b/include/asm-sh/user.h @@ -27,12 +27,19 @@ * to write an integer number of pages. */ +#if defined(__SH5__) || defined(CONFIG_CPU_SH5) +struct user_fpu_struct { + unsigned long fp_regs[32]; + unsigned int fpscr; +}; +#else struct user_fpu_struct { unsigned long fp_regs[16]; unsigned long xfp_regs[16]; unsigned long fpscr; unsigned long fpul; }; +#endif struct user { struct pt_regs regs; /* entire machine state */ diff --git a/include/asm-sh/voyagergx.h b/include/asm-sh/voyagergx.h deleted file mode 100644 index d825596562d..00000000000 --- a/include/asm-sh/voyagergx.h +++ /dev/null @@ -1,341 +0,0 @@ -/* -------------------------------------------------------------------- */ -/* voyagergx.h */ -/* -------------------------------------------------------------------- */ -/* This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - Copyright 2003 (c) Lineo uSolutions,Inc. -*/ -/* -------------------------------------------------------------------- */ - -#ifndef _VOYAGER_GX_REG_H -#define _VOYAGER_GX_REG_H - -#define VOYAGER_BASE 0xb3e00000 -#define VOYAGER_USBH_BASE (0x40000 + VOYAGER_BASE) -#define VOYAGER_UART_BASE (0x30000 + VOYAGER_BASE) -#define VOYAGER_AC97_BASE (0xa0000 + VOYAGER_BASE) - -#define VOYAGER_IRQ_NUM 26 -#define VOYAGER_IRQ_BASE 200 - -#define IRQ_SM501_UP (VOYAGER_IRQ_BASE + 0) -#define IRQ_SM501_G54 (VOYAGER_IRQ_BASE + 1) -#define IRQ_SM501_G53 (VOYAGER_IRQ_BASE + 2) -#define IRQ_SM501_G52 (VOYAGER_IRQ_BASE + 3) -#define IRQ_SM501_G51 (VOYAGER_IRQ_BASE + 4) -#define IRQ_SM501_G50 (VOYAGER_IRQ_BASE + 5) -#define IRQ_SM501_G49 (VOYAGER_IRQ_BASE + 6) -#define IRQ_SM501_G48 (VOYAGER_IRQ_BASE + 7) -#define IRQ_SM501_I2C (VOYAGER_IRQ_BASE + 8) -#define IRQ_SM501_PW (VOYAGER_IRQ_BASE + 9) -#define IRQ_SM501_DMA (VOYAGER_IRQ_BASE + 10) -#define IRQ_SM501_PCI (VOYAGER_IRQ_BASE + 11) -#define IRQ_SM501_I2S (VOYAGER_IRQ_BASE + 12) -#define IRQ_SM501_AC (VOYAGER_IRQ_BASE + 13) -#define IRQ_SM501_US (VOYAGER_IRQ_BASE + 14) -#define IRQ_SM501_U1 (VOYAGER_IRQ_BASE + 15) -#define IRQ_SM501_U0 (VOYAGER_IRQ_BASE + 16) -#define IRQ_SM501_CV (VOYAGER_IRQ_BASE + 17) -#define IRQ_SM501_MC (VOYAGER_IRQ_BASE + 18) -#define IRQ_SM501_S1 (VOYAGER_IRQ_BASE + 19) -#define IRQ_SM501_S0 (VOYAGER_IRQ_BASE + 20) -#define IRQ_SM501_UH (VOYAGER_IRQ_BASE + 21) -#define IRQ_SM501_2D (VOYAGER_IRQ_BASE + 22) -#define IRQ_SM501_ZD (VOYAGER_IRQ_BASE + 23) -#define IRQ_SM501_PV (VOYAGER_IRQ_BASE + 24) -#define IRQ_SM501_CI (VOYAGER_IRQ_BASE + 25) - -/* ----- MISC controle register ------------------------------ */ -#define MISC_CTRL (0x000004 + VOYAGER_BASE) -#define MISC_CTRL_USBCLK_48 (3 << 28) -#define MISC_CTRL_USBCLK_96 (2 << 28) -#define MISC_CTRL_USBCLK_CRYSTAL (1 << 28) - -/* ----- GPIO[31:0] register --------------------------------- */ -#define GPIO_MUX_LOW (0x000008 + VOYAGER_BASE) -#define GPIO_MUX_LOW_AC97 0x1F000000 -#define GPIO_MUX_LOW_8051 0x0000ffff -#define GPIO_MUX_LOW_PWM (1 << 29) - -/* ----- GPIO[63:32] register --------------------------------- */ -#define GPIO_MUX_HIGH (0x00000C + VOYAGER_BASE) - -/* ----- DRAM controle register ------------------------------- */ -#define DRAM_CTRL (0x000010 + VOYAGER_BASE) -#define DRAM_CTRL_EMBEDDED (1 << 31) -#define DRAM_CTRL_CPU_BURST_1 (0 << 28) -#define DRAM_CTRL_CPU_BURST_2 (1 << 28) -#define DRAM_CTRL_CPU_BURST_4 (2 << 28) -#define DRAM_CTRL_CPU_BURST_8 (3 << 28) -#define DRAM_CTRL_CPU_CAS_LATENCY (1 << 27) -#define DRAM_CTRL_CPU_SIZE_2 (0 << 24) -#define DRAM_CTRL_CPU_SIZE_4 (1 << 24) -#define DRAM_CTRL_CPU_SIZE_64 (4 << 24) -#define DRAM_CTRL_CPU_SIZE_32 (5 << 24) -#define DRAM_CTRL_CPU_SIZE_16 (6 << 24) -#define DRAM_CTRL_CPU_SIZE_8 (7 << 24) -#define DRAM_CTRL_CPU_COLUMN_SIZE_1024 (0 << 22) -#define DRAM_CTRL_CPU_COLUMN_SIZE_512 (2 << 22) -#define DRAM_CTRL_CPU_COLUMN_SIZE_256 (3 << 22) -#define DRAM_CTRL_CPU_ACTIVE_PRECHARGE (1 << 21) -#define DRAM_CTRL_CPU_RESET (1 << 20) -#define DRAM_CTRL_CPU_BANKS (1 << 19) -#define DRAM_CTRL_CPU_WRITE_PRECHARGE (1 << 18) -#define DRAM_CTRL_BLOCK_WRITE (1 << 17) -#define DRAM_CTRL_REFRESH_COMMAND (1 << 16) -#define DRAM_CTRL_SIZE_4 (0 << 13) -#define DRAM_CTRL_SIZE_8 (1 << 13) -#define DRAM_CTRL_SIZE_16 (2 << 13) -#define DRAM_CTRL_SIZE_32 (3 << 13) -#define DRAM_CTRL_SIZE_64 (4 << 13) -#define DRAM_CTRL_SIZE_2 (5 << 13) -#define DRAM_CTRL_COLUMN_SIZE_256 (0 << 11) -#define DRAM_CTRL_COLUMN_SIZE_512 (2 << 11) -#define DRAM_CTRL_COLUMN_SIZE_1024 (3 << 11) -#define DRAM_CTRL_BLOCK_WRITE_TIME (1 << 10) -#define DRAM_CTRL_BLOCK_WRITE_PRECHARGE (1 << 9) -#define DRAM_CTRL_ACTIVE_PRECHARGE (1 << 8) -#define DRAM_CTRL_RESET (1 << 7) -#define DRAM_CTRL_REMAIN_ACTIVE (1 << 6) -#define DRAM_CTRL_BANKS (1 << 1) -#define DRAM_CTRL_WRITE_PRECHARGE (1 << 0) - -/* ----- Arvitration control register -------------------------- */ -#define ARBITRATION_CTRL (0x000014 + VOYAGER_BASE) -#define ARBITRATION_CTRL_CPUMEM (1 << 29) -#define ARBITRATION_CTRL_INTMEM (1 << 28) -#define ARBITRATION_CTRL_USB_OFF (0 << 24) -#define ARBITRATION_CTRL_USB_PRIORITY_1 (1 << 24) -#define ARBITRATION_CTRL_USB_PRIORITY_2 (2 << 24) -#define ARBITRATION_CTRL_USB_PRIORITY_3 (3 << 24) -#define ARBITRATION_CTRL_USB_PRIORITY_4 (4 << 24) -#define ARBITRATION_CTRL_USB_PRIORITY_5 (5 << 24) -#define ARBITRATION_CTRL_USB_PRIORITY_6 (6 << 24) -#define ARBITRATION_CTRL_USB_PRIORITY_7 (7 << 24) -#define ARBITRATION_CTRL_PANEL_OFF (0 << 20) -#define ARBITRATION_CTRL_PANEL_PRIORITY_1 (1 << 20) -#define ARBITRATION_CTRL_PANEL_PRIORITY_2 (2 << 20) -#define ARBITRATION_CTRL_PANEL_PRIORITY_3 (3 << 20) -#define ARBITRATION_CTRL_PANEL_PRIORITY_4 (4 << 20) -#define ARBITRATION_CTRL_PANEL_PRIORITY_5 (5 << 20) -#define ARBITRATION_CTRL_PANEL_PRIORITY_6 (6 << 20) -#define ARBITRATION_CTRL_PANEL_PRIORITY_7 (7 << 20) -#define ARBITRATION_CTRL_ZVPORT_OFF (0 << 16) -#define ARBITRATION_CTRL_ZVPORTL_PRIORITY_1 (1 << 16) -#define ARBITRATION_CTRL_ZVPORTL_PRIORITY_2 (2 << 16) -#define ARBITRATION_CTRL_ZVPORTL_PRIORITY_3 (3 << 16) -#define ARBITRATION_CTRL_ZVPORTL_PRIORITY_4 (4 << 16) -#define ARBITRATION_CTRL_ZVPORTL_PRIORITY_5 (5 << 16) -#define ARBITRATION_CTRL_ZVPORTL_PRIORITY_6 (6 << 16) -#define ARBITRATION_CTRL_ZVPORTL_PRIORITY_7 (7 << 16) -#define ARBITRATION_CTRL_CMD_INTPR_OFF (0 << 12) -#define ARBITRATION_CTRL_CMD_INTPR_PRIORITY_1 (1 << 12) -#define ARBITRATION_CTRL_CMD_INTPR_PRIORITY_2 (2 << 12) -#define ARBITRATION_CTRL_CMD_INTPR_PRIORITY_3 (3 << 12) -#define ARBITRATION_CTRL_CMD_INTPR_PRIORITY_4 (4 << 12) -#define ARBITRATION_CTRL_CMD_INTPR_PRIORITY_5 (5 << 12) -#define ARBITRATION_CTRL_CMD_INTPR_PRIORITY_6 (6 << 12) -#define ARBITRATION_CTRL_CMD_INTPR_PRIORITY_7 (7 << 12) -#define ARBITRATION_CTRL_DMA_OFF (0 << 8) -#define ARBITRATION_CTRL_DMA_PRIORITY_1 (1 << 8) -#define ARBITRATION_CTRL_DMA_PRIORITY_2 (2 << 8) -#define ARBITRATION_CTRL_DMA_PRIORITY_3 (3 << 8) -#define ARBITRATION_CTRL_DMA_PRIORITY_4 (4 << 8) -#define ARBITRATION_CTRL_DMA_PRIORITY_5 (5 << 8) -#define ARBITRATION_CTRL_DMA_PRIORITY_6 (6 << 8) -#define ARBITRATION_CTRL_DMA_PRIORITY_7 (7 << 8) -#define ARBITRATION_CTRL_VIDEO_OFF (0 << 4) -#define ARBITRATION_CTRL_VIDEO_PRIORITY_1 (1 << 4) -#define ARBITRATION_CTRL_VIDEO_PRIORITY_2 (2 << 4) -#define ARBITRATION_CTRL_VIDEO_PRIORITY_3 (3 << 4) -#define ARBITRATION_CTRL_VIDEO_PRIORITY_4 (4 << 4) -#define ARBITRATION_CTRL_VIDEO_PRIORITY_5 (5 << 4) -#define ARBITRATION_CTRL_VIDEO_PRIORITY_6 (6 << 4) -#define ARBITRATION_CTRL_VIDEO_PRIORITY_7 (7 << 4) -#define ARBITRATION_CTRL_CRT_OFF (0 << 0) -#define ARBITRATION_CTRL_CRT_PRIORITY_1 (1 << 0) -#define ARBITRATION_CTRL_CRT_PRIORITY_2 (2 << 0) -#define ARBITRATION_CTRL_CRT_PRIORITY_3 (3 << 0) -#define ARBITRATION_CTRL_CRT_PRIORITY_4 (4 << 0) -#define ARBITRATION_CTRL_CRT_PRIORITY_5 (5 << 0) -#define ARBITRATION_CTRL_CRT_PRIORITY_6 (6 << 0) -#define ARBITRATION_CTRL_CRT_PRIORITY_7 (7 << 0) - -/* ----- Command list status register -------------------------- */ -#define CMD_INTPR_STATUS (0x000024 + VOYAGER_BASE) - -/* ----- Interrupt status register ----------------------------- */ -#define INT_STATUS (0x00002c + VOYAGER_BASE) -#define INT_STATUS_UH (1 << 6) -#define INT_STATUS_MC (1 << 10) -#define INT_STATUS_U0 (1 << 12) -#define INT_STATUS_U1 (1 << 13) -#define INT_STATUS_AC (1 << 17) - -/* ----- Interrupt mask register ------------------------------ */ -#define VOYAGER_INT_MASK (0x000030 + VOYAGER_BASE) -#define VOYAGER_INT_MASK_AC (1 << 17) - -/* ----- Current Gate register ---------------------------------*/ -#define CURRENT_GATE (0x000038 + VOYAGER_BASE) - -/* ----- Power mode 0 gate register --------------------------- */ -#define POWER_MODE0_GATE (0x000040 + VOYAGER_BASE) -#define POWER_MODE0_GATE_G (1 << 6) -#define POWER_MODE0_GATE_U0 (1 << 7) -#define POWER_MODE0_GATE_U1 (1 << 8) -#define POWER_MODE0_GATE_UH (1 << 11) -#define POWER_MODE0_GATE_AC (1 << 18) - -/* ----- Power mode 1 gate register --------------------------- */ -#define POWER_MODE1_GATE (0x000048 + VOYAGER_BASE) -#define POWER_MODE1_GATE_G (1 << 6) -#define POWER_MODE1_GATE_U0 (1 << 7) -#define POWER_MODE1_GATE_U1 (1 << 8) -#define POWER_MODE1_GATE_UH (1 << 11) -#define POWER_MODE1_GATE_AC (1 << 18) - -/* ----- Power mode 0 clock register -------------------------- */ -#define POWER_MODE0_CLOCK (0x000044 + VOYAGER_BASE) - -/* ----- Power mode 1 clock register -------------------------- */ -#define POWER_MODE1_CLOCK (0x00004C + VOYAGER_BASE) - -/* ----- Power mode controll register ------------------------- */ -#define POWER_MODE_CTRL (0x000054 + VOYAGER_BASE) - -/* ----- Miscellaneous Timing register ------------------------ */ -#define SYSTEM_DRAM_CTRL (0x000068 + VOYAGER_BASE) - -/* ----- PWM register ------------------------------------------*/ -#define PWM_0 (0x010020 + VOYAGER_BASE) -#define PWM_0_HC(x) (((x)&0x0fff)<<20) -#define PWM_0_LC(x) (((x)&0x0fff)<<8 ) -#define PWM_0_CLK_DEV(x) (((x)&0x000f)<<4 ) -#define PWM_0_EN (1<<0) - -/* ----- I2C register ----------------------------------------- */ -#define I2C_BYTECOUNT (0x010040 + VOYAGER_BASE) -#define I2C_CONTROL (0x010041 + VOYAGER_BASE) -#define I2C_STATUS (0x010042 + VOYAGER_BASE) -#define I2C_RESET (0x010042 + VOYAGER_BASE) -#define I2C_SADDRESS (0x010043 + VOYAGER_BASE) -#define I2C_DATA (0x010044 + VOYAGER_BASE) - -/* ----- Controle register bits ----------------------------------------- */ -#define I2C_CONTROL_E (1 << 0) -#define I2C_CONTROL_MODE (1 << 1) -#define I2C_CONTROL_STATUS (1 << 2) -#define I2C_CONTROL_INT (1 << 4) -#define I2C_CONTROL_INTACK (1 << 5) -#define I2C_CONTROL_REPEAT (1 << 6) - -/* ----- Status register bits ----------------------------------------- */ -#define I2C_STATUS_BUSY (1 << 0) -#define I2C_STATUS_ACK (1 << 1) -#define I2C_STATUS_ERROR (1 << 2) -#define I2C_STATUS_COMPLETE (1 << 3) - -/* ----- Reset register ---------------------------------------------- */ -#define I2C_RESET_ERROR (1 << 2) - -/* ----- transmission frequencies ------------------------------------- */ -#define I2C_SADDRESS_SELECT (1 << 0) - -/* ----- Display Controll register ----------------------------------------- */ -#define PANEL_DISPLAY_CTRL (0x080000 + VOYAGER_BASE) -#define PANEL_DISPLAY_CTRL_BIAS (1<<26) -#define PANEL_PAN_CTRL (0x080004 + VOYAGER_BASE) -#define PANEL_COLOR_KEY (0x080008 + VOYAGER_BASE) -#define PANEL_FB_ADDRESS (0x08000C + VOYAGER_BASE) -#define PANEL_FB_WIDTH (0x080010 + VOYAGER_BASE) -#define PANEL_WINDOW_WIDTH (0x080014 + VOYAGER_BASE) -#define PANEL_WINDOW_HEIGHT (0x080018 + VOYAGER_BASE) -#define PANEL_PLANE_TL (0x08001C + VOYAGER_BASE) -#define PANEL_PLANE_BR (0x080020 + VOYAGER_BASE) -#define PANEL_HORIZONTAL_TOTAL (0x080024 + VOYAGER_BASE) -#define PANEL_HORIZONTAL_SYNC (0x080028 + VOYAGER_BASE) -#define PANEL_VERTICAL_TOTAL (0x08002C + VOYAGER_BASE) -#define PANEL_VERTICAL_SYNC (0x080030 + VOYAGER_BASE) -#define PANEL_CURRENT_LINE (0x080034 + VOYAGER_BASE) -#define VIDEO_DISPLAY_CTRL (0x080040 + VOYAGER_BASE) -#define VIDEO_FB_0_ADDRESS (0x080044 + VOYAGER_BASE) -#define VIDEO_FB_WIDTH (0x080048 + VOYAGER_BASE) -#define VIDEO_FB_0_LAST_ADDRESS (0x08004C + VOYAGER_BASE) -#define VIDEO_PLANE_TL (0x080050 + VOYAGER_BASE) -#define VIDEO_PLANE_BR (0x080054 + VOYAGER_BASE) -#define VIDEO_SCALE (0x080058 + VOYAGER_BASE) -#define VIDEO_INITIAL_SCALE (0x08005C + VOYAGER_BASE) -#define VIDEO_YUV_CONSTANTS (0x080060 + VOYAGER_BASE) -#define VIDEO_FB_1_ADDRESS (0x080064 + VOYAGER_BASE) -#define VIDEO_FB_1_LAST_ADDRESS (0x080068 + VOYAGER_BASE) -#define VIDEO_ALPHA_DISPLAY_CTRL (0x080080 + VOYAGER_BASE) -#define VIDEO_ALPHA_FB_ADDRESS (0x080084 + VOYAGER_BASE) -#define VIDEO_ALPHA_FB_WIDTH (0x080088 + VOYAGER_BASE) -#define VIDEO_ALPHA_FB_LAST_ADDRESS (0x08008C + VOYAGER_BASE) -#define VIDEO_ALPHA_PLANE_TL (0x080090 + VOYAGER_BASE) -#define VIDEO_ALPHA_PLANE_BR (0x080094 + VOYAGER_BASE) -#define VIDEO_ALPHA_SCALE (0x080098 + VOYAGER_BASE) -#define VIDEO_ALPHA_INITIAL_SCALE (0x08009C + VOYAGER_BASE) -#define VIDEO_ALPHA_CHROMA_KEY (0x0800A0 + VOYAGER_BASE) -#define PANEL_HWC_ADDRESS (0x0800F0 + VOYAGER_BASE) -#define PANEL_HWC_LOCATION (0x0800F4 + VOYAGER_BASE) -#define PANEL_HWC_COLOR_12 (0x0800F8 + VOYAGER_BASE) -#define PANEL_HWC_COLOR_3 (0x0800FC + VOYAGER_BASE) -#define ALPHA_DISPLAY_CTRL (0x080100 + VOYAGER_BASE) -#define ALPHA_FB_ADDRESS (0x080104 + VOYAGER_BASE) -#define ALPHA_FB_WIDTH (0x080108 + VOYAGER_BASE) -#define ALPHA_PLANE_TL (0x08010C + VOYAGER_BASE) -#define ALPHA_PLANE_BR (0x080110 + VOYAGER_BASE) -#define ALPHA_CHROMA_KEY (0x080114 + VOYAGER_BASE) -#define CRT_DISPLAY_CTRL (0x080200 + VOYAGER_BASE) -#define CRT_FB_ADDRESS (0x080204 + VOYAGER_BASE) -#define CRT_FB_WIDTH (0x080208 + VOYAGER_BASE) -#define CRT_HORIZONTAL_TOTAL (0x08020C + VOYAGER_BASE) -#define CRT_HORIZONTAL_SYNC (0x080210 + VOYAGER_BASE) -#define CRT_VERTICAL_TOTAL (0x080214 + VOYAGER_BASE) -#define CRT_VERTICAL_SYNC (0x080218 + VOYAGER_BASE) -#define CRT_SIGNATURE_ANALYZER (0x08021C + VOYAGER_BASE) -#define CRT_CURRENT_LINE (0x080220 + VOYAGER_BASE) -#define CRT_MONITOR_DETECT (0x080224 + VOYAGER_BASE) -#define CRT_HWC_ADDRESS (0x080230 + VOYAGER_BASE) -#define CRT_HWC_LOCATION (0x080234 + VOYAGER_BASE) -#define CRT_HWC_COLOR_12 (0x080238 + VOYAGER_BASE) -#define CRT_HWC_COLOR_3 (0x08023C + VOYAGER_BASE) -#define CRT_PALETTE_RAM (0x080400 + VOYAGER_BASE) -#define PANEL_PALETTE_RAM (0x080800 + VOYAGER_BASE) -#define VIDEO_PALETTE_RAM (0x080C00 + VOYAGER_BASE) - -/* ----- 8051 Controle register ----------------------------------------- */ -#define VOYAGER_8051_BASE (0x000c0000 + VOYAGER_BASE) -#define VOYAGER_8051_RESET (0x000b0000 + VOYAGER_BASE) -#define VOYAGER_8051_SELECT (0x000b0004 + VOYAGER_BASE) -#define VOYAGER_8051_CPU_INT (0x000b000c + VOYAGER_BASE) - -/* ----- AC97 Controle register ----------------------------------------- */ -#define AC97_TX_SLOT0 (0x00000000 + VOYAGER_AC97_BASE) -#define AC97_CONTROL_STATUS (0x00000080 + VOYAGER_AC97_BASE) -#define AC97C_READ (1 << 19) -#define AC97C_WD_BIT (1 << 2) -#define AC97C_INDEX_MASK 0x7f - -/* arch/sh/cchips/voyagergx/consistent.c */ -void *voyagergx_consistent_alloc(struct device *, size_t, dma_addr_t *, gfp_t); -int voyagergx_consistent_free(struct device *, size_t, void *, dma_addr_t); - -/* arch/sh/cchips/voyagergx/irq.c */ -void setup_voyagergx_irq(void); - -#endif /* _VOYAGER_GX_REG_H */ |