diff options
Diffstat (limited to 'include/asm-powerpc')
53 files changed, 3299 insertions, 179 deletions
diff --git a/include/asm-powerpc/abs_addr.h b/include/asm-powerpc/abs_addr.h new file mode 100644 index 000000000000..18415108fc56 --- /dev/null +++ b/include/asm-powerpc/abs_addr.h @@ -0,0 +1,73 @@ +#ifndef _ASM_POWERPC_ABS_ADDR_H +#define _ASM_POWERPC_ABS_ADDR_H + +#include <linux/config.h> + +/* + * c 2001 PPC 64 Team, IBM Corp + * + * 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. + */ + +#include <asm/types.h> +#include <asm/page.h> +#include <asm/prom.h> +#include <asm/lmb.h> +#include <asm/firmware.h> + +struct mschunks_map { + unsigned long num_chunks; + unsigned long chunk_size; + unsigned long chunk_shift; + unsigned long chunk_mask; + u32 *mapping; +}; + +extern struct mschunks_map mschunks_map; + +/* Chunks are 256 KB */ +#define MSCHUNKS_CHUNK_SHIFT (18) +#define MSCHUNKS_CHUNK_SIZE (1UL << MSCHUNKS_CHUNK_SHIFT) +#define MSCHUNKS_OFFSET_MASK (MSCHUNKS_CHUNK_SIZE - 1) + +static inline unsigned long chunk_to_addr(unsigned long chunk) +{ + return chunk << MSCHUNKS_CHUNK_SHIFT; +} + +static inline unsigned long addr_to_chunk(unsigned long addr) +{ + return addr >> MSCHUNKS_CHUNK_SHIFT; +} + +static inline unsigned long phys_to_abs(unsigned long pa) +{ + unsigned long chunk; + + /* This is a no-op on non-iSeries */ + if (!firmware_has_feature(FW_FEATURE_ISERIES)) + return pa; + + chunk = addr_to_chunk(pa); + + if (chunk < mschunks_map.num_chunks) + chunk = mschunks_map.mapping[chunk]; + + return chunk_to_addr(chunk) + (pa & MSCHUNKS_OFFSET_MASK); +} + +/* Convenience macros */ +#define virt_to_abs(va) phys_to_abs(__pa(va)) +#define abs_to_virt(aa) __va(aa) + +/* + * Converts Virtual Address to Real Address for + * Legacy iSeries Hypervisor calls + */ +#define iseries_hv_addr(virtaddr) \ + (0x8000000000000000 | virt_to_abs(virtaddr)) + +#endif /* _ASM_POWERPC_ABS_ADDR_H */ diff --git a/include/asm-powerpc/asm-compat.h b/include/asm-powerpc/asm-compat.h new file mode 100644 index 000000000000..8b133efc9f79 --- /dev/null +++ b/include/asm-powerpc/asm-compat.h @@ -0,0 +1,55 @@ +#ifndef _ASM_POWERPC_ASM_COMPAT_H +#define _ASM_POWERPC_ASM_COMPAT_H + +#include <linux/config.h> +#include <asm/types.h> + +#ifdef __ASSEMBLY__ +# define stringify_in_c(...) __VA_ARGS__ +# define ASM_CONST(x) x +#else +/* This version of stringify will deal with commas... */ +# define __stringify_in_c(...) #__VA_ARGS__ +# define stringify_in_c(...) __stringify_in_c(__VA_ARGS__) " " +# define __ASM_CONST(x) x##UL +# define ASM_CONST(x) __ASM_CONST(x) +#endif + +#ifdef __powerpc64__ + +/* operations for longs and pointers */ +#define PPC_LL stringify_in_c(ld) +#define PPC_STL stringify_in_c(std) +#define PPC_LCMPI stringify_in_c(cmpdi) +#define PPC_LONG stringify_in_c(.llong) +#define PPC_TLNEI stringify_in_c(tdnei) +#define PPC_LLARX stringify_in_c(ldarx) +#define PPC_STLCX stringify_in_c(stdcx.) +#define PPC_CNTLZL stringify_in_c(cntlzd) + +#else /* 32-bit */ + +/* operations for longs and pointers */ +#define PPC_LL stringify_in_c(lwz) +#define PPC_STL stringify_in_c(stw) +#define PPC_LCMPI stringify_in_c(cmpwi) +#define PPC_LONG stringify_in_c(.long) +#define PPC_TLNEI stringify_in_c(twnei) +#define PPC_LLARX stringify_in_c(lwarx) +#define PPC_STLCX stringify_in_c(stwcx.) +#define PPC_CNTLZL stringify_in_c(cntlzw) + +#endif + +#ifdef CONFIG_IBM405_ERR77 +/* Erratum #77 on the 405 means we need a sync or dcbt before every + * stwcx. The old ATOMIC_SYNC_FIX covered some but not all of this. + */ +#define PPC405_ERR77(ra,rb) stringify_in_c(dcbt ra, rb;) +#define PPC405_ERR77_SYNC stringify_in_c(sync;) +#else +#define PPC405_ERR77(ra,rb) +#define PPC405_ERR77_SYNC +#endif + +#endif /* _ASM_POWERPC_ASM_COMPAT_H */ diff --git a/include/asm-powerpc/atomic.h b/include/asm-powerpc/atomic.h index ed4b345ed75d..ec4b14468959 100644 --- a/include/asm-powerpc/atomic.h +++ b/include/asm-powerpc/atomic.h @@ -9,21 +9,13 @@ typedef struct { volatile int counter; } atomic_t; #ifdef __KERNEL__ #include <asm/synch.h> +#include <asm/asm-compat.h> #define ATOMIC_INIT(i) { (i) } #define atomic_read(v) ((v)->counter) #define atomic_set(v,i) (((v)->counter) = (i)) -/* Erratum #77 on the 405 means we need a sync or dcbt before every stwcx. - * The old ATOMIC_SYNC_FIX covered some but not all of this. - */ -#ifdef CONFIG_IBM405_ERR77 -#define PPC405_ERR77(ra,rb) "dcbt " #ra "," #rb ";" -#else -#define PPC405_ERR77(ra,rb) -#endif - static __inline__ void atomic_add(int a, atomic_t *v) { int t; @@ -172,6 +164,33 @@ static __inline__ int atomic_dec_return(atomic_t *v) return t; } +#define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n))) + +/** + * atomic_add_unless - add unless the number is a given value + * @v: pointer of type atomic_t + * @a: the amount to add to v... + * @u: ...unless v is equal to u. + * + * Atomically adds @a to @v, so long as it was not @u. + * Returns non-zero if @v was not @u, and zero otherwise. + */ +#define atomic_add_unless(v, a, u) \ +({ \ + int c, old; \ + c = atomic_read(v); \ + for (;;) { \ + if (unlikely(c == (u))) \ + break; \ + old = atomic_cmpxchg((v), c, c + (a)); \ + if (likely(old == c)) \ + break; \ + c = old; \ + } \ + c != (u); \ +}) +#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0) + #define atomic_sub_and_test(a, v) (atomic_sub_return((a), (v)) == 0) #define atomic_dec_and_test(v) (atomic_dec_return((v)) == 0) @@ -205,5 +224,183 @@ static __inline__ int atomic_dec_if_positive(atomic_t *v) #define smp_mb__before_atomic_inc() smp_mb() #define smp_mb__after_atomic_inc() smp_mb() +#ifdef __powerpc64__ + +typedef struct { volatile long counter; } atomic64_t; + +#define ATOMIC64_INIT(i) { (i) } + +#define atomic64_read(v) ((v)->counter) +#define atomic64_set(v,i) (((v)->counter) = (i)) + +static __inline__ void atomic64_add(long a, atomic64_t *v) +{ + long t; + + __asm__ __volatile__( +"1: ldarx %0,0,%3 # atomic64_add\n\ + add %0,%2,%0\n\ + stdcx. %0,0,%3 \n\ + bne- 1b" + : "=&r" (t), "=m" (v->counter) + : "r" (a), "r" (&v->counter), "m" (v->counter) + : "cc"); +} + +static __inline__ long atomic64_add_return(long a, atomic64_t *v) +{ + long t; + + __asm__ __volatile__( + EIEIO_ON_SMP +"1: ldarx %0,0,%2 # atomic64_add_return\n\ + add %0,%1,%0\n\ + stdcx. %0,0,%2 \n\ + bne- 1b" + ISYNC_ON_SMP + : "=&r" (t) + : "r" (a), "r" (&v->counter) + : "cc", "memory"); + + return t; +} + +#define atomic64_add_negative(a, v) (atomic64_add_return((a), (v)) < 0) + +static __inline__ void atomic64_sub(long a, atomic64_t *v) +{ + long t; + + __asm__ __volatile__( +"1: ldarx %0,0,%3 # atomic64_sub\n\ + subf %0,%2,%0\n\ + stdcx. %0,0,%3 \n\ + bne- 1b" + : "=&r" (t), "=m" (v->counter) + : "r" (a), "r" (&v->counter), "m" (v->counter) + : "cc"); +} + +static __inline__ long atomic64_sub_return(long a, atomic64_t *v) +{ + long t; + + __asm__ __volatile__( + EIEIO_ON_SMP +"1: ldarx %0,0,%2 # atomic64_sub_return\n\ + subf %0,%1,%0\n\ + stdcx. %0,0,%2 \n\ + bne- 1b" + ISYNC_ON_SMP + : "=&r" (t) + : "r" (a), "r" (&v->counter) + : "cc", "memory"); + + return t; +} + +static __inline__ void atomic64_inc(atomic64_t *v) +{ + long t; + + __asm__ __volatile__( +"1: ldarx %0,0,%2 # atomic64_inc\n\ + addic %0,%0,1\n\ + stdcx. %0,0,%2 \n\ + bne- 1b" + : "=&r" (t), "=m" (v->counter) + : "r" (&v->counter), "m" (v->counter) + : "cc"); +} + +static __inline__ long atomic64_inc_return(atomic64_t *v) +{ + long t; + + __asm__ __volatile__( + EIEIO_ON_SMP +"1: ldarx %0,0,%1 # atomic64_inc_return\n\ + addic %0,%0,1\n\ + stdcx. %0,0,%1 \n\ + bne- 1b" + ISYNC_ON_SMP + : "=&r" (t) + : "r" (&v->counter) + : "cc", "memory"); + + return t; +} + +/* + * atomic64_inc_and_test - increment and test + * @v: pointer of type atomic64_t + * + * Atomically increments @v by 1 + * and returns true if the result is zero, or false for all + * other cases. + */ +#define atomic64_inc_and_test(v) (atomic64_inc_return(v) == 0) + +static __inline__ void atomic64_dec(atomic64_t *v) +{ + long t; + + __asm__ __volatile__( +"1: ldarx %0,0,%2 # atomic64_dec\n\ + addic %0,%0,-1\n\ + stdcx. %0,0,%2\n\ + bne- 1b" + : "=&r" (t), "=m" (v->counter) + : "r" (&v->counter), "m" (v->counter) + : "cc"); +} + +static __inline__ long atomic64_dec_return(atomic64_t *v) +{ + long t; + + __asm__ __volatile__( + EIEIO_ON_SMP +"1: ldarx %0,0,%1 # atomic64_dec_return\n\ + addic %0,%0,-1\n\ + stdcx. %0,0,%1\n\ + bne- 1b" + ISYNC_ON_SMP + : "=&r" (t) + : "r" (&v->counter) + : "cc", "memory"); + + return t; +} + +#define atomic64_sub_and_test(a, v) (atomic64_sub_return((a), (v)) == 0) +#define atomic64_dec_and_test(v) (atomic64_dec_return((v)) == 0) + +/* + * Atomically test *v and decrement if it is greater than 0. + * The function returns the old value of *v minus 1. + */ +static __inline__ long atomic64_dec_if_positive(atomic64_t *v) +{ + long t; + + __asm__ __volatile__( + EIEIO_ON_SMP +"1: ldarx %0,0,%1 # atomic64_dec_if_positive\n\ + addic. %0,%0,-1\n\ + blt- 2f\n\ + stdcx. %0,0,%1\n\ + bne- 1b" + ISYNC_ON_SMP + "\n\ +2:" : "=&r" (t) + : "r" (&v->counter) + : "cc", "memory"); + + return t; +} + +#endif /* __powerpc64__ */ + #endif /* __KERNEL__ */ #endif /* _ASM_POWERPC_ATOMIC_H_ */ diff --git a/include/asm-powerpc/auxvec.h b/include/asm-powerpc/auxvec.h index 79d8c4732309..19a099b62cd6 100644 --- a/include/asm-powerpc/auxvec.h +++ b/include/asm-powerpc/auxvec.h @@ -14,8 +14,6 @@ /* The vDSO location. We have to use the same value as x86 for glibc's * sake :-) */ -#ifdef __powerpc64__ #define AT_SYSINFO_EHDR 33 -#endif #endif diff --git a/include/asm-powerpc/bitops.h b/include/asm-powerpc/bitops.h index dc25c53704d5..5727229b0444 100644 --- a/include/asm-powerpc/bitops.h +++ b/include/asm-powerpc/bitops.h @@ -40,6 +40,7 @@ #include <linux/compiler.h> #include <asm/atomic.h> +#include <asm/asm-compat.h> #include <asm/synch.h> /* @@ -52,16 +53,6 @@ #define BITOP_WORD(nr) ((nr) / BITS_PER_LONG) #define BITOP_LE_SWIZZLE ((BITS_PER_LONG-1) & ~0x7) -#ifdef CONFIG_PPC64 -#define LARXL "ldarx" -#define STCXL "stdcx." -#define CNTLZL "cntlzd" -#else -#define LARXL "lwarx" -#define STCXL "stwcx." -#define CNTLZL "cntlzw" -#endif - static __inline__ void set_bit(int nr, volatile unsigned long *addr) { unsigned long old; @@ -69,10 +60,10 @@ static __inline__ void set_bit(int nr, volatile unsigned long *addr) unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr); __asm__ __volatile__( -"1:" LARXL " %0,0,%3 # set_bit\n" +"1:" PPC_LLARX "%0,0,%3 # set_bit\n" "or %0,%0,%2\n" PPC405_ERR77(0,%3) - STCXL " %0,0,%3\n" + PPC_STLCX "%0,0,%3\n" "bne- 1b" : "=&r"(old), "=m"(*p) : "r"(mask), "r"(p), "m"(*p) @@ -86,10 +77,10 @@ static __inline__ void clear_bit(int nr, volatile unsigned long *addr) unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr); __asm__ __volatile__( -"1:" LARXL " %0,0,%3 # set_bit\n" +"1:" PPC_LLARX "%0,0,%3 # clear_bit\n" "andc %0,%0,%2\n" PPC405_ERR77(0,%3) - STCXL " %0,0,%3\n" + PPC_STLCX "%0,0,%3\n" "bne- 1b" : "=&r"(old), "=m"(*p) : "r"(mask), "r"(p), "m"(*p) @@ -103,10 +94,10 @@ static __inline__ void change_bit(int nr, volatile unsigned long *addr) unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr); __asm__ __volatile__( -"1:" LARXL " %0,0,%3 # set_bit\n" +"1:" PPC_LLARX "%0,0,%3 # change_bit\n" "xor %0,%0,%2\n" PPC405_ERR77(0,%3) - STCXL " %0,0,%3\n" + PPC_STLCX "%0,0,%3\n" "bne- 1b" : "=&r"(old), "=m"(*p) : "r"(mask), "r"(p), "m"(*p) @@ -122,10 +113,10 @@ static __inline__ int test_and_set_bit(unsigned long nr, __asm__ __volatile__( EIEIO_ON_SMP -"1:" LARXL " %0,0,%3 # test_and_set_bit\n" +"1:" PPC_LLARX "%0,0,%3 # test_and_set_bit\n" "or %1,%0,%2 \n" PPC405_ERR77(0,%3) - STCXL " %1,0,%3 \n" + PPC_STLCX "%1,0,%3 \n" "bne- 1b" ISYNC_ON_SMP : "=&r" (old), "=&r" (t) @@ -144,10 +135,10 @@ static __inline__ int test_and_clear_bit(unsigned long nr, __asm__ __volatile__( EIEIO_ON_SMP -"1:" LARXL " %0,0,%3 # test_and_clear_bit\n" +"1:" PPC_LLARX "%0,0,%3 # test_and_clear_bit\n" "andc %1,%0,%2 \n" PPC405_ERR77(0,%3) - STCXL " %1,0,%3 \n" + PPC_STLCX "%1,0,%3 \n" "bne- 1b" ISYNC_ON_SMP : "=&r" (old), "=&r" (t) @@ -166,10 +157,10 @@ static __inline__ int test_and_change_bit(unsigned long nr, __asm__ __volatile__( EIEIO_ON_SMP -"1:" LARXL " %0,0,%3 # test_and_change_bit\n" +"1:" PPC_LLARX "%0,0,%3 # test_and_change_bit\n" "xor %1,%0,%2 \n" PPC405_ERR77(0,%3) - STCXL " %1,0,%3 \n" + PPC_STLCX "%1,0,%3 \n" "bne- 1b" ISYNC_ON_SMP : "=&r" (old), "=&r" (t) @@ -184,9 +175,9 @@ static __inline__ void set_bits(unsigned long mask, unsigned long *addr) unsigned long old; __asm__ __volatile__( -"1:" LARXL " %0,0,%3 # set_bit\n" +"1:" PPC_LLARX "%0,0,%3 # set_bits\n" "or %0,%0,%2\n" - STCXL " %0,0,%3\n" + PPC_STLCX "%0,0,%3\n" "bne- 1b" : "=&r" (old), "=m" (*addr) : "r" (mask), "r" (addr), "m" (*addr) @@ -268,7 +259,7 @@ static __inline__ int __ilog2(unsigned long x) { int lz; - asm (CNTLZL " %0,%1" : "=r" (lz) : "r" (x)); + asm (PPC_CNTLZL "%0,%1" : "=r" (lz) : "r" (x)); return BITS_PER_LONG - 1 - lz; } diff --git a/include/asm-powerpc/btext.h b/include/asm-powerpc/btext.h new file mode 100644 index 000000000000..71cce36bc630 --- /dev/null +++ b/include/asm-powerpc/btext.h @@ -0,0 +1,27 @@ +/* + * Definitions for using the procedures in btext.c. + * + * Benjamin Herrenschmidt <benh@kernel.crashing.org> + */ +#ifndef __PPC_BTEXT_H +#define __PPC_BTEXT_H +#ifdef __KERNEL__ + +extern void btext_clearscreen(void); +extern void btext_flushscreen(void); + +extern int boot_text_mapped; + +extern int btext_initialize(struct device_node *np); + +extern void map_boot_text(void); +extern void init_boot_display(void); +extern void btext_update_display(unsigned long phys, int width, int height, + int depth, int pitch); + +extern void btext_drawchar(char c); +extern void btext_drawstring(const char *str); +extern void btext_drawhex(unsigned long v); + +#endif /* __KERNEL__ */ +#endif /* __PPC_BTEXT_H */ diff --git a/include/asm-powerpc/bug.h b/include/asm-powerpc/bug.h index d625ee55f957..b001ecb3cd99 100644 --- a/include/asm-powerpc/bug.h +++ b/include/asm-powerpc/bug.h @@ -1,6 +1,7 @@ #ifndef _ASM_POWERPC_BUG_H #define _ASM_POWERPC_BUG_H +#include <asm/asm-compat.h> /* * Define an illegal instr to trap on the bug. * We don't use 0 because that marks the end of a function @@ -11,14 +12,6 @@ #ifndef __ASSEMBLY__ -#ifdef __powerpc64__ -#define BUG_TABLE_ENTRY ".llong" -#define BUG_TRAP_OP "tdnei" -#else -#define BUG_TABLE_ENTRY ".long" -#define BUG_TRAP_OP "twnei" -#endif /* __powerpc64__ */ - struct bug_entry { unsigned long bug_addr; long line; @@ -40,16 +33,16 @@ struct bug_entry *find_bug(unsigned long bugaddr); __asm__ __volatile__( \ "1: twi 31,0,0\n" \ ".section __bug_table,\"a\"\n" \ - "\t"BUG_TABLE_ENTRY" 1b,%0,%1,%2\n" \ + "\t"PPC_LONG" 1b,%0,%1,%2\n" \ ".previous" \ : : "i" (__LINE__), "i" (__FILE__), "i" (__FUNCTION__)); \ } while (0) #define BUG_ON(x) do { \ __asm__ __volatile__( \ - "1: "BUG_TRAP_OP" %0,0\n" \ + "1: "PPC_TLNEI" %0,0\n" \ ".section __bug_table,\"a\"\n" \ - "\t"BUG_TABLE_ENTRY" 1b,%1,%2,%3\n" \ + "\t"PPC_LONG" 1b,%1,%2,%3\n" \ ".previous" \ : : "r" ((long)(x)), "i" (__LINE__), \ "i" (__FILE__), "i" (__FUNCTION__)); \ @@ -57,9 +50,9 @@ struct bug_entry *find_bug(unsigned long bugaddr); #define WARN_ON(x) do { \ __asm__ __volatile__( \ - "1: "BUG_TRAP_OP" %0,0\n" \ + "1: "PPC_TLNEI" %0,0\n" \ ".section __bug_table,\"a\"\n" \ - "\t"BUG_TABLE_ENTRY" 1b,%1,%2,%3\n" \ + "\t"PPC_LONG" 1b,%1,%2,%3\n" \ ".previous" \ : : "r" ((long)(x)), \ "i" (__LINE__ + BUG_WARNING_TRAP), \ diff --git a/include/asm-powerpc/cache.h b/include/asm-powerpc/cache.h new file mode 100644 index 000000000000..26ce502e76e8 --- /dev/null +++ b/include/asm-powerpc/cache.h @@ -0,0 +1,40 @@ +#ifndef _ASM_POWERPC_CACHE_H +#define _ASM_POWERPC_CACHE_H + +#ifdef __KERNEL__ + +#include <linux/config.h> + +/* bytes per L1 cache line */ +#if defined(CONFIG_8xx) || defined(CONFIG_403GCX) +#define L1_CACHE_SHIFT 4 +#define MAX_COPY_PREFETCH 1 +#elif defined(CONFIG_PPC32) +#define L1_CACHE_SHIFT 5 +#define MAX_COPY_PREFETCH 4 +#else /* CONFIG_PPC64 */ +#define L1_CACHE_SHIFT 7 +#endif + +#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT) + +#define SMP_CACHE_BYTES L1_CACHE_BYTES +#define L1_CACHE_SHIFT_MAX 7 /* largest L1 which this arch supports */ + +#if defined(__powerpc64__) && !defined(__ASSEMBLY__) +struct ppc64_caches { + u32 dsize; /* L1 d-cache size */ + u32 dline_size; /* L1 d-cache line size */ + u32 log_dline_size; + u32 dlines_per_page; + u32 isize; /* L1 i-cache size */ + u32 iline_size; /* L1 i-cache line size */ + u32 log_iline_size; + u32 ilines_per_page; +}; + +extern struct ppc64_caches ppc64_caches; +#endif /* __powerpc64__ && ! __ASSEMBLY__ */ + +#endif /* __KERNEL__ */ +#endif /* _ASM_POWERPC_CACHE_H */ diff --git a/include/asm-powerpc/cacheflush.h b/include/asm-powerpc/cacheflush.h new file mode 100644 index 000000000000..8a740c88d93d --- /dev/null +++ b/include/asm-powerpc/cacheflush.h @@ -0,0 +1,68 @@ +/* + * 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. + */ +#ifndef _ASM_POWERPC_CACHEFLUSH_H +#define _ASM_POWERPC_CACHEFLUSH_H + +#ifdef __KERNEL__ + +#include <linux/mm.h> +#include <asm/cputable.h> + +/* + * No cache flushing is required when address mappings are changed, + * because the caches on PowerPCs are physically addressed. + */ +#define flush_cache_all() do { } while (0) +#define flush_cache_mm(mm) do { } while (0) +#define flush_cache_range(vma, start, end) do { } while (0) +#define flush_cache_page(vma, vmaddr, pfn) do { } while (0) +#define flush_icache_page(vma, page) do { } while (0) +#define flush_cache_vmap(start, end) do { } while (0) +#define flush_cache_vunmap(start, end) do { } while (0) + +extern void flush_dcache_page(struct page *page); +#define flush_dcache_mmap_lock(mapping) do { } while (0) +#define flush_dcache_mmap_unlock(mapping) do { } while (0) + +extern void __flush_icache_range(unsigned long, unsigned long); +static inline void flush_icache_range(unsigned long start, unsigned long stop) +{ + if (!cpu_has_feature(CPU_FTR_COHERENT_ICACHE)) + __flush_icache_range(start, stop); +} + +extern void flush_icache_user_range(struct vm_area_struct *vma, + struct page *page, unsigned long addr, + int len); +extern void __flush_dcache_icache(void *page_va); +extern void flush_dcache_icache_page(struct page *page); +#if defined(CONFIG_PPC32) && !defined(CONFIG_BOOKE) +extern void __flush_dcache_icache_phys(unsigned long physaddr); +#endif /* CONFIG_PPC32 && !CONFIG_BOOKE */ + +extern void flush_dcache_range(unsigned long start, unsigned long stop); +#ifdef CONFIG_PPC32 +extern void clean_dcache_range(unsigned long start, unsigned long stop); +extern void invalidate_dcache_range(unsigned long start, unsigned long stop); +#endif /* CONFIG_PPC32 */ +#ifdef CONFIG_PPC64 +extern void flush_inval_dcache_range(unsigned long start, unsigned long stop); +extern void flush_dcache_phys_range(unsigned long start, unsigned long stop); +#endif + +#define copy_to_user_page(vma, page, vaddr, dst, src, len) \ + do { \ + memcpy(dst, src, len); \ + flush_icache_user_range(vma, page, vaddr, len); \ + } while (0) +#define copy_from_user_page(vma, page, vaddr, dst, src, len) \ + memcpy(dst, src, len) + + +#endif /* __KERNEL__ */ + +#endif /* _ASM_POWERPC_CACHEFLUSH_H */ diff --git a/include/asm-powerpc/compat.h b/include/asm-powerpc/compat.h new file mode 100644 index 000000000000..4db4360c4d4a --- /dev/null +++ b/include/asm-powerpc/compat.h @@ -0,0 +1,205 @@ +#ifndef _ASM_POWERPC_COMPAT_H +#define _ASM_POWERPC_COMPAT_H +/* + * Architecture specific compatibility types + */ +#include <linux/types.h> +#include <linux/sched.h> + +#define COMPAT_USER_HZ 100 + +typedef u32 compat_size_t; +typedef s32 compat_ssize_t; +typedef s32 compat_time_t; +typedef s32 compat_clock_t; +typedef s32 compat_pid_t; +typedef u32 __compat_uid_t; +typedef u32 __compat_gid_t; +typedef u32 __compat_uid32_t; +typedef u32 __compat_gid32_t; +typedef u32 compat_mode_t; +typedef u32 compat_ino_t; +typedef u32 compat_dev_t; +typedef s32 compat_off_t; +typedef s64 compat_loff_t; +typedef s16 compat_nlink_t; +typedef u16 compat_ipc_pid_t; +typedef s32 compat_daddr_t; +typedef u32 compat_caddr_t; +typedef __kernel_fsid_t compat_fsid_t; +typedef s32 compat_key_t; +typedef s32 compat_timer_t; + +typedef s32 compat_int_t; +typedef s32 compat_long_t; +typedef u32 compat_uint_t; +typedef u32 compat_ulong_t; + +struct compat_timespec { + compat_time_t tv_sec; + s32 tv_nsec; +}; + +struct compat_timeval { + compat_time_t tv_sec; + s32 tv_usec; +}; + +struct compat_stat { + compat_dev_t st_dev; + compat_ino_t st_ino; + compat_mode_t st_mode; + compat_nlink_t st_nlink; + __compat_uid32_t st_uid; + __compat_gid32_t st_gid; + compat_dev_t st_rdev; + compat_off_t st_size; + compat_off_t st_blksize; + compat_off_t st_blocks; + compat_time_t st_atime; + u32 st_atime_nsec; + compat_time_t st_mtime; + u32 st_mtime_nsec; + compat_time_t st_ctime; + u32 st_ctime_nsec; + u32 __unused4[2]; +}; + +struct compat_flock { + short l_type; + short l_whence; + compat_off_t l_start; + compat_off_t l_len; + compat_pid_t l_pid; +}; + +#define F_GETLK64 12 /* using 'struct flock64' */ +#define F_SETLK64 13 +#define F_SETLKW64 14 + +struct compat_flock64 { + short l_type; + short l_whence; + compat_loff_t l_start; + compat_loff_t l_len; + compat_pid_t l_pid; +}; + +struct compat_statfs { + int f_type; + int f_bsize; + int f_blocks; + int f_bfree; + int f_bavail; + int f_files; + int f_ffree; + compat_fsid_t f_fsid; + int f_namelen; /* SunOS ignores this field. */ + int f_frsize; + int f_spare[5]; +}; + +#define COMPAT_RLIM_OLD_INFINITY 0x7fffffff +#define COMPAT_RLIM_INFINITY 0xffffffff + +typedef u32 compat_old_sigset_t; + +#define _COMPAT_NSIG 64 +#define _COMPAT_NSIG_BPW 32 + +typedef u32 compat_sigset_word; + +#define COMPAT_OFF_T_MAX 0x7fffffff +#define COMPAT_LOFF_T_MAX 0x7fffffffffffffffL + +/* + * A pointer passed in from user mode. This should not + * be used for syscall parameters, just declare them + * as pointers because the syscall entry code will have + * appropriately comverted them already. + */ +typedef u32 compat_uptr_t; + +static inline void __user *compat_ptr(compat_uptr_t uptr) +{ + return (void __user *)(unsigned long)uptr; +} + +static inline void __user *compat_alloc_user_space(long len) +{ + struct pt_regs *regs = current->thread.regs; + unsigned long usp = regs->gpr[1]; + + /* + * We cant access below the stack pointer in the 32bit ABI and + * can access 288 bytes in the 64bit ABI + */ + if (!(test_thread_flag(TIF_32BIT))) + usp -= 288; + + return (void __user *) (usp - len); +} + +/* + * ipc64_perm is actually 32/64bit clean but since the compat layer refers to + * it we may as well define it. + */ +struct compat_ipc64_perm { + compat_key_t key; + __compat_uid_t uid; + __compat_gid_t gid; + __compat_uid_t cuid; + __compat_gid_t cgid; + compat_mode_t mode; + unsigned int seq; + unsigned int __pad2; + unsigned long __unused1; /* yes they really are 64bit pads */ + unsigned long __unused2; +}; + +struct compat_semid64_ds { + struct compat_ipc64_perm sem_perm; + unsigned int __unused1; + compat_time_t sem_otime; + unsigned int __unused2; + compat_time_t sem_ctime; + compat_ulong_t sem_nsems; + compat_ulong_t __unused3; + compat_ulong_t __unused4; +}; + +struct compat_msqid64_ds { + struct compat_ipc64_perm msg_perm; + unsigned int __unused1; + compat_time_t msg_stime; + unsigned int __unused2; + compat_time_t msg_rtime; + unsigned int __unused3; + compat_time_t msg_ctime; + compat_ulong_t msg_cbytes; + compat_ulong_t msg_qnum; + compat_ulong_t msg_qbytes; + compat_pid_t msg_lspid; + compat_pid_t msg_lrpid; + compat_ulong_t __unused4; + compat_ulong_t __unused5; +}; + +struct compat_shmid64_ds { + struct compat_ipc64_perm shm_perm; + unsigned int __unused1; + compat_time_t shm_atime; + unsigned int __unused2; + compat_time_t shm_dtime; + unsigned int __unused3; + compat_time_t shm_ctime; + unsigned int __unused4; + compat_size_t shm_segsz; + compat_pid_t shm_cpid; + compat_pid_t shm_lpid; + compat_ulong_t shm_nattch; + compat_ulong_t __unused5; + compat_ulong_t __unused6; +}; + +#endif /* _ASM_POWERPC_COMPAT_H */ diff --git a/include/asm-powerpc/cputable.h b/include/asm-powerpc/cputable.h index 79a0556a0ab8..04e2726002cf 100644 --- a/include/asm-powerpc/cputable.h +++ b/include/asm-powerpc/cputable.h @@ -2,7 +2,7 @@ #define __ASM_POWERPC_CPUTABLE_H #include <linux/config.h> -#include <asm/ppc_asm.h> /* for ASM_CONST */ +#include <asm/asm-compat.h> #define PPC_FEATURE_32 0x80000000 #define PPC_FEATURE_64 0x40000000 @@ -16,6 +16,10 @@ #define PPC_FEATURE_HAS_EFP_SINGLE 0x00400000 #define PPC_FEATURE_HAS_EFP_DOUBLE 0x00200000 #define PPC_FEATURE_NO_TB 0x00100000 +#define PPC_FEATURE_POWER4 0x00080000 +#define PPC_FEATURE_POWER5 0x00040000 +#define PPC_FEATURE_POWER5_PLUS 0x00020000 +#define PPC_FEATURE_CELL 0x00010000 #ifdef __KERNEL__ #ifndef __ASSEMBLY__ diff --git a/include/asm-powerpc/current.h b/include/asm-powerpc/current.h new file mode 100644 index 000000000000..82cd4a9ca99a --- /dev/null +++ b/include/asm-powerpc/current.h @@ -0,0 +1,27 @@ +#ifndef _ASM_POWERPC_CURRENT_H +#define _ASM_POWERPC_CURRENT_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. + */ + +struct task_struct; + +#ifdef __powerpc64__ +#include <asm/paca.h> + +#define current (get_paca()->__current) + +#else + +/* + * We keep `current' in r2 for speed. + */ +register struct task_struct *current asm ("r2"); + +#endif + +#endif /* _ASM_POWERPC_CURRENT_H */ diff --git a/include/asm-powerpc/delay.h b/include/asm-powerpc/delay.h new file mode 100644 index 000000000000..1492aa9ab716 --- /dev/null +++ b/include/asm-powerpc/delay.h @@ -0,0 +1,55 @@ +#ifndef _ASM_POWERPC_DELAY_H +#define _ASM_POWERPC_DELAY_H + +/* + * Copyright 1996, Paul Mackerras. + * + * 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. + * + * PPC64 Support added by Dave Engebretsen, Todd Inglett, Mike Corrigan, + * Anton Blanchard. + */ + +extern unsigned long tb_ticks_per_usec; + +#ifdef CONFIG_PPC64 +/* define these here to prevent circular dependencies */ +/* these instructions control the thread priority on multi-threaded cpus */ +#define __HMT_low() asm volatile("or 1,1,1") +#define __HMT_medium() asm volatile("or 2,2,2") +#else +#define __HMT_low() +#define __HMT_medium() +#endif + +#define __barrier() asm volatile("" ::: "memory") + +static inline unsigned long __get_tb(void) +{ + unsigned long rval; + + asm volatile("mftb %0" : "=r" (rval)); + return rval; +} + +static inline void __delay(unsigned long loops) +{ + unsigned long start = __get_tb(); + + while((__get_tb() - start) < loops) + __HMT_low(); + __HMT_medium(); + __barrier(); +} + +static inline void udelay(unsigned long usecs) +{ + unsigned long loops = tb_ticks_per_usec * usecs; + + __delay(loops); +} + +#endif /* _ASM_POWERPC_DELAY_H */ diff --git a/include/asm-powerpc/eeh.h b/include/asm-powerpc/eeh.h new file mode 100644 index 000000000000..89f26ab31908 --- /dev/null +++ b/include/asm-powerpc/eeh.h @@ -0,0 +1,364 @@ +/* + * eeh.h + * Copyright (C) 2001 Dave Engebretsen & Todd Inglett IBM Corporation. + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _PPC64_EEH_H +#define _PPC64_EEH_H + +#include <linux/config.h> +#include <linux/init.h> +#include <linux/list.h> +#include <linux/string.h> + +struct pci_dev; +struct device_node; + +#ifdef CONFIG_EEH + +/* Values for eeh_mode bits in device_node */ +#define EEH_MODE_SUPPORTED (1<<0) +#define EEH_MODE_NOCHECK (1<<1) +#define EEH_MODE_ISOLATED (1<<2) + +/* Max number of EEH freezes allowed before we consider the device + * to be permanently disabled. */ +#define EEH_MAX_ALLOWED_FREEZES 5 + +void __init eeh_init(void); +unsigned long eeh_check_failure(const volatile void __iomem *token, + unsigned long val); +int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev); +void __init pci_addr_cache_build(void); + +/** + * eeh_add_device_early + * eeh_add_device_late + * + * Perform eeh initialization for devices added after boot. + * Call eeh_add_device_early before doing any i/o to the + * device (including config space i/o). Call eeh_add_device_late + * to finish the eeh setup for this device. + */ +void eeh_add_device_early(struct device_node *); +void eeh_add_device_late(struct pci_dev *); + +/** + * eeh_remove_device - undo EEH setup for the indicated pci device + * @dev: pci device to be removed + * + * This routine should be called when a device is removed from + * a running system (e.g. by hotplug or dlpar). It unregisters + * the PCI device from the EEH subsystem. I/O errors affecting + * this device will no longer be detected after this call; thus, + * i/o errors affecting this slot may leave this device unusable. + */ +void eeh_remove_device(struct pci_dev *); + +/** + * EEH_POSSIBLE_ERROR() -- test for possible MMIO failure. + * + * If this macro yields TRUE, the caller relays to eeh_check_failure() + * which does further tests out of line. + */ +#define EEH_POSSIBLE_ERROR(val, type) ((val) == (type)~0) + +/* + * Reads from a device which has been isolated by EEH will return + * all 1s. This macro gives an all-1s value of the given size (in + * bytes: 1, 2, or 4) for comparing with the result of a read. + */ +#define EEH_IO_ERROR_VALUE(size) (~0U >> ((4 - (size)) * 8)) + +#else /* !CONFIG_EEH */ +static inline void eeh_init(void) { } + +static inline unsigned long eeh_check_failure(const volatile void __iomem *token, unsigned long val) +{ + return val; +} + +static inline int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev) +{ + return 0; +} + +static inline void pci_addr_cache_build(void) { } + +static inline void eeh_add_device_early(struct device_node *dn) { } + +static inline void eeh_add_device_late(struct pci_dev *dev) { } + +static inline void eeh_remove_device(struct pci_dev *dev) { } + +#define EEH_POSSIBLE_ERROR(val, type) (0) +#define EEH_IO_ERROR_VALUE(size) (-1UL) +#endif /* CONFIG_EEH */ + +/* + * MMIO read/write operations with EEH support. + */ +static inline u8 eeh_readb(const volatile void __iomem *addr) +{ + u8 val = in_8(addr); + if (EEH_POSSIBLE_ERROR(val, u8)) + return eeh_check_failure(addr, val); + return val; +} +static inline void eeh_writeb(u8 val, volatile void __iomem *addr) +{ + out_8(addr, val); +} + +static inline u16 eeh_readw(const volatile void __iomem *addr) +{ + u16 val = in_le16(addr); + if (EEH_POSSIBLE_ERROR(val, u16)) + return eeh_check_failure(addr, val); + return val; +} +static inline void eeh_writew(u16 val, volatile void __iomem *addr) +{ + out_le16(addr, val); +} +static inline u16 eeh_raw_readw(const volatile void __iomem *addr) +{ + u16 val = in_be16(addr); + if (EEH_POSSIBLE_ERROR(val, u16)) + return eeh_check_failure(addr, val); + return val; +} +static inline void eeh_raw_writew(u16 val, volatile void __iomem *addr) { + volatile u16 __iomem *vaddr = (volatile u16 __iomem *) addr; + out_be16(vaddr, val); +} + +static inline u32 eeh_readl(const volatile void __iomem *addr) +{ + u32 val = in_le32(addr); + if (EEH_POSSIBLE_ERROR(val, u32)) + return eeh_check_failure(addr, val); + return val; +} +static inline void eeh_writel(u32 val, volatile void __iomem *addr) +{ + out_le32(addr, val); +} +static inline u32 eeh_raw_readl(const volatile void __iomem *addr) +{ + u32 val = in_be32(addr); + if (EEH_POSSIBLE_ERROR(val, u32)) + return eeh_check_failure(addr, val); + return val; +} +static inline void eeh_raw_writel(u32 val, volatile void __iomem *addr) +{ + out_be32(addr, val); +} + +static inline u64 eeh_readq(const volatile void __iomem *addr) +{ + u64 val = in_le64(addr); + if (EEH_POSSIBLE_ERROR(val, u64)) + return eeh_check_failure(addr, val); + return val; +} +static inline void eeh_writeq(u64 val, volatile void __iomem *addr) +{ + out_le64(addr, val); +} +static inline u64 eeh_raw_readq(const volatile void __iomem *addr) +{ + u64 val = in_be64(addr); + if (EEH_POSSIBLE_ERROR(val, u64)) + return eeh_check_failure(addr, val); + return val; +} +static inline void eeh_raw_writeq(u64 val, volatile void __iomem *addr) +{ + out_be64(addr, val); +} + +#define EEH_CHECK_ALIGN(v,a) \ + ((((unsigned long)(v)) & ((a) - 1)) == 0) + +static inline void eeh_memset_io(volatile void __iomem *addr, int c, + unsigned long n) +{ + void *p = (void __force *)addr; + u32 lc = c; + lc |= lc << 8; + lc |= lc << 16; + + while(n && !EEH_CHECK_ALIGN(p, 4)) { + *((volatile u8 *)p) = c; + p++; + n--; + } + while(n >= 4) { + *((volatile u32 *)p) = lc; + p += 4; + n -= 4; + } + while(n) { + *((volatile u8 *)p) = c; + p++; + n--; + } + __asm__ __volatile__ ("sync" : : : "memory"); +} +static inline void eeh_memcpy_fromio(void *dest, const volatile void __iomem *src, + unsigned long n) +{ + void *vsrc = (void __force *) src; + void *destsave = dest; + unsigned long nsave = n; + + while(n && (!EEH_CHECK_ALIGN(vsrc, 4) || !EEH_CHECK_ALIGN(dest, 4))) { + *((u8 *)dest) = *((volatile u8 *)vsrc); + __asm__ __volatile__ ("eieio" : : : "memory"); + vsrc++; + dest++; + n--; + } + while(n > 4) { + *((u32 *)dest) = *((volatile u32 *)vsrc); + __asm__ __volatile__ ("eieio" : : : "memory"); + vsrc += 4; + dest += 4; + n -= 4; + } + while(n) { + *((u8 *)dest) = *((volatile u8 *)vsrc); + __asm__ __volatile__ ("eieio" : : : "memory"); + vsrc++; + dest++; + n--; + } + __asm__ __volatile__ ("sync" : : : "memory"); + + /* Look for ffff's here at dest[n]. Assume that at least 4 bytes + * were copied. Check all four bytes. + */ + if ((nsave >= 4) && + (EEH_POSSIBLE_ERROR((*((u32 *) destsave+nsave-4)), u32))) { + eeh_check_failure(src, (*((u32 *) destsave+nsave-4))); + } +} + +static inline void eeh_memcpy_toio(volatile void __iomem *dest, const void *src, + unsigned long n) +{ + void *vdest = (void __force *) dest; + + while(n && (!EEH_CHECK_ALIGN(vdest, 4) || !EEH_CHECK_ALIGN(src, 4))) { + *((volatile u8 *)vdest) = *((u8 *)src); + src++; + vdest++; + n--; + } + while(n > 4) { + *((volatile u32 *)vdest) = *((volatile u32 *)src); + src += 4; + vdest += 4; + n-=4; + } + while(n) { + *((volatile u8 *)vdest) = *((u8 *)src); + src++; + vdest++; + n--; + } + __asm__ __volatile__ ("sync" : : : "memory"); +} + +#undef EEH_CHECK_ALIGN + +static inline u8 eeh_inb(unsigned long port) +{ + u8 val; + if (!_IO_IS_VALID(port)) + return ~0; + val = in_8((u8 __iomem *)(port+pci_io_base)); + if (EEH_POSSIBLE_ERROR(val, u8)) + return eeh_check_failure((void __iomem *)(port), val); + return val; +} + +static inline void eeh_outb(u8 val, unsigned long port) +{ + if (_IO_IS_VALID(port)) + out_8((u8 __iomem *)(port+pci_io_base), val); +} + +static inline u16 eeh_inw(unsigned long port) +{ + u16 val; + if (!_IO_IS_VALID(port)) + return ~0; + val = in_le16((u16 __iomem *)(port+pci_io_base)); + if (EEH_POSSIBLE_ERROR(val, u16)) + return eeh_check_failure((void __iomem *)(port), val); + return val; +} + +static inline void eeh_outw(u16 val, unsigned long port) +{ + if (_IO_IS_VALID(port)) + out_le16((u16 __iomem *)(port+pci_io_base), val); +} + +static inline u32 eeh_inl(unsigned long port) +{ + u32 val; + if (!_IO_IS_VALID(port)) + return ~0; + val = in_le32((u32 __iomem *)(port+pci_io_base)); + if (EEH_POSSIBLE_ERROR(val, u32)) + return eeh_check_failure((void __iomem *)(port), val); + return val; +} + +static inline void eeh_outl(u32 val, unsigned long port) +{ + if (_IO_IS_VALID(port)) + out_le32((u32 __iomem *)(port+pci_io_base), val); +} + +/* in-string eeh macros */ +static inline void eeh_insb(unsigned long port, void * buf, int ns) +{ + _insb((u8 __iomem *)(port+pci_io_base), buf, ns); + if (EEH_POSSIBLE_ERROR((*(((u8*)buf)+ns-1)), u8)) + eeh_check_failure((void __iomem *)(port), *(u8*)buf); +} + +static inline void eeh_insw_ns(unsigned long port, void * buf, int ns) +{ + _insw_ns((u16 __iomem *)(port+pci_io_base), buf, ns); + if (EEH_POSSIBLE_ERROR((*(((u16*)buf)+ns-1)), u16)) + eeh_check_failure((void __iomem *)(port), *(u16*)buf); +} + +static inline void eeh_insl_ns(unsigned long port, void * buf, int nl) +{ + _insl_ns((u32 __iomem *)(port+pci_io_base), buf, nl); + if (EEH_POSSIBLE_ERROR((*(((u32*)buf)+nl-1)), u32)) + eeh_check_failure((void __iomem *)(port), *(u32*)buf); +} + +#endif /* _PPC64_EEH_H */ diff --git a/include/asm-powerpc/eeh_event.h b/include/asm-powerpc/eeh_event.h new file mode 100644 index 000000000000..d168a30b3866 --- /dev/null +++ b/include/asm-powerpc/eeh_event.h @@ -0,0 +1,52 @@ +/* + * eeh_event.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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Copyright (c) 2005 Linas Vepstas <linas@linas.org> + */ + +#ifndef ASM_PPC64_EEH_EVENT_H +#define ASM_PPC64_EEH_EVENT_H + +/** EEH event -- structure holding pci controller data that describes + * a change in the isolation status of a PCI slot. A pointer + * to this struct is passed as the data pointer in a notify callback. + */ +struct eeh_event { + struct list_head list; + struct device_node *dn; /* struct device node */ + struct pci_dev *dev; /* affected device */ + int state; + int time_unavail; /* milliseconds until device might be available */ +}; + +/** + * eeh_send_failure_event - generate a PCI error event + * @dev pci device + * + * This routine builds a PCI error event which will be delivered + * to all listeners on the peh_notifier_chain. + * + * This routine can be called within an interrupt context; + * the actual event will be delivered in a normal context + * (from a workqueue). + */ +int eeh_send_failure_event (struct device_node *dn, + struct pci_dev *dev, + int reset_state, + int time_unavail); + +#endif /* ASM_PPC64_EEH_EVENT_H */ diff --git a/include/asm-powerpc/elf.h b/include/asm-powerpc/elf.h index d140577d0a05..3dcd65edf978 100644 --- a/include/asm-powerpc/elf.h +++ b/include/asm-powerpc/elf.h @@ -1,11 +1,13 @@ #ifndef _ASM_POWERPC_ELF_H #define _ASM_POWERPC_ELF_H +#include <linux/sched.h> /* for task_struct */ #include <asm/types.h> #include <asm/ptrace.h> #include <asm/cputable.h> #include <asm/auxvec.h> #include <asm/page.h> +#include <asm/string.h> /* PowerPC relocations defined by the ABIs */ #define R_PPC_NONE 0 @@ -267,14 +269,12 @@ extern int dcache_bsize; extern int icache_bsize; extern int ucache_bsize; -#ifdef __powerpc64__ +/* vDSO has arch_setup_additional_pages */ +#define ARCH_HAS_SETUP_ADDITIONAL_PAGES struct linux_binprm; -#define ARCH_HAS_SETUP_ADDITIONAL_PAGES /* vDSO has arch_setup_additional_pages */ -extern int arch_setup_additional_pages(struct linux_binprm *bprm, int executable_stack); +extern int arch_setup_additional_pages(struct linux_binprm *bprm, + int executable_stack); #define VDSO_AUX_ENT(a,b) NEW_AUX_ENT(a,b); -#else -#define VDSO_AUX_ENT(a,b) -#endif /* __powerpc64__ */ /* * The requirements here are: diff --git a/include/asm-powerpc/firmware.h b/include/asm-powerpc/firmware.h index 806c142ae9ea..12fabbcb04f0 100644 --- a/include/asm-powerpc/firmware.h +++ b/include/asm-powerpc/firmware.h @@ -43,6 +43,7 @@ #define FW_FEATURE_ISERIES (1UL<<21) enum { +#ifdef CONFIG_PPC64 FW_FEATURE_PSERIES_POSSIBLE = FW_FEATURE_PFT | FW_FEATURE_TCE | FW_FEATURE_SPRG0 | FW_FEATURE_DABR | FW_FEATURE_COPY | FW_FEATURE_ASR | FW_FEATURE_DEBUG | FW_FEATURE_TERM | @@ -70,6 +71,11 @@ enum { FW_FEATURE_ISERIES_ALWAYS & #endif FW_FEATURE_POSSIBLE, + +#else /* CONFIG_PPC64 */ + FW_FEATURE_POSSIBLE = 0, + FW_FEATURE_ALWAYS = 0, +#endif }; /* This is used to identify firmware features which are available diff --git a/include/asm-powerpc/floppy.h b/include/asm-powerpc/floppy.h new file mode 100644 index 000000000000..64276a3f6153 --- /dev/null +++ b/include/asm-powerpc/floppy.h @@ -0,0 +1,105 @@ +/* + * Architecture specific parts of the Floppy driver + * + * 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) 1995 + */ +#ifndef __ASM_POWERPC_FLOPPY_H +#define __ASM_POWERPC_FLOPPY_H + +#include <linux/config.h> +#include <asm/machdep.h> + +#define fd_inb(port) inb_p(port) +#define fd_outb(value,port) outb_p(value,port) + +#define fd_enable_dma() enable_dma(FLOPPY_DMA) +#define fd_disable_dma() disable_dma(FLOPPY_DMA) +#define fd_request_dma() request_dma(FLOPPY_DMA, "floppy") +#define fd_free_dma() free_dma(FLOPPY_DMA) +#define fd_clear_dma_ff() clear_dma_ff(FLOPPY_DMA) +#define fd_set_dma_mode(mode) set_dma_mode(FLOPPY_DMA, mode) +#define fd_set_dma_count(count) set_dma_count(FLOPPY_DMA, count) +#define fd_enable_irq() enable_irq(FLOPPY_IRQ) +#define fd_disable_irq() disable_irq(FLOPPY_IRQ) +#define fd_cacheflush(addr,size) /* nothing */ +#define fd_request_irq() request_irq(FLOPPY_IRQ, floppy_interrupt, \ + SA_INTERRUPT|SA_SAMPLE_RANDOM, \ + "floppy", NULL) +#define fd_free_irq() free_irq(FLOPPY_IRQ, NULL); + +#ifdef CONFIG_PCI + +#include <linux/pci.h> + +#define fd_dma_setup(addr,size,mode,io) powerpc_fd_dma_setup(addr,size,mode,io) + +static __inline__ int powerpc_fd_dma_setup(char *addr, unsigned long size, + int mode, int io) +{ + static unsigned long prev_size; + static dma_addr_t bus_addr = 0; + static char *prev_addr; + static int prev_dir; + int dir; + + dir = (mode == DMA_MODE_READ) ? PCI_DMA_FROMDEVICE : PCI_DMA_TODEVICE; + + if (bus_addr + && (addr != prev_addr || size != prev_size || dir != prev_dir)) { + /* different from last time -- unmap prev */ + pci_unmap_single(NULL, bus_addr, prev_size, prev_dir); + bus_addr = 0; + } + + if (!bus_addr) /* need to map it */ + bus_addr = pci_map_single(NULL, addr, size, dir); + + /* remember this one as prev */ + prev_addr = addr; + prev_size = size; + prev_dir = dir; + + fd_clear_dma_ff(); + fd_cacheflush(addr, size); + fd_set_dma_mode(mode); + set_dma_addr(FLOPPY_DMA, bus_addr); + fd_set_dma_count(size); + virtual_dma_port = io; + fd_enable_dma(); + + return 0; +} + +#endif /* CONFIG_PCI */ + +__inline__ void virtual_dma_init(void) +{ + /* Nothing to do on PowerPC */ +} + +static int FDC1 = 0x3f0; +static int FDC2 = -1; + +/* + * Again, the CMOS information not available + */ +#define FLOPPY0_TYPE 6 +#define FLOPPY1_TYPE 0 + +#define N_FDC 2 /* Don't change this! */ +#define N_DRIVE 8 + +#define FLOPPY_MOTOR_MASK 0xf0 + +/* + * The PowerPC has no problems with floppy DMA crossing 64k borders. + */ +#define CROSS_64KB(a,s) (0) + +#define EXTRA_FLOPPY_PARAMS + +#endif /* __ASM_POWERPC_FLOPPY_H */ diff --git a/include/asm-powerpc/futex.h b/include/asm-powerpc/futex.h index 37c94e52ab6d..f0319d50b129 100644 --- a/include/asm-powerpc/futex.h +++ b/include/asm-powerpc/futex.h @@ -7,13 +7,14 @@ #include <asm/errno.h> #include <asm/synch.h> #include <asm/uaccess.h> -#include <asm/ppc_asm.h> +#include <asm/asm-compat.h> #define __futex_atomic_op(insn, ret, oldval, uaddr, oparg) \ __asm__ __volatile ( \ SYNC_ON_SMP \ "1: lwarx %0,0,%2\n" \ insn \ + PPC405_ERR77(0, %2) \ "2: stwcx. %1,0,%2\n" \ "bne- 1b\n" \ "li %1,0\n" \ @@ -23,7 +24,7 @@ ".previous\n" \ ".section __ex_table,\"a\"\n" \ ".align 3\n" \ - DATAL " 1b,4b,2b,4b\n" \ + PPC_LONG "1b,4b,2b,4b\n" \ ".previous" \ : "=&r" (oldval), "=&r" (ret) \ : "b" (uaddr), "i" (-EFAULT), "1" (oparg) \ diff --git a/include/asm-powerpc/hvcall.h b/include/asm-powerpc/hvcall.h new file mode 100644 index 000000000000..d36da61dbc53 --- /dev/null +++ b/include/asm-powerpc/hvcall.h @@ -0,0 +1,173 @@ +#ifndef _ASM_POWERPC_HVCALL_H +#define _ASM_POWERPC_HVCALL_H + +#define HVSC .long 0x44000022 + +#define H_Success 0 +#define H_Busy 1 /* Hardware busy -- retry later */ +#define H_Constrained 4 /* Resource request constrained to max allowed */ +#define H_LongBusyStartRange 9900 /* Start of long busy range */ +#define H_LongBusyOrder1msec 9900 /* Long busy, hint that 1msec is a good time to retry */ +#define H_LongBusyOrder10msec 9901 /* Long busy, hint that 10msec is a good time to retry */ +#define H_LongBusyOrder100msec 9902 /* Long busy, hint that 100msec is a good time to retry */ +#define H_LongBusyOrder1sec 9903 /* Long busy, hint that 1sec is a good time to retry */ +#define H_LongBusyOrder10sec 9904 /* Long busy, hint that 10sec is a good time to retry */ +#define H_LongBusyOrder100sec 9905 /* Long busy, hint that 100sec is a good time to retry */ +#define H_LongBusyEndRange 9905 /* End of long busy range */ +#define H_Hardware -1 /* Hardware error */ +#define H_Function -2 /* Function not supported */ +#define H_Privilege -3 /* Caller not privileged */ +#define H_Parameter -4 /* Parameter invalid, out-of-range or conflicting */ +#define H_Bad_Mode -5 /* Illegal msr value */ +#define H_PTEG_Full -6 /* PTEG is full */ +#define H_Not_Found -7 /* PTE was not found" */ +#define H_Reserved_DABR -8 /* DABR address is reserved by the hypervisor on this processor" */ +#define H_NoMem -9 +#define H_Authority -10 +#define H_Permission -11 +#define H_Dropped -12 +#define H_SourceParm -13 +#define H_DestParm -14 +#define H_RemoteParm -15 +#define H_Resource -16 + +/* Long Busy is a condition that can be returned by the firmware + * when a call cannot be completed now, but the identical call + * should be retried later. This prevents calls blocking in the + * firmware for long periods of time. Annoyingly the firmware can return + * a range of return codes, hinting at how long we should wait before + * retrying. If you don't care for the hint, the macro below is a good + * way to check for the long_busy return codes + */ +#define H_isLongBusy(x) ((x >= H_LongBusyStartRange) && (x <= H_LongBusyEndRange)) + +/* Flags */ +#define H_LARGE_PAGE (1UL<<(63-16)) +#define H_EXACT (1UL<<(63-24)) /* Use exact PTE or return H_PTEG_FULL */ +#define H_R_XLATE (1UL<<(63-25)) /* include a valid logical page num in the pte if the valid bit is set */ +#define H_READ_4 (1UL<<(63-26)) /* Return 4 PTEs */ +#define H_AVPN (1UL<<(63-32)) /* An avpn is provided as a sanity test */ +#define H_ANDCOND (1UL<<(63-33)) +#define H_ICACHE_INVALIDATE (1UL<<(63-40)) /* icbi, etc. (ignored for IO pages) */ +#define H_ICACHE_SYNCHRONIZE (1UL<<(63-41)) /* dcbst, icbi, etc (ignored for IO pages */ +#define H_ZERO_PAGE (1UL<<(63-48)) /* zero the page before mapping (ignored for IO pages) */ +#define H_COPY_PAGE (1UL<<(63-49)) +#define H_N (1UL<<(63-61)) +#define H_PP1 (1UL<<(63-62)) +#define H_PP2 (1UL<<(63-63)) + +/* DABRX flags */ +#define H_DABRX_HYPERVISOR (1UL<<(63-61)) +#define H_DABRX_KERNEL (1UL<<(63-62)) +#define H_DABRX_USER (1UL<<(63-63)) + +/* pSeries hypervisor opcodes */ +#define H_REMOVE 0x04 +#define H_ENTER 0x08 +#define H_READ 0x0c +#define H_CLEAR_MOD 0x10 +#define H_CLEAR_REF 0x14 +#define H_PROTECT 0x18 +#define H_GET_TCE 0x1c +#define H_PUT_TCE 0x20 +#define H_SET_SPRG0 0x24 +#define H_SET_DABR 0x28 +#define H_PAGE_INIT 0x2c +#define H_SET_ASR 0x30 +#define H_ASR_ON 0x34 +#define H_ASR_OFF 0x38 +#define H_LOGICAL_CI_LOAD 0x3c +#define H_LOGICAL_CI_STORE 0x40 +#define H_LOGICAL_CACHE_LOAD 0x44 +#define H_LOGICAL_CACHE_STORE 0x48 +#define H_LOGICAL_ICBI 0x4c +#define H_LOGICAL_DCBF 0x50 +#define H_GET_TERM_CHAR 0x54 +#define H_PUT_TERM_CHAR 0x58 +#define H_REAL_TO_LOGICAL 0x5c +#define H_HYPERVISOR_DATA 0x60 +#define H_EOI 0x64 +#define H_CPPR 0x68 +#define H_IPI 0x6c +#define H_IPOLL 0x70 +#define H_XIRR 0x74 +#define H_PERFMON 0x7c +#define H_MIGRATE_DMA 0x78 +#define H_REGISTER_VPA 0xDC +#define H_CEDE 0xE0 +#define H_CONFER 0xE4 +#define H_PROD 0xE8 +#define H_GET_PPP 0xEC +#define H_SET_PPP 0xF0 +#define H_PURR 0xF4 +#define H_PIC 0xF8 +#define H_REG_CRQ 0xFC +#define H_FREE_CRQ 0x100 +#define H_VIO_SIGNAL 0x104 +#define H_SEND_CRQ 0x108 +#define H_COPY_RDMA 0x110 +#define H_SET_XDABR 0x134 +#define H_STUFF_TCE 0x138 +#define H_PUT_TCE_INDIRECT 0x13C +#define H_VTERM_PARTNER_INFO 0x150 +#define H_REGISTER_VTERM 0x154 +#define H_FREE_VTERM 0x158 +#define H_POLL_PENDING 0x1D8 + +#ifndef __ASSEMBLY__ + +/* plpar_hcall() -- Generic call interface using above opcodes + * + * The actual call interface is a hypervisor call instruction with + * the opcode in R3 and input args in R4-R7. + * Status is returned in R3 with variable output values in R4-R11. + * Only H_PTE_READ with H_READ_4 uses R6-R11 so we ignore it for now + * and return only two out args which MUST ALWAYS BE PROVIDED. + */ +long plpar_hcall(unsigned long opcode, + unsigned long arg1, + unsigned long arg2, + unsigned long arg3, + unsigned long arg4, + unsigned long *out1, + unsigned long *out2, + unsigned long *out3); + +/* Same as plpar_hcall but for those opcodes that return no values + * other than status. Slightly more efficient. + */ +long plpar_hcall_norets(unsigned long opcode, ...); + +/* + * Special hcall interface for ibmveth support. + * Takes 8 input parms. Returns a rc and stores the + * R4 return value in *out1. + */ +long plpar_hcall_8arg_2ret(unsigned long opcode, + unsigned long arg1, + unsigned long arg2, + unsigned long arg3, + unsigned long arg4, + unsigned long arg5, + unsigned long arg6, + unsigned long arg7, + unsigned long arg8, + unsigned long *out1); + +/* plpar_hcall_4out() + * + * same as plpar_hcall except with 4 output arguments. + * + */ +long plpar_hcall_4out(unsigned long opcode, + unsigned long arg1, + unsigned long arg2, + unsigned long arg3, + unsigned long arg4, + unsigned long *out1, + unsigned long *out2, + unsigned long *out3, + unsigned long *out4); + +#endif /* __ASSEMBLY__ */ +#endif /* _ASM_POWERPC_HVCALL_H */ diff --git a/include/asm-powerpc/hvconsole.h b/include/asm-powerpc/hvconsole.h new file mode 100644 index 000000000000..6da93ce74dc0 --- /dev/null +++ b/include/asm-powerpc/hvconsole.h @@ -0,0 +1,49 @@ +/* + * hvconsole.h + * Copyright (C) 2004 Ryan S Arnold, IBM Corporation + * + * LPAR console support. + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _PPC64_HVCONSOLE_H +#define _PPC64_HVCONSOLE_H + +/* + * This is the max number of console adapters that can/will be found as + * console devices on first stage console init. Any number beyond this range + * can't be used as a console device but is still a valid tty device. + */ +#define MAX_NR_HVC_CONSOLES 16 + +/* implemented by a low level driver */ +struct hv_ops { + int (*get_chars)(uint32_t vtermno, char *buf, int count); + int (*put_chars)(uint32_t vtermno, const char *buf, int count); +}; +extern int hvc_get_chars(uint32_t vtermno, char *buf, int count); +extern int hvc_put_chars(uint32_t vtermno, const char *buf, int count); + +struct hvc_struct; + +/* Register a vterm and a slot index for use as a console (console_init) */ +extern int hvc_instantiate(uint32_t vtermno, int index, struct hv_ops *ops); +/* register a vterm for hvc tty operation (module_init or hotplug add) */ +extern struct hvc_struct * __devinit hvc_alloc(uint32_t vtermno, int irq, + struct hv_ops *ops); +/* remove a vterm from hvc tty operation (modele_exit or hotplug remove) */ +extern int __devexit hvc_remove(struct hvc_struct *hp); +#endif /* _PPC64_HVCONSOLE_H */ diff --git a/include/asm-powerpc/hvcserver.h b/include/asm-powerpc/hvcserver.h new file mode 100644 index 000000000000..aecba9665796 --- /dev/null +++ b/include/asm-powerpc/hvcserver.h @@ -0,0 +1,57 @@ +/* + * hvcserver.h + * Copyright (C) 2004 Ryan S Arnold, IBM Corporation + * + * PPC64 virtual I/O console server support. + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _PPC64_HVCSERVER_H +#define _PPC64_HVCSERVER_H + +#include <linux/list.h> + +/* Converged Location Code length */ +#define HVCS_CLC_LENGTH 79 + +/** + * hvcs_partner_info - an element in a list of partner info + * @node: list_head denoting this partner_info struct's position in the list of + * partner info. + * @unit_address: The partner unit address of this entry. + * @partition_ID: The partner partition ID of this entry. + * @location_code: The converged location code of this entry + 1 char for the + * null-term. + * + * This structure outlines the format that partner info is presented to a caller + * of the hvcs partner info fetching functions. These are strung together into + * a list using linux kernel lists. + */ +struct hvcs_partner_info { + struct list_head node; + uint32_t unit_address; + uint32_t partition_ID; + char location_code[HVCS_CLC_LENGTH + 1]; /* CLC + 1 null-term char */ +}; + +extern int hvcs_free_partner_info(struct list_head *head); +extern int hvcs_get_partner_info(uint32_t unit_address, + struct list_head *head, unsigned long *pi_buff); +extern int hvcs_register_connection(uint32_t unit_address, + uint32_t p_partition_ID, uint32_t p_unit_address); +extern int hvcs_free_connection(uint32_t unit_address); + +#endif /* _PPC64_HVCSERVER_H */ diff --git a/include/asm-powerpc/hw_irq.h b/include/asm-powerpc/hw_irq.h index c37b31b96337..26b89d859c56 100644 --- a/include/asm-powerpc/hw_irq.h +++ b/include/asm-powerpc/hw_irq.h @@ -12,7 +12,6 @@ #include <asm/processor.h> extern void timer_interrupt(struct pt_regs *); -extern void ppc_irq_dispatch_handler(struct pt_regs *regs, int irq); #ifdef CONFIG_PPC_ISERIES diff --git a/include/asm-powerpc/ide.h b/include/asm-powerpc/ide.h new file mode 100644 index 000000000000..da5f640480cf --- /dev/null +++ b/include/asm-powerpc/ide.h @@ -0,0 +1,83 @@ +/* + * Copyright (C) 1994-1996 Linus Torvalds & authors + * + * This file contains the powerpc architecture specific IDE code. + */ +#ifndef _ASM_POWERPC_IDE_H +#define _ASM_POWERPC_IDE_H + +#ifdef __KERNEL__ + +#ifndef __powerpc64__ +#include <linux/sched.h> +#include <asm/mpc8xx.h> +#endif + +#ifndef MAX_HWIFS +#ifdef __powerpc64__ +#define MAX_HWIFS 10 +#else +#define MAX_HWIFS 8 +#endif +#endif + +#ifndef __powerpc64__ +#include <linux/config.h> +#include <linux/hdreg.h> +#include <linux/ioport.h> +#include <asm/io.h> + +extern void __ide_mm_insw(void __iomem *port, void *addr, u32 count); +extern void __ide_mm_outsw(void __iomem *port, void *addr, u32 count); +extern void __ide_mm_insl(void __iomem *port, void *addr, u32 count); +extern void __ide_mm_outsl(void __iomem *port, void *addr, u32 count); + +struct ide_machdep_calls { + int (*default_irq)(unsigned long base); + unsigned long (*default_io_base)(int index); + void (*ide_init_hwif)(hw_regs_t *hw, + unsigned long data_port, + unsigned long ctrl_port, + int *irq); +}; + +extern struct ide_machdep_calls ppc_ide_md; + +#undef SUPPORT_SLOW_DATA_PORTS +#define SUPPORT_SLOW_DATA_PORTS 0 + +#define IDE_ARCH_OBSOLETE_DEFAULTS + +static __inline__ int ide_default_irq(unsigned long base) +{ + if (ppc_ide_md.default_irq) + return ppc_ide_md.default_irq(base); + return 0; +} + +static __inline__ unsigned long ide_default_io_base(int index) +{ + if (ppc_ide_md.default_io_base) + return ppc_ide_md.default_io_base(index); + return 0; +} + +#ifdef CONFIG_PCI +#define ide_init_default_irq(base) (0) +#else +#define ide_init_default_irq(base) ide_default_irq(base) +#endif + +#if (defined CONFIG_APUS || defined CONFIG_BLK_DEV_MPC8xx_IDE ) +#define IDE_ARCH_ACK_INTR 1 +#define ide_ack_intr(hwif) (hwif->hw.ack_intr ? hwif->hw.ack_intr(hwif) : 1) +#endif + +#endif /* __powerpc64__ */ + +#define IDE_ARCH_OBSOLETE_INIT +#define ide_default_io_ctl(base) ((base) + 0x206) /* obsolete */ + +#endif /* __KERNEL__ */ + +#endif /* _ASM_POWERPC_IDE_H */ diff --git a/include/asm-powerpc/irq.h b/include/asm-powerpc/irq.h index b3935ea28fff..8eb7e857ec4c 100644 --- a/include/asm-powerpc/irq.h +++ b/include/asm-powerpc/irq.h @@ -389,6 +389,7 @@ extern u64 ppc64_interrupt_controller; #define SIU_INT_TIMER4 ((uint)0x0f + CPM_IRQ_OFFSET) #define SIU_INT_TMCNT ((uint)0x10 + CPM_IRQ_OFFSET) #define SIU_INT_PIT ((uint)0x11 + CPM_IRQ_OFFSET) +#define SIU_INT_PCI ((uint)0x12 + CPM_IRQ_OFFSET) #define SIU_INT_IRQ1 ((uint)0x13 + CPM_IRQ_OFFSET) #define SIU_INT_IRQ2 ((uint)0x14 + CPM_IRQ_OFFSET) #define SIU_INT_IRQ3 ((uint)0x15 + CPM_IRQ_OFFSET) @@ -429,7 +430,6 @@ extern u64 ppc64_interrupt_controller; #define NR_MASK_WORDS ((NR_IRQS + 31) / 32) /* pedantic: these are long because they are used with set_bit --RR */ extern unsigned long ppc_cached_irq_mask[NR_MASK_WORDS]; -extern unsigned long ppc_lost_interrupts[NR_MASK_WORDS]; extern atomic_t ppc_n_lost_interrupts; #define virt_irq_create_mapping(x) (x) @@ -488,8 +488,8 @@ extern struct thread_info *softirq_ctx[NR_CPUS]; extern void irq_ctx_init(void); extern void call_do_softirq(struct thread_info *tp); -extern int call_handle_IRQ_event(int irq, struct pt_regs *regs, - struct irqaction *action, struct thread_info *tp); +extern int call___do_IRQ(int irq, struct pt_regs *regs, + struct thread_info *tp); #define __ARCH_HAS_DO_SOFTIRQ diff --git a/include/asm-powerpc/kexec.h b/include/asm-powerpc/kexec.h index 062ab9ba68eb..c72ffc709ea8 100644 --- a/include/asm-powerpc/kexec.h +++ b/include/asm-powerpc/kexec.h @@ -40,6 +40,7 @@ extern note_buf_t crash_notes[]; #ifdef __powerpc64__ extern void kexec_smp_wait(void); /* get and clear naca physid, wait for master to copy new code to 0 */ +extern void __init kexec_setup(void); #else struct kimage; extern void machine_kexec_simple(struct kimage *image); diff --git a/include/asm-powerpc/kprobes.h b/include/asm-powerpc/kprobes.h index b2f09f17fbe0..6cd0a3bfa280 100644 --- a/include/asm-powerpc/kprobes.h +++ b/include/asm-powerpc/kprobes.h @@ -27,6 +27,7 @@ */ #include <linux/types.h> #include <linux/ptrace.h> +#include <linux/percpu.h> struct pt_regs; @@ -53,6 +54,20 @@ struct arch_specific_insn { kprobe_opcode_t *insn; }; +struct prev_kprobe { + struct kprobe *kp; + unsigned long status; + unsigned long saved_msr; +}; + +/* per-cpu kprobe control block */ +struct kprobe_ctlblk { + unsigned long kprobe_status; + unsigned long kprobe_saved_msr; + struct pt_regs jprobe_saved_regs; + struct prev_kprobe prev_kprobe; +}; + #ifdef CONFIG_KPROBES extern int kprobe_exceptions_notify(struct notifier_block *self, unsigned long val, void *data); diff --git a/include/asm-powerpc/lppaca.h b/include/asm-powerpc/lppaca.h new file mode 100644 index 000000000000..c1bedab1515b --- /dev/null +++ b/include/asm-powerpc/lppaca.h @@ -0,0 +1,131 @@ +/* + * lppaca.h + * Copyright (C) 2001 Mike Corrigan IBM Corporation + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef _ASM_POWERPC_LPPACA_H +#define _ASM_POWERPC_LPPACA_H + +//============================================================================= +// +// This control block contains the data that is shared between the +// hypervisor (PLIC) and the OS. +// +// +//---------------------------------------------------------------------------- +#include <asm/types.h> + +struct lppaca { +//============================================================================= +// CACHE_LINE_1 0x0000 - 0x007F Contains read-only data +// NOTE: The xDynXyz fields are fields that will be dynamically changed by +// PLIC when preparing to bring a processor online or when dispatching a +// virtual processor! +//============================================================================= + u32 desc; // Eye catcher 0xD397D781 x00-x03 + u16 size; // Size of this struct x04-x05 + u16 reserved1; // Reserved x06-x07 + u16 reserved2:14; // Reserved x08-x09 + u8 shared_proc:1; // Shared processor indicator ... + u8 secondary_thread:1; // Secondary thread indicator ... + volatile u8 dyn_proc_status:8; // Dynamic Status of this proc x0A-x0A + u8 secondary_thread_count; // Secondary thread count x0B-x0B + volatile u16 dyn_hv_phys_proc_index;// Dynamic HV Physical Proc Index0C-x0D + volatile u16 dyn_hv_log_proc_index;// Dynamic HV Logical Proc Indexx0E-x0F + u32 decr_val; // Value for Decr programming x10-x13 + u32 pmc_val; // Value for PMC regs x14-x17 + volatile u32 dyn_hw_node_id; // Dynamic Hardware Node id x18-x1B + volatile u32 dyn_hw_proc_id; // Dynamic Hardware Proc Id x1C-x1F + volatile u32 dyn_pir; // Dynamic ProcIdReg value x20-x23 + u32 dsei_data; // DSEI data x24-x27 + u64 sprg3; // SPRG3 value x28-x2F + u8 reserved3[80]; // Reserved x30-x7F + +//============================================================================= +// CACHE_LINE_2 0x0080 - 0x00FF Contains local read-write data +//============================================================================= + // This Dword contains a byte for each type of interrupt that can occur. + // The IPI is a count while the others are just a binary 1 or 0. + union { + u64 any_int; + struct { + u16 reserved; // Reserved - cleared by #mpasmbl + u8 xirr_int; // Indicates xXirrValue is valid or Immed IO + u8 ipi_cnt; // IPI Count + u8 decr_int; // DECR interrupt occurred + u8 pdc_int; // PDC interrupt occurred + u8 quantum_int; // Interrupt quantum reached + u8 old_plic_deferred_ext_int; // Old PLIC has a deferred XIRR pending + } fields; + } int_dword; + + // Whenever any fields in this Dword are set then PLIC will defer the + // processing of external interrupts. Note that PLIC will store the + // XIRR directly into the xXirrValue field so that another XIRR will + // not be presented until this one clears. The layout of the low + // 4-bytes of this Dword is upto SLIC - PLIC just checks whether the + // entire Dword is zero or not. A non-zero value in the low order + // 2-bytes will result in SLIC being granted the highest thread + // priority upon return. A 0 will return to SLIC as medium priority. + u64 plic_defer_ints_area; // Entire Dword + + // Used to pass the real SRR0/1 from PLIC to SLIC as well as to + // pass the target SRR0/1 from SLIC to PLIC on a SetAsrAndRfid. + u64 saved_srr0; // Saved SRR0 x10-x17 + u64 saved_srr1; // Saved SRR1 x18-x1F + + // Used to pass parms from the OS to PLIC for SetAsrAndRfid + u64 saved_gpr3; // Saved GPR3 x20-x27 + u64 saved_gpr4; // Saved GPR4 x28-x2F + u64 saved_gpr5; // Saved GPR5 x30-x37 + + u8 reserved4; // Reserved x38-x38 + u8 cpuctls_task_attrs; // Task attributes for cpuctls x39-x39 + u8 fpregs_in_use; // FP regs in use x3A-x3A + u8 pmcregs_in_use; // PMC regs in use x3B-x3B + volatile u32 saved_decr; // Saved Decr Value x3C-x3F + volatile u64 emulated_time_base;// Emulated TB for this thread x40-x47 + volatile u64 cur_plic_latency; // Unaccounted PLIC latency x48-x4F + u64 tot_plic_latency; // Accumulated PLIC latency x50-x57 + u64 wait_state_cycles; // Wait cycles for this proc x58-x5F + u64 end_of_quantum; // TB at end of quantum x60-x67 + u64 pdc_saved_sprg1; // Saved SPRG1 for PMC int x68-x6F + u64 pdc_saved_srr0; // Saved SRR0 for PMC int x70-x77 + volatile u32 virtual_decr; // Virtual DECR for shared procsx78-x7B + u16 slb_count; // # of SLBs to maintain x7C-x7D + u8 idle; // Indicate OS is idle x7E + u8 vmxregs_in_use; // VMX registers in use x7F + + +//============================================================================= +// CACHE_LINE_3 0x0100 - 0x007F: This line is shared with other processors +//============================================================================= + // This is the yield_count. An "odd" value (low bit on) means that + // the processor is yielded (either because of an OS yield or a PLIC + // preempt). An even value implies that the processor is currently + // executing. + // NOTE: This value will ALWAYS be zero for dedicated processors and + // will NEVER be zero for shared processors (ie, initialized to a 1). + volatile u32 yield_count; // PLIC increments each dispatchx00-x03 + u8 reserved6[124]; // Reserved x04-x7F + +//============================================================================= +// CACHE_LINE_4-5 0x0100 - 0x01FF Contains PMC interrupt data +//============================================================================= + u8 pmc_save_area[256]; // PMC interrupt Area x00-xFF +}; + +#endif /* _ASM_POWERPC_LPPACA_H */ diff --git a/include/asm-powerpc/machdep.h b/include/asm-powerpc/machdep.h index fa03864d06eb..c011abb8b600 100644 --- a/include/asm-powerpc/machdep.h +++ b/include/asm-powerpc/machdep.h @@ -82,7 +82,6 @@ struct machdep_calls { void (*iommu_dev_setup)(struct pci_dev *dev); void (*iommu_bus_setup)(struct pci_bus *bus); void (*irq_bus_setup)(struct pci_bus *bus); - int (*set_dabr)(unsigned long dabr); #endif int (*probe)(int platform); @@ -94,7 +93,9 @@ struct machdep_calls { void (*init_IRQ)(void); int (*get_irq)(struct pt_regs *); - void (*cpu_irq_down)(int secondary); +#ifdef CONFIG_KEXEC + void (*kexec_cpu_down)(int crash_shutdown, int secondary); +#endif /* PCI stuff */ /* Called after scanning the bus, before allocating resources */ @@ -158,6 +159,9 @@ struct machdep_calls { platform, called once per cpu. */ void (*enable_pmcs)(void); + /* Set DABR for this platform, leave empty for default implemenation */ + int (*set_dabr)(unsigned long dabr); + #ifdef CONFIG_PPC32 /* XXX for now */ /* A general init function, called by ppc_init in init/main.c. May be NULL. */ diff --git a/include/asm-powerpc/nvram.h b/include/asm-powerpc/nvram.h new file mode 100644 index 000000000000..24bd8c2388ea --- /dev/null +++ b/include/asm-powerpc/nvram.h @@ -0,0 +1,119 @@ +/* + * NVRAM definitions and access functions. + * + * 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. + */ + +#ifndef _ASM_POWERPC_NVRAM_H +#define _ASM_POWERPC_NVRAM_H + +#define NVRW_CNT 0x20 +#define NVRAM_HEADER_LEN 16 /* sizeof(struct nvram_header) */ +#define NVRAM_BLOCK_LEN 16 +#define NVRAM_MAX_REQ (2080/NVRAM_BLOCK_LEN) +#define NVRAM_MIN_REQ (1056/NVRAM_BLOCK_LEN) + +#define NVRAM_AS0 0x74 +#define NVRAM_AS1 0x75 +#define NVRAM_DATA 0x77 + + +/* RTC Offsets */ + +#define MOTO_RTC_SECONDS 0x1FF9 +#define MOTO_RTC_MINUTES 0x1FFA +#define MOTO_RTC_HOURS 0x1FFB +#define MOTO_RTC_DAY_OF_WEEK 0x1FFC +#define MOTO_RTC_DAY_OF_MONTH 0x1FFD +#define MOTO_RTC_MONTH 0x1FFE +#define MOTO_RTC_YEAR 0x1FFF +#define MOTO_RTC_CONTROLA 0x1FF8 +#define MOTO_RTC_CONTROLB 0x1FF9 + +#define NVRAM_SIG_SP 0x02 /* support processor */ +#define NVRAM_SIG_OF 0x50 /* open firmware config */ +#define NVRAM_SIG_FW 0x51 /* general firmware */ +#define NVRAM_SIG_HW 0x52 /* hardware (VPD) */ +#define NVRAM_SIG_FLIP 0x5a /* Apple flip/flop header */ +#define NVRAM_SIG_APPL 0x5f /* Apple "system" (???) */ +#define NVRAM_SIG_SYS 0x70 /* system env vars */ +#define NVRAM_SIG_CFG 0x71 /* config data */ +#define NVRAM_SIG_ELOG 0x72 /* error log */ +#define NVRAM_SIG_VEND 0x7e /* vendor defined */ +#define NVRAM_SIG_FREE 0x7f /* Free space */ +#define NVRAM_SIG_OS 0xa0 /* OS defined */ +#define NVRAM_SIG_PANIC 0xa1 /* Apple OSX "panic" */ + +/* If change this size, then change the size of NVNAME_LEN */ +struct nvram_header { + unsigned char signature; + unsigned char checksum; + unsigned short length; + char name[12]; +}; + +struct nvram_partition { + struct list_head partition; + struct nvram_header header; + unsigned int index; +}; + + +extern int nvram_write_error_log(char * buff, int length, unsigned int err_type); +extern int nvram_read_error_log(char * buff, int length, unsigned int * err_type); +extern int nvram_clear_error_log(void); +extern struct nvram_partition *nvram_find_partition(int sig, const char *name); + +extern int pSeries_nvram_init(void); +extern int mmio_nvram_init(void); + +/* PowerMac specific nvram stuffs */ + +enum { + pmac_nvram_OF, /* Open Firmware partition */ + pmac_nvram_XPRAM, /* MacOS XPRAM partition */ + pmac_nvram_NR /* MacOS Name Registry partition */ +}; + +/* Return partition offset in nvram */ +extern int pmac_get_partition(int partition); + +/* Direct access to XPRAM on PowerMacs */ +extern u8 pmac_xpram_read(int xpaddr); +extern void pmac_xpram_write(int xpaddr, u8 data); + +/* Synchronize NVRAM */ +extern void nvram_sync(void); + +/* Normal access to NVRAM */ +extern unsigned char nvram_read_byte(int i); +extern void nvram_write_byte(unsigned char c, int i); + +/* Some offsets in XPRAM */ +#define PMAC_XPRAM_MACHINE_LOC 0xe4 +#define PMAC_XPRAM_SOUND_VOLUME 0x08 + +/* Machine location structure in PowerMac XPRAM */ +struct pmac_machine_location { + unsigned int latitude; /* 2+30 bit Fractional number */ + unsigned int longitude; /* 2+30 bit Fractional number */ + unsigned int delta; /* mix of GMT delta and DLS */ +}; + +/* + * /dev/nvram ioctls + * + * Note that PMAC_NVRAM_GET_OFFSET is still supported, but is + * definitely obsolete. Do not use it if you can avoid it + */ + +#define OBSOLETE_PMAC_NVRAM_GET_OFFSET \ + _IOWR('p', 0x40, int) + +#define IOC_NVRAM_GET_OFFSET _IOWR('p', 0x42, int) /* Get NVRAM partition offset */ +#define IOC_NVRAM_SYNC _IO('p', 0x43) /* Sync NVRAM image */ + +#endif /* _ASM_POWERPC_NVRAM_H */ diff --git a/include/asm-powerpc/paca.h b/include/asm-powerpc/paca.h new file mode 100644 index 000000000000..92c765c35bd0 --- /dev/null +++ b/include/asm-powerpc/paca.h @@ -0,0 +1,120 @@ +/* + * include/asm-powerpc/paca.h + * + * This control block defines the PACA which defines the processor + * specific data for each logical processor on the system. + * There are some pointers defined that are utilized by PLIC. + * + * C 2001 PPC 64 Team, IBM Corp + * + * 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. + */ +#ifndef _ASM_POWERPC_PACA_H +#define _ASM_POWERPC_PACA_H + +#include <linux/config.h> +#include <asm/types.h> +#include <asm/lppaca.h> +#include <asm/iseries/it_lp_reg_save.h> +#include <asm/mmu.h> + +register struct paca_struct *local_paca asm("r13"); +#define get_paca() local_paca + +struct task_struct; + +/* + * Defines the layout of the paca. + * + * This structure is not directly accessed by firmware or the service + * processor except for the first two pointers that point to the + * lppaca area and the ItLpRegSave area for this CPU. Both the + * lppaca and ItLpRegSave objects are currently contained within the + * PACA but they do not need to be. + */ +struct paca_struct { + /* + * Because hw_cpu_id, unlike other paca fields, is accessed + * routinely from other CPUs (from the IRQ code), we stick to + * read-only (after boot) fields in the first cacheline to + * avoid cacheline bouncing. + */ + + /* + * MAGIC: These first two pointers can't be moved - they're + * accessed by the firmware + */ + struct lppaca *lppaca_ptr; /* Pointer to LpPaca for PLIC */ + struct ItLpRegSave *reg_save_ptr; /* Pointer to LpRegSave for PLIC */ + + /* + * MAGIC: the spinlock functions in arch/ppc64/lib/locks.c + * load lock_token and paca_index with a single lwz + * instruction. They must travel together and be properly + * aligned. + */ + u16 lock_token; /* Constant 0x8000, used in locks */ + u16 paca_index; /* Logical processor number */ + + u32 default_decr; /* Default decrementer value */ + u64 kernel_toc; /* Kernel TOC address */ + u64 stab_real; /* Absolute address of segment table */ + u64 stab_addr; /* Virtual address of segment table */ + void *emergency_sp; /* pointer to emergency stack */ + s16 hw_cpu_id; /* Physical processor number */ + u8 cpu_start; /* At startup, processor spins until */ + /* this becomes non-zero. */ + + /* + * Now, starting in cacheline 2, the exception save areas + */ + /* used for most interrupts/exceptions */ + u64 exgen[10] __attribute__((aligned(0x80))); + u64 exmc[10]; /* used for machine checks */ + u64 exslb[10]; /* used for SLB/segment table misses + * on the linear mapping */ +#ifdef CONFIG_PPC_64K_PAGES + pgd_t *pgdir; +#endif /* CONFIG_PPC_64K_PAGES */ + + mm_context_t context; + u16 slb_cache[SLB_CACHE_ENTRIES]; + u16 slb_cache_ptr; + + /* + * then miscellaneous read-write fields + */ + struct task_struct *__current; /* Pointer to current */ + u64 kstack; /* Saved Kernel stack addr */ + u64 stab_rr; /* stab/slb round-robin counter */ + u64 next_jiffy_update_tb; /* TB value for next jiffy update */ + u64 saved_r1; /* r1 save for RTAS calls */ + u64 saved_msr; /* MSR saved here by enter_rtas */ + u8 proc_enabled; /* irq soft-enable flag */ + + /* not yet used */ + u64 exdsi[8]; /* used for linear mapping hash table misses */ + + /* + * iSeries structure which the hypervisor knows about - + * this structure should not cross a page boundary. + * The vpa_init/register_vpa call is now known to fail if the + * lppaca structure crosses a page boundary. + * The lppaca is also used on POWER5 pSeries boxes. + * The lppaca is 640 bytes long, and cannot readily change + * since the hypervisor knows its layout, so a 1kB + * alignment will suffice to ensure that it doesn't + * cross a page boundary. + */ + struct lppaca lppaca __attribute__((__aligned__(0x400))); +#ifdef CONFIG_PPC_ISERIES + struct ItLpRegSave reg_save; +#endif +}; + +extern struct paca_struct paca[]; + +#endif /* _ASM_POWERPC_PACA_H */ diff --git a/include/asm-powerpc/page.h b/include/asm-powerpc/page.h new file mode 100644 index 000000000000..18c1e5ee81a3 --- /dev/null +++ b/include/asm-powerpc/page.h @@ -0,0 +1,179 @@ +#ifndef _ASM_POWERPC_PAGE_H +#define _ASM_POWERPC_PAGE_H + +/* + * Copyright (C) 2001,2005 IBM Corporation. + * + * 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. + */ + +#ifdef __KERNEL__ +#include <linux/config.h> +#include <asm/asm-compat.h> + +/* + * On PPC32 page size is 4K. For PPC64 we support either 4K or 64K software + * page size. When using 64K pages however, whether we are really supporting + * 64K pages in HW or not is irrelevant to those definitions. + */ +#ifdef CONFIG_PPC_64K_PAGES +#define PAGE_SHIFT 16 +#else +#define PAGE_SHIFT 12 +#endif + +#define PAGE_SIZE (ASM_CONST(1) << PAGE_SHIFT) + +/* We do define AT_SYSINFO_EHDR but don't use the gate mechanism */ +#define __HAVE_ARCH_GATE_AREA 1 + +/* + * Subtle: (1 << PAGE_SHIFT) is an int, not an unsigned long. So if we + * assign PAGE_MASK to a larger type it gets extended the way we want + * (i.e. with 1s in the high bits) + */ +#define PAGE_MASK (~((1 << PAGE_SHIFT) - 1)) + +#define PAGE_OFFSET ASM_CONST(CONFIG_KERNEL_START) +#define KERNELBASE PAGE_OFFSET + +#ifdef CONFIG_DISCONTIGMEM +#define page_to_pfn(page) discontigmem_page_to_pfn(page) +#define pfn_to_page(pfn) discontigmem_pfn_to_page(pfn) +#define pfn_valid(pfn) discontigmem_pfn_valid(pfn) +#endif + +#ifdef CONFIG_FLATMEM +#define pfn_to_page(pfn) (mem_map + (pfn)) +#define page_to_pfn(page) ((unsigned long)((page) - mem_map)) +#define pfn_valid(pfn) ((pfn) < max_mapnr) +#endif + +#define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT) +#define pfn_to_kaddr(pfn) __va((pfn) << PAGE_SHIFT) +#define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT) + +#define __va(x) ((void *)((unsigned long)(x) + KERNELBASE)) +#define __pa(x) ((unsigned long)(x) - PAGE_OFFSET) + +/* + * Unfortunately the PLT is in the BSS in the PPC32 ELF ABI, + * and needs to be executable. This means the whole heap ends + * up being executable. + */ +#define VM_DATA_DEFAULT_FLAGS32 (VM_READ | VM_WRITE | VM_EXEC | \ + VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) + +#define VM_DATA_DEFAULT_FLAGS64 (VM_READ | VM_WRITE | \ + VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) + +#ifdef __powerpc64__ +#include <asm/page_64.h> +#else +#include <asm/page_32.h> +#endif + +/* align addr on a size boundary - adjust address up/down if needed */ +#define _ALIGN_UP(addr,size) (((addr)+((size)-1))&(~((size)-1))) +#define _ALIGN_DOWN(addr,size) ((addr)&(~((size)-1))) + +/* align addr on a size boundary - adjust address up if needed */ +#define _ALIGN(addr,size) _ALIGN_UP(addr,size) + +/* to align the pointer to the (next) page boundary */ +#define PAGE_ALIGN(addr) _ALIGN(addr, PAGE_SIZE) + +#ifndef __ASSEMBLY__ + +#undef STRICT_MM_TYPECHECKS + +#ifdef STRICT_MM_TYPECHECKS +/* These are used to make use of C type-checking. */ + +/* PTE level */ +typedef struct { pte_basic_t pte; } pte_t; +#define pte_val(x) ((x).pte) +#define __pte(x) ((pte_t) { (x) }) + +/* 64k pages additionally define a bigger "real PTE" type that gathers + * the "second half" part of the PTE for pseudo 64k pages + */ +#ifdef CONFIG_PPC_64K_PAGES +typedef struct { pte_t pte; unsigned long hidx; } real_pte_t; +#else +typedef struct { pte_t pte; } real_pte_t; +#endif + +/* PMD level */ +typedef struct { unsigned long pmd; } pmd_t; +#define pmd_val(x) ((x).pmd) +#define __pmd(x) ((pmd_t) { (x) }) + +/* PUD level exusts only on 4k pages */ +#ifndef CONFIG_PPC_64K_PAGES +typedef struct { unsigned long pud; } pud_t; +#define pud_val(x) ((x).pud) +#define __pud(x) ((pud_t) { (x) }) +#endif + +/* PGD level */ +typedef struct { unsigned long pgd; } pgd_t; +#define pgd_val(x) ((x).pgd) +#define __pgd(x) ((pgd_t) { (x) }) + +/* Page protection bits */ +typedef struct { unsigned long pgprot; } pgprot_t; +#define pgprot_val(x) ((x).pgprot) +#define __pgprot(x) ((pgprot_t) { (x) }) + +#else + +/* + * .. while these make it easier on the compiler + */ + +typedef pte_basic_t pte_t; +#define pte_val(x) (x) +#define __pte(x) (x) + +#ifdef CONFIG_PPC_64K_PAGES +typedef struct { pte_t pte; unsigned long hidx; } real_pte_t; +#else +typedef unsigned long real_pte_t; +#endif + + +typedef unsigned long pmd_t; +#define pmd_val(x) (x) +#define __pmd(x) (x) + +#ifndef CONFIG_PPC_64K_PAGES +typedef unsigned long pud_t; +#define pud_val(x) (x) +#define __pud(x) (x) +#endif + +typedef unsigned long pgd_t; +#define pgd_val(x) (x) +#define pgprot_val(x) (x) + +typedef unsigned long pgprot_t; +#define __pgd(x) (x) +#define __pgprot(x) (x) + +#endif + +struct page; +extern void clear_user_page(void *page, unsigned long vaddr, struct page *pg); +extern void copy_user_page(void *to, void *from, unsigned long vaddr, + struct page *p); +extern int page_is_ram(unsigned long pfn); + +#endif /* __ASSEMBLY__ */ + +#endif /* __KERNEL__ */ + +#endif /* _ASM_POWERPC_PAGE_H */ diff --git a/include/asm-powerpc/page_32.h b/include/asm-powerpc/page_32.h new file mode 100644 index 000000000000..7259cfd85da9 --- /dev/null +++ b/include/asm-powerpc/page_32.h @@ -0,0 +1,40 @@ +#ifndef _ASM_POWERPC_PAGE_32_H +#define _ASM_POWERPC_PAGE_32_H + +#define VM_DATA_DEFAULT_FLAGS VM_DATA_DEFAULT_FLAGS32 + +#define PPC_MEMSTART 0 + +#ifndef __ASSEMBLY__ +/* + * The basic type of a PTE - 64 bits for those CPUs with > 32 bit + * physical addressing. For now this just the IBM PPC440. + */ +#ifdef CONFIG_PTE_64BIT +typedef unsigned long long pte_basic_t; +#define PTE_SHIFT (PAGE_SHIFT - 3) /* 512 ptes per page */ +#define PTE_FMT "%16Lx" +#else +typedef unsigned long pte_basic_t; +#define PTE_SHIFT (PAGE_SHIFT - 2) /* 1024 ptes per page */ +#define PTE_FMT "%.8lx" +#endif + +struct page; +extern void clear_pages(void *page, int order); +static inline void clear_page(void *page) { clear_pages(page, 0); } +extern void copy_page(void *to, void *from); + +/* Pure 2^n version of get_order */ +extern __inline__ int get_order(unsigned long size) +{ + int lz; + + size = (size-1) >> PAGE_SHIFT; + asm ("cntlzw %0,%1" : "=r" (lz) : "r" (size)); + return 32 - lz; +} + +#endif /* __ASSEMBLY__ */ + +#endif /* _ASM_POWERPC_PAGE_32_H */ diff --git a/include/asm-powerpc/page_64.h b/include/asm-powerpc/page_64.h new file mode 100644 index 000000000000..c16f106b5373 --- /dev/null +++ b/include/asm-powerpc/page_64.h @@ -0,0 +1,174 @@ +#ifndef _ASM_POWERPC_PAGE_64_H +#define _ASM_POWERPC_PAGE_64_H + +/* + * Copyright (C) 2001 PPC64 Team, IBM Corp + * + * 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. + */ + +/* + * We always define HW_PAGE_SHIFT to 12 as use of 64K pages remains Linux + * specific, every notion of page number shared with the firmware, TCEs, + * iommu, etc... still uses a page size of 4K. + */ +#define HW_PAGE_SHIFT 12 +#define HW_PAGE_SIZE (ASM_CONST(1) << HW_PAGE_SHIFT) +#define HW_PAGE_MASK (~(HW_PAGE_SIZE-1)) + +/* + * PAGE_FACTOR is the number of bits factor between PAGE_SHIFT and + * HW_PAGE_SHIFT, that is 4K pages. + */ +#define PAGE_FACTOR (PAGE_SHIFT - HW_PAGE_SHIFT) + +#define REGION_SIZE 4UL +#define REGION_SHIFT 60UL +#define REGION_MASK (((1UL<<REGION_SIZE)-1UL)<<REGION_SHIFT) + +#define VMALLOCBASE ASM_CONST(0xD000000000000000) +#define VMALLOC_REGION_ID (VMALLOCBASE >> REGION_SHIFT) +#define KERNEL_REGION_ID (KERNELBASE >> REGION_SHIFT) +#define USER_REGION_ID (0UL) +#define REGION_ID(ea) (((unsigned long)(ea)) >> REGION_SHIFT) + +/* Segment size */ +#define SID_SHIFT 28 +#define SID_MASK 0xfffffffffUL +#define ESID_MASK 0xfffffffff0000000UL +#define GET_ESID(x) (((x) >> SID_SHIFT) & SID_MASK) + +#ifndef __ASSEMBLY__ +#include <asm/cache.h> + +typedef unsigned long pte_basic_t; + +static __inline__ void clear_page(void *addr) +{ + unsigned long lines, line_size; + + line_size = ppc64_caches.dline_size; + lines = ppc64_caches.dlines_per_page; + + __asm__ __volatile__( + "mtctr %1 # clear_page\n\ +1: dcbz 0,%0\n\ + add %0,%0,%3\n\ + bdnz+ 1b" + : "=r" (addr) + : "r" (lines), "0" (addr), "r" (line_size) + : "ctr", "memory"); +} + +extern void copy_4K_page(void *to, void *from); + +#ifdef CONFIG_PPC_64K_PAGES +static inline void copy_page(void *to, void *from) +{ + unsigned int i; + for (i=0; i < (1 << (PAGE_SHIFT - 12)); i++) { + copy_4K_page(to, from); + to += 4096; + from += 4096; + } +} +#else /* CONFIG_PPC_64K_PAGES */ +static inline void copy_page(void *to, void *from) +{ + copy_4K_page(to, from); +} +#endif /* CONFIG_PPC_64K_PAGES */ + +/* Log 2 of page table size */ +extern u64 ppc64_pft_size; + +/* Large pages size */ +extern unsigned int HPAGE_SHIFT; +#define HPAGE_SIZE ((1UL) << HPAGE_SHIFT) +#define HPAGE_MASK (~(HPAGE_SIZE - 1)) +#define HUGETLB_PAGE_ORDER (HPAGE_SHIFT - PAGE_SHIFT) + +#endif /* __ASSEMBLY__ */ + +#ifdef CONFIG_HUGETLB_PAGE + +#define HTLB_AREA_SHIFT 40 +#define HTLB_AREA_SIZE (1UL << HTLB_AREA_SHIFT) +#define GET_HTLB_AREA(x) ((x) >> HTLB_AREA_SHIFT) + +#define LOW_ESID_MASK(addr, len) (((1U << (GET_ESID(addr+len-1)+1)) \ + - (1U << GET_ESID(addr))) & 0xffff) +#define HTLB_AREA_MASK(addr, len) (((1U << (GET_HTLB_AREA(addr+len-1)+1)) \ + - (1U << GET_HTLB_AREA(addr))) & 0xffff) + +#define ARCH_HAS_HUGEPAGE_ONLY_RANGE +#define ARCH_HAS_PREPARE_HUGEPAGE_RANGE +#define ARCH_HAS_SETCLEAR_HUGE_PTE + +#define touches_hugepage_low_range(mm, addr, len) \ + (LOW_ESID_MASK((addr), (len)) & (mm)->context.low_htlb_areas) +#define touches_hugepage_high_range(mm, addr, len) \ + (HTLB_AREA_MASK((addr), (len)) & (mm)->context.high_htlb_areas) + +#define __within_hugepage_low_range(addr, len, segmask) \ + ((LOW_ESID_MASK((addr), (len)) | (segmask)) == (segmask)) +#define within_hugepage_low_range(addr, len) \ + __within_hugepage_low_range((addr), (len), \ + current->mm->context.low_htlb_areas) +#define __within_hugepage_high_range(addr, len, zonemask) \ + ((HTLB_AREA_MASK((addr), (len)) | (zonemask)) == (zonemask)) +#define within_hugepage_high_range(addr, len) \ + __within_hugepage_high_range((addr), (len), \ + current->mm->context.high_htlb_areas) + +#define is_hugepage_only_range(mm, addr, len) \ + (touches_hugepage_high_range((mm), (addr), (len)) || \ + touches_hugepage_low_range((mm), (addr), (len))) +#define HAVE_ARCH_HUGETLB_UNMAPPED_AREA + +#define in_hugepage_area(context, addr) \ + (cpu_has_feature(CPU_FTR_16M_PAGE) && \ + ( ((1 << GET_HTLB_AREA(addr)) & (context).high_htlb_areas) || \ + ( ((addr) < 0x100000000L) && \ + ((1 << GET_ESID(addr)) & (context).low_htlb_areas) ) ) ) + +#else /* !CONFIG_HUGETLB_PAGE */ + +#define in_hugepage_area(mm, addr) 0 + +#endif /* !CONFIG_HUGETLB_PAGE */ + +#ifdef MODULE +#define __page_aligned __attribute__((__aligned__(PAGE_SIZE))) +#else +#define __page_aligned \ + __attribute__((__aligned__(PAGE_SIZE), \ + __section__(".data.page_aligned"))) +#endif + +#define VM_DATA_DEFAULT_FLAGS \ + (test_thread_flag(TIF_32BIT) ? \ + VM_DATA_DEFAULT_FLAGS32 : VM_DATA_DEFAULT_FLAGS64) + +/* + * This is the default if a program doesn't have a PT_GNU_STACK + * program header entry. The PPC64 ELF ABI has a non executable stack + * stack by default, so in the absense of a PT_GNU_STACK program header + * we turn execute permission off. + */ +#define VM_STACK_DEFAULT_FLAGS32 (VM_READ | VM_WRITE | VM_EXEC | \ + VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) + +#define VM_STACK_DEFAULT_FLAGS64 (VM_READ | VM_WRITE | \ + VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) + +#define VM_STACK_DEFAULT_FLAGS \ + (test_thread_flag(TIF_32BIT) ? \ + VM_STACK_DEFAULT_FLAGS32 : VM_STACK_DEFAULT_FLAGS64) + +#include <asm-generic/page.h> + +#endif /* _ASM_POWERPC_PAGE_64_H */ diff --git a/include/asm-powerpc/pmc.h b/include/asm-powerpc/pmc.h index 2f3c3fc2b796..5f41f3a2b293 100644 --- a/include/asm-powerpc/pmc.h +++ b/include/asm-powerpc/pmc.h @@ -22,6 +22,7 @@ #include <asm/ptrace.h> typedef void (*perf_irq_t)(struct pt_regs *); +extern perf_irq_t perf_irq; int reserve_pmc_hardware(perf_irq_t new_perf_irq); void release_pmc_hardware(void); diff --git a/include/asm-powerpc/ppc-pci.h b/include/asm-powerpc/ppc-pci.h index a88728fba8f6..2e36e5a7f4f3 100644 --- a/include/asm-powerpc/ppc-pci.h +++ b/include/asm-powerpc/ppc-pci.h @@ -14,7 +14,6 @@ extern unsigned long isa_io_base; -extern void pci_setup_pci_controller(struct pci_controller *hose); extern void pci_setup_phb_io(struct pci_controller *hose, int primary); extern void pci_setup_phb_io_dynamic(struct pci_controller *hose, int primary); @@ -26,6 +25,10 @@ extern unsigned long find_and_init_phbs(void); extern struct pci_dev *ppc64_isabridge_dev; /* may be NULL if no ISA bus */ +/** Bus Unit ID macros; get low and hi 32-bits of the 64-bit BUID */ +#define BUID_HI(buid) ((buid) >> 32) +#define BUID_LO(buid) ((buid) & 0xffffffff) + /* PCI device_node operations */ struct device_node; typedef void *(*traverse_func)(struct device_node *me, void *data); @@ -34,10 +37,7 @@ void *traverse_pci_devices(struct device_node *start, traverse_func pre, void pci_devs_phb_init(void); void pci_devs_phb_init_dynamic(struct pci_controller *phb); - -/* PCI address cache management routines */ -void pci_addr_cache_insert_device(struct pci_dev *dev); -void pci_addr_cache_remove_device(struct pci_dev *dev); +void __devinit scan_phb(struct pci_controller *hose); /* From rtas_pci.h */ void init_pci_config_tokens (void); @@ -51,4 +51,48 @@ extern unsigned long pci_probe_only; extern unsigned long pci_assign_all_buses; extern int pci_read_irq_line(struct pci_dev *pci_dev); +/* ---- EEH internal-use-only related routines ---- */ +#ifdef CONFIG_EEH +/** + * rtas_set_slot_reset -- unfreeze a frozen slot + * + * Clear the EEH-frozen condition on a slot. This routine + * does this by asserting the PCI #RST line for 1/8th of + * a second; this routine will sleep while the adapter is + * being reset. + */ +void rtas_set_slot_reset (struct pci_dn *); + +/** + * eeh_restore_bars - Restore device configuration info. + * + * A reset of a PCI device will clear out its config space. + * This routines will restore the config space for this + * device, and is children, to values previously obtained + * from the firmware. + */ +void eeh_restore_bars(struct pci_dn *); + +/** + * rtas_configure_bridge -- firmware initialization of pci bridge + * + * Ask the firmware to configure all PCI bridges devices + * located behind the indicated node. Required after a + * pci device reset. Does essentially the same hing as + * eeh_restore_bars, but for brdges, and lets firmware + * do the work. + */ +void rtas_configure_bridge(struct pci_dn *); + +int rtas_write_config(struct pci_dn *, int where, int size, u32 val); + +/** + * mark and clear slots: find "partition endpoint" PE and set or + * clear the flags for each subnode of the PE. + */ +void eeh_mark_slot (struct device_node *dn, int mode_flag); +void eeh_clear_slot (struct device_node *dn, int mode_flag); + +#endif + #endif /* _ASM_POWERPC_PPC_PCI_H */ diff --git a/include/asm-powerpc/ppc_asm.h b/include/asm-powerpc/ppc_asm.h index c534ca41224b..c27baa0563fe 100644 --- a/include/asm-powerpc/ppc_asm.h +++ b/include/asm-powerpc/ppc_asm.h @@ -6,8 +6,13 @@ #include <linux/stringify.h> #include <linux/config.h> +#include <asm/asm-compat.h> -#ifdef __ASSEMBLY__ +#ifndef __ASSEMBLY__ +#error __FILE__ should only be used in assembler files +#else + +#define SZL (BITS_PER_LONG/8) /* * Macros for storing registers into and loading registers from @@ -184,12 +189,6 @@ n: oris reg,reg,(label)@h; \ ori reg,reg,(label)@l; -/* operations for longs and pointers */ -#define LDL ld -#define STL std -#define CMPI cmpdi -#define SZL 8 - /* offsets for stack frame layout */ #define LRSAVE 16 @@ -203,12 +202,6 @@ n: #define OFF(name) name@l -/* operations for longs and pointers */ -#define LDL lwz -#define STL stw -#define CMPI cmpwi -#define SZL 4 - /* offsets for stack frame layout */ #define LRSAVE 4 @@ -266,15 +259,6 @@ END_FTR_SECTION_IFCLR(CPU_FTR_601) #endif -#ifdef CONFIG_IBM405_ERR77 -#define PPC405_ERR77(ra,rb) dcbt ra, rb; -#define PPC405_ERR77_SYNC sync; -#else -#define PPC405_ERR77(ra,rb) -#define PPC405_ERR77_SYNC -#endif - - #ifdef CONFIG_IBM440EP_ERR42 #define PPC440EP_ERR42 isync #else @@ -502,17 +486,6 @@ END_FTR_SECTION_IFCLR(CPU_FTR_601) #define N_SLINE 68 #define N_SO 100 -#define ASM_CONST(x) x -#else - #define __ASM_CONST(x) x##UL - #define ASM_CONST(x) __ASM_CONST(x) - -#ifdef CONFIG_PPC64 -#define DATAL ".llong" -#else -#define DATAL ".long" -#endif - #endif /* __ASSEMBLY__ */ #endif /* _ASM_POWERPC_PPC_ASM_H */ diff --git a/include/asm-powerpc/processor.h b/include/asm-powerpc/processor.h index 1dc4bf7b52b3..d12382d292d4 100644 --- a/include/asm-powerpc/processor.h +++ b/include/asm-powerpc/processor.h @@ -17,65 +17,71 @@ #include <linux/compiler.h> #include <asm/ptrace.h> #include <asm/types.h> -#ifdef CONFIG_PPC64 -#include <asm/systemcfg.h> -#endif -#ifdef CONFIG_PPC32 -/* 32-bit platform types */ -/* We only need to define a new _MACH_xxx for machines which are part of - * a configuration which supports more than one type of different machine. - * This is currently limited to CONFIG_PPC_MULTIPLATFORM and CHRP/PReP/PMac. - * -- Tom +/* We do _not_ want to define new machine types at all, those must die + * in favor of using the device-tree + * -- BenH. */ -#define _MACH_prep 0x00000001 -#define _MACH_Pmac 0x00000002 /* pmac or pmac clone (non-chrp) */ -#define _MACH_chrp 0x00000004 /* chrp machine */ -/* see residual.h for these */ +/* Platforms codes (to be obsoleted) */ +#define PLATFORM_PSERIES 0x0100 +#define PLATFORM_PSERIES_LPAR 0x0101 +#define PLATFORM_ISERIES_LPAR 0x0201 +#define PLATFORM_LPAR 0x0001 +#define PLATFORM_POWERMAC 0x0400 +#define PLATFORM_MAPLE 0x0500 +#define PLATFORM_PREP 0x0600 +#define PLATFORM_CHRP 0x0700 +#define PLATFORM_CELL 0x1000 + +/* Compat platform codes for 32 bits */ +#define _MACH_prep PLATFORM_PREP +#define _MACH_Pmac PLATFORM_POWERMAC +#define _MACH_chrp PLATFORM_CHRP + +/* PREP sub-platform types see residual.h for these */ #define _PREP_Motorola 0x01 /* motorola prep */ #define _PREP_Firm 0x02 /* firmworks prep */ #define _PREP_IBM 0x00 /* ibm prep */ #define _PREP_Bull 0x03 /* bull prep */ -/* these are arbitrary */ +/* CHRP sub-platform types. These are arbitrary */ #define _CHRP_Motorola 0x04 /* motorola chrp, the cobra */ #define _CHRP_IBM 0x05 /* IBM chrp, the longtrail and longtrail 2 */ #define _CHRP_Pegasos 0x06 /* Genesi/bplan's Pegasos and Pegasos2 */ -#ifdef CONFIG_PPC_MULTIPLATFORM +#define platform_is_pseries() (_machine == PLATFORM_PSERIES || \ + _machine == PLATFORM_PSERIES_LPAR) +#define platform_is_lpar() (!!(_machine & PLATFORM_LPAR)) + +#if defined(CONFIG_PPC_MULTIPLATFORM) extern int _machine; +#ifdef CONFIG_PPC32 + /* what kind of prep workstation we are */ extern int _prep_type; extern int _chrp_type; /* * This is used to identify the board type from a given PReP board - * vendor. Board revision is also made available. + * vendor. Board revision is also made available. This will be moved + * elsewhere soon */ extern unsigned char ucSystemType; extern unsigned char ucBoardRev; extern unsigned char ucBoardRevMaj, ucBoardRevMin; + +#endif /* CONFIG_PPC32 */ + +#elif defined(CONFIG_PPC_ISERIES) +/* + * iSeries is soon to become MULTIPLATFORM hopefully ... + */ +#define _machine PLATFORM_ISERIES_LPAR #else #define _machine 0 #endif /* CONFIG_PPC_MULTIPLATFORM */ -#endif /* CONFIG_PPC32 */ - -#ifdef CONFIG_PPC64 -/* Platforms supported by PPC64 */ -#define PLATFORM_PSERIES 0x0100 -#define PLATFORM_PSERIES_LPAR 0x0101 -#define PLATFORM_ISERIES_LPAR 0x0201 -#define PLATFORM_LPAR 0x0001 -#define PLATFORM_POWERMAC 0x0400 -#define PLATFORM_MAPLE 0x0500 -#define PLATFORM_CELL 0x1000 - -/* Compatibility with drivers coming from PPC32 world */ -#define _machine (systemcfg->platform) -#define _MACH_Pmac PLATFORM_POWERMAC -#endif /* * Default implementation of macro that returns current @@ -171,8 +177,8 @@ struct thread_struct { #ifdef CONFIG_PPC64 unsigned long start_tb; /* Start purr when proc switched in */ unsigned long accum_tb; /* Total accumilated purr for process */ - unsigned long vdso_base; /* base of the vDSO library */ #endif + unsigned long vdso_base; /* base of the vDSO library */ unsigned long dabr; /* Data address breakpoint register */ #ifdef CONFIG_ALTIVEC /* Complete AltiVec register set */ diff --git a/include/asm-powerpc/prom.h b/include/asm-powerpc/prom.h index 7587bf5f38c6..f999df1c5c90 100644 --- a/include/asm-powerpc/prom.h +++ b/include/asm-powerpc/prom.h @@ -203,7 +203,7 @@ extern int prom_n_addr_cells(struct device_node* np); extern int prom_n_size_cells(struct device_node* np); extern int prom_n_intr_cells(struct device_node* np); extern void prom_get_irq_senses(unsigned char *senses, int off, int max); -extern void prom_add_property(struct device_node* np, struct property* prop); +extern int prom_add_property(struct device_node* np, struct property* prop); #ifdef CONFIG_PPC32 /* diff --git a/include/asm-powerpc/reg.h b/include/asm-powerpc/reg.h index da848412f11b..eb392d038ed7 100644 --- a/include/asm-powerpc/reg.h +++ b/include/asm-powerpc/reg.h @@ -16,7 +16,11 @@ /* Pickup Book E specific registers. */ #if defined(CONFIG_BOOKE) || defined(CONFIG_40x) #include <asm/reg_booke.h> -#endif +#endif /* CONFIG_BOOKE || CONFIG_40x */ + +#ifdef CONFIG_8xx +#include <asm/reg_8xx.h> +#endif /* CONFIG_8xx */ #define MSR_SF_LG 63 /* Enable 64 bit mode */ #define MSR_ISF_LG 61 /* Interrupt 64b mode valid on 630 */ @@ -359,6 +363,7 @@ #define SPRN_RPA 0x3D6 /* Required Physical Address Register */ #define SPRN_SDA 0x3BF /* Sampled Data Address Register */ #define SPRN_SDR1 0x019 /* MMU Hash Base Register */ +#define SPRN_ASR 0x118 /* Address Space Register */ #define SPRN_SIA 0x3BB /* Sampled Instruction Address Register */ #define SPRN_SPRG0 0x110 /* Special Purpose Register General 0 */ #define SPRN_SPRG1 0x111 /* Special Purpose Register General 1 */ @@ -396,6 +401,9 @@ #define SPRN_VRSAVE 0x100 /* Vector Register Save Register */ #define SPRN_XER 0x001 /* Fixed Point Exception Register */ +#define SPRN_SCOMC 0x114 /* SCOM Access Control */ +#define SPRN_SCOMD 0x115 /* SCOM Access DATA */ + /* Performance monitor SPRs */ #ifdef CONFIG_PPC64 #define SPRN_MMCR0 795 @@ -594,7 +602,11 @@ static inline void ppc64_runlatch_off(void) mtspr(SPRN_CTRLT, ctrl); } } -#endif + +extern unsigned long scom970_read(unsigned int address); +extern void scom970_write(unsigned int address, unsigned long value); + +#endif /* CONFIG_PPC64 */ #define __get_SP() ({unsigned long sp; \ asm volatile("mr %0,1": "=r" (sp)); sp;}) diff --git a/include/asm-powerpc/reg_8xx.h b/include/asm-powerpc/reg_8xx.h new file mode 100644 index 000000000000..e8ea346b21d3 --- /dev/null +++ b/include/asm-powerpc/reg_8xx.h @@ -0,0 +1,42 @@ +/* + * Contains register definitions common to PowerPC 8xx CPUs. Notice + */ +#ifndef _ASM_POWERPC_REG_8xx_H +#define _ASM_POWERPC_REG_8xx_H + +/* Cache control on the MPC8xx is provided through some additional + * special purpose registers. + */ +#define SPRN_IC_CST 560 /* Instruction cache control/status */ +#define SPRN_IC_ADR 561 /* Address needed for some commands */ +#define SPRN_IC_DAT 562 /* Read-only data register */ +#define SPRN_DC_CST 568 /* Data cache control/status */ +#define SPRN_DC_ADR 569 /* Address needed for some commands */ +#define SPRN_DC_DAT 570 /* Read-only data register */ + +/* Commands. Only the first few are available to the instruction cache. +*/ +#define IDC_ENABLE 0x02000000 /* Cache enable */ +#define IDC_DISABLE 0x04000000 /* Cache disable */ +#define IDC_LDLCK 0x06000000 /* Load and lock */ +#define IDC_UNLINE 0x08000000 /* Unlock line */ +#define IDC_UNALL 0x0a000000 /* Unlock all */ +#define IDC_INVALL 0x0c000000 /* Invalidate all */ + +#define DC_FLINE 0x0e000000 /* Flush data cache line */ +#define DC_SFWT 0x01000000 /* Set forced writethrough mode */ +#define DC_CFWT 0x03000000 /* Clear forced writethrough mode */ +#define DC_SLES 0x05000000 /* Set little endian swap mode */ +#define DC_CLES 0x07000000 /* Clear little endian swap mode */ + +/* Status. +*/ +#define IDC_ENABLED 0x80000000 /* Cache is enabled */ +#define IDC_CERR1 0x00200000 /* Cache error 1 */ +#define IDC_CERR2 0x00100000 /* Cache error 2 */ +#define IDC_CERR3 0x00080000 /* Cache error 3 */ + +#define DC_DFWT 0x40000000 /* Data cache is forced write through */ +#define DC_LES 0x20000000 /* Caches are little endian mode */ + +#endif /* _ASM_POWERPC_REG_8xx_H */ diff --git a/include/asm-powerpc/serial.h b/include/asm-powerpc/serial.h new file mode 100644 index 000000000000..b273d630b32f --- /dev/null +++ b/include/asm-powerpc/serial.h @@ -0,0 +1,18 @@ +/* + * 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. + */ +#ifndef _ASM_POWERPC_SERIAL_H +#define _ASM_POWERPC_SERIAL_H + +/* + * Serial ports are not listed here, because they are discovered + * through the device tree. + */ + +/* Default baud base if not found in device-tree */ +#define BASE_BAUD ( 1843200 / 16 ) + +#endif /* _PPC64_SERIAL_H */ diff --git a/include/asm-powerpc/signal.h b/include/asm-powerpc/signal.h new file mode 100644 index 000000000000..694c8d2dab87 --- /dev/null +++ b/include/asm-powerpc/signal.h @@ -0,0 +1,150 @@ +#ifndef _ASM_POWERPC_SIGNAL_H +#define _ASM_POWERPC_SIGNAL_H + +#include <linux/types.h> +#include <linux/config.h> + +#define _NSIG 64 +#define _NSIG_BPW BITS_PER_LONG +#define _NSIG_WORDS (_NSIG / _NSIG_BPW) + +typedef unsigned long old_sigset_t; /* at least 32 bits */ + +typedef struct { + unsigned long sig[_NSIG_WORDS]; +} sigset_t; + +#define SIGHUP 1 +#define SIGINT 2 +#define SIGQUIT 3 +#define SIGILL 4 +#define SIGTRAP 5 +#define SIGABRT 6 +#define SIGIOT 6 +#define SIGBUS 7 +#define SIGFPE 8 +#define SIGKILL 9 +#define SIGUSR1 10 +#define SIGSEGV 11 +#define SIGUSR2 12 +#define SIGPIPE 13 +#define SIGALRM 14 +#define SIGTERM 15 +#define SIGSTKFLT 16 +#define SIGCHLD 17 +#define SIGCONT 18 +#define SIGSTOP 19 +#define SIGTSTP 20 +#define SIGTTIN 21 +#define SIGTTOU 22 +#define SIGURG 23 +#define SIGXCPU 24 +#define SIGXFSZ 25 +#define SIGVTALRM 26 +#define SIGPROF 27 +#define SIGWINCH 28 +#define SIGIO 29 +#define SIGPOLL SIGIO +/* +#define SIGLOST 29 +*/ +#define SIGPWR 30 +#define SIGSYS 31 +#define SIGUNUSED 31 + +/* These should not be considered constants from userland. */ +#define SIGRTMIN 32 +#define SIGRTMAX _NSIG + +/* + * SA_FLAGS values: + * + * SA_ONSTACK is not currently supported, but will allow sigaltstack(2). + * SA_INTERRUPT is a no-op, but left due to historical reasons. Use the + * SA_RESTART flag to get restarting signals (which were the default long ago) + * SA_NOCLDSTOP flag to turn off SIGCHLD when children stop. + * SA_RESETHAND clears the handler when the signal is delivered. + * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies. + * SA_NODEFER prevents the current signal from being masked in the handler. + * + * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single + * Unix names RESETHAND and NODEFER respectively. + */ +#define SA_NOCLDSTOP 0x00000001U +#define SA_NOCLDWAIT 0x00000002U +#define SA_SIGINFO 0x00000004U +#define SA_ONSTACK 0x08000000U +#define SA_RESTART 0x10000000U +#define SA_NODEFER 0x40000000U +#define SA_RESETHAND 0x80000000U + +#define SA_NOMASK SA_NODEFER +#define SA_ONESHOT SA_RESETHAND +#define SA_INTERRUPT 0x20000000u /* dummy -- ignored */ + +#define SA_RESTORER 0x04000000U + +/* + * sigaltstack controls + */ +#define SS_ONSTACK 1 +#define SS_DISABLE 2 + +#define MINSIGSTKSZ 2048 +#define SIGSTKSZ 8192 + +#include <asm-generic/signal.h> + +struct old_sigaction { + __sighandler_t sa_handler; + old_sigset_t sa_mask; + unsigned long sa_flags; + __sigrestore_t sa_restorer; +}; + +struct sigaction { + __sighandler_t sa_handler; + unsigned long sa_flags; + __sigrestore_t sa_restorer; + sigset_t sa_mask; /* mask last for extensibility */ +}; + +struct k_sigaction { + struct sigaction sa; +}; + +typedef struct sigaltstack { + void __user *ss_sp; + int ss_flags; + size_t ss_size; +} stack_t; + +#ifdef __KERNEL__ +struct pt_regs; +extern int do_signal(sigset_t *oldset, struct pt_regs *regs); +extern int do_signal32(sigset_t *oldset, struct pt_regs *regs); +#define ptrace_signal_deliver(regs, cookie) do { } while (0) +#endif /* __KERNEL__ */ + +#ifndef __powerpc64__ +/* + * These are parameters to dbg_sigreturn syscall. They enable or + * disable certain debugging things that can be done from signal + * handlers. The dbg_sigreturn syscall *must* be called from a + * SA_SIGINFO signal so the ucontext can be passed to it. It takes an + * array of struct sig_dbg_op, which has the debug operations to + * perform before returning from the signal. + */ +struct sig_dbg_op { + int dbg_type; + unsigned long dbg_value; +}; + +/* Enable or disable single-stepping. The value sets the state. */ +#define SIG_DBG_SINGLE_STEPPING 1 + +/* Enable or disable branch tracing. The value sets the state. */ +#define SIG_DBG_BRANCH_TRACING 2 +#endif /* ! __powerpc64__ */ + +#endif /* _ASM_POWERPC_SIGNAL_H */ diff --git a/include/asm-powerpc/smp.h b/include/asm-powerpc/smp.h index 8bcdd0faefea..98581e5a8279 100644 --- a/include/asm-powerpc/smp.h +++ b/include/asm-powerpc/smp.h @@ -86,7 +86,6 @@ extern void __cpu_die(unsigned int cpu); #else /* for UP */ #define smp_setup_cpu_maps() -#define smp_release_cpus() #endif /* CONFIG_SMP */ @@ -94,6 +93,9 @@ extern void __cpu_die(unsigned int cpu); #define get_hard_smp_processor_id(CPU) (paca[(CPU)].hw_cpu_id) #define set_hard_smp_processor_id(CPU, VAL) \ do { (paca[(CPU)].hw_cpu_id = (VAL)); } while (0) + +extern void smp_release_cpus(void); + #else /* 32-bit */ #ifndef CONFIG_SMP diff --git a/include/asm-powerpc/smu.h b/include/asm-powerpc/smu.h index dee8eefe47bc..76c29a9784dd 100644 --- a/include/asm-powerpc/smu.h +++ b/include/asm-powerpc/smu.h @@ -20,16 +20,52 @@ /* * Partition info commands * - * I do not know what those are for at this point + * These commands are used to retreive the sdb-partition-XX datas from + * the SMU. The lenght is always 2. First byte is the subcommand code + * and second byte is the partition ID. + * + * The reply is 6 bytes: + * + * - 0..1 : partition address + * - 2 : a byte containing the partition ID + * - 3 : length (maybe other bits are rest of header ?) + * + * The data must then be obtained with calls to another command: + * SMU_CMD_MISC_ee_GET_DATABLOCK_REC (described below). */ #define SMU_CMD_PARTITION_COMMAND 0x3e +#define SMU_CMD_PARTITION_LATEST 0x01 +#define SMU_CMD_PARTITION_BASE 0x02 +#define SMU_CMD_PARTITION_UPDATE 0x03 /* * Fan control * - * This is a "mux" for fan control commands, first byte is the - * "sub" command. + * This is a "mux" for fan control commands. The command seem to + * act differently based on the number of arguments. With 1 byte + * of argument, this seem to be queries for fans status, setpoint, + * etc..., while with 0xe arguments, we will set the fans speeds. + * + * Queries (1 byte arg): + * --------------------- + * + * arg=0x01: read RPM fans status + * arg=0x02: read RPM fans setpoint + * arg=0x11: read PWM fans status + * arg=0x12: read PWM fans setpoint + * + * the "status" queries return the current speed while the "setpoint" ones + * return the programmed/target speed. It _seems_ that the result is a bit + * mask in the first byte of active/available fans, followed by 6 words (16 + * bits) containing the requested speed. + * + * Setpoint (14 bytes arg): + * ------------------------ + * + * first arg byte is 0 for RPM fans and 0x10 for PWM. Second arg byte is the + * mask of fans affected by the command. Followed by 6 words containing the + * setpoint value for selected fans in the mask (or 0 if mask value is 0) */ #define SMU_CMD_FAN_COMMAND 0x4a @@ -144,7 +180,11 @@ * - lenght 8 ("VSLEWxyz") has 3 additional bytes appended, and is * used to set the voltage slewing point. The SMU replies with "DONE" * I yet have to figure out their exact meaning of those 3 bytes in - * both cases. + * both cases. They seem to be: + * x = processor mask + * y = op. point index + * z = processor freq. step index + * I haven't yet decyphered result codes * */ #define SMU_CMD_POWER_COMMAND 0xaa @@ -152,6 +192,14 @@ #define SMU_CMD_POWER_SHUTDOWN "SHUTDOWN" #define SMU_CMD_POWER_VOLTAGE_SLEW "VSLEW" +/* + * Read ADC sensors + * + * This command takes one byte of parameter: the sensor ID (or "reg" + * value in the device-tree) and returns a 16 bits value + */ +#define SMU_CMD_READ_ADC 0xd8 + /* Misc commands * * This command seem to be a grab bag of various things @@ -172,6 +220,25 @@ * Misc commands * * This command seem to be a grab bag of various things + * + * SMU_CMD_MISC_ee_GET_DATABLOCK_REC is used, among others, to + * transfer blocks of data from the SMU. So far, I've decrypted it's + * usage to retreive partition data. In order to do that, you have to + * break your transfer in "chunks" since that command cannot transfer + * more than a chunk at a time. The chunk size used by OF is 0xe bytes, + * but it seems that the darwin driver will let you do 0x1e bytes if + * your "PMU" version is >= 0x30. You can get the "PMU" version apparently + * either in the last 16 bits of property "smu-version-pmu" or as the 16 + * bytes at offset 1 of "smu-version-info" + * + * For each chunk, the command takes 7 bytes of arguments: + * byte 0: subcommand code (0x02) + * byte 1: 0x04 (always, I don't know what it means, maybe the address + * space to use or some other nicety. It's hard coded in OF) + * byte 2..5: SMU address of the chunk (big endian 32 bits) + * byte 6: size to transfer (up to max chunk size) + * + * The data is returned directly */ #define SMU_CMD_MISC_ee_COMMAND 0xee #define SMU_CMD_MISC_ee_GET_DATABLOCK_REC 0x02 @@ -333,6 +400,128 @@ extern int smu_queue_i2c(struct smu_i2c_cmd *cmd); #endif /* __KERNEL__ */ + +/* + * - SMU "sdb" partitions informations - + */ + + +/* + * Partition header format + */ +struct smu_sdbp_header { + __u8 id; + __u8 len; + __u8 version; + __u8 flags; +}; + + + /* + * demangle 16 and 32 bits integer in some SMU partitions + * (currently, afaik, this concerns only the FVT partition + * (0x12) + */ +#define SMU_U16_MIX(x) le16_to_cpu(x); +#define SMU_U32_MIX(x) ((((x) & 0xff00ff00u) >> 8)|(((x) & 0x00ff00ffu) << 8)) + + +/* This is the definition of the SMU sdb-partition-0x12 table (called + * CPU F/V/T operating points in Darwin). The definition for all those + * SMU tables should be moved to some separate file + */ +#define SMU_SDB_FVT_ID 0x12 + +struct smu_sdbp_fvt { + __u32 sysclk; /* Base SysClk frequency in Hz for + * this operating point. Value need to + * be unmixed with SMU_U32_MIX() + */ + __u8 pad; + __u8 maxtemp; /* Max temp. supported by this + * operating point + */ + + __u16 volts[3]; /* CPU core voltage for the 3 + * PowerTune modes, a mode with + * 0V = not supported. Value need + * to be unmixed with SMU_U16_MIX() + */ +}; + +/* This partition contains voltage & current sensor calibration + * informations + */ +#define SMU_SDB_CPUVCP_ID 0x21 + +struct smu_sdbp_cpuvcp { + __u16 volt_scale; /* u4.12 fixed point */ + __s16 volt_offset; /* s4.12 fixed point */ + __u16 curr_scale; /* u4.12 fixed point */ + __s16 curr_offset; /* s4.12 fixed point */ + __s32 power_quads[3]; /* s4.28 fixed point */ +}; + +/* This partition contains CPU thermal diode calibration + */ +#define SMU_SDB_CPUDIODE_ID 0x18 + +struct smu_sdbp_cpudiode { + __u16 m_value; /* u1.15 fixed point */ + __s16 b_value; /* s10.6 fixed point */ + +}; + +/* This partition contains Slots power calibration + */ +#define SMU_SDB_SLOTSPOW_ID 0x78 + +struct smu_sdbp_slotspow { + __u16 pow_scale; /* u4.12 fixed point */ + __s16 pow_offset; /* s4.12 fixed point */ +}; + +/* This partition contains machine specific version information about + * the sensor/control layout + */ +#define SMU_SDB_SENSORTREE_ID 0x25 + +struct smu_sdbp_sensortree { + u8 model_id; + u8 unknown[3]; +}; + +/* This partition contains CPU thermal control PID informations. So far + * only single CPU machines have been seen with an SMU, so we assume this + * carries only informations for those + */ +#define SMU_SDB_CPUPIDDATA_ID 0x17 + +struct smu_sdbp_cpupiddata { + u8 unknown1; + u8 target_temp_delta; + u8 unknown2; + u8 history_len; + s16 power_adj; + u16 max_power; + s32 gp,gr,gd; +}; + + +/* Other partitions without known structures */ +#define SMU_SDB_DEBUG_SWITCHES_ID 0x05 + +#ifdef __KERNEL__ +/* + * This returns the pointer to an SMU "sdb" partition data or NULL + * if not found. The data format is described below + */ +extern struct smu_sdbp_header *smu_get_sdb_partition(int id, + unsigned int *size); + +#endif /* __KERNEL__ */ + + /* * - Userland interface - */ @@ -365,8 +554,10 @@ struct smu_user_cmd_hdr __u32 cmdtype; #define SMU_CMDTYPE_SMU 0 /* SMU command */ #define SMU_CMDTYPE_WANTS_EVENTS 1 /* switch fd to events mode */ +#define SMU_CMDTYPE_GET_PARTITION 2 /* retreive an sdb partition */ __u8 cmd; /* SMU command byte */ + __u8 pad[3]; /* padding */ __u32 data_len; /* Lenght of data following */ }; diff --git a/include/asm-powerpc/sparsemem.h b/include/asm-powerpc/sparsemem.h index 1c95ab99deb3..ba1b34fdb967 100644 --- a/include/asm-powerpc/sparsemem.h +++ b/include/asm-powerpc/sparsemem.h @@ -8,8 +8,12 @@ * MAX_PHYSMEM_BITS 2^N: how much memory we can have in that space */ #define SECTION_SIZE_BITS 24 -#define MAX_PHYSADDR_BITS 38 -#define MAX_PHYSMEM_BITS 36 +#define MAX_PHYSADDR_BITS 44 +#define MAX_PHYSMEM_BITS 44 + +#ifdef CONFIG_MEMORY_HOTPLUG +extern void create_section_mapping(unsigned long start, unsigned long end); +#endif /* CONFIG_MEMORY_HOTPLUG */ #endif /* CONFIG_SPARSEMEM */ diff --git a/include/asm-powerpc/system.h b/include/asm-powerpc/system.h index 3536a5cd7a2d..5341b75c75cb 100644 --- a/include/asm-powerpc/system.h +++ b/include/asm-powerpc/system.h @@ -8,7 +8,6 @@ #include <linux/kernel.h> #include <asm/hw_irq.h> -#include <asm/ppc_asm.h> #include <asm/atomic.h> /* @@ -180,6 +179,7 @@ extern struct task_struct *_switch(struct thread_struct *prev, extern unsigned int rtas_data; extern int mem_init_done; /* set on boot once kmalloc can be called */ extern unsigned long memory_limit; +extern unsigned long klimit; extern int powersave_nap; /* set if nap mode can be used in idle loop */ diff --git a/include/asm-powerpc/tce.h b/include/asm-powerpc/tce.h new file mode 100644 index 000000000000..d099d5200f9b --- /dev/null +++ b/include/asm-powerpc/tce.h @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2001 Mike Corrigan & Dave Engebretsen, IBM Corporation + * Rewrite, cleanup: + * Copyright (C) 2004 Olof Johansson <olof@austin.ibm.com>, IBM Corporation + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _ASM_POWERPC_TCE_H +#define _ASM_POWERPC_TCE_H + +/* + * Tces come in two formats, one for the virtual bus and a different + * format for PCI + */ +#define TCE_VB 0 +#define TCE_PCI 1 + +/* TCE page size is 4096 bytes (1 << 12) */ + +#define TCE_SHIFT 12 +#define TCE_PAGE_SIZE (1 << TCE_SHIFT) +#define TCE_PAGE_FACTOR (PAGE_SHIFT - TCE_SHIFT) + + +/* tce_entry + * Used by pSeries (SMP) and iSeries/pSeries LPAR, but there it's + * abstracted so layout is irrelevant. + */ +union tce_entry { + unsigned long te_word; + struct { + unsigned int tb_cacheBits :6; /* Cache hash bits - not used */ + unsigned int tb_rsvd :6; + unsigned long tb_rpn :40; /* Real page number */ + unsigned int tb_valid :1; /* Tce is valid (vb only) */ + unsigned int tb_allio :1; /* Tce is valid for all lps (vb only) */ + unsigned int tb_lpindex :8; /* LpIndex for user of TCE (vb only) */ + unsigned int tb_pciwr :1; /* Write allowed (pci only) */ + unsigned int tb_rdwr :1; /* Read allowed (pci), Write allowed (vb) */ + } te_bits; +#define te_cacheBits te_bits.tb_cacheBits +#define te_rpn te_bits.tb_rpn +#define te_valid te_bits.tb_valid +#define te_allio te_bits.tb_allio +#define te_lpindex te_bits.tb_lpindex +#define te_pciwr te_bits.tb_pciwr +#define te_rdwr te_bits.tb_rdwr +}; + + +#endif /* _ASM_POWERPC_TCE_H */ diff --git a/include/asm-powerpc/topology.h b/include/asm-powerpc/topology.h index 2512e3836bf4..015d28746e1b 100644 --- a/include/asm-powerpc/topology.h +++ b/include/asm-powerpc/topology.h @@ -9,15 +9,7 @@ static inline int cpu_to_node(int cpu) { - int node; - - node = numa_cpu_lookup_table[cpu]; - -#ifdef DEBUG_NUMA - BUG_ON(node == -1); -#endif - - return node; + return numa_cpu_lookup_table[cpu]; } #define parent_node(node) (node) @@ -37,8 +29,6 @@ static inline int node_to_first_cpu(int node) #define pcibus_to_node(node) (-1) #define pcibus_to_cpumask(bus) (cpu_online_map) -#define nr_cpus_node(node) (nr_cpus_in_node[node]) - /* sched_domains SD_NODE_INIT for PPC64 machines */ #define SD_NODE_INIT (struct sched_domain) { \ .span = CPU_MASK_NONE, \ diff --git a/include/asm-powerpc/uaccess.h b/include/asm-powerpc/uaccess.h index 33af730f0d19..3872e924cdd6 100644 --- a/include/asm-powerpc/uaccess.h +++ b/include/asm-powerpc/uaccess.h @@ -120,14 +120,6 @@ struct exception_table_entry { extern long __put_user_bad(void); -#ifdef __powerpc64__ -#define __EX_TABLE_ALIGN "3" -#define __EX_TABLE_TYPE "llong" -#else -#define __EX_TABLE_ALIGN "2" -#define __EX_TABLE_TYPE "long" -#endif - /* * We don't tell gcc that we are accessing memory, but this is OK * because we do not write to any memory gcc knows about, so there @@ -142,11 +134,12 @@ extern long __put_user_bad(void); " b 2b\n" \ ".previous\n" \ ".section __ex_table,\"a\"\n" \ - " .align " __EX_TABLE_ALIGN "\n" \ - " ."__EX_TABLE_TYPE" 1b,3b\n" \ + " .balign %5\n" \ + PPC_LONG "1b,3b\n" \ ".previous" \ : "=r" (err) \ - : "r" (x), "b" (addr), "i" (-EFAULT), "0" (err)) + : "r" (x), "b" (addr), "i" (-EFAULT), "0" (err),\ + "i"(sizeof(unsigned long))) #ifdef __powerpc64__ #define __put_user_asm2(x, ptr, retval) \ @@ -162,12 +155,13 @@ extern long __put_user_bad(void); " b 3b\n" \ ".previous\n" \ ".section __ex_table,\"a\"\n" \ - " .align " __EX_TABLE_ALIGN "\n" \ - " ." __EX_TABLE_TYPE " 1b,4b\n" \ - " ." __EX_TABLE_TYPE " 2b,4b\n" \ + " .balign %5\n" \ + PPC_LONG "1b,4b\n" \ + PPC_LONG "2b,4b\n" \ ".previous" \ : "=r" (err) \ - : "r" (x), "b" (addr), "i" (-EFAULT), "0" (err)) + : "r" (x), "b" (addr), "i" (-EFAULT), "0" (err),\ + "i"(sizeof(unsigned long))) #endif /* __powerpc64__ */ #define __put_user_size(x, ptr, size, retval) \ @@ -213,11 +207,12 @@ extern long __get_user_bad(void); " b 2b\n" \ ".previous\n" \ ".section __ex_table,\"a\"\n" \ - " .align "__EX_TABLE_ALIGN "\n" \ - " ." __EX_TABLE_TYPE " 1b,3b\n" \ + " .balign %5\n" \ + PPC_LONG "1b,3b\n" \ ".previous" \ : "=r" (err), "=r" (x) \ - : "b" (addr), "i" (-EFAULT), "0" (err)) + : "b" (addr), "i" (-EFAULT), "0" (err), \ + "i"(sizeof(unsigned long))) #ifdef __powerpc64__ #define __get_user_asm2(x, addr, err) \ @@ -235,12 +230,13 @@ extern long __get_user_bad(void); " b 3b\n" \ ".previous\n" \ ".section __ex_table,\"a\"\n" \ - " .align " __EX_TABLE_ALIGN "\n" \ - " ." __EX_TABLE_TYPE " 1b,4b\n" \ - " ." __EX_TABLE_TYPE " 2b,4b\n" \ + " .balign %5\n" \ + PPC_LONG "1b,4b\n" \ + PPC_LONG "2b,4b\n" \ ".previous" \ : "=r" (err), "=&r" (x) \ - : "b" (addr), "i" (-EFAULT), "0" (err)) + : "b" (addr), "i" (-EFAULT), "0" (err), \ + "i"(sizeof(unsigned long))) #endif /* __powerpc64__ */ #define __get_user_size(x, ptr, size, retval) \ diff --git a/include/asm-powerpc/udbg.h b/include/asm-powerpc/udbg.h new file mode 100644 index 000000000000..a383383bc4d4 --- /dev/null +++ b/include/asm-powerpc/udbg.h @@ -0,0 +1,31 @@ +/* + * c 2001 PPC 64 Team, IBM Corp + * + * 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. + */ + +#ifndef _ASM_POWERPC_UDBG_H +#define _ASM_POWERPC_UDBG_H + +#include <linux/compiler.h> +#include <linux/init.h> + +extern void (*udbg_putc)(unsigned char c); +extern unsigned char (*udbg_getc)(void); +extern int (*udbg_getc_poll)(void); + +extern void udbg_puts(const char *s); +extern int udbg_write(const char *s, int n); +extern int udbg_read(char *buf, int buflen); + +extern void register_early_udbg_console(void); +extern void udbg_printf(const char *fmt, ...); + +extern void udbg_init_uart(void __iomem *comport, unsigned int speed); + +struct device_node; +extern void udbg_init_scc(struct device_node *np); +#endif /* _ASM_POWERPC_UDBG_H */ diff --git a/include/asm-powerpc/vdso.h b/include/asm-powerpc/vdso.h new file mode 100644 index 000000000000..b9f9118b1607 --- /dev/null +++ b/include/asm-powerpc/vdso.h @@ -0,0 +1,83 @@ +#ifndef __PPC64_VDSO_H__ +#define __PPC64_VDSO_H__ + +#ifdef __KERNEL__ + +/* Default link addresses for the vDSOs */ +#define VDSO32_LBASE 0x100000 +#define VDSO64_LBASE 0x100000 + +/* Default map addresses */ +#define VDSO32_MBASE VDSO32_LBASE +#define VDSO64_MBASE VDSO64_LBASE + +#define VDSO_VERSION_STRING LINUX_2.6.15 + +/* Define if 64 bits VDSO has procedure descriptors */ +#undef VDS64_HAS_DESCRIPTORS + +#ifndef __ASSEMBLY__ + +extern unsigned int vdso64_pages; +extern unsigned int vdso32_pages; + +/* Offsets relative to thread->vdso_base */ +extern unsigned long vdso64_rt_sigtramp; +extern unsigned long vdso32_sigtramp; +extern unsigned long vdso32_rt_sigtramp; + +extern void vdso_init(void); + +#else /* __ASSEMBLY__ */ + +#ifdef __VDSO64__ +#ifdef VDS64_HAS_DESCRIPTORS +#define V_FUNCTION_BEGIN(name) \ + .globl name; \ + .section ".opd","a"; \ + .align 3; \ + name: \ + .quad .name,.TOC.@tocbase,0; \ + .previous; \ + .globl .name; \ + .type .name,@function; \ + .name: \ + +#define V_FUNCTION_END(name) \ + .size .name,.-.name; + +#define V_LOCAL_FUNC(name) (.name) + +#else /* VDS64_HAS_DESCRIPTORS */ + +#define V_FUNCTION_BEGIN(name) \ + .globl name; \ + name: \ + +#define V_FUNCTION_END(name) \ + .size name,.-name; + +#define V_LOCAL_FUNC(name) (name) + +#endif /* VDS64_HAS_DESCRIPTORS */ +#endif /* __VDSO64__ */ + +#ifdef __VDSO32__ + +#define V_FUNCTION_BEGIN(name) \ + .globl name; \ + .type name,@function; \ + name: \ + +#define V_FUNCTION_END(name) \ + .size name,.-name; + +#define V_LOCAL_FUNC(name) (name) + +#endif /* __VDSO32__ */ + +#endif /* __ASSEMBLY__ */ + +#endif /* __KERNEL__ */ + +#endif /* __PPC64_VDSO_H__ */ diff --git a/include/asm-powerpc/vdso_datapage.h b/include/asm-powerpc/vdso_datapage.h new file mode 100644 index 000000000000..411832d5bbdb --- /dev/null +++ b/include/asm-powerpc/vdso_datapage.h @@ -0,0 +1,108 @@ +#ifndef _VDSO_DATAPAGE_H +#define _VDSO_DATAPAGE_H + +/* + * Copyright (C) 2002 Peter Bergner <bergner@vnet.ibm.com>, IBM + * Copyright (C) 2005 Benjamin Herrenschmidy <benh@kernel.crashing.org>, + * IBM Corp. + * + * 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. + */ + + +/* + * Note about this structure: + * + * This structure was historically called systemcfg and exposed to + * userland via /proc/ppc64/systemcfg. Unfortunately, this became an + * ABI issue as some proprietary software started relying on being able + * to mmap() it, thus we have to keep the base layout at least for a + * few kernel versions. + * + * However, since ppc32 doesn't suffer from this backward handicap, + * a simpler version of the data structure is used there with only the + * fields actually used by the vDSO. + * + */ + +/* + * If the major version changes we are incompatible. + * Minor version changes are a hint. + */ +#define SYSTEMCFG_MAJOR 1 +#define SYSTEMCFG_MINOR 1 + +#ifndef __ASSEMBLY__ + +#include <linux/unistd.h> + +#define SYSCALL_MAP_SIZE ((__NR_syscalls + 31) / 32) + +/* + * So here is the ppc64 backward compatible version + */ + +#ifdef CONFIG_PPC64 + +struct vdso_data { + __u8 eye_catcher[16]; /* Eyecatcher: SYSTEMCFG:PPC64 0x00 */ + struct { /* Systemcfg version numbers */ + __u32 major; /* Major number 0x10 */ + __u32 minor; /* Minor number 0x14 */ + } version; + + __u32 platform; /* Platform flags 0x18 */ + __u32 processor; /* Processor type 0x1C */ + __u64 processorCount; /* # of physical processors 0x20 */ + __u64 physicalMemorySize; /* Size of real memory(B) 0x28 */ + __u64 tb_orig_stamp; /* Timebase at boot 0x30 */ + __u64 tb_ticks_per_sec; /* Timebase tics / sec 0x38 */ + __u64 tb_to_xs; /* Inverse of TB to 2^20 0x40 */ + __u64 stamp_xsec; /* 0x48 */ + __u64 tb_update_count; /* Timebase atomicity ctr 0x50 */ + __u32 tz_minuteswest; /* Minutes west of Greenwich 0x58 */ + __u32 tz_dsttime; /* Type of dst correction 0x5C */ + __u32 dcache_size; /* L1 d-cache size 0x60 */ + __u32 dcache_line_size; /* L1 d-cache line size 0x64 */ + __u32 icache_size; /* L1 i-cache size 0x68 */ + __u32 icache_line_size; /* L1 i-cache line size 0x6C */ + + /* those additional ones don't have to be located anywhere + * special as they were not part of the original systemcfg + */ + __s32 wtom_clock_sec; /* Wall to monotonic clock */ + __s32 wtom_clock_nsec; + __u32 syscall_map_64[SYSCALL_MAP_SIZE]; /* map of syscalls */ + __u32 syscall_map_32[SYSCALL_MAP_SIZE]; /* map of syscalls */ +}; + +#else /* CONFIG_PPC64 */ + +/* + * And here is the simpler 32 bits version + */ +struct vdso_data { + __u64 tb_orig_stamp; /* Timebase at boot 0x30 */ + __u64 tb_ticks_per_sec; /* Timebase tics / sec 0x38 */ + __u64 tb_to_xs; /* Inverse of TB to 2^20 0x40 */ + __u64 stamp_xsec; /* 0x48 */ + __u32 tb_update_count; /* Timebase atomicity ctr 0x50 */ + __u32 tz_minuteswest; /* Minutes west of Greenwich 0x58 */ + __u32 tz_dsttime; /* Type of dst correction 0x5C */ + __s32 wtom_clock_sec; /* Wall to monotonic clock */ + __s32 wtom_clock_nsec; + __u32 syscall_map_32[SYSCALL_MAP_SIZE]; /* map of syscalls */ +}; + +#endif /* CONFIG_PPC64 */ + +#ifdef __KERNEL__ +extern struct vdso_data *vdso_data; +#endif + +#endif /* __ASSEMBLY__ */ + +#endif /* _SYSTEMCFG_H */ |