summaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorMiguel de Icaza <miguel@nuclecu.unam.mx>1997-08-06 19:14:48 +0000
committerMiguel de Icaza <miguel@nuclecu.unam.mx>1997-08-06 19:14:48 +0000
commite2819e52a162873ff5061de81bb749831bdb5de9 (patch)
tree6067ea700202750ba335a423696f2972700e5f76 /include
parent17a005074429bbf143e40401f405ae4363e56828 (diff)
Merge to 2.1.38.
IMPORTANT NOTE: I could not figure out what information is the one that should be used for the following files (ie, those that were in our tree, or those that came from Linus' patch), please, check these: include/asm-mips/jazz.h include/asm-mips/jazzdma.h include/asm-mips/ioctls.h
Diffstat (limited to 'include')
-rw-r--r--include/asm-alpha/keyboard.h6
-rw-r--r--include/asm-i386/keyboard.h6
-rw-r--r--include/asm-i386/smp_lock.h4
-rw-r--r--include/asm-m68k/serial.h2
-rw-r--r--include/asm-mips/ioctls.h4
-rw-r--r--include/asm-mips/keyboard.h6
-rw-r--r--include/asm-ppc/atomic.h119
-rw-r--r--include/asm-ppc/bitops.h178
-rw-r--r--include/asm-ppc/bugs.h6
-rw-r--r--include/asm-ppc/byteorder.h60
-rw-r--r--include/asm-ppc/cache.h3
-rw-r--r--include/asm-ppc/checksum.h14
-rw-r--r--include/asm-ppc/current.h12
-rw-r--r--include/asm-ppc/delay.h27
-rw-r--r--include/asm-ppc/dma.h11
-rw-r--r--include/asm-ppc/errno.h2
-rw-r--r--include/asm-ppc/ide.h107
-rw-r--r--include/asm-ppc/init.h21
-rw-r--r--include/asm-ppc/io.h182
-rw-r--r--include/asm-ppc/ioctls.h4
-rw-r--r--include/asm-ppc/irq.h6
-rw-r--r--include/asm-ppc/keyboard.h30
-rw-r--r--include/asm-ppc/mc146818rtc.h128
-rw-r--r--include/asm-ppc/mmu.h95
-rw-r--r--include/asm-ppc/mmu_context.h56
-rw-r--r--include/asm-ppc/nvram.h3
-rw-r--r--include/asm-ppc/page.h32
-rw-r--r--include/asm-ppc/pgtable.h253
-rw-r--r--include/asm-ppc/ppc_machine.h56
-rw-r--r--include/asm-ppc/processor.h119
-rw-r--r--include/asm-ppc/ptrace.h82
-rw-r--r--include/asm-ppc/semaphore.h70
-rw-r--r--include/asm-ppc/smp.h2
-rw-r--r--include/asm-ppc/socket.h9
-rw-r--r--include/asm-ppc/string.h41
-rw-r--r--include/asm-ppc/system.h63
-rw-r--r--include/asm-ppc/termbits.h41
-rw-r--r--include/asm-ppc/termios.h222
-rw-r--r--include/asm-ppc/uaccess.h339
-rw-r--r--include/asm-ppc/unistd.h183
-rw-r--r--include/asm-sparc/fbio.h43
-rw-r--r--include/asm-sparc/smp.h2
-rw-r--r--include/asm-sparc64/oplib.h5
-rw-r--r--include/asm-sparc64/pgtable.h64
-rw-r--r--include/asm-sparc64/semaphore.h25
-rw-r--r--include/asm-sparc64/smp.h52
-rw-r--r--include/asm-sparc64/smp_lock.h64
-rw-r--r--include/asm-sparc64/softirq.h8
-rw-r--r--include/asm-sparc64/spinlock.h106
-rw-r--r--include/asm-sparc64/system.h108
-rw-r--r--include/linux/dcache.h10
-rw-r--r--include/linux/fs.h2
-rw-r--r--include/linux/miscdevice.h1
-rw-r--r--include/linux/mm.h3
-rw-r--r--include/linux/msdos_fs.h7
-rw-r--r--include/linux/msdos_fs_sb.h3
-rw-r--r--include/linux/parport.h10
-rw-r--r--include/linux/proc_fs.h2
-rw-r--r--include/linux/sched.h21
-rw-r--r--include/linux/selection.h14
-rw-r--r--include/linux/sysrq.h17
61 files changed, 1813 insertions, 1358 deletions
diff --git a/include/asm-alpha/keyboard.h b/include/asm-alpha/keyboard.h
index 263cf8050..951cb5077 100644
--- a/include/asm-alpha/keyboard.h
+++ b/include/asm-alpha/keyboard.h
@@ -3,7 +3,7 @@
*
* Created 3 Nov 1996 by Geert Uytterhoeven
*
- * $Id: keyboard.h,v 1.3 1997/07/22 23:18:14 ralf Exp $
+ * $Id: keyboard.h,v 1.3 1997/07/24 01:55:54 ralf Exp $
*/
/*
@@ -30,6 +30,7 @@ extern int pckbd_translate(unsigned char scancode, unsigned char *keycode,
extern char pckbd_unexpected_up(unsigned char keycode);
extern void pckbd_leds(unsigned char leds);
extern void pckbd_init_hw(void);
+extern unsigned char pckbd_sysrq_xlate[128];
#define kbd_setkeycode pckbd_setkeycode
#define kbd_getkeycode pckbd_getkeycode
@@ -38,9 +39,12 @@ extern void pckbd_init_hw(void);
#define kbd_unexpected_up pckbd_unexpected_up
#define kbd_leds pckbd_leds
#define kbd_init_hw pckbd_init_hw
+#define kbd_sysrq_xlate pckbd_sysrq_xlate
#define INIT_KBD
+#define SYSRQ_KEY 0x54
+
/*
* keyboard controller registers
*/
diff --git a/include/asm-i386/keyboard.h b/include/asm-i386/keyboard.h
index eaf0fa874..ab936e6bc 100644
--- a/include/asm-i386/keyboard.h
+++ b/include/asm-i386/keyboard.h
@@ -3,7 +3,7 @@
*
* Created 3 Nov 1996 by Geert Uytterhoeven
*
- * $Id: keyboard.h,v 1.4 1997/07/23 06:06:09 ralf Exp $
+ * $Id: keyboard.h,v 1.3 1997/07/24 01:55:55 ralf Exp $
*/
/*
@@ -30,6 +30,7 @@ extern int pckbd_translate(unsigned char scancode, unsigned char *keycode,
extern char pckbd_unexpected_up(unsigned char keycode);
extern void pckbd_leds(unsigned char leds);
extern void pckbd_init_hw(void);
+extern unsigned char pckbd_sysrq_xlate[128];
#define kbd_setkeycode pckbd_setkeycode
#define kbd_getkeycode pckbd_getkeycode
@@ -38,6 +39,9 @@ extern void pckbd_init_hw(void);
#define kbd_unexpected_up pckbd_unexpected_up
#define kbd_leds pckbd_leds
#define kbd_init_hw pckbd_init_hw
+#define kbd_sysrq_xlate pckbd_sysrq_xlate
+
+#define SYSRQ_KEY 0x54
/* How to access the keyboard macros on this platform. */
#define kbd_read_input() inb(KBD_DATA_REG)
diff --git a/include/asm-i386/smp_lock.h b/include/asm-i386/smp_lock.h
index 4f78f97fb..fc7eb94de 100644
--- a/include/asm-i386/smp_lock.h
+++ b/include/asm-i386/smp_lock.h
@@ -39,6 +39,8 @@ do { if (depth) __asm__ __volatile__( \
} while (0)
+extern const char lk_lockmsg[];
+
/* Locking the kernel */
extern __inline__ void lock_kernel(void)
{
@@ -46,7 +48,7 @@ extern __inline__ void lock_kernel(void)
if (local_irq_count[cpu]) {
__label__ l1;
-l1: printk("lock from interrupt context at %p\n", &&l1);
+l1: printk(lk_lockmsg, &&l1);
}
if (cpu == global_irq_holder) {
__label__ l2;
diff --git a/include/asm-m68k/serial.h b/include/asm-m68k/serial.h
index 7c873c341..607b408ec 100644
--- a/include/asm-m68k/serial.h
+++ b/include/asm-m68k/serial.h
@@ -31,7 +31,7 @@
#define SER_AMIGA 105 /* Amiga built-in serial port */
#define SER_IOEXT 106 /* Amiga GVP IO-Extender (16c552) */
#define SER_MFC_III 107 /* Amiga BSC Multiface Card III (MC68681) */
-
+#define SER_WHIPPET 108 /* Amiga Hisoft Whippet PCMCIA (16c550B) */
struct serial_struct {
int type;
diff --git a/include/asm-mips/ioctls.h b/include/asm-mips/ioctls.h
index 5648eae7f..c0c3d2dad 100644
--- a/include/asm-mips/ioctls.h
+++ b/include/asm-mips/ioctls.h
@@ -96,8 +96,10 @@
#define TCSBRKP 0x5486 /* Needed for POSIX tcsendbreak() */
#define TIOCTTYGSTRUCT 0x5487 /* For debugging only */
+#ifdef WHAT_TO_DO_WITH_THIS_DULPLICATE
#define TIOCSBRK 0x5427 /* BSD compatibility */
#define TIOCCBRK 0x5428 /* BSD compatibility */
+#endif
#define TIOCSERCONFIG 0x5488
#define TIOCSERGWILD 0x5489
@@ -110,5 +112,7 @@
#define TIOCSERSETMULTI 0x5490 /* Set multiport config */
#define TIOCMIWAIT 0x5491 /* wait for a change on serial input line(s) */
#define TIOCGICOUNT 0x5492 /* read serial port inline interrupt counts */
+#define TIOCSBRK 0x5491 /* BSD compatibility */
+#define TIOCCBRK 0x5492 /* BSD compatibility */
#endif /* __ASM_MIPS_IOCTLS_H */
diff --git a/include/asm-mips/keyboard.h b/include/asm-mips/keyboard.h
index 499024c3b..813cb7c69 100644
--- a/include/asm-mips/keyboard.h
+++ b/include/asm-mips/keyboard.h
@@ -5,7 +5,7 @@
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
- * $Id: keyboard.h,v 1.5 1997/07/23 17:41:07 ralf Exp $
+ * $Id: keyboard.h,v 1.4 1997/07/24 01:55:56 ralf Exp $
*/
#ifndef __ASM_MIPS_KEYBOARD_H
#define __ASM_MIPS_KEYBOARD_H
@@ -25,6 +25,7 @@ extern int pckbd_translate(unsigned char scancode, unsigned char *keycode,
extern char pckbd_unexpected_up(unsigned char keycode);
extern void pckbd_leds(unsigned char leds);
extern void pckbd_init_hw(void);
+extern unsigned char pckbd_sysrq_xlate[128];
#define kbd_setkeycode pckbd_setkeycode
#define kbd_getkeycode pckbd_getkeycode
@@ -33,6 +34,9 @@ extern void pckbd_init_hw(void);
#define kbd_unexpected_up pckbd_unexpected_up
#define kbd_leds pckbd_leds
#define kbd_init_hw pckbd_init_hw
+#define kbd_sysrq_xlate pckbd_sysrq_xlate
+
+#define SYSRQ_KEY 0x54
#define INIT_KBD /* full initialization for the keyboard controller. */
diff --git a/include/asm-ppc/atomic.h b/include/asm-ppc/atomic.h
index c34bc36ef..6070ea738 100644
--- a/include/asm-ppc/atomic.h
+++ b/include/asm-ppc/atomic.h
@@ -5,23 +5,116 @@
#ifndef _ASM_PPC_ATOMIC_H_
#define _ASM_PPC_ATOMIC_H_
+#ifdef __SMP__
+typedef struct { volatile int counter; } atomic_t;
+#else
typedef struct { int counter; } atomic_t;
-#define ATOMIC_INIT(i) { (i) }
+#endif
-/*
- * Make sure gcc doesn't try to be clever and move things around
- * on us. We need to use _exactly_ the address the user gave us,
- * not some alias that contains the same information.
- */
-#define __atomic_fool_gcc(x) (*(struct { int a[100]; } *)x)
+#define ATOMIC_INIT(i) { (i) }
#define atomic_read(v) ((v)->counter)
-#define atomic_set(v) (((v)->counter) = i)
+#define atomic_set(v,i) (((v)->counter) = (i))
-#define atomic_dec_return(v) ({atomic_sub(1,(v));(v);})
-#define atomic_inc_return(v) ({atomic_add(1,(v));(v);})
+extern void atomic_add(int a, atomic_t *v);
+extern void atomic_sub(int a, atomic_t *v);
+extern void atomic_inc(atomic_t *v);
+extern int atomic_inc_return(atomic_t *v);
+extern void atomic_dec(atomic_t *v);
+extern int atomic_dec_return(atomic_t *v);
+extern int atomic_dec_and_test(atomic_t *v);
-#define atomic_inc(v) atomic_add(1,(v))
-#define atomic_dec(v) atomic_sub(1,(v))
-#endif
+extern void atomic_clear_mask(unsigned long mask, unsigned long *addr);
+extern void atomic_set_mask(unsigned long mask, unsigned long *addr);
+
+#if 0 /* for now */
+extern __inline__ void atomic_add(atomic_t a, atomic_t *v)
+{
+ atomic_t t;
+
+ __asm__ __volatile__("\n\
+1: lwarx %0,0,%3\n\
+ add %0,%2,%0\n\
+ stwcx. %0,0,%3\n\
+ bne 1b"
+ : "=&r" (t), "=m" (*v)
+ : "r" (a), "r" (v)
+ : "cc");
+}
+
+extern __inline__ void atomic_sub(atomic_t a, atomic_t *v)
+{
+ atomic_t t;
+
+ __asm__ __volatile__("\n\
+1: lwarx %0,0,%3\n\
+ subf %0,%2,%0\n\
+ stwcx. %0,0,%3\n\
+ bne 1b"
+ : "=&r" (t), "=m" (*v)
+ : "r" (a), "r" (v)
+ : "cc");
+}
+
+extern __inline__ int atomic_sub_and_test(atomic_t a, atomic_t *v)
+{
+ atomic_t t;
+
+ __asm__ __volatile__("\n\
+1: lwarx %0,0,%3\n\
+ subf %0,%2,%0\n\
+ stwcx. %0,0,%3\n\
+ bne 1b"
+ : "=&r" (t), "=m" (*v)
+ : "r" (a), "r" (v)
+ : "cc");
+
+ return t == 0;
+}
+
+extern __inline__ void atomic_inc(atomic_t *v)
+{
+ atomic_t t;
+
+ __asm__ __volatile__("\n\
+1: lwarx %0,0,%2\n\
+ addic %0,%0,1\n\
+ stwcx. %0,0,%2\n\
+ bne 1b"
+ : "=&r" (t), "=m" (*v)
+ : "r" (v)
+ : "cc");
+}
+
+extern __inline__ void atomic_dec(atomic_t *v)
+{
+ atomic_t t;
+
+ __asm__ __volatile__("\n\
+1: lwarx %0,0,%2\n\
+ addic %0,%0,-1\n\
+ stwcx. %0,0,%2\n\
+ bne 1b"
+ : "=&r" (t), "=m" (*v)
+ : "r" (v)
+ : "cc");
+}
+
+extern __inline__ int atomic_dec_and_test(atomic_t *v)
+{
+ atomic_t t;
+
+ __asm__ __volatile__("\n\
+1: lwarx %0,0,%2\n\
+ addic %0,%0,-1\n\
+ stwcx. %0,0,%2\n\
+ bne 1b"
+ : "=&r" (t), "=m" (*v)
+ : "r" (v)
+ : "cc");
+
+ return t == 0;
+}
+#endif /* 0 */
+#endif /* _ASM_PPC_ATOMIC_H_ */
diff --git a/include/asm-ppc/bitops.h b/include/asm-ppc/bitops.h
index 959f2b302..3b8a24575 100644
--- a/include/asm-ppc/bitops.h
+++ b/include/asm-ppc/bitops.h
@@ -3,67 +3,155 @@
#include <asm/system.h>
#include <asm/byteorder.h>
+#include <linux/kernel.h> /* for printk */
#define BIT(n) 1<<(n&0x1F)
typedef unsigned long BITFIELD;
-/* Set bit 'nr' in 32-bit quantity at address 'addr' where bit '0'
- * is in the highest of the four bytes and bit '31' is the high bit
- * within the first byte. powerpc is BIG-Endian. Unless noted otherwise
- * all bit-ops return 0 if bit was previously clear and != 0 otherwise.
+/*
+ * These are ifdef'd out here because using : "cc" as a constraing
+ * results in errors from gcc. -- Cort
*/
-extern __inline__ int set_bit(int nr, void * add)
+#if 0
+extern __inline__ int set_bit(int nr, void * addr)
{
- BITFIELD *addr = add;
- long mask,oldbit;
-#ifdef __KERNEL__
- int s = _disable_interrupts();
-#endif
- addr += nr >> 5;
- mask = BIT(nr);
- oldbit = (mask & *addr) != 0;
- *addr |= mask;
-#ifdef __KERNEL__
- _enable_interrupts(s);
-#endif
- return oldbit;
+ unsigned long old, t;
+ unsigned long mask = 1 << (nr & 0x1f);
+ unsigned long *p = ((unsigned long *)addr) + (nr >> 5);
+
+ if ((unsigned long)addr & 3)
+ printk("set_bit(%lx, %p)\n", nr, addr);
+
+ __asm__ __volatile__(
+ "1:lwarx %0,0,%3 \n\t"
+ "or %1,%0,%2 \n\t"
+ "stwcx. %1,0,%3 \n\t"
+ "bne 1b \n\t"
+ : "=&r" (old), "=&r" (t) /*, "=m" (*p)*/
+ : "r" (mask), "r" (p)
+ /*: "cc" */);
+
+n return (old & mask) != 0;
}
-extern __inline__ int change_bit(int nr, void *add)
+extern __inline__ unsigned long clear_bit(unsigned long nr, void *addr)
{
- BITFIELD *addr = add;
- int mask, retval;
-#ifdef __KERNEL__
- int s = _disable_interrupts();
-#endif
- addr += nr >> 5;
- mask = BIT(nr);
- retval = (mask & *addr) != 0;
- *addr ^= mask;
-#ifdef __KERNEL__
- _enable_interrupts(s);
-#endif
- return retval;
+ unsigned long old, t;
+ unsigned long mask = 1 << (nr & 0x1f);
+ unsigned long *p = ((unsigned long *)addr) + (nr >> 5);
+
+ if ((unsigned long)addr & 3)
+ printk("clear_bit(%lx, %p)\n", nr, addr);
+ __asm__ __volatile__("\n\
+1: lwarx %0,0,%3
+ andc %1,%0,%2
+ stwcx. %1,0,%3
+ bne 1b"
+ : "=&r" (old), "=&r" (t) /*, "=m" (*p)*/
+ : "r" (mask), "r" (p)
+ /*: "cc"*/);
+
+ return (old & mask) != 0;
}
-extern __inline__ int clear_bit(int nr, void *add)
+extern __inline__ unsigned long change_bit(unsigned long nr, void *addr)
{
- BITFIELD *addr = add;
- int mask, retval;
-#ifdef __KERNEL__
- int s = _disable_interrupts();
-#endif
- addr += nr >> 5;
- mask = BIT(nr);
- retval = (mask & *addr) != 0;
- *addr &= ~mask;
-#ifdef __KERNEL__
- _enable_interrupts(s);
+ unsigned long old, t;
+ unsigned long mask = 1 << (nr & 0x1f);
+ unsigned long *p = ((unsigned long *)addr) + (nr >> 5);
+
+ if ((unsigned long)addr & 3)
+ printk("change_bit(%lx, %p)\n", nr, addr);
+ __asm__ __volatile__("\n\
+1: lwarx %0,0,%3
+ xor %1,%0,%2
+ stwcx. %1,0,%3
+ bne 1b"
+ : "=&r" (old), "=&r" (t) /*, "=m" (*p)*/
+ : "r" (mask), "r" (p)
+ /*: "cc"*/);
+
+ return (old & mask) != 0;
+}
#endif
- return retval;
+
+extern __inline__ int ffz(unsigned int x)
+{
+ int n;
+
+ x = ~x & (x+1); /* set LS zero to 1, other bits to 0 */
+ __asm__ ("cntlzw %0,%1" : "=r" (n) : "r" (x));
+ return 31 - n;
}
+/*
+ * This implementation of find_{first,next}_zero_bit was stolen from
+ * Linus' asm-alpha/bitops.h.
+ */
+
+extern __inline__ unsigned long find_first_zero_bit(void * addr, unsigned long size)
+{
+ unsigned int * p = ((unsigned int *) addr);
+ unsigned int result = 0;
+ unsigned int tmp;
+
+ if (size == 0)
+ return 0;
+ while (size & ~31UL) {
+ if (~(tmp = *(p++)))
+ goto found_middle;
+ result += 32;
+ size -= 32;
+ }
+ if (!size)
+ return result;
+ tmp = *p;
+ tmp |= ~0UL << size;
+found_middle:
+ return result + ffz(tmp);
+}
+
+/*
+ * Find next zero bit in a bitmap reasonably efficiently..
+ */
+extern __inline__ unsigned long find_next_zero_bit(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 = *(p++);
+ tmp |= ~0UL >> (32-offset);
+ if (size < 32)
+ goto found_first;
+ if (~tmp)
+ goto found_middle;
+ size -= 32;
+ result += 32;
+ }
+ while (size & ~31UL) {
+ if (~(tmp = *(p++)))
+ goto found_middle;
+ result += 32;
+ size -= 32;
+ }
+ if (!size)
+ return result;
+ tmp = *p;
+found_first:
+ tmp |= ~0UL << size;
+found_middle:
+ return result + ffz(tmp);
+}
+
+
#define _EXT2_HAVE_ASM_BITOPS_
#define ext2_find_first_zero_bit(addr, size) \
ext2_find_next_zero_bit((addr), (size), 0)
diff --git a/include/asm-ppc/bugs.h b/include/asm-ppc/bugs.h
index 202f9ab06..8dce1e290 100644
--- a/include/asm-ppc/bugs.h
+++ b/include/asm-ppc/bugs.h
@@ -2,7 +2,5 @@
* This file is included by 'init/main.c'
*/
-void
-check_bugs(void)
-{
-}
+extern void
+check_bugs(void);
diff --git a/include/asm-ppc/byteorder.h b/include/asm-ppc/byteorder.h
index bbb257941..eab03c752 100644
--- a/include/asm-ppc/byteorder.h
+++ b/include/asm-ppc/byteorder.h
@@ -1,6 +1,8 @@
#ifndef _PPC_BYTEORDER_H
#define _PPC_BYTEORDER_H
+#include <asm/types.h>
+
#ifndef __BIG_ENDIAN
#define __BIG_ENDIAN
#endif
@@ -16,21 +18,50 @@
#define __htonl(x) ntohl(x)
#define __htons(x) ntohs(x)
+
+#define __constant_ntohs(x) ntohs(x)
+#define __constant_ntohl(x) ntohl(x)
#define __constant_htonl(x) ntohl(x)
#define __constant_htons(x) ntohs(x)
#ifdef __KERNEL__
+/*
+ * 16 and 32 bit little-endian loads and stores.
+ */
+extern inline unsigned ld_le16(volatile unsigned short *addr)
+{
+ unsigned val;
-/* Convert from CPU byte order, to specified byte order. */
-extern __inline__ __u16 cpu_to_le16(__u16 value)
+ asm volatile("lhbrx %0,0,%1" : "=r" (val) : "r" (addr));
+ return val;
+}
+
+extern inline void st_le16(volatile unsigned short *addr, unsigned val)
+{
+ asm volatile("sthbrx %0,0,%1" : : "r" (val), "r" (addr) : "memory");
+}
+
+extern inline unsigned ld_le32(volatile unsigned *addr)
+{
+ unsigned val;
+
+ asm volatile("lwbrx %0,0,%1" : "=r" (val) : "r" (addr));
+ return val;
+}
+
+extern inline void st_le32(volatile unsigned *addr, unsigned val)
{
- return (value >> 8) | (value << 8);
+ asm volatile("stwbrx %0,0,%1" : : "r" (val), "r" (addr) : "memory");
}
+
+extern __inline__ __u16 cpu_to_le16(__u16 value)
+{
+ return ld_le16(&value);
+}
extern __inline__ __u32 cpu_to_le32(__u32 value)
{
- return((value>>24) | ((value>>8)&0xff00) |
- ((value<<8)&0xff0000) | (value<<24));
+ return ld_le32(&value);
}
#define cpu_to_be16(x) (x)
#define cpu_to_be32(x) (x)
@@ -38,33 +69,33 @@ extern __inline__ __u32 cpu_to_le32(__u32 value)
/* The same, but returns converted value from the location pointer by addr. */
extern __inline__ __u16 cpu_to_le16p(__u16 *addr)
{
- return cpu_to_le16(*addr);
+ return ld_le16(addr);
}
extern __inline__ __u32 cpu_to_le32p(__u32 *addr)
{
- return cpu_to_le32(*addr);
+ return ld_le32(addr);
}
extern __inline__ __u16 cpu_to_be16p(__u16 *addr)
{
- return cpu_to_be16(*addr);
+ return *addr;
}
extern __inline__ __u32 cpu_to_be32p(__u32 *addr)
{
- return cpu_to_be32(*addr);
+ return *addr;
}
/* The same, but do the conversion in situ, ie. put the value back to addr. */
extern __inline__ void cpu_to_le16s(__u16 *addr)
{
- *addr = cpu_to_le16(*addr);
+ st_le16(addr,*addr);
}
extern __inline__ void cpu_to_le32s(__u32 *addr)
{
- *addr = cpu_to_le32(*addr);
+ st_le32(addr,*addr);
}
#define cpu_to_be16s(x) do { } while (0)
@@ -86,5 +117,12 @@ extern __inline__ void cpu_to_le32s(__u32 *addr)
#define be16_to_cpus(x) cpu_to_be16s(x)
#define be32_to_cpus(x) cpu_to_be32s(x)
+
#endif /* __KERNEL__ */
#endif /* !(_PPC_BYTEORDER_H) */
+
+
+
+
+
+
diff --git a/include/asm-ppc/cache.h b/include/asm-ppc/cache.h
index da609f271..8bdffcdfb 100644
--- a/include/asm-ppc/cache.h
+++ b/include/asm-ppc/cache.h
@@ -5,7 +5,8 @@
#define __ARCH_PPC_CACHE_H
/* bytes per L1 cache line */
-#define L1_CACHE_BYTES 32 /* a guess */
+/* a guess */ /* a correct one -- Cort */
+#define L1_CACHE_BYTES 32
#define L1_CACHE_ALIGN(x) (((x)+(L1_CACHE_BYTES-1))&~(L1_CACHE_BYTES-1))
diff --git a/include/asm-ppc/checksum.h b/include/asm-ppc/checksum.h
index 74e943792..7b55f0032 100644
--- a/include/asm-ppc/checksum.h
+++ b/include/asm-ppc/checksum.h
@@ -47,6 +47,20 @@ unsigned int csum_partial_copy( const char *src, char *dst, int len, int sum);
*/
#define csum_partial_copy_fromuser csum_partial_copy
+/*
+ * this is a new version of the above that records errors it finds in *errp,
+ * but continues and zeros the rest of the buffer.
+ *
+ * right now - it just calls csum_partial_copy()
+ * -- Cort
+ */
+extern __inline__
+unsigned int csum_partial_copy_from_user ( const char *src, char *dst,
+ int len, int sum, int *err_ptr)
+{
+ int *dst_err_ptr=NULL;
+ return csum_partial_copy( src, dst, len, sum);
+}
/*
* this routine is used for miscellaneous IP-like checksums, mainly
diff --git a/include/asm-ppc/current.h b/include/asm-ppc/current.h
index d815aaad3..d7a0a9215 100644
--- a/include/asm-ppc/current.h
+++ b/include/asm-ppc/current.h
@@ -1,12 +1,10 @@
#ifndef _PPC_CURRENT_H
#define _PPC_CURRENT_H
-/* Some architectures may want to do something "clever" here since
- * this is the most frequently accessed piece of data in the entire
- * kernel. For an example, see the Sparc implementation where an
- * entire register is hard locked to contain the value of current.
- */
-extern struct task_struct *current_set[NR_CPUS];
-#define current (current_set[smp_processor_id()]) /* Current on this processor */
+#include <linux/config.h>
+
+extern struct task_struct *current_set[1];
+
+register struct task_struct *current asm("r2");
#endif /* !(_PPC_CURRENT_H) */
diff --git a/include/asm-ppc/delay.h b/include/asm-ppc/delay.h
index 68f1a4da7..9da227167 100644
--- a/include/asm-ppc/delay.h
+++ b/include/asm-ppc/delay.h
@@ -1,14 +1,31 @@
#ifndef _PPC_DELAY_H
#define _PPC_DELAY_H
+/*
+ * Copyright 1996, Paul Mackerras.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
-extern __inline__ void __delay(unsigned long );
-extern __inline__ void __udelay(unsigned long );
-
+extern __inline__ void __delay(unsigned int loops)
+{
+ if (loops != 0)
+ __asm__ __volatile__("mtctr %0; 1: bdnz 1b" : :
+ "r" (loops) : "ctr");
+}
-extern __inline__ unsigned long muldiv(unsigned long a, unsigned long b, unsigned long c)
+extern __inline__ void udelay(unsigned long usecs)
{
- return (a*b)/c;
+ unsigned long loops;
+
+ /* compute (usecs * 2^32 / 10^6) * loops_per_sec / 2^32 */
+ usecs *= 0x10c6; /* 2^32 / 10^6 */
+ __asm__("mulhwu %0,%1,%2" : "=r" (loops) :
+ "r" (usecs), "r" (loops_per_sec));
+ __delay(loops);
}
#endif /* defined(_PPC_DELAY_H) */
diff --git a/include/asm-ppc/dma.h b/include/asm-ppc/dma.h
index ca609062e..7becf0190 100644
--- a/include/asm-ppc/dma.h
+++ b/include/asm-ppc/dma.h
@@ -1,16 +1,21 @@
-/* $Id: dma.h,v 1.7 1992/12/14 00:29:34 root Exp root $
+/* $Id: dma.h,v 1.3 1997/03/16 06:20:39 cort Exp $
* linux/include/asm/dma.h: Defines for using and allocating dma channels.
* Written by Hennus Bergman, 1992.
* High DMA channel support & info by Hannu Savolainen
* and John Boyd, Nov. 1992.
*/
+#include <linux/config.h>
+
/*
* Note: Adapted for PowerPC by Gary Thomas
* Modified by Cort Dougan <cort@cs.nmt.edu>
*
+ * None of this really applies for Power Macintoshes. There is
+ * basically just enough here to get kernel/dma.c to compile.
+ *
* There may be some comments or restrictions made here which are
- * not valid for the PowerPC (PreP) platform. Take what you read
+ * not valid for the PReP platform. Take what you read
* with a grain of salt.
*/
@@ -18,6 +23,7 @@
#ifndef _ASM_DMA_H
#define _ASM_DMA_H
+#ifdef CONFIG_PREP
#include <asm/io.h> /* need byte IO */
@@ -295,5 +301,6 @@ static __inline__ int get_dma_residue(unsigned int dmanr)
/* These are in kernel/dma.c: */
extern void free_dma(unsigned int dmanr); /* release it again */
+#endif /* CONFIG_PREP */
#endif /* _ASM_DMA_H */
diff --git a/include/asm-ppc/errno.h b/include/asm-ppc/errno.h
index 8c47b73e7..ff364b820 100644
--- a/include/asm-ppc/errno.h
+++ b/include/asm-ppc/errno.h
@@ -133,4 +133,6 @@
#define ERESTARTNOHAND 514 /* restart if no handler.. */
#define ENOIOCTLCMD 515 /* No ioctl command */
+#define _LAST_ERRNO 515
+
#endif
diff --git a/include/asm-ppc/ide.h b/include/asm-ppc/ide.h
index 69838b8b1..bc16288a8 100644
--- a/include/asm-ppc/ide.h
+++ b/include/asm-ppc/ide.h
@@ -1,5 +1,5 @@
/*
- * linux/include/asm-i386/ide.h
+ * linux/include/asm-ppc/ide.h
*
* Copyright (C) 1994-1996 Linus Torvalds & authors
*/
@@ -13,7 +13,7 @@
#ifdef __KERNEL__
-typedef unsigned short ide_ioreg_t;
+#include <linux/config.h>
#ifndef MAX_HWIFS
#define MAX_HWIFS 4
@@ -21,11 +21,15 @@ typedef unsigned short ide_ioreg_t;
#define ide_sti() sti()
+#ifdef CONFIG_PREP
+
+typedef unsigned short ide_ioreg_t;
+
static __inline__ int ide_default_irq(ide_ioreg_t base)
{
switch (base) {
- case 0x1f0: return 14;
- case 0x170: return 15;
+ case 0x1f0: return 13;
+ case 0x170: return 13;
case 0x1e8: return 11;
case 0x168: return 10;
default:
@@ -66,18 +70,7 @@ typedef union {
unsigned lba : 1; /* using LBA instead of CHS */
unsigned bit7 : 1; /* always 1 */
} b;
- } select_t;
-
-static __inline__ int ide_request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *),
- unsigned long flags, const char *device, void *dev_id)
-{
- return request_irq(irq, handler, flags, device, dev_id);
-}
-
-static __inline__ void ide_free_irq(unsigned int irq, void *dev_id)
-{
- free_irq(irq, dev_id);
-}
+} select_t;
static __inline__ int ide_check_region (ide_ioreg_t from, unsigned int extent)
{
@@ -94,26 +87,92 @@ static __inline__ void ide_release_region (ide_ioreg_t from, unsigned int extent
release_region(from, extent);
}
-/*
- * The following are not needed for the non-m68k ports
- */
-static __inline__ int ide_ack_intr (ide_ioreg_t base_port, ide_ioreg_t irq_port)
+#define ide_fix_driveid(id) do {} while (0)
+
+#endif
+
+#ifdef CONFIG_PMAC
+
+#include <asm/io.h> /* so we can redefine insw/outsw */
+
+typedef unsigned long ide_ioreg_t;
+
+static __inline__ int ide_default_irq(ide_ioreg_t base)
+{
+ return 0;
+}
+
+extern __inline__ ide_ioreg_t ide_default_io_base(int index)
+{
+ return index;
+}
+
+extern void ide_init_hwif_ports(ide_ioreg_t *p, ide_ioreg_t base, int *irq);
+
+typedef union {
+ unsigned all : 8; /* all of the bits together */
+ struct {
+ unsigned bit7 : 1; /* always 1 */
+ unsigned lba : 1; /* using LBA instead of CHS */
+ unsigned bit5 : 1; /* always 1 */
+ unsigned unit : 1; /* drive select number, 0/1 */
+ unsigned head : 4; /* always zeros here */
+ } b;
+} select_t;
+
+#undef SUPPORT_SLOW_DATA_PORTS
+#define SUPPORT_SLOW_DATA_PORTS 0
+#undef SUPPORT_VLB_SYNC
+#define SUPPORT_VLB_SYNC 0
+
+static __inline__ int ide_check_region (ide_ioreg_t from, unsigned int extent)
{
- return(1);
+ return 0;
}
-static __inline__ void ide_fix_driveid(struct hd_driveid *id)
+static __inline__ void ide_request_region (ide_ioreg_t from, unsigned int extent, const char *name)
{
}
-static __inline__ void ide_release_lock (int *ide_lock)
+static __inline__ void ide_release_region (ide_ioreg_t from, unsigned int extent)
{
}
-static __inline__ void ide_get_lock (int *ide_lock, void (*handler)(int, void *, struct pt_regs *), void *data)
+#undef insw
+#undef outsw
+#define insw(port, buf, ns) ide_insw((port), (buf), (ns))
+#define outsw(port, buf, ns) ide_outsw((port), (buf), (ns))
+
+void ide_insw(ide_ioreg_t port, void *buf, int ns);
+void ide_outsw(ide_ioreg_t port, void *buf, int ns);
+
+#define ide_fix_driveid(id) do { \
+ int nh; \
+ unsigned short *p = (unsigned short *) id; \
+ for (nh = SECTOR_WORDS * 2; nh != 0; --nh, ++p) \
+ *p = (*p << 8) + (*p >> 8); \
+} while (0)
+
+#endif
+
+static __inline__ int ide_request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *),
+ unsigned long flags, const char *device, void *dev_id)
{
+ return request_irq(irq, handler, flags, device, dev_id);
+}
+
+static __inline__ void ide_free_irq(unsigned int irq, void *dev_id)
+{
+ free_irq(irq, dev_id);
}
+/*
+ * The following are not needed for the non-m68k ports
+ */
+#define ide_ack_intr(base, irq) (1)
+#define ide_release_lock(lock) do {} while (0)
+#define ide_get_lock(lock, hdlr, data) do {} while (0)
+
#endif /* __KERNEL__ */
#endif /* __ASMPPC_IDE_H */
diff --git a/include/asm-ppc/init.h b/include/asm-ppc/init.h
index 82ce44ce8..09b38d899 100644
--- a/include/asm-ppc/init.h
+++ b/include/asm-ppc/init.h
@@ -1,14 +1,23 @@
#ifndef _PPC_INIT_H
#define _PPC_INIT_H
-/* Throwing the initialization code and data out is not supported yet... */
-
-#define __init
+#define __init
#define __initdata
-#define __initfunc(__arginit) __arginit
-/* For assembly routines */
+#define __initfunc(x) x
+/*
+#define __init __attribute__ ((__section__ (".text.init")))
+#define __initdata __attribute__ ((__section__ (".data.init")))
+#define __initfunc(__arginit) \
+ __arginit __init; \
+ __arginit
+*/
+ /* For assembly routines */
#define __INIT
#define __FINIT
#define __INITDATA
-
+/*
+#define __INIT .section ".text.init",#alloc,#execinstr
+#define __FINIT .previous
+#define __INITDATA .section ".data.init",#alloc,#write
+*/
#endif
diff --git a/include/asm-ppc/io.h b/include/asm-ppc/io.h
index 581d51643..e2dfcc49a 100644
--- a/include/asm-ppc/io.h
+++ b/include/asm-ppc/io.h
@@ -1,8 +1,11 @@
#ifndef _PPC_IO_H
#define _PPC_IO_H
+#include <linux/config.h>
#include <asm/page.h>
+#include <asm/byteorder.h>
+#ifdef CONFIG_PREP
/* from the Carolina Technical Spec -- Cort */
#define IBM_ACORN 0x82A
#define SIO_CONFIG_RA 0x398
@@ -14,15 +17,67 @@
#define IBM_L2_INVALIDATE 0x814
#define IBM_SYS_CTL 0x81c
-
-
-/* Define the particulars of outb/outw/outl "instructions" */
#define SLOW_DOWN_IO
#ifndef PCI_DRAM_OFFSET
#define PCI_DRAM_OFFSET 0x80000000
#endif
+#define readb(addr) (*(volatile unsigned char *) (addr))
+#define readw(addr) (*(volatile unsigned short *) (addr))
+#define readl(addr) (*(volatile unsigned int *) (addr))
+#define writeb(b,addr) ((*(volatile unsigned char *) (addr)) = (b))
+#define writew(b,addr) ((*(volatile unsigned short *) (addr)) = (b))
+#define writel(b,addr) ((*(volatile unsigned int *) (addr)) = (b))
+
+void outsl(int port, long *ptr, int len);
+
+__inline__ unsigned char outb(unsigned char val, int port);
+__inline__ unsigned short outw(unsigned short val, int port);
+__inline__ unsigned long outl(unsigned long val, int port);
+__inline__ unsigned char inb(int port);
+__inline__ unsigned short inw(int port);
+__inline__ unsigned long inl(int port);
+
+#define inb_p inb
+#define inw_p inw
+#define inl_p inl
+#define outb_p outb
+#define outw_p outw
+#define outl_p outl
+
+#endif /* CONFIG_PREP */
+
+#ifdef CONFIG_PMAC
+/*
+ * Read and write the non-volatile RAM.
+ */
+extern int nvram_readb(int addr);
+extern void nvram_writeb(int addr, int val);
+
+#ifndef PCI_DRAM_OFFSET
+#define PCI_DRAM_OFFSET 0
+#endif
+
+#define inb(port) in_8((unsigned char *)(port))
+#define outb(val, port) out_8((unsigned char *)(port), (val))
+#define inw(port) in_le16((unsigned short *)(port))
+#define outw(val, port) out_le16((unsigned short *)(port), (val))
+#define inl(port) in_le32((unsigned long *)(port))
+#define outl(val, port) out_le32((unsigned long *)(port), (val))
+
+#define inb_p(port) in_8((unsigned char *)(port))
+#define outb_p(val, port) out_8((unsigned char *)(port), (val))
+#define inw_p(port) in_le16((unsigned short *)(port))
+#define outw_p(val, port) out_le16((unsigned short *)(port), (val))
+#define inl_p(port) in_le32(((unsigned long *)port))
+#define outl_p(val, port) out_le32((unsigned long *)(port), (val))
+
+#define insw(port, buf, ns) _insw((unsigned short *)(port), (buf), (ns))
+#define outsw(port, buf, ns) _outsw((unsigned short *)(port), (buf), (ns))
+#define insl(port, buf, nl) _insl((unsigned long *)(port), (buf), (nl))
+#define outsl(port, buf, nl) _outsl((unsigned long *)(port), (buf), (nl))
+#endif /* CONFIG_PMAC */
/*
* The PCI bus is inherently Little-Endian. The PowerPC is being
@@ -42,19 +97,12 @@ extern inline void * bus_to_virt(unsigned long address)
if (address == 0) return 0;
return ((void *)(address - PCI_DRAM_OFFSET + KERNELBASE));
}
-/* #define virt_to_bus(a) ((unsigned long)(((char *)a==(char *) 0) ? ((char *)0) \
- : ((char *)((long)a - KERNELBASE + PCI_DRAM_OFFSET))))
-#define bus_to_virt(a) ((void *) (((char *)a==(char *)0) ? ((char *)0) \
- : ((char *)((long)a - PCI_DRAM_OFFSET + KERNELBASE))))
-*/
-
-#define readb(addr) (*(volatile unsigned char *) (addr))
-#define readw(addr) (*(volatile unsigned short *) (addr))
-#define readl(addr) (*(volatile unsigned int *) (addr))
-#define writeb(b,addr) ((*(volatile unsigned char *) (addr)) = (b))
-#define writew(b,addr) ((*(volatile unsigned short *) (addr)) = (b))
-#define writel(b,addr) ((*(volatile unsigned int *) (addr)) = (b))
+/*
+ * Map in an area of physical address space, for accessing
+ * I/O devices etc.
+ */
+extern void *ioremap(unsigned long address, unsigned long size);
/*
* Change virtual addresses to physical addresses and vv.
@@ -72,27 +120,101 @@ extern inline void * phys_to_virt(unsigned long address)
return (void *) address;
}
-/* from arch/ppc/kernel/port_io.c
- * -- Cort
+#define _IO_BASE ((unsigned long)0x80000000)
+
+/*
+ * These are much more useful le/be io functions from Paul
+ * than leXX_to_cpu() style functions since the ppc has
+ * load/store byte reverse instructions
+ * -- Cort
*/
-unsigned char inb(int port);
-unsigned short inw(int port);
-unsigned long inl(int port);
-unsigned char outb(unsigned char val,int port);
-unsigned short outw(unsigned short val,int port);
-unsigned long outl(unsigned long val,int port);
-void outsl(int port, long *ptr, int len);
-static inline unsigned char inb_p(int port) {return (inb(port)); }
-static inline unsigned short inw_p(int port) {return (inw(port)); }
-static inline unsigned long inl_p(int port) {return (inl(port)); }
+/*
+ * Enforce In-order Execution of I/O:
+ * Acts as a barrier to ensure all previous I/O accesses have
+ * completed before any further ones are issued.
+ */
+extern inline void eieio(void)
+{
+ asm volatile ("eieio" : :);
+}
+
+/*
+ * 8, 16 and 32 bit, big and little endian I/O operations, with barrier.
+ */
+extern inline int in_8(volatile unsigned char *addr)
+{
+ int ret;
+
+ ret = *addr;
+ eieio();
+ return ret;
+}
+
+extern inline void out_8(volatile unsigned char *addr, int val)
+{
+ *addr = val;
+ eieio();
+}
+
+extern inline int in_le16(volatile unsigned short *addr)
+{
+ int ret;
+
+ ret = ld_le16(addr);
+ eieio();
+ return ret;
+}
+
+extern inline int in_be16(volatile unsigned short *addr)
+{
+ int ret;
+
+ ret = *addr;
+ eieio();
+ return ret;
+}
+extern inline void out_le16(volatile unsigned short *addr, int val)
+{
+ st_le16(addr, val);
+ eieio();
+}
+extern inline void out_be16(volatile unsigned short *addr, int val)
+{
+ *addr = val;
+ eieio();
+}
-static inline unsigned char outb_p(unsigned char val,int port) { return (outb(val,port)); }
-static inline unsigned short outw_p(unsigned short val,int port) { return (outw(val,port)); }
-static inline unsigned long outl_p(unsigned long val,int port) { return (outl(val,port)); }
+extern inline unsigned in_le32(volatile unsigned *addr)
+{
+ unsigned ret;
+ ret = ld_le32(addr);
+ eieio();
+ return ret;
+}
+extern inline int in_be32(volatile unsigned *addr)
+{
+ int ret;
+
+ ret = *addr;
+ eieio();
+ return ret;
+}
+
+extern inline void out_le32(volatile unsigned *addr, int val)
+{
+ st_le32(addr, val);
+ eieio();
+}
+
+extern inline void out_be32(volatile unsigned *addr, int val)
+{
+ *addr = val;
+ eieio();
+}
#endif
diff --git a/include/asm-ppc/ioctls.h b/include/asm-ppc/ioctls.h
index f56e53db7..2039f4954 100644
--- a/include/asm-ppc/ioctls.h
+++ b/include/asm-ppc/ioctls.h
@@ -83,8 +83,8 @@
#define TIOCGETD 0x5424
#define TCSBRKP 0x5425 /* Needed for POSIX tcsendbreak() */
#define TIOCTTYGSTRUCT 0x5426 /* For debugging only */
-#define TIOCSBRK 0x5427 /* BSD compatibility */
-#define TIOCCBRK 0x5428 /* BSD compatibility */
+#define TIOCSBRK 0x5427 /* BSD compatibility */
+#define TIOCCBRK 0x5428 /* BSD compatibility */
#define TIOCSERCONFIG 0x5453
#define TIOCSERGWILD 0x5454
diff --git a/include/asm-ppc/irq.h b/include/asm-ppc/irq.h
index f457f82c3..ebffe2bcb 100644
--- a/include/asm-ppc/irq.h
+++ b/include/asm-ppc/irq.h
@@ -1,7 +1,13 @@
#ifndef _ASM_IRQ_H
#define _ASM_IRQ_H
+#include <linux/config.h>
+
+#ifdef CONFIG_PMAC
#define NR_IRQS 32
+#else
+#define NR_IRQS 16
+#endif
extern void disable_irq(unsigned int);
extern void enable_irq(unsigned int);
diff --git a/include/asm-ppc/keyboard.h b/include/asm-ppc/keyboard.h
index 9ac4139b9..0c7240d14 100644
--- a/include/asm-ppc/keyboard.h
+++ b/include/asm-ppc/keyboard.h
@@ -2,12 +2,14 @@
* linux/include/asm-ppc/keyboard.h
*
* Created 3 Nov 1996 by Geert Uytterhoeven
+ * Modified for Power Macintosh by Paul Mackerras
*
- * $Id: keyboard.h,v 1.3 1997/07/22 23:18:19 ralf Exp $
+ * $Id: keyboard.h,v 1.3 1997/07/24 01:55:57 ralf Exp $
*/
/*
- * This file contains the ppc architecture specific keyboard definitions
+ * This file contains the ppc architecture specific keyboard definitions -
+ * like the intel pc for prep systems, different for power macs.
*/
#ifndef __ASMPPC_KEYBOARD_H
@@ -17,6 +19,29 @@
#include <asm/io.h>
+#include <linux/config.h>
+
+#ifdef CONFIG_MAC_KEYBOARD
+
+extern int mackbd_setkeycode(unsigned int scancode, unsigned int keycode);
+extern int mackbd_getkeycode(unsigned int scancode);
+extern int mackbd_pretranslate(unsigned char scancode, char raw_mode);
+extern int mackbd_translate(unsigned char scancode, unsigned char *keycode,
+ char raw_mode);
+extern int mackbd_unexpected_up(unsigned char keycode);
+extern void mackbd_leds(unsigned char leds);
+extern void mackbd_init_hw(void);
+
+#define kbd_setkeycode mackbd_setkeycode
+#define kbd_getkeycode mackbd_getkeycode
+#define kbd_pretranslate mackbd_pretranslate
+#define kbd_translate mackbd_translate
+#define kbd_unexpected_up mackbd_unexpected_up
+#define kbd_leds mackbd_leds
+#define kbd_init_hw mackbd_init_hw
+
+#else /* CONFIG_MAC_KEYBOARD */
+
#define KEYBOARD_IRQ 1
#define DISABLE_KBD_DURING_INTERRUPTS 0
@@ -47,6 +72,7 @@ extern void pckbd_init_hw(void);
#define kbd_pause() do { } while(0)
#define INIT_KBD
+#endif /* CONFIG_MAC_KEYBOARD */
#define keyboard_setup() \
request_region(0x60, 16, "keyboard")
diff --git a/include/asm-ppc/mc146818rtc.h b/include/asm-ppc/mc146818rtc.h
index 91f93f598..e69de29bb 100644
--- a/include/asm-ppc/mc146818rtc.h
+++ b/include/asm-ppc/mc146818rtc.h
@@ -1,128 +0,0 @@
-/* mc146818rtc.h - register definitions for the Real-Time-Clock / CMOS RAM
- * Copyright Torsten Duwe <duwe@informatik.uni-erlangen.de> 1993
- * derived from Data Sheet, Copyright Motorola 1984 (!).
- * It was written to be part of the Linux operating system.
- */
-/* permission is hereby granted to copy, modify and redistribute this code
- * in terms of the GNU Library General Public License, Version 2 or later,
- * at your option.
- */
-
-#ifndef _MC146818RTC_H
-#define _MC146818RTC_H
-
-#include <asm/io.h>
-
-#ifndef RTC_PORT
-#define RTC_PORT(x) (0x70 + (x))
-#define RTC_ALWAYS_BCD 1 /* RTC operates in binary mode */
-#endif
-
-/*
- * The yet supported machines all access the RTC index register via
- * an ISA port access but the way to access the date register differs ...
- */
-#define CMOS_READ(addr) ({ \
-outb_p((addr),RTC_PORT(0)); \
-inb_p(RTC_PORT(1)); \
-})
-#define CMOS_WRITE(val, addr) ({ \
-outb_p((addr),RTC_PORT(0)); \
-outb_p((val),RTC_PORT(1)); \
-})
-
-#ifndef MCRTC_PORT
-#define MCRTC_PORT(x) (0x70 + (x))
-#define MCRTC_ALWAYS_BCD 1
-#endif
-
-#define CMOS_MCRTC_READ(addr) ({ \
-outb_p((addr),MCRTC_PORT(0)); \
-inb_p(MCRTC_PORT(1)); \
-})
-#define CMOS_MCRTC_WRITE(val, addr) ({ \
-outb_p((addr),MCRTC_PORT(0)); \
-outb_p((val),MCRTC_PORT(1)); \
-})
-
-/**********************************************************************
- * register summary
- **********************************************************************/
-#define MCRTC_SECONDS 0
-#define MCRTC_SECONDS_ALARM 1
-#define MCRTC_MINUTES 2
-#define MCRTC_MINUTES_ALARM 3
-#define MCRTC_HOURS 4
-#define MCRTC_HOURS_ALARM 5
-/* RTC_*_alarm is always true if 2 MSBs are set */
-# define MCRTC_ALARM_DONT_CARE 0xC0
-
-#define MCRTC_DAY_OF_WEEK 6
-#define MCRTC_DAY_OF_MONTH 7
-#define MCRTC_MONTH 8
-#define MCRTC_YEAR 9
-
-/* control registers - Moto names
- */
-#define MCRTC_REG_A 10
-#define MCRTC_REG_B 11
-#define MCRTC_REG_C 12
-#define MCRTC_REG_D 13
-
-/**********************************************************************
- * register details
- **********************************************************************/
-#define MCRTC_FREQ_SELECT MCRTC_REG_A
-
-/* update-in-progress - set to "1" 244 microsecs before RTC goes off the bus,
- * reset after update (may take 1.984ms @ 32768Hz RefClock) is complete,
- * totalling to a max high interval of 2.228 ms.
- */
-# define MCRTC_UIP 0x80
-# define MCRTC_DIV_CTL 0x70
- /* divider control: refclock values 4.194 / 1.049 MHz / 32.768 kHz */
-# define MCRTC_REF_CLCK_4MHZ 0x00
-# define MCRTC_REF_CLCK_1MHZ 0x10
-# define MCRTC_REF_CLCK_32KHZ 0x20
- /* 2 values for divider stage reset, others for "testing purposes only" */
-# define MCRTC_DIV_RESET1 0x60
-# define MCRTC_DIV_RESET2 0x70
- /* Periodic intr. / Square wave rate select. 0=none, 1=32.8kHz,... 15=2Hz */
-# define MCRTC_RATE_SELECT 0x0F
-
-/**********************************************************************/
-#define MCRTC_CONTROL MCRTC_REG_B
-# define MCRTC_SET 0x80 /* disable updates for clock setting */
-# define MCRTC_PIE 0x40 /* periodic interrupt enable */
-# define MCRTC_AIE 0x20 /* alarm interrupt enable */
-# define MCRTC_UIE 0x10 /* update-finished interrupt enable */
-# define MCRTC_SQWE 0x08 /* enable square-wave output */
-# define MCRTC_DM_BINARY 0x04 /* all time/date values are BCD if clear */
-# define MCRTC_24H 0x02 /* 24 hour mode - else hours bit 7 means pm */
-# define MCRTC_DST_EN 0x01 /* auto switch DST - works f. USA only */
-
-/**********************************************************************/
-#define MCRTC_INTR_FLAGS MCRTC_REG_C
-/* caution - cleared by read */
-# define MCRTC_IRQF 0x80 /* any of the following 3 is active */
-# define MCRTC_PF 0x40
-# define MCRTC_AF 0x20
-# define MCRTC_UF 0x10
-
-/**********************************************************************/
-#define MCRTC_VALID MCRTC_REG_D
-# define MCRTC_VRT 0x80 /* valid RAM and time */
-/**********************************************************************/
-
-/* example: !(CMOS_READ(MCRTC_CONTROL) & MCRTC_DM_BINARY)
- * determines if the following two #defines are needed
- */
-#ifndef BCD_TO_BIN
-#define BCD_TO_BIN(val) ((val)=((val)&15) + ((val)>>4)*10)
-#endif
-
-#ifndef BIN_TO_BCD
-#define BIN_TO_BCD(val) ((val)=(((val)/10)<<4) + (val)%10)
-#endif
-
-#endif /* _MC146818RTC_H */
diff --git a/include/asm-ppc/mmu.h b/include/asm-ppc/mmu.h
index 1b3217cfd..c6c835229 100644
--- a/include/asm-ppc/mmu.h
+++ b/include/asm-ppc/mmu.h
@@ -32,42 +32,68 @@ typedef struct _PTE
/* Segment Register */
typedef struct _SEGREG
- {
- unsigned long t:1; /* Normal or I/O type */
- unsigned long ks:1; /* Supervisor 'key' (normally 0) */
- unsigned long kp:1; /* User 'key' (normally 1) */
- unsigned long n:1; /* No-execute */
- unsigned long :4; /* Unused */
- unsigned long vsid:24; /* Virtual Segment Identifier */
- } SEGREG;
+{
+ unsigned long t:1; /* Normal or I/O type */
+ unsigned long ks:1; /* Supervisor 'key' (normally 0) */
+ unsigned long kp:1; /* User 'key' (normally 1) */
+ unsigned long n:1; /* No-execute */
+ unsigned long :4; /* Unused */
+ unsigned long vsid:24; /* Virtual Segment Identifier */
+} SEGREG;
/* Block Address Translation (BAT) Registers */
+typedef struct _P601_BATU
+{
+ unsigned long bepi:15; /* Effective page index (virtual address) */
+ unsigned long :8; /* unused */
+ unsigned long w:1;
+ unsigned long i:1; /* Cache inhibit */
+ unsigned long m:1; /* Memory coherence */
+ unsigned long vs:1; /* Supervisor valid */
+ unsigned long vp:1; /* User valid */
+ unsigned long pp:2; /* Page access protections */
+} P601_BATU;
+
typedef struct _BATU /* Upper part of BAT */
- {
- unsigned long bepi:15; /* Effective page index (virtual address) */
- unsigned long :4; /* Unused */
- unsigned long bl:11; /* Block size mask */
- unsigned long vs:1; /* Supervisor valid */
- unsigned long vp:1; /* User valid */
- } BATU;
+{
+ unsigned long bepi:15; /* Effective page index (virtual address) */
+ unsigned long :4; /* Unused */
+ unsigned long bl:11; /* Block size mask */
+ unsigned long vs:1; /* Supervisor valid */
+ unsigned long vp:1; /* User valid */
+} BATU;
+
+typedef struct _P601_BATL
+{
+ unsigned long brpn:15; /* Real page index (physical address) */
+ unsigned long :10; /* Unused */
+ unsigned long v:1; /* valid/invalid */
+ unsigned long bl:6; /* Block size mask */
+} P601_BATL;
typedef struct _BATL /* Lower part of BAT */
- {
- unsigned long brpn:15; /* Real page index (physical address) */
- unsigned long :10; /* Unused */
- unsigned long w:1; /* Write-thru cache */
- unsigned long i:1; /* Cache inhibit */
- unsigned long m:1; /* Memory coherence */
- unsigned long g:1; /* Guarded (MBZ) */
- unsigned long :1; /* Unused */
- unsigned long pp:2; /* Page access protections */
- } BATL;
+{
+ unsigned long brpn:15; /* Real page index (physical address) */
+ unsigned long :10; /* Unused */
+ unsigned long w:1; /* Write-thru cache */
+ unsigned long i:1; /* Cache inhibit */
+ unsigned long m:1; /* Memory coherence */
+ unsigned long g:1; /* Guarded (MBZ) */
+ unsigned long :1; /* Unused */
+ unsigned long pp:2; /* Page access protections */
+} BATL;
typedef struct _BAT
- {
- BATU batu; /* Upper register */
- BATL batl; /* Lower register */
- } BAT;
+{
+ BATU batu; /* Upper register */
+ BATL batl; /* Lower register */
+} BAT;
+
+typedef struct _P601_BAT
+{
+ P601_BATU batu; /* Upper register */
+ P601_BATL batl; /* Lower register */
+} P601_BAT;
/* Block size masks */
#define BL_128K 0x000
@@ -118,15 +144,6 @@ typedef struct _MMU_context
pte **pmap; /* Two-level page-map structure */
} MMU_context;
-#if 0
-BAT ibat[4]; /* Instruction BAT images */
-BAT dbat[4]; /* Data BAT images */
-PTE *hash_table; /* Hardware hashed page table */
-int hash_table_size;
-int hash_table_mask;
-unsigned long sdr; /* Hardware image of SDR */
-#endif
-
/* Used to set up SDR register */
#define HASH_TABLE_SIZE_64K 0x00010000
#define HASH_TABLE_SIZE_128K 0x00020000
@@ -143,6 +160,4 @@ unsigned long sdr; /* Hardware image of SDR */
#define HASH_TABLE_MASK_2M 0x01F
#define HASH_TABLE_MASK_4M 0x03F
-extern inline int MMU_hash_page(struct thread_struct *tss, unsigned long va, pte *pg);
-
#endif
diff --git a/include/asm-ppc/mmu_context.h b/include/asm-ppc/mmu_context.h
index f4bd1e84f..89a649bb3 100644
--- a/include/asm-ppc/mmu_context.h
+++ b/include/asm-ppc/mmu_context.h
@@ -1,13 +1,59 @@
#ifndef __PPC_MMU_CONTEXT_H
#define __PPC_MMU_CONTEXT_H
+/* the way contexts are handled on the ppc they are vsid's and
+ don't need any special treatment right now.
+ perhaps I can defer flushing the tlb by keeping a list of
+ zombie vsid/context's and handling that through destroy_context
+ later -- Cort
+ */
+
+#define NO_CONTEXT 0
+#define LAST_CONTEXT 0xfffff
+
+extern int next_mmu_context;
+extern void mmu_context_overflow(void);
+extern void set_context(int context);
+
/*
- * get a new mmu context.. PowerPC's don't know about contexts [yet]
+ * Allocating context numbers this way tends to spread out
+ * the entries in the hash table better than a simple linear
+ * allocation.
*/
-#define get_mmu_context(x) do { } while (0)
+#define MUNGE_CONTEXT(n) (((n) * 897) & LAST_CONTEXT)
-#define init_new_context(mm) do { } while(0)
-#define destroy_context(mm) do { } while(0)
+/*
+ * Get a new mmu context for task tsk if necessary.
+ */
+#define get_mmu_context(tsk) \
+do { \
+ struct mm_struct *mm = (tsk)->mm; \
+ if (mm->context == NO_CONTEXT) { \
+ int i; \
+ if (next_mmu_context == LAST_CONTEXT) \
+ mmu_context_overflow(); \
+ mm->context = MUNGE_CONTEXT(++next_mmu_context);\
+ if ( tsk == current ) \
+ set_context(mm->context); \
+ } \
+} while (0)
-#endif
+/*
+ * Set up the context for a new address space.
+ */
+#define init_new_context(mm) ((mm)->context = NO_CONTEXT)
+
+/*
+ * We're finished using the context for an address space.
+ */
+#define destroy_context(mm) do { } while (0)
+/*
+ * compute the vsid from the context and segment
+ * segments > 7 are kernel segments and their
+ * vsid is the segment -- Cort
+ */
+#define VSID_FROM_CONTEXT(segment,context) \
+ ((segment < 8) ? ((segment) | (context)<<4) : (segment))
+
+#endif
diff --git a/include/asm-ppc/nvram.h b/include/asm-ppc/nvram.h
index 1d704ff6a..665bc76af 100644
--- a/include/asm-ppc/nvram.h
+++ b/include/asm-ppc/nvram.h
@@ -9,6 +9,7 @@
#define NVRAM_AS1 0x75
#define NVRAM_DATA 0x77
+
/* RTC Offsets */
#define RTC_SECONDS 0x1FF9
@@ -18,6 +19,8 @@
#define RTC_DAY_OF_MONTH 0x1FFD
#define RTC_MONTH 0x1FFE
#define RTC_YEAR 0x1FFF
+#define RTC_CONTROLA 0x1FF8
+#define RTC_CONTROLB 0x1FF9
#ifndef BCD_TO_BIN
#define BCD_TO_BIN(val) ((val)=((val)&15) + ((val)>>4)*10)
diff --git a/include/asm-ppc/page.h b/include/asm-ppc/page.h
index 273d31fd0..a18d5e324 100644
--- a/include/asm-ppc/page.h
+++ b/include/asm-ppc/page.h
@@ -1,11 +1,32 @@
#ifndef _PPC_PAGE_H
#define _PPC_PAGE_H
+#include <linux/config.h>
+
/* PAGE_SHIFT determines the page size */
#define PAGE_SHIFT 12
#define PAGE_SIZE (1UL << PAGE_SHIFT)
#define PAGE_MASK (~(PAGE_SIZE-1))
+/* This handles the memory map.. */
+
+/*
+ * these virtual mappings for prep and pmac
+ * on the prep machine the io areas are at different physical locations
+ * than their virtual address. On the pmac the io areas
+ * are mapped 1-1 virtual/physical.
+ * -- Cort
+ */
+#ifdef CONFIG_PREP
+#define KERNELBASE 0x90000000
+#endif
+#ifdef CONFIG_PMAC
+#define KERNELBASE 0xc0000000
+#endif
+#define PAGE_OFFSET KERNELBASE
+
+
+#ifndef __ASSEMBLY__
#ifdef __KERNEL__
#define STRICT_MM_TYPECHECKS
@@ -50,13 +71,13 @@ typedef unsigned long pgprot_t;
#endif
+
+/* align addr on a size boundry - adjust address up if needed -- Cort */
+#define _ALIGN(addr,size) (((addr)+size-1)&(~(size-1)))
+
/* to align the pointer to the (next) page boundary */
#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK)
-/* This handles the memory map.. */
-
-#define KERNELBASE 0x90000000
-#define PAGE_OFFSET KERNELBASE
#define clear_page(page) memset((void *)(page), 0, PAGE_SIZE)
#define copy_page(to,from) memcpy((void *)(to), (void *)(from), PAGE_SIZE)
@@ -67,7 +88,8 @@ typedef unsigned long pgprot_t;
#define MAP_NR(addr) (__pa(addr) >> PAGE_SHIFT)
#define MAP_PAGE_RESERVED (1<<15)
+extern __inline__ unsigned long get_prezerod_page(void);
#endif /* __KERNEL__ */
-
+#endif /* __ASSEMBLY__ */
#endif /* _PPC_PAGE_H */
diff --git a/include/asm-ppc/pgtable.h b/include/asm-ppc/pgtable.h
index e9c400345..fd52a64c7 100644
--- a/include/asm-ppc/pgtable.h
+++ b/include/asm-ppc/pgtable.h
@@ -1,22 +1,31 @@
-/* * Last edited: Nov 7 23:44 1995 (cort) */
#ifndef _PPC_PGTABLE_H
#define _PPC_PGTABLE_H
+#include <linux/config.h>
#include <asm/page.h>
#include <asm/mmu.h>
-inline void flush_tlb(void);
-inline void flush_tlb_all(void);
-inline void flush_tlb_mm(struct mm_struct *mm);
-inline void flush_tlb_page(struct vm_area_struct *vma, long vmaddr);
-inline void flush_tlb_range(struct mm_struct *mm, long start, long end);
-inline void flush_page_to_ram(unsigned long);
-inline void really_flush_cache_all(void);
+extern void flush_tlb_all(void);
+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_range(struct mm_struct *mm, unsigned long start,
+ unsigned long end);
+extern void flush_tlb(void);
+
+/* Caches aren't brain-dead on the ppc. */
+#define flush_cache_all()
+#define flush_cache_mm(mm)
+#define flush_cache_range(mm, start, end)
+#define flush_cache_page(vma, vmaddr)
+/*
+ * For the page specified, write modified lines in the data cache
+ * out to memory, and invalidate lines in the instruction cache.
+ */
+extern void flush_page_to_ram(unsigned long);
-/* only called from asm in head.S, so why bother? */
-/*void MMU_init(void);*/
+extern unsigned long va_to_phys(unsigned long address);
-/* PMD_SHIFT determines the size of the area a second-level page table can map */
+/* PMD_SHIFT determines the size of the area mapped by the second-level page tables */
#define PMD_SHIFT 22
#define PMD_SIZE (1UL << PMD_SHIFT)
#define PMD_MASK (~(PMD_SIZE-1))
@@ -27,8 +36,8 @@ inline void really_flush_cache_all(void);
#define PGDIR_MASK (~(PGDIR_SIZE-1))
/*
- * entries per page directory level: the i386 is two-level, so
- * we don't really have any PMD directory physically.
+ * entries per page directory level: our page-table tree is two-level, so
+ * we don't really have any PMD directory.
*/
#define PTRS_PER_PTE 1024
#define PTRS_PER_PMD 1
@@ -41,41 +50,42 @@ inline void really_flush_cache_all(void);
* The vmalloc() routines leaves a hole of 4kB between each vmalloced
* area for the same reason. ;)
*/
-/* this must be a decent size since the ppc bat's can map only certain sizes
- but these can be different from the physical ram size configured.
- bat mapping must map at least physical ram size and vmalloc start addr
- must beging AFTER the area mapped by the bat.
- 32 works for now, but may need to be changed with larger differences.
- offset = next greatest bat mapping to ramsize - ramsize
- (ie would be 0 if batmapping = ramsize)
- -- Cort 10/6/96
- */
-#define VMALLOC_OFFSET (32*1024*1024)
+#define VMALLOC_OFFSET (0x2000000) /* 32M */
#define VMALLOC_START ((((long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1)))
#define VMALLOC_VMADDR(x) ((unsigned long)(x))
-#define _PAGE_PRESENT 0x001
-#define _PAGE_RW 0x002
-#define _PAGE_USER 0x004
-#define _PAGE_PCD 0x010
-#define _PAGE_ACCESSED 0x020
-#define _PAGE_DIRTY 0x040
-#define _PAGE_COW 0x200 /* implemented in software (one of the AVL bits) */
-#define _PAGE_NO_CACHE 0x400
+/*
+ * Bits in a linux-style PTE. These match the bits in the
+ * (hardware-defined) PowerPC PTE as closely as possible.
+ */
+#define _PAGE_PRESENT 0x001 /* software: pte contains a translation */
+#define _PAGE_USER 0x002 /* matches one of the PP bits */
+#define _PAGE_RW 0x004 /* software: user write access allowed */
+#define _PAGE_GUARDED 0x008
+#define _PAGE_COHERENT 0x010 /* M: enforce memory coherence (SMP systems) */
+#define _PAGE_NO_CACHE 0x020 /* I: cache inhibit */
+#define _PAGE_WRITETHRU 0x040 /* W: cache write-through */
+#define _PAGE_DIRTY 0x080 /* C: page changed */
+#define _PAGE_ACCESSED 0x100 /* R: page referenced */
+#define _PAGE_HWWRITE 0x200 /* software: _PAGE_RW & _PAGE_DIRTY */
-#define _PAGE_TABLE (_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED | _PAGE_DIRTY)
#define _PAGE_CHG_MASK (PAGE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY)
#define PAGE_NONE __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED)
-#define PAGE_SHARED __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED)
-#define PAGE_COPY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_COW)
+#define PAGE_SHARED __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | \
+ _PAGE_ACCESSED)
+#define PAGE_COPY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
#define PAGE_READONLY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
-#define PAGE_KERNEL __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED)
-#define PAGE_KERNEL_NO_CACHE __pgprot(_PAGE_NO_CACHE | _PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED)
+#define PAGE_KERNEL __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | \
+ _PAGE_HWWRITE | _PAGE_ACCESSED)
+#define PAGE_KERNEL_CI __pgprot(_PAGE_PRESENT | _PAGE_NO_CACHE | _PAGE_RW | \
+ _PAGE_HWWRITE | _PAGE_DIRTY | _PAGE_ACCESSED)
/*
- * The i386 can't do page protection for execute, and considers that the same are read.
- * Also, write permissions imply read permissions. This is the closest we can get..
+ * The PowerPC can only do execute protection on a segment (256MB) basis,
+ * not on a page basis. So we consider execute permission the same as read.
+ * Also, write permissions imply read permissions.
+ * This is the closest we can get..
*/
#define __P000 PAGE_NONE
#define __P001 PAGE_READONLY
@@ -96,18 +106,6 @@ inline void really_flush_cache_all(void);
#define __S111 PAGE_SHARED
/*
- * Define this if things work differently on a i386 and a i486:
- * it will (on a i486) warn about kernel memory accesses that are
- * done without a 'verify_area(VERIFY_WRITE,..)'
- */
-#undef CONFIG_TEST_VERIFY_AREA
-
-#if 0
-/* page table for 0-4MB for everybody */
-extern unsigned long pg0[1024];
-#endif
-
-/*
* BAD_PAGETABLE is used when we need a bogus page-table, while
* BAD_PAGE is used for a bogus page.
*
@@ -119,49 +117,36 @@ extern pte_t * __bad_pagetable(void);
extern unsigned long empty_zero_page[1024];
-#define BAD_PAGETABLE __bad_pagetable()
-#define BAD_PAGE __bad_page()
-#define ZERO_PAGE ((unsigned long) empty_zero_page)
+#define BAD_PAGETABLE __bad_pagetable()
+#define BAD_PAGE __bad_page()
+#define ZERO_PAGE ((unsigned long) empty_zero_page)
/* number of bits that fit into a memory pointer */
-#define BITS_PER_PTR (8*sizeof(unsigned long))
+#define BITS_PER_PTR (8*sizeof(unsigned long))
/* to align the pointer to a pointer address */
-#define PTR_MASK (~(sizeof(void*)-1))
+#define PTR_MASK (~(sizeof(void*)-1))
-/* sizeof(void*)==1<<SIZEOF_PTR_LOG2 */
+/* sizeof(void*) == 1<<SIZEOF_PTR_LOG2 */
/* 64-bit machines, beware! SRB. */
-#define SIZEOF_PTR_LOG2 2
-
-/* to find an entry in a page-table */
-#define PAGE_PTR(address) \
-((unsigned long)(address)>>(PAGE_SHIFT-SIZEOF_PTR_LOG2)&PTR_MASK&~PAGE_MASK)
+#define SIZEOF_PTR_LOG2 2
/* to set the page-dir */
/* tsk is a task_struct and pgdir is a pte_t */
-#define SET_PAGE_DIR(tsk,pgdir) \
-do { \
- (tsk)->tss.pg_tables = (unsigned long *)(pgdir); \
- if ((tsk) == current) \
- { \
-/*_printk("Change page tables = %x\n", pgdir);*/ \
- } \
-} while (0)
-
-/* comes from include/linux/mm.h now -- Cort */
-/*extern void *high_memory;*/
+#define SET_PAGE_DIR(tsk,pgdir) ({ \
+ ((tsk)->tss.pg_tables = (unsigned long *)(pgdir)); \
+})
extern inline int pte_none(pte_t pte) { return !pte_val(pte); }
extern inline int pte_present(pte_t pte) { return pte_val(pte) & _PAGE_PRESENT; }
extern inline void pte_clear(pte_t *ptep) { pte_val(*ptep) = 0; }
extern inline int pmd_none(pmd_t pmd) { return !pmd_val(pmd); }
-extern inline int pmd_bad(pmd_t pmd) { return (pmd_val(pmd) & ~PAGE_MASK) != _PAGE_TABLE; }
-extern inline int pmd_present(pmd_t pmd) { return pmd_val(pmd) & _PAGE_PRESENT; }
-extern inline int pmd_inuse(pmd_t *pmdp) { return 0; }
+extern inline int pmd_bad(pmd_t pmd) { return (pmd_val(pmd) & ~PAGE_MASK) != 0; }
+extern inline int pmd_present(pmd_t pmd) { return (pmd_val(pmd) & PAGE_MASK) != 0; }
extern inline void pmd_clear(pmd_t * pmdp) { pmd_val(*pmdp) = 0; }
-extern inline void pmd_reuse(pmd_t * pmdp) { }
+
/*
* The "pgd_xxx()" functions here are trivial for a folded two-level
* setup: the pgd is never bad, and a pmd always exists (as it's folded
@@ -172,7 +157,6 @@ extern inline int pgd_bad(pgd_t pgd) { return 0; }
extern inline int pgd_present(pgd_t pgd) { return 1; }
extern inline void pgd_clear(pgd_t * pgdp) { }
-
/*
* The following only work if pte_present() is true.
* Undefined behaviour if not..
@@ -182,48 +166,82 @@ extern inline int pte_write(pte_t pte) { return pte_val(pte) & _PAGE_RW; }
extern inline int pte_exec(pte_t pte) { return pte_val(pte) & _PAGE_USER; }
extern inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; }
extern inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; }
-extern inline int pte_cow(pte_t pte) { return pte_val(pte) & _PAGE_COW; }
-
-extern inline pte_t pte_wrprotect(pte_t pte) { pte_val(pte) &= ~_PAGE_RW; return pte; }
-extern inline pte_t pte_rdprotect(pte_t pte) { pte_val(pte) &= ~_PAGE_USER; return pte; }
-extern inline pte_t pte_exprotect(pte_t pte) { pte_val(pte) &= ~_PAGE_USER; return pte; }
-extern inline pte_t pte_mkclean(pte_t pte) { pte_val(pte) &= ~_PAGE_DIRTY; return pte; }
-extern inline pte_t pte_mkold(pte_t pte) { pte_val(pte) &= ~_PAGE_ACCESSED; return pte; }
-extern inline pte_t pte_uncow(pte_t pte) { pte_val(pte) &= ~_PAGE_COW; return pte; }
-extern inline pte_t pte_mkwrite(pte_t pte) { pte_val(pte) |= _PAGE_RW; return pte; }
-extern inline pte_t pte_mkread(pte_t pte) { pte_val(pte) |= _PAGE_USER; return pte; }
-extern inline pte_t pte_mkexec(pte_t pte) { pte_val(pte) |= _PAGE_USER; return pte; }
-extern inline pte_t pte_mkdirty(pte_t pte) { pte_val(pte) |= _PAGE_DIRTY; return pte; }
-extern inline pte_t pte_mkyoung(pte_t pte) { pte_val(pte) |= _PAGE_ACCESSED; return pte; }
-extern inline pte_t pte_mkcow(pte_t pte) { pte_val(pte) |= _PAGE_COW; return pte; }
-/*
- * Conversion functions: convert a page and protection to a page entry,
- * and a page entry and page directory to the page they refer to.
- */
+extern inline int pte_uncache(pte_t pte) { return pte_val(pte) |= _PAGE_NO_CACHE; }
+extern inline int pte_cache(pte_t pte) { return pte_val(pte) &= ~_PAGE_NO_CACHE; }
+
+extern inline pte_t pte_rdprotect(pte_t pte) {
+ pte_val(pte) &= ~_PAGE_USER; return pte; }
+extern inline pte_t pte_exprotect(pte_t pte) {
+ pte_val(pte) &= ~_PAGE_USER; return pte; }
+extern inline pte_t pte_wrprotect(pte_t pte) {
+ pte_val(pte) &= ~(_PAGE_RW | _PAGE_HWWRITE); return pte; }
+extern inline pte_t pte_mkclean(pte_t pte) {
+ pte_val(pte) &= ~(_PAGE_DIRTY | _PAGE_HWWRITE); return pte; }
+extern inline pte_t pte_mkold(pte_t pte) {
+ pte_val(pte) &= ~_PAGE_ACCESSED; return pte; }
+
+extern inline pte_t pte_mkread(pte_t pte) {
+ pte_val(pte) |= _PAGE_USER; return pte; }
+extern inline pte_t pte_mkexec(pte_t pte) {
+ pte_val(pte) |= _PAGE_USER; return pte; }
+extern inline pte_t pte_mkwrite(pte_t pte)
+{
+ pte_val(pte) |= _PAGE_RW;
+ if (pte_val(pte) & _PAGE_DIRTY)
+ pte_val(pte) |= _PAGE_HWWRITE;
+ return pte;
+}
+extern inline pte_t pte_mkdirty(pte_t pte)
+{
+ pte_val(pte) |= _PAGE_DIRTY;
+ if (pte_val(pte) & _PAGE_RW)
+ pte_val(pte) |= _PAGE_HWWRITE;
+ return pte;
+}
+extern inline pte_t pte_mkyoung(pte_t pte) {
+ pte_val(pte) |= _PAGE_ACCESSED; return pte; }
/* Certain architectures need to do special things when pte's
* within a page table are directly modified. Thus, the following
* hook is made available.
*/
-#define set_pte(pteptr, pteval) ((*(pteptr)) = (pteval))
+#if 1
+#define set_pte(pteptr, pteval) ((*(pteptr)) = (pteval))
+#else
+extern inline void set_pte(pte_t *pteptr, pte_t pteval)
+{
+ unsigned long val = pte_val(pteval);
+ extern void xmon(void *);
+
+ if ((val & _PAGE_PRESENT) && ((val < 0x111000 || (val & 0x800)
+ || ((val & _PAGE_HWWRITE) && (~val & (_PAGE_RW|_PAGE_DIRTY)))) {
+ printk("bad pte val %lx ptr=%p\n", val, pteptr);
+ xmon(0);
+ }
+ *pteptr = pteval;
+}
+#endif
-static pte_t mk_pte_phys(unsigned long page, pgprot_t pgprot)
+/*
+ * Conversion functions: convert a page and protection to a page entry,
+ * and a page entry and page directory to the page they refer to.
+ */
+
+static inline pte_t mk_pte_phys(unsigned long page, pgprot_t pgprot)
{ pte_t pte; pte_val(pte) = (page) | pgprot_val(pgprot); return pte; }
-/*#define mk_pte_phys(physpage, pgprot) \
-({ pte_t __pte; pte_val(__pte) = physpage + pgprot_val(pgprot); __pte; })*/
extern inline pte_t mk_pte(unsigned long page, pgprot_t pgprot)
-{ pte_t pte; pte_val(pte) = page | pgprot_val(pgprot); return pte; }
+{ pte_t pte; pte_val(pte) = __pa(page) | pgprot_val(pgprot); return pte; }
extern inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
{ pte_val(pte) = (pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot); return pte; }
extern inline unsigned long pte_page(pte_t pte)
-{ return pte_val(pte) & PAGE_MASK; }
+{ return (pte_val(pte) & PAGE_MASK) + KERNELBASE; }
extern inline unsigned long pmd_page(pmd_t pmd)
-{ return pmd_val(pmd) & PAGE_MASK; }
+{ return pmd_val(pmd); }
/* to find an entry in a kernel page-table-directory */
@@ -250,13 +268,14 @@ extern inline pte_t * pte_offset(pmd_t * dir, unsigned long address)
/*
* Allocate and free page tables. The xxx_kernel() versions are
- * used to allocate a kernel page table - this turns on ASN bits
- * if any, and marks the page tables reserved.
+ * used to allocate a kernel page table, but are actually identical
+ * to the xxx() versions.
*/
extern inline void pte_free_kernel(pte_t * pte)
{
free_page((unsigned long) pte);
}
+
extern inline pte_t * pte_alloc_kernel(pmd_t * pmd, unsigned long address)
{
address = (address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1);
@@ -264,20 +283,17 @@ extern inline pte_t * pte_alloc_kernel(pmd_t * pmd, unsigned long address)
pte_t * page = (pte_t *) get_free_page(GFP_KERNEL);
if (pmd_none(*pmd)) {
if (page) {
-/* pmd_set(pmd,page);*/
- pmd_val(*pmd) = _PAGE_TABLE | (unsigned long) page;
+ pmd_val(*pmd) = (unsigned long) page;
return page + address;
}
-/* pmd_set(pmd, BAD_PAGETABLE);*/
- pmd_val(*pmd) = _PAGE_TABLE | (unsigned long) BAD_PAGETABLE;
+ pmd_val(*pmd) = (unsigned long) BAD_PAGETABLE;
return NULL;
}
free_page((unsigned long) page);
}
if (pmd_bad(*pmd)) {
printk("Bad pmd in pte_alloc: %08lx\n", pmd_val(*pmd));
-/* pmd_set(pmd, (pte_t *) BAD_PAGETABLE); */
- pmd_val(*pmd) = _PAGE_TABLE | (unsigned long) BAD_PAGETABLE;
+ pmd_val(*pmd) = (unsigned long) BAD_PAGETABLE;
return NULL;
}
return (pte_t *) pmd_page(*pmd) + address;
@@ -308,17 +324,17 @@ extern inline pte_t * pte_alloc(pmd_t * pmd, unsigned long address)
pte_t * page = (pte_t *) get_free_page(GFP_KERNEL);
if (pmd_none(*pmd)) {
if (page) {
- pmd_val(*pmd) = _PAGE_TABLE | (unsigned long) page;
+ pmd_val(*pmd) = (unsigned long) page;
return page + address;
}
- pmd_val(*pmd) = _PAGE_TABLE | (unsigned long) BAD_PAGETABLE;
+ pmd_val(*pmd) = (unsigned long) BAD_PAGETABLE;
return NULL;
}
free_page((unsigned long) page);
}
if (pmd_bad(*pmd)) {
printk("Bad pmd in pte_alloc: %08lx\n", pmd_val(*pmd));
- pmd_val(*pmd) = _PAGE_TABLE | (unsigned long) BAD_PAGETABLE;
+ pmd_val(*pmd) = (unsigned long) BAD_PAGETABLE;
return NULL;
}
return (pte_t *) pmd_page(*pmd) + address;
@@ -350,18 +366,17 @@ extern inline pgd_t * pgd_alloc(void)
extern pgd_t swapper_pg_dir[1024];
/*
- * Software maintained MMU tables may have changed -- update the
- * hardware [aka cache]
+ * Page tables may have changed. We don't need to do anything here
+ * as entries are faulted into the hash table by the low-level
+ * data/instruction access exception handlers.
*/
-extern inline void update_mmu_cache(struct vm_area_struct * vma,
- unsigned long address, pte_t _pte);
+#define update_mmu_cache(vma,address,pte) while(0){}
#define SWP_TYPE(entry) (((entry) >> 1) & 0x7f)
#define SWP_OFFSET(entry) ((entry) >> 8)
#define SWP_ENTRY(type,offset) (((type) << 1) | ((offset) << 8))
-#define module_map vmalloc
-#define module_unmap vfree
+
#endif /* _PPC_PAGE_H */
diff --git a/include/asm-ppc/ppc_machine.h b/include/asm-ppc/ppc_machine.h
index 1cf9a7930..e69de29bb 100644
--- a/include/asm-ppc/ppc_machine.h
+++ b/include/asm-ppc/ppc_machine.h
@@ -1,56 +0,0 @@
-/*
- * PowerPC machine specifics
- */
-
-#ifndef _PPC_MACHINE_H_
-#define _PPC_MACHINE_H_
-
-#define KERNEL_STACK_SIZE (4096) /* usable stack -- not buffers at either end */
-#define KERNEL_STACK_MASK (~(KERNEL_STACK_SIZE-1))
-
-/* Bit encodings for Machine State Register (MSR) */
-#define MSR_POW (1<<18) /* Enable Power Management */
-#define MSR_TGPR (1<<17) /* TLB Update registers in use */
-#define MSR_ILE (1<<16) /* Interrupt Little-Endian enable */
-#define MSR_EE (1<<15) /* External Interrupt enable */
-#define MSR_PR (1<<14) /* Supervisor/User privilege */
-#define MSR_FP (1<<13) /* Floating Point enable */
-#define MSR_ME (1<<12) /* Machine Check enable */
-#define MSR_FE0 (1<<11) /* Floating Exception mode 0 */
-#define MSR_SE (1<<10) /* Single Step */
-#define MSR_BE (1<<9) /* Branch Trace */
-#define MSR_FE1 (1<<8) /* Floating Exception mode 1 */
-#define MSR_IP (1<<6) /* Exception prefix 0x000/0xFFF */
-#define MSR_IR (1<<5) /* Instruction MMU enable */
-#define MSR_DR (1<<4) /* Data MMU enable */
-#define MSR_RI (1<<1) /* Recoverable Exception */
-#define MSR_LE (1<<0) /* Little-Endian enable */
-
-#define MSR_ MSR_FE0|MSR_FE1|MSR_ME|MSR_FP
-#define MSR_USER MSR_FE0|MSR_FE1|MSR_ME|MSR_PR|MSR_EE|MSR_IR|MSR_DR
-
-/* Bit encodings for Hardware Implementation Register (HID0) */
-#define HID0_EMCP (1<<31) /* Enable Machine Check pin */
-#define HID0_EBA (1<<29) /* Enable Bus Address Parity */
-#define HID0_EBD (1<<28) /* Enable Bus Data Parity */
-#define HID0_SBCLK (1<<27)
-#define HID0_EICE (1<<26)
-#define HID0_ECLK (1<<25)
-#define HID0_PAR (1<<24)
-#define HID0_DOZE (1<<23)
-#define HID0_NAP (1<<22)
-#define HID0_SLEEP (1<<21)
-#define HID0_DPM (1<<20)
-#define HID0_ICE (1<<15) /* Instruction Cache Enable */
-#define HID0_DCE (1<<14) /* Data Cache Enable */
-#define HID0_ILOCK (1<<13) /* Instruction Cache Lock */
-#define HID0_DLOCK (1<<12) /* Data Cache Lock */
-#define HID0_ICFI (1<<11) /* Instruction Cache Flash Invalidate */
-#define HID0_DCI (1<<10) /* Data Cache Invalidate */
-#define HID0_SIED (1<<7) /* Serial Instruction Execution [Disable] */
-#define HID0_BHTE (1<<2) /* Branch History Table Enable */
-
-/* fpscr settings */
-#define FPSCR_FX (1<<31)
-#define FPSCR_FEX (1<<30)
-#endif
diff --git a/include/asm-ppc/processor.h b/include/asm-ppc/processor.h
index e3c715c0d..1e6baf0a6 100644
--- a/include/asm-ppc/processor.h
+++ b/include/asm-ppc/processor.h
@@ -1,12 +1,8 @@
#ifndef __ASM_PPC_PROCESSOR_H
#define __ASM_PPC_PROCESSOR_H
-/*
- * PowerPC machine specifics
- */
+#include <linux/config.h>
-#define KERNEL_STACK_SIZE (4096) /* usable stack -- not buffers at either end */
-#define KERNEL_STACK_MASK (~(KERNEL_STACK_SIZE-1))
/* Bit encodings for Machine State Register (MSR) */
#define MSR_POW (1<<18) /* Enable Power Management */
@@ -26,7 +22,8 @@
#define MSR_RI (1<<1) /* Recoverable Exception */
#define MSR_LE (1<<0) /* Little-Endian enable */
-#define MSR_ MSR_FE0|MSR_FE1|MSR_ME|MSR_FP
+#define MSR_ MSR_FE0|MSR_FE1|MSR_ME
+#define MSR_KERNEL MSR_|MSR_IR|MSR_DR
#define MSR_USER MSR_FE0|MSR_FE1|MSR_ME|MSR_PR|MSR_EE|MSR_IR|MSR_DR
/* Bit encodings for Hardware Implementation Register (HID0) */
@@ -49,20 +46,16 @@
#define HID0_DCI (1<<10) /* Data Cache Invalidate */
#define HID0_SIED (1<<7) /* Serial Instruction Execution [Disable] */
#define HID0_BHTE (1<<2) /* Branch History Table Enable */
-
/* fpscr settings */
#define FPSCR_FX (1<<31)
#define FPSCR_FEX (1<<30)
-
-
#ifndef __ASSEMBLY__
/*
* PowerPC machine specifics
*/
extern inline void start_thread(struct pt_regs *, unsigned long, unsigned long );
-
/*
* Bus types
*/
@@ -77,82 +70,86 @@ extern inline void start_thread(struct pt_regs *, unsigned long, unsigned long )
#define wp_works_ok 1
#define wp_works_ok__is_a_macro /* for versions in ksyms.c */
-/*
- * User space process size: 2GB. This is hardcoded into a few places,
- * so don't change it unless you know what you are doing.
- *
- * "this is gonna have to change to 1gig for the sparc" - David S. Miller
- */
#define TASK_SIZE (0x80000000UL)
-
/* This decides where the kernel will search for a free chunk of vm
* space during mmap's.
*/
#define TASK_UNMAPPED_BASE (TASK_SIZE / 3)
-
struct thread_struct
{
- unsigned long ksp; /* Kernel stack pointer */
- unsigned long *pg_tables; /* MMU information */
- unsigned long segs[16]; /* MMU Segment registers */
- unsigned long last_pc; /* PC when last entered system */
- unsigned long user_stack; /* [User] Stack when entered kernel */
- double fpr[32]; /* Complete floating point set */
- unsigned long wchan; /* Event task is sleeping on */
- unsigned long *regs; /* Pointer to saved register state */
- unsigned long fp_used; /* number of quantums fp was used */
- unsigned long fs; /* for get_fs() validation */
- unsigned long expc; /* exception handler addr (see fault.c) */
- unsigned long excount; /* exception handler count */
+ unsigned long ksp; /* Kernel stack pointer */
+ unsigned long *pg_tables; /* MMU information */
+#ifdef CONFIG_PMAC
+ unsigned long last_pc; /* PC when last entered system */
+ unsigned long user_stack; /* [User] Stack when entered kernel */
+#endif
+ unsigned long fpscr_pad; /* (so we can save fpscr with stfd) */
+ unsigned long fpscr; /* fp status reg */
+ double fpr[32]; /* Complete floating point set */
+ unsigned long fp_used;
+ unsigned long wchan; /* Event task is sleeping on */
+ struct pt_regs *regs; /* Pointer to saved register state */
+ unsigned long fs; /* for get_fs() validation */
+ signed long last_syscall;
+ unsigned long pad[2]; /* pad to 16-byte boundry */
};
+/* Points to the thread_struct of the thread (if any) which
+ currently owns the FPU. */
+#define fpu_tss (&(last_task_used_math->tss))
+
+#ifdef CONFIG_PMAC
+#define LAZY_TSS_FPR_INIT 0,0,0,0,{0},
+#endif
+#ifdef CONFIG_PREP
+#define LAZY_TSS_FPR_INIT 0,0,{0},
+#endif
#define INIT_TSS { \
- sizeof(init_kernel_stack) + (long) &init_kernel_stack,\
- (long *)swapper_pg_dir, {0}, \
- 0, 0, {0}, \
- 0, 0, 0, \
- KERNEL_DS, 0, 0 \
+ sizeof(init_stack) + (long) &init_stack, /* ksp */ \
+ (long *)swapper_pg_dir, /* pg_tables */ \
+ LAZY_TSS_FPR_INIT \
+ 0, /*fp_used*/ 0, /*wchan*/ \
+ sizeof(init_stack) + (long)&init_stack - \
+ sizeof(struct pt_regs), /* regs */ \
+ KERNEL_DS /*fs*/, 0 /*last_syscall*/ \
}
-#define INIT_MMAP { &init_mm, 0, 0x40000000, \
- PAGE_SHARED, VM_READ | VM_WRITE | VM_EXEC, NULL, &init_mm.mmap }
-
-/* Free all resources held by a thread. */
-extern void release_thread(struct task_struct *);
+#define INIT_MMAP { &init_mm, KERNELBASE/*0*/, 0xffffffff/*0x40000000*/, \
+ PAGE_SHARED, VM_READ | VM_WRITE | VM_EXEC }
/*
* Return saved PC of a blocked thread. For now, this is the "user" PC
*/
static inline unsigned long thread_saved_pc(struct thread_struct *t)
{
- return (t->last_pc);
+ return (t->regs) ? t->regs->nip : 0;
+ /*return (t->last_pc);*/
}
-#define _PROC_Motorola 0
-#define _PROC_IBM 1
-#define _PROC_Be 2
-
-int _Processor;
+extern int _machine;
+#define _MACH_Motorola 0
+#define _MACH_IBM 1
+#define _MACH_Be 2
+#define _MACH_Pmac 3
-/* Allocation and freeing of basic task resources. */
-#define alloc_task_struct() kmalloc(sizeof(struct task_struct), GFP_KERNEL)
-#define free_task_struct(p) kfree(p)
-
-#ifdef KERNEL_STACK_BUFFER
-/* give a 1 page buffer below the stack - if change then change ppc_machine.h */
-#define alloc_kernel_stack() \
- (memset((void *)__get_free_pages(GFP_KERNEL,1,0),0,KERNEL_STACK_SIZE+PAGE_SIZE)+PAGE_SIZE)
-#define free_kernel_stack(page) free_pages((page)-PAGE_SIZE,1)
-#else
-#define alloc_kernel_stack() get_free_page(GFP_KERNEL)
-#define free_kernel_stack(page) free_page((page))
-#endif
+/*
+ * NOTE! The task struct and the stack go together
+ */
+#define alloc_task_struct() \
+ ((struct task_struct *) __get_free_pages(GFP_KERNEL,1,0))
+#define free_task_struct(p) free_pages((unsigned long)(p),1)
-#endif /* ASSEMBLY*/
+/* in process.c - for early bootup debug -- Cort */
+int ll_printk(const char *, ...);
+void ll_puts(const char *);
-/*
+#endif /* ndef ASSEMBLY*/
* Return_address is a replacement for __builtin_return_address(count)
+#define init_task (init_task_union.task)
+#define init_stack (init_task_union.stack)
+
+#endif /* __ASM_PPC_PROCESSOR_H */
* which on certain architectures cannot reasonably be implemented in GCC
* (MIPS, Alpha) or is unuseable with -fomit-frame-pointer (i386).
* Note that __builtin_return_address(x>=1) is forbidden because the GCC
diff --git a/include/asm-ppc/ptrace.h b/include/asm-ppc/ptrace.h
index 5bad3b9da..13b526172 100644
--- a/include/asm-ppc/ptrace.h
+++ b/include/asm-ppc/ptrace.h
@@ -2,54 +2,61 @@
#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.
- * Note: the "_overhead" and "_underhead" spaces are stack locations
- * used by called routines. Because of the way the PowerPC ABI
- * specifies the function prologue/epilogue, registers can be
- * saved in stack locations which are below the current stack
- * pointer (_underhead). If an interrupt occurs during this
- * [albeit] small time interval, registers which were saved on
- * the stack could be trashed by the interrupt save code. The
- * "_underhead" leaves a hole just in case this happens. It also
- * wastes 80 bytes of stack if it doesn't! Similarly, the called
- * routine stores some information "above" the stack pointer before
- * if gets adjusted. This is covered by the "_overhead" field
- * and [thankfully] is not totally wasted.
+ * this should only contain volatile regs
+ * since we can keep non-volatile in the tss
+ * should set this up when only volatiles are saved
+ * by intr code.
*
+ * I can't find any reference to the above comment (from Gary Thomas)
+ * about _underhead/_overhead in the sys V abi for the ppc
+ * dated july 25, 1994.
+ *
+ * the stack must be kept to a size that is a multiple of 16
+ * so this includes the stack frame overhead
+ * -- Cort.
+ */
+
+/*
+ * GCC sometimes accesses words at negative offsets from the stack
+ * pointer, although the SysV ABI says it shouldn't. To cope with
+ * this, we leave this much untouched space on the stack on exception
+ * entry.
*/
+#define STACK_FRAME_OVERHEAD 16
+#define STACK_UNDERHEAD 64
+#ifndef __ASSEMBLY__
struct pt_regs {
- unsigned long _overhead[14]; /* Callee's SP,LR,params */
- unsigned long gpr[32];
- unsigned long nip;
- unsigned long msr;
- unsigned long ctr;
- unsigned long link;
- unsigned long ccr;
- unsigned long xer;
- unsigned long dar; /* Fault registers */
- unsigned long dsisr;
- unsigned long srr1;
- unsigned long srr0;
- unsigned long hash1, hash2;
- unsigned long imiss, dmiss;
- unsigned long icmp, dcmp;
- unsigned long orig_gpr3; /* Used for restarting system calls */
- unsigned long result; /* Result of a system call */
- double fpcsr;
- unsigned long trap; /* Reason for being here */
- unsigned long marker; /* Should have DEADDEAD */
- /*unsigned long _underhead[20]; *//* Callee's register save area */
- unsigned long edx; /* for binfmt_elf.c which wants edx */
+ unsigned long gpr[32];
+ unsigned long nip;
+ unsigned long msr;
+ unsigned long ctr;
+ unsigned long link;
+ unsigned long ccr;
+ unsigned long xer;
+ unsigned long dar; /* Fault registers */
+ unsigned long dsisr;
+#if 0
+ unsigned long srr1;
+ unsigned long srr0;
+ unsigned long hash1, hash2;
+ unsigned long imiss, dmiss;
+ unsigned long icmp, dcmp;
+#endif
+ unsigned long orig_gpr3; /* Used for restarting system calls */
+ unsigned long result; /* Result of a system call */
+ unsigned long trap; /* Reason for being here */
+ unsigned long marker; /* Should have DEADDEAD */
};
+
#define instruction_pointer(regs) ((regs)->nip)
#define user_mode(regs) ((regs)->msr & 0x4000)
#ifdef KERNEL
extern void show_regs(struct pt_regs *);
#endif
+/* should include and generate these in ppc_defs.h -- Cort */
/* Offsets used by 'ptrace' system call interface */
/* Note: these should correspond to gpr[x] */
#define PT_R0 0
@@ -94,6 +101,7 @@ extern void show_regs(struct pt_regs *);
#define PT_CCR 38
#define PT_FPR0 48
+#endif /* __ASSEMBLY__ */
-#endif
+#endif /* _PPC_PTRACE_H */
diff --git a/include/asm-ppc/semaphore.h b/include/asm-ppc/semaphore.h
index 4d1f91372..a4dfa0312 100644
--- a/include/asm-ppc/semaphore.h
+++ b/include/asm-ppc/semaphore.h
@@ -1,11 +1,18 @@
#ifndef _PPC_SEMAPHORE_H
#define _PPC_SEMAPHORE_H
+/*
+ * SMP- and interrupt-safe semaphores..
+ *
+ * (C) Copyright 1996 Linus Torvalds
+ * Adapted for PowerPC by Gary Thomas and Paul Mackerras
+ */
+
#include <asm/atomic.h>
struct semaphore {
atomic_t count;
- atomic_t waiting;
+ atomic_t waking;
struct wait_queue * wait;
};
@@ -13,44 +20,61 @@ struct semaphore {
#define MUTEX_LOCKED ((struct semaphore) { ATOMIC_INIT(0), ATOMIC_INIT(0), NULL })
extern void __down(struct semaphore * sem);
+extern int __down_interruptible(struct semaphore * sem);
extern void __up(struct semaphore * sem);
-extern void atomic_add(int c, int *v);
-extern void atomic_sub(int c, int *v);
+#define sema_init(sem, val) atomic_set(&((sem)->count), (val))
+
+/*
+ * These two _must_ execute atomically wrt each other.
+ *
+ * This is trivially done with load_locked/store_cond,
+ * i.e. load with reservation and store conditional on the ppc.
+ */
-#define sema_init(sem, val) atomic_set(&((sem)->count), val)
+static inline void wake_one_more(struct semaphore * sem)
+{
+ atomic_inc(&sem->waking);
+}
static inline int waking_non_zero(struct semaphore *sem)
{
- unsigned long flags;
- int ret = 0;
+ int ret, tmp;
+
+ __asm__ __volatile__(
+ "1: lwarx %1,0,%2\n"
+ " cmpwi 0,%1,0\n"
+ " addi %1,%1,-1\n"
+ " ble- 2f\n"
+ " stwcx. %1,0,%2\n"
+ " bne- 1b\n"
+ " mr %0,%1\n"
+ "2:"
+ : "=r" (ret), "=r" (tmp)
+ : "r" (&sem->waking), "0" (0)
+ : "cr0", "memory");
- save_flags(flags);
- cli();
- if (atomic_read(&sem->waking) > 0) {
- atomic_dec(&sem->waking);
- ret = 1;
- }
- restore_flags(flags);
return ret;
}
extern inline void down(struct semaphore * sem)
{
- for (;;)
- {
- atomic_dec_return(&sem->count);
- if ( sem->count >= 0)
- break;
- __down(sem);
- }
+ if (atomic_dec_return(&sem->count) < 0)
+ __down(sem);
+}
+
+extern inline int down_interruptible(struct semaphore * sem)
+{
+ int ret = 0;
+ if (atomic_dec_return(&sem->count) < 0)
+ ret = __down_interruptible(sem);
+ return ret;
}
extern inline void up(struct semaphore * sem)
{
- atomic_inc_return(&sem->count);
- if ( sem->count <= 0)
- __up(sem);
+ if (atomic_inc_return(&sem->count) <= 0)
+ __up(sem);
}
#endif /* !(_PPC_SEMAPHORE_H) */
diff --git a/include/asm-ppc/smp.h b/include/asm-ppc/smp.h
index 00a1e7c9a..7f54dd779 100644
--- a/include/asm-ppc/smp.h
+++ b/include/asm-ppc/smp.h
@@ -19,7 +19,7 @@ struct cpuinfo_PPC {
};
extern struct cpuinfo_PPC cpu_data[NR_CPUS];
-
+#endif /* __ASSEMBLY__ */
#endif /* !(__SMP__) */
diff --git a/include/asm-ppc/socket.h b/include/asm-ppc/socket.h
index d09474696..632717509 100644
--- a/include/asm-ppc/socket.h
+++ b/include/asm-ppc/socket.h
@@ -26,15 +26,12 @@
#define SO_PRIORITY 12
#define SO_LINGER 13
#define SO_BSDCOMPAT 14
-/* To add :#define SO_REUSEPORT 14 */
+/* To add :#define SO_REUSEPORT 15 */
#define SO_RCVLOWAT 16
#define SO_SNDLOWAT 17
#define SO_RCVTIMEO 18
#define SO_SNDTIMEO 19
-
-/* Security levels - as per NRL IPv6 - don't actually do anything */
-#define SO_SECURITY_AUTHENTICATION 20
-#define SO_SECURITY_ENCRYPTION_TRANSPORT 21
-#define SO_SECURITY_ENCRYPTION_NETWORK 22
+#define SO_PASSCRED 20
+#define SO_PEERCRED 21
#endif /* _ASM_SOCKET_H */
diff --git a/include/asm-ppc/string.h b/include/asm-ppc/string.h
index 66243582e..207ab3689 100644
--- a/include/asm-ppc/string.h
+++ b/include/asm-ppc/string.h
@@ -1,26 +1,27 @@
#ifndef _PPC_STRING_H_
#define _PPC_STRING_H_
-
-
-/*
- * keep things happy, the compile became unhappy since memset is
- * in include/linux/string.h and lib/string.c with different prototypes
- * -- Cort
- */
-#if 1
-#define __HAVE_ARCH_MEMSET
-extern __inline__ void * memset(void * s,int c,__kernel_size_t count)
+#define __HAVE_ARCH_STRCPY
+#define __HAVE_ARCH_STRNCPY
+#define __HAVE_ARCH_STRLEN
+#define __HAVE_ARCH_STRCMP
+#define __HAVE_ARCH_STRCAT
+#define __HAVE_ARCH_MEMSET
+#define __HAVE_ARCH_BCOPY
+#define __HAVE_ARCH_MEMCPY
+#define __HAVE_ARCH_MEMMOVE
+#define __HAVE_ARCH_MEMCMP
+#define __HAVE_ARCH_MEMCHR
+/*#define bzero(addr,size) memset((addr),(int)(0),(size))*/
+extern inline void * memchr(const void * cs,int c,size_t count)
{
- char *xs = (char *) s;
-
- while (count--)
- *xs++ = c;
-
- return s;
+ unsigned long i = 0;
+ while ( count != i )
+ {
+ if ( (char)c == *(char *)(cs + i) )
+ return (void *)(cs + i);
+ i--;
+ }
+ return NULL;
}
#endif
-#define bzero(addr,size) memset((addr),(int)(0),(size))
-
-
-#endif
diff --git a/include/asm-ppc/system.h b/include/asm-ppc/system.h
index a1a3f12a0..df527e474 100644
--- a/include/asm-ppc/system.h
+++ b/include/asm-ppc/system.h
@@ -1,27 +1,66 @@
#ifndef __PPC_SYSTEM_H
#define __PPC_SYSTEM_H
-#if 0
-#define mb() \
-__asm__ __volatile__("mb": : :"memory")
-#endif
-#define mb() __asm__ __volatile__ ("" : : :"memory")
+#include <linux/delay.h>
+
+#define mb() __asm__ __volatile__ ("sync" : : : "memory")
+
+#define __save_flags(flags) ({\
+ __asm__ __volatile__ ("mfmsr %0" : "=r" ((flags)) : : "memory"); })
+/* using Paul's in misc.S now -- Cort */
+extern void __restore_flags(unsigned long flags);
+/*
+ #define __sti() _soft_sti(void)
+ #define __cli() _soft_cli(void)
+ */
+extern void __sti(void);
+extern void __cli(void);
-extern void __save_flags(long *flags);
-extern void __restore_flags(long flags);
-extern void sti(void);
-extern void cli(void);
+extern void _hard_sti(void);
+extern void _hard_cli(void);
+extern void _soft_sti(void);
+extern void _soft_cli(void);
extern int _disable_interrupts(void);
extern void _enable_interrupts(int);
-/*extern void memcpy(void *, void *, int);*/
+extern void flush_instruction_cache(void);
+extern void hard_reset_now(void);
+extern void poweroff_now(void);
+extern void find_scsi_boot(void);
+extern int sd_find_target(void *, int);
+extern int _get_PVR(void);
+extern void via_cuda_init(void);
+extern void read_rtc_time(void);
+extern void pmac_find_display(void);
+extern void giveup_fpu(void);
+extern void store_cache_range(unsigned long, unsigned long);
+extern void cvt_fd(float *from, double *to);
+extern void cvt_df(double *from, float *to);
+
+struct device_node;
+extern void note_scsi_host(struct device_node *, void *);
struct task_struct;
extern void switch_to(struct task_struct *prev, struct task_struct *next);
-#define save_flags(flags) __save_flags(&(flags))
-#define restore_flags(flags) __restore_flags(flags)
+struct thread_struct;
+extern void _switch(struct thread_struct *prev, struct thread_struct *next,
+ unsigned long context);
+
+struct pt_regs;
+extern int do_signal(unsigned long oldmask, struct pt_regs *regs);
+extern void dump_regs(struct pt_regs *);
+
+#ifndef __SMP__
+#define cli() __cli()
+#define sti() __sti()
+#define save_flags(flags) __save_flags(flags)
+#define restore_flags(flags) __restore_flags(flags)
+
+#else
+#error need global cli/sti etc. defined for SMP
+#endif
#define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
diff --git a/include/asm-ppc/termbits.h b/include/asm-ppc/termbits.h
index 6c19c1fef..65cab0612 100644
--- a/include/asm-ppc/termbits.h
+++ b/include/asm-ppc/termbits.h
@@ -7,7 +7,6 @@ typedef unsigned char cc_t;
typedef unsigned int speed_t;
typedef unsigned int tcflag_t;
-#if 0 /* This is how it's done on Alpha - maybe later. */
/*
* termios type and macro definitions. Be careful about adding stuff
* to this file since it's used in GNU libc and there are strict rules
@@ -27,23 +26,24 @@ struct termios {
};
/* c_cc characters */
-#define VEOF 0
-#define VEOL 1
-#define VEOL2 2
-#define VERASE 3
-#define VWERASE 4
-#define VKILL 5
-#define VREPRINT 6
-#define VSWTC 7
-#define VINTR 8
-#define VQUIT 9
-#define VSUSP 10
-#define VSTART 12
-#define VSTOP 13
-#define VLNEXT 14
-#define VDISCARD 15
-#define VMIN 16
-#define VTIME 17
+#define VINTR 0
+#define VQUIT 1
+#define VERASE 2
+#define VKILL 3
+#define VEOF 4
+#define VMIN 5
+#define VEOL 6
+#define VTIME 7
+#define VEOL2 8
+#define VSWTC 9
+
+#define VWERASE 10
+#define VREPRINT 11
+#define VSUSP 12
+#define VSTART 13
+#define VSTOP 14
+#define VLNEXT 15
+#define VDISCARD 16
/* c_iflag bits */
#define IGNBRK 0000001
@@ -57,7 +57,7 @@ struct termios {
#define ICRNL 0000400
#define IXON 0001000
#define IXOFF 0002000
-#if !defined(KERNEL) || defined(__USE_BSD)
+#if defined(__KERNEL__) || defined(__USE_BSD)
/* POSIX.1 doesn't want these... */
# define IXANY 0004000
# define IUCLC 0010000
@@ -102,7 +102,7 @@ struct termios {
#define XTABS 01000000 /* Hmm.. Linux/i386 considers this part of TABDLY.. */
/* c_cflag bit meaning */
-#define CBAUD 0000017
+#define CBAUD 0000377
#define B0 0000000 /* hang up */
#define B50 0000001
#define B75 0000002
@@ -173,6 +173,5 @@ struct termios {
#define TCSANOW 0
#define TCSADRAIN 1
#define TCSAFLUSH 2
-#endif
#endif /* _PPC_TERMBITS_H */
diff --git a/include/asm-ppc/termios.h b/include/asm-ppc/termios.h
index 26d88027f..b5e8c78df 100644
--- a/include/asm-ppc/termios.h
+++ b/include/asm-ppc/termios.h
@@ -137,18 +137,6 @@ struct termio {
unsigned char c_cc[NCC]; /* control characters */
};
-#define NCCS 19
-struct termios {
- tcflag_t c_iflag; /* input mode flags */
- tcflag_t c_oflag; /* output mode flags */
- tcflag_t c_cflag; /* control mode flags */
- tcflag_t c_lflag; /* local mode flags */
- cc_t c_cc[NCCS]; /* control characters */
- cc_t c_line; /* line discipline (== c_cc[19]) */
- int c_ispeed; /* input speed */
- int c_ospeed; /* output speed */
-};
-
/* c_cc characters */
#define _VINTR 0
#define _VQUIT 1
@@ -161,150 +149,11 @@ struct termios {
#define _VEOL2 8
#define _VSWTC 9
-#define VINTR 0
-#define VQUIT 1
-#define VERASE 2
-#define VKILL 3
-#define VEOF 4
-#define VMIN 5
-#define VEOL 6
-#define VTIME 7
-#define VEOL2 8
-#define VSWTC 9
-
-#define VWERASE 10
-#define VREPRINT 11
-#define VSUSP 12
-#define VSTART 13
-#define VSTOP 14
-#define VLNEXT 15
-#define VDISCARD 16
-
-
#ifdef __KERNEL__
-/* eof=^D eol=\0 eol2=\0 erase=del
- werase=^W kill=^U reprint=^R sxtc=\0
- intr=^C quit=^\ susp=^Z <OSF/1 VDSUSP>
- start=^Q stop=^S lnext=^V discard=^U
- vmin=\1 vtime=\0
-#define INIT_C_CC "\004\000\000\177\027\025\022\000\003\034\032\000\021\023\026\025\001\000"
-*/
-
/* ^C ^\ del ^U ^D 1 0 0 0 0 ^W ^R ^Z ^Q ^S ^V ^U */
#define INIT_C_CC "\003\034\177\025\004\001\000\000\000\000\027\022\032\021\023\026\025"
#endif
-/* c_iflag bits */
-#define IGNBRK 0000001
-#define BRKINT 0000002
-#define IGNPAR 0000004
-#define PARMRK 0000010
-#define INPCK 0000020
-#define ISTRIP 0000040
-#define INLCR 0000100
-#define IGNCR 0000200
-#define ICRNL 0000400
-#define IXON 0001000
-#define IXOFF 0002000
-#define IXANY 0004000
-#define IUCLC 0010000
-#define IMAXBEL 0020000
-
-/* c_oflag bits */
-#define OPOST 0000001
-#define ONLCR 0000002
-#define OLCUC 0000004
-
-#define OCRNL 0000010
-#define ONOCR 0000020
-#define ONLRET 0000040
-
-#define OFILL 00000100
-#define OFDEL 00000200
-#define NLDLY 00001400
-#define NL0 00000000
-#define NL1 00000400
-#define NL2 00001000
-#define NL3 00001400
-#define TABDLY 00006000
-#define TAB0 00000000
-#define TAB1 00002000
-#define TAB2 00004000
-#define TAB3 00006000
-#define CRDLY 00030000
-#define CR0 00000000
-#define CR1 00010000
-#define CR2 00020000
-#define CR3 00030000
-#define FFDLY 00040000
-#define FF0 00000000
-#define FF1 00040000
-#define BSDLY 00100000
-#define BS0 00000000
-#define BS1 00100000
-#define VTDLY 00200000
-#define VT0 00000000
-#define VT1 00200000
-#define XTABS 01000000 /* Hmm.. Linux/i386 considers this part of TABDLY.. */
-
-/* c_cflag bit meaning */
-#define CBAUD 0000377
-#define B0 0000000 /* hang up */
-#define B50 0000001
-#define B75 0000002
-#define B110 0000003
-#define B134 0000004
-#define B150 0000005
-#define B200 0000006
-#define B300 0000007
-#define B600 0000010
-#define B1200 0000011
-#define B1800 0000012
-#define B2400 0000013
-#define B4800 0000014
-#define B9600 0000015
-#define B19200 0000016
-#define B38400 0000017
-#define EXTA B19200
-#define EXTB B38400
-#define CBAUDEX 0000020
-#define B57600 00020
-#define B115200 00021
-#define B230400 00022
-#define B460800 00023
-
-#define CSIZE 00001400
-#define CS5 00000000
-#define CS6 00000400
-#define CS7 00001000
-#define CS8 00001400
-
-#define CSTOPB 00002000
-#define CREAD 00004000
-#define PARENB 00010000
-#define PARODD 00020000
-#define HUPCL 00040000
-
-#define CLOCAL 00100000
-#define CRTSCTS 020000000000 /* flow control */
-
-/* c_lflag bits */
-#define ISIG 0x00000080
-#define ICANON 0x00000100
-#define XCASE 0x00004000
-#define ECHO 0x00000008
-#define ECHOE 0x00000002
-#define ECHOK 0x00000004
-#define ECHONL 0x00000010
-#define NOFLSH 0x80000000
-#define TOSTOP 0x00400000
-#define ECHOCTL 0x00000040
-#define ECHOPRT 0x00000020
-#define ECHOKE 0x00000001
-#define FLUSHO 0x00800000
-#define PENDIN 0x20000000
-#define IEXTEN 0x00000400
-
/* modem lines */
#define TIOCM_LE 0x001
#define TIOCM_DTR 0x002
@@ -321,23 +170,6 @@ struct termios {
/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
#define TIOCSER_TEMT 0x01 /* Transmitter physically empty */
-
-/* tcflow() and TCXONC use these */
-#define TCOOFF 0
-#define TCOON 1
-#define TCIOFF 2
-#define TCION 3
-
-/* tcflush() and TCFLSH use these */
-#define TCIFLUSH 0
-#define TCOFLUSH 1
-#define TCIOFLUSH 2
-
-/* tcsetattr uses these */
-#define TCSANOW 0
-#define TCSADRAIN 1
-#define TCSAFLUSH 2
-
/* line disciplines */
#define N_TTY 0
#define N_SLIP 1
@@ -349,55 +181,33 @@ struct termios {
/*
* 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) \
-do { \
- unsigned short tmp; \
- get_user(tmp, &(termio)->c_iflag); \
- (termios)->c_iflag = (0xffff0000 & ((termios)->c_iflag)) | tmp; \
- get_user(tmp, &(termio)->c_oflag); \
- (termios)->c_oflag = (0xffff0000 & ((termios)->c_oflag)) | tmp; \
- get_user(tmp, &(termio)->c_cflag); \
- (termios)->c_cflag = (0xffff0000 & ((termios)->c_cflag)) | tmp; \
- get_user(tmp, &(termio)->c_lflag); \
- (termios)->c_lflag = (0xffff0000 & ((termios)->c_lflag)) | tmp; \
- get_user((termios)->c_line, &(termio)->c_line); \
- get_user((termios)->c_cc[VINTR], &(termio)->c_cc[_VINTR]); \
- get_user((termios)->c_cc[VQUIT], &(termio)->c_cc[_VQUIT]); \
- get_user((termios)->c_cc[VERASE], &(termio)->c_cc[_VERASE]); \
- get_user((termios)->c_cc[VKILL], &(termio)->c_cc[_VKILL]); \
- get_user((termios)->c_cc[VEOF], &(termio)->c_cc[_VEOF]); \
- get_user((termios)->c_cc[VMIN], &(termio)->c_cc[_VMIN]); \
- get_user((termios)->c_cc[VEOL], &(termio)->c_cc[_VEOL]); \
- get_user((termios)->c_cc[VTIME], &(termio)->c_cc[_VTIME]); \
- get_user((termios)->c_cc[VEOL2], &(termio)->c_cc[_VEOL2]); \
- get_user((termios)->c_cc[VSWTC], &(termio)->c_cc[_VSWTC]); \
-} while(0)
+({ \
+ 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.
- *
- * Note the "fun" _VMIN overloading.
*/
#define kernel_termios_to_user_termio(termio, termios) \
-do { \
+({ \
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); \
- put_user((termios)->c_cc[VINTR], &(termio)->c_cc[_VINTR]); \
- put_user((termios)->c_cc[VQUIT], &(termio)->c_cc[_VQUIT]); \
- put_user((termios)->c_cc[VERASE], &(termio)->c_cc[_VERASE]); \
- put_user((termios)->c_cc[VKILL], &(termio)->c_cc[_VKILL]); \
- put_user((termios)->c_cc[VEOF], &(termio)->c_cc[_VEOF]); \
- put_user((termios)->c_cc[VEOL], &(termio)->c_cc[_VEOL]); \
- put_user((termios)->c_cc[VEOL2], &(termio)->c_cc[_VEOL2]); \
- put_user((termios)->c_cc[VSWTC], &(termio)->c_cc[_VSWTC]); \
- if (1/*!((termios)->c_lflag & ICANON)*/) { \
- put_user((termios)->c_cc[VMIN], &(termio)->c_cc[_VMIN]); \
- put_user((termios)->c_cc[VTIME], &(termio)->c_cc[_VTIME]); \
- } \
-} while(0)
+ 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))
diff --git a/include/asm-ppc/uaccess.h b/include/asm-ppc/uaccess.h
index 927447dbd..b1e19ef1f 100644
--- a/include/asm-ppc/uaccess.h
+++ b/include/asm-ppc/uaccess.h
@@ -1,22 +1,30 @@
-#ifndef _ASM_UACCESS_H
-#define _ASM_UACCESS_H
+#ifndef _PPC_UACCESS_H
+#define _PPC_UACCESS_H
#ifndef __ASSEMBLY__
#include <linux/sched.h>
#include <linux/errno.h>
-#define KERNEL_DS (0)
-#define USER_DS (1)
-
#define VERIFY_READ 0
#define VERIFY_WRITE 1
-#define get_fs() (current->tss.fs)
-#define get_ds() (KERNEL_DS)
-#define set_fs(val) ( current->tss.fs = (val))
+/*
+ * The fs value determines whether argument validity checking should be
+ * performed or not. If get_fs() == USER_DS, checking is performed, with
+ * get_fs() == KERNEL_DS, checking is bypassed.
+ *
+ * For historical reasons, these macros are grossly misnamed.
+ */
+
+#define KERNEL_DS (0)
+#define USER_DS (1)
+
+#define get_fs() (current->tss.fs)
+#define get_ds() (KERNEL_DS)
+#define set_fs(val) (current->tss.fs = (val))
#define __user_ok(addr,size) (((size) <= 0x80000000)&&((addr) <= 0x80000000-(size)))
-#define __kernel_ok (get_fs() == KERNEL_DS)
+#define __kernel_ok (get_fs() == KERNEL_DS)
#define __access_ok(addr,size) (__kernel_ok || __user_ok((addr),(size)))
#define access_ok(type,addr,size) __access_ok((unsigned long)(addr),(size))
@@ -25,126 +33,227 @@ extern inline int verify_area(int type, const void * addr, unsigned long size)
return access_ok(type,addr,size) ? 0 : -EFAULT;
}
+
+/*
+ * 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.
*
- * As the powerpc uses the same address space for kernel and user
- * data, we can just do these as direct assignments. (Of course, the
- * exception handling means that it's no longer "just"...)
+ * 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 uglyness 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).
*
- * Careful to not
- * (a) re-use the arguments for side effects (sizeof/typeof is ok)
- * (b) require any knowledge of processes at this stage
+ * 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)))
+
/*
- * The "__xxx" versions do not do address space checking, useful when
- * doing multiple accesses to the same area (the programmer has to do the
- * checks by hand with "access_ok()")
+ * The "xxx_ret" versions return constant specified in third argument, if
+ * something bad happens. These macros can be optimized for the
+ * case of just returning from the function xxx_ret is used.
*/
-#define put_user(x,ptr) ({ \
-unsigned long __pu_addr = (unsigned long)(ptr); \
-__put_user_check((__typeof__(*(ptr)))(x),__pu_addr,sizeof(*(ptr))); })
-#define get_user(x,ptr) ({ \
-unsigned long __gu_addr = (unsigned long)(ptr); \
-__get_user_check((x),__gu_addr,sizeof(*(ptr)),__typeof__(*(ptr))); })
+#define put_user_ret(x,ptr,ret) ({ \
+if (put_user(x,ptr)) return ret; })
+
+#define get_user_ret(x,ptr,ret) ({ \
+if (get_user(x,ptr)) return ret; })
+
+#define __put_user_ret(x,ptr,ret) ({ \
+if (__put_user(x,ptr)) return ret; })
+
+#define __get_user_ret(x,ptr,ret) ({ \
+if (__get_user(x,ptr)) return ret; })
+
+
+extern long __put_user_bad(void);
+
+#define __put_user_nocheck(x,ptr,size) \
+({ \
+ long __pu_err; \
+ __put_user_size((x),(ptr),(size),__pu_err); \
+ __pu_err; \
+})
+
+#define __put_user_check(x,ptr,size) \
+({ \
+ long __pu_err = -EFAULT; \
+ __typeof__(*(ptr)) *__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; \
+ default: __put_user_bad(); \
+ } \
+} while (0)
-#define __put_user(x,ptr) __put_user_nocheck((x),(ptr),sizeof(*(ptr)))
-#define __get_user(x,ptr) __get_user_nocheck((x),(ptr),sizeof(*(ptr)),__typeof__(*(ptr)))
struct __large_struct { unsigned long buf[100]; };
-#define __m(x) ((struct __large_struct *)(x))
-
-#define __put_user_check(x,addr,size) ({ \
-int __pu_ret; \
-__pu_ret = -EFAULT; \
-if (__access_ok(addr,size)) { \
-switch (size) { \
-case 1: __pu_ret =__put_user_8(x,addr); break; \
-case 2: __pu_ret =__put_user_16(x,addr); break; \
-case 4: __pu_ret =__put_user_32(x,addr); break; \
-default: __pu_ret = __put_user_bad(); break; \
-} } __pu_ret; })
-
-#define __put_user_nocheck(x,addr,size) ({ \
-int __pu_ret; \
-__pu_ret = -EFAULT; \
-switch (size) { \
-case 1: __pu_ret =__put_user_8(x,addr); break; \
-case 2: __pu_ret =__put_user_16(x,addr); break; \
-case 4: __pu_ret =__put_user_32(x,addr); break; \
-default: __pu_ret = __put_user_bad(); break; \
-} __pu_ret; })
-
-extern int __put_user_bad(void);
-
-#define __get_user_check(x,addr,size,type) ({ \
-register int __gu_ret asm("r4"); \
-unsigned long __gu_val = 0; \
-__gu_ret = -EFAULT; \
-if (__access_ok(addr,size)) { \
-switch (size) { \
-case 1: __gu_val = __get_user_8(__gu_val,addr); break; \
-case 2: __gu_val = __get_user_16(__gu_val,addr); break; \
-case 4: __gu_val = __get_user_32(__gu_val,addr); break; \
-default: __get_user_bad(); break; \
-} } (x) = (type) __gu_val; __gu_ret; })
-
-#define __get_user_nocheck(x,addr,size,type) ({ \
-register int __gu_ret asm("r4"); \
-unsigned long __gu_val = 0; \
-__gu_ret = -EFAULT; \
-switch (size) { \
-case 1: __gu_val =__get_user_8(__gu_val,addr); break; \
-case 2: __gu_val =__get_user_16(__gu_val,addr); break; \
-case 4: __gu_val =__get_user_32(__gu_val,addr); break; \
-default: __gu_val = __get_user_bad(); break; \
-} (x) = (type) __gu_val; __gu_ret; })
-
+#define __m(x) (*(struct __large_struct *)(x))
+
+/*
+ * 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" \
+ ".section __ex_table,\"a\"\n" \
+ " .align 2\n" \
+ " .long 1b,3b\n" \
+ ".text" \
+ : "=r"(err) \
+ : "r"(x), "b"(addr), "i"(-EFAULT), "0"(err))
+
+
+#define __get_user_nocheck(x,ptr,size) \
+({ \
+ long __gu_err, __gu_val; \
+ __get_user_size(__gu_val,(ptr),(size),__gu_err); \
+ (x) = (__typeof__(*(ptr)))__gu_val; \
+ __gu_err; \
+})
+
+#define __get_user_check(x,ptr,size) \
+({ \
+ long __gu_err = -EFAULT, __gu_val = 0; \
+ const __typeof__(*(ptr)) *__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; \
+})
+
+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_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" \
+ ".section __ex_table,\"a\"\n" \
+ " .align 2\n" \
+ " .long 1b,3b\n" \
+ ".text" \
+ : "=r"(err), "=r"(x) \
+ : "b"(addr), "i"(-EFAULT), "0"(err))
/* more complex routines */
-extern int __copy_tofrom_user(unsigned long to, unsigned long from, int size);
-
-#define copy_to_user(to,from,n) ({ \
-unsigned long __copy_to = (unsigned long) (to); \
-unsigned long __copy_size = (unsigned long) (n); \
-unsigned long __copy_res = -EFAULT; \
-if(__copy_size && __access_ok(__copy_to, __copy_size)) { \
-__copy_res = __copy_tofrom_user(__copy_to, (unsigned long) (from), __copy_size); \
-} \
-__copy_res; })
-
-#define copy_from_user(to,from,n) ({ \
-unsigned long __copy_from = (unsigned long) (from); \
-unsigned long __copy_size = (unsigned long) (n); \
-unsigned long __copy_res = -EFAULT; \
-if(__copy_size && __access_ok(__copy_from, __copy_size)) { \
-__copy_res = __copy_tofrom_user((unsigned long) (to), __copy_from, __copy_size); \
-} \
-__copy_res; })
-
-extern int __clear_user(unsigned long addr, int size);
-
-#define clear_user(addr,n) ({ \
-unsigned long __clear_addr = (unsigned long) (addr); \
-int __clear_size = (int) (n); \
-int __clear_res = -EFAULT; \
-if(__clear_size && __access_ok(__clear_addr, __clear_size)) { \
-__clear_res = __clear_user(__clear_addr, __clear_size); \
-} \
-__clear_res; })
-
-extern int __strncpy_from_user(unsigned long dest, unsigned long src, int count);
-
-#define strncpy_from_user(dest,src,count) ({ \
-unsigned long __sfu_src = (unsigned long) (src); \
-int __sfu_count = (int) (count); \
-long __sfu_res = -EFAULT; \
-if(__access_ok(__sfu_src, __sfu_count)) { \
-__sfu_res = __strncpy_from_user((unsigned long) (dest), __sfu_src, __sfu_count); \
-} __sfu_res; })
+extern int __copy_tofrom_user(void *to, const void *from, unsigned long size);
+
+extern inline unsigned long
+copy_from_user(void *to, const void *from, unsigned long n)
+{
+ if (access_ok(VERIFY_READ, from, n))
+ return __copy_tofrom_user(to, from, n);
+ return n? -EFAULT: 0;
+}
+
+extern inline unsigned long
+copy_to_user(void *to, const void *from, unsigned long n)
+{
+ if (access_ok(VERIFY_WRITE, to, n))
+ return __copy_tofrom_user(to, from, n);
+ return n? -EFAULT: 0;
+}
+
+#define __copy_from_user(to, from, size) \
+ __copy_tofrom_user((to), (from), (size))
+#define __copy_to_user(to, from, size) \
+ __copy_tofrom_user((to), (from), (size))
+
+extern unsigned long __clear_user(void *addr, unsigned long size);
+
+extern inline unsigned long
+clear_user(void *addr, unsigned long size)
+{
+ if (access_ok(VERIFY_WRITE, addr, size))
+ return __clear_user(addr, size);
+ return size? -EFAULT: 0;
+}
+
+extern int __strncpy_from_user(char *dst, const char *src, long count);
+
+extern inline long
+strncpy_from_user(char *dst, const char *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 long strlen_user(const char *);
#endif /* __ASSEMBLY__ */
-#endif /* _ASM_UACCESS_H */
+#endif /* _PPC_UACCESS_H */
diff --git a/include/asm-ppc/unistd.h b/include/asm-ppc/unistd.h
index 47b0a7912..5665d906c 100644
--- a/include/asm-ppc/unistd.h
+++ b/include/asm-ppc/unistd.h
@@ -1,10 +1,6 @@
-/* * Last edited: Nov 17 16:28 1995 (cort) */
#ifndef _ASM_PPC_UNISTD_H_
#define _ASM_PPC_UNISTD_H_
-#define _NR(n) #n
-#define _lisc(n) "li 0," _NR(n)
-
/*
* This file contains the system call numbers.
*/
@@ -175,180 +171,79 @@
#define __NR_mremap 163
#define __NR_setresuid 164
#define __NR_getresuid 165
-#define __NR_nfsservctl 166
+#define __NR_query_module 166
+#define __NR_poll 167
+#define __NR_nfsservctl 168
+
+#define __NR(n) #n
+#define __do_syscall(n) \
+ asm volatile ("li 0,%0\n\
+ sc\n\
+ bns 1f\n\
+ mr 0,3\n\
+ lis 3,errno@ha\n\
+ stw 0,errno@l(3)\n\
+ li 3,-1\n\
+1:" : : "i" (n) : "r0", "r3")
-/* XXX - _foo needs to be __foo, while __NR_bar could be _NR_bar. */
#define _syscall0(type,name) \
type name(void) \
-{ \
- __asm__ (_lisc(__NR_##name)); \
- __asm__ ("sc"); \
- __asm__ ("mr 31,3"); \
- __asm__ ("bns 10f"); \
- __asm__ ("mr 0,3"); \
- __asm__ ("lis 3,errno@ha"); \
- __asm__ ("stw 0,errno@l(3)"); \
- __asm__ ("li 3,-1"); \
- __asm__ ("10:"); \
-}
-
+{ __do_syscall(__NR_##name); }
#define _syscall1(type,name,type1,arg1) \
type name(type1 arg1) \
-{ \
- __asm__ (_lisc(__NR_##name)); \
- __asm__ ("sc"); \
- __asm__ ("mr 31,3"); \
- __asm__ ("bns 10f"); \
- __asm__ ("mr 0,3"); \
- __asm__ ("lis 3,errno@ha"); \
- __asm__ ("stw 0,errno@l(3)"); \
- __asm__ ("li 3,-1"); \
- __asm__ ("10:"); \
-}
-
+{ __do_syscall(__NR_##name); }
#define _syscall2(type,name,type1,arg1,type2,arg2) \
type name(type1 arg1,type2 arg2) \
-{ \
- __asm__ (_lisc(__NR_##name)); \
- __asm__ ("sc"); \
- __asm__ ("mr 31,3"); \
- __asm__ ("bns 10f"); \
- __asm__ ("mr 0,3"); \
- __asm__ ("lis 3,errno@ha"); \
- __asm__ ("stw 0,errno@l(3)"); \
- __asm__ ("li 3,-1"); \
- __asm__ ("10:"); \
-}
-
+{ __do_syscall(__NR_##name); }
#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
type name(type1 arg1,type2 arg2,type3 arg3) \
-{ \
- __asm__ (_lisc(__NR_##name)); \
- __asm__ ("sc"); \
- __asm__ ("mr 31,3"); \
- __asm__ ("bns 10f"); \
- __asm__ ("mr 0,3"); \
- __asm__ ("lis 3,errno@ha"); \
- __asm__ ("stw 0,errno@l(3)"); \
- __asm__ ("li 3,-1"); \
- __asm__ ("10:"); \
-}
-
+{ __do_syscall(__NR_##name); }
#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4) \
-{ \
- __asm__ (_lisc(__NR_##name)); \
- __asm__ ("sc"); \
- __asm__ ("mr 31,3"); \
- __asm__ ("bns 10f"); \
- __asm__ ("mr 0,3"); \
- __asm__ ("lis 3,errno@ha"); \
- __asm__ ("stw 0,errno@l(3)"); \
- __asm__ ("li 3,-1"); \
- __asm__ ("10:"); \
-}
-
+{ __do_syscall(__NR_##name); }
#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
type5,arg5) \
type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \
-{ \
- __asm__ (_lisc(__NR_##name)); \
- __asm__ ("sc"); \
- __asm__ ("mr 31,3"); \
- __asm__ ("bns 10f"); \
- __asm__ ("mr 0,3"); \
- __asm__ ("lis 3,errno@ha"); \
- __asm__ ("stw 0,errno@l(3)"); \
- __asm__ ("li 3,-1"); \
- __asm__ ("10:"); \
-}
+{ __do_syscall(__NR_##name); }
#ifdef __KERNEL_SYSCALLS__
/*
- * we need this inline - forking from kernel space will result
- * in NO COPY ON WRITE (!!!), until an execve is executed. This
- * is no problem, but for the stack. This is handled by not letting
- * main() use the stack at all after fork(). Thus, no function
- * calls - which means inline code for fork too, as otherwise we
- * would use the stack upon exit from 'fork()'.
- *
- * Actually only pause and fork are needed inline, so that there
- * won't be any messing with the stack from main(), but we define
- * some others too.
+ * Forking from kernel space will result in NO COPY ON WRITE (!!!),
+ * until an execve is executed. This is no problem, but for the stack.
+ * This is handled by not letting main() use the stack at all after
+ * fork(). On the PowerPC, this means we can only call leaf functions.
*/
-
-#if 0
/*
- This is the mechanism for creating a new kernel thread.
- For the time being it only behaves the same as clone().
- It should be changed very soon to work properly and cleanly. This
- gets us going for now, though.
-
- some versions of gcc hate this -- complains about constraints being
- incorrect. not sure why so it's in arch/ppc/kernel/misc.S now.
- -- Cort
+ * Create a new kernel thread.
*/
-static __inline__ long kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
-{
- long retval;
- __asm__ (
- "li 0, 120 \n\t" /* __NR_clone */
- "li 3, %5 \n\t" /* load flags as arg to clone */
- /*"mr 1,7 \n\t"*/ /* save kernel stack */
- "sc \n\t" /* syscall */
- /*"cmp 0,1,7 \n\t"*/ /* if kernel stack changes -- child */
- "cmpi 0,3,0 \n\t"
- "bne 1f \n\t" /* return if parent */
- /* this is in child */
- "li 3, %3 \n\t" /* child -- load args and call fn */
- "mtlr %4 \n\t"
- "blrl \n\t"
- "li 0, %2 \n\t" /* exit after child exits */
- "li 3, 0 \n\t"
- "sc \n\t"
- /* parent */
- "1: \n\t"
- :"=3" (retval)
- :"i" (__NR_clone), "i" (__NR_exit),
- "r" (arg), "r" (fn), "g" (CLONE_VM|flags)
- :"cc", "1", "0", "3", "7", "31", "memory" );
- return retval;
-}
-#else
extern long __kernel_thread(unsigned long, int (*)(void *), void *);
static inline long kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
{
return __kernel_thread(flags | CLONE_VM, fn, arg);
}
-#endif
-#define __NR__exit __NR_exit
-static inline _syscall0(int,idle) /* made inline "just in case" -- Cort */
-static inline _syscall0(int,fork) /* needs to be inline */
-static inline _syscall0(int,pause) /* needs to be inline */
-static inline _syscall1(int,setup,int,magic) /* called in init before execve */
-static inline _syscall0(int,sync)
-static inline _syscall0(pid_t,setsid)
-static /*inline*/ _syscall3(int,write,int,fd,const char *,buf,off_t,count)
-static /*inline*/ _syscall1(int,dup,int,fd)
-static /*inline*/ _syscall3(int,execve,const char *,file,char **,argv,char **,envp)
-static /*inline*/ _syscall3(int,open,const char *,file,int,flag,int,mode)
-static /*inline*/ _syscall1(int,close,int,fd)
-static /*inline*/ _syscall1(int,_exit,int,exitcode)
-static inline _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options)
-static inline _syscall2(int,clone,unsigned long,flags,char *,esp)
+/*
+ * System call prototypes.
+ */
+int idle(void);
+int setup(int);
+int sync(void);
+pid_t setsid(void);
+int write(int, const char *, off_t);
+int dup(int);
+int execve(const char *, char **, char **);
+int open(const char *, int, int);
+int close(int);
+pid_t waitpid(pid_t, int *, int);
-/* called from init before execve -- need to be inline? -- Cort */
static inline pid_t wait(int * wait_stat)
{
return waitpid(-1,wait_stat,0);
}
-#endif
+#endif /* __KERNEL_SYSCALLS__ */
#endif /* _ASM_PPC_UNISTD_H_ */
-
-
diff --git a/include/asm-sparc/fbio.h b/include/asm-sparc/fbio.h
index 7c4ba26e4..6d2f1e730 100644
--- a/include/asm-sparc/fbio.h
+++ b/include/asm-sparc/fbio.h
@@ -48,7 +48,6 @@ struct fbtype {
};
#define FBIOGTYPE _IOR('F', 0, struct fbtype)
-/* Used by FBIOPUTCMAP */
struct fbcmap {
int index; /* first element (0 origin) */
int count;
@@ -150,6 +149,21 @@ struct fb_wid_list {
#define FBIO_WID_PUT _IOW('F', 32, struct fb_wid_list)
#define FBIO_WID_GET _IOWR('F', 33, struct fb_wid_list)
+/* Creator ioctls */
+#define FFB_IOCTL ('F'<<8)
+#define FFB_SYS_INFO (FFB_IOCTL|80)
+#define FFB_CLUTREAD (FFB_IOCTL|81)
+#define FFB_CLUTPOST (FFB_IOCTL|82)
+#define FFB_SETDIAGMODE (FFB_IOCTL|83)
+#define FFB_GETMONITORID (FFB_IOCTL|84)
+#define FFB_GETVIDEOMODE (FFB_IOCTL|85)
+#define FFB_SETVIDEOMODE (FFB_IOCTL|86)
+#define FFB_SETSERVER (FFB_IOCTL|87)
+#define FFB_SETOVCTL (FFB_IOCTL|88)
+#define FFB_GETOVCTL (FFB_IOCTL|89)
+#define FFB_GETSAXNUM (FFB_IOCTL|90)
+#define FFB_FBDEBUG (FFB_IOCTL|91)
+
/* Cg14 ioctls */
#define MDI_IOCTL ('M'<<8)
#define MDI_RESET (MDI_IOCTL|1)
@@ -174,15 +188,15 @@ struct mdi_cfginfo {
*/
#define MDI_CLEAR_XLUT (MDI_IOCTL|9)
-/* leo ioctls */
-struct leo_clut_alloc {
+/* leo & ffb ioctls */
+struct fb_clut_alloc {
__u32 clutid; /* Set on return */
__u32 flag;
__u32 index;
};
-struct leo_clut {
-#define LEO_CLUT_WAIT 0x00000001 /* Not yet implemented */
+struct fb_clut {
+#define FB_CLUT_WAIT 0x00000001 /* Not yet implemented */
__u32 flag;
__u32 clutid;
__u32 offset;
@@ -191,10 +205,21 @@ struct leo_clut {
char * green;
char * blue;
};
-#define LEO_CLUTALLOC _IOWR('L', 53, struct leo_clut_alloc)
-#define LEO_CLUTFREE _IOW('L', 54, struct leo_clut_alloc)
-#define LEO_CLUTREAD _IOW('L', 55, struct leo_clut)
-#define LEO_CLUTPOST _IOW('L', 56, struct leo_clut)
+
+struct fb_clut32 {
+ __u32 flag;
+ __u32 clutid;
+ __u32 offset;
+ __u32 count;
+ __u32 red;
+ __u32 green;
+ __u32 blue;
+};
+
+#define LEO_CLUTALLOC _IOWR('L', 53, struct fb_clut_alloc)
+#define LEO_CLUTFREE _IOW('L', 54, struct fb_clut_alloc)
+#define LEO_CLUTREAD _IOW('L', 55, struct fb_clut)
+#define LEO_CLUTPOST _IOW('L', 56, struct fb_clut)
#define LEO_SETGAMMA _IOW('L', 68, int) /* Not yet implemented */
#define LEO_GETGAMMA _IOR('L', 69, int) /* Not yet implemented */
diff --git a/include/asm-sparc/smp.h b/include/asm-sparc/smp.h
index 106fa4e1b..62a97ed40 100644
--- a/include/asm-sparc/smp.h
+++ b/include/asm-sparc/smp.h
@@ -6,6 +6,8 @@
#ifndef _SPARC_SMP_H
#define _SPARC_SMP_H
+#include <asm/head.h>
+
#ifndef __ASSEMBLY__
/* PROM provided per-processor information we need
* to start them all up.
diff --git a/include/asm-sparc64/oplib.h b/include/asm-sparc64/oplib.h
index 577f3c877..6b2852c29 100644
--- a/include/asm-sparc64/oplib.h
+++ b/include/asm-sparc64/oplib.h
@@ -1,4 +1,4 @@
-/* $Id: oplib.h,v 1.7 1997/04/03 09:29:25 davem Exp $
+/* $Id: oplib.h,v 1.8 1997/07/24 12:15:15 davem Exp $
* oplib.h: Describes the interface and available routines in the
* Linux Prom library.
*
@@ -179,8 +179,7 @@ extern enum prom_output_device prom_query_output_device(void);
/* Start the CPU with the given device tree node, context table, and context
* at the passed program counter.
*/
-extern int prom_startcpu(int cpunode, struct linux_prom_registers *context_table,
- int context, char *program_counter);
+extern void prom_startcpu(int cpunode, unsigned long pc, unsigned long o0);
/* Stop the CPU with the passed device tree node. */
extern int prom_stopcpu(int cpunode);
diff --git a/include/asm-sparc64/pgtable.h b/include/asm-sparc64/pgtable.h
index 5cbd9a3c5..5d31b3bf5 100644
--- a/include/asm-sparc64/pgtable.h
+++ b/include/asm-sparc64/pgtable.h
@@ -1,4 +1,4 @@
-/* $Id: pgtable.h,v 1.49 1997/06/30 09:24:12 jj Exp $
+/* $Id: pgtable.h,v 1.50 1997/07/24 16:48:31 davem Exp $
* pgtable.h: SpitFire page table operations.
*
* Copyright 1996,1997 David S. Miller (davem@caip.rutgers.edu)
@@ -158,33 +158,33 @@ extern void *sparc_init_alloc(unsigned long *kbrk, unsigned long size);
/* Cache and TLB flush operations. */
-#define flush_cache_all() \
-do { unsigned long va; \
- flushw_all(); \
- for(va = 0; \
- va<(PAGE_SIZE<<1); \
- va += 32) \
-spitfire_put_icache_tag(va,0x0);\
-} while(0)
-
+/* These are the same regardless of whether this is an SMP kernel or not. */
#define flush_cache_mm(mm) do { } while(0)
#define flush_cache_range(mm, start, end) do { } while(0)
#define flush_cache_page(vma, page) do { } while(0)
/* This operation in unnecessary on the SpitFire since D-CACHE is write-through. */
-#define flush_page_to_ram(page) do { } while (0)
+#define flush_page_to_ram(page) do { } while (0)
-extern void flush_tlb_all(void);
+extern void __flush_cache_all(void);
+extern void __flush_tlb_all(void);
extern void __flush_tlb_mm(unsigned long context);
+extern void __flush_tlb_range(unsigned long context, unsigned long start,
+ unsigned long end);
+extern void __flush_tlb_page(unsigned long context, unsigned long page);
+
+#ifndef __SMP__
+
+#define flush_cache_all() __flush_cache_all()
+#define flush_tlb_all() __flush_tlb_all()
+
extern __inline__ void flush_tlb_mm(struct mm_struct *mm)
{
if(mm->context != NO_CONTEXT)
__flush_tlb_mm(mm->context & 0x1fff);
}
-extern void __flush_tlb_range(unsigned long context, unsigned long start,
- unsigned long end);
extern __inline__ void flush_tlb_range(struct mm_struct *mm, unsigned long start,
unsigned long end)
{
@@ -192,7 +192,6 @@ extern __inline__ void flush_tlb_range(struct mm_struct *mm, unsigned long start
__flush_tlb_range(mm->context & 0x1fff, start, end);
}
-extern void __flush_tlb_page(unsigned long context, unsigned long page);
extern __inline__ void flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
{
struct mm_struct *mm = vma->vm_mm;
@@ -201,6 +200,41 @@ extern __inline__ void flush_tlb_page(struct vm_area_struct *vma, unsigned long
__flush_tlb_page(mm->context & 0x1fff, page & PAGE_MASK);
}
+#else /* __SMP__ */
+
+extern void smp_flush_cache_all(void);
+extern void smp_flush_tlb_all(void);
+extern void smp_flush_tlb_mm(struct mm_struct *mm);
+extern void smp_flush_tlb_range(struct mm_struct *mm, unsigned long start,
+ unsigned long end);
+extern void smp_flush_tlb_page(struct vm_area_struct *vma, unsigned long page);
+
+#define flush_cache_all() smp_flush_cache_all()
+#define flush_tlb_all() smp_flush_tlb_all()
+
+extern __inline__ void flush_tlb_mm(struct mm_struct *mm)
+{
+ if(mm->context != NO_CONTEXT)
+ smp_flush_tlb_mm(mm);
+}
+
+extern __inline__ void flush_tlb_range(struct mm_struct *mm, unsigned long start,
+ unsigned long end)
+{
+ if(mm->context != NO_CONTEXT)
+ smp_flush_tlb_range(mm, start, end);
+}
+
+extern __inline__ void flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
+{
+ struct mm_struct *mm = vma->vm_mm;
+
+ if(mm->context != NO_CONTEXT)
+ smp_flush_tlb_page(vma, page);
+}
+
+#endif
+
extern inline pte_t mk_pte(unsigned long page, pgprot_t pgprot)
{ return __pte(__pa(page) | pgprot_val(pgprot)); }
diff --git a/include/asm-sparc64/semaphore.h b/include/asm-sparc64/semaphore.h
index 57dc42260..297173a89 100644
--- a/include/asm-sparc64/semaphore.h
+++ b/include/asm-sparc64/semaphore.h
@@ -24,20 +24,17 @@ extern void __up(struct semaphore * sem);
#define wake_one_more(sem) atomic_inc(&sem->waking);
-extern __inline__ int waking_non_zero(struct semaphore *sem)
-{
- unsigned long flags;
- int ret = 0;
-
- save_flags(flags);
- cli();
- if (atomic_read(&sem->waking) > 0) {
- atomic_dec(&sem->waking);
- ret = 1;
- }
- restore_flags(flags);
- return ret;
-}
+#define waking_non_zero(sem) \
+({ unsigned long flags; \
+ int ret = 0; \
+ save_and_cli(flags); \
+ if (atomic_read(&sem->waking) > 0) { \
+ atomic_dec(&sem->waking); \
+ ret = 1; \
+ } \
+ restore_flags(flags); \
+ ret; \
+})
extern __inline__ void down(struct semaphore * sem)
{
diff --git a/include/asm-sparc64/smp.h b/include/asm-sparc64/smp.h
index 73fc71780..116f83237 100644
--- a/include/asm-sparc64/smp.h
+++ b/include/asm-sparc64/smp.h
@@ -19,7 +19,7 @@ struct prom_cpuinfo {
};
extern int linux_num_cpus; /* number of CPUs probed */
-extern struct prom_cpuinfo linux_cpus[NCPUS];
+extern struct prom_cpuinfo linux_cpus[NR_CPUS];
#endif /* !(__ASSEMBLY__) */
@@ -35,8 +35,12 @@ struct cpuinfo_sparc {
extern struct cpuinfo_sparc cpu_data[NR_CPUS];
-typedef __volatile__ unsigned char klock_t;
-extern klock_t kernel_flag;
+struct klock_info {
+ unsigned char kernel_flag;
+ unsigned char akp;
+};
+
+extern struct klock_info klock_info;
#define KLOCK_HELD 0xff
#define KLOCK_CLEAR 0x00
@@ -47,7 +51,7 @@ extern klock_t kernel_flag;
extern int smp_found_cpus;
extern unsigned char boot_cpu_id;
-extern unsigned int cpu_present_map;
+extern unsigned long cpu_present_map;
extern __volatile__ unsigned long smp_invalidate_needed[NR_CPUS];
extern __volatile__ unsigned long kernel_counter;
extern __volatile__ unsigned char active_kernel_processor;
@@ -68,42 +72,21 @@ typedef void (*smpfunc_t)(unsigned long, unsigned long, unsigned long,
extern void smp_callin(void);
extern void smp_boot_cpus(void);
extern void smp_store_cpu_info(int id);
-extern void smp_cross_call(smpfunc_t func, unsigned long arg1, unsigned long arg2,
- unsigned long arg3, unsigned long arg4, unsigned long arg5);
-
-extern __inline__ void xc0(smpfunc_t func) { smp_cross_call(func, 0, 0, 0, 0, 0); }
-extern __inline__ void xc1(smpfunc_t func, unsigned long arg1)
-{ smp_cross_call(func, arg1, 0, 0, 0, 0); }
-extern __inline__ void xc2(smpfunc_t func, unsigned long arg1, unsigned long arg2)
-{ smp_cross_call(func, arg1, arg2, 0, 0, 0); }
-extern __inline__ void xc3(smpfunc_t func, unsigned long arg1, unsigned long arg2,
- unsigned long arg3)
-{ smp_cross_call(func, arg1, arg2, arg3, 0, 0); }
-extern __inline__ void xc4(smpfunc_t func, unsigned long arg1, unsigned long arg2,
- unsigned long arg3, unsigned long arg4)
-{ smp_cross_call(func, arg1, arg2, arg3, arg4, 0); }
-extern __inline__ void xc5(smpfunc_t func, unsigned long arg1, unsigned long arg2,
- unsigned long arg3, unsigned long arg4, unsigned long arg5)
-{ smp_cross_call(func, arg1, arg2, arg3, arg4, arg5); }
extern __volatile__ int cpu_number_map[NR_CPUS];
extern __volatile__ int cpu_logical_map[NR_CPUS];
-extern __inline__ int smp_processor_id(void)
+extern __inline__ int hard_smp_processor_id(void)
{
- int cpuid;
+ unsigned long upaconfig;
- /* Get MID from UPA Config register, and use that. */
- __asm__ __volatile__("
- ldxa [%g0] %1, %0
- srlx %0, 17, %0
- and %0, 0x1f, %0
- " : "=r" cpuid
- : "i" (ASI_UPA_CONFIG));
-
- return cpuid;
+ __asm__ __volatile__("ldxa [%%g0] %1, %0"
+ : "=r" (upaconfig)
+ : "i" (ASI_UPA_CONFIG));
+ return ((upaconfig >> 17) & 0x1f);
}
+#define smp_processor_id() (current->processor)
extern __volatile__ unsigned long smp_proc_in_lock[NR_CPUS]; /* for computing process time */
#endif /* !(__ASSEMBLY__) */
@@ -122,9 +105,6 @@ extern __volatile__ unsigned long smp_proc_in_lock[NR_CPUS]; /* for computing pr
#define MBOX_IDLECPU2 0xFD
#define MBOX_STOPCPU2 0xFE
-
-#define NO_PROC_ID 0xFF
-
#define PROC_CHANGE_PENALTY 20
#define SMP_FROM_INT 1
@@ -132,4 +112,6 @@ extern __volatile__ unsigned long smp_proc_in_lock[NR_CPUS]; /* for computing pr
#endif /* !(__SMP__) */
+#define NO_PROC_ID 0xFF
+
#endif /* !(_SPARC64_SMP_H) */
diff --git a/include/asm-sparc64/smp_lock.h b/include/asm-sparc64/smp_lock.h
index 12821b215..3012ed6bb 100644
--- a/include/asm-sparc64/smp_lock.h
+++ b/include/asm-sparc64/smp_lock.h
@@ -18,7 +18,69 @@
#define reacquire_kernel_lock(task, cpu, depth) do { } while(0)
#else
-#error SMP on sparc64 not supported yet
+
+#include <asm/hardirq.h>
+
+/* Release global kernel lock and global interrupt lock */
+#define release_kernel_lock(task, cpu, depth) \
+do { \
+ if((depth = (task)->lock_depth) != 0) { \
+ __cli(); \
+ (task)->lock_depth = 0; \
+ klock_info.akp = NO_PROC_ID; \
+ klock_info.kernel_flag = 0; \
+ } \
+ release_irqlock(cpu); \
+ __sti(); \
+} while(0)
+
+/* Do not fuck with this without consulting arch/sparc64/lib/locks.S first! */
+#define reacquire_kernel_lock(task, cpu, depth) \
+do { \
+ if(depth) { \
+ register struct klock_info *klip asm("g1"); \
+ klip = &klock_info; \
+ __asm__ __volatile__("mov %%o7, %%g5\n\t" \
+ "call ___lock_reacquire_kernel\n\t" \
+ " mov %1, %%g2" \
+ : /* No outputs. */ \
+ : "r" (klip), "r" (depth) \
+ : "g2", "g3", "g5", "g7", "memory", "cc"); \
+ } \
+} while(0)
+
+/* The following acquire and release the master kernel global lock,
+ * the idea is that the usage of this mechanmism becomes less and less
+ * as time goes on, to the point where they are no longer needed at all
+ * and can thus disappear.
+ */
+
+/* Do not fuck with this without consulting arch/sparc64/lib/locks.S first! */
+extern __inline__ void lock_kernel(void)
+{
+ register struct klock_info *klip asm("g1");
+ klip = &klock_info;
+ __asm__ __volatile__("
+ mov %%o7, %%g5
+ call ___lock_kernel
+ ld [%%g6 + %0], %%g2
+" : : "i" (AOFF_task_lock_depth), "r" (klip)
+ : "g2", "g3", "g5", "g7", "memory", "cc");
+}
+
+/* Release kernel global lock. */
+extern __inline__ void unlock_kernel(void)
+{
+ register struct klock_info *klip asm("g1");
+ klip = &klock_info;
+ __asm__ __volatile__("
+ mov %%o7, %%g5
+ call ___unlock_kernel
+ ld [%%g6 + %0], %%g2
+" : : "i" (AOFF_task_lock_depth), "r" (klip)
+ : "g2", "g3", "g5", "memory", "cc");
+}
+
#endif /* (__SMP__) */
#endif /* !(__SPARC64_SMPLOCK_H) */
diff --git a/include/asm-sparc64/softirq.h b/include/asm-sparc64/softirq.h
index 8386e4a15..397d6bf50 100644
--- a/include/asm-sparc64/softirq.h
+++ b/include/asm-sparc64/softirq.h
@@ -68,6 +68,8 @@ extern atomic_t __sparc64_bh_counter;
#include <asm/spinlock.h>
+extern spinlock_t global_bh_lock;
+
#define init_bh(nr, routine) \
do { unsigned long flags; \
int ent = nr; \
@@ -115,13 +117,13 @@ do { unsigned long flags; \
#define softirq_trylock() \
({ \
int ret = 1; \
- if(atomic_add_return(1, &__sparc_bh_counter) != 1) { \
- atomic_dec(&__sparc_bh_counter); \
+ if(atomic_add_return(1, &__sparc64_bh_counter) != 1) { \
+ atomic_dec(&__sparc64_bh_counter); \
ret = 0; \
} \
ret; \
})
-#define softirq_endlock() atomic_dec(&__sparc_bh_counter)
+#define softirq_endlock() atomic_dec(&__sparc64_bh_counter)
#define clear_active_bhs(mask) \
do { unsigned long flags; \
spin_lock_irqsave(&global_bh_lock, flags); \
diff --git a/include/asm-sparc64/spinlock.h b/include/asm-sparc64/spinlock.h
index cefd43309..cf2e51c71 100644
--- a/include/asm-sparc64/spinlock.h
+++ b/include/asm-sparc64/spinlock.h
@@ -56,6 +56,14 @@ typedef struct { } rwlock_t;
/* All of these locking primitives are expected to work properly
* even in an RMO memory model, which currently is what the kernel
* runs in.
+ *
+ * There is another issue. Because we play games to save cycles
+ * in the non-contention case, we need to be extra careful about
+ * branch targets into the "spinning" code. They live in their
+ * own section, but the newer V9 branches have a shorter range
+ * than the traditional 32-bit sparc branch variants. The rule
+ * is that the branches that go into and out of the spinner sections
+ * must be pre-V9 branches.
*/
typedef unsigned char spinlock_t;
@@ -67,13 +75,15 @@ extern __inline__ void spin_lock(spinlock_t *lock)
{
__asm__ __volatile__("
1: ldstub [%0], %%g2
- brnz,a,pn %%g2, 2f
- ldub [%0], %%g2
- membar #LoadLoad | #LoadStore
+ brz,pt %%g2, 2f
+ membar #LoadLoad | #LoadStore
+ b,a %%xcc, 3f
+2:
.text 2
-2: brnz,a,pt 2b
+3: ldub [%0], %%g2
+4: brnz,a,pt %%g2, 4b
ldub [%0], %%g2
- b,a,pt %%xcc, 1b
+ b,a 1b
.previous
" : /* no outputs */
: "r" (lock)
@@ -104,14 +114,16 @@ extern __inline__ void spin_lock_irq(spinlock_t *lock)
{
__asm__ __volatile__("
wrpr %%g0, 15, %%pil
- ldstub [%0], %%g2
- brnz,a,pn %%g2, 2f
- ldub [%0], %%g2
- membar #LoadLoad | #LoadStore
+1: ldstub [%0], %%g2
+ brz,pt %%g2, 2f
+ membar #LoadLoad | #LoadStore
+ b,a 3f
+2:
.text 2
-2: brnz,a,pt 2b
+3: ldub [%0], %%g2
+4: brnz,a,pt %%g2, 4b
ldub [%0], %%g2
- b,a,pt %%xcc, 1b
+ b,a 1b
.previous
" : /* no outputs */
: "r" (lock)
@@ -133,18 +145,20 @@ extern __inline__ void spin_unlock_irq(spinlock_t *lock)
do { register spinlock_t *lp asm("g1"); \
lp = lock; \
__asm__ __volatile__( \
- " rdpr %%pil, %0\n\t" \
- " wrpr %%g0, 15, %%pil\n\t" \
- "1: ldstub [%1], %%g2\n\t" \
- " brnz,a,pnt %%g2, 2f\n\t" \
- " ldub [%1], %%g2\n\t" \
- " membar #LoadLoad | #LoadStore\n\t" \
- " .text 2\n\t" \
- "2: brnz,a,pt %%g2, 2b\n\t" \
- " ldub [%1], %%g2\n\t" \
- " b,a,pt %%xcc, 1b\n\t" \
+ "\n rdpr %%pil, %0\n" \
+ " wrpr %%g0, 15, %%pil\n" \
+ "1: ldstub [%1], %%g2\n" \
+ " brz,pt %%g2, 2f\n" \
+ " membar #LoadLoad | #LoadStore\n" \
+ " b,a 3f\n" \
+ "2:\n" \
+ " .text 2\n" \
+ "3: ldub [%1], %%g2\n" \
+ "4: brnz,a,pt %%g2, 4b\n" \
+ " ldub [%1], %%g2\n" \
+ " b,a 1b\n" \
" .previous\n" \
- : "=r" (flags) \
+ : "=&r" (flags) \
: "r" (lp) \
: "g2", "memory"); \
} while(0)
@@ -169,19 +183,20 @@ extern __inline__ void read_lock(rwlock_t *rw)
{
__asm__ __volatile__("
ldx [%0], %%g2
-1:
- brlz,pn %%g2, 2f
-4: add %%g2, 1, %%g3
- casx [%0], %%g2, %%g3
+1: brgez,pt %%g2, 4f
+ add %%g2, 1, %%g3
+ b,a 2f
+4: casx [%0], %%g2, %%g3
cmp %%g2, %%g3
bne,a,pn %%xcc, 1b
- ldx [%0],%%g2
+ ldx [%0], %%g2
membar #LoadLoad | #LoadStore
.text 2
2: ldx [%0], %%g2
-3: brlz,pt %%g2, 3b
+3: brlz,a,pt %%g2, 3b
ldx [%0], %%g2
- b,a,pt %%xcc, 4b
+ b 4b
+ add %%g2, 1, %%g3
.previous
" : /* no outputs */
: "r" (rw)
@@ -193,8 +208,7 @@ extern __inline__ void read_unlock(rwlock_t *rw)
__asm__ __volatile__("
membar #StoreStore | #LoadStore
ldx [%0], %%g2
-1:
- sub %%g2, 1, %%g3
+1: sub %%g2, 1, %%g3
casx [%0], %%g2, %%g3
cmp %%g2, %%g3
bne,a,pn %%xcc, 1b
@@ -208,31 +222,34 @@ extern __inline__ void write_lock(rwlock_t *rw)
{
__asm__ __volatile__("
sethi %%uhi(0x8000000000000000), %%g5
- ldx [%0] %%g2
+ ldx [%0], %%g2
sllx %%g5, 32, %%g5
-1:
- brlz,pn %%g2, 5f
-4: or %%g2, %%g5, %%g3
- casx [%0], %%g2, %%g3
+1: brgez,pt %%g2, 4f
+ or %%g2, %%g5, %%g3
+ b,a 5f
+4: casx [%0], %%g2, %%g3
cmp %%g2, %%g3
bne,a,pn %%xcc, 1b
ldx [%0], %%g2
andncc %%g3, %%g5, %%g0
- bne,a,pn %%xcc, 3f
- ldx [%0], %%g2
- membar #LoadLoad | #LoadStore
+ be,pt %%xcc, 2f
+ membar #LoadLoad | #LoadStore
+ b,a 7f
+2:
.text 2
-3:
- andn %%g2, %%g5, %%g3
+7: ldx [%0], %%g2
+3: andn %%g2, %%g5, %%g3
casx [%0], %%g2, %%g3
cmp %%g2, %%g3
bne,a,pn %%xcc, 3b
ldx [%0], %%g2
membar #LoadLoad | #LoadStore
5: ldx [%0], %%g2
-6: brlz,pt %%g2, 6b
+6: brlz,a,pt %%g2, 6b
ldx [%0], %%g2
- b,a,pt %%xcc, 4b
+ b 4b
+ or %%g2, %%g5, %%g3
+ .previous
" : /* no outputs */
: "r" (rw)
: "g2", "g3", "g5", "memory", "cc");
@@ -245,8 +262,7 @@ extern __inline__ void write_unlock(rwlock_t *rw)
sethi %%uhi(0x8000000000000000), %%g5
ldx [%0], %%g2
sllx %%g5, 32, %%g5
-1:
- andn %%g2, %%g5, %%g3
+1: andn %%g2, %%g5, %%g3
casx [%0], %%g2, %%g3
cmp %%g2, %%g3
bne,a,pn %%xcc, 1b
diff --git a/include/asm-sparc64/system.h b/include/asm-sparc64/system.h
index 6e7c42e55..ab05190e9 100644
--- a/include/asm-sparc64/system.h
+++ b/include/asm-sparc64/system.h
@@ -1,4 +1,4 @@
-/* $Id: system.h,v 1.26 1997/06/28 10:04:03 davem Exp $ */
+/* $Id: system.h,v 1.29 1997/07/24 16:48:32 davem Exp $ */
#ifndef __SPARC64_SYSTEM_H
#define __SPARC64_SYSTEM_H
@@ -74,7 +74,27 @@ extern unsigned long empty_zero_page;
#define restore_flags(x) __restore_flags(x)
#define save_and_cli(x) __save_and_cli(x)
#else
-#error SMP not supported on sparc64
+
+#ifndef __ASSEMBLY__
+extern unsigned char global_irq_holder;
+#endif
+
+#define save_flags(x) \
+do { ((x) = ((global_irq_holder == (unsigned char) smp_processor_id()) ? 1 : \
+ ((getipl() != 0) ? 2 : 0))); } while(0)
+
+#define save_and_cli(flags) do { save_flags(flags); cli(); } while(0)
+
+#ifndef __ASSEMBLY__
+extern void __global_cli(void);
+extern void __global_sti(void);
+extern void __global_restore_flags(unsigned long flags);
+#endif
+
+#define cli() __global_cli()
+#define sti() __global_sti()
+#define restore_flags(flags) __global_restore_flags(flags)
+
#endif
#define mb() __asm__ __volatile__ ("stbar" : : : "memory")
@@ -112,48 +132,48 @@ extern __inline__ void flushw_user(void)
* when modifying this code inspect output of sched.s very
* carefully to make sure things still work. -DaveM
*/
-#define switch_to(prev, next) \
-do { \
- __label__ switch_continue; \
- register unsigned long task_pc asm("o7"); \
- (prev)->tss.kregs->fprs = 0; \
- task_pc = ((unsigned long) &&switch_continue) - 0x8; \
- __asm__ __volatile__( \
- "rdpr %%pstate, %%g2\n\t" \
- "wrpr %%g2, 0x3, %%pstate\n\t" \
- "flushw\n\t" \
-/*XXX*/ "wr %%g0, 0, %%fprs\n\t" \
- "stx %%i6, [%%sp + 2047 + 0x70]\n\t" \
- "stx %%i7, [%%sp + 2047 + 0x78]\n\t" \
- "rdpr %%wstate, %%o5\n\t" \
- "stx %%o6, [%%g6 + %3]\n\t" \
- "stx %%o5, [%%g6 + %2]\n\t" \
- "rdpr %%cwp, %%o5\n\t" \
- "stx %%o7, [%%g6 + %4]\n\t" \
- "st %%o5, [%%g6 + %5]\n\t" \
- "mov %0, %%g6\n\t" \
- "ld [%0 + %5], %%g1\n\t" \
- "wrpr %%g1, %%cwp\n\t" \
- "ldx [%%g6 + %2], %%o5\n\t" \
- "ldx [%%g6 + %3], %%o6\n\t" \
- "ldx [%%g6 + %4], %%o7\n\t" \
- "mov %%g6, %0\n\t" \
- "wrpr %%o5, 0x0, %%wstate\n\t" \
- "ldx [%%sp + 2047 + 0x70], %%i6\n\t" \
- "ldx [%%sp + 2047 + 0x78], %%i7\n\t" \
- "wrpr %%g0, 0x96, %%pstate\n\t" \
- "jmpl %%o7 + 0x8, %%g0\n\t" \
- " mov %0, %%g6\n\t" \
- : /* No outputs */ \
- : "r" (next), "r" (task_pc), \
- "i" ((const unsigned long)(&((struct task_struct *)0)->tss.wstate)), \
- "i" ((const unsigned long)(&((struct task_struct *)0)->tss.ksp)), \
- "i" ((const unsigned long)(&((struct task_struct *)0)->tss.kpc)), \
- "i" ((const unsigned long)(&((struct task_struct *)0)->tss.cwp)) \
- : "cc", "g1", "g2", "g3", "g5", "g7", \
- "l1", "l2", "l3", "l4", "l5", "l6", "l7", \
- "i0", "i1", "i2", "i3", "i4", "i5", \
- "o0", "o1", "o2", "o3", "o4", "o5"); \
+#define switch_to(prev, next) \
+do { __label__ switch_continue; \
+ register unsigned long task_pc asm("o7"); \
+ (prev)->tss.kregs->fprs = 0; \
+ task_pc = ((unsigned long) &&switch_continue) - 0x8; \
+ (next)->mm->cpu_vm_mask |= (1UL << smp_processor_id()); \
+ __asm__ __volatile__( \
+ "rdpr %%pstate, %%g2\n\t" \
+ "wrpr %%g2, 0x3, %%pstate\n\t" \
+ "flushw\n\t" \
+/*XXX*/ "wr %%g0, 0, %%fprs\n\t" \
+ "stx %%i6, [%%sp + 2047 + 0x70]\n\t" \
+ "stx %%i7, [%%sp + 2047 + 0x78]\n\t" \
+ "rdpr %%wstate, %%o5\n\t" \
+ "stx %%o6, [%%g6 + %3]\n\t" \
+ "stx %%o5, [%%g6 + %2]\n\t" \
+ "rdpr %%cwp, %%o5\n\t" \
+ "stx %%o7, [%%g6 + %4]\n\t" \
+ "st %%o5, [%%g6 + %5]\n\t" \
+ "mov %0, %%g6\n\t" \
+ "ld [%0 + %5], %%g1\n\t" \
+ "wrpr %%g1, %%cwp\n\t" \
+ "ldx [%%g6 + %2], %%o5\n\t" \
+ "ldx [%%g6 + %3], %%o6\n\t" \
+ "ldx [%%g6 + %4], %%o7\n\t" \
+ "mov %%g6, %0\n\t" \
+ "wrpr %%o5, 0x0, %%wstate\n\t" \
+ "ldx [%%sp + 2047 + 0x70], %%i6\n\t" \
+ "ldx [%%sp + 2047 + 0x78], %%i7\n\t" \
+ "wrpr %%g0, 0x96, %%pstate\n\t" \
+ "jmpl %%o7 + 0x8, %%g0\n\t" \
+ " mov %0, %%g6\n\t" \
+ : /* No outputs */ \
+ : "r" (next), "r" (task_pc), \
+ "i" ((const unsigned long)(&((struct task_struct *)0)->tss.wstate)), \
+ "i" ((const unsigned long)(&((struct task_struct *)0)->tss.ksp)), \
+ "i" ((const unsigned long)(&((struct task_struct *)0)->tss.kpc)), \
+ "i" ((const unsigned long)(&((struct task_struct *)0)->tss.cwp)) \
+ : "cc", "g1", "g2", "g3", "g5", "g7", \
+ "l1", "l2", "l3", "l4", "l5", "l6", "l7", \
+ "i0", "i1", "i2", "i3", "i4", "i5", \
+ "o0", "o1", "o2", "o3", "o4", "o5"); \
switch_continue: } while(0)
/* Unlike the hybrid v7/v8 kernel, we can assume swap exists under V9. */
diff --git a/include/linux/dcache.h b/include/linux/dcache.h
index 5a1dc90bf..82390ea64 100644
--- a/include/linux/dcache.h
+++ b/include/linux/dcache.h
@@ -49,9 +49,13 @@ struct dentry {
struct list_head d_alias; /* inode alias list */
struct list_head d_lru; /* d_count = 0 LRU list */
struct qstr d_name;
- struct dentry * (*d_revalidate)(struct dentry *);
+ unsigned long d_time; /* used by d_revalidate */
+ int (*d_revalidate)(struct dentry *);
};
+/* d_flags entries */
+#define DCACHE_AUTOFS_PENDING 0x0001 /* autofs: "under construction" */
+
/*
* d_drop() unhashes the entry from the parent
* dentry hashes, so that it won't be found through
@@ -102,8 +106,8 @@ extern struct dentry * d_lookup(struct dentry * dir, struct qstr * name);
extern int d_validate(struct dentry *dentry, struct dentry *dparent,
unsigned int hash, unsigned int len);
-/* write full pathname into buffer and return length */
-extern int d_path(struct dentry * entry, struct dentry * chroot, char * buf);
+/* write full pathname into buffer and return start of pathname */
+extern char * d_path(struct dentry * entry, char * buf, int buflen);
/* Allocation counts.. */
static inline struct dentry * dget(struct dentry *dentry)
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 4ccb6d569..665b56c38 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -672,7 +672,7 @@ extern inline void mark_buffer_dirty(struct buffer_head * bh, int flag)
}
extern int check_disk_change(kdev_t dev);
-extern void invalidate_inodes(kdev_t dev);
+extern int invalidate_inodes(kdev_t dev);
extern void invalidate_inode_pages(struct inode *);
extern void invalidate_buffers(kdev_t dev);
extern int floppy_is_wp(int minor);
diff --git a/include/linux/miscdevice.h b/include/linux/miscdevice.h
index 6ea9d896e..4886d464c 100644
--- a/include/linux/miscdevice.h
+++ b/include/linux/miscdevice.h
@@ -11,6 +11,7 @@
#define PC110PAD_MINOR 9
#define RTC_MINOR 135
#define SUN_OPENPROM_MINOR 139
+#define NVRAM_MINOR 144
#define MISC_DYNAMIC_MINOR 255
#define SGI_GRAPHICS_MINOR 146
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 674f69479..cab25f117 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -118,9 +118,8 @@ typedef struct page {
unsigned long offset;
struct page *next_hash;
atomic_t count;
+ unsigned int age;
unsigned long flags; /* atomic flags, some possibly updated asynchronously */
- unsigned dirty:16,
- age:8;
struct wait_queue *wait;
struct page **pprev_hash;
struct buffer_head * buffers;
diff --git a/include/linux/msdos_fs.h b/include/linux/msdos_fs.h
index fb17117a0..dba07c796 100644
--- a/include/linux/msdos_fs.h
+++ b/include/linux/msdos_fs.h
@@ -7,7 +7,6 @@
#include <linux/fs.h>
#include <linux/stat.h>
#include <linux/fd.h>
-#include <linux/config.h>
#include <asm/byteorder.h>
@@ -72,13 +71,9 @@
#define MSDOS_FAT12 4078 /* maximum number of clusters in a 12 bit FAT */
-#ifdef CONFIG_ATARI
-#define EOF_FAT12 0xFFF /* Atari GEMDOS fs uses a different EOF */
-#define EOF_FAT16 0xFFFF
-#else
#define EOF_FAT12 0xFF8 /* standard EOF */
#define EOF_FAT16 0xFFF8
-#endif
+#define EOF_FAT(s) (MSDOS_SB(s)->fat_bits == 16 ? 0xFFF8 : 0xFF8)
/*
* Inode flags
diff --git a/include/linux/msdos_fs_sb.h b/include/linux/msdos_fs_sb.h
index bf5ea6345..4cc224838 100644
--- a/include/linux/msdos_fs_sb.h
+++ b/include/linux/msdos_fs_sb.h
@@ -18,7 +18,8 @@ struct fat_mount_options {
isvfat:1, /* 0=no vfat long filename support, 1=vfat support */
unicode_xlate:1, /* create escape sequences for unhandled Unicode */
posixfs:1, /* Allow names like makefile and Makefile to coexist */
- numtail:1; /* Does first alias have a numeric '~1' type tail? */
+ numtail:1, /* Does first alias have a numeric '~1' type tail? */
+ atari:1; /* Use Atari GEMDOS variation of MS-DOS fs */
};
diff --git a/include/linux/parport.h b/include/linux/parport.h
index 45c55f5a3..eca37ac03 100644
--- a/include/linux/parport.h
+++ b/include/linux/parport.h
@@ -1,4 +1,4 @@
-/* $Id: parport.h,v 1.2.6.3.2.2 1997/04/18 15:03:53 phil Exp $ */
+/* $Id: parport.h,v 1.2 1997/07/29 04:00:12 ralf Exp $ */
#ifndef _PARPORT_H_
#define _PARPORT_H_
@@ -130,8 +130,7 @@ struct parport_device_info {
*
* 2) a wake-up function, called by the resource manager to tell drivers
* that the port is available to be claimed. If a driver wants to use
- * the port, it should call parport_claim() here. The return value from
- * this function is ignored.
+ * the port, it should call parport_claim() here.
*/
/* A parallel port device */
@@ -187,6 +186,9 @@ struct parport {
struct parport *parport_register_port(unsigned long base, int irq, int dma,
struct parport_operations *ops);
+/* Unregister a port. */
+void parport_unregister_port(struct parport *port);
+
/* parport_in_use returns nonzero if there are devices attached to a port. */
#define parport_in_use(x) ((x)->devices != NULL)
@@ -209,7 +211,7 @@ struct parport *parport_enumerate(void);
*/
struct pardevice *parport_register_device(struct parport *port,
const char *name,
- int (*pf)(void *), int (*kf)(void *),
+ int (*pf)(void *), void (*kf)(void *),
void (*irq_func)(int, void *, struct pt_regs *),
int flags, void *handle);
diff --git a/include/linux/proc_fs.h b/include/linux/proc_fs.h
index 80cdf71a7..901a8b9ef 100644
--- a/include/linux/proc_fs.h
+++ b/include/linux/proc_fs.h
@@ -336,7 +336,7 @@ struct openpromfs_dev {
};
extern struct inode_operations *
proc_openprom_register(int (*readdir)(struct inode *, struct file *, void *, filldir_t),
- int (*lookup)(struct inode *, struct qstr *, struct inode **),
+ int (*lookup)(struct inode *, struct dentry *),
void (*use)(struct inode *, int),
struct openpromfs_dev ***);
extern void proc_openprom_deregister(void);
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 1aafb505f..f1fc28b18 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -384,33 +384,36 @@ extern spinlock_t pidhash_lock;
extern __inline__ void hash_pid(struct task_struct *p)
{
struct task_struct **htable = &pidhash[pid_hashfn(p->pid)];
+ unsigned long flags;
- spin_lock(&pidhash_lock);
+ spin_lock_irqsave(&pidhash_lock, flags);
if((p->pidhash_next = *htable) != NULL)
(*htable)->pidhash_pprev = &p->pidhash_next;
*htable = p;
p->pidhash_pprev = htable;
- spin_unlock(&pidhash_lock);
+ spin_unlock_irqrestore(&pidhash_lock, flags);
}
extern __inline__ void unhash_pid(struct task_struct *p)
{
- spin_lock(&pidhash_lock);
+ unsigned long flags;
+
+ spin_lock_irqsave(&pidhash_lock, flags);
if(p->pidhash_next)
p->pidhash_next->pidhash_pprev = p->pidhash_pprev;
*p->pidhash_pprev = p->pidhash_next;
- spin_unlock(&pidhash_lock);
+ spin_unlock_irqrestore(&pidhash_lock, flags);
}
extern __inline__ struct task_struct *find_task_by_pid(int pid)
{
- struct task_struct **htable = &pidhash[pid_hashfn(pid)];
- struct task_struct *p;
+ struct task_struct *p, **htable = &pidhash[pid_hashfn(pid)];
+ unsigned long flags;
- spin_lock(&pidhash_lock);
+ spin_lock_irqsave(&pidhash_lock, flags);
for(p = *htable; p && p->pid != pid; p = p->pidhash_next)
;
- spin_unlock(&pidhash_lock);
+ spin_unlock_irqrestore(&pidhash_lock, flags);
return p;
}
@@ -441,7 +444,7 @@ extern void wake_up(struct wait_queue ** p);
extern void wake_up_interruptible(struct wait_queue ** p);
extern void wake_up_process(struct task_struct * tsk);
-extern void notify_parent(struct task_struct * tsk);
+extern void notify_parent(struct task_struct * tsk, int signal);
extern void release(struct task_struct * p);
extern void force_sig(unsigned long sig,struct task_struct * p);
extern int send_sig(unsigned long sig,struct task_struct * p,int priv);
diff --git a/include/linux/selection.h b/include/linux/selection.h
index cad2a29b0..e41e9ebef 100644
--- a/include/linux/selection.h
+++ b/include/linux/selection.h
@@ -23,11 +23,11 @@ extern unsigned long get_video_size_row(unsigned int console);
#define get_video_num_columns(dummy) video_num_columns
#define get_video_num_lines(dummy) video_num_lines
#define get_video_size_row(dummy) video_size_row
+#endif
+
extern unsigned long video_num_columns;
extern unsigned long video_num_lines;
extern unsigned long video_size_row;
-#endif
-
extern unsigned char video_type;
extern unsigned long video_mem_base;
extern unsigned long video_mem_term;
@@ -73,8 +73,6 @@ extern void putconsxy(int currcons, char *p);
/* how to access screen memory */
-#include <linux/config.h>
-
#if defined(CONFIG_TGA_CONSOLE)
extern int tga_blitc(unsigned int, unsigned long);
@@ -244,17 +242,25 @@ static inline unsigned char scr_readb(unsigned char * addr)
static inline void scr_writew(unsigned short val, unsigned short * addr)
{
+#ifdef __powerpc__
+ st_le16(addr, val);
+#else
if ((long) addr < 0)
*addr = val;
else
writew(val, (unsigned long) addr);
+#endif /* !__powerpc__ */
}
static inline unsigned short scr_readw(unsigned short * addr)
{
+#ifdef __powerpc__
+ return ld_le16(addr);
+#else
if ((long) addr < 0)
return *addr;
return readw((unsigned long) addr);
+#endif /* !__powerpc__ */
}
#endif /* CONFIG_TGA_CONSOLE */
diff --git a/include/linux/sysrq.h b/include/linux/sysrq.h
index 8cfd21b0e..c65304671 100644
--- a/include/linux/sysrq.h
+++ b/include/linux/sysrq.h
@@ -1,6 +1,6 @@
/* -*- linux-c -*-
*
- * $Id: sysrq.h,v 1.2 1997/05/31 18:33:41 mj Exp $
+ * $Id: sysrq.h,v 1.1 1997/06/17 13:30:39 ralf Exp $
*
* Linux Magic System Request Key Hacks
*
@@ -9,12 +9,25 @@
#include <linux/config.h>
+struct pt_regs;
+struct kbd_struct;
+struct tty_struct;
+
+/* Generic SysRq interface -- you may call it from any device driver, supplying
+ * ASCII code of the key, pointer to registers and kbd/tty structs (if they
+ * are available -- else NULL's).
+ */
+
+void handle_sysrq(int, struct pt_regs *, struct kbd_struct *, struct tty_struct *);
+
+/* Deferred actions */
+
extern int emergency_sync_scheduled;
#define EMERG_SYNC 1
#define EMERG_REMOUNT 2
-extern void do_emergency_sync(void);
+void do_emergency_sync(void);
#ifdef CONFIG_MAGIC_SYSRQ
#define CHECK_EMERGENCY_SYNC \