sparc: join the remaining header files
With this commit all sparc64 header files are moved to asm-sparc. The remaining files (71 files) were too different to be trivially merged so divide them up in a _32.h and a _64.h file which are both included from the file with no bit size. The following script were used: cd include FILES=`wc -l asm-sparc64/*h | grep -v '^ 1' | cut -b 20-` for FILE in ${FILES}; do echo $FILE: BASE=`echo $FILE | cut -d '.' -f 1` FN32=${BASE}_32.h FN64=${BASE}_64.h GUARD=___ASM_SPARC_`echo $BASE | tr '-' '_' | tr [:lower:] [:upper:]`_H git mv asm-sparc/$FILE asm-sparc/$FN32 git mv asm-sparc64/$FILE asm-sparc/$FN64 echo git mv done printf "#ifndef %s\n" $GUARD > asm-sparc/$FILE printf "#define %s\n" $GUARD >> asm-sparc/$FILE printf "#if defined(__sparc__) && defined(__arch64__)\n" >> asm-sparc/$FILE printf "#include <asm-sparc/%s>\n" $FN64 >> asm-sparc/$FILE printf "#else\n" >> asm-sparc/$FILE printf "#include <asm-sparc/%s>\n" $FN32 >> asm-sparc/$FILE printf "#endif\n" >> asm-sparc/$FILE printf "#endif\n" >> asm-sparc/$FILE git add asm-sparc/$FILE echo new file done printf "#include <asm-sparc/%s>\n" $FILE > asm-sparc64/$FILE git add asm-sparc64/$FILE echo sparc64 file done done The guard contains three '_' to avoid conflict with existing guards. In additing the two Kbuild files are emptied to avoid breaking headers_* targets. We will reintroduce the exported header files when the necessary kbuild changes are merged. Signed-off-by: Sam Ravnborg <sam@ravnborg.org> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
5e3609f60c
commit
f5e706ad88
254 changed files with 17513 additions and 16987 deletions
|
@ -1,22 +1 @@
|
|||
include include/asm-generic/Kbuild.asm
|
||||
|
||||
header-y += apc.h
|
||||
header-y += asi.h
|
||||
header-y += bpp.h
|
||||
header-y += display7seg.h
|
||||
header-y += envctrl.h
|
||||
header-y += jsflash.h
|
||||
header-y += openprom.h
|
||||
header-y += openpromio.h
|
||||
header-y += psrcompat.h
|
||||
header-y += pstate.h
|
||||
header-y += reg.h
|
||||
header-y += traps.h
|
||||
header-y += uctx.h
|
||||
header-y += utrap.h
|
||||
header-y += vfc_ioctls.h
|
||||
header-y += watchdog.h
|
||||
|
||||
unifdef-y += fbio.h
|
||||
unifdef-y += perfctr.h
|
||||
unifdef-y += psr.h
|
||||
# dummy file to avoid breaking make headers_install
|
||||
|
|
|
@ -1,165 +1,8 @@
|
|||
/* atomic.h: These still suck, but the I-cache hit rate is higher.
|
||||
*
|
||||
* Copyright (C) 1996 David S. Miller (davem@davemloft.net)
|
||||
* Copyright (C) 2000 Anton Blanchard (anton@linuxcare.com.au)
|
||||
* Copyright (C) 2007 Kyle McMartin (kyle@parisc-linux.org)
|
||||
*
|
||||
* Additions by Keith M Wesolowski (wesolows@foobazco.org) based
|
||||
* on asm-parisc/atomic.h Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org>.
|
||||
*/
|
||||
|
||||
#ifndef __ARCH_SPARC_ATOMIC__
|
||||
#define __ARCH_SPARC_ATOMIC__
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
typedef struct { volatile int counter; } atomic_t;
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
#define ATOMIC_INIT(i) { (i) }
|
||||
|
||||
extern int __atomic_add_return(int, atomic_t *);
|
||||
extern int atomic_cmpxchg(atomic_t *, int, int);
|
||||
#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
|
||||
extern int atomic_add_unless(atomic_t *, int, int);
|
||||
extern void atomic_set(atomic_t *, int);
|
||||
|
||||
#define atomic_read(v) ((v)->counter)
|
||||
|
||||
#define atomic_add(i, v) ((void)__atomic_add_return( (int)(i), (v)))
|
||||
#define atomic_sub(i, v) ((void)__atomic_add_return(-(int)(i), (v)))
|
||||
#define atomic_inc(v) ((void)__atomic_add_return( 1, (v)))
|
||||
#define atomic_dec(v) ((void)__atomic_add_return( -1, (v)))
|
||||
|
||||
#define atomic_add_return(i, v) (__atomic_add_return( (int)(i), (v)))
|
||||
#define atomic_sub_return(i, v) (__atomic_add_return(-(int)(i), (v)))
|
||||
#define atomic_inc_return(v) (__atomic_add_return( 1, (v)))
|
||||
#define atomic_dec_return(v) (__atomic_add_return( -1, (v)))
|
||||
|
||||
#define atomic_add_negative(a, v) (atomic_add_return((a), (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_inc_return(v) == 0)
|
||||
|
||||
#define atomic_dec_and_test(v) (atomic_dec_return(v) == 0)
|
||||
#define atomic_sub_and_test(i, v) (atomic_sub_return(i, v) == 0)
|
||||
|
||||
#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
|
||||
|
||||
/* This is the old 24-bit implementation. It's still used internally
|
||||
* by some sparc-specific code, notably the semaphore implementation.
|
||||
*/
|
||||
typedef struct { volatile int counter; } atomic24_t;
|
||||
|
||||
#ifndef CONFIG_SMP
|
||||
|
||||
#define ATOMIC24_INIT(i) { (i) }
|
||||
#define atomic24_read(v) ((v)->counter)
|
||||
#define atomic24_set(v, i) (((v)->counter) = i)
|
||||
|
||||
#ifndef ___ASM_SPARC_ATOMIC_H
|
||||
#define ___ASM_SPARC_ATOMIC_H
|
||||
#if defined(__sparc__) && defined(__arch64__)
|
||||
#include <asm-sparc/atomic_64.h>
|
||||
#else
|
||||
/* We do the bulk of the actual work out of line in two common
|
||||
* routines in assembler, see arch/sparc/lib/atomic.S for the
|
||||
* "fun" details.
|
||||
*
|
||||
* For SMP the trick is you embed the spin lock byte within
|
||||
* the word, use the low byte so signedness is easily retained
|
||||
* via a quick arithmetic shift. It looks like this:
|
||||
*
|
||||
* ----------------------------------------
|
||||
* | signed 24-bit counter value | lock | atomic_t
|
||||
* ----------------------------------------
|
||||
* 31 8 7 0
|
||||
*/
|
||||
|
||||
#define ATOMIC24_INIT(i) { ((i) << 8) }
|
||||
|
||||
static inline int atomic24_read(const atomic24_t *v)
|
||||
{
|
||||
int ret = v->counter;
|
||||
|
||||
while(ret & 0xff)
|
||||
ret = v->counter;
|
||||
|
||||
return ret >> 8;
|
||||
}
|
||||
|
||||
#define atomic24_set(v, i) (((v)->counter) = ((i) << 8))
|
||||
#include <asm-sparc/atomic_32.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
static inline int __atomic24_add(int i, atomic24_t *v)
|
||||
{
|
||||
register volatile int *ptr asm("g1");
|
||||
register int increment asm("g2");
|
||||
register int tmp1 asm("g3");
|
||||
register int tmp2 asm("g4");
|
||||
register int tmp3 asm("g7");
|
||||
|
||||
ptr = &v->counter;
|
||||
increment = i;
|
||||
|
||||
__asm__ __volatile__(
|
||||
"mov %%o7, %%g4\n\t"
|
||||
"call ___atomic24_add\n\t"
|
||||
" add %%o7, 8, %%o7\n"
|
||||
: "=&r" (increment), "=r" (tmp1), "=r" (tmp2), "=r" (tmp3)
|
||||
: "0" (increment), "r" (ptr)
|
||||
: "memory", "cc");
|
||||
|
||||
return increment;
|
||||
}
|
||||
|
||||
static inline int __atomic24_sub(int i, atomic24_t *v)
|
||||
{
|
||||
register volatile int *ptr asm("g1");
|
||||
register int increment asm("g2");
|
||||
register int tmp1 asm("g3");
|
||||
register int tmp2 asm("g4");
|
||||
register int tmp3 asm("g7");
|
||||
|
||||
ptr = &v->counter;
|
||||
increment = i;
|
||||
|
||||
__asm__ __volatile__(
|
||||
"mov %%o7, %%g4\n\t"
|
||||
"call ___atomic24_sub\n\t"
|
||||
" add %%o7, 8, %%o7\n"
|
||||
: "=&r" (increment), "=r" (tmp1), "=r" (tmp2), "=r" (tmp3)
|
||||
: "0" (increment), "r" (ptr)
|
||||
: "memory", "cc");
|
||||
|
||||
return increment;
|
||||
}
|
||||
|
||||
#define atomic24_add(i, v) ((void)__atomic24_add((i), (v)))
|
||||
#define atomic24_sub(i, v) ((void)__atomic24_sub((i), (v)))
|
||||
|
||||
#define atomic24_dec_return(v) __atomic24_sub(1, (v))
|
||||
#define atomic24_inc_return(v) __atomic24_add(1, (v))
|
||||
|
||||
#define atomic24_sub_and_test(i, v) (__atomic24_sub((i), (v)) == 0)
|
||||
#define atomic24_dec_and_test(v) (__atomic24_sub(1, (v)) == 0)
|
||||
|
||||
#define atomic24_inc(v) ((void)__atomic24_add(1, (v)))
|
||||
#define atomic24_dec(v) ((void)__atomic24_sub(1, (v)))
|
||||
|
||||
#define atomic24_add_negative(i, v) (__atomic24_add((i), (v)) < 0)
|
||||
|
||||
/* 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__) */
|
||||
|
||||
#include <asm-generic/atomic.h>
|
||||
#endif /* !(__ARCH_SPARC_ATOMIC__) */
|
||||
|
|
165
include/asm-sparc/atomic_32.h
Normal file
165
include/asm-sparc/atomic_32.h
Normal file
|
@ -0,0 +1,165 @@
|
|||
/* atomic.h: These still suck, but the I-cache hit rate is higher.
|
||||
*
|
||||
* Copyright (C) 1996 David S. Miller (davem@davemloft.net)
|
||||
* Copyright (C) 2000 Anton Blanchard (anton@linuxcare.com.au)
|
||||
* Copyright (C) 2007 Kyle McMartin (kyle@parisc-linux.org)
|
||||
*
|
||||
* Additions by Keith M Wesolowski (wesolows@foobazco.org) based
|
||||
* on asm-parisc/atomic.h Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org>.
|
||||
*/
|
||||
|
||||
#ifndef __ARCH_SPARC_ATOMIC__
|
||||
#define __ARCH_SPARC_ATOMIC__
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
typedef struct { volatile int counter; } atomic_t;
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
#define ATOMIC_INIT(i) { (i) }
|
||||
|
||||
extern int __atomic_add_return(int, atomic_t *);
|
||||
extern int atomic_cmpxchg(atomic_t *, int, int);
|
||||
#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
|
||||
extern int atomic_add_unless(atomic_t *, int, int);
|
||||
extern void atomic_set(atomic_t *, int);
|
||||
|
||||
#define atomic_read(v) ((v)->counter)
|
||||
|
||||
#define atomic_add(i, v) ((void)__atomic_add_return( (int)(i), (v)))
|
||||
#define atomic_sub(i, v) ((void)__atomic_add_return(-(int)(i), (v)))
|
||||
#define atomic_inc(v) ((void)__atomic_add_return( 1, (v)))
|
||||
#define atomic_dec(v) ((void)__atomic_add_return( -1, (v)))
|
||||
|
||||
#define atomic_add_return(i, v) (__atomic_add_return( (int)(i), (v)))
|
||||
#define atomic_sub_return(i, v) (__atomic_add_return(-(int)(i), (v)))
|
||||
#define atomic_inc_return(v) (__atomic_add_return( 1, (v)))
|
||||
#define atomic_dec_return(v) (__atomic_add_return( -1, (v)))
|
||||
|
||||
#define atomic_add_negative(a, v) (atomic_add_return((a), (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_inc_return(v) == 0)
|
||||
|
||||
#define atomic_dec_and_test(v) (atomic_dec_return(v) == 0)
|
||||
#define atomic_sub_and_test(i, v) (atomic_sub_return(i, v) == 0)
|
||||
|
||||
#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
|
||||
|
||||
/* This is the old 24-bit implementation. It's still used internally
|
||||
* by some sparc-specific code, notably the semaphore implementation.
|
||||
*/
|
||||
typedef struct { volatile int counter; } atomic24_t;
|
||||
|
||||
#ifndef CONFIG_SMP
|
||||
|
||||
#define ATOMIC24_INIT(i) { (i) }
|
||||
#define atomic24_read(v) ((v)->counter)
|
||||
#define atomic24_set(v, i) (((v)->counter) = i)
|
||||
|
||||
#else
|
||||
/* We do the bulk of the actual work out of line in two common
|
||||
* routines in assembler, see arch/sparc/lib/atomic.S for the
|
||||
* "fun" details.
|
||||
*
|
||||
* For SMP the trick is you embed the spin lock byte within
|
||||
* the word, use the low byte so signedness is easily retained
|
||||
* via a quick arithmetic shift. It looks like this:
|
||||
*
|
||||
* ----------------------------------------
|
||||
* | signed 24-bit counter value | lock | atomic_t
|
||||
* ----------------------------------------
|
||||
* 31 8 7 0
|
||||
*/
|
||||
|
||||
#define ATOMIC24_INIT(i) { ((i) << 8) }
|
||||
|
||||
static inline int atomic24_read(const atomic24_t *v)
|
||||
{
|
||||
int ret = v->counter;
|
||||
|
||||
while(ret & 0xff)
|
||||
ret = v->counter;
|
||||
|
||||
return ret >> 8;
|
||||
}
|
||||
|
||||
#define atomic24_set(v, i) (((v)->counter) = ((i) << 8))
|
||||
#endif
|
||||
|
||||
static inline int __atomic24_add(int i, atomic24_t *v)
|
||||
{
|
||||
register volatile int *ptr asm("g1");
|
||||
register int increment asm("g2");
|
||||
register int tmp1 asm("g3");
|
||||
register int tmp2 asm("g4");
|
||||
register int tmp3 asm("g7");
|
||||
|
||||
ptr = &v->counter;
|
||||
increment = i;
|
||||
|
||||
__asm__ __volatile__(
|
||||
"mov %%o7, %%g4\n\t"
|
||||
"call ___atomic24_add\n\t"
|
||||
" add %%o7, 8, %%o7\n"
|
||||
: "=&r" (increment), "=r" (tmp1), "=r" (tmp2), "=r" (tmp3)
|
||||
: "0" (increment), "r" (ptr)
|
||||
: "memory", "cc");
|
||||
|
||||
return increment;
|
||||
}
|
||||
|
||||
static inline int __atomic24_sub(int i, atomic24_t *v)
|
||||
{
|
||||
register volatile int *ptr asm("g1");
|
||||
register int increment asm("g2");
|
||||
register int tmp1 asm("g3");
|
||||
register int tmp2 asm("g4");
|
||||
register int tmp3 asm("g7");
|
||||
|
||||
ptr = &v->counter;
|
||||
increment = i;
|
||||
|
||||
__asm__ __volatile__(
|
||||
"mov %%o7, %%g4\n\t"
|
||||
"call ___atomic24_sub\n\t"
|
||||
" add %%o7, 8, %%o7\n"
|
||||
: "=&r" (increment), "=r" (tmp1), "=r" (tmp2), "=r" (tmp3)
|
||||
: "0" (increment), "r" (ptr)
|
||||
: "memory", "cc");
|
||||
|
||||
return increment;
|
||||
}
|
||||
|
||||
#define atomic24_add(i, v) ((void)__atomic24_add((i), (v)))
|
||||
#define atomic24_sub(i, v) ((void)__atomic24_sub((i), (v)))
|
||||
|
||||
#define atomic24_dec_return(v) __atomic24_sub(1, (v))
|
||||
#define atomic24_inc_return(v) __atomic24_add(1, (v))
|
||||
|
||||
#define atomic24_sub_and_test(i, v) (__atomic24_sub((i), (v)) == 0)
|
||||
#define atomic24_dec_and_test(v) (__atomic24_sub(1, (v)) == 0)
|
||||
|
||||
#define atomic24_inc(v) ((void)__atomic24_add(1, (v)))
|
||||
#define atomic24_dec(v) ((void)__atomic24_sub(1, (v)))
|
||||
|
||||
#define atomic24_add_negative(i, v) (__atomic24_add((i), (v)) < 0)
|
||||
|
||||
/* 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__) */
|
||||
|
||||
#include <asm-generic/atomic.h>
|
||||
#endif /* !(__ARCH_SPARC_ATOMIC__) */
|
128
include/asm-sparc/atomic_64.h
Normal file
128
include/asm-sparc/atomic_64.h
Normal file
|
@ -0,0 +1,128 @@
|
|||
/* atomic.h: Thankfully the V9 is at least reasonable for this
|
||||
* stuff.
|
||||
*
|
||||
* Copyright (C) 1996, 1997, 2000 David S. Miller (davem@redhat.com)
|
||||
*/
|
||||
|
||||
#ifndef __ARCH_SPARC64_ATOMIC__
|
||||
#define __ARCH_SPARC64_ATOMIC__
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <asm/system.h>
|
||||
|
||||
typedef struct { volatile int counter; } atomic_t;
|
||||
typedef struct { volatile __s64 counter; } atomic64_t;
|
||||
|
||||
#define ATOMIC_INIT(i) { (i) }
|
||||
#define ATOMIC64_INIT(i) { (i) }
|
||||
|
||||
#define atomic_read(v) ((v)->counter)
|
||||
#define atomic64_read(v) ((v)->counter)
|
||||
|
||||
#define atomic_set(v, i) (((v)->counter) = i)
|
||||
#define atomic64_set(v, i) (((v)->counter) = i)
|
||||
|
||||
extern void atomic_add(int, atomic_t *);
|
||||
extern void atomic64_add(int, atomic64_t *);
|
||||
extern void atomic_sub(int, atomic_t *);
|
||||
extern void atomic64_sub(int, atomic64_t *);
|
||||
|
||||
extern int atomic_add_ret(int, atomic_t *);
|
||||
extern int atomic64_add_ret(int, atomic64_t *);
|
||||
extern int atomic_sub_ret(int, atomic_t *);
|
||||
extern int atomic64_sub_ret(int, atomic64_t *);
|
||||
|
||||
#define atomic_dec_return(v) atomic_sub_ret(1, v)
|
||||
#define atomic64_dec_return(v) atomic64_sub_ret(1, v)
|
||||
|
||||
#define atomic_inc_return(v) atomic_add_ret(1, v)
|
||||
#define atomic64_inc_return(v) atomic64_add_ret(1, v)
|
||||
|
||||
#define atomic_sub_return(i, v) atomic_sub_ret(i, v)
|
||||
#define atomic64_sub_return(i, v) atomic64_sub_ret(i, v)
|
||||
|
||||
#define atomic_add_return(i, v) atomic_add_ret(i, v)
|
||||
#define atomic64_add_return(i, v) atomic64_add_ret(i, v)
|
||||
|
||||
/*
|
||||
* 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_inc_return(v) == 0)
|
||||
#define atomic64_inc_and_test(v) (atomic64_inc_return(v) == 0)
|
||||
|
||||
#define atomic_sub_and_test(i, v) (atomic_sub_ret(i, v) == 0)
|
||||
#define atomic64_sub_and_test(i, v) (atomic64_sub_ret(i, v) == 0)
|
||||
|
||||
#define atomic_dec_and_test(v) (atomic_sub_ret(1, v) == 0)
|
||||
#define atomic64_dec_and_test(v) (atomic64_sub_ret(1, v) == 0)
|
||||
|
||||
#define atomic_inc(v) atomic_add(1, v)
|
||||
#define atomic64_inc(v) atomic64_add(1, v)
|
||||
|
||||
#define atomic_dec(v) atomic_sub(1, v)
|
||||
#define atomic64_dec(v) atomic64_sub(1, v)
|
||||
|
||||
#define atomic_add_negative(i, v) (atomic_add_ret(i, v) < 0)
|
||||
#define atomic64_add_negative(i, v) (atomic64_add_ret(i, v) < 0)
|
||||
|
||||
#define atomic_cmpxchg(v, o, n) (cmpxchg(&((v)->counter), (o), (n)))
|
||||
#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
|
||||
|
||||
static inline int atomic_add_unless(atomic_t *v, int a, int u)
|
||||
{
|
||||
int c, old;
|
||||
c = atomic_read(v);
|
||||
for (;;) {
|
||||
if (unlikely(c == (u)))
|
||||
break;
|
||||
old = atomic_cmpxchg((v), c, c + (a));
|
||||
if (likely(old == c))
|
||||
break;
|
||||
c = old;
|
||||
}
|
||||
return c != (u);
|
||||
}
|
||||
|
||||
#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
|
||||
|
||||
#define atomic64_cmpxchg(v, o, n) \
|
||||
((__typeof__((v)->counter))cmpxchg(&((v)->counter), (o), (n)))
|
||||
#define atomic64_xchg(v, new) (xchg(&((v)->counter), new))
|
||||
|
||||
static inline int atomic64_add_unless(atomic64_t *v, long a, long u)
|
||||
{
|
||||
long c, old;
|
||||
c = atomic64_read(v);
|
||||
for (;;) {
|
||||
if (unlikely(c == (u)))
|
||||
break;
|
||||
old = atomic64_cmpxchg((v), c, c + (a));
|
||||
if (likely(old == c))
|
||||
break;
|
||||
c = old;
|
||||
}
|
||||
return c != (u);
|
||||
}
|
||||
|
||||
#define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0)
|
||||
|
||||
/* Atomic operations are already serializing */
|
||||
#ifdef CONFIG_SMP
|
||||
#define smp_mb__before_atomic_dec() membar_storeload_loadload();
|
||||
#define smp_mb__after_atomic_dec() membar_storeload_storestore();
|
||||
#define smp_mb__before_atomic_inc() membar_storeload_loadload();
|
||||
#define smp_mb__after_atomic_inc() membar_storeload_storestore();
|
||||
#else
|
||||
#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
|
||||
|
||||
#include <asm-generic/atomic.h>
|
||||
#endif /* !(__ARCH_SPARC64_ATOMIC__) */
|
|
@ -1,89 +1,8 @@
|
|||
/*
|
||||
* auxio.h: Definitions and code for the Auxiliary I/O register.
|
||||
*
|
||||
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
|
||||
*/
|
||||
#ifndef _SPARC_AUXIO_H
|
||||
#define _SPARC_AUXIO_H
|
||||
|
||||
#include <asm/system.h>
|
||||
#include <asm/vaddrs.h>
|
||||
|
||||
/* This register is an unsigned char in IO space. It does two things.
|
||||
* First, it is used to control the front panel LED light on machines
|
||||
* that have it (good for testing entry points to trap handlers and irq's)
|
||||
* Secondly, it controls various floppy drive parameters.
|
||||
*/
|
||||
#define AUXIO_ORMEIN 0xf0 /* All writes must set these bits. */
|
||||
#define AUXIO_ORMEIN4M 0xc0 /* sun4m - All writes must set these bits. */
|
||||
#define AUXIO_FLPY_DENS 0x20 /* Floppy density, high if set. Read only. */
|
||||
#define AUXIO_FLPY_DCHG 0x10 /* A disk change occurred. Read only. */
|
||||
#define AUXIO_EDGE_ON 0x10 /* sun4m - On means Jumper block is in. */
|
||||
#define AUXIO_FLPY_DSEL 0x08 /* Drive select/start-motor. Write only. */
|
||||
#define AUXIO_LINK_TEST 0x08 /* sun4m - On means TPE Carrier detect. */
|
||||
|
||||
/* Set the following to one, then zero, after doing a pseudo DMA transfer. */
|
||||
#define AUXIO_FLPY_TCNT 0x04 /* Floppy terminal count. Write only. */
|
||||
|
||||
/* Set the following to zero to eject the floppy. */
|
||||
#define AUXIO_FLPY_EJCT 0x02 /* Eject floppy disk. Write only. */
|
||||
#define AUXIO_LED 0x01 /* On if set, off if unset. Read/Write */
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
/*
|
||||
* NOTE: these routines are implementation dependent--
|
||||
* understand the hardware you are querying!
|
||||
*/
|
||||
extern void set_auxio(unsigned char bits_on, unsigned char bits_off);
|
||||
extern unsigned char get_auxio(void); /* .../asm-sparc/floppy.h */
|
||||
|
||||
/*
|
||||
* The following routines are provided for driver-compatibility
|
||||
* with sparc64 (primarily sunlance.c)
|
||||
*/
|
||||
|
||||
#define AUXIO_LTE_ON 1
|
||||
#define AUXIO_LTE_OFF 0
|
||||
|
||||
/* auxio_set_lte - Set Link Test Enable (TPE Link Detect)
|
||||
*
|
||||
* on - AUXIO_LTE_ON or AUXIO_LTE_OFF
|
||||
*/
|
||||
#define auxio_set_lte(on) \
|
||||
do { \
|
||||
if(on) { \
|
||||
set_auxio(AUXIO_LINK_TEST, 0); \
|
||||
} else { \
|
||||
set_auxio(0, AUXIO_LINK_TEST); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define AUXIO_LED_ON 1
|
||||
#define AUXIO_LED_OFF 0
|
||||
|
||||
/* auxio_set_led - Set system front panel LED
|
||||
*
|
||||
* on - AUXIO_LED_ON or AUXIO_LED_OFF
|
||||
*/
|
||||
#define auxio_set_led(on) \
|
||||
do { \
|
||||
if(on) { \
|
||||
set_auxio(AUXIO_LED, 0); \
|
||||
} else { \
|
||||
set_auxio(0, AUXIO_LED); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#endif /* !(__ASSEMBLY__) */
|
||||
|
||||
|
||||
/* AUXIO2 (Power Off Control) */
|
||||
extern __volatile__ unsigned char * auxio_power_register;
|
||||
|
||||
#define AUXIO_POWER_DETECT_FAILURE 32
|
||||
#define AUXIO_POWER_CLEAR_FAILURE 2
|
||||
#define AUXIO_POWER_OFF 1
|
||||
|
||||
|
||||
#endif /* !(_SPARC_AUXIO_H) */
|
||||
#ifndef ___ASM_SPARC_AUXIO_H
|
||||
#define ___ASM_SPARC_AUXIO_H
|
||||
#if defined(__sparc__) && defined(__arch64__)
|
||||
#include <asm-sparc/auxio_64.h>
|
||||
#else
|
||||
#include <asm-sparc/auxio_32.h>
|
||||
#endif
|
||||
#endif
|
||||
|
|
89
include/asm-sparc/auxio_32.h
Normal file
89
include/asm-sparc/auxio_32.h
Normal file
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
* auxio.h: Definitions and code for the Auxiliary I/O register.
|
||||
*
|
||||
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
|
||||
*/
|
||||
#ifndef _SPARC_AUXIO_H
|
||||
#define _SPARC_AUXIO_H
|
||||
|
||||
#include <asm/system.h>
|
||||
#include <asm/vaddrs.h>
|
||||
|
||||
/* This register is an unsigned char in IO space. It does two things.
|
||||
* First, it is used to control the front panel LED light on machines
|
||||
* that have it (good for testing entry points to trap handlers and irq's)
|
||||
* Secondly, it controls various floppy drive parameters.
|
||||
*/
|
||||
#define AUXIO_ORMEIN 0xf0 /* All writes must set these bits. */
|
||||
#define AUXIO_ORMEIN4M 0xc0 /* sun4m - All writes must set these bits. */
|
||||
#define AUXIO_FLPY_DENS 0x20 /* Floppy density, high if set. Read only. */
|
||||
#define AUXIO_FLPY_DCHG 0x10 /* A disk change occurred. Read only. */
|
||||
#define AUXIO_EDGE_ON 0x10 /* sun4m - On means Jumper block is in. */
|
||||
#define AUXIO_FLPY_DSEL 0x08 /* Drive select/start-motor. Write only. */
|
||||
#define AUXIO_LINK_TEST 0x08 /* sun4m - On means TPE Carrier detect. */
|
||||
|
||||
/* Set the following to one, then zero, after doing a pseudo DMA transfer. */
|
||||
#define AUXIO_FLPY_TCNT 0x04 /* Floppy terminal count. Write only. */
|
||||
|
||||
/* Set the following to zero to eject the floppy. */
|
||||
#define AUXIO_FLPY_EJCT 0x02 /* Eject floppy disk. Write only. */
|
||||
#define AUXIO_LED 0x01 /* On if set, off if unset. Read/Write */
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
/*
|
||||
* NOTE: these routines are implementation dependent--
|
||||
* understand the hardware you are querying!
|
||||
*/
|
||||
extern void set_auxio(unsigned char bits_on, unsigned char bits_off);
|
||||
extern unsigned char get_auxio(void); /* .../asm-sparc/floppy.h */
|
||||
|
||||
/*
|
||||
* The following routines are provided for driver-compatibility
|
||||
* with sparc64 (primarily sunlance.c)
|
||||
*/
|
||||
|
||||
#define AUXIO_LTE_ON 1
|
||||
#define AUXIO_LTE_OFF 0
|
||||
|
||||
/* auxio_set_lte - Set Link Test Enable (TPE Link Detect)
|
||||
*
|
||||
* on - AUXIO_LTE_ON or AUXIO_LTE_OFF
|
||||
*/
|
||||
#define auxio_set_lte(on) \
|
||||
do { \
|
||||
if(on) { \
|
||||
set_auxio(AUXIO_LINK_TEST, 0); \
|
||||
} else { \
|
||||
set_auxio(0, AUXIO_LINK_TEST); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define AUXIO_LED_ON 1
|
||||
#define AUXIO_LED_OFF 0
|
||||
|
||||
/* auxio_set_led - Set system front panel LED
|
||||
*
|
||||
* on - AUXIO_LED_ON or AUXIO_LED_OFF
|
||||
*/
|
||||
#define auxio_set_led(on) \
|
||||
do { \
|
||||
if(on) { \
|
||||
set_auxio(AUXIO_LED, 0); \
|
||||
} else { \
|
||||
set_auxio(0, AUXIO_LED); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#endif /* !(__ASSEMBLY__) */
|
||||
|
||||
|
||||
/* AUXIO2 (Power Off Control) */
|
||||
extern __volatile__ unsigned char * auxio_power_register;
|
||||
|
||||
#define AUXIO_POWER_DETECT_FAILURE 32
|
||||
#define AUXIO_POWER_CLEAR_FAILURE 2
|
||||
#define AUXIO_POWER_OFF 1
|
||||
|
||||
|
||||
#endif /* !(_SPARC_AUXIO_H) */
|
100
include/asm-sparc/auxio_64.h
Normal file
100
include/asm-sparc/auxio_64.h
Normal file
|
@ -0,0 +1,100 @@
|
|||
/*
|
||||
* auxio.h: Definitions and code for the Auxiliary I/O registers.
|
||||
*
|
||||
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
|
||||
*
|
||||
* Refactoring for unified NCR/PCIO support 2002 Eric Brower (ebrower@usa.net)
|
||||
*/
|
||||
#ifndef _SPARC64_AUXIO_H
|
||||
#define _SPARC64_AUXIO_H
|
||||
|
||||
/* AUXIO implementations:
|
||||
* sbus-based NCR89C105 "Slavio"
|
||||
* LED/Floppy (AUX1) register
|
||||
* Power (AUX2) register
|
||||
*
|
||||
* ebus-based auxio on PCIO
|
||||
* LED Auxio Register
|
||||
* Power Auxio Register
|
||||
*
|
||||
* Register definitions from NCR _NCR89C105 Chip Specification_
|
||||
*
|
||||
* SLAVIO AUX1 @ 0x1900000
|
||||
* -------------------------------------------------
|
||||
* | (R) | (R) | D | (R) | E | M | T | L |
|
||||
* -------------------------------------------------
|
||||
* (R) - bit 7:6,4 are reserved and should be masked in s/w
|
||||
* D - Floppy Density Sense (1=high density) R/O
|
||||
* E - Link Test Enable, directly reflected on AT&T 7213 LTE pin
|
||||
* M - Monitor/Mouse Mux, directly reflected on MON_MSE_MUX pin
|
||||
* T - Terminal Count: sends TC pulse to 82077 floppy controller
|
||||
* L - System LED on front panel (0=off, 1=on)
|
||||
*/
|
||||
#define AUXIO_AUX1_MASK 0xc0 /* Mask bits */
|
||||
#define AUXIO_AUX1_FDENS 0x20 /* Floppy Density Sense */
|
||||
#define AUXIO_AUX1_LTE 0x08 /* Link Test Enable */
|
||||
#define AUXIO_AUX1_MMUX 0x04 /* Monitor/Mouse Mux */
|
||||
#define AUXIO_AUX1_FTCNT 0x02 /* Terminal Count, */
|
||||
#define AUXIO_AUX1_LED 0x01 /* System LED */
|
||||
|
||||
/* SLAVIO AUX2 @ 0x1910000
|
||||
* -------------------------------------------------
|
||||
* | (R) | (R) | D | (R) | (R) | (R) | C | F |
|
||||
* -------------------------------------------------
|
||||
* (R) - bits 7:6,4:2 are reserved and should be masked in s/w
|
||||
* D - Power Failure Detect (1=power fail)
|
||||
* C - Clear Power Failure Detect Int (1=clear)
|
||||
* F - Power Off (1=power off)
|
||||
*/
|
||||
#define AUXIO_AUX2_MASK 0xdc /* Mask Bits */
|
||||
#define AUXIO_AUX2_PFAILDET 0x20 /* Power Fail Detect */
|
||||
#define AUXIO_AUX2_PFAILCLR 0x02 /* Clear Pwr Fail Det Intr */
|
||||
#define AUXIO_AUX2_PWR_OFF 0x01 /* Power Off */
|
||||
|
||||
/* Register definitions from Sun Microsystems _PCIO_ p/n 802-7837
|
||||
*
|
||||
* PCIO LED Auxio @ 0x726000
|
||||
* -------------------------------------------------
|
||||
* | 31:1 Unused | LED |
|
||||
* -------------------------------------------------
|
||||
* Bits 31:1 unused
|
||||
* LED - System LED on front panel (0=off, 1=on)
|
||||
*/
|
||||
#define AUXIO_PCIO_LED 0x01 /* System LED */
|
||||
|
||||
/* PCIO Power Auxio @ 0x724000
|
||||
* -------------------------------------------------
|
||||
* | 31:2 Unused | CPO | SPO |
|
||||
* -------------------------------------------------
|
||||
* Bits 31:2 unused
|
||||
* CPO - Courtesy Power Off (1=off)
|
||||
* SPO - System Power Off (1=off)
|
||||
*/
|
||||
#define AUXIO_PCIO_CPWR_OFF 0x02 /* Courtesy Power Off */
|
||||
#define AUXIO_PCIO_SPWR_OFF 0x01 /* System Power Off */
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
extern void __iomem *auxio_register;
|
||||
|
||||
#define AUXIO_LTE_ON 1
|
||||
#define AUXIO_LTE_OFF 0
|
||||
|
||||
/* auxio_set_lte - Set Link Test Enable (TPE Link Detect)
|
||||
*
|
||||
* on - AUXIO_LTE_ON or AUXIO_LTE_OFF
|
||||
*/
|
||||
extern void auxio_set_lte(int on);
|
||||
|
||||
#define AUXIO_LED_ON 1
|
||||
#define AUXIO_LED_OFF 0
|
||||
|
||||
/* auxio_set_led - Set system front panel LED
|
||||
*
|
||||
* on - AUXIO_LED_ON or AUXIO_LED_OFF
|
||||
*/
|
||||
extern void auxio_set_led(int on);
|
||||
|
||||
#endif /* ifndef __ASSEMBLY__ */
|
||||
|
||||
#endif /* !(_SPARC64_AUXIO_H) */
|
|
@ -1,111 +1,8 @@
|
|||
/*
|
||||
* bitops.h: Bit string operations on the Sparc.
|
||||
*
|
||||
* Copyright 1995 David S. Miller (davem@caip.rutgers.edu)
|
||||
* Copyright 1996 Eddie C. Dost (ecd@skynet.be)
|
||||
* Copyright 2001 Anton Blanchard (anton@samba.org)
|
||||
*/
|
||||
|
||||
#ifndef _SPARC_BITOPS_H
|
||||
#define _SPARC_BITOPS_H
|
||||
|
||||
#include <linux/compiler.h>
|
||||
#include <asm/byteorder.h>
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
#ifndef _LINUX_BITOPS_H
|
||||
#error only <linux/bitops.h> can be included directly
|
||||
#ifndef ___ASM_SPARC_BITOPS_H
|
||||
#define ___ASM_SPARC_BITOPS_H
|
||||
#if defined(__sparc__) && defined(__arch64__)
|
||||
#include <asm-sparc/bitops_64.h>
|
||||
#else
|
||||
#include <asm-sparc/bitops_32.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
extern unsigned long ___set_bit(unsigned long *addr, unsigned long mask);
|
||||
extern unsigned long ___clear_bit(unsigned long *addr, unsigned long mask);
|
||||
extern unsigned long ___change_bit(unsigned long *addr, unsigned long mask);
|
||||
|
||||
/*
|
||||
* Set bit 'nr' in 32-bit quantity at address 'addr' where bit '0'
|
||||
* is in the highest of the four bytes and bit '31' is the high bit
|
||||
* within the first byte. Sparc is BIG-Endian. Unless noted otherwise
|
||||
* all bit-ops return 0 if bit was previously clear and != 0 otherwise.
|
||||
*/
|
||||
static inline int test_and_set_bit(unsigned long nr, volatile unsigned long *addr)
|
||||
{
|
||||
unsigned long *ADDR, mask;
|
||||
|
||||
ADDR = ((unsigned long *) addr) + (nr >> 5);
|
||||
mask = 1 << (nr & 31);
|
||||
|
||||
return ___set_bit(ADDR, mask) != 0;
|
||||
}
|
||||
|
||||
static inline void set_bit(unsigned long nr, volatile unsigned long *addr)
|
||||
{
|
||||
unsigned long *ADDR, mask;
|
||||
|
||||
ADDR = ((unsigned long *) addr) + (nr >> 5);
|
||||
mask = 1 << (nr & 31);
|
||||
|
||||
(void) ___set_bit(ADDR, mask);
|
||||
}
|
||||
|
||||
static inline int test_and_clear_bit(unsigned long nr, volatile unsigned long *addr)
|
||||
{
|
||||
unsigned long *ADDR, mask;
|
||||
|
||||
ADDR = ((unsigned long *) addr) + (nr >> 5);
|
||||
mask = 1 << (nr & 31);
|
||||
|
||||
return ___clear_bit(ADDR, mask) != 0;
|
||||
}
|
||||
|
||||
static inline void clear_bit(unsigned long nr, volatile unsigned long *addr)
|
||||
{
|
||||
unsigned long *ADDR, mask;
|
||||
|
||||
ADDR = ((unsigned long *) addr) + (nr >> 5);
|
||||
mask = 1 << (nr & 31);
|
||||
|
||||
(void) ___clear_bit(ADDR, mask);
|
||||
}
|
||||
|
||||
static inline int test_and_change_bit(unsigned long nr, volatile unsigned long *addr)
|
||||
{
|
||||
unsigned long *ADDR, mask;
|
||||
|
||||
ADDR = ((unsigned long *) addr) + (nr >> 5);
|
||||
mask = 1 << (nr & 31);
|
||||
|
||||
return ___change_bit(ADDR, mask) != 0;
|
||||
}
|
||||
|
||||
static inline void change_bit(unsigned long nr, volatile unsigned long *addr)
|
||||
{
|
||||
unsigned long *ADDR, mask;
|
||||
|
||||
ADDR = ((unsigned long *) addr) + (nr >> 5);
|
||||
mask = 1 << (nr & 31);
|
||||
|
||||
(void) ___change_bit(ADDR, mask);
|
||||
}
|
||||
|
||||
#include <asm-generic/bitops/non-atomic.h>
|
||||
|
||||
#define smp_mb__before_clear_bit() do { } while(0)
|
||||
#define smp_mb__after_clear_bit() do { } while(0)
|
||||
|
||||
#include <asm-generic/bitops/ffz.h>
|
||||
#include <asm-generic/bitops/__ffs.h>
|
||||
#include <asm-generic/bitops/sched.h>
|
||||
#include <asm-generic/bitops/ffs.h>
|
||||
#include <asm-generic/bitops/fls.h>
|
||||
#include <asm-generic/bitops/fls64.h>
|
||||
#include <asm-generic/bitops/hweight.h>
|
||||
#include <asm-generic/bitops/lock.h>
|
||||
#include <asm-generic/bitops/find.h>
|
||||
#include <asm-generic/bitops/ext2-non-atomic.h>
|
||||
#include <asm-generic/bitops/ext2-atomic.h>
|
||||
#include <asm-generic/bitops/minix.h>
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
#endif /* defined(_SPARC_BITOPS_H) */
|
||||
|
|
111
include/asm-sparc/bitops_32.h
Normal file
111
include/asm-sparc/bitops_32.h
Normal file
|
@ -0,0 +1,111 @@
|
|||
/*
|
||||
* bitops.h: Bit string operations on the Sparc.
|
||||
*
|
||||
* Copyright 1995 David S. Miller (davem@caip.rutgers.edu)
|
||||
* Copyright 1996 Eddie C. Dost (ecd@skynet.be)
|
||||
* Copyright 2001 Anton Blanchard (anton@samba.org)
|
||||
*/
|
||||
|
||||
#ifndef _SPARC_BITOPS_H
|
||||
#define _SPARC_BITOPS_H
|
||||
|
||||
#include <linux/compiler.h>
|
||||
#include <asm/byteorder.h>
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
#ifndef _LINUX_BITOPS_H
|
||||
#error only <linux/bitops.h> can be included directly
|
||||
#endif
|
||||
|
||||
extern unsigned long ___set_bit(unsigned long *addr, unsigned long mask);
|
||||
extern unsigned long ___clear_bit(unsigned long *addr, unsigned long mask);
|
||||
extern unsigned long ___change_bit(unsigned long *addr, unsigned long mask);
|
||||
|
||||
/*
|
||||
* Set bit 'nr' in 32-bit quantity at address 'addr' where bit '0'
|
||||
* is in the highest of the four bytes and bit '31' is the high bit
|
||||
* within the first byte. Sparc is BIG-Endian. Unless noted otherwise
|
||||
* all bit-ops return 0 if bit was previously clear and != 0 otherwise.
|
||||
*/
|
||||
static inline int test_and_set_bit(unsigned long nr, volatile unsigned long *addr)
|
||||
{
|
||||
unsigned long *ADDR, mask;
|
||||
|
||||
ADDR = ((unsigned long *) addr) + (nr >> 5);
|
||||
mask = 1 << (nr & 31);
|
||||
|
||||
return ___set_bit(ADDR, mask) != 0;
|
||||
}
|
||||
|
||||
static inline void set_bit(unsigned long nr, volatile unsigned long *addr)
|
||||
{
|
||||
unsigned long *ADDR, mask;
|
||||
|
||||
ADDR = ((unsigned long *) addr) + (nr >> 5);
|
||||
mask = 1 << (nr & 31);
|
||||
|
||||
(void) ___set_bit(ADDR, mask);
|
||||
}
|
||||
|
||||
static inline int test_and_clear_bit(unsigned long nr, volatile unsigned long *addr)
|
||||
{
|
||||
unsigned long *ADDR, mask;
|
||||
|
||||
ADDR = ((unsigned long *) addr) + (nr >> 5);
|
||||
mask = 1 << (nr & 31);
|
||||
|
||||
return ___clear_bit(ADDR, mask) != 0;
|
||||
}
|
||||
|
||||
static inline void clear_bit(unsigned long nr, volatile unsigned long *addr)
|
||||
{
|
||||
unsigned long *ADDR, mask;
|
||||
|
||||
ADDR = ((unsigned long *) addr) + (nr >> 5);
|
||||
mask = 1 << (nr & 31);
|
||||
|
||||
(void) ___clear_bit(ADDR, mask);
|
||||
}
|
||||
|
||||
static inline int test_and_change_bit(unsigned long nr, volatile unsigned long *addr)
|
||||
{
|
||||
unsigned long *ADDR, mask;
|
||||
|
||||
ADDR = ((unsigned long *) addr) + (nr >> 5);
|
||||
mask = 1 << (nr & 31);
|
||||
|
||||
return ___change_bit(ADDR, mask) != 0;
|
||||
}
|
||||
|
||||
static inline void change_bit(unsigned long nr, volatile unsigned long *addr)
|
||||
{
|
||||
unsigned long *ADDR, mask;
|
||||
|
||||
ADDR = ((unsigned long *) addr) + (nr >> 5);
|
||||
mask = 1 << (nr & 31);
|
||||
|
||||
(void) ___change_bit(ADDR, mask);
|
||||
}
|
||||
|
||||
#include <asm-generic/bitops/non-atomic.h>
|
||||
|
||||
#define smp_mb__before_clear_bit() do { } while(0)
|
||||
#define smp_mb__after_clear_bit() do { } while(0)
|
||||
|
||||
#include <asm-generic/bitops/ffz.h>
|
||||
#include <asm-generic/bitops/__ffs.h>
|
||||
#include <asm-generic/bitops/sched.h>
|
||||
#include <asm-generic/bitops/ffs.h>
|
||||
#include <asm-generic/bitops/fls.h>
|
||||
#include <asm-generic/bitops/fls64.h>
|
||||
#include <asm-generic/bitops/hweight.h>
|
||||
#include <asm-generic/bitops/lock.h>
|
||||
#include <asm-generic/bitops/find.h>
|
||||
#include <asm-generic/bitops/ext2-non-atomic.h>
|
||||
#include <asm-generic/bitops/ext2-atomic.h>
|
||||
#include <asm-generic/bitops/minix.h>
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
#endif /* defined(_SPARC_BITOPS_H) */
|
107
include/asm-sparc/bitops_64.h
Normal file
107
include/asm-sparc/bitops_64.h
Normal file
|
@ -0,0 +1,107 @@
|
|||
/*
|
||||
* bitops.h: Bit string operations on the V9.
|
||||
*
|
||||
* Copyright 1996, 1997 David S. Miller (davem@caip.rutgers.edu)
|
||||
*/
|
||||
|
||||
#ifndef _SPARC64_BITOPS_H
|
||||
#define _SPARC64_BITOPS_H
|
||||
|
||||
#ifndef _LINUX_BITOPS_H
|
||||
#error only <linux/bitops.h> can be included directly
|
||||
#endif
|
||||
|
||||
#include <linux/compiler.h>
|
||||
#include <asm/byteorder.h>
|
||||
|
||||
extern int test_and_set_bit(unsigned long nr, volatile unsigned long *addr);
|
||||
extern int test_and_clear_bit(unsigned long nr, volatile unsigned long *addr);
|
||||
extern int test_and_change_bit(unsigned long nr, volatile unsigned long *addr);
|
||||
extern void set_bit(unsigned long nr, volatile unsigned long *addr);
|
||||
extern void clear_bit(unsigned long nr, volatile unsigned long *addr);
|
||||
extern void change_bit(unsigned long nr, volatile unsigned long *addr);
|
||||
|
||||
#include <asm-generic/bitops/non-atomic.h>
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
#define smp_mb__before_clear_bit() membar_storeload_loadload()
|
||||
#define smp_mb__after_clear_bit() membar_storeload_storestore()
|
||||
#else
|
||||
#define smp_mb__before_clear_bit() barrier()
|
||||
#define smp_mb__after_clear_bit() barrier()
|
||||
#endif
|
||||
|
||||
#include <asm-generic/bitops/ffz.h>
|
||||
#include <asm-generic/bitops/__ffs.h>
|
||||
#include <asm-generic/bitops/fls.h>
|
||||
#include <asm-generic/bitops/__fls.h>
|
||||
#include <asm-generic/bitops/fls64.h>
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
#include <asm-generic/bitops/sched.h>
|
||||
#include <asm-generic/bitops/ffs.h>
|
||||
|
||||
/*
|
||||
* hweightN: returns the hamming weight (i.e. the number
|
||||
* of bits set) of a N-bit word
|
||||
*/
|
||||
|
||||
#ifdef ULTRA_HAS_POPULATION_COUNT
|
||||
|
||||
static inline unsigned int hweight64(unsigned long w)
|
||||
{
|
||||
unsigned int res;
|
||||
|
||||
__asm__ ("popc %1,%0" : "=r" (res) : "r" (w));
|
||||
return res;
|
||||
}
|
||||
|
||||
static inline unsigned int hweight32(unsigned int w)
|
||||
{
|
||||
unsigned int res;
|
||||
|
||||
__asm__ ("popc %1,%0" : "=r" (res) : "r" (w & 0xffffffff));
|
||||
return res;
|
||||
}
|
||||
|
||||
static inline unsigned int hweight16(unsigned int w)
|
||||
{
|
||||
unsigned int res;
|
||||
|
||||
__asm__ ("popc %1,%0" : "=r" (res) : "r" (w & 0xffff));
|
||||
return res;
|
||||
}
|
||||
|
||||
static inline unsigned int hweight8(unsigned int w)
|
||||
{
|
||||
unsigned int res;
|
||||
|
||||
__asm__ ("popc %1,%0" : "=r" (res) : "r" (w & 0xff));
|
||||
return res;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#include <asm-generic/bitops/hweight.h>
|
||||
|
||||
#endif
|
||||
#include <asm-generic/bitops/lock.h>
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
#include <asm-generic/bitops/find.h>
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
#include <asm-generic/bitops/ext2-non-atomic.h>
|
||||
|
||||
#define ext2_set_bit_atomic(lock,nr,addr) \
|
||||
test_and_set_bit((nr) ^ 0x38,(unsigned long *)(addr))
|
||||
#define ext2_clear_bit_atomic(lock,nr,addr) \
|
||||
test_and_clear_bit((nr) ^ 0x38,(unsigned long *)(addr))
|
||||
|
||||
#include <asm-generic/bitops/minix.h>
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
#endif /* defined(_SPARC64_BITOPS_H) */
|
|
@ -1,85 +1,8 @@
|
|||
#ifndef _SPARC_CACHEFLUSH_H
|
||||
#define _SPARC_CACHEFLUSH_H
|
||||
|
||||
#include <linux/mm.h> /* Common for other includes */
|
||||
// #include <linux/kernel.h> from pgalloc.h
|
||||
// #include <linux/sched.h> from pgalloc.h
|
||||
|
||||
// #include <asm/page.h>
|
||||
#include <asm/btfixup.h>
|
||||
|
||||
/*
|
||||
* Fine grained cache flushing.
|
||||
*/
|
||||
#ifdef CONFIG_SMP
|
||||
|
||||
BTFIXUPDEF_CALL(void, local_flush_cache_all, void)
|
||||
BTFIXUPDEF_CALL(void, local_flush_cache_mm, struct mm_struct *)
|
||||
BTFIXUPDEF_CALL(void, local_flush_cache_range, struct vm_area_struct *, unsigned long, unsigned long)
|
||||
BTFIXUPDEF_CALL(void, local_flush_cache_page, struct vm_area_struct *, unsigned long)
|
||||
|
||||
#define local_flush_cache_all() BTFIXUP_CALL(local_flush_cache_all)()
|
||||
#define local_flush_cache_mm(mm) BTFIXUP_CALL(local_flush_cache_mm)(mm)
|
||||
#define local_flush_cache_range(vma,start,end) BTFIXUP_CALL(local_flush_cache_range)(vma,start,end)
|
||||
#define local_flush_cache_page(vma,addr) BTFIXUP_CALL(local_flush_cache_page)(vma,addr)
|
||||
|
||||
BTFIXUPDEF_CALL(void, local_flush_page_to_ram, unsigned long)
|
||||
BTFIXUPDEF_CALL(void, local_flush_sig_insns, struct mm_struct *, unsigned long)
|
||||
|
||||
#define local_flush_page_to_ram(addr) BTFIXUP_CALL(local_flush_page_to_ram)(addr)
|
||||
#define local_flush_sig_insns(mm,insn_addr) BTFIXUP_CALL(local_flush_sig_insns)(mm,insn_addr)
|
||||
|
||||
extern void smp_flush_cache_all(void);
|
||||
extern void smp_flush_cache_mm(struct mm_struct *mm);
|
||||
extern void smp_flush_cache_range(struct vm_area_struct *vma,
|
||||
unsigned long start,
|
||||
unsigned long end);
|
||||
extern void smp_flush_cache_page(struct vm_area_struct *vma, unsigned long page);
|
||||
|
||||
extern void smp_flush_page_to_ram(unsigned long page);
|
||||
extern void smp_flush_sig_insns(struct mm_struct *mm, unsigned long insn_addr);
|
||||
|
||||
#endif /* CONFIG_SMP */
|
||||
|
||||
BTFIXUPDEF_CALL(void, flush_cache_all, void)
|
||||
BTFIXUPDEF_CALL(void, flush_cache_mm, struct mm_struct *)
|
||||
BTFIXUPDEF_CALL(void, flush_cache_range, struct vm_area_struct *, unsigned long, unsigned long)
|
||||
BTFIXUPDEF_CALL(void, flush_cache_page, struct vm_area_struct *, unsigned long)
|
||||
|
||||
#define flush_cache_all() BTFIXUP_CALL(flush_cache_all)()
|
||||
#define flush_cache_mm(mm) BTFIXUP_CALL(flush_cache_mm)(mm)
|
||||
#define flush_cache_dup_mm(mm) BTFIXUP_CALL(flush_cache_mm)(mm)
|
||||
#define flush_cache_range(vma,start,end) BTFIXUP_CALL(flush_cache_range)(vma,start,end)
|
||||
#define flush_cache_page(vma,addr,pfn) BTFIXUP_CALL(flush_cache_page)(vma,addr)
|
||||
#define flush_icache_range(start, end) do { } while (0)
|
||||
#define flush_icache_page(vma, pg) do { } while (0)
|
||||
|
||||
#define flush_icache_user_range(vma,pg,adr,len) do { } while (0)
|
||||
|
||||
#define copy_to_user_page(vma, page, vaddr, dst, src, len) \
|
||||
do { \
|
||||
flush_cache_page(vma, vaddr, page_to_pfn(page));\
|
||||
memcpy(dst, src, len); \
|
||||
} while (0)
|
||||
#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
|
||||
do { \
|
||||
flush_cache_page(vma, vaddr, page_to_pfn(page));\
|
||||
memcpy(dst, src, len); \
|
||||
} while (0)
|
||||
|
||||
BTFIXUPDEF_CALL(void, __flush_page_to_ram, unsigned long)
|
||||
BTFIXUPDEF_CALL(void, flush_sig_insns, struct mm_struct *, unsigned long)
|
||||
|
||||
#define __flush_page_to_ram(addr) BTFIXUP_CALL(__flush_page_to_ram)(addr)
|
||||
#define flush_sig_insns(mm,insn_addr) BTFIXUP_CALL(flush_sig_insns)(mm,insn_addr)
|
||||
|
||||
extern void sparc_flush_page_to_ram(struct page *page);
|
||||
|
||||
#define flush_dcache_page(page) sparc_flush_page_to_ram(page)
|
||||
#define flush_dcache_mmap_lock(mapping) do { } while (0)
|
||||
#define flush_dcache_mmap_unlock(mapping) do { } while (0)
|
||||
|
||||
#define flush_cache_vmap(start, end) flush_cache_all()
|
||||
#define flush_cache_vunmap(start, end) flush_cache_all()
|
||||
|
||||
#endif /* _SPARC_CACHEFLUSH_H */
|
||||
#ifndef ___ASM_SPARC_CACHEFLUSH_H
|
||||
#define ___ASM_SPARC_CACHEFLUSH_H
|
||||
#if defined(__sparc__) && defined(__arch64__)
|
||||
#include <asm-sparc/cacheflush_64.h>
|
||||
#else
|
||||
#include <asm-sparc/cacheflush_32.h>
|
||||
#endif
|
||||
#endif
|
||||
|
|
85
include/asm-sparc/cacheflush_32.h
Normal file
85
include/asm-sparc/cacheflush_32.h
Normal file
|
@ -0,0 +1,85 @@
|
|||
#ifndef _SPARC_CACHEFLUSH_H
|
||||
#define _SPARC_CACHEFLUSH_H
|
||||
|
||||
#include <linux/mm.h> /* Common for other includes */
|
||||
// #include <linux/kernel.h> from pgalloc.h
|
||||
// #include <linux/sched.h> from pgalloc.h
|
||||
|
||||
// #include <asm/page.h>
|
||||
#include <asm/btfixup.h>
|
||||
|
||||
/*
|
||||
* Fine grained cache flushing.
|
||||
*/
|
||||
#ifdef CONFIG_SMP
|
||||
|
||||
BTFIXUPDEF_CALL(void, local_flush_cache_all, void)
|
||||
BTFIXUPDEF_CALL(void, local_flush_cache_mm, struct mm_struct *)
|
||||
BTFIXUPDEF_CALL(void, local_flush_cache_range, struct vm_area_struct *, unsigned long, unsigned long)
|
||||
BTFIXUPDEF_CALL(void, local_flush_cache_page, struct vm_area_struct *, unsigned long)
|
||||
|
||||
#define local_flush_cache_all() BTFIXUP_CALL(local_flush_cache_all)()
|
||||
#define local_flush_cache_mm(mm) BTFIXUP_CALL(local_flush_cache_mm)(mm)
|
||||
#define local_flush_cache_range(vma,start,end) BTFIXUP_CALL(local_flush_cache_range)(vma,start,end)
|
||||
#define local_flush_cache_page(vma,addr) BTFIXUP_CALL(local_flush_cache_page)(vma,addr)
|
||||
|
||||
BTFIXUPDEF_CALL(void, local_flush_page_to_ram, unsigned long)
|
||||
BTFIXUPDEF_CALL(void, local_flush_sig_insns, struct mm_struct *, unsigned long)
|
||||
|
||||
#define local_flush_page_to_ram(addr) BTFIXUP_CALL(local_flush_page_to_ram)(addr)
|
||||
#define local_flush_sig_insns(mm,insn_addr) BTFIXUP_CALL(local_flush_sig_insns)(mm,insn_addr)
|
||||
|
||||
extern void smp_flush_cache_all(void);
|
||||
extern void smp_flush_cache_mm(struct mm_struct *mm);
|
||||
extern void smp_flush_cache_range(struct vm_area_struct *vma,
|
||||
unsigned long start,
|
||||
unsigned long end);
|
||||
extern void smp_flush_cache_page(struct vm_area_struct *vma, unsigned long page);
|
||||
|
||||
extern void smp_flush_page_to_ram(unsigned long page);
|
||||
extern void smp_flush_sig_insns(struct mm_struct *mm, unsigned long insn_addr);
|
||||
|
||||
#endif /* CONFIG_SMP */
|
||||
|
||||
BTFIXUPDEF_CALL(void, flush_cache_all, void)
|
||||
BTFIXUPDEF_CALL(void, flush_cache_mm, struct mm_struct *)
|
||||
BTFIXUPDEF_CALL(void, flush_cache_range, struct vm_area_struct *, unsigned long, unsigned long)
|
||||
BTFIXUPDEF_CALL(void, flush_cache_page, struct vm_area_struct *, unsigned long)
|
||||
|
||||
#define flush_cache_all() BTFIXUP_CALL(flush_cache_all)()
|
||||
#define flush_cache_mm(mm) BTFIXUP_CALL(flush_cache_mm)(mm)
|
||||
#define flush_cache_dup_mm(mm) BTFIXUP_CALL(flush_cache_mm)(mm)
|
||||
#define flush_cache_range(vma,start,end) BTFIXUP_CALL(flush_cache_range)(vma,start,end)
|
||||
#define flush_cache_page(vma,addr,pfn) BTFIXUP_CALL(flush_cache_page)(vma,addr)
|
||||
#define flush_icache_range(start, end) do { } while (0)
|
||||
#define flush_icache_page(vma, pg) do { } while (0)
|
||||
|
||||
#define flush_icache_user_range(vma,pg,adr,len) do { } while (0)
|
||||
|
||||
#define copy_to_user_page(vma, page, vaddr, dst, src, len) \
|
||||
do { \
|
||||
flush_cache_page(vma, vaddr, page_to_pfn(page));\
|
||||
memcpy(dst, src, len); \
|
||||
} while (0)
|
||||
#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
|
||||
do { \
|
||||
flush_cache_page(vma, vaddr, page_to_pfn(page));\
|
||||
memcpy(dst, src, len); \
|
||||
} while (0)
|
||||
|
||||
BTFIXUPDEF_CALL(void, __flush_page_to_ram, unsigned long)
|
||||
BTFIXUPDEF_CALL(void, flush_sig_insns, struct mm_struct *, unsigned long)
|
||||
|
||||
#define __flush_page_to_ram(addr) BTFIXUP_CALL(__flush_page_to_ram)(addr)
|
||||
#define flush_sig_insns(mm,insn_addr) BTFIXUP_CALL(flush_sig_insns)(mm,insn_addr)
|
||||
|
||||
extern void sparc_flush_page_to_ram(struct page *page);
|
||||
|
||||
#define flush_dcache_page(page) sparc_flush_page_to_ram(page)
|
||||
#define flush_dcache_mmap_lock(mapping) do { } while (0)
|
||||
#define flush_dcache_mmap_unlock(mapping) do { } while (0)
|
||||
|
||||
#define flush_cache_vmap(start, end) flush_cache_all()
|
||||
#define flush_cache_vunmap(start, end) flush_cache_all()
|
||||
|
||||
#endif /* _SPARC_CACHEFLUSH_H */
|
76
include/asm-sparc/cacheflush_64.h
Normal file
76
include/asm-sparc/cacheflush_64.h
Normal file
|
@ -0,0 +1,76 @@
|
|||
#ifndef _SPARC64_CACHEFLUSH_H
|
||||
#define _SPARC64_CACHEFLUSH_H
|
||||
|
||||
#include <asm/page.h>
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
#include <linux/mm.h>
|
||||
|
||||
/* Cache flush operations. */
|
||||
|
||||
/* These are the same regardless of whether this is an SMP kernel or not. */
|
||||
#define flush_cache_mm(__mm) \
|
||||
do { if ((__mm) == current->mm) flushw_user(); } while(0)
|
||||
#define flush_cache_dup_mm(mm) flush_cache_mm(mm)
|
||||
#define flush_cache_range(vma, start, end) \
|
||||
flush_cache_mm((vma)->vm_mm)
|
||||
#define flush_cache_page(vma, page, pfn) \
|
||||
flush_cache_mm((vma)->vm_mm)
|
||||
|
||||
/*
|
||||
* On spitfire, the icache doesn't snoop local stores and we don't
|
||||
* use block commit stores (which invalidate icache lines) during
|
||||
* module load, so we need this.
|
||||
*/
|
||||
extern void flush_icache_range(unsigned long start, unsigned long end);
|
||||
extern void __flush_icache_page(unsigned long);
|
||||
|
||||
extern void __flush_dcache_page(void *addr, int flush_icache);
|
||||
extern void flush_dcache_page_impl(struct page *page);
|
||||
#ifdef CONFIG_SMP
|
||||
extern void smp_flush_dcache_page_impl(struct page *page, int cpu);
|
||||
extern void flush_dcache_page_all(struct mm_struct *mm, struct page *page);
|
||||
#else
|
||||
#define smp_flush_dcache_page_impl(page,cpu) flush_dcache_page_impl(page)
|
||||
#define flush_dcache_page_all(mm,page) flush_dcache_page_impl(page)
|
||||
#endif
|
||||
|
||||
extern void __flush_dcache_range(unsigned long start, unsigned long end);
|
||||
extern void flush_dcache_page(struct page *page);
|
||||
|
||||
#define flush_icache_page(vma, pg) do { } while(0)
|
||||
#define flush_icache_user_range(vma,pg,adr,len) do { } while (0)
|
||||
|
||||
extern void flush_ptrace_access(struct vm_area_struct *, struct page *,
|
||||
unsigned long uaddr, void *kaddr,
|
||||
unsigned long len, int write);
|
||||
|
||||
#define copy_to_user_page(vma, page, vaddr, dst, src, len) \
|
||||
do { \
|
||||
flush_cache_page(vma, vaddr, page_to_pfn(page)); \
|
||||
memcpy(dst, src, len); \
|
||||
flush_ptrace_access(vma, page, vaddr, src, len, 0); \
|
||||
} while (0)
|
||||
|
||||
#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
|
||||
do { \
|
||||
flush_cache_page(vma, vaddr, page_to_pfn(page)); \
|
||||
memcpy(dst, src, len); \
|
||||
flush_ptrace_access(vma, page, vaddr, dst, len, 1); \
|
||||
} while (0)
|
||||
|
||||
#define flush_dcache_mmap_lock(mapping) do { } while (0)
|
||||
#define flush_dcache_mmap_unlock(mapping) do { } while (0)
|
||||
|
||||
#define flush_cache_vmap(start, end) do { } while (0)
|
||||
#define flush_cache_vunmap(start, end) do { } while (0)
|
||||
|
||||
#ifdef CONFIG_DEBUG_PAGEALLOC
|
||||
/* internal debugging function */
|
||||
void kernel_map_pages(struct page *page, int numpages, int enable);
|
||||
#endif
|
||||
|
||||
#endif /* !__ASSEMBLY__ */
|
||||
|
||||
#endif /* _SPARC64_CACHEFLUSH_H */
|
|
@ -1,241 +1,8 @@
|
|||
#ifndef __SPARC_CHECKSUM_H
|
||||
#define __SPARC_CHECKSUM_H
|
||||
|
||||
/* checksum.h: IP/UDP/TCP checksum routines on the Sparc.
|
||||
*
|
||||
* Copyright(C) 1995 Linus Torvalds
|
||||
* Copyright(C) 1995 Miguel de Icaza
|
||||
* Copyright(C) 1996 David S. Miller
|
||||
* Copyright(C) 1996 Eddie C. Dost
|
||||
* Copyright(C) 1997 Jakub Jelinek
|
||||
*
|
||||
* derived from:
|
||||
* Alpha checksum c-code
|
||||
* ix86 inline assembly
|
||||
* RFC1071 Computing the Internet Checksum
|
||||
*/
|
||||
|
||||
#include <linux/in6.h>
|
||||
#include <asm/uaccess.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
|
||||
*/
|
||||
extern __wsum csum_partial(const void *buff, int len, __wsum sum);
|
||||
|
||||
/* the same as csum_partial, but copies from fs:src while it
|
||||
* checksums
|
||||
*
|
||||
* here even more important to align src and dst on a 32-bit (or even
|
||||
* better 64-bit) boundary
|
||||
*/
|
||||
|
||||
extern unsigned int __csum_partial_copy_sparc_generic (const unsigned char *, unsigned char *);
|
||||
|
||||
static inline __wsum
|
||||
csum_partial_copy_nocheck(const void *src, void *dst, int len, __wsum sum)
|
||||
{
|
||||
register unsigned int ret asm("o0") = (unsigned int)src;
|
||||
register char *d asm("o1") = dst;
|
||||
register int l asm("g1") = len;
|
||||
|
||||
__asm__ __volatile__ (
|
||||
"call __csum_partial_copy_sparc_generic\n\t"
|
||||
" mov %6, %%g7\n"
|
||||
: "=&r" (ret), "=&r" (d), "=&r" (l)
|
||||
: "0" (ret), "1" (d), "2" (l), "r" (sum)
|
||||
: "o2", "o3", "o4", "o5", "o7",
|
||||
"g2", "g3", "g4", "g5", "g7",
|
||||
"memory", "cc");
|
||||
return (__force __wsum)ret;
|
||||
}
|
||||
|
||||
static inline __wsum
|
||||
csum_partial_copy_from_user(const void __user *src, void *dst, int len,
|
||||
__wsum sum, int *err)
|
||||
{
|
||||
register unsigned long ret asm("o0") = (unsigned long)src;
|
||||
register char *d asm("o1") = dst;
|
||||
register int l asm("g1") = len;
|
||||
register __wsum s asm("g7") = sum;
|
||||
|
||||
__asm__ __volatile__ (
|
||||
".section __ex_table,#alloc\n\t"
|
||||
".align 4\n\t"
|
||||
".word 1f,2\n\t"
|
||||
".previous\n"
|
||||
"1:\n\t"
|
||||
"call __csum_partial_copy_sparc_generic\n\t"
|
||||
" st %8, [%%sp + 64]\n"
|
||||
: "=&r" (ret), "=&r" (d), "=&r" (l), "=&r" (s)
|
||||
: "0" (ret), "1" (d), "2" (l), "3" (s), "r" (err)
|
||||
: "o2", "o3", "o4", "o5", "o7", "g2", "g3", "g4", "g5",
|
||||
"cc", "memory");
|
||||
return (__force __wsum)ret;
|
||||
}
|
||||
|
||||
static inline __wsum
|
||||
csum_partial_copy_to_user(const void *src, void __user *dst, int len,
|
||||
__wsum sum, int *err)
|
||||
{
|
||||
if (!access_ok (VERIFY_WRITE, dst, len)) {
|
||||
*err = -EFAULT;
|
||||
return sum;
|
||||
} else {
|
||||
register unsigned long ret asm("o0") = (unsigned long)src;
|
||||
register char __user *d asm("o1") = dst;
|
||||
register int l asm("g1") = len;
|
||||
register __wsum s asm("g7") = sum;
|
||||
|
||||
__asm__ __volatile__ (
|
||||
".section __ex_table,#alloc\n\t"
|
||||
".align 4\n\t"
|
||||
".word 1f,1\n\t"
|
||||
".previous\n"
|
||||
"1:\n\t"
|
||||
"call __csum_partial_copy_sparc_generic\n\t"
|
||||
" st %8, [%%sp + 64]\n"
|
||||
: "=&r" (ret), "=&r" (d), "=&r" (l), "=&r" (s)
|
||||
: "0" (ret), "1" (d), "2" (l), "3" (s), "r" (err)
|
||||
: "o2", "o3", "o4", "o5", "o7",
|
||||
"g2", "g3", "g4", "g5",
|
||||
"cc", "memory");
|
||||
return (__force __wsum)ret;
|
||||
}
|
||||
}
|
||||
|
||||
#define HAVE_CSUM_COPY_USER
|
||||
#define csum_and_copy_to_user csum_partial_copy_to_user
|
||||
|
||||
/* ihl is always 5 or greater, almost always is 5, and iph is word aligned
|
||||
* the majority of the time.
|
||||
*/
|
||||
static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl)
|
||||
{
|
||||
__sum16 sum;
|
||||
|
||||
/* Note: We must read %2 before we touch %0 for the first time,
|
||||
* because GCC can legitimately use the same register for
|
||||
* both operands.
|
||||
*/
|
||||
__asm__ __volatile__("sub\t%2, 4, %%g4\n\t"
|
||||
"ld\t[%1 + 0x00], %0\n\t"
|
||||
"ld\t[%1 + 0x04], %%g2\n\t"
|
||||
"ld\t[%1 + 0x08], %%g3\n\t"
|
||||
"addcc\t%%g2, %0, %0\n\t"
|
||||
"addxcc\t%%g3, %0, %0\n\t"
|
||||
"ld\t[%1 + 0x0c], %%g2\n\t"
|
||||
"ld\t[%1 + 0x10], %%g3\n\t"
|
||||
"addxcc\t%%g2, %0, %0\n\t"
|
||||
"addx\t%0, %%g0, %0\n"
|
||||
"1:\taddcc\t%%g3, %0, %0\n\t"
|
||||
"add\t%1, 4, %1\n\t"
|
||||
"addxcc\t%0, %%g0, %0\n\t"
|
||||
"subcc\t%%g4, 1, %%g4\n\t"
|
||||
"be,a\t2f\n\t"
|
||||
"sll\t%0, 16, %%g2\n\t"
|
||||
"b\t1b\n\t"
|
||||
"ld\t[%1 + 0x10], %%g3\n"
|
||||
"2:\taddcc\t%0, %%g2, %%g2\n\t"
|
||||
"srl\t%%g2, 16, %0\n\t"
|
||||
"addx\t%0, %%g0, %0\n\t"
|
||||
"xnor\t%%g0, %0, %0"
|
||||
: "=r" (sum), "=&r" (iph)
|
||||
: "r" (ihl), "1" (iph)
|
||||
: "g2", "g3", "g4", "cc", "memory");
|
||||
return sum;
|
||||
}
|
||||
|
||||
/* Fold a partial checksum without adding pseudo headers. */
|
||||
static inline __sum16 csum_fold(__wsum sum)
|
||||
{
|
||||
unsigned int tmp;
|
||||
|
||||
__asm__ __volatile__("addcc\t%0, %1, %1\n\t"
|
||||
"srl\t%1, 16, %1\n\t"
|
||||
"addx\t%1, %%g0, %1\n\t"
|
||||
"xnor\t%%g0, %1, %0"
|
||||
: "=&r" (sum), "=r" (tmp)
|
||||
: "0" (sum), "1" ((__force u32)sum<<16)
|
||||
: "cc");
|
||||
return (__force __sum16)sum;
|
||||
}
|
||||
|
||||
static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
|
||||
unsigned short len,
|
||||
unsigned short proto,
|
||||
__wsum sum)
|
||||
{
|
||||
__asm__ __volatile__("addcc\t%1, %0, %0\n\t"
|
||||
"addxcc\t%2, %0, %0\n\t"
|
||||
"addxcc\t%3, %0, %0\n\t"
|
||||
"addx\t%0, %%g0, %0\n\t"
|
||||
: "=r" (sum), "=r" (saddr)
|
||||
: "r" (daddr), "r" (proto + len), "0" (sum),
|
||||
"1" (saddr)
|
||||
: "cc");
|
||||
return sum;
|
||||
}
|
||||
|
||||
/*
|
||||
* computes the checksum of the TCP/UDP pseudo-header
|
||||
* returns a 16-bit checksum, already complemented
|
||||
*/
|
||||
static inline __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr,
|
||||
unsigned short len,
|
||||
unsigned short proto,
|
||||
__wsum sum)
|
||||
{
|
||||
return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum));
|
||||
}
|
||||
|
||||
#define _HAVE_ARCH_IPV6_CSUM
|
||||
|
||||
static inline __sum16 csum_ipv6_magic(const struct in6_addr *saddr,
|
||||
const struct in6_addr *daddr,
|
||||
__u32 len, unsigned short proto,
|
||||
__wsum sum)
|
||||
{
|
||||
__asm__ __volatile__ (
|
||||
"addcc %3, %4, %%g4\n\t"
|
||||
"addxcc %5, %%g4, %%g4\n\t"
|
||||
"ld [%2 + 0x0c], %%g2\n\t"
|
||||
"ld [%2 + 0x08], %%g3\n\t"
|
||||
"addxcc %%g2, %%g4, %%g4\n\t"
|
||||
"ld [%2 + 0x04], %%g2\n\t"
|
||||
"addxcc %%g3, %%g4, %%g4\n\t"
|
||||
"ld [%2 + 0x00], %%g3\n\t"
|
||||
"addxcc %%g2, %%g4, %%g4\n\t"
|
||||
"ld [%1 + 0x0c], %%g2\n\t"
|
||||
"addxcc %%g3, %%g4, %%g4\n\t"
|
||||
"ld [%1 + 0x08], %%g3\n\t"
|
||||
"addxcc %%g2, %%g4, %%g4\n\t"
|
||||
"ld [%1 + 0x04], %%g2\n\t"
|
||||
"addxcc %%g3, %%g4, %%g4\n\t"
|
||||
"ld [%1 + 0x00], %%g3\n\t"
|
||||
"addxcc %%g2, %%g4, %%g4\n\t"
|
||||
"addxcc %%g3, %%g4, %0\n\t"
|
||||
"addx 0, %0, %0\n"
|
||||
: "=&r" (sum)
|
||||
: "r" (saddr), "r" (daddr),
|
||||
"r"(htonl(len)), "r"(htonl(proto)), "r"(sum)
|
||||
: "g2", "g3", "g4", "cc");
|
||||
|
||||
return csum_fold(sum);
|
||||
}
|
||||
|
||||
/* this routine is used for miscellaneous IP-like checksums, mainly in icmp.c */
|
||||
static inline __sum16 ip_compute_csum(const void *buff, int len)
|
||||
{
|
||||
return csum_fold(csum_partial(buff, len, 0));
|
||||
}
|
||||
|
||||
#endif /* !(__SPARC_CHECKSUM_H) */
|
||||
#ifndef ___ASM_SPARC_CHECKSUM_H
|
||||
#define ___ASM_SPARC_CHECKSUM_H
|
||||
#if defined(__sparc__) && defined(__arch64__)
|
||||
#include <asm-sparc/checksum_64.h>
|
||||
#else
|
||||
#include <asm-sparc/checksum_32.h>
|
||||
#endif
|
||||
#endif
|
||||
|
|
241
include/asm-sparc/checksum_32.h
Normal file
241
include/asm-sparc/checksum_32.h
Normal file
|
@ -0,0 +1,241 @@
|
|||
#ifndef __SPARC_CHECKSUM_H
|
||||
#define __SPARC_CHECKSUM_H
|
||||
|
||||
/* checksum.h: IP/UDP/TCP checksum routines on the Sparc.
|
||||
*
|
||||
* Copyright(C) 1995 Linus Torvalds
|
||||
* Copyright(C) 1995 Miguel de Icaza
|
||||
* Copyright(C) 1996 David S. Miller
|
||||
* Copyright(C) 1996 Eddie C. Dost
|
||||
* Copyright(C) 1997 Jakub Jelinek
|
||||
*
|
||||
* derived from:
|
||||
* Alpha checksum c-code
|
||||
* ix86 inline assembly
|
||||
* RFC1071 Computing the Internet Checksum
|
||||
*/
|
||||
|
||||
#include <linux/in6.h>
|
||||
#include <asm/uaccess.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
|
||||
*/
|
||||
extern __wsum csum_partial(const void *buff, int len, __wsum sum);
|
||||
|
||||
/* the same as csum_partial, but copies from fs:src while it
|
||||
* checksums
|
||||
*
|
||||
* here even more important to align src and dst on a 32-bit (or even
|
||||
* better 64-bit) boundary
|
||||
*/
|
||||
|
||||
extern unsigned int __csum_partial_copy_sparc_generic (const unsigned char *, unsigned char *);
|
||||
|
||||
static inline __wsum
|
||||
csum_partial_copy_nocheck(const void *src, void *dst, int len, __wsum sum)
|
||||
{
|
||||
register unsigned int ret asm("o0") = (unsigned int)src;
|
||||
register char *d asm("o1") = dst;
|
||||
register int l asm("g1") = len;
|
||||
|
||||
__asm__ __volatile__ (
|
||||
"call __csum_partial_copy_sparc_generic\n\t"
|
||||
" mov %6, %%g7\n"
|
||||
: "=&r" (ret), "=&r" (d), "=&r" (l)
|
||||
: "0" (ret), "1" (d), "2" (l), "r" (sum)
|
||||
: "o2", "o3", "o4", "o5", "o7",
|
||||
"g2", "g3", "g4", "g5", "g7",
|
||||
"memory", "cc");
|
||||
return (__force __wsum)ret;
|
||||
}
|
||||
|
||||
static inline __wsum
|
||||
csum_partial_copy_from_user(const void __user *src, void *dst, int len,
|
||||
__wsum sum, int *err)
|
||||
{
|
||||
register unsigned long ret asm("o0") = (unsigned long)src;
|
||||
register char *d asm("o1") = dst;
|
||||
register int l asm("g1") = len;
|
||||
register __wsum s asm("g7") = sum;
|
||||
|
||||
__asm__ __volatile__ (
|
||||
".section __ex_table,#alloc\n\t"
|
||||
".align 4\n\t"
|
||||
".word 1f,2\n\t"
|
||||
".previous\n"
|
||||
"1:\n\t"
|
||||
"call __csum_partial_copy_sparc_generic\n\t"
|
||||
" st %8, [%%sp + 64]\n"
|
||||
: "=&r" (ret), "=&r" (d), "=&r" (l), "=&r" (s)
|
||||
: "0" (ret), "1" (d), "2" (l), "3" (s), "r" (err)
|
||||
: "o2", "o3", "o4", "o5", "o7", "g2", "g3", "g4", "g5",
|
||||
"cc", "memory");
|
||||
return (__force __wsum)ret;
|
||||
}
|
||||
|
||||
static inline __wsum
|
||||
csum_partial_copy_to_user(const void *src, void __user *dst, int len,
|
||||
__wsum sum, int *err)
|
||||
{
|
||||
if (!access_ok (VERIFY_WRITE, dst, len)) {
|
||||
*err = -EFAULT;
|
||||
return sum;
|
||||
} else {
|
||||
register unsigned long ret asm("o0") = (unsigned long)src;
|
||||
register char __user *d asm("o1") = dst;
|
||||
register int l asm("g1") = len;
|
||||
register __wsum s asm("g7") = sum;
|
||||
|
||||
__asm__ __volatile__ (
|
||||
".section __ex_table,#alloc\n\t"
|
||||
".align 4\n\t"
|
||||
".word 1f,1\n\t"
|
||||
".previous\n"
|
||||
"1:\n\t"
|
||||
"call __csum_partial_copy_sparc_generic\n\t"
|
||||
" st %8, [%%sp + 64]\n"
|
||||
: "=&r" (ret), "=&r" (d), "=&r" (l), "=&r" (s)
|
||||
: "0" (ret), "1" (d), "2" (l), "3" (s), "r" (err)
|
||||
: "o2", "o3", "o4", "o5", "o7",
|
||||
"g2", "g3", "g4", "g5",
|
||||
"cc", "memory");
|
||||
return (__force __wsum)ret;
|
||||
}
|
||||
}
|
||||
|
||||
#define HAVE_CSUM_COPY_USER
|
||||
#define csum_and_copy_to_user csum_partial_copy_to_user
|
||||
|
||||
/* ihl is always 5 or greater, almost always is 5, and iph is word aligned
|
||||
* the majority of the time.
|
||||
*/
|
||||
static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl)
|
||||
{
|
||||
__sum16 sum;
|
||||
|
||||
/* Note: We must read %2 before we touch %0 for the first time,
|
||||
* because GCC can legitimately use the same register for
|
||||
* both operands.
|
||||
*/
|
||||
__asm__ __volatile__("sub\t%2, 4, %%g4\n\t"
|
||||
"ld\t[%1 + 0x00], %0\n\t"
|
||||
"ld\t[%1 + 0x04], %%g2\n\t"
|
||||
"ld\t[%1 + 0x08], %%g3\n\t"
|
||||
"addcc\t%%g2, %0, %0\n\t"
|
||||
"addxcc\t%%g3, %0, %0\n\t"
|
||||
"ld\t[%1 + 0x0c], %%g2\n\t"
|
||||
"ld\t[%1 + 0x10], %%g3\n\t"
|
||||
"addxcc\t%%g2, %0, %0\n\t"
|
||||
"addx\t%0, %%g0, %0\n"
|
||||
"1:\taddcc\t%%g3, %0, %0\n\t"
|
||||
"add\t%1, 4, %1\n\t"
|
||||
"addxcc\t%0, %%g0, %0\n\t"
|
||||
"subcc\t%%g4, 1, %%g4\n\t"
|
||||
"be,a\t2f\n\t"
|
||||
"sll\t%0, 16, %%g2\n\t"
|
||||
"b\t1b\n\t"
|
||||
"ld\t[%1 + 0x10], %%g3\n"
|
||||
"2:\taddcc\t%0, %%g2, %%g2\n\t"
|
||||
"srl\t%%g2, 16, %0\n\t"
|
||||
"addx\t%0, %%g0, %0\n\t"
|
||||
"xnor\t%%g0, %0, %0"
|
||||
: "=r" (sum), "=&r" (iph)
|
||||
: "r" (ihl), "1" (iph)
|
||||
: "g2", "g3", "g4", "cc", "memory");
|
||||
return sum;
|
||||
}
|
||||
|
||||
/* Fold a partial checksum without adding pseudo headers. */
|
||||
static inline __sum16 csum_fold(__wsum sum)
|
||||
{
|
||||
unsigned int tmp;
|
||||
|
||||
__asm__ __volatile__("addcc\t%0, %1, %1\n\t"
|
||||
"srl\t%1, 16, %1\n\t"
|
||||
"addx\t%1, %%g0, %1\n\t"
|
||||
"xnor\t%%g0, %1, %0"
|
||||
: "=&r" (sum), "=r" (tmp)
|
||||
: "0" (sum), "1" ((__force u32)sum<<16)
|
||||
: "cc");
|
||||
return (__force __sum16)sum;
|
||||
}
|
||||
|
||||
static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
|
||||
unsigned short len,
|
||||
unsigned short proto,
|
||||
__wsum sum)
|
||||
{
|
||||
__asm__ __volatile__("addcc\t%1, %0, %0\n\t"
|
||||
"addxcc\t%2, %0, %0\n\t"
|
||||
"addxcc\t%3, %0, %0\n\t"
|
||||
"addx\t%0, %%g0, %0\n\t"
|
||||
: "=r" (sum), "=r" (saddr)
|
||||
: "r" (daddr), "r" (proto + len), "0" (sum),
|
||||
"1" (saddr)
|
||||
: "cc");
|
||||
return sum;
|
||||
}
|
||||
|
||||
/*
|
||||
* computes the checksum of the TCP/UDP pseudo-header
|
||||
* returns a 16-bit checksum, already complemented
|
||||
*/
|
||||
static inline __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr,
|
||||
unsigned short len,
|
||||
unsigned short proto,
|
||||
__wsum sum)
|
||||
{
|
||||
return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum));
|
||||
}
|
||||
|
||||
#define _HAVE_ARCH_IPV6_CSUM
|
||||
|
||||
static inline __sum16 csum_ipv6_magic(const struct in6_addr *saddr,
|
||||
const struct in6_addr *daddr,
|
||||
__u32 len, unsigned short proto,
|
||||
__wsum sum)
|
||||
{
|
||||
__asm__ __volatile__ (
|
||||
"addcc %3, %4, %%g4\n\t"
|
||||
"addxcc %5, %%g4, %%g4\n\t"
|
||||
"ld [%2 + 0x0c], %%g2\n\t"
|
||||
"ld [%2 + 0x08], %%g3\n\t"
|
||||
"addxcc %%g2, %%g4, %%g4\n\t"
|
||||
"ld [%2 + 0x04], %%g2\n\t"
|
||||
"addxcc %%g3, %%g4, %%g4\n\t"
|
||||
"ld [%2 + 0x00], %%g3\n\t"
|
||||
"addxcc %%g2, %%g4, %%g4\n\t"
|
||||
"ld [%1 + 0x0c], %%g2\n\t"
|
||||
"addxcc %%g3, %%g4, %%g4\n\t"
|
||||
"ld [%1 + 0x08], %%g3\n\t"
|
||||
"addxcc %%g2, %%g4, %%g4\n\t"
|
||||
"ld [%1 + 0x04], %%g2\n\t"
|
||||
"addxcc %%g3, %%g4, %%g4\n\t"
|
||||
"ld [%1 + 0x00], %%g3\n\t"
|
||||
"addxcc %%g2, %%g4, %%g4\n\t"
|
||||
"addxcc %%g3, %%g4, %0\n\t"
|
||||
"addx 0, %0, %0\n"
|
||||
: "=&r" (sum)
|
||||
: "r" (saddr), "r" (daddr),
|
||||
"r"(htonl(len)), "r"(htonl(proto)), "r"(sum)
|
||||
: "g2", "g3", "g4", "cc");
|
||||
|
||||
return csum_fold(sum);
|
||||
}
|
||||
|
||||
/* this routine is used for miscellaneous IP-like checksums, mainly in icmp.c */
|
||||
static inline __sum16 ip_compute_csum(const void *buff, int len)
|
||||
{
|
||||
return csum_fold(csum_partial(buff, len, 0));
|
||||
}
|
||||
|
||||
#endif /* !(__SPARC_CHECKSUM_H) */
|
167
include/asm-sparc/checksum_64.h
Normal file
167
include/asm-sparc/checksum_64.h
Normal file
|
@ -0,0 +1,167 @@
|
|||
#ifndef __SPARC64_CHECKSUM_H
|
||||
#define __SPARC64_CHECKSUM_H
|
||||
|
||||
/* checksum.h: IP/UDP/TCP checksum routines on the V9.
|
||||
*
|
||||
* Copyright(C) 1995 Linus Torvalds
|
||||
* Copyright(C) 1995 Miguel de Icaza
|
||||
* Copyright(C) 1996 David S. Miller
|
||||
* Copyright(C) 1996 Eddie C. Dost
|
||||
* Copyright(C) 1997 Jakub Jelinek
|
||||
*
|
||||
* derived from:
|
||||
* Alpha checksum c-code
|
||||
* ix86 inline assembly
|
||||
* RFC1071 Computing the Internet Checksum
|
||||
*/
|
||||
|
||||
#include <linux/in6.h>
|
||||
#include <asm/uaccess.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
|
||||
*/
|
||||
extern __wsum csum_partial(const void * buff, int len, __wsum sum);
|
||||
|
||||
/* the same as csum_partial, but copies from user space while it
|
||||
* checksums
|
||||
*
|
||||
* here even more important to align src and dst on a 32-bit (or even
|
||||
* better 64-bit) boundary
|
||||
*/
|
||||
extern __wsum csum_partial_copy_nocheck(const void *src, void *dst,
|
||||
int len, __wsum sum);
|
||||
|
||||
extern long __csum_partial_copy_from_user(const void __user *src,
|
||||
void *dst, int len,
|
||||
__wsum sum);
|
||||
|
||||
static inline __wsum
|
||||
csum_partial_copy_from_user(const void __user *src,
|
||||
void *dst, int len,
|
||||
__wsum sum, int *err)
|
||||
{
|
||||
long ret = __csum_partial_copy_from_user(src, dst, len, sum);
|
||||
if (ret < 0)
|
||||
*err = -EFAULT;
|
||||
return (__force __wsum) ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy and checksum to user
|
||||
*/
|
||||
#define HAVE_CSUM_COPY_USER
|
||||
extern long __csum_partial_copy_to_user(const void *src,
|
||||
void __user *dst, int len,
|
||||
__wsum sum);
|
||||
|
||||
static inline __wsum
|
||||
csum_and_copy_to_user(const void *src,
|
||||
void __user *dst, int len,
|
||||
__wsum sum, int *err)
|
||||
{
|
||||
long ret = __csum_partial_copy_to_user(src, dst, len, sum);
|
||||
if (ret < 0)
|
||||
*err = -EFAULT;
|
||||
return (__force __wsum) ret;
|
||||
}
|
||||
|
||||
/* ihl is always 5 or greater, almost always is 5, and iph is word aligned
|
||||
* the majority of the time.
|
||||
*/
|
||||
extern __sum16 ip_fast_csum(const void *iph, unsigned int ihl);
|
||||
|
||||
/* Fold a partial checksum without adding pseudo headers. */
|
||||
static inline __sum16 csum_fold(__wsum sum)
|
||||
{
|
||||
unsigned int tmp;
|
||||
|
||||
__asm__ __volatile__(
|
||||
" addcc %0, %1, %1\n"
|
||||
" srl %1, 16, %1\n"
|
||||
" addc %1, %%g0, %1\n"
|
||||
" xnor %%g0, %1, %0\n"
|
||||
: "=&r" (sum), "=r" (tmp)
|
||||
: "0" (sum), "1" ((__force u32)sum<<16)
|
||||
: "cc");
|
||||
return (__force __sum16)sum;
|
||||
}
|
||||
|
||||
static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
|
||||
unsigned int len,
|
||||
unsigned short proto,
|
||||
__wsum sum)
|
||||
{
|
||||
__asm__ __volatile__(
|
||||
" addcc %1, %0, %0\n"
|
||||
" addccc %2, %0, %0\n"
|
||||
" addccc %3, %0, %0\n"
|
||||
" addc %0, %%g0, %0\n"
|
||||
: "=r" (sum), "=r" (saddr)
|
||||
: "r" (daddr), "r" (proto + len), "0" (sum), "1" (saddr)
|
||||
: "cc");
|
||||
return sum;
|
||||
}
|
||||
|
||||
/*
|
||||
* computes the checksum of the TCP/UDP pseudo-header
|
||||
* returns a 16-bit checksum, already complemented
|
||||
*/
|
||||
static inline __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr,
|
||||
unsigned short len,
|
||||
unsigned short proto,
|
||||
__wsum sum)
|
||||
{
|
||||
return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum));
|
||||
}
|
||||
|
||||
#define _HAVE_ARCH_IPV6_CSUM
|
||||
|
||||
static inline __sum16 csum_ipv6_magic(const struct in6_addr *saddr,
|
||||
const struct in6_addr *daddr,
|
||||
__u32 len, unsigned short proto,
|
||||
__wsum sum)
|
||||
{
|
||||
__asm__ __volatile__ (
|
||||
" addcc %3, %4, %%g7\n"
|
||||
" addccc %5, %%g7, %%g7\n"
|
||||
" lduw [%2 + 0x0c], %%g2\n"
|
||||
" lduw [%2 + 0x08], %%g3\n"
|
||||
" addccc %%g2, %%g7, %%g7\n"
|
||||
" lduw [%2 + 0x04], %%g2\n"
|
||||
" addccc %%g3, %%g7, %%g7\n"
|
||||
" lduw [%2 + 0x00], %%g3\n"
|
||||
" addccc %%g2, %%g7, %%g7\n"
|
||||
" lduw [%1 + 0x0c], %%g2\n"
|
||||
" addccc %%g3, %%g7, %%g7\n"
|
||||
" lduw [%1 + 0x08], %%g3\n"
|
||||
" addccc %%g2, %%g7, %%g7\n"
|
||||
" lduw [%1 + 0x04], %%g2\n"
|
||||
" addccc %%g3, %%g7, %%g7\n"
|
||||
" lduw [%1 + 0x00], %%g3\n"
|
||||
" addccc %%g2, %%g7, %%g7\n"
|
||||
" addccc %%g3, %%g7, %0\n"
|
||||
" addc 0, %0, %0\n"
|
||||
: "=&r" (sum)
|
||||
: "r" (saddr), "r" (daddr), "r"(htonl(len)),
|
||||
"r"(htonl(proto)), "r"(sum)
|
||||
: "g2", "g3", "g7", "cc");
|
||||
|
||||
return csum_fold(sum);
|
||||
}
|
||||
|
||||
/* this routine is used for miscellaneous IP-like checksums, mainly in icmp.c */
|
||||
static inline __sum16 ip_compute_csum(const void *buff, int len)
|
||||
{
|
||||
return csum_fold(csum_partial(buff, len, 0));
|
||||
}
|
||||
|
||||
#endif /* !(__SPARC64_CHECKSUM_H) */
|
|
@ -1,27 +1,8 @@
|
|||
/* cpudata.h: Per-cpu parameters.
|
||||
*
|
||||
* Copyright (C) 2004 Keith M Wesolowski (wesolows@foobazco.org)
|
||||
*
|
||||
* Based on include/asm-sparc64/cpudata.h and Linux 2.4 smp.h
|
||||
* both (C) David S. Miller.
|
||||
*/
|
||||
|
||||
#ifndef _SPARC_CPUDATA_H
|
||||
#define _SPARC_CPUDATA_H
|
||||
|
||||
#include <linux/percpu.h>
|
||||
|
||||
typedef struct {
|
||||
unsigned long udelay_val;
|
||||
unsigned long clock_tick;
|
||||
unsigned int multiplier;
|
||||
unsigned int counter;
|
||||
int prom_node;
|
||||
int mid;
|
||||
int next;
|
||||
} cpuinfo_sparc;
|
||||
|
||||
DECLARE_PER_CPU(cpuinfo_sparc, __cpu_data);
|
||||
#define cpu_data(__cpu) per_cpu(__cpu_data, (__cpu))
|
||||
|
||||
#endif /* _SPARC_CPUDATA_H */
|
||||
#ifndef ___ASM_SPARC_CPUDATA_H
|
||||
#define ___ASM_SPARC_CPUDATA_H
|
||||
#if defined(__sparc__) && defined(__arch64__)
|
||||
#include <asm-sparc/cpudata_64.h>
|
||||
#else
|
||||
#include <asm-sparc/cpudata_32.h>
|
||||
#endif
|
||||
#endif
|
||||
|
|
27
include/asm-sparc/cpudata_32.h
Normal file
27
include/asm-sparc/cpudata_32.h
Normal file
|
@ -0,0 +1,27 @@
|
|||
/* cpudata.h: Per-cpu parameters.
|
||||
*
|
||||
* Copyright (C) 2004 Keith M Wesolowski (wesolows@foobazco.org)
|
||||
*
|
||||
* Based on include/asm-sparc64/cpudata.h and Linux 2.4 smp.h
|
||||
* both (C) David S. Miller.
|
||||
*/
|
||||
|
||||
#ifndef _SPARC_CPUDATA_H
|
||||
#define _SPARC_CPUDATA_H
|
||||
|
||||
#include <linux/percpu.h>
|
||||
|
||||
typedef struct {
|
||||
unsigned long udelay_val;
|
||||
unsigned long clock_tick;
|
||||
unsigned int multiplier;
|
||||
unsigned int counter;
|
||||
int prom_node;
|
||||
int mid;
|
||||
int next;
|
||||
} cpuinfo_sparc;
|
||||
|
||||
DECLARE_PER_CPU(cpuinfo_sparc, __cpu_data);
|
||||
#define cpu_data(__cpu) per_cpu(__cpu_data, (__cpu))
|
||||
|
||||
#endif /* _SPARC_CPUDATA_H */
|
240
include/asm-sparc/cpudata_64.h
Normal file
240
include/asm-sparc/cpudata_64.h
Normal file
|
@ -0,0 +1,240 @@
|
|||
/* cpudata.h: Per-cpu parameters.
|
||||
*
|
||||
* Copyright (C) 2003, 2005, 2006 David S. Miller (davem@davemloft.net)
|
||||
*/
|
||||
|
||||
#ifndef _SPARC64_CPUDATA_H
|
||||
#define _SPARC64_CPUDATA_H
|
||||
|
||||
#include <asm/hypervisor.h>
|
||||
#include <asm/asi.h>
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
#include <linux/percpu.h>
|
||||
#include <linux/threads.h>
|
||||
|
||||
typedef struct {
|
||||
/* Dcache line 1 */
|
||||
unsigned int __softirq_pending; /* must be 1st, see rtrap.S */
|
||||
unsigned int __pad0;
|
||||
unsigned long clock_tick; /* %tick's per second */
|
||||
unsigned long __pad;
|
||||
unsigned int __pad1;
|
||||
unsigned int __pad2;
|
||||
|
||||
/* Dcache line 2, rarely used */
|
||||
unsigned int dcache_size;
|
||||
unsigned int dcache_line_size;
|
||||
unsigned int icache_size;
|
||||
unsigned int icache_line_size;
|
||||
unsigned int ecache_size;
|
||||
unsigned int ecache_line_size;
|
||||
int core_id;
|
||||
int proc_id;
|
||||
} cpuinfo_sparc;
|
||||
|
||||
DECLARE_PER_CPU(cpuinfo_sparc, __cpu_data);
|
||||
#define cpu_data(__cpu) per_cpu(__cpu_data, (__cpu))
|
||||
#define local_cpu_data() __get_cpu_var(__cpu_data)
|
||||
|
||||
/* Trap handling code needs to get at a few critical values upon
|
||||
* trap entry and to process TSB misses. These cannot be in the
|
||||
* per_cpu() area as we really need to lock them into the TLB and
|
||||
* thus make them part of the main kernel image. As a result we
|
||||
* try to make this as small as possible.
|
||||
*
|
||||
* This is padded out and aligned to 64-bytes to avoid false sharing
|
||||
* on SMP.
|
||||
*/
|
||||
|
||||
/* If you modify the size of this structure, please update
|
||||
* TRAP_BLOCK_SZ_SHIFT below.
|
||||
*/
|
||||
struct thread_info;
|
||||
struct trap_per_cpu {
|
||||
/* D-cache line 1: Basic thread information, cpu and device mondo queues */
|
||||
struct thread_info *thread;
|
||||
unsigned long pgd_paddr;
|
||||
unsigned long cpu_mondo_pa;
|
||||
unsigned long dev_mondo_pa;
|
||||
|
||||
/* D-cache line 2: Error Mondo Queue and kernel buffer pointers */
|
||||
unsigned long resum_mondo_pa;
|
||||
unsigned long resum_kernel_buf_pa;
|
||||
unsigned long nonresum_mondo_pa;
|
||||
unsigned long nonresum_kernel_buf_pa;
|
||||
|
||||
/* Dcache lines 3, 4, 5, and 6: Hypervisor Fault Status */
|
||||
struct hv_fault_status fault_info;
|
||||
|
||||
/* Dcache line 7: Physical addresses of CPU send mondo block and CPU list. */
|
||||
unsigned long cpu_mondo_block_pa;
|
||||
unsigned long cpu_list_pa;
|
||||
unsigned long tsb_huge;
|
||||
unsigned long tsb_huge_temp;
|
||||
|
||||
/* Dcache line 8: IRQ work list, and keep trap_block a power-of-2 in size. */
|
||||
unsigned long irq_worklist_pa;
|
||||
unsigned int cpu_mondo_qmask;
|
||||
unsigned int dev_mondo_qmask;
|
||||
unsigned int resum_qmask;
|
||||
unsigned int nonresum_qmask;
|
||||
void *hdesc;
|
||||
} __attribute__((aligned(64)));
|
||||
extern struct trap_per_cpu trap_block[NR_CPUS];
|
||||
extern void init_cur_cpu_trap(struct thread_info *);
|
||||
extern void setup_tba(void);
|
||||
extern int ncpus_probed;
|
||||
extern void __init cpu_probe(void);
|
||||
extern const struct seq_operations cpuinfo_op;
|
||||
|
||||
extern unsigned long real_hard_smp_processor_id(void);
|
||||
|
||||
struct cpuid_patch_entry {
|
||||
unsigned int addr;
|
||||
unsigned int cheetah_safari[4];
|
||||
unsigned int cheetah_jbus[4];
|
||||
unsigned int starfire[4];
|
||||
unsigned int sun4v[4];
|
||||
};
|
||||
extern struct cpuid_patch_entry __cpuid_patch, __cpuid_patch_end;
|
||||
|
||||
struct sun4v_1insn_patch_entry {
|
||||
unsigned int addr;
|
||||
unsigned int insn;
|
||||
};
|
||||
extern struct sun4v_1insn_patch_entry __sun4v_1insn_patch,
|
||||
__sun4v_1insn_patch_end;
|
||||
|
||||
struct sun4v_2insn_patch_entry {
|
||||
unsigned int addr;
|
||||
unsigned int insns[2];
|
||||
};
|
||||
extern struct sun4v_2insn_patch_entry __sun4v_2insn_patch,
|
||||
__sun4v_2insn_patch_end;
|
||||
|
||||
#endif /* !(__ASSEMBLY__) */
|
||||
|
||||
#define TRAP_PER_CPU_THREAD 0x00
|
||||
#define TRAP_PER_CPU_PGD_PADDR 0x08
|
||||
#define TRAP_PER_CPU_CPU_MONDO_PA 0x10
|
||||
#define TRAP_PER_CPU_DEV_MONDO_PA 0x18
|
||||
#define TRAP_PER_CPU_RESUM_MONDO_PA 0x20
|
||||
#define TRAP_PER_CPU_RESUM_KBUF_PA 0x28
|
||||
#define TRAP_PER_CPU_NONRESUM_MONDO_PA 0x30
|
||||
#define TRAP_PER_CPU_NONRESUM_KBUF_PA 0x38
|
||||
#define TRAP_PER_CPU_FAULT_INFO 0x40
|
||||
#define TRAP_PER_CPU_CPU_MONDO_BLOCK_PA 0xc0
|
||||
#define TRAP_PER_CPU_CPU_LIST_PA 0xc8
|
||||
#define TRAP_PER_CPU_TSB_HUGE 0xd0
|
||||
#define TRAP_PER_CPU_TSB_HUGE_TEMP 0xd8
|
||||
#define TRAP_PER_CPU_IRQ_WORKLIST_PA 0xe0
|
||||
#define TRAP_PER_CPU_CPU_MONDO_QMASK 0xe8
|
||||
#define TRAP_PER_CPU_DEV_MONDO_QMASK 0xec
|
||||
#define TRAP_PER_CPU_RESUM_QMASK 0xf0
|
||||
#define TRAP_PER_CPU_NONRESUM_QMASK 0xf4
|
||||
|
||||
#define TRAP_BLOCK_SZ_SHIFT 8
|
||||
|
||||
#include <asm/scratchpad.h>
|
||||
|
||||
#define __GET_CPUID(REG) \
|
||||
/* Spitfire implementation (default). */ \
|
||||
661: ldxa [%g0] ASI_UPA_CONFIG, REG; \
|
||||
srlx REG, 17, REG; \
|
||||
and REG, 0x1f, REG; \
|
||||
nop; \
|
||||
.section .cpuid_patch, "ax"; \
|
||||
/* Instruction location. */ \
|
||||
.word 661b; \
|
||||
/* Cheetah Safari implementation. */ \
|
||||
ldxa [%g0] ASI_SAFARI_CONFIG, REG; \
|
||||
srlx REG, 17, REG; \
|
||||
and REG, 0x3ff, REG; \
|
||||
nop; \
|
||||
/* Cheetah JBUS implementation. */ \
|
||||
ldxa [%g0] ASI_JBUS_CONFIG, REG; \
|
||||
srlx REG, 17, REG; \
|
||||
and REG, 0x1f, REG; \
|
||||
nop; \
|
||||
/* Starfire implementation. */ \
|
||||
sethi %hi(0x1fff40000d0 >> 9), REG; \
|
||||
sllx REG, 9, REG; \
|
||||
or REG, 0xd0, REG; \
|
||||
lduwa [REG] ASI_PHYS_BYPASS_EC_E, REG;\
|
||||
/* sun4v implementation. */ \
|
||||
mov SCRATCHPAD_CPUID, REG; \
|
||||
ldxa [REG] ASI_SCRATCHPAD, REG; \
|
||||
nop; \
|
||||
nop; \
|
||||
.previous;
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
|
||||
#define TRAP_LOAD_TRAP_BLOCK(DEST, TMP) \
|
||||
__GET_CPUID(TMP) \
|
||||
sethi %hi(trap_block), DEST; \
|
||||
sllx TMP, TRAP_BLOCK_SZ_SHIFT, TMP; \
|
||||
or DEST, %lo(trap_block), DEST; \
|
||||
add DEST, TMP, DEST; \
|
||||
|
||||
/* Clobbers TMP, current address space PGD phys address into DEST. */
|
||||
#define TRAP_LOAD_PGD_PHYS(DEST, TMP) \
|
||||
TRAP_LOAD_TRAP_BLOCK(DEST, TMP) \
|
||||
ldx [DEST + TRAP_PER_CPU_PGD_PADDR], DEST;
|
||||
|
||||
/* Clobbers TMP, loads local processor's IRQ work area into DEST. */
|
||||
#define TRAP_LOAD_IRQ_WORK_PA(DEST, TMP) \
|
||||
TRAP_LOAD_TRAP_BLOCK(DEST, TMP) \
|
||||
add DEST, TRAP_PER_CPU_IRQ_WORKLIST_PA, DEST;
|
||||
|
||||
/* Clobbers TMP, loads DEST with current thread info pointer. */
|
||||
#define TRAP_LOAD_THREAD_REG(DEST, TMP) \
|
||||
TRAP_LOAD_TRAP_BLOCK(DEST, TMP) \
|
||||
ldx [DEST + TRAP_PER_CPU_THREAD], DEST;
|
||||
|
||||
/* Given the current thread info pointer in THR, load the per-cpu
|
||||
* area base of the current processor into DEST. REG1, REG2, and REG3 are
|
||||
* clobbered.
|
||||
*
|
||||
* You absolutely cannot use DEST as a temporary in this code. The
|
||||
* reason is that traps can happen during execution, and return from
|
||||
* trap will load the fully resolved DEST per-cpu base. This can corrupt
|
||||
* the calculations done by the macro mid-stream.
|
||||
*/
|
||||
#define LOAD_PER_CPU_BASE(DEST, THR, REG1, REG2, REG3) \
|
||||
lduh [THR + TI_CPU], REG1; \
|
||||
sethi %hi(__per_cpu_shift), REG3; \
|
||||
sethi %hi(__per_cpu_base), REG2; \
|
||||
ldx [REG3 + %lo(__per_cpu_shift)], REG3; \
|
||||
ldx [REG2 + %lo(__per_cpu_base)], REG2; \
|
||||
sllx REG1, REG3, REG3; \
|
||||
add REG3, REG2, DEST;
|
||||
|
||||
#else
|
||||
|
||||
#define TRAP_LOAD_TRAP_BLOCK(DEST, TMP) \
|
||||
sethi %hi(trap_block), DEST; \
|
||||
or DEST, %lo(trap_block), DEST; \
|
||||
|
||||
/* Uniprocessor versions, we know the cpuid is zero. */
|
||||
#define TRAP_LOAD_PGD_PHYS(DEST, TMP) \
|
||||
TRAP_LOAD_TRAP_BLOCK(DEST, TMP) \
|
||||
ldx [DEST + TRAP_PER_CPU_PGD_PADDR], DEST;
|
||||
|
||||
/* Clobbers TMP, loads local processor's IRQ work area into DEST. */
|
||||
#define TRAP_LOAD_IRQ_WORK_PA(DEST, TMP) \
|
||||
TRAP_LOAD_TRAP_BLOCK(DEST, TMP) \
|
||||
add DEST, TRAP_PER_CPU_IRQ_WORKLIST_PA, DEST;
|
||||
|
||||
#define TRAP_LOAD_THREAD_REG(DEST, TMP) \
|
||||
TRAP_LOAD_TRAP_BLOCK(DEST, TMP) \
|
||||
ldx [DEST + TRAP_PER_CPU_THREAD], DEST;
|
||||
|
||||
/* No per-cpu areas on uniprocessor, so no need to load DEST. */
|
||||
#define LOAD_PER_CPU_BASE(DEST, THR, REG1, REG2, REG3)
|
||||
|
||||
#endif /* !(CONFIG_SMP) */
|
||||
|
||||
#endif /* _SPARC64_CPUDATA_H */
|
|
@ -1,34 +1,8 @@
|
|||
/*
|
||||
* delay.h: Linux delay routines on the Sparc.
|
||||
*
|
||||
* Copyright (C) 1994 David S. Miller (davem@caip.rutgers.edu).
|
||||
*/
|
||||
|
||||
#ifndef __SPARC_DELAY_H
|
||||
#define __SPARC_DELAY_H
|
||||
|
||||
#include <asm/cpudata.h>
|
||||
|
||||
static inline void __delay(unsigned long loops)
|
||||
{
|
||||
__asm__ __volatile__("cmp %0, 0\n\t"
|
||||
"1: bne 1b\n\t"
|
||||
"subcc %0, 1, %0\n" :
|
||||
"=&r" (loops) :
|
||||
"0" (loops) :
|
||||
"cc");
|
||||
}
|
||||
|
||||
/* This is too messy with inline asm on the Sparc. */
|
||||
extern void __udelay(unsigned long usecs, unsigned long lpj);
|
||||
extern void __ndelay(unsigned long nsecs, unsigned long lpj);
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
#define __udelay_val cpu_data(smp_processor_id()).udelay_val
|
||||
#else /* SMP */
|
||||
#define __udelay_val loops_per_jiffy
|
||||
#endif /* SMP */
|
||||
#define udelay(__usecs) __udelay(__usecs, __udelay_val)
|
||||
#define ndelay(__nsecs) __ndelay(__nsecs, __udelay_val)
|
||||
|
||||
#endif /* defined(__SPARC_DELAY_H) */
|
||||
#ifndef ___ASM_SPARC_DELAY_H
|
||||
#define ___ASM_SPARC_DELAY_H
|
||||
#if defined(__sparc__) && defined(__arch64__)
|
||||
#include <asm-sparc/delay_64.h>
|
||||
#else
|
||||
#include <asm-sparc/delay_32.h>
|
||||
#endif
|
||||
#endif
|
||||
|
|
34
include/asm-sparc/delay_32.h
Normal file
34
include/asm-sparc/delay_32.h
Normal file
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* delay.h: Linux delay routines on the Sparc.
|
||||
*
|
||||
* Copyright (C) 1994 David S. Miller (davem@caip.rutgers.edu).
|
||||
*/
|
||||
|
||||
#ifndef __SPARC_DELAY_H
|
||||
#define __SPARC_DELAY_H
|
||||
|
||||
#include <asm/cpudata.h>
|
||||
|
||||
static inline void __delay(unsigned long loops)
|
||||
{
|
||||
__asm__ __volatile__("cmp %0, 0\n\t"
|
||||
"1: bne 1b\n\t"
|
||||
"subcc %0, 1, %0\n" :
|
||||
"=&r" (loops) :
|
||||
"0" (loops) :
|
||||
"cc");
|
||||
}
|
||||
|
||||
/* This is too messy with inline asm on the Sparc. */
|
||||
extern void __udelay(unsigned long usecs, unsigned long lpj);
|
||||
extern void __ndelay(unsigned long nsecs, unsigned long lpj);
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
#define __udelay_val cpu_data(smp_processor_id()).udelay_val
|
||||
#else /* SMP */
|
||||
#define __udelay_val loops_per_jiffy
|
||||
#endif /* SMP */
|
||||
#define udelay(__usecs) __udelay(__usecs, __udelay_val)
|
||||
#define ndelay(__nsecs) __ndelay(__nsecs, __udelay_val)
|
||||
|
||||
#endif /* defined(__SPARC_DELAY_H) */
|
17
include/asm-sparc/delay_64.h
Normal file
17
include/asm-sparc/delay_64.h
Normal file
|
@ -0,0 +1,17 @@
|
|||
/* delay.h: Linux delay routines on sparc64.
|
||||
*
|
||||
* Copyright (C) 1996, 2004, 2007 David S. Miller (davem@davemloft.net).
|
||||
*/
|
||||
|
||||
#ifndef _SPARC64_DELAY_H
|
||||
#define _SPARC64_DELAY_H
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
extern void __delay(unsigned long loops);
|
||||
extern void udelay(unsigned long usecs);
|
||||
#define mdelay(n) udelay((n) * 1000)
|
||||
|
||||
#endif /* !__ASSEMBLY__ */
|
||||
|
||||
#endif /* _SPARC64_DELAY_H */
|
|
@ -1,11 +1,8 @@
|
|||
#ifndef _ASM_SPARC_DMA_MAPPING_H
|
||||
#define _ASM_SPARC_DMA_MAPPING_H
|
||||
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
#include <asm-generic/dma-mapping.h>
|
||||
#ifndef ___ASM_SPARC_DMA_MAPPING_H
|
||||
#define ___ASM_SPARC_DMA_MAPPING_H
|
||||
#if defined(__sparc__) && defined(__arch64__)
|
||||
#include <asm-sparc/dma-mapping_64.h>
|
||||
#else
|
||||
#include <asm-generic/dma-mapping-broken.h>
|
||||
#endif /* PCI */
|
||||
|
||||
#endif /* _ASM_SPARC_DMA_MAPPING_H */
|
||||
#include <asm-sparc/dma-mapping_32.h>
|
||||
#endif
|
||||
#endif
|
||||
|
|
11
include/asm-sparc/dma-mapping_32.h
Normal file
11
include/asm-sparc/dma-mapping_32.h
Normal file
|
@ -0,0 +1,11 @@
|
|||
#ifndef _ASM_SPARC_DMA_MAPPING_H
|
||||
#define _ASM_SPARC_DMA_MAPPING_H
|
||||
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
#include <asm-generic/dma-mapping.h>
|
||||
#else
|
||||
#include <asm-generic/dma-mapping-broken.h>
|
||||
#endif /* PCI */
|
||||
|
||||
#endif /* _ASM_SPARC_DMA_MAPPING_H */
|
154
include/asm-sparc/dma-mapping_64.h
Normal file
154
include/asm-sparc/dma-mapping_64.h
Normal file
|
@ -0,0 +1,154 @@
|
|||
#ifndef _ASM_SPARC64_DMA_MAPPING_H
|
||||
#define _ASM_SPARC64_DMA_MAPPING_H
|
||||
|
||||
#include <linux/scatterlist.h>
|
||||
#include <linux/mm.h>
|
||||
|
||||
#define DMA_ERROR_CODE (~(dma_addr_t)0x0)
|
||||
|
||||
struct dma_ops {
|
||||
void *(*alloc_coherent)(struct device *dev, size_t size,
|
||||
dma_addr_t *dma_handle, gfp_t flag);
|
||||
void (*free_coherent)(struct device *dev, size_t size,
|
||||
void *cpu_addr, dma_addr_t dma_handle);
|
||||
dma_addr_t (*map_single)(struct device *dev, void *cpu_addr,
|
||||
size_t size,
|
||||
enum dma_data_direction direction);
|
||||
void (*unmap_single)(struct device *dev, dma_addr_t dma_addr,
|
||||
size_t size,
|
||||
enum dma_data_direction direction);
|
||||
int (*map_sg)(struct device *dev, struct scatterlist *sg, int nents,
|
||||
enum dma_data_direction direction);
|
||||
void (*unmap_sg)(struct device *dev, struct scatterlist *sg,
|
||||
int nhwentries,
|
||||
enum dma_data_direction direction);
|
||||
void (*sync_single_for_cpu)(struct device *dev,
|
||||
dma_addr_t dma_handle, size_t size,
|
||||
enum dma_data_direction direction);
|
||||
void (*sync_sg_for_cpu)(struct device *dev, struct scatterlist *sg,
|
||||
int nelems,
|
||||
enum dma_data_direction direction);
|
||||
};
|
||||
extern const struct dma_ops *dma_ops;
|
||||
|
||||
extern int dma_supported(struct device *dev, u64 mask);
|
||||
extern int dma_set_mask(struct device *dev, u64 dma_mask);
|
||||
|
||||
static inline void *dma_alloc_coherent(struct device *dev, size_t size,
|
||||
dma_addr_t *dma_handle, gfp_t flag)
|
||||
{
|
||||
return dma_ops->alloc_coherent(dev, size, dma_handle, flag);
|
||||
}
|
||||
|
||||
static inline void dma_free_coherent(struct device *dev, size_t size,
|
||||
void *cpu_addr, dma_addr_t dma_handle)
|
||||
{
|
||||
dma_ops->free_coherent(dev, size, cpu_addr, dma_handle);
|
||||
}
|
||||
|
||||
static inline dma_addr_t dma_map_single(struct device *dev, void *cpu_addr,
|
||||
size_t size,
|
||||
enum dma_data_direction direction)
|
||||
{
|
||||
return dma_ops->map_single(dev, cpu_addr, size, direction);
|
||||
}
|
||||
|
||||
static inline void dma_unmap_single(struct device *dev, dma_addr_t dma_addr,
|
||||
size_t size,
|
||||
enum dma_data_direction direction)
|
||||
{
|
||||
dma_ops->unmap_single(dev, dma_addr, size, direction);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
return dma_ops->map_single(dev, page_address(page) + offset,
|
||||
size, direction);
|
||||
}
|
||||
|
||||
static inline void dma_unmap_page(struct device *dev, dma_addr_t dma_address,
|
||||
size_t size,
|
||||
enum dma_data_direction direction)
|
||||
{
|
||||
dma_ops->unmap_single(dev, dma_address, size, direction);
|
||||
}
|
||||
|
||||
static inline int dma_map_sg(struct device *dev, struct scatterlist *sg,
|
||||
int nents, enum dma_data_direction direction)
|
||||
{
|
||||
return dma_ops->map_sg(dev, sg, nents, direction);
|
||||
}
|
||||
|
||||
static inline void dma_unmap_sg(struct device *dev, struct scatterlist *sg,
|
||||
int nents, enum dma_data_direction direction)
|
||||
{
|
||||
dma_ops->unmap_sg(dev, sg, nents, direction);
|
||||
}
|
||||
|
||||
static inline void dma_sync_single_for_cpu(struct device *dev,
|
||||
dma_addr_t dma_handle, size_t size,
|
||||
enum dma_data_direction direction)
|
||||
{
|
||||
dma_ops->sync_single_for_cpu(dev, 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)
|
||||
{
|
||||
/* No flushing needed to sync cpu writes to the device. */
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
dma_sync_single_for_cpu(dev, 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)
|
||||
{
|
||||
/* No flushing needed to sync cpu writes to the device. */
|
||||
}
|
||||
|
||||
|
||||
static inline void dma_sync_sg_for_cpu(struct device *dev,
|
||||
struct scatterlist *sg, int nelems,
|
||||
enum dma_data_direction direction)
|
||||
{
|
||||
dma_ops->sync_sg_for_cpu(dev, sg, nelems, direction);
|
||||
}
|
||||
|
||||
static inline void dma_sync_sg_for_device(struct device *dev,
|
||||
struct scatterlist *sg, int nelems,
|
||||
enum dma_data_direction direction)
|
||||
{
|
||||
/* No flushing needed to sync cpu writes to the device. */
|
||||
}
|
||||
|
||||
static inline int dma_mapping_error(dma_addr_t dma_addr)
|
||||
{
|
||||
return (dma_addr == DMA_ERROR_CODE);
|
||||
}
|
||||
|
||||
static inline int dma_get_cache_alignment(void)
|
||||
{
|
||||
/* no easy way to get cache size on all processors, so return
|
||||
* the maximum possible, to be safe */
|
||||
return (1 << INTERNODE_CACHE_SHIFT);
|
||||
}
|
||||
|
||||
#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)
|
||||
#define dma_is_consistent(d, h) (1)
|
||||
|
||||
#endif /* _ASM_SPARC64_DMA_MAPPING_H */
|
|
@ -1,288 +1,8 @@
|
|||
/* include/asm-sparc/dma.h
|
||||
*
|
||||
* Copyright 1995 (C) David S. Miller (davem@davemloft.net)
|
||||
*/
|
||||
|
||||
#ifndef _ASM_SPARC_DMA_H
|
||||
#define _ASM_SPARC_DMA_H
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
#include <asm/vac-ops.h> /* for invalidate's, etc. */
|
||||
#include <asm/sbus.h>
|
||||
#include <asm/delay.h>
|
||||
#include <asm/oplib.h>
|
||||
#include <asm/system.h>
|
||||
#include <asm/io.h>
|
||||
#include <linux/spinlock.h>
|
||||
|
||||
struct page;
|
||||
extern spinlock_t dma_spin_lock;
|
||||
|
||||
static inline unsigned long claim_dma_lock(void)
|
||||
{
|
||||
unsigned long flags;
|
||||
spin_lock_irqsave(&dma_spin_lock, flags);
|
||||
return flags;
|
||||
}
|
||||
|
||||
static inline void release_dma_lock(unsigned long flags)
|
||||
{
|
||||
spin_unlock_irqrestore(&dma_spin_lock, flags);
|
||||
}
|
||||
|
||||
/* These are irrelevant for Sparc DMA, but we leave it in so that
|
||||
* things can compile.
|
||||
*/
|
||||
#define MAX_DMA_CHANNELS 8
|
||||
#define MAX_DMA_ADDRESS (~0UL)
|
||||
#define DMA_MODE_READ 1
|
||||
#define DMA_MODE_WRITE 2
|
||||
|
||||
/* Useful constants */
|
||||
#define SIZE_16MB (16*1024*1024)
|
||||
#define SIZE_64K (64*1024)
|
||||
|
||||
/* SBUS DMA controller reg offsets */
|
||||
#define DMA_CSR 0x00UL /* rw DMA control/status register 0x00 */
|
||||
#define DMA_ADDR 0x04UL /* rw DMA transfer address register 0x04 */
|
||||
#define DMA_COUNT 0x08UL /* rw DMA transfer count register 0x08 */
|
||||
#define DMA_TEST 0x0cUL /* rw DMA test/debug register 0x0c */
|
||||
|
||||
/* DVMA chip revisions */
|
||||
enum dvma_rev {
|
||||
dvmarev0,
|
||||
dvmaesc1,
|
||||
dvmarev1,
|
||||
dvmarev2,
|
||||
dvmarev3,
|
||||
dvmarevplus,
|
||||
dvmahme
|
||||
};
|
||||
|
||||
#define DMA_HASCOUNT(rev) ((rev)==dvmaesc1)
|
||||
|
||||
/* Linux DMA information structure, filled during probe. */
|
||||
struct sbus_dma {
|
||||
struct sbus_dma *next;
|
||||
struct sbus_dev *sdev;
|
||||
void __iomem *regs;
|
||||
|
||||
/* Status, misc info */
|
||||
int node; /* Prom node for this DMA device */
|
||||
int running; /* Are we doing DMA now? */
|
||||
int allocated; /* Are we "owned" by anyone yet? */
|
||||
|
||||
/* Transfer information. */
|
||||
unsigned long addr; /* Start address of current transfer */
|
||||
int nbytes; /* Size of current transfer */
|
||||
int realbytes; /* For splitting up large transfers, etc. */
|
||||
|
||||
/* DMA revision */
|
||||
enum dvma_rev revision;
|
||||
};
|
||||
|
||||
extern struct sbus_dma *dma_chain;
|
||||
|
||||
/* Broken hardware... */
|
||||
#ifdef CONFIG_SUN4
|
||||
/* Have to sort this out. Does rev0 work fine on sun4[cmd] without isbroken?
|
||||
* Or is rev0 present only on sun4 boxes? -jj */
|
||||
#define DMA_ISBROKEN(dma) ((dma)->revision == dvmarev0 || (dma)->revision == dvmarev1)
|
||||
#ifndef ___ASM_SPARC_DMA_H
|
||||
#define ___ASM_SPARC_DMA_H
|
||||
#if defined(__sparc__) && defined(__arch64__)
|
||||
#include <asm-sparc/dma_64.h>
|
||||
#else
|
||||
#define DMA_ISBROKEN(dma) ((dma)->revision == dvmarev1)
|
||||
#include <asm-sparc/dma_32.h>
|
||||
#endif
|
||||
#define DMA_ISESC1(dma) ((dma)->revision == dvmaesc1)
|
||||
|
||||
/* Main routines in dma.c */
|
||||
extern void dvma_init(struct sbus_bus *);
|
||||
|
||||
/* Fields in the cond_reg register */
|
||||
/* First, the version identification bits */
|
||||
#define DMA_DEVICE_ID 0xf0000000 /* Device identification bits */
|
||||
#define DMA_VERS0 0x00000000 /* Sunray DMA version */
|
||||
#define DMA_ESCV1 0x40000000 /* DMA ESC Version 1 */
|
||||
#define DMA_VERS1 0x80000000 /* DMA rev 1 */
|
||||
#define DMA_VERS2 0xa0000000 /* DMA rev 2 */
|
||||
#define DMA_VERHME 0xb0000000 /* DMA hme gate array */
|
||||
#define DMA_VERSPLUS 0x90000000 /* DMA rev 1 PLUS */
|
||||
|
||||
#define DMA_HNDL_INTR 0x00000001 /* An IRQ needs to be handled */
|
||||
#define DMA_HNDL_ERROR 0x00000002 /* We need to take an error */
|
||||
#define DMA_FIFO_ISDRAIN 0x0000000c /* The DMA FIFO is draining */
|
||||
#define DMA_INT_ENAB 0x00000010 /* Turn on interrupts */
|
||||
#define DMA_FIFO_INV 0x00000020 /* Invalidate the FIFO */
|
||||
#define DMA_ACC_SZ_ERR 0x00000040 /* The access size was bad */
|
||||
#define DMA_FIFO_STDRAIN 0x00000040 /* DMA_VERS1 Drain the FIFO */
|
||||
#define DMA_RST_SCSI 0x00000080 /* Reset the SCSI controller */
|
||||
#define DMA_RST_ENET DMA_RST_SCSI /* Reset the ENET controller */
|
||||
#define DMA_RST_BPP DMA_RST_SCSI /* Reset the BPP controller */
|
||||
#define DMA_ST_WRITE 0x00000100 /* write from device to memory */
|
||||
#define DMA_ENABLE 0x00000200 /* Fire up DMA, handle requests */
|
||||
#define DMA_PEND_READ 0x00000400 /* DMA_VERS1/0/PLUS Pending Read */
|
||||
#define DMA_ESC_BURST 0x00000800 /* 1=16byte 0=32byte */
|
||||
#define DMA_READ_AHEAD 0x00001800 /* DMA read ahead partial longword */
|
||||
#define DMA_DSBL_RD_DRN 0x00001000 /* No EC drain on slave reads */
|
||||
#define DMA_BCNT_ENAB 0x00002000 /* If on, use the byte counter */
|
||||
#define DMA_TERM_CNTR 0x00004000 /* Terminal counter */
|
||||
#define DMA_SCSI_SBUS64 0x00008000 /* HME: Enable 64-bit SBUS mode. */
|
||||
#define DMA_CSR_DISAB 0x00010000 /* No FIFO drains during csr */
|
||||
#define DMA_SCSI_DISAB 0x00020000 /* No FIFO drains during reg */
|
||||
#define DMA_DSBL_WR_INV 0x00020000 /* No EC inval. on slave writes */
|
||||
#define DMA_ADD_ENABLE 0x00040000 /* Special ESC DVMA optimization */
|
||||
#define DMA_E_BURSTS 0x000c0000 /* ENET: SBUS r/w burst mask */
|
||||
#define DMA_E_BURST32 0x00040000 /* ENET: SBUS 32 byte r/w burst */
|
||||
#define DMA_E_BURST16 0x00000000 /* ENET: SBUS 16 byte r/w burst */
|
||||
#define DMA_BRST_SZ 0x000c0000 /* SCSI: SBUS r/w burst size */
|
||||
#define DMA_BRST64 0x00080000 /* SCSI: 64byte bursts (HME on UltraSparc only) */
|
||||
#define DMA_BRST32 0x00040000 /* SCSI/BPP: 32byte bursts */
|
||||
#define DMA_BRST16 0x00000000 /* SCSI/BPP: 16byte bursts */
|
||||
#define DMA_BRST0 0x00080000 /* SCSI: no bursts (non-HME gate arrays) */
|
||||
#define DMA_ADDR_DISAB 0x00100000 /* No FIFO drains during addr */
|
||||
#define DMA_2CLKS 0x00200000 /* Each transfer = 2 clock ticks */
|
||||
#define DMA_3CLKS 0x00400000 /* Each transfer = 3 clock ticks */
|
||||
#define DMA_EN_ENETAUI DMA_3CLKS /* Put lance into AUI-cable mode */
|
||||
#define DMA_CNTR_DISAB 0x00800000 /* No IRQ when DMA_TERM_CNTR set */
|
||||
#define DMA_AUTO_NADDR 0x01000000 /* Use "auto nxt addr" feature */
|
||||
#define DMA_SCSI_ON 0x02000000 /* Enable SCSI dma */
|
||||
#define DMA_BPP_ON DMA_SCSI_ON /* Enable BPP dma */
|
||||
#define DMA_PARITY_OFF 0x02000000 /* HME: disable parity checking */
|
||||
#define DMA_LOADED_ADDR 0x04000000 /* Address has been loaded */
|
||||
#define DMA_LOADED_NADDR 0x08000000 /* Next address has been loaded */
|
||||
#define DMA_RESET_FAS366 0x08000000 /* HME: Assert RESET to FAS366 */
|
||||
|
||||
/* Values describing the burst-size property from the PROM */
|
||||
#define DMA_BURST1 0x01
|
||||
#define DMA_BURST2 0x02
|
||||
#define DMA_BURST4 0x04
|
||||
#define DMA_BURST8 0x08
|
||||
#define DMA_BURST16 0x10
|
||||
#define DMA_BURST32 0x20
|
||||
#define DMA_BURST64 0x40
|
||||
#define DMA_BURSTBITS 0x7f
|
||||
|
||||
/* Determine highest possible final transfer address given a base */
|
||||
#define DMA_MAXEND(addr) (0x01000000UL-(((unsigned long)(addr))&0x00ffffffUL))
|
||||
|
||||
/* Yes, I hack a lot of elisp in my spare time... */
|
||||
#define DMA_ERROR_P(regs) ((((regs)->cond_reg) & DMA_HNDL_ERROR))
|
||||
#define DMA_IRQ_P(regs) ((((regs)->cond_reg) & (DMA_HNDL_INTR | DMA_HNDL_ERROR)))
|
||||
#define DMA_WRITE_P(regs) ((((regs)->cond_reg) & DMA_ST_WRITE))
|
||||
#define DMA_OFF(regs) ((((regs)->cond_reg) &= (~DMA_ENABLE)))
|
||||
#define DMA_INTSOFF(regs) ((((regs)->cond_reg) &= (~DMA_INT_ENAB)))
|
||||
#define DMA_INTSON(regs) ((((regs)->cond_reg) |= (DMA_INT_ENAB)))
|
||||
#define DMA_PUNTFIFO(regs) ((((regs)->cond_reg) |= DMA_FIFO_INV))
|
||||
#define DMA_SETSTART(regs, addr) ((((regs)->st_addr) = (char *) addr))
|
||||
#define DMA_BEGINDMA_W(regs) \
|
||||
((((regs)->cond_reg |= (DMA_ST_WRITE|DMA_ENABLE|DMA_INT_ENAB))))
|
||||
#define DMA_BEGINDMA_R(regs) \
|
||||
((((regs)->cond_reg |= ((DMA_ENABLE|DMA_INT_ENAB)&(~DMA_ST_WRITE)))))
|
||||
|
||||
/* For certain DMA chips, we need to disable ints upon irq entry
|
||||
* and turn them back on when we are done. So in any ESP interrupt
|
||||
* handler you *must* call DMA_IRQ_ENTRY upon entry and DMA_IRQ_EXIT
|
||||
* when leaving the handler. You have been warned...
|
||||
*/
|
||||
#define DMA_IRQ_ENTRY(dma, dregs) do { \
|
||||
if(DMA_ISBROKEN(dma)) DMA_INTSOFF(dregs); \
|
||||
} while (0)
|
||||
|
||||
#define DMA_IRQ_EXIT(dma, dregs) do { \
|
||||
if(DMA_ISBROKEN(dma)) DMA_INTSON(dregs); \
|
||||
} while(0)
|
||||
|
||||
#if 0 /* P3 this stuff is inline in ledma.c:init_restart_ledma() */
|
||||
/* Pause until counter runs out or BIT isn't set in the DMA condition
|
||||
* register.
|
||||
*/
|
||||
static inline void sparc_dma_pause(struct sparc_dma_registers *regs,
|
||||
unsigned long bit)
|
||||
{
|
||||
int ctr = 50000; /* Let's find some bugs ;) */
|
||||
|
||||
/* Busy wait until the bit is not set any more */
|
||||
while((regs->cond_reg&bit) && (ctr>0)) {
|
||||
ctr--;
|
||||
__delay(5);
|
||||
}
|
||||
|
||||
/* Check for bogus outcome. */
|
||||
if(!ctr)
|
||||
panic("DMA timeout");
|
||||
}
|
||||
|
||||
/* Reset the friggin' thing... */
|
||||
#define DMA_RESET(dma) do { \
|
||||
struct sparc_dma_registers *regs = dma->regs; \
|
||||
/* Let the current FIFO drain itself */ \
|
||||
sparc_dma_pause(regs, (DMA_FIFO_ISDRAIN)); \
|
||||
/* Reset the logic */ \
|
||||
regs->cond_reg |= (DMA_RST_SCSI); /* assert */ \
|
||||
__delay(400); /* let the bits set ;) */ \
|
||||
regs->cond_reg &= ~(DMA_RST_SCSI); /* de-assert */ \
|
||||
sparc_dma_enable_interrupts(regs); /* Re-enable interrupts */ \
|
||||
/* Enable FAST transfers if available */ \
|
||||
if(dma->revision>dvmarev1) regs->cond_reg |= DMA_3CLKS; \
|
||||
dma->running = 0; \
|
||||
} while(0)
|
||||
#endif
|
||||
|
||||
#define for_each_dvma(dma) \
|
||||
for((dma) = dma_chain; (dma); (dma) = (dma)->next)
|
||||
|
||||
extern int get_dma_list(char *);
|
||||
extern int request_dma(unsigned int, __const__ char *);
|
||||
extern void free_dma(unsigned int);
|
||||
|
||||
/* From PCI */
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
extern int isa_dma_bridge_buggy;
|
||||
#else
|
||||
#define isa_dma_bridge_buggy (0)
|
||||
#endif
|
||||
|
||||
/* Routines for data transfer buffers. */
|
||||
BTFIXUPDEF_CALL(char *, mmu_lockarea, char *, unsigned long)
|
||||
BTFIXUPDEF_CALL(void, mmu_unlockarea, char *, unsigned long)
|
||||
|
||||
#define mmu_lockarea(vaddr,len) BTFIXUP_CALL(mmu_lockarea)(vaddr,len)
|
||||
#define mmu_unlockarea(vaddr,len) BTFIXUP_CALL(mmu_unlockarea)(vaddr,len)
|
||||
|
||||
/* These are implementations for sbus_map_sg/sbus_unmap_sg... collapse later */
|
||||
BTFIXUPDEF_CALL(__u32, mmu_get_scsi_one, char *, unsigned long, struct sbus_bus *sbus)
|
||||
BTFIXUPDEF_CALL(void, mmu_get_scsi_sgl, struct scatterlist *, int, struct sbus_bus *sbus)
|
||||
BTFIXUPDEF_CALL(void, mmu_release_scsi_one, __u32, unsigned long, struct sbus_bus *sbus)
|
||||
BTFIXUPDEF_CALL(void, mmu_release_scsi_sgl, struct scatterlist *, int, struct sbus_bus *sbus)
|
||||
|
||||
#define mmu_get_scsi_one(vaddr,len,sbus) BTFIXUP_CALL(mmu_get_scsi_one)(vaddr,len,sbus)
|
||||
#define mmu_get_scsi_sgl(sg,sz,sbus) BTFIXUP_CALL(mmu_get_scsi_sgl)(sg,sz,sbus)
|
||||
#define mmu_release_scsi_one(vaddr,len,sbus) BTFIXUP_CALL(mmu_release_scsi_one)(vaddr,len,sbus)
|
||||
#define mmu_release_scsi_sgl(sg,sz,sbus) BTFIXUP_CALL(mmu_release_scsi_sgl)(sg,sz,sbus)
|
||||
|
||||
/*
|
||||
* mmu_map/unmap are provided by iommu/iounit; Invalid to call on IIep.
|
||||
*
|
||||
* The mmu_map_dma_area establishes two mappings in one go.
|
||||
* These mappings point to pages normally mapped at 'va' (linear address).
|
||||
* First mapping is for CPU visible address at 'a', uncached.
|
||||
* This is an alias, but it works because it is an uncached mapping.
|
||||
* Second mapping is for device visible address, or "bus" address.
|
||||
* The bus address is returned at '*pba'.
|
||||
*
|
||||
* These functions seem distinct, but are hard to split. On sun4c,
|
||||
* at least for now, 'a' is equal to bus address, and retured in *pba.
|
||||
* On sun4m, page attributes depend on the CPU type, so we have to
|
||||
* know if we are mapping RAM or I/O, so it has to be an additional argument
|
||||
* to a separate mapping function for CPU visible mappings.
|
||||
*/
|
||||
BTFIXUPDEF_CALL(int, mmu_map_dma_area, dma_addr_t *, unsigned long, unsigned long, int len)
|
||||
BTFIXUPDEF_CALL(struct page *, mmu_translate_dvma, unsigned long busa)
|
||||
BTFIXUPDEF_CALL(void, mmu_unmap_dma_area, unsigned long busa, int len)
|
||||
|
||||
#define mmu_map_dma_area(pba,va,a,len) BTFIXUP_CALL(mmu_map_dma_area)(pba,va,a,len)
|
||||
#define mmu_unmap_dma_area(ba,len) BTFIXUP_CALL(mmu_unmap_dma_area)(ba,len)
|
||||
#define mmu_translate_dvma(ba) BTFIXUP_CALL(mmu_translate_dvma)(ba)
|
||||
|
||||
#endif /* !(_ASM_SPARC_DMA_H) */
|
||||
|
|
288
include/asm-sparc/dma_32.h
Normal file
288
include/asm-sparc/dma_32.h
Normal file
|
@ -0,0 +1,288 @@
|
|||
/* include/asm-sparc/dma.h
|
||||
*
|
||||
* Copyright 1995 (C) David S. Miller (davem@davemloft.net)
|
||||
*/
|
||||
|
||||
#ifndef _ASM_SPARC_DMA_H
|
||||
#define _ASM_SPARC_DMA_H
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
#include <asm/vac-ops.h> /* for invalidate's, etc. */
|
||||
#include <asm/sbus.h>
|
||||
#include <asm/delay.h>
|
||||
#include <asm/oplib.h>
|
||||
#include <asm/system.h>
|
||||
#include <asm/io.h>
|
||||
#include <linux/spinlock.h>
|
||||
|
||||
struct page;
|
||||
extern spinlock_t dma_spin_lock;
|
||||
|
||||
static inline unsigned long claim_dma_lock(void)
|
||||
{
|
||||
unsigned long flags;
|
||||
spin_lock_irqsave(&dma_spin_lock, flags);
|
||||
return flags;
|
||||
}
|
||||
|
||||
static inline void release_dma_lock(unsigned long flags)
|
||||
{
|
||||
spin_unlock_irqrestore(&dma_spin_lock, flags);
|
||||
}
|
||||
|
||||
/* These are irrelevant for Sparc DMA, but we leave it in so that
|
||||
* things can compile.
|
||||
*/
|
||||
#define MAX_DMA_CHANNELS 8
|
||||
#define MAX_DMA_ADDRESS (~0UL)
|
||||
#define DMA_MODE_READ 1
|
||||
#define DMA_MODE_WRITE 2
|
||||
|
||||
/* Useful constants */
|
||||
#define SIZE_16MB (16*1024*1024)
|
||||
#define SIZE_64K (64*1024)
|
||||
|
||||
/* SBUS DMA controller reg offsets */
|
||||
#define DMA_CSR 0x00UL /* rw DMA control/status register 0x00 */
|
||||
#define DMA_ADDR 0x04UL /* rw DMA transfer address register 0x04 */
|
||||
#define DMA_COUNT 0x08UL /* rw DMA transfer count register 0x08 */
|
||||
#define DMA_TEST 0x0cUL /* rw DMA test/debug register 0x0c */
|
||||
|
||||
/* DVMA chip revisions */
|
||||
enum dvma_rev {
|
||||
dvmarev0,
|
||||
dvmaesc1,
|
||||
dvmarev1,
|
||||
dvmarev2,
|
||||
dvmarev3,
|
||||
dvmarevplus,
|
||||
dvmahme
|
||||
};
|
||||
|
||||
#define DMA_HASCOUNT(rev) ((rev)==dvmaesc1)
|
||||
|
||||
/* Linux DMA information structure, filled during probe. */
|
||||
struct sbus_dma {
|
||||
struct sbus_dma *next;
|
||||
struct sbus_dev *sdev;
|
||||
void __iomem *regs;
|
||||
|
||||
/* Status, misc info */
|
||||
int node; /* Prom node for this DMA device */
|
||||
int running; /* Are we doing DMA now? */
|
||||
int allocated; /* Are we "owned" by anyone yet? */
|
||||
|
||||
/* Transfer information. */
|
||||
unsigned long addr; /* Start address of current transfer */
|
||||
int nbytes; /* Size of current transfer */
|
||||
int realbytes; /* For splitting up large transfers, etc. */
|
||||
|
||||
/* DMA revision */
|
||||
enum dvma_rev revision;
|
||||
};
|
||||
|
||||
extern struct sbus_dma *dma_chain;
|
||||
|
||||
/* Broken hardware... */
|
||||
#ifdef CONFIG_SUN4
|
||||
/* Have to sort this out. Does rev0 work fine on sun4[cmd] without isbroken?
|
||||
* Or is rev0 present only on sun4 boxes? -jj */
|
||||
#define DMA_ISBROKEN(dma) ((dma)->revision == dvmarev0 || (dma)->revision == dvmarev1)
|
||||
#else
|
||||
#define DMA_ISBROKEN(dma) ((dma)->revision == dvmarev1)
|
||||
#endif
|
||||
#define DMA_ISESC1(dma) ((dma)->revision == dvmaesc1)
|
||||
|
||||
/* Main routines in dma.c */
|
||||
extern void dvma_init(struct sbus_bus *);
|
||||
|
||||
/* Fields in the cond_reg register */
|
||||
/* First, the version identification bits */
|
||||
#define DMA_DEVICE_ID 0xf0000000 /* Device identification bits */
|
||||
#define DMA_VERS0 0x00000000 /* Sunray DMA version */
|
||||
#define DMA_ESCV1 0x40000000 /* DMA ESC Version 1 */
|
||||
#define DMA_VERS1 0x80000000 /* DMA rev 1 */
|
||||
#define DMA_VERS2 0xa0000000 /* DMA rev 2 */
|
||||
#define DMA_VERHME 0xb0000000 /* DMA hme gate array */
|
||||
#define DMA_VERSPLUS 0x90000000 /* DMA rev 1 PLUS */
|
||||
|
||||
#define DMA_HNDL_INTR 0x00000001 /* An IRQ needs to be handled */
|
||||
#define DMA_HNDL_ERROR 0x00000002 /* We need to take an error */
|
||||
#define DMA_FIFO_ISDRAIN 0x0000000c /* The DMA FIFO is draining */
|
||||
#define DMA_INT_ENAB 0x00000010 /* Turn on interrupts */
|
||||
#define DMA_FIFO_INV 0x00000020 /* Invalidate the FIFO */
|
||||
#define DMA_ACC_SZ_ERR 0x00000040 /* The access size was bad */
|
||||
#define DMA_FIFO_STDRAIN 0x00000040 /* DMA_VERS1 Drain the FIFO */
|
||||
#define DMA_RST_SCSI 0x00000080 /* Reset the SCSI controller */
|
||||
#define DMA_RST_ENET DMA_RST_SCSI /* Reset the ENET controller */
|
||||
#define DMA_RST_BPP DMA_RST_SCSI /* Reset the BPP controller */
|
||||
#define DMA_ST_WRITE 0x00000100 /* write from device to memory */
|
||||
#define DMA_ENABLE 0x00000200 /* Fire up DMA, handle requests */
|
||||
#define DMA_PEND_READ 0x00000400 /* DMA_VERS1/0/PLUS Pending Read */
|
||||
#define DMA_ESC_BURST 0x00000800 /* 1=16byte 0=32byte */
|
||||
#define DMA_READ_AHEAD 0x00001800 /* DMA read ahead partial longword */
|
||||
#define DMA_DSBL_RD_DRN 0x00001000 /* No EC drain on slave reads */
|
||||
#define DMA_BCNT_ENAB 0x00002000 /* If on, use the byte counter */
|
||||
#define DMA_TERM_CNTR 0x00004000 /* Terminal counter */
|
||||
#define DMA_SCSI_SBUS64 0x00008000 /* HME: Enable 64-bit SBUS mode. */
|
||||
#define DMA_CSR_DISAB 0x00010000 /* No FIFO drains during csr */
|
||||
#define DMA_SCSI_DISAB 0x00020000 /* No FIFO drains during reg */
|
||||
#define DMA_DSBL_WR_INV 0x00020000 /* No EC inval. on slave writes */
|
||||
#define DMA_ADD_ENABLE 0x00040000 /* Special ESC DVMA optimization */
|
||||
#define DMA_E_BURSTS 0x000c0000 /* ENET: SBUS r/w burst mask */
|
||||
#define DMA_E_BURST32 0x00040000 /* ENET: SBUS 32 byte r/w burst */
|
||||
#define DMA_E_BURST16 0x00000000 /* ENET: SBUS 16 byte r/w burst */
|
||||
#define DMA_BRST_SZ 0x000c0000 /* SCSI: SBUS r/w burst size */
|
||||
#define DMA_BRST64 0x00080000 /* SCSI: 64byte bursts (HME on UltraSparc only) */
|
||||
#define DMA_BRST32 0x00040000 /* SCSI/BPP: 32byte bursts */
|
||||
#define DMA_BRST16 0x00000000 /* SCSI/BPP: 16byte bursts */
|
||||
#define DMA_BRST0 0x00080000 /* SCSI: no bursts (non-HME gate arrays) */
|
||||
#define DMA_ADDR_DISAB 0x00100000 /* No FIFO drains during addr */
|
||||
#define DMA_2CLKS 0x00200000 /* Each transfer = 2 clock ticks */
|
||||
#define DMA_3CLKS 0x00400000 /* Each transfer = 3 clock ticks */
|
||||
#define DMA_EN_ENETAUI DMA_3CLKS /* Put lance into AUI-cable mode */
|
||||
#define DMA_CNTR_DISAB 0x00800000 /* No IRQ when DMA_TERM_CNTR set */
|
||||
#define DMA_AUTO_NADDR 0x01000000 /* Use "auto nxt addr" feature */
|
||||
#define DMA_SCSI_ON 0x02000000 /* Enable SCSI dma */
|
||||
#define DMA_BPP_ON DMA_SCSI_ON /* Enable BPP dma */
|
||||
#define DMA_PARITY_OFF 0x02000000 /* HME: disable parity checking */
|
||||
#define DMA_LOADED_ADDR 0x04000000 /* Address has been loaded */
|
||||
#define DMA_LOADED_NADDR 0x08000000 /* Next address has been loaded */
|
||||
#define DMA_RESET_FAS366 0x08000000 /* HME: Assert RESET to FAS366 */
|
||||
|
||||
/* Values describing the burst-size property from the PROM */
|
||||
#define DMA_BURST1 0x01
|
||||
#define DMA_BURST2 0x02
|
||||
#define DMA_BURST4 0x04
|
||||
#define DMA_BURST8 0x08
|
||||
#define DMA_BURST16 0x10
|
||||
#define DMA_BURST32 0x20
|
||||
#define DMA_BURST64 0x40
|
||||
#define DMA_BURSTBITS 0x7f
|
||||
|
||||
/* Determine highest possible final transfer address given a base */
|
||||
#define DMA_MAXEND(addr) (0x01000000UL-(((unsigned long)(addr))&0x00ffffffUL))
|
||||
|
||||
/* Yes, I hack a lot of elisp in my spare time... */
|
||||
#define DMA_ERROR_P(regs) ((((regs)->cond_reg) & DMA_HNDL_ERROR))
|
||||
#define DMA_IRQ_P(regs) ((((regs)->cond_reg) & (DMA_HNDL_INTR | DMA_HNDL_ERROR)))
|
||||
#define DMA_WRITE_P(regs) ((((regs)->cond_reg) & DMA_ST_WRITE))
|
||||
#define DMA_OFF(regs) ((((regs)->cond_reg) &= (~DMA_ENABLE)))
|
||||
#define DMA_INTSOFF(regs) ((((regs)->cond_reg) &= (~DMA_INT_ENAB)))
|
||||
#define DMA_INTSON(regs) ((((regs)->cond_reg) |= (DMA_INT_ENAB)))
|
||||
#define DMA_PUNTFIFO(regs) ((((regs)->cond_reg) |= DMA_FIFO_INV))
|
||||
#define DMA_SETSTART(regs, addr) ((((regs)->st_addr) = (char *) addr))
|
||||
#define DMA_BEGINDMA_W(regs) \
|
||||
((((regs)->cond_reg |= (DMA_ST_WRITE|DMA_ENABLE|DMA_INT_ENAB))))
|
||||
#define DMA_BEGINDMA_R(regs) \
|
||||
((((regs)->cond_reg |= ((DMA_ENABLE|DMA_INT_ENAB)&(~DMA_ST_WRITE)))))
|
||||
|
||||
/* For certain DMA chips, we need to disable ints upon irq entry
|
||||
* and turn them back on when we are done. So in any ESP interrupt
|
||||
* handler you *must* call DMA_IRQ_ENTRY upon entry and DMA_IRQ_EXIT
|
||||
* when leaving the handler. You have been warned...
|
||||
*/
|
||||
#define DMA_IRQ_ENTRY(dma, dregs) do { \
|
||||
if(DMA_ISBROKEN(dma)) DMA_INTSOFF(dregs); \
|
||||
} while (0)
|
||||
|
||||
#define DMA_IRQ_EXIT(dma, dregs) do { \
|
||||
if(DMA_ISBROKEN(dma)) DMA_INTSON(dregs); \
|
||||
} while(0)
|
||||
|
||||
#if 0 /* P3 this stuff is inline in ledma.c:init_restart_ledma() */
|
||||
/* Pause until counter runs out or BIT isn't set in the DMA condition
|
||||
* register.
|
||||
*/
|
||||
static inline void sparc_dma_pause(struct sparc_dma_registers *regs,
|
||||
unsigned long bit)
|
||||
{
|
||||
int ctr = 50000; /* Let's find some bugs ;) */
|
||||
|
||||
/* Busy wait until the bit is not set any more */
|
||||
while((regs->cond_reg&bit) && (ctr>0)) {
|
||||
ctr--;
|
||||
__delay(5);
|
||||
}
|
||||
|
||||
/* Check for bogus outcome. */
|
||||
if(!ctr)
|
||||
panic("DMA timeout");
|
||||
}
|
||||
|
||||
/* Reset the friggin' thing... */
|
||||
#define DMA_RESET(dma) do { \
|
||||
struct sparc_dma_registers *regs = dma->regs; \
|
||||
/* Let the current FIFO drain itself */ \
|
||||
sparc_dma_pause(regs, (DMA_FIFO_ISDRAIN)); \
|
||||
/* Reset the logic */ \
|
||||
regs->cond_reg |= (DMA_RST_SCSI); /* assert */ \
|
||||
__delay(400); /* let the bits set ;) */ \
|
||||
regs->cond_reg &= ~(DMA_RST_SCSI); /* de-assert */ \
|
||||
sparc_dma_enable_interrupts(regs); /* Re-enable interrupts */ \
|
||||
/* Enable FAST transfers if available */ \
|
||||
if(dma->revision>dvmarev1) regs->cond_reg |= DMA_3CLKS; \
|
||||
dma->running = 0; \
|
||||
} while(0)
|
||||
#endif
|
||||
|
||||
#define for_each_dvma(dma) \
|
||||
for((dma) = dma_chain; (dma); (dma) = (dma)->next)
|
||||
|
||||
extern int get_dma_list(char *);
|
||||
extern int request_dma(unsigned int, __const__ char *);
|
||||
extern void free_dma(unsigned int);
|
||||
|
||||
/* From PCI */
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
extern int isa_dma_bridge_buggy;
|
||||
#else
|
||||
#define isa_dma_bridge_buggy (0)
|
||||
#endif
|
||||
|
||||
/* Routines for data transfer buffers. */
|
||||
BTFIXUPDEF_CALL(char *, mmu_lockarea, char *, unsigned long)
|
||||
BTFIXUPDEF_CALL(void, mmu_unlockarea, char *, unsigned long)
|
||||
|
||||
#define mmu_lockarea(vaddr,len) BTFIXUP_CALL(mmu_lockarea)(vaddr,len)
|
||||
#define mmu_unlockarea(vaddr,len) BTFIXUP_CALL(mmu_unlockarea)(vaddr,len)
|
||||
|
||||
/* These are implementations for sbus_map_sg/sbus_unmap_sg... collapse later */
|
||||
BTFIXUPDEF_CALL(__u32, mmu_get_scsi_one, char *, unsigned long, struct sbus_bus *sbus)
|
||||
BTFIXUPDEF_CALL(void, mmu_get_scsi_sgl, struct scatterlist *, int, struct sbus_bus *sbus)
|
||||
BTFIXUPDEF_CALL(void, mmu_release_scsi_one, __u32, unsigned long, struct sbus_bus *sbus)
|
||||
BTFIXUPDEF_CALL(void, mmu_release_scsi_sgl, struct scatterlist *, int, struct sbus_bus *sbus)
|
||||
|
||||
#define mmu_get_scsi_one(vaddr,len,sbus) BTFIXUP_CALL(mmu_get_scsi_one)(vaddr,len,sbus)
|
||||
#define mmu_get_scsi_sgl(sg,sz,sbus) BTFIXUP_CALL(mmu_get_scsi_sgl)(sg,sz,sbus)
|
||||
#define mmu_release_scsi_one(vaddr,len,sbus) BTFIXUP_CALL(mmu_release_scsi_one)(vaddr,len,sbus)
|
||||
#define mmu_release_scsi_sgl(sg,sz,sbus) BTFIXUP_CALL(mmu_release_scsi_sgl)(sg,sz,sbus)
|
||||
|
||||
/*
|
||||
* mmu_map/unmap are provided by iommu/iounit; Invalid to call on IIep.
|
||||
*
|
||||
* The mmu_map_dma_area establishes two mappings in one go.
|
||||
* These mappings point to pages normally mapped at 'va' (linear address).
|
||||
* First mapping is for CPU visible address at 'a', uncached.
|
||||
* This is an alias, but it works because it is an uncached mapping.
|
||||
* Second mapping is for device visible address, or "bus" address.
|
||||
* The bus address is returned at '*pba'.
|
||||
*
|
||||
* These functions seem distinct, but are hard to split. On sun4c,
|
||||
* at least for now, 'a' is equal to bus address, and retured in *pba.
|
||||
* On sun4m, page attributes depend on the CPU type, so we have to
|
||||
* know if we are mapping RAM or I/O, so it has to be an additional argument
|
||||
* to a separate mapping function for CPU visible mappings.
|
||||
*/
|
||||
BTFIXUPDEF_CALL(int, mmu_map_dma_area, dma_addr_t *, unsigned long, unsigned long, int len)
|
||||
BTFIXUPDEF_CALL(struct page *, mmu_translate_dvma, unsigned long busa)
|
||||
BTFIXUPDEF_CALL(void, mmu_unmap_dma_area, unsigned long busa, int len)
|
||||
|
||||
#define mmu_map_dma_area(pba,va,a,len) BTFIXUP_CALL(mmu_map_dma_area)(pba,va,a,len)
|
||||
#define mmu_unmap_dma_area(ba,len) BTFIXUP_CALL(mmu_unmap_dma_area)(ba,len)
|
||||
#define mmu_translate_dvma(ba) BTFIXUP_CALL(mmu_translate_dvma)(ba)
|
||||
|
||||
#endif /* !(_ASM_SPARC_DMA_H) */
|
205
include/asm-sparc/dma_64.h
Normal file
205
include/asm-sparc/dma_64.h
Normal file
|
@ -0,0 +1,205 @@
|
|||
/*
|
||||
* include/asm-sparc64/dma.h
|
||||
*
|
||||
* Copyright 1996 (C) David S. Miller (davem@caip.rutgers.edu)
|
||||
*/
|
||||
|
||||
#ifndef _ASM_SPARC64_DMA_H
|
||||
#define _ASM_SPARC64_DMA_H
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/spinlock.h>
|
||||
|
||||
#include <asm/sbus.h>
|
||||
#include <asm/delay.h>
|
||||
#include <asm/oplib.h>
|
||||
|
||||
/* These are irrelevant for Sparc DMA, but we leave it in so that
|
||||
* things can compile.
|
||||
*/
|
||||
#define MAX_DMA_CHANNELS 8
|
||||
#define DMA_MODE_READ 1
|
||||
#define DMA_MODE_WRITE 2
|
||||
#define MAX_DMA_ADDRESS (~0UL)
|
||||
|
||||
/* Useful constants */
|
||||
#define SIZE_16MB (16*1024*1024)
|
||||
#define SIZE_64K (64*1024)
|
||||
|
||||
/* SBUS DMA controller reg offsets */
|
||||
#define DMA_CSR 0x00UL /* rw DMA control/status register 0x00 */
|
||||
#define DMA_ADDR 0x04UL /* rw DMA transfer address register 0x04 */
|
||||
#define DMA_COUNT 0x08UL /* rw DMA transfer count register 0x08 */
|
||||
#define DMA_TEST 0x0cUL /* rw DMA test/debug register 0x0c */
|
||||
|
||||
/* DVMA chip revisions */
|
||||
enum dvma_rev {
|
||||
dvmarev0,
|
||||
dvmaesc1,
|
||||
dvmarev1,
|
||||
dvmarev2,
|
||||
dvmarev3,
|
||||
dvmarevplus,
|
||||
dvmahme
|
||||
};
|
||||
|
||||
#define DMA_HASCOUNT(rev) ((rev)==dvmaesc1)
|
||||
|
||||
/* Linux DMA information structure, filled during probe. */
|
||||
struct sbus_dma {
|
||||
struct sbus_dma *next;
|
||||
struct sbus_dev *sdev;
|
||||
void __iomem *regs;
|
||||
|
||||
/* Status, misc info */
|
||||
int node; /* Prom node for this DMA device */
|
||||
int running; /* Are we doing DMA now? */
|
||||
int allocated; /* Are we "owned" by anyone yet? */
|
||||
|
||||
/* Transfer information. */
|
||||
u32 addr; /* Start address of current transfer */
|
||||
int nbytes; /* Size of current transfer */
|
||||
int realbytes; /* For splitting up large transfers, etc. */
|
||||
|
||||
/* DMA revision */
|
||||
enum dvma_rev revision;
|
||||
};
|
||||
|
||||
extern struct sbus_dma *dma_chain;
|
||||
|
||||
/* Broken hardware... */
|
||||
#define DMA_ISBROKEN(dma) ((dma)->revision == dvmarev1)
|
||||
#define DMA_ISESC1(dma) ((dma)->revision == dvmaesc1)
|
||||
|
||||
/* Main routines in dma.c */
|
||||
extern void dvma_init(struct sbus_bus *);
|
||||
|
||||
/* Fields in the cond_reg register */
|
||||
/* First, the version identification bits */
|
||||
#define DMA_DEVICE_ID 0xf0000000 /* Device identification bits */
|
||||
#define DMA_VERS0 0x00000000 /* Sunray DMA version */
|
||||
#define DMA_ESCV1 0x40000000 /* DMA ESC Version 1 */
|
||||
#define DMA_VERS1 0x80000000 /* DMA rev 1 */
|
||||
#define DMA_VERS2 0xa0000000 /* DMA rev 2 */
|
||||
#define DMA_VERHME 0xb0000000 /* DMA hme gate array */
|
||||
#define DMA_VERSPLUS 0x90000000 /* DMA rev 1 PLUS */
|
||||
|
||||
#define DMA_HNDL_INTR 0x00000001 /* An IRQ needs to be handled */
|
||||
#define DMA_HNDL_ERROR 0x00000002 /* We need to take an error */
|
||||
#define DMA_FIFO_ISDRAIN 0x0000000c /* The DMA FIFO is draining */
|
||||
#define DMA_INT_ENAB 0x00000010 /* Turn on interrupts */
|
||||
#define DMA_FIFO_INV 0x00000020 /* Invalidate the FIFO */
|
||||
#define DMA_ACC_SZ_ERR 0x00000040 /* The access size was bad */
|
||||
#define DMA_FIFO_STDRAIN 0x00000040 /* DMA_VERS1 Drain the FIFO */
|
||||
#define DMA_RST_SCSI 0x00000080 /* Reset the SCSI controller */
|
||||
#define DMA_RST_ENET DMA_RST_SCSI /* Reset the ENET controller */
|
||||
#define DMA_ST_WRITE 0x00000100 /* write from device to memory */
|
||||
#define DMA_ENABLE 0x00000200 /* Fire up DMA, handle requests */
|
||||
#define DMA_PEND_READ 0x00000400 /* DMA_VERS1/0/PLUS Pending Read */
|
||||
#define DMA_ESC_BURST 0x00000800 /* 1=16byte 0=32byte */
|
||||
#define DMA_READ_AHEAD 0x00001800 /* DMA read ahead partial longword */
|
||||
#define DMA_DSBL_RD_DRN 0x00001000 /* No EC drain on slave reads */
|
||||
#define DMA_BCNT_ENAB 0x00002000 /* If on, use the byte counter */
|
||||
#define DMA_TERM_CNTR 0x00004000 /* Terminal counter */
|
||||
#define DMA_SCSI_SBUS64 0x00008000 /* HME: Enable 64-bit SBUS mode. */
|
||||
#define DMA_CSR_DISAB 0x00010000 /* No FIFO drains during csr */
|
||||
#define DMA_SCSI_DISAB 0x00020000 /* No FIFO drains during reg */
|
||||
#define DMA_DSBL_WR_INV 0x00020000 /* No EC inval. on slave writes */
|
||||
#define DMA_ADD_ENABLE 0x00040000 /* Special ESC DVMA optimization */
|
||||
#define DMA_E_BURSTS 0x000c0000 /* ENET: SBUS r/w burst mask */
|
||||
#define DMA_E_BURST32 0x00040000 /* ENET: SBUS 32 byte r/w burst */
|
||||
#define DMA_E_BURST16 0x00000000 /* ENET: SBUS 16 byte r/w burst */
|
||||
#define DMA_BRST_SZ 0x000c0000 /* SCSI: SBUS r/w burst size */
|
||||
#define DMA_BRST64 0x000c0000 /* SCSI: 64byte bursts (HME on UltraSparc only) */
|
||||
#define DMA_BRST32 0x00040000 /* SCSI: 32byte bursts */
|
||||
#define DMA_BRST16 0x00000000 /* SCSI: 16byte bursts */
|
||||
#define DMA_BRST0 0x00080000 /* SCSI: no bursts (non-HME gate arrays) */
|
||||
#define DMA_ADDR_DISAB 0x00100000 /* No FIFO drains during addr */
|
||||
#define DMA_2CLKS 0x00200000 /* Each transfer = 2 clock ticks */
|
||||
#define DMA_3CLKS 0x00400000 /* Each transfer = 3 clock ticks */
|
||||
#define DMA_EN_ENETAUI DMA_3CLKS /* Put lance into AUI-cable mode */
|
||||
#define DMA_CNTR_DISAB 0x00800000 /* No IRQ when DMA_TERM_CNTR set */
|
||||
#define DMA_AUTO_NADDR 0x01000000 /* Use "auto nxt addr" feature */
|
||||
#define DMA_SCSI_ON 0x02000000 /* Enable SCSI dma */
|
||||
#define DMA_PARITY_OFF 0x02000000 /* HME: disable parity checking */
|
||||
#define DMA_LOADED_ADDR 0x04000000 /* Address has been loaded */
|
||||
#define DMA_LOADED_NADDR 0x08000000 /* Next address has been loaded */
|
||||
#define DMA_RESET_FAS366 0x08000000 /* HME: Assert RESET to FAS366 */
|
||||
|
||||
/* Values describing the burst-size property from the PROM */
|
||||
#define DMA_BURST1 0x01
|
||||
#define DMA_BURST2 0x02
|
||||
#define DMA_BURST4 0x04
|
||||
#define DMA_BURST8 0x08
|
||||
#define DMA_BURST16 0x10
|
||||
#define DMA_BURST32 0x20
|
||||
#define DMA_BURST64 0x40
|
||||
#define DMA_BURSTBITS 0x7f
|
||||
|
||||
/* Determine highest possible final transfer address given a base */
|
||||
#define DMA_MAXEND(addr) (0x01000000UL-(((unsigned long)(addr))&0x00ffffffUL))
|
||||
|
||||
/* Yes, I hack a lot of elisp in my spare time... */
|
||||
#define DMA_ERROR_P(regs) ((sbus_readl((regs) + DMA_CSR) & DMA_HNDL_ERROR))
|
||||
#define DMA_IRQ_P(regs) ((sbus_readl((regs) + DMA_CSR)) & (DMA_HNDL_INTR | DMA_HNDL_ERROR))
|
||||
#define DMA_WRITE_P(regs) ((sbus_readl((regs) + DMA_CSR) & DMA_ST_WRITE))
|
||||
#define DMA_OFF(__regs) \
|
||||
do { u32 tmp = sbus_readl((__regs) + DMA_CSR); \
|
||||
tmp &= ~DMA_ENABLE; \
|
||||
sbus_writel(tmp, (__regs) + DMA_CSR); \
|
||||
} while(0)
|
||||
#define DMA_INTSOFF(__regs) \
|
||||
do { u32 tmp = sbus_readl((__regs) + DMA_CSR); \
|
||||
tmp &= ~DMA_INT_ENAB; \
|
||||
sbus_writel(tmp, (__regs) + DMA_CSR); \
|
||||
} while(0)
|
||||
#define DMA_INTSON(__regs) \
|
||||
do { u32 tmp = sbus_readl((__regs) + DMA_CSR); \
|
||||
tmp |= DMA_INT_ENAB; \
|
||||
sbus_writel(tmp, (__regs) + DMA_CSR); \
|
||||
} while(0)
|
||||
#define DMA_PUNTFIFO(__regs) \
|
||||
do { u32 tmp = sbus_readl((__regs) + DMA_CSR); \
|
||||
tmp |= DMA_FIFO_INV; \
|
||||
sbus_writel(tmp, (__regs) + DMA_CSR); \
|
||||
} while(0)
|
||||
#define DMA_SETSTART(__regs, __addr) \
|
||||
sbus_writel((u32)(__addr), (__regs) + DMA_ADDR);
|
||||
#define DMA_BEGINDMA_W(__regs) \
|
||||
do { u32 tmp = sbus_readl((__regs) + DMA_CSR); \
|
||||
tmp |= (DMA_ST_WRITE|DMA_ENABLE|DMA_INT_ENAB); \
|
||||
sbus_writel(tmp, (__regs) + DMA_CSR); \
|
||||
} while(0)
|
||||
#define DMA_BEGINDMA_R(__regs) \
|
||||
do { u32 tmp = sbus_readl((__regs) + DMA_CSR); \
|
||||
tmp |= (DMA_ENABLE|DMA_INT_ENAB); \
|
||||
tmp &= ~DMA_ST_WRITE; \
|
||||
sbus_writel(tmp, (__regs) + DMA_CSR); \
|
||||
} while(0)
|
||||
|
||||
/* For certain DMA chips, we need to disable ints upon irq entry
|
||||
* and turn them back on when we are done. So in any ESP interrupt
|
||||
* handler you *must* call DMA_IRQ_ENTRY upon entry and DMA_IRQ_EXIT
|
||||
* when leaving the handler. You have been warned...
|
||||
*/
|
||||
#define DMA_IRQ_ENTRY(dma, dregs) do { \
|
||||
if(DMA_ISBROKEN(dma)) DMA_INTSOFF(dregs); \
|
||||
} while (0)
|
||||
|
||||
#define DMA_IRQ_EXIT(dma, dregs) do { \
|
||||
if(DMA_ISBROKEN(dma)) DMA_INTSON(dregs); \
|
||||
} while(0)
|
||||
|
||||
#define for_each_dvma(dma) \
|
||||
for((dma) = dma_chain; (dma); (dma) = (dma)->next)
|
||||
|
||||
/* From PCI */
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
extern int isa_dma_bridge_buggy;
|
||||
#else
|
||||
#define isa_dma_bridge_buggy (0)
|
||||
#endif
|
||||
|
||||
#endif /* !(_ASM_SPARC64_DMA_H) */
|
|
@ -1,99 +1,8 @@
|
|||
/*
|
||||
* ebus.h: PCI to Ebus pseudo driver software state.
|
||||
*
|
||||
* Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be)
|
||||
*
|
||||
* Adopted for sparc by V. Roganov and G. Raiko.
|
||||
*/
|
||||
|
||||
#ifndef __SPARC_EBUS_H
|
||||
#define __SPARC_EBUS_H
|
||||
|
||||
#ifndef _LINUX_IOPORT_H
|
||||
#include <linux/ioport.h>
|
||||
#ifndef ___ASM_SPARC_EBUS_H
|
||||
#define ___ASM_SPARC_EBUS_H
|
||||
#if defined(__sparc__) && defined(__arch64__)
|
||||
#include <asm-sparc/ebus_64.h>
|
||||
#else
|
||||
#include <asm-sparc/ebus_32.h>
|
||||
#endif
|
||||
#endif
|
||||
#include <asm/oplib.h>
|
||||
#include <asm/prom.h>
|
||||
#include <asm/of_device.h>
|
||||
|
||||
struct linux_ebus_child {
|
||||
struct linux_ebus_child *next;
|
||||
struct linux_ebus_device *parent;
|
||||
struct linux_ebus *bus;
|
||||
struct device_node *prom_node;
|
||||
struct resource resource[PROMREG_MAX];
|
||||
int num_addrs;
|
||||
unsigned int irqs[PROMINTR_MAX];
|
||||
int num_irqs;
|
||||
};
|
||||
|
||||
struct linux_ebus_device {
|
||||
struct of_device ofdev;
|
||||
struct linux_ebus_device *next;
|
||||
struct linux_ebus_child *children;
|
||||
struct linux_ebus *bus;
|
||||
struct device_node *prom_node;
|
||||
struct resource resource[PROMREG_MAX];
|
||||
int num_addrs;
|
||||
unsigned int irqs[PROMINTR_MAX];
|
||||
int num_irqs;
|
||||
};
|
||||
#define to_ebus_device(d) container_of(d, struct linux_ebus_device, ofdev.dev)
|
||||
|
||||
struct linux_ebus {
|
||||
struct of_device ofdev;
|
||||
struct linux_ebus *next;
|
||||
struct linux_ebus_device *devices;
|
||||
struct linux_pbm_info *parent;
|
||||
struct pci_dev *self;
|
||||
struct device_node *prom_node;
|
||||
};
|
||||
#define to_ebus(d) container_of(d, struct linux_ebus, ofdev.dev)
|
||||
|
||||
struct linux_ebus_dma {
|
||||
unsigned int dcsr;
|
||||
unsigned int dacr;
|
||||
unsigned int dbcr;
|
||||
};
|
||||
|
||||
#define EBUS_DCSR_INT_PEND 0x00000001
|
||||
#define EBUS_DCSR_ERR_PEND 0x00000002
|
||||
#define EBUS_DCSR_DRAIN 0x00000004
|
||||
#define EBUS_DCSR_INT_EN 0x00000010
|
||||
#define EBUS_DCSR_RESET 0x00000080
|
||||
#define EBUS_DCSR_WRITE 0x00000100
|
||||
#define EBUS_DCSR_EN_DMA 0x00000200
|
||||
#define EBUS_DCSR_CYC_PEND 0x00000400
|
||||
#define EBUS_DCSR_DIAG_RD_DONE 0x00000800
|
||||
#define EBUS_DCSR_DIAG_WR_DONE 0x00001000
|
||||
#define EBUS_DCSR_EN_CNT 0x00002000
|
||||
#define EBUS_DCSR_TC 0x00004000
|
||||
#define EBUS_DCSR_DIS_CSR_DRN 0x00010000
|
||||
#define EBUS_DCSR_BURST_SZ_MASK 0x000c0000
|
||||
#define EBUS_DCSR_BURST_SZ_1 0x00080000
|
||||
#define EBUS_DCSR_BURST_SZ_4 0x00000000
|
||||
#define EBUS_DCSR_BURST_SZ_8 0x00040000
|
||||
#define EBUS_DCSR_BURST_SZ_16 0x000c0000
|
||||
#define EBUS_DCSR_DIAG_EN 0x00100000
|
||||
#define EBUS_DCSR_DIS_ERR_PEND 0x00400000
|
||||
#define EBUS_DCSR_TCI_DIS 0x00800000
|
||||
#define EBUS_DCSR_EN_NEXT 0x01000000
|
||||
#define EBUS_DCSR_DMA_ON 0x02000000
|
||||
#define EBUS_DCSR_A_LOADED 0x04000000
|
||||
#define EBUS_DCSR_NA_LOADED 0x08000000
|
||||
#define EBUS_DCSR_DEV_ID_MASK 0xf0000000
|
||||
|
||||
extern struct linux_ebus *ebus_chain;
|
||||
|
||||
extern void ebus_init(void);
|
||||
|
||||
#define for_each_ebus(bus) \
|
||||
for((bus) = ebus_chain; (bus); (bus) = (bus)->next)
|
||||
|
||||
#define for_each_ebusdev(dev, bus) \
|
||||
for((dev) = (bus)->devices; (dev); (dev) = (dev)->next)
|
||||
|
||||
#define for_each_edevchild(dev, child) \
|
||||
for((child) = (dev)->children; (child); (child) = (child)->next)
|
||||
|
||||
#endif /* !(__SPARC_EBUS_H) */
|
||||
|
|
99
include/asm-sparc/ebus_32.h
Normal file
99
include/asm-sparc/ebus_32.h
Normal file
|
@ -0,0 +1,99 @@
|
|||
/*
|
||||
* ebus.h: PCI to Ebus pseudo driver software state.
|
||||
*
|
||||
* Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be)
|
||||
*
|
||||
* Adopted for sparc by V. Roganov and G. Raiko.
|
||||
*/
|
||||
|
||||
#ifndef __SPARC_EBUS_H
|
||||
#define __SPARC_EBUS_H
|
||||
|
||||
#ifndef _LINUX_IOPORT_H
|
||||
#include <linux/ioport.h>
|
||||
#endif
|
||||
#include <asm/oplib.h>
|
||||
#include <asm/prom.h>
|
||||
#include <asm/of_device.h>
|
||||
|
||||
struct linux_ebus_child {
|
||||
struct linux_ebus_child *next;
|
||||
struct linux_ebus_device *parent;
|
||||
struct linux_ebus *bus;
|
||||
struct device_node *prom_node;
|
||||
struct resource resource[PROMREG_MAX];
|
||||
int num_addrs;
|
||||
unsigned int irqs[PROMINTR_MAX];
|
||||
int num_irqs;
|
||||
};
|
||||
|
||||
struct linux_ebus_device {
|
||||
struct of_device ofdev;
|
||||
struct linux_ebus_device *next;
|
||||
struct linux_ebus_child *children;
|
||||
struct linux_ebus *bus;
|
||||
struct device_node *prom_node;
|
||||
struct resource resource[PROMREG_MAX];
|
||||
int num_addrs;
|
||||
unsigned int irqs[PROMINTR_MAX];
|
||||
int num_irqs;
|
||||
};
|
||||
#define to_ebus_device(d) container_of(d, struct linux_ebus_device, ofdev.dev)
|
||||
|
||||
struct linux_ebus {
|
||||
struct of_device ofdev;
|
||||
struct linux_ebus *next;
|
||||
struct linux_ebus_device *devices;
|
||||
struct linux_pbm_info *parent;
|
||||
struct pci_dev *self;
|
||||
struct device_node *prom_node;
|
||||
};
|
||||
#define to_ebus(d) container_of(d, struct linux_ebus, ofdev.dev)
|
||||
|
||||
struct linux_ebus_dma {
|
||||
unsigned int dcsr;
|
||||
unsigned int dacr;
|
||||
unsigned int dbcr;
|
||||
};
|
||||
|
||||
#define EBUS_DCSR_INT_PEND 0x00000001
|
||||
#define EBUS_DCSR_ERR_PEND 0x00000002
|
||||
#define EBUS_DCSR_DRAIN 0x00000004
|
||||
#define EBUS_DCSR_INT_EN 0x00000010
|
||||
#define EBUS_DCSR_RESET 0x00000080
|
||||
#define EBUS_DCSR_WRITE 0x00000100
|
||||
#define EBUS_DCSR_EN_DMA 0x00000200
|
||||
#define EBUS_DCSR_CYC_PEND 0x00000400
|
||||
#define EBUS_DCSR_DIAG_RD_DONE 0x00000800
|
||||
#define EBUS_DCSR_DIAG_WR_DONE 0x00001000
|
||||
#define EBUS_DCSR_EN_CNT 0x00002000
|
||||
#define EBUS_DCSR_TC 0x00004000
|
||||
#define EBUS_DCSR_DIS_CSR_DRN 0x00010000
|
||||
#define EBUS_DCSR_BURST_SZ_MASK 0x000c0000
|
||||
#define EBUS_DCSR_BURST_SZ_1 0x00080000
|
||||
#define EBUS_DCSR_BURST_SZ_4 0x00000000
|
||||
#define EBUS_DCSR_BURST_SZ_8 0x00040000
|
||||
#define EBUS_DCSR_BURST_SZ_16 0x000c0000
|
||||
#define EBUS_DCSR_DIAG_EN 0x00100000
|
||||
#define EBUS_DCSR_DIS_ERR_PEND 0x00400000
|
||||
#define EBUS_DCSR_TCI_DIS 0x00800000
|
||||
#define EBUS_DCSR_EN_NEXT 0x01000000
|
||||
#define EBUS_DCSR_DMA_ON 0x02000000
|
||||
#define EBUS_DCSR_A_LOADED 0x04000000
|
||||
#define EBUS_DCSR_NA_LOADED 0x08000000
|
||||
#define EBUS_DCSR_DEV_ID_MASK 0xf0000000
|
||||
|
||||
extern struct linux_ebus *ebus_chain;
|
||||
|
||||
extern void ebus_init(void);
|
||||
|
||||
#define for_each_ebus(bus) \
|
||||
for((bus) = ebus_chain; (bus); (bus) = (bus)->next)
|
||||
|
||||
#define for_each_ebusdev(dev, bus) \
|
||||
for((dev) = (bus)->devices; (dev); (dev) = (dev)->next)
|
||||
|
||||
#define for_each_edevchild(dev, child) \
|
||||
for((child) = (dev)->children; (child); (child) = (child)->next)
|
||||
|
||||
#endif /* !(__SPARC_EBUS_H) */
|
94
include/asm-sparc/ebus_64.h
Normal file
94
include/asm-sparc/ebus_64.h
Normal file
|
@ -0,0 +1,94 @@
|
|||
/*
|
||||
* ebus.h: PCI to Ebus pseudo driver software state.
|
||||
*
|
||||
* Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be)
|
||||
* Copyright (C) 1999 David S. Miller (davem@redhat.com)
|
||||
*/
|
||||
|
||||
#ifndef __SPARC64_EBUS_H
|
||||
#define __SPARC64_EBUS_H
|
||||
|
||||
#include <asm/oplib.h>
|
||||
#include <asm/prom.h>
|
||||
#include <asm/of_device.h>
|
||||
|
||||
struct linux_ebus_child {
|
||||
struct linux_ebus_child *next;
|
||||
struct linux_ebus_device *parent;
|
||||
struct linux_ebus *bus;
|
||||
struct device_node *prom_node;
|
||||
struct resource resource[PROMREG_MAX];
|
||||
int num_addrs;
|
||||
unsigned int irqs[PROMINTR_MAX];
|
||||
int num_irqs;
|
||||
};
|
||||
|
||||
struct linux_ebus_device {
|
||||
struct of_device ofdev;
|
||||
struct linux_ebus_device *next;
|
||||
struct linux_ebus_child *children;
|
||||
struct linux_ebus *bus;
|
||||
struct device_node *prom_node;
|
||||
struct resource resource[PROMREG_MAX];
|
||||
int num_addrs;
|
||||
unsigned int irqs[PROMINTR_MAX];
|
||||
int num_irqs;
|
||||
};
|
||||
#define to_ebus_device(d) container_of(d, struct linux_ebus_device, ofdev.dev)
|
||||
|
||||
struct linux_ebus {
|
||||
struct of_device ofdev;
|
||||
struct linux_ebus *next;
|
||||
struct linux_ebus_device *devices;
|
||||
struct pci_dev *self;
|
||||
int index;
|
||||
int is_rio;
|
||||
struct device_node *prom_node;
|
||||
};
|
||||
#define to_ebus(d) container_of(d, struct linux_ebus, ofdev.dev)
|
||||
|
||||
struct ebus_dma_info {
|
||||
spinlock_t lock;
|
||||
void __iomem *regs;
|
||||
|
||||
unsigned int flags;
|
||||
#define EBUS_DMA_FLAG_USE_EBDMA_HANDLER 0x00000001
|
||||
#define EBUS_DMA_FLAG_TCI_DISABLE 0x00000002
|
||||
|
||||
/* These are only valid is EBUS_DMA_FLAG_USE_EBDMA_HANDLER is
|
||||
* set.
|
||||
*/
|
||||
void (*callback)(struct ebus_dma_info *p, int event, void *cookie);
|
||||
void *client_cookie;
|
||||
unsigned int irq;
|
||||
#define EBUS_DMA_EVENT_ERROR 1
|
||||
#define EBUS_DMA_EVENT_DMA 2
|
||||
#define EBUS_DMA_EVENT_DEVICE 4
|
||||
|
||||
unsigned char name[64];
|
||||
};
|
||||
|
||||
extern int ebus_dma_register(struct ebus_dma_info *p);
|
||||
extern int ebus_dma_irq_enable(struct ebus_dma_info *p, int on);
|
||||
extern void ebus_dma_unregister(struct ebus_dma_info *p);
|
||||
extern int ebus_dma_request(struct ebus_dma_info *p, dma_addr_t bus_addr,
|
||||
size_t len);
|
||||
extern void ebus_dma_prepare(struct ebus_dma_info *p, int write);
|
||||
extern unsigned int ebus_dma_residue(struct ebus_dma_info *p);
|
||||
extern unsigned int ebus_dma_addr(struct ebus_dma_info *p);
|
||||
extern void ebus_dma_enable(struct ebus_dma_info *p, int on);
|
||||
|
||||
extern struct linux_ebus *ebus_chain;
|
||||
|
||||
extern void ebus_init(void);
|
||||
|
||||
#define for_each_ebus(bus) \
|
||||
for((bus) = ebus_chain; (bus); (bus) = (bus)->next)
|
||||
|
||||
#define for_each_ebusdev(dev, bus) \
|
||||
for((dev) = (bus)->devices; (dev); (dev) = (dev)->next)
|
||||
|
||||
#define for_each_edevchild(dev, child) \
|
||||
for((child) = (dev)->children; (child); (child) = (child)->next)
|
||||
|
||||
#endif /* !(__SPARC64_EBUS_H) */
|
|
@ -1,145 +1,8 @@
|
|||
#ifndef __ASMSPARC_ELF_H
|
||||
#define __ASMSPARC_ELF_H
|
||||
|
||||
/*
|
||||
* ELF register definitions..
|
||||
*/
|
||||
|
||||
#include <asm/ptrace.h>
|
||||
|
||||
/*
|
||||
* Sparc section types
|
||||
*/
|
||||
#define STT_REGISTER 13
|
||||
|
||||
/*
|
||||
* Sparc ELF relocation types
|
||||
*/
|
||||
#define R_SPARC_NONE 0
|
||||
#define R_SPARC_8 1
|
||||
#define R_SPARC_16 2
|
||||
#define R_SPARC_32 3
|
||||
#define R_SPARC_DISP8 4
|
||||
#define R_SPARC_DISP16 5
|
||||
#define R_SPARC_DISP32 6
|
||||
#define R_SPARC_WDISP30 7
|
||||
#define R_SPARC_WDISP22 8
|
||||
#define R_SPARC_HI22 9
|
||||
#define R_SPARC_22 10
|
||||
#define R_SPARC_13 11
|
||||
#define R_SPARC_LO10 12
|
||||
#define R_SPARC_GOT10 13
|
||||
#define R_SPARC_GOT13 14
|
||||
#define R_SPARC_GOT22 15
|
||||
#define R_SPARC_PC10 16
|
||||
#define R_SPARC_PC22 17
|
||||
#define R_SPARC_WPLT30 18
|
||||
#define R_SPARC_COPY 19
|
||||
#define R_SPARC_GLOB_DAT 20
|
||||
#define R_SPARC_JMP_SLOT 21
|
||||
#define R_SPARC_RELATIVE 22
|
||||
#define R_SPARC_UA32 23
|
||||
#define R_SPARC_PLT32 24
|
||||
#define R_SPARC_HIPLT22 25
|
||||
#define R_SPARC_LOPLT10 26
|
||||
#define R_SPARC_PCPLT32 27
|
||||
#define R_SPARC_PCPLT22 28
|
||||
#define R_SPARC_PCPLT10 29
|
||||
#define R_SPARC_10 30
|
||||
#define R_SPARC_11 31
|
||||
#define R_SPARC_64 32
|
||||
#define R_SPARC_OLO10 33
|
||||
#define R_SPARC_WDISP16 40
|
||||
#define R_SPARC_WDISP19 41
|
||||
#define R_SPARC_7 43
|
||||
#define R_SPARC_5 44
|
||||
#define R_SPARC_6 45
|
||||
|
||||
/* Bits present in AT_HWCAP, primarily for Sparc32. */
|
||||
|
||||
#define HWCAP_SPARC_FLUSH 1 /* CPU supports flush instruction. */
|
||||
#define HWCAP_SPARC_STBAR 2
|
||||
#define HWCAP_SPARC_SWAP 4
|
||||
#define HWCAP_SPARC_MULDIV 8
|
||||
#define HWCAP_SPARC_V9 16
|
||||
#define HWCAP_SPARC_ULTRA3 32
|
||||
|
||||
#define CORE_DUMP_USE_REGSET
|
||||
|
||||
/* Format is:
|
||||
* G0 --> G7
|
||||
* O0 --> O7
|
||||
* L0 --> L7
|
||||
* I0 --> I7
|
||||
* PSR, PC, nPC, Y, WIM, TBR
|
||||
*/
|
||||
typedef unsigned long elf_greg_t;
|
||||
#define ELF_NGREG 38
|
||||
typedef elf_greg_t elf_gregset_t[ELF_NGREG];
|
||||
|
||||
typedef struct {
|
||||
union {
|
||||
unsigned long pr_regs[32];
|
||||
double pr_dregs[16];
|
||||
} pr_fr;
|
||||
unsigned long __unused;
|
||||
unsigned long pr_fsr;
|
||||
unsigned char pr_qcnt;
|
||||
unsigned char pr_q_entrysize;
|
||||
unsigned char pr_en;
|
||||
unsigned int pr_q[64];
|
||||
} elf_fpregset_t;
|
||||
|
||||
#include <asm/mbus.h>
|
||||
|
||||
/*
|
||||
* This is used to ensure we don't load something for the wrong architecture.
|
||||
*/
|
||||
#define elf_check_arch(x) ((x)->e_machine == EM_SPARC)
|
||||
|
||||
/*
|
||||
* These are used to set parameters in the core dumps.
|
||||
*/
|
||||
#define ELF_ARCH EM_SPARC
|
||||
#define ELF_CLASS ELFCLASS32
|
||||
#define ELF_DATA ELFDATA2MSB
|
||||
|
||||
#define USE_ELF_CORE_DUMP
|
||||
#ifndef CONFIG_SUN4
|
||||
#define ELF_EXEC_PAGESIZE 4096
|
||||
#ifndef ___ASM_SPARC_ELF_H
|
||||
#define ___ASM_SPARC_ELF_H
|
||||
#if defined(__sparc__) && defined(__arch64__)
|
||||
#include <asm-sparc/elf_64.h>
|
||||
#else
|
||||
#define ELF_EXEC_PAGESIZE 8192
|
||||
#include <asm-sparc/elf_32.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
/* 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 (TASK_UNMAPPED_BASE)
|
||||
|
||||
/* This yields a mask that user programs can use to figure out what
|
||||
instruction set this cpu supports. This can NOT be done in userspace
|
||||
on Sparc. */
|
||||
|
||||
/* Sun4c has none of the capabilities, most sun4m's have them all.
|
||||
* XXX This is gross, set some global variable at boot time. -DaveM
|
||||
*/
|
||||
#define ELF_HWCAP ((ARCH_SUN4C_SUN4) ? 0 : \
|
||||
(HWCAP_SPARC_FLUSH | HWCAP_SPARC_STBAR | \
|
||||
HWCAP_SPARC_SWAP | \
|
||||
((srmmu_modtype != Cypress && \
|
||||
srmmu_modtype != Cypress_vE && \
|
||||
srmmu_modtype != Cypress_vD) ? \
|
||||
HWCAP_SPARC_MULDIV : 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. */
|
||||
|
||||
#define ELF_PLATFORM (NULL)
|
||||
|
||||
#define SET_PERSONALITY(ex, ibcs2) set_personality((ibcs2)?PER_SVR4:PER_LINUX)
|
||||
|
||||
#endif /* !(__ASMSPARC_ELF_H) */
|
||||
|
|
145
include/asm-sparc/elf_32.h
Normal file
145
include/asm-sparc/elf_32.h
Normal file
|
@ -0,0 +1,145 @@
|
|||
#ifndef __ASMSPARC_ELF_H
|
||||
#define __ASMSPARC_ELF_H
|
||||
|
||||
/*
|
||||
* ELF register definitions..
|
||||
*/
|
||||
|
||||
#include <asm/ptrace.h>
|
||||
|
||||
/*
|
||||
* Sparc section types
|
||||
*/
|
||||
#define STT_REGISTER 13
|
||||
|
||||
/*
|
||||
* Sparc ELF relocation types
|
||||
*/
|
||||
#define R_SPARC_NONE 0
|
||||
#define R_SPARC_8 1
|
||||
#define R_SPARC_16 2
|
||||
#define R_SPARC_32 3
|
||||
#define R_SPARC_DISP8 4
|
||||
#define R_SPARC_DISP16 5
|
||||
#define R_SPARC_DISP32 6
|
||||
#define R_SPARC_WDISP30 7
|
||||
#define R_SPARC_WDISP22 8
|
||||
#define R_SPARC_HI22 9
|
||||
#define R_SPARC_22 10
|
||||
#define R_SPARC_13 11
|
||||
#define R_SPARC_LO10 12
|
||||
#define R_SPARC_GOT10 13
|
||||
#define R_SPARC_GOT13 14
|
||||
#define R_SPARC_GOT22 15
|
||||
#define R_SPARC_PC10 16
|
||||
#define R_SPARC_PC22 17
|
||||
#define R_SPARC_WPLT30 18
|
||||
#define R_SPARC_COPY 19
|
||||
#define R_SPARC_GLOB_DAT 20
|
||||
#define R_SPARC_JMP_SLOT 21
|
||||
#define R_SPARC_RELATIVE 22
|
||||
#define R_SPARC_UA32 23
|
||||
#define R_SPARC_PLT32 24
|
||||
#define R_SPARC_HIPLT22 25
|
||||
#define R_SPARC_LOPLT10 26
|
||||
#define R_SPARC_PCPLT32 27
|
||||
#define R_SPARC_PCPLT22 28
|
||||
#define R_SPARC_PCPLT10 29
|
||||
#define R_SPARC_10 30
|
||||
#define R_SPARC_11 31
|
||||
#define R_SPARC_64 32
|
||||
#define R_SPARC_OLO10 33
|
||||
#define R_SPARC_WDISP16 40
|
||||
#define R_SPARC_WDISP19 41
|
||||
#define R_SPARC_7 43
|
||||
#define R_SPARC_5 44
|
||||
#define R_SPARC_6 45
|
||||
|
||||
/* Bits present in AT_HWCAP, primarily for Sparc32. */
|
||||
|
||||
#define HWCAP_SPARC_FLUSH 1 /* CPU supports flush instruction. */
|
||||
#define HWCAP_SPARC_STBAR 2
|
||||
#define HWCAP_SPARC_SWAP 4
|
||||
#define HWCAP_SPARC_MULDIV 8
|
||||
#define HWCAP_SPARC_V9 16
|
||||
#define HWCAP_SPARC_ULTRA3 32
|
||||
|
||||
#define CORE_DUMP_USE_REGSET
|
||||
|
||||
/* Format is:
|
||||
* G0 --> G7
|
||||
* O0 --> O7
|
||||
* L0 --> L7
|
||||
* I0 --> I7
|
||||
* PSR, PC, nPC, Y, WIM, TBR
|
||||
*/
|
||||
typedef unsigned long elf_greg_t;
|
||||
#define ELF_NGREG 38
|
||||
typedef elf_greg_t elf_gregset_t[ELF_NGREG];
|
||||
|
||||
typedef struct {
|
||||
union {
|
||||
unsigned long pr_regs[32];
|
||||
double pr_dregs[16];
|
||||
} pr_fr;
|
||||
unsigned long __unused;
|
||||
unsigned long pr_fsr;
|
||||
unsigned char pr_qcnt;
|
||||
unsigned char pr_q_entrysize;
|
||||
unsigned char pr_en;
|
||||
unsigned int pr_q[64];
|
||||
} elf_fpregset_t;
|
||||
|
||||
#include <asm/mbus.h>
|
||||
|
||||
/*
|
||||
* This is used to ensure we don't load something for the wrong architecture.
|
||||
*/
|
||||
#define elf_check_arch(x) ((x)->e_machine == EM_SPARC)
|
||||
|
||||
/*
|
||||
* These are used to set parameters in the core dumps.
|
||||
*/
|
||||
#define ELF_ARCH EM_SPARC
|
||||
#define ELF_CLASS ELFCLASS32
|
||||
#define ELF_DATA ELFDATA2MSB
|
||||
|
||||
#define USE_ELF_CORE_DUMP
|
||||
#ifndef CONFIG_SUN4
|
||||
#define ELF_EXEC_PAGESIZE 4096
|
||||
#else
|
||||
#define ELF_EXEC_PAGESIZE 8192
|
||||
#endif
|
||||
|
||||
|
||||
/* 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 (TASK_UNMAPPED_BASE)
|
||||
|
||||
/* This yields a mask that user programs can use to figure out what
|
||||
instruction set this cpu supports. This can NOT be done in userspace
|
||||
on Sparc. */
|
||||
|
||||
/* Sun4c has none of the capabilities, most sun4m's have them all.
|
||||
* XXX This is gross, set some global variable at boot time. -DaveM
|
||||
*/
|
||||
#define ELF_HWCAP ((ARCH_SUN4C_SUN4) ? 0 : \
|
||||
(HWCAP_SPARC_FLUSH | HWCAP_SPARC_STBAR | \
|
||||
HWCAP_SPARC_SWAP | \
|
||||
((srmmu_modtype != Cypress && \
|
||||
srmmu_modtype != Cypress_vE && \
|
||||
srmmu_modtype != Cypress_vD) ? \
|
||||
HWCAP_SPARC_MULDIV : 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. */
|
||||
|
||||
#define ELF_PLATFORM (NULL)
|
||||
|
||||
#define SET_PERSONALITY(ex, ibcs2) set_personality((ibcs2)?PER_SVR4:PER_LINUX)
|
||||
|
||||
#endif /* !(__ASMSPARC_ELF_H) */
|
217
include/asm-sparc/elf_64.h
Normal file
217
include/asm-sparc/elf_64.h
Normal file
|
@ -0,0 +1,217 @@
|
|||
#ifndef __ASM_SPARC64_ELF_H
|
||||
#define __ASM_SPARC64_ELF_H
|
||||
|
||||
/*
|
||||
* ELF register definitions..
|
||||
*/
|
||||
|
||||
#include <asm/ptrace.h>
|
||||
#include <asm/processor.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/spitfire.h>
|
||||
|
||||
/*
|
||||
* Sparc section types
|
||||
*/
|
||||
#define STT_REGISTER 13
|
||||
|
||||
/*
|
||||
* Sparc ELF relocation types
|
||||
*/
|
||||
#define R_SPARC_NONE 0
|
||||
#define R_SPARC_8 1
|
||||
#define R_SPARC_16 2
|
||||
#define R_SPARC_32 3
|
||||
#define R_SPARC_DISP8 4
|
||||
#define R_SPARC_DISP16 5
|
||||
#define R_SPARC_DISP32 6
|
||||
#define R_SPARC_WDISP30 7
|
||||
#define R_SPARC_WDISP22 8
|
||||
#define R_SPARC_HI22 9
|
||||
#define R_SPARC_22 10
|
||||
#define R_SPARC_13 11
|
||||
#define R_SPARC_LO10 12
|
||||
#define R_SPARC_GOT10 13
|
||||
#define R_SPARC_GOT13 14
|
||||
#define R_SPARC_GOT22 15
|
||||
#define R_SPARC_PC10 16
|
||||
#define R_SPARC_PC22 17
|
||||
#define R_SPARC_WPLT30 18
|
||||
#define R_SPARC_COPY 19
|
||||
#define R_SPARC_GLOB_DAT 20
|
||||
#define R_SPARC_JMP_SLOT 21
|
||||
#define R_SPARC_RELATIVE 22
|
||||
#define R_SPARC_UA32 23
|
||||
#define R_SPARC_PLT32 24
|
||||
#define R_SPARC_HIPLT22 25
|
||||
#define R_SPARC_LOPLT10 26
|
||||
#define R_SPARC_PCPLT32 27
|
||||
#define R_SPARC_PCPLT22 28
|
||||
#define R_SPARC_PCPLT10 29
|
||||
#define R_SPARC_10 30
|
||||
#define R_SPARC_11 31
|
||||
#define R_SPARC_64 32
|
||||
#define R_SPARC_OLO10 33
|
||||
#define R_SPARC_WDISP16 40
|
||||
#define R_SPARC_WDISP19 41
|
||||
#define R_SPARC_7 43
|
||||
#define R_SPARC_5 44
|
||||
#define R_SPARC_6 45
|
||||
|
||||
/* Bits present in AT_HWCAP, primarily for Sparc32. */
|
||||
|
||||
#define HWCAP_SPARC_FLUSH 1 /* CPU supports flush instruction. */
|
||||
#define HWCAP_SPARC_STBAR 2
|
||||
#define HWCAP_SPARC_SWAP 4
|
||||
#define HWCAP_SPARC_MULDIV 8
|
||||
#define HWCAP_SPARC_V9 16
|
||||
#define HWCAP_SPARC_ULTRA3 32
|
||||
#define HWCAP_SPARC_BLKINIT 64
|
||||
#define HWCAP_SPARC_N2 128
|
||||
|
||||
#define CORE_DUMP_USE_REGSET
|
||||
|
||||
/*
|
||||
* These are used to set parameters in the core dumps.
|
||||
*/
|
||||
#define ELF_ARCH EM_SPARCV9
|
||||
#define ELF_CLASS ELFCLASS64
|
||||
#define ELF_DATA ELFDATA2MSB
|
||||
|
||||
/* Format of 64-bit elf_gregset_t is:
|
||||
* G0 --> G7
|
||||
* O0 --> O7
|
||||
* L0 --> L7
|
||||
* I0 --> I7
|
||||
* TSTATE
|
||||
* TPC
|
||||
* TNPC
|
||||
* Y
|
||||
*/
|
||||
typedef unsigned long elf_greg_t;
|
||||
#define ELF_NGREG 36
|
||||
typedef elf_greg_t elf_gregset_t[ELF_NGREG];
|
||||
|
||||
typedef struct {
|
||||
unsigned long pr_regs[32];
|
||||
unsigned long pr_fsr;
|
||||
unsigned long pr_gsr;
|
||||
unsigned long pr_fprs;
|
||||
} elf_fpregset_t;
|
||||
|
||||
/* Format of 32-bit elf_gregset_t is:
|
||||
* G0 --> G7
|
||||
* O0 --> O7
|
||||
* L0 --> L7
|
||||
* I0 --> I7
|
||||
* PSR, PC, nPC, Y, WIM, TBR
|
||||
*/
|
||||
typedef unsigned int compat_elf_greg_t;
|
||||
#define COMPAT_ELF_NGREG 38
|
||||
typedef compat_elf_greg_t compat_elf_gregset_t[COMPAT_ELF_NGREG];
|
||||
|
||||
typedef struct {
|
||||
union {
|
||||
unsigned int pr_regs[32];
|
||||
unsigned long pr_dregs[16];
|
||||
} pr_fr;
|
||||
unsigned int __unused;
|
||||
unsigned int pr_fsr;
|
||||
unsigned char pr_qcnt;
|
||||
unsigned char pr_q_entrysize;
|
||||
unsigned char pr_en;
|
||||
unsigned int pr_q[64];
|
||||
} compat_elf_fpregset_t;
|
||||
|
||||
/* UltraSparc extensions. Still unused, but will be eventually. */
|
||||
typedef struct {
|
||||
unsigned int pr_type;
|
||||
unsigned int pr_align;
|
||||
union {
|
||||
struct {
|
||||
union {
|
||||
unsigned int pr_regs[32];
|
||||
unsigned long pr_dregs[16];
|
||||
long double pr_qregs[8];
|
||||
} pr_xfr;
|
||||
} pr_v8p;
|
||||
unsigned int pr_xfsr;
|
||||
unsigned int pr_fprs;
|
||||
unsigned int pr_xg[8];
|
||||
unsigned int pr_xo[8];
|
||||
unsigned long pr_tstate;
|
||||
unsigned int pr_filler[8];
|
||||
} pr_un;
|
||||
} elf_xregset_t;
|
||||
|
||||
/*
|
||||
* This is used to ensure we don't load something for the wrong architecture.
|
||||
*/
|
||||
#define elf_check_arch(x) ((x)->e_machine == ELF_ARCH)
|
||||
#define compat_elf_check_arch(x) ((x)->e_machine == EM_SPARC || \
|
||||
(x)->e_machine == EM_SPARC32PLUS)
|
||||
#define compat_start_thread start_thread32
|
||||
|
||||
#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 0x0000010000000000UL
|
||||
#define COMPAT_ELF_ET_DYN_BASE 0x0000000070000000UL
|
||||
|
||||
|
||||
/* This yields a mask that user programs can use to figure out what
|
||||
instruction set this cpu supports. */
|
||||
|
||||
/* On Ultra, we support all of the v8 capabilities. */
|
||||
static inline unsigned int sparc64_elf_hwcap(void)
|
||||
{
|
||||
unsigned int cap = (HWCAP_SPARC_FLUSH | HWCAP_SPARC_STBAR |
|
||||
HWCAP_SPARC_SWAP | HWCAP_SPARC_MULDIV |
|
||||
HWCAP_SPARC_V9);
|
||||
|
||||
if (tlb_type == cheetah || tlb_type == cheetah_plus)
|
||||
cap |= HWCAP_SPARC_ULTRA3;
|
||||
else if (tlb_type == hypervisor) {
|
||||
if (sun4v_chip_type == SUN4V_CHIP_NIAGARA1 ||
|
||||
sun4v_chip_type == SUN4V_CHIP_NIAGARA2)
|
||||
cap |= HWCAP_SPARC_BLKINIT;
|
||||
if (sun4v_chip_type == SUN4V_CHIP_NIAGARA2)
|
||||
cap |= HWCAP_SPARC_N2;
|
||||
}
|
||||
|
||||
return cap;
|
||||
}
|
||||
|
||||
#define ELF_HWCAP sparc64_elf_hwcap();
|
||||
|
||||
/* 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. */
|
||||
|
||||
#define ELF_PLATFORM (NULL)
|
||||
|
||||
#define SET_PERSONALITY(ex, ibcs2) \
|
||||
do { unsigned long new_flags = current_thread_info()->flags; \
|
||||
new_flags &= _TIF_32BIT; \
|
||||
if ((ex).e_ident[EI_CLASS] == ELFCLASS32) \
|
||||
new_flags |= _TIF_32BIT; \
|
||||
else \
|
||||
new_flags &= ~_TIF_32BIT; \
|
||||
if ((current_thread_info()->flags & _TIF_32BIT) \
|
||||
!= new_flags) \
|
||||
set_thread_flag(TIF_ABI_PENDING); \
|
||||
else \
|
||||
clear_thread_flag(TIF_ABI_PENDING); \
|
||||
/* flush_thread will update pgd cache */ \
|
||||
if (ibcs2) \
|
||||
set_personality(PER_SVR4); \
|
||||
else if (current->personality != PER_LINUX32) \
|
||||
set_personality(PER_LINUX); \
|
||||
} while (0)
|
||||
|
||||
#endif /* !(__ASM_SPARC64_ELF_H) */
|
|
@ -1,388 +1,8 @@
|
|||
/* asm-sparc/floppy.h: Sparc specific parts of the Floppy driver.
|
||||
*
|
||||
* Copyright (C) 1995 David S. Miller (davem@davemloft.net)
|
||||
*/
|
||||
|
||||
#ifndef __ASM_SPARC_FLOPPY_H
|
||||
#define __ASM_SPARC_FLOPPY_H
|
||||
|
||||
#include <asm/page.h>
|
||||
#include <asm/pgtable.h>
|
||||
#include <asm/system.h>
|
||||
#include <asm/idprom.h>
|
||||
#include <asm/machines.h>
|
||||
#include <asm/oplib.h>
|
||||
#include <asm/auxio.h>
|
||||
#include <asm/irq.h>
|
||||
|
||||
/* We don't need no stinkin' I/O port allocation crap. */
|
||||
#undef release_region
|
||||
#undef request_region
|
||||
#define release_region(X, Y) do { } while(0)
|
||||
#define request_region(X, Y, Z) (1)
|
||||
|
||||
/* References:
|
||||
* 1) Netbsd Sun floppy driver.
|
||||
* 2) NCR 82077 controller manual
|
||||
* 3) Intel 82077 controller manual
|
||||
*/
|
||||
struct sun_flpy_controller {
|
||||
volatile unsigned char status_82072; /* Main Status reg. */
|
||||
#define dcr_82072 status_82072 /* Digital Control reg. */
|
||||
#define status1_82077 status_82072 /* Auxiliary Status reg. 1 */
|
||||
|
||||
volatile unsigned char data_82072; /* Data fifo. */
|
||||
#define status2_82077 data_82072 /* Auxiliary Status reg. 2 */
|
||||
|
||||
volatile unsigned char dor_82077; /* Digital Output reg. */
|
||||
volatile unsigned char tapectl_82077; /* What the? Tape control reg? */
|
||||
|
||||
volatile unsigned char status_82077; /* Main Status Register. */
|
||||
#define drs_82077 status_82077 /* Digital Rate Select reg. */
|
||||
|
||||
volatile unsigned char data_82077; /* Data fifo. */
|
||||
volatile unsigned char ___unused;
|
||||
volatile unsigned char dir_82077; /* Digital Input reg. */
|
||||
#define dcr_82077 dir_82077 /* Config Control reg. */
|
||||
};
|
||||
|
||||
/* You'll only ever find one controller on a SparcStation anyways. */
|
||||
static struct sun_flpy_controller *sun_fdc = NULL;
|
||||
extern volatile unsigned char *fdc_status;
|
||||
|
||||
struct sun_floppy_ops {
|
||||
unsigned char (*fd_inb)(int port);
|
||||
void (*fd_outb)(unsigned char value, int port);
|
||||
};
|
||||
|
||||
static struct sun_floppy_ops sun_fdops;
|
||||
|
||||
#define fd_inb(port) sun_fdops.fd_inb(port)
|
||||
#define fd_outb(value,port) sun_fdops.fd_outb(value,port)
|
||||
#define fd_enable_dma() sun_fd_enable_dma()
|
||||
#define fd_disable_dma() sun_fd_disable_dma()
|
||||
#define fd_request_dma() (0) /* nothing... */
|
||||
#define fd_free_dma() /* nothing... */
|
||||
#define fd_clear_dma_ff() /* nothing... */
|
||||
#define fd_set_dma_mode(mode) sun_fd_set_dma_mode(mode)
|
||||
#define fd_set_dma_addr(addr) sun_fd_set_dma_addr(addr)
|
||||
#define fd_set_dma_count(count) sun_fd_set_dma_count(count)
|
||||
#define fd_enable_irq() /* nothing... */
|
||||
#define fd_disable_irq() /* nothing... */
|
||||
#define fd_cacheflush(addr, size) /* nothing... */
|
||||
#define fd_request_irq() sun_fd_request_irq()
|
||||
#define fd_free_irq() /* nothing... */
|
||||
#if 0 /* P3: added by Alain, these cause a MMU corruption. 19960524 XXX */
|
||||
#define fd_dma_mem_alloc(size) ((unsigned long) vmalloc(size))
|
||||
#define fd_dma_mem_free(addr,size) (vfree((void *)(addr)))
|
||||
#ifndef ___ASM_SPARC_FLOPPY_H
|
||||
#define ___ASM_SPARC_FLOPPY_H
|
||||
#if defined(__sparc__) && defined(__arch64__)
|
||||
#include <asm-sparc/floppy_64.h>
|
||||
#else
|
||||
#include <asm-sparc/floppy_32.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* XXX This isn't really correct. XXX */
|
||||
#define get_dma_residue(x) (0)
|
||||
|
||||
#define FLOPPY0_TYPE 4
|
||||
#define FLOPPY1_TYPE 0
|
||||
|
||||
/* Super paranoid... */
|
||||
#undef HAVE_DISABLE_HLT
|
||||
|
||||
/* Here is where we catch the floppy driver trying to initialize,
|
||||
* therefore this is where we call the PROM device tree probing
|
||||
* routine etc. on the Sparc.
|
||||
*/
|
||||
#define FDC1 sun_floppy_init()
|
||||
|
||||
#define N_FDC 1
|
||||
#define N_DRIVE 8
|
||||
|
||||
/* No 64k boundary crossing problems on the Sparc. */
|
||||
#define CROSS_64KB(a,s) (0)
|
||||
|
||||
/* Routines unique to each controller type on a Sun. */
|
||||
static void sun_set_dor(unsigned char value, int fdc_82077)
|
||||
{
|
||||
if (sparc_cpu_model == sun4c) {
|
||||
unsigned int bits = 0;
|
||||
if (value & 0x10)
|
||||
bits |= AUXIO_FLPY_DSEL;
|
||||
if ((value & 0x80) == 0)
|
||||
bits |= AUXIO_FLPY_EJCT;
|
||||
set_auxio(bits, (~bits) & (AUXIO_FLPY_DSEL|AUXIO_FLPY_EJCT));
|
||||
}
|
||||
if (fdc_82077) {
|
||||
sun_fdc->dor_82077 = value;
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned char sun_read_dir(void)
|
||||
{
|
||||
if (sparc_cpu_model == sun4c)
|
||||
return (get_auxio() & AUXIO_FLPY_DCHG) ? 0x80 : 0;
|
||||
else
|
||||
return sun_fdc->dir_82077;
|
||||
}
|
||||
|
||||
static unsigned char sun_82072_fd_inb(int port)
|
||||
{
|
||||
udelay(5);
|
||||
switch(port & 7) {
|
||||
default:
|
||||
printk("floppy: Asked to read unknown port %d\n", port);
|
||||
panic("floppy: Port bolixed.");
|
||||
case 4: /* FD_STATUS */
|
||||
return sun_fdc->status_82072 & ~STATUS_DMA;
|
||||
case 5: /* FD_DATA */
|
||||
return sun_fdc->data_82072;
|
||||
case 7: /* FD_DIR */
|
||||
return sun_read_dir();
|
||||
};
|
||||
panic("sun_82072_fd_inb: How did I get here?");
|
||||
}
|
||||
|
||||
static void sun_82072_fd_outb(unsigned char value, int port)
|
||||
{
|
||||
udelay(5);
|
||||
switch(port & 7) {
|
||||
default:
|
||||
printk("floppy: Asked to write to unknown port %d\n", port);
|
||||
panic("floppy: Port bolixed.");
|
||||
case 2: /* FD_DOR */
|
||||
sun_set_dor(value, 0);
|
||||
break;
|
||||
case 5: /* FD_DATA */
|
||||
sun_fdc->data_82072 = value;
|
||||
break;
|
||||
case 7: /* FD_DCR */
|
||||
sun_fdc->dcr_82072 = value;
|
||||
break;
|
||||
case 4: /* FD_STATUS */
|
||||
sun_fdc->status_82072 = value;
|
||||
break;
|
||||
};
|
||||
return;
|
||||
}
|
||||
|
||||
static unsigned char sun_82077_fd_inb(int port)
|
||||
{
|
||||
udelay(5);
|
||||
switch(port & 7) {
|
||||
default:
|
||||
printk("floppy: Asked to read unknown port %d\n", port);
|
||||
panic("floppy: Port bolixed.");
|
||||
case 0: /* FD_STATUS_0 */
|
||||
return sun_fdc->status1_82077;
|
||||
case 1: /* FD_STATUS_1 */
|
||||
return sun_fdc->status2_82077;
|
||||
case 2: /* FD_DOR */
|
||||
return sun_fdc->dor_82077;
|
||||
case 3: /* FD_TDR */
|
||||
return sun_fdc->tapectl_82077;
|
||||
case 4: /* FD_STATUS */
|
||||
return sun_fdc->status_82077 & ~STATUS_DMA;
|
||||
case 5: /* FD_DATA */
|
||||
return sun_fdc->data_82077;
|
||||
case 7: /* FD_DIR */
|
||||
return sun_read_dir();
|
||||
};
|
||||
panic("sun_82077_fd_inb: How did I get here?");
|
||||
}
|
||||
|
||||
static void sun_82077_fd_outb(unsigned char value, int port)
|
||||
{
|
||||
udelay(5);
|
||||
switch(port & 7) {
|
||||
default:
|
||||
printk("floppy: Asked to write to unknown port %d\n", port);
|
||||
panic("floppy: Port bolixed.");
|
||||
case 2: /* FD_DOR */
|
||||
sun_set_dor(value, 1);
|
||||
break;
|
||||
case 5: /* FD_DATA */
|
||||
sun_fdc->data_82077 = value;
|
||||
break;
|
||||
case 7: /* FD_DCR */
|
||||
sun_fdc->dcr_82077 = value;
|
||||
break;
|
||||
case 4: /* FD_STATUS */
|
||||
sun_fdc->status_82077 = value;
|
||||
break;
|
||||
case 3: /* FD_TDR */
|
||||
sun_fdc->tapectl_82077 = value;
|
||||
break;
|
||||
};
|
||||
return;
|
||||
}
|
||||
|
||||
/* For pseudo-dma (Sun floppy drives have no real DMA available to
|
||||
* them so we must eat the data fifo bytes directly ourselves) we have
|
||||
* three state variables. doing_pdma tells our inline low-level
|
||||
* assembly floppy interrupt entry point whether it should sit and eat
|
||||
* bytes from the fifo or just transfer control up to the higher level
|
||||
* floppy interrupt c-code. I tried very hard but I could not get the
|
||||
* pseudo-dma to work in c-code without getting many overruns and
|
||||
* underruns. If non-zero, doing_pdma encodes the direction of
|
||||
* the transfer for debugging. 1=read 2=write
|
||||
*/
|
||||
extern char *pdma_vaddr;
|
||||
extern unsigned long pdma_size;
|
||||
extern volatile int doing_pdma;
|
||||
|
||||
/* This is software state */
|
||||
extern char *pdma_base;
|
||||
extern unsigned long pdma_areasize;
|
||||
|
||||
/* Common routines to all controller types on the Sparc. */
|
||||
static inline void virtual_dma_init(void)
|
||||
{
|
||||
/* nothing... */
|
||||
}
|
||||
|
||||
static inline void sun_fd_disable_dma(void)
|
||||
{
|
||||
doing_pdma = 0;
|
||||
if (pdma_base) {
|
||||
mmu_unlockarea(pdma_base, pdma_areasize);
|
||||
pdma_base = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void sun_fd_set_dma_mode(int mode)
|
||||
{
|
||||
switch(mode) {
|
||||
case DMA_MODE_READ:
|
||||
doing_pdma = 1;
|
||||
break;
|
||||
case DMA_MODE_WRITE:
|
||||
doing_pdma = 2;
|
||||
break;
|
||||
default:
|
||||
printk("Unknown dma mode %d\n", mode);
|
||||
panic("floppy: Giving up...");
|
||||
}
|
||||
}
|
||||
|
||||
static inline void sun_fd_set_dma_addr(char *buffer)
|
||||
{
|
||||
pdma_vaddr = buffer;
|
||||
}
|
||||
|
||||
static inline void sun_fd_set_dma_count(int length)
|
||||
{
|
||||
pdma_size = length;
|
||||
}
|
||||
|
||||
static inline void sun_fd_enable_dma(void)
|
||||
{
|
||||
pdma_vaddr = mmu_lockarea(pdma_vaddr, pdma_size);
|
||||
pdma_base = pdma_vaddr;
|
||||
pdma_areasize = pdma_size;
|
||||
}
|
||||
|
||||
/* Our low-level entry point in arch/sparc/kernel/entry.S */
|
||||
extern int sparc_floppy_request_irq(int irq, unsigned long flags,
|
||||
irq_handler_t irq_handler);
|
||||
|
||||
static int sun_fd_request_irq(void)
|
||||
{
|
||||
static int once = 0;
|
||||
int error;
|
||||
|
||||
if(!once) {
|
||||
once = 1;
|
||||
error = sparc_floppy_request_irq(FLOPPY_IRQ,
|
||||
IRQF_DISABLED,
|
||||
floppy_interrupt);
|
||||
return ((error == 0) ? 0 : -1);
|
||||
} else return 0;
|
||||
}
|
||||
|
||||
static struct linux_prom_registers fd_regs[2];
|
||||
|
||||
static int sun_floppy_init(void)
|
||||
{
|
||||
char state[128];
|
||||
int tnode, fd_node, num_regs;
|
||||
struct resource r;
|
||||
|
||||
use_virtual_dma = 1;
|
||||
|
||||
FLOPPY_IRQ = 11;
|
||||
/* Forget it if we aren't on a machine that could possibly
|
||||
* ever have a floppy drive.
|
||||
*/
|
||||
if((sparc_cpu_model != sun4c && sparc_cpu_model != sun4m) ||
|
||||
((idprom->id_machtype == (SM_SUN4C | SM_4C_SLC)) ||
|
||||
(idprom->id_machtype == (SM_SUN4C | SM_4C_ELC)))) {
|
||||
/* We certainly don't have a floppy controller. */
|
||||
goto no_sun_fdc;
|
||||
}
|
||||
/* Well, try to find one. */
|
||||
tnode = prom_getchild(prom_root_node);
|
||||
fd_node = prom_searchsiblings(tnode, "obio");
|
||||
if(fd_node != 0) {
|
||||
tnode = prom_getchild(fd_node);
|
||||
fd_node = prom_searchsiblings(tnode, "SUNW,fdtwo");
|
||||
} else {
|
||||
fd_node = prom_searchsiblings(tnode, "fd");
|
||||
}
|
||||
if(fd_node == 0) {
|
||||
goto no_sun_fdc;
|
||||
}
|
||||
|
||||
/* The sun4m lets us know if the controller is actually usable. */
|
||||
if(sparc_cpu_model == sun4m &&
|
||||
prom_getproperty(fd_node, "status", state, sizeof(state)) != -1) {
|
||||
if(!strcmp(state, "disabled")) {
|
||||
goto no_sun_fdc;
|
||||
}
|
||||
}
|
||||
num_regs = prom_getproperty(fd_node, "reg", (char *) fd_regs, sizeof(fd_regs));
|
||||
num_regs = (num_regs / sizeof(fd_regs[0]));
|
||||
prom_apply_obio_ranges(fd_regs, num_regs);
|
||||
memset(&r, 0, sizeof(r));
|
||||
r.flags = fd_regs[0].which_io;
|
||||
r.start = fd_regs[0].phys_addr;
|
||||
sun_fdc = (struct sun_flpy_controller *)
|
||||
sbus_ioremap(&r, 0, fd_regs[0].reg_size, "floppy");
|
||||
|
||||
/* Last minute sanity check... */
|
||||
if(sun_fdc->status_82072 == 0xff) {
|
||||
sun_fdc = NULL;
|
||||
goto no_sun_fdc;
|
||||
}
|
||||
|
||||
sun_fdops.fd_inb = sun_82077_fd_inb;
|
||||
sun_fdops.fd_outb = sun_82077_fd_outb;
|
||||
fdc_status = &sun_fdc->status_82077;
|
||||
|
||||
if (sun_fdc->dor_82077 == 0x80) {
|
||||
sun_fdc->dor_82077 = 0x02;
|
||||
if (sun_fdc->dor_82077 == 0x80) {
|
||||
sun_fdops.fd_inb = sun_82072_fd_inb;
|
||||
sun_fdops.fd_outb = sun_82072_fd_outb;
|
||||
fdc_status = &sun_fdc->status_82072;
|
||||
}
|
||||
}
|
||||
|
||||
/* Success... */
|
||||
allowed_drive_mask = 0x01;
|
||||
return (int) sun_fdc;
|
||||
|
||||
no_sun_fdc:
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int sparc_eject(void)
|
||||
{
|
||||
set_dor(0x00, 0xff, 0x90);
|
||||
udelay(500);
|
||||
set_dor(0x00, 0x6f, 0x00);
|
||||
udelay(500);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define fd_eject(drive) sparc_eject()
|
||||
|
||||
#define EXTRA_FLOPPY_PARAMS
|
||||
|
||||
#endif /* !(__ASM_SPARC_FLOPPY_H) */
|
||||
|
|
388
include/asm-sparc/floppy_32.h
Normal file
388
include/asm-sparc/floppy_32.h
Normal file
|
@ -0,0 +1,388 @@
|
|||
/* asm-sparc/floppy.h: Sparc specific parts of the Floppy driver.
|
||||
*
|
||||
* Copyright (C) 1995 David S. Miller (davem@davemloft.net)
|
||||
*/
|
||||
|
||||
#ifndef __ASM_SPARC_FLOPPY_H
|
||||
#define __ASM_SPARC_FLOPPY_H
|
||||
|
||||
#include <asm/page.h>
|
||||
#include <asm/pgtable.h>
|
||||
#include <asm/system.h>
|
||||
#include <asm/idprom.h>
|
||||
#include <asm/machines.h>
|
||||
#include <asm/oplib.h>
|
||||
#include <asm/auxio.h>
|
||||
#include <asm/irq.h>
|
||||
|
||||
/* We don't need no stinkin' I/O port allocation crap. */
|
||||
#undef release_region
|
||||
#undef request_region
|
||||
#define release_region(X, Y) do { } while(0)
|
||||
#define request_region(X, Y, Z) (1)
|
||||
|
||||
/* References:
|
||||
* 1) Netbsd Sun floppy driver.
|
||||
* 2) NCR 82077 controller manual
|
||||
* 3) Intel 82077 controller manual
|
||||
*/
|
||||
struct sun_flpy_controller {
|
||||
volatile unsigned char status_82072; /* Main Status reg. */
|
||||
#define dcr_82072 status_82072 /* Digital Control reg. */
|
||||
#define status1_82077 status_82072 /* Auxiliary Status reg. 1 */
|
||||
|
||||
volatile unsigned char data_82072; /* Data fifo. */
|
||||
#define status2_82077 data_82072 /* Auxiliary Status reg. 2 */
|
||||
|
||||
volatile unsigned char dor_82077; /* Digital Output reg. */
|
||||
volatile unsigned char tapectl_82077; /* What the? Tape control reg? */
|
||||
|
||||
volatile unsigned char status_82077; /* Main Status Register. */
|
||||
#define drs_82077 status_82077 /* Digital Rate Select reg. */
|
||||
|
||||
volatile unsigned char data_82077; /* Data fifo. */
|
||||
volatile unsigned char ___unused;
|
||||
volatile unsigned char dir_82077; /* Digital Input reg. */
|
||||
#define dcr_82077 dir_82077 /* Config Control reg. */
|
||||
};
|
||||
|
||||
/* You'll only ever find one controller on a SparcStation anyways. */
|
||||
static struct sun_flpy_controller *sun_fdc = NULL;
|
||||
extern volatile unsigned char *fdc_status;
|
||||
|
||||
struct sun_floppy_ops {
|
||||
unsigned char (*fd_inb)(int port);
|
||||
void (*fd_outb)(unsigned char value, int port);
|
||||
};
|
||||
|
||||
static struct sun_floppy_ops sun_fdops;
|
||||
|
||||
#define fd_inb(port) sun_fdops.fd_inb(port)
|
||||
#define fd_outb(value,port) sun_fdops.fd_outb(value,port)
|
||||
#define fd_enable_dma() sun_fd_enable_dma()
|
||||
#define fd_disable_dma() sun_fd_disable_dma()
|
||||
#define fd_request_dma() (0) /* nothing... */
|
||||
#define fd_free_dma() /* nothing... */
|
||||
#define fd_clear_dma_ff() /* nothing... */
|
||||
#define fd_set_dma_mode(mode) sun_fd_set_dma_mode(mode)
|
||||
#define fd_set_dma_addr(addr) sun_fd_set_dma_addr(addr)
|
||||
#define fd_set_dma_count(count) sun_fd_set_dma_count(count)
|
||||
#define fd_enable_irq() /* nothing... */
|
||||
#define fd_disable_irq() /* nothing... */
|
||||
#define fd_cacheflush(addr, size) /* nothing... */
|
||||
#define fd_request_irq() sun_fd_request_irq()
|
||||
#define fd_free_irq() /* nothing... */
|
||||
#if 0 /* P3: added by Alain, these cause a MMU corruption. 19960524 XXX */
|
||||
#define fd_dma_mem_alloc(size) ((unsigned long) vmalloc(size))
|
||||
#define fd_dma_mem_free(addr,size) (vfree((void *)(addr)))
|
||||
#endif
|
||||
|
||||
/* XXX This isn't really correct. XXX */
|
||||
#define get_dma_residue(x) (0)
|
||||
|
||||
#define FLOPPY0_TYPE 4
|
||||
#define FLOPPY1_TYPE 0
|
||||
|
||||
/* Super paranoid... */
|
||||
#undef HAVE_DISABLE_HLT
|
||||
|
||||
/* Here is where we catch the floppy driver trying to initialize,
|
||||
* therefore this is where we call the PROM device tree probing
|
||||
* routine etc. on the Sparc.
|
||||
*/
|
||||
#define FDC1 sun_floppy_init()
|
||||
|
||||
#define N_FDC 1
|
||||
#define N_DRIVE 8
|
||||
|
||||
/* No 64k boundary crossing problems on the Sparc. */
|
||||
#define CROSS_64KB(a,s) (0)
|
||||
|
||||
/* Routines unique to each controller type on a Sun. */
|
||||
static void sun_set_dor(unsigned char value, int fdc_82077)
|
||||
{
|
||||
if (sparc_cpu_model == sun4c) {
|
||||
unsigned int bits = 0;
|
||||
if (value & 0x10)
|
||||
bits |= AUXIO_FLPY_DSEL;
|
||||
if ((value & 0x80) == 0)
|
||||
bits |= AUXIO_FLPY_EJCT;
|
||||
set_auxio(bits, (~bits) & (AUXIO_FLPY_DSEL|AUXIO_FLPY_EJCT));
|
||||
}
|
||||
if (fdc_82077) {
|
||||
sun_fdc->dor_82077 = value;
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned char sun_read_dir(void)
|
||||
{
|
||||
if (sparc_cpu_model == sun4c)
|
||||
return (get_auxio() & AUXIO_FLPY_DCHG) ? 0x80 : 0;
|
||||
else
|
||||
return sun_fdc->dir_82077;
|
||||
}
|
||||
|
||||
static unsigned char sun_82072_fd_inb(int port)
|
||||
{
|
||||
udelay(5);
|
||||
switch(port & 7) {
|
||||
default:
|
||||
printk("floppy: Asked to read unknown port %d\n", port);
|
||||
panic("floppy: Port bolixed.");
|
||||
case 4: /* FD_STATUS */
|
||||
return sun_fdc->status_82072 & ~STATUS_DMA;
|
||||
case 5: /* FD_DATA */
|
||||
return sun_fdc->data_82072;
|
||||
case 7: /* FD_DIR */
|
||||
return sun_read_dir();
|
||||
};
|
||||
panic("sun_82072_fd_inb: How did I get here?");
|
||||
}
|
||||
|
||||
static void sun_82072_fd_outb(unsigned char value, int port)
|
||||
{
|
||||
udelay(5);
|
||||
switch(port & 7) {
|
||||
default:
|
||||
printk("floppy: Asked to write to unknown port %d\n", port);
|
||||
panic("floppy: Port bolixed.");
|
||||
case 2: /* FD_DOR */
|
||||
sun_set_dor(value, 0);
|
||||
break;
|
||||
case 5: /* FD_DATA */
|
||||
sun_fdc->data_82072 = value;
|
||||
break;
|
||||
case 7: /* FD_DCR */
|
||||
sun_fdc->dcr_82072 = value;
|
||||
break;
|
||||
case 4: /* FD_STATUS */
|
||||
sun_fdc->status_82072 = value;
|
||||
break;
|
||||
};
|
||||
return;
|
||||
}
|
||||
|
||||
static unsigned char sun_82077_fd_inb(int port)
|
||||
{
|
||||
udelay(5);
|
||||
switch(port & 7) {
|
||||
default:
|
||||
printk("floppy: Asked to read unknown port %d\n", port);
|
||||
panic("floppy: Port bolixed.");
|
||||
case 0: /* FD_STATUS_0 */
|
||||
return sun_fdc->status1_82077;
|
||||
case 1: /* FD_STATUS_1 */
|
||||
return sun_fdc->status2_82077;
|
||||
case 2: /* FD_DOR */
|
||||
return sun_fdc->dor_82077;
|
||||
case 3: /* FD_TDR */
|
||||
return sun_fdc->tapectl_82077;
|
||||
case 4: /* FD_STATUS */
|
||||
return sun_fdc->status_82077 & ~STATUS_DMA;
|
||||
case 5: /* FD_DATA */
|
||||
return sun_fdc->data_82077;
|
||||
case 7: /* FD_DIR */
|
||||
return sun_read_dir();
|
||||
};
|
||||
panic("sun_82077_fd_inb: How did I get here?");
|
||||
}
|
||||
|
||||
static void sun_82077_fd_outb(unsigned char value, int port)
|
||||
{
|
||||
udelay(5);
|
||||
switch(port & 7) {
|
||||
default:
|
||||
printk("floppy: Asked to write to unknown port %d\n", port);
|
||||
panic("floppy: Port bolixed.");
|
||||
case 2: /* FD_DOR */
|
||||
sun_set_dor(value, 1);
|
||||
break;
|
||||
case 5: /* FD_DATA */
|
||||
sun_fdc->data_82077 = value;
|
||||
break;
|
||||
case 7: /* FD_DCR */
|
||||
sun_fdc->dcr_82077 = value;
|
||||
break;
|
||||
case 4: /* FD_STATUS */
|
||||
sun_fdc->status_82077 = value;
|
||||
break;
|
||||
case 3: /* FD_TDR */
|
||||
sun_fdc->tapectl_82077 = value;
|
||||
break;
|
||||
};
|
||||
return;
|
||||
}
|
||||
|
||||
/* For pseudo-dma (Sun floppy drives have no real DMA available to
|
||||
* them so we must eat the data fifo bytes directly ourselves) we have
|
||||
* three state variables. doing_pdma tells our inline low-level
|
||||
* assembly floppy interrupt entry point whether it should sit and eat
|
||||
* bytes from the fifo or just transfer control up to the higher level
|
||||
* floppy interrupt c-code. I tried very hard but I could not get the
|
||||
* pseudo-dma to work in c-code without getting many overruns and
|
||||
* underruns. If non-zero, doing_pdma encodes the direction of
|
||||
* the transfer for debugging. 1=read 2=write
|
||||
*/
|
||||
extern char *pdma_vaddr;
|
||||
extern unsigned long pdma_size;
|
||||
extern volatile int doing_pdma;
|
||||
|
||||
/* This is software state */
|
||||
extern char *pdma_base;
|
||||
extern unsigned long pdma_areasize;
|
||||
|
||||
/* Common routines to all controller types on the Sparc. */
|
||||
static inline void virtual_dma_init(void)
|
||||
{
|
||||
/* nothing... */
|
||||
}
|
||||
|
||||
static inline void sun_fd_disable_dma(void)
|
||||
{
|
||||
doing_pdma = 0;
|
||||
if (pdma_base) {
|
||||
mmu_unlockarea(pdma_base, pdma_areasize);
|
||||
pdma_base = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void sun_fd_set_dma_mode(int mode)
|
||||
{
|
||||
switch(mode) {
|
||||
case DMA_MODE_READ:
|
||||
doing_pdma = 1;
|
||||
break;
|
||||
case DMA_MODE_WRITE:
|
||||
doing_pdma = 2;
|
||||
break;
|
||||
default:
|
||||
printk("Unknown dma mode %d\n", mode);
|
||||
panic("floppy: Giving up...");
|
||||
}
|
||||
}
|
||||
|
||||
static inline void sun_fd_set_dma_addr(char *buffer)
|
||||
{
|
||||
pdma_vaddr = buffer;
|
||||
}
|
||||
|
||||
static inline void sun_fd_set_dma_count(int length)
|
||||
{
|
||||
pdma_size = length;
|
||||
}
|
||||
|
||||
static inline void sun_fd_enable_dma(void)
|
||||
{
|
||||
pdma_vaddr = mmu_lockarea(pdma_vaddr, pdma_size);
|
||||
pdma_base = pdma_vaddr;
|
||||
pdma_areasize = pdma_size;
|
||||
}
|
||||
|
||||
/* Our low-level entry point in arch/sparc/kernel/entry.S */
|
||||
extern int sparc_floppy_request_irq(int irq, unsigned long flags,
|
||||
irq_handler_t irq_handler);
|
||||
|
||||
static int sun_fd_request_irq(void)
|
||||
{
|
||||
static int once = 0;
|
||||
int error;
|
||||
|
||||
if(!once) {
|
||||
once = 1;
|
||||
error = sparc_floppy_request_irq(FLOPPY_IRQ,
|
||||
IRQF_DISABLED,
|
||||
floppy_interrupt);
|
||||
return ((error == 0) ? 0 : -1);
|
||||
} else return 0;
|
||||
}
|
||||
|
||||
static struct linux_prom_registers fd_regs[2];
|
||||
|
||||
static int sun_floppy_init(void)
|
||||
{
|
||||
char state[128];
|
||||
int tnode, fd_node, num_regs;
|
||||
struct resource r;
|
||||
|
||||
use_virtual_dma = 1;
|
||||
|
||||
FLOPPY_IRQ = 11;
|
||||
/* Forget it if we aren't on a machine that could possibly
|
||||
* ever have a floppy drive.
|
||||
*/
|
||||
if((sparc_cpu_model != sun4c && sparc_cpu_model != sun4m) ||
|
||||
((idprom->id_machtype == (SM_SUN4C | SM_4C_SLC)) ||
|
||||
(idprom->id_machtype == (SM_SUN4C | SM_4C_ELC)))) {
|
||||
/* We certainly don't have a floppy controller. */
|
||||
goto no_sun_fdc;
|
||||
}
|
||||
/* Well, try to find one. */
|
||||
tnode = prom_getchild(prom_root_node);
|
||||
fd_node = prom_searchsiblings(tnode, "obio");
|
||||
if(fd_node != 0) {
|
||||
tnode = prom_getchild(fd_node);
|
||||
fd_node = prom_searchsiblings(tnode, "SUNW,fdtwo");
|
||||
} else {
|
||||
fd_node = prom_searchsiblings(tnode, "fd");
|
||||
}
|
||||
if(fd_node == 0) {
|
||||
goto no_sun_fdc;
|
||||
}
|
||||
|
||||
/* The sun4m lets us know if the controller is actually usable. */
|
||||
if(sparc_cpu_model == sun4m &&
|
||||
prom_getproperty(fd_node, "status", state, sizeof(state)) != -1) {
|
||||
if(!strcmp(state, "disabled")) {
|
||||
goto no_sun_fdc;
|
||||
}
|
||||
}
|
||||
num_regs = prom_getproperty(fd_node, "reg", (char *) fd_regs, sizeof(fd_regs));
|
||||
num_regs = (num_regs / sizeof(fd_regs[0]));
|
||||
prom_apply_obio_ranges(fd_regs, num_regs);
|
||||
memset(&r, 0, sizeof(r));
|
||||
r.flags = fd_regs[0].which_io;
|
||||
r.start = fd_regs[0].phys_addr;
|
||||
sun_fdc = (struct sun_flpy_controller *)
|
||||
sbus_ioremap(&r, 0, fd_regs[0].reg_size, "floppy");
|
||||
|
||||
/* Last minute sanity check... */
|
||||
if(sun_fdc->status_82072 == 0xff) {
|
||||
sun_fdc = NULL;
|
||||
goto no_sun_fdc;
|
||||
}
|
||||
|
||||
sun_fdops.fd_inb = sun_82077_fd_inb;
|
||||
sun_fdops.fd_outb = sun_82077_fd_outb;
|
||||
fdc_status = &sun_fdc->status_82077;
|
||||
|
||||
if (sun_fdc->dor_82077 == 0x80) {
|
||||
sun_fdc->dor_82077 = 0x02;
|
||||
if (sun_fdc->dor_82077 == 0x80) {
|
||||
sun_fdops.fd_inb = sun_82072_fd_inb;
|
||||
sun_fdops.fd_outb = sun_82072_fd_outb;
|
||||
fdc_status = &sun_fdc->status_82072;
|
||||
}
|
||||
}
|
||||
|
||||
/* Success... */
|
||||
allowed_drive_mask = 0x01;
|
||||
return (int) sun_fdc;
|
||||
|
||||
no_sun_fdc:
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int sparc_eject(void)
|
||||
{
|
||||
set_dor(0x00, 0xff, 0x90);
|
||||
udelay(500);
|
||||
set_dor(0x00, 0x6f, 0x00);
|
||||
udelay(500);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define fd_eject(drive) sparc_eject()
|
||||
|
||||
#define EXTRA_FLOPPY_PARAMS
|
||||
|
||||
#endif /* !(__ASM_SPARC_FLOPPY_H) */
|
782
include/asm-sparc/floppy_64.h
Normal file
782
include/asm-sparc/floppy_64.h
Normal file
|
@ -0,0 +1,782 @@
|
|||
/* floppy.h: Sparc specific parts of the Floppy driver.
|
||||
*
|
||||
* Copyright (C) 1996, 2007 David S. Miller (davem@davemloft.net)
|
||||
* Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
|
||||
*
|
||||
* Ultra/PCI support added: Sep 1997 Eddie C. Dost (ecd@skynet.be)
|
||||
*/
|
||||
|
||||
#ifndef __ASM_SPARC64_FLOPPY_H
|
||||
#define __ASM_SPARC64_FLOPPY_H
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/pci.h>
|
||||
|
||||
#include <asm/page.h>
|
||||
#include <asm/pgtable.h>
|
||||
#include <asm/system.h>
|
||||
#include <asm/idprom.h>
|
||||
#include <asm/oplib.h>
|
||||
#include <asm/auxio.h>
|
||||
#include <asm/sbus.h>
|
||||
#include <asm/irq.h>
|
||||
|
||||
|
||||
/*
|
||||
* Define this to enable exchanging drive 0 and 1 if only drive 1 is
|
||||
* probed on PCI machines.
|
||||
*/
|
||||
#undef PCI_FDC_SWAP_DRIVES
|
||||
|
||||
|
||||
/* References:
|
||||
* 1) Netbsd Sun floppy driver.
|
||||
* 2) NCR 82077 controller manual
|
||||
* 3) Intel 82077 controller manual
|
||||
*/
|
||||
struct sun_flpy_controller {
|
||||
volatile unsigned char status1_82077; /* Auxiliary Status reg. 1 */
|
||||
volatile unsigned char status2_82077; /* Auxiliary Status reg. 2 */
|
||||
volatile unsigned char dor_82077; /* Digital Output reg. */
|
||||
volatile unsigned char tapectl_82077; /* Tape Control reg */
|
||||
volatile unsigned char status_82077; /* Main Status Register. */
|
||||
#define drs_82077 status_82077 /* Digital Rate Select reg. */
|
||||
volatile unsigned char data_82077; /* Data fifo. */
|
||||
volatile unsigned char ___unused;
|
||||
volatile unsigned char dir_82077; /* Digital Input reg. */
|
||||
#define dcr_82077 dir_82077 /* Config Control reg. */
|
||||
};
|
||||
|
||||
/* You'll only ever find one controller on an Ultra anyways. */
|
||||
static struct sun_flpy_controller *sun_fdc = (struct sun_flpy_controller *)-1;
|
||||
unsigned long fdc_status;
|
||||
static struct sbus_dev *floppy_sdev = NULL;
|
||||
|
||||
struct sun_floppy_ops {
|
||||
unsigned char (*fd_inb) (unsigned long port);
|
||||
void (*fd_outb) (unsigned char value, unsigned long port);
|
||||
void (*fd_enable_dma) (void);
|
||||
void (*fd_disable_dma) (void);
|
||||
void (*fd_set_dma_mode) (int);
|
||||
void (*fd_set_dma_addr) (char *);
|
||||
void (*fd_set_dma_count) (int);
|
||||
unsigned int (*get_dma_residue) (void);
|
||||
int (*fd_request_irq) (void);
|
||||
void (*fd_free_irq) (void);
|
||||
int (*fd_eject) (int);
|
||||
};
|
||||
|
||||
static struct sun_floppy_ops sun_fdops;
|
||||
|
||||
#define fd_inb(port) sun_fdops.fd_inb(port)
|
||||
#define fd_outb(value,port) sun_fdops.fd_outb(value,port)
|
||||
#define fd_enable_dma() sun_fdops.fd_enable_dma()
|
||||
#define fd_disable_dma() sun_fdops.fd_disable_dma()
|
||||
#define fd_request_dma() (0) /* nothing... */
|
||||
#define fd_free_dma() /* nothing... */
|
||||
#define fd_clear_dma_ff() /* nothing... */
|
||||
#define fd_set_dma_mode(mode) sun_fdops.fd_set_dma_mode(mode)
|
||||
#define fd_set_dma_addr(addr) sun_fdops.fd_set_dma_addr(addr)
|
||||
#define fd_set_dma_count(count) sun_fdops.fd_set_dma_count(count)
|
||||
#define get_dma_residue(x) sun_fdops.get_dma_residue()
|
||||
#define fd_cacheflush(addr, size) /* nothing... */
|
||||
#define fd_request_irq() sun_fdops.fd_request_irq()
|
||||
#define fd_free_irq() sun_fdops.fd_free_irq()
|
||||
#define fd_eject(drive) sun_fdops.fd_eject(drive)
|
||||
|
||||
/* Super paranoid... */
|
||||
#undef HAVE_DISABLE_HLT
|
||||
|
||||
static int sun_floppy_types[2] = { 0, 0 };
|
||||
|
||||
/* Here is where we catch the floppy driver trying to initialize,
|
||||
* therefore this is where we call the PROM device tree probing
|
||||
* routine etc. on the Sparc.
|
||||
*/
|
||||
#define FLOPPY0_TYPE sun_floppy_init()
|
||||
#define FLOPPY1_TYPE sun_floppy_types[1]
|
||||
|
||||
#define FDC1 ((unsigned long)sun_fdc)
|
||||
|
||||
#define N_FDC 1
|
||||
#define N_DRIVE 8
|
||||
|
||||
/* No 64k boundary crossing problems on the Sparc. */
|
||||
#define CROSS_64KB(a,s) (0)
|
||||
|
||||
static unsigned char sun_82077_fd_inb(unsigned long port)
|
||||
{
|
||||
udelay(5);
|
||||
switch(port & 7) {
|
||||
default:
|
||||
printk("floppy: Asked to read unknown port %lx\n", port);
|
||||
panic("floppy: Port bolixed.");
|
||||
case 4: /* FD_STATUS */
|
||||
return sbus_readb(&sun_fdc->status_82077) & ~STATUS_DMA;
|
||||
case 5: /* FD_DATA */
|
||||
return sbus_readb(&sun_fdc->data_82077);
|
||||
case 7: /* FD_DIR */
|
||||
/* XXX: Is DCL on 0x80 in sun4m? */
|
||||
return sbus_readb(&sun_fdc->dir_82077);
|
||||
};
|
||||
panic("sun_82072_fd_inb: How did I get here?");
|
||||
}
|
||||
|
||||
static void sun_82077_fd_outb(unsigned char value, unsigned long port)
|
||||
{
|
||||
udelay(5);
|
||||
switch(port & 7) {
|
||||
default:
|
||||
printk("floppy: Asked to write to unknown port %lx\n", port);
|
||||
panic("floppy: Port bolixed.");
|
||||
case 2: /* FD_DOR */
|
||||
/* Happily, the 82077 has a real DOR register. */
|
||||
sbus_writeb(value, &sun_fdc->dor_82077);
|
||||
break;
|
||||
case 5: /* FD_DATA */
|
||||
sbus_writeb(value, &sun_fdc->data_82077);
|
||||
break;
|
||||
case 7: /* FD_DCR */
|
||||
sbus_writeb(value, &sun_fdc->dcr_82077);
|
||||
break;
|
||||
case 4: /* FD_STATUS */
|
||||
sbus_writeb(value, &sun_fdc->status_82077);
|
||||
break;
|
||||
};
|
||||
return;
|
||||
}
|
||||
|
||||
/* For pseudo-dma (Sun floppy drives have no real DMA available to
|
||||
* them so we must eat the data fifo bytes directly ourselves) we have
|
||||
* three state variables. doing_pdma tells our inline low-level
|
||||
* assembly floppy interrupt entry point whether it should sit and eat
|
||||
* bytes from the fifo or just transfer control up to the higher level
|
||||
* floppy interrupt c-code. I tried very hard but I could not get the
|
||||
* pseudo-dma to work in c-code without getting many overruns and
|
||||
* underruns. If non-zero, doing_pdma encodes the direction of
|
||||
* the transfer for debugging. 1=read 2=write
|
||||
*/
|
||||
unsigned char *pdma_vaddr;
|
||||
unsigned long pdma_size;
|
||||
volatile int doing_pdma = 0;
|
||||
|
||||
/* This is software state */
|
||||
char *pdma_base = NULL;
|
||||
unsigned long pdma_areasize;
|
||||
|
||||
/* Common routines to all controller types on the Sparc. */
|
||||
static void sun_fd_disable_dma(void)
|
||||
{
|
||||
doing_pdma = 0;
|
||||
if (pdma_base) {
|
||||
mmu_unlockarea(pdma_base, pdma_areasize);
|
||||
pdma_base = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void sun_fd_set_dma_mode(int mode)
|
||||
{
|
||||
switch(mode) {
|
||||
case DMA_MODE_READ:
|
||||
doing_pdma = 1;
|
||||
break;
|
||||
case DMA_MODE_WRITE:
|
||||
doing_pdma = 2;
|
||||
break;
|
||||
default:
|
||||
printk("Unknown dma mode %d\n", mode);
|
||||
panic("floppy: Giving up...");
|
||||
}
|
||||
}
|
||||
|
||||
static void sun_fd_set_dma_addr(char *buffer)
|
||||
{
|
||||
pdma_vaddr = buffer;
|
||||
}
|
||||
|
||||
static void sun_fd_set_dma_count(int length)
|
||||
{
|
||||
pdma_size = length;
|
||||
}
|
||||
|
||||
static void sun_fd_enable_dma(void)
|
||||
{
|
||||
pdma_vaddr = mmu_lockarea(pdma_vaddr, pdma_size);
|
||||
pdma_base = pdma_vaddr;
|
||||
pdma_areasize = pdma_size;
|
||||
}
|
||||
|
||||
irqreturn_t sparc_floppy_irq(int irq, void *dev_cookie)
|
||||
{
|
||||
if (likely(doing_pdma)) {
|
||||
void __iomem *stat = (void __iomem *) fdc_status;
|
||||
unsigned char *vaddr = pdma_vaddr;
|
||||
unsigned long size = pdma_size;
|
||||
u8 val;
|
||||
|
||||
while (size) {
|
||||
val = readb(stat);
|
||||
if (unlikely(!(val & 0x80))) {
|
||||
pdma_vaddr = vaddr;
|
||||
pdma_size = size;
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
if (unlikely(!(val & 0x20))) {
|
||||
pdma_vaddr = vaddr;
|
||||
pdma_size = size;
|
||||
doing_pdma = 0;
|
||||
goto main_interrupt;
|
||||
}
|
||||
if (val & 0x40) {
|
||||
/* read */
|
||||
*vaddr++ = readb(stat + 1);
|
||||
} else {
|
||||
unsigned char data = *vaddr++;
|
||||
|
||||
/* write */
|
||||
writeb(data, stat + 1);
|
||||
}
|
||||
size--;
|
||||
}
|
||||
|
||||
pdma_vaddr = vaddr;
|
||||
pdma_size = size;
|
||||
|
||||
/* Send Terminal Count pulse to floppy controller. */
|
||||
val = readb(auxio_register);
|
||||
val |= AUXIO_AUX1_FTCNT;
|
||||
writeb(val, auxio_register);
|
||||
val &= ~AUXIO_AUX1_FTCNT;
|
||||
writeb(val, auxio_register);
|
||||
|
||||
doing_pdma = 0;
|
||||
}
|
||||
|
||||
main_interrupt:
|
||||
return floppy_interrupt(irq, dev_cookie);
|
||||
}
|
||||
|
||||
static int sun_fd_request_irq(void)
|
||||
{
|
||||
static int once = 0;
|
||||
int error;
|
||||
|
||||
if(!once) {
|
||||
once = 1;
|
||||
|
||||
error = request_irq(FLOPPY_IRQ, sparc_floppy_irq,
|
||||
IRQF_DISABLED, "floppy", NULL);
|
||||
|
||||
return ((error == 0) ? 0 : -1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void sun_fd_free_irq(void)
|
||||
{
|
||||
}
|
||||
|
||||
static unsigned int sun_get_dma_residue(void)
|
||||
{
|
||||
/* XXX This isn't really correct. XXX */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sun_fd_eject(int drive)
|
||||
{
|
||||
set_dor(0x00, 0xff, 0x90);
|
||||
udelay(500);
|
||||
set_dor(0x00, 0x6f, 0x00);
|
||||
udelay(500);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
#include <asm/ebus.h>
|
||||
#include <asm/ns87303.h>
|
||||
|
||||
static struct ebus_dma_info sun_pci_fd_ebus_dma;
|
||||
static struct pci_dev *sun_pci_ebus_dev;
|
||||
static int sun_pci_broken_drive = -1;
|
||||
|
||||
struct sun_pci_dma_op {
|
||||
unsigned int addr;
|
||||
int len;
|
||||
int direction;
|
||||
char *buf;
|
||||
};
|
||||
static struct sun_pci_dma_op sun_pci_dma_current = { -1U, 0, 0, NULL};
|
||||
static struct sun_pci_dma_op sun_pci_dma_pending = { -1U, 0, 0, NULL};
|
||||
|
||||
extern irqreturn_t floppy_interrupt(int irq, void *dev_id);
|
||||
|
||||
static unsigned char sun_pci_fd_inb(unsigned long port)
|
||||
{
|
||||
udelay(5);
|
||||
return inb(port);
|
||||
}
|
||||
|
||||
static void sun_pci_fd_outb(unsigned char val, unsigned long port)
|
||||
{
|
||||
udelay(5);
|
||||
outb(val, port);
|
||||
}
|
||||
|
||||
static void sun_pci_fd_broken_outb(unsigned char val, unsigned long port)
|
||||
{
|
||||
udelay(5);
|
||||
/*
|
||||
* XXX: Due to SUN's broken floppy connector on AX and AXi
|
||||
* we need to turn on MOTOR_0 also, if the floppy is
|
||||
* jumpered to DS1 (like most PC floppies are). I hope
|
||||
* this does not hurt correct hardware like the AXmp.
|
||||
* (Eddie, Sep 12 1998).
|
||||
*/
|
||||
if (port == ((unsigned long)sun_fdc) + 2) {
|
||||
if (((val & 0x03) == sun_pci_broken_drive) && (val & 0x20)) {
|
||||
val |= 0x10;
|
||||
}
|
||||
}
|
||||
outb(val, port);
|
||||
}
|
||||
|
||||
#ifdef PCI_FDC_SWAP_DRIVES
|
||||
static void sun_pci_fd_lde_broken_outb(unsigned char val, unsigned long port)
|
||||
{
|
||||
udelay(5);
|
||||
/*
|
||||
* XXX: Due to SUN's broken floppy connector on AX and AXi
|
||||
* we need to turn on MOTOR_0 also, if the floppy is
|
||||
* jumpered to DS1 (like most PC floppies are). I hope
|
||||
* this does not hurt correct hardware like the AXmp.
|
||||
* (Eddie, Sep 12 1998).
|
||||
*/
|
||||
if (port == ((unsigned long)sun_fdc) + 2) {
|
||||
if (((val & 0x03) == sun_pci_broken_drive) && (val & 0x10)) {
|
||||
val &= ~(0x03);
|
||||
val |= 0x21;
|
||||
}
|
||||
}
|
||||
outb(val, port);
|
||||
}
|
||||
#endif /* PCI_FDC_SWAP_DRIVES */
|
||||
|
||||
static void sun_pci_fd_enable_dma(void)
|
||||
{
|
||||
BUG_ON((NULL == sun_pci_dma_pending.buf) ||
|
||||
(0 == sun_pci_dma_pending.len) ||
|
||||
(0 == sun_pci_dma_pending.direction));
|
||||
|
||||
sun_pci_dma_current.buf = sun_pci_dma_pending.buf;
|
||||
sun_pci_dma_current.len = sun_pci_dma_pending.len;
|
||||
sun_pci_dma_current.direction = sun_pci_dma_pending.direction;
|
||||
|
||||
sun_pci_dma_pending.buf = NULL;
|
||||
sun_pci_dma_pending.len = 0;
|
||||
sun_pci_dma_pending.direction = 0;
|
||||
sun_pci_dma_pending.addr = -1U;
|
||||
|
||||
sun_pci_dma_current.addr =
|
||||
pci_map_single(sun_pci_ebus_dev,
|
||||
sun_pci_dma_current.buf,
|
||||
sun_pci_dma_current.len,
|
||||
sun_pci_dma_current.direction);
|
||||
|
||||
ebus_dma_enable(&sun_pci_fd_ebus_dma, 1);
|
||||
|
||||
if (ebus_dma_request(&sun_pci_fd_ebus_dma,
|
||||
sun_pci_dma_current.addr,
|
||||
sun_pci_dma_current.len))
|
||||
BUG();
|
||||
}
|
||||
|
||||
static void sun_pci_fd_disable_dma(void)
|
||||
{
|
||||
ebus_dma_enable(&sun_pci_fd_ebus_dma, 0);
|
||||
if (sun_pci_dma_current.addr != -1U)
|
||||
pci_unmap_single(sun_pci_ebus_dev,
|
||||
sun_pci_dma_current.addr,
|
||||
sun_pci_dma_current.len,
|
||||
sun_pci_dma_current.direction);
|
||||
sun_pci_dma_current.addr = -1U;
|
||||
}
|
||||
|
||||
static void sun_pci_fd_set_dma_mode(int mode)
|
||||
{
|
||||
if (mode == DMA_MODE_WRITE)
|
||||
sun_pci_dma_pending.direction = PCI_DMA_TODEVICE;
|
||||
else
|
||||
sun_pci_dma_pending.direction = PCI_DMA_FROMDEVICE;
|
||||
|
||||
ebus_dma_prepare(&sun_pci_fd_ebus_dma, mode != DMA_MODE_WRITE);
|
||||
}
|
||||
|
||||
static void sun_pci_fd_set_dma_count(int length)
|
||||
{
|
||||
sun_pci_dma_pending.len = length;
|
||||
}
|
||||
|
||||
static void sun_pci_fd_set_dma_addr(char *buffer)
|
||||
{
|
||||
sun_pci_dma_pending.buf = buffer;
|
||||
}
|
||||
|
||||
static unsigned int sun_pci_get_dma_residue(void)
|
||||
{
|
||||
return ebus_dma_residue(&sun_pci_fd_ebus_dma);
|
||||
}
|
||||
|
||||
static int sun_pci_fd_request_irq(void)
|
||||
{
|
||||
return ebus_dma_irq_enable(&sun_pci_fd_ebus_dma, 1);
|
||||
}
|
||||
|
||||
static void sun_pci_fd_free_irq(void)
|
||||
{
|
||||
ebus_dma_irq_enable(&sun_pci_fd_ebus_dma, 0);
|
||||
}
|
||||
|
||||
static int sun_pci_fd_eject(int drive)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
void sun_pci_fd_dma_callback(struct ebus_dma_info *p, int event, void *cookie)
|
||||
{
|
||||
floppy_interrupt(0, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Floppy probing, we'd like to use /dev/fd0 for a single Floppy on PCI,
|
||||
* even if this is configured using DS1, thus looks like /dev/fd1 with
|
||||
* the cabling used in Ultras.
|
||||
*/
|
||||
#define DOR (port + 2)
|
||||
#define MSR (port + 4)
|
||||
#define FIFO (port + 5)
|
||||
|
||||
static void sun_pci_fd_out_byte(unsigned long port, unsigned char val,
|
||||
unsigned long reg)
|
||||
{
|
||||
unsigned char status;
|
||||
int timeout = 1000;
|
||||
|
||||
while (!((status = inb(MSR)) & 0x80) && --timeout)
|
||||
udelay(100);
|
||||
outb(val, reg);
|
||||
}
|
||||
|
||||
static unsigned char sun_pci_fd_sensei(unsigned long port)
|
||||
{
|
||||
unsigned char result[2] = { 0x70, 0x00 };
|
||||
unsigned char status;
|
||||
int i = 0;
|
||||
|
||||
sun_pci_fd_out_byte(port, 0x08, FIFO);
|
||||
do {
|
||||
int timeout = 1000;
|
||||
|
||||
while (!((status = inb(MSR)) & 0x80) && --timeout)
|
||||
udelay(100);
|
||||
|
||||
if (!timeout)
|
||||
break;
|
||||
|
||||
if ((status & 0xf0) == 0xd0)
|
||||
result[i++] = inb(FIFO);
|
||||
else
|
||||
break;
|
||||
} while (i < 2);
|
||||
|
||||
return result[0];
|
||||
}
|
||||
|
||||
static void sun_pci_fd_reset(unsigned long port)
|
||||
{
|
||||
unsigned char mask = 0x00;
|
||||
unsigned char status;
|
||||
int timeout = 10000;
|
||||
|
||||
outb(0x80, MSR);
|
||||
do {
|
||||
status = sun_pci_fd_sensei(port);
|
||||
if ((status & 0xc0) == 0xc0)
|
||||
mask |= 1 << (status & 0x03);
|
||||
else
|
||||
udelay(100);
|
||||
} while ((mask != 0x0f) && --timeout);
|
||||
}
|
||||
|
||||
static int sun_pci_fd_test_drive(unsigned long port, int drive)
|
||||
{
|
||||
unsigned char status, data;
|
||||
int timeout = 1000;
|
||||
int ready;
|
||||
|
||||
sun_pci_fd_reset(port);
|
||||
|
||||
data = (0x10 << drive) | 0x0c | drive;
|
||||
sun_pci_fd_out_byte(port, data, DOR);
|
||||
|
||||
sun_pci_fd_out_byte(port, 0x07, FIFO);
|
||||
sun_pci_fd_out_byte(port, drive & 0x03, FIFO);
|
||||
|
||||
do {
|
||||
udelay(100);
|
||||
status = sun_pci_fd_sensei(port);
|
||||
} while (((status & 0xc0) == 0x80) && --timeout);
|
||||
|
||||
if (!timeout)
|
||||
ready = 0;
|
||||
else
|
||||
ready = (status & 0x10) ? 0 : 1;
|
||||
|
||||
sun_pci_fd_reset(port);
|
||||
return ready;
|
||||
}
|
||||
#undef FIFO
|
||||
#undef MSR
|
||||
#undef DOR
|
||||
|
||||
#endif /* CONFIG_PCI */
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
static int __init ebus_fdthree_p(struct linux_ebus_device *edev)
|
||||
{
|
||||
if (!strcmp(edev->prom_node->name, "fdthree"))
|
||||
return 1;
|
||||
if (!strcmp(edev->prom_node->name, "floppy")) {
|
||||
const char *compat;
|
||||
|
||||
compat = of_get_property(edev->prom_node,
|
||||
"compatible", NULL);
|
||||
if (compat && !strcmp(compat, "fdthree"))
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static unsigned long __init sun_floppy_init(void)
|
||||
{
|
||||
char state[128];
|
||||
struct sbus_bus *bus;
|
||||
struct sbus_dev *sdev = NULL;
|
||||
static int initialized = 0;
|
||||
|
||||
if (initialized)
|
||||
return sun_floppy_types[0];
|
||||
initialized = 1;
|
||||
|
||||
for_all_sbusdev (sdev, bus) {
|
||||
if (!strcmp(sdev->prom_name, "SUNW,fdtwo"))
|
||||
break;
|
||||
}
|
||||
if(sdev) {
|
||||
floppy_sdev = sdev;
|
||||
FLOPPY_IRQ = sdev->irqs[0];
|
||||
} else {
|
||||
#ifdef CONFIG_PCI
|
||||
struct linux_ebus *ebus;
|
||||
struct linux_ebus_device *edev = NULL;
|
||||
unsigned long config = 0;
|
||||
void __iomem *auxio_reg;
|
||||
const char *state_prop;
|
||||
|
||||
for_each_ebus(ebus) {
|
||||
for_each_ebusdev(edev, ebus) {
|
||||
if (ebus_fdthree_p(edev))
|
||||
goto ebus_done;
|
||||
}
|
||||
}
|
||||
ebus_done:
|
||||
if (!edev)
|
||||
return 0;
|
||||
|
||||
state_prop = of_get_property(edev->prom_node, "status", NULL);
|
||||
if (state_prop && !strncmp(state_prop, "disabled", 8))
|
||||
return 0;
|
||||
|
||||
FLOPPY_IRQ = edev->irqs[0];
|
||||
|
||||
/* Make sure the high density bit is set, some systems
|
||||
* (most notably Ultra5/Ultra10) come up with it clear.
|
||||
*/
|
||||
auxio_reg = (void __iomem *) edev->resource[2].start;
|
||||
writel(readl(auxio_reg)|0x2, auxio_reg);
|
||||
|
||||
sun_pci_ebus_dev = ebus->self;
|
||||
|
||||
spin_lock_init(&sun_pci_fd_ebus_dma.lock);
|
||||
|
||||
/* XXX ioremap */
|
||||
sun_pci_fd_ebus_dma.regs = (void __iomem *)
|
||||
edev->resource[1].start;
|
||||
if (!sun_pci_fd_ebus_dma.regs)
|
||||
return 0;
|
||||
|
||||
sun_pci_fd_ebus_dma.flags = (EBUS_DMA_FLAG_USE_EBDMA_HANDLER |
|
||||
EBUS_DMA_FLAG_TCI_DISABLE);
|
||||
sun_pci_fd_ebus_dma.callback = sun_pci_fd_dma_callback;
|
||||
sun_pci_fd_ebus_dma.client_cookie = NULL;
|
||||
sun_pci_fd_ebus_dma.irq = FLOPPY_IRQ;
|
||||
strcpy(sun_pci_fd_ebus_dma.name, "floppy");
|
||||
if (ebus_dma_register(&sun_pci_fd_ebus_dma))
|
||||
return 0;
|
||||
|
||||
/* XXX ioremap */
|
||||
sun_fdc = (struct sun_flpy_controller *)edev->resource[0].start;
|
||||
|
||||
sun_fdops.fd_inb = sun_pci_fd_inb;
|
||||
sun_fdops.fd_outb = sun_pci_fd_outb;
|
||||
|
||||
can_use_virtual_dma = use_virtual_dma = 0;
|
||||
sun_fdops.fd_enable_dma = sun_pci_fd_enable_dma;
|
||||
sun_fdops.fd_disable_dma = sun_pci_fd_disable_dma;
|
||||
sun_fdops.fd_set_dma_mode = sun_pci_fd_set_dma_mode;
|
||||
sun_fdops.fd_set_dma_addr = sun_pci_fd_set_dma_addr;
|
||||
sun_fdops.fd_set_dma_count = sun_pci_fd_set_dma_count;
|
||||
sun_fdops.get_dma_residue = sun_pci_get_dma_residue;
|
||||
|
||||
sun_fdops.fd_request_irq = sun_pci_fd_request_irq;
|
||||
sun_fdops.fd_free_irq = sun_pci_fd_free_irq;
|
||||
|
||||
sun_fdops.fd_eject = sun_pci_fd_eject;
|
||||
|
||||
fdc_status = (unsigned long) &sun_fdc->status_82077;
|
||||
|
||||
/*
|
||||
* XXX: Find out on which machines this is really needed.
|
||||
*/
|
||||
if (1) {
|
||||
sun_pci_broken_drive = 1;
|
||||
sun_fdops.fd_outb = sun_pci_fd_broken_outb;
|
||||
}
|
||||
|
||||
allowed_drive_mask = 0;
|
||||
if (sun_pci_fd_test_drive((unsigned long)sun_fdc, 0))
|
||||
sun_floppy_types[0] = 4;
|
||||
if (sun_pci_fd_test_drive((unsigned long)sun_fdc, 1))
|
||||
sun_floppy_types[1] = 4;
|
||||
|
||||
/*
|
||||
* Find NS87303 SuperIO config registers (through ecpp).
|
||||
*/
|
||||
for_each_ebus(ebus) {
|
||||
for_each_ebusdev(edev, ebus) {
|
||||
if (!strcmp(edev->prom_node->name, "ecpp")) {
|
||||
config = edev->resource[1].start;
|
||||
goto config_done;
|
||||
}
|
||||
}
|
||||
}
|
||||
config_done:
|
||||
|
||||
/*
|
||||
* Sanity check, is this really the NS87303?
|
||||
*/
|
||||
switch (config & 0x3ff) {
|
||||
case 0x02e:
|
||||
case 0x15c:
|
||||
case 0x26e:
|
||||
case 0x398:
|
||||
break;
|
||||
default:
|
||||
config = 0;
|
||||
}
|
||||
|
||||
if (!config)
|
||||
return sun_floppy_types[0];
|
||||
|
||||
/* Enable PC-AT mode. */
|
||||
ns87303_modify(config, ASC, 0, 0xc0);
|
||||
|
||||
#ifdef PCI_FDC_SWAP_DRIVES
|
||||
/*
|
||||
* If only Floppy 1 is present, swap drives.
|
||||
*/
|
||||
if (!sun_floppy_types[0] && sun_floppy_types[1]) {
|
||||
/*
|
||||
* Set the drive exchange bit in FCR on NS87303,
|
||||
* make sure other bits are sane before doing so.
|
||||
*/
|
||||
ns87303_modify(config, FER, FER_EDM, 0);
|
||||
ns87303_modify(config, ASC, ASC_DRV2_SEL, 0);
|
||||
ns87303_modify(config, FCR, 0, FCR_LDE);
|
||||
|
||||
config = sun_floppy_types[0];
|
||||
sun_floppy_types[0] = sun_floppy_types[1];
|
||||
sun_floppy_types[1] = config;
|
||||
|
||||
if (sun_pci_broken_drive != -1) {
|
||||
sun_pci_broken_drive = 1 - sun_pci_broken_drive;
|
||||
sun_fdops.fd_outb = sun_pci_fd_lde_broken_outb;
|
||||
}
|
||||
}
|
||||
#endif /* PCI_FDC_SWAP_DRIVES */
|
||||
|
||||
return sun_floppy_types[0];
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
prom_getproperty(sdev->prom_node, "status", state, sizeof(state));
|
||||
if(!strncmp(state, "disabled", 8))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* We cannot do sbus_ioremap here: it does request_region,
|
||||
* which the generic floppy driver tries to do once again.
|
||||
* But we must use the sdev resource values as they have
|
||||
* had parent ranges applied.
|
||||
*/
|
||||
sun_fdc = (struct sun_flpy_controller *)
|
||||
(sdev->resource[0].start +
|
||||
((sdev->resource[0].flags & 0x1ffUL) << 32UL));
|
||||
|
||||
/* Last minute sanity check... */
|
||||
if(sbus_readb(&sun_fdc->status1_82077) == 0xff) {
|
||||
sun_fdc = (struct sun_flpy_controller *)-1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
sun_fdops.fd_inb = sun_82077_fd_inb;
|
||||
sun_fdops.fd_outb = sun_82077_fd_outb;
|
||||
|
||||
can_use_virtual_dma = use_virtual_dma = 1;
|
||||
sun_fdops.fd_enable_dma = sun_fd_enable_dma;
|
||||
sun_fdops.fd_disable_dma = sun_fd_disable_dma;
|
||||
sun_fdops.fd_set_dma_mode = sun_fd_set_dma_mode;
|
||||
sun_fdops.fd_set_dma_addr = sun_fd_set_dma_addr;
|
||||
sun_fdops.fd_set_dma_count = sun_fd_set_dma_count;
|
||||
sun_fdops.get_dma_residue = sun_get_dma_residue;
|
||||
|
||||
sun_fdops.fd_request_irq = sun_fd_request_irq;
|
||||
sun_fdops.fd_free_irq = sun_fd_free_irq;
|
||||
|
||||
sun_fdops.fd_eject = sun_fd_eject;
|
||||
|
||||
fdc_status = (unsigned long) &sun_fdc->status_82077;
|
||||
|
||||
/* Success... */
|
||||
allowed_drive_mask = 0x01;
|
||||
sun_floppy_types[0] = 4;
|
||||
sun_floppy_types[1] = 0;
|
||||
|
||||
return sun_floppy_types[0];
|
||||
}
|
||||
|
||||
#define EXTRA_FLOPPY_PARAMS
|
||||
|
||||
static DEFINE_SPINLOCK(dma_spin_lock);
|
||||
|
||||
#define claim_dma_lock() \
|
||||
({ unsigned long flags; \
|
||||
spin_lock_irqsave(&dma_spin_lock, flags); \
|
||||
flags; \
|
||||
})
|
||||
|
||||
#define release_dma_lock(__flags) \
|
||||
spin_unlock_irqrestore(&dma_spin_lock, __flags);
|
||||
|
||||
#endif /* !(__ASM_SPARC64_FLOPPY_H) */
|
|
@ -1,6 +1,8 @@
|
|||
#ifndef _ASM_FUTEX_H
|
||||
#define _ASM_FUTEX_H
|
||||
|
||||
#include <asm-generic/futex.h>
|
||||
|
||||
#ifndef ___ASM_SPARC_FUTEX_H
|
||||
#define ___ASM_SPARC_FUTEX_H
|
||||
#if defined(__sparc__) && defined(__arch64__)
|
||||
#include <asm-sparc/futex_64.h>
|
||||
#else
|
||||
#include <asm-sparc/futex_32.h>
|
||||
#endif
|
||||
#endif
|
||||
|
|
6
include/asm-sparc/futex_32.h
Normal file
6
include/asm-sparc/futex_32.h
Normal file
|
@ -0,0 +1,6 @@
|
|||
#ifndef _ASM_FUTEX_H
|
||||
#define _ASM_FUTEX_H
|
||||
|
||||
#include <asm-generic/futex.h>
|
||||
|
||||
#endif
|
110
include/asm-sparc/futex_64.h
Normal file
110
include/asm-sparc/futex_64.h
Normal file
|
@ -0,0 +1,110 @@
|
|||
#ifndef _SPARC64_FUTEX_H
|
||||
#define _SPARC64_FUTEX_H
|
||||
|
||||
#include <linux/futex.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <asm/errno.h>
|
||||
#include <asm/system.h>
|
||||
|
||||
#define __futex_cas_op(insn, ret, oldval, uaddr, oparg) \
|
||||
__asm__ __volatile__( \
|
||||
"\n1: lduwa [%3] %%asi, %2\n" \
|
||||
" " insn "\n" \
|
||||
"2: casa [%3] %%asi, %2, %1\n" \
|
||||
" cmp %2, %1\n" \
|
||||
" bne,pn %%icc, 1b\n" \
|
||||
" mov 0, %0\n" \
|
||||
"3:\n" \
|
||||
" .section .fixup,#alloc,#execinstr\n" \
|
||||
" .align 4\n" \
|
||||
"4: sethi %%hi(3b), %0\n" \
|
||||
" jmpl %0 + %%lo(3b), %%g0\n" \
|
||||
" mov %5, %0\n" \
|
||||
" .previous\n" \
|
||||
" .section __ex_table,\"a\"\n" \
|
||||
" .align 4\n" \
|
||||
" .word 1b, 4b\n" \
|
||||
" .word 2b, 4b\n" \
|
||||
" .previous\n" \
|
||||
: "=&r" (ret), "=&r" (oldval), "=&r" (tem) \
|
||||
: "r" (uaddr), "r" (oparg), "i" (-EFAULT) \
|
||||
: "memory")
|
||||
|
||||
static inline int futex_atomic_op_inuser(int encoded_op, int __user *uaddr)
|
||||
{
|
||||
int op = (encoded_op >> 28) & 7;
|
||||
int cmp = (encoded_op >> 24) & 15;
|
||||
int oparg = (encoded_op << 8) >> 20;
|
||||
int cmparg = (encoded_op << 20) >> 20;
|
||||
int oldval = 0, ret, tem;
|
||||
|
||||
if (unlikely(!access_ok(VERIFY_WRITE, uaddr, sizeof(int))))
|
||||
return -EFAULT;
|
||||
if (unlikely((((unsigned long) uaddr) & 0x3UL)))
|
||||
return -EINVAL;
|
||||
|
||||
if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
|
||||
oparg = 1 << oparg;
|
||||
|
||||
pagefault_disable();
|
||||
|
||||
switch (op) {
|
||||
case FUTEX_OP_SET:
|
||||
__futex_cas_op("mov\t%4, %1", ret, oldval, uaddr, oparg);
|
||||
break;
|
||||
case FUTEX_OP_ADD:
|
||||
__futex_cas_op("add\t%2, %4, %1", ret, oldval, uaddr, oparg);
|
||||
break;
|
||||
case FUTEX_OP_OR:
|
||||
__futex_cas_op("or\t%2, %4, %1", ret, oldval, uaddr, oparg);
|
||||
break;
|
||||
case FUTEX_OP_ANDN:
|
||||
__futex_cas_op("and\t%2, %4, %1", ret, oldval, uaddr, oparg);
|
||||
break;
|
||||
case FUTEX_OP_XOR:
|
||||
__futex_cas_op("xor\t%2, %4, %1", ret, oldval, uaddr, oparg);
|
||||
break;
|
||||
default:
|
||||
ret = -ENOSYS;
|
||||
}
|
||||
|
||||
pagefault_enable();
|
||||
|
||||
if (!ret) {
|
||||
switch (cmp) {
|
||||
case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break;
|
||||
case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break;
|
||||
case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break;
|
||||
case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break;
|
||||
case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break;
|
||||
case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break;
|
||||
default: ret = -ENOSYS;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline int
|
||||
futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval)
|
||||
{
|
||||
__asm__ __volatile__(
|
||||
"\n1: casa [%3] %%asi, %2, %0\n"
|
||||
"2:\n"
|
||||
" .section .fixup,#alloc,#execinstr\n"
|
||||
" .align 4\n"
|
||||
"3: sethi %%hi(2b), %0\n"
|
||||
" jmpl %0 + %%lo(2b), %%g0\n"
|
||||
" mov %4, %0\n"
|
||||
" .previous\n"
|
||||
" .section __ex_table,\"a\"\n"
|
||||
" .align 4\n"
|
||||
" .word 1b, 3b\n"
|
||||
" .previous\n"
|
||||
: "=r" (newval)
|
||||
: "0" (newval), "r" (oldval), "r" (uaddr), "i" (-EFAULT)
|
||||
: "memory");
|
||||
|
||||
return newval;
|
||||
}
|
||||
|
||||
#endif /* !(_SPARC64_FUTEX_H) */
|
|
@ -1,23 +1,8 @@
|
|||
/* hardirq.h: 32-bit Sparc hard IRQ support.
|
||||
*
|
||||
* Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
|
||||
* Copyright (C) 1998-2000 Anton Blanchard (anton@samba.org)
|
||||
*/
|
||||
|
||||
#ifndef __SPARC_HARDIRQ_H
|
||||
#define __SPARC_HARDIRQ_H
|
||||
|
||||
#include <linux/threads.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/cache.h>
|
||||
|
||||
/* entry.S is sensitive to the offsets of these fields */ /* XXX P3 Is it? */
|
||||
typedef struct {
|
||||
unsigned int __softirq_pending;
|
||||
} ____cacheline_aligned irq_cpustat_t;
|
||||
|
||||
#include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */
|
||||
|
||||
#define HARDIRQ_BITS 8
|
||||
|
||||
#endif /* __SPARC_HARDIRQ_H */
|
||||
#ifndef ___ASM_SPARC_HARDIRQ_H
|
||||
#define ___ASM_SPARC_HARDIRQ_H
|
||||
#if defined(__sparc__) && defined(__arch64__)
|
||||
#include <asm-sparc/hardirq_64.h>
|
||||
#else
|
||||
#include <asm-sparc/hardirq_32.h>
|
||||
#endif
|
||||
#endif
|
||||
|
|
23
include/asm-sparc/hardirq_32.h
Normal file
23
include/asm-sparc/hardirq_32.h
Normal file
|
@ -0,0 +1,23 @@
|
|||
/* hardirq.h: 32-bit Sparc hard IRQ support.
|
||||
*
|
||||
* Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
|
||||
* Copyright (C) 1998-2000 Anton Blanchard (anton@samba.org)
|
||||
*/
|
||||
|
||||
#ifndef __SPARC_HARDIRQ_H
|
||||
#define __SPARC_HARDIRQ_H
|
||||
|
||||
#include <linux/threads.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/cache.h>
|
||||
|
||||
/* entry.S is sensitive to the offsets of these fields */ /* XXX P3 Is it? */
|
||||
typedef struct {
|
||||
unsigned int __softirq_pending;
|
||||
} ____cacheline_aligned irq_cpustat_t;
|
||||
|
||||
#include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */
|
||||
|
||||
#define HARDIRQ_BITS 8
|
||||
|
||||
#endif /* __SPARC_HARDIRQ_H */
|
19
include/asm-sparc/hardirq_64.h
Normal file
19
include/asm-sparc/hardirq_64.h
Normal file
|
@ -0,0 +1,19 @@
|
|||
/* hardirq.h: 64-bit Sparc hard IRQ support.
|
||||
*
|
||||
* Copyright (C) 1997, 1998, 2005 David S. Miller (davem@davemloft.net)
|
||||
*/
|
||||
|
||||
#ifndef __SPARC64_HARDIRQ_H
|
||||
#define __SPARC64_HARDIRQ_H
|
||||
|
||||
#include <asm/cpudata.h>
|
||||
|
||||
#define __ARCH_IRQ_STAT
|
||||
#define local_softirq_pending() \
|
||||
(local_cpu_data().__softirq_pending)
|
||||
|
||||
void ack_bad_irq(unsigned int irq);
|
||||
|
||||
#define HARDIRQ_BITS 8
|
||||
|
||||
#endif /* !(__SPARC64_HARDIRQ_H) */
|
|
@ -1,102 +1,8 @@
|
|||
#ifndef __SPARC_HEAD_H
|
||||
#define __SPARC_HEAD_H
|
||||
|
||||
#define KERNBASE 0xf0000000 /* First address the kernel will eventually be */
|
||||
#define LOAD_ADDR 0x4000 /* prom jumps to us here unless this is elf /boot */
|
||||
#define SUN4C_SEGSZ (1 << 18)
|
||||
#define SRMMU_L1_KBASE_OFFSET ((KERNBASE>>24)<<2) /* Used in boot remapping. */
|
||||
#define INTS_ENAB 0x01 /* entry.S uses this. */
|
||||
|
||||
#define SUN4_PROM_VECTOR 0xFFE81000 /* SUN4 PROM needs to be hardwired */
|
||||
|
||||
#define WRITE_PAUSE nop; nop; nop; /* Have to do this after %wim/%psr chg */
|
||||
#define NOP_INSN 0x01000000 /* Used to patch sparc_save_state */
|
||||
|
||||
/* Here are some trap goodies */
|
||||
|
||||
/* Generic trap entry. */
|
||||
#define TRAP_ENTRY(type, label) \
|
||||
rd %psr, %l0; b label; rd %wim, %l3; nop;
|
||||
|
||||
/* Data/text faults. Defaults to sun4c version at boot time. */
|
||||
#define SPARC_TFAULT rd %psr, %l0; rd %wim, %l3; b sun4c_fault; mov 1, %l7;
|
||||
#define SPARC_DFAULT rd %psr, %l0; rd %wim, %l3; b sun4c_fault; mov 0, %l7;
|
||||
#define SRMMU_TFAULT rd %psr, %l0; rd %wim, %l3; b srmmu_fault; mov 1, %l7;
|
||||
#define SRMMU_DFAULT rd %psr, %l0; rd %wim, %l3; b srmmu_fault; mov 0, %l7;
|
||||
|
||||
/* This is for traps we should NEVER get. */
|
||||
#define BAD_TRAP(num) \
|
||||
rd %psr, %l0; mov num, %l7; b bad_trap_handler; rd %wim, %l3;
|
||||
|
||||
/* This is for traps when we want just skip the instruction which caused it */
|
||||
#define SKIP_TRAP(type, name) \
|
||||
jmpl %l2, %g0; rett %l2 + 4; nop; nop;
|
||||
|
||||
/* Notice that for the system calls we pull a trick. We load up a
|
||||
* different pointer to the system call vector table in %l7, but call
|
||||
* the same generic system call low-level entry point. The trap table
|
||||
* entry sequences are also HyperSparc pipeline friendly ;-)
|
||||
*/
|
||||
|
||||
/* Software trap for Linux system calls. */
|
||||
#define LINUX_SYSCALL_TRAP \
|
||||
sethi %hi(sys_call_table), %l7; \
|
||||
or %l7, %lo(sys_call_table), %l7; \
|
||||
b linux_sparc_syscall; \
|
||||
rd %psr, %l0;
|
||||
|
||||
#define BREAKPOINT_TRAP \
|
||||
b breakpoint_trap; \
|
||||
rd %psr,%l0; \
|
||||
nop; \
|
||||
nop;
|
||||
|
||||
#ifdef CONFIG_KGDB
|
||||
#define KGDB_TRAP(num) \
|
||||
b kgdb_trap_low; \
|
||||
rd %psr,%l0; \
|
||||
nop; \
|
||||
nop;
|
||||
#ifndef ___ASM_SPARC_HEAD_H
|
||||
#define ___ASM_SPARC_HEAD_H
|
||||
#if defined(__sparc__) && defined(__arch64__)
|
||||
#include <asm-sparc/head_64.h>
|
||||
#else
|
||||
#define KGDB_TRAP(num) \
|
||||
BAD_TRAP(num)
|
||||
#include <asm-sparc/head_32.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* The Get Condition Codes software trap for userland. */
|
||||
#define GETCC_TRAP \
|
||||
b getcc_trap_handler; mov %psr, %l0; nop; nop;
|
||||
|
||||
/* The Set Condition Codes software trap for userland. */
|
||||
#define SETCC_TRAP \
|
||||
b setcc_trap_handler; mov %psr, %l0; nop; nop;
|
||||
|
||||
/* The Get PSR software trap for userland. */
|
||||
#define GETPSR_TRAP \
|
||||
mov %psr, %i0; jmp %l2; rett %l2 + 4; nop;
|
||||
|
||||
/* This is for hard interrupts from level 1-14, 15 is non-maskable (nmi) and
|
||||
* gets handled with another macro.
|
||||
*/
|
||||
#define TRAP_ENTRY_INTERRUPT(int_level) \
|
||||
mov int_level, %l7; rd %psr, %l0; b real_irq_entry; rd %wim, %l3;
|
||||
|
||||
/* NMI's (Non Maskable Interrupts) are special, you can't keep them
|
||||
* from coming in, and basically if you get one, the shows over. ;(
|
||||
* On the sun4c they are usually asynchronous memory errors, on the
|
||||
* the sun4m they could be either due to mem errors or a software
|
||||
* initiated interrupt from the prom/kern on an SMP box saying "I
|
||||
* command you to do CPU tricks, read your mailbox for more info."
|
||||
*/
|
||||
#define NMI_TRAP \
|
||||
rd %wim, %l3; b linux_trap_nmi_sun4c; mov %psr, %l0; nop;
|
||||
|
||||
/* Window overflows/underflows are special and we need to try to be as
|
||||
* efficient as possible here....
|
||||
*/
|
||||
#define WINDOW_SPILL \
|
||||
rd %psr, %l0; rd %wim, %l3; b spill_window_entry; andcc %l0, PSR_PS, %g0;
|
||||
|
||||
#define WINDOW_FILL \
|
||||
rd %psr, %l0; rd %wim, %l3; b fill_window_entry; andcc %l0, PSR_PS, %g0;
|
||||
|
||||
#endif /* __SPARC_HEAD_H */
|
||||
|
|
102
include/asm-sparc/head_32.h
Normal file
102
include/asm-sparc/head_32.h
Normal file
|
@ -0,0 +1,102 @@
|
|||
#ifndef __SPARC_HEAD_H
|
||||
#define __SPARC_HEAD_H
|
||||
|
||||
#define KERNBASE 0xf0000000 /* First address the kernel will eventually be */
|
||||
#define LOAD_ADDR 0x4000 /* prom jumps to us here unless this is elf /boot */
|
||||
#define SUN4C_SEGSZ (1 << 18)
|
||||
#define SRMMU_L1_KBASE_OFFSET ((KERNBASE>>24)<<2) /* Used in boot remapping. */
|
||||
#define INTS_ENAB 0x01 /* entry.S uses this. */
|
||||
|
||||
#define SUN4_PROM_VECTOR 0xFFE81000 /* SUN4 PROM needs to be hardwired */
|
||||
|
||||
#define WRITE_PAUSE nop; nop; nop; /* Have to do this after %wim/%psr chg */
|
||||
#define NOP_INSN 0x01000000 /* Used to patch sparc_save_state */
|
||||
|
||||
/* Here are some trap goodies */
|
||||
|
||||
/* Generic trap entry. */
|
||||
#define TRAP_ENTRY(type, label) \
|
||||
rd %psr, %l0; b label; rd %wim, %l3; nop;
|
||||
|
||||
/* Data/text faults. Defaults to sun4c version at boot time. */
|
||||
#define SPARC_TFAULT rd %psr, %l0; rd %wim, %l3; b sun4c_fault; mov 1, %l7;
|
||||
#define SPARC_DFAULT rd %psr, %l0; rd %wim, %l3; b sun4c_fault; mov 0, %l7;
|
||||
#define SRMMU_TFAULT rd %psr, %l0; rd %wim, %l3; b srmmu_fault; mov 1, %l7;
|
||||
#define SRMMU_DFAULT rd %psr, %l0; rd %wim, %l3; b srmmu_fault; mov 0, %l7;
|
||||
|
||||
/* This is for traps we should NEVER get. */
|
||||
#define BAD_TRAP(num) \
|
||||
rd %psr, %l0; mov num, %l7; b bad_trap_handler; rd %wim, %l3;
|
||||
|
||||
/* This is for traps when we want just skip the instruction which caused it */
|
||||
#define SKIP_TRAP(type, name) \
|
||||
jmpl %l2, %g0; rett %l2 + 4; nop; nop;
|
||||
|
||||
/* Notice that for the system calls we pull a trick. We load up a
|
||||
* different pointer to the system call vector table in %l7, but call
|
||||
* the same generic system call low-level entry point. The trap table
|
||||
* entry sequences are also HyperSparc pipeline friendly ;-)
|
||||
*/
|
||||
|
||||
/* Software trap for Linux system calls. */
|
||||
#define LINUX_SYSCALL_TRAP \
|
||||
sethi %hi(sys_call_table), %l7; \
|
||||
or %l7, %lo(sys_call_table), %l7; \
|
||||
b linux_sparc_syscall; \
|
||||
rd %psr, %l0;
|
||||
|
||||
#define BREAKPOINT_TRAP \
|
||||
b breakpoint_trap; \
|
||||
rd %psr,%l0; \
|
||||
nop; \
|
||||
nop;
|
||||
|
||||
#ifdef CONFIG_KGDB
|
||||
#define KGDB_TRAP(num) \
|
||||
b kgdb_trap_low; \
|
||||
rd %psr,%l0; \
|
||||
nop; \
|
||||
nop;
|
||||
#else
|
||||
#define KGDB_TRAP(num) \
|
||||
BAD_TRAP(num)
|
||||
#endif
|
||||
|
||||
/* The Get Condition Codes software trap for userland. */
|
||||
#define GETCC_TRAP \
|
||||
b getcc_trap_handler; mov %psr, %l0; nop; nop;
|
||||
|
||||
/* The Set Condition Codes software trap for userland. */
|
||||
#define SETCC_TRAP \
|
||||
b setcc_trap_handler; mov %psr, %l0; nop; nop;
|
||||
|
||||
/* The Get PSR software trap for userland. */
|
||||
#define GETPSR_TRAP \
|
||||
mov %psr, %i0; jmp %l2; rett %l2 + 4; nop;
|
||||
|
||||
/* This is for hard interrupts from level 1-14, 15 is non-maskable (nmi) and
|
||||
* gets handled with another macro.
|
||||
*/
|
||||
#define TRAP_ENTRY_INTERRUPT(int_level) \
|
||||
mov int_level, %l7; rd %psr, %l0; b real_irq_entry; rd %wim, %l3;
|
||||
|
||||
/* NMI's (Non Maskable Interrupts) are special, you can't keep them
|
||||
* from coming in, and basically if you get one, the shows over. ;(
|
||||
* On the sun4c they are usually asynchronous memory errors, on the
|
||||
* the sun4m they could be either due to mem errors or a software
|
||||
* initiated interrupt from the prom/kern on an SMP box saying "I
|
||||
* command you to do CPU tricks, read your mailbox for more info."
|
||||
*/
|
||||
#define NMI_TRAP \
|
||||
rd %wim, %l3; b linux_trap_nmi_sun4c; mov %psr, %l0; nop;
|
||||
|
||||
/* Window overflows/underflows are special and we need to try to be as
|
||||
* efficient as possible here....
|
||||
*/
|
||||
#define WINDOW_SPILL \
|
||||
rd %psr, %l0; rd %wim, %l3; b spill_window_entry; andcc %l0, PSR_PS, %g0;
|
||||
|
||||
#define WINDOW_FILL \
|
||||
rd %psr, %l0; rd %wim, %l3; b fill_window_entry; andcc %l0, PSR_PS, %g0;
|
||||
|
||||
#endif /* __SPARC_HEAD_H */
|
76
include/asm-sparc/head_64.h
Normal file
76
include/asm-sparc/head_64.h
Normal file
|
@ -0,0 +1,76 @@
|
|||
#ifndef _SPARC64_HEAD_H
|
||||
#define _SPARC64_HEAD_H
|
||||
|
||||
#include <asm/pstate.h>
|
||||
|
||||
/* wrpr %g0, val, %gl */
|
||||
#define SET_GL(val) \
|
||||
.word 0xa1902000 | val
|
||||
|
||||
/* rdpr %gl, %gN */
|
||||
#define GET_GL_GLOBAL(N) \
|
||||
.word 0x81540000 | (N << 25)
|
||||
|
||||
#define KERNBASE 0x400000
|
||||
|
||||
#define PTREGS_OFF (STACK_BIAS + STACKFRAME_SZ)
|
||||
|
||||
#define __CHEETAH_ID 0x003e0014
|
||||
#define __JALAPENO_ID 0x003e0016
|
||||
#define __SERRANO_ID 0x003e0022
|
||||
|
||||
#define CHEETAH_MANUF 0x003e
|
||||
#define CHEETAH_IMPL 0x0014 /* Ultra-III */
|
||||
#define CHEETAH_PLUS_IMPL 0x0015 /* Ultra-III+ */
|
||||
#define JALAPENO_IMPL 0x0016 /* Ultra-IIIi */
|
||||
#define JAGUAR_IMPL 0x0018 /* Ultra-IV */
|
||||
#define PANTHER_IMPL 0x0019 /* Ultra-IV+ */
|
||||
#define SERRANO_IMPL 0x0022 /* Ultra-IIIi+ */
|
||||
|
||||
#define BRANCH_IF_SUN4V(tmp1,label) \
|
||||
sethi %hi(is_sun4v), %tmp1; \
|
||||
lduw [%tmp1 + %lo(is_sun4v)], %tmp1; \
|
||||
brnz,pn %tmp1, label; \
|
||||
nop
|
||||
|
||||
#define BRANCH_IF_CHEETAH_BASE(tmp1,tmp2,label) \
|
||||
rdpr %ver, %tmp1; \
|
||||
sethi %hi(__CHEETAH_ID), %tmp2; \
|
||||
srlx %tmp1, 32, %tmp1; \
|
||||
or %tmp2, %lo(__CHEETAH_ID), %tmp2;\
|
||||
cmp %tmp1, %tmp2; \
|
||||
be,pn %icc, label; \
|
||||
nop;
|
||||
|
||||
#define BRANCH_IF_JALAPENO(tmp1,tmp2,label) \
|
||||
rdpr %ver, %tmp1; \
|
||||
sethi %hi(__JALAPENO_ID), %tmp2; \
|
||||
srlx %tmp1, 32, %tmp1; \
|
||||
or %tmp2, %lo(__JALAPENO_ID), %tmp2;\
|
||||
cmp %tmp1, %tmp2; \
|
||||
be,pn %icc, label; \
|
||||
nop;
|
||||
|
||||
#define BRANCH_IF_CHEETAH_PLUS_OR_FOLLOWON(tmp1,tmp2,label) \
|
||||
rdpr %ver, %tmp1; \
|
||||
srlx %tmp1, (32 + 16), %tmp2; \
|
||||
cmp %tmp2, CHEETAH_MANUF; \
|
||||
bne,pt %xcc, 99f; \
|
||||
sllx %tmp1, 16, %tmp1; \
|
||||
srlx %tmp1, (32 + 16), %tmp2; \
|
||||
cmp %tmp2, CHEETAH_PLUS_IMPL; \
|
||||
bgeu,pt %xcc, label; \
|
||||
99: nop;
|
||||
|
||||
#define BRANCH_IF_ANY_CHEETAH(tmp1,tmp2,label) \
|
||||
rdpr %ver, %tmp1; \
|
||||
srlx %tmp1, (32 + 16), %tmp2; \
|
||||
cmp %tmp2, CHEETAH_MANUF; \
|
||||
bne,pt %xcc, 99f; \
|
||||
sllx %tmp1, 16, %tmp1; \
|
||||
srlx %tmp1, (32 + 16), %tmp2; \
|
||||
cmp %tmp2, CHEETAH_IMPL; \
|
||||
bgeu,pt %xcc, label; \
|
||||
99: nop;
|
||||
|
||||
#endif /* !(_SPARC64_HEAD_H) */
|
|
@ -1,95 +1,8 @@
|
|||
/* ide.h: SPARC PCI specific IDE glue.
|
||||
*
|
||||
* Copyright (C) 1997 David S. Miller (davem@davemloft.net)
|
||||
* Copyright (C) 1998 Eddie C. Dost (ecd@skynet.be)
|
||||
* Adaptation from sparc64 version to sparc by Pete Zaitcev.
|
||||
*/
|
||||
|
||||
#ifndef _SPARC_IDE_H
|
||||
#define _SPARC_IDE_H
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
#include <asm/pgtable.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/psr.h>
|
||||
|
||||
#undef MAX_HWIFS
|
||||
#define MAX_HWIFS 2
|
||||
|
||||
#define __ide_insl(data_reg, buffer, wcount) \
|
||||
__ide_insw(data_reg, buffer, (wcount)<<1)
|
||||
#define __ide_outsl(data_reg, buffer, wcount) \
|
||||
__ide_outsw(data_reg, buffer, (wcount)<<1)
|
||||
|
||||
/* On sparc, I/O ports and MMIO registers are accessed identically. */
|
||||
#define __ide_mm_insw __ide_insw
|
||||
#define __ide_mm_insl __ide_insl
|
||||
#define __ide_mm_outsw __ide_outsw
|
||||
#define __ide_mm_outsl __ide_outsl
|
||||
|
||||
static inline void __ide_insw(unsigned long port,
|
||||
void *dst,
|
||||
unsigned long count)
|
||||
{
|
||||
volatile unsigned short *data_port;
|
||||
/* unsigned long end = (unsigned long)dst + (count << 1); */ /* P3 */
|
||||
u16 *ps = dst;
|
||||
u32 *pi;
|
||||
|
||||
data_port = (volatile unsigned short *)port;
|
||||
|
||||
if(((unsigned long)ps) & 0x2) {
|
||||
*ps++ = *data_port;
|
||||
count--;
|
||||
}
|
||||
pi = (u32 *)ps;
|
||||
while(count >= 2) {
|
||||
u32 w;
|
||||
|
||||
w = (*data_port) << 16;
|
||||
w |= (*data_port);
|
||||
*pi++ = w;
|
||||
count -= 2;
|
||||
}
|
||||
ps = (u16 *)pi;
|
||||
if(count)
|
||||
*ps++ = *data_port;
|
||||
|
||||
/* __flush_dcache_range((unsigned long)dst, end); */ /* P3 see hme */
|
||||
}
|
||||
|
||||
static inline void __ide_outsw(unsigned long port,
|
||||
const void *src,
|
||||
unsigned long count)
|
||||
{
|
||||
volatile unsigned short *data_port;
|
||||
/* unsigned long end = (unsigned long)src + (count << 1); */
|
||||
const u16 *ps = src;
|
||||
const u32 *pi;
|
||||
|
||||
data_port = (volatile unsigned short *)port;
|
||||
|
||||
if(((unsigned long)src) & 0x2) {
|
||||
*data_port = *ps++;
|
||||
count--;
|
||||
}
|
||||
pi = (const u32 *)ps;
|
||||
while(count >= 2) {
|
||||
u32 w;
|
||||
|
||||
w = *pi++;
|
||||
*data_port = (w >> 16);
|
||||
*data_port = w;
|
||||
count -= 2;
|
||||
}
|
||||
ps = (const u16 *)pi;
|
||||
if(count)
|
||||
*data_port = *ps;
|
||||
|
||||
/* __flush_dcache_range((unsigned long)src, end); */ /* P3 see hme */
|
||||
}
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
#endif /* _SPARC_IDE_H */
|
||||
#ifndef ___ASM_SPARC_IDE_H
|
||||
#define ___ASM_SPARC_IDE_H
|
||||
#if defined(__sparc__) && defined(__arch64__)
|
||||
#include <asm-sparc/ide_64.h>
|
||||
#else
|
||||
#include <asm-sparc/ide_32.h>
|
||||
#endif
|
||||
#endif
|
||||
|
|
95
include/asm-sparc/ide_32.h
Normal file
95
include/asm-sparc/ide_32.h
Normal file
|
@ -0,0 +1,95 @@
|
|||
/* ide.h: SPARC PCI specific IDE glue.
|
||||
*
|
||||
* Copyright (C) 1997 David S. Miller (davem@davemloft.net)
|
||||
* Copyright (C) 1998 Eddie C. Dost (ecd@skynet.be)
|
||||
* Adaptation from sparc64 version to sparc by Pete Zaitcev.
|
||||
*/
|
||||
|
||||
#ifndef _SPARC_IDE_H
|
||||
#define _SPARC_IDE_H
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
#include <asm/pgtable.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/psr.h>
|
||||
|
||||
#undef MAX_HWIFS
|
||||
#define MAX_HWIFS 2
|
||||
|
||||
#define __ide_insl(data_reg, buffer, wcount) \
|
||||
__ide_insw(data_reg, buffer, (wcount)<<1)
|
||||
#define __ide_outsl(data_reg, buffer, wcount) \
|
||||
__ide_outsw(data_reg, buffer, (wcount)<<1)
|
||||
|
||||
/* On sparc, I/O ports and MMIO registers are accessed identically. */
|
||||
#define __ide_mm_insw __ide_insw
|
||||
#define __ide_mm_insl __ide_insl
|
||||
#define __ide_mm_outsw __ide_outsw
|
||||
#define __ide_mm_outsl __ide_outsl
|
||||
|
||||
static inline void __ide_insw(unsigned long port,
|
||||
void *dst,
|
||||
unsigned long count)
|
||||
{
|
||||
volatile unsigned short *data_port;
|
||||
/* unsigned long end = (unsigned long)dst + (count << 1); */ /* P3 */
|
||||
u16 *ps = dst;
|
||||
u32 *pi;
|
||||
|
||||
data_port = (volatile unsigned short *)port;
|
||||
|
||||
if(((unsigned long)ps) & 0x2) {
|
||||
*ps++ = *data_port;
|
||||
count--;
|
||||
}
|
||||
pi = (u32 *)ps;
|
||||
while(count >= 2) {
|
||||
u32 w;
|
||||
|
||||
w = (*data_port) << 16;
|
||||
w |= (*data_port);
|
||||
*pi++ = w;
|
||||
count -= 2;
|
||||
}
|
||||
ps = (u16 *)pi;
|
||||
if(count)
|
||||
*ps++ = *data_port;
|
||||
|
||||
/* __flush_dcache_range((unsigned long)dst, end); */ /* P3 see hme */
|
||||
}
|
||||
|
||||
static inline void __ide_outsw(unsigned long port,
|
||||
const void *src,
|
||||
unsigned long count)
|
||||
{
|
||||
volatile unsigned short *data_port;
|
||||
/* unsigned long end = (unsigned long)src + (count << 1); */
|
||||
const u16 *ps = src;
|
||||
const u32 *pi;
|
||||
|
||||
data_port = (volatile unsigned short *)port;
|
||||
|
||||
if(((unsigned long)src) & 0x2) {
|
||||
*data_port = *ps++;
|
||||
count--;
|
||||
}
|
||||
pi = (const u32 *)ps;
|
||||
while(count >= 2) {
|
||||
u32 w;
|
||||
|
||||
w = *pi++;
|
||||
*data_port = (w >> 16);
|
||||
*data_port = w;
|
||||
count -= 2;
|
||||
}
|
||||
ps = (const u16 *)pi;
|
||||
if(count)
|
||||
*data_port = *ps;
|
||||
|
||||
/* __flush_dcache_range((unsigned long)src, end); */ /* P3 see hme */
|
||||
}
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
#endif /* _SPARC_IDE_H */
|
118
include/asm-sparc/ide_64.h
Normal file
118
include/asm-sparc/ide_64.h
Normal file
|
@ -0,0 +1,118 @@
|
|||
/*
|
||||
* ide.h: Ultra/PCI specific IDE glue.
|
||||
*
|
||||
* Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
|
||||
* Copyright (C) 1998 Eddie C. Dost (ecd@skynet.be)
|
||||
*/
|
||||
|
||||
#ifndef _SPARC64_IDE_H
|
||||
#define _SPARC64_IDE_H
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
#include <asm/pgalloc.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/spitfire.h>
|
||||
#include <asm/cacheflush.h>
|
||||
#include <asm/page.h>
|
||||
|
||||
#ifndef MAX_HWIFS
|
||||
# ifdef CONFIG_BLK_DEV_IDEPCI
|
||||
#define MAX_HWIFS 10
|
||||
# else
|
||||
#define MAX_HWIFS 2
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#define __ide_insl(data_reg, buffer, wcount) \
|
||||
__ide_insw(data_reg, buffer, (wcount)<<1)
|
||||
#define __ide_outsl(data_reg, buffer, wcount) \
|
||||
__ide_outsw(data_reg, buffer, (wcount)<<1)
|
||||
|
||||
/* On sparc64, I/O ports and MMIO registers are accessed identically. */
|
||||
#define __ide_mm_insw __ide_insw
|
||||
#define __ide_mm_insl __ide_insl
|
||||
#define __ide_mm_outsw __ide_outsw
|
||||
#define __ide_mm_outsl __ide_outsl
|
||||
|
||||
static inline unsigned int inw_be(void __iomem *addr)
|
||||
{
|
||||
unsigned int ret;
|
||||
|
||||
__asm__ __volatile__("lduha [%1] %2, %0"
|
||||
: "=r" (ret)
|
||||
: "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline void __ide_insw(void __iomem *port, void *dst, u32 count)
|
||||
{
|
||||
#ifdef DCACHE_ALIASING_POSSIBLE
|
||||
unsigned long end = (unsigned long)dst + (count << 1);
|
||||
#endif
|
||||
u16 *ps = dst;
|
||||
u32 *pi;
|
||||
|
||||
if(((u64)ps) & 0x2) {
|
||||
*ps++ = inw_be(port);
|
||||
count--;
|
||||
}
|
||||
pi = (u32 *)ps;
|
||||
while(count >= 2) {
|
||||
u32 w;
|
||||
|
||||
w = inw_be(port) << 16;
|
||||
w |= inw_be(port);
|
||||
*pi++ = w;
|
||||
count -= 2;
|
||||
}
|
||||
ps = (u16 *)pi;
|
||||
if(count)
|
||||
*ps++ = inw_be(port);
|
||||
|
||||
#ifdef DCACHE_ALIASING_POSSIBLE
|
||||
__flush_dcache_range((unsigned long)dst, end);
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void outw_be(unsigned short w, void __iomem *addr)
|
||||
{
|
||||
__asm__ __volatile__("stha %0, [%1] %2"
|
||||
: /* no outputs */
|
||||
: "r" (w), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
|
||||
}
|
||||
|
||||
static inline void __ide_outsw(void __iomem *port, void *src, u32 count)
|
||||
{
|
||||
#ifdef DCACHE_ALIASING_POSSIBLE
|
||||
unsigned long end = (unsigned long)src + (count << 1);
|
||||
#endif
|
||||
const u16 *ps = src;
|
||||
const u32 *pi;
|
||||
|
||||
if(((u64)src) & 0x2) {
|
||||
outw_be(*ps++, port);
|
||||
count--;
|
||||
}
|
||||
pi = (const u32 *)ps;
|
||||
while(count >= 2) {
|
||||
u32 w;
|
||||
|
||||
w = *pi++;
|
||||
outw_be((w >> 16), port);
|
||||
outw_be(w, port);
|
||||
count -= 2;
|
||||
}
|
||||
ps = (const u16 *)pi;
|
||||
if(count)
|
||||
outw_be(*ps, port);
|
||||
|
||||
#ifdef DCACHE_ALIASING_POSSIBLE
|
||||
__flush_dcache_range((unsigned long)src, end);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
#endif /* _SPARC64_IDE_H */
|
|
@ -1,325 +1,8 @@
|
|||
#ifndef __SPARC_IO_H
|
||||
#define __SPARC_IO_H
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/ioport.h> /* struct resource */
|
||||
|
||||
#include <asm/page.h> /* IO address mapping routines need this */
|
||||
#include <asm/system.h>
|
||||
|
||||
#define page_to_phys(page) (((page) - mem_map) << PAGE_SHIFT)
|
||||
|
||||
static inline u32 flip_dword (u32 l)
|
||||
{
|
||||
return ((l&0xff)<<24) | (((l>>8)&0xff)<<16) | (((l>>16)&0xff)<<8)| ((l>>24)&0xff);
|
||||
}
|
||||
|
||||
static inline u16 flip_word (u16 w)
|
||||
{
|
||||
return ((w&0xff) << 8) | ((w>>8)&0xff);
|
||||
}
|
||||
|
||||
#define mmiowb()
|
||||
|
||||
/*
|
||||
* Memory mapped I/O to PCI
|
||||
*/
|
||||
|
||||
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 w, volatile void __iomem *addr)
|
||||
{
|
||||
*(__force volatile u16 *)addr = w;
|
||||
}
|
||||
|
||||
static inline void __raw_writel(u32 l, volatile void __iomem *addr)
|
||||
{
|
||||
*(__force volatile u32 *)addr = l;
|
||||
}
|
||||
|
||||
static inline u8 __readb(const volatile void __iomem *addr)
|
||||
{
|
||||
return *(__force volatile u8 *)addr;
|
||||
}
|
||||
|
||||
static inline u16 __readw(const volatile void __iomem *addr)
|
||||
{
|
||||
return flip_word(*(__force volatile u16 *)addr);
|
||||
}
|
||||
|
||||
static inline u32 __readl(const volatile void __iomem *addr)
|
||||
{
|
||||
return flip_dword(*(__force volatile u32 *)addr);
|
||||
}
|
||||
|
||||
static inline void __writeb(u8 b, volatile void __iomem *addr)
|
||||
{
|
||||
*(__force volatile u8 *)addr = b;
|
||||
}
|
||||
|
||||
static inline void __writew(u16 w, volatile void __iomem *addr)
|
||||
{
|
||||
*(__force volatile u16 *)addr = flip_word(w);
|
||||
}
|
||||
|
||||
static inline void __writel(u32 l, volatile void __iomem *addr)
|
||||
{
|
||||
*(__force volatile u32 *)addr = flip_dword(l);
|
||||
}
|
||||
|
||||
#define readb(__addr) __readb(__addr)
|
||||
#define readw(__addr) __readw(__addr)
|
||||
#define readl(__addr) __readl(__addr)
|
||||
#define readb_relaxed(__addr) readb(__addr)
|
||||
#define readw_relaxed(__addr) readw(__addr)
|
||||
#define readl_relaxed(__addr) readl(__addr)
|
||||
|
||||
#define writeb(__b, __addr) __writeb((__b),(__addr))
|
||||
#define writew(__w, __addr) __writew((__w),(__addr))
|
||||
#define writel(__l, __addr) __writel((__l),(__addr))
|
||||
|
||||
/*
|
||||
* I/O space operations
|
||||
*
|
||||
* Arrangement on a Sun is somewhat complicated.
|
||||
*
|
||||
* First of all, we want to use standard Linux drivers
|
||||
* for keyboard, PC serial, etc. These drivers think
|
||||
* they access I/O space and use inb/outb.
|
||||
* On the other hand, EBus bridge accepts PCI *memory*
|
||||
* cycles and converts them into ISA *I/O* cycles.
|
||||
* Ergo, we want inb & outb to generate PCI memory cycles.
|
||||
*
|
||||
* If we want to issue PCI *I/O* cycles, we do this
|
||||
* with a low 64K fixed window in PCIC. This window gets
|
||||
* mapped somewhere into virtual kernel space and we
|
||||
* can use inb/outb again.
|
||||
*/
|
||||
#define inb_local(__addr) __readb((void __iomem *)(unsigned long)(__addr))
|
||||
#define inb(__addr) __readb((void __iomem *)(unsigned long)(__addr))
|
||||
#define inw(__addr) __readw((void __iomem *)(unsigned long)(__addr))
|
||||
#define inl(__addr) __readl((void __iomem *)(unsigned long)(__addr))
|
||||
|
||||
#define outb_local(__b, __addr) __writeb(__b, (void __iomem *)(unsigned long)(__addr))
|
||||
#define outb(__b, __addr) __writeb(__b, (void __iomem *)(unsigned long)(__addr))
|
||||
#define outw(__w, __addr) __writew(__w, (void __iomem *)(unsigned long)(__addr))
|
||||
#define outl(__l, __addr) __writel(__l, (void __iomem *)(unsigned long)(__addr))
|
||||
|
||||
#define inb_p(__addr) inb(__addr)
|
||||
#define outb_p(__b, __addr) outb(__b, __addr)
|
||||
#define inw_p(__addr) inw(__addr)
|
||||
#define outw_p(__w, __addr) outw(__w, __addr)
|
||||
#define inl_p(__addr) inl(__addr)
|
||||
#define outl_p(__l, __addr) outl(__l, __addr)
|
||||
|
||||
void outsb(unsigned long addr, const void *src, unsigned long cnt);
|
||||
void outsw(unsigned long addr, const void *src, unsigned long cnt);
|
||||
void outsl(unsigned long addr, const void *src, unsigned long cnt);
|
||||
void insb(unsigned long addr, void *dst, unsigned long count);
|
||||
void insw(unsigned long addr, void *dst, unsigned long count);
|
||||
void insl(unsigned long addr, void *dst, unsigned long count);
|
||||
|
||||
#define IO_SPACE_LIMIT 0xffffffff
|
||||
|
||||
/*
|
||||
* SBus accessors.
|
||||
*
|
||||
* SBus has only one, memory mapped, I/O space.
|
||||
* We do not need to flip bytes for SBus of course.
|
||||
*/
|
||||
static inline u8 _sbus_readb(const volatile void __iomem *addr)
|
||||
{
|
||||
return *(__force volatile u8 *)addr;
|
||||
}
|
||||
|
||||
static inline u16 _sbus_readw(const volatile void __iomem *addr)
|
||||
{
|
||||
return *(__force volatile u16 *)addr;
|
||||
}
|
||||
|
||||
static inline u32 _sbus_readl(const volatile void __iomem *addr)
|
||||
{
|
||||
return *(__force volatile u32 *)addr;
|
||||
}
|
||||
|
||||
static inline void _sbus_writeb(u8 b, volatile void __iomem *addr)
|
||||
{
|
||||
*(__force volatile u8 *)addr = b;
|
||||
}
|
||||
|
||||
static inline void _sbus_writew(u16 w, volatile void __iomem *addr)
|
||||
{
|
||||
*(__force volatile u16 *)addr = w;
|
||||
}
|
||||
|
||||
static inline void _sbus_writel(u32 l, volatile void __iomem *addr)
|
||||
{
|
||||
*(__force volatile u32 *)addr = l;
|
||||
}
|
||||
|
||||
/*
|
||||
* The only reason for #define's is to hide casts to unsigned long.
|
||||
*/
|
||||
#define sbus_readb(__addr) _sbus_readb(__addr)
|
||||
#define sbus_readw(__addr) _sbus_readw(__addr)
|
||||
#define sbus_readl(__addr) _sbus_readl(__addr)
|
||||
#define sbus_writeb(__b, __addr) _sbus_writeb(__b, __addr)
|
||||
#define sbus_writew(__w, __addr) _sbus_writew(__w, __addr)
|
||||
#define sbus_writel(__l, __addr) _sbus_writel(__l, __addr)
|
||||
|
||||
static inline void sbus_memset_io(volatile void __iomem *__dst, int c, __kernel_size_t n)
|
||||
{
|
||||
while(n--) {
|
||||
sbus_writeb(c, __dst);
|
||||
__dst++;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
_memset_io(volatile void __iomem *dst, int c, __kernel_size_t n)
|
||||
{
|
||||
volatile void __iomem *d = dst;
|
||||
|
||||
while (n--) {
|
||||
writeb(c, d);
|
||||
d++;
|
||||
}
|
||||
}
|
||||
|
||||
#define memset_io(d,c,sz) _memset_io(d,c,sz)
|
||||
|
||||
static inline void
|
||||
_memcpy_fromio(void *dst, const volatile void __iomem *src, __kernel_size_t n)
|
||||
{
|
||||
char *d = dst;
|
||||
|
||||
while (n--) {
|
||||
char tmp = readb(src);
|
||||
*d++ = tmp;
|
||||
src++;
|
||||
}
|
||||
}
|
||||
|
||||
#define memcpy_fromio(d,s,sz) _memcpy_fromio(d,s,sz)
|
||||
|
||||
static inline void
|
||||
_memcpy_toio(volatile void __iomem *dst, const void *src, __kernel_size_t n)
|
||||
{
|
||||
const char *s = src;
|
||||
volatile void __iomem *d = dst;
|
||||
|
||||
while (n--) {
|
||||
char tmp = *s++;
|
||||
writeb(tmp, d);
|
||||
d++;
|
||||
}
|
||||
}
|
||||
|
||||
#define memcpy_toio(d,s,sz) _memcpy_toio(d,s,sz)
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
/*
|
||||
* Bus number may be embedded in the higher bits of the physical address.
|
||||
* This is why we have no bus number argument to ioremap().
|
||||
*/
|
||||
extern void __iomem *ioremap(unsigned long offset, unsigned long size);
|
||||
#define ioremap_nocache(X,Y) ioremap((X),(Y))
|
||||
extern void iounmap(volatile void __iomem *addr);
|
||||
|
||||
#define ioread8(X) readb(X)
|
||||
#define ioread16(X) readw(X)
|
||||
#define ioread32(X) readl(X)
|
||||
#define iowrite8(val,X) writeb(val,X)
|
||||
#define iowrite16(val,X) writew(val,X)
|
||||
#define iowrite32(val,X) writel(val,X)
|
||||
|
||||
static inline void ioread8_rep(void __iomem *port, void *buf, unsigned long count)
|
||||
{
|
||||
insb((unsigned long __force)port, buf, count);
|
||||
}
|
||||
static inline void ioread16_rep(void __iomem *port, void *buf, unsigned long count)
|
||||
{
|
||||
insw((unsigned long __force)port, buf, count);
|
||||
}
|
||||
|
||||
static inline void ioread32_rep(void __iomem *port, void *buf, unsigned long count)
|
||||
{
|
||||
insl((unsigned long __force)port, buf, count);
|
||||
}
|
||||
|
||||
static inline void iowrite8_rep(void __iomem *port, const void *buf, unsigned long count)
|
||||
{
|
||||
outsb((unsigned long __force)port, buf, count);
|
||||
}
|
||||
|
||||
static inline void iowrite16_rep(void __iomem *port, const void *buf, unsigned long count)
|
||||
{
|
||||
outsw((unsigned long __force)port, buf, count);
|
||||
}
|
||||
|
||||
static inline void iowrite32_rep(void __iomem *port, const void *buf, unsigned long count)
|
||||
{
|
||||
outsl((unsigned long __force)port, buf, count);
|
||||
}
|
||||
|
||||
/* Create a virtual mapping cookie for an IO port range */
|
||||
extern void __iomem *ioport_map(unsigned long port, unsigned int nr);
|
||||
extern void ioport_unmap(void __iomem *);
|
||||
|
||||
/* Create a virtual mapping cookie for a PCI BAR (memory or IO) */
|
||||
struct pci_dev;
|
||||
extern void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max);
|
||||
extern void pci_iounmap(struct pci_dev *dev, void __iomem *);
|
||||
|
||||
/*
|
||||
* Bus number may be in res->flags... somewhere.
|
||||
*/
|
||||
extern void __iomem *sbus_ioremap(struct resource *res, unsigned long offset,
|
||||
unsigned long size, char *name);
|
||||
extern void sbus_iounmap(volatile void __iomem *vaddr, unsigned long size);
|
||||
|
||||
|
||||
/*
|
||||
* At the moment, we do not use CMOS_READ anywhere outside of rtc.c,
|
||||
* so rtc_port is static in it. This should not change unless a new
|
||||
* hardware pops up.
|
||||
*/
|
||||
#define RTC_PORT(x) (rtc_port + (x))
|
||||
#define RTC_ALWAYS_BCD 0
|
||||
|
||||
#ifndef ___ASM_SPARC_IO_H
|
||||
#define ___ASM_SPARC_IO_H
|
||||
#if defined(__sparc__) && defined(__arch64__)
|
||||
#include <asm-sparc/io_64.h>
|
||||
#else
|
||||
#include <asm-sparc/io_32.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define __ARCH_HAS_NO_PAGE_ZERO_MAPPED 1
|
||||
|
||||
/*
|
||||
* 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 /* !(__SPARC_IO_H) */
|
||||
|
|
325
include/asm-sparc/io_32.h
Normal file
325
include/asm-sparc/io_32.h
Normal file
|
@ -0,0 +1,325 @@
|
|||
#ifndef __SPARC_IO_H
|
||||
#define __SPARC_IO_H
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/ioport.h> /* struct resource */
|
||||
|
||||
#include <asm/page.h> /* IO address mapping routines need this */
|
||||
#include <asm/system.h>
|
||||
|
||||
#define page_to_phys(page) (((page) - mem_map) << PAGE_SHIFT)
|
||||
|
||||
static inline u32 flip_dword (u32 l)
|
||||
{
|
||||
return ((l&0xff)<<24) | (((l>>8)&0xff)<<16) | (((l>>16)&0xff)<<8)| ((l>>24)&0xff);
|
||||
}
|
||||
|
||||
static inline u16 flip_word (u16 w)
|
||||
{
|
||||
return ((w&0xff) << 8) | ((w>>8)&0xff);
|
||||
}
|
||||
|
||||
#define mmiowb()
|
||||
|
||||
/*
|
||||
* Memory mapped I/O to PCI
|
||||
*/
|
||||
|
||||
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 w, volatile void __iomem *addr)
|
||||
{
|
||||
*(__force volatile u16 *)addr = w;
|
||||
}
|
||||
|
||||
static inline void __raw_writel(u32 l, volatile void __iomem *addr)
|
||||
{
|
||||
*(__force volatile u32 *)addr = l;
|
||||
}
|
||||
|
||||
static inline u8 __readb(const volatile void __iomem *addr)
|
||||
{
|
||||
return *(__force volatile u8 *)addr;
|
||||
}
|
||||
|
||||
static inline u16 __readw(const volatile void __iomem *addr)
|
||||
{
|
||||
return flip_word(*(__force volatile u16 *)addr);
|
||||
}
|
||||
|
||||
static inline u32 __readl(const volatile void __iomem *addr)
|
||||
{
|
||||
return flip_dword(*(__force volatile u32 *)addr);
|
||||
}
|
||||
|
||||
static inline void __writeb(u8 b, volatile void __iomem *addr)
|
||||
{
|
||||
*(__force volatile u8 *)addr = b;
|
||||
}
|
||||
|
||||
static inline void __writew(u16 w, volatile void __iomem *addr)
|
||||
{
|
||||
*(__force volatile u16 *)addr = flip_word(w);
|
||||
}
|
||||
|
||||
static inline void __writel(u32 l, volatile void __iomem *addr)
|
||||
{
|
||||
*(__force volatile u32 *)addr = flip_dword(l);
|
||||
}
|
||||
|
||||
#define readb(__addr) __readb(__addr)
|
||||
#define readw(__addr) __readw(__addr)
|
||||
#define readl(__addr) __readl(__addr)
|
||||
#define readb_relaxed(__addr) readb(__addr)
|
||||
#define readw_relaxed(__addr) readw(__addr)
|
||||
#define readl_relaxed(__addr) readl(__addr)
|
||||
|
||||
#define writeb(__b, __addr) __writeb((__b),(__addr))
|
||||
#define writew(__w, __addr) __writew((__w),(__addr))
|
||||
#define writel(__l, __addr) __writel((__l),(__addr))
|
||||
|
||||
/*
|
||||
* I/O space operations
|
||||
*
|
||||
* Arrangement on a Sun is somewhat complicated.
|
||||
*
|
||||
* First of all, we want to use standard Linux drivers
|
||||
* for keyboard, PC serial, etc. These drivers think
|
||||
* they access I/O space and use inb/outb.
|
||||
* On the other hand, EBus bridge accepts PCI *memory*
|
||||
* cycles and converts them into ISA *I/O* cycles.
|
||||
* Ergo, we want inb & outb to generate PCI memory cycles.
|
||||
*
|
||||
* If we want to issue PCI *I/O* cycles, we do this
|
||||
* with a low 64K fixed window in PCIC. This window gets
|
||||
* mapped somewhere into virtual kernel space and we
|
||||
* can use inb/outb again.
|
||||
*/
|
||||
#define inb_local(__addr) __readb((void __iomem *)(unsigned long)(__addr))
|
||||
#define inb(__addr) __readb((void __iomem *)(unsigned long)(__addr))
|
||||
#define inw(__addr) __readw((void __iomem *)(unsigned long)(__addr))
|
||||
#define inl(__addr) __readl((void __iomem *)(unsigned long)(__addr))
|
||||
|
||||
#define outb_local(__b, __addr) __writeb(__b, (void __iomem *)(unsigned long)(__addr))
|
||||
#define outb(__b, __addr) __writeb(__b, (void __iomem *)(unsigned long)(__addr))
|
||||
#define outw(__w, __addr) __writew(__w, (void __iomem *)(unsigned long)(__addr))
|
||||
#define outl(__l, __addr) __writel(__l, (void __iomem *)(unsigned long)(__addr))
|
||||
|
||||
#define inb_p(__addr) inb(__addr)
|
||||
#define outb_p(__b, __addr) outb(__b, __addr)
|
||||
#define inw_p(__addr) inw(__addr)
|
||||
#define outw_p(__w, __addr) outw(__w, __addr)
|
||||
#define inl_p(__addr) inl(__addr)
|
||||
#define outl_p(__l, __addr) outl(__l, __addr)
|
||||
|
||||
void outsb(unsigned long addr, const void *src, unsigned long cnt);
|
||||
void outsw(unsigned long addr, const void *src, unsigned long cnt);
|
||||
void outsl(unsigned long addr, const void *src, unsigned long cnt);
|
||||
void insb(unsigned long addr, void *dst, unsigned long count);
|
||||
void insw(unsigned long addr, void *dst, unsigned long count);
|
||||
void insl(unsigned long addr, void *dst, unsigned long count);
|
||||
|
||||
#define IO_SPACE_LIMIT 0xffffffff
|
||||
|
||||
/*
|
||||
* SBus accessors.
|
||||
*
|
||||
* SBus has only one, memory mapped, I/O space.
|
||||
* We do not need to flip bytes for SBus of course.
|
||||
*/
|
||||
static inline u8 _sbus_readb(const volatile void __iomem *addr)
|
||||
{
|
||||
return *(__force volatile u8 *)addr;
|
||||
}
|
||||
|
||||
static inline u16 _sbus_readw(const volatile void __iomem *addr)
|
||||
{
|
||||
return *(__force volatile u16 *)addr;
|
||||
}
|
||||
|
||||
static inline u32 _sbus_readl(const volatile void __iomem *addr)
|
||||
{
|
||||
return *(__force volatile u32 *)addr;
|
||||
}
|
||||
|
||||
static inline void _sbus_writeb(u8 b, volatile void __iomem *addr)
|
||||
{
|
||||
*(__force volatile u8 *)addr = b;
|
||||
}
|
||||
|
||||
static inline void _sbus_writew(u16 w, volatile void __iomem *addr)
|
||||
{
|
||||
*(__force volatile u16 *)addr = w;
|
||||
}
|
||||
|
||||
static inline void _sbus_writel(u32 l, volatile void __iomem *addr)
|
||||
{
|
||||
*(__force volatile u32 *)addr = l;
|
||||
}
|
||||
|
||||
/*
|
||||
* The only reason for #define's is to hide casts to unsigned long.
|
||||
*/
|
||||
#define sbus_readb(__addr) _sbus_readb(__addr)
|
||||
#define sbus_readw(__addr) _sbus_readw(__addr)
|
||||
#define sbus_readl(__addr) _sbus_readl(__addr)
|
||||
#define sbus_writeb(__b, __addr) _sbus_writeb(__b, __addr)
|
||||
#define sbus_writew(__w, __addr) _sbus_writew(__w, __addr)
|
||||
#define sbus_writel(__l, __addr) _sbus_writel(__l, __addr)
|
||||
|
||||
static inline void sbus_memset_io(volatile void __iomem *__dst, int c, __kernel_size_t n)
|
||||
{
|
||||
while(n--) {
|
||||
sbus_writeb(c, __dst);
|
||||
__dst++;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
_memset_io(volatile void __iomem *dst, int c, __kernel_size_t n)
|
||||
{
|
||||
volatile void __iomem *d = dst;
|
||||
|
||||
while (n--) {
|
||||
writeb(c, d);
|
||||
d++;
|
||||
}
|
||||
}
|
||||
|
||||
#define memset_io(d,c,sz) _memset_io(d,c,sz)
|
||||
|
||||
static inline void
|
||||
_memcpy_fromio(void *dst, const volatile void __iomem *src, __kernel_size_t n)
|
||||
{
|
||||
char *d = dst;
|
||||
|
||||
while (n--) {
|
||||
char tmp = readb(src);
|
||||
*d++ = tmp;
|
||||
src++;
|
||||
}
|
||||
}
|
||||
|
||||
#define memcpy_fromio(d,s,sz) _memcpy_fromio(d,s,sz)
|
||||
|
||||
static inline void
|
||||
_memcpy_toio(volatile void __iomem *dst, const void *src, __kernel_size_t n)
|
||||
{
|
||||
const char *s = src;
|
||||
volatile void __iomem *d = dst;
|
||||
|
||||
while (n--) {
|
||||
char tmp = *s++;
|
||||
writeb(tmp, d);
|
||||
d++;
|
||||
}
|
||||
}
|
||||
|
||||
#define memcpy_toio(d,s,sz) _memcpy_toio(d,s,sz)
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
/*
|
||||
* Bus number may be embedded in the higher bits of the physical address.
|
||||
* This is why we have no bus number argument to ioremap().
|
||||
*/
|
||||
extern void __iomem *ioremap(unsigned long offset, unsigned long size);
|
||||
#define ioremap_nocache(X,Y) ioremap((X),(Y))
|
||||
extern void iounmap(volatile void __iomem *addr);
|
||||
|
||||
#define ioread8(X) readb(X)
|
||||
#define ioread16(X) readw(X)
|
||||
#define ioread32(X) readl(X)
|
||||
#define iowrite8(val,X) writeb(val,X)
|
||||
#define iowrite16(val,X) writew(val,X)
|
||||
#define iowrite32(val,X) writel(val,X)
|
||||
|
||||
static inline void ioread8_rep(void __iomem *port, void *buf, unsigned long count)
|
||||
{
|
||||
insb((unsigned long __force)port, buf, count);
|
||||
}
|
||||
static inline void ioread16_rep(void __iomem *port, void *buf, unsigned long count)
|
||||
{
|
||||
insw((unsigned long __force)port, buf, count);
|
||||
}
|
||||
|
||||
static inline void ioread32_rep(void __iomem *port, void *buf, unsigned long count)
|
||||
{
|
||||
insl((unsigned long __force)port, buf, count);
|
||||
}
|
||||
|
||||
static inline void iowrite8_rep(void __iomem *port, const void *buf, unsigned long count)
|
||||
{
|
||||
outsb((unsigned long __force)port, buf, count);
|
||||
}
|
||||
|
||||
static inline void iowrite16_rep(void __iomem *port, const void *buf, unsigned long count)
|
||||
{
|
||||
outsw((unsigned long __force)port, buf, count);
|
||||
}
|
||||
|
||||
static inline void iowrite32_rep(void __iomem *port, const void *buf, unsigned long count)
|
||||
{
|
||||
outsl((unsigned long __force)port, buf, count);
|
||||
}
|
||||
|
||||
/* Create a virtual mapping cookie for an IO port range */
|
||||
extern void __iomem *ioport_map(unsigned long port, unsigned int nr);
|
||||
extern void ioport_unmap(void __iomem *);
|
||||
|
||||
/* Create a virtual mapping cookie for a PCI BAR (memory or IO) */
|
||||
struct pci_dev;
|
||||
extern void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max);
|
||||
extern void pci_iounmap(struct pci_dev *dev, void __iomem *);
|
||||
|
||||
/*
|
||||
* Bus number may be in res->flags... somewhere.
|
||||
*/
|
||||
extern void __iomem *sbus_ioremap(struct resource *res, unsigned long offset,
|
||||
unsigned long size, char *name);
|
||||
extern void sbus_iounmap(volatile void __iomem *vaddr, unsigned long size);
|
||||
|
||||
|
||||
/*
|
||||
* At the moment, we do not use CMOS_READ anywhere outside of rtc.c,
|
||||
* so rtc_port is static in it. This should not change unless a new
|
||||
* hardware pops up.
|
||||
*/
|
||||
#define RTC_PORT(x) (rtc_port + (x))
|
||||
#define RTC_ALWAYS_BCD 0
|
||||
|
||||
#endif
|
||||
|
||||
#define __ARCH_HAS_NO_PAGE_ZERO_MAPPED 1
|
||||
|
||||
/*
|
||||
* 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 /* !(__SPARC_IO_H) */
|
511
include/asm-sparc/io_64.h
Normal file
511
include/asm-sparc/io_64.h
Normal file
|
@ -0,0 +1,511 @@
|
|||
#ifndef __SPARC64_IO_H
|
||||
#define __SPARC64_IO_H
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/compiler.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
#include <asm/page.h> /* IO address mapping routines need this */
|
||||
#include <asm/system.h>
|
||||
#include <asm/asi.h>
|
||||
|
||||
/* PC crapola... */
|
||||
#define __SLOW_DOWN_IO do { } while (0)
|
||||
#define SLOW_DOWN_IO do { } while (0)
|
||||
|
||||
/* BIO layer definitions. */
|
||||
extern unsigned long kern_base, kern_size;
|
||||
#define page_to_phys(page) (page_to_pfn(page) << PAGE_SHIFT)
|
||||
#define BIO_VMERGE_BOUNDARY 8192
|
||||
|
||||
static inline u8 _inb(unsigned long addr)
|
||||
{
|
||||
u8 ret;
|
||||
|
||||
__asm__ __volatile__("lduba\t[%1] %2, %0\t/* pci_inb */"
|
||||
: "=r" (ret)
|
||||
: "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)
|
||||
: "memory");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline u16 _inw(unsigned long addr)
|
||||
{
|
||||
u16 ret;
|
||||
|
||||
__asm__ __volatile__("lduha\t[%1] %2, %0\t/* pci_inw */"
|
||||
: "=r" (ret)
|
||||
: "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)
|
||||
: "memory");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline u32 _inl(unsigned long addr)
|
||||
{
|
||||
u32 ret;
|
||||
|
||||
__asm__ __volatile__("lduwa\t[%1] %2, %0\t/* pci_inl */"
|
||||
: "=r" (ret)
|
||||
: "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)
|
||||
: "memory");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline void _outb(u8 b, unsigned long addr)
|
||||
{
|
||||
__asm__ __volatile__("stba\t%r0, [%1] %2\t/* pci_outb */"
|
||||
: /* no outputs */
|
||||
: "Jr" (b), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)
|
||||
: "memory");
|
||||
}
|
||||
|
||||
static inline void _outw(u16 w, unsigned long addr)
|
||||
{
|
||||
__asm__ __volatile__("stha\t%r0, [%1] %2\t/* pci_outw */"
|
||||
: /* no outputs */
|
||||
: "Jr" (w), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)
|
||||
: "memory");
|
||||
}
|
||||
|
||||
static inline void _outl(u32 l, unsigned long addr)
|
||||
{
|
||||
__asm__ __volatile__("stwa\t%r0, [%1] %2\t/* pci_outl */"
|
||||
: /* no outputs */
|
||||
: "Jr" (l), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)
|
||||
: "memory");
|
||||
}
|
||||
|
||||
#define inb(__addr) (_inb((unsigned long)(__addr)))
|
||||
#define inw(__addr) (_inw((unsigned long)(__addr)))
|
||||
#define inl(__addr) (_inl((unsigned long)(__addr)))
|
||||
#define outb(__b, __addr) (_outb((u8)(__b), (unsigned long)(__addr)))
|
||||
#define outw(__w, __addr) (_outw((u16)(__w), (unsigned long)(__addr)))
|
||||
#define outl(__l, __addr) (_outl((u32)(__l), (unsigned long)(__addr)))
|
||||
|
||||
#define inb_p(__addr) inb(__addr)
|
||||
#define outb_p(__b, __addr) outb(__b, __addr)
|
||||
#define inw_p(__addr) inw(__addr)
|
||||
#define outw_p(__w, __addr) outw(__w, __addr)
|
||||
#define inl_p(__addr) inl(__addr)
|
||||
#define outl_p(__l, __addr) outl(__l, __addr)
|
||||
|
||||
extern void outsb(unsigned long, const void *, unsigned long);
|
||||
extern void outsw(unsigned long, const void *, unsigned long);
|
||||
extern void outsl(unsigned long, const void *, unsigned long);
|
||||
extern void insb(unsigned long, void *, unsigned long);
|
||||
extern void insw(unsigned long, void *, unsigned long);
|
||||
extern void insl(unsigned long, void *, unsigned long);
|
||||
|
||||
static inline void ioread8_rep(void __iomem *port, void *buf, unsigned long count)
|
||||
{
|
||||
insb((unsigned long __force)port, buf, count);
|
||||
}
|
||||
static inline void ioread16_rep(void __iomem *port, void *buf, unsigned long count)
|
||||
{
|
||||
insw((unsigned long __force)port, buf, count);
|
||||
}
|
||||
|
||||
static inline void ioread32_rep(void __iomem *port, void *buf, unsigned long count)
|
||||
{
|
||||
insl((unsigned long __force)port, buf, count);
|
||||
}
|
||||
|
||||
static inline void iowrite8_rep(void __iomem *port, const void *buf, unsigned long count)
|
||||
{
|
||||
outsb((unsigned long __force)port, buf, count);
|
||||
}
|
||||
|
||||
static inline void iowrite16_rep(void __iomem *port, const void *buf, unsigned long count)
|
||||
{
|
||||
outsw((unsigned long __force)port, buf, count);
|
||||
}
|
||||
|
||||
static inline void iowrite32_rep(void __iomem *port, const void *buf, unsigned long count)
|
||||
{
|
||||
outsl((unsigned long __force)port, buf, count);
|
||||
}
|
||||
|
||||
/* Memory functions, same as I/O accesses on Ultra. */
|
||||
static inline u8 _readb(const volatile void __iomem *addr)
|
||||
{ u8 ret;
|
||||
|
||||
__asm__ __volatile__("lduba\t[%1] %2, %0\t/* pci_readb */"
|
||||
: "=r" (ret)
|
||||
: "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)
|
||||
: "memory");
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline u16 _readw(const volatile void __iomem *addr)
|
||||
{ u16 ret;
|
||||
|
||||
__asm__ __volatile__("lduha\t[%1] %2, %0\t/* pci_readw */"
|
||||
: "=r" (ret)
|
||||
: "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)
|
||||
: "memory");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline u32 _readl(const volatile void __iomem *addr)
|
||||
{ u32 ret;
|
||||
|
||||
__asm__ __volatile__("lduwa\t[%1] %2, %0\t/* pci_readl */"
|
||||
: "=r" (ret)
|
||||
: "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)
|
||||
: "memory");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline u64 _readq(const volatile void __iomem *addr)
|
||||
{ u64 ret;
|
||||
|
||||
__asm__ __volatile__("ldxa\t[%1] %2, %0\t/* pci_readq */"
|
||||
: "=r" (ret)
|
||||
: "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)
|
||||
: "memory");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline void _writeb(u8 b, volatile void __iomem *addr)
|
||||
{
|
||||
__asm__ __volatile__("stba\t%r0, [%1] %2\t/* pci_writeb */"
|
||||
: /* no outputs */
|
||||
: "Jr" (b), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)
|
||||
: "memory");
|
||||
}
|
||||
|
||||
static inline void _writew(u16 w, volatile void __iomem *addr)
|
||||
{
|
||||
__asm__ __volatile__("stha\t%r0, [%1] %2\t/* pci_writew */"
|
||||
: /* no outputs */
|
||||
: "Jr" (w), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)
|
||||
: "memory");
|
||||
}
|
||||
|
||||
static inline void _writel(u32 l, volatile void __iomem *addr)
|
||||
{
|
||||
__asm__ __volatile__("stwa\t%r0, [%1] %2\t/* pci_writel */"
|
||||
: /* no outputs */
|
||||
: "Jr" (l), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)
|
||||
: "memory");
|
||||
}
|
||||
|
||||
static inline void _writeq(u64 q, volatile void __iomem *addr)
|
||||
{
|
||||
__asm__ __volatile__("stxa\t%r0, [%1] %2\t/* pci_writeq */"
|
||||
: /* no outputs */
|
||||
: "Jr" (q), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)
|
||||
: "memory");
|
||||
}
|
||||
|
||||
#define readb(__addr) _readb(__addr)
|
||||
#define readw(__addr) _readw(__addr)
|
||||
#define readl(__addr) _readl(__addr)
|
||||
#define readq(__addr) _readq(__addr)
|
||||
#define readb_relaxed(__addr) _readb(__addr)
|
||||
#define readw_relaxed(__addr) _readw(__addr)
|
||||
#define readl_relaxed(__addr) _readl(__addr)
|
||||
#define readq_relaxed(__addr) _readq(__addr)
|
||||
#define writeb(__b, __addr) _writeb(__b, __addr)
|
||||
#define writew(__w, __addr) _writew(__w, __addr)
|
||||
#define writel(__l, __addr) _writel(__l, __addr)
|
||||
#define writeq(__q, __addr) _writeq(__q, __addr)
|
||||
|
||||
/* Now versions without byte-swapping. */
|
||||
static inline u8 _raw_readb(unsigned long addr)
|
||||
{
|
||||
u8 ret;
|
||||
|
||||
__asm__ __volatile__("lduba\t[%1] %2, %0\t/* pci_raw_readb */"
|
||||
: "=r" (ret)
|
||||
: "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline u16 _raw_readw(unsigned long addr)
|
||||
{
|
||||
u16 ret;
|
||||
|
||||
__asm__ __volatile__("lduha\t[%1] %2, %0\t/* pci_raw_readw */"
|
||||
: "=r" (ret)
|
||||
: "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline u32 _raw_readl(unsigned long addr)
|
||||
{
|
||||
u32 ret;
|
||||
|
||||
__asm__ __volatile__("lduwa\t[%1] %2, %0\t/* pci_raw_readl */"
|
||||
: "=r" (ret)
|
||||
: "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline u64 _raw_readq(unsigned long addr)
|
||||
{
|
||||
u64 ret;
|
||||
|
||||
__asm__ __volatile__("ldxa\t[%1] %2, %0\t/* pci_raw_readq */"
|
||||
: "=r" (ret)
|
||||
: "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline void _raw_writeb(u8 b, unsigned long addr)
|
||||
{
|
||||
__asm__ __volatile__("stba\t%r0, [%1] %2\t/* pci_raw_writeb */"
|
||||
: /* no outputs */
|
||||
: "Jr" (b), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
|
||||
}
|
||||
|
||||
static inline void _raw_writew(u16 w, unsigned long addr)
|
||||
{
|
||||
__asm__ __volatile__("stha\t%r0, [%1] %2\t/* pci_raw_writew */"
|
||||
: /* no outputs */
|
||||
: "Jr" (w), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
|
||||
}
|
||||
|
||||
static inline void _raw_writel(u32 l, unsigned long addr)
|
||||
{
|
||||
__asm__ __volatile__("stwa\t%r0, [%1] %2\t/* pci_raw_writel */"
|
||||
: /* no outputs */
|
||||
: "Jr" (l), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
|
||||
}
|
||||
|
||||
static inline void _raw_writeq(u64 q, unsigned long addr)
|
||||
{
|
||||
__asm__ __volatile__("stxa\t%r0, [%1] %2\t/* pci_raw_writeq */"
|
||||
: /* no outputs */
|
||||
: "Jr" (q), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
|
||||
}
|
||||
|
||||
#define __raw_readb(__addr) (_raw_readb((unsigned long)(__addr)))
|
||||
#define __raw_readw(__addr) (_raw_readw((unsigned long)(__addr)))
|
||||
#define __raw_readl(__addr) (_raw_readl((unsigned long)(__addr)))
|
||||
#define __raw_readq(__addr) (_raw_readq((unsigned long)(__addr)))
|
||||
#define __raw_writeb(__b, __addr) (_raw_writeb((u8)(__b), (unsigned long)(__addr)))
|
||||
#define __raw_writew(__w, __addr) (_raw_writew((u16)(__w), (unsigned long)(__addr)))
|
||||
#define __raw_writel(__l, __addr) (_raw_writel((u32)(__l), (unsigned long)(__addr)))
|
||||
#define __raw_writeq(__q, __addr) (_raw_writeq((u64)(__q), (unsigned long)(__addr)))
|
||||
|
||||
/* Valid I/O Space regions are anywhere, because each PCI bus supported
|
||||
* can live in an arbitrary area of the physical address range.
|
||||
*/
|
||||
#define IO_SPACE_LIMIT 0xffffffffffffffffUL
|
||||
|
||||
/* Now, SBUS variants, only difference from PCI is that we do
|
||||
* not use little-endian ASIs.
|
||||
*/
|
||||
static inline u8 _sbus_readb(const volatile void __iomem *addr)
|
||||
{
|
||||
u8 ret;
|
||||
|
||||
__asm__ __volatile__("lduba\t[%1] %2, %0\t/* sbus_readb */"
|
||||
: "=r" (ret)
|
||||
: "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)
|
||||
: "memory");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline u16 _sbus_readw(const volatile void __iomem *addr)
|
||||
{
|
||||
u16 ret;
|
||||
|
||||
__asm__ __volatile__("lduha\t[%1] %2, %0\t/* sbus_readw */"
|
||||
: "=r" (ret)
|
||||
: "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)
|
||||
: "memory");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline u32 _sbus_readl(const volatile void __iomem *addr)
|
||||
{
|
||||
u32 ret;
|
||||
|
||||
__asm__ __volatile__("lduwa\t[%1] %2, %0\t/* sbus_readl */"
|
||||
: "=r" (ret)
|
||||
: "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)
|
||||
: "memory");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline u64 _sbus_readq(const volatile void __iomem *addr)
|
||||
{
|
||||
u64 ret;
|
||||
|
||||
__asm__ __volatile__("ldxa\t[%1] %2, %0\t/* sbus_readq */"
|
||||
: "=r" (ret)
|
||||
: "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)
|
||||
: "memory");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline void _sbus_writeb(u8 b, volatile void __iomem *addr)
|
||||
{
|
||||
__asm__ __volatile__("stba\t%r0, [%1] %2\t/* sbus_writeb */"
|
||||
: /* no outputs */
|
||||
: "Jr" (b), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)
|
||||
: "memory");
|
||||
}
|
||||
|
||||
static inline void _sbus_writew(u16 w, volatile void __iomem *addr)
|
||||
{
|
||||
__asm__ __volatile__("stha\t%r0, [%1] %2\t/* sbus_writew */"
|
||||
: /* no outputs */
|
||||
: "Jr" (w), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)
|
||||
: "memory");
|
||||
}
|
||||
|
||||
static inline void _sbus_writel(u32 l, volatile void __iomem *addr)
|
||||
{
|
||||
__asm__ __volatile__("stwa\t%r0, [%1] %2\t/* sbus_writel */"
|
||||
: /* no outputs */
|
||||
: "Jr" (l), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)
|
||||
: "memory");
|
||||
}
|
||||
|
||||
static inline void _sbus_writeq(u64 l, volatile void __iomem *addr)
|
||||
{
|
||||
__asm__ __volatile__("stxa\t%r0, [%1] %2\t/* sbus_writeq */"
|
||||
: /* no outputs */
|
||||
: "Jr" (l), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)
|
||||
: "memory");
|
||||
}
|
||||
|
||||
#define sbus_readb(__addr) _sbus_readb(__addr)
|
||||
#define sbus_readw(__addr) _sbus_readw(__addr)
|
||||
#define sbus_readl(__addr) _sbus_readl(__addr)
|
||||
#define sbus_readq(__addr) _sbus_readq(__addr)
|
||||
#define sbus_writeb(__b, __addr) _sbus_writeb(__b, __addr)
|
||||
#define sbus_writew(__w, __addr) _sbus_writew(__w, __addr)
|
||||
#define sbus_writel(__l, __addr) _sbus_writel(__l, __addr)
|
||||
#define sbus_writeq(__l, __addr) _sbus_writeq(__l, __addr)
|
||||
|
||||
static inline void _sbus_memset_io(volatile void __iomem *dst, int c, __kernel_size_t n)
|
||||
{
|
||||
while(n--) {
|
||||
sbus_writeb(c, dst);
|
||||
dst++;
|
||||
}
|
||||
}
|
||||
|
||||
#define sbus_memset_io(d,c,sz) _sbus_memset_io(d,c,sz)
|
||||
|
||||
static inline void
|
||||
_memset_io(volatile void __iomem *dst, int c, __kernel_size_t n)
|
||||
{
|
||||
volatile void __iomem *d = dst;
|
||||
|
||||
while (n--) {
|
||||
writeb(c, d);
|
||||
d++;
|
||||
}
|
||||
}
|
||||
|
||||
#define memset_io(d,c,sz) _memset_io(d,c,sz)
|
||||
|
||||
static inline void
|
||||
_memcpy_fromio(void *dst, const volatile void __iomem *src, __kernel_size_t n)
|
||||
{
|
||||
char *d = dst;
|
||||
|
||||
while (n--) {
|
||||
char tmp = readb(src);
|
||||
*d++ = tmp;
|
||||
src++;
|
||||
}
|
||||
}
|
||||
|
||||
#define memcpy_fromio(d,s,sz) _memcpy_fromio(d,s,sz)
|
||||
|
||||
static inline void
|
||||
_memcpy_toio(volatile void __iomem *dst, const void *src, __kernel_size_t n)
|
||||
{
|
||||
const char *s = src;
|
||||
volatile void __iomem *d = dst;
|
||||
|
||||
while (n--) {
|
||||
char tmp = *s++;
|
||||
writeb(tmp, d);
|
||||
d++;
|
||||
}
|
||||
}
|
||||
|
||||
#define memcpy_toio(d,s,sz) _memcpy_toio(d,s,sz)
|
||||
|
||||
#define mmiowb()
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
/* On sparc64 we have the whole physical IO address space accessible
|
||||
* using physically addressed loads and stores, so this does nothing.
|
||||
*/
|
||||
static inline void __iomem *ioremap(unsigned long offset, unsigned long size)
|
||||
{
|
||||
return (void __iomem *)offset;
|
||||
}
|
||||
|
||||
#define ioremap_nocache(X,Y) ioremap((X),(Y))
|
||||
|
||||
static inline void iounmap(volatile void __iomem *addr)
|
||||
{
|
||||
}
|
||||
|
||||
#define ioread8(X) readb(X)
|
||||
#define ioread16(X) readw(X)
|
||||
#define ioread32(X) readl(X)
|
||||
#define iowrite8(val,X) writeb(val,X)
|
||||
#define iowrite16(val,X) writew(val,X)
|
||||
#define iowrite32(val,X) writel(val,X)
|
||||
|
||||
/* Create a virtual mapping cookie for an IO port range */
|
||||
extern void __iomem *ioport_map(unsigned long port, unsigned int nr);
|
||||
extern void ioport_unmap(void __iomem *);
|
||||
|
||||
/* Create a virtual mapping cookie for a PCI BAR (memory or IO) */
|
||||
struct pci_dev;
|
||||
extern void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max);
|
||||
extern void pci_iounmap(struct pci_dev *dev, void __iomem *);
|
||||
|
||||
/* Similarly for SBUS. */
|
||||
#define sbus_ioremap(__res, __offset, __size, __name) \
|
||||
({ unsigned long __ret; \
|
||||
__ret = (__res)->start + (((__res)->flags & 0x1ffUL) << 32UL); \
|
||||
__ret += (unsigned long) (__offset); \
|
||||
if (! request_region((__ret), (__size), (__name))) \
|
||||
__ret = 0UL; \
|
||||
(void __iomem *) __ret; \
|
||||
})
|
||||
|
||||
#define sbus_iounmap(__addr, __size) \
|
||||
release_region((unsigned long)(__addr), (__size))
|
||||
|
||||
/*
|
||||
* 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
|
||||
|
||||
#endif /* !(__SPARC64_IO_H) */
|
|
@ -1,121 +1,8 @@
|
|||
/* iommu.h: Definitions for the sun4m IOMMU.
|
||||
*
|
||||
* Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
|
||||
*/
|
||||
#ifndef _SPARC_IOMMU_H
|
||||
#define _SPARC_IOMMU_H
|
||||
|
||||
#include <asm/page.h>
|
||||
#include <asm/bitext.h>
|
||||
|
||||
/* The iommu handles all virtual to physical address translations
|
||||
* that occur between the SBUS and physical memory. Access by
|
||||
* the cpu to IO registers and similar go over the mbus so are
|
||||
* translated by the on chip SRMMU. The iommu and the srmmu do
|
||||
* not need to have the same translations at all, in fact most
|
||||
* of the time the translations they handle are a disjunct set.
|
||||
* Basically the iommu handles all dvma sbus activity.
|
||||
*/
|
||||
|
||||
/* The IOMMU registers occupy three pages in IO space. */
|
||||
struct iommu_regs {
|
||||
/* First page */
|
||||
volatile unsigned long control; /* IOMMU control */
|
||||
volatile unsigned long base; /* Physical base of iopte page table */
|
||||
volatile unsigned long _unused1[3];
|
||||
volatile unsigned long tlbflush; /* write only */
|
||||
volatile unsigned long pageflush; /* write only */
|
||||
volatile unsigned long _unused2[1017];
|
||||
/* Second page */
|
||||
volatile unsigned long afsr; /* Async-fault status register */
|
||||
volatile unsigned long afar; /* Async-fault physical address */
|
||||
volatile unsigned long _unused3[2];
|
||||
volatile unsigned long sbuscfg0; /* SBUS configuration registers, per-slot */
|
||||
volatile unsigned long sbuscfg1;
|
||||
volatile unsigned long sbuscfg2;
|
||||
volatile unsigned long sbuscfg3;
|
||||
volatile unsigned long mfsr; /* Memory-fault status register */
|
||||
volatile unsigned long mfar; /* Memory-fault physical address */
|
||||
volatile unsigned long _unused4[1014];
|
||||
/* Third page */
|
||||
volatile unsigned long mid; /* IOMMU module-id */
|
||||
};
|
||||
|
||||
#define IOMMU_CTRL_IMPL 0xf0000000 /* Implementation */
|
||||
#define IOMMU_CTRL_VERS 0x0f000000 /* Version */
|
||||
#define IOMMU_CTRL_RNGE 0x0000001c /* Mapping RANGE */
|
||||
#define IOMMU_RNGE_16MB 0x00000000 /* 0xff000000 -> 0xffffffff */
|
||||
#define IOMMU_RNGE_32MB 0x00000004 /* 0xfe000000 -> 0xffffffff */
|
||||
#define IOMMU_RNGE_64MB 0x00000008 /* 0xfc000000 -> 0xffffffff */
|
||||
#define IOMMU_RNGE_128MB 0x0000000c /* 0xf8000000 -> 0xffffffff */
|
||||
#define IOMMU_RNGE_256MB 0x00000010 /* 0xf0000000 -> 0xffffffff */
|
||||
#define IOMMU_RNGE_512MB 0x00000014 /* 0xe0000000 -> 0xffffffff */
|
||||
#define IOMMU_RNGE_1GB 0x00000018 /* 0xc0000000 -> 0xffffffff */
|
||||
#define IOMMU_RNGE_2GB 0x0000001c /* 0x80000000 -> 0xffffffff */
|
||||
#define IOMMU_CTRL_ENAB 0x00000001 /* IOMMU Enable */
|
||||
|
||||
#define IOMMU_AFSR_ERR 0x80000000 /* LE, TO, or BE asserted */
|
||||
#define IOMMU_AFSR_LE 0x40000000 /* SBUS reports error after transaction */
|
||||
#define IOMMU_AFSR_TO 0x20000000 /* Write access took more than 12.8 us. */
|
||||
#define IOMMU_AFSR_BE 0x10000000 /* Write access received error acknowledge */
|
||||
#define IOMMU_AFSR_SIZE 0x0e000000 /* Size of transaction causing error */
|
||||
#define IOMMU_AFSR_S 0x01000000 /* Sparc was in supervisor mode */
|
||||
#define IOMMU_AFSR_RESV 0x00f00000 /* Reserver, forced to 0x8 by hardware */
|
||||
#define IOMMU_AFSR_ME 0x00080000 /* Multiple errors occurred */
|
||||
#define IOMMU_AFSR_RD 0x00040000 /* A read operation was in progress */
|
||||
#define IOMMU_AFSR_FAV 0x00020000 /* IOMMU afar has valid contents */
|
||||
|
||||
#define IOMMU_SBCFG_SAB30 0x00010000 /* Phys-address bit 30 when bypass enabled */
|
||||
#define IOMMU_SBCFG_BA16 0x00000004 /* Slave supports 16 byte bursts */
|
||||
#define IOMMU_SBCFG_BA8 0x00000002 /* Slave supports 8 byte bursts */
|
||||
#define IOMMU_SBCFG_BYPASS 0x00000001 /* Bypass IOMMU, treat all addresses
|
||||
produced by this device as pure
|
||||
physical. */
|
||||
|
||||
#define IOMMU_MFSR_ERR 0x80000000 /* One or more of PERR1 or PERR0 */
|
||||
#define IOMMU_MFSR_S 0x01000000 /* Sparc was in supervisor mode */
|
||||
#define IOMMU_MFSR_CPU 0x00800000 /* CPU transaction caused parity error */
|
||||
#define IOMMU_MFSR_ME 0x00080000 /* Multiple parity errors occurred */
|
||||
#define IOMMU_MFSR_PERR 0x00006000 /* high bit indicates parity error occurred
|
||||
on the even word of the access, low bit
|
||||
indicated odd word caused the parity error */
|
||||
#define IOMMU_MFSR_BM 0x00001000 /* Error occurred while in boot mode */
|
||||
#define IOMMU_MFSR_C 0x00000800 /* Address causing error was marked cacheable */
|
||||
#define IOMMU_MFSR_RTYP 0x000000f0 /* Memory request transaction type */
|
||||
|
||||
#define IOMMU_MID_SBAE 0x001f0000 /* SBus arbitration enable */
|
||||
#define IOMMU_MID_SE 0x00100000 /* Enables SCSI/ETHERNET arbitration */
|
||||
#define IOMMU_MID_SB3 0x00080000 /* Enable SBUS device 3 arbitration */
|
||||
#define IOMMU_MID_SB2 0x00040000 /* Enable SBUS device 2 arbitration */
|
||||
#define IOMMU_MID_SB1 0x00020000 /* Enable SBUS device 1 arbitration */
|
||||
#define IOMMU_MID_SB0 0x00010000 /* Enable SBUS device 0 arbitration */
|
||||
#define IOMMU_MID_MID 0x0000000f /* Module-id, hardcoded to 0x8 */
|
||||
|
||||
/* The format of an iopte in the page tables */
|
||||
#define IOPTE_PAGE 0x07ffff00 /* Physical page number (PA[30:12]) */
|
||||
#define IOPTE_CACHE 0x00000080 /* Cached (in vme IOCACHE or Viking/MXCC) */
|
||||
#define IOPTE_WRITE 0x00000004 /* Writeable */
|
||||
#define IOPTE_VALID 0x00000002 /* IOPTE is valid */
|
||||
#define IOPTE_WAZ 0x00000001 /* Write as zeros */
|
||||
|
||||
struct iommu_struct {
|
||||
struct iommu_regs *regs;
|
||||
iopte_t *page_table;
|
||||
/* For convenience */
|
||||
unsigned long start; /* First managed virtual address */
|
||||
unsigned long end; /* Last managed virtual address */
|
||||
|
||||
struct bit_map usemap;
|
||||
};
|
||||
|
||||
static inline void iommu_invalidate(struct iommu_regs *regs)
|
||||
{
|
||||
regs->tlbflush = 0;
|
||||
}
|
||||
|
||||
static inline void iommu_invalidate_page(struct iommu_regs *regs, unsigned long ba)
|
||||
{
|
||||
regs->pageflush = (ba & PAGE_MASK);
|
||||
}
|
||||
|
||||
#endif /* !(_SPARC_IOMMU_H) */
|
||||
#ifndef ___ASM_SPARC_IOMMU_H
|
||||
#define ___ASM_SPARC_IOMMU_H
|
||||
#if defined(__sparc__) && defined(__arch64__)
|
||||
#include <asm-sparc/iommu_64.h>
|
||||
#else
|
||||
#include <asm-sparc/iommu_32.h>
|
||||
#endif
|
||||
#endif
|
||||
|
|
121
include/asm-sparc/iommu_32.h
Normal file
121
include/asm-sparc/iommu_32.h
Normal file
|
@ -0,0 +1,121 @@
|
|||
/* iommu.h: Definitions for the sun4m IOMMU.
|
||||
*
|
||||
* Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
|
||||
*/
|
||||
#ifndef _SPARC_IOMMU_H
|
||||
#define _SPARC_IOMMU_H
|
||||
|
||||
#include <asm/page.h>
|
||||
#include <asm/bitext.h>
|
||||
|
||||
/* The iommu handles all virtual to physical address translations
|
||||
* that occur between the SBUS and physical memory. Access by
|
||||
* the cpu to IO registers and similar go over the mbus so are
|
||||
* translated by the on chip SRMMU. The iommu and the srmmu do
|
||||
* not need to have the same translations at all, in fact most
|
||||
* of the time the translations they handle are a disjunct set.
|
||||
* Basically the iommu handles all dvma sbus activity.
|
||||
*/
|
||||
|
||||
/* The IOMMU registers occupy three pages in IO space. */
|
||||
struct iommu_regs {
|
||||
/* First page */
|
||||
volatile unsigned long control; /* IOMMU control */
|
||||
volatile unsigned long base; /* Physical base of iopte page table */
|
||||
volatile unsigned long _unused1[3];
|
||||
volatile unsigned long tlbflush; /* write only */
|
||||
volatile unsigned long pageflush; /* write only */
|
||||
volatile unsigned long _unused2[1017];
|
||||
/* Second page */
|
||||
volatile unsigned long afsr; /* Async-fault status register */
|
||||
volatile unsigned long afar; /* Async-fault physical address */
|
||||
volatile unsigned long _unused3[2];
|
||||
volatile unsigned long sbuscfg0; /* SBUS configuration registers, per-slot */
|
||||
volatile unsigned long sbuscfg1;
|
||||
volatile unsigned long sbuscfg2;
|
||||
volatile unsigned long sbuscfg3;
|
||||
volatile unsigned long mfsr; /* Memory-fault status register */
|
||||
volatile unsigned long mfar; /* Memory-fault physical address */
|
||||
volatile unsigned long _unused4[1014];
|
||||
/* Third page */
|
||||
volatile unsigned long mid; /* IOMMU module-id */
|
||||
};
|
||||
|
||||
#define IOMMU_CTRL_IMPL 0xf0000000 /* Implementation */
|
||||
#define IOMMU_CTRL_VERS 0x0f000000 /* Version */
|
||||
#define IOMMU_CTRL_RNGE 0x0000001c /* Mapping RANGE */
|
||||
#define IOMMU_RNGE_16MB 0x00000000 /* 0xff000000 -> 0xffffffff */
|
||||
#define IOMMU_RNGE_32MB 0x00000004 /* 0xfe000000 -> 0xffffffff */
|
||||
#define IOMMU_RNGE_64MB 0x00000008 /* 0xfc000000 -> 0xffffffff */
|
||||
#define IOMMU_RNGE_128MB 0x0000000c /* 0xf8000000 -> 0xffffffff */
|
||||
#define IOMMU_RNGE_256MB 0x00000010 /* 0xf0000000 -> 0xffffffff */
|
||||
#define IOMMU_RNGE_512MB 0x00000014 /* 0xe0000000 -> 0xffffffff */
|
||||
#define IOMMU_RNGE_1GB 0x00000018 /* 0xc0000000 -> 0xffffffff */
|
||||
#define IOMMU_RNGE_2GB 0x0000001c /* 0x80000000 -> 0xffffffff */
|
||||
#define IOMMU_CTRL_ENAB 0x00000001 /* IOMMU Enable */
|
||||
|
||||
#define IOMMU_AFSR_ERR 0x80000000 /* LE, TO, or BE asserted */
|
||||
#define IOMMU_AFSR_LE 0x40000000 /* SBUS reports error after transaction */
|
||||
#define IOMMU_AFSR_TO 0x20000000 /* Write access took more than 12.8 us. */
|
||||
#define IOMMU_AFSR_BE 0x10000000 /* Write access received error acknowledge */
|
||||
#define IOMMU_AFSR_SIZE 0x0e000000 /* Size of transaction causing error */
|
||||
#define IOMMU_AFSR_S 0x01000000 /* Sparc was in supervisor mode */
|
||||
#define IOMMU_AFSR_RESV 0x00f00000 /* Reserver, forced to 0x8 by hardware */
|
||||
#define IOMMU_AFSR_ME 0x00080000 /* Multiple errors occurred */
|
||||
#define IOMMU_AFSR_RD 0x00040000 /* A read operation was in progress */
|
||||
#define IOMMU_AFSR_FAV 0x00020000 /* IOMMU afar has valid contents */
|
||||
|
||||
#define IOMMU_SBCFG_SAB30 0x00010000 /* Phys-address bit 30 when bypass enabled */
|
||||
#define IOMMU_SBCFG_BA16 0x00000004 /* Slave supports 16 byte bursts */
|
||||
#define IOMMU_SBCFG_BA8 0x00000002 /* Slave supports 8 byte bursts */
|
||||
#define IOMMU_SBCFG_BYPASS 0x00000001 /* Bypass IOMMU, treat all addresses
|
||||
produced by this device as pure
|
||||
physical. */
|
||||
|
||||
#define IOMMU_MFSR_ERR 0x80000000 /* One or more of PERR1 or PERR0 */
|
||||
#define IOMMU_MFSR_S 0x01000000 /* Sparc was in supervisor mode */
|
||||
#define IOMMU_MFSR_CPU 0x00800000 /* CPU transaction caused parity error */
|
||||
#define IOMMU_MFSR_ME 0x00080000 /* Multiple parity errors occurred */
|
||||
#define IOMMU_MFSR_PERR 0x00006000 /* high bit indicates parity error occurred
|
||||
on the even word of the access, low bit
|
||||
indicated odd word caused the parity error */
|
||||
#define IOMMU_MFSR_BM 0x00001000 /* Error occurred while in boot mode */
|
||||
#define IOMMU_MFSR_C 0x00000800 /* Address causing error was marked cacheable */
|
||||
#define IOMMU_MFSR_RTYP 0x000000f0 /* Memory request transaction type */
|
||||
|
||||
#define IOMMU_MID_SBAE 0x001f0000 /* SBus arbitration enable */
|
||||
#define IOMMU_MID_SE 0x00100000 /* Enables SCSI/ETHERNET arbitration */
|
||||
#define IOMMU_MID_SB3 0x00080000 /* Enable SBUS device 3 arbitration */
|
||||
#define IOMMU_MID_SB2 0x00040000 /* Enable SBUS device 2 arbitration */
|
||||
#define IOMMU_MID_SB1 0x00020000 /* Enable SBUS device 1 arbitration */
|
||||
#define IOMMU_MID_SB0 0x00010000 /* Enable SBUS device 0 arbitration */
|
||||
#define IOMMU_MID_MID 0x0000000f /* Module-id, hardcoded to 0x8 */
|
||||
|
||||
/* The format of an iopte in the page tables */
|
||||
#define IOPTE_PAGE 0x07ffff00 /* Physical page number (PA[30:12]) */
|
||||
#define IOPTE_CACHE 0x00000080 /* Cached (in vme IOCACHE or Viking/MXCC) */
|
||||
#define IOPTE_WRITE 0x00000004 /* Writeable */
|
||||
#define IOPTE_VALID 0x00000002 /* IOPTE is valid */
|
||||
#define IOPTE_WAZ 0x00000001 /* Write as zeros */
|
||||
|
||||
struct iommu_struct {
|
||||
struct iommu_regs *regs;
|
||||
iopte_t *page_table;
|
||||
/* For convenience */
|
||||
unsigned long start; /* First managed virtual address */
|
||||
unsigned long end; /* Last managed virtual address */
|
||||
|
||||
struct bit_map usemap;
|
||||
};
|
||||
|
||||
static inline void iommu_invalidate(struct iommu_regs *regs)
|
||||
{
|
||||
regs->tlbflush = 0;
|
||||
}
|
||||
|
||||
static inline void iommu_invalidate_page(struct iommu_regs *regs, unsigned long ba)
|
||||
{
|
||||
regs->pageflush = (ba & PAGE_MASK);
|
||||
}
|
||||
|
||||
#endif /* !(_SPARC_IOMMU_H) */
|
62
include/asm-sparc/iommu_64.h
Normal file
62
include/asm-sparc/iommu_64.h
Normal file
|
@ -0,0 +1,62 @@
|
|||
/* iommu.h: Definitions for the sun5 IOMMU.
|
||||
*
|
||||
* Copyright (C) 1996, 1999, 2007 David S. Miller (davem@davemloft.net)
|
||||
*/
|
||||
#ifndef _SPARC64_IOMMU_H
|
||||
#define _SPARC64_IOMMU_H
|
||||
|
||||
/* The format of an iopte in the page tables. */
|
||||
#define IOPTE_VALID 0x8000000000000000UL
|
||||
#define IOPTE_64K 0x2000000000000000UL
|
||||
#define IOPTE_STBUF 0x1000000000000000UL
|
||||
#define IOPTE_INTRA 0x0800000000000000UL
|
||||
#define IOPTE_CONTEXT 0x07ff800000000000UL
|
||||
#define IOPTE_PAGE 0x00007fffffffe000UL
|
||||
#define IOPTE_CACHE 0x0000000000000010UL
|
||||
#define IOPTE_WRITE 0x0000000000000002UL
|
||||
|
||||
#define IOMMU_NUM_CTXS 4096
|
||||
|
||||
struct iommu_arena {
|
||||
unsigned long *map;
|
||||
unsigned int hint;
|
||||
unsigned int limit;
|
||||
};
|
||||
|
||||
struct iommu {
|
||||
spinlock_t lock;
|
||||
struct iommu_arena arena;
|
||||
void (*flush_all)(struct iommu *);
|
||||
iopte_t *page_table;
|
||||
u32 page_table_map_base;
|
||||
unsigned long iommu_control;
|
||||
unsigned long iommu_tsbbase;
|
||||
unsigned long iommu_flush;
|
||||
unsigned long iommu_flushinv;
|
||||
unsigned long iommu_tags;
|
||||
unsigned long iommu_ctxflush;
|
||||
unsigned long write_complete_reg;
|
||||
unsigned long dummy_page;
|
||||
unsigned long dummy_page_pa;
|
||||
unsigned long ctx_lowest_free;
|
||||
DECLARE_BITMAP(ctx_bitmap, IOMMU_NUM_CTXS);
|
||||
u32 dma_addr_mask;
|
||||
};
|
||||
|
||||
struct strbuf {
|
||||
int strbuf_enabled;
|
||||
unsigned long strbuf_control;
|
||||
unsigned long strbuf_pflush;
|
||||
unsigned long strbuf_fsync;
|
||||
unsigned long strbuf_ctxflush;
|
||||
unsigned long strbuf_ctxmatch_base;
|
||||
unsigned long strbuf_flushflag_pa;
|
||||
volatile unsigned long *strbuf_flushflag;
|
||||
volatile unsigned long __flushflag_buf[(64+(64-1)) / sizeof(long)];
|
||||
};
|
||||
|
||||
extern int iommu_table_init(struct iommu *iommu, int tsbsize,
|
||||
u32 dma_offset, u32 dma_addr_mask,
|
||||
int numa_node);
|
||||
|
||||
#endif /* !(_SPARC64_IOMMU_H) */
|
|
@ -1,31 +1,8 @@
|
|||
#ifndef _SPARC_IPCBUF_H
|
||||
#define _SPARC_IPCBUF_H
|
||||
|
||||
/*
|
||||
* The ipc64_perm structure for sparc architecture.
|
||||
* Note extra padding because this structure is passed back and forth
|
||||
* between kernel and user space.
|
||||
*
|
||||
* Pad space is left for:
|
||||
* - 32-bit mode
|
||||
* - 32-bit seq
|
||||
* - 2 miscellaneous 64-bit values (so that this structure matches
|
||||
* sparc64 ipc64_perm)
|
||||
*/
|
||||
|
||||
struct ipc64_perm
|
||||
{
|
||||
__kernel_key_t key;
|
||||
__kernel_uid32_t uid;
|
||||
__kernel_gid32_t gid;
|
||||
__kernel_uid32_t cuid;
|
||||
__kernel_gid32_t cgid;
|
||||
unsigned short __pad1;
|
||||
__kernel_mode_t mode;
|
||||
unsigned short __pad2;
|
||||
unsigned short seq;
|
||||
unsigned long long __unused1;
|
||||
unsigned long long __unused2;
|
||||
};
|
||||
|
||||
#endif /* _SPARC_IPCBUF_H */
|
||||
#ifndef ___ASM_SPARC_IPCBUF_H
|
||||
#define ___ASM_SPARC_IPCBUF_H
|
||||
#if defined(__sparc__) && defined(__arch64__)
|
||||
#include <asm-sparc/ipcbuf_64.h>
|
||||
#else
|
||||
#include <asm-sparc/ipcbuf_32.h>
|
||||
#endif
|
||||
#endif
|
||||
|
|
31
include/asm-sparc/ipcbuf_32.h
Normal file
31
include/asm-sparc/ipcbuf_32.h
Normal file
|
@ -0,0 +1,31 @@
|
|||
#ifndef _SPARC_IPCBUF_H
|
||||
#define _SPARC_IPCBUF_H
|
||||
|
||||
/*
|
||||
* The ipc64_perm structure for sparc architecture.
|
||||
* Note extra padding because this structure is passed back and forth
|
||||
* between kernel and user space.
|
||||
*
|
||||
* Pad space is left for:
|
||||
* - 32-bit mode
|
||||
* - 32-bit seq
|
||||
* - 2 miscellaneous 64-bit values (so that this structure matches
|
||||
* sparc64 ipc64_perm)
|
||||
*/
|
||||
|
||||
struct ipc64_perm
|
||||
{
|
||||
__kernel_key_t key;
|
||||
__kernel_uid32_t uid;
|
||||
__kernel_gid32_t gid;
|
||||
__kernel_uid32_t cuid;
|
||||
__kernel_gid32_t cgid;
|
||||
unsigned short __pad1;
|
||||
__kernel_mode_t mode;
|
||||
unsigned short __pad2;
|
||||
unsigned short seq;
|
||||
unsigned long long __unused1;
|
||||
unsigned long long __unused2;
|
||||
};
|
||||
|
||||
#endif /* _SPARC_IPCBUF_H */
|
28
include/asm-sparc/ipcbuf_64.h
Normal file
28
include/asm-sparc/ipcbuf_64.h
Normal file
|
@ -0,0 +1,28 @@
|
|||
#ifndef _SPARC64_IPCBUF_H
|
||||
#define _SPARC64_IPCBUF_H
|
||||
|
||||
/*
|
||||
* The ipc64_perm structure for sparc64 architecture.
|
||||
* Note extra padding because this structure is passed back and forth
|
||||
* between kernel and user space.
|
||||
*
|
||||
* Pad space is left for:
|
||||
* - 32-bit seq
|
||||
* - 2 miscellaneous 64-bit values
|
||||
*/
|
||||
|
||||
struct ipc64_perm
|
||||
{
|
||||
__kernel_key_t key;
|
||||
__kernel_uid_t uid;
|
||||
__kernel_gid_t gid;
|
||||
__kernel_uid_t cuid;
|
||||
__kernel_gid_t cgid;
|
||||
__kernel_mode_t mode;
|
||||
unsigned short __pad1;
|
||||
unsigned short seq;
|
||||
unsigned long __unused1;
|
||||
unsigned long __unused2;
|
||||
};
|
||||
|
||||
#endif /* _SPARC64_IPCBUF_H */
|
|
@ -1,15 +1,8 @@
|
|||
/* irq.h: IRQ registers on the Sparc.
|
||||
*
|
||||
* Copyright (C) 1995, 2007 David S. Miller (davem@davemloft.net)
|
||||
*/
|
||||
|
||||
#ifndef _SPARC_IRQ_H
|
||||
#define _SPARC_IRQ_H
|
||||
|
||||
#include <linux/interrupt.h>
|
||||
|
||||
#define NR_IRQS 16
|
||||
|
||||
#define irq_canonicalize(irq) (irq)
|
||||
|
||||
#ifndef ___ASM_SPARC_IRQ_H
|
||||
#define ___ASM_SPARC_IRQ_H
|
||||
#if defined(__sparc__) && defined(__arch64__)
|
||||
#include <asm-sparc/irq_64.h>
|
||||
#else
|
||||
#include <asm-sparc/irq_32.h>
|
||||
#endif
|
||||
#endif
|
||||
|
|
15
include/asm-sparc/irq_32.h
Normal file
15
include/asm-sparc/irq_32.h
Normal file
|
@ -0,0 +1,15 @@
|
|||
/* irq.h: IRQ registers on the Sparc.
|
||||
*
|
||||
* Copyright (C) 1995, 2007 David S. Miller (davem@davemloft.net)
|
||||
*/
|
||||
|
||||
#ifndef _SPARC_IRQ_H
|
||||
#define _SPARC_IRQ_H
|
||||
|
||||
#include <linux/interrupt.h>
|
||||
|
||||
#define NR_IRQS 16
|
||||
|
||||
#define irq_canonicalize(irq) (irq)
|
||||
|
||||
#endif
|
93
include/asm-sparc/irq_64.h
Normal file
93
include/asm-sparc/irq_64.h
Normal file
|
@ -0,0 +1,93 @@
|
|||
/* irq.h: IRQ registers on the 64-bit Sparc.
|
||||
*
|
||||
* Copyright (C) 1996 David S. Miller (davem@davemloft.net)
|
||||
* Copyright (C) 1998 Jakub Jelinek (jj@ultra.linux.cz)
|
||||
*/
|
||||
|
||||
#ifndef _SPARC64_IRQ_H
|
||||
#define _SPARC64_IRQ_H
|
||||
|
||||
#include <linux/linkage.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <asm/pil.h>
|
||||
#include <asm/ptrace.h>
|
||||
|
||||
/* IMAP/ICLR register defines */
|
||||
#define IMAP_VALID 0x80000000UL /* IRQ Enabled */
|
||||
#define IMAP_TID_UPA 0x7c000000UL /* UPA TargetID */
|
||||
#define IMAP_TID_JBUS 0x7c000000UL /* JBUS TargetID */
|
||||
#define IMAP_TID_SHIFT 26
|
||||
#define IMAP_AID_SAFARI 0x7c000000UL /* Safari AgentID */
|
||||
#define IMAP_AID_SHIFT 26
|
||||
#define IMAP_NID_SAFARI 0x03e00000UL /* Safari NodeID */
|
||||
#define IMAP_NID_SHIFT 21
|
||||
#define IMAP_IGN 0x000007c0UL /* IRQ Group Number */
|
||||
#define IMAP_INO 0x0000003fUL /* IRQ Number */
|
||||
#define IMAP_INR 0x000007ffUL /* Full interrupt number*/
|
||||
|
||||
#define ICLR_IDLE 0x00000000UL /* Idle state */
|
||||
#define ICLR_TRANSMIT 0x00000001UL /* Transmit state */
|
||||
#define ICLR_PENDING 0x00000003UL /* Pending state */
|
||||
|
||||
/* The largest number of unique interrupt sources we support.
|
||||
* If this needs to ever be larger than 255, you need to change
|
||||
* the type of ino_bucket->virt_irq as appropriate.
|
||||
*
|
||||
* ino_bucket->virt_irq allocation is made during {sun4v_,}build_irq().
|
||||
*/
|
||||
#define NR_IRQS 255
|
||||
|
||||
extern void irq_install_pre_handler(int virt_irq,
|
||||
void (*func)(unsigned int, void *, void *),
|
||||
void *arg1, void *arg2);
|
||||
#define irq_canonicalize(irq) (irq)
|
||||
extern unsigned int build_irq(int inofixup, unsigned long iclr, unsigned long imap);
|
||||
extern unsigned int sun4v_build_irq(u32 devhandle, unsigned int devino);
|
||||
extern unsigned int sun4v_build_virq(u32 devhandle, unsigned int devino);
|
||||
extern unsigned int sun4v_build_msi(u32 devhandle, unsigned int *virt_irq_p,
|
||||
unsigned int msi_devino_start,
|
||||
unsigned int msi_devino_end);
|
||||
extern void sun4v_destroy_msi(unsigned int virt_irq);
|
||||
extern unsigned int sun4u_build_msi(u32 portid, unsigned int *virt_irq_p,
|
||||
unsigned int msi_devino_start,
|
||||
unsigned int msi_devino_end,
|
||||
unsigned long imap_base,
|
||||
unsigned long iclr_base);
|
||||
extern void sun4u_destroy_msi(unsigned int virt_irq);
|
||||
extern unsigned int sbus_build_irq(void *sbus, unsigned int ino);
|
||||
|
||||
extern unsigned char virt_irq_alloc(unsigned int dev_handle,
|
||||
unsigned int dev_ino);
|
||||
#ifdef CONFIG_PCI_MSI
|
||||
extern void virt_irq_free(unsigned int virt_irq);
|
||||
#endif
|
||||
|
||||
extern void __init init_IRQ(void);
|
||||
extern void fixup_irqs(void);
|
||||
|
||||
static inline void set_softint(unsigned long bits)
|
||||
{
|
||||
__asm__ __volatile__("wr %0, 0x0, %%set_softint"
|
||||
: /* No outputs */
|
||||
: "r" (bits));
|
||||
}
|
||||
|
||||
static inline void clear_softint(unsigned long bits)
|
||||
{
|
||||
__asm__ __volatile__("wr %0, 0x0, %%clear_softint"
|
||||
: /* No outputs */
|
||||
: "r" (bits));
|
||||
}
|
||||
|
||||
static inline unsigned long get_softint(void)
|
||||
{
|
||||
unsigned long retval;
|
||||
|
||||
__asm__ __volatile__("rd %%softint, %0"
|
||||
: "=r" (retval));
|
||||
return retval;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,39 +1,8 @@
|
|||
/*
|
||||
* include/asm-sparc/irqflags.h
|
||||
*
|
||||
* IRQ flags handling
|
||||
*
|
||||
* This file gets included from lowlevel asm headers too, to provide
|
||||
* wrapped versions of the local_irq_*() APIs, based on the
|
||||
* raw_local_irq_*() functions from the lowlevel headers.
|
||||
*/
|
||||
#ifndef _ASM_IRQFLAGS_H
|
||||
#define _ASM_IRQFLAGS_H
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
extern void raw_local_irq_restore(unsigned long);
|
||||
extern unsigned long __raw_local_irq_save(void);
|
||||
extern void raw_local_irq_enable(void);
|
||||
|
||||
static inline unsigned long getipl(void)
|
||||
{
|
||||
unsigned long retval;
|
||||
|
||||
__asm__ __volatile__("rd %%psr, %0" : "=r" (retval));
|
||||
return retval;
|
||||
}
|
||||
|
||||
#define raw_local_save_flags(flags) ((flags) = getipl())
|
||||
#define raw_local_irq_save(flags) ((flags) = __raw_local_irq_save())
|
||||
#define raw_local_irq_disable() ((void) __raw_local_irq_save())
|
||||
#define raw_irqs_disabled() ((getipl() & PSR_PIL) != 0)
|
||||
|
||||
static inline int raw_irqs_disabled_flags(unsigned long flags)
|
||||
{
|
||||
return ((flags & PSR_PIL) != 0);
|
||||
}
|
||||
|
||||
#endif /* (__ASSEMBLY__) */
|
||||
|
||||
#endif /* !(_ASM_IRQFLAGS_H) */
|
||||
#ifndef ___ASM_SPARC_IRQFLAGS_H
|
||||
#define ___ASM_SPARC_IRQFLAGS_H
|
||||
#if defined(__sparc__) && defined(__arch64__)
|
||||
#include <asm-sparc/irqflags_64.h>
|
||||
#else
|
||||
#include <asm-sparc/irqflags_32.h>
|
||||
#endif
|
||||
#endif
|
||||
|
|
39
include/asm-sparc/irqflags_32.h
Normal file
39
include/asm-sparc/irqflags_32.h
Normal file
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* include/asm-sparc/irqflags.h
|
||||
*
|
||||
* IRQ flags handling
|
||||
*
|
||||
* This file gets included from lowlevel asm headers too, to provide
|
||||
* wrapped versions of the local_irq_*() APIs, based on the
|
||||
* raw_local_irq_*() functions from the lowlevel headers.
|
||||
*/
|
||||
#ifndef _ASM_IRQFLAGS_H
|
||||
#define _ASM_IRQFLAGS_H
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
extern void raw_local_irq_restore(unsigned long);
|
||||
extern unsigned long __raw_local_irq_save(void);
|
||||
extern void raw_local_irq_enable(void);
|
||||
|
||||
static inline unsigned long getipl(void)
|
||||
{
|
||||
unsigned long retval;
|
||||
|
||||
__asm__ __volatile__("rd %%psr, %0" : "=r" (retval));
|
||||
return retval;
|
||||
}
|
||||
|
||||
#define raw_local_save_flags(flags) ((flags) = getipl())
|
||||
#define raw_local_irq_save(flags) ((flags) = __raw_local_irq_save())
|
||||
#define raw_local_irq_disable() ((void) __raw_local_irq_save())
|
||||
#define raw_irqs_disabled() ((getipl() & PSR_PIL) != 0)
|
||||
|
||||
static inline int raw_irqs_disabled_flags(unsigned long flags)
|
||||
{
|
||||
return ((flags & PSR_PIL) != 0);
|
||||
}
|
||||
|
||||
#endif /* (__ASSEMBLY__) */
|
||||
|
||||
#endif /* !(_ASM_IRQFLAGS_H) */
|
89
include/asm-sparc/irqflags_64.h
Normal file
89
include/asm-sparc/irqflags_64.h
Normal file
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
* include/asm-sparc64/irqflags.h
|
||||
*
|
||||
* IRQ flags handling
|
||||
*
|
||||
* This file gets included from lowlevel asm headers too, to provide
|
||||
* wrapped versions of the local_irq_*() APIs, based on the
|
||||
* raw_local_irq_*() functions from the lowlevel headers.
|
||||
*/
|
||||
#ifndef _ASM_IRQFLAGS_H
|
||||
#define _ASM_IRQFLAGS_H
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
static inline unsigned long __raw_local_save_flags(void)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
__asm__ __volatile__(
|
||||
"rdpr %%pil, %0"
|
||||
: "=r" (flags)
|
||||
);
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
#define raw_local_save_flags(flags) \
|
||||
do { (flags) = __raw_local_save_flags(); } while (0)
|
||||
|
||||
static inline void raw_local_irq_restore(unsigned long flags)
|
||||
{
|
||||
__asm__ __volatile__(
|
||||
"wrpr %0, %%pil"
|
||||
: /* no output */
|
||||
: "r" (flags)
|
||||
: "memory"
|
||||
);
|
||||
}
|
||||
|
||||
static inline void raw_local_irq_disable(void)
|
||||
{
|
||||
__asm__ __volatile__(
|
||||
"wrpr 15, %%pil"
|
||||
: /* no outputs */
|
||||
: /* no inputs */
|
||||
: "memory"
|
||||
);
|
||||
}
|
||||
|
||||
static inline void raw_local_irq_enable(void)
|
||||
{
|
||||
__asm__ __volatile__(
|
||||
"wrpr 0, %%pil"
|
||||
: /* no outputs */
|
||||
: /* no inputs */
|
||||
: "memory"
|
||||
);
|
||||
}
|
||||
|
||||
static inline int raw_irqs_disabled_flags(unsigned long flags)
|
||||
{
|
||||
return (flags > 0);
|
||||
}
|
||||
|
||||
static inline int raw_irqs_disabled(void)
|
||||
{
|
||||
unsigned long flags = __raw_local_save_flags();
|
||||
|
||||
return raw_irqs_disabled_flags(flags);
|
||||
}
|
||||
|
||||
/*
|
||||
* For spinlocks, etc:
|
||||
*/
|
||||
static inline unsigned long __raw_local_irq_save(void)
|
||||
{
|
||||
unsigned long flags = __raw_local_save_flags();
|
||||
|
||||
raw_local_irq_disable();
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
#define raw_local_irq_save(flags) \
|
||||
do { (flags) = __raw_local_irq_save(); } while (0)
|
||||
|
||||
#endif /* (__ASSEMBLY__) */
|
||||
|
||||
#endif /* !(_ASM_IRQFLAGS_H) */
|
|
@ -1,73 +1,8 @@
|
|||
/*
|
||||
* kdebug.h: Defines and definitions for debugging the Linux kernel
|
||||
* under various kernel debuggers.
|
||||
*
|
||||
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
|
||||
*/
|
||||
#ifndef _SPARC_KDEBUG_H
|
||||
#define _SPARC_KDEBUG_H
|
||||
|
||||
#include <asm/openprom.h>
|
||||
#include <asm/vaddrs.h>
|
||||
|
||||
/* Breakpoints are enter through trap table entry 126. So in sparc assembly
|
||||
* if you want to drop into the debugger you do:
|
||||
*
|
||||
* t DEBUG_BP_TRAP
|
||||
*/
|
||||
|
||||
#define DEBUG_BP_TRAP 126
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
/* The debug vector is passed in %o1 at boot time. It is a pointer to
|
||||
* a structure in the debuggers address space. Here is its format.
|
||||
*/
|
||||
|
||||
typedef unsigned int (*debugger_funct)(void);
|
||||
|
||||
struct kernel_debug {
|
||||
/* First the entry point into the debugger. You jump here
|
||||
* to give control over to the debugger.
|
||||
*/
|
||||
unsigned long kdebug_entry;
|
||||
unsigned long kdebug_trapme; /* Figure out later... */
|
||||
/* The following is the number of pages that the debugger has
|
||||
* taken from to total pool.
|
||||
*/
|
||||
unsigned long *kdebug_stolen_pages;
|
||||
/* Ok, after you remap yourself and/or change the trap table
|
||||
* from what you were left with at boot time you have to call
|
||||
* this synchronization function so the debugger can check out
|
||||
* what you have done.
|
||||
*/
|
||||
debugger_funct teach_debugger;
|
||||
}; /* I think that is it... */
|
||||
|
||||
extern struct kernel_debug *linux_dbvec;
|
||||
|
||||
/* Use this macro in C-code to enter the debugger. */
|
||||
static inline void sp_enter_debugger(void)
|
||||
{
|
||||
__asm__ __volatile__("jmpl %0, %%o7\n\t"
|
||||
"nop\n\t" : :
|
||||
"r" (linux_dbvec) : "o7", "memory");
|
||||
}
|
||||
|
||||
#define SP_ENTER_DEBUGGER do { \
|
||||
if((linux_dbvec!=0) && ((*(short *)linux_dbvec)!=-1)) \
|
||||
sp_enter_debugger(); \
|
||||
} while(0)
|
||||
|
||||
enum die_val {
|
||||
DIE_UNUSED,
|
||||
};
|
||||
|
||||
#endif /* !(__ASSEMBLY__) */
|
||||
|
||||
/* Some nice offset defines for assembler code. */
|
||||
#define KDEBUG_ENTRY_OFF 0x0
|
||||
#define KDEBUG_DUNNO_OFF 0x4
|
||||
#define KDEBUG_DUNNO2_OFF 0x8
|
||||
#define KDEBUG_TEACH_OFF 0xc
|
||||
|
||||
#endif /* !(_SPARC_KDEBUG_H) */
|
||||
#ifndef ___ASM_SPARC_KDEBUG_H
|
||||
#define ___ASM_SPARC_KDEBUG_H
|
||||
#if defined(__sparc__) && defined(__arch64__)
|
||||
#include <asm-sparc/kdebug_64.h>
|
||||
#else
|
||||
#include <asm-sparc/kdebug_32.h>
|
||||
#endif
|
||||
#endif
|
||||
|
|
73
include/asm-sparc/kdebug_32.h
Normal file
73
include/asm-sparc/kdebug_32.h
Normal file
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* kdebug.h: Defines and definitions for debugging the Linux kernel
|
||||
* under various kernel debuggers.
|
||||
*
|
||||
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
|
||||
*/
|
||||
#ifndef _SPARC_KDEBUG_H
|
||||
#define _SPARC_KDEBUG_H
|
||||
|
||||
#include <asm/openprom.h>
|
||||
#include <asm/vaddrs.h>
|
||||
|
||||
/* Breakpoints are enter through trap table entry 126. So in sparc assembly
|
||||
* if you want to drop into the debugger you do:
|
||||
*
|
||||
* t DEBUG_BP_TRAP
|
||||
*/
|
||||
|
||||
#define DEBUG_BP_TRAP 126
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
/* The debug vector is passed in %o1 at boot time. It is a pointer to
|
||||
* a structure in the debuggers address space. Here is its format.
|
||||
*/
|
||||
|
||||
typedef unsigned int (*debugger_funct)(void);
|
||||
|
||||
struct kernel_debug {
|
||||
/* First the entry point into the debugger. You jump here
|
||||
* to give control over to the debugger.
|
||||
*/
|
||||
unsigned long kdebug_entry;
|
||||
unsigned long kdebug_trapme; /* Figure out later... */
|
||||
/* The following is the number of pages that the debugger has
|
||||
* taken from to total pool.
|
||||
*/
|
||||
unsigned long *kdebug_stolen_pages;
|
||||
/* Ok, after you remap yourself and/or change the trap table
|
||||
* from what you were left with at boot time you have to call
|
||||
* this synchronization function so the debugger can check out
|
||||
* what you have done.
|
||||
*/
|
||||
debugger_funct teach_debugger;
|
||||
}; /* I think that is it... */
|
||||
|
||||
extern struct kernel_debug *linux_dbvec;
|
||||
|
||||
/* Use this macro in C-code to enter the debugger. */
|
||||
static inline void sp_enter_debugger(void)
|
||||
{
|
||||
__asm__ __volatile__("jmpl %0, %%o7\n\t"
|
||||
"nop\n\t" : :
|
||||
"r" (linux_dbvec) : "o7", "memory");
|
||||
}
|
||||
|
||||
#define SP_ENTER_DEBUGGER do { \
|
||||
if((linux_dbvec!=0) && ((*(short *)linux_dbvec)!=-1)) \
|
||||
sp_enter_debugger(); \
|
||||
} while(0)
|
||||
|
||||
enum die_val {
|
||||
DIE_UNUSED,
|
||||
};
|
||||
|
||||
#endif /* !(__ASSEMBLY__) */
|
||||
|
||||
/* Some nice offset defines for assembler code. */
|
||||
#define KDEBUG_ENTRY_OFF 0x0
|
||||
#define KDEBUG_DUNNO_OFF 0x4
|
||||
#define KDEBUG_DUNNO2_OFF 0x8
|
||||
#define KDEBUG_TEACH_OFF 0xc
|
||||
|
||||
#endif /* !(_SPARC_KDEBUG_H) */
|
19
include/asm-sparc/kdebug_64.h
Normal file
19
include/asm-sparc/kdebug_64.h
Normal file
|
@ -0,0 +1,19 @@
|
|||
#ifndef _SPARC64_KDEBUG_H
|
||||
#define _SPARC64_KDEBUG_H
|
||||
|
||||
struct pt_regs;
|
||||
|
||||
extern void bad_trap(struct pt_regs *, long);
|
||||
|
||||
/* Grossly misnamed. */
|
||||
enum die_val {
|
||||
DIE_OOPS = 1,
|
||||
DIE_DEBUG, /* ta 0x70 */
|
||||
DIE_DEBUG_2, /* ta 0x71 */
|
||||
DIE_DIE,
|
||||
DIE_TRAP,
|
||||
DIE_TRAP_TL1,
|
||||
DIE_CALL,
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,29 +1,8 @@
|
|||
/*
|
||||
* Machine dependent access functions for RTC registers.
|
||||
*/
|
||||
#ifndef __ASM_SPARC_MC146818RTC_H
|
||||
#define __ASM_SPARC_MC146818RTC_H
|
||||
|
||||
#include <asm/io.h>
|
||||
|
||||
#ifndef RTC_PORT
|
||||
#define RTC_PORT(x) (0x70 + (x))
|
||||
#define RTC_ALWAYS_BCD 1 /* RTC operates in binary mode */
|
||||
#ifndef ___ASM_SPARC_MC146818RTC_H
|
||||
#define ___ASM_SPARC_MC146818RTC_H
|
||||
#if defined(__sparc__) && defined(__arch64__)
|
||||
#include <asm-sparc/mc146818rtc_64.h>
|
||||
#else
|
||||
#include <asm-sparc/mc146818rtc_32.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The yet supported machines all access the RTC index register via
|
||||
* an ISA port access but the way to access the date register differs ...
|
||||
*/
|
||||
#define CMOS_READ(addr) ({ \
|
||||
outb_p((addr),RTC_PORT(0)); \
|
||||
inb_p(RTC_PORT(1)); \
|
||||
})
|
||||
#define CMOS_WRITE(val, addr) ({ \
|
||||
outb_p((addr),RTC_PORT(0)); \
|
||||
outb_p((val),RTC_PORT(1)); \
|
||||
})
|
||||
|
||||
#define RTC_IRQ 8
|
||||
|
||||
#endif /* __ASM_SPARC_MC146818RTC_H */
|
||||
|
|
29
include/asm-sparc/mc146818rtc_32.h
Normal file
29
include/asm-sparc/mc146818rtc_32.h
Normal file
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* Machine dependent access functions for RTC registers.
|
||||
*/
|
||||
#ifndef __ASM_SPARC_MC146818RTC_H
|
||||
#define __ASM_SPARC_MC146818RTC_H
|
||||
|
||||
#include <asm/io.h>
|
||||
|
||||
#ifndef RTC_PORT
|
||||
#define RTC_PORT(x) (0x70 + (x))
|
||||
#define RTC_ALWAYS_BCD 1 /* RTC operates in binary mode */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The yet supported machines all access the RTC index register via
|
||||
* an ISA port access but the way to access the date register differs ...
|
||||
*/
|
||||
#define CMOS_READ(addr) ({ \
|
||||
outb_p((addr),RTC_PORT(0)); \
|
||||
inb_p(RTC_PORT(1)); \
|
||||
})
|
||||
#define CMOS_WRITE(val, addr) ({ \
|
||||
outb_p((addr),RTC_PORT(0)); \
|
||||
outb_p((val),RTC_PORT(1)); \
|
||||
})
|
||||
|
||||
#define RTC_IRQ 8
|
||||
|
||||
#endif /* __ASM_SPARC_MC146818RTC_H */
|
34
include/asm-sparc/mc146818rtc_64.h
Normal file
34
include/asm-sparc/mc146818rtc_64.h
Normal file
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Machine dependent access functions for RTC registers.
|
||||
*/
|
||||
#ifndef __ASM_SPARC64_MC146818RTC_H
|
||||
#define __ASM_SPARC64_MC146818RTC_H
|
||||
|
||||
#include <asm/io.h>
|
||||
|
||||
#ifndef RTC_PORT
|
||||
#ifdef CONFIG_PCI
|
||||
extern unsigned long ds1287_regs;
|
||||
#else
|
||||
#define ds1287_regs (0UL)
|
||||
#endif
|
||||
#define RTC_PORT(x) (ds1287_regs + (x))
|
||||
#define RTC_ALWAYS_BCD 0
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The yet supported machines all access the RTC index register via
|
||||
* an ISA port access but the way to access the date register differs ...
|
||||
*/
|
||||
#define CMOS_READ(addr) ({ \
|
||||
outb_p((addr),RTC_PORT(0)); \
|
||||
inb_p(RTC_PORT(1)); \
|
||||
})
|
||||
#define CMOS_WRITE(val, addr) ({ \
|
||||
outb_p((addr),RTC_PORT(0)); \
|
||||
outb_p((val),RTC_PORT(1)); \
|
||||
})
|
||||
|
||||
#define RTC_IRQ 8
|
||||
|
||||
#endif /* __ASM_SPARC64_MC146818RTC_H */
|
|
@ -1,7 +1,8 @@
|
|||
#ifndef __MMU_H
|
||||
#define __MMU_H
|
||||
|
||||
/* Default "unsigned long" context */
|
||||
typedef unsigned long mm_context_t;
|
||||
|
||||
#ifndef ___ASM_SPARC_MMU_H
|
||||
#define ___ASM_SPARC_MMU_H
|
||||
#if defined(__sparc__) && defined(__arch64__)
|
||||
#include <asm-sparc/mmu_64.h>
|
||||
#else
|
||||
#include <asm-sparc/mmu_32.h>
|
||||
#endif
|
||||
#endif
|
||||
|
|
7
include/asm-sparc/mmu_32.h
Normal file
7
include/asm-sparc/mmu_32.h
Normal file
|
@ -0,0 +1,7 @@
|
|||
#ifndef __MMU_H
|
||||
#define __MMU_H
|
||||
|
||||
/* Default "unsigned long" context */
|
||||
typedef unsigned long mm_context_t;
|
||||
|
||||
#endif
|
127
include/asm-sparc/mmu_64.h
Normal file
127
include/asm-sparc/mmu_64.h
Normal file
|
@ -0,0 +1,127 @@
|
|||
#ifndef __MMU_H
|
||||
#define __MMU_H
|
||||
|
||||
#include <linux/const.h>
|
||||
#include <asm/page.h>
|
||||
#include <asm/hypervisor.h>
|
||||
|
||||
#define CTX_NR_BITS 13
|
||||
|
||||
#define TAG_CONTEXT_BITS ((_AC(1,UL) << CTX_NR_BITS) - _AC(1,UL))
|
||||
|
||||
/* UltraSPARC-III+ and later have a feature whereby you can
|
||||
* select what page size the various Data-TLB instances in the
|
||||
* chip. In order to gracefully support this, we put the version
|
||||
* field in a spot outside of the areas of the context register
|
||||
* where this parameter is specified.
|
||||
*/
|
||||
#define CTX_VERSION_SHIFT 22
|
||||
#define CTX_VERSION_MASK ((~0UL) << CTX_VERSION_SHIFT)
|
||||
|
||||
#define CTX_PGSZ_8KB _AC(0x0,UL)
|
||||
#define CTX_PGSZ_64KB _AC(0x1,UL)
|
||||
#define CTX_PGSZ_512KB _AC(0x2,UL)
|
||||
#define CTX_PGSZ_4MB _AC(0x3,UL)
|
||||
#define CTX_PGSZ_BITS _AC(0x7,UL)
|
||||
#define CTX_PGSZ0_NUC_SHIFT 61
|
||||
#define CTX_PGSZ1_NUC_SHIFT 58
|
||||
#define CTX_PGSZ0_SHIFT 16
|
||||
#define CTX_PGSZ1_SHIFT 19
|
||||
#define CTX_PGSZ_MASK ((CTX_PGSZ_BITS << CTX_PGSZ0_SHIFT) | \
|
||||
(CTX_PGSZ_BITS << CTX_PGSZ1_SHIFT))
|
||||
|
||||
#if defined(CONFIG_SPARC64_PAGE_SIZE_8KB)
|
||||
#define CTX_PGSZ_BASE CTX_PGSZ_8KB
|
||||
#elif defined(CONFIG_SPARC64_PAGE_SIZE_64KB)
|
||||
#define CTX_PGSZ_BASE CTX_PGSZ_64KB
|
||||
#elif defined(CONFIG_SPARC64_PAGE_SIZE_512KB)
|
||||
#define CTX_PGSZ_BASE CTX_PGSZ_512KB
|
||||
#elif defined(CONFIG_SPARC64_PAGE_SIZE_4MB)
|
||||
#define CTX_PGSZ_BASE CTX_PGSZ_4MB
|
||||
#else
|
||||
#error No page size specified in kernel configuration
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_HUGETLB_PAGE_SIZE_4MB)
|
||||
#define CTX_PGSZ_HUGE CTX_PGSZ_4MB
|
||||
#elif defined(CONFIG_HUGETLB_PAGE_SIZE_512K)
|
||||
#define CTX_PGSZ_HUGE CTX_PGSZ_512KB
|
||||
#elif defined(CONFIG_HUGETLB_PAGE_SIZE_64K)
|
||||
#define CTX_PGSZ_HUGE CTX_PGSZ_64KB
|
||||
#endif
|
||||
|
||||
#define CTX_PGSZ_KERN CTX_PGSZ_4MB
|
||||
|
||||
/* Thus, when running on UltraSPARC-III+ and later, we use the following
|
||||
* PRIMARY_CONTEXT register values for the kernel context.
|
||||
*/
|
||||
#define CTX_CHEETAH_PLUS_NUC \
|
||||
((CTX_PGSZ_KERN << CTX_PGSZ0_NUC_SHIFT) | \
|
||||
(CTX_PGSZ_BASE << CTX_PGSZ1_NUC_SHIFT))
|
||||
|
||||
#define CTX_CHEETAH_PLUS_CTX0 \
|
||||
((CTX_PGSZ_KERN << CTX_PGSZ0_SHIFT) | \
|
||||
(CTX_PGSZ_BASE << CTX_PGSZ1_SHIFT))
|
||||
|
||||
/* If you want "the TLB context number" use CTX_NR_MASK. If you
|
||||
* want "the bits I program into the context registers" use
|
||||
* CTX_HW_MASK.
|
||||
*/
|
||||
#define CTX_NR_MASK TAG_CONTEXT_BITS
|
||||
#define CTX_HW_MASK (CTX_NR_MASK | CTX_PGSZ_MASK)
|
||||
|
||||
#define CTX_FIRST_VERSION ((_AC(1,UL) << CTX_VERSION_SHIFT) + _AC(1,UL))
|
||||
#define CTX_VALID(__ctx) \
|
||||
(!(((__ctx.sparc64_ctx_val) ^ tlb_context_cache) & CTX_VERSION_MASK))
|
||||
#define CTX_HWBITS(__ctx) ((__ctx.sparc64_ctx_val) & CTX_HW_MASK)
|
||||
#define CTX_NRBITS(__ctx) ((__ctx.sparc64_ctx_val) & CTX_NR_MASK)
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
#define TSB_ENTRY_ALIGNMENT 16
|
||||
|
||||
struct tsb {
|
||||
unsigned long tag;
|
||||
unsigned long pte;
|
||||
} __attribute__((aligned(TSB_ENTRY_ALIGNMENT)));
|
||||
|
||||
extern void __tsb_insert(unsigned long ent, unsigned long tag, unsigned long pte);
|
||||
extern void tsb_flush(unsigned long ent, unsigned long tag);
|
||||
extern void tsb_init(struct tsb *tsb, unsigned long size);
|
||||
|
||||
struct tsb_config {
|
||||
struct tsb *tsb;
|
||||
unsigned long tsb_rss_limit;
|
||||
unsigned long tsb_nentries;
|
||||
unsigned long tsb_reg_val;
|
||||
unsigned long tsb_map_vaddr;
|
||||
unsigned long tsb_map_pte;
|
||||
};
|
||||
|
||||
#define MM_TSB_BASE 0
|
||||
|
||||
#ifdef CONFIG_HUGETLB_PAGE
|
||||
#define MM_TSB_HUGE 1
|
||||
#define MM_NUM_TSBS 2
|
||||
#else
|
||||
#define MM_NUM_TSBS 1
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
spinlock_t lock;
|
||||
unsigned long sparc64_ctx_val;
|
||||
unsigned long huge_pte_count;
|
||||
struct tsb_config tsb_block[MM_NUM_TSBS];
|
||||
struct hv_tsb_descr tsb_descr[MM_NUM_TSBS];
|
||||
} mm_context_t;
|
||||
|
||||
#endif /* !__ASSEMBLY__ */
|
||||
|
||||
#define TSB_CONFIG_TSB 0x00
|
||||
#define TSB_CONFIG_RSS_LIMIT 0x08
|
||||
#define TSB_CONFIG_NENTRIES 0x10
|
||||
#define TSB_CONFIG_REG_VAL 0x18
|
||||
#define TSB_CONFIG_MAP_VADDR 0x20
|
||||
#define TSB_CONFIG_MAP_PTE 0x28
|
||||
|
||||
#endif /* __MMU_H */
|
|
@ -1,42 +1,8 @@
|
|||
#ifndef __SPARC_MMU_CONTEXT_H
|
||||
#define __SPARC_MMU_CONTEXT_H
|
||||
|
||||
#include <asm/btfixup.h>
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
#include <asm-generic/mm_hooks.h>
|
||||
|
||||
static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize a new mmu context. This is invoked when a new
|
||||
* address space instance (unique or shared) is instantiated.
|
||||
*/
|
||||
#define init_new_context(tsk, mm) (((mm)->context = NO_CONTEXT), 0)
|
||||
|
||||
/*
|
||||
* Destroy a dead context. This occurs when mmput drops the
|
||||
* mm_users count to zero, the mmaps have been released, and
|
||||
* all the page tables have been flushed. Our job is to destroy
|
||||
* any remaining processor-specific state.
|
||||
*/
|
||||
BTFIXUPDEF_CALL(void, destroy_context, struct mm_struct *)
|
||||
|
||||
#define destroy_context(mm) BTFIXUP_CALL(destroy_context)(mm)
|
||||
|
||||
/* Switch the current MM context. */
|
||||
BTFIXUPDEF_CALL(void, switch_mm, struct mm_struct *, struct mm_struct *, struct task_struct *)
|
||||
|
||||
#define switch_mm(old_mm, mm, tsk) BTFIXUP_CALL(switch_mm)(old_mm, mm, tsk)
|
||||
|
||||
#define deactivate_mm(tsk,mm) do { } while (0)
|
||||
|
||||
/* Activate a new MM instance for the current task. */
|
||||
#define activate_mm(active_mm, mm) switch_mm((active_mm), (mm), NULL)
|
||||
|
||||
#endif /* !(__ASSEMBLY__) */
|
||||
|
||||
#endif /* !(__SPARC_MMU_CONTEXT_H) */
|
||||
#ifndef ___ASM_SPARC_MMU_CONTEXT_H
|
||||
#define ___ASM_SPARC_MMU_CONTEXT_H
|
||||
#if defined(__sparc__) && defined(__arch64__)
|
||||
#include <asm-sparc/mmu_context_64.h>
|
||||
#else
|
||||
#include <asm-sparc/mmu_context_32.h>
|
||||
#endif
|
||||
#endif
|
||||
|
|
42
include/asm-sparc/mmu_context_32.h
Normal file
42
include/asm-sparc/mmu_context_32.h
Normal file
|
@ -0,0 +1,42 @@
|
|||
#ifndef __SPARC_MMU_CONTEXT_H
|
||||
#define __SPARC_MMU_CONTEXT_H
|
||||
|
||||
#include <asm/btfixup.h>
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
#include <asm-generic/mm_hooks.h>
|
||||
|
||||
static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize a new mmu context. This is invoked when a new
|
||||
* address space instance (unique or shared) is instantiated.
|
||||
*/
|
||||
#define init_new_context(tsk, mm) (((mm)->context = NO_CONTEXT), 0)
|
||||
|
||||
/*
|
||||
* Destroy a dead context. This occurs when mmput drops the
|
||||
* mm_users count to zero, the mmaps have been released, and
|
||||
* all the page tables have been flushed. Our job is to destroy
|
||||
* any remaining processor-specific state.
|
||||
*/
|
||||
BTFIXUPDEF_CALL(void, destroy_context, struct mm_struct *)
|
||||
|
||||
#define destroy_context(mm) BTFIXUP_CALL(destroy_context)(mm)
|
||||
|
||||
/* Switch the current MM context. */
|
||||
BTFIXUPDEF_CALL(void, switch_mm, struct mm_struct *, struct mm_struct *, struct task_struct *)
|
||||
|
||||
#define switch_mm(old_mm, mm, tsk) BTFIXUP_CALL(switch_mm)(old_mm, mm, tsk)
|
||||
|
||||
#define deactivate_mm(tsk,mm) do { } while (0)
|
||||
|
||||
/* Activate a new MM instance for the current task. */
|
||||
#define activate_mm(active_mm, mm) switch_mm((active_mm), (mm), NULL)
|
||||
|
||||
#endif /* !(__ASSEMBLY__) */
|
||||
|
||||
#endif /* !(__SPARC_MMU_CONTEXT_H) */
|
155
include/asm-sparc/mmu_context_64.h
Normal file
155
include/asm-sparc/mmu_context_64.h
Normal file
|
@ -0,0 +1,155 @@
|
|||
#ifndef __SPARC64_MMU_CONTEXT_H
|
||||
#define __SPARC64_MMU_CONTEXT_H
|
||||
|
||||
/* Derived heavily from Linus's Alpha/AXP ASN code... */
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
#include <linux/spinlock.h>
|
||||
#include <asm/system.h>
|
||||
#include <asm/spitfire.h>
|
||||
#include <asm-generic/mm_hooks.h>
|
||||
|
||||
static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
|
||||
{
|
||||
}
|
||||
|
||||
extern spinlock_t ctx_alloc_lock;
|
||||
extern unsigned long tlb_context_cache;
|
||||
extern unsigned long mmu_context_bmap[];
|
||||
|
||||
extern void get_new_mmu_context(struct mm_struct *mm);
|
||||
#ifdef CONFIG_SMP
|
||||
extern void smp_new_mmu_context_version(void);
|
||||
#else
|
||||
#define smp_new_mmu_context_version() do { } while (0)
|
||||
#endif
|
||||
|
||||
extern int init_new_context(struct task_struct *tsk, struct mm_struct *mm);
|
||||
extern void destroy_context(struct mm_struct *mm);
|
||||
|
||||
extern void __tsb_context_switch(unsigned long pgd_pa,
|
||||
struct tsb_config *tsb_base,
|
||||
struct tsb_config *tsb_huge,
|
||||
unsigned long tsb_descr_pa);
|
||||
|
||||
static inline void tsb_context_switch(struct mm_struct *mm)
|
||||
{
|
||||
__tsb_context_switch(__pa(mm->pgd),
|
||||
&mm->context.tsb_block[0],
|
||||
#ifdef CONFIG_HUGETLB_PAGE
|
||||
(mm->context.tsb_block[1].tsb ?
|
||||
&mm->context.tsb_block[1] :
|
||||
NULL)
|
||||
#else
|
||||
NULL
|
||||
#endif
|
||||
, __pa(&mm->context.tsb_descr[0]));
|
||||
}
|
||||
|
||||
extern void tsb_grow(struct mm_struct *mm, unsigned long tsb_index, unsigned long mm_rss);
|
||||
#ifdef CONFIG_SMP
|
||||
extern void smp_tsb_sync(struct mm_struct *mm);
|
||||
#else
|
||||
#define smp_tsb_sync(__mm) do { } while (0)
|
||||
#endif
|
||||
|
||||
/* Set MMU context in the actual hardware. */
|
||||
#define load_secondary_context(__mm) \
|
||||
__asm__ __volatile__( \
|
||||
"\n661: stxa %0, [%1] %2\n" \
|
||||
" .section .sun4v_1insn_patch, \"ax\"\n" \
|
||||
" .word 661b\n" \
|
||||
" stxa %0, [%1] %3\n" \
|
||||
" .previous\n" \
|
||||
" flush %%g6\n" \
|
||||
: /* No outputs */ \
|
||||
: "r" (CTX_HWBITS((__mm)->context)), \
|
||||
"r" (SECONDARY_CONTEXT), "i" (ASI_DMMU), "i" (ASI_MMU))
|
||||
|
||||
extern void __flush_tlb_mm(unsigned long, unsigned long);
|
||||
|
||||
/* Switch the current MM context. Interrupts are disabled. */
|
||||
static inline void switch_mm(struct mm_struct *old_mm, struct mm_struct *mm, struct task_struct *tsk)
|
||||
{
|
||||
unsigned long ctx_valid, flags;
|
||||
int cpu;
|
||||
|
||||
if (unlikely(mm == &init_mm))
|
||||
return;
|
||||
|
||||
spin_lock_irqsave(&mm->context.lock, flags);
|
||||
ctx_valid = CTX_VALID(mm->context);
|
||||
if (!ctx_valid)
|
||||
get_new_mmu_context(mm);
|
||||
|
||||
/* We have to be extremely careful here or else we will miss
|
||||
* a TSB grow if we switch back and forth between a kernel
|
||||
* thread and an address space which has it's TSB size increased
|
||||
* on another processor.
|
||||
*
|
||||
* It is possible to play some games in order to optimize the
|
||||
* switch, but the safest thing to do is to unconditionally
|
||||
* perform the secondary context load and the TSB context switch.
|
||||
*
|
||||
* For reference the bad case is, for address space "A":
|
||||
*
|
||||
* CPU 0 CPU 1
|
||||
* run address space A
|
||||
* set cpu0's bits in cpu_vm_mask
|
||||
* switch to kernel thread, borrow
|
||||
* address space A via entry_lazy_tlb
|
||||
* run address space A
|
||||
* set cpu1's bit in cpu_vm_mask
|
||||
* flush_tlb_pending()
|
||||
* reset cpu_vm_mask to just cpu1
|
||||
* TSB grow
|
||||
* run address space A
|
||||
* context was valid, so skip
|
||||
* TSB context switch
|
||||
*
|
||||
* At that point cpu0 continues to use a stale TSB, the one from
|
||||
* before the TSB grow performed on cpu1. cpu1 did not cross-call
|
||||
* cpu0 to update it's TSB because at that point the cpu_vm_mask
|
||||
* only had cpu1 set in it.
|
||||
*/
|
||||
load_secondary_context(mm);
|
||||
tsb_context_switch(mm);
|
||||
|
||||
/* Any time a processor runs a context on an address space
|
||||
* for the first time, we must flush that context out of the
|
||||
* local TLB.
|
||||
*/
|
||||
cpu = smp_processor_id();
|
||||
if (!ctx_valid || !cpu_isset(cpu, mm->cpu_vm_mask)) {
|
||||
cpu_set(cpu, mm->cpu_vm_mask);
|
||||
__flush_tlb_mm(CTX_HWBITS(mm->context),
|
||||
SECONDARY_CONTEXT);
|
||||
}
|
||||
spin_unlock_irqrestore(&mm->context.lock, flags);
|
||||
}
|
||||
|
||||
#define deactivate_mm(tsk,mm) do { } while (0)
|
||||
|
||||
/* Activate a new MM instance for the current task. */
|
||||
static inline void activate_mm(struct mm_struct *active_mm, struct mm_struct *mm)
|
||||
{
|
||||
unsigned long flags;
|
||||
int cpu;
|
||||
|
||||
spin_lock_irqsave(&mm->context.lock, flags);
|
||||
if (!CTX_VALID(mm->context))
|
||||
get_new_mmu_context(mm);
|
||||
cpu = smp_processor_id();
|
||||
if (!cpu_isset(cpu, mm->cpu_vm_mask))
|
||||
cpu_set(cpu, mm->cpu_vm_mask);
|
||||
|
||||
load_secondary_context(mm);
|
||||
__flush_tlb_mm(CTX_HWBITS(mm->context), SECONDARY_CONTEXT);
|
||||
tsb_context_switch(mm);
|
||||
spin_unlock_irqrestore(&mm->context.lock, flags);
|
||||
}
|
||||
|
||||
#endif /* !(__ASSEMBLY__) */
|
||||
|
||||
#endif /* !(__SPARC64_MMU_CONTEXT_H) */
|
|
@ -1,7 +1,8 @@
|
|||
#ifndef _ASM_SPARC_MODULE_H
|
||||
#define _ASM_SPARC_MODULE_H
|
||||
struct mod_arch_specific { };
|
||||
#define Elf_Shdr Elf32_Shdr
|
||||
#define Elf_Sym Elf32_Sym
|
||||
#define Elf_Ehdr Elf32_Ehdr
|
||||
#endif /* _ASM_SPARC_MODULE_H */
|
||||
#ifndef ___ASM_SPARC_MODULE_H
|
||||
#define ___ASM_SPARC_MODULE_H
|
||||
#if defined(__sparc__) && defined(__arch64__)
|
||||
#include <asm-sparc/module_64.h>
|
||||
#else
|
||||
#include <asm-sparc/module_32.h>
|
||||
#endif
|
||||
#endif
|
||||
|
|
7
include/asm-sparc/module_32.h
Normal file
7
include/asm-sparc/module_32.h
Normal file
|
@ -0,0 +1,7 @@
|
|||
#ifndef _ASM_SPARC_MODULE_H
|
||||
#define _ASM_SPARC_MODULE_H
|
||||
struct mod_arch_specific { };
|
||||
#define Elf_Shdr Elf32_Shdr
|
||||
#define Elf_Sym Elf32_Sym
|
||||
#define Elf_Ehdr Elf32_Ehdr
|
||||
#endif /* _ASM_SPARC_MODULE_H */
|
7
include/asm-sparc/module_64.h
Normal file
7
include/asm-sparc/module_64.h
Normal file
|
@ -0,0 +1,7 @@
|
|||
#ifndef _ASM_SPARC64_MODULE_H
|
||||
#define _ASM_SPARC64_MODULE_H
|
||||
struct mod_arch_specific { };
|
||||
#define Elf_Shdr Elf64_Shdr
|
||||
#define Elf_Sym Elf64_Sym
|
||||
#define Elf_Ehdr Elf64_Ehdr
|
||||
#endif /* _ASM_SPARC64_MODULE_H */
|
|
@ -1,171 +1,8 @@
|
|||
/*
|
||||
* mostek.h: Describes the various Mostek time of day clock registers.
|
||||
*
|
||||
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
|
||||
* Copyright (C) 1996 Thomas K. Dyas (tdyas@eden.rutgers.edu)
|
||||
* Added intersil code 05/25/98 Chris Davis (cdavis@cois.on.ca)
|
||||
*/
|
||||
|
||||
#ifndef _SPARC_MOSTEK_H
|
||||
#define _SPARC_MOSTEK_H
|
||||
|
||||
#include <asm/idprom.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
/* M48T02 Register Map (adapted from Sun NVRAM/Hostid FAQ)
|
||||
*
|
||||
* Data
|
||||
* Address Function
|
||||
* Bit 7 Bit 6 Bit 5 Bit 4Bit 3 Bit 2 Bit 1 Bit 0
|
||||
* 7ff - - - - - - - - Year 00-99
|
||||
* 7fe 0 0 0 - - - - - Month 01-12
|
||||
* 7fd 0 0 - - - - - - Date 01-31
|
||||
* 7fc 0 FT 0 0 0 - - - Day 01-07
|
||||
* 7fb KS 0 - - - - - - Hours 00-23
|
||||
* 7fa 0 - - - - - - - Minutes 00-59
|
||||
* 7f9 ST - - - - - - - Seconds 00-59
|
||||
* 7f8 W R S - - - - - Control
|
||||
*
|
||||
* * ST is STOP BIT
|
||||
* * W is WRITE BIT
|
||||
* * R is READ BIT
|
||||
* * S is SIGN BIT
|
||||
* * FT is FREQ TEST BIT
|
||||
* * KS is KICK START BIT
|
||||
*/
|
||||
|
||||
/* The Mostek 48t02 real time clock and NVRAM chip. The registers
|
||||
* other than the control register are in binary coded decimal. Some
|
||||
* control bits also live outside the control register.
|
||||
*/
|
||||
#define mostek_read(_addr) readb(_addr)
|
||||
#define mostek_write(_addr,_val) writeb(_val, _addr)
|
||||
#define MOSTEK_EEPROM 0x0000UL
|
||||
#define MOSTEK_IDPROM 0x07d8UL
|
||||
#define MOSTEK_CREG 0x07f8UL
|
||||
#define MOSTEK_SEC 0x07f9UL
|
||||
#define MOSTEK_MIN 0x07faUL
|
||||
#define MOSTEK_HOUR 0x07fbUL
|
||||
#define MOSTEK_DOW 0x07fcUL
|
||||
#define MOSTEK_DOM 0x07fdUL
|
||||
#define MOSTEK_MONTH 0x07feUL
|
||||
#define MOSTEK_YEAR 0x07ffUL
|
||||
|
||||
struct mostek48t02 {
|
||||
volatile char eeprom[2008]; /* This is the eeprom, don't touch! */
|
||||
struct idprom idprom; /* The idprom lives here. */
|
||||
volatile unsigned char creg; /* Control register */
|
||||
volatile unsigned char sec; /* Seconds (0-59) */
|
||||
volatile unsigned char min; /* Minutes (0-59) */
|
||||
volatile unsigned char hour; /* Hour (0-23) */
|
||||
volatile unsigned char dow; /* Day of the week (1-7) */
|
||||
volatile unsigned char dom; /* Day of the month (1-31) */
|
||||
volatile unsigned char month; /* Month of year (1-12) */
|
||||
volatile unsigned char year; /* Year (0-99) */
|
||||
};
|
||||
|
||||
extern spinlock_t mostek_lock;
|
||||
extern void __iomem *mstk48t02_regs;
|
||||
|
||||
/* Control register values. */
|
||||
#define MSTK_CREG_WRITE 0x80 /* Must set this before placing values. */
|
||||
#define MSTK_CREG_READ 0x40 /* Stop updates to allow a clean read. */
|
||||
#define MSTK_CREG_SIGN 0x20 /* Slow/speed clock in calibration mode. */
|
||||
|
||||
/* Control bits that live in the other registers. */
|
||||
#define MSTK_STOP 0x80 /* Stop the clock oscillator. (sec) */
|
||||
#define MSTK_KICK_START 0x80 /* Kick start the clock chip. (hour) */
|
||||
#define MSTK_FREQ_TEST 0x40 /* Frequency test mode. (day) */
|
||||
|
||||
#define MSTK_YEAR_ZERO 1968 /* If year reg has zero, it is 1968. */
|
||||
#define MSTK_CVT_YEAR(yr) ((yr) + MSTK_YEAR_ZERO)
|
||||
|
||||
/* Masks that define how much space each value takes up. */
|
||||
#define MSTK_SEC_MASK 0x7f
|
||||
#define MSTK_MIN_MASK 0x7f
|
||||
#define MSTK_HOUR_MASK 0x3f
|
||||
#define MSTK_DOW_MASK 0x07
|
||||
#define MSTK_DOM_MASK 0x3f
|
||||
#define MSTK_MONTH_MASK 0x1f
|
||||
#define MSTK_YEAR_MASK 0xffU
|
||||
|
||||
/* Binary coded decimal conversion macros. */
|
||||
#define MSTK_REGVAL_TO_DECIMAL(x) (((x) & 0x0F) + 0x0A * ((x) >> 0x04))
|
||||
#define MSTK_DECIMAL_TO_REGVAL(x) ((((x) / 0x0A) << 0x04) + ((x) % 0x0A))
|
||||
|
||||
/* Generic register set and get macros for internal use. */
|
||||
#define MSTK_GET(regs,var,mask) (MSTK_REGVAL_TO_DECIMAL(((struct mostek48t02 *)regs)->var & MSTK_ ## mask ## _MASK))
|
||||
#define MSTK_SET(regs,var,value,mask) do { ((struct mostek48t02 *)regs)->var &= ~(MSTK_ ## mask ## _MASK); ((struct mostek48t02 *)regs)->var |= MSTK_DECIMAL_TO_REGVAL(value) & (MSTK_ ## mask ## _MASK); } while (0)
|
||||
|
||||
/* Macros to make register access easier on our fingers. These give you
|
||||
* the decimal value of the register requested if applicable. You pass
|
||||
* the a pointer to a 'struct mostek48t02'.
|
||||
*/
|
||||
#define MSTK_REG_CREG(regs) (((struct mostek48t02 *)regs)->creg)
|
||||
#define MSTK_REG_SEC(regs) MSTK_GET(regs,sec,SEC)
|
||||
#define MSTK_REG_MIN(regs) MSTK_GET(regs,min,MIN)
|
||||
#define MSTK_REG_HOUR(regs) MSTK_GET(regs,hour,HOUR)
|
||||
#define MSTK_REG_DOW(regs) MSTK_GET(regs,dow,DOW)
|
||||
#define MSTK_REG_DOM(regs) MSTK_GET(regs,dom,DOM)
|
||||
#define MSTK_REG_MONTH(regs) MSTK_GET(regs,month,MONTH)
|
||||
#define MSTK_REG_YEAR(regs) MSTK_GET(regs,year,YEAR)
|
||||
|
||||
#define MSTK_SET_REG_SEC(regs,value) MSTK_SET(regs,sec,value,SEC)
|
||||
#define MSTK_SET_REG_MIN(regs,value) MSTK_SET(regs,min,value,MIN)
|
||||
#define MSTK_SET_REG_HOUR(regs,value) MSTK_SET(regs,hour,value,HOUR)
|
||||
#define MSTK_SET_REG_DOW(regs,value) MSTK_SET(regs,dow,value,DOW)
|
||||
#define MSTK_SET_REG_DOM(regs,value) MSTK_SET(regs,dom,value,DOM)
|
||||
#define MSTK_SET_REG_MONTH(regs,value) MSTK_SET(regs,month,value,MONTH)
|
||||
#define MSTK_SET_REG_YEAR(regs,value) MSTK_SET(regs,year,value,YEAR)
|
||||
|
||||
|
||||
/* The Mostek 48t08 clock chip. Found on Sun4m's I think. It has the
|
||||
* same (basically) layout of the 48t02 chip except for the extra
|
||||
* NVRAM on board (8 KB against the 48t02's 2 KB).
|
||||
*/
|
||||
struct mostek48t08 {
|
||||
char offset[6*1024]; /* Magic things may be here, who knows? */
|
||||
struct mostek48t02 regs; /* Here is what we are interested in. */
|
||||
};
|
||||
|
||||
#ifdef CONFIG_SUN4
|
||||
enum sparc_clock_type { MSTK48T02, MSTK48T08, \
|
||||
INTERSIL, MSTK_INVALID };
|
||||
#ifndef ___ASM_SPARC_MOSTEK_H
|
||||
#define ___ASM_SPARC_MOSTEK_H
|
||||
#if defined(__sparc__) && defined(__arch64__)
|
||||
#include <asm-sparc/mostek_64.h>
|
||||
#else
|
||||
enum sparc_clock_type { MSTK48T02, MSTK48T08, \
|
||||
MSTK_INVALID };
|
||||
#include <asm-sparc/mostek_32.h>
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SUN4
|
||||
/* intersil on a sun 4/260 code data from harris doc */
|
||||
struct intersil_dt {
|
||||
volatile unsigned char int_csec;
|
||||
volatile unsigned char int_hour;
|
||||
volatile unsigned char int_min;
|
||||
volatile unsigned char int_sec;
|
||||
volatile unsigned char int_month;
|
||||
volatile unsigned char int_day;
|
||||
volatile unsigned char int_year;
|
||||
volatile unsigned char int_dow;
|
||||
};
|
||||
|
||||
struct intersil {
|
||||
struct intersil_dt clk;
|
||||
struct intersil_dt cmp;
|
||||
volatile unsigned char int_intr_reg;
|
||||
volatile unsigned char int_cmd_reg;
|
||||
};
|
||||
|
||||
#define INTERSIL_STOP 0x0
|
||||
#define INTERSIL_START 0x8
|
||||
#define INTERSIL_INTR_DISABLE 0x0
|
||||
#define INTERSIL_INTR_ENABLE 0x10
|
||||
#define INTERSIL_32K 0x0
|
||||
#define INTERSIL_NORMAL 0x0
|
||||
#define INTERSIL_24H 0x4
|
||||
#define INTERSIL_INT_100HZ 0x2
|
||||
|
||||
/* end of intersil info */
|
||||
#endif
|
||||
|
||||
#endif /* !(_SPARC_MOSTEK_H) */
|
||||
|
|
171
include/asm-sparc/mostek_32.h
Normal file
171
include/asm-sparc/mostek_32.h
Normal file
|
@ -0,0 +1,171 @@
|
|||
/*
|
||||
* mostek.h: Describes the various Mostek time of day clock registers.
|
||||
*
|
||||
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
|
||||
* Copyright (C) 1996 Thomas K. Dyas (tdyas@eden.rutgers.edu)
|
||||
* Added intersil code 05/25/98 Chris Davis (cdavis@cois.on.ca)
|
||||
*/
|
||||
|
||||
#ifndef _SPARC_MOSTEK_H
|
||||
#define _SPARC_MOSTEK_H
|
||||
|
||||
#include <asm/idprom.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
/* M48T02 Register Map (adapted from Sun NVRAM/Hostid FAQ)
|
||||
*
|
||||
* Data
|
||||
* Address Function
|
||||
* Bit 7 Bit 6 Bit 5 Bit 4Bit 3 Bit 2 Bit 1 Bit 0
|
||||
* 7ff - - - - - - - - Year 00-99
|
||||
* 7fe 0 0 0 - - - - - Month 01-12
|
||||
* 7fd 0 0 - - - - - - Date 01-31
|
||||
* 7fc 0 FT 0 0 0 - - - Day 01-07
|
||||
* 7fb KS 0 - - - - - - Hours 00-23
|
||||
* 7fa 0 - - - - - - - Minutes 00-59
|
||||
* 7f9 ST - - - - - - - Seconds 00-59
|
||||
* 7f8 W R S - - - - - Control
|
||||
*
|
||||
* * ST is STOP BIT
|
||||
* * W is WRITE BIT
|
||||
* * R is READ BIT
|
||||
* * S is SIGN BIT
|
||||
* * FT is FREQ TEST BIT
|
||||
* * KS is KICK START BIT
|
||||
*/
|
||||
|
||||
/* The Mostek 48t02 real time clock and NVRAM chip. The registers
|
||||
* other than the control register are in binary coded decimal. Some
|
||||
* control bits also live outside the control register.
|
||||
*/
|
||||
#define mostek_read(_addr) readb(_addr)
|
||||
#define mostek_write(_addr,_val) writeb(_val, _addr)
|
||||
#define MOSTEK_EEPROM 0x0000UL
|
||||
#define MOSTEK_IDPROM 0x07d8UL
|
||||
#define MOSTEK_CREG 0x07f8UL
|
||||
#define MOSTEK_SEC 0x07f9UL
|
||||
#define MOSTEK_MIN 0x07faUL
|
||||
#define MOSTEK_HOUR 0x07fbUL
|
||||
#define MOSTEK_DOW 0x07fcUL
|
||||
#define MOSTEK_DOM 0x07fdUL
|
||||
#define MOSTEK_MONTH 0x07feUL
|
||||
#define MOSTEK_YEAR 0x07ffUL
|
||||
|
||||
struct mostek48t02 {
|
||||
volatile char eeprom[2008]; /* This is the eeprom, don't touch! */
|
||||
struct idprom idprom; /* The idprom lives here. */
|
||||
volatile unsigned char creg; /* Control register */
|
||||
volatile unsigned char sec; /* Seconds (0-59) */
|
||||
volatile unsigned char min; /* Minutes (0-59) */
|
||||
volatile unsigned char hour; /* Hour (0-23) */
|
||||
volatile unsigned char dow; /* Day of the week (1-7) */
|
||||
volatile unsigned char dom; /* Day of the month (1-31) */
|
||||
volatile unsigned char month; /* Month of year (1-12) */
|
||||
volatile unsigned char year; /* Year (0-99) */
|
||||
};
|
||||
|
||||
extern spinlock_t mostek_lock;
|
||||
extern void __iomem *mstk48t02_regs;
|
||||
|
||||
/* Control register values. */
|
||||
#define MSTK_CREG_WRITE 0x80 /* Must set this before placing values. */
|
||||
#define MSTK_CREG_READ 0x40 /* Stop updates to allow a clean read. */
|
||||
#define MSTK_CREG_SIGN 0x20 /* Slow/speed clock in calibration mode. */
|
||||
|
||||
/* Control bits that live in the other registers. */
|
||||
#define MSTK_STOP 0x80 /* Stop the clock oscillator. (sec) */
|
||||
#define MSTK_KICK_START 0x80 /* Kick start the clock chip. (hour) */
|
||||
#define MSTK_FREQ_TEST 0x40 /* Frequency test mode. (day) */
|
||||
|
||||
#define MSTK_YEAR_ZERO 1968 /* If year reg has zero, it is 1968. */
|
||||
#define MSTK_CVT_YEAR(yr) ((yr) + MSTK_YEAR_ZERO)
|
||||
|
||||
/* Masks that define how much space each value takes up. */
|
||||
#define MSTK_SEC_MASK 0x7f
|
||||
#define MSTK_MIN_MASK 0x7f
|
||||
#define MSTK_HOUR_MASK 0x3f
|
||||
#define MSTK_DOW_MASK 0x07
|
||||
#define MSTK_DOM_MASK 0x3f
|
||||
#define MSTK_MONTH_MASK 0x1f
|
||||
#define MSTK_YEAR_MASK 0xffU
|
||||
|
||||
/* Binary coded decimal conversion macros. */
|
||||
#define MSTK_REGVAL_TO_DECIMAL(x) (((x) & 0x0F) + 0x0A * ((x) >> 0x04))
|
||||
#define MSTK_DECIMAL_TO_REGVAL(x) ((((x) / 0x0A) << 0x04) + ((x) % 0x0A))
|
||||
|
||||
/* Generic register set and get macros for internal use. */
|
||||
#define MSTK_GET(regs,var,mask) (MSTK_REGVAL_TO_DECIMAL(((struct mostek48t02 *)regs)->var & MSTK_ ## mask ## _MASK))
|
||||
#define MSTK_SET(regs,var,value,mask) do { ((struct mostek48t02 *)regs)->var &= ~(MSTK_ ## mask ## _MASK); ((struct mostek48t02 *)regs)->var |= MSTK_DECIMAL_TO_REGVAL(value) & (MSTK_ ## mask ## _MASK); } while (0)
|
||||
|
||||
/* Macros to make register access easier on our fingers. These give you
|
||||
* the decimal value of the register requested if applicable. You pass
|
||||
* the a pointer to a 'struct mostek48t02'.
|
||||
*/
|
||||
#define MSTK_REG_CREG(regs) (((struct mostek48t02 *)regs)->creg)
|
||||
#define MSTK_REG_SEC(regs) MSTK_GET(regs,sec,SEC)
|
||||
#define MSTK_REG_MIN(regs) MSTK_GET(regs,min,MIN)
|
||||
#define MSTK_REG_HOUR(regs) MSTK_GET(regs,hour,HOUR)
|
||||
#define MSTK_REG_DOW(regs) MSTK_GET(regs,dow,DOW)
|
||||
#define MSTK_REG_DOM(regs) MSTK_GET(regs,dom,DOM)
|
||||
#define MSTK_REG_MONTH(regs) MSTK_GET(regs,month,MONTH)
|
||||
#define MSTK_REG_YEAR(regs) MSTK_GET(regs,year,YEAR)
|
||||
|
||||
#define MSTK_SET_REG_SEC(regs,value) MSTK_SET(regs,sec,value,SEC)
|
||||
#define MSTK_SET_REG_MIN(regs,value) MSTK_SET(regs,min,value,MIN)
|
||||
#define MSTK_SET_REG_HOUR(regs,value) MSTK_SET(regs,hour,value,HOUR)
|
||||
#define MSTK_SET_REG_DOW(regs,value) MSTK_SET(regs,dow,value,DOW)
|
||||
#define MSTK_SET_REG_DOM(regs,value) MSTK_SET(regs,dom,value,DOM)
|
||||
#define MSTK_SET_REG_MONTH(regs,value) MSTK_SET(regs,month,value,MONTH)
|
||||
#define MSTK_SET_REG_YEAR(regs,value) MSTK_SET(regs,year,value,YEAR)
|
||||
|
||||
|
||||
/* The Mostek 48t08 clock chip. Found on Sun4m's I think. It has the
|
||||
* same (basically) layout of the 48t02 chip except for the extra
|
||||
* NVRAM on board (8 KB against the 48t02's 2 KB).
|
||||
*/
|
||||
struct mostek48t08 {
|
||||
char offset[6*1024]; /* Magic things may be here, who knows? */
|
||||
struct mostek48t02 regs; /* Here is what we are interested in. */
|
||||
};
|
||||
|
||||
#ifdef CONFIG_SUN4
|
||||
enum sparc_clock_type { MSTK48T02, MSTK48T08, \
|
||||
INTERSIL, MSTK_INVALID };
|
||||
#else
|
||||
enum sparc_clock_type { MSTK48T02, MSTK48T08, \
|
||||
MSTK_INVALID };
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SUN4
|
||||
/* intersil on a sun 4/260 code data from harris doc */
|
||||
struct intersil_dt {
|
||||
volatile unsigned char int_csec;
|
||||
volatile unsigned char int_hour;
|
||||
volatile unsigned char int_min;
|
||||
volatile unsigned char int_sec;
|
||||
volatile unsigned char int_month;
|
||||
volatile unsigned char int_day;
|
||||
volatile unsigned char int_year;
|
||||
volatile unsigned char int_dow;
|
||||
};
|
||||
|
||||
struct intersil {
|
||||
struct intersil_dt clk;
|
||||
struct intersil_dt cmp;
|
||||
volatile unsigned char int_intr_reg;
|
||||
volatile unsigned char int_cmd_reg;
|
||||
};
|
||||
|
||||
#define INTERSIL_STOP 0x0
|
||||
#define INTERSIL_START 0x8
|
||||
#define INTERSIL_INTR_DISABLE 0x0
|
||||
#define INTERSIL_INTR_ENABLE 0x10
|
||||
#define INTERSIL_32K 0x0
|
||||
#define INTERSIL_NORMAL 0x0
|
||||
#define INTERSIL_24H 0x4
|
||||
#define INTERSIL_INT_100HZ 0x2
|
||||
|
||||
/* end of intersil info */
|
||||
#endif
|
||||
|
||||
#endif /* !(_SPARC_MOSTEK_H) */
|
143
include/asm-sparc/mostek_64.h
Normal file
143
include/asm-sparc/mostek_64.h
Normal file
|
@ -0,0 +1,143 @@
|
|||
/* mostek.h: Describes the various Mostek time of day clock registers.
|
||||
*
|
||||
* Copyright (C) 1995 David S. Miller (davem@davemloft.net)
|
||||
* Copyright (C) 1996 Thomas K. Dyas (tdyas@eden.rutgers.edu)
|
||||
*/
|
||||
|
||||
#ifndef _SPARC64_MOSTEK_H
|
||||
#define _SPARC64_MOSTEK_H
|
||||
|
||||
#include <asm/idprom.h>
|
||||
|
||||
/* M48T02 Register Map (adapted from Sun NVRAM/Hostid FAQ)
|
||||
*
|
||||
* Data
|
||||
* Address Function
|
||||
* Bit 7 Bit 6 Bit 5 Bit 4Bit 3 Bit 2 Bit 1 Bit 0
|
||||
* 7ff - - - - - - - - Year 00-99
|
||||
* 7fe 0 0 0 - - - - - Month 01-12
|
||||
* 7fd 0 0 - - - - - - Date 01-31
|
||||
* 7fc 0 FT 0 0 0 - - - Day 01-07
|
||||
* 7fb KS 0 - - - - - - Hours 00-23
|
||||
* 7fa 0 - - - - - - - Minutes 00-59
|
||||
* 7f9 ST - - - - - - - Seconds 00-59
|
||||
* 7f8 W R S - - - - - Control
|
||||
*
|
||||
* * ST is STOP BIT
|
||||
* * W is WRITE BIT
|
||||
* * R is READ BIT
|
||||
* * S is SIGN BIT
|
||||
* * FT is FREQ TEST BIT
|
||||
* * KS is KICK START BIT
|
||||
*/
|
||||
|
||||
/* The Mostek 48t02 real time clock and NVRAM chip. The registers
|
||||
* other than the control register are in binary coded decimal. Some
|
||||
* control bits also live outside the control register.
|
||||
*
|
||||
* We now deal with physical addresses for I/O to the chip. -DaveM
|
||||
*/
|
||||
static inline u8 mostek_read(void __iomem *addr)
|
||||
{
|
||||
u8 ret;
|
||||
|
||||
__asm__ __volatile__("lduba [%1] %2, %0"
|
||||
: "=r" (ret)
|
||||
: "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline void mostek_write(void __iomem *addr, u8 val)
|
||||
{
|
||||
__asm__ __volatile__("stba %0, [%1] %2"
|
||||
: /* no outputs */
|
||||
: "r" (val), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
|
||||
}
|
||||
|
||||
#define MOSTEK_EEPROM 0x0000UL
|
||||
#define MOSTEK_IDPROM 0x07d8UL
|
||||
#define MOSTEK_CREG 0x07f8UL
|
||||
#define MOSTEK_SEC 0x07f9UL
|
||||
#define MOSTEK_MIN 0x07faUL
|
||||
#define MOSTEK_HOUR 0x07fbUL
|
||||
#define MOSTEK_DOW 0x07fcUL
|
||||
#define MOSTEK_DOM 0x07fdUL
|
||||
#define MOSTEK_MONTH 0x07feUL
|
||||
#define MOSTEK_YEAR 0x07ffUL
|
||||
|
||||
extern spinlock_t mostek_lock;
|
||||
extern void __iomem *mstk48t02_regs;
|
||||
|
||||
/* Control register values. */
|
||||
#define MSTK_CREG_WRITE 0x80 /* Must set this before placing values. */
|
||||
#define MSTK_CREG_READ 0x40 /* Stop updates to allow a clean read. */
|
||||
#define MSTK_CREG_SIGN 0x20 /* Slow/speed clock in calibration mode. */
|
||||
|
||||
/* Control bits that live in the other registers. */
|
||||
#define MSTK_STOP 0x80 /* Stop the clock oscillator. (sec) */
|
||||
#define MSTK_KICK_START 0x80 /* Kick start the clock chip. (hour) */
|
||||
#define MSTK_FREQ_TEST 0x40 /* Frequency test mode. (day) */
|
||||
|
||||
#define MSTK_YEAR_ZERO 1968 /* If year reg has zero, it is 1968. */
|
||||
#define MSTK_CVT_YEAR(yr) ((yr) + MSTK_YEAR_ZERO)
|
||||
|
||||
/* Masks that define how much space each value takes up. */
|
||||
#define MSTK_SEC_MASK 0x7f
|
||||
#define MSTK_MIN_MASK 0x7f
|
||||
#define MSTK_HOUR_MASK 0x3f
|
||||
#define MSTK_DOW_MASK 0x07
|
||||
#define MSTK_DOM_MASK 0x3f
|
||||
#define MSTK_MONTH_MASK 0x1f
|
||||
#define MSTK_YEAR_MASK 0xffU
|
||||
|
||||
/* Binary coded decimal conversion macros. */
|
||||
#define MSTK_REGVAL_TO_DECIMAL(x) (((x) & 0x0F) + 0x0A * ((x) >> 0x04))
|
||||
#define MSTK_DECIMAL_TO_REGVAL(x) ((((x) / 0x0A) << 0x04) + ((x) % 0x0A))
|
||||
|
||||
/* Generic register set and get macros for internal use. */
|
||||
#define MSTK_GET(regs,name) \
|
||||
(MSTK_REGVAL_TO_DECIMAL(mostek_read(regs + MOSTEK_ ## name) & MSTK_ ## name ## _MASK))
|
||||
#define MSTK_SET(regs,name,value) \
|
||||
do { u8 __val = mostek_read(regs + MOSTEK_ ## name); \
|
||||
__val &= ~(MSTK_ ## name ## _MASK); \
|
||||
__val |= (MSTK_DECIMAL_TO_REGVAL(value) & \
|
||||
(MSTK_ ## name ## _MASK)); \
|
||||
mostek_write(regs + MOSTEK_ ## name, __val); \
|
||||
} while(0)
|
||||
|
||||
/* Macros to make register access easier on our fingers. These give you
|
||||
* the decimal value of the register requested if applicable. You pass
|
||||
* the a pointer to a 'struct mostek48t02'.
|
||||
*/
|
||||
#define MSTK_REG_CREG(regs) (mostek_read((regs) + MOSTEK_CREG))
|
||||
#define MSTK_REG_SEC(regs) MSTK_GET(regs,SEC)
|
||||
#define MSTK_REG_MIN(regs) MSTK_GET(regs,MIN)
|
||||
#define MSTK_REG_HOUR(regs) MSTK_GET(regs,HOUR)
|
||||
#define MSTK_REG_DOW(regs) MSTK_GET(regs,DOW)
|
||||
#define MSTK_REG_DOM(regs) MSTK_GET(regs,DOM)
|
||||
#define MSTK_REG_MONTH(regs) MSTK_GET(regs,MONTH)
|
||||
#define MSTK_REG_YEAR(regs) MSTK_GET(regs,YEAR)
|
||||
|
||||
#define MSTK_SET_REG_SEC(regs,value) MSTK_SET(regs,SEC,value)
|
||||
#define MSTK_SET_REG_MIN(regs,value) MSTK_SET(regs,MIN,value)
|
||||
#define MSTK_SET_REG_HOUR(regs,value) MSTK_SET(regs,HOUR,value)
|
||||
#define MSTK_SET_REG_DOW(regs,value) MSTK_SET(regs,DOW,value)
|
||||
#define MSTK_SET_REG_DOM(regs,value) MSTK_SET(regs,DOM,value)
|
||||
#define MSTK_SET_REG_MONTH(regs,value) MSTK_SET(regs,MONTH,value)
|
||||
#define MSTK_SET_REG_YEAR(regs,value) MSTK_SET(regs,YEAR,value)
|
||||
|
||||
|
||||
/* The Mostek 48t08 clock chip. Found on Sun4m's I think. It has the
|
||||
* same (basically) layout of the 48t02 chip except for the extra
|
||||
* NVRAM on board (8 KB against the 48t02's 2 KB).
|
||||
*/
|
||||
#define MOSTEK_48T08_OFFSET 0x0000UL /* Lower NVRAM portions */
|
||||
#define MOSTEK_48T08_48T02 0x1800UL /* Offset to 48T02 chip */
|
||||
|
||||
/* SUN5 systems usually have 48t59 model clock chipsets. But we keep the older
|
||||
* clock chip definitions around just in case.
|
||||
*/
|
||||
#define MOSTEK_48T59_OFFSET 0x0000UL /* Lower NVRAM portions */
|
||||
#define MOSTEK_48T59_48T02 0x1800UL /* Offset to 48T02 chip */
|
||||
|
||||
#endif /* !(_SPARC64_MOSTEK_H) */
|
|
@ -1,13 +1,8 @@
|
|||
/*
|
||||
* linux/include/asm-sparc/namei.h
|
||||
*
|
||||
* Routines to handle famous /usr/gnemul/s*.
|
||||
* Included from linux/fs/namei.c
|
||||
*/
|
||||
|
||||
#ifndef __SPARC_NAMEI_H
|
||||
#define __SPARC_NAMEI_H
|
||||
|
||||
#define __emul_prefix() NULL
|
||||
|
||||
#endif /* __SPARC_NAMEI_H */
|
||||
#ifndef ___ASM_SPARC_NAMEI_H
|
||||
#define ___ASM_SPARC_NAMEI_H
|
||||
#if defined(__sparc__) && defined(__arch64__)
|
||||
#include <asm-sparc/namei_64.h>
|
||||
#else
|
||||
#include <asm-sparc/namei_32.h>
|
||||
#endif
|
||||
#endif
|
||||
|
|
13
include/asm-sparc/namei_32.h
Normal file
13
include/asm-sparc/namei_32.h
Normal file
|
@ -0,0 +1,13 @@
|
|||
/*
|
||||
* linux/include/asm-sparc/namei.h
|
||||
*
|
||||
* Routines to handle famous /usr/gnemul/s*.
|
||||
* Included from linux/fs/namei.c
|
||||
*/
|
||||
|
||||
#ifndef __SPARC_NAMEI_H
|
||||
#define __SPARC_NAMEI_H
|
||||
|
||||
#define __emul_prefix() NULL
|
||||
|
||||
#endif /* __SPARC_NAMEI_H */
|
13
include/asm-sparc/namei_64.h
Normal file
13
include/asm-sparc/namei_64.h
Normal file
|
@ -0,0 +1,13 @@
|
|||
/*
|
||||
* linux/include/asm-sparc64/namei.h
|
||||
*
|
||||
* Routines to handle famous /usr/gnemul/s*.
|
||||
* Included from linux/fs/namei.c
|
||||
*/
|
||||
|
||||
#ifndef __SPARC64_NAMEI_H
|
||||
#define __SPARC64_NAMEI_H
|
||||
|
||||
#define __emul_prefix() NULL
|
||||
|
||||
#endif /* __SPARC64_NAMEI_H */
|
|
@ -1,24 +1,8 @@
|
|||
#ifndef _ASM_SPARC_OF_PLATFORM_H
|
||||
#define _ASM_SPARC_OF_PLATFORM_H
|
||||
/*
|
||||
* Copyright (C) 2006 Benjamin Herrenschmidt, IBM Corp.
|
||||
* <benh@kernel.crashing.org>
|
||||
* Modified for Sparc by merging parts of asm-sparc/of_device.h
|
||||
* by Stephen Rothwell
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version
|
||||
* 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
*/
|
||||
|
||||
/* This is just here during the transition */
|
||||
#include <linux/of_platform.h>
|
||||
|
||||
extern struct bus_type ebus_bus_type;
|
||||
extern struct bus_type sbus_bus_type;
|
||||
|
||||
#define of_bus_type of_platform_bus_type /* for compatibility */
|
||||
|
||||
#endif /* _ASM_SPARC_OF_PLATFORM_H */
|
||||
#ifndef ___ASM_SPARC_OF_PLATFORM_H
|
||||
#define ___ASM_SPARC_OF_PLATFORM_H
|
||||
#if defined(__sparc__) && defined(__arch64__)
|
||||
#include <asm-sparc/of_platform_64.h>
|
||||
#else
|
||||
#include <asm-sparc/of_platform_32.h>
|
||||
#endif
|
||||
#endif
|
||||
|
|
24
include/asm-sparc/of_platform_32.h
Normal file
24
include/asm-sparc/of_platform_32.h
Normal file
|
@ -0,0 +1,24 @@
|
|||
#ifndef _ASM_SPARC_OF_PLATFORM_H
|
||||
#define _ASM_SPARC_OF_PLATFORM_H
|
||||
/*
|
||||
* Copyright (C) 2006 Benjamin Herrenschmidt, IBM Corp.
|
||||
* <benh@kernel.crashing.org>
|
||||
* Modified for Sparc by merging parts of asm-sparc/of_device.h
|
||||
* by Stephen Rothwell
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version
|
||||
* 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
*/
|
||||
|
||||
/* This is just here during the transition */
|
||||
#include <linux/of_platform.h>
|
||||
|
||||
extern struct bus_type ebus_bus_type;
|
||||
extern struct bus_type sbus_bus_type;
|
||||
|
||||
#define of_bus_type of_platform_bus_type /* for compatibility */
|
||||
|
||||
#endif /* _ASM_SPARC_OF_PLATFORM_H */
|
25
include/asm-sparc/of_platform_64.h
Normal file
25
include/asm-sparc/of_platform_64.h
Normal file
|
@ -0,0 +1,25 @@
|
|||
#ifndef _ASM_SPARC64_OF_PLATFORM_H
|
||||
#define _ASM_SPARC64_OF_PLATFORM_H
|
||||
/*
|
||||
* Copyright (C) 2006 Benjamin Herrenschmidt, IBM Corp.
|
||||
* <benh@kernel.crashing.org>
|
||||
* Modified for Sparc by merging parts of asm-sparc/of_device.h
|
||||
* by Stephen Rothwell
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version
|
||||
* 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
*/
|
||||
|
||||
/* This is just here during the transition */
|
||||
#include <linux/of_platform.h>
|
||||
|
||||
extern struct bus_type isa_bus_type;
|
||||
extern struct bus_type ebus_bus_type;
|
||||
extern struct bus_type sbus_bus_type;
|
||||
|
||||
#define of_bus_type of_platform_bus_type /* for compatibility */
|
||||
|
||||
#endif /* _ASM_SPARC64_OF_PLATFORM_H */
|
|
@ -1,255 +1,8 @@
|
|||
#ifndef __SPARC_OPENPROM_H
|
||||
#define __SPARC_OPENPROM_H
|
||||
|
||||
/* openprom.h: Prom structures and defines for access to the OPENBOOT
|
||||
* prom routines and data areas.
|
||||
*
|
||||
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
|
||||
*/
|
||||
|
||||
/* Empirical constants... */
|
||||
#define LINUX_OPPROM_MAGIC 0x10010407
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
/* V0 prom device operations. */
|
||||
struct linux_dev_v0_funcs {
|
||||
int (*v0_devopen)(char *device_str);
|
||||
int (*v0_devclose)(int dev_desc);
|
||||
int (*v0_rdblkdev)(int dev_desc, int num_blks, int blk_st, char *buf);
|
||||
int (*v0_wrblkdev)(int dev_desc, int num_blks, int blk_st, char *buf);
|
||||
int (*v0_wrnetdev)(int dev_desc, int num_bytes, char *buf);
|
||||
int (*v0_rdnetdev)(int dev_desc, int num_bytes, char *buf);
|
||||
int (*v0_rdchardev)(int dev_desc, int num_bytes, int dummy, char *buf);
|
||||
int (*v0_wrchardev)(int dev_desc, int num_bytes, int dummy, char *buf);
|
||||
int (*v0_seekdev)(int dev_desc, long logical_offst, int from);
|
||||
};
|
||||
|
||||
/* V2 and later prom device operations. */
|
||||
struct linux_dev_v2_funcs {
|
||||
int (*v2_inst2pkg)(int d); /* Convert ihandle to phandle */
|
||||
char * (*v2_dumb_mem_alloc)(char *va, unsigned sz);
|
||||
void (*v2_dumb_mem_free)(char *va, unsigned sz);
|
||||
|
||||
/* To map devices into virtual I/O space. */
|
||||
char * (*v2_dumb_mmap)(char *virta, int which_io, unsigned paddr, unsigned sz);
|
||||
void (*v2_dumb_munmap)(char *virta, unsigned size);
|
||||
|
||||
int (*v2_dev_open)(char *devpath);
|
||||
void (*v2_dev_close)(int d);
|
||||
int (*v2_dev_read)(int d, char *buf, int nbytes);
|
||||
int (*v2_dev_write)(int d, char *buf, int nbytes);
|
||||
int (*v2_dev_seek)(int d, int hi, int lo);
|
||||
|
||||
/* Never issued (multistage load support) */
|
||||
void (*v2_wheee2)(void);
|
||||
void (*v2_wheee3)(void);
|
||||
};
|
||||
|
||||
struct linux_mlist_v0 {
|
||||
struct linux_mlist_v0 *theres_more;
|
||||
char *start_adr;
|
||||
unsigned num_bytes;
|
||||
};
|
||||
|
||||
struct linux_mem_v0 {
|
||||
struct linux_mlist_v0 **v0_totphys;
|
||||
struct linux_mlist_v0 **v0_prommap;
|
||||
struct linux_mlist_v0 **v0_available; /* What we can use */
|
||||
};
|
||||
|
||||
/* Arguments sent to the kernel from the boot prompt. */
|
||||
struct linux_arguments_v0 {
|
||||
char *argv[8];
|
||||
char args[100];
|
||||
char boot_dev[2];
|
||||
int boot_dev_ctrl;
|
||||
int boot_dev_unit;
|
||||
int dev_partition;
|
||||
char *kernel_file_name;
|
||||
void *aieee1; /* XXX */
|
||||
};
|
||||
|
||||
/* V2 and up boot things. */
|
||||
struct linux_bootargs_v2 {
|
||||
char **bootpath;
|
||||
char **bootargs;
|
||||
int *fd_stdin;
|
||||
int *fd_stdout;
|
||||
};
|
||||
|
||||
/* The top level PROM vector. */
|
||||
struct linux_romvec {
|
||||
/* Version numbers. */
|
||||
unsigned int pv_magic_cookie;
|
||||
unsigned int pv_romvers;
|
||||
unsigned int pv_plugin_revision;
|
||||
unsigned int pv_printrev;
|
||||
|
||||
/* Version 0 memory descriptors. */
|
||||
struct linux_mem_v0 pv_v0mem;
|
||||
|
||||
/* Node operations. */
|
||||
struct linux_nodeops *pv_nodeops;
|
||||
|
||||
char **pv_bootstr;
|
||||
struct linux_dev_v0_funcs pv_v0devops;
|
||||
|
||||
char *pv_stdin;
|
||||
char *pv_stdout;
|
||||
#define PROMDEV_KBD 0 /* input from keyboard */
|
||||
#define PROMDEV_SCREEN 0 /* output to screen */
|
||||
#define PROMDEV_TTYA 1 /* in/out to ttya */
|
||||
#define PROMDEV_TTYB 2 /* in/out to ttyb */
|
||||
|
||||
/* Blocking getchar/putchar. NOT REENTRANT! (grr) */
|
||||
int (*pv_getchar)(void);
|
||||
void (*pv_putchar)(int ch);
|
||||
|
||||
/* Non-blocking variants. */
|
||||
int (*pv_nbgetchar)(void);
|
||||
int (*pv_nbputchar)(int ch);
|
||||
|
||||
void (*pv_putstr)(char *str, int len);
|
||||
|
||||
/* Miscellany. */
|
||||
void (*pv_reboot)(char *bootstr);
|
||||
void (*pv_printf)(__const__ char *fmt, ...);
|
||||
void (*pv_abort)(void);
|
||||
__volatile__ int *pv_ticks;
|
||||
void (*pv_halt)(void);
|
||||
void (**pv_synchook)(void);
|
||||
|
||||
/* Evaluate a forth string, not different proto for V0 and V2->up. */
|
||||
union {
|
||||
void (*v0_eval)(int len, char *str);
|
||||
void (*v2_eval)(char *str);
|
||||
} pv_fortheval;
|
||||
|
||||
struct linux_arguments_v0 **pv_v0bootargs;
|
||||
|
||||
/* Get ether address. */
|
||||
unsigned int (*pv_enaddr)(int d, char *enaddr);
|
||||
|
||||
struct linux_bootargs_v2 pv_v2bootargs;
|
||||
struct linux_dev_v2_funcs pv_v2devops;
|
||||
|
||||
int filler[15];
|
||||
|
||||
/* This one is sun4c/sun4 only. */
|
||||
void (*pv_setctxt)(int ctxt, char *va, int pmeg);
|
||||
|
||||
/* Prom version 3 Multiprocessor routines. This stuff is crazy.
|
||||
* No joke. Calling these when there is only one cpu probably
|
||||
* crashes the machine, have to test this. :-)
|
||||
*/
|
||||
|
||||
/* v3_cpustart() will start the cpu 'whichcpu' in mmu-context
|
||||
* 'thiscontext' executing at address 'prog_counter'
|
||||
*/
|
||||
int (*v3_cpustart)(unsigned int whichcpu, int ctxtbl_ptr,
|
||||
int thiscontext, char *prog_counter);
|
||||
|
||||
/* v3_cpustop() will cause cpu 'whichcpu' to stop executing
|
||||
* until a resume cpu call is made.
|
||||
*/
|
||||
int (*v3_cpustop)(unsigned int whichcpu);
|
||||
|
||||
/* v3_cpuidle() will idle cpu 'whichcpu' until a stop or
|
||||
* resume cpu call is made.
|
||||
*/
|
||||
int (*v3_cpuidle)(unsigned int whichcpu);
|
||||
|
||||
/* v3_cpuresume() will resume processor 'whichcpu' executing
|
||||
* starting with whatever 'pc' and 'npc' were left at the
|
||||
* last 'idle' or 'stop' call.
|
||||
*/
|
||||
int (*v3_cpuresume)(unsigned int whichcpu);
|
||||
};
|
||||
|
||||
/* Routines for traversing the prom device tree. */
|
||||
struct linux_nodeops {
|
||||
int (*no_nextnode)(int node);
|
||||
int (*no_child)(int node);
|
||||
int (*no_proplen)(int node, char *name);
|
||||
int (*no_getprop)(int node, char *name, char *val);
|
||||
int (*no_setprop)(int node, char *name, char *val, int len);
|
||||
char * (*no_nextprop)(int node, char *name);
|
||||
};
|
||||
|
||||
/* More fun PROM structures for device probing. */
|
||||
#define PROMREG_MAX 16
|
||||
#define PROMVADDR_MAX 16
|
||||
#define PROMINTR_MAX 15
|
||||
|
||||
struct linux_prom_registers {
|
||||
unsigned int which_io; /* is this in OBIO space? */
|
||||
unsigned int phys_addr; /* The physical address of this register */
|
||||
unsigned int reg_size; /* How many bytes does this register take up? */
|
||||
};
|
||||
|
||||
struct linux_prom_irqs {
|
||||
int pri; /* IRQ priority */
|
||||
int vector; /* This is foobar, what does it do? */
|
||||
};
|
||||
|
||||
/* Element of the "ranges" vector */
|
||||
struct linux_prom_ranges {
|
||||
unsigned int ot_child_space;
|
||||
unsigned int ot_child_base; /* Bus feels this */
|
||||
unsigned int ot_parent_space;
|
||||
unsigned int ot_parent_base; /* CPU looks from here */
|
||||
unsigned int or_size;
|
||||
};
|
||||
|
||||
/* Ranges and reg properties are a bit different for PCI. */
|
||||
struct linux_prom_pci_registers {
|
||||
/*
|
||||
* We don't know what information this field contain.
|
||||
* We guess, PCI device function is in bits 15:8
|
||||
* So, ...
|
||||
*/
|
||||
unsigned int which_io; /* Let it be which_io */
|
||||
|
||||
unsigned int phys_hi;
|
||||
unsigned int phys_lo;
|
||||
|
||||
unsigned int size_hi;
|
||||
unsigned int size_lo;
|
||||
};
|
||||
|
||||
struct linux_prom_pci_ranges {
|
||||
unsigned int child_phys_hi; /* Only certain bits are encoded here. */
|
||||
unsigned int child_phys_mid;
|
||||
unsigned int child_phys_lo;
|
||||
|
||||
unsigned int parent_phys_hi;
|
||||
unsigned int parent_phys_lo;
|
||||
|
||||
unsigned int size_hi;
|
||||
unsigned int size_lo;
|
||||
};
|
||||
|
||||
struct linux_prom_pci_assigned_addresses {
|
||||
unsigned int which_io;
|
||||
|
||||
unsigned int phys_hi;
|
||||
unsigned int phys_lo;
|
||||
|
||||
unsigned int size_hi;
|
||||
unsigned int size_lo;
|
||||
};
|
||||
|
||||
struct linux_prom_ebus_ranges {
|
||||
unsigned int child_phys_hi;
|
||||
unsigned int child_phys_lo;
|
||||
|
||||
unsigned int parent_phys_hi;
|
||||
unsigned int parent_phys_mid;
|
||||
unsigned int parent_phys_lo;
|
||||
|
||||
unsigned int size;
|
||||
};
|
||||
|
||||
#endif /* !(__ASSEMBLY__) */
|
||||
|
||||
#endif /* !(__SPARC_OPENPROM_H) */
|
||||
#ifndef ___ASM_SPARC_OPENPROM_H
|
||||
#define ___ASM_SPARC_OPENPROM_H
|
||||
#if defined(__sparc__) && defined(__arch64__)
|
||||
#include <asm-sparc/openprom_64.h>
|
||||
#else
|
||||
#include <asm-sparc/openprom_32.h>
|
||||
#endif
|
||||
#endif
|
||||
|
|
255
include/asm-sparc/openprom_32.h
Normal file
255
include/asm-sparc/openprom_32.h
Normal file
|
@ -0,0 +1,255 @@
|
|||
#ifndef __SPARC_OPENPROM_H
|
||||
#define __SPARC_OPENPROM_H
|
||||
|
||||
/* openprom.h: Prom structures and defines for access to the OPENBOOT
|
||||
* prom routines and data areas.
|
||||
*
|
||||
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
|
||||
*/
|
||||
|
||||
/* Empirical constants... */
|
||||
#define LINUX_OPPROM_MAGIC 0x10010407
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
/* V0 prom device operations. */
|
||||
struct linux_dev_v0_funcs {
|
||||
int (*v0_devopen)(char *device_str);
|
||||
int (*v0_devclose)(int dev_desc);
|
||||
int (*v0_rdblkdev)(int dev_desc, int num_blks, int blk_st, char *buf);
|
||||
int (*v0_wrblkdev)(int dev_desc, int num_blks, int blk_st, char *buf);
|
||||
int (*v0_wrnetdev)(int dev_desc, int num_bytes, char *buf);
|
||||
int (*v0_rdnetdev)(int dev_desc, int num_bytes, char *buf);
|
||||
int (*v0_rdchardev)(int dev_desc, int num_bytes, int dummy, char *buf);
|
||||
int (*v0_wrchardev)(int dev_desc, int num_bytes, int dummy, char *buf);
|
||||
int (*v0_seekdev)(int dev_desc, long logical_offst, int from);
|
||||
};
|
||||
|
||||
/* V2 and later prom device operations. */
|
||||
struct linux_dev_v2_funcs {
|
||||
int (*v2_inst2pkg)(int d); /* Convert ihandle to phandle */
|
||||
char * (*v2_dumb_mem_alloc)(char *va, unsigned sz);
|
||||
void (*v2_dumb_mem_free)(char *va, unsigned sz);
|
||||
|
||||
/* To map devices into virtual I/O space. */
|
||||
char * (*v2_dumb_mmap)(char *virta, int which_io, unsigned paddr, unsigned sz);
|
||||
void (*v2_dumb_munmap)(char *virta, unsigned size);
|
||||
|
||||
int (*v2_dev_open)(char *devpath);
|
||||
void (*v2_dev_close)(int d);
|
||||
int (*v2_dev_read)(int d, char *buf, int nbytes);
|
||||
int (*v2_dev_write)(int d, char *buf, int nbytes);
|
||||
int (*v2_dev_seek)(int d, int hi, int lo);
|
||||
|
||||
/* Never issued (multistage load support) */
|
||||
void (*v2_wheee2)(void);
|
||||
void (*v2_wheee3)(void);
|
||||
};
|
||||
|
||||
struct linux_mlist_v0 {
|
||||
struct linux_mlist_v0 *theres_more;
|
||||
char *start_adr;
|
||||
unsigned num_bytes;
|
||||
};
|
||||
|
||||
struct linux_mem_v0 {
|
||||
struct linux_mlist_v0 **v0_totphys;
|
||||
struct linux_mlist_v0 **v0_prommap;
|
||||
struct linux_mlist_v0 **v0_available; /* What we can use */
|
||||
};
|
||||
|
||||
/* Arguments sent to the kernel from the boot prompt. */
|
||||
struct linux_arguments_v0 {
|
||||
char *argv[8];
|
||||
char args[100];
|
||||
char boot_dev[2];
|
||||
int boot_dev_ctrl;
|
||||
int boot_dev_unit;
|
||||
int dev_partition;
|
||||
char *kernel_file_name;
|
||||
void *aieee1; /* XXX */
|
||||
};
|
||||
|
||||
/* V2 and up boot things. */
|
||||
struct linux_bootargs_v2 {
|
||||
char **bootpath;
|
||||
char **bootargs;
|
||||
int *fd_stdin;
|
||||
int *fd_stdout;
|
||||
};
|
||||
|
||||
/* The top level PROM vector. */
|
||||
struct linux_romvec {
|
||||
/* Version numbers. */
|
||||
unsigned int pv_magic_cookie;
|
||||
unsigned int pv_romvers;
|
||||
unsigned int pv_plugin_revision;
|
||||
unsigned int pv_printrev;
|
||||
|
||||
/* Version 0 memory descriptors. */
|
||||
struct linux_mem_v0 pv_v0mem;
|
||||
|
||||
/* Node operations. */
|
||||
struct linux_nodeops *pv_nodeops;
|
||||
|
||||
char **pv_bootstr;
|
||||
struct linux_dev_v0_funcs pv_v0devops;
|
||||
|
||||
char *pv_stdin;
|
||||
char *pv_stdout;
|
||||
#define PROMDEV_KBD 0 /* input from keyboard */
|
||||
#define PROMDEV_SCREEN 0 /* output to screen */
|
||||
#define PROMDEV_TTYA 1 /* in/out to ttya */
|
||||
#define PROMDEV_TTYB 2 /* in/out to ttyb */
|
||||
|
||||
/* Blocking getchar/putchar. NOT REENTRANT! (grr) */
|
||||
int (*pv_getchar)(void);
|
||||
void (*pv_putchar)(int ch);
|
||||
|
||||
/* Non-blocking variants. */
|
||||
int (*pv_nbgetchar)(void);
|
||||
int (*pv_nbputchar)(int ch);
|
||||
|
||||
void (*pv_putstr)(char *str, int len);
|
||||
|
||||
/* Miscellany. */
|
||||
void (*pv_reboot)(char *bootstr);
|
||||
void (*pv_printf)(__const__ char *fmt, ...);
|
||||
void (*pv_abort)(void);
|
||||
__volatile__ int *pv_ticks;
|
||||
void (*pv_halt)(void);
|
||||
void (**pv_synchook)(void);
|
||||
|
||||
/* Evaluate a forth string, not different proto for V0 and V2->up. */
|
||||
union {
|
||||
void (*v0_eval)(int len, char *str);
|
||||
void (*v2_eval)(char *str);
|
||||
} pv_fortheval;
|
||||
|
||||
struct linux_arguments_v0 **pv_v0bootargs;
|
||||
|
||||
/* Get ether address. */
|
||||
unsigned int (*pv_enaddr)(int d, char *enaddr);
|
||||
|
||||
struct linux_bootargs_v2 pv_v2bootargs;
|
||||
struct linux_dev_v2_funcs pv_v2devops;
|
||||
|
||||
int filler[15];
|
||||
|
||||
/* This one is sun4c/sun4 only. */
|
||||
void (*pv_setctxt)(int ctxt, char *va, int pmeg);
|
||||
|
||||
/* Prom version 3 Multiprocessor routines. This stuff is crazy.
|
||||
* No joke. Calling these when there is only one cpu probably
|
||||
* crashes the machine, have to test this. :-)
|
||||
*/
|
||||
|
||||
/* v3_cpustart() will start the cpu 'whichcpu' in mmu-context
|
||||
* 'thiscontext' executing at address 'prog_counter'
|
||||
*/
|
||||
int (*v3_cpustart)(unsigned int whichcpu, int ctxtbl_ptr,
|
||||
int thiscontext, char *prog_counter);
|
||||
|
||||
/* v3_cpustop() will cause cpu 'whichcpu' to stop executing
|
||||
* until a resume cpu call is made.
|
||||
*/
|
||||
int (*v3_cpustop)(unsigned int whichcpu);
|
||||
|
||||
/* v3_cpuidle() will idle cpu 'whichcpu' until a stop or
|
||||
* resume cpu call is made.
|
||||
*/
|
||||
int (*v3_cpuidle)(unsigned int whichcpu);
|
||||
|
||||
/* v3_cpuresume() will resume processor 'whichcpu' executing
|
||||
* starting with whatever 'pc' and 'npc' were left at the
|
||||
* last 'idle' or 'stop' call.
|
||||
*/
|
||||
int (*v3_cpuresume)(unsigned int whichcpu);
|
||||
};
|
||||
|
||||
/* Routines for traversing the prom device tree. */
|
||||
struct linux_nodeops {
|
||||
int (*no_nextnode)(int node);
|
||||
int (*no_child)(int node);
|
||||
int (*no_proplen)(int node, char *name);
|
||||
int (*no_getprop)(int node, char *name, char *val);
|
||||
int (*no_setprop)(int node, char *name, char *val, int len);
|
||||
char * (*no_nextprop)(int node, char *name);
|
||||
};
|
||||
|
||||
/* More fun PROM structures for device probing. */
|
||||
#define PROMREG_MAX 16
|
||||
#define PROMVADDR_MAX 16
|
||||
#define PROMINTR_MAX 15
|
||||
|
||||
struct linux_prom_registers {
|
||||
unsigned int which_io; /* is this in OBIO space? */
|
||||
unsigned int phys_addr; /* The physical address of this register */
|
||||
unsigned int reg_size; /* How many bytes does this register take up? */
|
||||
};
|
||||
|
||||
struct linux_prom_irqs {
|
||||
int pri; /* IRQ priority */
|
||||
int vector; /* This is foobar, what does it do? */
|
||||
};
|
||||
|
||||
/* Element of the "ranges" vector */
|
||||
struct linux_prom_ranges {
|
||||
unsigned int ot_child_space;
|
||||
unsigned int ot_child_base; /* Bus feels this */
|
||||
unsigned int ot_parent_space;
|
||||
unsigned int ot_parent_base; /* CPU looks from here */
|
||||
unsigned int or_size;
|
||||
};
|
||||
|
||||
/* Ranges and reg properties are a bit different for PCI. */
|
||||
struct linux_prom_pci_registers {
|
||||
/*
|
||||
* We don't know what information this field contain.
|
||||
* We guess, PCI device function is in bits 15:8
|
||||
* So, ...
|
||||
*/
|
||||
unsigned int which_io; /* Let it be which_io */
|
||||
|
||||
unsigned int phys_hi;
|
||||
unsigned int phys_lo;
|
||||
|
||||
unsigned int size_hi;
|
||||
unsigned int size_lo;
|
||||
};
|
||||
|
||||
struct linux_prom_pci_ranges {
|
||||
unsigned int child_phys_hi; /* Only certain bits are encoded here. */
|
||||
unsigned int child_phys_mid;
|
||||
unsigned int child_phys_lo;
|
||||
|
||||
unsigned int parent_phys_hi;
|
||||
unsigned int parent_phys_lo;
|
||||
|
||||
unsigned int size_hi;
|
||||
unsigned int size_lo;
|
||||
};
|
||||
|
||||
struct linux_prom_pci_assigned_addresses {
|
||||
unsigned int which_io;
|
||||
|
||||
unsigned int phys_hi;
|
||||
unsigned int phys_lo;
|
||||
|
||||
unsigned int size_hi;
|
||||
unsigned int size_lo;
|
||||
};
|
||||
|
||||
struct linux_prom_ebus_ranges {
|
||||
unsigned int child_phys_hi;
|
||||
unsigned int child_phys_lo;
|
||||
|
||||
unsigned int parent_phys_hi;
|
||||
unsigned int parent_phys_mid;
|
||||
unsigned int parent_phys_lo;
|
||||
|
||||
unsigned int size;
|
||||
};
|
||||
|
||||
#endif /* !(__ASSEMBLY__) */
|
||||
|
||||
#endif /* !(__SPARC_OPENPROM_H) */
|
280
include/asm-sparc/openprom_64.h
Normal file
280
include/asm-sparc/openprom_64.h
Normal file
|
@ -0,0 +1,280 @@
|
|||
#ifndef __SPARC64_OPENPROM_H
|
||||
#define __SPARC64_OPENPROM_H
|
||||
|
||||
/* openprom.h: Prom structures and defines for access to the OPENBOOT
|
||||
* prom routines and data areas.
|
||||
*
|
||||
* Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
|
||||
*/
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
/* V0 prom device operations. */
|
||||
struct linux_dev_v0_funcs {
|
||||
int (*v0_devopen)(char *device_str);
|
||||
int (*v0_devclose)(int dev_desc);
|
||||
int (*v0_rdblkdev)(int dev_desc, int num_blks, int blk_st, char *buf);
|
||||
int (*v0_wrblkdev)(int dev_desc, int num_blks, int blk_st, char *buf);
|
||||
int (*v0_wrnetdev)(int dev_desc, int num_bytes, char *buf);
|
||||
int (*v0_rdnetdev)(int dev_desc, int num_bytes, char *buf);
|
||||
int (*v0_rdchardev)(int dev_desc, int num_bytes, int dummy, char *buf);
|
||||
int (*v0_wrchardev)(int dev_desc, int num_bytes, int dummy, char *buf);
|
||||
int (*v0_seekdev)(int dev_desc, long logical_offst, int from);
|
||||
};
|
||||
|
||||
/* V2 and later prom device operations. */
|
||||
struct linux_dev_v2_funcs {
|
||||
int (*v2_inst2pkg)(int d); /* Convert ihandle to phandle */
|
||||
char * (*v2_dumb_mem_alloc)(char *va, unsigned sz);
|
||||
void (*v2_dumb_mem_free)(char *va, unsigned sz);
|
||||
|
||||
/* To map devices into virtual I/O space. */
|
||||
char * (*v2_dumb_mmap)(char *virta, int which_io, unsigned paddr, unsigned sz);
|
||||
void (*v2_dumb_munmap)(char *virta, unsigned size);
|
||||
|
||||
int (*v2_dev_open)(char *devpath);
|
||||
void (*v2_dev_close)(int d);
|
||||
int (*v2_dev_read)(int d, char *buf, int nbytes);
|
||||
int (*v2_dev_write)(int d, char *buf, int nbytes);
|
||||
int (*v2_dev_seek)(int d, int hi, int lo);
|
||||
|
||||
/* Never issued (multistage load support) */
|
||||
void (*v2_wheee2)(void);
|
||||
void (*v2_wheee3)(void);
|
||||
};
|
||||
|
||||
struct linux_mlist_v0 {
|
||||
struct linux_mlist_v0 *theres_more;
|
||||
unsigned start_adr;
|
||||
unsigned num_bytes;
|
||||
};
|
||||
|
||||
struct linux_mem_v0 {
|
||||
struct linux_mlist_v0 **v0_totphys;
|
||||
struct linux_mlist_v0 **v0_prommap;
|
||||
struct linux_mlist_v0 **v0_available; /* What we can use */
|
||||
};
|
||||
|
||||
/* Arguments sent to the kernel from the boot prompt. */
|
||||
struct linux_arguments_v0 {
|
||||
char *argv[8];
|
||||
char args[100];
|
||||
char boot_dev[2];
|
||||
int boot_dev_ctrl;
|
||||
int boot_dev_unit;
|
||||
int dev_partition;
|
||||
char *kernel_file_name;
|
||||
void *aieee1; /* XXX */
|
||||
};
|
||||
|
||||
/* V2 and up boot things. */
|
||||
struct linux_bootargs_v2 {
|
||||
char **bootpath;
|
||||
char **bootargs;
|
||||
int *fd_stdin;
|
||||
int *fd_stdout;
|
||||
};
|
||||
|
||||
/* The top level PROM vector. */
|
||||
struct linux_romvec {
|
||||
/* Version numbers. */
|
||||
unsigned int pv_magic_cookie;
|
||||
unsigned int pv_romvers;
|
||||
unsigned int pv_plugin_revision;
|
||||
unsigned int pv_printrev;
|
||||
|
||||
/* Version 0 memory descriptors. */
|
||||
struct linux_mem_v0 pv_v0mem;
|
||||
|
||||
/* Node operations. */
|
||||
struct linux_nodeops *pv_nodeops;
|
||||
|
||||
char **pv_bootstr;
|
||||
struct linux_dev_v0_funcs pv_v0devops;
|
||||
|
||||
char *pv_stdin;
|
||||
char *pv_stdout;
|
||||
#define PROMDEV_KBD 0 /* input from keyboard */
|
||||
#define PROMDEV_SCREEN 0 /* output to screen */
|
||||
#define PROMDEV_TTYA 1 /* in/out to ttya */
|
||||
#define PROMDEV_TTYB 2 /* in/out to ttyb */
|
||||
|
||||
/* Blocking getchar/putchar. NOT REENTRANT! (grr) */
|
||||
int (*pv_getchar)(void);
|
||||
void (*pv_putchar)(int ch);
|
||||
|
||||
/* Non-blocking variants. */
|
||||
int (*pv_nbgetchar)(void);
|
||||
int (*pv_nbputchar)(int ch);
|
||||
|
||||
void (*pv_putstr)(char *str, int len);
|
||||
|
||||
/* Miscellany. */
|
||||
void (*pv_reboot)(char *bootstr);
|
||||
void (*pv_printf)(__const__ char *fmt, ...);
|
||||
void (*pv_abort)(void);
|
||||
__volatile__ int *pv_ticks;
|
||||
void (*pv_halt)(void);
|
||||
void (**pv_synchook)(void);
|
||||
|
||||
/* Evaluate a forth string, not different proto for V0 and V2->up. */
|
||||
union {
|
||||
void (*v0_eval)(int len, char *str);
|
||||
void (*v2_eval)(char *str);
|
||||
} pv_fortheval;
|
||||
|
||||
struct linux_arguments_v0 **pv_v0bootargs;
|
||||
|
||||
/* Get ether address. */
|
||||
unsigned int (*pv_enaddr)(int d, char *enaddr);
|
||||
|
||||
struct linux_bootargs_v2 pv_v2bootargs;
|
||||
struct linux_dev_v2_funcs pv_v2devops;
|
||||
|
||||
int filler[15];
|
||||
|
||||
/* This one is sun4c/sun4 only. */
|
||||
void (*pv_setctxt)(int ctxt, char *va, int pmeg);
|
||||
|
||||
/* Prom version 3 Multiprocessor routines. This stuff is crazy.
|
||||
* No joke. Calling these when there is only one cpu probably
|
||||
* crashes the machine, have to test this. :-)
|
||||
*/
|
||||
|
||||
/* v3_cpustart() will start the cpu 'whichcpu' in mmu-context
|
||||
* 'thiscontext' executing at address 'prog_counter'
|
||||
*/
|
||||
int (*v3_cpustart)(unsigned int whichcpu, int ctxtbl_ptr,
|
||||
int thiscontext, char *prog_counter);
|
||||
|
||||
/* v3_cpustop() will cause cpu 'whichcpu' to stop executing
|
||||
* until a resume cpu call is made.
|
||||
*/
|
||||
int (*v3_cpustop)(unsigned int whichcpu);
|
||||
|
||||
/* v3_cpuidle() will idle cpu 'whichcpu' until a stop or
|
||||
* resume cpu call is made.
|
||||
*/
|
||||
int (*v3_cpuidle)(unsigned int whichcpu);
|
||||
|
||||
/* v3_cpuresume() will resume processor 'whichcpu' executing
|
||||
* starting with whatever 'pc' and 'npc' were left at the
|
||||
* last 'idle' or 'stop' call.
|
||||
*/
|
||||
int (*v3_cpuresume)(unsigned int whichcpu);
|
||||
};
|
||||
|
||||
/* Routines for traversing the prom device tree. */
|
||||
struct linux_nodeops {
|
||||
int (*no_nextnode)(int node);
|
||||
int (*no_child)(int node);
|
||||
int (*no_proplen)(int node, char *name);
|
||||
int (*no_getprop)(int node, char *name, char *val);
|
||||
int (*no_setprop)(int node, char *name, char *val, int len);
|
||||
char * (*no_nextprop)(int node, char *name);
|
||||
};
|
||||
|
||||
/* More fun PROM structures for device probing. */
|
||||
#define PROMREG_MAX 24
|
||||
#define PROMVADDR_MAX 16
|
||||
#define PROMINTR_MAX 32
|
||||
|
||||
struct linux_prom_registers {
|
||||
unsigned which_io; /* hi part of physical address */
|
||||
unsigned phys_addr; /* The physical address of this register */
|
||||
int reg_size; /* How many bytes does this register take up? */
|
||||
};
|
||||
|
||||
struct linux_prom64_registers {
|
||||
unsigned long phys_addr;
|
||||
unsigned long reg_size;
|
||||
};
|
||||
|
||||
struct linux_prom_irqs {
|
||||
int pri; /* IRQ priority */
|
||||
int vector; /* This is foobar, what does it do? */
|
||||
};
|
||||
|
||||
/* Element of the "ranges" vector */
|
||||
struct linux_prom_ranges {
|
||||
unsigned int ot_child_space;
|
||||
unsigned int ot_child_base; /* Bus feels this */
|
||||
unsigned int ot_parent_space;
|
||||
unsigned int ot_parent_base; /* CPU looks from here */
|
||||
unsigned int or_size;
|
||||
};
|
||||
|
||||
struct linux_prom64_ranges {
|
||||
unsigned long ot_child_base; /* Bus feels this */
|
||||
unsigned long ot_parent_base; /* CPU looks from here */
|
||||
unsigned long or_size;
|
||||
};
|
||||
|
||||
/* Ranges and reg properties are a bit different for PCI. */
|
||||
struct linux_prom_pci_registers {
|
||||
unsigned int phys_hi;
|
||||
unsigned int phys_mid;
|
||||
unsigned int phys_lo;
|
||||
|
||||
unsigned int size_hi;
|
||||
unsigned int size_lo;
|
||||
};
|
||||
|
||||
struct linux_prom_pci_ranges {
|
||||
unsigned int child_phys_hi; /* Only certain bits are encoded here. */
|
||||
unsigned int child_phys_mid;
|
||||
unsigned int child_phys_lo;
|
||||
|
||||
unsigned int parent_phys_hi;
|
||||
unsigned int parent_phys_lo;
|
||||
|
||||
unsigned int size_hi;
|
||||
unsigned int size_lo;
|
||||
};
|
||||
|
||||
struct linux_prom_pci_intmap {
|
||||
unsigned int phys_hi;
|
||||
unsigned int phys_mid;
|
||||
unsigned int phys_lo;
|
||||
|
||||
unsigned int interrupt;
|
||||
|
||||
int cnode;
|
||||
unsigned int cinterrupt;
|
||||
};
|
||||
|
||||
struct linux_prom_pci_intmask {
|
||||
unsigned int phys_hi;
|
||||
unsigned int phys_mid;
|
||||
unsigned int phys_lo;
|
||||
unsigned int interrupt;
|
||||
};
|
||||
|
||||
struct linux_prom_ebus_ranges {
|
||||
unsigned int child_phys_hi;
|
||||
unsigned int child_phys_lo;
|
||||
|
||||
unsigned int parent_phys_hi;
|
||||
unsigned int parent_phys_mid;
|
||||
unsigned int parent_phys_lo;
|
||||
|
||||
unsigned int size;
|
||||
};
|
||||
|
||||
struct linux_prom_ebus_intmap {
|
||||
unsigned int phys_hi;
|
||||
unsigned int phys_lo;
|
||||
|
||||
unsigned int interrupt;
|
||||
|
||||
int cnode;
|
||||
unsigned int cinterrupt;
|
||||
};
|
||||
|
||||
struct linux_prom_ebus_intmask {
|
||||
unsigned int phys_hi;
|
||||
unsigned int phys_lo;
|
||||
unsigned int interrupt;
|
||||
};
|
||||
#endif /* !(__ASSEMBLY__) */
|
||||
|
||||
#endif /* !(__SPARC64_OPENPROM_H) */
|
|
@ -1,272 +1,8 @@
|
|||
/*
|
||||
* oplib.h: Describes the interface and available routines in the
|
||||
* Linux Prom library.
|
||||
*
|
||||
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
|
||||
*/
|
||||
|
||||
#ifndef __SPARC_OPLIB_H
|
||||
#define __SPARC_OPLIB_H
|
||||
|
||||
#include <asm/openprom.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/compiler.h>
|
||||
|
||||
/* The master romvec pointer... */
|
||||
extern struct linux_romvec *romvec;
|
||||
|
||||
/* Enumeration to describe the prom major version we have detected. */
|
||||
enum prom_major_version {
|
||||
PROM_V0, /* Original sun4c V0 prom */
|
||||
PROM_V2, /* sun4c and early sun4m V2 prom */
|
||||
PROM_V3, /* sun4m and later, up to sun4d/sun4e machines V3 */
|
||||
PROM_P1275, /* IEEE compliant ISA based Sun PROM, only sun4u */
|
||||
PROM_SUN4, /* Old sun4 proms are totally different, but we'll shoehorn it to make it fit */
|
||||
};
|
||||
|
||||
extern enum prom_major_version prom_vers;
|
||||
/* Revision, and firmware revision. */
|
||||
extern unsigned int prom_rev, prom_prev;
|
||||
|
||||
/* Root node of the prom device tree, this stays constant after
|
||||
* initialization is complete.
|
||||
*/
|
||||
extern int prom_root_node;
|
||||
|
||||
/* Pointer to prom structure containing the device tree traversal
|
||||
* and usage utility functions. Only prom-lib should use these,
|
||||
* users use the interface defined by the library only!
|
||||
*/
|
||||
extern struct linux_nodeops *prom_nodeops;
|
||||
|
||||
/* The functions... */
|
||||
|
||||
/* You must call prom_init() before using any of the library services,
|
||||
* preferably as early as possible. Pass it the romvec pointer.
|
||||
*/
|
||||
extern void prom_init(struct linux_romvec *rom_ptr);
|
||||
|
||||
/* Boot argument acquisition, returns the boot command line string. */
|
||||
extern char *prom_getbootargs(void);
|
||||
|
||||
/* Device utilities. */
|
||||
|
||||
/* Map and unmap devices in IO space at virtual addresses. Note that the
|
||||
* virtual address you pass is a request and the prom may put your mappings
|
||||
* somewhere else, so check your return value as that is where your new
|
||||
* mappings really are!
|
||||
*
|
||||
* Another note, these are only available on V2 or higher proms!
|
||||
*/
|
||||
extern char *prom_mapio(char *virt_hint, int io_space, unsigned int phys_addr, unsigned int num_bytes);
|
||||
extern void prom_unmapio(char *virt_addr, unsigned int num_bytes);
|
||||
|
||||
/* Device operations. */
|
||||
|
||||
/* Open the device described by the passed string. Note, that the format
|
||||
* of the string is different on V0 vs. V2->higher proms. The caller must
|
||||
* know what he/she is doing! Returns the device descriptor, an int.
|
||||
*/
|
||||
extern int prom_devopen(char *device_string);
|
||||
|
||||
/* Close a previously opened device described by the passed integer
|
||||
* descriptor.
|
||||
*/
|
||||
extern int prom_devclose(int device_handle);
|
||||
|
||||
/* Do a seek operation on the device described by the passed integer
|
||||
* descriptor.
|
||||
*/
|
||||
extern void prom_seek(int device_handle, unsigned int seek_hival,
|
||||
unsigned int seek_lowval);
|
||||
|
||||
/* Miscellaneous routines, don't really fit in any category per se. */
|
||||
|
||||
/* Reboot the machine with the command line passed. */
|
||||
extern void prom_reboot(char *boot_command);
|
||||
|
||||
/* Evaluate the forth string passed. */
|
||||
extern void prom_feval(char *forth_string);
|
||||
|
||||
/* Enter the prom, with possibility of continuation with the 'go'
|
||||
* command in newer proms.
|
||||
*/
|
||||
extern void prom_cmdline(void);
|
||||
|
||||
/* Enter the prom, with no chance of continuation for the stand-alone
|
||||
* which calls this.
|
||||
*/
|
||||
extern void prom_halt(void) __attribute__ ((noreturn));
|
||||
|
||||
/* Set the PROM 'sync' callback function to the passed function pointer.
|
||||
* When the user gives the 'sync' command at the prom prompt while the
|
||||
* kernel is still active, the prom will call this routine.
|
||||
*
|
||||
* XXX The arguments are different on V0 vs. V2->higher proms, grrr! XXX
|
||||
*/
|
||||
typedef void (*sync_func_t)(void);
|
||||
extern void prom_setsync(sync_func_t func_ptr);
|
||||
|
||||
/* Acquire the IDPROM of the root node in the prom device tree. This
|
||||
* gets passed a buffer where you would like it stuffed. The return value
|
||||
* is the format type of this idprom or 0xff on error.
|
||||
*/
|
||||
extern unsigned char prom_get_idprom(char *idp_buffer, int idpbuf_size);
|
||||
|
||||
/* Get the prom major version. */
|
||||
extern int prom_version(void);
|
||||
|
||||
/* Get the prom plugin revision. */
|
||||
extern int prom_getrev(void);
|
||||
|
||||
/* Get the prom firmware revision. */
|
||||
extern int prom_getprev(void);
|
||||
|
||||
/* Character operations to/from the console.... */
|
||||
|
||||
/* Non-blocking get character from console. */
|
||||
extern int prom_nbgetchar(void);
|
||||
|
||||
/* Non-blocking put character to console. */
|
||||
extern int prom_nbputchar(char character);
|
||||
|
||||
/* Blocking get character from console. */
|
||||
extern char prom_getchar(void);
|
||||
|
||||
/* Blocking put character to console. */
|
||||
extern void prom_putchar(char character);
|
||||
|
||||
/* Prom's internal routines, don't use in kernel/boot code. */
|
||||
extern void prom_printf(char *fmt, ...);
|
||||
extern void prom_write(const char *buf, unsigned int len);
|
||||
|
||||
/* Multiprocessor operations... */
|
||||
|
||||
/* Start the CPU with the given device tree node, context table, and context
|
||||
* at the passed program counter.
|
||||
*/
|
||||
extern int prom_startcpu(int cpunode, struct linux_prom_registers *context_table,
|
||||
int context, char *program_counter);
|
||||
|
||||
/* Stop the CPU with the passed device tree node. */
|
||||
extern int prom_stopcpu(int cpunode);
|
||||
|
||||
/* Idle the CPU with the passed device tree node. */
|
||||
extern int prom_idlecpu(int cpunode);
|
||||
|
||||
/* Re-Start the CPU with the passed device tree node. */
|
||||
extern int prom_restartcpu(int cpunode);
|
||||
|
||||
/* PROM memory allocation facilities... */
|
||||
|
||||
/* Allocated at possibly the given virtual address a chunk of the
|
||||
* indicated size.
|
||||
*/
|
||||
extern char *prom_alloc(char *virt_hint, unsigned int size);
|
||||
|
||||
/* Free a previously allocated chunk. */
|
||||
extern void prom_free(char *virt_addr, unsigned int size);
|
||||
|
||||
/* Sun4/sun4c specific memory-management startup hook. */
|
||||
|
||||
/* Map the passed segment in the given context at the passed
|
||||
* virtual address.
|
||||
*/
|
||||
extern void prom_putsegment(int context, unsigned long virt_addr,
|
||||
int physical_segment);
|
||||
|
||||
|
||||
/* PROM device tree traversal functions... */
|
||||
|
||||
#ifdef PROMLIB_INTERNAL
|
||||
|
||||
/* Internal version of prom_getchild. */
|
||||
extern int __prom_getchild(int parent_node);
|
||||
|
||||
/* Internal version of prom_getsibling. */
|
||||
extern int __prom_getsibling(int node);
|
||||
|
||||
#ifndef ___ASM_SPARC_OPLIB_H
|
||||
#define ___ASM_SPARC_OPLIB_H
|
||||
#if defined(__sparc__) && defined(__arch64__)
|
||||
#include <asm-sparc/oplib_64.h>
|
||||
#else
|
||||
#include <asm-sparc/oplib_32.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
/* Get the child node of the given node, or zero if no child exists. */
|
||||
extern int prom_getchild(int parent_node);
|
||||
|
||||
/* Get the next sibling node of the given node, or zero if no further
|
||||
* siblings exist.
|
||||
*/
|
||||
extern int prom_getsibling(int node);
|
||||
|
||||
/* Get the length, at the passed node, of the given property type.
|
||||
* Returns -1 on error (ie. no such property at this node).
|
||||
*/
|
||||
extern int prom_getproplen(int thisnode, char *property);
|
||||
|
||||
/* Fetch the requested property using the given buffer. Returns
|
||||
* the number of bytes the prom put into your buffer or -1 on error.
|
||||
*/
|
||||
extern int __must_check prom_getproperty(int thisnode, char *property,
|
||||
char *prop_buffer, int propbuf_size);
|
||||
|
||||
/* Acquire an integer property. */
|
||||
extern int prom_getint(int node, char *property);
|
||||
|
||||
/* Acquire an integer property, with a default value. */
|
||||
extern int prom_getintdefault(int node, char *property, int defval);
|
||||
|
||||
/* Acquire a boolean property, 0=FALSE 1=TRUE. */
|
||||
extern int prom_getbool(int node, char *prop);
|
||||
|
||||
/* Acquire a string property, null string on error. */
|
||||
extern void prom_getstring(int node, char *prop, char *buf, int bufsize);
|
||||
|
||||
/* Does the passed node have the given "name"? YES=1 NO=0 */
|
||||
extern int prom_nodematch(int thisnode, char *name);
|
||||
|
||||
/* Search all siblings starting at the passed node for "name" matching
|
||||
* the given string. Returns the node on success, zero on failure.
|
||||
*/
|
||||
extern int prom_searchsiblings(int node_start, char *name);
|
||||
|
||||
/* Return the first property type, as a string, for the given node.
|
||||
* Returns a null string on error.
|
||||
*/
|
||||
extern char *prom_firstprop(int node, char *buffer);
|
||||
|
||||
/* Returns the next property after the passed property for the given
|
||||
* node. Returns null string on failure.
|
||||
*/
|
||||
extern char *prom_nextprop(int node, char *prev_property, char *buffer);
|
||||
|
||||
/* Returns phandle of the path specified */
|
||||
extern int prom_finddevice(char *name);
|
||||
|
||||
/* Returns 1 if the specified node has given property. */
|
||||
extern int prom_node_has_property(int node, char *property);
|
||||
|
||||
/* Set the indicated property at the given node with the passed value.
|
||||
* Returns the number of bytes of your value that the prom took.
|
||||
*/
|
||||
extern int prom_setprop(int node, char *prop_name, char *prop_value,
|
||||
int value_size);
|
||||
|
||||
extern int prom_pathtoinode(char *path);
|
||||
extern int prom_inst2pkg(int);
|
||||
|
||||
/* Dorking with Bus ranges... */
|
||||
|
||||
/* Apply promlib probes OBIO ranges to registers. */
|
||||
extern void prom_apply_obio_ranges(struct linux_prom_registers *obioregs, int nregs);
|
||||
|
||||
/* Apply ranges of any prom node (and optionally parent node as well) to registers. */
|
||||
extern void prom_apply_generic_ranges(int node, int parent,
|
||||
struct linux_prom_registers *sbusregs, int nregs);
|
||||
|
||||
/* CPU probing helpers. */
|
||||
int cpu_find_by_instance(int instance, int *prom_node, int *mid);
|
||||
int cpu_find_by_mid(int mid, int *prom_node);
|
||||
int cpu_get_hwmid(int prom_node);
|
||||
|
||||
extern spinlock_t prom_lock;
|
||||
|
||||
#endif /* !(__SPARC_OPLIB_H) */
|
||||
|
|
272
include/asm-sparc/oplib_32.h
Normal file
272
include/asm-sparc/oplib_32.h
Normal file
|
@ -0,0 +1,272 @@
|
|||
/*
|
||||
* oplib.h: Describes the interface and available routines in the
|
||||
* Linux Prom library.
|
||||
*
|
||||
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
|
||||
*/
|
||||
|
||||
#ifndef __SPARC_OPLIB_H
|
||||
#define __SPARC_OPLIB_H
|
||||
|
||||
#include <asm/openprom.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/compiler.h>
|
||||
|
||||
/* The master romvec pointer... */
|
||||
extern struct linux_romvec *romvec;
|
||||
|
||||
/* Enumeration to describe the prom major version we have detected. */
|
||||
enum prom_major_version {
|
||||
PROM_V0, /* Original sun4c V0 prom */
|
||||
PROM_V2, /* sun4c and early sun4m V2 prom */
|
||||
PROM_V3, /* sun4m and later, up to sun4d/sun4e machines V3 */
|
||||
PROM_P1275, /* IEEE compliant ISA based Sun PROM, only sun4u */
|
||||
PROM_SUN4, /* Old sun4 proms are totally different, but we'll shoehorn it to make it fit */
|
||||
};
|
||||
|
||||
extern enum prom_major_version prom_vers;
|
||||
/* Revision, and firmware revision. */
|
||||
extern unsigned int prom_rev, prom_prev;
|
||||
|
||||
/* Root node of the prom device tree, this stays constant after
|
||||
* initialization is complete.
|
||||
*/
|
||||
extern int prom_root_node;
|
||||
|
||||
/* Pointer to prom structure containing the device tree traversal
|
||||
* and usage utility functions. Only prom-lib should use these,
|
||||
* users use the interface defined by the library only!
|
||||
*/
|
||||
extern struct linux_nodeops *prom_nodeops;
|
||||
|
||||
/* The functions... */
|
||||
|
||||
/* You must call prom_init() before using any of the library services,
|
||||
* preferably as early as possible. Pass it the romvec pointer.
|
||||
*/
|
||||
extern void prom_init(struct linux_romvec *rom_ptr);
|
||||
|
||||
/* Boot argument acquisition, returns the boot command line string. */
|
||||
extern char *prom_getbootargs(void);
|
||||
|
||||
/* Device utilities. */
|
||||
|
||||
/* Map and unmap devices in IO space at virtual addresses. Note that the
|
||||
* virtual address you pass is a request and the prom may put your mappings
|
||||
* somewhere else, so check your return value as that is where your new
|
||||
* mappings really are!
|
||||
*
|
||||
* Another note, these are only available on V2 or higher proms!
|
||||
*/
|
||||
extern char *prom_mapio(char *virt_hint, int io_space, unsigned int phys_addr, unsigned int num_bytes);
|
||||
extern void prom_unmapio(char *virt_addr, unsigned int num_bytes);
|
||||
|
||||
/* Device operations. */
|
||||
|
||||
/* Open the device described by the passed string. Note, that the format
|
||||
* of the string is different on V0 vs. V2->higher proms. The caller must
|
||||
* know what he/she is doing! Returns the device descriptor, an int.
|
||||
*/
|
||||
extern int prom_devopen(char *device_string);
|
||||
|
||||
/* Close a previously opened device described by the passed integer
|
||||
* descriptor.
|
||||
*/
|
||||
extern int prom_devclose(int device_handle);
|
||||
|
||||
/* Do a seek operation on the device described by the passed integer
|
||||
* descriptor.
|
||||
*/
|
||||
extern void prom_seek(int device_handle, unsigned int seek_hival,
|
||||
unsigned int seek_lowval);
|
||||
|
||||
/* Miscellaneous routines, don't really fit in any category per se. */
|
||||
|
||||
/* Reboot the machine with the command line passed. */
|
||||
extern void prom_reboot(char *boot_command);
|
||||
|
||||
/* Evaluate the forth string passed. */
|
||||
extern void prom_feval(char *forth_string);
|
||||
|
||||
/* Enter the prom, with possibility of continuation with the 'go'
|
||||
* command in newer proms.
|
||||
*/
|
||||
extern void prom_cmdline(void);
|
||||
|
||||
/* Enter the prom, with no chance of continuation for the stand-alone
|
||||
* which calls this.
|
||||
*/
|
||||
extern void prom_halt(void) __attribute__ ((noreturn));
|
||||
|
||||
/* Set the PROM 'sync' callback function to the passed function pointer.
|
||||
* When the user gives the 'sync' command at the prom prompt while the
|
||||
* kernel is still active, the prom will call this routine.
|
||||
*
|
||||
* XXX The arguments are different on V0 vs. V2->higher proms, grrr! XXX
|
||||
*/
|
||||
typedef void (*sync_func_t)(void);
|
||||
extern void prom_setsync(sync_func_t func_ptr);
|
||||
|
||||
/* Acquire the IDPROM of the root node in the prom device tree. This
|
||||
* gets passed a buffer where you would like it stuffed. The return value
|
||||
* is the format type of this idprom or 0xff on error.
|
||||
*/
|
||||
extern unsigned char prom_get_idprom(char *idp_buffer, int idpbuf_size);
|
||||
|
||||
/* Get the prom major version. */
|
||||
extern int prom_version(void);
|
||||
|
||||
/* Get the prom plugin revision. */
|
||||
extern int prom_getrev(void);
|
||||
|
||||
/* Get the prom firmware revision. */
|
||||
extern int prom_getprev(void);
|
||||
|
||||
/* Character operations to/from the console.... */
|
||||
|
||||
/* Non-blocking get character from console. */
|
||||
extern int prom_nbgetchar(void);
|
||||
|
||||
/* Non-blocking put character to console. */
|
||||
extern int prom_nbputchar(char character);
|
||||
|
||||
/* Blocking get character from console. */
|
||||
extern char prom_getchar(void);
|
||||
|
||||
/* Blocking put character to console. */
|
||||
extern void prom_putchar(char character);
|
||||
|
||||
/* Prom's internal routines, don't use in kernel/boot code. */
|
||||
extern void prom_printf(char *fmt, ...);
|
||||
extern void prom_write(const char *buf, unsigned int len);
|
||||
|
||||
/* Multiprocessor operations... */
|
||||
|
||||
/* Start the CPU with the given device tree node, context table, and context
|
||||
* at the passed program counter.
|
||||
*/
|
||||
extern int prom_startcpu(int cpunode, struct linux_prom_registers *context_table,
|
||||
int context, char *program_counter);
|
||||
|
||||
/* Stop the CPU with the passed device tree node. */
|
||||
extern int prom_stopcpu(int cpunode);
|
||||
|
||||
/* Idle the CPU with the passed device tree node. */
|
||||
extern int prom_idlecpu(int cpunode);
|
||||
|
||||
/* Re-Start the CPU with the passed device tree node. */
|
||||
extern int prom_restartcpu(int cpunode);
|
||||
|
||||
/* PROM memory allocation facilities... */
|
||||
|
||||
/* Allocated at possibly the given virtual address a chunk of the
|
||||
* indicated size.
|
||||
*/
|
||||
extern char *prom_alloc(char *virt_hint, unsigned int size);
|
||||
|
||||
/* Free a previously allocated chunk. */
|
||||
extern void prom_free(char *virt_addr, unsigned int size);
|
||||
|
||||
/* Sun4/sun4c specific memory-management startup hook. */
|
||||
|
||||
/* Map the passed segment in the given context at the passed
|
||||
* virtual address.
|
||||
*/
|
||||
extern void prom_putsegment(int context, unsigned long virt_addr,
|
||||
int physical_segment);
|
||||
|
||||
|
||||
/* PROM device tree traversal functions... */
|
||||
|
||||
#ifdef PROMLIB_INTERNAL
|
||||
|
||||
/* Internal version of prom_getchild. */
|
||||
extern int __prom_getchild(int parent_node);
|
||||
|
||||
/* Internal version of prom_getsibling. */
|
||||
extern int __prom_getsibling(int node);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/* Get the child node of the given node, or zero if no child exists. */
|
||||
extern int prom_getchild(int parent_node);
|
||||
|
||||
/* Get the next sibling node of the given node, or zero if no further
|
||||
* siblings exist.
|
||||
*/
|
||||
extern int prom_getsibling(int node);
|
||||
|
||||
/* Get the length, at the passed node, of the given property type.
|
||||
* Returns -1 on error (ie. no such property at this node).
|
||||
*/
|
||||
extern int prom_getproplen(int thisnode, char *property);
|
||||
|
||||
/* Fetch the requested property using the given buffer. Returns
|
||||
* the number of bytes the prom put into your buffer or -1 on error.
|
||||
*/
|
||||
extern int __must_check prom_getproperty(int thisnode, char *property,
|
||||
char *prop_buffer, int propbuf_size);
|
||||
|
||||
/* Acquire an integer property. */
|
||||
extern int prom_getint(int node, char *property);
|
||||
|
||||
/* Acquire an integer property, with a default value. */
|
||||
extern int prom_getintdefault(int node, char *property, int defval);
|
||||
|
||||
/* Acquire a boolean property, 0=FALSE 1=TRUE. */
|
||||
extern int prom_getbool(int node, char *prop);
|
||||
|
||||
/* Acquire a string property, null string on error. */
|
||||
extern void prom_getstring(int node, char *prop, char *buf, int bufsize);
|
||||
|
||||
/* Does the passed node have the given "name"? YES=1 NO=0 */
|
||||
extern int prom_nodematch(int thisnode, char *name);
|
||||
|
||||
/* Search all siblings starting at the passed node for "name" matching
|
||||
* the given string. Returns the node on success, zero on failure.
|
||||
*/
|
||||
extern int prom_searchsiblings(int node_start, char *name);
|
||||
|
||||
/* Return the first property type, as a string, for the given node.
|
||||
* Returns a null string on error.
|
||||
*/
|
||||
extern char *prom_firstprop(int node, char *buffer);
|
||||
|
||||
/* Returns the next property after the passed property for the given
|
||||
* node. Returns null string on failure.
|
||||
*/
|
||||
extern char *prom_nextprop(int node, char *prev_property, char *buffer);
|
||||
|
||||
/* Returns phandle of the path specified */
|
||||
extern int prom_finddevice(char *name);
|
||||
|
||||
/* Returns 1 if the specified node has given property. */
|
||||
extern int prom_node_has_property(int node, char *property);
|
||||
|
||||
/* Set the indicated property at the given node with the passed value.
|
||||
* Returns the number of bytes of your value that the prom took.
|
||||
*/
|
||||
extern int prom_setprop(int node, char *prop_name, char *prop_value,
|
||||
int value_size);
|
||||
|
||||
extern int prom_pathtoinode(char *path);
|
||||
extern int prom_inst2pkg(int);
|
||||
|
||||
/* Dorking with Bus ranges... */
|
||||
|
||||
/* Apply promlib probes OBIO ranges to registers. */
|
||||
extern void prom_apply_obio_ranges(struct linux_prom_registers *obioregs, int nregs);
|
||||
|
||||
/* Apply ranges of any prom node (and optionally parent node as well) to registers. */
|
||||
extern void prom_apply_generic_ranges(int node, int parent,
|
||||
struct linux_prom_registers *sbusregs, int nregs);
|
||||
|
||||
/* CPU probing helpers. */
|
||||
int cpu_find_by_instance(int instance, int *prom_node, int *mid);
|
||||
int cpu_find_by_mid(int mid, int *prom_node);
|
||||
int cpu_get_hwmid(int prom_node);
|
||||
|
||||
extern spinlock_t prom_lock;
|
||||
|
||||
#endif /* !(__SPARC_OPLIB_H) */
|
322
include/asm-sparc/oplib_64.h
Normal file
322
include/asm-sparc/oplib_64.h
Normal file
|
@ -0,0 +1,322 @@
|
|||
/* oplib.h: Describes the interface and available routines in the
|
||||
* Linux Prom library.
|
||||
*
|
||||
* Copyright (C) 1995, 2007 David S. Miller (davem@davemloft.net)
|
||||
* Copyright (C) 1996 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
|
||||
*/
|
||||
|
||||
#ifndef __SPARC64_OPLIB_H
|
||||
#define __SPARC64_OPLIB_H
|
||||
|
||||
#include <asm/openprom.h>
|
||||
|
||||
/* OBP version string. */
|
||||
extern char prom_version[];
|
||||
|
||||
/* Root node of the prom device tree, this stays constant after
|
||||
* initialization is complete.
|
||||
*/
|
||||
extern int prom_root_node;
|
||||
|
||||
/* PROM stdin and stdout */
|
||||
extern int prom_stdin, prom_stdout;
|
||||
|
||||
/* /chosen node of the prom device tree, this stays constant after
|
||||
* initialization is complete.
|
||||
*/
|
||||
extern int prom_chosen_node;
|
||||
|
||||
/* Helper values and strings in arch/sparc64/kernel/head.S */
|
||||
extern const char prom_peer_name[];
|
||||
extern const char prom_compatible_name[];
|
||||
extern const char prom_root_compatible[];
|
||||
extern const char prom_cpu_compatible[];
|
||||
extern const char prom_finddev_name[];
|
||||
extern const char prom_chosen_path[];
|
||||
extern const char prom_cpu_path[];
|
||||
extern const char prom_getprop_name[];
|
||||
extern const char prom_mmu_name[];
|
||||
extern const char prom_callmethod_name[];
|
||||
extern const char prom_translate_name[];
|
||||
extern const char prom_map_name[];
|
||||
extern const char prom_unmap_name[];
|
||||
extern int prom_mmu_ihandle_cache;
|
||||
extern unsigned int prom_boot_mapped_pc;
|
||||
extern unsigned int prom_boot_mapping_mode;
|
||||
extern unsigned long prom_boot_mapping_phys_high, prom_boot_mapping_phys_low;
|
||||
|
||||
struct linux_mlist_p1275 {
|
||||
struct linux_mlist_p1275 *theres_more;
|
||||
unsigned long start_adr;
|
||||
unsigned long num_bytes;
|
||||
};
|
||||
|
||||
struct linux_mem_p1275 {
|
||||
struct linux_mlist_p1275 **p1275_totphys;
|
||||
struct linux_mlist_p1275 **p1275_prommap;
|
||||
struct linux_mlist_p1275 **p1275_available; /* What we can use */
|
||||
};
|
||||
|
||||
/* The functions... */
|
||||
|
||||
/* You must call prom_init() before using any of the library services,
|
||||
* preferably as early as possible. Pass it the romvec pointer.
|
||||
*/
|
||||
extern void prom_init(void *cif_handler, void *cif_stack);
|
||||
|
||||
/* Boot argument acquisition, returns the boot command line string. */
|
||||
extern char *prom_getbootargs(void);
|
||||
|
||||
/* Device utilities. */
|
||||
|
||||
/* Device operations. */
|
||||
|
||||
/* Open the device described by the passed string. Note, that the format
|
||||
* of the string is different on V0 vs. V2->higher proms. The caller must
|
||||
* know what he/she is doing! Returns the device descriptor, an int.
|
||||
*/
|
||||
extern int prom_devopen(const char *device_string);
|
||||
|
||||
/* Close a previously opened device described by the passed integer
|
||||
* descriptor.
|
||||
*/
|
||||
extern int prom_devclose(int device_handle);
|
||||
|
||||
/* Do a seek operation on the device described by the passed integer
|
||||
* descriptor.
|
||||
*/
|
||||
extern void prom_seek(int device_handle, unsigned int seek_hival,
|
||||
unsigned int seek_lowval);
|
||||
|
||||
/* Miscellaneous routines, don't really fit in any category per se. */
|
||||
|
||||
/* Reboot the machine with the command line passed. */
|
||||
extern void prom_reboot(const char *boot_command);
|
||||
|
||||
/* Evaluate the forth string passed. */
|
||||
extern void prom_feval(const char *forth_string);
|
||||
|
||||
/* Enter the prom, with possibility of continuation with the 'go'
|
||||
* command in newer proms.
|
||||
*/
|
||||
extern void prom_cmdline(void);
|
||||
|
||||
/* Enter the prom, with no chance of continuation for the stand-alone
|
||||
* which calls this.
|
||||
*/
|
||||
extern void prom_halt(void) __attribute__ ((noreturn));
|
||||
|
||||
/* Halt and power-off the machine. */
|
||||
extern void prom_halt_power_off(void) __attribute__ ((noreturn));
|
||||
|
||||
/* Set the PROM 'sync' callback function to the passed function pointer.
|
||||
* When the user gives the 'sync' command at the prom prompt while the
|
||||
* kernel is still active, the prom will call this routine.
|
||||
*
|
||||
*/
|
||||
typedef int (*callback_func_t)(long *cmd);
|
||||
extern void prom_setcallback(callback_func_t func_ptr);
|
||||
|
||||
/* Acquire the IDPROM of the root node in the prom device tree. This
|
||||
* gets passed a buffer where you would like it stuffed. The return value
|
||||
* is the format type of this idprom or 0xff on error.
|
||||
*/
|
||||
extern unsigned char prom_get_idprom(char *idp_buffer, int idpbuf_size);
|
||||
|
||||
/* Character operations to/from the console.... */
|
||||
|
||||
/* Non-blocking get character from console. */
|
||||
extern int prom_nbgetchar(void);
|
||||
|
||||
/* Non-blocking put character to console. */
|
||||
extern int prom_nbputchar(char character);
|
||||
|
||||
/* Blocking get character from console. */
|
||||
extern char prom_getchar(void);
|
||||
|
||||
/* Blocking put character to console. */
|
||||
extern void prom_putchar(char character);
|
||||
|
||||
/* Prom's internal routines, don't use in kernel/boot code. */
|
||||
extern void prom_printf(const char *fmt, ...);
|
||||
extern void prom_write(const char *buf, unsigned int len);
|
||||
|
||||
/* Multiprocessor operations... */
|
||||
#ifdef CONFIG_SMP
|
||||
/* Start the CPU with the given device tree node at the passed program
|
||||
* counter with the given arg passed in via register %o0.
|
||||
*/
|
||||
extern void prom_startcpu(int cpunode, unsigned long pc, unsigned long arg);
|
||||
|
||||
/* Start the CPU with the given cpu ID at the passed program
|
||||
* counter with the given arg passed in via register %o0.
|
||||
*/
|
||||
extern void prom_startcpu_cpuid(int cpuid, unsigned long pc, unsigned long arg);
|
||||
|
||||
/* Stop the CPU with the given cpu ID. */
|
||||
extern void prom_stopcpu_cpuid(int cpuid);
|
||||
|
||||
/* Stop the current CPU. */
|
||||
extern void prom_stopself(void);
|
||||
|
||||
/* Idle the current CPU. */
|
||||
extern void prom_idleself(void);
|
||||
|
||||
/* Resume the CPU with the passed device tree node. */
|
||||
extern void prom_resumecpu(int cpunode);
|
||||
#endif
|
||||
|
||||
/* Power management interfaces. */
|
||||
|
||||
/* Put the current CPU to sleep. */
|
||||
extern void prom_sleepself(void);
|
||||
|
||||
/* Put the entire system to sleep. */
|
||||
extern int prom_sleepsystem(void);
|
||||
|
||||
/* Initiate a wakeup event. */
|
||||
extern int prom_wakeupsystem(void);
|
||||
|
||||
/* MMU and memory related OBP interfaces. */
|
||||
|
||||
/* Get unique string identifying SIMM at given physical address. */
|
||||
extern int prom_getunumber(int syndrome_code,
|
||||
unsigned long phys_addr,
|
||||
char *buf, int buflen);
|
||||
|
||||
/* Retain physical memory to the caller across soft resets. */
|
||||
extern unsigned long prom_retain(const char *name,
|
||||
unsigned long pa_low, unsigned long pa_high,
|
||||
long size, long align);
|
||||
|
||||
/* Load explicit I/D TLB entries into the calling processor. */
|
||||
extern long prom_itlb_load(unsigned long index,
|
||||
unsigned long tte_data,
|
||||
unsigned long vaddr);
|
||||
|
||||
extern long prom_dtlb_load(unsigned long index,
|
||||
unsigned long tte_data,
|
||||
unsigned long vaddr);
|
||||
|
||||
/* Map/Unmap client program address ranges. First the format of
|
||||
* the mapping mode argument.
|
||||
*/
|
||||
#define PROM_MAP_WRITE 0x0001 /* Writable */
|
||||
#define PROM_MAP_READ 0x0002 /* Readable - sw */
|
||||
#define PROM_MAP_EXEC 0x0004 /* Executable - sw */
|
||||
#define PROM_MAP_LOCKED 0x0010 /* Locked, use i/dtlb load calls for this instead */
|
||||
#define PROM_MAP_CACHED 0x0020 /* Cacheable in both L1 and L2 caches */
|
||||
#define PROM_MAP_SE 0x0040 /* Side-Effects */
|
||||
#define PROM_MAP_GLOB 0x0080 /* Global */
|
||||
#define PROM_MAP_IE 0x0100 /* Invert-Endianness */
|
||||
#define PROM_MAP_DEFAULT (PROM_MAP_WRITE | PROM_MAP_READ | PROM_MAP_EXEC | PROM_MAP_CACHED)
|
||||
|
||||
extern int prom_map(int mode, unsigned long size,
|
||||
unsigned long vaddr, unsigned long paddr);
|
||||
extern void prom_unmap(unsigned long size, unsigned long vaddr);
|
||||
|
||||
|
||||
/* PROM device tree traversal functions... */
|
||||
|
||||
#ifdef PROMLIB_INTERNAL
|
||||
|
||||
/* Internal version of prom_getchild. */
|
||||
extern int __prom_getchild(int parent_node);
|
||||
|
||||
/* Internal version of prom_getsibling. */
|
||||
extern int __prom_getsibling(int node);
|
||||
|
||||
#endif
|
||||
|
||||
/* Get the child node of the given node, or zero if no child exists. */
|
||||
extern int prom_getchild(int parent_node);
|
||||
|
||||
/* Get the next sibling node of the given node, or zero if no further
|
||||
* siblings exist.
|
||||
*/
|
||||
extern int prom_getsibling(int node);
|
||||
|
||||
/* Get the length, at the passed node, of the given property type.
|
||||
* Returns -1 on error (ie. no such property at this node).
|
||||
*/
|
||||
extern int prom_getproplen(int thisnode, const char *property);
|
||||
|
||||
/* Fetch the requested property using the given buffer. Returns
|
||||
* the number of bytes the prom put into your buffer or -1 on error.
|
||||
*/
|
||||
extern int prom_getproperty(int thisnode, const char *property,
|
||||
char *prop_buffer, int propbuf_size);
|
||||
|
||||
/* Acquire an integer property. */
|
||||
extern int prom_getint(int node, const char *property);
|
||||
|
||||
/* Acquire an integer property, with a default value. */
|
||||
extern int prom_getintdefault(int node, const char *property, int defval);
|
||||
|
||||
/* Acquire a boolean property, 0=FALSE 1=TRUE. */
|
||||
extern int prom_getbool(int node, const char *prop);
|
||||
|
||||
/* Acquire a string property, null string on error. */
|
||||
extern void prom_getstring(int node, const char *prop, char *buf, int bufsize);
|
||||
|
||||
/* Does the passed node have the given "name"? YES=1 NO=0 */
|
||||
extern int prom_nodematch(int thisnode, const char *name);
|
||||
|
||||
/* Search all siblings starting at the passed node for "name" matching
|
||||
* the given string. Returns the node on success, zero on failure.
|
||||
*/
|
||||
extern int prom_searchsiblings(int node_start, const char *name);
|
||||
|
||||
/* Return the first property type, as a string, for the given node.
|
||||
* Returns a null string on error. Buffer should be at least 32B long.
|
||||
*/
|
||||
extern char *prom_firstprop(int node, char *buffer);
|
||||
|
||||
/* Returns the next property after the passed property for the given
|
||||
* node. Returns null string on failure. Buffer should be at least 32B long.
|
||||
*/
|
||||
extern char *prom_nextprop(int node, const char *prev_property, char *buffer);
|
||||
|
||||
/* Returns 1 if the specified node has given property. */
|
||||
extern int prom_node_has_property(int node, const char *property);
|
||||
|
||||
/* Returns phandle of the path specified */
|
||||
extern int prom_finddevice(const char *name);
|
||||
|
||||
/* Set the indicated property at the given node with the passed value.
|
||||
* Returns the number of bytes of your value that the prom took.
|
||||
*/
|
||||
extern int prom_setprop(int node, const char *prop_name, char *prop_value,
|
||||
int value_size);
|
||||
|
||||
extern int prom_pathtoinode(const char *path);
|
||||
extern int prom_inst2pkg(int);
|
||||
extern int prom_service_exists(const char *service_name);
|
||||
extern void prom_sun4v_guest_soft_state(void);
|
||||
|
||||
extern int prom_ihandle2path(int handle, char *buffer, int bufsize);
|
||||
|
||||
/* Client interface level routines. */
|
||||
extern long p1275_cmd(const char *, long, ...);
|
||||
|
||||
#if 0
|
||||
#define P1275_SIZE(x) ((((long)((x) / 32)) << 32) | (x))
|
||||
#else
|
||||
#define P1275_SIZE(x) x
|
||||
#endif
|
||||
|
||||
/* We support at most 16 input and 1 output argument */
|
||||
#define P1275_ARG_NUMBER 0
|
||||
#define P1275_ARG_IN_STRING 1
|
||||
#define P1275_ARG_OUT_BUF 2
|
||||
#define P1275_ARG_OUT_32B 3
|
||||
#define P1275_ARG_IN_FUNCTION 4
|
||||
#define P1275_ARG_IN_BUF 5
|
||||
#define P1275_ARG_IN_64B 6
|
||||
|
||||
#define P1275_IN(x) ((x) & 0xf)
|
||||
#define P1275_OUT(x) (((x) << 4) & 0xf0)
|
||||
#define P1275_INOUT(i,o) (P1275_IN(i)|P1275_OUT(o))
|
||||
#define P1275_ARG(n,x) ((x) << ((n)*3 + 8))
|
||||
|
||||
#endif /* !(__SPARC64_OPLIB_H) */
|
|
@ -1,163 +1,8 @@
|
|||
/*
|
||||
* page.h: Various defines and such for MMU operations on the Sparc for
|
||||
* the Linux kernel.
|
||||
*
|
||||
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
|
||||
*/
|
||||
|
||||
#ifndef _SPARC_PAGE_H
|
||||
#define _SPARC_PAGE_H
|
||||
|
||||
#ifdef CONFIG_SUN4
|
||||
#define PAGE_SHIFT 13
|
||||
#ifndef ___ASM_SPARC_PAGE_H
|
||||
#define ___ASM_SPARC_PAGE_H
|
||||
#if defined(__sparc__) && defined(__arch64__)
|
||||
#include <asm-sparc/page_64.h>
|
||||
#else
|
||||
#define PAGE_SHIFT 12
|
||||
#include <asm-sparc/page_32.h>
|
||||
#endif
|
||||
#ifndef __ASSEMBLY__
|
||||
/* I have my suspicions... -DaveM */
|
||||
#define PAGE_SIZE (1UL << PAGE_SHIFT)
|
||||
#else
|
||||
#define PAGE_SIZE (1 << PAGE_SHIFT)
|
||||
#endif
|
||||
#define PAGE_MASK (~(PAGE_SIZE-1))
|
||||
|
||||
#include <asm/btfixup.h>
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
#define clear_page(page) memset((void *)(page), 0, PAGE_SIZE)
|
||||
#define copy_page(to,from) memcpy((void *)(to), (void *)(from), PAGE_SIZE)
|
||||
#define clear_user_page(addr, vaddr, page) \
|
||||
do { clear_page(addr); \
|
||||
sparc_flush_page_to_ram(page); \
|
||||
} while (0)
|
||||
#define copy_user_page(to, from, vaddr, page) \
|
||||
do { copy_page(to, from); \
|
||||
sparc_flush_page_to_ram(page); \
|
||||
} while (0)
|
||||
|
||||
/* The following structure is used to hold the physical
|
||||
* memory configuration of the machine. This is filled in
|
||||
* prom_meminit() and is later used by mem_init() to set up
|
||||
* mem_map[]. We statically allocate SPARC_PHYS_BANKS+1 of
|
||||
* these structs, this is arbitrary. The entry after the
|
||||
* last valid one has num_bytes==0.
|
||||
*/
|
||||
struct sparc_phys_banks {
|
||||
unsigned long base_addr;
|
||||
unsigned long num_bytes;
|
||||
};
|
||||
|
||||
#define SPARC_PHYS_BANKS 32
|
||||
|
||||
extern struct sparc_phys_banks sp_banks[SPARC_PHYS_BANKS+1];
|
||||
|
||||
/* Cache alias structure. Entry is valid if context != -1. */
|
||||
struct cache_palias {
|
||||
unsigned long vaddr;
|
||||
int context;
|
||||
};
|
||||
|
||||
/* passing structs on the Sparc slow us down tremendously... */
|
||||
|
||||
/* #define STRICT_MM_TYPECHECKS */
|
||||
|
||||
#ifdef STRICT_MM_TYPECHECKS
|
||||
/*
|
||||
* These are used to make use of C type-checking..
|
||||
*/
|
||||
typedef struct { unsigned long pte; } pte_t;
|
||||
typedef struct { unsigned long iopte; } iopte_t;
|
||||
typedef struct { unsigned long pmdv[16]; } pmd_t;
|
||||
typedef struct { unsigned long pgd; } pgd_t;
|
||||
typedef struct { unsigned long ctxd; } ctxd_t;
|
||||
typedef struct { unsigned long pgprot; } pgprot_t;
|
||||
typedef struct { unsigned long iopgprot; } iopgprot_t;
|
||||
|
||||
#define pte_val(x) ((x).pte)
|
||||
#define iopte_val(x) ((x).iopte)
|
||||
#define pmd_val(x) ((x).pmdv[0])
|
||||
#define pgd_val(x) ((x).pgd)
|
||||
#define ctxd_val(x) ((x).ctxd)
|
||||
#define pgprot_val(x) ((x).pgprot)
|
||||
#define iopgprot_val(x) ((x).iopgprot)
|
||||
|
||||
#define __pte(x) ((pte_t) { (x) } )
|
||||
#define __iopte(x) ((iopte_t) { (x) } )
|
||||
/* #define __pmd(x) ((pmd_t) { (x) } ) */ /* XXX procedure with loop */
|
||||
#define __pgd(x) ((pgd_t) { (x) } )
|
||||
#define __ctxd(x) ((ctxd_t) { (x) } )
|
||||
#define __pgprot(x) ((pgprot_t) { (x) } )
|
||||
#define __iopgprot(x) ((iopgprot_t) { (x) } )
|
||||
|
||||
#else
|
||||
/*
|
||||
* .. while these make it easier on the compiler
|
||||
*/
|
||||
typedef unsigned long pte_t;
|
||||
typedef unsigned long iopte_t;
|
||||
typedef struct { unsigned long pmdv[16]; } pmd_t;
|
||||
typedef unsigned long pgd_t;
|
||||
typedef unsigned long ctxd_t;
|
||||
typedef unsigned long pgprot_t;
|
||||
typedef unsigned long iopgprot_t;
|
||||
|
||||
#define pte_val(x) (x)
|
||||
#define iopte_val(x) (x)
|
||||
#define pmd_val(x) ((x).pmdv[0])
|
||||
#define pgd_val(x) (x)
|
||||
#define ctxd_val(x) (x)
|
||||
#define pgprot_val(x) (x)
|
||||
#define iopgprot_val(x) (x)
|
||||
|
||||
#define __pte(x) (x)
|
||||
#define __iopte(x) (x)
|
||||
/* #define __pmd(x) (x) */ /* XXX later */
|
||||
#define __pgd(x) (x)
|
||||
#define __ctxd(x) (x)
|
||||
#define __pgprot(x) (x)
|
||||
#define __iopgprot(x) (x)
|
||||
|
||||
#endif
|
||||
|
||||
typedef struct page *pgtable_t;
|
||||
|
||||
extern unsigned long sparc_unmapped_base;
|
||||
|
||||
BTFIXUPDEF_SETHI(sparc_unmapped_base)
|
||||
|
||||
#define TASK_UNMAPPED_BASE BTFIXUP_SETHI(sparc_unmapped_base)
|
||||
|
||||
#else /* !(__ASSEMBLY__) */
|
||||
|
||||
#define __pgprot(x) (x)
|
||||
|
||||
#endif /* !(__ASSEMBLY__) */
|
||||
|
||||
/* to align the pointer to the (next) page boundary */
|
||||
#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK)
|
||||
|
||||
#define PAGE_OFFSET 0xf0000000
|
||||
#ifndef __ASSEMBLY__
|
||||
extern unsigned long phys_base;
|
||||
extern unsigned long pfn_base;
|
||||
#endif
|
||||
#define __pa(x) ((unsigned long)(x) - PAGE_OFFSET + phys_base)
|
||||
#define __va(x) ((void *)((unsigned long) (x) - phys_base + PAGE_OFFSET))
|
||||
|
||||
#define virt_to_phys __pa
|
||||
#define phys_to_virt __va
|
||||
|
||||
#define ARCH_PFN_OFFSET (pfn_base)
|
||||
#define virt_to_page(kaddr) (mem_map + ((((unsigned long)(kaddr)-PAGE_OFFSET)>>PAGE_SHIFT)))
|
||||
|
||||
#define pfn_valid(pfn) (((pfn) >= (pfn_base)) && (((pfn)-(pfn_base)) < max_mapnr))
|
||||
#define virt_addr_valid(kaddr) ((((unsigned long)(kaddr)-PAGE_OFFSET)>>PAGE_SHIFT) < max_mapnr)
|
||||
|
||||
#define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \
|
||||
VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
|
||||
|
||||
#include <asm-generic/memory_model.h>
|
||||
#include <asm-generic/page.h>
|
||||
|
||||
#endif /* _SPARC_PAGE_H */
|
||||
|
|
163
include/asm-sparc/page_32.h
Normal file
163
include/asm-sparc/page_32.h
Normal file
|
@ -0,0 +1,163 @@
|
|||
/*
|
||||
* page.h: Various defines and such for MMU operations on the Sparc for
|
||||
* the Linux kernel.
|
||||
*
|
||||
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
|
||||
*/
|
||||
|
||||
#ifndef _SPARC_PAGE_H
|
||||
#define _SPARC_PAGE_H
|
||||
|
||||
#ifdef CONFIG_SUN4
|
||||
#define PAGE_SHIFT 13
|
||||
#else
|
||||
#define PAGE_SHIFT 12
|
||||
#endif
|
||||
#ifndef __ASSEMBLY__
|
||||
/* I have my suspicions... -DaveM */
|
||||
#define PAGE_SIZE (1UL << PAGE_SHIFT)
|
||||
#else
|
||||
#define PAGE_SIZE (1 << PAGE_SHIFT)
|
||||
#endif
|
||||
#define PAGE_MASK (~(PAGE_SIZE-1))
|
||||
|
||||
#include <asm/btfixup.h>
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
#define clear_page(page) memset((void *)(page), 0, PAGE_SIZE)
|
||||
#define copy_page(to,from) memcpy((void *)(to), (void *)(from), PAGE_SIZE)
|
||||
#define clear_user_page(addr, vaddr, page) \
|
||||
do { clear_page(addr); \
|
||||
sparc_flush_page_to_ram(page); \
|
||||
} while (0)
|
||||
#define copy_user_page(to, from, vaddr, page) \
|
||||
do { copy_page(to, from); \
|
||||
sparc_flush_page_to_ram(page); \
|
||||
} while (0)
|
||||
|
||||
/* The following structure is used to hold the physical
|
||||
* memory configuration of the machine. This is filled in
|
||||
* prom_meminit() and is later used by mem_init() to set up
|
||||
* mem_map[]. We statically allocate SPARC_PHYS_BANKS+1 of
|
||||
* these structs, this is arbitrary. The entry after the
|
||||
* last valid one has num_bytes==0.
|
||||
*/
|
||||
struct sparc_phys_banks {
|
||||
unsigned long base_addr;
|
||||
unsigned long num_bytes;
|
||||
};
|
||||
|
||||
#define SPARC_PHYS_BANKS 32
|
||||
|
||||
extern struct sparc_phys_banks sp_banks[SPARC_PHYS_BANKS+1];
|
||||
|
||||
/* Cache alias structure. Entry is valid if context != -1. */
|
||||
struct cache_palias {
|
||||
unsigned long vaddr;
|
||||
int context;
|
||||
};
|
||||
|
||||
/* passing structs on the Sparc slow us down tremendously... */
|
||||
|
||||
/* #define STRICT_MM_TYPECHECKS */
|
||||
|
||||
#ifdef STRICT_MM_TYPECHECKS
|
||||
/*
|
||||
* These are used to make use of C type-checking..
|
||||
*/
|
||||
typedef struct { unsigned long pte; } pte_t;
|
||||
typedef struct { unsigned long iopte; } iopte_t;
|
||||
typedef struct { unsigned long pmdv[16]; } pmd_t;
|
||||
typedef struct { unsigned long pgd; } pgd_t;
|
||||
typedef struct { unsigned long ctxd; } ctxd_t;
|
||||
typedef struct { unsigned long pgprot; } pgprot_t;
|
||||
typedef struct { unsigned long iopgprot; } iopgprot_t;
|
||||
|
||||
#define pte_val(x) ((x).pte)
|
||||
#define iopte_val(x) ((x).iopte)
|
||||
#define pmd_val(x) ((x).pmdv[0])
|
||||
#define pgd_val(x) ((x).pgd)
|
||||
#define ctxd_val(x) ((x).ctxd)
|
||||
#define pgprot_val(x) ((x).pgprot)
|
||||
#define iopgprot_val(x) ((x).iopgprot)
|
||||
|
||||
#define __pte(x) ((pte_t) { (x) } )
|
||||
#define __iopte(x) ((iopte_t) { (x) } )
|
||||
/* #define __pmd(x) ((pmd_t) { (x) } ) */ /* XXX procedure with loop */
|
||||
#define __pgd(x) ((pgd_t) { (x) } )
|
||||
#define __ctxd(x) ((ctxd_t) { (x) } )
|
||||
#define __pgprot(x) ((pgprot_t) { (x) } )
|
||||
#define __iopgprot(x) ((iopgprot_t) { (x) } )
|
||||
|
||||
#else
|
||||
/*
|
||||
* .. while these make it easier on the compiler
|
||||
*/
|
||||
typedef unsigned long pte_t;
|
||||
typedef unsigned long iopte_t;
|
||||
typedef struct { unsigned long pmdv[16]; } pmd_t;
|
||||
typedef unsigned long pgd_t;
|
||||
typedef unsigned long ctxd_t;
|
||||
typedef unsigned long pgprot_t;
|
||||
typedef unsigned long iopgprot_t;
|
||||
|
||||
#define pte_val(x) (x)
|
||||
#define iopte_val(x) (x)
|
||||
#define pmd_val(x) ((x).pmdv[0])
|
||||
#define pgd_val(x) (x)
|
||||
#define ctxd_val(x) (x)
|
||||
#define pgprot_val(x) (x)
|
||||
#define iopgprot_val(x) (x)
|
||||
|
||||
#define __pte(x) (x)
|
||||
#define __iopte(x) (x)
|
||||
/* #define __pmd(x) (x) */ /* XXX later */
|
||||
#define __pgd(x) (x)
|
||||
#define __ctxd(x) (x)
|
||||
#define __pgprot(x) (x)
|
||||
#define __iopgprot(x) (x)
|
||||
|
||||
#endif
|
||||
|
||||
typedef struct page *pgtable_t;
|
||||
|
||||
extern unsigned long sparc_unmapped_base;
|
||||
|
||||
BTFIXUPDEF_SETHI(sparc_unmapped_base)
|
||||
|
||||
#define TASK_UNMAPPED_BASE BTFIXUP_SETHI(sparc_unmapped_base)
|
||||
|
||||
#else /* !(__ASSEMBLY__) */
|
||||
|
||||
#define __pgprot(x) (x)
|
||||
|
||||
#endif /* !(__ASSEMBLY__) */
|
||||
|
||||
/* to align the pointer to the (next) page boundary */
|
||||
#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK)
|
||||
|
||||
#define PAGE_OFFSET 0xf0000000
|
||||
#ifndef __ASSEMBLY__
|
||||
extern unsigned long phys_base;
|
||||
extern unsigned long pfn_base;
|
||||
#endif
|
||||
#define __pa(x) ((unsigned long)(x) - PAGE_OFFSET + phys_base)
|
||||
#define __va(x) ((void *)((unsigned long) (x) - phys_base + PAGE_OFFSET))
|
||||
|
||||
#define virt_to_phys __pa
|
||||
#define phys_to_virt __va
|
||||
|
||||
#define ARCH_PFN_OFFSET (pfn_base)
|
||||
#define virt_to_page(kaddr) (mem_map + ((((unsigned long)(kaddr)-PAGE_OFFSET)>>PAGE_SHIFT)))
|
||||
|
||||
#define pfn_valid(pfn) (((pfn) >= (pfn_base)) && (((pfn)-(pfn_base)) < max_mapnr))
|
||||
#define virt_addr_valid(kaddr) ((((unsigned long)(kaddr)-PAGE_OFFSET)>>PAGE_SHIFT) < max_mapnr)
|
||||
|
||||
#define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \
|
||||
VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
|
||||
|
||||
#include <asm-generic/memory_model.h>
|
||||
#include <asm-generic/page.h>
|
||||
|
||||
#endif /* _SPARC_PAGE_H */
|
142
include/asm-sparc/page_64.h
Normal file
142
include/asm-sparc/page_64.h
Normal file
|
@ -0,0 +1,142 @@
|
|||
#ifndef _SPARC64_PAGE_H
|
||||
#define _SPARC64_PAGE_H
|
||||
|
||||
#include <linux/const.h>
|
||||
|
||||
#if defined(CONFIG_SPARC64_PAGE_SIZE_8KB)
|
||||
#define PAGE_SHIFT 13
|
||||
#elif defined(CONFIG_SPARC64_PAGE_SIZE_64KB)
|
||||
#define PAGE_SHIFT 16
|
||||
#elif defined(CONFIG_SPARC64_PAGE_SIZE_512KB)
|
||||
#define PAGE_SHIFT 19
|
||||
#elif defined(CONFIG_SPARC64_PAGE_SIZE_4MB)
|
||||
#define PAGE_SHIFT 22
|
||||
#else
|
||||
#error No page size specified in kernel configuration
|
||||
#endif
|
||||
|
||||
#define PAGE_SIZE (_AC(1,UL) << PAGE_SHIFT)
|
||||
#define PAGE_MASK (~(PAGE_SIZE-1))
|
||||
|
||||
/* Flushing for D-cache alias handling is only needed if
|
||||
* the page size is smaller than 16K.
|
||||
*/
|
||||
#if PAGE_SHIFT < 14
|
||||
#define DCACHE_ALIASING_POSSIBLE
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_HUGETLB_PAGE_SIZE_4MB)
|
||||
#define HPAGE_SHIFT 22
|
||||
#elif defined(CONFIG_HUGETLB_PAGE_SIZE_512K)
|
||||
#define HPAGE_SHIFT 19
|
||||
#elif defined(CONFIG_HUGETLB_PAGE_SIZE_64K)
|
||||
#define HPAGE_SHIFT 16
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_HUGETLB_PAGE
|
||||
#define HPAGE_SIZE (_AC(1,UL) << HPAGE_SHIFT)
|
||||
#define HPAGE_MASK (~(HPAGE_SIZE - 1UL))
|
||||
#define HUGETLB_PAGE_ORDER (HPAGE_SHIFT - PAGE_SHIFT)
|
||||
#define HAVE_ARCH_HUGETLB_UNMAPPED_AREA
|
||||
#endif
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
extern void _clear_page(void *page);
|
||||
#define clear_page(X) _clear_page((void *)(X))
|
||||
struct page;
|
||||
extern void clear_user_page(void *addr, unsigned long vaddr, struct page *page);
|
||||
#define copy_page(X,Y) memcpy((void *)(X), (void *)(Y), PAGE_SIZE)
|
||||
extern void copy_user_page(void *to, void *from, unsigned long vaddr, struct page *topage);
|
||||
|
||||
/* Unlike sparc32, sparc64's parameter passing API is more
|
||||
* sane in that structures which as small enough are passed
|
||||
* in registers instead of on the stack. Thus, setting
|
||||
* STRICT_MM_TYPECHECKS does not generate worse code so
|
||||
* let's enable it to get the type checking.
|
||||
*/
|
||||
|
||||
#define STRICT_MM_TYPECHECKS
|
||||
|
||||
#ifdef STRICT_MM_TYPECHECKS
|
||||
/* These are used to make use of C type-checking.. */
|
||||
typedef struct { unsigned long pte; } pte_t;
|
||||
typedef struct { unsigned long iopte; } iopte_t;
|
||||
typedef struct { unsigned int pmd; } pmd_t;
|
||||
typedef struct { unsigned int pgd; } pgd_t;
|
||||
typedef struct { unsigned long pgprot; } pgprot_t;
|
||||
|
||||
#define pte_val(x) ((x).pte)
|
||||
#define iopte_val(x) ((x).iopte)
|
||||
#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 __iopte(x) ((iopte_t) { (x) } )
|
||||
#define __pmd(x) ((pmd_t) { (x) } )
|
||||
#define __pgd(x) ((pgd_t) { (x) } )
|
||||
#define __pgprot(x) ((pgprot_t) { (x) } )
|
||||
|
||||
#else
|
||||
/* .. while these make it easier on the compiler */
|
||||
typedef unsigned long pte_t;
|
||||
typedef unsigned long iopte_t;
|
||||
typedef unsigned int pmd_t;
|
||||
typedef unsigned int pgd_t;
|
||||
typedef unsigned long pgprot_t;
|
||||
|
||||
#define pte_val(x) (x)
|
||||
#define iopte_val(x) (x)
|
||||
#define pmd_val(x) (x)
|
||||
#define pgd_val(x) (x)
|
||||
#define pgprot_val(x) (x)
|
||||
|
||||
#define __pte(x) (x)
|
||||
#define __iopte(x) (x)
|
||||
#define __pmd(x) (x)
|
||||
#define __pgd(x) (x)
|
||||
#define __pgprot(x) (x)
|
||||
|
||||
#endif /* (STRICT_MM_TYPECHECKS) */
|
||||
|
||||
typedef struct page *pgtable_t;
|
||||
|
||||
#define TASK_UNMAPPED_BASE (test_thread_flag(TIF_32BIT) ? \
|
||||
(_AC(0x0000000070000000,UL)) : \
|
||||
(_AC(0xfffff80000000000,UL) + (1UL << 32UL)))
|
||||
|
||||
#include <asm-generic/memory_model.h>
|
||||
|
||||
#endif /* !(__ASSEMBLY__) */
|
||||
|
||||
/* to align the pointer to the (next) page boundary */
|
||||
#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK)
|
||||
|
||||
/* We used to stick this into a hard-coded global register (%g4)
|
||||
* but that does not make sense anymore.
|
||||
*/
|
||||
#define PAGE_OFFSET _AC(0xFFFFF80000000000,UL)
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
#define __pa(x) ((unsigned long)(x) - PAGE_OFFSET)
|
||||
#define __va(x) ((void *)((unsigned long) (x) + PAGE_OFFSET))
|
||||
|
||||
#define pfn_to_kaddr(pfn) __va((pfn) << PAGE_SHIFT)
|
||||
|
||||
#define virt_to_page(kaddr) pfn_to_page(__pa(kaddr)>>PAGE_SHIFT)
|
||||
|
||||
#define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
|
||||
|
||||
#define virt_to_phys __pa
|
||||
#define phys_to_virt __va
|
||||
|
||||
#endif /* !(__ASSEMBLY__) */
|
||||
|
||||
#define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \
|
||||
VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
|
||||
|
||||
#include <asm-generic/page.h>
|
||||
|
||||
#endif /* _SPARC64_PAGE_H */
|
|
@ -1,170 +1,8 @@
|
|||
#ifndef __SPARC_PCI_H
|
||||
#define __SPARC_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
|
||||
#define pcibios_scan_all_fns(a, b) 0
|
||||
|
||||
#define PCIBIOS_MIN_IO 0UL
|
||||
#define PCIBIOS_MIN_MEM 0UL
|
||||
|
||||
#define PCI_IRQ_NONE 0xffffffff
|
||||
|
||||
static inline void pcibios_set_master(struct pci_dev *dev)
|
||||
{
|
||||
/* No special bus mastering setup handling */
|
||||
}
|
||||
|
||||
static inline void pcibios_penalize_isa_irq(int irq, int active)
|
||||
{
|
||||
/* We don't do dynamic PCI IRQ allocation */
|
||||
}
|
||||
|
||||
/* Dynamic DMA mapping stuff.
|
||||
*/
|
||||
#define PCI_DMA_BUS_IS_PHYS (0)
|
||||
|
||||
#include <asm/scatterlist.h>
|
||||
|
||||
struct pci_dev;
|
||||
|
||||
/* Allocate and map kernel buffer using consistent mode DMA for a device.
|
||||
* hwdev should be valid struct pci_dev pointer for PCI devices.
|
||||
*/
|
||||
extern void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size, dma_addr_t *dma_handle);
|
||||
|
||||
/* Free and unmap a consistent DMA buffer.
|
||||
* cpu_addr is what was returned from pci_alloc_consistent,
|
||||
* size must be the same as what as passed into pci_alloc_consistent,
|
||||
* and likewise dma_addr must be the same as what *dma_addrp was set to.
|
||||
*
|
||||
* References to the memory and mappings assosciated with cpu_addr/dma_addr
|
||||
* past this call are illegal.
|
||||
*/
|
||||
extern void pci_free_consistent(struct pci_dev *hwdev, size_t size, void *vaddr, dma_addr_t dma_handle);
|
||||
|
||||
/* Map a single buffer of the indicated size for DMA in streaming mode.
|
||||
* The 32-bit bus address to use is returned.
|
||||
*
|
||||
* Once the device is given the dma address, the device owns this memory
|
||||
* until either pci_unmap_single or pci_dma_sync_single_for_cpu is performed.
|
||||
*/
|
||||
extern dma_addr_t pci_map_single(struct pci_dev *hwdev, void *ptr, size_t size, int direction);
|
||||
|
||||
/* Unmap a single streaming mode DMA translation. The dma_addr and size
|
||||
* must match what was provided for in a previous pci_map_single call. All
|
||||
* other usages are undefined.
|
||||
*
|
||||
* After this call, reads by the cpu to the buffer are guaranteed to see
|
||||
* whatever the device wrote there.
|
||||
*/
|
||||
extern void pci_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr, size_t size, int direction);
|
||||
|
||||
/* pci_unmap_{single,page} is not a nop, thus... */
|
||||
#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME) \
|
||||
dma_addr_t ADDR_NAME;
|
||||
#define DECLARE_PCI_UNMAP_LEN(LEN_NAME) \
|
||||
__u32 LEN_NAME;
|
||||
#define pci_unmap_addr(PTR, ADDR_NAME) \
|
||||
((PTR)->ADDR_NAME)
|
||||
#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL) \
|
||||
(((PTR)->ADDR_NAME) = (VAL))
|
||||
#define pci_unmap_len(PTR, LEN_NAME) \
|
||||
((PTR)->LEN_NAME)
|
||||
#define pci_unmap_len_set(PTR, LEN_NAME, VAL) \
|
||||
(((PTR)->LEN_NAME) = (VAL))
|
||||
|
||||
/*
|
||||
* Same as above, only with pages instead of mapped addresses.
|
||||
*/
|
||||
extern dma_addr_t pci_map_page(struct pci_dev *hwdev, struct page *page,
|
||||
unsigned long offset, size_t size, int direction);
|
||||
extern void pci_unmap_page(struct pci_dev *hwdev,
|
||||
dma_addr_t dma_address, size_t size, int direction);
|
||||
|
||||
/* Map a set of buffers described by scatterlist in streaming
|
||||
* mode for DMA. This is the scather-gather version of the
|
||||
* above pci_map_single interface. Here the scatter gather list
|
||||
* elements are each tagged with the appropriate dma address
|
||||
* and length. They are obtained via sg_dma_{address,length}(SG).
|
||||
*
|
||||
* NOTE: An implementation may be able to use a smaller number of
|
||||
* DMA address/length pairs than there are SG table elements.
|
||||
* (for example via virtual mapping capabilities)
|
||||
* The routine returns the number of addr/length pairs actually
|
||||
* used, at most nents.
|
||||
*
|
||||
* Device ownership issues as mentioned above for pci_map_single are
|
||||
* the same here.
|
||||
*/
|
||||
extern int pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nents, int direction);
|
||||
|
||||
/* Unmap a set of streaming mode DMA translations.
|
||||
* Again, cpu read rules concerning calls here are the same as for
|
||||
* pci_unmap_single() above.
|
||||
*/
|
||||
extern void pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nhwents, int direction);
|
||||
|
||||
/* Make physical memory consistent for a single
|
||||
* streaming mode DMA translation after a transfer.
|
||||
*
|
||||
* If you perform a pci_map_single() but wish to interrogate the
|
||||
* buffer using the cpu, yet do not wish to teardown the PCI dma
|
||||
* mapping, you must call this function before doing so. At the
|
||||
* next point you give the PCI dma address back to the card, you
|
||||
* must first perform a pci_dma_sync_for_device, and then the device
|
||||
* again owns the buffer.
|
||||
*/
|
||||
extern void pci_dma_sync_single_for_cpu(struct pci_dev *hwdev, dma_addr_t dma_handle, size_t size, int direction);
|
||||
extern void pci_dma_sync_single_for_device(struct pci_dev *hwdev, dma_addr_t dma_handle, size_t size, int direction);
|
||||
|
||||
/* Make physical memory consistent for a set of streaming
|
||||
* mode DMA translations after a transfer.
|
||||
*
|
||||
* The same as pci_dma_sync_single_* but for a scatter-gather list,
|
||||
* same rules and usage.
|
||||
*/
|
||||
extern void pci_dma_sync_sg_for_cpu(struct pci_dev *hwdev, struct scatterlist *sg, int nelems, int direction);
|
||||
extern void pci_dma_sync_sg_for_device(struct pci_dev *hwdev, struct scatterlist *sg, int nelems, int direction);
|
||||
|
||||
/* Return whether the given PCI device DMA address mask can
|
||||
* be supported properly. For example, if your device can
|
||||
* only drive the low 24-bits during PCI bus mastering, then
|
||||
* you would pass 0x00ffffff as the mask to this function.
|
||||
*/
|
||||
static inline int pci_dma_supported(struct pci_dev *hwdev, u64 mask)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
static inline void pci_dma_burst_advice(struct pci_dev *pdev,
|
||||
enum pci_dma_burst_strategy *strat,
|
||||
unsigned long *strategy_parameter)
|
||||
{
|
||||
*strat = PCI_DMA_BURST_INFINITY;
|
||||
*strategy_parameter = ~0UL;
|
||||
}
|
||||
#ifndef ___ASM_SPARC_PCI_H
|
||||
#define ___ASM_SPARC_PCI_H
|
||||
#if defined(__sparc__) && defined(__arch64__)
|
||||
#include <asm-sparc/pci_64.h>
|
||||
#else
|
||||
#include <asm-sparc/pci_32.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define PCI_DMA_ERROR_CODE (~(dma_addr_t)0x0)
|
||||
|
||||
static inline int pci_dma_mapping_error(dma_addr_t dma_addr)
|
||||
{
|
||||
return (dma_addr == PCI_DMA_ERROR_CODE);
|
||||
}
|
||||
|
||||
struct device_node;
|
||||
extern struct device_node *pci_device_to_OF_node(struct pci_dev *pdev);
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
/* generic pci stuff */
|
||||
#include <asm-generic/pci.h>
|
||||
|
||||
#endif /* __SPARC_PCI_H */
|
||||
|
|
170
include/asm-sparc/pci_32.h
Normal file
170
include/asm-sparc/pci_32.h
Normal file
|
@ -0,0 +1,170 @@
|
|||
#ifndef __SPARC_PCI_H
|
||||
#define __SPARC_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
|
||||
#define pcibios_scan_all_fns(a, b) 0
|
||||
|
||||
#define PCIBIOS_MIN_IO 0UL
|
||||
#define PCIBIOS_MIN_MEM 0UL
|
||||
|
||||
#define PCI_IRQ_NONE 0xffffffff
|
||||
|
||||
static inline void pcibios_set_master(struct pci_dev *dev)
|
||||
{
|
||||
/* No special bus mastering setup handling */
|
||||
}
|
||||
|
||||
static inline void pcibios_penalize_isa_irq(int irq, int active)
|
||||
{
|
||||
/* We don't do dynamic PCI IRQ allocation */
|
||||
}
|
||||
|
||||
/* Dynamic DMA mapping stuff.
|
||||
*/
|
||||
#define PCI_DMA_BUS_IS_PHYS (0)
|
||||
|
||||
#include <asm/scatterlist.h>
|
||||
|
||||
struct pci_dev;
|
||||
|
||||
/* Allocate and map kernel buffer using consistent mode DMA for a device.
|
||||
* hwdev should be valid struct pci_dev pointer for PCI devices.
|
||||
*/
|
||||
extern void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size, dma_addr_t *dma_handle);
|
||||
|
||||
/* Free and unmap a consistent DMA buffer.
|
||||
* cpu_addr is what was returned from pci_alloc_consistent,
|
||||
* size must be the same as what as passed into pci_alloc_consistent,
|
||||
* and likewise dma_addr must be the same as what *dma_addrp was set to.
|
||||
*
|
||||
* References to the memory and mappings assosciated with cpu_addr/dma_addr
|
||||
* past this call are illegal.
|
||||
*/
|
||||
extern void pci_free_consistent(struct pci_dev *hwdev, size_t size, void *vaddr, dma_addr_t dma_handle);
|
||||
|
||||
/* Map a single buffer of the indicated size for DMA in streaming mode.
|
||||
* The 32-bit bus address to use is returned.
|
||||
*
|
||||
* Once the device is given the dma address, the device owns this memory
|
||||
* until either pci_unmap_single or pci_dma_sync_single_for_cpu is performed.
|
||||
*/
|
||||
extern dma_addr_t pci_map_single(struct pci_dev *hwdev, void *ptr, size_t size, int direction);
|
||||
|
||||
/* Unmap a single streaming mode DMA translation. The dma_addr and size
|
||||
* must match what was provided for in a previous pci_map_single call. All
|
||||
* other usages are undefined.
|
||||
*
|
||||
* After this call, reads by the cpu to the buffer are guaranteed to see
|
||||
* whatever the device wrote there.
|
||||
*/
|
||||
extern void pci_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr, size_t size, int direction);
|
||||
|
||||
/* pci_unmap_{single,page} is not a nop, thus... */
|
||||
#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME) \
|
||||
dma_addr_t ADDR_NAME;
|
||||
#define DECLARE_PCI_UNMAP_LEN(LEN_NAME) \
|
||||
__u32 LEN_NAME;
|
||||
#define pci_unmap_addr(PTR, ADDR_NAME) \
|
||||
((PTR)->ADDR_NAME)
|
||||
#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL) \
|
||||
(((PTR)->ADDR_NAME) = (VAL))
|
||||
#define pci_unmap_len(PTR, LEN_NAME) \
|
||||
((PTR)->LEN_NAME)
|
||||
#define pci_unmap_len_set(PTR, LEN_NAME, VAL) \
|
||||
(((PTR)->LEN_NAME) = (VAL))
|
||||
|
||||
/*
|
||||
* Same as above, only with pages instead of mapped addresses.
|
||||
*/
|
||||
extern dma_addr_t pci_map_page(struct pci_dev *hwdev, struct page *page,
|
||||
unsigned long offset, size_t size, int direction);
|
||||
extern void pci_unmap_page(struct pci_dev *hwdev,
|
||||
dma_addr_t dma_address, size_t size, int direction);
|
||||
|
||||
/* Map a set of buffers described by scatterlist in streaming
|
||||
* mode for DMA. This is the scather-gather version of the
|
||||
* above pci_map_single interface. Here the scatter gather list
|
||||
* elements are each tagged with the appropriate dma address
|
||||
* and length. They are obtained via sg_dma_{address,length}(SG).
|
||||
*
|
||||
* NOTE: An implementation may be able to use a smaller number of
|
||||
* DMA address/length pairs than there are SG table elements.
|
||||
* (for example via virtual mapping capabilities)
|
||||
* The routine returns the number of addr/length pairs actually
|
||||
* used, at most nents.
|
||||
*
|
||||
* Device ownership issues as mentioned above for pci_map_single are
|
||||
* the same here.
|
||||
*/
|
||||
extern int pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nents, int direction);
|
||||
|
||||
/* Unmap a set of streaming mode DMA translations.
|
||||
* Again, cpu read rules concerning calls here are the same as for
|
||||
* pci_unmap_single() above.
|
||||
*/
|
||||
extern void pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nhwents, int direction);
|
||||
|
||||
/* Make physical memory consistent for a single
|
||||
* streaming mode DMA translation after a transfer.
|
||||
*
|
||||
* If you perform a pci_map_single() but wish to interrogate the
|
||||
* buffer using the cpu, yet do not wish to teardown the PCI dma
|
||||
* mapping, you must call this function before doing so. At the
|
||||
* next point you give the PCI dma address back to the card, you
|
||||
* must first perform a pci_dma_sync_for_device, and then the device
|
||||
* again owns the buffer.
|
||||
*/
|
||||
extern void pci_dma_sync_single_for_cpu(struct pci_dev *hwdev, dma_addr_t dma_handle, size_t size, int direction);
|
||||
extern void pci_dma_sync_single_for_device(struct pci_dev *hwdev, dma_addr_t dma_handle, size_t size, int direction);
|
||||
|
||||
/* Make physical memory consistent for a set of streaming
|
||||
* mode DMA translations after a transfer.
|
||||
*
|
||||
* The same as pci_dma_sync_single_* but for a scatter-gather list,
|
||||
* same rules and usage.
|
||||
*/
|
||||
extern void pci_dma_sync_sg_for_cpu(struct pci_dev *hwdev, struct scatterlist *sg, int nelems, int direction);
|
||||
extern void pci_dma_sync_sg_for_device(struct pci_dev *hwdev, struct scatterlist *sg, int nelems, int direction);
|
||||
|
||||
/* Return whether the given PCI device DMA address mask can
|
||||
* be supported properly. For example, if your device can
|
||||
* only drive the low 24-bits during PCI bus mastering, then
|
||||
* you would pass 0x00ffffff as the mask to this function.
|
||||
*/
|
||||
static inline int pci_dma_supported(struct pci_dev *hwdev, u64 mask)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
static inline void pci_dma_burst_advice(struct pci_dev *pdev,
|
||||
enum pci_dma_burst_strategy *strat,
|
||||
unsigned long *strategy_parameter)
|
||||
{
|
||||
*strat = PCI_DMA_BURST_INFINITY;
|
||||
*strategy_parameter = ~0UL;
|
||||
}
|
||||
#endif
|
||||
|
||||
#define PCI_DMA_ERROR_CODE (~(dma_addr_t)0x0)
|
||||
|
||||
static inline int pci_dma_mapping_error(dma_addr_t dma_addr)
|
||||
{
|
||||
return (dma_addr == PCI_DMA_ERROR_CODE);
|
||||
}
|
||||
|
||||
struct device_node;
|
||||
extern struct device_node *pci_device_to_OF_node(struct pci_dev *pdev);
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
/* generic pci stuff */
|
||||
#include <asm-generic/pci.h>
|
||||
|
||||
#endif /* __SPARC_PCI_H */
|
209
include/asm-sparc/pci_64.h
Normal file
209
include/asm-sparc/pci_64.h
Normal file
|
@ -0,0 +1,209 @@
|
|||
#ifndef __SPARC64_PCI_H
|
||||
#define __SPARC64_PCI_H
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
#include <linux/dma-mapping.h>
|
||||
|
||||
/* 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
|
||||
#define pcibios_scan_all_fns(a, b) 0
|
||||
|
||||
#define PCIBIOS_MIN_IO 0UL
|
||||
#define PCIBIOS_MIN_MEM 0UL
|
||||
|
||||
#define PCI_IRQ_NONE 0xffffffff
|
||||
|
||||
#define PCI_CACHE_LINE_BYTES 64
|
||||
|
||||
static inline void pcibios_set_master(struct pci_dev *dev)
|
||||
{
|
||||
/* No special bus mastering setup handling */
|
||||
}
|
||||
|
||||
static inline void pcibios_penalize_isa_irq(int irq, int active)
|
||||
{
|
||||
/* We don't do dynamic PCI IRQ allocation */
|
||||
}
|
||||
|
||||
/* The PCI address space does not 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 (0)
|
||||
|
||||
static inline void *pci_alloc_consistent(struct pci_dev *pdev, size_t size,
|
||||
dma_addr_t *dma_handle)
|
||||
{
|
||||
return dma_alloc_coherent(&pdev->dev, size, dma_handle, GFP_ATOMIC);
|
||||
}
|
||||
|
||||
static inline void pci_free_consistent(struct pci_dev *pdev, size_t size,
|
||||
void *vaddr, dma_addr_t dma_handle)
|
||||
{
|
||||
return dma_free_coherent(&pdev->dev, size, vaddr, dma_handle);
|
||||
}
|
||||
|
||||
static inline dma_addr_t pci_map_single(struct pci_dev *pdev, void *ptr,
|
||||
size_t size, int direction)
|
||||
{
|
||||
return dma_map_single(&pdev->dev, ptr, size,
|
||||
(enum dma_data_direction) direction);
|
||||
}
|
||||
|
||||
static inline void pci_unmap_single(struct pci_dev *pdev, dma_addr_t dma_addr,
|
||||
size_t size, int direction)
|
||||
{
|
||||
dma_unmap_single(&pdev->dev, dma_addr, size,
|
||||
(enum dma_data_direction) direction);
|
||||
}
|
||||
|
||||
#define pci_map_page(dev, page, off, size, dir) \
|
||||
pci_map_single(dev, (page_address(page) + (off)), size, dir)
|
||||
#define pci_unmap_page(dev,addr,sz,dir) \
|
||||
pci_unmap_single(dev,addr,sz,dir)
|
||||
|
||||
/* pci_unmap_{single,page} is not a nop, thus... */
|
||||
#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME) \
|
||||
dma_addr_t ADDR_NAME;
|
||||
#define DECLARE_PCI_UNMAP_LEN(LEN_NAME) \
|
||||
__u32 LEN_NAME;
|
||||
#define pci_unmap_addr(PTR, ADDR_NAME) \
|
||||
((PTR)->ADDR_NAME)
|
||||
#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL) \
|
||||
(((PTR)->ADDR_NAME) = (VAL))
|
||||
#define pci_unmap_len(PTR, LEN_NAME) \
|
||||
((PTR)->LEN_NAME)
|
||||
#define pci_unmap_len_set(PTR, LEN_NAME, VAL) \
|
||||
(((PTR)->LEN_NAME) = (VAL))
|
||||
|
||||
static inline int pci_map_sg(struct pci_dev *pdev, struct scatterlist *sg,
|
||||
int nents, int direction)
|
||||
{
|
||||
return dma_map_sg(&pdev->dev, sg, nents,
|
||||
(enum dma_data_direction) direction);
|
||||
}
|
||||
|
||||
static inline void pci_unmap_sg(struct pci_dev *pdev, struct scatterlist *sg,
|
||||
int nents, int direction)
|
||||
{
|
||||
dma_unmap_sg(&pdev->dev, sg, nents,
|
||||
(enum dma_data_direction) direction);
|
||||
}
|
||||
|
||||
static inline void pci_dma_sync_single_for_cpu(struct pci_dev *pdev,
|
||||
dma_addr_t dma_handle,
|
||||
size_t size, int direction)
|
||||
{
|
||||
dma_sync_single_for_cpu(&pdev->dev, dma_handle, size,
|
||||
(enum dma_data_direction) direction);
|
||||
}
|
||||
|
||||
static inline void pci_dma_sync_single_for_device(struct pci_dev *pdev,
|
||||
dma_addr_t dma_handle,
|
||||
size_t size, int direction)
|
||||
{
|
||||
/* No flushing needed to sync cpu writes to the device. */
|
||||
}
|
||||
|
||||
static inline void pci_dma_sync_sg_for_cpu(struct pci_dev *pdev,
|
||||
struct scatterlist *sg,
|
||||
int nents, int direction)
|
||||
{
|
||||
dma_sync_sg_for_cpu(&pdev->dev, sg, nents,
|
||||
(enum dma_data_direction) direction);
|
||||
}
|
||||
|
||||
static inline void pci_dma_sync_sg_for_device(struct pci_dev *pdev,
|
||||
struct scatterlist *sg,
|
||||
int nelems, int direction)
|
||||
{
|
||||
/* No flushing needed to sync cpu writes to the device. */
|
||||
}
|
||||
|
||||
/* Return whether the given PCI device DMA address mask can
|
||||
* be supported properly. For example, if your device can
|
||||
* only drive the low 24-bits during PCI bus mastering, then
|
||||
* you would pass 0x00ffffff as the mask to this function.
|
||||
*/
|
||||
extern int pci_dma_supported(struct pci_dev *hwdev, u64 mask);
|
||||
|
||||
/* PCI IOMMU mapping bypass support. */
|
||||
|
||||
/* PCI 64-bit addressing works for all slots on all controller
|
||||
* types on sparc64. However, it requires that the device
|
||||
* can drive enough of the 64 bits.
|
||||
*/
|
||||
#define PCI64_REQUIRED_MASK (~(dma64_addr_t)0)
|
||||
#define PCI64_ADDR_BASE 0xfffc000000000000UL
|
||||
|
||||
static inline int pci_dma_mapping_error(dma_addr_t dma_addr)
|
||||
{
|
||||
return dma_mapping_error(dma_addr);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
static inline void pci_dma_burst_advice(struct pci_dev *pdev,
|
||||
enum pci_dma_burst_strategy *strat,
|
||||
unsigned long *strategy_parameter)
|
||||
{
|
||||
unsigned long cacheline_size;
|
||||
u8 byte;
|
||||
|
||||
pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &byte);
|
||||
if (byte == 0)
|
||||
cacheline_size = 1024;
|
||||
else
|
||||
cacheline_size = (int) byte * 4;
|
||||
|
||||
*strat = PCI_DMA_BURST_BOUNDARY;
|
||||
*strategy_parameter = cacheline_size;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Return the index of the PCI controller for device PDEV. */
|
||||
|
||||
extern int pci_domain_nr(struct pci_bus *bus);
|
||||
static inline int pci_proc_domain(struct pci_bus *bus)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Platform support for /proc/bus/pci/X/Y mmap()s. */
|
||||
|
||||
#define HAVE_PCI_MMAP
|
||||
#define HAVE_ARCH_PCI_GET_UNMAPPED_AREA
|
||||
#define get_pci_unmapped_area get_fb_unmapped_area
|
||||
|
||||
extern int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
|
||||
enum pci_mmap_state mmap_state,
|
||||
int write_combine);
|
||||
|
||||
extern void
|
||||
pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
|
||||
struct resource *res);
|
||||
|
||||
extern void
|
||||
pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
|
||||
struct pci_bus_region *region);
|
||||
|
||||
extern struct resource *pcibios_select_root(struct pci_dev *, struct resource *);
|
||||
|
||||
static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel)
|
||||
{
|
||||
return PCI_IRQ_NONE;
|
||||
}
|
||||
|
||||
struct device_node;
|
||||
extern struct device_node *pci_device_to_OF_node(struct pci_dev *pdev);
|
||||
|
||||
#define HAVE_ARCH_PCI_RESOURCE_TO_USER
|
||||
extern void pci_resource_to_user(const struct pci_dev *dev, int bar,
|
||||
const struct resource *rsrc,
|
||||
resource_size_t *start, resource_size_t *end);
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
#endif /* __SPARC64_PCI_H */
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue