]> pilppa.org Git - linux-2.6-omap-h63xx.git/commitdiff
[PATCH] xtensa: Architecture support for Tensilica Xtensa Part 6
authorChris Zankel <czankel@tensilica.com>
Fri, 24 Jun 2005 05:01:26 +0000 (22:01 -0700)
committerLinus Torvalds <torvalds@ppc970.osdl.org>
Fri, 24 Jun 2005 07:05:22 +0000 (00:05 -0700)
The attached patches provides part 6 of an architecture implementation for the
Tensilica Xtensa CPU series.

Signed-off-by: Chris Zankel <chris@zankel.net>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
92 files changed:
include/asm-xtensa/a.out.h [new file with mode: 0644]
include/asm-xtensa/atomic.h [new file with mode: 0644]
include/asm-xtensa/bitops.h [new file with mode: 0644]
include/asm-xtensa/bootparam.h [new file with mode: 0644]
include/asm-xtensa/bug.h [new file with mode: 0644]
include/asm-xtensa/bugs.h [new file with mode: 0644]
include/asm-xtensa/byteorder.h [new file with mode: 0644]
include/asm-xtensa/cache.h [new file with mode: 0644]
include/asm-xtensa/cacheflush.h [new file with mode: 0644]
include/asm-xtensa/checksum.h [new file with mode: 0644]
include/asm-xtensa/coprocessor.h [new file with mode: 0644]
include/asm-xtensa/cpumask.h [new file with mode: 0644]
include/asm-xtensa/cputime.h [new file with mode: 0644]
include/asm-xtensa/current.h [new file with mode: 0644]
include/asm-xtensa/delay.h [new file with mode: 0644]
include/asm-xtensa/div64.h [new file with mode: 0644]
include/asm-xtensa/dma-mapping.h [new file with mode: 0644]
include/asm-xtensa/dma.h [new file with mode: 0644]
include/asm-xtensa/elf.h [new file with mode: 0644]
include/asm-xtensa/errno.h [new file with mode: 0644]
include/asm-xtensa/fcntl.h [new file with mode: 0644]
include/asm-xtensa/fixmap.h [new file with mode: 0644]
include/asm-xtensa/hardirq.h [new file with mode: 0644]
include/asm-xtensa/hdreg.h [new file with mode: 0644]
include/asm-xtensa/highmem.h [new file with mode: 0644]
include/asm-xtensa/hw_irq.h [new file with mode: 0644]
include/asm-xtensa/ide.h [new file with mode: 0644]
include/asm-xtensa/io.h [new file with mode: 0644]
include/asm-xtensa/ioctl.h [new file with mode: 0644]
include/asm-xtensa/ioctls.h [new file with mode: 0644]
include/asm-xtensa/ipc.h [new file with mode: 0644]
include/asm-xtensa/ipcbuf.h [new file with mode: 0644]
include/asm-xtensa/irq.h [new file with mode: 0644]
include/asm-xtensa/kmap_types.h [new file with mode: 0644]
include/asm-xtensa/linkage.h [new file with mode: 0644]
include/asm-xtensa/local.h [new file with mode: 0644]
include/asm-xtensa/mman.h [new file with mode: 0644]
include/asm-xtensa/mmu.h [new file with mode: 0644]
include/asm-xtensa/mmu_context.h [new file with mode: 0644]
include/asm-xtensa/module.h [new file with mode: 0644]
include/asm-xtensa/msgbuf.h [new file with mode: 0644]
include/asm-xtensa/namei.h [new file with mode: 0644]
include/asm-xtensa/page.h [new file with mode: 0644]
include/asm-xtensa/page.h.n [new file with mode: 0644]
include/asm-xtensa/param.h [new file with mode: 0644]
include/asm-xtensa/pci-bridge.h [new file with mode: 0644]
include/asm-xtensa/pci.h [new file with mode: 0644]
include/asm-xtensa/percpu.h [new file with mode: 0644]
include/asm-xtensa/pgalloc.h [new file with mode: 0644]
include/asm-xtensa/pgtable.h [new file with mode: 0644]
include/asm-xtensa/poll.h [new file with mode: 0644]
include/asm-xtensa/posix_types.h [new file with mode: 0644]
include/asm-xtensa/processor.h [new file with mode: 0644]
include/asm-xtensa/ptrace.h [new file with mode: 0644]
include/asm-xtensa/resource.h [new file with mode: 0644]
include/asm-xtensa/rmap.h [new file with mode: 0644]
include/asm-xtensa/rwsem.h [new file with mode: 0644]
include/asm-xtensa/scatterlist.h [new file with mode: 0644]
include/asm-xtensa/sections.h [new file with mode: 0644]
include/asm-xtensa/segment.h [new file with mode: 0644]
include/asm-xtensa/semaphore.h [new file with mode: 0644]
include/asm-xtensa/sembuf.h [new file with mode: 0644]
include/asm-xtensa/serial.h [new file with mode: 0644]
include/asm-xtensa/setup.h [new file with mode: 0644]
include/asm-xtensa/shmbuf.h [new file with mode: 0644]
include/asm-xtensa/shmparam.h [new file with mode: 0644]
include/asm-xtensa/sigcontext.h [new file with mode: 0644]
include/asm-xtensa/siginfo.h [new file with mode: 0644]
include/asm-xtensa/signal.h [new file with mode: 0644]
include/asm-xtensa/smp.h [new file with mode: 0644]
include/asm-xtensa/socket.h [new file with mode: 0644]
include/asm-xtensa/sockios.h [new file with mode: 0644]
include/asm-xtensa/spinlock.h [new file with mode: 0644]
include/asm-xtensa/stat.h [new file with mode: 0644]
include/asm-xtensa/statfs.h [new file with mode: 0644]
include/asm-xtensa/string.h [new file with mode: 0644]
include/asm-xtensa/system.h [new file with mode: 0644]
include/asm-xtensa/termbits.h [new file with mode: 0644]
include/asm-xtensa/termios.h [new file with mode: 0644]
include/asm-xtensa/thread_info.h [new file with mode: 0644]
include/asm-xtensa/timex.h [new file with mode: 0644]
include/asm-xtensa/tlb.h [new file with mode: 0644]
include/asm-xtensa/tlbflush.h [new file with mode: 0644]
include/asm-xtensa/topology.h [new file with mode: 0644]
include/asm-xtensa/types.h [new file with mode: 0644]
include/asm-xtensa/uaccess.h [new file with mode: 0644]
include/asm-xtensa/ucontext.h [new file with mode: 0644]
include/asm-xtensa/unaligned.h [new file with mode: 0644]
include/asm-xtensa/unistd.h [new file with mode: 0644]
include/asm-xtensa/user.h [new file with mode: 0644]
include/asm-xtensa/vga.h [new file with mode: 0644]
include/asm-xtensa/xor.h [new file with mode: 0644]

diff --git a/include/asm-xtensa/a.out.h b/include/asm-xtensa/a.out.h
new file mode 100644 (file)
index 0000000..3be701d
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * include/asm-xtensa/addrspace.h
+ *
+ * Dummy a.out file. Xtensa does not support the a.out format, but the kernel
+ * seems to depend on it.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_A_OUT_H
+#define _XTENSA_A_OUT_H
+
+/* Note: the kernel needs the a.out definitions, even if only ELF is used. */
+
+#define STACK_TOP      TASK_SIZE
+
+struct exec
+{
+  unsigned long a_info;
+  unsigned a_text;
+  unsigned a_data;
+  unsigned a_bss;
+  unsigned a_syms;
+  unsigned a_entry;
+  unsigned a_trsize;
+  unsigned a_drsize;
+};
+
+#endif /* _XTENSA_A_OUT_H */
diff --git a/include/asm-xtensa/atomic.h b/include/asm-xtensa/atomic.h
new file mode 100644 (file)
index 0000000..d72bcb3
--- /dev/null
@@ -0,0 +1,272 @@
+/*
+ * include/asm-xtensa/atomic.h
+ *
+ * Atomic operations that C can't guarantee us.  Useful for resource counting..
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_ATOMIC_H
+#define _XTENSA_ATOMIC_H
+
+#include <linux/config.h>
+#include <linux/stringify.h>
+
+typedef struct { volatile int counter; } atomic_t;
+
+#ifdef __KERNEL__
+#include <asm/processor.h>
+#include <asm/system.h>
+
+#define ATOMIC_INIT(i) ( (atomic_t) { (i) } )
+
+/*
+ * This Xtensa implementation assumes that the right mechanism
+ * for exclusion is for locking interrupts to level 1.
+ *
+ * Locking interrupts looks like this:
+ *
+ *    rsil a15, 1
+ *    <code>
+ *    wsr  a15, PS
+ *    rsync
+ *
+ * Note that a15 is used here because the register allocation
+ * done by the compiler is not guaranteed and a window overflow
+ * may not occur between the rsil and wsr instructions. By using
+ * a15 in the rsil, the machine is guaranteed to be in a state
+ * where no register reference will cause an overflow.
+ */
+
+/**
+ * atomic_read - read atomic variable
+ * @v: pointer of type atomic_t
+ *
+ * Atomically reads the value of @v.
+ */
+#define atomic_read(v)         ((v)->counter)
+
+/**
+ * atomic_set - set atomic variable
+ * @v: pointer of type atomic_t
+ * @i: required value
+ *
+ * Atomically sets the value of @v to @i.
+ */
+#define atomic_set(v,i)                ((v)->counter = (i))
+
+/**
+ * atomic_add - add integer to atomic variable
+ * @i: integer value to add
+ * @v: pointer of type atomic_t
+ *
+ * Atomically adds @i to @v.
+ */
+extern __inline__ void atomic_add(int i, atomic_t * v)
+{
+    unsigned int vval;
+
+    __asm__ __volatile__(
+       "rsil    a15, "__stringify(LOCKLEVEL)"\n\t"
+       "l32i    %0, %2, 0              \n\t"
+       "add     %0, %0, %1             \n\t"
+       "s32i    %0, %2, 0              \n\t"
+       "wsr     a15, "__stringify(PS)"       \n\t"
+       "rsync                          \n"
+       : "=&a" (vval)
+       : "a" (i), "a" (v)
+       : "a15", "memory"
+       );
+}
+
+/**
+ * atomic_sub - subtract the atomic variable
+ * @i: integer value to subtract
+ * @v: pointer of type atomic_t
+ *
+ * Atomically subtracts @i from @v.
+ */
+extern __inline__ void atomic_sub(int i, atomic_t *v)
+{
+    unsigned int vval;
+
+    __asm__ __volatile__(
+       "rsil    a15, "__stringify(LOCKLEVEL)"\n\t"
+       "l32i    %0, %2, 0              \n\t"
+       "sub     %0, %0, %1             \n\t"
+       "s32i    %0, %2, 0              \n\t"
+       "wsr     a15, "__stringify(PS)"       \n\t"
+       "rsync                          \n"
+       : "=&a" (vval)
+       : "a" (i), "a" (v)
+       : "a15", "memory"
+       );
+}
+
+/*
+ * We use atomic_{add|sub}_return to define other functions.
+ */
+
+extern __inline__ int atomic_add_return(int i, atomic_t * v)
+{
+     unsigned int vval;
+
+    __asm__ __volatile__(
+       "rsil    a15,"__stringify(LOCKLEVEL)"\n\t"
+       "l32i    %0, %2, 0             \n\t"
+       "add     %0, %0, %1            \n\t"
+       "s32i    %0, %2, 0             \n\t"
+       "wsr     a15, "__stringify(PS)"      \n\t"
+       "rsync                         \n"
+       : "=&a" (vval)
+       : "a" (i), "a" (v)
+       : "a15", "memory"
+       );
+
+    return vval;
+}
+
+extern __inline__ int atomic_sub_return(int i, atomic_t * v)
+{
+    unsigned int vval;
+
+    __asm__ __volatile__(
+       "rsil    a15,"__stringify(LOCKLEVEL)"\n\t"
+       "l32i    %0, %2, 0             \n\t"
+       "sub     %0, %0, %1            \n\t"
+       "s32i    %0, %2, 0             \n\t"
+       "wsr     a15, "__stringify(PS)"       \n\t"
+       "rsync                         \n"
+       : "=&a" (vval)
+       : "a" (i), "a" (v)
+       : "a15", "memory"
+       );
+
+    return vval;
+}
+
+/**
+ * atomic_sub_and_test - subtract value from variable and test result
+ * @i: integer value to subtract
+ * @v: pointer of type atomic_t
+ *
+ * Atomically subtracts @i from @v and returns
+ * true if the result is zero, or false for all
+ * other cases.
+ */
+#define atomic_sub_and_test(i,v) (atomic_sub_return((i),(v)) == 0)
+
+/**
+ * atomic_inc - increment atomic variable
+ * @v: pointer of type atomic_t
+ *
+ * Atomically increments @v by 1.
+ */
+#define atomic_inc(v) atomic_add(1,(v))
+
+/**
+ * atomic_inc - increment atomic variable
+ * @v: pointer of type atomic_t
+ *
+ * Atomically increments @v by 1.
+ */
+#define atomic_inc_return(v) atomic_add_return(1,(v))
+
+/**
+ * atomic_dec - decrement atomic variable
+ * @v: pointer of type atomic_t
+ *
+ * Atomically decrements @v by 1.
+ */
+#define atomic_dec(v) atomic_sub(1,(v))
+
+/**
+ * atomic_dec_return - decrement atomic variable
+ * @v: pointer of type atomic_t
+ *
+ * Atomically decrements @v by 1.
+ */
+#define atomic_dec_return(v) atomic_sub_return(1,(v))
+
+/**
+ * atomic_dec_and_test - decrement and test
+ * @v: pointer of type atomic_t
+ *
+ * Atomically decrements @v by 1 and
+ * returns true if the result is 0, or false for all other
+ * cases.
+ */
+#define atomic_dec_and_test(v) (atomic_sub_return(1,(v)) == 0)
+
+/**
+ * atomic_inc_and_test - increment and test
+ * @v: pointer of type atomic_t
+ *
+ * Atomically increments @v by 1
+ * and returns true if the result is zero, or false for all
+ * other cases.
+ */
+#define atomic_inc_and_test(v) (atomic_add_return(1,(v)) == 0)
+
+/**
+ * atomic_add_negative - add and test if negative
+ * @v: pointer of type atomic_t
+ * @i: integer value to add
+ *
+ * Atomically adds @i to @v and returns true
+ * if the result is negative, or false when
+ * result is greater than or equal to zero.
+ */
+#define atomic_add_negative(i,v) (atomic_add_return((i),(v)) < 0)
+
+
+extern __inline__ void atomic_clear_mask(unsigned int mask, atomic_t *v)
+{
+    unsigned int all_f = -1;
+    unsigned int vval;
+
+    __asm__ __volatile__(
+       "rsil    a15,"__stringify(LOCKLEVEL)"\n\t"
+       "l32i    %0, %2, 0             \n\t"
+       "xor     %1, %4, %3            \n\t"
+       "and     %0, %0, %4            \n\t"
+       "s32i    %0, %2, 0             \n\t"
+       "wsr     a15, "__stringify(PS)"      \n\t"
+       "rsync                         \n"
+       : "=&a" (vval), "=a" (mask)
+       : "a" (v), "a" (all_f), "1" (mask)
+       : "a15", "memory"
+       );
+}
+
+extern __inline__ void atomic_set_mask(unsigned int mask, atomic_t *v)
+{
+    unsigned int vval;
+
+    __asm__ __volatile__(
+       "rsil    a15,"__stringify(LOCKLEVEL)"\n\t"
+       "l32i    %0, %2, 0             \n\t"
+       "or      %0, %0, %1            \n\t"
+       "s32i    %0, %2, 0             \n\t"
+       "wsr     a15, "__stringify(PS)"       \n\t"
+       "rsync                         \n"
+       : "=&a" (vval)
+       : "a" (mask), "a" (v)
+       : "a15", "memory"
+       );
+}
+
+/* Atomic operations are already serializing */
+#define smp_mb__before_atomic_dec()    barrier()
+#define smp_mb__after_atomic_dec()     barrier()
+#define smp_mb__before_atomic_inc()    barrier()
+#define smp_mb__after_atomic_inc()     barrier()
+
+#endif /* __KERNEL__ */
+
+#endif /* _XTENSA_ATOMIC_H */
+
diff --git a/include/asm-xtensa/bitops.h b/include/asm-xtensa/bitops.h
new file mode 100644 (file)
index 0000000..d395ef2
--- /dev/null
@@ -0,0 +1,446 @@
+/*
+ * include/asm-xtensa/bitops.h
+ *
+ * Atomic operations that C can't guarantee us.Useful for resource counting etc.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_BITOPS_H
+#define _XTENSA_BITOPS_H
+
+#ifdef __KERNEL__
+
+#include <asm/processor.h>
+#include <asm/byteorder.h>
+#include <asm/system.h>
+
+#ifdef CONFIG_SMP
+# error SMP not supported on this architecture
+#endif
+
+static __inline__ void set_bit(int nr, volatile void * addr)
+{
+       unsigned long mask = 1 << (nr & 0x1f);
+       unsigned long *a = ((unsigned long *)addr) + (nr >> 5);
+       unsigned long flags;
+
+       local_irq_save(flags);
+       *a |= mask;
+       local_irq_restore(flags);
+}
+
+static __inline__ void __set_bit(int nr, volatile unsigned long * addr)
+{
+       unsigned long mask = 1 << (nr & 0x1f);
+       unsigned long *a = ((unsigned long *)addr) + (nr >> 5);
+
+       *a |= mask;
+}
+
+static __inline__ void clear_bit(int nr, volatile void * addr)
+{
+       unsigned long mask = 1 << (nr & 0x1f);
+       unsigned long *a = ((unsigned long *)addr) + (nr >> 5);
+       unsigned long flags;
+
+       local_irq_save(flags);
+       *a &= ~mask;
+       local_irq_restore(flags);
+}
+
+static __inline__ void __clear_bit(int nr, volatile unsigned long *addr)
+{
+       unsigned long mask = 1 << (nr & 0x1f);
+       unsigned long *a = ((unsigned long *)addr) + (nr >> 5);
+
+       *a &= ~mask;
+}
+
+/*
+ * clear_bit() doesn't provide any barrier for the compiler.
+ */
+
+#define smp_mb__before_clear_bit()     barrier()
+#define smp_mb__after_clear_bit()      barrier()
+
+static __inline__ void change_bit(int nr, volatile void * addr)
+{
+       unsigned long mask = 1 << (nr & 0x1f);
+       unsigned long *a = ((unsigned long *)addr) + (nr >> 5);
+       unsigned long flags;
+
+       local_irq_save(flags);
+       *a ^= mask;
+       local_irq_restore(flags);
+}
+
+static __inline__ void __change_bit(int nr, volatile void * addr)
+{
+       unsigned long mask = 1 << (nr & 0x1f);
+       unsigned long *a = ((unsigned long *)addr) + (nr >> 5);
+
+       *a ^= mask;
+}
+
+static __inline__ int test_and_set_bit(int nr, volatile void * addr)
+{
+       unsigned long retval;
+       unsigned long mask = 1 << (nr & 0x1f);
+       unsigned long *a = ((unsigned long *)addr) + (nr >> 5);
+       unsigned long flags;
+
+       local_irq_save(flags);
+       retval = (mask & *a) != 0;
+       *a |= mask;
+       local_irq_restore(flags);
+
+       return retval;
+}
+
+static __inline__ int __test_and_set_bit(int nr, volatile void * addr)
+{
+       unsigned long retval;
+       unsigned long mask = 1 << (nr & 0x1f);
+       unsigned long *a = ((unsigned long *)addr) + (nr >> 5);
+
+       retval = (mask & *a) != 0;
+       *a |= mask;
+
+       return retval;
+}
+
+static __inline__ int test_and_clear_bit(int nr, volatile void * addr)
+{
+       unsigned long retval;
+       unsigned long mask = 1 << (nr & 0x1f);
+       unsigned long *a = ((unsigned long *)addr) + (nr >> 5);
+       unsigned long flags;
+
+       local_irq_save(flags);
+       retval = (mask & *a) != 0;
+       *a &= ~mask;
+       local_irq_restore(flags);
+
+       return retval;
+}
+
+static __inline__ int __test_and_clear_bit(int nr, volatile void * addr)
+{
+       unsigned long mask = 1 << (nr & 0x1f);
+       unsigned long *a = ((unsigned long *)addr) + (nr >> 5);
+       unsigned long old = *a;
+
+       *a = old & ~mask;
+       return (old & mask) != 0;
+}
+
+static __inline__ int test_and_change_bit(int nr, volatile void * addr)
+{
+       unsigned long retval;
+       unsigned long mask = 1 << (nr & 0x1f);
+       unsigned long *a = ((unsigned long *)addr) + (nr >> 5);
+       unsigned long flags;
+
+       local_irq_save(flags);
+
+       retval = (mask & *a) != 0;
+       *a ^= mask;
+       local_irq_restore(flags);
+
+       return retval;
+}
+
+/*
+ * non-atomic version; can be reordered
+ */
+
+static __inline__ int __test_and_change_bit(int nr, volatile void *addr)
+{
+       unsigned long mask = 1 << (nr & 0x1f);
+       unsigned long *a = ((unsigned long *)addr) + (nr >> 5);
+       unsigned long old = *a;
+
+       *a = old ^ mask;
+       return (old & mask) != 0;
+}
+
+static __inline__ int test_bit(int nr, const volatile void *addr)
+{
+       return 1UL & (((const volatile unsigned int *)addr)[nr>>5] >> (nr&31));
+}
+
+#if XCHAL_HAVE_NSAU
+
+static __inline__ int __cntlz (unsigned long x)
+{
+       int lz;
+       asm ("nsau %0, %1" : "=r" (lz) : "r" (x));
+       return 31 - lz;
+}
+
+#else
+
+static __inline__ int __cntlz (unsigned long x)
+{
+       unsigned long sum, x1, x2, x4, x8, x16;
+       x1  = x & 0xAAAAAAAA;
+       x2  = x & 0xCCCCCCCC;
+       x4  = x & 0xF0F0F0F0;
+       x8  = x & 0xFF00FF00;
+       x16 = x & 0xFFFF0000;
+       sum = x2 ? 2 : 0;
+       sum += (x16 != 0) * 16;
+       sum += (x8 != 0) * 8;
+       sum += (x4 != 0) * 4;
+       sum += (x1 != 0);
+
+       return sum;
+}
+
+#endif
+
+/*
+ * ffz: Find first zero in word. Undefined if no zero exists.
+ * bit 0 is the LSB of addr; bit 32 is the LSB of (addr+1).
+ */
+
+static __inline__ int ffz(unsigned long x)
+{
+       if ((x = ~x) == 0)
+               return 32;
+       return __cntlz(x & -x);
+}
+
+/*
+ * __ffs: Find first bit set in word. Return 0 for bit 0
+ */
+
+static __inline__ int __ffs(unsigned long x)
+{
+       return __cntlz(x & -x);
+}
+
+/*
+ * ffs: Find first bit set in word. This is defined the same way as
+ * the libc and compiler builtin ffs routines, therefore
+ * differs in spirit from the above ffz (man ffs).
+ */
+
+static __inline__ int ffs(unsigned long x)
+{
+       return __cntlz(x & -x) + 1;
+}
+
+/*
+ * fls: Find last (most-significant) bit set in word.
+ * Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32.
+ */
+
+static __inline__ int fls (unsigned int x)
+{
+       return __cntlz(x);
+}
+
+static __inline__ int
+find_next_bit(const unsigned long *addr, int size, int offset)
+{
+       const unsigned long *p = addr + (offset >> 5);
+       unsigned long result = offset & ~31UL;
+       unsigned long tmp;
+
+       if (offset >= size)
+               return size;
+       size -= result;
+       offset &= 31UL;
+       if (offset) {
+               tmp = *p++;
+               tmp &= ~0UL << offset;
+               if (size < 32)
+                       goto found_first;
+               if (tmp)
+                       goto found_middle;
+               size -= 32;
+               result += 32;
+       }
+       while (size >= 32) {
+               if ((tmp = *p++) != 0)
+                       goto found_middle;
+               result += 32;
+               size -= 32;
+       }
+       if (!size)
+               return result;
+       tmp = *p;
+
+found_first:
+       tmp &= ~0UL >> (32 - size);
+       if (tmp == 0UL) /* Are any bits set? */
+               return result + size;   /* Nope. */
+found_middle:
+       return result + __ffs(tmp);
+}
+
+/**
+ * find_first_bit - find the first set bit in a memory region
+ * @addr: The address to start the search at
+ * @size: The maximum size to search
+ *
+ * Returns the bit-number of the first set bit, not the number of the byte
+ * containing a bit.
+ */
+
+#define find_first_bit(addr, size) \
+        find_next_bit((addr), (size), 0)
+
+static __inline__ int
+find_next_zero_bit(const unsigned long *addr, int size, int offset)
+{
+       const unsigned long *p = addr + (offset >> 5);
+       unsigned long result = offset & ~31UL;
+       unsigned long 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 find_first_zero_bit(addr, size) \
+        find_next_zero_bit((addr), (size), 0)
+
+#ifdef __XTENSA_EL__
+# define ext2_set_bit(nr,addr) __test_and_set_bit((nr), (addr))
+# define ext2_set_bit_atomic(lock,nr,addr) test_and_set_bit((nr),(addr))
+# define ext2_clear_bit(nr,addr) __test_and_clear_bit((nr), (addr))
+# define ext2_clear_bit_atomic(lock,nr,addr) test_and_clear_bit((nr),(addr))
+# define ext2_test_bit(nr,addr) test_bit((nr), (addr))
+# define ext2_find_first_zero_bit(addr, size) find_first_zero_bit((addr),(size))
+# define ext2_find_next_zero_bit(addr, size, offset) \
+                find_next_zero_bit((addr), (size), (offset))
+#elif defined(__XTENSA_EB__)
+# define ext2_set_bit(nr,addr) __test_and_set_bit((nr) ^ 0x18, (addr))
+# define ext2_set_bit_atomic(lock,nr,addr) test_and_set_bit((nr) ^ 0x18, (addr))
+# define ext2_clear_bit(nr,addr) __test_and_clear_bit((nr) ^ 18, (addr))
+# define ext2_clear_bit_atomic(lock,nr,addr) test_and_clear_bit((nr)^0x18,(addr))
+# define ext2_test_bit(nr,addr) test_bit((nr) ^ 0x18, (addr))
+# define ext2_find_first_zero_bit(addr, size) \
+        ext2_find_next_zero_bit((addr), (size), 0)
+
+static __inline__ unsigned long ext2_find_next_zero_bit(void *addr, unsigned long size, unsigned long offset)
+{
+       unsigned long *p = ((unsigned long *) addr) + (offset >> 5);
+       unsigned long result = offset & ~31UL;
+       unsigned long tmp;
+
+       if (offset >= size)
+               return size;
+       size -= result;
+       offset &= 31UL;
+       if(offset) {
+               /* We hold the little endian value in tmp, but then the
+                * shift is illegal. So we could keep a big endian value
+                * in tmp, like this:
+                *
+                * tmp = __swab32(*(p++));
+                * tmp |= ~0UL >> (32-offset);
+                *
+                * but this would decrease preformance, so we change the
+                * shift:
+                */
+               tmp = *(p++);
+               tmp |= __swab32(~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 is little endian, so we would have to swab the shift,
+        * see above. But then we have to swab tmp below for ffz, so
+        * we might as well do this here.
+        */
+       return result + ffz(__swab32(tmp) | (~0UL << size));
+found_middle:
+       return result + ffz(__swab32(tmp));
+}
+
+#else
+# error processor byte order undefined!
+#endif
+
+
+#define hweight32(x)   generic_hweight32(x)
+#define hweight16(x)   generic_hweight16(x)
+#define hweight8(x)    generic_hweight8(x)
+
+/*
+ * Find the first bit set in a 140-bit bitmap.
+ * The first 100 bits are unlikely to be set.
+ */
+
+static inline int sched_find_first_bit(const unsigned long *b)
+{
+       if (unlikely(b[0]))
+               return __ffs(b[0]);
+       if (unlikely(b[1]))
+               return __ffs(b[1]) + 32;
+       if (unlikely(b[2]))
+               return __ffs(b[2]) + 64;
+       if (b[3])
+               return __ffs(b[3]) + 96;
+       return __ffs(b[4]) + 128;
+}
+
+
+/* Bitmap functions for the minix filesystem.  */
+
+#define minix_test_and_set_bit(nr,addr) test_and_set_bit(nr,addr)
+#define minix_set_bit(nr,addr) set_bit(nr,addr)
+#define minix_test_and_clear_bit(nr,addr) test_and_clear_bit(nr,addr)
+#define minix_test_bit(nr,addr) test_bit(nr,addr)
+#define minix_find_first_zero_bit(addr,size) find_first_zero_bit(addr,size)
+
+#endif /* __KERNEL__ */
+
+#endif /* _XTENSA_BITOPS_H */
diff --git a/include/asm-xtensa/bootparam.h b/include/asm-xtensa/bootparam.h
new file mode 100644 (file)
index 0000000..9983f2c
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * include/asm-xtensa/bootparam.h
+ *
+ * Definition of the Linux/Xtensa boot parameter structure
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005  Tensilica Inc.
+ *
+ * (Concept borrowed from the 68K port)
+ */
+
+#ifndef _XTENSA_BOOTPARAM_H
+#define _XTENSA_BOOTPARAM_H
+
+#define BP_VERSION 0x0001
+
+#define BP_TAG_COMMAND_LINE    0x1001  /* command line (0-terminated string)*/
+#define BP_TAG_INITRD          0x1002  /* ramdisk addr and size (bp_meminfo) */
+#define BP_TAG_MEMORY          0x1003  /* memory addr and size (bp_meminfo) */
+#define BP_TAG_SERIAL_BAUSRATE 0x1004  /* baud rate of current console. */
+#define BP_TAG_SERIAL_PORT     0x1005  /* serial device of current console */
+
+#define BP_TAG_FIRST           0x7B0B  /* first tag with a version number */
+#define BP_TAG_LAST            0x7E0B  /* last tag */
+
+#ifndef __ASSEMBLY__
+
+/* All records are aligned to 4 bytes */
+
+typedef struct bp_tag {
+  unsigned short id;           /* tag id */
+  unsigned short size;         /* size of this record excluding the structure*/
+  unsigned long data[0];       /* data */
+} bp_tag_t;
+
+typedef struct meminfo {
+  unsigned long type;
+  unsigned long start;
+  unsigned long end;
+} meminfo_t;
+
+#define SYSMEM_BANKS_MAX 5
+
+#define MEMORY_TYPE_CONVENTIONAL       0x1000
+#define MEMORY_TYPE_NONE               0x2000
+
+typedef struct sysmem_info {
+  int nr_banks;
+  meminfo_t bank[SYSMEM_BANKS_MAX];
+} sysmem_info_t;
+
+extern sysmem_info_t sysmem;
+
+#endif
+#endif
+
+
+
diff --git a/include/asm-xtensa/bug.h b/include/asm-xtensa/bug.h
new file mode 100644 (file)
index 0000000..5670365
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * include/asm-xtensa/bug.h
+ *
+ * Macros to cause a 'bug' message.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_BUG_H
+#define _XTENSA_BUG_H
+
+#include <linux/stringify.h>
+
+#define ILL    __asm__ __volatile__ (".byte 0,0,0\n")
+
+#ifdef CONFIG_KALLSYMS
+# define BUG() do {                                                    \
+       printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__);           \
+       ILL;                                                            \
+} while (0)
+#else
+# define BUG() do {                                                    \
+       printk("kernel BUG!\n");                                        \
+       ILL;                                                            \
+} while (0)
+#endif
+
+#define BUG_ON(condition) do { if (unlikely((condition)!=0)) BUG(); } while(0)
+#define PAGE_BUG(page) do {  BUG(); } while (0)
+#define WARN_ON(condition) do {                                                   \
+  if (unlikely((condition)!=0)) {                                         \
+    printk ("Warning in %s at %s:%d\n", __FUNCTION__, __FILE__, __LINE__); \
+      dump_stack();                                                       \
+  }                                                                       \
+} while (0)
+
+#endif /* _XTENSA_BUG_H */
diff --git a/include/asm-xtensa/bugs.h b/include/asm-xtensa/bugs.h
new file mode 100644 (file)
index 0000000..c422853
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ * include/asm-xtensa/bugs.h
+ *
+ * This is included by init/main.c to check for architecture-dependent bugs.
+ *
+ * Xtensa processors don't have any bugs.  :)
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file "COPYING" in the main directory of
+ * this archive for more details.
+ */
+
+#ifndef _XTENSA_BUGS_H
+#define _XTENSA_BUGS_H
+
+#include <asm/processor.h>
+
+static void __init check_bugs(void)
+{
+}
+
+#endif /* _XTENSA_BUGS_H */
diff --git a/include/asm-xtensa/byteorder.h b/include/asm-xtensa/byteorder.h
new file mode 100644 (file)
index 0000000..0b15525
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * include/asm-xtensa/byteorder.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_BYTEORDER_H
+#define _XTENSA_BYTEORDER_H
+
+#include <asm/processor.h>
+#include <asm/types.h>
+
+static __inline__ __const__ __u32 ___arch__swab32(__u32 x)
+{
+    __u32 res;
+    /* instruction sequence from Xtensa ISA release 2/2000 */
+    __asm__("ssai     8           \n\t"
+           "srli     %0, %1, 16  \n\t"
+           "src      %0, %0, %1  \n\t"
+           "src      %0, %0, %0  \n\t"
+           "src      %0, %1, %0  \n"
+           : "=&a" (res)
+           : "a" (x)
+           );
+    return res;
+}
+
+static __inline__ __const__ __u16 ___arch__swab16(__u16 x)
+{
+    /* Given that 'short' values are signed (i.e., can be negative),
+     * we cannot assume that the upper 16-bits of the register are
+     * zero.  We are careful to mask values after shifting.
+     */
+
+    /* There exists an anomaly between xt-gcc and xt-xcc.  xt-gcc
+     * inserts an extui instruction after putting this function inline
+     * to ensure that it uses only the least-significant 16 bits of
+     * the result.  xt-xcc doesn't use an extui, but assumes the
+     * __asm__ macro follows convention that the upper 16 bits of an
+     * 'unsigned short' result are still zero.  This macro doesn't
+     * follow convention; indeed, it leaves garbage in the upport 16
+     * bits of the register.
+
+     * Declaring the temporary variables 'res' and 'tmp' to be 32-bit
+     * types while the return type of the function is a 16-bit type
+     * forces both compilers to insert exactly one extui instruction
+     * (or equivalent) to mask off the upper 16 bits. */
+
+    __u32 res;
+    __u32 tmp;
+
+    __asm__("extui    %1, %2, 8, 8\n\t"
+           "slli     %0, %2, 8   \n\t"
+           "or       %0, %0, %1  \n"
+           : "=&a" (res), "=&a" (tmp)
+           : "a" (x)
+           );
+
+    return res;
+}
+
+#define __arch__swab32(x) ___arch__swab32(x)
+#define __arch__swab16(x) ___arch__swab16(x)
+
+#if !defined(__STRICT_ANSI__) || defined(__KERNEL__)
+#  define __BYTEORDER_HAS_U64__
+#  define __SWAB_64_THRU_32__
+#endif
+
+#ifdef __XTENSA_EL__
+# include <linux/byteorder/little_endian.h>
+#elif defined(__XTENSA_EB__)
+# include <linux/byteorder/big_endian.h>
+#else
+# error processor byte order undefined!
+#endif
+
+#endif /* __ASM_XTENSA_BYTEORDER_H */
diff --git a/include/asm-xtensa/cache.h b/include/asm-xtensa/cache.h
new file mode 100644 (file)
index 0000000..5aae3f1
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * include/asm-xtensa/cacheflush.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ * 2 of the License, or (at your option) any later version.
+ *
+ * (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_CACHE_H
+#define _XTENSA_CACHE_H
+
+#include <xtensa/config/core.h>
+
+#if XCHAL_ICACHE_SIZE > 0
+# if (XCHAL_ICACHE_SIZE % (XCHAL_ICACHE_LINESIZE*XCHAL_ICACHE_WAYS*4)) != 0
+#  error cache configuration outside expected/supported range!
+# endif
+#endif
+
+#if XCHAL_DCACHE_SIZE > 0
+# if (XCHAL_DCACHE_SIZE % (XCHAL_DCACHE_LINESIZE*XCHAL_DCACHE_WAYS*4)) != 0
+#  error cache configuration outside expected/supported range!
+# endif
+#endif
+
+#define L1_CACHE_SHIFT         XCHAL_CACHE_LINEWIDTH_MAX
+#define L1_CACHE_BYTES         XCHAL_CACHE_LINESIZE_MAX
+
+#endif /* _XTENSA_CACHE_H */
diff --git a/include/asm-xtensa/cacheflush.h b/include/asm-xtensa/cacheflush.h
new file mode 100644 (file)
index 0000000..44a36e0
--- /dev/null
@@ -0,0 +1,122 @@
+/*
+ * include/asm-xtensa/cacheflush.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_CACHEFLUSH_H
+#define _XTENSA_CACHEFLUSH_H
+
+#ifdef __KERNEL__
+
+#include <linux/mm.h>
+#include <asm/processor.h>
+#include <asm/page.h>
+
+/*
+ * flush and invalidate data cache, invalidate instruction cache:
+ *
+ * __flush_invalidate_cache_all()
+ * __flush_invalidate_cache_range(from,sze)
+ *
+ * invalidate data or instruction cache:
+ *
+ * __invalidate_icache_all()
+ * __invalidate_icache_page(adr)
+ * __invalidate_dcache_page(adr)
+ * __invalidate_icache_range(from,size)
+ * __invalidate_dcache_range(from,size)
+ *
+ * flush data cache:
+ *
+ * __flush_dcache_page(adr)
+ *
+ * flush and invalidate data cache:
+ *
+ * __flush_invalidate_dcache_all()
+ * __flush_invalidate_dcache_page(adr)
+ * __flush_invalidate_dcache_range(from,size)
+ */
+
+extern void __flush_invalidate_cache_all(void);
+extern void __flush_invalidate_cache_range(unsigned long, unsigned long);
+extern void __flush_invalidate_dcache_all(void);
+extern void __invalidate_icache_all(void);
+
+extern void __invalidate_dcache_page(unsigned long);
+extern void __invalidate_icache_page(unsigned long);
+extern void __invalidate_icache_range(unsigned long, unsigned long);
+extern void __invalidate_dcache_range(unsigned long, unsigned long);
+
+#if XCHAL_DCACHE_IS_WRITEBACK
+extern void __flush_dcache_page(unsigned long);
+extern void __flush_invalidate_dcache_page(unsigned long);
+extern void __flush_invalidate_dcache_range(unsigned long, unsigned long);
+#else
+# define __flush_dcache_page(p)                                do { } while(0)
+# define __flush_invalidate_dcache_page(p)             do { } while(0)
+# define __flush_invalidate_dcache_range(p,s)          do { } while(0)
+#endif
+
+/*
+ * We have physically tagged caches - nothing to do here -
+ * unless we have cache aliasing.
+ *
+ * Pages can get remapped. Because this might change the 'color' of that page,
+ * we have to flush the cache before the PTE is changed.
+ * (see also Documentation/cachetlb.txt)
+ */
+
+#if (DCACHE_WAY_SIZE > PAGE_SIZE) && XCHAL_DCACHE_IS_WRITEBACK
+
+#define flush_cache_all()              __flush_invalidate_cache_all();
+#define flush_cache_mm(mm)             __flush_invalidate_cache_all();
+
+#define flush_cache_vmap(start,end)    __flush_invalidate_cache_all();
+#define flush_cache_vunmap(start,end)  __flush_invalidate_cache_all();
+
+extern void flush_dcache_page(struct page*);
+
+extern void flush_cache_range(struct vm_area_struct*, ulong, ulong);
+extern void flush_cache_page(struct vm_area_struct*, unsigned long, unsigned long);
+
+#else
+
+#define flush_cache_all()                              do { } while (0)
+#define flush_cache_mm(mm)                             do { } while (0)
+
+#define flush_cache_vmap(start,end)                    do { } while (0)
+#define flush_cache_vunmap(start,end)                  do { } while (0)
+
+#define flush_dcache_page(page)                                do { } while (0)
+
+#define flush_cache_page(vma,addr,pfn)                 do { } while (0)
+#define flush_cache_range(vma,start,end)               do { } while (0)
+
+#endif
+
+#define flush_icache_range(start,end)                                  \
+       __invalidate_icache_range(start,(end)-(start))
+
+/* This is not required, see Documentation/cachetlb.txt */
+
+#define        flush_icache_page(vma,page)                     do { } while(0)
+
+#define flush_dcache_mmap_lock(mapping)                        do { } while (0)
+#define flush_dcache_mmap_unlock(mapping)              do { } while (0)
+
+
+#define copy_to_user_page(vma, page, vaddr, dst, src, len) \
+       memcpy(dst, src, len)
+
+#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
+       memcpy(dst, src, len)
+
+#endif /* __KERNEL__ */
+
+#endif /* _XTENSA_CACHEFLUSH_H */
+
diff --git a/include/asm-xtensa/checksum.h b/include/asm-xtensa/checksum.h
new file mode 100644 (file)
index 0000000..1a00fad
--- /dev/null
@@ -0,0 +1,264 @@
+/*
+ * include/asm-xtensa/checksum.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_CHECKSUM_H
+#define _XTENSA_CHECKSUM_H
+
+#include <linux/config.h>
+#include <linux/in6.h>
+#include <xtensa/config/core.h>
+
+/*
+ * computes the checksum of a memory block at buff, length len,
+ * and adds in "sum" (32-bit)
+ *
+ * returns a 32-bit number suitable for feeding into itself
+ * or csum_tcpudp_magic
+ *
+ * this function must be called with even lengths, except
+ * for the last fragment, which may be odd
+ *
+ * it's best to have buff aligned on a 32-bit boundary
+ */
+asmlinkage unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum);
+
+/*
+ * the same as csum_partial, but copies from src while it
+ * checksums, and handles user-space pointer exceptions correctly, when needed.
+ *
+ * here even more important to align src and dst on a 32-bit (or even
+ * better 64-bit) boundary
+ */
+
+asmlinkage unsigned int csum_partial_copy_generic( const char *src, char *dst, int len, int sum,
+                                                  int *src_err_ptr, int *dst_err_ptr);
+
+/*
+ *     Note: when you get a NULL pointer exception here this means someone
+ *     passed in an incorrect kernel address to one of these functions.
+ *
+ *     If you use these functions directly please don't forget the
+ *     verify_area().
+ */
+extern __inline__
+unsigned int csum_partial_copy_nocheck ( const char *src, char *dst,
+                                       int len, int sum)
+{
+       return csum_partial_copy_generic ( src, dst, len, sum, NULL, NULL);
+}
+
+extern __inline__
+unsigned int csum_partial_copy_from_user ( const char *src, char *dst,
+                                               int len, int sum, int *err_ptr)
+{
+       return csum_partial_copy_generic ( src, dst, len, sum, err_ptr, NULL);
+}
+
+/*
+ * These are the old (and unsafe) way of doing checksums, a warning message will be
+ * printed if they are used and an exeption occurs.
+ *
+ * these functions should go away after some time.
+ */
+
+#define csum_partial_copy_fromuser csum_partial_copy
+unsigned int csum_partial_copy( const char *src, char *dst, int len, int sum);
+
+/*
+ *     Fold a partial checksum
+ */
+
+static __inline__ unsigned int csum_fold(unsigned int sum)
+{
+       unsigned int __dummy;
+       __asm__("extui  %1, %0, 16, 16\n\t"
+               "extui  %0 ,%0, 0, 16\n\t"
+               "add    %0, %0, %1\n\t"
+               "slli   %1, %0, 16\n\t"
+               "add    %0, %0, %1\n\t"
+               "extui  %0, %0, 16, 16\n\t"
+               "neg    %0, %0\n\t"
+               "addi   %0, %0, -1\n\t"
+               "extui  %0, %0, 0, 16\n\t"
+               : "=r" (sum), "=&r" (__dummy)
+               : "0" (sum));
+       return sum;
+}
+
+/*
+ *     This is a version of ip_compute_csum() optimized for IP headers,
+ *     which always checksum on 4 octet boundaries.
+ */
+static __inline__ unsigned short ip_fast_csum(unsigned char * iph, unsigned int ihl)
+{
+       unsigned int sum, tmp, endaddr;
+
+       __asm__ __volatile__(
+               "sub            %0, %0, %0\n\t"
+#if XCHAL_HAVE_LOOPS
+               "loopgtz        %2, 2f\n\t"
+#else
+               "beqz           %2, 2f\n\t"
+               "slli           %4, %2, 2\n\t"
+               "add            %4, %4, %1\n\t"
+               "0:\t"
+#endif
+               "l32i           %3, %1, 0\n\t"
+               "add            %0, %0, %3\n\t"
+               "bgeu           %0, %3, 1f\n\t"
+               "addi           %0, %0, 1\n\t"
+               "1:\t"
+               "addi           %1, %1, 4\n\t"
+#if !XCHAL_HAVE_LOOPS
+               "blt            %1, %4, 0b\n\t"
+#endif
+               "2:\t"
+       /* Since the input registers which are loaded with iph and ihl
+          are modified, we must also specify them as outputs, or gcc
+          will assume they contain their original values. */
+               : "=r" (sum), "=r" (iph), "=r" (ihl), "=&r" (tmp), "=&r" (endaddr)
+               : "1" (iph), "2" (ihl));
+
+       return  csum_fold(sum);
+}
+
+static __inline__ unsigned long csum_tcpudp_nofold(unsigned long saddr,
+                                                  unsigned long daddr,
+                                                  unsigned short len,
+                                                  unsigned short proto,
+                                                  unsigned int sum)
+{
+
+#ifdef __XTENSA_EL__
+       unsigned long len_proto = (ntohs(len)<<16)+proto*256;
+#elif defined(__XTENSA_EB__)
+       unsigned long len_proto = (proto<<16)+len;
+#else
+# error processor byte order undefined!
+#endif
+       __asm__("add    %0, %0, %1\n\t"
+               "bgeu   %0, %1, 1f\n\t"
+               "addi   %0, %0, 1\n\t"
+               "1:\t"
+               "add    %0, %0, %2\n\t"
+               "bgeu   %0, %2, 1f\n\t"
+               "addi   %0, %0, 1\n\t"
+               "1:\t"
+               "add    %0, %0, %3\n\t"
+               "bgeu   %0, %3, 1f\n\t"
+               "addi   %0, %0, 1\n\t"
+               "1:\t"
+               : "=r" (sum), "=r" (len_proto)
+               : "r" (daddr), "r" (saddr), "1" (len_proto), "0" (sum));
+       return sum;
+}
+
+/*
+ * computes the checksum of the TCP/UDP pseudo-header
+ * returns a 16-bit checksum, already complemented
+ */
+static __inline__ unsigned short int csum_tcpudp_magic(unsigned long saddr,
+                                                      unsigned long daddr,
+                                                      unsigned short len,
+                                                      unsigned short proto,
+                                                      unsigned int sum)
+{
+       return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum));
+}
+
+/*
+ * this routine is used for miscellaneous IP-like checksums, mainly
+ * in icmp.c
+ */
+
+static __inline__ unsigned short ip_compute_csum(unsigned char * buff, int len)
+{
+    return csum_fold (csum_partial(buff, len, 0));
+}
+
+#define _HAVE_ARCH_IPV6_CSUM
+static __inline__ unsigned short int csum_ipv6_magic(struct in6_addr *saddr,
+                                                    struct in6_addr *daddr,
+                                                    __u32 len,
+                                                    unsigned short proto,
+                                                    unsigned int sum)
+{
+       unsigned int __dummy;
+       __asm__("l32i   %1, %2, 0\n\t"
+               "add    %0, %0, %1\n\t"
+               "bgeu   %0, %1, 1f\n\t"
+               "addi   %0, %0, 1\n\t"
+               "1:\t"
+               "l32i   %1, %2, 4\n\t"
+               "add    %0, %0, %1\n\t"
+               "bgeu   %0, %1, 1f\n\t"
+               "addi   %0, %0, 1\n\t"
+               "1:\t"
+               "l32i   %1, %2, 8\n\t"
+               "add    %0, %0, %1\n\t"
+               "bgeu   %0, %1, 1f\n\t"
+               "addi   %0, %0, 1\n\t"
+               "1:\t"
+               "l32i   %1, %2, 12\n\t"
+               "add    %0, %0, %1\n\t"
+               "bgeu   %0, %1, 1f\n\t"
+               "addi   %0, %0, 1\n\t"
+               "1:\t"
+               "l32i   %1, %3, 0\n\t"
+               "add    %0, %0, %1\n\t"
+               "bgeu   %0, %1, 1f\n\t"
+               "addi   %0, %0, 1\n\t"
+               "1:\t"
+               "l32i   %1, %3, 4\n\t"
+               "add    %0, %0, %1\n\t"
+               "bgeu   %0, %1, 1f\n\t"
+               "addi   %0, %0, 1\n\t"
+               "1:\t"
+               "l32i   %1, %3, 8\n\t"
+               "add    %0, %0, %1\n\t"
+               "bgeu   %0, %1, 1f\n\t"
+               "addi   %0, %0, 1\n\t"
+               "1:\t"
+               "l32i   %1, %3, 12\n\t"
+               "add    %0, %0, %1\n\t"
+               "bgeu   %0, %1, 1f\n\t"
+               "addi   %0, %0, 1\n\t"
+               "1:\t"
+               "add    %0, %0, %4\n\t"
+               "bgeu   %0, %4, 1f\n\t"
+               "addi   %0, %0, 1\n\t"
+               "1:\t"
+               "add    %0, %0, %5\n\t"
+               "bgeu   %0, %5, 1f\n\t"
+               "addi   %0, %0, 1\n\t"
+               "1:\t"
+               : "=r" (sum), "=&r" (__dummy)
+               : "r" (saddr), "r" (daddr),
+                 "r" (htonl(len)), "r" (htonl(proto)), "0" (sum));
+
+       return csum_fold(sum);
+}
+
+/*
+ *     Copy and checksum to user
+ */
+#define HAVE_CSUM_COPY_USER
+static __inline__ unsigned int csum_and_copy_to_user (const char *src, char *dst,
+                                   int len, int sum, int *err_ptr)
+{
+       if (access_ok(VERIFY_WRITE, dst, len))
+               return csum_partial_copy_generic(src, dst, len, sum, NULL, err_ptr);
+
+       if (len)
+               *err_ptr = -EFAULT;
+
+       return -1; /* invalid checksum */
+}
+#endif
diff --git a/include/asm-xtensa/coprocessor.h b/include/asm-xtensa/coprocessor.h
new file mode 100644 (file)
index 0000000..a91b96d
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * include/asm-xtensa/cpextra.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2003 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_COPROCESSOR_H
+#define _XTENSA_COPROCESSOR_H
+
+#include <xtensa/config/core.h>
+
+#define XTOFS(last_start,last_size,align) \
+       ((last_start+last_size+align-1) & -align)
+
+#define XTENSA_CP_EXTRA_OFFSET 0
+#define XTENSA_CP_EXTRA_ALIGN  XCHAL_EXTRA_SA_ALIGN
+
+#define XTENSA_CPE_CP0_OFFSET  \
+       XTOFS(XTENSA_CP_EXTRA_OFFSET, XCHAL_EXTRA_SA_SIZE, XCHAL_CP0_SA_ALIGN)
+#define XTENSA_CPE_CP1_OFFSET  \
+       XTOFS(XTENSA_CPE_CP0_OFFSET, XCHAL_CP0_SA_SIZE, XCHAL_CP1_SA_ALIGN)
+#define XTENSA_CPE_CP2_OFFSET  \
+       XTOFS(XTENSA_CPE_CP1_OFFSET, XCHAL_CP1_SA_SIZE, XCHAL_CP2_SA_ALIGN)
+#define XTENSA_CPE_CP3_OFFSET  \
+       XTOFS(XTENSA_CPE_CP2_OFFSET, XCHAL_CP2_SA_SIZE, XCHAL_CP3_SA_ALIGN)
+#define XTENSA_CPE_CP4_OFFSET  \
+       XTOFS(XTENSA_CPE_CP3_OFFSET, XCHAL_CP3_SA_SIZE, XCHAL_CP4_SA_ALIGN)
+#define XTENSA_CPE_CP5_OFFSET  \
+       XTOFS(XTENSA_CPE_CP4_OFFSET, XCHAL_CP4_SA_SIZE, XCHAL_CP5_SA_ALIGN)
+#define XTENSA_CPE_CP6_OFFSET  \
+       XTOFS(XTENSA_CPE_CP5_OFFSET, XCHAL_CP5_SA_SIZE, XCHAL_CP6_SA_ALIGN)
+#define XTENSA_CPE_CP7_OFFSET  \
+       XTOFS(XTENSA_CPE_CP6_OFFSET, XCHAL_CP6_SA_SIZE, XCHAL_CP7_SA_ALIGN)
+#define XTENSA_CP_EXTRA_SIZE   \
+       XTOFS(XTENSA_CPE_CP7_OFFSET, XCHAL_CP7_SA_SIZE, 16)
+
+#if XCHAL_CP_NUM > 0
+# ifndef __ASSEMBLY__
+/*
+ * Tasks that own contents of (last user) each coprocessor.
+ * Entries are 0 for not-owned or non-existent coprocessors.
+ * Note: The size of this structure is fixed to 8 bytes in entry.S
+ */
+typedef struct {
+       struct task_struct *owner;      /* owner */
+       int offset;                     /* offset in cpextra space. */
+} coprocessor_info_t;
+# else
+#  define COPROCESSOR_INFO_OWNER 0
+#  define COPROCESSOR_INFO_OFFSET 4
+#  define COPROCESSOR_INFO_SIZE 8
+# endif
+#endif
+
+
+#ifndef __ASSEMBLY__
+# if XCHAL_CP_NUM > 0
+struct task_struct;
+extern void release_coprocessors (struct task_struct*);
+extern void save_coprocessor_registers(void*, int);
+# else
+#  define release_coprocessors(task)
+# endif
+#endif
+
+#endif /* _XTENSA_COPROCESSOR_H */
diff --git a/include/asm-xtensa/cpumask.h b/include/asm-xtensa/cpumask.h
new file mode 100644 (file)
index 0000000..ebeede3
--- /dev/null
@@ -0,0 +1,16 @@
+/*
+ * include/asm-xtensa/cpumask.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_CPUMASK_H
+#define _XTENSA_CPUMASK_H
+
+#include <asm-generic/cpumask.h>
+
+#endif /* _XTENSA_CPUMASK_H */
diff --git a/include/asm-xtensa/cputime.h b/include/asm-xtensa/cputime.h
new file mode 100644 (file)
index 0000000..a7fb864
--- /dev/null
@@ -0,0 +1,6 @@
+#ifndef _XTENSA_CPUTIME_H
+#define _XTENSA_CPUTIME_H
+
+#include <asm-generic/cputime.h>
+
+#endif /* _XTENSA_CPUTIME_H */
diff --git a/include/asm-xtensa/current.h b/include/asm-xtensa/current.h
new file mode 100644 (file)
index 0000000..8d1eb5d
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * include/asm-xtensa/current.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_CURRENT_H
+#define _XTENSA_CURRENT_H
+
+#ifndef __ASSEMBLY__
+
+#include <linux/thread_info.h>
+
+struct task_struct;
+
+static inline struct task_struct *get_current(void)
+{
+       return current_thread_info()->task;
+}
+
+#define current get_current()
+
+#else
+
+#define CURRENT_SHIFT 13
+
+#define GET_CURRENT(reg,sp)            \
+       GET_THREAD_INFO(reg,sp);        \
+       l32i reg, reg, TI_TASK          \
+
+#endif
+
+
+#endif /* XTENSA_CURRENT_H */
diff --git a/include/asm-xtensa/delay.h b/include/asm-xtensa/delay.h
new file mode 100644 (file)
index 0000000..6359c55
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * include/asm-xtensa/delay.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ *
+ */
+
+#ifndef _XTENSA_DELAY_H
+#define _XTENSA_DELAY_H
+
+#include <linux/config.h>
+#include <asm/processor.h>
+#include <asm/param.h>
+
+extern unsigned long loops_per_jiffy;
+
+extern __inline__ void __delay(unsigned long loops)
+{
+  /* 2 cycles per loop. */
+  __asm__ __volatile__ ("1: addi %0, %0, -2; bgeui %0, 1, 1b"
+                       : "=r" (loops) : "0" (loops));
+}
+
+static __inline__ u32 xtensa_get_ccount(void)
+{
+       u32 ccount;
+       asm volatile ("rsr %0, 234; # CCOUNT\n" : "=r" (ccount));
+       return ccount;
+}
+
+/* For SMP/NUMA systems, change boot_cpu_data to something like
+ * local_cpu_data->... where local_cpu_data points to the current
+ * cpu. */
+
+static __inline__ void udelay (unsigned long usecs)
+{
+       unsigned long start = xtensa_get_ccount();
+       unsigned long cycles = usecs * (loops_per_jiffy / (1000000UL / HZ));
+
+       /* Note: all variables are unsigned (can wrap around)! */
+       while (((unsigned long)xtensa_get_ccount()) - start < cycles)
+               ;
+}
+
+#endif
+
diff --git a/include/asm-xtensa/div64.h b/include/asm-xtensa/div64.h
new file mode 100644 (file)
index 0000000..c4a1057
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ * include/asm-xtensa/div64.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_DIV64_H
+#define _XTENSA_DIV64_H
+
+#define do_div(n,base) ({ \
+       int __res = n % ((unsigned int) base); \
+       n /= (unsigned int) base; \
+       __res; })
+
+#endif
diff --git a/include/asm-xtensa/dma-mapping.h b/include/asm-xtensa/dma-mapping.h
new file mode 100644 (file)
index 0000000..e86a206
--- /dev/null
@@ -0,0 +1,182 @@
+/*
+ * include/asm-xtensa/dma_mapping.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2003 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_DMA_MAPPING_H
+#define _XTENSA_DMA_MAPPING_H
+
+#include <asm/scatterlist.h>
+#include <asm/cache.h>
+#include <asm/io.h>
+#include <linux/mm.h>
+
+/*
+ * DMA-consistent mapping functions.
+ */
+
+extern void *consistent_alloc(int, size_t, dma_addr_t, unsigned long);
+extern void consistent_free(void*, size_t, dma_addr_t);
+extern void consistent_sync(void*, size_t, int);
+
+#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
+#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
+
+void *dma_alloc_coherent(struct device *dev, size_t size,
+                          dma_addr_t *dma_handle, int flag);
+
+void dma_free_coherent(struct device *dev, size_t size,
+                        void *vaddr, dma_addr_t dma_handle);
+
+static inline dma_addr_t
+dma_map_single(struct device *dev, void *ptr, size_t size,
+              enum dma_data_direction direction)
+{
+       BUG_ON(direction == DMA_NONE);
+       consistent_sync(ptr, size, direction);
+       return virt_to_phys(ptr);
+}
+
+static inline void
+dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
+                enum dma_data_direction direction)
+{
+       BUG_ON(direction == DMA_NONE);
+}
+
+static inline int
+dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
+          enum dma_data_direction direction)
+{
+       int i;
+
+       BUG_ON(direction == DMA_NONE);
+
+       for (i = 0; i < nents; i++, sg++ ) {
+               BUG_ON(!sg->page);
+
+               sg->dma_address = page_to_phys(sg->page) + sg->offset;
+               consistent_sync(page_address(sg->page) + sg->offset,
+                               sg->length, direction);
+       }
+
+       return nents;
+}
+
+static inline dma_addr_t
+dma_map_page(struct device *dev, struct page *page, unsigned long offset,
+            size_t size, enum dma_data_direction direction)
+{
+       BUG_ON(direction == DMA_NONE);
+       return (dma_addr_t)(page_to_pfn(page)) * PAGE_SIZE + offset;
+}
+
+static inline void
+dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size,
+              enum dma_data_direction direction)
+{
+       BUG_ON(direction == DMA_NONE);
+}
+
+
+static inline void
+dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries,
+            enum dma_data_direction direction)
+{
+       BUG_ON(direction == DMA_NONE);
+}
+
+static inline void
+dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, size_t size,
+               enum dma_data_direction direction)
+{
+       consistent_sync((void *)bus_to_virt(dma_handle), size, direction);
+}
+
+static inline void
+dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle, size_t size,
+               enum dma_data_direction direction)
+{
+       consistent_sync((void *)bus_to_virt(dma_handle), size, direction);
+}
+
+static inline void
+dma_sync_single_range_for_cpu(struct device *dev, dma_addr_t dma_handle,
+                     unsigned long offset, size_t size,
+                     enum dma_data_direction direction)
+{
+
+       consistent_sync((void *)bus_to_virt(dma_handle)+offset,size,direction);
+}
+
+static inline void
+dma_sync_single_range_for_device(struct device *dev, dma_addr_t dma_handle,
+                     unsigned long offset, size_t size,
+                     enum dma_data_direction direction)
+{
+
+       consistent_sync((void *)bus_to_virt(dma_handle)+offset,size,direction);
+}
+static inline void
+dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems,
+                enum dma_data_direction dir)
+{
+       int i;
+       for (i = 0; i < nelems; i++, sg++)
+               consistent_sync(page_address(sg->page) + sg->offset,
+                               sg->length, dir);
+}
+
+static inline void
+dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nelems,
+                enum dma_data_direction dir)
+{
+       int i;
+       for (i = 0; i < nelems; i++, sg++)
+               consistent_sync(page_address(sg->page) + sg->offset,
+                               sg->length, dir);
+}
+static inline int
+dma_mapping_error(dma_addr_t dma_addr)
+{
+       return 0;
+}
+
+static inline int
+dma_supported(struct device *dev, u64 mask)
+{
+       return 1;
+}
+
+static inline int
+dma_set_mask(struct device *dev, u64 mask)
+{
+       if(!dev->dma_mask || !dma_supported(dev, mask))
+               return -EIO;
+
+       *dev->dma_mask = mask;
+
+       return 0;
+}
+
+static inline int
+dma_get_cache_alignment(void)
+{
+       return L1_CACHE_BYTES;
+}
+
+#define dma_is_consistent(d)   (1)
+
+static inline void
+dma_cache_sync(void *vaddr, size_t size,
+              enum dma_data_direction direction)
+{
+       consistent_sync(vaddr, size, direction);
+}
+
+#endif /* _XTENSA_DMA_MAPPING_H */
diff --git a/include/asm-xtensa/dma.h b/include/asm-xtensa/dma.h
new file mode 100644 (file)
index 0000000..1c22b02
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * include/asm-xtensa/dma.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2003 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_DMA_H
+#define _XTENSA_DMA_H
+
+#include <linux/config.h>
+#include <asm/io.h>            /* need byte IO */
+#include <xtensa/config/core.h>
+
+/*
+ * This is only to be defined if we have PC-like DMA.
+ * By default this is not true on an Xtensa processor,
+ * however on boards with a PCI bus, such functionality
+ * might be emulated externally.
+ *
+ * NOTE:  there still exists driver code that assumes
+ * this is defined, eg. drivers/sound/soundcard.c (as of 2.4).
+ */
+#define MAX_DMA_CHANNELS       8
+
+/*
+ * The maximum virtual address to which DMA transfers
+ * can be performed on this platform.
+ *
+ * NOTE: This is board (platform) specific, not processor-specific!
+ *
+ * NOTE: This assumes DMA transfers can only be performed on
+ *     the section of physical memory contiguously mapped in virtual
+ *     space for the kernel.  For the Xtensa architecture, this
+ *     means the maximum possible size of this DMA area is
+ *     the size of the statically mapped kernel segment
+ *     (XCHAL_KSEG_{CACHED,BYPASS}_SIZE), ie. 128 MB.
+ *
+ * NOTE: When the entire KSEG area is DMA capable, we substract
+ *     one from the max address so that the virt_to_phys() macro
+ *     works correctly on the address (otherwise the address
+ *     enters another area, and virt_to_phys() may not return
+ *     the value desired).
+ */
+#define MAX_DMA_ADDRESS                (PAGE_OFFSET + XCHAL_KSEG_CACHED_SIZE - 1)
+
+/* Reserve and release a DMA channel */
+extern int request_dma(unsigned int dmanr, const char * device_id);
+extern void free_dma(unsigned int dmanr);
+
+#ifdef CONFIG_PCI
+extern int isa_dma_bridge_buggy;
+#else
+#define isa_dma_bridge_buggy   (0)
+#endif
+
+
+#endif
diff --git a/include/asm-xtensa/elf.h b/include/asm-xtensa/elf.h
new file mode 100644 (file)
index 0000000..64f1f53
--- /dev/null
@@ -0,0 +1,222 @@
+/*
+ * include/asm-xtensa/elf.h
+ *
+ * ELF register definitions
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_ELF_H
+#define _XTENSA_ELF_H
+
+#include <asm/ptrace.h>
+#include <asm/coprocessor.h>
+#include <xtensa/config/core.h>
+
+/* Xtensa processor ELF architecture-magic number */
+
+#define EM_XTENSA      94
+#define EM_XTENSA_OLD  0xABC7
+
+/* ELF register definitions. This is needed for core dump support.  */
+
+/*
+ * elf_gregset_t contains the application-level state in the following order:
+ * Processor info:     config_version, cpuxy
+ * Processor state:    pc, ps, exccause, excvaddr, wb, ws,
+ *                     lbeg, lend, lcount, sar
+ * GP regs:            ar0 - arXX
+ */
+
+typedef unsigned long elf_greg_t;
+
+typedef struct {
+       elf_greg_t xchal_config_id0;
+       elf_greg_t xchal_config_id1;
+       elf_greg_t cpux;
+       elf_greg_t cpuy;
+       elf_greg_t pc;
+       elf_greg_t ps;
+       elf_greg_t exccause;
+       elf_greg_t excvaddr;
+       elf_greg_t windowbase;
+       elf_greg_t windowstart;
+       elf_greg_t lbeg;
+       elf_greg_t lend;
+       elf_greg_t lcount;
+       elf_greg_t sar;
+       elf_greg_t syscall;
+       elf_greg_t ar[XCHAL_NUM_AREGS];
+} xtensa_gregset_t;
+
+#define ELF_NGREG      (sizeof(xtensa_gregset_t) / sizeof(elf_greg_t))
+
+typedef elf_greg_t elf_gregset_t[ELF_NGREG];
+
+/*
+ *  Compute the size of the coprocessor and extra state layout (register info)
+ *  table (in bytes).
+ *  This is actually the maximum size of the table, as opposed to the size,
+ *  which is available from the _xtensa_reginfo_table_size global variable.
+ *
+ *  (See also arch/xtensa/kernel/coprocessor.S)
+ *
+ */
+
+#ifndef XCHAL_EXTRA_SA_CONTENTS_LIBDB_NUM
+# define XTENSA_CPE_LTABLE_SIZE                0
+#else
+# define XTENSA_CPE_SEGMENT(num)       (num ? (1+num) : 0)
+# define XTENSA_CPE_LTABLE_ENTRIES     \
+               ( XTENSA_CPE_SEGMENT(XCHAL_EXTRA_SA_CONTENTS_LIBDB_NUM) \
+               + XTENSA_CPE_SEGMENT(XCHAL_CP0_SA_CONTENTS_LIBDB_NUM)   \
+               + XTENSA_CPE_SEGMENT(XCHAL_CP1_SA_CONTENTS_LIBDB_NUM)   \
+               + XTENSA_CPE_SEGMENT(XCHAL_CP2_SA_CONTENTS_LIBDB_NUM)   \
+               + XTENSA_CPE_SEGMENT(XCHAL_CP3_SA_CONTENTS_LIBDB_NUM)   \
+               + XTENSA_CPE_SEGMENT(XCHAL_CP4_SA_CONTENTS_LIBDB_NUM)   \
+               + XTENSA_CPE_SEGMENT(XCHAL_CP5_SA_CONTENTS_LIBDB_NUM)   \
+               + XTENSA_CPE_SEGMENT(XCHAL_CP6_SA_CONTENTS_LIBDB_NUM)   \
+               + XTENSA_CPE_SEGMENT(XCHAL_CP7_SA_CONTENTS_LIBDB_NUM)   \
+               + 1             /* final entry */                       \
+               )
+# define XTENSA_CPE_LTABLE_SIZE                (XTENSA_CPE_LTABLE_ENTRIES * 8)
+#endif
+
+
+/*
+ * Instantiations of the elf_fpregset_t type contain, in most
+ * architectures, the floating point (FPU) register set.
+ * For Xtensa, this type is extended to contain all custom state,
+ * ie. coprocessor and "extra" (non-coprocessor) state (including,
+ * for example, TIE-defined states and register files; as well
+ * as other optional processor state).
+ * This includes FPU state if a floating-point coprocessor happens
+ * to have been configured within the Xtensa processor.
+ *
+ * TOTAL_FPREGS_SIZE is the required size (without rounding)
+ * of elf_fpregset_t.  It provides space for the following:
+ *
+ *  a) 32-bit mask of active coprocessors for this task (similar
+ *     to CPENABLE in single-threaded Xtensa processor systems)
+ *
+ *  b) table describing the layout of custom states (ie. of
+ *      individual registers, etc) within the save areas
+ *
+ *  c)  save areas for each coprocessor and for non-coprocessor
+ *      ("extra") state
+ *
+ * Note that save areas may require up to 16-byte alignment when
+ * accessed by save/restore sequences.  We do not need to ensure
+ * such alignment in an elf_fpregset_t structure because custom
+ * state is not directly loaded/stored into it; rather, save area
+ * contents are copied to elf_fpregset_t from the active save areas
+ * (see 'struct task_struct' definition in processor.h for that)
+ * using memcpy().  But we do allow space for such alignment,
+ * to allow optimizations of layout and copying.
+ */
+
+#define TOTAL_FPREGS_SIZE                                              \
+       (4 + XTENSA_CPE_LTABLE_SIZE + XTENSA_CP_EXTRA_SIZE)
+#define ELF_NFPREG                                                     \
+       ((TOTAL_FPREGS_SIZE + sizeof(elf_fpreg_t) - 1) / sizeof(elf_fpreg_t))
+
+typedef unsigned int elf_fpreg_t;
+typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
+
+#define ELF_CORE_COPY_REGS(_eregs, _pregs)                             \
+       xtensa_elf_core_copy_regs (&_eregs, _pregs);
+
+extern void xtensa_elf_core_copy_regs (xtensa_gregset_t *, struct pt_regs *);
+
+/*
+ * This is used to ensure we don't load something for the wrong architecture.
+ */
+
+#define elf_check_arch(x) ( ( (x)->e_machine == EM_XTENSA )  || \
+                           ( (x)->e_machine == EM_XTENSA_OLD ) )
+
+/*
+ * These are used to set parameters in the core dumps.
+ */
+
+#ifdef __XTENSA_EL__
+# define ELF_DATA      ELFDATA2LSB
+#elif defined(__XTENSA_EB__)
+# define ELF_DATA      ELFDATA2MSB
+#else
+# error processor byte order undefined!
+#endif
+
+#define ELF_CLASS      ELFCLASS32
+#define ELF_ARCH       EM_XTENSA
+
+#define USE_ELF_CORE_DUMP
+#define ELF_EXEC_PAGESIZE      PAGE_SIZE
+
+/*
+ * This is the location that an ET_DYN program is loaded if exec'ed.  Typical
+ * use of this is to invoke "./ld.so someprog" to test out a new version of
+ * the loader.  We need to make sure that it is out of the way of the program
+ * that it will "exec", and that there is sufficient room for the brk.
+ */
+
+#define ELF_ET_DYN_BASE         (2 * TASK_SIZE / 3)
+
+/*
+ * This yields a mask that user programs can use to figure out what
+ * instruction set this CPU supports.  This could be done in user space,
+ * but it's not easy, and we've already done it here.
+ */
+
+#define ELF_HWCAP      (0)
+
+/*
+ * This yields a string that ld.so will use to load implementation
+ * specific libraries for optimization.  This is more specific in
+ * intent than poking at uname or /proc/cpuinfo.
+ * For the moment, we have only optimizations for the Intel generations,
+ * but that could change...
+ */
+
+#define ELF_PLATFORM  (NULL)
+
+/*
+ * The Xtensa processor ABI says that when the program starts, a2
+ * contains a pointer to a function which might be registered using
+ * `atexit'.  This provides a mean for the dynamic linker to call
+ * DT_FINI functions for shared libraries that have been loaded before
+ * the code runs.
+ *
+ * A value of 0 tells we have no such handler.
+ *
+ * We might as well make sure everything else is cleared too (except
+ * for the stack pointer in a1), just to make things more
+ * deterministic.  Also, clearing a0 terminates debugger backtraces.
+ */
+
+#define ELF_PLAT_INIT(_r, load_addr) \
+  do { _r->areg[0]=0; /*_r->areg[1]=0;*/ _r->areg[2]=0;  _r->areg[3]=0;  \
+       _r->areg[4]=0;  _r->areg[5]=0;    _r->areg[6]=0;  _r->areg[7]=0;  \
+       _r->areg[8]=0;  _r->areg[9]=0;    _r->areg[10]=0; _r->areg[11]=0; \
+       _r->areg[12]=0; _r->areg[13]=0;   _r->areg[14]=0; _r->areg[15]=0; \
+  } while (0)
+
+#ifdef __KERNEL__
+
+#define SET_PERSONALITY(ex, ibcs2) set_personality(PER_LINUX_32BIT)
+
+extern void do_copy_regs (xtensa_gregset_t*, struct pt_regs*,
+                         struct task_struct*);
+extern void do_restore_regs (xtensa_gregset_t*, struct pt_regs*,
+                            struct task_struct*);
+extern void do_save_fpregs (elf_fpregset_t*, struct pt_regs*,
+                           struct task_struct*);
+extern int do_restore_fpregs (elf_fpregset_t*, struct pt_regs*,
+                             struct task_struct*);
+
+#endif /* __KERNEL__ */
+#endif /* _XTENSA_ELF_H */
diff --git a/include/asm-xtensa/errno.h b/include/asm-xtensa/errno.h
new file mode 100644 (file)
index 0000000..ced5194
--- /dev/null
@@ -0,0 +1,142 @@
+/*
+ * include/asm-xtensa/errno.h
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file "COPYING" in the main directory of
+ * this archive for more details.
+ *
+ * Copyright (C) 2002 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_ERRNO_H
+#define _XTENSA_ERRNO_H
+
+#define        EPERM            1      /* Operation not permitted */
+#define        ENOENT           2      /* No such file or directory */
+#define        ESRCH            3      /* No such process */
+#define        EINTR            4      /* Interrupted system call */
+#define        EIO              5      /* I/O error */
+#define        ENXIO            6      /* No such device or address */
+#define        E2BIG            7      /* Arg list too long */
+#define        ENOEXEC          8      /* Exec format error */
+#define        EBADF            9      /* Bad file number */
+#define        ECHILD          10      /* No child processes */
+#define        EAGAIN          11      /* Try again */
+#define        ENOMEM          12      /* Out of memory */
+#define        EACCES          13      /* Permission denied */
+#define        EFAULT          14      /* Bad address */
+#define        ENOTBLK         15      /* Block device required */
+#define        EBUSY           16      /* Device or resource busy */
+#define        EEXIST          17      /* File exists */
+#define        EXDEV           18      /* Cross-device link */
+#define        ENODEV          19      /* No such device */
+#define        ENOTDIR         20      /* Not a directory */
+#define        EISDIR          21      /* Is a directory */
+#define        EINVAL          22      /* Invalid argument */
+#define        ENFILE          23      /* File table overflow */
+#define        EMFILE          24      /* Too many open files */
+#define        ENOTTY          25      /* Not a typewriter */
+#define        ETXTBSY         26      /* Text file busy */
+#define        EFBIG           27      /* File too large */
+#define        ENOSPC          28      /* No space left on device */
+#define        ESPIPE          29      /* Illegal seek */
+#define        EROFS           30      /* Read-only file system */
+#define        EMLINK          31      /* Too many links */
+#define        EPIPE           32      /* Broken pipe */
+#define        EDOM            33      /* Math argument out of domain of func */
+#define        ERANGE          34      /* Math result not representable */
+#define        EDEADLK         35      /* Resource deadlock would occur */
+#define        ENAMETOOLONG    36      /* File name too long */
+#define        ENOLCK          37      /* No record locks available */
+#define        ENOSYS          38      /* Function not implemented */
+#define        ENOTEMPTY       39      /* Directory not empty */
+#define        ELOOP           40      /* Too many symbolic links encountered */
+#define        EWOULDBLOCK     EAGAIN  /* Operation would block */
+#define        ENOMSG          42      /* No message of desired type */
+#define        EIDRM           43      /* Identifier removed */
+#define        ECHRNG          44      /* Channel number out of range */
+#define        EL2NSYNC        45      /* Level 2 not synchronized */
+#define        EL3HLT          46      /* Level 3 halted */
+#define        EL3RST          47      /* Level 3 reset */
+#define        ELNRNG          48      /* Link number out of range */
+#define        EUNATCH         49      /* Protocol driver not attached */
+#define        ENOCSI          50      /* No CSI structure available */
+#define        EL2HLT          51      /* Level 2 halted */
+#define        EBADE           52      /* Invalid exchange */
+#define        EBADR           53      /* Invalid request descriptor */
+#define        EXFULL          54      /* Exchange full */
+#define        ENOANO          55      /* No anode */
+#define        EBADRQC         56      /* Invalid request code */
+#define        EBADSLT         57      /* Invalid slot */
+
+#define        EDEADLOCK       EDEADLK
+
+#define        EBFONT          59      /* Bad font file format */
+#define        ENOSTR          60      /* Device not a stream */
+#define        ENODATA         61      /* No data available */
+#define        ETIME           62      /* Timer expired */
+#define        ENOSR           63      /* Out of streams resources */
+#define        ENONET          64      /* Machine is not on the network */
+#define        ENOPKG          65      /* Package not installed */
+#define        EREMOTE         66      /* Object is remote */
+#define        ENOLINK         67      /* Link has been severed */
+#define        EADV            68      /* Advertise error */
+#define        ESRMNT          69      /* Srmount error */
+#define        ECOMM           70      /* Communication error on send */
+#define        EPROTO          71      /* Protocol error */
+#define        EMULTIHOP       72      /* Multihop attempted */
+#define        EDOTDOT         73      /* RFS specific error */
+#define        EBADMSG         74      /* Not a data message */
+#define        EOVERFLOW       75      /* Value too large for defined data type */
+#define        ENOTUNIQ        76      /* Name not unique on network */
+#define        EBADFD          77      /* File descriptor in bad state */
+#define        EREMCHG         78      /* Remote address changed */
+#define        ELIBACC         79      /* Can not access a needed shared library */
+#define        ELIBBAD         80      /* Accessing a corrupted shared library */
+#define        ELIBSCN         81      /* .lib section in a.out corrupted */
+#define        ELIBMAX         82      /* Attempting to link in too many shared libraries */
+#define        ELIBEXEC        83      /* Cannot exec a shared library directly */
+#define        EILSEQ          84      /* Illegal byte sequence */
+#define        ERESTART        85      /* Interrupted system call should be restarted */
+#define        ESTRPIPE        86      /* Streams pipe error */
+#define        EUSERS          87      /* Too many users */
+#define        ENOTSOCK        88      /* Socket operation on non-socket */
+#define        EDESTADDRREQ    89      /* Destination address required */
+#define        EMSGSIZE        90      /* Message too long */
+#define        EPROTOTYPE      91      /* Protocol wrong type for socket */
+#define        ENOPROTOOPT     92      /* Protocol not available */
+#define        EPROTONOSUPPORT 93      /* Protocol not supported */
+#define        ESOCKTNOSUPPORT 94      /* Socket type not supported */
+#define        EOPNOTSUPP      95      /* Operation not supported on transport endpoint */
+#define        EPFNOSUPPORT    96      /* Protocol family not supported */
+#define        EAFNOSUPPORT    97      /* Address family not supported by protocol */
+#define        EADDRINUSE      98      /* Address already in use */
+#define        EADDRNOTAVAIL   99      /* Cannot assign requested address */
+#define        ENETDOWN        100     /* Network is down */
+#define        ENETUNREACH     101     /* Network is unreachable */
+#define        ENETRESET       102     /* Network dropped connection because of reset */
+#define        ECONNABORTED    103     /* Software caused connection abort */
+#define        ECONNRESET      104     /* Connection reset by peer */
+#define        ENOBUFS         105     /* No buffer space available */
+#define        EISCONN         106     /* Transport endpoint is already connected */
+#define        ENOTCONN        107     /* Transport endpoint is not connected */
+#define        ESHUTDOWN       108     /* Cannot send after transport endpoint shutdown */
+#define        ETOOMANYREFS    109     /* Too many references: cannot splice */
+#define        ETIMEDOUT       110     /* Connection timed out */
+#define        ECONNREFUSED    111     /* Connection refused */
+#define        EHOSTDOWN       112     /* Host is down */
+#define        EHOSTUNREACH    113     /* No route to host */
+#define        EALREADY        114     /* Operation already in progress */
+#define        EINPROGRESS     115     /* Operation now in progress */
+#define        ESTALE          116     /* Stale NFS file handle */
+#define        EUCLEAN         117     /* Structure needs cleaning */
+#define        ENOTNAM         118     /* Not a XENIX named type file */
+#define        ENAVAIL         119     /* No XENIX semaphores available */
+#define        EISNAM          120     /* Is a named type file */
+#define        EREMOTEIO       121     /* Remote I/O error */
+#define        EDQUOT          122     /* Quota exceeded */
+
+#define        ENOMEDIUM       123     /* No medium found */
+#define        EMEDIUMTYPE     124     /* Wrong medium type */
+
+#endif /* _XTENSA_ERRNO_H */
diff --git a/include/asm-xtensa/fcntl.h b/include/asm-xtensa/fcntl.h
new file mode 100644 (file)
index 0000000..48876bb
--- /dev/null
@@ -0,0 +1,101 @@
+/*
+ * include/asm-xtensa/fcntl.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1995, 1996, 1997, 1998 by Ralf Baechle
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_FCNTL_H
+#define _XTENSA_FCNTL_H
+
+/* open/fcntl - O_SYNC is only implemented on blocks devices and on files
+   located on an ext2 file system */
+#define O_ACCMODE      0x0003
+#define O_RDONLY       0x0000
+#define O_WRONLY       0x0001
+#define O_RDWR         0x0002
+#define O_APPEND       0x0008
+#define O_SYNC         0x0010
+#define O_NONBLOCK     0x0080
+#define O_CREAT         0x0100 /* not fcntl */
+#define O_TRUNC                0x0200  /* not fcntl */
+#define O_EXCL         0x0400  /* not fcntl */
+#define O_NOCTTY       0x0800  /* not fcntl */
+#define FASYNC         0x1000  /* fcntl, for BSD compatibility */
+#define O_LARGEFILE    0x2000  /* allow large file opens - currently ignored */
+#define O_DIRECT       0x8000  /* direct disk access hint - currently ignored*/
+#define O_DIRECTORY    0x10000 /* must be a directory */
+#define O_NOFOLLOW     0x20000 /* don't follow links */
+#define O_NOATIME      0x100000
+
+#define O_NDELAY       O_NONBLOCK
+
+#define F_DUPFD                0       /* dup */
+#define F_GETFD                1       /* get close_on_exec */
+#define F_SETFD                2       /* set/clear close_on_exec */
+#define F_GETFL                3       /* get file->f_flags */
+#define F_SETFL                4       /* set file->f_flags */
+#define F_GETLK                14
+#define F_GETLK64       15
+#define F_SETLK                6
+#define F_SETLKW       7
+#define F_SETLK64       16
+#define F_SETLKW64      17
+
+#define F_SETOWN       24      /*  for sockets. */
+#define F_GETOWN       23      /*  for sockets. */
+#define F_SETSIG       10      /*  for sockets. */
+#define F_GETSIG       11      /*  for sockets. */
+
+/* for F_[GET|SET]FL */
+#define FD_CLOEXEC     1       /* actually anything with low bit set goes */
+
+/* for posix fcntl() and lockf() */
+#define F_RDLCK                0
+#define F_WRLCK                1
+#define F_UNLCK                2
+
+/* for old implementation of bsd flock () */
+#define F_EXLCK                4       /* or 3 */
+#define F_SHLCK                8       /* or 4 */
+
+/* for leases */
+#define F_INPROGRESS   16
+
+/* operations for bsd flock(), also used by the kernel implementation */
+#define LOCK_SH                1       /* shared lock */
+#define LOCK_EX                2       /* exclusive lock */
+#define LOCK_NB                4       /* or'd with one of the above to prevent
+                                  blocking */
+#define LOCK_UN                8       /* remove lock */
+
+#define LOCK_MAND      32      /* This is a mandatory flock ... */
+#define LOCK_READ      64      /*  which allows concurrent read operations */
+#define LOCK_WRITE     128     /*  which allows concurrent write operations */
+#define LOCK_RW                192     /*  which allows concurrent read & write ops */
+
+typedef struct flock {
+       short l_type;
+       short l_whence;
+       __kernel_off_t l_start;
+       __kernel_off_t l_len;
+       long  l_sysid;
+       __kernel_pid_t l_pid;
+       long  pad[4];
+} flock_t;
+
+struct flock64 {
+       short  l_type;
+       short  l_whence;
+       __kernel_off_t l_start;
+       __kernel_off_t l_len;
+       pid_t  l_pid;
+};
+
+#define F_LINUX_SPECIFIC_BASE  1024
+
+#endif /* _XTENSA_FCNTL_H */
diff --git a/include/asm-xtensa/fixmap.h b/include/asm-xtensa/fixmap.h
new file mode 100644 (file)
index 0000000..4423b8a
--- /dev/null
@@ -0,0 +1,252 @@
+/*
+ * include/asm-xtensa/fixmap.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_FIXMAP_H
+#define _XTENSA_FIXMAP_H
+
+#include <asm/processor.h>
+
+#ifdef CONFIG_MMU
+
+/*
+ * Here we define all the compile-time virtual addresses.
+ */
+
+#if XCHAL_SEG_MAPPABLE_VADDR != 0
+# error "Current port requires virtual user space starting at 0"
+#endif
+#if XCHAL_SEG_MAPPABLE_SIZE < 0x80000000
+# error "Current port requires at least 0x8000000 bytes for user space"
+#endif
+
+/* Verify instruction/data ram/rom and xlmi don't overlay vmalloc space. */
+
+#define __IN_VMALLOC(addr)                                             \
+       (((addr) >= VMALLOC_START) && ((addr) < VMALLOC_END))
+#define __SPAN_VMALLOC(start,end)                                      \
+       (((start) < VMALLOC_START) && ((end) >= VMALLOC_END))
+#define INSIDE_VMALLOC(start,end)                                      \
+       (__IN_VMALLOC((start)) || __IN_VMALLOC(end) || __SPAN_VMALLOC((start),(end)))
+
+#if XCHAL_NUM_INSTROM
+# if XCHAL_NUM_INSTROM == 1
+#  if INSIDE_VMALLOC(XCHAL_INSTROM0_VADDR,XCHAL_INSTROM0_VADDR+XCHAL_INSTROM0_SIZE)
+#   error vmalloc range conflicts with instrom0
+#  endif
+# endif
+# if XCHAL_NUM_INSTROM == 2
+#  if INSIDE_VMALLOC(XCHAL_INSTROM1_VADDR,XCHAL_INSTROM1_VADDR+XCHAL_INSTROM1_SIZE)
+#   error vmalloc range conflicts with instrom1
+#  endif
+# endif
+#endif
+
+#if XCHAL_NUM_INSTRAM
+# if XCHAL_NUM_INSTRAM == 1
+#  if INSIDE_VMALLOC(XCHAL_INSTRAM0_VADDR,XCHAL_INSTRAM0_VADDR+XCHAL_INSTRAM0_SIZE)
+#   error vmalloc range conflicts with instram0
+#  endif
+# endif
+# if XCHAL_NUM_INSTRAM == 2
+#  if INSIDE_VMALLOC(XCHAL_INSTRAM1_VADDR,XCHAL_INSTRAM1_VADDR+XCHAL_INSTRAM1_SIZE)
+#   error vmalloc range conflicts with instram1
+#  endif
+# endif
+#endif
+
+#if XCHAL_NUM_DATAROM
+# if XCHAL_NUM_DATAROM == 1
+#  if INSIDE_VMALLOC(XCHAL_DATAROM0_VADDR,XCHAL_DATAROM0_VADDR+XCHAL_DATAROM0_SIZE)
+#   error vmalloc range conflicts with datarom0
+#  endif
+# endif
+# if XCHAL_NUM_DATAROM == 2
+#  if INSIDE_VMALLOC(XCHAL_DATAROM1_VADDR,XCHAL_DATAROM1_VADDR+XCHAL_DATAROM1_SIZE)
+#   error vmalloc range conflicts with datarom1
+#  endif
+# endif
+#endif
+
+#if XCHAL_NUM_DATARAM
+# if XCHAL_NUM_DATARAM == 1
+#  if INSIDE_VMALLOC(XCHAL_DATARAM0_VADDR,XCHAL_DATARAM0_VADDR+XCHAL_DATARAM0_SIZE)
+#   error vmalloc range conflicts with dataram0
+#  endif
+# endif
+# if XCHAL_NUM_DATARAM == 2
+#  if INSIDE_VMALLOC(XCHAL_DATARAM1_VADDR,XCHAL_DATARAM1_VADDR+XCHAL_DATARAM1_SIZE)
+#   error vmalloc range conflicts with dataram1
+#  endif
+# endif
+#endif
+
+#if XCHAL_NUM_XLMI
+# if XCHAL_NUM_XLMI == 1
+#  if INSIDE_VMALLOC(XCHAL_XLMI0_VADDR,XCHAL_XLMI0_VADDR+XCHAL_XLMI0_SIZE)
+#   error vmalloc range conflicts with xlmi0
+#  endif
+# endif
+# if XCHAL_NUM_XLMI == 2
+#  if INSIDE_VMALLOC(XCHAL_XLMI1_VADDR,XCHAL_XLMI1_VADDR+XCHAL_XLMI1_SIZE)
+#   error vmalloc range conflicts with xlmi1
+#  endif
+# endif
+#endif
+
+#if (XCHAL_NUM_INSTROM > 2) || \
+    (XCHAL_NUM_INSTRAM > 2) || \
+    (XCHAL_NUM_DATARAM > 2) || \
+    (XCHAL_NUM_DATAROM > 2) || \
+    (XCHAL_NUM_XLMI    > 2)
+# error Insufficient checks on vmalloc above for more than 2 devices
+#endif
+
+/*
+ * USER_VM_SIZE does not necessarily equal TASK_SIZE.  We bumped
+ * TASK_SIZE down to 0x4000000 to simplify the handling of windowed
+ * call instructions (currently limited to a range of 1 GByte).  User
+ * tasks may very well reclaim the VM space from 0x40000000 to
+ * 0x7fffffff in the future, so we do not want the kernel becoming
+ * accustomed to having any of its stuff (e.g., page tables) in this
+ * region.  This VM region is no-man's land for now.
+ */
+
+#define USER_VM_START          XCHAL_SEG_MAPPABLE_VADDR
+#define USER_VM_SIZE           0x80000000
+
+/*  Size of page table:  */
+
+#define PGTABLE_SIZE_BITS      (32 - XCHAL_MMU_MIN_PTE_PAGE_SIZE + 2)
+#define PGTABLE_SIZE           (1L << PGTABLE_SIZE_BITS)
+
+/*  All kernel-mappable space:  */
+
+#define KERNEL_ALLMAP_START    (USER_VM_START + USER_VM_SIZE)
+#define KERNEL_ALLMAP_SIZE     (XCHAL_SEG_MAPPABLE_SIZE - KERNEL_ALLMAP_START)
+
+/*  Carve out page table at start of kernel-mappable area:  */
+
+#if KERNEL_ALLMAP_SIZE < PGTABLE_SIZE
+#error "Gimme some space for page table!"
+#endif
+#define PGTABLE_START          KERNEL_ALLMAP_START
+
+/*  Remaining kernel-mappable space:  */
+
+#define KERNEL_MAPPED_START    (KERNEL_ALLMAP_START + PGTABLE_SIZE)
+#define KERNEL_MAPPED_SIZE     (KERNEL_ALLMAP_SIZE - PGTABLE_SIZE)
+
+#if KERNEL_MAPPED_SIZE < 0x01000000    /* 16 MB is arbitrary for now */
+# error "Shouldn't the kernel have at least *some* mappable space?"
+#endif
+
+#define MAX_LOW_MEMORY         XCHAL_KSEG_CACHED_SIZE
+
+#endif
+
+/*
+ *  Some constants used elsewhere, but perhaps only in Xtensa header
+ *  files, so maybe we can get rid of some and access compile-time HAL
+ *  directly...
+ *
+ *  Note:  We assume that system RAM is located at the very start of the
+ *        kernel segments !!
+ */
+#define KERNEL_VM_LOW           XCHAL_KSEG_CACHED_VADDR
+#define KERNEL_VM_HIGH          XCHAL_KSEG_BYPASS_VADDR
+#define KERNEL_SPACE            XCHAL_KSEG_CACHED_VADDR
+
+/*
+ * Returns the physical/virtual addresses of the kernel space
+ * (works with the cached kernel segment only, which is the
+ *  one normally used for kernel operation).
+ */
+
+/*                     PHYSICAL        BYPASS          CACHED
+ *
+ *  bypass vaddr       bypass paddr    *               cached vaddr
+ *  cached vaddr       cached paddr    bypass vaddr    *
+ *  bypass paddr       *               bypass vaddr    cached vaddr
+ *  cached paddr       *               bypass vaddr    cached vaddr
+ *  other              *               *               *
+ */
+
+#define PHYSADDR(a)                                                          \
+(((unsigned)(a) >= XCHAL_KSEG_BYPASS_VADDR                                   \
+  && (unsigned)(a) < XCHAL_KSEG_BYPASS_VADDR + XCHAL_KSEG_BYPASS_SIZE) ?      \
+    (unsigned)(a) - XCHAL_KSEG_BYPASS_VADDR + XCHAL_KSEG_BYPASS_PADDR :       \
+    ((unsigned)(a) >= XCHAL_KSEG_CACHED_VADDR                                \
+     && (unsigned)(a) < XCHAL_KSEG_CACHED_VADDR + XCHAL_KSEG_CACHED_SIZE) ?   \
+        (unsigned)(a) - XCHAL_KSEG_CACHED_VADDR + XCHAL_KSEG_CACHED_PADDR :   \
+       (unsigned)(a))
+
+#define BYPASS_ADDR(a)                                                       \
+(((unsigned)(a) >= XCHAL_KSEG_BYPASS_PADDR                                   \
+  && (unsigned)(a) < XCHAL_KSEG_BYPASS_PADDR + XCHAL_KSEG_BYPASS_SIZE) ?      \
+    (unsigned)(a) - XCHAL_KSEG_BYPASS_PADDR + XCHAL_KSEG_BYPASS_VADDR :       \
+    ((unsigned)(a) >= XCHAL_KSEG_CACHED_PADDR                                \
+     && (unsigned)(a) < XCHAL_KSEG_CACHED_PADDR + XCHAL_KSEG_CACHED_SIZE) ?   \
+        (unsigned)(a) - XCHAL_KSEG_CACHED_PADDR + XCHAL_KSEG_BYPASS_VADDR :   \
+        ((unsigned)(a) >= XCHAL_KSEG_CACHED_VADDR                            \
+         && (unsigned)(a) < XCHAL_KSEG_CACHED_VADDR+XCHAL_KSEG_CACHED_SIZE)?  \
+            (unsigned)(a) - XCHAL_KSEG_CACHED_VADDR+XCHAL_KSEG_BYPASS_VADDR:  \
+           (unsigned)(a))
+
+#define CACHED_ADDR(a)                                                       \
+(((unsigned)(a) >= XCHAL_KSEG_BYPASS_PADDR                                   \
+  && (unsigned)(a) < XCHAL_KSEG_BYPASS_PADDR + XCHAL_KSEG_BYPASS_SIZE) ?      \
+    (unsigned)(a) - XCHAL_KSEG_BYPASS_PADDR + XCHAL_KSEG_CACHED_VADDR :       \
+    ((unsigned)(a) >= XCHAL_KSEG_CACHED_PADDR                                \
+     && (unsigned)(a) < XCHAL_KSEG_CACHED_PADDR + XCHAL_KSEG_CACHED_SIZE) ?   \
+        (unsigned)(a) - XCHAL_KSEG_CACHED_PADDR + XCHAL_KSEG_CACHED_VADDR :   \
+        ((unsigned)(a) >= XCHAL_KSEG_BYPASS_VADDR                            \
+         && (unsigned)(a) < XCHAL_KSEG_BYPASS_VADDR+XCHAL_KSEG_BYPASS_SIZE) ? \
+            (unsigned)(a) - XCHAL_KSEG_BYPASS_VADDR+XCHAL_KSEG_CACHED_VADDR : \
+           (unsigned)(a))
+
+#define PHYSADDR_IO(a)                                                       \
+(((unsigned)(a) >= XCHAL_KIO_BYPASS_VADDR                                    \
+  && (unsigned)(a) < XCHAL_KIO_BYPASS_VADDR + XCHAL_KIO_BYPASS_SIZE) ?       \
+    (unsigned)(a) - XCHAL_KIO_BYPASS_VADDR + XCHAL_KIO_BYPASS_PADDR :        \
+    ((unsigned)(a) >= XCHAL_KIO_CACHED_VADDR                                 \
+     && (unsigned)(a) < XCHAL_KIO_CACHED_VADDR + XCHAL_KIO_CACHED_SIZE) ?     \
+        (unsigned)(a) - XCHAL_KIO_CACHED_VADDR + XCHAL_KIO_CACHED_PADDR :     \
+       (unsigned)(a))
+
+#define BYPASS_ADDR_IO(a)                                                    \
+(((unsigned)(a) >= XCHAL_KIO_BYPASS_PADDR                                    \
+  && (unsigned)(a) < XCHAL_KIO_BYPASS_PADDR + XCHAL_KIO_BYPASS_SIZE) ?       \
+    (unsigned)(a) - XCHAL_KIO_BYPASS_PADDR + XCHAL_KIO_BYPASS_VADDR :        \
+    ((unsigned)(a) >= XCHAL_KIO_CACHED_PADDR                                 \
+     && (unsigned)(a) < XCHAL_KIO_CACHED_PADDR + XCHAL_KIO_CACHED_SIZE) ?     \
+        (unsigned)(a) - XCHAL_KIO_CACHED_PADDR + XCHAL_KIO_BYPASS_VADDR :     \
+        ((unsigned)(a) >= XCHAL_KIO_CACHED_VADDR                             \
+         && (unsigned)(a) < XCHAL_KIO_CACHED_VADDR + XCHAL_KIO_CACHED_SIZE) ? \
+            (unsigned)(a) - XCHAL_KIO_CACHED_VADDR + XCHAL_KIO_BYPASS_VADDR : \
+           (unsigned)(a))
+
+#define CACHED_ADDR_IO(a)                                                    \
+(((unsigned)(a) >= XCHAL_KIO_BYPASS_PADDR                                    \
+  && (unsigned)(a) < XCHAL_KIO_BYPASS_PADDR + XCHAL_KIO_BYPASS_SIZE) ?       \
+    (unsigned)(a) - XCHAL_KIO_BYPASS_PADDR + XCHAL_KIO_CACHED_VADDR :        \
+    ((unsigned)(a) >= XCHAL_KIO_CACHED_PADDR                                 \
+     && (unsigned)(a) < XCHAL_KIO_CACHED_PADDR + XCHAL_KIO_CACHED_SIZE) ?     \
+        (unsigned)(a) - XCHAL_KIO_CACHED_PADDR + XCHAL_KIO_CACHED_VADDR :     \
+        ((unsigned)(a) >= XCHAL_KIO_BYPASS_VADDR                             \
+         && (unsigned)(a) < XCHAL_KIO_BYPASS_VADDR + XCHAL_KIO_BYPASS_SIZE) ? \
+            (unsigned)(a) - XCHAL_KIO_BYPASS_VADDR + XCHAL_KIO_CACHED_VADDR : \
+           (unsigned)(a))
+
+#endif /* _XTENSA_ADDRSPACE_H */
+
+
+
+
+
diff --git a/include/asm-xtensa/hardirq.h b/include/asm-xtensa/hardirq.h
new file mode 100644 (file)
index 0000000..e07c76c
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * include/asm-xtensa/hardirq.h
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file "COPYING" in the main directory of
+ * this archive for more details.
+ *
+ * Copyright (C) 2002 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_HARDIRQ_H
+#define _XTENSA_HARDIRQ_H
+
+#include <linux/config.h>
+#include <linux/cache.h>
+#include <asm/irq.h>
+
+/* headers.S is sensitive to the offsets of these fields */
+typedef struct {
+       unsigned int __softirq_pending;
+       unsigned int __syscall_count;
+       struct task_struct * __ksoftirqd_task; /* waitqueue is too large */
+       unsigned int __nmi_count;              /* arch dependent */
+} ____cacheline_aligned irq_cpustat_t;
+
+#include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */
+
+#endif /* _XTENSA_HARDIRQ_H */
diff --git a/include/asm-xtensa/hdreg.h b/include/asm-xtensa/hdreg.h
new file mode 100644 (file)
index 0000000..64b8060
--- /dev/null
@@ -0,0 +1,17 @@
+/*
+ * include/asm-xtensa/hdreg.h
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file "COPYING" in the main directory of
+ * this archive for more details.
+ *
+ * Copyright (C) 2002 - 2005 Tensilica Inc.
+ * Copyright (C) 1994-1996  Linus Torvalds & authors
+ */
+
+#ifndef _XTENSA_HDREG_H
+#define _XTENSA_HDREG_H
+
+typedef unsigned int ide_ioreg_t;
+
+#endif
diff --git a/include/asm-xtensa/highmem.h b/include/asm-xtensa/highmem.h
new file mode 100644 (file)
index 0000000..0a046ca
--- /dev/null
@@ -0,0 +1,17 @@
+/*
+ * include/asm-xtensa/highmem.h
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file "COPYING" in the main directory of
+ * this archive for more details.
+ *
+ * Copyright (C) 2003 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_HIGHMEM_H
+#define _XTENSA_HIGHMEM_H
+
+extern void flush_cache_kmaps(void);
+
+#endif
+
diff --git a/include/asm-xtensa/hw_irq.h b/include/asm-xtensa/hw_irq.h
new file mode 100644 (file)
index 0000000..ccf4362
--- /dev/null
@@ -0,0 +1,18 @@
+/*
+ * include/asm-xtensa/hw_irq.h
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file "COPYING" in the main directory of
+ * this archive for more details.
+ *
+ * Copyright (C) 2002 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_HW_IRQ_H
+#define _XTENSA_HW_IRQ_H
+
+static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i)
+{
+}
+
+#endif
diff --git a/include/asm-xtensa/ide.h b/include/asm-xtensa/ide.h
new file mode 100644 (file)
index 0000000..b523cd4
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * include/asm-xtensa/ide.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1994 - 1996  Linus Torvalds & authors
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_IDE_H
+#define _XTENSA_IDE_H
+
+#ifdef __KERNEL__
+
+#include <linux/config.h>
+
+#ifndef MAX_HWIFS
+# define MAX_HWIFS     1
+#endif
+
+static __inline__ int ide_default_irq(unsigned long base)
+{
+       /* Unsupported! */
+       return 0;
+}
+
+static __inline__ unsigned long ide_default_io_base(int index)
+{
+       /* Unsupported! */
+       return 0;
+}
+
+#endif /* __KERNEL__ */
+#endif /* _XTENSA_IDE_H */
diff --git a/include/asm-xtensa/io.h b/include/asm-xtensa/io.h
new file mode 100644 (file)
index 0000000..2c471c4
--- /dev/null
@@ -0,0 +1,197 @@
+/*
+ * linux/include/asm-xtensa/io.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_IO_H
+#define _XTENSA_IO_H
+
+#ifdef __KERNEL__
+#include <linux/config.h>
+#include <asm/byteorder.h>
+
+#include <linux/types.h>
+#include <asm/fixmap.h>
+
+#define _IO_BASE 0
+
+
+/*
+ * swap functions to change byte order from little-endian to big-endian and
+ * vice versa.
+ */
+
+static inline unsigned short _swapw (unsigned short v)
+{
+       return (v << 8) | (v >> 8);
+}
+
+static inline unsigned int _swapl (unsigned int v)
+{
+       return (v << 24) | ((v & 0xff00) << 8) | ((v >> 8) & 0xff00) | (v >> 24);
+}
+
+/*
+ * Change virtual addresses to physical addresses and vv.
+ * These are trivial on the 1:1 Linux/Xtensa mapping
+ */
+
+extern inline unsigned long virt_to_phys(volatile void * address)
+{
+       return PHYSADDR((unsigned long)address);
+}
+
+extern inline void * phys_to_virt(unsigned long address)
+{
+       return (void*) CACHED_ADDR(address);
+}
+
+/*
+ * IO bus memory addresses are also 1:1 with the physical address
+ */
+
+extern inline unsigned long virt_to_bus(volatile void * address)
+{
+       return PHYSADDR((unsigned long)address);
+}
+
+extern inline void * bus_to_virt (unsigned long address)
+{
+       return (void *) CACHED_ADDR(address);
+}
+
+/*
+ * Change "struct page" to physical address.
+ */
+
+extern inline void *ioremap(unsigned long offset, unsigned long size)
+{
+        return (void *) CACHED_ADDR_IO(offset);
+}
+
+extern inline void *ioremap_nocache(unsigned long offset, unsigned long size)
+{
+        return (void *) BYPASS_ADDR_IO(offset);
+}
+
+extern inline void iounmap(void *addr)
+{
+}
+
+/*
+ * Generic I/O
+ */
+
+#define readb(addr) \
+       ({ unsigned char __v = (*(volatile unsigned char *)(addr)); __v; })
+#define readw(addr) \
+       ({ unsigned short __v = (*(volatile unsigned short *)(addr)); __v; })
+#define readl(addr) \
+       ({ unsigned int __v = (*(volatile unsigned int *)(addr)); __v; })
+#define writeb(b, addr) (void)((*(volatile unsigned char *)(addr)) = (b))
+#define writew(b, addr) (void)((*(volatile unsigned short *)(addr)) = (b))
+#define writel(b, addr) (void)((*(volatile unsigned int *)(addr)) = (b))
+
+static inline __u8 __raw_readb(const volatile void __iomem *addr)
+{
+          return *(__force volatile __u8 *)(addr);
+}
+static inline __u16 __raw_readw(const volatile void __iomem *addr)
+{
+          return *(__force volatile __u16 *)(addr);
+}
+static inline __u32 __raw_readl(const volatile void __iomem *addr)
+{
+          return *(__force volatile __u32 *)(addr);
+}
+static inline void __raw_writeb(__u8 b, volatile void __iomem *addr)
+{
+          *(__force volatile __u8 *)(addr) = b;
+}
+static inline void __raw_writew(__u16 b, volatile void __iomem *addr)
+{
+          *(__force volatile __u16 *)(addr) = b;
+}
+static inline void __raw_writel(__u32 b, volatile void __iomem *addr)
+{
+          *(__force volatile __u32 *)(addr) = b;
+}
+
+
+
+
+/* These are the definitions for the x86 IO instructions
+ * inb/inw/inl/outb/outw/outl, the "string" versions
+ * insb/insw/insl/outsb/outsw/outsl, and the "pausing" versions
+ * inb_p/inw_p/...
+ * The macros don't do byte-swapping.
+ */
+
+#define inb(port)              readb((u8 *)((port)+_IO_BASE))
+#define outb(val, port)                writeb((val),(u8 *)((unsigned long)(port)+_IO_BASE))
+#define inw(port)              readw((u16 *)((port)+_IO_BASE))
+#define outw(val, port)                writew((val),(u16 *)((unsigned long)(port)+_IO_BASE))
+#define inl(port)              readl((u32 *)((port)+_IO_BASE))
+#define outl(val, port)                writel((val),(u32 *)((unsigned long)(port)))
+
+#define inb_p(port)            inb((port))
+#define outb_p(val, port)      outb((val), (port))
+#define inw_p(port)            inw((port))
+#define outw_p(val, port)      outw((val), (port))
+#define inl_p(port)            inl((port))
+#define outl_p(val, port)      outl((val), (port))
+
+extern void insb (unsigned long port, void *dst, unsigned long count);
+extern void insw (unsigned long port, void *dst, unsigned long count);
+extern void insl (unsigned long port, void *dst, unsigned long count);
+extern void outsb (unsigned long port, const void *src, unsigned long count);
+extern void outsw (unsigned long port, const void *src, unsigned long count);
+extern void outsl (unsigned long port, const void *src, unsigned long count);
+
+#define IO_SPACE_LIMIT ~0
+
+#define memset_io(a,b,c)       memset((void *)(a),(b),(c))
+#define memcpy_fromio(a,b,c)   memcpy((a),(void *)(b),(c))
+#define memcpy_toio(a,b,c)      memcpy((void *)(a),(b),(c))
+
+/* At this point the Xtensa doesn't provide byte swap instructions */
+
+#ifdef __XTENSA_EB__
+# define in_8(addr) (*(u8*)(addr))
+# define in_le16(addr) _swapw(*(u16*)(addr))
+# define in_le32(addr) _swapl(*(u32*)(addr))
+# define out_8(b, addr) *(u8*)(addr) = (b)
+# define out_le16(b, addr) *(u16*)(addr) = _swapw(b)
+# define out_le32(b, addr) *(u32*)(addr) = _swapl(b)
+#elif defined(__XTENSA_EL__)
+# define in_8(addr)  (*(u8*)(addr))
+# define in_le16(addr) (*(u16*)(addr))
+# define in_le32(addr) (*(u32*)(addr))
+# define out_8(b, addr) *(u8*)(addr) = (b)
+# define out_le16(b, addr) *(u16*)(addr) = (b)
+# define out_le32(b, addr) *(u32*)(addr) = (b)
+#else
+# error processor byte order undefined!
+#endif
+
+
+/*
+ *  * Convert a physical pointer to a virtual kernel pointer for /dev/mem
+ *   * access
+ *    */
+#define xlate_dev_mem_ptr(p)    __va(p)
+
+/*
+ *  * Convert a virtual cached pointer to an uncached pointer
+ *   */
+#define xlate_dev_kmem_ptr(p)   p
+
+
+#endif /* __KERNEL__ */
+
+#endif /* _XTENSA_IO_H */
diff --git a/include/asm-xtensa/ioctl.h b/include/asm-xtensa/ioctl.h
new file mode 100644 (file)
index 0000000..856c605
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * include/asm-xtensa/ioctl.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2003 - 2005 Tensilica Inc.
+ *
+ * Derived from "include/asm-i386/ioctl.h"
+ */
+
+#ifndef _XTENSA_IOCTL_H
+#define _XTENSA_IOCTL_H
+
+
+/* ioctl command encoding: 32 bits total, command in lower 16 bits,
+ * size of the parameter structure in the lower 14 bits of the
+ * upper 16 bits.
+ * Encoding the size of the parameter structure in the ioctl request
+ * is useful for catching programs compiled with old versions
+ * and to avoid overwriting user space outside the user buffer area.
+ * The highest 2 bits are reserved for indicating the ``access mode''.
+ * NOTE: This limits the max parameter size to 16kB -1 !
+ */
+
+/*
+ * The following is for compatibility across the various Linux
+ * platforms.  The i386 ioctl numbering scheme doesn't really enforce
+ * a type field.  De facto, however, the top 8 bits of the lower 16
+ * bits are indeed used as a type field, so we might just as well make
+ * this explicit here.  Please be sure to use the decoding macros
+ * below from now on.
+ */
+#define _IOC_NRBITS    8
+#define _IOC_TYPEBITS  8
+#define _IOC_SIZEBITS  14
+#define _IOC_DIRBITS   2
+
+#define _IOC_NRMASK    ((1 << _IOC_NRBITS)-1)
+#define _IOC_TYPEMASK  ((1 << _IOC_TYPEBITS)-1)
+#define _IOC_SIZEMASK  ((1 << _IOC_SIZEBITS)-1)
+#define _IOC_DIRMASK   ((1 << _IOC_DIRBITS)-1)
+
+#define _IOC_NRSHIFT   0
+#define _IOC_TYPESHIFT (_IOC_NRSHIFT+_IOC_NRBITS)
+#define _IOC_SIZESHIFT (_IOC_TYPESHIFT+_IOC_TYPEBITS)
+#define _IOC_DIRSHIFT  (_IOC_SIZESHIFT+_IOC_SIZEBITS)
+
+/*
+ * Direction bits.
+ */
+#define _IOC_NONE      0U
+#define _IOC_WRITE     1U
+#define _IOC_READ      2U
+
+#define _IOC(dir,type,nr,size) \
+       (((dir)  << _IOC_DIRSHIFT) | \
+        ((type) << _IOC_TYPESHIFT) | \
+        ((nr)   << _IOC_NRSHIFT) | \
+        ((size) << _IOC_SIZESHIFT))
+
+/* used to create numbers */
+#define _IO(type,nr)           _IOC(_IOC_NONE,(type),(nr),0)
+#define _IOR(type,nr,size)     _IOC(_IOC_READ,(type),(nr),sizeof(size))
+#define _IOW(type,nr,size)     _IOC(_IOC_WRITE,(type),(nr),sizeof(size))
+#define _IOWR(type,nr,size)    _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size))
+
+/* used to decode ioctl numbers.. */
+#define _IOC_DIR(nr)           (((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK)
+#define _IOC_TYPE(nr)          (((nr) >> _IOC_TYPESHIFT) & _IOC_TYPEMASK)
+#define _IOC_NR(nr)            (((nr) >> _IOC_NRSHIFT) & _IOC_NRMASK)
+#define _IOC_SIZE(nr)          (((nr) >> _IOC_SIZESHIFT) & _IOC_SIZEMASK)
+
+/* ...and for the drivers/sound files... */
+
+#define IOC_IN         (_IOC_WRITE << _IOC_DIRSHIFT)
+#define IOC_OUT                (_IOC_READ << _IOC_DIRSHIFT)
+#define IOC_INOUT      ((_IOC_WRITE|_IOC_READ) << _IOC_DIRSHIFT)
+#define IOCSIZE_MASK   (_IOC_SIZEMASK << _IOC_SIZESHIFT)
+#define IOCSIZE_SHIFT  (_IOC_SIZESHIFT)
+
+#endif
diff --git a/include/asm-xtensa/ioctls.h b/include/asm-xtensa/ioctls.h
new file mode 100644 (file)
index 0000000..10c4434
--- /dev/null
@@ -0,0 +1,112 @@
+/*
+ * include/asm-xtensa/ioctl.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2003 - 2005 Tensilica Inc.
+ *
+ * Derived from "include/asm-i386/ioctls.h"
+ */
+
+#ifndef _XTENSA_IOCTLS_H
+#define _XTENSA_IOCTLS_H
+
+#include <asm/ioctl.h>
+
+#define FIOCLEX                _IO('f', 1)
+#define FIONCLEX       _IO('f', 2)
+#define FIOASYNC       _IOW('f', 125, int)
+#define FIONBIO                _IOW('f', 126, int)
+#define FIONREAD       _IOR('f', 127, int)
+#define TIOCINQ                FIONREAD
+#define FIOQSIZE       _IOR('f', 128, loff_t)
+
+#define TCGETS         0x5401
+#define TCSETS         0x5402
+#define TCSETSW                0x5403
+#define TCSETSF                0x5404
+
+#define TCGETA         _IOR('t', 23, struct termio)
+#define TCSETA         _IOW('t', 24, struct termio)
+#define TCSETAW                _IOW('t', 25, struct termio)
+#define TCSETAF                _IOW('t', 28, struct termio)
+
+#define TCSBRK         _IO('t', 29)
+#define TCXONC         _IO('t', 30)
+#define TCFLSH         _IO('t', 31)
+
+#define TIOCSWINSZ     _IOW('t', 103, struct winsize)
+#define TIOCGWINSZ     _IOR('t', 104, struct winsize)
+#define        TIOCSTART       _IO('t', 110)           /* start output, like ^Q */
+#define        TIOCSTOP        _IO('t', 111)           /* stop output, like ^S */
+#define TIOCOUTQ        _IOR('t', 115, int)     /* output queue size */
+
+#define TIOCSPGRP      _IOW('t', 118, int)
+#define TIOCGPGRP      _IOR('t', 119, int)
+
+#define TIOCEXCL       _IO('T', 12)
+#define TIOCNXCL       _IO('T', 13)
+#define TIOCSCTTY      _IO('T', 14)
+
+#define TIOCSTI                _IOW('T', 18, char)
+#define TIOCMGET       _IOR('T', 21, unsigned int)
+#define TIOCMBIS       _IOW('T', 22, unsigned int)
+#define TIOCMBIC       _IOW('T', 23, unsigned int)
+#define TIOCMSET       _IOW('T', 24, unsigned int)
+# define TIOCM_LE      0x001
+# define TIOCM_DTR     0x002
+# define TIOCM_RTS     0x004
+# define TIOCM_ST      0x008
+# define TIOCM_SR      0x010
+# define TIOCM_CTS     0x020
+# define TIOCM_CAR     0x040
+# define TIOCM_RNG     0x080
+# define TIOCM_DSR     0x100
+# define TIOCM_CD      TIOCM_CAR
+# define TIOCM_RI      TIOCM_RNG
+
+#define TIOCGSOFTCAR   _IOR('T', 25, unsigned int)
+#define TIOCSSOFTCAR   _IOW('T', 26, unsigned int)
+#define TIOCLINUX      _IOW('T', 28, char)
+#define TIOCCONS       _IO('T', 29)
+#define TIOCGSERIAL    _IOR('T', 30, struct serial_struct)
+#define TIOCSSERIAL    _IOW('T', 31, struct serial_struct)
+#define TIOCPKT                _IOW('T', 32, int)
+# define TIOCPKT_DATA           0
+# define TIOCPKT_FLUSHREAD      1
+# define TIOCPKT_FLUSHWRITE     2
+# define TIOCPKT_STOP           4
+# define TIOCPKT_START          8
+# define TIOCPKT_NOSTOP                16
+# define TIOCPKT_DOSTOP                32
+
+
+#define TIOCNOTTY      _IO('T', 34)
+#define TIOCSETD       _IOW('T', 35, int)
+#define TIOCGETD       _IOR('T', 36, int)
+#define TCSBRKP                _IOW('T', 37, int)   /* Needed for POSIX tcsendbreak()*/
+#define TIOCTTYGSTRUCT _IOR('T', 38, struct tty_struct) /* For debugging only*/
+#define TIOCSBRK       _IO('T', 39)         /* BSD compatibility */
+#define TIOCCBRK       _IO('T', 40)         /* BSD compatibility */
+#define TIOCGSID       _IOR('T', 41, pid_t) /* Return the session ID of FD*/
+#define TIOCGPTN       _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */
+#define TIOCSPTLCK     _IOW('T',0x31, int)  /* Lock/unlock Pty */
+
+#define TIOCSERCONFIG  _IO('T', 83)
+#define TIOCSERGWILD   _IOR('T', 84,  int)
+#define TIOCSERSWILD   _IOW('T', 85,  int)
+#define TIOCGLCKTRMIOS 0x5456
+#define TIOCSLCKTRMIOS 0x5457
+#define TIOCSERGSTRUCT 0x5458               /* For debugging only */
+#define TIOCSERGETLSR   _IOR('T', 89, unsigned int) /* Get line status reg. */
+  /* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
+# define TIOCSER_TEMT    0x01               /* Transmitter physically empty */
+#define TIOCSERGETMULTI _IOR('T', 90, struct serial_multiport_struct) /* Get multiport config  */
+#define TIOCSERSETMULTI _IOW('T', 91, struct serial_multiport_struct) /* Set multiport config */
+
+#define TIOCMIWAIT     _IO('T', 92) /* wait for a change on serial input line(s) */
+#define TIOCGICOUNT    _IOR('T', 93, struct async_icount) /* read serial port inline interrupt counts */
+
+#endif /* _XTENSA_IOCTLS_H */
diff --git a/include/asm-xtensa/ipc.h b/include/asm-xtensa/ipc.h
new file mode 100644 (file)
index 0000000..d37bdb4
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * include/asm-xtensa/ipc.h
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file "COPYING" in the main directory of
+ * this archive for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_IPC_H
+#define _XTENSA_IPC_H
+
+struct ipc_kludge {
+       struct msgbuf __user *msgp;
+       long msgtyp;
+};
+
+#define SEMOP           1
+#define SEMGET          2
+#define SEMCTL          3
+#define SEMTIMEDOP      4
+#define MSGSND         11
+#define MSGRCV         12
+#define MSGGET         13
+#define MSGCTL         14
+#define SHMAT          21
+#define SHMDT          22
+#define SHMGET         23
+#define SHMCTL         24
+
+#define IPCCALL(version,op)    ((version)<<16 | (op))
+
+#endif /* _XTENSA_IPC_H */
diff --git a/include/asm-xtensa/ipcbuf.h b/include/asm-xtensa/ipcbuf.h
new file mode 100644 (file)
index 0000000..c33aa6a
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * include/asm-xtensa/ipcbuf.h
+ *
+ * The ipc64_perm structure for the Xtensa architecture.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_IPCBUF_H
+#define _XTENSA_IPCBUF_H
+
+/*
+ * Pad space is left for:
+ * - 32-bit mode_t and seq
+ * - 2 miscellaneous 32-bit values
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file "COPYING" in the main directory of
+ * this archive for more details.
+ */
+
+struct ipc64_perm
+{
+       __kernel_key_t          key;
+       __kernel_uid32_t        uid;
+       __kernel_gid32_t        gid;
+       __kernel_uid32_t        cuid;
+       __kernel_gid32_t        cgid;
+       __kernel_mode_t         mode;
+       unsigned long           seq;
+       unsigned long           __unused1;
+       unsigned long           __unused2;
+};
+
+#endif /* _XTENSA_IPCBUF_H */
diff --git a/include/asm-xtensa/irq.h b/include/asm-xtensa/irq.h
new file mode 100644 (file)
index 0000000..d984e95
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * include/asm-xtensa/irq.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_IRQ_H
+#define _XTENSA_IRQ_H
+
+#include <linux/config.h>
+#include <asm/platform/hardware.h>
+
+#include <xtensa/config/core.h>
+
+#ifndef PLATFORM_NR_IRQS
+# define PLATFORM_NR_IRQS 0
+#endif
+#define XTENSA_NR_IRQS XCHAL_NUM_INTERRUPTS
+#define NR_IRQS (XTENSA_NR_IRQS + PLATFORM_NR_IRQS)
+
+static __inline__ int irq_canonicalize(int irq)
+{
+       return (irq);
+}
+
+struct irqaction;
+#if 0 // FIXME
+extern void disable_irq_nosync(unsigned int);
+extern void disable_irq(unsigned int);
+extern void enable_irq(unsigned int);
+#endif
+
+#endif /* _XTENSA_IRQ_H */
diff --git a/include/asm-xtensa/kmap_types.h b/include/asm-xtensa/kmap_types.h
new file mode 100644 (file)
index 0000000..9e822d2
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * include/asm-xtensa/kmap_types.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_KMAP_TYPES_H
+#define _XTENSA_KMAP_TYPES_H
+
+enum km_type {
+  KM_BOUNCE_READ,
+  KM_SKB_SUNRPC_DATA,
+  KM_SKB_DATA_SOFTIRQ,
+  KM_USER0,
+  KM_USER1,
+  KM_BIO_SRC_IRQ,
+  KM_BIO_DST_IRQ,
+  KM_PTE0,
+  KM_PTE1,
+  KM_IRQ0,
+  KM_IRQ1,
+  KM_SOFTIRQ0,
+  KM_SOFTIRQ1,
+  KM_TYPE_NR
+};
+
+#endif /* _XTENSA_KMAP_TYPES_H */
diff --git a/include/asm-xtensa/linkage.h b/include/asm-xtensa/linkage.h
new file mode 100644 (file)
index 0000000..bf2128a
--- /dev/null
@@ -0,0 +1,16 @@
+/*
+ * include/asm-xtensa/linkage.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_LINKAGE_H
+#define _XTENSA_LINKAGE_H
+
+/* Nothing to do here ... */
+
+#endif /* _XTENSA_LINKAGE_H */
diff --git a/include/asm-xtensa/local.h b/include/asm-xtensa/local.h
new file mode 100644 (file)
index 0000000..48723e5
--- /dev/null
@@ -0,0 +1,16 @@
+/*
+ * include/asm-xtensa/local.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_LOCAL_H
+#define _XTENSA_LOCAL_H
+
+#include <asm-generic/local.h>
+
+#endif /* _XTENSA_LOCAL_H */
diff --git a/include/asm-xtensa/mman.h b/include/asm-xtensa/mman.h
new file mode 100644 (file)
index 0000000..9a95a45
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ * include/asm-xtensa/mman.h
+ *
+ * Xtensa Processor memory-manager definitions
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1995 by Ralf Baechle
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_MMAN_H
+#define _XTENSA_MMAN_H
+
+/*
+ * Protections are chosen from these bits, OR'd together.  The
+ * implementation does not necessarily support PROT_EXEC or PROT_WRITE
+ * without PROT_READ.  The only guarantees are that no writing will be
+ * allowed without PROT_WRITE and no access will be allowed for PROT_NONE.
+ */
+
+#define PROT_NONE      0x0             /* page can not be accessed */
+#define PROT_READ      0x1             /* page can be read */
+#define PROT_WRITE     0x2             /* page can be written */
+#define PROT_EXEC      0x4             /* page can be executed */
+
+#define PROT_SEM       0x10            /* page may be used for atomic ops */
+#define PROT_GROWSDOWN 0x01000000      /* mprotect flag: extend change to start of growsdown vma */
+#define PROT_GROWSUP   0x02000000      /* mprotect flag: extend change to end fo growsup vma */
+
+/*
+ * Flags for mmap
+ */
+#define MAP_SHARED     0x001           /* Share changes */
+#define MAP_PRIVATE    0x002           /* Changes are private */
+#define MAP_TYPE       0x00f           /* Mask for type of mapping */
+#define MAP_FIXED      0x010           /* Interpret addr exactly */
+
+/* not used by linux, but here to make sure we don't clash with ABI defines */
+#define MAP_RENAME     0x020           /* Assign page to file */
+#define MAP_AUTOGROW   0x040           /* File may grow by writing */
+#define MAP_LOCAL      0x080           /* Copy on fork/sproc */
+#define MAP_AUTORSRV   0x100           /* Logical swap reserved on demand */
+
+/* These are linux-specific */
+#define MAP_NORESERVE  0x0400          /* don't check for reservations */
+#define MAP_ANONYMOUS  0x0800          /* don't use a file */
+#define MAP_GROWSDOWN  0x1000          /* stack-like segment */
+#define MAP_DENYWRITE  0x2000          /* ETXTBSY */
+#define MAP_EXECUTABLE 0x4000          /* mark it as an executable */
+#define MAP_LOCKED     0x8000          /* pages are locked */
+#define MAP_POPULATE   0x10000         /* populate (prefault) pagetables */
+#define MAP_NONBLOCK   0x20000         /* do not block on IO */
+
+/*
+ * Flags for msync
+ */
+#define MS_ASYNC       0x0001          /* sync memory asynchronously */
+#define MS_INVALIDATE  0x0002          /* invalidate mappings & caches */
+#define MS_SYNC                0x0004          /* synchronous memory sync */
+
+/*
+ * Flags for mlockall
+ */
+#define MCL_CURRENT    1               /* lock all current mappings */
+#define MCL_FUTURE     2               /* lock all future mappings */
+
+#define MADV_NORMAL    0x0             /* default page-in behavior */
+#define MADV_RANDOM    0x1             /* page-in minimum required */
+#define MADV_SEQUENTIAL        0x2             /* read-ahead aggressively */
+#define MADV_WILLNEED  0x3             /* pre-fault pages */
+#define MADV_DONTNEED  0x4             /* discard these pages */
+
+/* compatibility flags */
+#define MAP_ANON       MAP_ANONYMOUS
+#define MAP_FILE       0
+
+#endif /* _XTENSA_MMAN_H */
diff --git a/include/asm-xtensa/mmu.h b/include/asm-xtensa/mmu.h
new file mode 100644 (file)
index 0000000..44c5bb0
--- /dev/null
@@ -0,0 +1,17 @@
+/*
+ * include/asm-xtensa/mmu.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_MMU_H
+#define _XTENSA_MMU_H
+
+/* Default "unsigned long" context */
+typedef unsigned long mm_context_t;
+
+#endif /* _XTENSA_MMU_H */
diff --git a/include/asm-xtensa/mmu_context.h b/include/asm-xtensa/mmu_context.h
new file mode 100644 (file)
index 0000000..1b08015
--- /dev/null
@@ -0,0 +1,330 @@
+/*
+ * include/asm-xtensa/mmu_context.h
+ *
+ * Switch an MMU context.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_MMU_CONTEXT_H
+#define _XTENSA_MMU_CONTEXT_H
+
+#include <linux/config.h>
+#include <linux/stringify.h>
+
+#include <asm/pgtable.h>
+#include <asm/mmu_context.h>
+#include <asm/cacheflush.h>
+#include <asm/tlbflush.h>
+
+/*
+ * Linux was ported to Xtensa assuming all auto-refill ways in set 0
+ * had the same properties (a very likely assumption).  Multiple sets
+ * of auto-refill ways will still work properly, but not as optimally
+ * as the Xtensa designer may have assumed.
+ *
+ * We make this case a hard #error, killing the kernel build, to alert
+ * the developer to this condition (which is more likely an error).
+ * You super-duper clever developers can change it to a warning or
+ * remove it altogether if you think you know what you're doing.  :)
+ */
+
+#if (XCHAL_HAVE_TLBS != 1)
+# error "Linux must have an MMU!"
+#endif
+
+#if ((XCHAL_ITLB_ARF_WAYS == 0) || (XCHAL_DTLB_ARF_WAYS == 0))
+# error "MMU must have auto-refill ways"
+#endif
+
+#if ((XCHAL_ITLB_ARF_SETS != 1) || (XCHAL_DTLB_ARF_SETS != 1))
+# error Linux may not use all auto-refill ways as efficiently as you think
+#endif
+
+#if (XCHAL_MMU_MAX_PTE_PAGE_SIZE != XCHAL_MMU_MIN_PTE_PAGE_SIZE)
+# error Only one page size allowed!
+#endif
+
+extern unsigned long asid_cache;
+extern pgd_t *current_pgd;
+
+/*
+ * Define the number of entries per auto-refill way in set 0 of both I and D
+ * TLBs.  We deal only with set 0 here (an assumption further explained in
+ * assertions.h).  Also, define the total number of ARF entries in both TLBs.
+ */
+
+#define ITLB_ENTRIES_PER_ARF_WAY  (XCHAL_ITLB_SET(XCHAL_ITLB_ARF_SET0,ENTRIES))
+#define DTLB_ENTRIES_PER_ARF_WAY  (XCHAL_DTLB_SET(XCHAL_DTLB_ARF_SET0,ENTRIES))
+
+#define ITLB_ENTRIES                                                   \
+       (ITLB_ENTRIES_PER_ARF_WAY * (XCHAL_ITLB_SET(XCHAL_ITLB_ARF_SET0,WAYS)))
+#define DTLB_ENTRIES                                                   \
+       (DTLB_ENTRIES_PER_ARF_WAY * (XCHAL_DTLB_SET(XCHAL_DTLB_ARF_SET0,WAYS)))
+
+
+/*
+ * SMALLEST_NTLB_ENTRIES is the smaller of ITLB_ENTRIES and DTLB_ENTRIES.
+ * In practice, they are probably equal.  This macro simplifies function
+ * flush_tlb_range().
+ */
+
+#if (DTLB_ENTRIES < ITLB_ENTRIES)
+# define SMALLEST_NTLB_ENTRIES  DTLB_ENTRIES
+#else
+# define SMALLEST_NTLB_ENTRIES  ITLB_ENTRIES
+#endif
+
+
+/*
+ * asid_cache tracks only the ASID[USER_RING] field of the RASID special
+ * register, which is the current user-task asid allocation value.
+ * mm->context has the same meaning.  When it comes time to write the
+ * asid_cache or mm->context values to the RASID special register, we first
+ * shift the value left by 8, then insert the value.
+ * ASID[0] always contains the kernel's asid value, and we reserve three
+ * other asid values that we never assign to user tasks.
+ */
+
+#define ASID_INC       0x1
+#define ASID_MASK      ((1 << XCHAL_MMU_ASID_BITS) - 1)
+
+/*
+ * XCHAL_MMU_ASID_INVALID is a configurable Xtensa processor constant
+ * indicating invalid address space.  XCHAL_MMU_ASID_KERNEL is a configurable
+ * Xtensa processor constant indicating the kernel address space.  They can
+ * be arbitrary values.
+ *
+ * We identify three more unique, reserved ASID values to use in the unused
+ * ring positions.  No other user process will be assigned these reserved
+ * ASID values.
+ *
+ * For example, given that
+ *
+ *     XCHAL_MMU_ASID_INVALID == 0
+ *     XCHAL_MMU_ASID_KERNEL  == 1
+ *
+ * the following maze of #if statements would generate
+ *
+ *     ASID_RESERVED_1        == 2
+ *     ASID_RESERVED_2        == 3
+ *     ASID_RESERVED_3        == 4
+ *     ASID_FIRST_NONRESERVED == 5
+ */
+
+#if (XCHAL_MMU_ASID_INVALID != XCHAL_MMU_ASID_KERNEL + 1)
+# define ASID_RESERVED_1         ((XCHAL_MMU_ASID_KERNEL + 1) & ASID_MASK)
+#else
+# define ASID_RESERVED_1         ((XCHAL_MMU_ASID_KERNEL + 2) & ASID_MASK)
+#endif
+
+#if (XCHAL_MMU_ASID_INVALID != ASID_RESERVED_1 + 1)
+# define ASID_RESERVED_2         ((ASID_RESERVED_1 + 1) & ASID_MASK)
+#else
+# define ASID_RESERVED_2         ((ASID_RESERVED_1 + 2) & ASID_MASK)
+#endif
+
+#if (XCHAL_MMU_ASID_INVALID != ASID_RESERVED_2 + 1)
+# define ASID_RESERVED_3         ((ASID_RESERVED_2 + 1) & ASID_MASK)
+#else
+# define ASID_RESERVED_3         ((ASID_RESERVED_2 + 2) & ASID_MASK)
+#endif
+
+#if (XCHAL_MMU_ASID_INVALID != ASID_RESERVED_3 + 1)
+# define ASID_FIRST_NONRESERVED  ((ASID_RESERVED_3 + 1) & ASID_MASK)
+#else
+# define ASID_FIRST_NONRESERVED  ((ASID_RESERVED_3 + 2) & ASID_MASK)
+#endif
+
+#define ASID_ALL_RESERVED ( ((ASID_RESERVED_1) << 24) + \
+                            ((ASID_RESERVED_2) << 16) + \
+                            ((ASID_RESERVED_3) <<  8) + \
+                            ((XCHAL_MMU_ASID_KERNEL))   )
+
+
+/*
+ * NO_CONTEXT is the invalid ASID value that we don't ever assign to
+ * any user or kernel context.  NO_CONTEXT is a better mnemonic than
+ * XCHAL_MMU_ASID_INVALID, so we use it in code instead.
+ */
+
+#define NO_CONTEXT   XCHAL_MMU_ASID_INVALID
+
+#if (KERNEL_RING != 0)
+# error The KERNEL_RING really should be zero.
+#endif
+
+#if (USER_RING >= XCHAL_MMU_RINGS)
+# error USER_RING cannot be greater than the highest numbered ring.
+#endif
+
+#if (USER_RING == KERNEL_RING)
+# error The user and kernel rings really should not be equal.
+#endif
+
+#if (USER_RING == 1)
+#define ASID_INSERT(x) ( ((ASID_RESERVED_1)   << 24) + \
+                         ((ASID_RESERVED_2)   << 16) + \
+                         (((x) & (ASID_MASK)) <<  8) + \
+                         ((XCHAL_MMU_ASID_KERNEL))   )
+
+#elif (USER_RING == 2)
+#define ASID_INSERT(x) ( ((ASID_RESERVED_1)   << 24) + \
+                         (((x) & (ASID_MASK)) << 16) + \
+                         ((ASID_RESERVED_2)   <<  8) + \
+                         ((XCHAL_MMU_ASID_KERNEL))   )
+
+#elif (USER_RING == 3)
+#define ASID_INSERT(x) ( (((x) & (ASID_MASK)) << 24) + \
+                        ((ASID_RESERVED_1)   << 16) + \
+                         ((ASID_RESERVED_2)   <<  8) + \
+                         ((XCHAL_MMU_ASID_KERNEL))   )
+
+#else
+#error Goofy value for USER_RING
+
+#endif /* USER_RING == 1 */
+
+
+/*
+ *  All unused by hardware upper bits will be considered
+ *  as a software asid extension.
+ */
+
+#define ASID_VERSION_MASK  ((unsigned long)~(ASID_MASK|(ASID_MASK-1)))
+#define ASID_FIRST_VERSION                                             \
+       ((unsigned long)(~ASID_VERSION_MASK) + 1 + ASID_FIRST_NONRESERVED)
+
+extern inline void set_rasid_register (unsigned long val)
+{
+       __asm__ __volatile__ (" wsr %0, "__stringify(RASID)"\n\t"
+                             " isync\n" : : "a" (val));
+}
+
+extern inline unsigned long get_rasid_register (void)
+{
+       unsigned long tmp;
+       __asm__ __volatile__ (" rsr %0, "__stringify(RASID)"\n\t" : "=a" (tmp));
+       return tmp;
+}
+
+
+#if ((XCHAL_MMU_ASID_INVALID == 0) && (XCHAL_MMU_ASID_KERNEL == 1))
+
+extern inline void
+get_new_mmu_context(struct mm_struct *mm, unsigned long asid)
+{
+       extern void flush_tlb_all(void);
+       if (! ((asid += ASID_INC) & ASID_MASK) ) {
+               flush_tlb_all(); /* start new asid cycle */
+               if (!asid)      /* fix version if needed */
+                       asid = ASID_FIRST_VERSION - ASID_FIRST_NONRESERVED;
+               asid += ASID_FIRST_NONRESERVED;
+       }
+       mm->context = asid_cache = asid;
+}
+
+#else
+#warning ASID_{INVALID,KERNEL} values impose non-optimal get_new_mmu_context implementation
+
+/* XCHAL_MMU_ASID_INVALID == 0 and XCHAL_MMU_ASID_KERNEL ==1 are
+   really the best, but if you insist... */
+
+extern inline int validate_asid (unsigned long asid)
+{
+       switch (asid) {
+       case XCHAL_MMU_ASID_INVALID:
+       case XCHAL_MMU_ASID_KERNEL:
+       case ASID_RESERVED_1:
+       case ASID_RESERVED_2:
+       case ASID_RESERVED_3:
+               return 0; /* can't use these values as ASIDs */
+       }
+       return 1; /* valid */
+}
+
+extern inline void
+get_new_mmu_context(struct mm_struct *mm, unsigned long asid)
+{
+       extern void flush_tlb_all(void);
+       while (1) {
+               asid += ASID_INC;
+               if ( ! (asid & ASID_MASK) ) {
+                       flush_tlb_all(); /* start new asid cycle */
+                       if (!asid)      /* fix version if needed */
+                               asid = ASID_FIRST_VERSION - ASID_FIRST_NONRESERVED;
+                       asid += ASID_FIRST_NONRESERVED;
+                       break; /* no need to validate here */
+               }
+               if (validate_asid (asid & ASID_MASK))
+                       break;
+       }
+       mm->context = asid_cache = asid;
+}
+
+#endif
+
+
+/*
+ * Initialize the context related info for a new mm_struct
+ * instance.
+ */
+
+extern inline int
+init_new_context(struct task_struct *tsk, struct mm_struct *mm)
+{
+       mm->context = NO_CONTEXT;
+       return 0;
+}
+
+extern inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
+                             struct task_struct *tsk)
+{
+       unsigned long asid = asid_cache;
+
+       /* Check if our ASID is of an older version and thus invalid */
+
+       if ((next->context ^ asid) & ASID_VERSION_MASK)
+               get_new_mmu_context(next, asid);
+
+       set_rasid_register (ASID_INSERT(next->context));
+       invalidate_page_directory();
+}
+
+#define deactivate_mm(tsk, mm) do { } while(0)
+
+/*
+ * Destroy context related info for an mm_struct that is about
+ * to be put to rest.
+ */
+extern inline void destroy_context(struct mm_struct *mm)
+{
+       /* Nothing to do. */
+}
+
+/*
+ * After we have set current->mm to a new value, this activates
+ * the context for the new mm so we see the new mappings.
+ */
+extern inline void
+activate_mm(struct mm_struct *prev, struct mm_struct *next)
+{
+       /* Unconditionally get a new ASID.  */
+
+       get_new_mmu_context(next, asid_cache);
+       set_rasid_register (ASID_INSERT(next->context));
+       invalidate_page_directory();
+}
+
+
+static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
+{
+       /* Nothing to do. */
+
+}
+
+#endif /* _XTENSA_MMU_CONTEXT_H */
diff --git a/include/asm-xtensa/module.h b/include/asm-xtensa/module.h
new file mode 100644 (file)
index 0000000..ffb25bf
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * include/asm-xtensa/module.h
+ *
+ * This file contains the module code specific to the Xtensa architecture.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_MODULE_H
+#define _XTENSA_MODULE_H
+
+struct mod_arch_specific
+{
+       /* Module support is not completely implemented. */
+};
+
+#define Elf_Shdr Elf32_Shdr
+#define Elf_Sym Elf32_Sym
+#define Elf_Ehdr Elf32_Ehdr
+
+#endif /* _XTENSA_MODULE_H */
diff --git a/include/asm-xtensa/msgbuf.h b/include/asm-xtensa/msgbuf.h
new file mode 100644 (file)
index 0000000..693c967
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * include/asm-xtensa/msgbuf.h
+ *
+ * The msqid64_ds structure for the Xtensa architecture.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - 64-bit time_t to solve y2038 problem
+ * - 2 miscellaneous 32-bit values
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file "COPYING" in the main directory of
+ * this archive for more details.
+ */
+
+#ifndef _XTENSA_MSGBUF_H
+#define _XTENSA_MSGBUF_H
+
+struct msqid64_ds {
+       struct ipc64_perm msg_perm;
+#ifdef __XTENSA_EB__
+       unsigned int    __unused1;
+       __kernel_time_t msg_stime;      /* last msgsnd time */
+       unsigned int    __unused2;
+       __kernel_time_t msg_rtime;      /* last msgrcv time */
+       unsigned int    __unused3;
+       __kernel_time_t msg_ctime;      /* last change time */
+#elif defined(__XTENSA_EL__)
+       __kernel_time_t msg_stime;      /* last msgsnd time */
+       unsigned int    __unused1;
+       __kernel_time_t msg_rtime;      /* last msgrcv time */
+       unsigned int    __unused2;
+       __kernel_time_t msg_ctime;      /* last change time */
+       unsigned int    __unused3;
+#else
+# error processor byte order undefined!
+#endif
+       unsigned long  msg_cbytes;      /* current number of bytes on queue */
+       unsigned long  msg_qnum;        /* number of messages in queue */
+       unsigned long  msg_qbytes;      /* max number of bytes on queue */
+       __kernel_pid_t msg_lspid;       /* pid of last msgsnd */
+       __kernel_pid_t msg_lrpid;       /* last receive pid */
+       unsigned long  __unused4;
+       unsigned long  __unused5;
+};
+
+#endif /* _XTENSA_MSGBUF_H */
diff --git a/include/asm-xtensa/namei.h b/include/asm-xtensa/namei.h
new file mode 100644 (file)
index 0000000..3fdff03
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * include/asm-xtensa/namei.h
+ *
+ * Included from linux/fs/namei.c
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_NAMEI_H
+#define _XTENSA_NAMEI_H
+
+#ifdef __KERNEL__
+
+/* This dummy routine maybe changed to something useful
+ * for /usr/gnemul/ emulation stuff.
+ * Look at asm-sparc/namei.h for details.
+ */
+
+#define __emul_prefix() NULL
+
+#endif /* __KERNEL__ */
+#endif /* _XTENSA_NAMEI_H */
diff --git a/include/asm-xtensa/page.h b/include/asm-xtensa/page.h
new file mode 100644 (file)
index 0000000..b495e5b
--- /dev/null
@@ -0,0 +1,133 @@
+/*
+ * linux/include/asm-xtensa/page.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version2 as
+ * published by the Free Software Foundation.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_PAGE_H
+#define _XTENSA_PAGE_H
+
+#ifdef __KERNEL__
+
+#include <asm/processor.h>
+#include <linux/config.h>
+
+/*
+ * PAGE_SHIFT determines the page size
+ * PAGE_ALIGN(x) aligns the pointer to the (next) page boundary
+ */
+
+#define PAGE_SHIFT             XCHAL_MMU_MIN_PTE_PAGE_SIZE
+#define PAGE_SIZE              (1 << PAGE_SHIFT)
+#define PAGE_MASK              (~(PAGE_SIZE-1))
+#define PAGE_ALIGN(addr)       (((addr)+PAGE_SIZE - 1) & PAGE_MASK)
+
+#define DCACHE_WAY_SIZE                (XCHAL_DCACHE_SIZE / XCHAL_DCACHE_WAYS)
+#define PAGE_OFFSET            XCHAL_KSEG_CACHED_VADDR
+
+#ifdef __ASSEMBLY__
+
+#define __pgprot(x)    (x)
+
+#else
+
+/*
+ * These are used to make use of C type-checking..
+ */
+
+typedef struct { unsigned long pte; } pte_t;           /* page table entry */
+typedef struct { unsigned long pgd; } pgd_t;           /* PGD table entry */
+typedef struct { unsigned long pgprot; } pgprot_t;
+
+#define pte_val(x)     ((x).pte)
+#define pgd_val(x)     ((x).pgd)
+#define pgprot_val(x)  ((x).pgprot)
+
+#define __pte(x)       ((pte_t) { (x) } )
+#define __pgd(x)       ((pgd_t) { (x) } )
+#define __pgprot(x)    ((pgprot_t) { (x) } )
+
+/*
+ * Pure 2^n version of get_order
+ */
+
+extern __inline__ int get_order(unsigned long size)
+{
+       int order;
+#ifndef XCHAL_HAVE_NSU
+       unsigned long x1, x2, x4, x8, x16;
+
+       size = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
+       x1  = size & 0xAAAAAAAA;
+       x2  = size & 0xCCCCCCCC;
+       x4  = size & 0xF0F0F0F0;
+       x8  = size & 0xFF00FF00;
+       x16 = size & 0xFFFF0000;
+       order = x2 ? 2 : 0;
+       order += (x16 != 0) * 16;
+       order += (x8 != 0) * 8;
+       order += (x4 != 0) * 4;
+       order += (x1 != 0);
+
+       return order;
+#else
+       size = (size - 1) >> PAGE_SHIFT;
+       asm ("nsau %0, %1" : "=r" (order) : "r" (size));
+       return 32 - order;
+#endif
+}
+
+
+struct page;
+extern void clear_page(void *page);
+extern void copy_page(void *to, void *from);
+
+/*
+ * If we have cache aliasing and writeback caches, we might have to do
+ * some extra work
+ */
+
+#if (DCACHE_WAY_SIZE > PAGE_SIZE)
+void clear_user_page(void *addr, unsigned long vaddr, struct page* page);
+void copy_user_page(void *to,void* from,unsigned long vaddr,struct page* page);
+#else
+# define clear_user_page(page,vaddr,pg)                clear_page(page)
+# define copy_user_page(to, from, vaddr, pg)   copy_page(to, from)
+#endif
+
+/*
+ * This handles the memory map.  We handle pages at
+ * XCHAL_KSEG_CACHED_VADDR for kernels with 32 bit address space.
+ * These macros are for conversion of kernel address, not user
+ * addresses.
+ */
+
+#define __pa(x)                        ((unsigned long) (x) - PAGE_OFFSET)
+#define __va(x)                        ((void *)((unsigned long) (x) + PAGE_OFFSET))
+#define pfn_valid(pfn)         ((unsigned long)pfn < max_mapnr)
+#ifndef CONFIG_DISCONTIGMEM
+# define pfn_to_page(pfn)      (mem_map + (pfn))
+# define page_to_pfn(page)     ((unsigned long)((page) - mem_map))
+#else
+# error CONFIG_DISCONTIGMEM not supported
+#endif
+
+#define virt_to_page(kaddr)    pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
+#define page_to_virt(page)     __va(page_to_pfn(page) << PAGE_SHIFT)
+#define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
+#define page_to_phys(page)     (page_to_pfn(page) << PAGE_SHIFT)
+
+#define WANT_PAGE_VIRTUAL
+
+
+#endif /* __ASSEMBLY__ */
+
+#define VM_DATA_DEFAULT_FLAGS  (VM_READ | VM_WRITE | VM_EXEC | \
+                                VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
+
+#endif /* __KERNEL__ */
+#endif /* _XTENSA_PAGE_H */
diff --git a/include/asm-xtensa/page.h.n b/include/asm-xtensa/page.h.n
new file mode 100644 (file)
index 0000000..546cc66
--- /dev/null
@@ -0,0 +1,135 @@
+/*
+ * linux/include/asm-xtensa/page.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version2 as
+ * published by the Free Software Foundation.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_PAGE_H
+#define _XTENSA_PAGE_H
+
+#ifdef __KERNEL__
+
+#include <asm/processor.h>
+#include <linux/config.h>
+
+/*
+ * PAGE_SHIFT determines the page size
+ * PAGE_ALIGN(x) aligns the pointer to the (next) page boundary
+ */
+#define PAGE_SHIFT             XCHAL_MMU_MIN_PTE_PAGE_SIZE
+#define PAGE_SIZE              (1 << PAGE_SHIFT)
+#define PAGE_MASK              (~(PAGE_SIZE-1))
+#define PAGE_ALIGN(addr)       (((addr)+PAGE_SIZE - 1) & PAGE_MASK)
+
+#define DCACHE_WAY_SIZE                (XCHAL_DCACHE_SIZE / XCHAL_DCACHE_WAYS)
+#define PAGE_OFFSET            XCHAL_KSEG_CACHED_VADDR
+
+#ifdef __ASSEMBLY__
+
+#define __pgprot(x)    (x)
+
+#else
+
+
+/*
+ * These are used to make use of C type-checking..
+ */
+typedef struct { unsigned long pte; } pte_t;           /* page table entry */
+typedef struct { unsigned long pmd; } pmd_t;           /* PMD table entry */
+typedef struct { unsigned long pgd; } pgd_t;           /* PGD table entry */
+typedef struct { unsigned long pgprot; } pgprot_t;
+
+#define pte_val(x)     ((x).pte)
+#define pmd_val(x)     ((x).pmd)
+#define pgd_val(x)     ((x).pgd)
+#define pgprot_val(x)  ((x).pgprot)
+
+#define __pte(x)       ((pte_t) { (x) } )
+#define __pmd(x)       ((pmd_t) { (x) } )
+#define __pgd(x)       ((pgd_t) { (x) } )
+#define __pgprot(x)    ((pgprot_t) { (x) } )
+
+/*
+ * Pure 2^n version of get_order
+ */
+extern __inline__ int get_order(unsigned long size)
+{
+       int order;
+#ifndef XCHAL_HAVE_NSU
+       unsigned long x1, x2, x4, x8, x16;
+
+       size = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
+       x1  = size & 0xAAAAAAAA;
+       x2  = size & 0xCCCCCCCC;
+       x4  = size & 0xF0F0F0F0;
+       x8  = size & 0xFF00FF00;
+       x16 = size & 0xFFFF0000;
+       order = x2 ? 2 : 0;
+       order += (x16 != 0) * 16;
+       order += (x8 != 0) * 8;
+       order += (x4 != 0) * 4;
+       order += (x1 != 0);
+
+       return order;
+#else
+       size = (size - 1) >> PAGE_SHIFT;
+       asm ("nsau %0, %1" : "=r" (order) : "r" (size));
+       return 32 - order;
+#endif
+}
+
+
+struct page;
+extern void clear_page(void *page);
+extern void copy_page(void *to, void *from);
+
+/*
+ * If we have cache aliasing and writeback caches, we might have to do
+ * some extra work
+ */
+
+#if (DCACHE_WAY_SIZE > PAGE_SIZE) && XCHAL_DCACHE_IS_WRITEBACK
+void clear_user_page(void *addr, unsigned long vaddr, struct page* page);
+void copy_user_page(void *to, void* from, unsigned long vaddr, struct page* page);
+#else
+# define clear_user_page(page,vaddr,pg)                clear_page(page)
+# define copy_user_page(to, from, vaddr, pg)   copy_page(to, from)
+#endif
+
+
+/*
+ * This handles the memory map.  We handle pages at
+ * XCHAL_KSEG_CACHED_VADDR for kernels with 32 bit address space.
+ * These macros are for conversion of kernel address, not user
+ * addresses.
+ */
+
+#define __pa(x)                        ((unsigned long) (x) - PAGE_OFFSET)
+#define __va(x)                        ((void *)((unsigned long) (x) + PAGE_OFFSET))
+#define pfn_valid(pfn)         ((unsigned long)pfn < max_mapnr)
+#ifndef CONFIG_DISCONTIGMEM
+# define pfn_to_page(pfn)      (mem_map + (pfn))
+# define page_to_pfn(page)     ((unsigned long)((page) - mem_map))
+#else
+# error CONFIG_DISCONTIGMEM not supported
+#endif
+
+#define virt_to_page(kaddr)    pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
+#define page_to_virt(page)     __va(page_to_pfn(page) << PAGE_SHIFT)
+#define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
+#define page_to_phys(page)     (page_to_pfn(page) << PAGE_SHIFT)
+
+#define WANT_PAGE_VIRTUAL
+
+
+#endif /* __ASSEMBLY__ */
+
+#define VM_DATA_DEFAULT_FLAGS  (VM_READ | VM_WRITE | VM_EXEC | \
+                                VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
+
+#endif /* __KERNEL__ */
+#endif /* _XTENSA_PAGE_H */
diff --git a/include/asm-xtensa/param.h b/include/asm-xtensa/param.h
new file mode 100644 (file)
index 0000000..c0eec82
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * include/asm-xtensa/param.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_PARAM_H
+#define _XTENSA_PARAM_H
+
+#include <xtensa/config/core.h>
+
+#ifdef __KERNEL__
+# define HZ            100             /* internal timer frequency */
+# define USER_HZ       100             /* for user interfaces in "ticks" */
+# define CLOCKS_PER_SEC (USER_HZ)      /* frequnzy at which times() counts */
+#endif
+
+#define EXEC_PAGESIZE  (1 << XCHAL_MMU_MIN_PTE_PAGE_SIZE)
+
+#ifndef NGROUPS
+#define NGROUPS                32
+#endif
+
+#ifndef NOGROUP
+#define NOGROUP                (-1)
+#endif
+
+#define MAXHOSTNAMELEN 64      /* max length of hostname */
+
+#endif /* _XTENSA_PARAM_H */
diff --git a/include/asm-xtensa/pci-bridge.h b/include/asm-xtensa/pci-bridge.h
new file mode 100644 (file)
index 0000000..00fcbd7
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ * include/asm-xtensa/pci-bridge.h
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file "COPYING" in the main directory of
+ * this archive for more details.
+ *
+ * Copyright (C) 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_PCI_BRIDGE_H
+#define _XTENSA_PCI_BRIDGE_H
+
+#ifdef __KERNEL__
+
+struct device_node;
+struct pci_controller;
+
+/*
+ * pciauto_bus_scan() enumerates the pci space.
+ */
+
+extern int pciauto_bus_scan(struct pci_controller *, int);
+
+struct pci_space {
+       unsigned long start;
+       unsigned long end;
+       unsigned long base;
+};
+
+/*
+ * Structure of a PCI controller (host bridge)
+ */
+
+struct pci_controller {
+       int index;                      /* used for pci_controller_num */
+       struct pci_controller *next;
+        struct pci_bus *bus;
+       void *arch_data;
+
+       int first_busno;
+       int last_busno;
+
+       struct pci_ops *ops;
+       volatile unsigned int *cfg_addr;
+       volatile unsigned char *cfg_data;
+
+       /* Currently, we limit ourselves to 1 IO range and 3 mem
+        * ranges since the common pci_bus structure can't handle more
+        */
+       struct resource io_resource;
+       struct resource mem_resources[3];
+       int mem_resource_count;
+
+       /* Host bridge I/O and Memory space
+        * Used for BAR placement algorithms
+        */
+       struct pci_space io_space;
+       struct pci_space mem_space;
+
+       /* Return the interrupt number fo a device. */
+       int (*map_irq)(struct pci_dev*, u8, u8);
+
+};
+
+static inline void pcibios_init_resource(struct resource *res,
+               unsigned long start, unsigned long end, int flags, char *name)
+{
+       res->start = start;
+       res->end = end;
+       res->flags = flags;
+       res->name = name;
+       res->parent = NULL;
+       res->sibling = NULL;
+       res->child = NULL;
+}
+
+
+/* These are used for config access before all the PCI probing has been done. */
+int early_read_config_byte(struct pci_controller*, int, int, int, u8*);
+int early_read_config_word(struct pci_controller*, int, int, int, u16*);
+int early_read_config_dword(struct pci_controller*, int, int, int, u32*);
+int early_write_config_byte(struct pci_controller*, int, int, int, u8);
+int early_write_config_word(struct pci_controller*, int, int, int, u16);
+int early_write_config_dword(struct pci_controller*, int, int, int, u32);
+
+#endif /* __KERNEL__ */
+#endif /* _XTENSA_PCI_BRIDGE_H */
diff --git a/include/asm-xtensa/pci.h b/include/asm-xtensa/pci.h
new file mode 100644 (file)
index 0000000..6817742
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ * linux/include/asm-xtensa/pci.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_PCI_H
+#define _XTENSA_PCI_H
+
+#ifdef __KERNEL__
+
+/* Can be used to override the logic in pci_scan_bus for skipping
+ * already-configured bus numbers - to be used for buggy BIOSes
+ * or architectures with incomplete PCI setup by the loader
+ */
+
+#define pcibios_assign_all_busses()    0
+
+extern struct pci_controller* pcibios_alloc_controller(void);
+
+extern inline void pcibios_set_master(struct pci_dev *dev)
+{
+       /* No special bus mastering setup handling */
+}
+
+extern inline void pcibios_penalize_isa_irq(int irq)
+{
+       /* We don't do dynamic PCI IRQ allocation */
+}
+
+/* Assume some values. (We should revise them, if necessary) */
+
+#define PCIBIOS_MIN_IO         0x2000
+#define PCIBIOS_MIN_MEM                0x10000000
+
+/* Dynamic DMA mapping stuff.
+ * Xtensa has everything mapped statically like x86.
+ */
+
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <asm/scatterlist.h>
+#include <linux/string.h>
+#include <asm/io.h>
+
+struct pci_dev;
+
+/* The PCI address space does equal the physical memory address space.
+ * The networking and block device layers use this boolean for bounce buffer
+ * decisions.
+ */
+
+#define PCI_DMA_BUS_IS_PHYS    (1)
+
+/* pci_unmap_{page,single} is a no-op, so */
+#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME)
+#define DECLARE_PCI_UNMAP_LEN(LEN_NAME)
+#define pci_unmap_addr(PTR, ADDR_NAME)         (0)
+#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL)        do { } while (0)
+#define pci_ubnmap_len(PTR, LEN_NAME)          (0)
+#define pci_unmap_len_set(PTR, LEN_NAME, VAL)  do { } while (0)
+
+/* We cannot access memory above 4GB */
+#define pci_dac_dma_supported(pci_dev, mask)   (0)
+
+/* Map a range of PCI memory or I/O space for a device into user space */
+int pci_mmap_page_range(struct pci_dev *pdev, struct vm_area_struct *vma,
+                        enum pci_mmap_state mmap_state, int write_combine);
+
+/* Tell drivers/pci/proc.c that we have pci_mmap_page_range() */
+#define HAVE_PCI_MMAP  1
+
+static inline void pcibios_add_platform_entries(struct pci_dev *dev)
+{
+}
+
+#endif /* __KERNEL__ */
+
+/* Implement the pci_ DMA API in terms of the generic device dma_ one */
+#include <asm-generic/pci-dma-compat.h>
+
+/* Generic PCI */
+#include <asm-generic/pci.h>
+
+#endif /* _XTENSA_PCI_H */
diff --git a/include/asm-xtensa/percpu.h b/include/asm-xtensa/percpu.h
new file mode 100644 (file)
index 0000000..6d2bc2a
--- /dev/null
@@ -0,0 +1,16 @@
+/*
+ * linux/include/asm-xtensa/percpu.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_PERCPU__
+#define _XTENSA_PERCPU__
+
+#include <asm-generic/percpu.h>
+
+#endif /* _XTENSA_PERCPU__ */
diff --git a/include/asm-xtensa/pgalloc.h b/include/asm-xtensa/pgalloc.h
new file mode 100644 (file)
index 0000000..734a8d0
--- /dev/null
@@ -0,0 +1,116 @@
+/*
+ * linux/include/asm-xtensa/pgalloc.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Copyright (C) 2001-2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_PGALLOC_H
+#define _XTENSA_PGALLOC_H
+
+#ifdef __KERNEL__
+
+#include <linux/config.h>
+#include <linux/threads.h>
+#include <linux/highmem.h>
+#include <asm/processor.h>
+#include <asm/cacheflush.h>
+
+
+/* Cache aliasing:
+ *
+ * If the cache size for one way is greater than the page size, we have to
+ * deal with cache aliasing. The cache index is wider than the page size:
+ *
+ *      |cache |
+ * |pgnum |page|       virtual address
+ * |xxxxxX|zzzz|
+ * |      |    |
+ *   \  / |    |
+ *  trans.|    |
+ *   /  \ |    |
+ * |yyyyyY|zzzz|       physical address
+ *
+ * When the page number is translated to the physical page address, the lowest
+ * bit(s) (X) that are also part of the cache index are also translated (Y).
+ * If this translation changes this bit (X), the cache index is also afected,
+ * thus resulting in a different cache line than before.
+ * The kernel does not provide a mechanism to ensure that the page color
+ * (represented by this bit) remains the same when allocated or when pages
+ * are remapped. When user pages are mapped into kernel space, the color of
+ * the page might also change.
+ *
+ * We use the address space VMALLOC_END ... VMALLOC_END + DCACHE_WAY_SIZE * 2
+ * to temporarily map a patch so we can match the color.
+ */
+
+#if (DCACHE_WAY_SIZE > PAGE_SIZE)
+# define PAGE_COLOR_MASK       (PAGE_MASK & (DCACHE_WAY_SIZE-1))
+# define PAGE_COLOR(a)         \
+       (((unsigned long)(a)&PAGE_COLOR_MASK) >> PAGE_SHIFT)
+# define PAGE_COLOR_EQ(a,b)    \
+       ((((unsigned long)(a) ^ (unsigned long)(b)) & PAGE_COLOR_MASK) == 0)
+# define PAGE_COLOR_MAP0(v)    \
+       (VMALLOC_END + ((unsigned long)(v) & PAGE_COLOR_MASK))
+# define PAGE_COLOR_MAP1(v)    \
+       (VMALLOC_END + ((unsigned long)(v) & PAGE_COLOR_MASK) + DCACHE_WAY_SIZE)
+#endif
+
+/*
+ * Allocating and freeing a pmd is trivial: the 1-entry pmd is
+ * inside the pgd, so has no extra memory associated with it.
+ */
+
+#define pgd_free(pgd)  free_page((unsigned long)(pgd))
+
+#if (DCACHE_WAY_SIZE > PAGE_SIZE) && XCHAL_DCACHE_IS_WRITEBACK
+
+static inline void
+pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmdp, pte_t *pte)
+{
+       pmd_val(*(pmdp)) = (unsigned long)(pte);
+       __asm__ __volatile__ ("memw; dhwb %0, 0; dsync" :: "a" (pmdp));
+}
+
+static inline void
+pmd_populate(struct mm_struct *mm, pmd_t *pmdp, struct page *page)
+{
+       pmd_val(*(pmdp)) = (unsigned long)page_to_virt(page);
+       __asm__ __volatile__ ("memw; dhwb %0, 0; dsync" :: "a" (pmdp));
+}
+
+
+
+#else
+
+# define pmd_populate_kernel(mm, pmdp, pte)                                 \
+       (pmd_val(*(pmdp)) = (unsigned long)(pte))
+# define pmd_populate(mm, pmdp, page)                                       \
+       (pmd_val(*(pmdp)) = (unsigned long)page_to_virt(page))
+
+#endif
+
+static inline pgd_t*
+pgd_alloc(struct mm_struct *mm)
+{
+       pgd_t *pgd;
+
+       pgd = (pgd_t *)__get_free_pages(GFP_KERNEL|__GFP_ZERO, PGD_ORDER);
+
+       if (likely(pgd != NULL))
+               __flush_dcache_page((unsigned long)pgd);
+
+       return pgd;
+}
+
+extern pte_t* pte_alloc_one_kernel(struct mm_struct* mm, unsigned long addr);
+extern struct page* pte_alloc_one(struct mm_struct* mm, unsigned long addr);
+
+#define pte_free_kernel(pte) free_page((unsigned long)pte)
+#define pte_free(pte) __free_page(pte)
+
+#endif /* __KERNEL__ */
+#endif /* _XTENSA_PGALLOC_H */
diff --git a/include/asm-xtensa/pgtable.h b/include/asm-xtensa/pgtable.h
new file mode 100644 (file)
index 0000000..0bb6416
--- /dev/null
@@ -0,0 +1,468 @@
+/*
+ * linux/include/asm-xtensa/page.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version2 as
+ * published by the Free Software Foundation.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_PGTABLE_H
+#define _XTENSA_PGTABLE_H
+
+#include <asm-generic/pgtable-nopmd.h>
+#include <asm/page.h>
+
+/* Assertions. */
+
+#ifdef CONFIG_MMU
+
+
+#if (XCHAL_MMU_RINGS < 2)
+# error Linux build assumes at least 2 ring levels.
+#endif
+
+#if (XCHAL_MMU_CA_BITS != 4)
+# error We assume exactly four bits for CA.
+#endif
+
+#if (XCHAL_MMU_SR_BITS != 0)
+# error We have no room for SR bits.
+#endif
+
+/*
+ * Use the first min-wired way for mapping page-table pages.
+ * Page coloring requires a second min-wired way.
+ */
+
+#if (XCHAL_DTLB_MINWIRED_SETS == 0)
+# error Need a min-wired way for mapping page-table pages
+#endif
+
+#define DTLB_WAY_PGTABLE XCHAL_DTLB_SET(XCHAL_DTLB_MINWIRED_SET0, WAY)
+
+#if (DCACHE_WAY_SIZE > PAGE_SIZE) && XCHAL_DCACHE_IS_WRITEBACK
+# if XCHAL_DTLB_SET(XCHAL_DTLB_MINWIRED_SET0, WAYS) >= 2
+#  define DTLB_WAY_DCACHE_ALIAS0 (DTLB_WAY_PGTABLE + 1)
+#  define DTLB_WAY_DCACHE_ALIAS1 (DTLB_WAY_PGTABLE + 2)
+# else
+#  error Page coloring requires its own wired dtlb way!
+# endif
+#endif
+
+#endif /* CONFIG_MMU */
+
+/*
+ * We only use two ring levels, user and kernel space.
+ */
+
+#define USER_RING              1       /* user ring level */
+#define KERNEL_RING            0       /* kernel ring level */
+
+/*
+ * The Xtensa architecture port of Linux has a two-level page table system,
+ * i.e. the logical three-level Linux page table layout are folded.
+ * Each task has the following memory page tables:
+ *
+ *   PGD table (page directory), ie. 3rd-level page table:
+ *     One page (4 kB) of 1024 (PTRS_PER_PGD) pointers to PTE tables
+ *     (Architectures that don't have the PMD folded point to the PMD tables)
+ *
+ *     The pointer to the PGD table for a given task can be retrieved from
+ *     the task structure (struct task_struct*) t, e.g. current():
+ *       (t->mm ? t->mm : t->active_mm)->pgd
+ *
+ *   PMD tables (page middle-directory), ie. 2nd-level page tables:
+ *     Absent for the Xtensa architecture (folded, PTRS_PER_PMD == 1).
+ *
+ *   PTE tables (page table entry), ie. 1st-level page tables:
+ *     One page (4 kB) of 1024 (PTRS_PER_PTE) PTEs with a special PTE
+ *     invalid_pte_table for absent mappings.
+ *
+ * The individual pages are 4 kB big with special pages for the empty_zero_page.
+ */
+#define PGDIR_SHIFT    22
+#define PGDIR_SIZE     (1UL << PGDIR_SHIFT)
+#define PGDIR_MASK     (~(PGDIR_SIZE-1))
+
+/*
+ * Entries per page directory level: we use two-level, so
+ * we don't really have any PMD directory physically.
+ */
+#define PTRS_PER_PTE           1024
+#define PTRS_PER_PTE_SHIFT     10
+#define PTRS_PER_PMD           1
+#define PTRS_PER_PGD           1024
+#define PGD_ORDER              0
+#define PMD_ORDER              0
+#define USER_PTRS_PER_PGD      (TASK_SIZE/PGDIR_SIZE)
+#define FIRST_USER_ADDRESS      XCHAL_SEG_MAPPABLE_VADDR
+#define FIRST_USER_PGD_NR      (FIRST_USER_ADDRESS >> PGDIR_SHIFT)
+
+/* virtual memory area. We keep a distance to other memory regions to be
+ * on the safe side. We also use this area for cache aliasing.
+ */
+
+// FIXME: virtual memory area must be configuration-dependent
+
+#define VMALLOC_START          0xC0000000
+#define VMALLOC_END            0xC7FF0000
+
+/* Xtensa Linux config PTE layout (when present):
+ *     31-12:  PPN
+ *     11-6:   Software
+ *     5-4:    RING
+ *     3-0:    CA
+ *
+ * Similar to the Alpha and MIPS ports, we need to keep track of the ref
+ * and mod bits in software.  We have a software "you can read
+ * from this page" bit, and a hardware one which actually lets the
+ * process read from the page.  On the same token we have a software
+ * writable bit and the real hardware one which actually lets the
+ * process write to the page.
+ *
+ * See further below for PTE layout for swapped-out pages.
+ */
+
+#define _PAGE_VALID            (1<<0)  /* hardware: page is accessible */
+#define _PAGE_WRENABLE         (1<<1)  /* hardware: page is writable */
+
+/* None of these cache modes include MP coherency:  */
+#define _PAGE_NO_CACHE         (0<<2)  /* bypass, non-speculative */
+#if XCHAL_DCACHE_IS_WRITEBACK
+# define _PAGE_WRITEBACK       (1<<2)  /* write back */
+# define _PAGE_WRITETHRU       (2<<2)  /* write through */
+#else
+# define _PAGE_WRITEBACK       (1<<2)  /* assume write through */
+# define _PAGE_WRITETHRU       (1<<2)
+#endif
+#define _PAGE_NOALLOC          (3<<2)  /* don't allocate cache,if not cached */
+#define _CACHE_MASK            (3<<2)
+
+#define _PAGE_USER             (1<<4)  /* user access (ring=1) */
+#define _PAGE_KERNEL           (0<<4)  /* kernel access (ring=0) */
+
+/* Software */
+#define _PAGE_RW               (1<<6)  /* software: page writable */
+#define _PAGE_DIRTY            (1<<7)  /* software: page dirty */
+#define _PAGE_ACCESSED         (1<<8)  /* software: page accessed (read) */
+#define _PAGE_FILE             (1<<9)  /* nonlinear file mapping*/
+
+#define _PAGE_CHG_MASK (PAGE_MASK | _PAGE_ACCESSED | _CACHE_MASK | _PAGE_DIRTY)
+#define _PAGE_PRESENT  ( _PAGE_VALID | _PAGE_WRITEBACK | _PAGE_ACCESSED)
+
+#ifdef CONFIG_MMU
+
+# define PAGE_NONE     __pgprot(_PAGE_PRESENT)
+# define PAGE_SHARED   __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_RW)
+# define PAGE_COPY     __pgprot(_PAGE_PRESENT | _PAGE_USER)
+# define PAGE_READONLY __pgprot(_PAGE_PRESENT | _PAGE_USER)
+# define PAGE_KERNEL   __pgprot(_PAGE_PRESENT | _PAGE_KERNEL | _PAGE_WRENABLE)
+# define PAGE_INVALID  __pgprot(_PAGE_USER)
+
+# if (DCACHE_WAY_SIZE > PAGE_SIZE)
+#  define PAGE_DIRECTORY  __pgprot(_PAGE_VALID | _PAGE_ACCESSED | _PAGE_KERNEL)
+# else
+#  define PAGE_DIRECTORY  __pgprot(_PAGE_PRESENT | _PAGE_KERNEL)
+# endif
+
+#else /* no mmu */
+
+# define PAGE_NONE       __pgprot(0)
+# define PAGE_SHARED     __pgprot(0)
+# define PAGE_COPY       __pgprot(0)
+# define PAGE_READONLY   __pgprot(0)
+# define PAGE_KERNEL     __pgprot(0)
+
+#endif
+
+/*
+ * On certain configurations of Xtensa MMUs (eg. the initial Linux config),
+ * the MMU can't do page protection for execute, and considers that the same as
+ * read.  Also, write permissions may imply read permissions.
+ * What follows is the closest we can get by reasonable means..
+ * See linux/mm/mmap.c for protection_map[] array that uses these definitions.
+ */
+#define __P000 PAGE_NONE       /* private --- */
+#define __P001 PAGE_READONLY   /* private --r */
+#define __P010 PAGE_COPY       /* private -w- */
+#define __P011 PAGE_COPY       /* private -wr */
+#define __P100 PAGE_READONLY   /* private x-- */
+#define __P101 PAGE_READONLY   /* private x-r */
+#define __P110 PAGE_COPY       /* private xw- */
+#define __P111 PAGE_COPY       /* private xwr */
+
+#define __S000 PAGE_NONE       /* shared  --- */
+#define __S001 PAGE_READONLY   /* shared  --r */
+#define __S010 PAGE_SHARED     /* shared  -w- */
+#define __S011 PAGE_SHARED     /* shared  -wr */
+#define __S100 PAGE_READONLY   /* shared  x-- */
+#define __S101 PAGE_READONLY   /* shared  x-r */
+#define __S110 PAGE_SHARED     /* shared  xw- */
+#define __S111 PAGE_SHARED     /* shared  xwr */
+
+#ifndef __ASSEMBLY__
+
+#define pte_ERROR(e) \
+       printk("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, pte_val(e))
+#define pgd_ERROR(e) \
+       printk("%s:%d: bad pgd entry %08lx.\n", __FILE__, __LINE__, pgd_val(e))
+
+extern unsigned long empty_zero_page[1024];
+
+#define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page))
+
+extern pgd_t swapper_pg_dir[PAGE_SIZE/sizeof(pgd_t)];
+
+/*
+ * The pmd contains the kernel virtual address of the pte page.
+ */
+#define pmd_page_kernel(pmd) ((unsigned long)(pmd_val(pmd) & PAGE_MASK))
+#define pmd_page(pmd) virt_to_page(pmd_val(pmd))
+
+/*
+ * The following only work if pte_present() is true.
+ */
+#define pte_none(pte)   (!(pte_val(pte) ^ _PAGE_USER))
+#define pte_present(pte) (pte_val(pte) & _PAGE_VALID)
+#define pte_clear(mm,addr,ptep)                                                \
+       do { update_pte(ptep, __pte(_PAGE_USER)); } while(0)
+
+#define pmd_none(pmd)   (!pmd_val(pmd))
+#define pmd_present(pmd) (pmd_val(pmd) & PAGE_MASK)
+#define pmd_clear(pmdp)         do { set_pmd(pmdp, __pmd(0)); } while (0)
+#define pmd_bad(pmd)    (pmd_val(pmd) & ~PAGE_MASK)
+
+/* Note: We use the _PAGE_USER bit to indicate write-protect kernel memory */
+
+static inline int pte_read(pte_t pte)  { return pte_val(pte) & _PAGE_USER; }
+static inline int pte_write(pte_t pte) { return pte_val(pte) & _PAGE_RW; }
+static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; }
+static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; }
+static inline int pte_file(pte_t pte)  { return pte_val(pte) & _PAGE_FILE; }
+static inline pte_t pte_wrprotect(pte_t pte)   { pte_val(pte) &= ~(_PAGE_RW | _PAGE_WRENABLE); return pte; }
+static inline pte_t pte_rdprotect(pte_t pte)   { pte_val(pte) &= ~_PAGE_USER; return pte; }
+static inline pte_t pte_mkclean(pte_t pte)     { pte_val(pte) &= ~_PAGE_DIRTY; return pte; }
+static inline pte_t pte_mkold(pte_t pte)       { pte_val(pte) &= ~_PAGE_ACCESSED; return pte; }
+static inline pte_t pte_mkread(pte_t pte)      { pte_val(pte) |= _PAGE_USER; return pte; }
+static inline pte_t pte_mkdirty(pte_t pte)     { pte_val(pte) |= _PAGE_DIRTY; return pte; }
+static inline pte_t pte_mkyoung(pte_t pte)     { pte_val(pte) |= _PAGE_ACCESSED; return pte; }
+static inline pte_t pte_mkwrite(pte_t pte)     { pte_val(pte) |= _PAGE_RW; 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.
+ */
+#define pte_pfn(pte)           (pte_val(pte) >> PAGE_SHIFT)
+#define pte_same(a,b)          (pte_val(a) == pte_val(b))
+#define pte_page(x)            pfn_to_page(pte_pfn(x))
+#define pfn_pte(pfn, prot)     __pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot))
+#define mk_pte(page, prot)     pfn_pte(page_to_pfn(page), prot)
+
+extern inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
+{
+       return __pte((pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot));
+}
+
+/*
+ * Certain architectures need to do special things when pte's
+ * within a page table are directly modified.  Thus, the following
+ * hook is made available.
+ */
+static inline void update_pte(pte_t *ptep, pte_t pteval)
+{
+       *ptep = pteval;
+#if (DCACHE_WAY_SIZE > PAGE_SIZE) && XCHAL_DCACHE_IS_WRITEBACK
+       __asm__ __volatile__ ("memw; dhwb %0, 0; dsync" :: "a" (ptep));
+#endif
+}
+
+extern inline void
+set_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pteval)
+{
+       update_pte(ptep, pteval);
+}
+
+
+extern inline void
+set_pmd(pmd_t *pmdp, pmd_t pmdval)
+{
+       *pmdp = pmdval;
+#if (DCACHE_WAY_SIZE > PAGE_SIZE) && XCHAL_DCACHE_IS_WRITEBACK
+       __asm__ __volatile__ ("memw; dhwb %0, 0; dsync" :: "a" (pmdp));
+#endif
+}
+
+
+static inline int
+ptep_test_and_clear_young(struct vm_area_struct *vma, unsigned long addr,
+                         pte_t *ptep)
+{
+       pte_t pte = *ptep;
+       if (!pte_young(pte))
+               return 0;
+       update_pte(ptep, pte_mkold(pte));
+       return 1;
+}
+
+static inline int
+ptep_test_and_clear_dirty(struct vm_area_struct *vma, unsigned long addr,
+                         pte_t *ptep)
+{
+       pte_t pte = *ptep;
+       if (!pte_dirty(pte))
+               return 0;
+       update_pte(ptep, pte_mkclean(pte));
+       return 1;
+}
+
+static inline pte_t
+ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
+{
+       pte_t pte = *ptep;
+       pte_clear(mm, addr, ptep);
+       return pte;
+}
+
+static inline void
+ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
+{
+       pte_t pte = *ptep;
+       update_pte(ptep, pte_wrprotect(pte));
+}
+
+/* to find an entry in a kernel page-table-directory */
+#define pgd_offset_k(address)  pgd_offset(&init_mm, address)
+
+/* to find an entry in a page-table-directory */
+#define pgd_offset(mm,address) ((mm)->pgd + pgd_index(address))
+
+#define pgd_index(address)     ((address) >> PGDIR_SHIFT)
+
+/* Find an entry in the second-level page table.. */
+#define pmd_offset(dir,address) ((pmd_t*)(dir))
+
+/* Find an entry in the third-level page table.. */
+#define pte_index(address)     (((address) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
+#define pte_offset_kernel(dir,addr)                                    \
+       ((pte_t*) pmd_page_kernel(*(dir)) + pte_index(addr))
+#define pte_offset_map(dir,addr)       pte_offset_kernel((dir),(addr))
+#define pte_offset_map_nested(dir,addr)        pte_offset_kernel((dir),(addr))
+
+#define pte_unmap(pte)         do { } while (0)
+#define pte_unmap_nested(pte)  do { } while (0)
+
+
+/*
+ * Encode and decode a swap entry.
+ * Each PTE in a process VM's page table is either:
+ *   "present" -- valid and not swapped out, protection bits are meaningful;
+ *   "not present" -- which further subdivides in these two cases:
+ *      "none" -- no mapping at all; identified by pte_none(), set by pte_clear(
+ *      "swapped out" -- the page is swapped out, and the SWP macros below
+ *                      are used to store swap file info in the PTE itself.
+ *
+ * In the Xtensa processor MMU, any PTE entries in user space (or anywhere
+ * in virtual memory that can map differently across address spaces)
+ * must have a correct ring value that represents the RASID field that
+ * is changed when switching address spaces.  Eg. such PTE entries cannot
+ * be set to ring zero, because that can cause a (global) kernel ASID
+ * entry to be created in the TLBs (even with invalid cache attribute),
+ * potentially causing a multihit exception when going back to another
+ * address space that mapped the same virtual address at another ring.
+ *
+ * SO: we avoid using ring bits (_PAGE_RING_MASK) in "not present" PTEs.
+ * We also avoid using the _PAGE_VALID bit which must be zero for non-present
+ * pages.
+ *
+ * We end up with the following available bits:  1..3 and 7..31.
+ * We don't bother with 1..3 for now (we can use them later if needed),
+ * and chose to allocate 6 bits for SWP_TYPE and the remaining 19 bits
+ * for SWP_OFFSET.  At least 5 bits are needed for SWP_TYPE, because it
+ * is currently implemented as an index into swap_info[MAX_SWAPFILES]
+ * and MAX_SWAPFILES is currently defined as 32 in <linux/swap.h>.
+ * However, for some reason all other architectures in the 2.4 kernel
+ * reserve either 6, 7, or 8 bits so I'll not detract from that for now.  :)
+ * SWP_OFFSET is an offset into the swap file in page-size units, so
+ * with 4 kB pages, 19 bits supports a maximum swap file size of 2 GB.
+ *
+ * FIXME:  2 GB isn't very big.  Other bits can be used to allow
+ * larger swap sizes.  In the meantime, it appears relatively easy to get
+ * around the 2 GB limitation by simply using multiple swap files.
+ */
+
+#define __swp_type(entry)      (((entry).val >> 7) & 0x3f)
+#define __swp_offset(entry)    ((entry).val >> 13)
+#define __swp_entry(type,offs) ((swp_entry_t) {((type) << 7) | ((offs) << 13)})
+#define __pte_to_swp_entry(pte)        ((swp_entry_t) { pte_val(pte) })
+#define __swp_entry_to_pte(x)  ((pte_t) { (x).val })
+
+#define PTE_FILE_MAX_BITS      29
+#define pte_to_pgoff(pte)      (pte_val(pte) >> 3)
+#define pgoff_to_pte(off)      ((pte_t) { ((off) << 3) | _PAGE_FILE })
+
+
+#endif /*  !defined (__ASSEMBLY__) */
+
+
+#ifdef __ASSEMBLY__
+
+/* Assembly macro _PGD_INDEX is the same as C pgd_index(unsigned long),
+ *                _PGD_OFFSET as C pgd_offset(struct mm_struct*, unsigned long),
+ *                _PMD_OFFSET as C pmd_offset(pgd_t*, unsigned long)
+ *                _PTE_OFFSET as C pte_offset(pmd_t*, unsigned long)
+ *
+ * Note: We require an additional temporary register which can be the same as
+ *       the register that holds the address.
+ *
+ * ((pte_t*) ((unsigned long)(pmd_val(*pmd) & PAGE_MASK)) + pte_index(addr))
+ *
+ */
+#define _PGD_INDEX(rt,rs)      extui   rt, rs, PGDIR_SHIFT, 32-PGDIR_SHIFT
+#define _PTE_INDEX(rt,rs)      extui   rt, rs, PAGE_SHIFT, PTRS_PER_PTE_SHIFT
+
+#define _PGD_OFFSET(mm,adr,tmp)                l32i    mm, mm, MM_PGD;         \
+                                       _PGD_INDEX(tmp, adr);           \
+                                       addx4   mm, tmp, mm
+
+#define _PTE_OFFSET(pmd,adr,tmp)       _PTE_INDEX(tmp, adr);           \
+                                       srli    pmd, pmd, PAGE_SHIFT;   \
+                                       slli    pmd, pmd, PAGE_SHIFT;   \
+                                       addx4   pmd, tmp, pmd
+
+#else
+
+extern void paging_init(void);
+
+#define kern_addr_valid(addr)  (1)
+
+extern  void update_mmu_cache(struct vm_area_struct * vma,
+                             unsigned long address, pte_t pte);
+
+/*
+ * remap a physical address `phys' of size `size' with page protection `prot'
+ * into virtual address `from'
+ */
+#define io_remap_page_range(vma,from,phys,size,prot) \
+                remap_pfn_range(vma, from, (phys) >> PAGE_SHIFT, size, prot)
+
+
+/* No page table caches to init */
+
+#define pgtable_cache_init()   do { } while (0)
+
+typedef pte_t *pte_addr_t;
+
+#endif /* !defined (__ASSEMBLY__) */
+
+#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
+#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_DIRTY
+#define __HAVE_ARCH_PTEP_GET_AND_CLEAR
+#define __HAVE_ARCH_PTEP_SET_WRPROTECT
+#define __HAVE_ARCH_PTEP_MKDIRTY
+#define __HAVE_ARCH_PTE_SAME
+
+#include <asm-generic/pgtable.h>
+
+#endif /* _XTENSA_PGTABLE_H */
diff --git a/include/asm-xtensa/poll.h b/include/asm-xtensa/poll.h
new file mode 100644 (file)
index 0000000..dffe447
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * include/asm-xtensa/poll.h
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file "COPYING" in the main directory of
+ * this archive for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_POLL_H
+#define _XTENSA_POLL_H
+
+
+#define POLLIN         0x0001
+#define POLLPRI                0x0002
+#define POLLOUT                0x0004
+
+#define POLLERR                0x0008
+#define POLLHUP                0x0010
+#define POLLNVAL       0x0020
+
+#define POLLRDNORM     0x0040
+#define POLLRDBAND     0x0080
+#define POLLWRNORM     POLLOUT
+#define POLLWRBAND     0x0100
+
+#define POLLMSG                0x0400
+#define POLLREMOVE     0x0800
+
+struct pollfd {
+       int fd;
+       short events;
+       short revents;
+};
+
+#endif /* _XTENSA_POLL_H */
diff --git a/include/asm-xtensa/posix_types.h b/include/asm-xtensa/posix_types.h
new file mode 100644 (file)
index 0000000..2c816b0
--- /dev/null
@@ -0,0 +1,123 @@
+/*
+ * include/asm-xtensa/posix_types.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Largely copied from include/asm-ppc/posix_types.h
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_POSIX_TYPES_H
+#define _XTENSA_POSIX_TYPES_H
+
+/*
+ * This file is generally used by user-level software, so you need to
+ * be a little careful about namespace pollution etc.  Also, we cannot
+ * assume GCC is being used.
+ */
+
+typedef unsigned long  __kernel_ino_t;
+typedef unsigned int   __kernel_mode_t;
+typedef unsigned short __kernel_nlink_t;
+typedef long           __kernel_off_t;
+typedef int            __kernel_pid_t;
+typedef unsigned short __kernel_ipc_pid_t;
+typedef unsigned int   __kernel_uid_t;
+typedef unsigned int   __kernel_gid_t;
+typedef unsigned int   __kernel_size_t;
+typedef int            __kernel_ssize_t;
+typedef long           __kernel_ptrdiff_t;
+typedef long           __kernel_time_t;
+typedef long           __kernel_suseconds_t;
+typedef long           __kernel_clock_t;
+typedef int            __kernel_timer_t;
+typedef int            __kernel_clockid_t;
+typedef int            __kernel_daddr_t;
+typedef char *         __kernel_caddr_t;
+typedef unsigned short __kernel_uid16_t;
+typedef unsigned short __kernel_gid16_t;
+typedef unsigned int   __kernel_uid32_t;
+typedef unsigned int   __kernel_gid32_t;
+
+typedef unsigned short __kernel_old_uid_t;
+typedef unsigned short __kernel_old_gid_t;
+typedef unsigned short __kernel_old_dev_t;
+
+#ifdef __GNUC__
+typedef long long      __kernel_loff_t;
+#endif
+
+typedef struct {
+       int     val[2];
+} __kernel_fsid_t;
+
+#ifndef __GNUC__
+
+#define        __FD_SET(d, set)        ((set)->fds_bits[__FDELT(d)] |= __FDMASK(d))
+#define        __FD_CLR(d, set)        ((set)->fds_bits[__FDELT(d)] &= ~__FDMASK(d))
+#define        __FD_ISSET(d, set)      ((set)->fds_bits[__FDELT(d)] & __FDMASK(d))
+#define        __FD_ZERO(set)  \
+  ((void) memset ((__ptr_t) (set), 0, sizeof (__kernel_fd_set)))
+
+#else /* __GNUC__ */
+
+#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) \
+    || (__GLIBC__ == 2 && __GLIBC_MINOR__ == 0)
+/* With GNU C, use inline functions instead so args are evaluated only once: */
+
+#undef __FD_SET
+static __inline__ void __FD_SET(unsigned long fd, __kernel_fd_set *fdsetp)
+{
+       unsigned long _tmp = fd / __NFDBITS;
+       unsigned long _rem = fd % __NFDBITS;
+       fdsetp->fds_bits[_tmp] |= (1UL<<_rem);
+}
+
+#undef __FD_CLR
+static __inline__ void __FD_CLR(unsigned long fd, __kernel_fd_set *fdsetp)
+{
+       unsigned long _tmp = fd / __NFDBITS;
+       unsigned long _rem = fd % __NFDBITS;
+       fdsetp->fds_bits[_tmp] &= ~(1UL<<_rem);
+}
+
+#undef __FD_ISSET
+static __inline__ int __FD_ISSET(unsigned long fd, __kernel_fd_set *p)
+{
+       unsigned long _tmp = fd / __NFDBITS;
+       unsigned long _rem = fd % __NFDBITS;
+       return (p->fds_bits[_tmp] & (1UL<<_rem)) != 0;
+}
+
+/*
+ * This will unroll the loop for the normal constant case (8 ints,
+ * for a 256-bit fd_set)
+ */
+#undef __FD_ZERO
+static __inline__ void __FD_ZERO(__kernel_fd_set *p)
+{
+       unsigned int *tmp = (unsigned int *)p->fds_bits;
+       int i;
+
+       if (__builtin_constant_p(__FDSET_LONGS)) {
+               switch (__FDSET_LONGS) {
+                       case 8:
+                               tmp[0] = 0; tmp[1] = 0; tmp[2] = 0; tmp[3] = 0;
+                               tmp[4] = 0; tmp[5] = 0; tmp[6] = 0; tmp[7] = 0;
+                               return;
+               }
+       }
+       i = __FDSET_LONGS;
+       while (i) {
+               i--;
+               *tmp = 0;
+               tmp++;
+       }
+}
+
+#endif /* defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) */
+#endif /* __GNUC__ */
+#endif /* _XTENSA_POSIX_TYPES_H */
diff --git a/include/asm-xtensa/processor.h b/include/asm-xtensa/processor.h
new file mode 100644 (file)
index 0000000..9cab5e4
--- /dev/null
@@ -0,0 +1,205 @@
+/*
+ * include/asm-xtensa/processor.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_PROCESSOR_H
+#define _XTENSA_PROCESSOR_H
+
+#ifdef __ASSEMBLY__
+#define _ASMLANGUAGE
+#endif
+
+#include <xtensa/config/core.h>
+#include <xtensa/config/specreg.h>
+#include <xtensa/config/tie.h>
+#include <xtensa/config/system.h>
+
+#include <asm/ptrace.h>
+#include <asm/types.h>
+#include <asm/coprocessor.h>
+
+/* Assertions. */
+
+#if (XCHAL_HAVE_WINDOWED != 1)
+#error Linux requires the Xtensa Windowed Registers Option.
+#endif
+
+/*
+ * User space process size: 1 GB.
+ * Windowed call ABI requires caller and callee to be located within the same
+ * 1 GB region. The C compiler places trampoline code on the stack for sources
+ * that take the address of a nested C function (a feature used by glibc), so
+ * the 1 GB requirement applies to the stack as well.
+ */
+
+#define TASK_SIZE      0x40000000
+
+/*
+ * General exception cause assigned to debug exceptions. Debug exceptions go
+ * to their own vector, rather than the general exception vectors (user,
+ * kernel, double); and their specific causes are reported via DEBUGCAUSE
+ * rather than EXCCAUSE.  However it is sometimes convenient to redirect debug
+ * exceptions to the general exception mechanism.  To do this, an otherwise
+ * unused EXCCAUSE value was assigned to debug exceptions for this purpose.
+ */
+
+#define EXCCAUSE_MAPPED_DEBUG  63
+
+/*
+ * We use DEPC also as a flag to distinguish between double and regular
+ * exceptions. For performance reasons, DEPC might contain the value of
+ * EXCCAUSE for regular exceptions, so we use this definition to mark a
+ * valid double exception address.
+ * (Note: We use it in bgeui, so it should be 64, 128, or 256)
+ */
+
+#define VALID_DOUBLE_EXCEPTION_ADDRESS 64
+
+/* LOCKLEVEL defines the interrupt level that masks all
+ * general-purpose interrupts.
+ */
+#define LOCKLEVEL 1
+
+/* WSBITS and WBBITS are the width of the WINDOWSTART and WINDOWBASE
+ * registers
+ */
+#define WSBITS  (XCHAL_NUM_AREGS / 4)      /* width of WINDOWSTART in bits */
+#define WBBITS  (XCHAL_NUM_AREGS_LOG2 - 2) /* width of WINDOWBASE in bits */
+
+#ifndef __ASSEMBLY__
+
+/* Build a valid return address for the specified call winsize.
+ * winsize must be 1 (call4), 2 (call8), or 3 (call12)
+ */
+#define MAKE_RA_FOR_CALL(ra,ws)   (((ra) & 0x3fffffff) | (ws) << 30)
+
+/* Convert return address to a valid pc
+ * Note: We assume that the stack pointer is in the same 1GB ranges as the ra
+ */
+#define MAKE_PC_FROM_RA(ra,sp)    (((ra) & 0x3fffffff) | ((sp) & 0xc0000000))
+
+typedef struct {
+    unsigned long seg;
+} mm_segment_t;
+
+struct thread_struct {
+
+       /* kernel's return address and stack pointer for context switching */
+       unsigned long ra; /* kernel's a0: return address and window call size */
+       unsigned long sp; /* kernel's a1: stack pointer */
+
+       mm_segment_t current_ds;    /* see uaccess.h for example uses */
+
+       /* struct xtensa_cpuinfo info; */
+
+       unsigned long bad_vaddr; /* last user fault */
+       unsigned long bad_uaddr; /* last kernel fault accessing user space */
+       unsigned long error_code;
+
+       unsigned long ibreak[XCHAL_NUM_IBREAK];
+       unsigned long dbreaka[XCHAL_NUM_DBREAK];
+       unsigned long dbreakc[XCHAL_NUM_DBREAK];
+
+       /* Allocate storage for extra state and coprocessor state. */
+       unsigned char cp_save[XTENSA_CP_EXTRA_SIZE]
+               __attribute__ ((aligned(XTENSA_CP_EXTRA_ALIGN)));
+
+       /* Make structure 16 bytes aligned. */
+       int align[0] __attribute__ ((aligned(16)));
+};
+
+
+/*
+ * Default implementation of macro that returns current
+ * instruction pointer ("program counter").
+ */
+#define current_text_addr()  ({ __label__ _l; _l: &&_l;})
+
+
+/* This decides where the kernel will search for a free chunk of vm
+ * space during mmap's.
+ */
+#define TASK_UNMAPPED_BASE     (TASK_SIZE / 2)
+
+#define INIT_THREAD  \
+{                                                                      \
+       ra:             0,                                              \
+       sp:             sizeof(init_stack) + (long) &init_stack,        \
+       current_ds:     {0},                                            \
+       /*info:         {0}, */                                         \
+       bad_vaddr:      0,                                              \
+       bad_uaddr:      0,                                              \
+       error_code:     0,                                              \
+}
+
+
+/*
+ * Do necessary setup to start up a newly executed thread.
+ * Note: We set-up ps as if we did a call4 to the new pc.
+ *       set_thread_state in signal.c depends on it.
+ */
+#define USER_PS_VALUE ( (1 << XCHAL_PS_WOE_SHIFT) + \
+                        (1 << XCHAL_PS_CALLINC_SHIFT) + \
+                        (USER_RING << XCHAL_PS_RING_SHIFT) + \
+                        (1 << XCHAL_PS_PROGSTACK_SHIFT) + \
+                        (1 << XCHAL_PS_EXCM_SHIFT) )
+
+/* Clearing a0 terminates the backtrace. */
+#define start_thread(regs, new_pc, new_sp) \
+       regs->pc = new_pc; \
+       regs->ps = USER_PS_VALUE; \
+       regs->areg[1] = new_sp; \
+       regs->areg[0] = 0; \
+       regs->wmask = 1; \
+       regs->depc = 0; \
+       regs->windowbase = 0; \
+       regs->windowstart = 1;
+
+/* Forward declaration */
+struct task_struct;
+struct mm_struct;
+
+// FIXME: do we need release_thread for CP??
+/* Free all resources held by a thread. */
+#define release_thread(thread) do { } while(0)
+
+// FIXME: do we need prepare_to_copy (lazy status) for CP??
+/* Prepare to copy thread state - unlazy all lazy status */
+#define prepare_to_copy(tsk)   do { } while (0)
+
+/*
+ * create a kernel thread without removing it from tasklists
+ */
+extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
+
+/* Copy and release all segment info associated with a VM */
+
+#define copy_segments(p, mm)   do { } while(0)
+#define release_segments(mm)   do { } while(0)
+#define forget_segments()      do { } while (0)
+
+#define thread_saved_pc(tsk)   (xtensa_pt_regs(tsk)->pc)
+
+extern unsigned long get_wchan(struct task_struct *p);
+
+#define KSTK_EIP(tsk)          (xtensa_pt_regs(tsk)->pc)
+#define KSTK_ESP(tsk)          (xtensa_pt_regs(tsk)->areg[1])
+
+#define cpu_relax()  do { } while (0)
+
+/* Special register access. */
+
+#define WSR(v,sr) __asm__ __volatile__ ("wsr %0,"__stringify(sr) :: "a"(v));
+#define RSR(v,sr) __asm__ __volatile__ ("rsr %0,"__stringify(sr) : "=a"(v));
+
+#define set_sr(x,sr) ({unsigned int v=(unsigned int)x; WSR(v,sr);})
+#define get_sr(sr) ({unsigned int v; RSR(v,sr); v; })
+
+#endif /* __ASSEMBLY__ */
+#endif /* _XTENSA_PROCESSOR_H */
diff --git a/include/asm-xtensa/ptrace.h b/include/asm-xtensa/ptrace.h
new file mode 100644 (file)
index 0000000..2848a5f
--- /dev/null
@@ -0,0 +1,135 @@
+/*
+ * include/asm-xtensa/ptrace.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_PTRACE_H
+#define _XTENSA_PTRACE_H
+
+#include <xtensa/config/core.h>
+
+/*
+ * Kernel stack
+ *
+ *             +-----------------------+  -------- STACK_SIZE
+ *             |     register file     |  |
+ *             +-----------------------+  |
+ *             |    struct pt_regs     |  |
+ *             +-----------------------+  | ------ PT_REGS_OFFSET
+ * double      :  16 bytes spill area  :  |  ^
+ * excetion    :- - - - - - - - - - - -:  |  |
+ * frame       :    struct pt_regs     :  |  |
+ *             :- - - - - - - - - - - -:  |  |
+ *             |                       |  |  |
+ *             |     memory stack      |  |  |
+ *             |                       |  |  |
+ *             ~                       ~  ~  ~
+ *             ~                       ~  ~  ~
+ *             |                       |  |  |
+ *             |                       |  |  |
+ *             +-----------------------+  |  | --- STACK_BIAS
+ *             |  struct task_struct   |  |  |  ^
+ *  current --> +-----------------------+  |  |  |
+ *             |  struct thread_info   |  |  |  |
+ *             +-----------------------+ --------
+ */
+
+#define KERNEL_STACK_SIZE (2 * PAGE_SIZE)
+
+/*  Offsets for exception_handlers[] (3 x 64-entries x 4-byte tables). */
+
+#define EXC_TABLE_KSTK         0x004   /* Kernel Stack */
+#define EXC_TABLE_DOUBLE_SAVE  0x008   /* Double exception save area for a0 */
+#define EXC_TABLE_FIXUP                0x00c   /* Fixup handler */
+#define EXC_TABLE_PARAM                0x010   /* For passing a parameter to fixup */
+#define EXC_TABLE_SYSCALL_SAVE 0x014   /* For fast syscall handler */
+#define EXC_TABLE_FAST_USER    0x100   /* Fast user exception handler */
+#define EXC_TABLE_FAST_KERNEL  0x200   /* Fast kernel exception handler */
+#define EXC_TABLE_DEFAULT      0x300   /* Default C-Handler */
+#define EXC_TABLE_SIZE         0x400
+
+/* Registers used by strace */
+
+#define REG_A_BASE     0xfc000000
+#define REG_AR_BASE    0x04000000
+#define REG_PC         0x14000000
+#define REG_PS         0x080000e6
+#define REG_WB         0x08000048
+#define REG_WS         0x08000049
+#define REG_LBEG       0x08000000
+#define REG_LEND       0x08000001
+#define REG_LCOUNT     0x08000002
+#define REG_SAR                0x08000003
+#define REG_DEPC       0x080000c0
+#define        REG_EXCCAUSE    0x080000e8
+#define REG_EXCVADDR   0x080000ee
+#define SYSCALL_NR     0x1
+
+#define AR_REGNO_TO_A_REGNO(ar, wb) (ar - wb*4) & ~(XCHAL_NUM_AREGS - 1)
+
+/* Other PTRACE_ values defined in <linux/ptrace.h> using values 0-9,16,17,24 */
+
+#define PTRACE_GETREGS            12
+#define PTRACE_SETREGS            13
+#define PTRACE_GETFPREGS          14
+#define PTRACE_SETFPREGS          15
+#define PTRACE_GETFPREGSIZE       18
+
+#ifndef __ASSEMBLY__
+
+/*
+ * This struct defines the way the registers are stored on the
+ * kernel stack during a system call or other kernel entry.
+ */
+struct pt_regs {
+       unsigned long pc;               /*   4 */
+       unsigned long ps;               /*   8 */
+       unsigned long depc;             /*  12 */
+       unsigned long exccause;         /*  16 */
+       unsigned long excvaddr;         /*  20 */
+       unsigned long debugcause;       /*  24 */
+       unsigned long wmask;            /*  28 */
+       unsigned long lbeg;             /*  32 */
+       unsigned long lend;             /*  36 */
+       unsigned long lcount;           /*  40 */
+       unsigned long sar;              /*  44 */
+       unsigned long windowbase;       /*  48 */
+       unsigned long windowstart;      /*  52 */
+       unsigned long syscall;          /*  56 */
+       int reserved[2];                /*  64 */
+
+       /* Make sure the areg field is 16 bytes aligned. */
+       int align[0] __attribute__ ((aligned(16)));
+
+       /* current register frame.
+        * Note: The ESF for kernel exceptions ends after 16 registers!
+        */
+       unsigned long areg[16];         /* 128 (64) */
+};
+
+#ifdef __KERNEL__
+# define xtensa_pt_regs(tsk) ((struct pt_regs*) \
+  (((long)(tsk)->thread_info + KERNEL_STACK_SIZE - (XCHAL_NUM_AREGS-16)*4)) - 1)
+# define user_mode(regs) (((regs)->ps & 0x00000020)!=0)
+# define instruction_pointer(regs) ((regs)->pc)
+extern void show_regs(struct pt_regs *);
+
+# ifndef CONFIG_SMP
+#  define profile_pc(regs) instruction_pointer(regs)
+# endif
+#endif /* __KERNEL__ */
+
+#else  /* __ASSEMBLY__ */
+
+#ifdef __KERNEL__
+# include <asm/offsets.h>
+#define PT_REGS_OFFSET   (KERNEL_STACK_SIZE - PT_USER_SIZE)
+#endif
+
+#endif /* !__ASSEMBLY__ */
+#endif /* _XTENSA_PTRACE_H */
diff --git a/include/asm-xtensa/resource.h b/include/asm-xtensa/resource.h
new file mode 100644 (file)
index 0000000..17b5ab3
--- /dev/null
@@ -0,0 +1,16 @@
+/*
+ * include/asm-xtensa/resource.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_RESOURCE_H
+#define _XTENSA_RESOURCE_H
+
+#include <asm-generic/resource.h>
+
+#endif /* _XTENSA_RESOURCE_H */
diff --git a/include/asm-xtensa/rmap.h b/include/asm-xtensa/rmap.h
new file mode 100644 (file)
index 0000000..649588b
--- /dev/null
@@ -0,0 +1,16 @@
+/*
+ * include/asm-xtensa/rmap.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_RMAP_H
+#define _XTENSA_RMAP_H
+
+#include <asm-generic/rmap.h>
+
+#endif
diff --git a/include/asm-xtensa/rwsem.h b/include/asm-xtensa/rwsem.h
new file mode 100644 (file)
index 0000000..3c02b0e
--- /dev/null
@@ -0,0 +1,175 @@
+/*
+ * include/asm-xtensa/rwsem.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Largely copied from include/asm-ppc/rwsem.h
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_RWSEM_H
+#define _XTENSA_RWSEM_H
+
+#include <linux/list.h>
+#include <linux/spinlock.h>
+#include <asm/atomic.h>
+#include <asm/system.h>
+
+/*
+ * the semaphore definition
+ */
+struct rw_semaphore {
+       signed long             count;
+#define RWSEM_UNLOCKED_VALUE           0x00000000
+#define RWSEM_ACTIVE_BIAS              0x00000001
+#define RWSEM_ACTIVE_MASK              0x0000ffff
+#define RWSEM_WAITING_BIAS             (-0x00010000)
+#define RWSEM_ACTIVE_READ_BIAS         RWSEM_ACTIVE_BIAS
+#define RWSEM_ACTIVE_WRITE_BIAS                (RWSEM_WAITING_BIAS + RWSEM_ACTIVE_BIAS)
+       spinlock_t              wait_lock;
+       struct list_head        wait_list;
+#if RWSEM_DEBUG
+       int                     debug;
+#endif
+};
+
+/*
+ * initialisation
+ */
+#if RWSEM_DEBUG
+#define __RWSEM_DEBUG_INIT      , 0
+#else
+#define __RWSEM_DEBUG_INIT     /* */
+#endif
+
+#define __RWSEM_INITIALIZER(name) \
+       { RWSEM_UNLOCKED_VALUE, SPIN_LOCK_UNLOCKED, \
+         LIST_HEAD_INIT((name).wait_list) \
+         __RWSEM_DEBUG_INIT }
+
+#define DECLARE_RWSEM(name)            \
+       struct rw_semaphore name = __RWSEM_INITIALIZER(name)
+
+extern struct rw_semaphore *rwsem_down_read_failed(struct rw_semaphore *sem);
+extern struct rw_semaphore *rwsem_down_write_failed(struct rw_semaphore *sem);
+extern struct rw_semaphore *rwsem_wake(struct rw_semaphore *sem);
+extern struct rw_semaphore *rwsem_downgrade_wake(struct rw_semaphore *sem);
+
+static inline void init_rwsem(struct rw_semaphore *sem)
+{
+       sem->count = RWSEM_UNLOCKED_VALUE;
+       spin_lock_init(&sem->wait_lock);
+       INIT_LIST_HEAD(&sem->wait_list);
+#if RWSEM_DEBUG
+       sem->debug = 0;
+#endif
+}
+
+/*
+ * lock for reading
+ */
+static inline void __down_read(struct rw_semaphore *sem)
+{
+       if (atomic_add_return(1,(atomic_t *)(&sem->count)) > 0)
+               smp_wmb();
+       else
+               rwsem_down_read_failed(sem);
+}
+
+static inline int __down_read_trylock(struct rw_semaphore *sem)
+{
+       int tmp;
+
+       while ((tmp = sem->count) >= 0) {
+               if (tmp == cmpxchg(&sem->count, tmp,
+                                  tmp + RWSEM_ACTIVE_READ_BIAS)) {
+                       smp_wmb();
+                       return 1;
+               }
+       }
+       return 0;
+}
+
+/*
+ * lock for writing
+ */
+static inline void __down_write(struct rw_semaphore *sem)
+{
+       int tmp;
+
+       tmp = atomic_add_return(RWSEM_ACTIVE_WRITE_BIAS,
+                               (atomic_t *)(&sem->count));
+       if (tmp == RWSEM_ACTIVE_WRITE_BIAS)
+               smp_wmb();
+       else
+               rwsem_down_write_failed(sem);
+}
+
+static inline int __down_write_trylock(struct rw_semaphore *sem)
+{
+       int tmp;
+
+       tmp = cmpxchg(&sem->count, RWSEM_UNLOCKED_VALUE,
+                     RWSEM_ACTIVE_WRITE_BIAS);
+       smp_wmb();
+       return tmp == RWSEM_UNLOCKED_VALUE;
+}
+
+/*
+ * unlock after reading
+ */
+static inline void __up_read(struct rw_semaphore *sem)
+{
+       int tmp;
+
+       smp_wmb();
+       tmp = atomic_sub_return(1,(atomic_t *)(&sem->count));
+       if (tmp < -1 && (tmp & RWSEM_ACTIVE_MASK) == 0)
+               rwsem_wake(sem);
+}
+
+/*
+ * unlock after writing
+ */
+static inline void __up_write(struct rw_semaphore *sem)
+{
+       smp_wmb();
+       if (atomic_sub_return(RWSEM_ACTIVE_WRITE_BIAS,
+                             (atomic_t *)(&sem->count)) < 0)
+               rwsem_wake(sem);
+}
+
+/*
+ * implement atomic add functionality
+ */
+static inline void rwsem_atomic_add(int delta, struct rw_semaphore *sem)
+{
+       atomic_add(delta, (atomic_t *)(&sem->count));
+}
+
+/*
+ * downgrade write lock to read lock
+ */
+static inline void __downgrade_write(struct rw_semaphore *sem)
+{
+       int tmp;
+
+       smp_wmb();
+       tmp = atomic_add_return(-RWSEM_WAITING_BIAS, (atomic_t *)(&sem->count));
+       if (tmp < 0)
+               rwsem_downgrade_wake(sem);
+}
+
+/*
+ * implement exchange and add functionality
+ */
+static inline int rwsem_atomic_update(int delta, struct rw_semaphore *sem)
+{
+       smp_mb();
+       return atomic_add_return(delta, (atomic_t *)(&sem->count));
+}
+
+#endif /* _XTENSA_RWSEM_XADD_H */
diff --git a/include/asm-xtensa/scatterlist.h b/include/asm-xtensa/scatterlist.h
new file mode 100644 (file)
index 0000000..38a2b9a
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * include/asm-xtensa/scatterlist.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_SCATTERLIST_H
+#define _XTENSA_SCATTERLIST_H
+
+struct scatterlist {
+       struct page     *page;
+       unsigned int    offset;
+       dma_addr_t      dma_address;
+       unsigned int    length;
+};
+
+/*
+ * These macros should be used after a pci_map_sg call has been done
+ * to get bus addresses of each of the SG entries and their lengths.
+ * You should only work with the number of sg entries pci_map_sg
+ * returns, or alternatively stop on the first sg_dma_len(sg) which
+ * is 0.
+ */
+#define sg_dma_address(sg)      ((sg)->dma_address)
+#define sg_dma_len(sg)          ((sg)->length)
+
+
+#define ISA_DMA_THRESHOLD (~0UL)
+
+#endif /* _XTENSA_SCATTERLIST_H */
diff --git a/include/asm-xtensa/sections.h b/include/asm-xtensa/sections.h
new file mode 100644 (file)
index 0000000..40b5191
--- /dev/null
@@ -0,0 +1,16 @@
+/*
+ * include/asm-xtensa/sections.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_SECTIONS_H
+#define _XTENSA_SECTIONS_H
+
+#include <asm-generic/sections.h>
+
+#endif /* _XTENSA_SECTIONS_H */
diff --git a/include/asm-xtensa/segment.h b/include/asm-xtensa/segment.h
new file mode 100644 (file)
index 0000000..a2eb547
--- /dev/null
@@ -0,0 +1,16 @@
+/*
+ * include/asm-xtensa/segment.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_SEGMENT_H
+#define _XTENSA_SEGMENT_H
+
+#include <asm/uaccess.h>
+
+#endif /* _XTENSA_SEGEMENT_H */
diff --git a/include/asm-xtensa/semaphore.h b/include/asm-xtensa/semaphore.h
new file mode 100644 (file)
index 0000000..c8a7574
--- /dev/null
@@ -0,0 +1,129 @@
+/*
+ * linux/include/asm-xtensa/semaphore.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_SEMAPHORE_H
+#define _XTENSA_SEMAPHORE_H
+
+#include <asm/atomic.h>
+#include <asm/system.h>
+#include <linux/wait.h>
+#include <linux/rwsem.h>
+
+struct semaphore {
+       atomic_t count;
+       int sleepers;
+       wait_queue_head_t wait;
+#if WAITQUEUE_DEBUG
+       long __magic;
+#endif
+};
+
+#if WAITQUEUE_DEBUG
+# define __SEM_DEBUG_INIT(name) \
+               , (int)&(name).__magic
+#else
+# define __SEM_DEBUG_INIT(name)
+#endif
+
+#define __SEMAPHORE_INITIALIZER(name,count)                    \
+       { ATOMIC_INIT(count),                                   \
+         0,                                                    \
+         __WAIT_QUEUE_HEAD_INITIALIZER((name).wait)            \
+       __SEM_DEBUG_INIT(name) }
+
+#define __MUTEX_INITIALIZER(name) \
+       __SEMAPHORE_INITIALIZER(name, 1)
+
+#define __DECLARE_SEMAPHORE_GENERIC(name,count) \
+       struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
+
+#define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1)
+#define DECLARE_MUTEX_LOCKED(name) __DECLARE_SEMAPHORE_GENERIC(name,0)
+
+extern inline void sema_init (struct semaphore *sem, int val)
+{
+/*
+ *     *sem = (struct semaphore)__SEMAPHORE_INITIALIZER((*sem),val);
+ *
+ * i'd rather use the more flexible initialization above, but sadly
+ * GCC 2.7.2.3 emits a bogus warning. EGCS doesnt. Oh well.
+ */
+       atomic_set(&sem->count, val);
+       init_waitqueue_head(&sem->wait);
+#if WAITQUEUE_DEBUG
+       sem->__magic = (int)&sem->__magic;
+#endif
+}
+
+static inline void init_MUTEX (struct semaphore *sem)
+{
+       sema_init(sem, 1);
+}
+
+static inline void init_MUTEX_LOCKED (struct semaphore *sem)
+{
+       sema_init(sem, 0);
+}
+
+asmlinkage void __down(struct semaphore * sem);
+asmlinkage int  __down_interruptible(struct semaphore * sem);
+asmlinkage int  __down_trylock(struct semaphore * sem);
+asmlinkage void __up(struct semaphore * sem);
+
+extern spinlock_t semaphore_wake_lock;
+
+extern __inline__ void down(struct semaphore * sem)
+{
+#if WAITQUEUE_DEBUG
+       CHECK_MAGIC(sem->__magic);
+#endif
+
+       if (atomic_sub_return(1, &sem->count) < 0)
+               __down(sem);
+}
+
+extern __inline__ int down_interruptible(struct semaphore * sem)
+{
+       int ret = 0;
+#if WAITQUEUE_DEBUG
+       CHECK_MAGIC(sem->__magic);
+#endif
+
+       if (atomic_sub_return(1, &sem->count) < 0)
+               ret = __down_interruptible(sem);
+       return ret;
+}
+
+extern __inline__ int down_trylock(struct semaphore * sem)
+{
+       int ret = 0;
+#if WAITQUEUE_DEBUG
+       CHECK_MAGIC(sem->__magic);
+#endif
+
+       if (atomic_sub_return(1, &sem->count) < 0)
+               ret = __down_trylock(sem);
+       return ret;
+}
+
+/*
+ * Note! This is subtle. We jump to wake people up only if
+ * the semaphore was negative (== somebody was waiting on it).
+ */
+extern __inline__ void up(struct semaphore * sem)
+{
+#if WAITQUEUE_DEBUG
+       CHECK_MAGIC(sem->__magic);
+#endif
+       if (atomic_add_return(1, &sem->count) <= 0)
+               __up(sem);
+}
+
+#endif /* _XTENSA_SEMAPHORE_H */
diff --git a/include/asm-xtensa/sembuf.h b/include/asm-xtensa/sembuf.h
new file mode 100644 (file)
index 0000000..2d26c47
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * include/asm-xtensa/sembuf.h
+ *
+ * The semid64_ds structure for Xtensa architecture.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ *
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - 64-bit time_t to solve y2038 problem
+ * - 2 miscellaneous 32-bit values
+ *
+ */
+
+#ifndef _XTENSA_SEMBUF_H
+#define _XTENSA_SEMBUF_H
+
+#include <asm/byteorder.h>
+
+struct semid64_ds {
+       struct ipc64_perm sem_perm;             /* permissions .. see ipc.h */
+#if XCHAL_HAVE_LE
+       __kernel_time_t sem_otime;              /* last semop time */
+       unsigned long   __unused1;
+       __kernel_time_t sem_ctime;              /* last change time */
+       unsigned long   __unused2;
+#else
+       unsigned long   __unused1;
+       __kernel_time_t sem_otime;              /* last semop time */
+       unsigned long   __unused2;
+       __kernel_time_t sem_ctime;              /* last change time */
+#endif
+       unsigned long   sem_nsems;              /* no. of semaphores in array */
+       unsigned long   __unused3;
+       unsigned long   __unused4;
+};
+
+#endif /* __ASM_XTENSA_SEMBUF_H */
diff --git a/include/asm-xtensa/serial.h b/include/asm-xtensa/serial.h
new file mode 100644 (file)
index 0000000..ec04114
--- /dev/null
@@ -0,0 +1,18 @@
+/*
+ * include/asm-xtensa/serial.h
+ *
+ * Configuration details for 8250, 16450, 16550, etc. serial ports
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_SERIAL_H
+#define _XTENSA_SERIAL_H
+
+#include <asm/platform/serial.h>
+
+#endif /* _XTENSA_SERIAL_H */
diff --git a/include/asm-xtensa/setup.h b/include/asm-xtensa/setup.h
new file mode 100644 (file)
index 0000000..e363652
--- /dev/null
@@ -0,0 +1,16 @@
+/*
+ * include/asm-xtensa/setup.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_SETUP_H
+#define _XTENSA_SETUP_H
+
+#define COMMAND_LINE_SIZE      256
+
+#endif
diff --git a/include/asm-xtensa/shmbuf.h b/include/asm-xtensa/shmbuf.h
new file mode 100644 (file)
index 0000000..a30b81a
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * include/asm-xtensa/shmbuf.h
+ *
+ * The shmid64_ds structure for Xtensa architecture.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - 64-bit time_t to solve y2038 problem
+ * - 2 miscellaneous 32-bit values
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_SHMBUF_H
+#define _XTENSA_SHMBUF_H
+
+struct shmid64_ds {
+       struct ipc64_perm       shm_perm;       /* operation perms */
+       size_t                  shm_segsz;      /* size of segment (bytes) */
+       __kernel_time_t         shm_atime;      /* last attach time */
+       unsigned long           __unused1;
+       __kernel_time_t         shm_dtime;      /* last detach time */
+       unsigned long           __unused2;
+       __kernel_time_t         shm_ctime;      /* last change time */
+       unsigned long           __unused3;
+       __kernel_pid_t          shm_cpid;       /* pid of creator */
+       __kernel_pid_t          shm_lpid;       /* pid of last operator */
+       unsigned long           shm_nattch;     /* no. of current attaches */
+       unsigned long           __unused4;
+       unsigned long           __unused5;
+};
+
+struct shminfo64 {
+       unsigned long   shmmax;
+       unsigned long   shmmin;
+       unsigned long   shmmni;
+       unsigned long   shmseg;
+       unsigned long   shmall;
+       unsigned long   __unused1;
+       unsigned long   __unused2;
+       unsigned long   __unused3;
+       unsigned long   __unused4;
+};
+
+#endif /* _XTENSA_SHMBUF_H */
diff --git a/include/asm-xtensa/shmparam.h b/include/asm-xtensa/shmparam.h
new file mode 100644 (file)
index 0000000..d3b65bf
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * include/asm-xtensa/shmparam.h
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file "COPYING" in the main directory of
+ * this archive for more details.
+ */
+
+#ifndef _XTENSA_SHMPARAM_H
+#define _XTENSA_SHMPARAM_H
+
+#include <asm/processor.h>
+
+/*
+ * Xtensa can have variable size caches, and if
+ * the size of single way is larger than the page size,
+ * then we have to start worrying about cache aliasing
+ * problems.
+ */
+
+#define SHMLBA ((PAGE_SIZE > DCACHE_WAY_SIZE)? PAGE_SIZE : DCACHE_WAY_SIZE)
+
+#endif /* _XTENSA_SHMPARAM_H */
diff --git a/include/asm-xtensa/sigcontext.h b/include/asm-xtensa/sigcontext.h
new file mode 100644 (file)
index 0000000..a751772
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * include/asm-xtensa/sigcontext.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2003 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_SIGCONTEXT_H
+#define _XTENSA_SIGCONTEXT_H
+
+#define _ASMLANGUAGE
+#include <asm/processor.h>
+#include <asm/coprocessor.h>
+
+
+struct _cpstate {
+       unsigned char _cpstate[XTENSA_CP_EXTRA_SIZE];
+} __attribute__ ((aligned (XTENSA_CP_EXTRA_ALIGN)));
+
+
+struct sigcontext {
+       unsigned long   oldmask;
+
+       /* CPU registers */
+       unsigned long sc_pc;
+       unsigned long sc_ps;
+       unsigned long sc_wmask;
+       unsigned long sc_windowbase;
+       unsigned long sc_windowstart;
+       unsigned long sc_lbeg;
+       unsigned long sc_lend;
+       unsigned long sc_lcount;
+       unsigned long sc_sar;
+       unsigned long sc_depc;
+       unsigned long sc_dareg0;
+       unsigned long sc_treg[4];
+       unsigned long sc_areg[XCHAL_NUM_AREGS];
+       struct _cpstate *sc_cpstate;
+};
+
+#endif /* __ASM_XTENSA_SIGCONTEXT_H */
diff --git a/include/asm-xtensa/siginfo.h b/include/asm-xtensa/siginfo.h
new file mode 100644 (file)
index 0000000..44f0ae7
--- /dev/null
@@ -0,0 +1,16 @@
+/*
+ * include/asm-xtensa/processor.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_SIGINFO_H
+#define _XTENSA_SIGINFO_H
+
+#include <asm-generic/siginfo.h>
+
+#endif /* _XTENSA_SIGINFO_H */
diff --git a/include/asm-xtensa/signal.h b/include/asm-xtensa/signal.h
new file mode 100644 (file)
index 0000000..5d6fc9c
--- /dev/null
@@ -0,0 +1,187 @@
+/*
+ * include/asm-xtensa/signal.h
+ *
+ * Swiped from SH.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_SIGNAL_H
+#define _XTENSA_SIGNAL_H
+
+
+#define _NSIG          64
+#define _NSIG_BPW      32
+#define _NSIG_WORDS    (_NSIG / _NSIG_BPW)
+
+#ifndef __ASSEMBLY__
+
+#include <linux/types.h>
+
+/* Avoid too many header ordering problems.  */
+struct siginfo;
+typedef unsigned long old_sigset_t;            /* at least 32 bits */
+typedef struct {
+       unsigned long sig[_NSIG_WORDS];
+} sigset_t;
+
+#endif
+
+#define SIGHUP          1
+#define SIGINT          2
+#define SIGQUIT                 3
+#define SIGILL          4
+#define SIGTRAP                 5
+#define SIGABRT                 6
+#define SIGIOT          6
+#define SIGBUS          7
+#define SIGFPE          8
+#define SIGKILL                 9
+#define SIGUSR1                10
+#define SIGSEGV                11
+#define SIGUSR2                12
+#define SIGPIPE                13
+#define SIGALRM                14
+#define SIGTERM                15
+#define SIGSTKFLT      16
+#define SIGCHLD                17
+#define SIGCONT                18
+#define SIGSTOP                19
+#define SIGTSTP                20
+#define SIGTTIN                21
+#define SIGTTOU                22
+#define SIGURG         23
+#define SIGXCPU                24
+#define SIGXFSZ                25
+#define SIGVTALRM      26
+#define SIGPROF                27
+#define SIGWINCH       28
+#define SIGIO          29
+#define SIGPOLL                SIGIO
+/* #define SIGLOST             29 */
+#define SIGPWR         30
+#define SIGSYS         31
+#define        SIGUNUSED       31
+
+/* These should not be considered constants from userland.  */
+#define SIGRTMIN       32
+#define SIGRTMAX       (_NSIG-1)
+
+/*
+ * SA_FLAGS values:
+ *
+ * SA_ONSTACK indicates that a registered stack_t will be used.
+ * SA_INTERRUPT is a no-op, but left due to historical reasons. Use the
+ * SA_RESTART flag to get restarting signals (which were the default long ago)
+ * SA_NOCLDSTOP flag to turn off SIGCHLD when children stop.
+ * SA_RESETHAND clears the handler when the signal is delivered.
+ * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies.
+ * SA_NODEFER prevents the current signal from being masked in the handler.
+ *
+ * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single
+ * Unix names RESETHAND and NODEFER respectively.
+ */
+#define SA_NOCLDSTOP   0x00000001
+#define SA_NOCLDWAIT   0x00000002 /* not supported yet */
+#define SA_SIGINFO     0x00000004
+#define SA_ONSTACK     0x08000000
+#define SA_RESTART     0x10000000
+#define SA_NODEFER     0x40000000
+#define SA_RESETHAND   0x80000000
+
+#define SA_NOMASK      SA_NODEFER
+#define SA_ONESHOT     SA_RESETHAND
+#define SA_INTERRUPT   0x20000000 /* dummy -- ignored */
+
+#define SA_RESTORER    0x04000000
+
+/*
+ * sigaltstack controls
+ */
+#define SS_ONSTACK     1
+#define SS_DISABLE     2
+
+#define MINSIGSTKSZ    2048
+#define SIGSTKSZ       8192
+
+#ifndef __ASSEMBLY__
+#ifdef __KERNEL__
+
+/*
+ * These values of sa_flags are used only by the kernel as part of the
+ * irq handling routines.
+ *
+ * SA_INTERRUPT is also used by the irq handling routines.
+ * SA_SHIRQ is for shared interrupt support on PCI and EISA.
+ */
+#define SA_PROBE               SA_ONESHOT
+#define SA_SAMPLE_RANDOM       SA_RESTART
+#define SA_SHIRQ               0x04000000
+#endif
+
+#define SIG_BLOCK          0   /* for blocking signals */
+#define SIG_UNBLOCK        1   /* for unblocking signals */
+#define SIG_SETMASK        2   /* for setting the signal mask */
+
+/* Type of a signal handler.  */
+typedef void (*__sighandler_t)(int);
+
+#define SIG_DFL        ((__sighandler_t)0)     /* default signal handling */
+#define SIG_IGN        ((__sighandler_t)1)     /* ignore signal */
+#define SIG_ERR        ((__sighandler_t)-1)    /* error return from signal */
+
+#ifdef __KERNEL__
+struct old_sigaction {
+       __sighandler_t sa_handler;
+       old_sigset_t sa_mask;
+       unsigned long sa_flags;
+       void (*sa_restorer)(void);
+};
+
+struct sigaction {
+       __sighandler_t sa_handler;
+       unsigned long sa_flags;
+       void (*sa_restorer)(void);
+       sigset_t sa_mask;               /* mask last for extensibility */
+};
+
+struct k_sigaction {
+       struct sigaction sa;
+};
+
+#else
+
+/* Here we must cater to libcs that poke about in kernel headers.  */
+
+struct sigaction {
+       union {
+         __sighandler_t _sa_handler;
+         void (*_sa_sigaction)(int, struct siginfo *, void *);
+       } _u;
+       sigset_t sa_mask;
+       unsigned long sa_flags;
+       void (*sa_restorer)(void);
+};
+
+#define sa_handler     _u._sa_handler
+#define sa_sigaction   _u._sa_sigaction
+
+#endif /* __KERNEL__ */
+
+typedef struct sigaltstack {
+       void *ss_sp;
+       int ss_flags;
+       size_t ss_size;
+} stack_t;
+
+#ifdef __KERNEL__
+#include <asm/sigcontext.h>
+#define ptrace_signal_deliver(regs, cookie) do { } while (0)
+
+#endif /* __KERNEL__ */
+#endif /* __ASSEMBLY__ */
+#endif /* _XTENSA_SIGNAL_H */
diff --git a/include/asm-xtensa/smp.h b/include/asm-xtensa/smp.h
new file mode 100644 (file)
index 0000000..83c569e
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * include/asm-xtensa/smp.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_SMP_H
+#define _XTENSA_SMP_H
+
+extern struct xtensa_cpuinfo boot_cpu_data;
+
+#define cpu_data (&boot_cpu_data)
+#define current_cpu_data boot_cpu_data
+
+struct xtensa_cpuinfo {
+       unsigned long   *pgd_cache;
+       unsigned long   *pte_cache;
+       unsigned long   pgtable_cache_sz;
+};
+
+#define cpu_logical_map(cpu)   (cpu)
+
+#endif /* _XTENSA_SMP_H */
diff --git a/include/asm-xtensa/socket.h b/include/asm-xtensa/socket.h
new file mode 100644 (file)
index 0000000..daccd05
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * include/asm-xtensa/socket.h
+ *
+ * Copied from i386.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#ifndef _XTENSA_SOCKET_H
+#define _XTENSA_SOCKET_H
+
+#include <asm/sockios.h>
+
+/* For setsockoptions(2) */
+#define SOL_SOCKET     1
+
+#define SO_DEBUG       1
+#define SO_REUSEADDR   2
+#define SO_TYPE                3
+#define SO_ERROR       4
+#define SO_DONTROUTE   5
+#define SO_BROADCAST   6
+#define SO_SNDBUF      7
+#define SO_RCVBUF      8
+#define SO_KEEPALIVE   9
+#define SO_OOBINLINE   10
+#define SO_NO_CHECK    11
+#define SO_PRIORITY    12
+#define SO_LINGER      13
+#define SO_BSDCOMPAT   14
+/* To add :#define SO_REUSEPORT 15 */
+#define SO_PASSCRED    16
+#define SO_PEERCRED    17
+#define SO_RCVLOWAT    18
+#define SO_SNDLOWAT    19
+#define SO_RCVTIMEO    20
+#define SO_SNDTIMEO    21
+
+/* Security levels - as per NRL IPv6 - don't actually do anything */
+
+#define SO_SECURITY_AUTHENTICATION             22
+#define SO_SECURITY_ENCRYPTION_TRANSPORT       23
+#define SO_SECURITY_ENCRYPTION_NETWORK         24
+
+#define SO_BINDTODEVICE        25
+
+/* Socket filtering */
+
+#define SO_ATTACH_FILTER        26
+#define SO_DETACH_FILTER        27
+
+#define SO_PEERNAME            28
+#define SO_TIMESTAMP           29
+#define SCM_TIMESTAMP          SO_TIMESTAMP
+
+#define SO_ACCEPTCONN          30
+#define SO_PEERSEC             31
+
+#endif /* _XTENSA_SOCKET_H */
diff --git a/include/asm-xtensa/sockios.h b/include/asm-xtensa/sockios.h
new file mode 100644 (file)
index 0000000..20d2ba1
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * include/asm-xtensa/sockios.h
+ *
+ * Socket-level I/O control calls.  Copied from MIPS.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1995 by Ralf Baechle
+ * Copyright (C) 2001 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_SOCKIOS_H
+#define _XTENSA_SOCKIOS_H
+
+#include <asm/ioctl.h>
+
+/* Socket-level I/O control calls. */
+
+#define FIOGETOWN      _IOR('f', 123, int)
+#define FIOSETOWN      _IOW('f', 124, int)
+
+#define SIOCATMARK     _IOR('s', 7, int)
+#define SIOCSPGRP      _IOW('s', 8, pid_t)
+#define SIOCGPGRP      _IOR('s', 9, pid_t)
+
+#define SIOCGSTAMP     0x8906          /* Get stamp - linux-specific */
+
+#endif /* _XTENSA_SOCKIOS_H */
diff --git a/include/asm-xtensa/spinlock.h b/include/asm-xtensa/spinlock.h
new file mode 100644 (file)
index 0000000..8ff2364
--- /dev/null
@@ -0,0 +1,16 @@
+/*
+ * include/asm-xtensa/spinlock.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_SPINLOCK_H
+#define _XTENSA_SPINLOCK_H
+
+#include <linux/spinlock.h>
+
+#endif /* _XTENSA_SPINLOCK_H */
diff --git a/include/asm-xtensa/stat.h b/include/asm-xtensa/stat.h
new file mode 100644 (file)
index 0000000..2f4662f
--- /dev/null
@@ -0,0 +1,105 @@
+/*
+ * include/asm-xtensa/stat.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_STAT_H
+#define _XTENSA_STAT_H
+
+#include <linux/types.h>
+
+struct __old_kernel_stat {
+       unsigned short st_dev;
+       unsigned short st_ino;
+       unsigned short st_mode;
+       unsigned short st_nlink;
+       unsigned short st_uid;
+       unsigned short st_gid;
+       unsigned short st_rdev;
+       unsigned long  st_size;
+       unsigned long  st_atime;
+       unsigned long  st_mtime;
+       unsigned long  st_ctime;
+};
+
+#define STAT_HAVE_NSEC 1
+
+struct stat {
+       unsigned short st_dev;
+       unsigned short __pad1;
+       unsigned long st_ino;
+       unsigned short st_mode;
+       unsigned short st_nlink;
+       unsigned short st_uid;
+       unsigned short st_gid;
+       unsigned short st_rdev;
+       unsigned short __pad2;
+       unsigned long  st_size;
+       unsigned long  st_blksize;
+       unsigned long  st_blocks;
+       unsigned long  st_atime;
+       unsigned long  st_atime_nsec;
+       unsigned long  st_mtime;
+       unsigned long  st_mtime_nsec;
+       unsigned long  st_ctime;
+       unsigned long  st_ctime_nsec;
+       unsigned long  __unused4;
+       unsigned long  __unused5;
+};
+
+/* This matches struct stat64 in glibc-2.2.3. */
+
+struct stat64  {
+#ifdef __XTENSA_EL__
+       unsigned short  st_dev;         /* Device */
+       unsigned char   __pad0[10];
+#else
+       unsigned char   __pad0[6];
+       unsigned short  st_dev;
+       unsigned char   __pad1[2];
+#endif
+
+#define STAT64_HAS_BROKEN_ST_INO       1
+       unsigned long __st_ino;         /* 32bit file serial number. */
+
+       unsigned int  st_mode;          /* File mode. */
+       unsigned int  st_nlink;         /* Link count. */
+       unsigned int  st_uid;           /* User ID of the file's owner. */
+       unsigned int  st_gid;           /* Group ID of the file's group. */
+
+#ifdef __XTENSA_EL__
+       unsigned short  st_rdev;        /* Device number, if device. */
+       unsigned char   __pad3[10];
+#else
+       unsigned char   __pad2[6];
+       unsigned short  st_rdev;
+       unsigned char   __pad3[2];
+#endif
+
+       long long int  st_size;         /* Size of file, in bytes. */
+       long int st_blksize;            /* Optimal block size for I/O. */
+
+#ifdef __XTENSA_EL__
+       unsigned long  st_blocks;       /* Number 512-byte blocks allocated. */
+       unsigned long  __pad4;
+#else
+       unsigned long  __pad4;
+       unsigned long  st_blocks;
+#endif
+
+       unsigned long  __pad5;
+       long int st_atime;              /* Time of last access. */
+       unsigned long  st_atime_nsec;
+       long int st_mtime;              /* Time of last modification. */
+       unsigned long  st_mtime_nsec;
+       long int  st_ctime;             /* Time of last status change. */
+       unsigned long  st_ctime_nsec;
+       unsigned long long int st_ino;  /* File serial number. */
+};
+
+#endif /* _XTENSA_STAT_H */
diff --git a/include/asm-xtensa/statfs.h b/include/asm-xtensa/statfs.h
new file mode 100644 (file)
index 0000000..9c3d1a2
--- /dev/null
@@ -0,0 +1,17 @@
+/*
+ * include/asm-xtensa/statfs.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_STATFS_H
+#define _XTENSA_STATFS_H
+
+#include <asm-generic/statfs.h>
+
+#endif /* _XTENSA_STATFS_H */
+
diff --git a/include/asm-xtensa/string.h b/include/asm-xtensa/string.h
new file mode 100644 (file)
index 0000000..3f81b27
--- /dev/null
@@ -0,0 +1,124 @@
+/*
+ * include/asm-xtensa/string.h
+ *
+ * These trivial string functions are considered part of the public domain.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+/* We should optimize these. See arch/xtensa/lib/strncpy_user.S */
+
+#ifndef _XTENSA_STRING_H
+#define _XTENSA_STRING_H
+
+#define __HAVE_ARCH_STRCPY
+extern __inline__ char *strcpy(char *__dest, const char *__src)
+{
+       register char *__xdest = __dest;
+       unsigned long __dummy;
+
+       __asm__ __volatile__("1:\n\t"
+               "l8ui   %2, %1, 0\n\t"
+               "s8i    %2, %0, 0\n\t"
+               "addi   %1, %1, 1\n\t"
+               "addi   %0, %0, 1\n\t"
+               "bnez   %2, 1b\n\t"
+               : "=r" (__dest), "=r" (__src), "=&r" (__dummy)
+               : "0" (__dest), "1" (__src)
+               : "memory");
+
+       return __xdest;
+}
+
+#define __HAVE_ARCH_STRNCPY
+extern __inline__ char *strncpy(char *__dest, const char *__src, size_t __n)
+{
+       register char *__xdest = __dest;
+       unsigned long __dummy;
+
+       if (__n == 0)
+               return __xdest;
+
+       __asm__ __volatile__(
+               "1:\n\t"
+               "l8ui   %2, %1, 0\n\t"
+               "s8i    %2, %0, 0\n\t"
+               "addi   %1, %1, 1\n\t"
+               "addi   %0, %0, 1\n\t"
+               "beqz   %2, 2f\n\t"
+               "bne    %1, %5, 1b\n"
+               "2:"
+               : "=r" (__dest), "=r" (__src), "=&r" (__dummy)
+               : "0" (__dest), "1" (__src), "r" (__src+__n)
+               : "memory");
+
+       return __xdest;
+}
+
+#define __HAVE_ARCH_STRCMP
+extern __inline__ int strcmp(const char *__cs, const char *__ct)
+{
+       register int __res;
+       unsigned long __dummy;
+
+       __asm__ __volatile__(
+               "1:\n\t"
+               "l8ui   %3, %1, 0\n\t"
+               "addi   %1, %1, 1\n\t"
+               "l8ui   %2, %0, 0\n\t"
+               "addi   %0, %0, 1\n\t"
+               "beqz   %2, 2f\n\t"
+               "beq    %2, %3, 1b\n"
+               "2:\n\t"
+               "sub    %2, %3, %2"
+               : "=r" (__cs), "=r" (__ct), "=&r" (__res), "=&r" (__dummy)
+               : "0" (__cs), "1" (__ct));
+
+       return __res;
+}
+
+#define __HAVE_ARCH_STRNCMP
+extern __inline__ int strncmp(const char *__cs, const char *__ct, size_t __n)
+{
+       register int __res;
+       unsigned long __dummy;
+
+       __asm__ __volatile__(
+               "mov    %2, %3\n"
+               "1:\n\t"
+               "beq    %0, %6, 2f\n\t"
+               "l8ui   %3, %1, 0\n\t"
+               "addi   %1, %1, 1\n\t"
+               "l8ui   %2, %0, 0\n\t"
+               "addi   %0, %0, 1\n\t"
+               "beqz   %2, 2f\n\t"
+               "beqz   %3, 2f\n\t"
+               "beq    %2, %3, 1b\n"
+               "2:\n\t"
+               "sub    %2, %3, %2"
+               : "=r" (__cs), "=r" (__ct), "=&r" (__res), "=&r" (__dummy)
+               : "0" (__cs), "1" (__ct), "r" (__cs+__n));
+
+       return __res;
+}
+
+#define __HAVE_ARCH_MEMSET
+extern void *memset(void *__s, int __c, size_t __count);
+
+#define __HAVE_ARCH_MEMCPY
+extern void *memcpy(void *__to, __const__ void *__from, size_t __n);
+
+#define __HAVE_ARCH_MEMMOVE
+extern void *memmove(void *__dest, __const__ void *__src, size_t __n);
+
+/* Don't build bcopy at all ...  */
+#define __HAVE_ARCH_BCOPY
+
+#define __HAVE_ARCH_MEMSCAN
+#define memscan memchr
+
+#endif /* _XTENSA_STRING_H */
diff --git a/include/asm-xtensa/system.h b/include/asm-xtensa/system.h
new file mode 100644 (file)
index 0000000..690fe32
--- /dev/null
@@ -0,0 +1,252 @@
+/*
+ * include/asm-xtensa/system.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_SYSTEM_H
+#define _XTENSA_SYSTEM_H
+
+#include <linux/config.h>
+#include <linux/stringify.h>
+
+#include <asm/processor.h>
+
+/* interrupt control */
+
+#define local_save_flags(x)                                            \
+       __asm__ __volatile__ ("rsr %0,"__stringify(PS) : "=a" (x));
+#define local_irq_restore(x)   do {                                    \
+       __asm__ __volatile__ ("wsr %0, "__stringify(PS)" ; rsync"       \
+                             :: "a" (x) : "memory"); } while(0);
+#define local_irq_save(x)      do {                                    \
+       __asm__ __volatile__ ("rsil %0, "__stringify(LOCKLEVEL)         \
+                             : "=a" (x) :: "memory");} while(0);
+
+static inline void local_irq_disable(void)
+{
+       unsigned long flags;
+       __asm__ __volatile__ ("rsil %0, "__stringify(LOCKLEVEL)
+                             : "=a" (flags) :: "memory");
+}
+static inline void local_irq_enable(void)
+{
+       unsigned long flags;
+       __asm__ __volatile__ ("rsil %0, 0" : "=a" (flags) :: "memory");
+
+}
+
+static inline int irqs_disabled(void)
+{
+       unsigned long flags;
+       local_save_flags(flags);
+       return flags & 0xf;
+}
+
+#define RSR_CPENABLE(x)        do {                                              \
+       __asm__ __volatile__("rsr %0," __stringify(CPENABLE) : "=a" (x)); \
+       } while(0);
+#define WSR_CPENABLE(x)        do {                                              \
+       __asm__ __volatile__("wsr %0," __stringify(CPENABLE)";rsync"      \
+                            :: "a" (x));} while(0);
+
+#define clear_cpenable() __clear_cpenable()
+
+extern __inline__ void __clear_cpenable(void)
+{
+#if XCHAL_HAVE_CP
+       unsigned long i = 0;
+       WSR_CPENABLE(i);
+#endif
+}
+
+extern __inline__ void enable_coprocessor(int i)
+{
+#if XCHAL_HAVE_CP
+       int cp;
+       RSR_CPENABLE(cp);
+       cp |= 1 << i;
+       WSR_CPENABLE(cp);
+#endif
+}
+
+extern __inline__ void disable_coprocessor(int i)
+{
+#if XCHAL_HAVE_CP
+       int cp;
+       RSR_CPENABLE(cp);
+       cp &= ~(1 << i);
+       WSR_CPENABLE(cp);
+#endif
+}
+
+#define smp_read_barrier_depends() do { } while(0)
+#define read_barrier_depends() do { } while(0)
+
+#define mb()  barrier()
+#define rmb() mb()
+#define wmb() mb()
+
+#ifdef CONFIG_SMP
+#error smp_* not defined
+#else
+#define smp_mb()       barrier()
+#define smp_rmb()      barrier()
+#define smp_wmb()      barrier()
+#endif
+
+#define set_mb(var, value)     do { var = value; mb(); } while (0)
+#define set_wmb(var, value)    do { var = value; wmb(); } while (0)
+
+#if !defined (__ASSEMBLY__)
+
+/* * switch_to(n) should switch tasks to task nr n, first
+ * checking that n isn't the current task, in which case it does nothing.
+ */
+extern void *_switch_to(void *last, void *next);
+
+#endif /* __ASSEMBLY__ */
+
+#define prepare_to_switch()    do { } while(0)
+
+#define switch_to(prev,next,last)              \
+do {                                           \
+       clear_cpenable();                       \
+       (last) = _switch_to(prev, next);        \
+} while(0)
+
+/*
+ * cmpxchg
+ */
+
+extern __inline__ unsigned long
+__cmpxchg_u32(volatile int *p, int old, int new)
+{
+  __asm__ __volatile__("rsil    a15, "__stringify(LOCKLEVEL)"\n\t"
+                      "l32i    %0, %1, 0              \n\t"
+                      "bne     %0, %2, 1f             \n\t"
+                      "s32i    %3, %1, 0              \n\t"
+                      "1:                             \n\t"
+                      "wsr     a15, "__stringify(PS)" \n\t"
+                      "rsync                          \n\t"
+                      : "=&a" (old)
+                      : "a" (p), "a" (old), "r" (new)
+                      : "a15", "memory");
+  return old;
+}
+/* This function doesn't exist, so you'll get a linker error
+ * if something tries to do an invalid cmpxchg(). */
+
+extern void __cmpxchg_called_with_bad_pointer(void);
+
+static __inline__ unsigned long
+__cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size)
+{
+       switch (size) {
+       case 4:  return __cmpxchg_u32(ptr, old, new);
+       default: __cmpxchg_called_with_bad_pointer();
+                return old;
+       }
+}
+
+#define cmpxchg(ptr,o,n)                                                     \
+       ({ __typeof__(*(ptr)) _o_ = (o);                                      \
+          __typeof__(*(ptr)) _n_ = (n);                                      \
+          (__typeof__(*(ptr))) __cmpxchg((ptr), (unsigned long)_o_,          \
+                                       (unsigned long)_n_, sizeof (*(ptr))); \
+       })
+
+
+
+
+/*
+ * xchg_u32
+ *
+ * Note that a15 is used here because the register allocation
+ * done by the compiler is not guaranteed and a window overflow
+ * may not occur between the rsil and wsr instructions. By using
+ * a15 in the rsil, the machine is guaranteed to be in a state
+ * where no register reference will cause an overflow.
+ */
+
+extern __inline__ unsigned long xchg_u32(volatile int * m, unsigned long val)
+{
+  unsigned long tmp;
+  __asm__ __volatile__("rsil    a15, "__stringify(LOCKLEVEL)"\n\t"
+                      "l32i    %0, %1, 0              \n\t"
+                      "s32i    %2, %1, 0              \n\t"
+                      "wsr     a15, "__stringify(PS)" \n\t"
+                      "rsync                          \n\t"
+                      : "=&a" (tmp)
+                      : "a" (m), "a" (val)
+                      : "a15", "memory");
+  return tmp;
+}
+
+#define tas(ptr) (xchg((ptr),1))
+
+#if ( __XCC__ == 1 )
+
+/* xt-xcc processes __inline__ differently than xt-gcc and decides to
+ * insert an out-of-line copy of function __xchg.  This presents the
+ * unresolved symbol at link time of __xchg_called_with_bad_pointer,
+ * even though such a function would never be called at run-time.
+ * xt-gcc always inlines __xchg, and optimizes away the undefined
+ * bad_pointer function.
+ */
+
+#define xchg(ptr,x) xchg_u32(ptr,x)
+
+#else  /* assume xt-gcc */
+
+#define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
+
+/*
+ * This only works if the compiler isn't horribly bad at optimizing.
+ * gcc-2.5.8 reportedly can't handle this, but I define that one to
+ * be dead anyway.
+ */
+
+extern void __xchg_called_with_bad_pointer(void);
+
+static __inline__ unsigned long
+__xchg(unsigned long x, volatile void * ptr, int size)
+{
+       switch (size) {
+               case 4:
+                       return xchg_u32(ptr, x);
+       }
+       __xchg_called_with_bad_pointer();
+       return x;
+}
+
+#endif
+
+extern void set_except_vector(int n, void *addr);
+
+static inline void spill_registers(void)
+{
+       unsigned int a0, ps;
+
+       __asm__ __volatile__ (
+               "movi   a14," __stringify (PS_EXCM_MASK) " | 1\n\t"
+               "mov    a12, a0\n\t"
+               "rsr    a13," __stringify(SAR) "\n\t"
+               "xsr    a14," __stringify(PS) "\n\t"
+               "movi   a0, _spill_registers\n\t"
+               "rsync\n\t"
+               "callx0 a0\n\t"
+               "mov    a0, a12\n\t"
+               "wsr    a13," __stringify(SAR) "\n\t"
+               "wsr    a14," __stringify(PS) "\n\t"
+               :: "a" (&a0), "a" (&ps)
+               : "a2", "a3", "a12", "a13", "a14", "a15", "memory");
+}
+
+#define arch_align_stack(x) (x)
+
+#endif /* _XTENSA_SYSTEM_H */
diff --git a/include/asm-xtensa/termbits.h b/include/asm-xtensa/termbits.h
new file mode 100644 (file)
index 0000000..c780593
--- /dev/null
@@ -0,0 +1,194 @@
+/*
+ * include/asm-xtensa/termbits.h
+ *
+ * Copied from SH.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_TERMBITS_H
+#define _XTENSA_TERMBITS_H
+
+
+#include <linux/posix_types.h>
+
+typedef unsigned char  cc_t;
+typedef unsigned int   speed_t;
+typedef unsigned int   tcflag_t;
+
+#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_line;                    /* line discipline */
+       cc_t c_cc[NCCS];                /* control characters */
+};
+
+/* c_cc characters */
+
+#define VINTR 0
+#define VQUIT 1
+#define VERASE 2
+#define VKILL 3
+#define VEOF 4
+#define VTIME 5
+#define VMIN 6
+#define VSWTC 7
+#define VSTART 8
+#define VSTOP 9
+#define VSUSP 10
+#define VEOL 11
+#define VREPRINT 12
+#define VDISCARD 13
+#define VWERASE 14
+#define VLNEXT 15
+#define VEOL2 16
+
+/* 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 IUCLC  0001000
+#define IXON   0002000
+#define IXANY  0004000
+#define IXOFF  0010000
+#define IMAXBEL        0020000
+#define IUTF8  0040000
+
+/* c_oflag bits */
+
+#define OPOST  0000001
+#define OLCUC  0000002
+#define ONLCR  0000004
+#define OCRNL  0000010
+#define ONOCR  0000020
+#define ONLRET 0000040
+#define OFILL  0000100
+#define OFDEL  0000200
+#define NLDLY  0000400
+#define   NL0  0000000
+#define   NL1  0000400
+#define CRDLY  0003000
+#define   CR0  0000000
+#define   CR1  0001000
+#define   CR2  0002000
+#define   CR3  0003000
+#define TABDLY 0014000
+#define   TAB0 0000000
+#define   TAB1 0004000
+#define   TAB2 0010000
+#define   TAB3 0014000
+#define   XTABS        0014000
+#define BSDLY  0020000
+#define   BS0  0000000
+#define   BS1  0020000
+#define VTDLY  0040000
+#define   VT0  0000000
+#define   VT1  0040000
+#define FFDLY  0100000
+#define   FF0  0000000
+#define   FF1  0100000
+
+/* c_cflag bit meaning */
+
+#define CBAUD  0010017
+#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 CSIZE  0000060
+#define   CS5  0000000
+#define   CS6  0000020
+#define   CS7  0000040
+#define   CS8  0000060
+#define CSTOPB 0000100
+#define CREAD  0000200
+#define PARENB 0000400
+#define PARODD 0001000
+#define HUPCL  0002000
+#define CLOCAL 0004000
+#define CBAUDEX 0010000
+#define    B57600 0010001
+#define   B115200 0010002
+#define   B230400 0010003
+#define   B460800 0010004
+#define   B500000 0010005
+#define   B576000 0010006
+#define   B921600 0010007
+#define  B1000000 0010010
+#define  B1152000 0010011
+#define  B1500000 0010012
+#define  B2000000 0010013
+#define  B2500000 0010014
+#define  B3000000 0010015
+#define  B3500000 0010016
+#define  B4000000 0010017
+#define CIBAUD   002003600000  /* input baud rate (not used) */
+#define CMSPAR   010000000000          /* mark or space (stick) parity */
+#define CRTSCTS          020000000000          /* flow control */
+
+/* c_lflag bits */
+
+#define ISIG   0000001
+#define ICANON 0000002
+#define XCASE  0000004
+#define ECHO   0000010
+#define ECHOE  0000020
+#define ECHOK  0000040
+#define ECHONL 0000100
+#define NOFLSH 0000200
+#define TOSTOP 0000400
+#define ECHOCTL        0001000
+#define ECHOPRT        0002000
+#define ECHOKE 0004000
+#define FLUSHO 0010000
+#define PENDIN 0040000
+#define IEXTEN 0100000
+
+/* 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
+
+#endif /* _XTENSA_TERMBITS_H */
diff --git a/include/asm-xtensa/termios.h b/include/asm-xtensa/termios.h
new file mode 100644 (file)
index 0000000..83c6aed
--- /dev/null
@@ -0,0 +1,122 @@
+/*
+ * include/asm-xtensa/termios.h
+ *
+ * Copied from SH.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_TERMIOS_H
+#define _XTENSA_TERMIOS_H
+
+#include <asm/termbits.h>
+#include <asm/ioctls.h>
+
+struct winsize {
+       unsigned short ws_row;
+       unsigned short ws_col;
+       unsigned short ws_xpixel;
+       unsigned short ws_ypixel;
+};
+
+#define NCC 8
+struct termio {
+       unsigned short c_iflag;         /* input mode flags */
+       unsigned short c_oflag;         /* output mode flags */
+       unsigned short c_cflag;         /* control mode flags */
+       unsigned short c_lflag;         /* local mode flags */
+       unsigned char c_line;           /* line discipline */
+       unsigned char c_cc[NCC];        /* control characters */
+};
+
+/* Modem lines */
+
+#define TIOCM_LE       0x001
+#define TIOCM_DTR      0x002
+#define TIOCM_RTS      0x004
+#define TIOCM_ST       0x008
+#define TIOCM_SR       0x010
+#define TIOCM_CTS      0x020
+#define TIOCM_CAR      0x040
+#define TIOCM_RNG      0x080
+#define TIOCM_DSR      0x100
+#define TIOCM_CD       TIOCM_CAR
+#define TIOCM_RI       TIOCM_RNG
+#define TIOCM_OUT1     0x2000
+#define TIOCM_OUT2     0x4000
+#define TIOCM_LOOP     0x8000
+
+/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
+
+/* Line disciplines */
+
+#define N_TTY          0
+#define N_SLIP         1
+#define N_MOUSE                2
+#define N_PPP          3
+#define N_STRIP                4
+#define N_AX25         5
+#define N_X25          6       /* X.25 async */
+#define N_6PACK                7
+#define N_MASC         8       /* Reserved for Mobitex module <kaz@cafe.net> */
+#define N_R3964                9       /* Reserved for Simatic R3964 module */
+#define N_PROFIBUS_FDL 10      /* Reserved for Profibus <Dave@mvhi.com> */
+#define N_IRDA         11      /* Linux IR - http://irda.sourceforge.net/ */
+#define N_SMSBLOCK     12      /* SMS block mode - for talking to GSM data cards about SMS messages */
+#define N_HDLC         13      /* synchronous HDLC */
+#define N_SYNC_PPP     14
+#define N_HCI          15      /* Bluetooth HCI UART */
+
+#ifdef __KERNEL__
+
+/*     intr=^C         quit=^\         erase=del       kill=^U
+       eof=^D          vtime=\0        vmin=\1         sxtc=\0
+       start=^Q        stop=^S         susp=^Z         eol=\0
+       reprint=^R      discard=^U      werase=^W       lnext=^V
+       eol2=\0
+*/
+#define INIT_C_CC "\003\034\177\025\004\0\1\0\021\023\032\0\022\017\027\026\0"
+
+/*
+ * Translate a "termio" structure into a "termios". Ugh.
+ */
+
+#define SET_LOW_TERMIOS_BITS(termios, termio, x) { \
+       unsigned short __tmp; \
+       get_user(__tmp,&(termio)->x); \
+       *(unsigned short *) &(termios)->x = __tmp; \
+}
+
+#define user_termio_to_kernel_termios(termios, termio) \
+({ \
+       SET_LOW_TERMIOS_BITS(termios, termio, c_iflag); \
+       SET_LOW_TERMIOS_BITS(termios, termio, c_oflag); \
+       SET_LOW_TERMIOS_BITS(termios, termio, c_cflag); \
+       SET_LOW_TERMIOS_BITS(termios, termio, c_lflag); \
+       copy_from_user((termios)->c_cc, (termio)->c_cc, NCC); \
+})
+
+/*
+ * Translate a "termios" structure into a "termio". Ugh.
+ */
+
+#define kernel_termios_to_user_termio(termio, termios) \
+({ \
+       put_user((termios)->c_iflag, &(termio)->c_iflag); \
+       put_user((termios)->c_oflag, &(termio)->c_oflag); \
+       put_user((termios)->c_cflag, &(termio)->c_cflag); \
+       put_user((termios)->c_lflag, &(termio)->c_lflag); \
+       put_user((termios)->c_line,  &(termio)->c_line); \
+       copy_to_user((termio)->c_cc, (termios)->c_cc, NCC); \
+})
+
+#define user_termios_to_kernel_termios(k, u) copy_from_user(k, u, sizeof(struct termios))
+#define kernel_termios_to_user_termios(u, k) copy_to_user(u, k, sizeof(struct termios))
+
+#endif /* __KERNEL__ */
+
+#endif /* _XTENSA_TERMIOS_H */
diff --git a/include/asm-xtensa/thread_info.h b/include/asm-xtensa/thread_info.h
new file mode 100644 (file)
index 0000000..af208d4
--- /dev/null
@@ -0,0 +1,146 @@
+/*
+ * include/asm-xtensa/thread_info.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_THREAD_INFO_H
+#define _XTENSA_THREAD_INFO_H
+
+#ifdef __KERNEL__
+
+#ifndef __ASSEMBLY__
+# include <asm/processor.h>
+#endif
+
+/*
+ * low level task data that entry.S needs immediate access to
+ * - this struct should fit entirely inside of one cache line
+ * - this struct shares the supervisor stack pages
+ * - if the contents of this structure are changed, the assembly constants
+ *   must also be changed
+ */
+
+#ifndef __ASSEMBLY__
+
+struct thread_info {
+       struct task_struct      *task;          /* main task structure */
+       struct exec_domain      *exec_domain;   /* execution domain */
+       unsigned long           flags;          /* low level flags */
+       unsigned long           status;         /* thread-synchronous flags */
+       __u32                   cpu;            /* current CPU */
+       __s32                   preempt_count;  /* 0 => preemptable,< 0 => BUG*/
+
+       mm_segment_t            addr_limit;     /* thread address space */
+       struct restart_block    restart_block;
+
+
+};
+
+#else /* !__ASSEMBLY__ */
+
+/* offsets into the thread_info struct for assembly code access */
+#define TI_TASK                 0x00000000
+#define TI_EXEC_DOMAIN  0x00000004
+#define TI_FLAGS        0x00000008
+#define TI_STATUS       0x0000000C
+#define TI_CPU          0x00000010
+#define TI_PRE_COUNT    0x00000014
+#define TI_ADDR_LIMIT   0x00000018
+#define TI_RESTART_BLOCK 0x000001C
+
+#endif
+
+#define PREEMPT_ACTIVE         0x10000000
+
+/*
+ * macros/functions for gaining access to the thread information structure
+ *
+ * preempt_count needs to be 1 initially, until the scheduler is functional.
+ */
+
+#ifndef __ASSEMBLY__
+
+#define INIT_THREAD_INFO(tsk)                  \
+{                                              \
+       .task           = &tsk,                 \
+       .exec_domain    = &default_exec_domain, \
+       .flags          = 0,                    \
+       .cpu            = 0,                    \
+       .preempt_count  = 1,                    \
+       .addr_limit     = KERNEL_DS,            \
+       .restart_block = {                      \
+               .fn = do_no_restart_syscall,    \
+       },                                      \
+}
+
+#define init_thread_info       (init_thread_union.thread_info)
+#define init_stack             (init_thread_union.stack)
+
+/* how to get the thread information struct from C */
+static inline struct thread_info *current_thread_info(void)
+{
+       struct thread_info *ti;
+        __asm__("extui %0,a1,0,13\n\t"
+                "xor %0, a1, %0" : "=&r" (ti) : );
+       return ti;
+}
+
+/* thread information allocation */
+#define alloc_thread_info(tsk) ((struct thread_info *) __get_free_pages(GFP_KERNEL,1))
+#define free_thread_info(ti) free_pages((unsigned long) (ti), 1)
+#define get_thread_info(ti) get_task_struct((ti)->task)
+#define put_thread_info(ti) put_task_struct((ti)->task)
+
+#else /* !__ASSEMBLY__ */
+
+/* how to get the thread information struct from ASM */
+#define GET_THREAD_INFO(reg,sp) \
+       extui reg, sp, 0, 13; \
+       xor   reg, sp, reg
+#endif
+
+
+/*
+ * thread information flags
+ * - these are process state flags that various assembly files may need to access
+ * - pending work-to-be-done flags are in LSW
+ * - other flags in MSW
+ */
+#define TIF_SYSCALL_TRACE      0       /* syscall trace active */
+#define TIF_NOTIFY_RESUME      1       /* resumption notification requested */
+#define TIF_SIGPENDING         2       /* signal pending */
+#define TIF_NEED_RESCHED       3       /* rescheduling necessary */
+#define TIF_SINGLESTEP         4       /* restore singlestep on return to user mode */
+#define TIF_IRET               5       /* return with iret */
+#define TIF_MEMDIE             6
+#define TIF_POLLING_NRFLAG     16      /* true if poll_idle() is polling TIF_NEED_RESCHED */
+
+#define _TIF_SYSCALL_TRACE     (1<<TIF_SYSCALL_TRACE)
+#define _TIF_NOTIFY_RESUME     (1<<TIF_NOTIFY_RESUME)
+#define _TIF_SIGPENDING                (1<<TIF_SIGPENDING)
+#define _TIF_NEED_RESCHED      (1<<TIF_NEED_RESCHED)
+#define _TIF_SINGLESTEP                (1<<TIF_SINGLESTEP)
+#define _TIF_IRET              (1<<TIF_IRET)
+#define _TIF_POLLING_NRFLAG    (1<<TIF_POLLING_NRFLAG)
+
+#define _TIF_WORK_MASK         0x0000FFFE      /* work to do on interrupt/exception return */
+#define _TIF_ALLWORK_MASK      0x0000FFFF      /* work to do on any return to u-space */
+
+/*
+ * Thread-synchronous status.
+ *
+ * This is different from the flags in that nobody else
+ * ever touches our thread-synchronous status, so we don't
+ * have to worry about atomic accesses.
+ */
+#define TS_USEDFPU             0x0001  /* FPU was used by this task this quantum (SMP) */
+
+#define THREAD_SIZE 8192       //(2*PAGE_SIZE)
+
+#endif /* __KERNEL__ */
+#endif /* _XTENSA_THREAD_INFO */
diff --git a/include/asm-xtensa/timex.h b/include/asm-xtensa/timex.h
new file mode 100644 (file)
index 0000000..d14a375
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+ * include/asm-xtensa/timex.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_TIMEX_H
+#define _XTENSA_TIMEX_H
+
+#ifdef __KERNEL__
+
+#include <asm/processor.h>
+#include <linux/stringify.h>
+
+#if XCHAL_INT_LEVEL(XCHAL_TIMER0_INTERRUPT) == 1
+# define LINUX_TIMER     0
+#elif XCHAL_INT_LEVEL(XCHAL_TIMER1_INTERRUPT) == 1
+# define LINUX_TIMER     1
+#elif XCHAL_INT_LEVEL(XCHAL_TIMER2_INTERRUPT) == 1
+# define LINUX_TIMER     2
+#else
+# error "Bad timer number for Linux configurations!"
+#endif
+
+#define LINUX_TIMER_INT         XCHAL_TIMER_INTERRUPT(LINUX_TIMER)
+#define LINUX_TIMER_MASK        (1L << LINUX_TIMER_INT)
+
+#define CLOCK_TICK_RATE        1193180 /* (everyone is using this value) */
+#define CLOCK_TICK_FACTOR       20 /* Factor of both 10^6 and CLOCK_TICK_RATE */
+#define FINETUNE ((((((long)LATCH * HZ - CLOCK_TICK_RATE) << SHIFT_HZ) * \
+       (1000000/CLOCK_TICK_FACTOR) / (CLOCK_TICK_RATE/CLOCK_TICK_FACTOR)) \
+               << (SHIFT_SCALE-SHIFT_HZ)) / HZ)
+
+#ifdef CONFIG_XTENSA_CALIBRATE_CCOUNT
+extern unsigned long ccount_per_jiffy;
+extern unsigned long ccount_nsec;
+#define CCOUNT_PER_JIFFY ccount_per_jiffy
+#define CCOUNT_NSEC ccount_nsec
+#else
+#define CCOUNT_PER_JIFFY (CONFIG_XTENSA_CPU_CLOCK*(1000000UL/HZ))
+#define CCOUNT_NSEC (1000000000UL / CONFIG_XTENSA_CPU_CLOCK)
+#endif
+
+
+typedef unsigned long long cycles_t;
+
+/*
+ * Only used for SMP.
+ */
+
+extern cycles_t cacheflush_time;
+
+#define get_cycles()   (0)
+
+
+/*
+ * Register access.
+ */
+
+#define WSR_CCOUNT(r)    __asm__("wsr %0,"__stringify(CCOUNT) :: "a" (r))
+#define RSR_CCOUNT(r)    __asm__("rsr %0,"__stringify(CCOUNT) : "=a" (r))
+#define WSR_CCOMPARE(x,r) __asm__("wsr %0,"__stringify(CCOMPARE_0)"+"__stringify(x) :: "a"(r))
+#define RSR_CCOMPARE(x,r) __asm__("rsr %0,"__stringify(CCOMPARE_0)"+"__stringify(x) : "=a"(r))
+
+static inline unsigned long get_ccount (void)
+{
+       unsigned long ccount;
+       RSR_CCOUNT(ccount);
+       return ccount;
+}
+
+static inline void set_ccount (unsigned long ccount)
+{
+       WSR_CCOUNT(ccount);
+}
+
+static inline unsigned long get_linux_timer (void)
+{
+       unsigned ccompare;
+       RSR_CCOMPARE(LINUX_TIMER, ccompare);
+       return ccompare;
+}
+
+static inline void set_linux_timer (unsigned long ccompare)
+{
+       WSR_CCOMPARE(LINUX_TIMER, ccompare);
+}
+
+#endif /* __KERNEL__ */
+#endif /* _XTENSA_TIMEX_H */
diff --git a/include/asm-xtensa/tlb.h b/include/asm-xtensa/tlb.h
new file mode 100644 (file)
index 0000000..4562b2d
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * include/asm-xtensa/tlb.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_TLB_H
+#define _XTENSA_TLB_H
+
+#define tlb_start_vma(tlb,vma)                 do { } while (0)
+#define tlb_end_vma(tlb,vma)                   do { } while (0)
+#define __tlb_remove_tlb_entry(tlb,pte,addr)   do { } while (0)
+
+#define tlb_flush(tlb)                         flush_tlb_mm((tlb)->mm)
+
+#include <asm-generic/tlb.h>
+#include <asm/page.h>
+
+#define __pte_free_tlb(tlb,pte)                        pte_free(pte)
+
+#endif /* _XTENSA_TLB_H */
diff --git a/include/asm-xtensa/tlbflush.h b/include/asm-xtensa/tlbflush.h
new file mode 100644 (file)
index 0000000..23bfe9d
--- /dev/null
@@ -0,0 +1,200 @@
+/*
+ * include/asm-xtensa/tlbflush.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_TLBFLUSH_H
+#define _XTENSA_TLBFLUSH_H
+
+#define DEBUG_TLB
+
+#ifdef __KERNEL__
+
+#include <asm/processor.h>
+#include <linux/stringify.h>
+
+/* TLB flushing:
+ *
+ *  - flush_tlb_all() flushes all processes TLB entries
+ *  - flush_tlb_mm(mm) flushes the specified mm context TLB entries
+ *  - flush_tlb_page(mm, vmaddr) flushes a single page
+ *  - flush_tlb_range(mm, start, end) flushes a range of pages
+ */
+
+extern void flush_tlb_all(void);
+extern void flush_tlb_mm(struct mm_struct*);
+extern void flush_tlb_page(struct vm_area_struct*,unsigned long);
+extern void flush_tlb_range(struct vm_area_struct*,unsigned long,unsigned long);
+
+#define flush_tlb_kernel_range(start,end) flush_tlb_all()
+
+
+/* This is calld in munmap when we have freed up some page-table pages.
+ * We don't need to do anything here, there's nothing special about our
+ * page-table pages.
+ */
+
+extern inline void flush_tlb_pgtables(struct mm_struct *mm,
+                                      unsigned long start, unsigned long end)
+{
+}
+
+/* TLB operations. */
+
+#define ITLB_WAYS_LOG2      XCHAL_ITLB_WAY_BITS
+#define DTLB_WAYS_LOG2      XCHAL_DTLB_WAY_BITS
+#define ITLB_PROBE_SUCCESS  (1 << ITLB_WAYS_LOG2)
+#define DTLB_PROBE_SUCCESS  (1 << DTLB_WAYS_LOG2)
+
+extern inline unsigned long itlb_probe(unsigned long addr)
+{
+       unsigned long tmp;
+       __asm__ __volatile__("pitlb  %0, %1\n\t" : "=a" (tmp) : "a" (addr));
+       return tmp;
+}
+
+extern inline unsigned long dtlb_probe(unsigned long addr)
+{
+       unsigned long tmp;
+       __asm__ __volatile__("pdtlb  %0, %1\n\t" : "=a" (tmp) : "a" (addr));
+       return tmp;
+}
+
+extern inline void invalidate_itlb_entry (unsigned long probe)
+{
+       __asm__ __volatile__("iitlb  %0; isync\n\t" : : "a" (probe));
+}
+
+extern inline void invalidate_dtlb_entry (unsigned long probe)
+{
+       __asm__ __volatile__("idtlb  %0; dsync\n\t" : : "a" (probe));
+}
+
+/* Use the .._no_isync functions with caution.  Generally, these are
+ * handy for bulk invalidates followed by a single 'isync'.  The
+ * caller must follow up with an 'isync', which can be relatively
+ * expensive on some Xtensa implementations.
+ */
+extern inline void invalidate_itlb_entry_no_isync (unsigned entry)
+{
+       /* Caller must follow up with 'isync'. */
+       __asm__ __volatile__ ("iitlb  %0\n" : : "a" (entry) );
+}
+
+extern inline void invalidate_dtlb_entry_no_isync (unsigned entry)
+{
+       /* Caller must follow up with 'isync'. */
+       __asm__ __volatile__ ("idtlb  %0\n" : : "a" (entry) );
+}
+
+extern inline void set_itlbcfg_register (unsigned long val)
+{
+       __asm__ __volatile__("wsr  %0, "__stringify(ITLBCFG)"\n\t" "isync\n\t"
+                            : : "a" (val));
+}
+
+extern inline void set_dtlbcfg_register (unsigned long val)
+{
+       __asm__ __volatile__("wsr  %0, "__stringify(DTLBCFG)"; dsync\n\t"
+                            : : "a" (val));
+}
+
+extern inline void set_ptevaddr_register (unsigned long val)
+{
+       __asm__ __volatile__(" wsr  %0, "__stringify(PTEVADDR)"; isync\n"
+                            : : "a" (val));
+}
+
+extern inline unsigned long read_ptevaddr_register (void)
+{
+       unsigned long tmp;
+       __asm__ __volatile__("rsr  %0, "__stringify(PTEVADDR)"\n\t" : "=a" (tmp));
+       return tmp;
+}
+
+extern inline void write_dtlb_entry (pte_t entry, int way)
+{
+       __asm__ __volatile__("wdtlb  %1, %0; dsync\n\t"
+                            : : "r" (way), "r" (entry) );
+}
+
+extern inline void write_itlb_entry (pte_t entry, int way)
+{
+       __asm__ __volatile__("witlb  %1, %0; isync\n\t"
+                            : : "r" (way), "r" (entry) );
+}
+
+extern inline void invalidate_page_directory (void)
+{
+       invalidate_dtlb_entry (DTLB_WAY_PGTABLE);
+}
+
+extern inline void invalidate_itlb_mapping (unsigned address)
+{
+       unsigned long tlb_entry;
+       while ((tlb_entry = itlb_probe (address)) & ITLB_PROBE_SUCCESS)
+               invalidate_itlb_entry (tlb_entry);
+}
+
+extern inline void invalidate_dtlb_mapping (unsigned address)
+{
+       unsigned long tlb_entry;
+       while ((tlb_entry = dtlb_probe (address)) & DTLB_PROBE_SUCCESS)
+               invalidate_dtlb_entry (tlb_entry);
+}
+
+#define check_pgt_cache()      do { } while (0)
+
+
+#ifdef DEBUG_TLB
+
+/* DO NOT USE THESE FUNCTIONS.  These instructions aren't part of the Xtensa
+ * ISA and exist only for test purposes..
+ * You may find it helpful for MMU debugging, however.
+ *
+ * 'at' is the unmodified input register
+ * 'as' is the output register, as follows (specific to the Linux config):
+ *
+ *      as[31..12] contain the virtual address
+ *      as[11..08] are meaningless
+ *      as[07..00] contain the asid
+ */
+
+extern inline unsigned long read_dtlb_virtual (int way)
+{
+       unsigned long tmp;
+       __asm__ __volatile__("rdtlb0  %0, %1\n\t" : "=a" (tmp), "+a" (way));
+       return tmp;
+}
+
+extern inline unsigned long read_dtlb_translation (int way)
+{
+       unsigned long tmp;
+       __asm__ __volatile__("rdtlb1  %0, %1\n\t" : "=a" (tmp), "+a" (way));
+       return tmp;
+}
+
+extern inline unsigned long read_itlb_virtual (int way)
+{
+       unsigned long tmp;
+       __asm__ __volatile__("ritlb0  %0, %1\n\t" : "=a" (tmp), "+a" (way));
+       return tmp;
+}
+
+extern inline unsigned long read_itlb_translation (int way)
+{
+       unsigned long tmp;
+       __asm__ __volatile__("ritlb1  %0, %1\n\t" : "=a" (tmp), "+a" (way));
+       return tmp;
+}
+
+#endif /* DEBUG_TLB */
+
+
+#endif /* __KERNEL__ */
+#endif /* _XTENSA_PGALLOC_H */
diff --git a/include/asm-xtensa/topology.h b/include/asm-xtensa/topology.h
new file mode 100644 (file)
index 0000000..7309e38
--- /dev/null
@@ -0,0 +1,16 @@
+/*
+ * include/asm-xtensa/topology.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_TOPOLOGY_H
+#define _XTENSA_TOPOLOGY_H
+
+#include <asm-generic/topology.h>
+
+#endif /* _XTENSA_TOPOLOGY_H */
diff --git a/include/asm-xtensa/types.h b/include/asm-xtensa/types.h
new file mode 100644 (file)
index 0000000..ebac004
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * include/asm-xtensa/types.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_TYPES_H
+#define _XTENSA_TYPES_H
+
+#ifndef __ASSEMBLY__
+
+typedef unsigned short umode_t;
+
+/*
+ * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the
+ * header files exported to user space
+ */
+
+typedef __signed__ char __s8;
+typedef unsigned char __u8;
+
+typedef __signed__ short __s16;
+typedef unsigned short __u16;
+
+typedef __signed__ int __s32;
+typedef unsigned int __u32;
+
+#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
+typedef __signed__ long long __s64;
+typedef unsigned long long __u64;
+#endif
+
+/*
+ * These aren't exported outside the kernel to avoid name space clashes
+ */
+#ifdef __KERNEL__
+
+typedef __signed__ char s8;
+typedef unsigned char u8;
+
+typedef __signed__ short s16;
+typedef unsigned short u16;
+
+typedef __signed__ int s32;
+typedef unsigned int u32;
+
+typedef __signed__ long long s64;
+typedef unsigned long long u64;
+
+
+#define BITS_PER_LONG 32
+
+/* Dma addresses are 32-bits wide.  */
+
+typedef u32 dma_addr_t;
+
+typedef unsigned int kmem_bufctl_t;
+
+#endif /* __KERNEL__ */
+#endif
+
+#endif /* _XTENSA_TYPES_H */
diff --git a/include/asm-xtensa/uaccess.h b/include/asm-xtensa/uaccess.h
new file mode 100644 (file)
index 0000000..35576b2
--- /dev/null
@@ -0,0 +1,532 @@
+/*
+ * include/asm-xtensa/uaccess.h
+ *
+ * User space memory access functions
+ *
+ * These routines provide basic accessing functions to the user memory
+ * space for the kernel. This header file provides fuctions such as:
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_UACCESS_H
+#define _XTENSA_UACCESS_H
+
+#include <linux/errno.h>
+
+#define VERIFY_READ    0
+#define VERIFY_WRITE   1
+
+#ifdef __ASSEMBLY__
+
+#define _ASMLANGUAGE
+#include <asm/current.h>
+#include <asm/offsets.h>
+#include <asm/processor.h>
+
+/*
+ * These assembly macros mirror the C macros that follow below.  They
+ * should always have identical functionality.  See
+ * arch/xtensa/kernel/sys.S for usage.
+ */
+
+#define KERNEL_DS      0
+#define USER_DS                1
+
+#define get_ds         (KERNEL_DS)
+
+/*
+ * get_fs reads current->thread.current_ds into a register.
+ * On Entry:
+ *     <ad>    anything
+ *     <sp>    stack
+ * On Exit:
+ *     <ad>    contains current->thread.current_ds
+ */
+       .macro  get_fs  ad, sp
+       GET_CURRENT(\ad,\sp)
+       l32i    \ad, \ad, THREAD_CURRENT_DS
+       .endm
+
+/*
+ * set_fs sets current->thread.current_ds to some value.
+ * On Entry:
+ *     <at>    anything (temp register)
+ *     <av>    value to write
+ *     <sp>    stack
+ * On Exit:
+ *     <at>    destroyed (actually, current)
+ *     <av>    preserved, value to write
+ */
+       .macro  set_fs  at, av, sp
+       GET_CURRENT(\at,\sp)
+       s32i    \av, \at, THREAD_CURRENT_DS
+       .endm
+
+/*
+ * kernel_ok determines whether we should bypass addr/size checking.
+ * See the equivalent C-macro version below for clarity.
+ * On success, kernel_ok branches to a label indicated by parameter
+ * <success>.  This implies that the macro falls through to the next
+ * insruction on an error.
+ *
+ * Note that while this macro can be used independently, we designed
+ * in for optimal use in the access_ok macro below (i.e., we fall
+ * through on error).
+ *
+ * On Entry:
+ *     <at>            anything (temp register)
+ *     <success>       label to branch to on success; implies
+ *                     fall-through macro on error
+ *     <sp>            stack pointer
+ * On Exit:
+ *     <at>            destroyed (actually, current->thread.current_ds)
+ */
+
+#if ((KERNEL_DS != 0) || (USER_DS == 0))
+# error Assembly macro kernel_ok fails
+#endif
+       .macro  kernel_ok  at, sp, success
+       get_fs  \at, \sp
+       beqz    \at, \success
+       .endm
+
+/*
+ * user_ok determines whether the access to user-space memory is allowed.
+ * See the equivalent C-macro version below for clarity.
+ *
+ * On error, user_ok branches to a label indicated by parameter
+ * <error>.  This implies that the macro falls through to the next
+ * instruction on success.
+ *
+ * Note that while this macro can be used independently, we designed
+ * in for optimal use in the access_ok macro below (i.e., we fall
+ * through on success).
+ *
+ * On Entry:
+ *     <aa>    register containing memory address
+ *     <as>    register containing memory size
+ *     <at>    temp register
+ *     <error> label to branch to on error; implies fall-through
+ *             macro on success
+ * On Exit:
+ *     <aa>    preserved
+ *     <as>    preserved
+ *     <at>    destroyed (actually, (TASK_SIZE + 1 - size))
+ */
+       .macro  user_ok aa, as, at, error
+       movi    \at, (TASK_SIZE+1)
+       bgeu    \as, \at, \error
+       sub     \at, \at, \as
+       bgeu    \aa, \at, \error
+       .endm
+
+/*
+ * access_ok determines whether a memory access is allowed.  See the
+ * equivalent C-macro version below for clarity.
+ *
+ * On error, access_ok branches to a label indicated by parameter
+ * <error>.  This implies that the macro falls through to the next
+ * instruction on success.
+ *
+ * Note that we assume success is the common case, and we optimize the
+ * branch fall-through case on success.
+ *
+ * On Entry:
+ *     <aa>    register containing memory address
+ *     <as>    register containing memory size
+ *     <at>    temp register
+ *     <sp>
+ *     <error> label to branch to on error; implies fall-through
+ *             macro on success
+ * On Exit:
+ *     <aa>    preserved
+ *     <as>    preserved
+ *     <at>    destroyed
+ */
+       .macro  access_ok  aa, as, at, sp, error
+       kernel_ok  \at, \sp, .Laccess_ok_\@
+       user_ok    \aa, \as, \at, \error
+.Laccess_ok_\@:
+       .endm
+
+/*
+ * verify_area determines whether a memory access is allowed.  It's
+ * mostly an unnecessary wrapper for access_ok, but we provide it as a
+ * duplicate of the verify_area() C inline function below.  See the
+ * equivalent C version below for clarity.
+ *
+ * On error, verify_area branches to a label indicated by parameter
+ * <error>.  This implies that the macro falls through to the next
+ * instruction on success.
+ *
+ * Note that we assume success is the common case, and we optimize the
+ * branch fall-through case on success.
+ *
+ * On Entry:
+ *     <aa>    register containing memory address
+ *     <as>    register containing memory size
+ *     <at>    temp register
+ *     <error> label to branch to on error; implies fall-through
+ *             macro on success
+ * On Exit:
+ *     <aa>    preserved
+ *     <as>    preserved
+ *     <at>    destroyed
+ */
+       .macro  verify_area     aa, as, at, sp, error
+       access_ok  \at, \aa, \as, \sp, \error
+       .endm
+
+
+#else /* __ASSEMBLY__ not defined */
+
+#include <linux/sched.h>
+#include <asm/types.h>
+
+/*
+ * The fs value determines whether argument validity checking should
+ * be performed or not.  If get_fs() == USER_DS, checking is
+ * performed, with get_fs() == KERNEL_DS, checking is bypassed.
+ *
+ * For historical reasons (Data Segment Register?), these macros are
+ * grossly misnamed.
+ */
+
+#define KERNEL_DS      ((mm_segment_t) { 0 })
+#define USER_DS                ((mm_segment_t) { 1 })
+
+#define get_ds()       (KERNEL_DS)
+#define get_fs()       (current->thread.current_ds)
+#define set_fs(val)    (current->thread.current_ds = (val))
+
+#define segment_eq(a,b)        ((a).seg == (b).seg)
+
+#define __kernel_ok (segment_eq(get_fs(), KERNEL_DS))
+#define __user_ok(addr,size) (((size) <= TASK_SIZE)&&((addr) <= TASK_SIZE-(size)))
+#define __access_ok(addr,size) (__kernel_ok || __user_ok((addr),(size)))
+#define access_ok(type,addr,size) __access_ok((unsigned long)(addr),(size))
+
+extern inline int verify_area(int type, const void * addr, unsigned long size)
+{
+       return access_ok(type,addr,size) ? 0 : -EFAULT;
+}
+
+/*
+ * These are the main single-value transfer routines.  They
+ * automatically use the right size if we just have the right pointer
+ * type.
+ *
+ * This gets kind of ugly. We want to return _two_ values in
+ * "get_user()" and yet we don't want to do any pointers, because that
+ * is too much of a performance impact. Thus we have a few rather ugly
+ * macros here, and hide all the uglyness from the user.
+ *
+ * Careful to not
+ * (a) re-use the arguments for side effects (sizeof is ok)
+ * (b) require any knowledge of processes at this stage
+ */
+#define put_user(x,ptr)        __put_user_check((x),(ptr),sizeof(*(ptr)))
+#define get_user(x,ptr) __get_user_check((x),(ptr),sizeof(*(ptr)))
+
+/*
+ * The "__xxx" versions 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).
+ */
+#define __put_user(x,ptr) __put_user_nocheck((x),(ptr),sizeof(*(ptr)))
+#define __get_user(x,ptr) __get_user_nocheck((x),(ptr),sizeof(*(ptr)))
+
+
+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,1,"s8i");  break;  \
+        case 2: __put_user_asm(x,ptr,retval,2,"s16i"); break;   \
+        case 4: __put_user_asm(x,ptr,retval,4,"s32i"); break;   \
+        case 8: {                                              \
+                    __typeof__(*ptr) __v64 = x;                \
+                    retval = __copy_to_user(ptr,&__v64,8);     \
+                    break;                                     \
+               }                                               \
+       default: __put_user_bad();                              \
+       }                                                       \
+} while (0)
+
+
+/*
+ * Consider a case of a user single load/store would cause both an
+ * unaligned exception and an MMU-related exception (unaligned
+ * exceptions happen first):
+ *
+ * User code passes a bad variable ptr to a system call.
+ * Kernel tries to access the variable.
+ * Unaligned exception occurs.
+ * Unaligned exception handler tries to make aligned accesses.
+ * Double exception occurs for MMU-related cause (e.g., page not mapped).
+ * do_page_fault() thinks the fault address belongs to the kernel, not the
+ * user, and panics.
+ *
+ * The kernel currently prohibits user unaligned accesses.  We use the
+ * __check_align_* macros to check for unaligned addresses before
+ * accessing user space so we don't crash the kernel.  Both
+ * __put_user_asm and __get_user_asm use these alignment macros, so
+ * macro-specific labels such as 0f, 1f, %0, %2, and %3 must stay in
+ * sync.
+ */
+
+#define __check_align_1  ""
+
+#define __check_align_2                                \
+       "   _bbci.l %2,  0, 1f          \n"     \
+       "   movi    %0, %3              \n"     \
+       "   _j      2f                  \n"
+
+#define __check_align_4                                \
+       "   _bbsi.l %2,  0, 0f          \n"     \
+       "   _bbci.l %2,  1, 1f          \n"     \
+       "0: movi    %0, %3              \n"     \
+       "   _j      2f                  \n"
+
+
+/*
+ * 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.
+ *
+ * WARNING: If you modify this macro at all, verify that the
+ * __check_align_* macros still work.
+ */
+#define __put_user_asm(x, addr, err, align, insn) \
+   __asm__ __volatile__(                       \
+       __check_align_##align                   \
+       "1: "insn"  %1, %2, 0           \n"     \
+       "2:                             \n"     \
+       "   .section  .fixup,\"ax\"     \n"     \
+       "   .align 4                    \n"     \
+       "4:                             \n"     \
+       "   .long  2b                   \n"     \
+       "5:                             \n"     \
+       "   l32r   %2, 4b               \n"     \
+        "   movi   %0, %3              \n"     \
+        "   jx     %2                  \n"     \
+       "   .previous                   \n"     \
+       "   .section  __ex_table,\"a\"  \n"     \
+       "   .long       1b, 5b          \n"     \
+       "   .previous"                          \
+       :"=r" (err)                             \
+       :"r" ((int)(x)), "r" (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,1,"l8ui");  break;       \
+          case 2: __get_user_asm(x,ptr,retval,2,"l16ui"); break;       \
+          case 4: __get_user_asm(x,ptr,retval,4,"l32i");  break;       \
+          case 8: retval = __copy_from_user(&x,ptr,8);    break;       \
+          default: (x) = __get_user_bad();                             \
+        }                                                              \
+} while (0)
+
+
+/*
+ * WARNING: If you modify this macro at all, verify that the
+ * __check_align_* macros still work.
+ */
+#define __get_user_asm(x, addr, err, align, insn) \
+   __asm__ __volatile__(                       \
+       __check_align_##align                   \
+       "1: "insn"  %1, %2, 0           \n"     \
+       "2:                             \n"     \
+       "   .section  .fixup,\"ax\"     \n"     \
+       "   .align 4                    \n"     \
+       "4:                             \n"     \
+       "   .long  2b                   \n"     \
+       "5:                             \n"     \
+       "   l32r   %2, 4b               \n"     \
+       "   movi   %1, 0                \n"     \
+        "   movi   %0, %3              \n"     \
+        "   jx     %2                  \n"     \
+       "   .previous                   \n"     \
+       "   .section  __ex_table,\"a\"  \n"     \
+       "   .long       1b, 5b          \n"     \
+       "   .previous"                          \
+       :"=r" (err), "=r" (x)                   \
+       :"r" (addr), "i" (-EFAULT), "0" (err))
+
+
+/*
+ * Copy to/from user space
+ */
+
+/*
+ * We use a generic, arbitrary-sized copy subroutine.  The Xtensa
+ * architecture would cause heavy code bloat if we tried to inline
+ * these functions and provide __constant_copy_* equivalents like the
+ * i386 versions.  __xtensa_copy_user is quite efficient.  See the
+ * .fixup section of __xtensa_copy_user for a discussion on the
+ * X_zeroing equivalents for Xtensa.
+ */
+
+extern unsigned __xtensa_copy_user(void *to, const void *from, unsigned n);
+#define __copy_user(to,from,size) __xtensa_copy_user(to,from,size)
+
+
+static inline unsigned long
+__generic_copy_from_user_nocheck(void *to, const void *from, unsigned long n)
+{
+       return __copy_user(to,from,n);
+}
+
+static inline unsigned long
+__generic_copy_to_user_nocheck(void *to, const void *from, unsigned long n)
+{
+       return __copy_user(to,from,n);
+}
+
+static inline unsigned long
+__generic_copy_to_user(void *to, const void *from, unsigned long n)
+{
+       prefetch(from);
+       if (access_ok(VERIFY_WRITE, to, n))
+               return __copy_user(to,from,n);
+       return n;
+}
+
+static inline unsigned long
+__generic_copy_from_user(void *to, const void *from, unsigned long n)
+{
+       prefetchw(to);
+       if (access_ok(VERIFY_READ, from, n))
+               return __copy_user(to,from,n);
+       else
+               memset(to, 0, n);
+       return n;
+}
+
+#define copy_to_user(to,from,n) __generic_copy_to_user((to),(from),(n))
+#define copy_from_user(to,from,n) __generic_copy_from_user((to),(from),(n))
+#define __copy_to_user(to,from,n) __generic_copy_to_user_nocheck((to),(from),(n))
+#define __copy_from_user(to,from,n) __generic_copy_from_user_nocheck((to),(from),(n))
+#define __copy_to_user_inatomic __copy_to_user
+#define __copy_from_user_inatomic __copy_from_user
+
+
+/*
+ * We need to return the number of bytes not cleared.  Our memset()
+ * returns zero if a problem occurs while accessing user-space memory.
+ * In that event, return no memory cleared.  Otherwise, zero for
+ * success.
+ */
+
+extern inline unsigned long
+__xtensa_clear_user(void *addr, unsigned long size)
+{
+       if ( ! memset(addr, 0, size) )
+               return size;
+       return 0;
+}
+
+extern inline unsigned long
+clear_user(void *addr, unsigned long size)
+{
+       if (access_ok(VERIFY_WRITE, addr, size))
+               return __xtensa_clear_user(addr, size);
+       return size ? -EFAULT : 0;
+}
+
+#define __clear_user  __xtensa_clear_user
+
+
+extern long __strncpy_user(char *, const char *, long);
+#define __strncpy_from_user __strncpy_user
+
+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;
+}
+
+
+#define strlen_user(str) strnlen_user((str), TASK_SIZE - 1)
+
+/*
+ * Return the size of a string (including the ending 0!)
+ */
+extern long __strnlen_user(const char *, long);
+
+extern inline long strnlen_user(const char *str, long len)
+{
+       unsigned long top = __kernel_ok ? ~0UL : TASK_SIZE - 1;
+
+       if ((unsigned long)str > top)
+               return 0;
+       return __strnlen_user(str, len);
+}
+
+
+struct exception_table_entry
+{
+       unsigned long insn, fixup;
+};
+
+/* Returns 0 if exception not found and fixup.unit otherwise.  */
+
+extern unsigned long search_exception_table(unsigned long addr);
+extern void sort_exception_table(void);
+
+/* Returns the new pc */
+#define fixup_exception(map_reg, fixup_unit, pc)                \
+({                                                              \
+       fixup_unit;                                             \
+})
+
+#endif /* __ASSEMBLY__ */
+#endif /* _XTENSA_UACCESS_H */
diff --git a/include/asm-xtensa/ucontext.h b/include/asm-xtensa/ucontext.h
new file mode 100644 (file)
index 0000000..94c94ed
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ * include/asm-xtensa/ucontext.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_UCONTEXT_H
+#define _XTENSA_UCONTEXT_H
+
+struct ucontext {
+       unsigned long     uc_flags;
+       struct ucontext  *uc_link;
+       stack_t           uc_stack;
+       struct sigcontext uc_mcontext;
+       sigset_t          uc_sigmask;   /* mask last for extensibility */
+};
+
+#endif /* _XTENSA_UCONTEXT_H */
diff --git a/include/asm-xtensa/unaligned.h b/include/asm-xtensa/unaligned.h
new file mode 100644 (file)
index 0000000..2822089
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * include/asm-xtensa/unaligned.h
+ *
+ * Xtensa doesn't handle unaligned accesses efficiently.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_UNALIGNED_H
+#define _XTENSA_UNALIGNED_H
+
+#include <linux/string.h>
+
+/* Use memmove here, so gcc does not insert a __builtin_memcpy. */
+
+#define get_unaligned(ptr) \
+  ({ __typeof__(*(ptr)) __tmp; memmove(&__tmp, (ptr), sizeof(*(ptr))); __tmp; })
+
+#define put_unaligned(val, ptr)                                \
+  ({ __typeof__(*(ptr)) __tmp = (val);                 \
+     memmove((ptr), &__tmp, sizeof(*(ptr)));           \
+     (void)0; })
+
+#endif /* _XTENSA_UNALIGNED_H */
diff --git a/include/asm-xtensa/unistd.h b/include/asm-xtensa/unistd.h
new file mode 100644 (file)
index 0000000..64c64dd
--- /dev/null
@@ -0,0 +1,537 @@
+/*
+ * include/asm-xtensa/unistd.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_UNISTD_H
+#define _XTENSA_UNISTD_H
+
+#include <linux/linkage.h>
+
+//#define __NR_setup             0 /* used only by init, to get system going */
+#define __NR_spill               0
+#define __NR_exit                1
+#define __NR_fork                2
+#define __NR_read                3
+#define __NR_write               4
+#define __NR_open                5
+#define __NR_close               6
+#define __NR_waitpid             7
+#define __NR_creat               8
+#define __NR_link                9
+#define __NR_unlink             10
+#define __NR_execve             11
+#define __NR_chdir              12
+#define __NR_time               13
+#define __NR_mknod              14
+#define __NR_chmod              15
+#define __NR_lchown             16
+#define __NR_break              17
+#define __NR_oldstat            18
+#define __NR_lseek              19
+#define __NR_getpid             20
+#define __NR_mount              21
+#define __NR_oldumount          22
+#define __NR_setuid             23
+#define __NR_getuid             24
+#define __NR_stime              25
+#define __NR_ptrace             26
+#define __NR_alarm              27
+#define __NR_oldfstat           28
+#define __NR_pause              29
+#define __NR_utime              30
+#define __NR_stty               31
+#define __NR_gtty               32
+#define __NR_access             33
+#define __NR_nice               34
+#define __NR_ftime              35
+#define __NR_sync               36
+#define __NR_kill               37
+#define __NR_rename             38
+#define __NR_mkdir              39
+#define __NR_rmdir              40
+#define __NR_dup                41
+#define __NR_pipe               42
+#define __NR_times              43
+#define __NR_prof               44
+#define __NR_brk                45
+#define __NR_setgid             46
+#define __NR_getgid             47
+#define __NR_signal             48
+#define __NR_geteuid            49
+#define __NR_getegid            50
+#define __NR_acct               51
+#define __NR_umount             52
+#define __NR_lock               53
+#define __NR_ioctl              54
+#define __NR_fcntl              55
+#define __NR_mpx                56
+#define __NR_setpgid            57
+#define __NR_ulimit             58
+#define __NR_oldolduname        59
+#define __NR_umask              60
+#define __NR_chroot             61
+#define __NR_ustat              62
+#define __NR_dup2               63
+#define __NR_getppid            64
+#define __NR_getpgrp            65
+#define __NR_setsid             66
+#define __NR_sigaction          67
+#define __NR_sgetmask           68
+#define __NR_ssetmask           69
+#define __NR_setreuid           70
+#define __NR_setregid           71
+#define __NR_sigsuspend                 72
+#define __NR_sigpending                 73
+#define __NR_sethostname        74
+#define __NR_setrlimit          75
+#define __NR_getrlimit          76     /* Back compatible 2Gig limited rlimit */
+#define __NR_getrusage          77
+#define __NR_gettimeofday       78
+#define __NR_settimeofday       79
+#define __NR_getgroups          80
+#define __NR_setgroups          81
+#define __NR_select             82
+#define __NR_symlink            83
+#define __NR_oldlstat           84
+#define __NR_readlink           85
+#define __NR_uselib             86
+#define __NR_swapon             87
+#define __NR_reboot             88
+#define __NR_readdir            89
+#define __NR_mmap               90
+#define __NR_munmap             91
+#define __NR_truncate           92
+#define __NR_ftruncate          93
+#define __NR_fchmod             94
+#define __NR_fchown             95
+#define __NR_getpriority        96
+#define __NR_setpriority        97
+#define __NR_profil             98
+#define __NR_statfs             99
+#define __NR_fstatfs           100
+#define __NR_ioperm            101
+#define __NR_socketcall                102
+#define __NR_syslog            103
+#define __NR_setitimer         104
+#define __NR_getitimer         105
+#define __NR_stat              106
+#define __NR_lstat             107
+#define __NR_fstat             108
+#define __NR_olduname          109
+#define __NR_iopl              110
+#define __NR_vhangup           111
+#define __NR_idle              112
+#define __NR_vm86              113
+#define __NR_wait4             114
+#define __NR_swapoff           115
+#define __NR_sysinfo           116
+#define __NR_ipc               117
+#define __NR_fsync             118
+#define __NR_sigreturn         119
+#define __NR_clone             120
+#define __NR_setdomainname     121
+#define __NR_uname             122
+#define __NR_modify_ldt                123
+#define __NR_adjtimex          124
+#define __NR_mprotect          125
+#define __NR_sigprocmask       126
+#define __NR_create_module     127
+#define __NR_init_module       128
+#define __NR_delete_module     129
+#define __NR_get_kernel_syms   130
+#define __NR_quotactl          131
+#define __NR_getpgid           132
+#define __NR_fchdir            133
+#define __NR_bdflush           134
+#define __NR_sysfs             135
+#define __NR_personality       136
+#define __NR_afs_syscall       137 /* Syscall for Andrew File System */
+#define __NR_setfsuid          138
+#define __NR_setfsgid          139
+#define __NR__llseek           140
+#define __NR_getdents          141
+#define __NR__newselect                142
+#define __NR_flock             143
+#define __NR_msync             144
+#define __NR_readv             145
+#define __NR_writev            146
+#define __NR_cacheflush         147
+#define __NR_cachectl           148
+#define __NR_sysxtensa          149
+#define __NR_sysdummy           150
+#define __NR_getsid            151
+#define __NR_fdatasync         152
+#define __NR__sysctl           153
+#define __NR_mlock             154
+#define __NR_munlock           155
+#define __NR_mlockall          156
+#define __NR_munlockall                157
+#define __NR_sched_setparam            158
+#define __NR_sched_getparam            159
+#define __NR_sched_setscheduler                160
+#define __NR_sched_getscheduler                161
+#define __NR_sched_yield               162
+#define __NR_sched_get_priority_max    163
+#define __NR_sched_get_priority_min    164
+#define __NR_sched_rr_get_interval     165
+#define __NR_nanosleep         166
+#define __NR_mremap            167
+#define __NR_accept             168
+#define __NR_bind               169
+#define __NR_connect            170
+#define __NR_getpeername        171
+#define __NR_getsockname        172
+#define __NR_getsockopt         173
+#define __NR_listen             174
+#define __NR_recv               175
+#define __NR_recvfrom           176
+#define __NR_recvmsg            177
+#define __NR_send               178
+#define __NR_sendmsg            179
+#define __NR_sendto             180
+#define __NR_setsockopt         181
+#define __NR_shutdown           182
+#define __NR_socket             183
+#define __NR_socketpair         184
+#define __NR_setresuid         185
+#define __NR_getresuid         186
+#define __NR_query_module      187
+#define __NR_poll              188
+#define __NR_nfsservctl                189
+#define __NR_setresgid         190
+#define __NR_getresgid         191
+#define __NR_prctl              192
+#define __NR_rt_sigreturn      193
+#define __NR_rt_sigaction      194
+#define __NR_rt_sigprocmask    195
+#define __NR_rt_sigpending     196
+#define __NR_rt_sigtimedwait   197
+#define __NR_rt_sigqueueinfo   198
+#define __NR_rt_sigsuspend     199
+#define __NR_pread             200
+#define __NR_pwrite            201
+#define __NR_chown             202
+#define __NR_getcwd            203
+#define __NR_capget            204
+#define __NR_capset            205
+#define __NR_sigaltstack       206
+#define __NR_sendfile          207
+#define __NR_streams1          208     /* some people actually want it */
+#define __NR_streams2          209     /* some people actually want it */
+#define __NR_mmap2             210
+#define __NR_truncate64                211
+#define __NR_ftruncate64       212
+#define __NR_stat64            213
+#define __NR_lstat64           214
+#define __NR_fstat64           215
+#define __NR_pivot_root                216
+#define __NR_mincore           217
+#define __NR_madvise           218
+#define __NR_getdents64                219
+#define __NR_vfork             220
+
+/* Keep this last; should always equal the last valid call number. */
+#define __NR_Linux_syscalls     220
+
+/* user-visible error numbers are in the range -1 - -125: see
+ * <asm-xtensa/errno.h> */
+
+#define SYSXTENSA_RESERVED        0    /* don't use this */
+#define SYSXTENSA_ATOMIC_SET      1    /* set variable */
+#define SYSXTENSA_ATOMIC_EXG_ADD   2   /* exchange memory and add */
+#define SYSXTENSA_ATOMIC_ADD      3    /* add to memory */
+#define SYSXTENSA_ATOMIC_CMP_SWP   4   /* compare and swap */
+
+#define SYSXTENSA_COUNT                   5    /* count of syscall0 functions*/
+
+#ifdef __KERNEL__
+#define __syscall_return(type, res) return ((type)(res))
+#else
+#define __syscall_return(type, res) \
+do { \
+       if ((unsigned long)(res) >= (unsigned long)(-125)) { \
+       /* Avoid using "res" which is declared to be in register r2; \
+        * errno might expand to a function call and clobber it.  */ \
+               int __err = -(res); \
+               errno = __err; \
+               res = -1; \
+       } \
+       return (type) (res); \
+} while (0)
+#endif
+
+
+/* Tensilica's xt-xcc compiler is much more agressive at code
+ * optimization than gcc.  Multiple __asm__ statements are
+ * insufficient for xt-xcc because subsequent optimization passes
+ * (beyond the front-end that knows of __asm__ statements and other
+ * such GNU Extensions to C) can modify the register selection for
+ * containment of C variables.
+ *
+ * xt-xcc cannot modify the contents of a single __asm__ statement, so
+ * we create single-asm versions of the syscall macros that are
+ * suitable and optimal for both xt-xcc and gcc.
+ *
+ * Linux takes system-call arguments in registers.  The following
+ * design is optimized for user-land apps (e.g., glibc) which
+ * typically have a function wrapper around the "syscall" assembly
+ * instruction.  It satisfies the Xtensa ABI while minizing argument
+ * shifting.
+ *
+ * The Xtensa ABI and software conventions require the system-call
+ * number in a2.  If an argument exists in a2, we move it to the next
+ * available register.  Note that for improved efficiency, we do NOT
+ * shift all parameters down one register to maintain the original
+ * order.
+ *
+ * At best case (zero arguments), we just write the syscall number to
+ * a2.  At worst case (1 to 6 arguments), we move the argument in a2
+ * to the next available register, then write the syscall number to
+ * a2.
+ *
+ * For clarity, the following truth table enumerates all possibilities.
+ *
+ * arguments   syscall number  arg0, arg1, arg2, arg3, arg4, arg5
+ * ---------   --------------  ----------------------------------
+ *     0             a2
+ *     1             a2        a3
+ *     2             a2        a4,   a3
+ *     3             a2        a5,   a3,   a4
+ *     4             a2        a6,   a3,   a4,   a5
+ *     5             a2        a7,   a3,   a4,   a5,   a6
+ *     6             a2        a8,   a3,   a4,   a5,   a6,   a7
+ */
+
+#define _syscall0(type,name) \
+type name(void) \
+{ \
+long __res; \
+__asm__ __volatile__ ( \
+       "  movi  a2, %1 \n" \
+       "  syscall      \n" \
+       "  mov   %0, a2 \n" \
+       : "=a" (__res) \
+       : "i" (__NR_##name) \
+       : "a2" \
+       ); \
+__syscall_return(type,__res); \
+}
+
+#define _syscall1(type,name,type0,arg0) \
+type name(type0 arg0) \
+{ \
+long __res; \
+__asm__ __volatile__ ( \
+       "  mov   a3, %2 \n" \
+       "  movi  a2, %1 \n" \
+       "  syscall      \n" \
+       "  mov   %0, a2 \n" \
+       : "=a" (__res) \
+       : "i" (__NR_##name), "a" (arg0) \
+       : "a2", "a3" \
+       ); \
+__syscall_return(type,__res); \
+}
+
+#define _syscall2(type,name,type0,arg0,type1,arg1) \
+type name(type0 arg0,type1 arg1) \
+{ \
+long __res; \
+__asm__ __volatile__ ( \
+       "  mov   a4, %2 \n" \
+       "  mov   a3, %3 \n" \
+       "  movi  a2, %1 \n" \
+       "  syscall      \n" \
+       "  mov   %0, a2 \n" \
+       : "=a" (__res) \
+       : "i" (__NR_##name), "a" (arg0), "a" (arg1) \
+       : "a2", "a3", "a4" \
+       ); \
+__syscall_return(type,__res); \
+}
+
+#define _syscall3(type,name,type0,arg0,type1,arg1,type2,arg2) \
+type name(type0 arg0,type1 arg1,type2 arg2) \
+{ \
+long __res; \
+__asm__ __volatile__ ( \
+       "  mov   a5, %2 \n" \
+       "  mov   a4, %4 \n" \
+       "  mov   a3, %3 \n" \
+       "  movi  a2, %1 \n" \
+       "  syscall      \n" \
+       "  mov   %0, a2 \n" \
+       : "=a" (__res) \
+       : "i" (__NR_##name), "a" (arg0), "a" (arg1), "a" (arg2) \
+       : "a2", "a3", "a4", "a5" \
+       ); \
+__syscall_return(type,__res); \
+}
+
+#define _syscall4(type,name,type0,arg0,type1,arg1,type2,arg2,type3,arg3) \
+type name(type0 arg0,type1 arg1,type2 arg2,type3 arg3) \
+{ \
+long __res; \
+__asm__ __volatile__ ( \
+       "  mov   a6, %2 \n" \
+       "  mov   a5, %5 \n" \
+       "  mov   a4, %4 \n" \
+       "  mov   a3, %3 \n" \
+       "  movi  a2, %1 \n" \
+       "  syscall      \n" \
+       "  mov   %0, a2 \n" \
+       : "=a" (__res) \
+       : "i" (__NR_##name), "a" (arg0), "a" (arg1), "a" (arg2), "a" (arg3) \
+       : "a2", "a3", "a4", "a5", "a6" \
+       ); \
+__syscall_return(type,__res); \
+}
+
+/* Note that we save and restore the a7 frame pointer.
+ * Including a7 in the clobber list doesn't do what you'd expect.
+ */
+#define _syscall5(type,name,type0,arg0,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
+type name(type0 arg0,type1 arg1,type2 arg2,type3 arg3,type4 arg4) \
+{ \
+long __res; \
+__asm__ __volatile__ ( \
+       "  mov   a9, a7 \n" \
+       "  mov   a7, %2 \n" \
+       "  mov   a6, %6 \n" \
+       "  mov   a5, %5 \n" \
+       "  mov   a4, %4 \n" \
+       "  mov   a3, %3 \n" \
+       "  movi  a2, %1 \n" \
+       "  syscall      \n" \
+       "  mov   a7, a9 \n" \
+       "  mov   %0, a2 \n" \
+       : "=a" (__res) \
+       : "i" (__NR_##name), "a" (arg0), "a" (arg1), "a" (arg2), \
+                             "a" (arg3), "a" (arg4) \
+       : "a2", "a3", "a4", "a5", "a6", "a9" \
+       ); \
+__syscall_return(type,__res); \
+}
+
+/* Note that we save and restore the a7 frame pointer.
+ * Including a7 in the clobber list doesn't do what you'd expect.
+ */
+#define _syscall6(type,name,type0,arg0,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5) \
+type name(type0 arg0,type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \
+{ \
+long __res; \
+__asm__ __volatile__ ( \
+       "  mov   a9, a7 \n" \
+       "  mov   a8, %2 \n" \
+       "  mov   a7, %7 \n" \
+       "  mov   a6, %6 \n" \
+       "  mov   a5, %5 \n" \
+       "  mov   a4, %4 \n" \
+       "  mov   a3, %3 \n" \
+       "  movi  a2, %1 \n" \
+       "  syscall      \n" \
+       "  mov   a7, a9 \n" \
+       "  mov   %0, a2 \n" \
+       : "=a" (__res) \
+       : "i" (__NR_##name), "a" (arg0), "a" (arg1), "a" (arg2), \
+                             "a" (arg3), "a" (arg4), "a" (arg5)  \
+       : "a2", "a3", "a4", "a5", "a6", "a8", "a9" \
+       ); \
+__syscall_return(type,__res); \
+}
+
+
+#ifdef __KERNEL_SYSCALLS__
+
+#include <linux/compiler.h>
+#include <linux/types.h>
+#include <linux/syscalls.h>
+
+/*
+ * 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.
+ */
+
+#define __NR__exit __NR_exit
+
+static __inline__ _syscall0(int,pause)
+//static __inline__ _syscall1(int,setup,int,magic) FIXME
+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__ _syscall3(int,read,int,fd,char *,buf,off_t,count)
+static __inline__ _syscall3(off_t,lseek,int,fd,off_t,offset,int,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__ _syscall1(int,delete_module,const char *,name)
+
+struct stat;
+static __inline__ _syscall2(int,fstat,int,fd,struct stat *,buf)
+static __inline__ _syscall0(pid_t,getpid)
+static __inline__ _syscall2(int,kill,int,pid,int,sig)
+static __inline__ _syscall2(int,stat,const char *, path,struct stat *,buf)
+static __inline__ _syscall1(int,unlink,char *,pathname)
+
+
+
+extern pid_t waitpid(int, int*, int );
+static __inline__ pid_t wait(int * wait_stat)
+{
+       return waitpid(-1,wait_stat,0);
+}
+#endif
+
+/*
+ * "Conditional" syscalls
+ *
+ * What we want is __attribute__((weak,alias("sys_ni_syscall"))),
+ * but it doesn't work on all toolchains, so we just do it by hand
+ */
+#define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall");
+
+#ifdef __KERNEL__
+#define __ARCH_WANT_IPC_PARSE_VERSION
+#define __ARCH_WANT_OLD_READDIR
+#define __ARCH_WANT_OLD_STAT
+#define __ARCH_WANT_STAT64
+#define __ARCH_WANT_SYS_ALARM
+#define __ARCH_WANT_SYS_GETHOSTNAME
+#define __ARCH_WANT_SYS_PAUSE
+#define __ARCH_WANT_SYS_SGETMASK
+#define __ARCH_WANT_SYS_SIGNAL
+#define __ARCH_WANT_SYS_TIME
+#define __ARCH_WANT_SYS_UTIME
+#define __ARCH_WANT_SYS_WAITPID
+#define __ARCH_WANT_SYS_SOCKETCALL
+#define __ARCH_WANT_SYS_FADVISE64
+#define __ARCH_WANT_SYS_GETPGRP
+#define __ARCH_WANT_SYS_LLSEEK
+#define __ARCH_WANT_SYS_NICE
+#define __ARCH_WANT_SYS_OLD_GETRLIMIT
+#define __ARCH_WANT_SYS_OLDUMOUNT
+#define __ARCH_WANT_SYS_SIGPENDING
+#define __ARCH_WANT_SYS_SIGPROCMASK
+#define __ARCH_WANT_SYS_RT_SIGACTION
+#endif
+
+
+
+#endif /* _XTENSA_UNISTD_H */
diff --git a/include/asm-xtensa/user.h b/include/asm-xtensa/user.h
new file mode 100644 (file)
index 0000000..2c3ed23
--- /dev/null
@@ -0,0 +1,20 @@
+/*
+ * include/asm-xtensa/user.h
+ *
+ * Xtensa Processor version.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_USER_H
+#define _XTENSA_USER_H
+
+/* This file usually defines a 'struct user' structure. However, it it only
+ * used for a.out file, which are not supported on Xtensa.
+ */
+
+#endif /* _XTENSA_USER_H */
diff --git a/include/asm-xtensa/vga.h b/include/asm-xtensa/vga.h
new file mode 100644 (file)
index 0000000..23d82f6
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ * include/asm-xtensa/vga.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_VGA_H
+#define _XTENSA_VGA_H
+
+#define VGA_MAP_MEM(x) (unsigned long)phys_to_virt(x)
+
+#define vga_readb(x)   (*(x))
+#define vga_writeb(x,y)        (*(y) = (x))
+
+#endif
diff --git a/include/asm-xtensa/xor.h b/include/asm-xtensa/xor.h
new file mode 100644 (file)
index 0000000..e7b1f08
--- /dev/null
@@ -0,0 +1,16 @@
+/*
+ * include/asm-xtensa/xor.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_XOR_H
+#define _XTENSA_XOR_H
+
+#include <asm-generic/xor.h>
+
+#endif