mirror of
https://github.com/torvalds/linux.git
synced 2024-11-10 22:21:40 +00:00
[PATCH] xtensa: Architecture support for Tensilica Xtensa Part 6
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>
This commit is contained in:
parent
3f65ce4d14
commit
9a8fd55899
33
include/asm-xtensa/a.out.h
Normal file
33
include/asm-xtensa/a.out.h
Normal file
@ -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 */
|
272
include/asm-xtensa/atomic.h
Normal file
272
include/asm-xtensa/atomic.h
Normal file
@ -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 */
|
||||
|
446
include/asm-xtensa/bitops.h
Normal file
446
include/asm-xtensa/bitops.h
Normal file
@ -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 */
|
61
include/asm-xtensa/bootparam.h
Normal file
61
include/asm-xtensa/bootparam.h
Normal file
@ -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
|
||||
|
||||
|
||||
|
41
include/asm-xtensa/bug.h
Normal file
41
include/asm-xtensa/bug.h
Normal file
@ -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 */
|
22
include/asm-xtensa/bugs.h
Normal file
22
include/asm-xtensa/bugs.h
Normal file
@ -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 */
|
82
include/asm-xtensa/byteorder.h
Normal file
82
include/asm-xtensa/byteorder.h
Normal file
@ -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 */
|
32
include/asm-xtensa/cache.h
Normal file
32
include/asm-xtensa/cache.h
Normal file
@ -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 */
|
122
include/asm-xtensa/cacheflush.h
Normal file
122
include/asm-xtensa/cacheflush.h
Normal file
@ -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 */
|
||||
|
264
include/asm-xtensa/checksum.h
Normal file
264
include/asm-xtensa/checksum.h
Normal file
@ -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
|
70
include/asm-xtensa/coprocessor.h
Normal file
70
include/asm-xtensa/coprocessor.h
Normal file
@ -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 */
|
16
include/asm-xtensa/cpumask.h
Normal file
16
include/asm-xtensa/cpumask.h
Normal file
@ -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 */
|
6
include/asm-xtensa/cputime.h
Normal file
6
include/asm-xtensa/cputime.h
Normal file
@ -0,0 +1,6 @@
|
||||
#ifndef _XTENSA_CPUTIME_H
|
||||
#define _XTENSA_CPUTIME_H
|
||||
|
||||
#include <asm-generic/cputime.h>
|
||||
|
||||
#endif /* _XTENSA_CPUTIME_H */
|
38
include/asm-xtensa/current.h
Normal file
38
include/asm-xtensa/current.h
Normal file
@ -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 */
|
50
include/asm-xtensa/delay.h
Normal file
50
include/asm-xtensa/delay.h
Normal file
@ -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
|
||||
|
19
include/asm-xtensa/div64.h
Normal file
19
include/asm-xtensa/div64.h
Normal file
@ -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
|
182
include/asm-xtensa/dma-mapping.h
Normal file
182
include/asm-xtensa/dma-mapping.h
Normal file
@ -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 */
|
61
include/asm-xtensa/dma.h
Normal file
61
include/asm-xtensa/dma.h
Normal file
@ -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
|
222
include/asm-xtensa/elf.h
Normal file
222
include/asm-xtensa/elf.h
Normal file
@ -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 */
|
142
include/asm-xtensa/errno.h
Normal file
142
include/asm-xtensa/errno.h
Normal file
@ -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 */
|
101
include/asm-xtensa/fcntl.h
Normal file
101
include/asm-xtensa/fcntl.h
Normal file
@ -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 */
|
252
include/asm-xtensa/fixmap.h
Normal file
252
include/asm-xtensa/fixmap.h
Normal file
@ -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 */
|
||||
|
||||
|
||||
|
||||
|
||||
|
28
include/asm-xtensa/hardirq.h
Normal file
28
include/asm-xtensa/hardirq.h
Normal file
@ -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 */
|
17
include/asm-xtensa/hdreg.h
Normal file
17
include/asm-xtensa/hdreg.h
Normal file
@ -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
|
17
include/asm-xtensa/highmem.h
Normal file
17
include/asm-xtensa/highmem.h
Normal file
@ -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
|
||||
|
18
include/asm-xtensa/hw_irq.h
Normal file
18
include/asm-xtensa/hw_irq.h
Normal file
@ -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
|
36
include/asm-xtensa/ide.h
Normal file
36
include/asm-xtensa/ide.h
Normal file
@ -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 */
|
197
include/asm-xtensa/io.h
Normal file
197
include/asm-xtensa/io.h
Normal file
@ -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 */
|
83
include/asm-xtensa/ioctl.h
Normal file
83
include/asm-xtensa/ioctl.h
Normal file
@ -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
|
112
include/asm-xtensa/ioctls.h
Normal file
112
include/asm-xtensa/ioctls.h
Normal file
@ -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 */
|
34
include/asm-xtensa/ipc.h
Normal file
34
include/asm-xtensa/ipc.h
Normal file
@ -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 */
|
37
include/asm-xtensa/ipcbuf.h
Normal file
37
include/asm-xtensa/ipcbuf.h
Normal file
@ -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 */
|
37
include/asm-xtensa/irq.h
Normal file
37
include/asm-xtensa/irq.h
Normal file
@ -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 */
|
31
include/asm-xtensa/kmap_types.h
Normal file
31
include/asm-xtensa/kmap_types.h
Normal file
@ -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 */
|
16
include/asm-xtensa/linkage.h
Normal file
16
include/asm-xtensa/linkage.h
Normal file
@ -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 */
|
16
include/asm-xtensa/local.h
Normal file
16
include/asm-xtensa/local.h
Normal file
@ -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 */
|
80
include/asm-xtensa/mman.h
Normal file
80
include/asm-xtensa/mman.h
Normal file
@ -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 */
|
17
include/asm-xtensa/mmu.h
Normal file
17
include/asm-xtensa/mmu.h
Normal file
@ -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 */
|
330
include/asm-xtensa/mmu_context.h
Normal file
330
include/asm-xtensa/mmu_context.h
Normal file
@ -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 */
|
25
include/asm-xtensa/module.h
Normal file
25
include/asm-xtensa/module.h
Normal file
@ -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 */
|
48
include/asm-xtensa/msgbuf.h
Normal file
48
include/asm-xtensa/msgbuf.h
Normal file
@ -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 */
|
26
include/asm-xtensa/namei.h
Normal file
26
include/asm-xtensa/namei.h
Normal file
@ -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 */
|
133
include/asm-xtensa/page.h
Normal file
133
include/asm-xtensa/page.h
Normal file
@ -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 */
|
135
include/asm-xtensa/page.h.n
Normal file
135
include/asm-xtensa/page.h.n
Normal file
@ -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 */
|
34
include/asm-xtensa/param.h
Normal file
34
include/asm-xtensa/param.h
Normal file
@ -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 */
|
88
include/asm-xtensa/pci-bridge.h
Normal file
88
include/asm-xtensa/pci-bridge.h
Normal file
@ -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 */
|
89
include/asm-xtensa/pci.h
Normal file
89
include/asm-xtensa/pci.h
Normal file
@ -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 */
|
16
include/asm-xtensa/percpu.h
Normal file
16
include/asm-xtensa/percpu.h
Normal file
@ -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__ */
|
116
include/asm-xtensa/pgalloc.h
Normal file
116
include/asm-xtensa/pgalloc.h
Normal file
@ -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 */
|
468
include/asm-xtensa/pgtable.h
Normal file
468
include/asm-xtensa/pgtable.h
Normal file
@ -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 */
|
37
include/asm-xtensa/poll.h
Normal file
37
include/asm-xtensa/poll.h
Normal file
@ -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 */
|
123
include/asm-xtensa/posix_types.h
Normal file
123
include/asm-xtensa/posix_types.h
Normal file
@ -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 */
|
205
include/asm-xtensa/processor.h
Normal file
205
include/asm-xtensa/processor.h
Normal file
@ -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 */
|
135
include/asm-xtensa/ptrace.h
Normal file
135
include/asm-xtensa/ptrace.h
Normal file
@ -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 */
|
16
include/asm-xtensa/resource.h
Normal file
16
include/asm-xtensa/resource.h
Normal file
@ -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 */
|
16
include/asm-xtensa/rmap.h
Normal file
16
include/asm-xtensa/rmap.h
Normal file
@ -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
|
175
include/asm-xtensa/rwsem.h
Normal file
175
include/asm-xtensa/rwsem.h
Normal file
@ -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 */
|
34
include/asm-xtensa/scatterlist.h
Normal file
34
include/asm-xtensa/scatterlist.h
Normal file
@ -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 */
|
16
include/asm-xtensa/sections.h
Normal file
16
include/asm-xtensa/sections.h
Normal file
@ -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 */
|
16
include/asm-xtensa/segment.h
Normal file
16
include/asm-xtensa/segment.h
Normal file
@ -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 */
|
129
include/asm-xtensa/semaphore.h
Normal file
129
include/asm-xtensa/semaphore.h
Normal file
@ -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 */
|
44
include/asm-xtensa/sembuf.h
Normal file
44
include/asm-xtensa/sembuf.h
Normal file
@ -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 */
|
18
include/asm-xtensa/serial.h
Normal file
18
include/asm-xtensa/serial.h
Normal file
@ -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 */
|
16
include/asm-xtensa/setup.h
Normal file
16
include/asm-xtensa/setup.h
Normal file
@ -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
|
50
include/asm-xtensa/shmbuf.h
Normal file
50
include/asm-xtensa/shmbuf.h
Normal file
@ -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 */
|
23
include/asm-xtensa/shmparam.h
Normal file
23
include/asm-xtensa/shmparam.h
Normal file
@ -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 */
|
44
include/asm-xtensa/sigcontext.h
Normal file
44
include/asm-xtensa/sigcontext.h
Normal file
@ -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 */
|
16
include/asm-xtensa/siginfo.h
Normal file
16
include/asm-xtensa/siginfo.h
Normal file
@ -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 */
|
187
include/asm-xtensa/signal.h
Normal file
187
include/asm-xtensa/signal.h
Normal file
@ -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 */
|
27
include/asm-xtensa/smp.h
Normal file
27
include/asm-xtensa/smp.h
Normal file
@ -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 */
|
61
include/asm-xtensa/socket.h
Normal file
61
include/asm-xtensa/socket.h
Normal file
@ -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 */
|
30
include/asm-xtensa/sockios.h
Normal file
30
include/asm-xtensa/sockios.h
Normal file
@ -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 */
|
16
include/asm-xtensa/spinlock.h
Normal file
16
include/asm-xtensa/spinlock.h
Normal file
@ -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 */
|
105
include/asm-xtensa/stat.h
Normal file
105
include/asm-xtensa/stat.h
Normal file
@ -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 */
|
17
include/asm-xtensa/statfs.h
Normal file
17
include/asm-xtensa/statfs.h
Normal file
@ -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 */
|
||||
|
124
include/asm-xtensa/string.h
Normal file
124
include/asm-xtensa/string.h
Normal file
@ -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 */
|
252
include/asm-xtensa/system.h
Normal file
252
include/asm-xtensa/system.h
Normal file
@ -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 */
|
194
include/asm-xtensa/termbits.h
Normal file
194
include/asm-xtensa/termbits.h
Normal file
@ -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 */
|
122
include/asm-xtensa/termios.h
Normal file
122
include/asm-xtensa/termios.h
Normal file
@ -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 */
|
146
include/asm-xtensa/thread_info.h
Normal file
146
include/asm-xtensa/thread_info.h
Normal file
@ -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 */
|
94
include/asm-xtensa/timex.h
Normal file
94
include/asm-xtensa/timex.h
Normal file
@ -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 */
|
25
include/asm-xtensa/tlb.h
Normal file
25
include/asm-xtensa/tlb.h
Normal file
@ -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 */
|
200
include/asm-xtensa/tlbflush.h
Normal file
200
include/asm-xtensa/tlbflush.h
Normal file
@ -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 */
|
16
include/asm-xtensa/topology.h
Normal file
16
include/asm-xtensa/topology.h
Normal file
@ -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 */
|
66
include/asm-xtensa/types.h
Normal file
66
include/asm-xtensa/types.h
Normal file
@ -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 */
|
532
include/asm-xtensa/uaccess.h
Normal file
532
include/asm-xtensa/uaccess.h
Normal file
@ -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 */
|
22
include/asm-xtensa/ucontext.h
Normal file
22
include/asm-xtensa/ucontext.h
Normal file
@ -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 */
|
28
include/asm-xtensa/unaligned.h
Normal file
28
include/asm-xtensa/unaligned.h
Normal file
@ -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 */
|
537
include/asm-xtensa/unistd.h
Normal file
537
include/asm-xtensa/unistd.h
Normal file
@ -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 */
|
20
include/asm-xtensa/user.h
Normal file
20
include/asm-xtensa/user.h
Normal file
@ -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 */
|
19
include/asm-xtensa/vga.h
Normal file
19
include/asm-xtensa/vga.h
Normal file
@ -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
|
16
include/asm-xtensa/xor.h
Normal file
16
include/asm-xtensa/xor.h
Normal file
@ -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
|
Loading…
Reference in New Issue
Block a user