Merge master.kernel.org:/pub/scm/linux/kernel/git/paulus/powerpc-merge

This commit is contained in:
Linus Torvalds
2005-11-04 16:27:50 -08:00
177 changed files with 8645 additions and 4019 deletions
+437
View File
@@ -0,0 +1,437 @@
/*
* PowerPC atomic bit operations.
*
* Merged version by David Gibson <david@gibson.dropbear.id.au>.
* Based on ppc64 versions by: Dave Engebretsen, Todd Inglett, Don
* Reed, Pat McCarthy, Peter Bergner, Anton Blanchard. They
* originally took it from the ppc32 code.
*
* Within a word, bits are numbered LSB first. Lot's of places make
* this assumption by directly testing bits with (val & (1<<nr)).
* This can cause confusion for large (> 1 word) bitmaps on a
* big-endian system because, unlike little endian, the number of each
* bit depends on the word size.
*
* The bitop functions are defined to work on unsigned longs, so for a
* ppc64 system the bits end up numbered:
* |63..............0|127............64|191...........128|255...........196|
* and on ppc32:
* |31.....0|63....31|95....64|127...96|159..128|191..160|223..192|255..224|
*
* There are a few little-endian macros used mostly for filesystem
* bitmaps, these work on similar bit arrays layouts, but
* byte-oriented:
* |7...0|15...8|23...16|31...24|39...32|47...40|55...48|63...56|
*
* The main difference is that bit 3-5 (64b) or 3-4 (32b) in the bit
* number field needs to be reversed compared to the big-endian bit
* fields. This can be achieved by XOR with 0x38 (64b) or 0x18 (32b).
*
* 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_BITOPS_H
#define _ASM_POWERPC_BITOPS_H
#ifdef __KERNEL__
#include <linux/compiler.h>
#include <asm/atomic.h>
#include <asm/synch.h>
/*
* clear_bit doesn't imply a memory barrier
*/
#define smp_mb__before_clear_bit() smp_mb()
#define smp_mb__after_clear_bit() smp_mb()
#define BITOP_MASK(nr) (1UL << ((nr) % BITS_PER_LONG))
#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;
unsigned long mask = BITOP_MASK(nr);
unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
__asm__ __volatile__(
"1:" LARXL " %0,0,%3 # set_bit\n"
"or %0,%0,%2\n"
PPC405_ERR77(0,%3)
STCXL " %0,0,%3\n"
"bne- 1b"
: "=&r"(old), "=m"(*p)
: "r"(mask), "r"(p), "m"(*p)
: "cc" );
}
static __inline__ void clear_bit(int nr, volatile unsigned long *addr)
{
unsigned long old;
unsigned long mask = BITOP_MASK(nr);
unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
__asm__ __volatile__(
"1:" LARXL " %0,0,%3 # set_bit\n"
"andc %0,%0,%2\n"
PPC405_ERR77(0,%3)
STCXL " %0,0,%3\n"
"bne- 1b"
: "=&r"(old), "=m"(*p)
: "r"(mask), "r"(p), "m"(*p)
: "cc" );
}
static __inline__ void change_bit(int nr, volatile unsigned long *addr)
{
unsigned long old;
unsigned long mask = BITOP_MASK(nr);
unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
__asm__ __volatile__(
"1:" LARXL " %0,0,%3 # set_bit\n"
"xor %0,%0,%2\n"
PPC405_ERR77(0,%3)
STCXL " %0,0,%3\n"
"bne- 1b"
: "=&r"(old), "=m"(*p)
: "r"(mask), "r"(p), "m"(*p)
: "cc" );
}
static __inline__ int test_and_set_bit(unsigned long nr,
volatile unsigned long *addr)
{
unsigned long old, t;
unsigned long mask = BITOP_MASK(nr);
unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
__asm__ __volatile__(
EIEIO_ON_SMP
"1:" LARXL " %0,0,%3 # test_and_set_bit\n"
"or %1,%0,%2 \n"
PPC405_ERR77(0,%3)
STCXL " %1,0,%3 \n"
"bne- 1b"
ISYNC_ON_SMP
: "=&r" (old), "=&r" (t)
: "r" (mask), "r" (p)
: "cc", "memory");
return (old & mask) != 0;
}
static __inline__ int test_and_clear_bit(unsigned long nr,
volatile unsigned long *addr)
{
unsigned long old, t;
unsigned long mask = BITOP_MASK(nr);
unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
__asm__ __volatile__(
EIEIO_ON_SMP
"1:" LARXL " %0,0,%3 # test_and_clear_bit\n"
"andc %1,%0,%2 \n"
PPC405_ERR77(0,%3)
STCXL " %1,0,%3 \n"
"bne- 1b"
ISYNC_ON_SMP
: "=&r" (old), "=&r" (t)
: "r" (mask), "r" (p)
: "cc", "memory");
return (old & mask) != 0;
}
static __inline__ int test_and_change_bit(unsigned long nr,
volatile unsigned long *addr)
{
unsigned long old, t;
unsigned long mask = BITOP_MASK(nr);
unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
__asm__ __volatile__(
EIEIO_ON_SMP
"1:" LARXL " %0,0,%3 # test_and_change_bit\n"
"xor %1,%0,%2 \n"
PPC405_ERR77(0,%3)
STCXL " %1,0,%3 \n"
"bne- 1b"
ISYNC_ON_SMP
: "=&r" (old), "=&r" (t)
: "r" (mask), "r" (p)
: "cc", "memory");
return (old & mask) != 0;
}
static __inline__ void set_bits(unsigned long mask, unsigned long *addr)
{
unsigned long old;
__asm__ __volatile__(
"1:" LARXL " %0,0,%3 # set_bit\n"
"or %0,%0,%2\n"
STCXL " %0,0,%3\n"
"bne- 1b"
: "=&r" (old), "=m" (*addr)
: "r" (mask), "r" (addr), "m" (*addr)
: "cc");
}
/* Non-atomic versions */
static __inline__ int test_bit(unsigned long nr,
__const__ volatile unsigned long *addr)
{
return 1UL & (addr[BITOP_WORD(nr)] >> (nr & (BITS_PER_LONG-1)));
}
static __inline__ void __set_bit(unsigned long nr,
volatile unsigned long *addr)
{
unsigned long mask = BITOP_MASK(nr);
unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
*p |= mask;
}
static __inline__ void __clear_bit(unsigned long nr,
volatile unsigned long *addr)
{
unsigned long mask = BITOP_MASK(nr);
unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
*p &= ~mask;
}
static __inline__ void __change_bit(unsigned long nr,
volatile unsigned long *addr)
{
unsigned long mask = BITOP_MASK(nr);
unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
*p ^= mask;
}
static __inline__ int __test_and_set_bit(unsigned long nr,
volatile unsigned long *addr)
{
unsigned long mask = BITOP_MASK(nr);
unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
unsigned long old = *p;
*p = old | mask;
return (old & mask) != 0;
}
static __inline__ int __test_and_clear_bit(unsigned long nr,
volatile unsigned long *addr)
{
unsigned long mask = BITOP_MASK(nr);
unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
unsigned long old = *p;
*p = old & ~mask;
return (old & mask) != 0;
}
static __inline__ int __test_and_change_bit(unsigned long nr,
volatile unsigned long *addr)
{
unsigned long mask = BITOP_MASK(nr);
unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
unsigned long old = *p;
*p = old ^ mask;
return (old & mask) != 0;
}
/*
* Return the zero-based bit position (LE, not IBM bit numbering) of
* the most significant 1-bit in a double word.
*/
static __inline__ int __ilog2(unsigned long x)
{
int lz;
asm (CNTLZL " %0,%1" : "=r" (lz) : "r" (x));
return BITS_PER_LONG - 1 - lz;
}
/*
* Determines the bit position of the least significant 0 bit in the
* specified double word. The returned bit position will be
* zero-based, starting from the right side (63/31 - 0).
*/
static __inline__ unsigned long ffz(unsigned long x)
{
/* no zero exists anywhere in the 8 byte area. */
if ((x = ~x) == 0)
return BITS_PER_LONG;
/*
* Calculate the bit position of the least signficant '1' bit in x
* (since x has been changed this will actually be the least signficant
* '0' bit in * the original x). Note: (x & -x) gives us a mask that
* is the least significant * (RIGHT-most) 1-bit of the value in x.
*/
return __ilog2(x & -x);
}
static __inline__ int __ffs(unsigned long x)
{
return __ilog2(x & -x);
}
/*
* ffs: find first bit set. This is defined the same way as
* the libc and compiler builtin ffs routines, therefore
* differs in spirit from the above ffz (man ffs).
*/
static __inline__ int ffs(int x)
{
unsigned long i = (unsigned long)x;
return __ilog2(i & -i) + 1;
}
/*
* fls: find last (most-significant) bit set.
* Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32.
*/
static __inline__ int fls(unsigned int x)
{
int lz;
asm ("cntlzw %0,%1" : "=r" (lz) : "r" (x));
return 32 - lz;
}
/*
* hweightN: returns the hamming weight (i.e. the number
* of bits set) of a N-bit word
*/
#define hweight64(x) generic_hweight64(x)
#define hweight32(x) generic_hweight32(x)
#define hweight16(x) generic_hweight16(x)
#define hweight8(x) generic_hweight8(x)
#define find_first_zero_bit(addr, size) find_next_zero_bit((addr), (size), 0)
unsigned long find_next_zero_bit(const unsigned long *addr,
unsigned long size, unsigned long offset);
/**
* find_first_bit - find the first set bit in a memory region
* @addr: The address to start the search at
* @size: The maximum size to search
*
* Returns the bit-number of the first set bit, not the number of the byte
* containing a bit.
*/
#define find_first_bit(addr, size) find_next_bit((addr), (size), 0)
unsigned long find_next_bit(const unsigned long *addr,
unsigned long size, unsigned long offset);
/* Little-endian versions */
static __inline__ int test_le_bit(unsigned long nr,
__const__ unsigned long *addr)
{
__const__ unsigned char *tmp = (__const__ unsigned char *) addr;
return (tmp[nr >> 3] >> (nr & 7)) & 1;
}
#define __set_le_bit(nr, addr) \
__set_bit((nr) ^ BITOP_LE_SWIZZLE, (addr))
#define __clear_le_bit(nr, addr) \
__clear_bit((nr) ^ BITOP_LE_SWIZZLE, (addr))
#define test_and_set_le_bit(nr, addr) \
test_and_set_bit((nr) ^ BITOP_LE_SWIZZLE, (addr))
#define test_and_clear_le_bit(nr, addr) \
test_and_clear_bit((nr) ^ BITOP_LE_SWIZZLE, (addr))
#define __test_and_set_le_bit(nr, addr) \
__test_and_set_bit((nr) ^ BITOP_LE_SWIZZLE, (addr))
#define __test_and_clear_le_bit(nr, addr) \
__test_and_clear_bit((nr) ^ BITOP_LE_SWIZZLE, (addr))
#define find_first_zero_le_bit(addr, size) find_next_zero_le_bit((addr), (size), 0)
unsigned long find_next_zero_le_bit(const unsigned long *addr,
unsigned long size, unsigned long offset);
/* Bitmap functions for the ext2 filesystem */
#define ext2_set_bit(nr,addr) \
__test_and_set_le_bit((nr), (unsigned long*)addr)
#define ext2_clear_bit(nr, addr) \
__test_and_clear_le_bit((nr), (unsigned long*)addr)
#define ext2_set_bit_atomic(lock, nr, addr) \
test_and_set_le_bit((nr), (unsigned long*)addr)
#define ext2_clear_bit_atomic(lock, nr, addr) \
test_and_clear_le_bit((nr), (unsigned long*)addr)
#define ext2_test_bit(nr, addr) test_le_bit((nr),(unsigned long*)addr)
#define ext2_find_first_zero_bit(addr, size) \
find_first_zero_le_bit((unsigned long*)addr, size)
#define ext2_find_next_zero_bit(addr, size, off) \
find_next_zero_le_bit((unsigned long*)addr, size, off)
/* Bitmap functions for the minix filesystem. */
#define minix_test_and_set_bit(nr,addr) \
__test_and_set_le_bit(nr, (unsigned long *)addr)
#define minix_set_bit(nr,addr) \
__set_le_bit(nr, (unsigned long *)addr)
#define minix_test_and_clear_bit(nr,addr) \
__test_and_clear_le_bit(nr, (unsigned long *)addr)
#define minix_test_bit(nr,addr) \
test_le_bit(nr, (unsigned long *)addr)
#define minix_find_first_zero_bit(addr,size) \
find_first_zero_le_bit((unsigned long *)addr, size)
/*
* Every architecture must define this function. It's the fastest
* way of searching a 140-bit bitmap where the first 100 bits are
* unlikely to be set. It's guaranteed that at least one of the 140
* bits is cleared.
*/
static inline int sched_find_first_bit(const unsigned long *b)
{
#ifdef CONFIG_PPC64
if (unlikely(b[0]))
return __ffs(b[0]);
if (unlikely(b[1]))
return __ffs(b[1]) + 64;
return __ffs(b[2]) + 128;
#else
if (unlikely(b[0]))
return __ffs(b[0]);
if (unlikely(b[1]))
return __ffs(b[1]) + 32;
if (unlikely(b[2]))
return __ffs(b[2]) + 64;
if (b[3])
return __ffs(b[3]) + 96;
return __ffs(b[4]) + 128;
#endif
}
#endif /* __KERNEL__ */
#endif /* _ASM_POWERPC_BITOPS_H */
+15 -19
View File
@@ -12,20 +12,16 @@
#ifndef __ASSEMBLY__
#ifdef __powerpc64__
#define BUG_TABLE_ENTRY(label, line, file, func) \
".llong " #label "\n .long " #line "\n .llong " #file ", " #func "\n"
#define TRAP_OP(ra, rb) "1: tdnei " #ra ", " #rb "\n"
#define DATA_TYPE long long
#define BUG_TABLE_ENTRY ".llong"
#define BUG_TRAP_OP "tdnei"
#else
#define BUG_TABLE_ENTRY(label, line, file, func) \
".long " #label ", " #line ", " #file ", " #func "\n"
#define TRAP_OP(ra, rb) "1: twnei " #ra ", " #rb "\n"
#define DATA_TYPE int
#define BUG_TABLE_ENTRY ".long"
#define BUG_TRAP_OP "twnei"
#endif /* __powerpc64__ */
struct bug_entry {
unsigned long bug_addr;
int line;
long line;
const char *file;
const char *function;
};
@@ -43,29 +39,29 @@ struct bug_entry *find_bug(unsigned long bugaddr);
#define BUG() do { \
__asm__ __volatile__( \
"1: twi 31,0,0\n" \
".section __bug_table,\"a\"\n\t" \
BUG_TABLE_ENTRY(1b,%0,%1,%2) \
".section __bug_table,\"a\"\n" \
"\t"BUG_TABLE_ENTRY" 1b,%0,%1,%2\n" \
".previous" \
: : "i" (__LINE__), "i" (__FILE__), "i" (__FUNCTION__)); \
} while (0)
#define BUG_ON(x) do { \
__asm__ __volatile__( \
TRAP_OP(%0,0) \
".section __bug_table,\"a\"\n\t" \
BUG_TABLE_ENTRY(1b,%1,%2,%3) \
"1: "BUG_TRAP_OP" %0,0\n" \
".section __bug_table,\"a\"\n" \
"\t"BUG_TABLE_ENTRY" 1b,%1,%2,%3\n" \
".previous" \
: : "r" ((DATA_TYPE)(x)), "i" (__LINE__), \
: : "r" ((long)(x)), "i" (__LINE__), \
"i" (__FILE__), "i" (__FUNCTION__)); \
} while (0)
#define WARN_ON(x) do { \
__asm__ __volatile__( \
TRAP_OP(%0,0) \
".section __bug_table,\"a\"\n\t" \
BUG_TABLE_ENTRY(1b,%1,%2,%3) \
"1: "BUG_TRAP_OP" %0,0\n" \
".section __bug_table,\"a\"\n" \
"\t"BUG_TABLE_ENTRY" 1b,%1,%2,%3\n" \
".previous" \
: : "r" ((DATA_TYPE)(x)), \
: : "r" ((long)(x)), \
"i" (__LINE__ + BUG_WARNING_TRAP), \
"i" (__FILE__), "i" (__FUNCTION__)); \
} while (0)
+13 -9
View File
@@ -178,18 +178,22 @@ typedef elf_vrreg_t elf_vrregset_t32[ELF_NVRREG32];
static inline void ppc_elf_core_copy_regs(elf_gregset_t elf_regs,
struct pt_regs *regs)
{
int i;
int gprs = sizeof(struct pt_regs)/sizeof(ELF_GREG_TYPE);
int i, nregs;
if (gprs > ELF_NGREG)
gprs = ELF_NGREG;
memset((void *)elf_regs, 0, sizeof(elf_gregset_t));
for (i=0; i < gprs; i++)
/* Our registers are always unsigned longs, whether we're a 32 bit
* process or 64 bit, on either a 64 bit or 32 bit kernel.
* Don't use ELF_GREG_TYPE here. */
nregs = sizeof(struct pt_regs) / sizeof(unsigned long);
if (nregs > ELF_NGREG)
nregs = ELF_NGREG;
for (i = 0; i < nregs; i++) {
/* This will correctly truncate 64 bit registers to 32 bits
* for a 32 bit process on a 64 bit kernel. */
elf_regs[i] = (elf_greg_t)((ELF_GREG_TYPE *)regs)[i];
memset((char *)(elf_regs) + sizeof(struct pt_regs), 0, \
sizeof(elf_gregset_t) - sizeof(struct pt_regs));
}
}
#define ELF_CORE_COPY_REGS(gregs, regs) ppc_elf_core_copy_regs(gregs, regs);
@@ -1,5 +1,5 @@
#ifndef _ASM_FUTEX_H
#define _ASM_FUTEX_H
#ifndef _ASM_POWERPC_FUTEX_H
#define _ASM_POWERPC_FUTEX_H
#ifdef __KERNEL__
@@ -7,28 +7,29 @@
#include <asm/errno.h>
#include <asm/synch.h>
#include <asm/uaccess.h>
#include <asm/ppc_asm.h>
#define __futex_atomic_op(insn, ret, oldval, uaddr, oparg) \
__asm__ __volatile (SYNC_ON_SMP \
"1: lwarx %0,0,%2\n" \
insn \
"2: stwcx. %1,0,%2\n\
bne- 1b\n\
li %1,0\n\
3: .section .fixup,\"ax\"\n\
4: li %1,%3\n\
b 3b\n\
.previous\n\
.section __ex_table,\"a\"\n\
.align 3\n\
.llong 1b,4b,2b,4b\n\
.previous" \
: "=&r" (oldval), "=&r" (ret) \
: "b" (uaddr), "i" (-EFAULT), "1" (oparg) \
__asm__ __volatile ( \
SYNC_ON_SMP \
"1: lwarx %0,0,%2\n" \
insn \
"2: stwcx. %1,0,%2\n" \
"bne- 1b\n" \
"li %1,0\n" \
"3: .section .fixup,\"ax\"\n" \
"4: li %1,%3\n" \
"b 3b\n" \
".previous\n" \
".section __ex_table,\"a\"\n" \
".align 3\n" \
DATAL " 1b,4b,2b,4b\n" \
".previous" \
: "=&r" (oldval), "=&r" (ret) \
: "b" (uaddr), "i" (-EFAULT), "1" (oparg) \
: "cr0", "memory")
static inline int
futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
static inline int futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
{
int op = (encoded_op >> 28) & 7;
int cmp = (encoded_op >> 24) & 15;
@@ -79,5 +80,5 @@ futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
return ret;
}
#endif
#endif
#endif /* __KERNEL__ */
#endif /* _ASM_POWERPC_FUTEX_H */
+3
View File
@@ -62,6 +62,9 @@
# define TIOCM_DSR 0x100
# define TIOCM_CD TIOCM_CAR
# define TIOCM_RI TIOCM_RNG
#define TIOCM_OUT1 0x2000
#define TIOCM_OUT2 0x4000
#define TIOCM_LOOP 0x8000
#define TIOCGSOFTCAR 0x5419
#define TIOCSSOFTCAR 0x541A
+34
View File
@@ -0,0 +1,34 @@
#ifndef _ASM_POWERPC_IPCBUF_H
#define _ASM_POWERPC_IPCBUF_H
/*
* The ipc64_perm structure for the powerpc is identical to
* kern_ipc_perm as we have always had 32-bit UIDs and GIDs in the
* kernel. Note extra padding because this structure is passed back
* and forth between kernel and user space. Pad space is left for:
* - 1 32-bit value to fill up for 8-byte alignment
* - 2 miscellaneous 64-bit values
*
* 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 <linux/types.h>
struct ipc64_perm
{
__kernel_key_t key;
__kernel_uid_t uid;
__kernel_gid_t gid;
__kernel_uid_t cuid;
__kernel_gid_t cgid;
__kernel_mode_t mode;
unsigned int seq;
unsigned int __pad1;
unsigned long long __unused1;
unsigned long long __unused2;
};
#endif /* _ASM_POWERPC_IPCBUF_H */
+1 -1
View File
@@ -73,7 +73,7 @@ extern unsigned int real_irq_to_virt_slowpath(unsigned int real_irq);
#define IC_INVALID 0
#define IC_OPEN_PIC 1
#define IC_PPC_XIC 2
#define IC_BPA_IIC 3
#define IC_CELL_PIC 3
#define IC_ISERIES 4
extern u64 ppc64_interrupt_controller;
@@ -20,11 +20,11 @@
* This file contains the "hypervisor call" interface which is used to
* drive the hypervisor from the OS.
*/
#ifndef _HVCALL_H
#define _HVCALL_H
#ifndef _ASM_POWERPC_ISERIES_HV_CALL_H
#define _ASM_POWERPC_ISERIES_HV_CALL_H
#include <asm/iSeries/HvCallSc.h>
#include <asm/iSeries/HvTypes.h>
#include <asm/iseries/hv_call_sc.h>
#include <asm/iseries/hv_types.h>
#include <asm/paca.h>
/* Type of yield for HvCallBaseYieldProcessor */
@@ -110,4 +110,4 @@ static inline void HvCall_sendIPI(struct paca_struct *targetPaca)
HvCall1(HvCallBaseSendIPI, targetPaca->paca_index);
}
#endif /* _HVCALL_H */
#endif /* _ASM_POWERPC_ISERIES_HV_CALL_H */
@@ -20,11 +20,11 @@
* This file contains the "hypervisor call" interface which is used to
* drive the hypervisor from the OS.
*/
#ifndef _HVCALLEVENT_H
#define _HVCALLEVENT_H
#ifndef _ASM_POWERPC_ISERIES_HV_CALL_EVENT_H
#define _ASM_POWERPC_ISERIES_HV_CALL_EVENT_H
#include <asm/iSeries/HvCallSc.h>
#include <asm/iSeries/HvTypes.h>
#include <asm/iseries/hv_call_sc.h>
#include <asm/iseries/hv_types.h>
#include <asm/abs_addr.h>
struct HvLpEvent;
@@ -250,4 +250,4 @@ static inline HvLpDma_Rc HvCallEvent_dmaToSp(void *local, u32 remote,
return HvCall4(HvCallEventDmaToSp, abs_addr, remote, length, dir);
}
#endif /* _HVCALLEVENT_H */
#endif /* _ASM_POWERPC_ISERIES_HV_CALL_EVENT_H */
@@ -16,8 +16,8 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _HVCALLSC_H
#define _HVCALLSC_H
#ifndef _ASM_POWERPC_ISERIES_HV_CALL_SC_H
#define _ASM_POWERPC_ISERIES_HV_CALL_SC_H
#include <linux/types.h>
@@ -48,4 +48,4 @@ extern u64 HvCall5Ret16(u64, void *, u64, u64, u64, u64, u64);
extern u64 HvCall6Ret16(u64, void *, u64, u64, u64, u64, u64, u64);
extern u64 HvCall7Ret16(u64, void *, u64, u64 ,u64 ,u64 ,u64 ,u64 ,u64);
#endif /* _HVCALLSC_H */
#endif /* _ASM_POWERPC_ISERIES_HV_CALL_SC_H */
@@ -2,11 +2,11 @@
* This file contains the "hypervisor call" interface which is used to
* drive the hypervisor from SLIC.
*/
#ifndef _HVCALLXM_H
#define _HVCALLXM_H
#ifndef _ASM_POWERPC_ISERIES_HV_CALL_XM_H
#define _ASM_POWERPC_ISERIES_HV_CALL_XM_H
#include <asm/iSeries/HvCallSc.h>
#include <asm/iSeries/HvTypes.h>
#include <asm/iseries/hv_call_sc.h>
#include <asm/iseries/hv_types.h>
#define HvCallXmGetTceTableParms HvCallXm + 0
#define HvCallXmTestBus HvCallXm + 1
@@ -75,4 +75,4 @@ static inline u64 HvCallXm_loadTod(void)
return HvCall0(HvCallXmLoadTod);
}
#endif /* _HVCALLXM_H */
#endif /* _ASM_POWERPC_ISERIES_HV_CALL_XM_H */
@@ -16,17 +16,17 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _HVLPCONFIG_H
#define _HVLPCONFIG_H
#ifndef _ASM_POWERPC_ISERIES_HV_LP_CONFIG_H
#define _ASM_POWERPC_ISERIES_HV_LP_CONFIG_H
/*
* This file contains the interface to the LPAR configuration data
* to determine which resources should be allocated to each partition.
*/
#include <asm/iSeries/HvCallSc.h>
#include <asm/iSeries/HvTypes.h>
#include <asm/iSeries/ItLpNaca.h>
#include <asm/iseries/hv_call_sc.h>
#include <asm/iseries/hv_types.h>
#include <asm/iseries/it_lp_naca.h>
enum {
HvCallCfg_Cur = 0,
@@ -135,4 +135,4 @@ static inline HvLpIndex HvLpConfig_getHostingLpIndex(HvLpIndex lp)
return HvCall1(HvCallCfgGetHostingLpIndex, lp);
}
#endif /* _HVLPCONFIG_H */
#endif /* _ASM_POWERPC_ISERIES_HV_LP_CONFIG_H */
@@ -19,13 +19,13 @@
/* This file contains the class for HV events in the system. */
#ifndef _HVLPEVENT_H
#define _HVLPEVENT_H
#ifndef _ASM_POWERPC_ISERIES_HV_LP_EVENT_H
#define _ASM_POWERPC_ISERIES_HV_LP_EVENT_H
#include <asm/types.h>
#include <asm/ptrace.h>
#include <asm/iSeries/HvTypes.h>
#include <asm/iSeries/HvCallEvent.h>
#include <asm/iseries/hv_types.h>
#include <asm/iseries/hv_call_event.h>
/*
* HvLpEvent is the structure for Lp Event messages passed between
@@ -139,4 +139,4 @@ extern int HvLpEvent_closePath(HvLpEvent_Type eventType, HvLpIndex lpIndex);
#define HvLpDma_Rc_InvalidAddress 4
#define HvLpDma_Rc_InvalidLength 5
#endif /* _HVLPEVENT_H */
#endif /* _ASM_POWERPC_ISERIES_HV_LP_EVENT_H */
@@ -16,8 +16,8 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _HVTYPES_H
#define _HVTYPES_H
#ifndef _ASM_POWERPC_ISERIES_HV_TYPES_H
#define _ASM_POWERPC_ISERIES_HV_TYPES_H
/*
* General typedefs for the hypervisor.
@@ -110,4 +110,4 @@ struct HvLpBufferList {
u64 len;
};
#endif /* _HVTYPES_H */
#endif /* _ASM_POWERPC_ISERIES_HV_TYPES_H */
@@ -1,5 +1,5 @@
#ifndef _ISERIES_IO_H
#define _ISERIES_IO_H
#ifndef _ASM_POWERPC_ISERIES_ISERIES_IO_H
#define _ASM_POWERPC_ISERIES_ISERIES_IO_H
#include <linux/config.h>
@@ -46,4 +46,4 @@ extern void iSeries_memcpy_fromio(void *dest,
const volatile void __iomem *source, size_t n);
#endif /* CONFIG_PPC_ISERIES */
#endif /* _ISERIES_IO_H */
#endif /* _ASM_POWERPC_ISERIES_ISERIES_IO_H */
@@ -16,8 +16,8 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _ITEXTVPDPANEL_H
#define _ITEXTVPDPANEL_H
#ifndef _ASM_POWERPC_ISERIES_IT_EXT_VPD_PANEL_H
#define _ASM_POWERPC_ISERIES_IT_EXT_VPD_PANEL_H
/*
* This struct maps the panel information
@@ -49,4 +49,4 @@ struct ItExtVpdPanel {
extern struct ItExtVpdPanel xItExtVpdPanel;
#endif /* _ITEXTVPDPANEL_H */
#endif /* _ASM_POWERPC_ISERIES_IT_EXT_VPD_PANEL_H */
@@ -16,8 +16,8 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _ITLPNACA_H
#define _ITLPNACA_H
#ifndef _ASM_POWERPC_ISERIES_IT_LP_NACA_H
#define _ASM_POWERPC_ISERIES_IT_LP_NACA_H
#include <linux/types.h>
@@ -77,4 +77,4 @@ struct ItLpNaca {
extern struct ItLpNaca itLpNaca;
#endif /* _ITLPNACA_H */
#endif /* _ASM_POWERPC_ISERIES_IT_LP_NACA_H */
@@ -16,8 +16,8 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _ITLPQUEUE_H
#define _ITLPQUEUE_H
#ifndef _ASM_POWERPC_ISERIES_IT_LP_QUEUE_H
#define _ASM_POWERPC_ISERIES_IT_LP_QUEUE_H
/*
* This control block defines the simple LP queue structure that is
@@ -78,4 +78,4 @@ extern int hvlpevent_is_pending(void);
extern void process_hvlpevents(struct pt_regs *);
extern void setup_hvlpevent_queue(void);
#endif /* _ITLPQUEUE_H */
#endif /* _ASM_POWERPC_ISERIES_IT_LP_QUEUE_H */
@@ -16,8 +16,8 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _ITLPREGSAVE_H
#define _ITLPREGSAVE_H
#ifndef _ASM_POWERPC_ISERIES_IT_LP_REG_SAVE_H
#define _ASM_POWERPC_ISERIES_IT_LP_REG_SAVE_H
/*
* This control block contains the data that is shared between PLIC
@@ -16,8 +16,8 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _LPARMAP_H
#define _LPARMAP_H
#ifndef _ASM_POWERPC_ISERIES_LPAR_MAP_H
#define _ASM_POWERPC_ISERIES_LPAR_MAP_H
#ifndef __ASSEMBLY__
@@ -80,4 +80,4 @@ extern const struct LparMap xLparMap;
/* the fixed address where the LparMap exists */
#define LPARMAP_PHYS 0x7000
#endif /* _LPARMAP_H */
#endif /* _ASM_POWERPC_ISERIES_LPAR_MAP_H */
@@ -23,13 +23,13 @@
* 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_PPC64_ISERIES_MF_H
#define _ASM_PPC64_ISERIES_MF_H
#ifndef _ASM_POWERPC_ISERIES_MF_H
#define _ASM_POWERPC_ISERIES_MF_H
#include <linux/types.h>
#include <asm/iSeries/HvTypes.h>
#include <asm/iSeries/HvCallEvent.h>
#include <asm/iseries/hv_types.h>
#include <asm/iseries/hv_call_event.h>
struct rtc_time;
@@ -54,4 +54,4 @@ extern int mf_get_rtc(struct rtc_time *tm);
extern int mf_get_boot_rtc(struct rtc_time *tm);
extern int mf_set_rtc(struct rtc_time *tm);
#endif /* _ASM_PPC64_ISERIES_MF_H */
#endif /* _ASM_POWERPC_ISERIES_MF_H */
@@ -38,11 +38,11 @@
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#ifndef _ISERIES_VIO_H
#define _ISERIES_VIO_H
#ifndef _ASM_POWERPC_ISERIES_VIO_H
#define _ASM_POWERPC_ISERIES_VIO_H
#include <asm/iSeries/HvTypes.h>
#include <asm/iSeries/HvLpEvent.h>
#include <asm/iseries/hv_types.h>
#include <asm/iseries/hv_lp_event.h>
/*
* iSeries virtual I/O events use the subtype field in
@@ -127,4 +127,4 @@ struct device;
extern struct device *iSeries_vio_dev;
#endif /* _ISERIES_VIO_H */
#endif /* _ASM_POWERPC_ISERIES_VIO_H */
+49
View File
@@ -0,0 +1,49 @@
#ifndef _ASM_POWERPC_KEXEC_H
#define _ASM_POWERPC_KEXEC_H
/*
* Maximum page that is mapped directly into kernel memory.
* XXX: Since we copy virt we can use any page we allocate
*/
#define KEXEC_SOURCE_MEMORY_LIMIT (-1UL)
/*
* Maximum address we can reach in physical address mode.
* XXX: I want to allow initrd in highmem. Otherwise set to rmo on LPAR.
*/
#define KEXEC_DESTINATION_MEMORY_LIMIT (-1UL)
/* Maximum address we can use for the control code buffer */
#ifdef __powerpc64__
#define KEXEC_CONTROL_MEMORY_LIMIT (-1UL)
#else
/* TASK_SIZE, probably left over from use_mm ?? */
#define KEXEC_CONTROL_MEMORY_LIMIT TASK_SIZE
#endif
#define KEXEC_CONTROL_CODE_SIZE 4096
/* The native architecture */
#ifdef __powerpc64__
#define KEXEC_ARCH KEXEC_ARCH_PPC64
#else
#define KEXEC_ARCH KEXEC_ARCH_PPC
#endif
#ifndef __ASSEMBLY__
#define MAX_NOTE_BYTES 1024
typedef u32 note_buf_t[MAX_NOTE_BYTES / sizeof(u32)];
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 */
#else
struct kimage;
extern void machine_kexec_simple(struct kimage *image);
#endif
#endif /* ! __ASSEMBLY__ */
#endif /* _ASM_POWERPC_KEXEC_H */
+1
View File
@@ -80,6 +80,7 @@ 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);
+7
View File
@@ -0,0 +1,7 @@
#ifndef _ASM_POWERPC_MAX_NUMNODES_H
#define _ASM_POWERPC_MAX_NUMNODES_H
/* Max 16 Nodes */
#define NODES_SHIFT 4
#endif /* _ASM_POWERPC_MAX_NUMNODES_H */
+7
View File
@@ -506,6 +506,13 @@ END_FTR_SECTION_IFCLR(CPU_FTR_601)
#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 */
+1 -1
View File
@@ -70,7 +70,7 @@ extern unsigned char ucBoardRevMaj, ucBoardRevMin;
#define PLATFORM_LPAR 0x0001
#define PLATFORM_POWERMAC 0x0400
#define PLATFORM_MAPLE 0x0500
#define PLATFORM_BPA 0x1000
#define PLATFORM_CELL 0x1000
/* Compatibility with drivers coming from PPC32 world */
#define _machine (systemcfg->platform)
@@ -1,5 +1,5 @@
#ifndef _PPC64_PTRACE_H
#define _PPC64_PTRACE_H
#ifndef _ASM_POWERPC_PTRACE_H
#define _ASM_POWERPC_PTRACE_H
/*
* Copyright (C) 2001 PPC64 Team, IBM Corp
@@ -16,7 +16,7 @@
* that the overall structure is a multiple of 16 bytes in length.
*
* Note that the offsets of the fields in this struct correspond with
* the PT_* values below. This simplifies arch/ppc64/kernel/ptrace.c.
* the PT_* values below. This simplifies arch/powerpc/kernel/ptrace.c.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -30,61 +30,30 @@ struct pt_regs {
unsigned long gpr[32];
unsigned long nip;
unsigned long msr;
unsigned long orig_gpr3; /* Used for restarting system calls */
unsigned long orig_gpr3; /* Used for restarting system calls */
unsigned long ctr;
unsigned long link;
unsigned long xer;
unsigned long ccr;
unsigned long softe; /* Soft enabled/disabled */
unsigned long trap; /* Reason for being here */
unsigned long dar; /* Fault registers */
unsigned long dsisr;
unsigned long result; /* Result of a system call */
#ifdef __powerpc64__
unsigned long softe; /* Soft enabled/disabled */
#else
unsigned long mq; /* 601 only (not used at present) */
/* Used on APUS to hold IPL value. */
#endif
unsigned long trap; /* Reason for being here */
/* N.B. for critical exceptions on 4xx, the dar and dsisr
fields are overloaded to hold srr0 and srr1. */
unsigned long dar; /* Fault registers */
unsigned long dsisr; /* on 4xx/Book-E used for ESR */
unsigned long result; /* Result of a system call */
};
struct pt_regs32 {
unsigned int gpr[32];
unsigned int nip;
unsigned int msr;
unsigned int orig_gpr3; /* Used for restarting system calls */
unsigned int ctr;
unsigned int link;
unsigned int xer;
unsigned int ccr;
unsigned int mq; /* 601 only (not used at present) */
unsigned int trap; /* Reason for being here */
unsigned int dar; /* Fault registers */
unsigned int dsisr;
unsigned int result; /* Result of a system call */
};
#endif /* __ASSEMBLY__ */
#ifdef __KERNEL__
#define instruction_pointer(regs) ((regs)->nip)
#ifdef CONFIG_SMP
extern unsigned long profile_pc(struct pt_regs *regs);
#else
#define profile_pc(regs) instruction_pointer(regs)
#endif
#define user_mode(regs) ((((regs)->msr) >> MSR_PR_LG) & 0x1)
#define force_successful_syscall_return() \
(current_thread_info()->syscall_noerror = 1)
/*
* We use the least-significant bit of the trap field to indicate
* whether we have saved the full set of registers, or only a
* partial set. A 1 there means the partial set.
*/
#define FULL_REGS(regs) (((regs)->trap & 1) == 0)
#define TRAP(regs) ((regs)->trap & ~0xF)
#define CHECK_FULL_REGS(regs) BUG_ON(regs->trap & 1)
#endif /* __KERNEL__ */
#endif /* __ASSEMBLY__ */
#ifdef __powerpc64__
#define STACK_FRAME_OVERHEAD 112 /* size of minimum stack frame */
@@ -92,8 +61,65 @@ extern unsigned long profile_pc(struct pt_regs *regs);
#define __SIGNAL_FRAMESIZE 128
#define __SIGNAL_FRAMESIZE32 64
#else /* __powerpc64__ */
#define STACK_FRAME_OVERHEAD 16 /* size of minimum stack frame */
/* Size of stack frame allocated when calling signal handler. */
#define __SIGNAL_FRAMESIZE 64
#endif /* __powerpc64__ */
#ifndef __ASSEMBLY__
#define instruction_pointer(regs) ((regs)->nip)
#ifdef CONFIG_SMP
extern unsigned long profile_pc(struct pt_regs *regs);
#else
#define profile_pc(regs) instruction_pointer(regs)
#endif
#ifdef __powerpc64__
#define user_mode(regs) ((((regs)->msr) >> MSR_PR_LG) & 0x1)
#else
#define user_mode(regs) (((regs)->msr & MSR_PR) != 0)
#endif
#define force_successful_syscall_return() \
do { \
current_thread_info()->syscall_noerror = 1; \
} while(0)
/*
* We use the least-significant bit of the trap field to indicate
* whether we have saved the full set of registers, or only a
* partial set. A 1 there means the partial set.
* On 4xx we use the next bit to indicate whether the exception
* is a critical exception (1 means it is).
*/
#define FULL_REGS(regs) (((regs)->trap & 1) == 0)
#ifndef __powerpc64__
#define IS_CRITICAL_EXC(regs) (((regs)->trap & 2) == 0)
#endif /* ! __powerpc64__ */
#define TRAP(regs) ((regs)->trap & ~0xF)
#ifdef __powerpc64__
#define CHECK_FULL_REGS(regs) BUG_ON(regs->trap & 1)
#else
#define CHECK_FULL_REGS(regs) \
do { \
if ((regs)->trap & 1) \
printk(KERN_CRIT "%s: partial register set\n", __FUNCTION__); \
} while (0)
#endif /* __powerpc64__ */
#endif /* __ASSEMBLY__ */
#endif /* __KERNEL__ */
/*
* Offsets used by 'ptrace' system call interface.
* These can't be changed without breaking binary compatibility
* with MkLinux, etc.
*/
#define PT_R0 0
#define PT_R1 1
@@ -137,18 +163,25 @@ extern unsigned long profile_pc(struct pt_regs *regs);
#define PT_LNK 36
#define PT_XER 37
#define PT_CCR 38
#ifndef __powerpc64__
#define PT_MQ 39
#else
#define PT_SOFTE 39
#define PT_TRAP 40
#define PT_DAR 41
#define PT_DSISR 42
#define PT_RESULT 43
#endif
#define PT_FPR0 48
#define PT_FPR0 48 /* each FP reg occupies 2 slots in this space */
#ifndef __powerpc64__
#define PT_FPR31 (PT_FPR0 + 2*31)
#define PT_FPSCR (PT_FPR0 + 2*32 + 1)
#else /* __powerpc64__ */
/*
* Kernel and userspace will both use this PT_FPSCR value. 32-bit apps will
* have visibility to the asm-ppc/ptrace.h header instead of this one.
*/
#define PT_FPSCR (PT_FPR0 + 32) /* each FP reg occupies 1 slot in 64-bit space */
#ifdef __KERNEL__
@@ -165,29 +198,29 @@ extern unsigned long profile_pc(struct pt_regs *regs);
#define PT_VRSAVE_32 (PT_VR0 + 33*4)
#endif
#endif /* __powerpc64__ */
/*
* Get/set all the altivec registers vr0..vr31, vscr, vrsave, in one go.
* The transfer totals 34 quadword. Quadwords 0-31 contain the
* corresponding vector registers. Quadword 32 contains the vscr as the
* last word (offset 12) within that quadword. Quadword 33 contains the
* Get/set all the altivec registers vr0..vr31, vscr, vrsave, in one go.
* The transfer totals 34 quadword. Quadwords 0-31 contain the
* corresponding vector registers. Quadword 32 contains the vscr as the
* last word (offset 12) within that quadword. Quadword 33 contains the
* vrsave as the first word (offset 0) within the quadword.
*
* This definition of the VMX state is compatible with the current PPC32
* ptrace interface. This allows signal handling and ptrace to use the same
* structures. This also simplifies the implementation of a bi-arch
* This definition of the VMX state is compatible with the current PPC32
* ptrace interface. This allows signal handling and ptrace to use the same
* structures. This also simplifies the implementation of a bi-arch
* (combined (32- and 64-bit) gdb.
*/
#define PTRACE_GETVRREGS 18
#define PTRACE_SETVRREGS 19
/*
* While we dont have 64bit book E processors, we need to reserve the
* relevant ptrace calls for 32bit compatibility.
*/
#if 0
#define PTRACE_GETEVRREGS 20
#define PTRACE_SETEVRREGS 21
#endif
#ifndef __powerpc64__
/* Get/set all the upper 32-bits of the SPE registers, accumulator, and
* spefscr, in one go */
#define PTRACE_GETEVRREGS 20
#define PTRACE_SETEVRREGS 21
#endif /* __powerpc64__ */
/*
* Get or set a debug register. The first 16 are DABR registers and the
@@ -196,6 +229,7 @@ extern unsigned long profile_pc(struct pt_regs *regs);
#define PTRACE_GET_DEBUGREG 25
#define PTRACE_SET_DEBUGREG 26
#ifdef __powerpc64__
/* Additional PTRACE requests implemented on PowerPC. */
#define PPC_PTRACE_GETREGS 0x99 /* Get GPRs 0 - 31 */
#define PPC_PTRACE_SETREGS 0x98 /* Set GPRs 0 - 31 */
@@ -209,5 +243,6 @@ extern unsigned long profile_pc(struct pt_regs *regs);
#define PPC_PTRACE_POKEDATA_3264 0x92
#define PPC_PTRACE_PEEKUSR_3264 0x91
#define PPC_PTRACE_POKEUSR_3264 0x90
#endif /* __powerpc64__ */
#endif /* _PPC64_PTRACE_H */
#endif /* _ASM_POWERPC_PTRACE_H */
+4 -21
View File
@@ -149,28 +149,11 @@ struct rtas_error_log {
unsigned char buffer[1];
};
struct flash_block {
char *data;
unsigned long length;
};
/* This struct is very similar but not identical to
* that needed by the rtas flash update.
* All we need to do for rtas is rewrite num_blocks
* into a version/length and translate the pointers
* to absolute.
/*
* This can be set by the rtas_flash module so that it can get called
* as the absolutely last thing before the kernel terminates.
*/
#define FLASH_BLOCKS_PER_NODE ((PAGE_SIZE - 16) / sizeof(struct flash_block))
struct flash_block_list {
unsigned long num_blocks;
struct flash_block_list *next;
struct flash_block blocks[FLASH_BLOCKS_PER_NODE];
};
struct flash_block_list_header { /* just the header of flash_block_list */
unsigned long num_blocks;
struct flash_block_list *next;
};
extern struct flash_block_list_header rtas_firmware_flash_list;
extern void (*rtas_flash_term_hook)(int);
extern struct rtas_t rtas;
@@ -1,5 +1,5 @@
#ifndef _ASM_PPC64_SIGCONTEXT_H
#define _ASM_PPC64_SIGCONTEXT_H
#ifndef _ASM_POWERPC_SIGCONTEXT_H
#define _ASM_POWERPC_SIGCONTEXT_H
/*
* This program is free software; you can redistribute it and/or
@@ -9,39 +9,44 @@
*/
#include <linux/compiler.h>
#include <asm/ptrace.h>
#ifdef __powerpc64__
#include <asm/elf.h>
#endif
struct sigcontext {
unsigned long _unused[4];
int signal;
#ifdef __powerpc64__
int _pad0;
#endif
unsigned long handler;
unsigned long oldmask;
struct pt_regs __user *regs;
#ifdef __powerpc64__
elf_gregset_t gp_regs;
elf_fpregset_t fp_regs;
/*
* To maintain compatibility with current implementations the sigcontext is
* extended by appending a pointer (v_regs) to a quadword type (elf_vrreg_t)
* followed by an unstructured (vmx_reserve) field of 69 doublewords. This
* allows the array of vector registers to be quadword aligned independent of
* the alignment of the containing sigcontext or ucontext. It is the
* responsibility of the code setting the sigcontext to set this pointer to
* either NULL (if this processor does not support the VMX feature) or the
* To maintain compatibility with current implementations the sigcontext is
* extended by appending a pointer (v_regs) to a quadword type (elf_vrreg_t)
* followed by an unstructured (vmx_reserve) field of 69 doublewords. This
* allows the array of vector registers to be quadword aligned independent of
* the alignment of the containing sigcontext or ucontext. It is the
* responsibility of the code setting the sigcontext to set this pointer to
* either NULL (if this processor does not support the VMX feature) or the
* address of the first quadword within the allocated (vmx_reserve) area.
*
* The pointer (v_regs) of vector type (elf_vrreg_t) is type compatible with
* an array of 34 quadword entries (elf_vrregset_t). The entries with
* indexes 0-31 contain the corresponding vector registers. The entry with
* index 32 contains the vscr as the last word (offset 12) within the
* quadword. This allows the vscr to be stored as either a quadword (since
* it must be copied via a vector register to/from storage) or as a word.
* The entry with index 33 contains the vrsave as the first word (offset 0)
* The pointer (v_regs) of vector type (elf_vrreg_t) is type compatible with
* an array of 34 quadword entries (elf_vrregset_t). The entries with
* indexes 0-31 contain the corresponding vector registers. The entry with
* index 32 contains the vscr as the last word (offset 12) within the
* quadword. This allows the vscr to be stored as either a quadword (since
* it must be copied via a vector register to/from storage) or as a word.
* The entry with index 33 contains the vrsave as the first word (offset 0)
* within the quadword.
*/
elf_vrreg_t __user *v_regs;
long vmx_reserve[ELF_NVRREG+ELF_NVRREG+1];
#endif
};
#endif /* _ASM_PPC64_SIGCONTEXT_H */
#endif /* _ASM_POWERPC_SIGCONTEXT_H */
@@ -1,5 +1,5 @@
/*
* smp.h: PPC64 specific SMP code.
* smp.h: PowerPC-specific SMP code.
*
* Original was a copy of sparc smp.h. Now heavily modified
* for PPC.
@@ -13,9 +13,9 @@
* 2 of the License, or (at your option) any later version.
*/
#ifndef _ASM_POWERPC_SMP_H
#define _ASM_POWERPC_SMP_H
#ifdef __KERNEL__
#ifndef _PPC64_SMP_H
#define _PPC64_SMP_H
#include <linux/config.h>
#include <linux/threads.h>
@@ -24,7 +24,9 @@
#ifndef __ASSEMBLY__
#ifdef CONFIG_PPC64
#include <asm/paca.h>
#endif
extern int boot_cpuid;
extern int boot_cpuid_phys;
@@ -45,8 +47,19 @@ void generic_cpu_die(unsigned int cpu);
void generic_mach_cpu_die(void);
#endif
#ifdef CONFIG_PPC64
#define raw_smp_processor_id() (get_paca()->paca_index)
#define hard_smp_processor_id() (get_paca()->hw_cpu_id)
#else
/* 32-bit */
extern int smp_hw_index[];
#define raw_smp_processor_id() (current_thread_info()->cpu)
#define hard_smp_processor_id() (smp_hw_index[smp_processor_id()])
#define get_hard_smp_processor_id(cpu) (smp_hw_index[(cpu)])
#define set_hard_smp_processor_id(cpu, phys)\
(smp_hw_index[(cpu)] = (phys))
#endif
extern cpumask_t cpu_sibling_map[NR_CPUS];
@@ -64,14 +77,30 @@ extern cpumask_t cpu_sibling_map[NR_CPUS];
void smp_init_iSeries(void);
void smp_init_pSeries(void);
void smp_init_cell(void);
void smp_setup_cpu_maps(void);
extern int __cpu_disable(void);
extern void __cpu_die(unsigned int cpu);
#else
/* for UP */
#define smp_setup_cpu_maps()
#define smp_release_cpus()
#endif /* CONFIG_SMP */
#ifdef CONFIG_PPC64
#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)
#else
/* 32-bit */
#ifndef CONFIG_SMP
#define get_hard_smp_processor_id(cpu) boot_cpuid_phys
#define set_hard_smp_processor_id(cpu, phys)
#endif
#endif
extern int smt_enabled_at_boot;
@@ -84,15 +113,7 @@ extern void smp_generic_take_timebase(void);
extern struct smp_ops_t *smp_ops;
#ifdef CONFIG_PPC_PSERIES
void vpa_init(int cpu);
#else
static inline void vpa_init(int cpu)
{
}
#endif /* CONFIG_PPC_PSERIES */
#endif /* __ASSEMBLY__ */
#endif /* !(_PPC64_SMP_H) */
#endif /* __KERNEL__ */
#endif /* _ASM_POWERPC_SMP_H) */
@@ -1,5 +1,5 @@
#ifndef _ASM_PPC64_SPARSEMEM_H
#define _ASM_PPC64_SPARSEMEM_H 1
#ifndef _ASM_POWERPC_SPARSEMEM_H
#define _ASM_POWERPC_SPARSEMEM_H 1
#ifdef CONFIG_SPARSEMEM
/*
@@ -13,4 +13,4 @@
#endif /* CONFIG_SPARSEMEM */
#endif /* _ASM_PPC64_SPARSEMEM_H */
#endif /* _ASM_POWERPC_SPARSEMEM_H */
+81
View File
@@ -0,0 +1,81 @@
#ifndef _ASM_POWERPC_STAT_H
#define _ASM_POWERPC_STAT_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.
*/
#include <linux/types.h>
#define STAT_HAVE_NSEC 1
#ifndef __powerpc64__
struct __old_kernel_stat {
unsigned short st_dev;
unsigned short st_ino;
unsigned short st_mode;
unsigned short st_nlink;
unsigned short st_uid;
unsigned short st_gid;
unsigned short st_rdev;
unsigned long st_size;
unsigned long st_atime;
unsigned long st_mtime;
unsigned long st_ctime;
};
#endif /* !__powerpc64__ */
struct stat {
unsigned long st_dev;
ino_t st_ino;
#ifdef __powerpc64__
nlink_t st_nlink;
mode_t st_mode;
#else
mode_t st_mode;
nlink_t st_nlink;
#endif
uid_t st_uid;
gid_t st_gid;
unsigned long st_rdev;
off_t st_size;
unsigned long st_blksize;
unsigned long st_blocks;
unsigned long st_atime;
unsigned long st_atime_nsec;
unsigned long st_mtime;
unsigned long st_mtime_nsec;
unsigned long st_ctime;
unsigned long st_ctime_nsec;
unsigned long __unused4;
unsigned long __unused5;
#ifdef __powerpc64__
unsigned long __unused6;
#endif
};
/* This matches struct stat64 in glibc2.1. Only used for 32 bit. */
struct stat64 {
unsigned long long st_dev; /* Device. */
unsigned long long st_ino; /* File serial number. */
unsigned int st_mode; /* File mode. */
unsigned int st_nlink; /* Link count. */
unsigned int st_uid; /* User ID of the file's owner. */
unsigned int st_gid; /* Group ID of the file's group. */
unsigned long long st_rdev; /* Device number, if device. */
unsigned short __pad2;
long long st_size; /* Size of file, in bytes. */
int st_blksize; /* Optimal block size for I/O. */
long long st_blocks; /* Number 512-byte blocks allocated. */
int st_atime; /* Time of last access. */
unsigned int st_atime_nsec;
int st_mtime; /* Time of last modification. */
unsigned int st_mtime_nsec;
int st_ctime; /* Time of last status change. */
unsigned int st_ctime_nsec;
unsigned int __unused4;
unsigned int __unused5;
};
#endif /* _ASM_POWERPC_STAT_H */
+48
View File
@@ -359,5 +359,53 @@ extern void reloc_got2(unsigned long);
#define PTRRELOC(x) ((typeof(x)) add_reloc_offset((unsigned long)(x)))
static inline void create_instruction(unsigned long addr, unsigned int instr)
{
unsigned int *p;
p = (unsigned int *)addr;
*p = instr;
asm ("dcbst 0, %0; sync; icbi 0,%0; sync; isync" : : "r" (p));
}
/* Flags for create_branch:
* "b" == create_branch(addr, target, 0);
* "ba" == create_branch(addr, target, BRANCH_ABSOLUTE);
* "bl" == create_branch(addr, target, BRANCH_SET_LINK);
* "bla" == create_branch(addr, target, BRANCH_ABSOLUTE | BRANCH_SET_LINK);
*/
#define BRANCH_SET_LINK 0x1
#define BRANCH_ABSOLUTE 0x2
static inline void create_branch(unsigned long addr,
unsigned long target, int flags)
{
unsigned int instruction;
if (! (flags & BRANCH_ABSOLUTE))
target = target - addr;
/* Mask out the flags and target, so they don't step on each other. */
instruction = 0x48000000 | (flags & 0x3) | (target & 0x03FFFFFC);
create_instruction(addr, instruction);
}
static inline void create_function_call(unsigned long addr, void * func)
{
unsigned long func_addr;
#ifdef CONFIG_PPC64
/*
* On PPC64 the function pointer actually points to the function's
* descriptor. The first entry in the descriptor is the address
* of the function text.
*/
func_addr = *(unsigned long *)func;
#else
func_addr = (unsigned long)func;
#endif
create_branch(addr, func_addr, BRANCH_SET_LINK);
}
#endif /* __KERNEL__ */
#endif /* _ASM_POWERPC_SYSTEM_H */
+1 -134
View File
@@ -94,142 +94,9 @@ struct termio {
#define INIT_C_CC "\003\034\177\025\004\001\000\000\000\000\027\022\032\021\023\026\025"
#endif
#define FIOCLEX _IO('f', 1)
#define FIONCLEX _IO('f', 2)
#define FIOASYNC _IOW('f', 125, int)
#define FIONBIO _IOW('f', 126, int)
#define FIONREAD _IOR('f', 127, int)
#define TIOCINQ FIONREAD
#define TIOCGETP _IOR('t', 8, struct sgttyb)
#define TIOCSETP _IOW('t', 9, struct sgttyb)
#define TIOCSETN _IOW('t', 10, struct sgttyb) /* TIOCSETP wo flush */
#define TIOCSETC _IOW('t', 17, struct tchars)
#define TIOCGETC _IOR('t', 18, struct tchars)
#define TCGETS _IOR('t', 19, struct termios)
#define TCSETS _IOW('t', 20, struct termios)
#define TCSETSW _IOW('t', 21, struct termios)
#define TCSETSF _IOW('t', 22, struct termios)
#define TCGETA _IOR('t', 23, struct termio)
#define TCSETA _IOW('t', 24, struct termio)
#define TCSETAW _IOW('t', 25, struct termio)
#define TCSETAF _IOW('t', 28, struct termio)
#define TCSBRK _IO('t', 29)
#define TCXONC _IO('t', 30)
#define TCFLSH _IO('t', 31)
#define TIOCSWINSZ _IOW('t', 103, struct winsize)
#define TIOCGWINSZ _IOR('t', 104, struct winsize)
#define TIOCSTART _IO('t', 110) /* start output, like ^Q */
#define TIOCSTOP _IO('t', 111) /* stop output, like ^S */
#define TIOCOUTQ _IOR('t', 115, int) /* output queue size */
#define TIOCGLTC _IOR('t', 116, struct ltchars)
#define TIOCSLTC _IOW('t', 117, struct ltchars)
#define TIOCSPGRP _IOW('t', 118, int)
#define TIOCGPGRP _IOR('t', 119, int)
#define TIOCEXCL 0x540C
#define TIOCNXCL 0x540D
#define TIOCSCTTY 0x540E
#define TIOCSTI 0x5412
#define TIOCMGET 0x5415
#define TIOCMBIS 0x5416
#define TIOCMBIC 0x5417
#define TIOCMSET 0x5418
#define TIOCGSOFTCAR 0x5419
#define TIOCSSOFTCAR 0x541A
#define TIOCLINUX 0x541C
#define TIOCCONS 0x541D
#define TIOCGSERIAL 0x541E
#define TIOCSSERIAL 0x541F
#define TIOCPKT 0x5420
#define TIOCNOTTY 0x5422
#define TIOCSETD 0x5423
#define TIOCGETD 0x5424
#define TCSBRKP 0x5425 /* Needed for POSIX tcsendbreak() */
#define TIOCSERCONFIG 0x5453
#define TIOCSERGWILD 0x5454
#define TIOCSERSWILD 0x5455
#define TIOCGLCKTRMIOS 0x5456
#define TIOCSLCKTRMIOS 0x5457
#define TIOCSERGSTRUCT 0x5458 /* For debugging only */
#define TIOCSERGETLSR 0x5459 /* Get line status register */
#define TIOCSERGETMULTI 0x545A /* Get multiport config */
#define TIOCSERSETMULTI 0x545B /* Set multiport config */
#define TIOCMIWAIT 0x545C /* wait for a change on serial input line(s) */
#define TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */
/* Used for packet mode */
#define TIOCPKT_DATA 0
#define TIOCPKT_FLUSHREAD 1
#define TIOCPKT_FLUSHWRITE 2
#define TIOCPKT_STOP 4
#define TIOCPKT_START 8
#define TIOCPKT_NOSTOP 16
#define TIOCPKT_DOSTOP 32
/* modem lines */
#define TIOCM_LE 0x001
#define TIOCM_DTR 0x002
#define TIOCM_RTS 0x004
#define TIOCM_ST 0x008
#define TIOCM_SR 0x010
#define TIOCM_CTS 0x020
#define TIOCM_CAR 0x040
#define TIOCM_RNG 0x080
#define TIOCM_DSR 0x100
#define TIOCM_CD TIOCM_CAR
#define TIOCM_RI TIOCM_RNG
#define TIOCM_OUT1 0x2000
#define TIOCM_OUT2 0x4000
#define TIOCM_LOOP 0x8000
/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
#define TIOCSER_TEMT 0x01 /* Transmitter physically empty */
#ifdef __KERNEL__
/*
* Translate a "termio" structure into a "termios". Ugh.
*/
#define SET_LOW_TERMIOS_BITS(termios, termio, x) { \
unsigned short __tmp; \
get_user(__tmp,&(termio)->x); \
(termios)->x = (0xffff0000 & (termios)->x) | __tmp; \
}
#define user_termio_to_kernel_termios(termios, termio) \
({ \
SET_LOW_TERMIOS_BITS(termios, termio, c_iflag); \
SET_LOW_TERMIOS_BITS(termios, termio, c_oflag); \
SET_LOW_TERMIOS_BITS(termios, termio, c_cflag); \
SET_LOW_TERMIOS_BITS(termios, termio, c_lflag); \
copy_from_user((termios)->c_cc, (termio)->c_cc, NCC); \
})
/*
* Translate a "termios" structure into a "termio". Ugh.
*/
#define kernel_termios_to_user_termio(termio, termios) \
({ \
put_user((termios)->c_iflag, &(termio)->c_iflag); \
put_user((termios)->c_oflag, &(termio)->c_oflag); \
put_user((termios)->c_cflag, &(termio)->c_cflag); \
put_user((termios)->c_lflag, &(termio)->c_lflag); \
put_user((termios)->c_line, &(termio)->c_line); \
copy_to_user((termio)->c_cc, (termios)->c_cc, NCC); \
})
#define user_termios_to_kernel_termios(k, u) copy_from_user(k, u, sizeof(struct termios))
#define kernel_termios_to_user_termios(u, k) copy_to_user(u, k, sizeof(struct termios))
#include <asm-generic/termios.h>
#endif /* __KERNEL__ */
+1 -1
View File
@@ -21,7 +21,7 @@
#include <asm/processor.h>
#ifdef CONFIG_PPC64
#include <asm/paca.h>
#include <asm/iSeries/HvCall.h>
#include <asm/iseries/hv_call.h>
#endif
/* time.c */
@@ -1,6 +1,7 @@
/*
* TLB shootdown specifics for PPC
* TLB shootdown specifics for powerpc
*
* Copyright (C) 2002 Anton Blanchard, IBM Corp.
* Copyright (C) 2002 Paul Mackerras, IBM Corp.
*
* This program is free software; you can redistribute it and/or
@@ -8,29 +9,53 @@
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
#ifndef _PPC_TLB_H
#define _PPC_TLB_H
#ifndef _ASM_POWERPC_TLB_H
#define _ASM_POWERPC_TLB_H
#include <linux/config.h>
#ifndef __powerpc64__
#include <asm/pgtable.h>
#endif
#include <asm/pgalloc.h>
#include <asm/tlbflush.h>
#ifndef __powerpc64__
#include <asm/page.h>
#include <asm/mmu.h>
#ifdef CONFIG_PPC_STD_MMU
/* Classic PPC with hash-table based MMU... */
#endif
struct mmu_gather;
#define tlb_start_vma(tlb, vma) do { } while (0)
#define tlb_end_vma(tlb, vma) do { } while (0)
#if !defined(CONFIG_PPC_STD_MMU)
#define tlb_flush(tlb) flush_tlb_mm((tlb)->mm)
#elif defined(__powerpc64__)
extern void pte_free_finish(void);
static inline void tlb_flush(struct mmu_gather *tlb)
{
flush_tlb_pending();
pte_free_finish();
}
#else
extern void tlb_flush(struct mmu_gather *tlb);
#endif
/* Get the generic bits... */
#include <asm-generic/tlb.h>
/* Nothing needed here in fact... */
#define tlb_start_vma(tlb, vma) do { } while (0)
#define tlb_end_vma(tlb, vma) do { } while (0)
#if !defined(CONFIG_PPC_STD_MMU) || defined(__powerpc64__)
#define __tlb_remove_tlb_entry(tlb, pte, address) do { } while (0)
#else
extern void flush_hash_entry(struct mm_struct *mm, pte_t *ptep,
unsigned long address);
@@ -41,17 +66,5 @@ static inline void __tlb_remove_tlb_entry(struct mmu_gather *tlb, pte_t *ptep,
flush_hash_entry(tlb->mm, ptep, address);
}
#else
/* Embedded PPC with software-loaded TLB, very simple... */
#define tlb_start_vma(tlb, vma) do { } while (0)
#define tlb_end_vma(tlb, vma) do { } while (0)
#define __tlb_remove_tlb_entry(tlb, pte, address) do { } while (0)
#define tlb_flush(tlb) flush_tlb_mm((tlb)->mm)
/* Get the generic bits... */
#include <asm-generic/tlb.h>
#endif /* CONFIG_PPC_STD_MMU */
#endif /* __PPC_TLB_H */
#endif
#endif /* __ASM_POWERPC_TLB_H */
+146
View File
@@ -0,0 +1,146 @@
#ifndef _ASM_POWERPC_TLBFLUSH_H
#define _ASM_POWERPC_TLBFLUSH_H
/*
* TLB flushing:
*
* - flush_tlb_mm(mm) flushes the specified mm context TLB's
* - flush_tlb_page(vma, vmaddr) flushes one page
* - flush_tlb_page_nohash(vma, vmaddr) flushes one page if SW loaded TLB
* - flush_tlb_range(vma, start, end) flushes a range of pages
* - flush_tlb_kernel_range(start, end) flushes a range of kernel pages
* - flush_tlb_pgtables(mm, start, end) flushes a range of page tables
*
* 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>
struct mm_struct;
#ifdef CONFIG_PPC64
#include <linux/percpu.h>
#include <asm/page.h>
#define PPC64_TLB_BATCH_NR 192
struct ppc64_tlb_batch {
unsigned long index;
struct mm_struct *mm;
pte_t pte[PPC64_TLB_BATCH_NR];
unsigned long vaddr[PPC64_TLB_BATCH_NR];
unsigned int large;
};
DECLARE_PER_CPU(struct ppc64_tlb_batch, ppc64_tlb_batch);
extern void __flush_tlb_pending(struct ppc64_tlb_batch *batch);
static inline void flush_tlb_pending(void)
{
struct ppc64_tlb_batch *batch = &get_cpu_var(ppc64_tlb_batch);
if (batch->index)
__flush_tlb_pending(batch);
put_cpu_var(ppc64_tlb_batch);
}
extern void flush_hash_page(unsigned long va, pte_t pte, int local);
void flush_hash_range(unsigned long number, int local);
#else /* CONFIG_PPC64 */
#include <linux/mm.h>
extern void _tlbie(unsigned long address);
extern void _tlbia(void);
/*
* TODO: (CONFIG_FSL_BOOKE) determine if flush_tlb_range &
* flush_tlb_kernel_range are best implemented as tlbia vs
* specific tlbie's
*/
#if (defined(CONFIG_4xx) && !defined(CONFIG_44x)) || defined(CONFIG_8xx)
#define flush_tlb_pending() asm volatile ("tlbia; sync" : : : "memory")
#elif defined(CONFIG_4xx) || defined(CONFIG_FSL_BOOKE)
#define flush_tlb_pending() _tlbia()
#endif
/*
* This gets called at the end of handling a page fault, when
* the kernel has put a new PTE into the page table for the process.
* We use it to ensure coherency between the i-cache and d-cache
* for the page which has just been mapped in.
* On machines which use an MMU hash table, we use this to put a
* corresponding HPTE into the hash table ahead of time, instead of
* waiting for the inevitable extra hash-table miss exception.
*/
extern void update_mmu_cache(struct vm_area_struct *, unsigned long, pte_t);
#endif /* CONFIG_PPC64 */
#if defined(CONFIG_PPC64) || defined(CONFIG_4xx) || \
defined(CONFIG_FSL_BOOKE) || defined(CONFIG_8xx)
static inline void flush_tlb_mm(struct mm_struct *mm)
{
flush_tlb_pending();
}
static inline void flush_tlb_page(struct vm_area_struct *vma,
unsigned long vmaddr)
{
#ifdef CONFIG_PPC64
flush_tlb_pending();
#else
_tlbie(vmaddr);
#endif
}
static inline void flush_tlb_page_nohash(struct vm_area_struct *vma,
unsigned long vmaddr)
{
#ifndef CONFIG_PPC64
_tlbie(vmaddr);
#endif
}
static inline void flush_tlb_range(struct vm_area_struct *vma,
unsigned long start, unsigned long end)
{
flush_tlb_pending();
}
static inline void flush_tlb_kernel_range(unsigned long start,
unsigned long end)
{
flush_tlb_pending();
}
#else /* 6xx, 7xx, 7xxx cpus */
extern void flush_tlb_mm(struct mm_struct *mm);
extern void flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr);
extern void flush_tlb_page_nohash(struct vm_area_struct *vma, unsigned long addr);
extern void flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
unsigned long end);
extern void flush_tlb_kernel_range(unsigned long start, unsigned long end);
#endif
/*
* This is called in munmap when we have freed up some page-table
* pages. We don't need to do anything here, there's nothing special
* about our page-table pages. -- paulus
*/
static inline void flush_tlb_pgtables(struct mm_struct *mm,
unsigned long start, unsigned long end)
{
}
#endif /*__KERNEL__ */
#endif /* _ASM_POWERPC_TLBFLUSH_H */
+468
View File
@@ -0,0 +1,468 @@
#ifndef _ARCH_POWERPC_UACCESS_H
#define _ARCH_POWERPC_UACCESS_H
#ifdef __KERNEL__
#ifndef __ASSEMBLY__
#include <linux/sched.h>
#include <linux/errno.h>
#include <asm/processor.h>
#define VERIFY_READ 0
#define VERIFY_WRITE 1
/*
* The fs value determines whether argument validity checking should be
* performed or not. If get_fs() == USER_DS, checking is performed, with
* get_fs() == KERNEL_DS, checking is bypassed.
*
* For historical reasons, these macros are grossly misnamed.
*
* The fs/ds values are now the highest legal address in the "segment".
* This simplifies the checking in the routines below.
*/
#define MAKE_MM_SEG(s) ((mm_segment_t) { (s) })
#define KERNEL_DS MAKE_MM_SEG(~0UL)
#ifdef __powerpc64__
/* We use TASK_SIZE_USER64 as TASK_SIZE is not constant */
#define USER_DS MAKE_MM_SEG(TASK_SIZE_USER64 - 1)
#else
#define USER_DS MAKE_MM_SEG(TASK_SIZE - 1)
#endif
#define get_ds() (KERNEL_DS)
#define get_fs() (current->thread.fs)
#define set_fs(val) (current->thread.fs = (val))
#define segment_eq(a, b) ((a).seg == (b).seg)
#ifdef __powerpc64__
/*
* This check is sufficient because there is a large enough
* gap between user addresses and the kernel addresses
*/
#define __access_ok(addr, size, segment) \
(((addr) <= (segment).seg) && ((size) <= (segment).seg))
#else
#define __access_ok(addr, size, segment) \
(((addr) <= (segment).seg) && \
(((size) == 0) || (((size) - 1) <= ((segment).seg - (addr)))))
#endif
#define access_ok(type, addr, size) \
(__chk_user_ptr(addr), \
__access_ok((__force unsigned long)(addr), (size), get_fs()))
/*
* The exception table consists of pairs of addresses: the first is the
* address of an instruction that is allowed to fault, and the second is
* the address at which the program should continue. No registers are
* modified, so it is entirely up to the continuation code to figure out
* what to do.
*
* All the routines below use bits of fixup code that are out of line
* with the main instruction path. This means when everything is well,
* we don't even have to jump over them. Further, they do not intrude
* on our cache or tlb entries.
*/
struct exception_table_entry {
unsigned long insn;
unsigned long fixup;
};
/*
* These are the main single-value transfer routines. They automatically
* use the right size if we just have the right pointer type.
*
* This gets kind of ugly. We want to return _two_ values in "get_user()"
* and yet we don't want to do any pointers, because that is too much
* of a performance impact. Thus we have a few rather ugly macros here,
* and hide all the ugliness from the user.
*
* The "__xxx" versions of the user access functions are versions that
* do not verify the address space, that must have been done previously
* with a separate "access_ok()" call (this is used when we do multiple
* accesses to the same area of user memory).
*
* As we use the same address space for kernel and user data on the
* PowerPC, we can just do these as direct assignments. (Of course, the
* exception handling means that it's no longer "just"...)
*
* The "user64" versions of the user access functions are versions that
* allow access of 64-bit data. The "get_user" functions do not
* properly handle 64-bit data because the value gets down cast to a long.
* The "put_user" functions already handle 64-bit data properly but we add
* "user64" versions for completeness
*/
#define get_user(x, ptr) \
__get_user_check((x), (ptr), sizeof(*(ptr)))
#define put_user(x, ptr) \
__put_user_check((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)))
#define __get_user(x, ptr) \
__get_user_nocheck((x), (ptr), sizeof(*(ptr)))
#define __put_user(x, ptr) \
__put_user_nocheck((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)))
#ifndef __powerpc64__
#define __get_user64(x, ptr) \
__get_user64_nocheck((x), (ptr), sizeof(*(ptr)))
#define __put_user64(x, ptr) __put_user(x, ptr)
#endif
#define __get_user_unaligned __get_user
#define __put_user_unaligned __put_user
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
* are no aliasing issues.
*/
#define __put_user_asm(x, addr, err, op) \
__asm__ __volatile__( \
"1: " op " %1,0(%2) # put_user\n" \
"2:\n" \
".section .fixup,\"ax\"\n" \
"3: li %0,%3\n" \
" b 2b\n" \
".previous\n" \
".section __ex_table,\"a\"\n" \
" .align " __EX_TABLE_ALIGN "\n" \
" ."__EX_TABLE_TYPE" 1b,3b\n" \
".previous" \
: "=r" (err) \
: "r" (x), "b" (addr), "i" (-EFAULT), "0" (err))
#ifdef __powerpc64__
#define __put_user_asm2(x, ptr, retval) \
__put_user_asm(x, ptr, retval, "std")
#else /* __powerpc64__ */
#define __put_user_asm2(x, addr, err) \
__asm__ __volatile__( \
"1: stw %1,0(%2)\n" \
"2: stw %1+1,4(%2)\n" \
"3:\n" \
".section .fixup,\"ax\"\n" \
"4: li %0,%3\n" \
" 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" \
".previous" \
: "=r" (err) \
: "r" (x), "b" (addr), "i" (-EFAULT), "0" (err))
#endif /* __powerpc64__ */
#define __put_user_size(x, ptr, size, retval) \
do { \
retval = 0; \
switch (size) { \
case 1: __put_user_asm(x, ptr, retval, "stb"); break; \
case 2: __put_user_asm(x, ptr, retval, "sth"); break; \
case 4: __put_user_asm(x, ptr, retval, "stw"); break; \
case 8: __put_user_asm2(x, ptr, retval); break; \
default: __put_user_bad(); \
} \
} while (0)
#define __put_user_nocheck(x, ptr, size) \
({ \
long __pu_err; \
might_sleep(); \
__chk_user_ptr(ptr); \
__put_user_size((x), (ptr), (size), __pu_err); \
__pu_err; \
})
#define __put_user_check(x, ptr, size) \
({ \
long __pu_err = -EFAULT; \
__typeof__(*(ptr)) __user *__pu_addr = (ptr); \
might_sleep(); \
if (access_ok(VERIFY_WRITE, __pu_addr, size)) \
__put_user_size((x), __pu_addr, (size), __pu_err); \
__pu_err; \
})
extern long __get_user_bad(void);
#define __get_user_asm(x, addr, err, op) \
__asm__ __volatile__( \
"1: "op" %1,0(%2) # get_user\n" \
"2:\n" \
".section .fixup,\"ax\"\n" \
"3: li %0,%3\n" \
" li %1,0\n" \
" b 2b\n" \
".previous\n" \
".section __ex_table,\"a\"\n" \
" .align "__EX_TABLE_ALIGN "\n" \
" ." __EX_TABLE_TYPE " 1b,3b\n" \
".previous" \
: "=r" (err), "=r" (x) \
: "b" (addr), "i" (-EFAULT), "0" (err))
#ifdef __powerpc64__
#define __get_user_asm2(x, addr, err) \
__get_user_asm(x, addr, err, "ld")
#else /* __powerpc64__ */
#define __get_user_asm2(x, addr, err) \
__asm__ __volatile__( \
"1: lwz %1,0(%2)\n" \
"2: lwz %1+1,4(%2)\n" \
"3:\n" \
".section .fixup,\"ax\"\n" \
"4: li %0,%3\n" \
" li %1,0\n" \
" li %1+1,0\n" \
" 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" \
".previous" \
: "=r" (err), "=&r" (x) \
: "b" (addr), "i" (-EFAULT), "0" (err))
#endif /* __powerpc64__ */
#define __get_user_size(x, ptr, size, retval) \
do { \
retval = 0; \
__chk_user_ptr(ptr); \
if (size > sizeof(x)) \
(x) = __get_user_bad(); \
switch (size) { \
case 1: __get_user_asm(x, ptr, retval, "lbz"); break; \
case 2: __get_user_asm(x, ptr, retval, "lhz"); break; \
case 4: __get_user_asm(x, ptr, retval, "lwz"); break; \
case 8: __get_user_asm2(x, ptr, retval); break; \
default: (x) = __get_user_bad(); \
} \
} while (0)
#define __get_user_nocheck(x, ptr, size) \
({ \
long __gu_err; \
unsigned long __gu_val; \
__chk_user_ptr(ptr); \
might_sleep(); \
__get_user_size(__gu_val, (ptr), (size), __gu_err); \
(x) = (__typeof__(*(ptr)))__gu_val; \
__gu_err; \
})
#ifndef __powerpc64__
#define __get_user64_nocheck(x, ptr, size) \
({ \
long __gu_err; \
long long __gu_val; \
__chk_user_ptr(ptr); \
might_sleep(); \
__get_user_size(__gu_val, (ptr), (size), __gu_err); \
(x) = (__typeof__(*(ptr)))__gu_val; \
__gu_err; \
})
#endif /* __powerpc64__ */
#define __get_user_check(x, ptr, size) \
({ \
long __gu_err = -EFAULT; \
unsigned long __gu_val = 0; \
const __typeof__(*(ptr)) __user *__gu_addr = (ptr); \
might_sleep(); \
if (access_ok(VERIFY_READ, __gu_addr, (size))) \
__get_user_size(__gu_val, __gu_addr, (size), __gu_err); \
(x) = (__typeof__(*(ptr)))__gu_val; \
__gu_err; \
})
/* more complex routines */
extern unsigned long __copy_tofrom_user(void __user *to,
const void __user *from, unsigned long size);
#ifndef __powerpc64__
extern inline unsigned long copy_from_user(void *to,
const void __user *from, unsigned long n)
{
unsigned long over;
if (access_ok(VERIFY_READ, from, n))
return __copy_tofrom_user((__force void __user *)to, from, n);
if ((unsigned long)from < TASK_SIZE) {
over = (unsigned long)from + n - TASK_SIZE;
return __copy_tofrom_user((__force void __user *)to, from,
n - over) + over;
}
return n;
}
extern inline unsigned long copy_to_user(void __user *to,
const void *from, unsigned long n)
{
unsigned long over;
if (access_ok(VERIFY_WRITE, to, n))
return __copy_tofrom_user(to, (__force void __user *)from, n);
if ((unsigned long)to < TASK_SIZE) {
over = (unsigned long)to + n - TASK_SIZE;
return __copy_tofrom_user(to, (__force void __user *)from,
n - over) + over;
}
return n;
}
#else /* __powerpc64__ */
#define __copy_in_user(to, from, size) \
__copy_tofrom_user((to), (from), (size))
extern unsigned long copy_from_user(void *to, const void __user *from,
unsigned long n);
extern unsigned long copy_to_user(void __user *to, const void *from,
unsigned long n);
extern unsigned long copy_in_user(void __user *to, const void __user *from,
unsigned long n);
#endif /* __powerpc64__ */
static inline unsigned long __copy_from_user_inatomic(void *to,
const void __user *from, unsigned long n)
{
if (__builtin_constant_p(n) && (n <= 8)) {
unsigned long ret;
switch (n) {
case 1:
__get_user_size(*(u8 *)to, from, 1, ret);
break;
case 2:
__get_user_size(*(u16 *)to, from, 2, ret);
break;
case 4:
__get_user_size(*(u32 *)to, from, 4, ret);
break;
case 8:
__get_user_size(*(u64 *)to, from, 8, ret);
break;
}
if (ret == 0)
return 0;
}
return __copy_tofrom_user((__force void __user *)to, from, n);
}
static inline unsigned long __copy_to_user_inatomic(void __user *to,
const void *from, unsigned long n)
{
if (__builtin_constant_p(n) && (n <= 8)) {
unsigned long ret;
switch (n) {
case 1:
__put_user_size(*(u8 *)from, (u8 __user *)to, 1, ret);
break;
case 2:
__put_user_size(*(u16 *)from, (u16 __user *)to, 2, ret);
break;
case 4:
__put_user_size(*(u32 *)from, (u32 __user *)to, 4, ret);
break;
case 8:
__put_user_size(*(u64 *)from, (u64 __user *)to, 8, ret);
break;
}
if (ret == 0)
return 0;
}
return __copy_tofrom_user(to, (__force const void __user *)from, n);
}
static inline unsigned long __copy_from_user(void *to,
const void __user *from, unsigned long size)
{
might_sleep();
return __copy_from_user_inatomic(to, from, size);
}
static inline unsigned long __copy_to_user(void __user *to,
const void *from, unsigned long size)
{
might_sleep();
return __copy_to_user_inatomic(to, from, size);
}
extern unsigned long __clear_user(void __user *addr, unsigned long size);
static inline unsigned long clear_user(void __user *addr, unsigned long size)
{
might_sleep();
if (likely(access_ok(VERIFY_WRITE, addr, size)))
return __clear_user(addr, size);
if ((unsigned long)addr < TASK_SIZE) {
unsigned long over = (unsigned long)addr + size - TASK_SIZE;
return __clear_user(addr, size - over) + over;
}
return size;
}
extern int __strncpy_from_user(char *dst, const char __user *src, long count);
static inline long strncpy_from_user(char *dst, const char __user *src,
long count)
{
might_sleep();
if (likely(access_ok(VERIFY_READ, src, 1)))
return __strncpy_from_user(dst, src, count);
return -EFAULT;
}
/*
* Return the size of a string (including the ending 0)
*
* Return 0 for error
*/
extern int __strnlen_user(const char __user *str, long len, unsigned long top);
/*
* Returns the length of the string at str (including the null byte),
* or 0 if we hit a page we can't access,
* or something > len if we didn't find a null byte.
*
* The `top' parameter to __strnlen_user is to make sure that
* we can never overflow from the user area into kernel space.
*/
static inline int strnlen_user(const char __user *str, long len)
{
unsigned long top = current->thread.fs.seg;
if ((unsigned long)str > top)
return 0;
return __strnlen_user(str, len, top);
}
#define strlen_user(str) strnlen_user((str), 0x7ffffffe)
#endif /* __ASSEMBLY__ */
#endif /* __KERNEL__ */
#endif /* _ARCH_POWERPC_UACCESS_H */
+40
View File
@@ -0,0 +1,40 @@
#ifndef _ASM_POWERPC_UCONTEXT_H
#define _ASM_POWERPC_UCONTEXT_H
#ifdef __powerpc64__
#include <asm/sigcontext.h>
#else
#include <asm/elf.h>
#endif
#include <asm/signal.h>
#ifndef __powerpc64__
struct mcontext {
elf_gregset_t mc_gregs;
elf_fpregset_t mc_fregs;
unsigned long mc_pad[2];
elf_vrregset_t mc_vregs __attribute__((__aligned__(16)));
};
#endif
struct ucontext {
unsigned long uc_flags;
struct ucontext __user *uc_link;
stack_t uc_stack;
#ifndef __powerpc64__
int uc_pad[7];
struct mcontext __user *uc_regs;/* points to uc_mcontext field */
#endif
sigset_t uc_sigmask;
/* glibc has 1024-bit signal masks, ours are 64-bit */
#ifdef __powerpc64__
sigset_t __unused[15]; /* Allow for uc_sigmask growth */
struct sigcontext uc_mcontext; /* last for extensibility */
#else
int uc_maskext[30];
int uc_pad2[3];
struct mcontext uc_mcontext;
#endif
};
#endif /* _ASM_POWERPC_UCONTEXT_H */
-460
View File
@@ -1,460 +0,0 @@
/*
* bitops.h: Bit string operations on the ppc
*/
#ifdef __KERNEL__
#ifndef _PPC_BITOPS_H
#define _PPC_BITOPS_H
#include <linux/config.h>
#include <linux/compiler.h>
#include <asm/byteorder.h>
#include <asm/atomic.h>
/*
* The test_and_*_bit operations are taken to imply a memory barrier
* on SMP systems.
*/
#ifdef CONFIG_SMP
#define SMP_WMB "eieio\n"
#define SMP_MB "\nsync"
#else
#define SMP_WMB
#define SMP_MB
#endif /* CONFIG_SMP */
static __inline__ void set_bit(int nr, volatile unsigned long * addr)
{
unsigned long old;
unsigned long mask = 1 << (nr & 0x1f);
unsigned long *p = ((unsigned long *)addr) + (nr >> 5);
__asm__ __volatile__("\n\
1: lwarx %0,0,%3 \n\
or %0,%0,%2 \n"
PPC405_ERR77(0,%3)
" stwcx. %0,0,%3 \n\
bne- 1b"
: "=&r" (old), "=m" (*p)
: "r" (mask), "r" (p), "m" (*p)
: "cc" );
}
/*
* non-atomic version
*/
static __inline__ void __set_bit(int nr, volatile unsigned long *addr)
{
unsigned long mask = 1 << (nr & 0x1f);
unsigned long *p = ((unsigned long *)addr) + (nr >> 5);
*p |= mask;
}
/*
* clear_bit doesn't imply a memory barrier
*/
#define smp_mb__before_clear_bit() smp_mb()
#define smp_mb__after_clear_bit() smp_mb()
static __inline__ void clear_bit(int nr, volatile unsigned long *addr)
{
unsigned long old;
unsigned long mask = 1 << (nr & 0x1f);
unsigned long *p = ((unsigned long *)addr) + (nr >> 5);
__asm__ __volatile__("\n\
1: lwarx %0,0,%3 \n\
andc %0,%0,%2 \n"
PPC405_ERR77(0,%3)
" stwcx. %0,0,%3 \n\
bne- 1b"
: "=&r" (old), "=m" (*p)
: "r" (mask), "r" (p), "m" (*p)
: "cc");
}
/*
* non-atomic version
*/
static __inline__ void __clear_bit(int nr, volatile unsigned long *addr)
{
unsigned long mask = 1 << (nr & 0x1f);
unsigned long *p = ((unsigned long *)addr) + (nr >> 5);
*p &= ~mask;
}
static __inline__ void change_bit(int nr, volatile unsigned long *addr)
{
unsigned long old;
unsigned long mask = 1 << (nr & 0x1f);
unsigned long *p = ((unsigned long *)addr) + (nr >> 5);
__asm__ __volatile__("\n\
1: lwarx %0,0,%3 \n\
xor %0,%0,%2 \n"
PPC405_ERR77(0,%3)
" stwcx. %0,0,%3 \n\
bne- 1b"
: "=&r" (old), "=m" (*p)
: "r" (mask), "r" (p), "m" (*p)
: "cc");
}
/*
* non-atomic version
*/
static __inline__ void __change_bit(int nr, volatile unsigned long *addr)
{
unsigned long mask = 1 << (nr & 0x1f);
unsigned long *p = ((unsigned long *)addr) + (nr >> 5);
*p ^= mask;
}
/*
* test_and_*_bit do imply a memory barrier (?)
*/
static __inline__ int test_and_set_bit(int nr, volatile unsigned long *addr)
{
unsigned int old, t;
unsigned int mask = 1 << (nr & 0x1f);
volatile unsigned int *p = ((volatile unsigned int *)addr) + (nr >> 5);
__asm__ __volatile__(SMP_WMB "\n\
1: lwarx %0,0,%4 \n\
or %1,%0,%3 \n"
PPC405_ERR77(0,%4)
" stwcx. %1,0,%4 \n\
bne 1b"
SMP_MB
: "=&r" (old), "=&r" (t), "=m" (*p)
: "r" (mask), "r" (p), "m" (*p)
: "cc", "memory");
return (old & mask) != 0;
}
/*
* non-atomic version
*/
static __inline__ int __test_and_set_bit(int nr, volatile unsigned long *addr)
{
unsigned long mask = 1 << (nr & 0x1f);
unsigned long *p = ((unsigned long *)addr) + (nr >> 5);
unsigned long old = *p;
*p = old | mask;
return (old & mask) != 0;
}
static __inline__ int test_and_clear_bit(int nr, volatile unsigned long *addr)
{
unsigned int old, t;
unsigned int mask = 1 << (nr & 0x1f);
volatile unsigned int *p = ((volatile unsigned int *)addr) + (nr >> 5);
__asm__ __volatile__(SMP_WMB "\n\
1: lwarx %0,0,%4 \n\
andc %1,%0,%3 \n"
PPC405_ERR77(0,%4)
" stwcx. %1,0,%4 \n\
bne 1b"
SMP_MB
: "=&r" (old), "=&r" (t), "=m" (*p)
: "r" (mask), "r" (p), "m" (*p)
: "cc", "memory");
return (old & mask) != 0;
}
/*
* non-atomic version
*/
static __inline__ int __test_and_clear_bit(int nr, volatile unsigned long *addr)
{
unsigned long mask = 1 << (nr & 0x1f);
unsigned long *p = ((unsigned long *)addr) + (nr >> 5);
unsigned long old = *p;
*p = old & ~mask;
return (old & mask) != 0;
}
static __inline__ int test_and_change_bit(int nr, volatile unsigned long *addr)
{
unsigned int old, t;
unsigned int mask = 1 << (nr & 0x1f);
volatile unsigned int *p = ((volatile unsigned int *)addr) + (nr >> 5);
__asm__ __volatile__(SMP_WMB "\n\
1: lwarx %0,0,%4 \n\
xor %1,%0,%3 \n"
PPC405_ERR77(0,%4)
" stwcx. %1,0,%4 \n\
bne 1b"
SMP_MB
: "=&r" (old), "=&r" (t), "=m" (*p)
: "r" (mask), "r" (p), "m" (*p)
: "cc", "memory");
return (old & mask) != 0;
}
/*
* non-atomic version
*/
static __inline__ int __test_and_change_bit(int nr, volatile unsigned long *addr)
{
unsigned long mask = 1 << (nr & 0x1f);
unsigned long *p = ((unsigned long *)addr) + (nr >> 5);
unsigned long old = *p;
*p = old ^ mask;
return (old & mask) != 0;
}
static __inline__ int test_bit(int nr, __const__ volatile unsigned long *addr)
{
return ((addr[nr >> 5] >> (nr & 0x1f)) & 1) != 0;
}
/* Return the bit position of the most significant 1 bit in a word */
static __inline__ int __ilog2(unsigned long x)
{
int lz;
asm ("cntlzw %0,%1" : "=r" (lz) : "r" (x));
return 31 - lz;
}
static __inline__ int ffz(unsigned long x)
{
if ((x = ~x) == 0)
return 32;
return __ilog2(x & -x);
}
static inline int __ffs(unsigned long x)
{
return __ilog2(x & -x);
}
/*
* ffs: find first bit set. This is defined the same way as
* the libc and compiler builtin ffs routines, therefore
* differs in spirit from the above ffz (man ffs).
*/
static __inline__ int ffs(int x)
{
return __ilog2(x & -x) + 1;
}
/*
* fls: find last (most-significant) bit set.
* Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32.
*/
static __inline__ int fls(unsigned int x)
{
int lz;
asm ("cntlzw %0,%1" : "=r" (lz) : "r" (x));
return 32 - lz;
}
/*
* hweightN: returns the hamming weight (i.e. the number
* of bits set) of a N-bit word
*/
#define hweight32(x) generic_hweight32(x)
#define hweight16(x) generic_hweight16(x)
#define hweight8(x) generic_hweight8(x)
/*
* Find the first bit set in a 140-bit bitmap.
* The first 100 bits are unlikely to be set.
*/
static inline int sched_find_first_bit(const unsigned long *b)
{
if (unlikely(b[0]))
return __ffs(b[0]);
if (unlikely(b[1]))
return __ffs(b[1]) + 32;
if (unlikely(b[2]))
return __ffs(b[2]) + 64;
if (b[3])
return __ffs(b[3]) + 96;
return __ffs(b[4]) + 128;
}
/**
* find_next_bit - find the next set bit in a memory region
* @addr: The address to base the search on
* @offset: The bitnumber to start searching at
* @size: The maximum size to search
*/
static __inline__ unsigned long find_next_bit(const unsigned long *addr,
unsigned long size, unsigned long offset)
{
unsigned int *p = ((unsigned int *) addr) + (offset >> 5);
unsigned int result = offset & ~31UL;
unsigned int tmp;
if (offset >= size)
return size;
size -= result;
offset &= 31UL;
if (offset) {
tmp = *p++;
tmp &= ~0UL << offset;
if (size < 32)
goto found_first;
if (tmp)
goto found_middle;
size -= 32;
result += 32;
}
while (size >= 32) {
if ((tmp = *p++) != 0)
goto found_middle;
result += 32;
size -= 32;
}
if (!size)
return result;
tmp = *p;
found_first:
tmp &= ~0UL >> (32 - size);
if (tmp == 0UL) /* Are any bits set? */
return result + size; /* Nope. */
found_middle:
return result + __ffs(tmp);
}
/**
* find_first_bit - find the first set bit in a memory region
* @addr: The address to start the search at
* @size: The maximum size to search
*
* Returns the bit-number of the first set bit, not the number of the byte
* containing a bit.
*/
#define find_first_bit(addr, size) \
find_next_bit((addr), (size), 0)
/*
* This implementation of find_{first,next}_zero_bit was stolen from
* Linus' asm-alpha/bitops.h.
*/
#define find_first_zero_bit(addr, size) \
find_next_zero_bit((addr), (size), 0)
static __inline__ unsigned long find_next_zero_bit(const unsigned long *addr,
unsigned long size, unsigned long offset)
{
unsigned int * p = ((unsigned int *) addr) + (offset >> 5);
unsigned int result = offset & ~31UL;
unsigned int tmp;
if (offset >= size)
return size;
size -= result;
offset &= 31UL;
if (offset) {
tmp = *p++;
tmp |= ~0UL >> (32-offset);
if (size < 32)
goto found_first;
if (tmp != ~0U)
goto found_middle;
size -= 32;
result += 32;
}
while (size >= 32) {
if ((tmp = *p++) != ~0U)
goto found_middle;
result += 32;
size -= 32;
}
if (!size)
return result;
tmp = *p;
found_first:
tmp |= ~0UL << size;
if (tmp == ~0UL) /* Are any bits zero? */
return result + size; /* Nope. */
found_middle:
return result + ffz(tmp);
}
#define ext2_set_bit(nr, addr) __test_and_set_bit((nr) ^ 0x18, (unsigned long *)(addr))
#define ext2_set_bit_atomic(lock, nr, addr) test_and_set_bit((nr) ^ 0x18, (unsigned long *)(addr))
#define ext2_clear_bit(nr, addr) __test_and_clear_bit((nr) ^ 0x18, (unsigned long *)(addr))
#define ext2_clear_bit_atomic(lock, nr, addr) test_and_clear_bit((nr) ^ 0x18, (unsigned long *)(addr))
static __inline__ int ext2_test_bit(int nr, __const__ void * addr)
{
__const__ unsigned char *ADDR = (__const__ unsigned char *) addr;
return (ADDR[nr >> 3] >> (nr & 7)) & 1;
}
/*
* This implementation of ext2_find_{first,next}_zero_bit was stolen from
* Linus' asm-alpha/bitops.h and modified for a big-endian machine.
*/
#define ext2_find_first_zero_bit(addr, size) \
ext2_find_next_zero_bit((addr), (size), 0)
static __inline__ unsigned long ext2_find_next_zero_bit(const void *addr,
unsigned long size, unsigned long offset)
{
unsigned int *p = ((unsigned int *) addr) + (offset >> 5);
unsigned int result = offset & ~31UL;
unsigned int tmp;
if (offset >= size)
return size;
size -= result;
offset &= 31UL;
if (offset) {
tmp = cpu_to_le32p(p++);
tmp |= ~0UL >> (32-offset);
if (size < 32)
goto found_first;
if (tmp != ~0U)
goto found_middle;
size -= 32;
result += 32;
}
while (size >= 32) {
if ((tmp = cpu_to_le32p(p++)) != ~0U)
goto found_middle;
result += 32;
size -= 32;
}
if (!size)
return result;
tmp = cpu_to_le32p(p);
found_first:
tmp |= ~0U << size;
if (tmp == ~0UL) /* Are any bits zero? */
return result + size; /* Nope. */
found_middle:
return result + ffz(tmp);
}
/* Bitmap functions for the minix filesystem. */
#define minix_test_and_set_bit(nr,addr) ext2_set_bit(nr,addr)
#define minix_set_bit(nr,addr) ((void)ext2_set_bit(nr,addr))
#define minix_test_and_clear_bit(nr,addr) ext2_clear_bit(nr,addr)
#define minix_test_bit(nr,addr) ext2_test_bit(nr,addr)
#define minix_find_first_zero_bit(addr,size) ext2_find_first_zero_bit(addr,size)
#endif /* _PPC_BITOPS_H */
#endif /* __KERNEL__ */
+2
View File
@@ -83,6 +83,8 @@ extern uint m8xx_cpm_hostalloc(uint size);
extern int m8xx_cpm_hostfree(uint start);
extern void m8xx_cpm_hostdump(void);
extern void cpm_load_patch(volatile immap_t *immr);
/* Buffer descriptors used by many of the CPM protocols.
*/
typedef struct cpm_buf_desc {
-53
View File
@@ -1,53 +0,0 @@
#ifndef _ASM_FUTEX_H
#define _ASM_FUTEX_H
#ifdef __KERNEL__
#include <linux/futex.h>
#include <asm/errno.h>
#include <asm/uaccess.h>
static inline int
futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
{
int op = (encoded_op >> 28) & 7;
int cmp = (encoded_op >> 24) & 15;
int oparg = (encoded_op << 8) >> 20;
int cmparg = (encoded_op << 20) >> 20;
int oldval = 0, ret;
if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
oparg = 1 << oparg;
if (! access_ok (VERIFY_WRITE, uaddr, sizeof(int)))
return -EFAULT;
inc_preempt_count();
switch (op) {
case FUTEX_OP_SET:
case FUTEX_OP_ADD:
case FUTEX_OP_OR:
case FUTEX_OP_ANDN:
case FUTEX_OP_XOR:
default:
ret = -ENOSYS;
}
dec_preempt_count();
if (!ret) {
switch (cmp) {
case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break;
case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break;
case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break;
case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break;
case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break;
case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break;
default: ret = -ENOSYS;
}
}
return ret;
}
#endif
#endif
-29
View File
@@ -1,29 +0,0 @@
#ifndef __PPC_IPCBUF_H__
#define __PPC_IPCBUF_H__
/*
* The ipc64_perm structure for PPC architecture.
* Note extra padding because this structure is passed back and forth
* between kernel and user space.
*
* Pad space is left for:
* - 1 32-bit value to fill up for 8-byte alignment
* - 2 miscellaneous 64-bit values (so that this structure matches
* PPC64 ipc64_perm)
*/
struct ipc64_perm
{
__kernel_key_t key;
__kernel_uid_t uid;
__kernel_gid_t gid;
__kernel_uid_t cuid;
__kernel_gid_t cgid;
__kernel_mode_t mode;
unsigned long seq;
unsigned int __pad2;
unsigned long long __unused1;
unsigned long long __unused2;
};
#endif /* __PPC_IPCBUF_H__ */
-40
View File
@@ -1,40 +0,0 @@
#ifndef _PPC_KEXEC_H
#define _PPC_KEXEC_H
#ifdef CONFIG_KEXEC
/*
* KEXEC_SOURCE_MEMORY_LIMIT maximum page get_free_page can return.
* I.e. Maximum page that is mapped directly into kernel memory,
* and kmap is not required.
*
* Someone correct me if FIXADDR_START - PAGEOFFSET is not the correct
* calculation for the amount of memory directly mappable into the
* kernel memory space.
*/
/* Maximum physical address we can use pages from */
#define KEXEC_SOURCE_MEMORY_LIMIT (-1UL)
/* Maximum address we can reach in physical address mode */
#define KEXEC_DESTINATION_MEMORY_LIMIT (-1UL)
/* Maximum address we can use for the control code buffer */
#define KEXEC_CONTROL_MEMORY_LIMIT TASK_SIZE
#define KEXEC_CONTROL_CODE_SIZE 4096
/* The native architecture */
#define KEXEC_ARCH KEXEC_ARCH_PPC
#ifndef __ASSEMBLY__
extern void *crash_notes;
struct kimage;
extern void machine_kexec_simple(struct kimage *image);
#endif /* __ASSEMBLY__ */
#endif /* CONFIG_KEXEC */
#endif /* _PPC_KEXEC_H */
-152
View File
@@ -1,152 +0,0 @@
#ifndef _PPC_PTRACE_H
#define _PPC_PTRACE_H
/*
* This struct defines the way the registers are stored on the
* kernel stack during a system call or other kernel entry.
*
* this should only contain volatile regs
* since we can keep non-volatile in the thread_struct
* should set this up when only volatiles are saved
* by intr code.
*
* Since this is going on the stack, *CARE MUST BE TAKEN* to insure
* that the overall structure is a multiple of 16 bytes in length.
*
* Note that the offsets of the fields in this struct correspond with
* the PT_* values below. This simplifies arch/ppc/kernel/ptrace.c.
*/
#ifndef __ASSEMBLY__
struct pt_regs {
unsigned long gpr[32];
unsigned long nip;
unsigned long msr;
unsigned long orig_gpr3; /* Used for restarting system calls */
unsigned long ctr;
unsigned long link;
unsigned long xer;
unsigned long ccr;
unsigned long mq; /* 601 only (not used at present) */
/* Used on APUS to hold IPL value. */
unsigned long trap; /* Reason for being here */
/* N.B. for critical exceptions on 4xx, the dar and dsisr
fields are overloaded to hold srr0 and srr1. */
unsigned long dar; /* Fault registers */
unsigned long dsisr; /* on 4xx/Book-E used for ESR */
unsigned long result; /* Result of a system call */
};
#endif /* __ASSEMBLY__ */
#ifdef __KERNEL__
#define STACK_FRAME_OVERHEAD 16 /* size of minimum stack frame */
/* Size of stack frame allocated when calling signal handler. */
#define __SIGNAL_FRAMESIZE 64
#ifndef __ASSEMBLY__
#define instruction_pointer(regs) ((regs)->nip)
#ifdef CONFIG_SMP
extern unsigned long profile_pc(struct pt_regs *regs);
#else
#define profile_pc(regs) instruction_pointer(regs)
#endif
#define user_mode(regs) (((regs)->msr & MSR_PR) != 0)
#define force_successful_syscall_return() \
do { \
current_thread_info()->syscall_noerror = 1; \
} while(0)
/*
* We use the least-significant bit of the trap field to indicate
* whether we have saved the full set of registers, or only a
* partial set. A 1 there means the partial set.
* On 4xx we use the next bit to indicate whether the exception
* is a critical exception (1 means it is).
*/
#define FULL_REGS(regs) (((regs)->trap & 1) == 0)
#define IS_CRITICAL_EXC(regs) (((regs)->trap & 2) == 0)
#define TRAP(regs) ((regs)->trap & ~0xF)
#define CHECK_FULL_REGS(regs) \
do { \
if ((regs)->trap & 1) \
printk(KERN_CRIT "%s: partial register set\n", __FUNCTION__); \
} while (0)
#endif /* __ASSEMBLY__ */
#endif /* __KERNEL__ */
/*
* Offsets used by 'ptrace' system call interface.
* These can't be changed without breaking binary compatibility
* with MkLinux, etc.
*/
#define PT_R0 0
#define PT_R1 1
#define PT_R2 2
#define PT_R3 3
#define PT_R4 4
#define PT_R5 5
#define PT_R6 6
#define PT_R7 7
#define PT_R8 8
#define PT_R9 9
#define PT_R10 10
#define PT_R11 11
#define PT_R12 12
#define PT_R13 13
#define PT_R14 14
#define PT_R15 15
#define PT_R16 16
#define PT_R17 17
#define PT_R18 18
#define PT_R19 19
#define PT_R20 20
#define PT_R21 21
#define PT_R22 22
#define PT_R23 23
#define PT_R24 24
#define PT_R25 25
#define PT_R26 26
#define PT_R27 27
#define PT_R28 28
#define PT_R29 29
#define PT_R30 30
#define PT_R31 31
#define PT_NIP 32
#define PT_MSR 33
#ifdef __KERNEL__
#define PT_ORIG_R3 34
#endif
#define PT_CTR 35
#define PT_LNK 36
#define PT_XER 37
#define PT_CCR 38
#define PT_MQ 39
#define PT_FPR0 48 /* each FP reg occupies 2 slots in this space */
#define PT_FPR31 (PT_FPR0 + 2*31)
#define PT_FPSCR (PT_FPR0 + 2*32 + 1)
/* Get/set all the altivec registers vr0..vr31, vscr, vrsave, in one go */
#define PTRACE_GETVRREGS 18
#define PTRACE_SETVRREGS 19
/* Get/set all the upper 32-bits of the SPE registers, accumulator, and
* spefscr, in one go */
#define PTRACE_GETEVRREGS 20
#define PTRACE_SETEVRREGS 21
/*
* Get or set a debug register. The first 16 are DABR registers and the
* second 16 are IABR registers.
*/
#define PTRACE_GET_DEBUGREG 25
#define PTRACE_SET_DEBUGREG 26
#endif
-15
View File
@@ -1,15 +0,0 @@
#ifndef _ASM_PPC_SIGCONTEXT_H
#define _ASM_PPC_SIGCONTEXT_H
#include <asm/ptrace.h>
#include <linux/compiler.h>
struct sigcontext {
unsigned long _unused[4];
int signal;
unsigned long handler;
unsigned long oldmask;
struct pt_regs __user *regs;
};
#endif
-69
View File
@@ -1,69 +0,0 @@
#ifndef _PPC_STAT_H
#define _PPC_STAT_H
#ifdef __KERNEL__
#include <linux/types.h>
#endif /* __KERNEL__ */
struct __old_kernel_stat {
unsigned short st_dev;
unsigned short st_ino;
unsigned short st_mode;
unsigned short st_nlink;
unsigned short st_uid;
unsigned short st_gid;
unsigned short st_rdev;
unsigned long st_size;
unsigned long st_atime;
unsigned long st_mtime;
unsigned long st_ctime;
};
#define STAT_HAVE_NSEC 1
struct stat {
unsigned st_dev;
ino_t st_ino;
mode_t st_mode;
nlink_t st_nlink;
uid_t st_uid;
gid_t st_gid;
unsigned st_rdev;
off_t st_size;
unsigned long st_blksize;
unsigned long st_blocks;
unsigned long st_atime;
unsigned long st_atime_nsec;
unsigned long st_mtime;
unsigned long st_mtime_nsec;
unsigned long st_ctime;
unsigned long st_ctime_nsec;
unsigned long __unused4;
unsigned long __unused5;
};
/* This matches struct stat64 in glibc2.1.
*/
struct stat64 {
unsigned long long st_dev; /* Device. */
unsigned long long st_ino; /* File serial number. */
unsigned int st_mode; /* File mode. */
unsigned int st_nlink; /* Link count. */
unsigned int st_uid; /* User ID of the file's owner. */
unsigned int st_gid; /* Group ID of the file's group. */
unsigned long long st_rdev; /* Device number, if device. */
unsigned short int __pad2;
long long st_size; /* Size of file, in bytes. */
long st_blksize; /* Optimal block size for I/O. */
long long st_blocks; /* Number 512-byte blocks allocated. */
long st_atime; /* Time of last access. */
unsigned long st_atime_nsec;
long st_mtime; /* Time of last modification. */
unsigned long int st_mtime_nsec;
long st_ctime; /* Time of last status change. */
unsigned long int st_ctime_nsec;
unsigned long int __unused4;
unsigned long int __unused5;
};
#endif
-115
View File
@@ -1,115 +0,0 @@
/*
* include/asm-ppc/tlbflush.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.
*/
#ifdef __KERNEL__
#ifndef _PPC_TLBFLUSH_H
#define _PPC_TLBFLUSH_H
#include <linux/config.h>
#include <linux/mm.h>
extern void _tlbie(unsigned long address);
extern void _tlbia(void);
#if defined(CONFIG_4xx)
#ifndef CONFIG_44x
#define __tlbia() asm volatile ("sync; tlbia; isync" : : : "memory")
#else
#define __tlbia _tlbia
#endif
static inline void flush_tlb_mm(struct mm_struct *mm)
{ __tlbia(); }
static inline void flush_tlb_page(struct vm_area_struct *vma,
unsigned long vmaddr)
{ _tlbie(vmaddr); }
static inline void flush_tlb_page_nohash(struct vm_area_struct *vma,
unsigned long vmaddr)
{ _tlbie(vmaddr); }
static inline void flush_tlb_range(struct vm_area_struct *vma,
unsigned long start, unsigned long end)
{ __tlbia(); }
static inline void flush_tlb_kernel_range(unsigned long start,
unsigned long end)
{ __tlbia(); }
#elif defined(CONFIG_FSL_BOOKE)
/* TODO: determine if flush_tlb_range & flush_tlb_kernel_range
* are best implemented as tlbia vs specific tlbie's */
#define __tlbia() _tlbia()
static inline void flush_tlb_mm(struct mm_struct *mm)
{ __tlbia(); }
static inline void flush_tlb_page(struct vm_area_struct *vma,
unsigned long vmaddr)
{ _tlbie(vmaddr); }
static inline void flush_tlb_page_nohash(struct vm_area_struct *vma,
unsigned long vmaddr)
{ _tlbie(vmaddr); }
static inline void flush_tlb_range(struct vm_area_struct *vma,
unsigned long start, unsigned long end)
{ __tlbia(); }
static inline void flush_tlb_kernel_range(unsigned long start,
unsigned long end)
{ __tlbia(); }
#elif defined(CONFIG_8xx)
#define __tlbia() asm volatile ("tlbia; sync" : : : "memory")
static inline void flush_tlb_mm(struct mm_struct *mm)
{ __tlbia(); }
static inline void flush_tlb_page(struct vm_area_struct *vma,
unsigned long vmaddr)
{ _tlbie(vmaddr); }
static inline void flush_tlb_page_nohash(struct vm_area_struct *vma,
unsigned long vmaddr)
{ _tlbie(vmaddr); }
static inline void flush_tlb_range(struct vm_area_struct *vma,
unsigned long start, unsigned long end)
{ __tlbia(); }
static inline void flush_tlb_kernel_range(unsigned long start,
unsigned long end)
{ __tlbia(); }
#else /* 6xx, 7xx, 7xxx cpus */
struct mm_struct;
struct vm_area_struct;
extern void flush_tlb_mm(struct mm_struct *mm);
extern void flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr);
extern void flush_tlb_page_nohash(struct vm_area_struct *vma, unsigned long addr);
extern void flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
unsigned long end);
extern void flush_tlb_kernel_range(unsigned long start, unsigned long end);
#endif
/*
* This is called in munmap when we have freed up some page-table
* pages. We don't need to do anything here, there's nothing special
* about our page-table pages. -- paulus
*/
static inline void flush_tlb_pgtables(struct mm_struct *mm,
unsigned long start, unsigned long end)
{
}
/*
* This gets called at the end of handling a page fault, when
* the kernel has put a new PTE into the page table for the process.
* We use it to ensure coherency between the i-cache and d-cache
* for the page which has just been mapped in.
* On machines which use an MMU hash table, we use this to put a
* corresponding HPTE into the hash table ahead of time, instead of
* waiting for the inevitable extra hash-table miss exception.
*/
extern void update_mmu_cache(struct vm_area_struct *, unsigned long, pte_t);
#endif /* _PPC_TLBFLUSH_H */
#endif /*__KERNEL__ */
-393
View File
@@ -1,393 +0,0 @@
#ifdef __KERNEL__
#ifndef _PPC_UACCESS_H
#define _PPC_UACCESS_H
#ifndef __ASSEMBLY__
#include <linux/sched.h>
#include <linux/errno.h>
#include <asm/processor.h>
#define VERIFY_READ 0
#define VERIFY_WRITE 1
/*
* The fs value determines whether argument validity checking should be
* performed or not. If get_fs() == USER_DS, checking is performed, with
* get_fs() == KERNEL_DS, checking is bypassed.
*
* For historical reasons, these macros are grossly misnamed.
*
* The fs/ds values are now the highest legal address in the "segment".
* This simplifies the checking in the routines below.
*/
#define KERNEL_DS ((mm_segment_t) { ~0UL })
#define USER_DS ((mm_segment_t) { TASK_SIZE - 1 })
#define get_ds() (KERNEL_DS)
#define get_fs() (current->thread.fs)
#define set_fs(val) (current->thread.fs = (val))
#define segment_eq(a,b) ((a).seg == (b).seg)
#define __access_ok(addr,size) \
((addr) <= current->thread.fs.seg \
&& ((size) == 0 || (size) - 1 <= current->thread.fs.seg - (addr)))
#define access_ok(type, addr, size) \
(__chk_user_ptr(addr),__access_ok((unsigned long)(addr),(size)))
/*
* The exception table consists of pairs of addresses: the first is the
* address of an instruction that is allowed to fault, and the second is
* the address at which the program should continue. No registers are
* modified, so it is entirely up to the continuation code to figure out
* what to do.
*
* All the routines below use bits of fixup code that are out of line
* with the main instruction path. This means when everything is well,
* we don't even have to jump over them. Further, they do not intrude
* on our cache or tlb entries.
*/
struct exception_table_entry
{
unsigned long insn, fixup;
};
/*
* These are the main single-value transfer routines. They automatically
* use the right size if we just have the right pointer type.
*
* This gets kind of ugly. We want to return _two_ values in "get_user()"
* and yet we don't want to do any pointers, because that is too much
* of a performance impact. Thus we have a few rather ugly macros here,
* and hide all the ugliness from the user.
*
* The "__xxx" versions of the user access functions are versions that
* do not verify the address space, that must have been done previously
* with a separate "access_ok()" call (this is used when we do multiple
* accesses to the same area of user memory).
*
* As we use the same address space for kernel and user data on the
* PowerPC, we can just do these as direct assignments. (Of course, the
* exception handling means that it's no longer "just"...)
*
* The "user64" versions of the user access functions are versions that
* allow access of 64-bit data. The "get_user" functions do not
* properly handle 64-bit data because the value gets down cast to a long.
* The "put_user" functions already handle 64-bit data properly but we add
* "user64" versions for completeness
*/
#define get_user(x,ptr) \
__get_user_check((x),(ptr),sizeof(*(ptr)))
#define get_user64(x,ptr) \
__get_user64_check((x),(ptr),sizeof(*(ptr)))
#define put_user(x,ptr) \
__put_user_check((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr)))
#define put_user64(x,ptr) put_user(x,ptr)
#define __get_user(x,ptr) \
__get_user_nocheck((x),(ptr),sizeof(*(ptr)))
#define __get_user64(x,ptr) \
__get_user64_nocheck((x),(ptr),sizeof(*(ptr)))
#define __put_user(x,ptr) \
__put_user_nocheck((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr)))
#define __put_user64(x,ptr) __put_user(x,ptr)
extern long __put_user_bad(void);
#define __put_user_nocheck(x,ptr,size) \
({ \
long __pu_err; \
__chk_user_ptr(ptr); \
__put_user_size((x),(ptr),(size),__pu_err); \
__pu_err; \
})
#define __put_user_check(x,ptr,size) \
({ \
long __pu_err = -EFAULT; \
__typeof__(*(ptr)) __user *__pu_addr = (ptr); \
if (access_ok(VERIFY_WRITE,__pu_addr,size)) \
__put_user_size((x),__pu_addr,(size),__pu_err); \
__pu_err; \
})
#define __put_user_size(x,ptr,size,retval) \
do { \
retval = 0; \
switch (size) { \
case 1: \
__put_user_asm(x, ptr, retval, "stb"); \
break; \
case 2: \
__put_user_asm(x, ptr, retval, "sth"); \
break; \
case 4: \
__put_user_asm(x, ptr, retval, "stw"); \
break; \
case 8: \
__put_user_asm2(x, ptr, retval); \
break; \
default: \
__put_user_bad(); \
} \
} while (0)
/*
* 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
* are no aliasing issues.
*/
#define __put_user_asm(x, addr, err, op) \
__asm__ __volatile__( \
"1: "op" %1,0(%2)\n" \
"2:\n" \
".section .fixup,\"ax\"\n" \
"3: li %0,%3\n" \
" b 2b\n" \
".previous\n" \
".section __ex_table,\"a\"\n" \
" .align 2\n" \
" .long 1b,3b\n" \
".previous" \
: "=r" (err) \
: "r" (x), "b" (addr), "i" (-EFAULT), "0" (err))
#define __put_user_asm2(x, addr, err) \
__asm__ __volatile__( \
"1: stw %1,0(%2)\n" \
"2: stw %1+1,4(%2)\n" \
"3:\n" \
".section .fixup,\"ax\"\n" \
"4: li %0,%3\n" \
" b 3b\n" \
".previous\n" \
".section __ex_table,\"a\"\n" \
" .align 2\n" \
" .long 1b,4b\n" \
" .long 2b,4b\n" \
".previous" \
: "=r" (err) \
: "r" (x), "b" (addr), "i" (-EFAULT), "0" (err))
#define __get_user_nocheck(x, ptr, size) \
({ \
long __gu_err; \
unsigned long __gu_val; \
__chk_user_ptr(ptr); \
__get_user_size(__gu_val, (ptr), (size), __gu_err); \
(x) = (__typeof__(*(ptr)))__gu_val; \
__gu_err; \
})
#define __get_user64_nocheck(x, ptr, size) \
({ \
long __gu_err; \
long long __gu_val; \
__chk_user_ptr(ptr); \
__get_user_size64(__gu_val, (ptr), (size), __gu_err); \
(x) = (__typeof__(*(ptr)))__gu_val; \
__gu_err; \
})
#define __get_user_check(x, ptr, size) \
({ \
long __gu_err = -EFAULT; \
unsigned long __gu_val = 0; \
const __typeof__(*(ptr)) __user *__gu_addr = (ptr); \
if (access_ok(VERIFY_READ, __gu_addr, (size))) \
__get_user_size(__gu_val, __gu_addr, (size), __gu_err); \
(x) = (__typeof__(*(ptr)))__gu_val; \
__gu_err; \
})
#define __get_user64_check(x, ptr, size) \
({ \
long __gu_err = -EFAULT; \
long long __gu_val = 0; \
const __typeof__(*(ptr)) __user *__gu_addr = (ptr); \
if (access_ok(VERIFY_READ, __gu_addr, (size))) \
__get_user_size64(__gu_val, __gu_addr, (size), __gu_err); \
(x) = (__typeof__(*(ptr)))__gu_val; \
__gu_err; \
})
extern long __get_user_bad(void);
#define __get_user_size(x, ptr, size, retval) \
do { \
retval = 0; \
switch (size) { \
case 1: \
__get_user_asm(x, ptr, retval, "lbz"); \
break; \
case 2: \
__get_user_asm(x, ptr, retval, "lhz"); \
break; \
case 4: \
__get_user_asm(x, ptr, retval, "lwz"); \
break; \
default: \
x = __get_user_bad(); \
} \
} while (0)
#define __get_user_size64(x, ptr, size, retval) \
do { \
retval = 0; \
switch (size) { \
case 1: \
__get_user_asm(x, ptr, retval, "lbz"); \
break; \
case 2: \
__get_user_asm(x, ptr, retval, "lhz"); \
break; \
case 4: \
__get_user_asm(x, ptr, retval, "lwz"); \
break; \
case 8: \
__get_user_asm2(x, ptr, retval); \
break; \
default: \
x = __get_user_bad(); \
} \
} while (0)
#define __get_user_asm(x, addr, err, op) \
__asm__ __volatile__( \
"1: "op" %1,0(%2)\n" \
"2:\n" \
".section .fixup,\"ax\"\n" \
"3: li %0,%3\n" \
" li %1,0\n" \
" b 2b\n" \
".previous\n" \
".section __ex_table,\"a\"\n" \
" .align 2\n" \
" .long 1b,3b\n" \
".previous" \
: "=r"(err), "=r"(x) \
: "b"(addr), "i"(-EFAULT), "0"(err))
#define __get_user_asm2(x, addr, err) \
__asm__ __volatile__( \
"1: lwz %1,0(%2)\n" \
"2: lwz %1+1,4(%2)\n" \
"3:\n" \
".section .fixup,\"ax\"\n" \
"4: li %0,%3\n" \
" li %1,0\n" \
" li %1+1,0\n" \
" b 3b\n" \
".previous\n" \
".section __ex_table,\"a\"\n" \
" .align 2\n" \
" .long 1b,4b\n" \
" .long 2b,4b\n" \
".previous" \
: "=r"(err), "=&r"(x) \
: "b"(addr), "i"(-EFAULT), "0"(err))
/* more complex routines */
extern int __copy_tofrom_user(void __user *to, const void __user *from,
unsigned long size);
extern inline unsigned long
copy_from_user(void *to, const void __user *from, unsigned long n)
{
unsigned long over;
if (access_ok(VERIFY_READ, from, n))
return __copy_tofrom_user((__force void __user *)to, from, n);
if ((unsigned long)from < TASK_SIZE) {
over = (unsigned long)from + n - TASK_SIZE;
return __copy_tofrom_user((__force void __user *)to, from, n - over) + over;
}
return n;
}
extern inline unsigned long
copy_to_user(void __user *to, const void *from, unsigned long n)
{
unsigned long over;
if (access_ok(VERIFY_WRITE, to, n))
return __copy_tofrom_user(to, (__force void __user *) from, n);
if ((unsigned long)to < TASK_SIZE) {
over = (unsigned long)to + n - TASK_SIZE;
return __copy_tofrom_user(to, (__force void __user *) from, n - over) + over;
}
return n;
}
static inline unsigned long __copy_from_user(void *to, const void __user *from, unsigned long size)
{
return __copy_tofrom_user((__force void __user *)to, from, size);
}
static inline unsigned long __copy_to_user(void __user *to, const void *from, unsigned long size)
{
return __copy_tofrom_user(to, (__force void __user *)from, size);
}
#define __copy_to_user_inatomic __copy_to_user
#define __copy_from_user_inatomic __copy_from_user
extern unsigned long __clear_user(void __user *addr, unsigned long size);
extern inline unsigned long
clear_user(void __user *addr, unsigned long size)
{
if (access_ok(VERIFY_WRITE, addr, size))
return __clear_user(addr, size);
if ((unsigned long)addr < TASK_SIZE) {
unsigned long over = (unsigned long)addr + size - TASK_SIZE;
return __clear_user(addr, size - over) + over;
}
return size;
}
extern int __strncpy_from_user(char *dst, const char __user *src, long count);
extern inline long
strncpy_from_user(char *dst, const char __user *src, long count)
{
if (access_ok(VERIFY_READ, src, 1))
return __strncpy_from_user(dst, src, count);
return -EFAULT;
}
/*
* Return the size of a string (including the ending 0)
*
* Return 0 for error
*/
extern int __strnlen_user(const char __user *str, long len, unsigned long top);
/*
* Returns the length of the string at str (including the null byte),
* or 0 if we hit a page we can't access,
* or something > len if we didn't find a null byte.
*
* The `top' parameter to __strnlen_user is to make sure that
* we can never overflow from the user area into kernel space.
*/
extern __inline__ int strnlen_user(const char __user *str, long len)
{
unsigned long top = current->thread.fs.seg;
if ((unsigned long)str > top)
return 0;
return __strnlen_user(str, len, top);
}
#define strlen_user(str) strnlen_user((str), 0x7ffffffe)
#endif /* __ASSEMBLY__ */
#endif /* _PPC_UACCESS_H */
#endif /* __KERNEL__ */
-27
View File
@@ -1,27 +0,0 @@
#ifndef _ASMPPC_UCONTEXT_H
#define _ASMPPC_UCONTEXT_H
#include <asm/elf.h>
#include <asm/signal.h>
struct mcontext {
elf_gregset_t mc_gregs;
elf_fpregset_t mc_fregs;
unsigned long mc_pad[2];
elf_vrregset_t mc_vregs __attribute__((__aligned__(16)));
};
struct ucontext {
unsigned long uc_flags;
struct ucontext __user *uc_link;
stack_t uc_stack;
int uc_pad[7];
struct mcontext __user *uc_regs;/* points to uc_mcontext field */
sigset_t uc_sigmask;
/* glibc has 1024-bit signal masks, ours are 64-bit */
int uc_maskext[30];
int uc_pad2[3];
struct mcontext uc_mcontext;
};
#endif /* !_ASMPPC_UCONTEXT_H */
-360
View File
@@ -1,360 +0,0 @@
/*
* PowerPC64 atomic bit operations.
* Dave Engebretsen, Todd Inglett, Don Reed, Pat McCarthy, Peter Bergner,
* Anton Blanchard
*
* Originally taken from the 32b PPC code. Modified to use 64b values for
* the various counters & memory references.
*
* Bitops are odd when viewed on big-endian systems. They were designed
* on little endian so the size of the bitset doesn't matter (low order bytes
* come first) as long as the bit in question is valid.
*
* Bits are "tested" often using the C expression (val & (1<<nr)) so we do
* our best to stay compatible with that. The assumption is that val will
* be unsigned long for such tests. As such, we assume the bits are stored
* as an array of unsigned long (the usual case is a single unsigned long,
* of course). Here's an example bitset with bit numbering:
*
* |63..........0|127........64|195.......128|255.......196|
*
* This leads to a problem. If an int, short or char is passed as a bitset
* it will be a bad memory reference since we want to store in chunks
* of unsigned long (64 bits here) size.
*
* There are a few little-endian macros used mostly for filesystem bitmaps,
* these work on similar bit arrays layouts, but byte-oriented:
*
* |7...0|15...8|23...16|31...24|39...32|47...40|55...48|63...56|
*
* The main difference is that bit 3-5 in the bit number field needs to be
* reversed compared to the big-endian bit fields. This can be achieved
* by XOR with 0b111000 (0x38).
*
* 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 _PPC64_BITOPS_H
#define _PPC64_BITOPS_H
#ifdef __KERNEL__
#include <asm/synch.h>
/*
* clear_bit doesn't imply a memory barrier
*/
#define smp_mb__before_clear_bit() smp_mb()
#define smp_mb__after_clear_bit() smp_mb()
static __inline__ int test_bit(unsigned long nr, __const__ volatile unsigned long *addr)
{
return (1UL & (addr[nr >> 6] >> (nr & 63)));
}
static __inline__ void set_bit(unsigned long nr, volatile unsigned long *addr)
{
unsigned long old;
unsigned long mask = 1UL << (nr & 0x3f);
unsigned long *p = ((unsigned long *)addr) + (nr >> 6);
__asm__ __volatile__(
"1: ldarx %0,0,%3 # set_bit\n\
or %0,%0,%2\n\
stdcx. %0,0,%3\n\
bne- 1b"
: "=&r" (old), "=m" (*p)
: "r" (mask), "r" (p), "m" (*p)
: "cc");
}
static __inline__ void clear_bit(unsigned long nr, volatile unsigned long *addr)
{
unsigned long old;
unsigned long mask = 1UL << (nr & 0x3f);
unsigned long *p = ((unsigned long *)addr) + (nr >> 6);
__asm__ __volatile__(
"1: ldarx %0,0,%3 # clear_bit\n\
andc %0,%0,%2\n\
stdcx. %0,0,%3\n\
bne- 1b"
: "=&r" (old), "=m" (*p)
: "r" (mask), "r" (p), "m" (*p)
: "cc");
}
static __inline__ void change_bit(unsigned long nr, volatile unsigned long *addr)
{
unsigned long old;
unsigned long mask = 1UL << (nr & 0x3f);
unsigned long *p = ((unsigned long *)addr) + (nr >> 6);
__asm__ __volatile__(
"1: ldarx %0,0,%3 # change_bit\n\
xor %0,%0,%2\n\
stdcx. %0,0,%3\n\
bne- 1b"
: "=&r" (old), "=m" (*p)
: "r" (mask), "r" (p), "m" (*p)
: "cc");
}
static __inline__ int test_and_set_bit(unsigned long nr, volatile unsigned long *addr)
{
unsigned long old, t;
unsigned long mask = 1UL << (nr & 0x3f);
unsigned long *p = ((unsigned long *)addr) + (nr >> 6);
__asm__ __volatile__(
EIEIO_ON_SMP
"1: ldarx %0,0,%3 # test_and_set_bit\n\
or %1,%0,%2 \n\
stdcx. %1,0,%3 \n\
bne- 1b"
ISYNC_ON_SMP
: "=&r" (old), "=&r" (t)
: "r" (mask), "r" (p)
: "cc", "memory");
return (old & mask) != 0;
}
static __inline__ int test_and_clear_bit(unsigned long nr, volatile unsigned long *addr)
{
unsigned long old, t;
unsigned long mask = 1UL << (nr & 0x3f);
unsigned long *p = ((unsigned long *)addr) + (nr >> 6);
__asm__ __volatile__(
EIEIO_ON_SMP
"1: ldarx %0,0,%3 # test_and_clear_bit\n\
andc %1,%0,%2\n\
stdcx. %1,0,%3\n\
bne- 1b"
ISYNC_ON_SMP
: "=&r" (old), "=&r" (t)
: "r" (mask), "r" (p)
: "cc", "memory");
return (old & mask) != 0;
}
static __inline__ int test_and_change_bit(unsigned long nr, volatile unsigned long *addr)
{
unsigned long old, t;
unsigned long mask = 1UL << (nr & 0x3f);
unsigned long *p = ((unsigned long *)addr) + (nr >> 6);
__asm__ __volatile__(
EIEIO_ON_SMP
"1: ldarx %0,0,%3 # test_and_change_bit\n\
xor %1,%0,%2\n\
stdcx. %1,0,%3\n\
bne- 1b"
ISYNC_ON_SMP
: "=&r" (old), "=&r" (t)
: "r" (mask), "r" (p)
: "cc", "memory");
return (old & mask) != 0;
}
static __inline__ void set_bits(unsigned long mask, unsigned long *addr)
{
unsigned long old;
__asm__ __volatile__(
"1: ldarx %0,0,%3 # set_bit\n\
or %0,%0,%2\n\
stdcx. %0,0,%3\n\
bne- 1b"
: "=&r" (old), "=m" (*addr)
: "r" (mask), "r" (addr), "m" (*addr)
: "cc");
}
/*
* non-atomic versions
*/
static __inline__ void __set_bit(unsigned long nr, volatile unsigned long *addr)
{
unsigned long mask = 1UL << (nr & 0x3f);
unsigned long *p = ((unsigned long *)addr) + (nr >> 6);
*p |= mask;
}
static __inline__ void __clear_bit(unsigned long nr, volatile unsigned long *addr)
{
unsigned long mask = 1UL << (nr & 0x3f);
unsigned long *p = ((unsigned long *)addr) + (nr >> 6);
*p &= ~mask;
}
static __inline__ void __change_bit(unsigned long nr, volatile unsigned long *addr)
{
unsigned long mask = 1UL << (nr & 0x3f);
unsigned long *p = ((unsigned long *)addr) + (nr >> 6);
*p ^= mask;
}
static __inline__ int __test_and_set_bit(unsigned long nr, volatile unsigned long *addr)
{
unsigned long mask = 1UL << (nr & 0x3f);
unsigned long *p = ((unsigned long *)addr) + (nr >> 6);
unsigned long old = *p;
*p = old | mask;
return (old & mask) != 0;
}
static __inline__ int __test_and_clear_bit(unsigned long nr, volatile unsigned long *addr)
{
unsigned long mask = 1UL << (nr & 0x3f);
unsigned long *p = ((unsigned long *)addr) + (nr >> 6);
unsigned long old = *p;
*p = old & ~mask;
return (old & mask) != 0;
}
static __inline__ int __test_and_change_bit(unsigned long nr, volatile unsigned long *addr)
{
unsigned long mask = 1UL << (nr & 0x3f);
unsigned long *p = ((unsigned long *)addr) + (nr >> 6);
unsigned long old = *p;
*p = old ^ mask;
return (old & mask) != 0;
}
/*
* Return the zero-based bit position (from RIGHT TO LEFT, 63 -> 0) of the
* most significant (left-most) 1-bit in a double word.
*/
static __inline__ int __ilog2(unsigned long x)
{
int lz;
asm ("cntlzd %0,%1" : "=r" (lz) : "r" (x));
return 63 - lz;
}
/*
* Determines the bit position of the least significant (rightmost) 0 bit
* in the specified double word. The returned bit position will be zero-based,
* starting from the right side (63 - 0).
*/
static __inline__ unsigned long ffz(unsigned long x)
{
/* no zero exists anywhere in the 8 byte area. */
if ((x = ~x) == 0)
return 64;
/*
* Calculate the bit position of the least signficant '1' bit in x
* (since x has been changed this will actually be the least signficant
* '0' bit in * the original x). Note: (x & -x) gives us a mask that
* is the least significant * (RIGHT-most) 1-bit of the value in x.
*/
return __ilog2(x & -x);
}
static __inline__ int __ffs(unsigned long x)
{
return __ilog2(x & -x);
}
/*
* ffs: find first bit set. This is defined the same way as
* the libc and compiler builtin ffs routines, therefore
* differs in spirit from the above ffz (man ffs).
*/
static __inline__ int ffs(int x)
{
unsigned long i = (unsigned long)x;
return __ilog2(i & -i) + 1;
}
/*
* fls: find last (most-significant) bit set.
* Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32.
*/
#define fls(x) generic_fls(x)
/*
* hweightN: returns the hamming weight (i.e. the number
* of bits set) of a N-bit word
*/
#define hweight64(x) generic_hweight64(x)
#define hweight32(x) generic_hweight32(x)
#define hweight16(x) generic_hweight16(x)
#define hweight8(x) generic_hweight8(x)
extern unsigned long find_next_zero_bit(const unsigned long *addr, unsigned long size, unsigned long offset);
#define find_first_zero_bit(addr, size) \
find_next_zero_bit((addr), (size), 0)
extern unsigned long find_next_bit(const unsigned long *addr, unsigned long size, unsigned long offset);
#define find_first_bit(addr, size) \
find_next_bit((addr), (size), 0)
extern unsigned long find_next_zero_le_bit(const unsigned long *addr, unsigned long size, unsigned long offset);
#define find_first_zero_le_bit(addr, size) \
find_next_zero_le_bit((addr), (size), 0)
static __inline__ int test_le_bit(unsigned long nr, __const__ unsigned long * addr)
{
__const__ unsigned char *ADDR = (__const__ unsigned char *) addr;
return (ADDR[nr >> 3] >> (nr & 7)) & 1;
}
#define test_and_clear_le_bit(nr, addr) \
test_and_clear_bit((nr) ^ 0x38, (addr))
#define test_and_set_le_bit(nr, addr) \
test_and_set_bit((nr) ^ 0x38, (addr))
/*
* non-atomic versions
*/
#define __set_le_bit(nr, addr) \
__set_bit((nr) ^ 0x38, (addr))
#define __clear_le_bit(nr, addr) \
__clear_bit((nr) ^ 0x38, (addr))
#define __test_and_clear_le_bit(nr, addr) \
__test_and_clear_bit((nr) ^ 0x38, (addr))
#define __test_and_set_le_bit(nr, addr) \
__test_and_set_bit((nr) ^ 0x38, (addr))
#define ext2_set_bit(nr,addr) \
__test_and_set_le_bit((nr), (unsigned long*)addr)
#define ext2_clear_bit(nr, addr) \
__test_and_clear_le_bit((nr), (unsigned long*)addr)
#define ext2_set_bit_atomic(lock, nr, addr) \
test_and_set_le_bit((nr), (unsigned long*)addr)
#define ext2_clear_bit_atomic(lock, nr, addr) \
test_and_clear_le_bit((nr), (unsigned long*)addr)
#define ext2_test_bit(nr, addr) test_le_bit((nr),(unsigned long*)addr)
#define ext2_find_first_zero_bit(addr, size) \
find_first_zero_le_bit((unsigned long*)addr, size)
#define ext2_find_next_zero_bit(addr, size, off) \
find_next_zero_le_bit((unsigned long*)addr, size, off)
#define minix_test_and_set_bit(nr,addr) test_and_set_bit(nr,addr)
#define minix_set_bit(nr,addr) set_bit(nr,addr)
#define minix_test_and_clear_bit(nr,addr) test_and_clear_bit(nr,addr)
#define minix_test_bit(nr,addr) test_bit(nr,addr)
#define minix_find_first_zero_bit(addr,size) find_first_zero_bit(addr,size)
#endif /* __KERNEL__ */
#endif /* _PPC64_BITOPS_H */
-59
View File
@@ -1,59 +0,0 @@
/*
* 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_DART_H
#define _ASM_DART_H
/* physical base of DART registers */
#define DART_BASE 0xf8033000UL
/* Offset from base to control register */
#define DARTCNTL 0
/* Offset from base to exception register */
#define DARTEXCP 0x10
/* Offset from base to TLB tag registers */
#define DARTTAG 0x1000
/* Control Register fields */
/* base address of table (pfn) */
#define DARTCNTL_BASE_MASK 0xfffff
#define DARTCNTL_BASE_SHIFT 12
#define DARTCNTL_FLUSHTLB 0x400
#define DARTCNTL_ENABLE 0x200
/* size of table in pages */
#define DARTCNTL_SIZE_MASK 0x1ff
#define DARTCNTL_SIZE_SHIFT 0
/* DART table fields */
#define DARTMAP_VALID 0x80000000
#define DARTMAP_RPNMASK 0x00ffffff
#define DART_PAGE_SHIFT 12
#define DART_PAGE_SIZE (1 << DART_PAGE_SHIFT)
#define DART_PAGE_FACTOR (PAGE_SHIFT - DART_PAGE_SHIFT)
#endif
+1 -1
View File
@@ -13,7 +13,7 @@
#include <asm/page.h>
#include <asm/byteorder.h>
#ifdef CONFIG_PPC_ISERIES
#include <asm/iSeries/iSeries_io.h>
#include <asm/iseries/iseries_io.h>
#endif
#include <asm/synch.h>
#include <asm/delay.h>
-28
View File
@@ -1,28 +0,0 @@
#ifndef __PPC64_IPCBUF_H__
#define __PPC64_IPCBUF_H__
/*
* The ipc64_perm structure for the PPC is identical to kern_ipc_perm
* as we have always had 32-bit UIDs and GIDs in the kernel.
*
* 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 ipc64_perm
{
__kernel_key_t key;
__kernel_uid_t uid;
__kernel_gid_t gid;
__kernel_uid_t cuid;
__kernel_gid_t cgid;
__kernel_mode_t mode;
unsigned int seq;
unsigned int __pad1;
unsigned long __unused1;
unsigned long __unused2;
};
#endif /* __PPC64_IPCBUF_H__ */
-41
View File
@@ -1,41 +0,0 @@
#ifndef _PPC64_KEXEC_H
#define _PPC64_KEXEC_H
/*
* KEXEC_SOURCE_MEMORY_LIMIT maximum page get_free_page can return.
* I.e. Maximum page that is mapped directly into kernel memory,
* and kmap is not required.
*/
/* Maximum physical address we can use pages from */
/* XXX: since we copy virt we can use any page we allocate */
#define KEXEC_SOURCE_MEMORY_LIMIT (-1UL)
/* Maximum address we can reach in physical address mode */
/* XXX: I want to allow initrd in highmem. otherwise set to rmo on lpar */
#define KEXEC_DESTINATION_MEMORY_LIMIT (-1UL)
/* Maximum address we can use for the control code buffer */
/* XXX: unused today, ppc32 uses TASK_SIZE, probably left over from use_mm */
#define KEXEC_CONTROL_MEMORY_LIMIT (-1UL)
/* XXX: today we don't use this at all, althogh we have a static stack */
#define KEXEC_CONTROL_CODE_SIZE 4096
/* The native architecture */
#define KEXEC_ARCH KEXEC_ARCH_PPC64
#define MAX_NOTE_BYTES 1024
#ifndef __ASSEMBLY__
typedef u32 note_buf_t[MAX_NOTE_BYTES/4];
extern note_buf_t crash_notes[];
extern void kexec_smp_wait(void); /* get and clear naca physid, wait for
master to copy new code to 0 */
#endif /* __ASSEMBLY__ */
#endif /* _PPC_KEXEC_H */
-15
View File
@@ -16,21 +16,6 @@
* 2 of the License, or (at your option) any later version.
*/
/*
* Every architecture must define this function. It's the fastest
* way of searching a 140-bit bitmap where the first 100 bits are
* unlikely to be set. It's guaranteed that at least one of the 140
* bits is cleared.
*/
static inline int sched_find_first_bit(unsigned long *b)
{
if (unlikely(b[0]))
return __ffs(b[0]);
if (unlikely(b[1]))
return __ffs(b[1]) + 64;
return __ffs(b[2]) + 128;
}
static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
{
}
-24
View File
@@ -1,24 +0,0 @@
#ifndef _NACA_H
#define _NACA_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>
struct naca_struct {
/* Kernel only data - undefined for user space */
void *xItVpdAreas; /* VPD Data 0x00 */
void *xRamDisk; /* iSeries ramdisk 0x08 */
u64 xRamDiskSize; /* In pages 0x10 */
};
extern struct naca_struct naca;
#endif /* _NACA_H */
-7
View File
@@ -1,7 +0,0 @@
#ifndef _ASM_MAX_NUMNODES_H
#define _ASM_MAX_NUMNODES_H
/* Max 16 Nodes */
#define NODES_SHIFT 4
#endif /* _ASM_MAX_NUMNODES_H */
+1 -1
View File
@@ -70,7 +70,7 @@ extern struct nvram_partition *nvram_find_partition(int sig, const char *name);
extern int pSeries_nvram_init(void);
extern int pmac_nvram_init(void);
extern int bpa_nvram_init(void);
extern int mmio_nvram_init(void);
/* PowerMac specific nvram stuffs */
+1 -1
View File
@@ -19,7 +19,7 @@
#include <linux/config.h>
#include <asm/types.h>
#include <asm/lppaca.h>
#include <asm/iSeries/ItLpRegSave.h>
#include <asm/iseries/it_lp_reg_save.h>
#include <asm/mmu.h>
register struct paca_struct *local_paca asm("r13");
-120
View File
@@ -1,120 +0,0 @@
#ifndef _PPC64_PLPAR_WRAPPERS_H
#define _PPC64_PLPAR_WRAPPERS_H
#include <asm/hvcall.h>
static inline long poll_pending(void)
{
unsigned long dummy;
return plpar_hcall(H_POLL_PENDING, 0, 0, 0, 0,
&dummy, &dummy, &dummy);
}
static inline long prod_processor(void)
{
plpar_hcall_norets(H_PROD);
return(0);
}
static inline long cede_processor(void)
{
plpar_hcall_norets(H_CEDE);
return(0);
}
static inline long register_vpa(unsigned long flags, unsigned long proc,
unsigned long vpa)
{
return plpar_hcall_norets(H_REGISTER_VPA, flags, proc, vpa);
}
void vpa_init(int cpu);
static inline long plpar_pte_remove(unsigned long flags,
unsigned long ptex,
unsigned long avpn,
unsigned long *old_pteh_ret,
unsigned long *old_ptel_ret)
{
unsigned long dummy;
return plpar_hcall(H_REMOVE, flags, ptex, avpn, 0,
old_pteh_ret, old_ptel_ret, &dummy);
}
static inline long plpar_pte_read(unsigned long flags,
unsigned long ptex,
unsigned long *old_pteh_ret, unsigned long *old_ptel_ret)
{
unsigned long dummy;
return plpar_hcall(H_READ, flags, ptex, 0, 0,
old_pteh_ret, old_ptel_ret, &dummy);
}
static inline long plpar_pte_protect(unsigned long flags,
unsigned long ptex,
unsigned long avpn)
{
return plpar_hcall_norets(H_PROTECT, flags, ptex, avpn);
}
static inline long plpar_tce_get(unsigned long liobn,
unsigned long ioba,
unsigned long *tce_ret)
{
unsigned long dummy;
return plpar_hcall(H_GET_TCE, liobn, ioba, 0, 0,
tce_ret, &dummy, &dummy);
}
static inline long plpar_tce_put(unsigned long liobn,
unsigned long ioba,
unsigned long tceval)
{
return plpar_hcall_norets(H_PUT_TCE, liobn, ioba, tceval);
}
static inline long plpar_tce_put_indirect(unsigned long liobn,
unsigned long ioba,
unsigned long page,
unsigned long count)
{
return plpar_hcall_norets(H_PUT_TCE_INDIRECT, liobn, ioba, page, count);
}
static inline long plpar_tce_stuff(unsigned long liobn,
unsigned long ioba,
unsigned long tceval,
unsigned long count)
{
return plpar_hcall_norets(H_STUFF_TCE, liobn, ioba, tceval, count);
}
static inline long plpar_get_term_char(unsigned long termno,
unsigned long *len_ret,
char *buf_ret)
{
unsigned long *lbuf = (unsigned long *)buf_ret; /* ToDo: alignment? */
return plpar_hcall(H_GET_TERM_CHAR, termno, 0, 0, 0,
len_ret, lbuf+0, lbuf+1);
}
static inline long plpar_put_term_char(unsigned long termno,
unsigned long len,
const char *buffer)
{
unsigned long *lbuf = (unsigned long *)buffer; /* ToDo: alignment? */
return plpar_hcall_norets(H_PUT_TERM_CHAR, termno, len, lbuf[0],
lbuf[1]);
}
static inline long plpar_set_xdabr(unsigned long address, unsigned long flags)
{
return plpar_hcall_norets(H_SET_XDABR, address, flags);
}
static inline long plpar_set_dabr(unsigned long val)
{
return plpar_hcall_norets(H_SET_DABR, val);
}
#endif /* _PPC64_PLPAR_WRAPPERS_H */
-122
View File
@@ -1,122 +0,0 @@
#ifndef _PPC64_PPC32_H
#define _PPC64_PPC32_H
#include <linux/compat.h>
#include <asm/siginfo.h>
#include <asm/signal.h>
/*
* Data types and macros for providing 32b PowerPC 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.
*/
/* These are here to support 32-bit syscalls on a 64-bit kernel. */
typedef struct compat_siginfo {
int si_signo;
int si_errno;
int si_code;
union {
int _pad[SI_PAD_SIZE32];
/* kill() */
struct {
compat_pid_t _pid; /* sender's pid */
compat_uid_t _uid; /* sender's uid */
} _kill;
/* POSIX.1b timers */
struct {
compat_timer_t _tid; /* timer id */
int _overrun; /* overrun count */
compat_sigval_t _sigval; /* same as below */
int _sys_private; /* not to be passed to user */
} _timer;
/* POSIX.1b signals */
struct {
compat_pid_t _pid; /* sender's pid */
compat_uid_t _uid; /* sender's uid */
compat_sigval_t _sigval;
} _rt;
/* SIGCHLD */
struct {
compat_pid_t _pid; /* which child */
compat_uid_t _uid; /* sender's uid */
int _status; /* exit code */
compat_clock_t _utime;
compat_clock_t _stime;
} _sigchld;
/* SIGILL, SIGFPE, SIGSEGV, SIGBUS, SIGEMT */
struct {
unsigned int _addr; /* faulting insn/memory ref. */
} _sigfault;
/* SIGPOLL */
struct {
int _band; /* POLL_IN, POLL_OUT, POLL_MSG */
int _fd;
} _sigpoll;
} _sifields;
} compat_siginfo_t;
#define __old_sigaction32 old_sigaction32
struct __old_sigaction32 {
compat_uptr_t sa_handler;
compat_old_sigset_t sa_mask;
unsigned int sa_flags;
compat_uptr_t sa_restorer; /* not used by Linux/SPARC yet */
};
struct sigaction32 {
compat_uptr_t sa_handler; /* Really a pointer, but need to deal with 32 bits */
unsigned int sa_flags;
compat_uptr_t sa_restorer; /* Another 32 bit pointer */
compat_sigset_t sa_mask; /* A 32 bit mask */
};
typedef struct sigaltstack_32 {
unsigned int ss_sp;
int ss_flags;
compat_size_t ss_size;
} stack_32_t;
struct sigcontext32 {
unsigned int _unused[4];
int signal;
compat_uptr_t handler;
unsigned int oldmask;
compat_uptr_t regs; /* 4 byte pointer to the pt_regs32 structure. */
};
struct mcontext32 {
elf_gregset_t32 mc_gregs;
elf_fpregset_t mc_fregs;
unsigned int mc_pad[2];
elf_vrregset_t32 mc_vregs __attribute__((__aligned__(16)));
};
struct ucontext32 {
unsigned int uc_flags;
unsigned int uc_link;
stack_32_t uc_stack;
int uc_pad[7];
compat_uptr_t uc_regs; /* points to uc_mcontext field */
compat_sigset_t uc_sigmask; /* mask last for extensibility */
/* glibc has 1024-bit signal masks, ours are 64-bit */
int uc_maskext[30];
int uc_pad2[3];
struct mcontext32 uc_mcontext;
};
#endif /* _PPC64_PPC32_H */
+1 -1
View File
@@ -21,7 +21,7 @@
#include <linux/config.h>
#include <asm/paca.h>
#include <asm/hvcall.h>
#include <asm/iSeries/HvCall.h>
#include <asm/iseries/hv_call.h>
#define __raw_spin_is_locked(x) ((x)->slock != 0)
-60
View File
@@ -1,60 +0,0 @@
#ifndef _PPC64_STAT_H
#define _PPC64_STAT_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.
*/
#include <linux/types.h>
struct stat {
unsigned long st_dev;
ino_t st_ino;
nlink_t st_nlink;
mode_t st_mode;
uid_t st_uid;
gid_t st_gid;
unsigned long st_rdev;
off_t st_size;
unsigned long st_blksize;
unsigned long st_blocks;
unsigned long st_atime;
unsigned long st_atime_nsec;
unsigned long st_mtime;
unsigned long st_mtime_nsec;
unsigned long st_ctime;
unsigned long st_ctime_nsec;
unsigned long __unused4;
unsigned long __unused5;
unsigned long __unused6;
};
#define STAT_HAVE_NSEC 1
/* This matches struct stat64 in glibc2.1. Only used for 32 bit. */
struct stat64 {
unsigned long st_dev; /* Device. */
unsigned long st_ino; /* File serial number. */
unsigned int st_mode; /* File mode. */
unsigned int st_nlink; /* Link count. */
unsigned int st_uid; /* User ID of the file's owner. */
unsigned int st_gid; /* Group ID of the file's group. */
unsigned long st_rdev; /* Device number, if device. */
unsigned short __pad2;
long st_size; /* Size of file, in bytes. */
int st_blksize; /* Optimal block size for I/O. */
long st_blocks; /* Number 512-byte blocks allocated. */
int st_atime; /* Time of last access. */
int st_atime_nsec;
int st_mtime; /* Time of last modification. */
int st_mtime_nsec;
int st_ctime; /* Time of last status change. */
int st_ctime_nsec;
unsigned int __unused4;
unsigned int __unused5;
};
#endif
-39
View File
@@ -1,39 +0,0 @@
/*
* TLB shootdown specifics for PPC64
*
* Copyright (C) 2002 Anton Blanchard, IBM Corp.
* Copyright (C) 2002 Paul Mackerras, 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 _PPC64_TLB_H
#define _PPC64_TLB_H
#include <asm/tlbflush.h>
struct mmu_gather;
extern void pte_free_finish(void);
static inline void tlb_flush(struct mmu_gather *tlb)
{
flush_tlb_pending();
pte_free_finish();
}
/* Avoid pulling in another include just for this */
#define check_pgt_cache() do { } while (0)
/* Get the generic bits... */
#include <asm-generic/tlb.h>
/* Nothing needed here in fact... */
#define tlb_start_vma(tlb, vma) do { } while (0)
#define tlb_end_vma(tlb, vma) do { } while (0)
#define __tlb_remove_tlb_entry(tlb, pte, address) do { } while (0)
#endif /* _PPC64_TLB_H */
-52
View File
@@ -1,52 +0,0 @@
#ifndef _PPC64_TLBFLUSH_H
#define _PPC64_TLBFLUSH_H
/*
* TLB flushing:
*
* - flush_tlb_mm(mm) flushes the specified mm context TLB's
* - flush_tlb_page(vma, vmaddr) flushes one page
* - flush_tlb_page_nohash(vma, vmaddr) flushes one page if SW loaded TLB
* - flush_tlb_range(vma, start, end) flushes a range of pages
* - flush_tlb_kernel_range(start, end) flushes a range of kernel pages
* - flush_tlb_pgtables(mm, start, end) flushes a range of page tables
*/
#include <linux/percpu.h>
#include <asm/page.h>
#define PPC64_TLB_BATCH_NR 192
struct mm_struct;
struct ppc64_tlb_batch {
unsigned long index;
struct mm_struct *mm;
pte_t pte[PPC64_TLB_BATCH_NR];
unsigned long vaddr[PPC64_TLB_BATCH_NR];
unsigned int large;
};
DECLARE_PER_CPU(struct ppc64_tlb_batch, ppc64_tlb_batch);
extern void __flush_tlb_pending(struct ppc64_tlb_batch *batch);
static inline void flush_tlb_pending(void)
{
struct ppc64_tlb_batch *batch = &get_cpu_var(ppc64_tlb_batch);
if (batch->index)
__flush_tlb_pending(batch);
put_cpu_var(ppc64_tlb_batch);
}
#define flush_tlb_mm(mm) flush_tlb_pending()
#define flush_tlb_page(vma, addr) flush_tlb_pending()
#define flush_tlb_page_nohash(vma, addr) do { } while (0)
#define flush_tlb_range(vma, start, end) \
do { (void)(start); flush_tlb_pending(); } while (0)
#define flush_tlb_kernel_range(start, end) flush_tlb_pending()
#define flush_tlb_pgtables(mm, start, end) do { } while (0)
extern void flush_hash_page(unsigned long va, pte_t pte, int local);
void flush_hash_range(unsigned long number, int local);
#endif /* _PPC64_TLBFLUSH_H */
-341
View File
@@ -1,341 +0,0 @@
#ifndef _PPC64_UACCESS_H
#define _PPC64_UACCESS_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.
*/
#ifndef __ASSEMBLY__
#include <linux/sched.h>
#include <linux/errno.h>
#include <asm/processor.h>
#define VERIFY_READ 0
#define VERIFY_WRITE 1
/*
* The fs value determines whether argument validity checking should be
* performed or not. If get_fs() == USER_DS, checking is performed, with
* get_fs() == KERNEL_DS, checking is bypassed.
*
* For historical reasons, these macros are grossly misnamed.
*/
#define MAKE_MM_SEG(s) ((mm_segment_t) { (s) })
#define KERNEL_DS MAKE_MM_SEG(0UL)
#define USER_DS MAKE_MM_SEG(0xf000000000000000UL)
#define get_ds() (KERNEL_DS)
#define get_fs() (current->thread.fs)
#define set_fs(val) (current->thread.fs = (val))
#define segment_eq(a,b) ((a).seg == (b).seg)
/*
* Use the alpha trick for checking ranges:
*
* Is a address valid? This does a straightforward calculation rather
* than tests.
*
* Address valid if:
* - "addr" doesn't have any high-bits set
* - AND "size" doesn't have any high-bits set
* - OR we are in kernel mode.
*
* We dont have to check for high bits in (addr+size) because the first
* two checks force the maximum result to be below the start of the
* kernel region.
*/
#define __access_ok(addr,size,segment) \
(((segment).seg & (addr | size )) == 0)
#define access_ok(type,addr,size) \
__access_ok(((__force unsigned long)(addr)),(size),get_fs())
/*
* The exception table consists of pairs of addresses: the first is the
* address of an instruction that is allowed to fault, and the second is
* the address at which the program should continue. No registers are
* modified, so it is entirely up to the continuation code to figure out
* what to do.
*
* All the routines below use bits of fixup code that are out of line
* with the main instruction path. This means when everything is well,
* we don't even have to jump over them. Further, they do not intrude
* on our cache or tlb entries.
*/
struct exception_table_entry
{
unsigned long insn, fixup;
};
/* Returns 0 if exception not found and fixup otherwise. */
extern unsigned long search_exception_table(unsigned long);
/*
* These are the main single-value transfer routines. They automatically
* use the right size if we just have the right pointer type.
*
* This gets kind of ugly. We want to return _two_ values in "get_user()"
* and yet we don't want to do any pointers, because that is too much
* of a performance impact. Thus we have a few rather ugly macros here,
* and hide all the ugliness from the user.
*
* The "__xxx" versions of the user access functions are versions that
* do not verify the address space, that must have been done previously
* with a separate "access_ok()" call (this is used when we do multiple
* accesses to the same area of user memory).
*
* As we use the same address space for kernel and user data on the
* PowerPC, we can just do these as direct assignments. (Of course, the
* exception handling means that it's no longer "just"...)
*/
#define get_user(x,ptr) \
__get_user_check((x),(ptr),sizeof(*(ptr)))
#define put_user(x,ptr) \
__put_user_check((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr)))
#define __get_user(x,ptr) \
__get_user_nocheck((x),(ptr),sizeof(*(ptr)))
#define __put_user(x,ptr) \
__put_user_nocheck((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr)))
#define __get_user_unaligned __get_user
#define __put_user_unaligned __put_user
extern long __put_user_bad(void);
#define __put_user_nocheck(x,ptr,size) \
({ \
long __pu_err; \
might_sleep(); \
__chk_user_ptr(ptr); \
__put_user_size((x),(ptr),(size),__pu_err,-EFAULT); \
__pu_err; \
})
#define __put_user_check(x,ptr,size) \
({ \
long __pu_err = -EFAULT; \
void __user *__pu_addr = (ptr); \
might_sleep(); \
if (access_ok(VERIFY_WRITE,__pu_addr,size)) \
__put_user_size((x),__pu_addr,(size),__pu_err,-EFAULT); \
__pu_err; \
})
#define __put_user_size(x,ptr,size,retval,errret) \
do { \
retval = 0; \
switch (size) { \
case 1: __put_user_asm(x,ptr,retval,"stb",errret); break; \
case 2: __put_user_asm(x,ptr,retval,"sth",errret); break; \
case 4: __put_user_asm(x,ptr,retval,"stw",errret); break; \
case 8: __put_user_asm(x,ptr,retval,"std",errret); break; \
default: __put_user_bad(); \
} \
} while (0)
/*
* 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
* are no aliasing issues.
*/
#define __put_user_asm(x, addr, err, op, errret) \
__asm__ __volatile__( \
"1: "op" %1,0(%2) # put_user\n" \
"2:\n" \
".section .fixup,\"ax\"\n" \
"3: li %0,%3\n" \
" b 2b\n" \
".previous\n" \
".section __ex_table,\"a\"\n" \
" .align 3\n" \
" .llong 1b,3b\n" \
".previous" \
: "=r"(err) \
: "r"(x), "b"(addr), "i"(errret), "0"(err))
#define __get_user_nocheck(x,ptr,size) \
({ \
long __gu_err; \
unsigned long __gu_val; \
might_sleep(); \
__get_user_size(__gu_val,(ptr),(size),__gu_err,-EFAULT);\
(x) = (__typeof__(*(ptr)))__gu_val; \
__gu_err; \
})
#define __get_user_check(x,ptr,size) \
({ \
long __gu_err = -EFAULT; \
unsigned long __gu_val = 0; \
const __typeof__(*(ptr)) __user *__gu_addr = (ptr); \
might_sleep(); \
if (access_ok(VERIFY_READ,__gu_addr,size)) \
__get_user_size(__gu_val,__gu_addr,(size),__gu_err,-EFAULT);\
(x) = (__typeof__(*(ptr)))__gu_val; \
__gu_err; \
})
extern long __get_user_bad(void);
#define __get_user_size(x,ptr,size,retval,errret) \
do { \
retval = 0; \
__chk_user_ptr(ptr); \
switch (size) { \
case 1: __get_user_asm(x,ptr,retval,"lbz",errret); break; \
case 2: __get_user_asm(x,ptr,retval,"lhz",errret); break; \
case 4: __get_user_asm(x,ptr,retval,"lwz",errret); break; \
case 8: __get_user_asm(x,ptr,retval,"ld",errret); break; \
default: (x) = __get_user_bad(); \
} \
} while (0)
#define __get_user_asm(x, addr, err, op, errret) \
__asm__ __volatile__( \
"1: "op" %1,0(%2) # get_user\n" \
"2:\n" \
".section .fixup,\"ax\"\n" \
"3: li %0,%3\n" \
" li %1,0\n" \
" b 2b\n" \
".previous\n" \
".section __ex_table,\"a\"\n" \
" .align 3\n" \
" .llong 1b,3b\n" \
".previous" \
: "=r"(err), "=r"(x) \
: "b"(addr), "i"(errret), "0"(err))
/* more complex routines */
extern unsigned long __copy_tofrom_user(void __user *to, const void __user *from,
unsigned long size);
static inline unsigned long
__copy_from_user_inatomic(void *to, const void __user *from, unsigned long n)
{
if (__builtin_constant_p(n)) {
unsigned long ret;
switch (n) {
case 1:
__get_user_size(*(u8 *)to, from, 1, ret, 1);
return ret;
case 2:
__get_user_size(*(u16 *)to, from, 2, ret, 2);
return ret;
case 4:
__get_user_size(*(u32 *)to, from, 4, ret, 4);
return ret;
case 8:
__get_user_size(*(u64 *)to, from, 8, ret, 8);
return ret;
}
}
return __copy_tofrom_user((__force void __user *) to, from, n);
}
static inline unsigned long
__copy_from_user(void *to, const void __user *from, unsigned long n)
{
might_sleep();
return __copy_from_user_inatomic(to, from, n);
}
static inline unsigned long
__copy_to_user_inatomic(void __user *to, const void *from, unsigned long n)
{
if (__builtin_constant_p(n)) {
unsigned long ret;
switch (n) {
case 1:
__put_user_size(*(u8 *)from, (u8 __user *)to, 1, ret, 1);
return ret;
case 2:
__put_user_size(*(u16 *)from, (u16 __user *)to, 2, ret, 2);
return ret;
case 4:
__put_user_size(*(u32 *)from, (u32 __user *)to, 4, ret, 4);
return ret;
case 8:
__put_user_size(*(u64 *)from, (u64 __user *)to, 8, ret, 8);
return ret;
}
}
return __copy_tofrom_user(to, (__force const void __user *) from, n);
}
static inline unsigned long
__copy_to_user(void __user *to, const void *from, unsigned long n)
{
might_sleep();
return __copy_to_user_inatomic(to, from, n);
}
#define __copy_in_user(to, from, size) \
__copy_tofrom_user((to), (from), (size))
extern unsigned long copy_from_user(void *to, const void __user *from,
unsigned long n);
extern unsigned long copy_to_user(void __user *to, const void *from,
unsigned long n);
extern unsigned long copy_in_user(void __user *to, const void __user *from,
unsigned long n);
extern unsigned long __clear_user(void __user *addr, unsigned long size);
static inline unsigned long
clear_user(void __user *addr, unsigned long size)
{
might_sleep();
if (likely(access_ok(VERIFY_WRITE, addr, size)))
size = __clear_user(addr, size);
return size;
}
extern int __strncpy_from_user(char *dst, const char __user *src, long count);
static inline long
strncpy_from_user(char *dst, const char __user *src, long count)
{
might_sleep();
if (likely(access_ok(VERIFY_READ, src, 1)))
return __strncpy_from_user(dst, src, count);
return -EFAULT;
}
/*
* Return the size of a string (including the ending 0)
*
* Return 0 for error
*/
extern int __strnlen_user(const char __user *str, long len);
/*
* Returns the length of the string at str (including the null byte),
* or 0 if we hit a page we can't access,
* or something > len if we didn't find a null byte.
*/
static inline int strnlen_user(const char __user *str, long len)
{
might_sleep();
if (likely(access_ok(VERIFY_READ, str, 1)))
return __strnlen_user(str, len);
return 0;
}
#define strlen_user(str) strnlen_user((str), 0x7ffffffe)
#endif /* __ASSEMBLY__ */
#endif /* _PPC64_UACCESS_H */
-22
View File
@@ -1,22 +0,0 @@
#ifndef _ASMPPC64_UCONTEXT_H
#define _ASMPPC64_UCONTEXT_H
#include <asm/sigcontext.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 ucontext {
unsigned long uc_flags;
struct ucontext *uc_link;
stack_t uc_stack;
sigset_t uc_sigmask;
sigset_t __unsued[15]; /* Allow for uc_sigmask growth */
struct sigcontext uc_mcontext; /* last for extensibility */
};
#endif /* _ASMPPC64_UCONTEXT_H */