diff options
Diffstat (limited to 'include/asm-powerpc')
36 files changed, 1770 insertions, 170 deletions
diff --git a/include/asm-powerpc/abs_addr.h b/include/asm-powerpc/abs_addr.h new file mode 100644 index 00000000000..18415108fc5 --- /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 00000000000..8b133efc9f7 --- /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 ed4b345ed75..9c0b372a46e 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; @@ -205,5 +197,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 79d8c473230..19a099b62cd 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 dc25c53704d..5727229b044 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/bug.h b/include/asm-powerpc/bug.h index d625ee55f95..b001ecb3cd9 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 00000000000..26ce502e76e --- /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 00000000000..8a740c88d93 --- /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 00000000000..4db4360c4d4 --- /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 79a0556a0ab..04e2726002c 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 00000000000..82cd4a9ca99 --- /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/eeh_event.h b/include/asm-powerpc/eeh_event.h new file mode 100644 index 00000000000..d168a30b386 --- /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 feac3458d71..3dcd65edf97 100644 --- a/include/asm-powerpc/elf.h +++ b/include/asm-powerpc/elf.h @@ -269,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 806c142ae9e..12fabbcb04f 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/futex.h b/include/asm-powerpc/futex.h index 37c94e52ab6..f0319d50b12 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 00000000000..d36da61dbc5 --- /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/hw_irq.h b/include/asm-powerpc/hw_irq.h index c37b31b9633..26b89d859c5 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/irq.h b/include/asm-powerpc/irq.h index b3935ea28ff..8eb7e857ec4 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/lppaca.h b/include/asm-powerpc/lppaca.h new file mode 100644 index 00000000000..c1bedab1515 --- /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/paca.h b/include/asm-powerpc/paca.h new file mode 100644 index 00000000000..92c765c35bd --- /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/pmc.h b/include/asm-powerpc/pmc.h index 2f3c3fc2b79..5f41f3a2b29 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 13aacff755f..9896fade98a 100644 --- a/include/asm-powerpc/ppc-pci.h +++ b/include/asm-powerpc/ppc-pci.h @@ -26,6 +26,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); @@ -36,10 +40,6 @@ void pci_devs_phb_init(void); void pci_devs_phb_init_dynamic(struct pci_controller *phb); void __devinit scan_phb(struct pci_controller *hose); -/* 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); - /* From rtas_pci.h */ void init_pci_config_tokens (void); unsigned long get_phb_buid (struct device_node *); @@ -52,4 +52,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 c534ca41224..c27baa0563f 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 1dc4bf7b52b..d12382d292d 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/reg.h b/include/asm-powerpc/reg.h index 489cf4c99c2..eb392d038ed 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 */ diff --git a/include/asm-powerpc/reg_8xx.h b/include/asm-powerpc/reg_8xx.h new file mode 100644 index 00000000000..e8ea346b21d --- /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/signal.h b/include/asm-powerpc/signal.h new file mode 100644 index 00000000000..694c8d2dab8 --- /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/sparsemem.h b/include/asm-powerpc/sparsemem.h index 1c95ab99deb..ba1b34fdb96 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 3536a5cd7a2..5341b75c75c 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 00000000000..d099d5200f9 --- /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 2512e3836bf..015d28746e1 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 33af730f0d1..3872e924cdd 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 00000000000..a383383bc4d --- /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 00000000000..85d8a7be25c --- /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.12 + +/* 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 00000000000..fc323b51366 --- /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 + */ + __s64 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 */ diff --git a/include/asm-powerpc/xmon.h b/include/asm-powerpc/xmon.h index ace2072d4a8..43f7129984c 100644 --- a/include/asm-powerpc/xmon.h +++ b/include/asm-powerpc/xmon.h @@ -7,7 +7,6 @@ struct pt_regs; extern int xmon(struct pt_regs *excp); extern void xmon_printf(const char *fmt, ...); extern void xmon_init(int); -extern void xmon_map_scc(void); #endif #endif |