mirror of https://github.com/hak5/openwrt-owl.git
1647 lines
43 KiB
Diff
1647 lines
43 KiB
Diff
From 127797e5cf8a036825007586b914b75897aba554 Mon Sep 17 00:00:00 2001
|
|
From: Kurt Mahan <kmahan@freescale.com>
|
|
Date: Wed, 31 Oct 2007 16:39:31 -0600
|
|
Subject: [PATCH] Add Coldfire Support into existing headers.
|
|
|
|
Modifications to the various M68k header files to add
|
|
Coldfire processor support.
|
|
|
|
LTIBName: mcfv4e-coldfire-headers
|
|
Signed-off-by: Kurt Mahan <kmahan@freescale.com>
|
|
---
|
|
include/asm-m68k/atomic.h | 23 ++-
|
|
include/asm-m68k/bitops.h | 426 ++++++++++++++++++++++++++++++++++++++++
|
|
include/asm-m68k/bootinfo.h | 13 ++
|
|
include/asm-m68k/byteorder.h | 12 +-
|
|
include/asm-m68k/cacheflush.h | 4 +
|
|
include/asm-m68k/checksum.h | 10 +
|
|
include/asm-m68k/delay.h | 26 +++
|
|
include/asm-m68k/div64.h | 4 +
|
|
include/asm-m68k/elf.h | 2 +-
|
|
include/asm-m68k/fpu.h | 2 +
|
|
include/asm-m68k/io.h | 26 +++-
|
|
include/asm-m68k/irq.h | 5 +-
|
|
include/asm-m68k/machdep.h | 7 +
|
|
include/asm-m68k/mmu_context.h | 84 ++++++++-
|
|
include/asm-m68k/page.h | 20 ++-
|
|
include/asm-m68k/page_offset.h | 7 +-
|
|
include/asm-m68k/pci.h | 99 ++++++----
|
|
include/asm-m68k/pgalloc.h | 4 +-
|
|
include/asm-m68k/pgtable.h | 15 ++
|
|
include/asm-m68k/processor.h | 46 ++++-
|
|
include/asm-m68k/ptrace.h | 11 +
|
|
include/asm-m68k/raw_io.h | 58 ++++++
|
|
include/asm-m68k/segment.h | 10 +
|
|
include/asm-m68k/setup.h | 27 +++
|
|
include/asm-m68k/signal.h | 5 +
|
|
include/asm-m68k/string.h | 2 +
|
|
include/asm-m68k/system.h | 17 ++-
|
|
include/asm-m68k/thread_info.h | 1 +
|
|
include/asm-m68k/tlbflush.h | 16 ++-
|
|
include/asm-m68k/uaccess.h | 4 +
|
|
30 files changed, 925 insertions(+), 61 deletions(-)
|
|
|
|
--- a/include/asm-m68k/atomic.h
|
|
+++ b/include/asm-m68k/atomic.h
|
|
@@ -2,7 +2,7 @@
|
|
#define __ARCH_M68K_ATOMIC__
|
|
|
|
|
|
-#include <asm/system.h>
|
|
+#include <asm/system.h> /* local_irq_XXX() */
|
|
|
|
/*
|
|
* Atomic operations that C can't guarantee us. Useful for
|
|
@@ -21,12 +21,20 @@ typedef struct { int counter; } atomic_t
|
|
|
|
static inline void atomic_add(int i, atomic_t *v)
|
|
{
|
|
+#ifndef CONFIG_COLDFIRE
|
|
__asm__ __volatile__("addl %1,%0" : "+m" (*v) : "id" (i));
|
|
+#else
|
|
+ __asm__ __volatile__("addl %1,%0" : "=m" (*v) : "d" (i), "m" (*v));
|
|
+#endif
|
|
}
|
|
|
|
static inline void atomic_sub(int i, atomic_t *v)
|
|
{
|
|
+#ifndef CONFIG_COLDFIRE
|
|
__asm__ __volatile__("subl %1,%0" : "+m" (*v) : "id" (i));
|
|
+#else
|
|
+ __asm__ __volatile__("subl %1,%0" : "=m" (*v) : "d" (i), "m" (*v));
|
|
+#endif
|
|
}
|
|
|
|
static inline void atomic_inc(atomic_t *v)
|
|
@@ -46,6 +54,14 @@ static inline int atomic_dec_and_test(at
|
|
return c != 0;
|
|
}
|
|
|
|
+static __inline__ int atomic_dec_and_test_lt(volatile atomic_t *v)
|
|
+{
|
|
+ char c;
|
|
+ __asm__ __volatile__("subql #1,%1; slt %0" : "=d" (c), "=m" (*v)
|
|
+ : "m" (*v));
|
|
+ return c != 0 ;
|
|
+}
|
|
+
|
|
static inline int atomic_inc_and_test(atomic_t *v)
|
|
{
|
|
char c;
|
|
@@ -156,7 +172,12 @@ static inline int atomic_sub_and_test(in
|
|
static inline int atomic_add_negative(int i, atomic_t *v)
|
|
{
|
|
char c;
|
|
+#ifndef CONFIG_COLDFIRE
|
|
__asm__ __volatile__("addl %2,%1; smi %0" : "=d" (c), "+m" (*v): "g" (i));
|
|
+#else
|
|
+ __asm__ __volatile__("addl %2,%1; smi %0" : "=d" (c), "=m" (*v)
|
|
+ : "d" (i) , "m" (*v));
|
|
+#endif
|
|
return c != 0;
|
|
}
|
|
|
|
--- a/include/asm-m68k/bitops.h
|
|
+++ b/include/asm-m68k/bitops.h
|
|
@@ -19,6 +19,7 @@
|
|
*
|
|
* They use the standard big-endian m680x0 bit ordering.
|
|
*/
|
|
+#ifndef CONFIG_COLDFIRE
|
|
|
|
#define test_and_set_bit(nr,vaddr) \
|
|
(__builtin_constant_p(nr) ? \
|
|
@@ -457,4 +458,429 @@ static inline int ext2_find_next_bit(con
|
|
|
|
#endif /* __KERNEL__ */
|
|
|
|
+#else /* CONFIG_COLDFIRE */
|
|
+
|
|
+#define test_and_set_bit(nr,vaddr) \
|
|
+ (__builtin_constant_p(nr) ? \
|
|
+ __constant_coldfire_test_and_set_bit(nr, vaddr) : \
|
|
+ __generic_coldfire_test_and_set_bit(nr, vaddr))
|
|
+
|
|
+
|
|
+static __inline__ int __constant_coldfire_test_and_set_bit(int nr,
|
|
+ volatile void *vaddr)
|
|
+{
|
|
+ char retval;
|
|
+ volatile char *p = &((volatile char *)vaddr)[(nr^31) >> 3];
|
|
+
|
|
+ __asm__ __volatile__ ("bset %2,%1; sne %0"
|
|
+ : "=d" (retval), "+QUd" (*p)
|
|
+ : "di" (nr & 7));
|
|
+ return retval;
|
|
+}
|
|
+
|
|
+static __inline__ int __generic_coldfire_test_and_set_bit(int nr,
|
|
+ volatile void *vaddr)
|
|
+{
|
|
+ char retval;
|
|
+
|
|
+ __asm__ __volatile__ ("bset %2,%1; sne %0"
|
|
+ : "=d" (retval), "=m" (((volatile char *)vaddr)[(nr^31) >> 3])
|
|
+ : "d" (nr)
|
|
+ : "memory");
|
|
+ return retval;
|
|
+}
|
|
+#define __test_and_set_bit(nr, vaddr) test_and_set_bit(nr, vaddr)
|
|
+
|
|
+#define set_bit(nr,vaddr) \
|
|
+ (__builtin_constant_p(nr) ? \
|
|
+ __constant_coldfire_set_bit(nr, vaddr) : \
|
|
+ __generic_coldfire_set_bit(nr, vaddr))
|
|
+
|
|
+static __inline__ void __constant_coldfire_set_bit(int nr,
|
|
+ volatile void *vaddr)
|
|
+{
|
|
+ volatile char *p = &((volatile char *)vaddr)[(nr^31) >> 3];
|
|
+ __asm__ __volatile__ ("bset %1,%0"
|
|
+ : "+QUd" (*p) : "di" (nr & 7));
|
|
+}
|
|
+
|
|
+static __inline__ void __generic_coldfire_set_bit(int nr, volatile void *vaddr)
|
|
+{
|
|
+ __asm__ __volatile__ ("bset %1,%0"
|
|
+ : "=m" (((volatile char *)vaddr)[(nr^31) >> 3])
|
|
+ : "d" (nr)
|
|
+ : "memory");
|
|
+}
|
|
+#define __set_bit(nr, vaddr) set_bit(nr, vaddr)
|
|
+
|
|
+#define test_and_clear_bit(nr, vaddr) \
|
|
+ (__builtin_constant_p(nr) ? \
|
|
+ __constant_coldfire_test_and_clear_bit(nr, vaddr) : \
|
|
+ __generic_coldfire_test_and_clear_bit(nr, vaddr))
|
|
+
|
|
+static __inline__ int __constant_coldfire_test_and_clear_bit(int nr,
|
|
+ volatile void *vaddr)
|
|
+{
|
|
+ char retval;
|
|
+ volatile char *p = &((volatile char *)vaddr)[(nr^31) >> 3];
|
|
+
|
|
+ __asm__ __volatile__ ("bclr %2,%1; sne %0"
|
|
+ : "=d" (retval), "+QUd" (*p)
|
|
+ : "id" (nr & 7));
|
|
+
|
|
+ return retval;
|
|
+}
|
|
+
|
|
+static __inline__ int __generic_coldfire_test_and_clear_bit(int nr,
|
|
+ volatile void *vaddr)
|
|
+{
|
|
+ char retval;
|
|
+
|
|
+ __asm__ __volatile__ ("bclr %2,%1; sne %0"
|
|
+ : "=d" (retval), "=m" (((volatile char *)vaddr)[(nr^31) >> 3])
|
|
+ : "d" (nr & 7)
|
|
+ : "memory");
|
|
+
|
|
+ return retval;
|
|
+}
|
|
+#define __test_and_clear_bit(nr, vaddr) test_and_clear_bit(nr, vaddr)
|
|
+
|
|
+/*
|
|
+ * clear_bit() doesn't provide any barrier for the compiler.
|
|
+ */
|
|
+#define smp_mb__before_clear_bit() barrier()
|
|
+#define smp_mb__after_clear_bit() barrier()
|
|
+
|
|
+#define clear_bit(nr,vaddr) \
|
|
+ (__builtin_constant_p(nr) ? \
|
|
+ __constant_coldfire_clear_bit(nr, vaddr) : \
|
|
+ __generic_coldfire_clear_bit(nr, vaddr))
|
|
+
|
|
+static __inline__ void __constant_coldfire_clear_bit(int nr,
|
|
+ volatile void *vaddr)
|
|
+{
|
|
+ volatile char *p = &((volatile char *)vaddr)[(nr^31) >> 3];
|
|
+ __asm__ __volatile__ ("bclr %1,%0"
|
|
+ : "+QUd" (*p) : "id" (nr & 7));
|
|
+}
|
|
+
|
|
+static __inline__ void __generic_coldfire_clear_bit(int nr,
|
|
+ volatile void *vaddr)
|
|
+{
|
|
+ __asm__ __volatile__ ("bclr %1,%0"
|
|
+ : "=m" (((volatile char *)vaddr)[(nr^31) >> 3])
|
|
+ : "d" (nr)
|
|
+ : "memory");
|
|
+}
|
|
+#define __clear_bit(nr, vaddr) clear_bit(nr, vaddr)
|
|
+
|
|
+#define test_and_change_bit(nr, vaddr) \
|
|
+ (__builtin_constant_p(nr) ? \
|
|
+ __constant_coldfire_test_and_change_bit(nr, vaddr) : \
|
|
+ __generic_coldfire_test_and_change_bit(nr, vaddr))
|
|
+
|
|
+static __inline__ int __constant_coldfire_test_and_change_bit(int nr,
|
|
+ volatile void *vaddr)
|
|
+{
|
|
+ char retval;
|
|
+ volatile char *p = &((volatile char *)vaddr)[(nr^31) >> 3];
|
|
+
|
|
+ __asm__ __volatile__ ("bchg %2,%1; sne %0"
|
|
+ : "=d" (retval), "+QUd" (*p)
|
|
+ : "id" (nr & 7));
|
|
+
|
|
+ return retval;
|
|
+}
|
|
+
|
|
+static __inline__ int __generic_coldfire_test_and_change_bit(int nr,
|
|
+ volatile void *vaddr)
|
|
+{
|
|
+ char retval;
|
|
+
|
|
+ __asm__ __volatile__ ("bchg %2,%1; sne %0"
|
|
+ : "=d" (retval), "=m" (((volatile char *)vaddr)[(nr^31) >> 3])
|
|
+ : "id" (nr)
|
|
+ : "memory");
|
|
+
|
|
+ return retval;
|
|
+}
|
|
+#define __test_and_change_bit(nr, vaddr) test_and_change_bit(nr, vaddr)
|
|
+#define __change_bit(nr, vaddr) change_bit(nr, vaddr)
|
|
+
|
|
+#define change_bit(nr,vaddr) \
|
|
+ (__builtin_constant_p(nr) ? \
|
|
+ __constant_coldfire_change_bit(nr, vaddr) : \
|
|
+ __generic_coldfire_change_bit(nr, vaddr))
|
|
+
|
|
+static __inline__ void __constant_coldfire_change_bit(int nr,
|
|
+ volatile void *vaddr)
|
|
+{
|
|
+ volatile char *p = &((volatile char *)vaddr)[(nr^31) >> 3];
|
|
+ __asm__ __volatile__ ("bchg %1,%0"
|
|
+ : "+QUd" (*p) : "id" (nr & 7));
|
|
+}
|
|
+
|
|
+static __inline__ void __generic_coldfire_change_bit(int nr,
|
|
+ volatile void *vaddr)
|
|
+{
|
|
+ __asm__ __volatile__ ("bchg %1,%0"
|
|
+ : "=m" (((volatile char *)vaddr)[(nr^31) >> 3])
|
|
+ : "d" (nr)
|
|
+ : "memory");
|
|
+}
|
|
+
|
|
+static inline int test_bit(int nr, const unsigned long *vaddr)
|
|
+{
|
|
+ return (vaddr[nr >> 5] & (1UL << (nr & 31))) != 0;
|
|
+}
|
|
+
|
|
+static __inline__ unsigned long ffz(unsigned long word)
|
|
+{
|
|
+ unsigned long result = 0;
|
|
+
|
|
+ while (word & 1) {
|
|
+ result++;
|
|
+ word >>= 1;
|
|
+ }
|
|
+ return result;
|
|
+}
|
|
+
|
|
+/* find_next_zero_bit() finds the first zero bit in a bit string of length
|
|
+ * 'size' bits, starting the search at bit 'offset'. This is largely based
|
|
+ * on Linus's ALPHA routines.
|
|
+ */
|
|
+static __inline__ unsigned long find_next_zero_bit(void *addr,
|
|
+ unsigned long size, unsigned long offset)
|
|
+{
|
|
+ unsigned long *p = ((unsigned long *) addr) + (offset >> 5);
|
|
+ unsigned long result = offset & ~31UL;
|
|
+ unsigned long tmp;
|
|
+
|
|
+ if (offset >= size)
|
|
+ return size;
|
|
+ size -= result;
|
|
+ offset &= 31UL;
|
|
+ if (offset) {
|
|
+ tmp = *(p++);
|
|
+ tmp |= ~0UL >> (32-offset);
|
|
+ if (size < 32)
|
|
+ goto found_first;
|
|
+ if (~tmp)
|
|
+ goto found_middle;
|
|
+ size -= 32;
|
|
+ result += 32;
|
|
+ }
|
|
+ while (size & ~31UL) {
|
|
+ tmp = *(p++);
|
|
+ if (~tmp)
|
|
+ goto found_middle;
|
|
+ result += 32;
|
|
+ size -= 32;
|
|
+ }
|
|
+ if (!size)
|
|
+ return result;
|
|
+ tmp = *p;
|
|
+
|
|
+found_first:
|
|
+ tmp |= ~0UL >> size;
|
|
+found_middle:
|
|
+ return result + ffz(tmp);
|
|
+}
|
|
+
|
|
+#define find_first_zero_bit(addr, size) find_next_zero_bit(((void *)addr), \
|
|
+ (size), 0)
|
|
+
|
|
+/* Ported from included/linux/bitops.h */
|
|
+static __inline__ int ffs(int x)
|
|
+{
|
|
+ int r = 1;
|
|
+
|
|
+ if (!x)
|
|
+ return 0;
|
|
+ if (!(x & 0xffff)) {
|
|
+ x >>= 16;
|
|
+ r += 16;
|
|
+ }
|
|
+ if (!(x & 0xff)) {
|
|
+ x >>= 8;
|
|
+ r += 8;
|
|
+ }
|
|
+ if (!(x & 0xf)) {
|
|
+ x >>= 4;
|
|
+ r += 4;
|
|
+ }
|
|
+ if (!(x & 3)) {
|
|
+ x >>= 2;
|
|
+ r += 2;
|
|
+ }
|
|
+ if (!(x & 1)) {
|
|
+ x >>= 1;
|
|
+ r += 1;
|
|
+ }
|
|
+ return r;
|
|
+}
|
|
+#define __ffs(x) (ffs(x) - 1)
|
|
+
|
|
+/* find_next_bit - find the next set bit in a memory region
|
|
+ * (from asm-ppc/bitops.h)
|
|
+ */
|
|
+static __inline__ unsigned long find_next_bit(const unsigned long *addr,
|
|
+ unsigned long size, unsigned long offset)
|
|
+{
|
|
+ unsigned int *p = ((unsigned int *) addr) + (offset >> 5);
|
|
+ unsigned int result = offset & ~31UL;
|
|
+ unsigned int tmp;
|
|
+
|
|
+ if (offset >= size)
|
|
+ return size;
|
|
+ size -= result;
|
|
+ offset &= 31UL;
|
|
+ if (offset) {
|
|
+ tmp = *p++;
|
|
+ tmp &= ~0UL << offset;
|
|
+ if (size < 32)
|
|
+ goto found_first;
|
|
+ if (tmp)
|
|
+ goto found_middle;
|
|
+ size -= 32;
|
|
+ result += 32;
|
|
+ }
|
|
+ while (size >= 32) {
|
|
+ tmp = *p++;
|
|
+ if (tmp != 0)
|
|
+ goto found_middle;
|
|
+ result += 32;
|
|
+ size -= 32;
|
|
+ }
|
|
+ if (!size)
|
|
+ return result;
|
|
+ tmp = *p;
|
|
+
|
|
+found_first:
|
|
+ tmp &= ~0UL >> (32 - size);
|
|
+ if (tmp == 0UL) /* Are any bits set? */
|
|
+ return result + size; /* Nope. */
|
|
+found_middle:
|
|
+ return result + __ffs(tmp);
|
|
+}
|
|
+
|
|
+#define find_first_bit(addr, size) find_next_bit((addr), (size), 0)
|
|
+
|
|
+#ifdef __KERNEL__
|
|
+
|
|
+/* Ported from include/linux/bitops.h */
|
|
+static __inline__ int fls(int x)
|
|
+{
|
|
+ int r = 32;
|
|
+
|
|
+ if (!x)
|
|
+ return 0;
|
|
+ if (!(x & 0xffff0000u)) {
|
|
+ x <<= 16;
|
|
+ r -= 16;
|
|
+ }
|
|
+ if (!(x & 0xff000000u)) {
|
|
+ x <<= 8;
|
|
+ r -= 8;
|
|
+ }
|
|
+ if (!(x & 0xf0000000u)) {
|
|
+ x <<= 4;
|
|
+ r -= 4;
|
|
+ }
|
|
+ if (!(x & 0xc0000000u)) {
|
|
+ x <<= 2;
|
|
+ r -= 2;
|
|
+ }
|
|
+ if (!(x & 0x80000000u)) {
|
|
+ x <<= 1;
|
|
+ r -= 1;
|
|
+ }
|
|
+ return r;
|
|
+}
|
|
+
|
|
+#include <asm-generic/bitops/fls64.h>
|
|
+#include <asm-generic/bitops/sched.h>
|
|
+#include <asm-generic/bitops/hweight.h>
|
|
+
|
|
+#define minix_find_first_zero_bit(addr, size) find_next_zero_bit((addr), \
|
|
+ (size), 0)
|
|
+#define minix_test_and_set_bit(nr, addr) test_and_set_bit((nr), \
|
|
+ (unsigned long *)(addr))
|
|
+#define minix_set_bit(nr, addr) set_bit((nr), \
|
|
+ (unsigned long *)(addr))
|
|
+#define minix_test_and_clear_bit(nr, addr) test_and_clear_bit((nr), \
|
|
+ (unsigned long *)(addr))
|
|
+
|
|
+static inline int minix_test_bit(int nr, const volatile unsigned long *vaddr)
|
|
+{
|
|
+ int *a = (int *)vaddr;
|
|
+ int mask;
|
|
+
|
|
+ a += nr >> 5;
|
|
+ mask = 1 << (nr & 0x1f);
|
|
+ return ((mask & *a) != 0);
|
|
+}
|
|
+
|
|
+#define ext2_set_bit(nr, addr) test_and_set_bit((nr) ^ 24, \
|
|
+ (unsigned long *)(addr))
|
|
+#define ext2_set_bit_atomic(lock, nr, addr) test_and_set_bit((nr) ^ 24, \
|
|
+ (unsigned long *)(addr))
|
|
+#define ext2_clear_bit(nr, addr) test_and_clear_bit((nr) ^ 24, \
|
|
+ (unsigned long *)(addr))
|
|
+#define ext2_clear_bit_atomic(lock, nr, addr) test_and_clear_bit((nr) ^ 24, \
|
|
+ (unsigned long *)(addr))
|
|
+
|
|
+static inline int ext2_test_bit(int nr, const void *vaddr)
|
|
+{
|
|
+ const unsigned char *p = vaddr;
|
|
+ return (p[nr >> 3] & (1U << (nr & 7))) != 0;
|
|
+}
|
|
+
|
|
+static inline int ext2_find_first_zero_bit(const void *vaddr, unsigned size)
|
|
+{
|
|
+ const unsigned long *p = vaddr, *addr = vaddr;
|
|
+ int res;
|
|
+
|
|
+ if (!size)
|
|
+ return 0;
|
|
+
|
|
+ size = (size >> 5) + ((size & 31) > 0);
|
|
+ while (*p++ == ~0UL) {
|
|
+ if (--size == 0)
|
|
+ return (p - addr) << 5;
|
|
+ }
|
|
+
|
|
+ --p;
|
|
+ for (res = 0; res < 32; res++)
|
|
+ if (!ext2_test_bit (res, p))
|
|
+ break;
|
|
+ return (p - addr) * 32 + res;
|
|
+}
|
|
+
|
|
+static inline int ext2_find_next_zero_bit(const void *vaddr, unsigned size,
|
|
+ unsigned offset)
|
|
+{
|
|
+ const unsigned long *addr = vaddr;
|
|
+ const unsigned long *p = addr + (offset >> 5);
|
|
+ int bit = offset & 31UL, res;
|
|
+
|
|
+ if (offset >= size)
|
|
+ return size;
|
|
+
|
|
+ if (bit) {
|
|
+ /* Look for zero in first longword */
|
|
+ for (res = bit; res < 32; res++)
|
|
+ if (!ext2_test_bit (res, p))
|
|
+ return (p - addr) * 32 + res;
|
|
+ p++;
|
|
+ }
|
|
+ /* No zero yet, search remaining full bytes for a zero */
|
|
+ res = ext2_find_first_zero_bit(p, size - 32 * (p - addr));
|
|
+ return (p - addr) * 32 + res;
|
|
+}
|
|
+
|
|
+#endif /* KERNEL */
|
|
+
|
|
+#endif /* CONFIG_COLDFIRE */
|
|
+
|
|
#endif /* _M68K_BITOPS_H */
|
|
--- a/include/asm-m68k/bootinfo.h
|
|
+++ b/include/asm-m68k/bootinfo.h
|
|
@@ -49,6 +49,19 @@ struct bi_record {
|
|
#endif /* __ASSEMBLY__ */
|
|
|
|
|
|
+#ifndef __ASSEMBLY__
|
|
+
|
|
+struct uboot_record {
|
|
+ unsigned long bd_info;
|
|
+ unsigned long initrd_start;
|
|
+ unsigned long initrd_end;
|
|
+ unsigned long cmd_line_start;
|
|
+ unsigned long cmd_line_stop;
|
|
+};
|
|
+
|
|
+#endif /* __ASSEMBLY__ */
|
|
+
|
|
+
|
|
/*
|
|
* Tag Definitions
|
|
*
|
|
--- a/include/asm-m68k/byteorder.h
|
|
+++ b/include/asm-m68k/byteorder.h
|
|
@@ -4,8 +4,15 @@
|
|
#include <asm/types.h>
|
|
#include <linux/compiler.h>
|
|
|
|
-#ifdef __GNUC__
|
|
-
|
|
+#if defined(__GNUC__)
|
|
+#if defined(__mcfisaaplus__) || defined(__mcfisac__)
|
|
+static __inline__ __attribute_const__ __u32 ___arch__swab32(__u32 val)
|
|
+{
|
|
+ __asm__ ("byterev %0" : "=d" (val) : "0" (val));
|
|
+ return val;
|
|
+}
|
|
+#define __arch__swab32(x) ___arch__swab32(x)
|
|
+#elif !defined(__mcoldfire__)
|
|
static __inline__ __attribute_const__ __u32 ___arch__swab32(__u32 val)
|
|
{
|
|
__asm__("rolw #8,%0; swap %0; rolw #8,%0" : "=d" (val) : "0" (val));
|
|
@@ -14,6 +21,7 @@ static __inline__ __attribute_const__ __
|
|
#define __arch__swab32(x) ___arch__swab32(x)
|
|
|
|
#endif
|
|
+#endif
|
|
|
|
#if defined(__GNUC__) && !defined(__STRICT_ANSI__) || defined(__KERNEL__)
|
|
# define __BYTEORDER_HAS_U64__
|
|
--- a/include/asm-m68k/cacheflush.h
|
|
+++ b/include/asm-m68k/cacheflush.h
|
|
@@ -6,6 +6,9 @@
|
|
/* cache code */
|
|
#define FLUSH_I_AND_D (0x00000808)
|
|
#define FLUSH_I (0x00000008)
|
|
+#ifdef CONFIG_COLDFIRE
|
|
+#include <asm/cf_cacheflush.h>
|
|
+#else /* !CONFIG_COLDFIRE */
|
|
|
|
/*
|
|
* Cache handling functions
|
|
@@ -153,4 +156,5 @@ static inline void copy_from_user_page(s
|
|
memcpy(dst, src, len);
|
|
}
|
|
|
|
+#endif /* !CONFIG_COLDFIRE */
|
|
#endif /* _M68K_CACHEFLUSH_H */
|
|
--- a/include/asm-m68k/checksum.h
|
|
+++ b/include/asm-m68k/checksum.h
|
|
@@ -34,6 +34,7 @@ extern __wsum csum_partial_copy_nocheck(
|
|
void *dst, int len,
|
|
__wsum sum);
|
|
|
|
+#ifndef CONFIG_COLDFIRE /* CF has own copy in arch/m68k/lib/checksum.c */
|
|
/*
|
|
* This is a version of ip_compute_csum() optimized for IP headers,
|
|
* which always checksum on 4 octet boundaries.
|
|
@@ -59,6 +60,9 @@ static inline __sum16 ip_fast_csum(const
|
|
: "memory");
|
|
return (__force __sum16)~sum;
|
|
}
|
|
+#else
|
|
+extern __sum16 ip_fast_csum(const void *iph, unsigned int ihl);
|
|
+#endif
|
|
|
|
/*
|
|
* Fold a partial checksum
|
|
@@ -67,6 +71,11 @@ static inline __sum16 ip_fast_csum(const
|
|
static inline __sum16 csum_fold(__wsum sum)
|
|
{
|
|
unsigned int tmp = (__force u32)sum;
|
|
+#ifdef CONFIG_COLDFIRE
|
|
+ tmp = (tmp & 0xffff) + (tmp >> 16);
|
|
+ tmp = (tmp & 0xffff) + (tmp >> 16);
|
|
+ return (__force __sum16) ~tmp;
|
|
+#else
|
|
__asm__("swap %1\n\t"
|
|
"addw %1, %0\n\t"
|
|
"clrw %1\n\t"
|
|
@@ -74,6 +83,7 @@ static inline __sum16 csum_fold(__wsum s
|
|
: "=&d" (sum), "=&d" (tmp)
|
|
: "0" (sum), "1" (tmp));
|
|
return (__force __sum16)~sum;
|
|
+#endif
|
|
}
|
|
|
|
|
|
--- a/include/asm-m68k/delay.h
|
|
+++ b/include/asm-m68k/delay.h
|
|
@@ -11,8 +11,25 @@
|
|
|
|
static inline void __delay(unsigned long loops)
|
|
{
|
|
+#if defined(CONFIG_COLDFIRE)
|
|
+ /* The coldfire runs this loop at significantly different speeds
|
|
+ * depending upon long word alignment or not. We'll pad it to
|
|
+ * long word alignment which is the faster version.
|
|
+ * The 0x4a8e is of course a 'tstl %fp' instruction. This is better
|
|
+ * than using a NOP (0x4e71) instruction because it executes in one
|
|
+ * cycle not three and doesn't allow for an arbitary delay waiting
|
|
+ * for bus cycles to finish. Also fp/a6 isn't likely to cause a
|
|
+ * stall waiting for the register to become valid if such is added
|
|
+ * to the coldfire at some stage.
|
|
+ */
|
|
+ __asm__ __volatile__ (".balignw 4, 0x4a8e\n\t"
|
|
+ "1: subql #1, %0\n\t"
|
|
+ "jcc 1b"
|
|
+ : "=d" (loops) : "0" (loops));
|
|
+#else
|
|
__asm__ __volatile__ ("1: subql #1,%0; jcc 1b"
|
|
: "=d" (loops) : "0" (loops));
|
|
+#endif
|
|
}
|
|
|
|
extern void __bad_udelay(void);
|
|
@@ -26,12 +43,17 @@ extern void __bad_udelay(void);
|
|
*/
|
|
static inline void __const_udelay(unsigned long xloops)
|
|
{
|
|
+#if defined(CONFIG_COLDFIRE)
|
|
+
|
|
+ __delay(((((unsigned long long) xloops * loops_per_jiffy))>>32)*HZ);
|
|
+#else
|
|
unsigned long tmp;
|
|
|
|
__asm__ ("mulul %2,%0:%1"
|
|
: "=d" (xloops), "=d" (tmp)
|
|
: "d" (xloops), "1" (loops_per_jiffy));
|
|
__delay(xloops * HZ);
|
|
+#endif
|
|
}
|
|
|
|
static inline void __udelay(unsigned long usecs)
|
|
@@ -46,12 +68,16 @@ static inline void __udelay(unsigned lon
|
|
static inline unsigned long muldiv(unsigned long a, unsigned long b,
|
|
unsigned long c)
|
|
{
|
|
+#if defined(CONFIG_COLDFIRE)
|
|
+ return (long)(((unsigned long long)a * b)/c);
|
|
+#else
|
|
unsigned long tmp;
|
|
|
|
__asm__ ("mulul %2,%0:%1; divul %3,%0:%1"
|
|
: "=d" (tmp), "=d" (a)
|
|
: "d" (b), "d" (c), "1" (a));
|
|
return a;
|
|
+#endif
|
|
}
|
|
|
|
#endif /* defined(_M68K_DELAY_H) */
|
|
--- a/include/asm-m68k/div64.h
|
|
+++ b/include/asm-m68k/div64.h
|
|
@@ -5,6 +5,7 @@
|
|
|
|
/* n = n / base; return rem; */
|
|
|
|
+#ifndef CONFIG_COLDFIRE
|
|
#define do_div(n, base) ({ \
|
|
union { \
|
|
unsigned long n32[2]; \
|
|
@@ -24,6 +25,9 @@
|
|
(n) = __n.n64; \
|
|
__rem; \
|
|
})
|
|
+#else
|
|
+# include <asm-generic/div64.h>
|
|
+#endif
|
|
|
|
extern uint64_t div64_64(uint64_t dividend, uint64_t divisor);
|
|
#endif /* _M68K_DIV64_H */
|
|
--- a/include/asm-m68k/elf.h
|
|
+++ b/include/asm-m68k/elf.h
|
|
@@ -60,7 +60,7 @@ typedef struct user_m68kfp_struct elf_fp
|
|
#define ELF_PLAT_INIT(_r, load_addr) _r->a1 = 0
|
|
|
|
#define USE_ELF_CORE_DUMP
|
|
-#ifndef CONFIG_SUN3
|
|
+#if !defined(CONFIG_SUN3) && !defined(CONFIG_COLDFIRE)
|
|
#define ELF_EXEC_PAGESIZE 4096
|
|
#else
|
|
#define ELF_EXEC_PAGESIZE 8192
|
|
--- a/include/asm-m68k/fpu.h
|
|
+++ b/include/asm-m68k/fpu.h
|
|
@@ -12,6 +12,8 @@
|
|
#define FPSTATESIZE (96/sizeof(unsigned char))
|
|
#elif defined(CONFIG_M68KFPU_EMU)
|
|
#define FPSTATESIZE (28/sizeof(unsigned char))
|
|
+#elif defined(CONFIG_CFV4E)
|
|
+#define FPSTATESIZE (16/sizeof(unsigned char))
|
|
#elif defined(CONFIG_M68060)
|
|
#define FPSTATESIZE (12/sizeof(unsigned char))
|
|
#else
|
|
--- a/include/asm-m68k/io.h
|
|
+++ b/include/asm-m68k/io.h
|
|
@@ -397,10 +397,12 @@ static inline void memcpy_toio(volatile
|
|
__builtin_memcpy((void __force *) dst, src, count);
|
|
}
|
|
|
|
-#ifndef CONFIG_SUN3
|
|
-#define IO_SPACE_LIMIT 0xffff
|
|
-#else
|
|
+#if defined(CONFIG_SUN3)
|
|
#define IO_SPACE_LIMIT 0x0fffffff
|
|
+#elif defined(CONFIG_COLDFIRE)
|
|
+#define IO_SPACE_LIMIT 0xffffffff
|
|
+#else
|
|
+#define IO_SPACE_LIMIT 0xffff
|
|
#endif
|
|
|
|
#endif /* __KERNEL__ */
|
|
@@ -418,4 +420,22 @@ static inline void memcpy_toio(volatile
|
|
*/
|
|
#define xlate_dev_kmem_ptr(p) p
|
|
|
|
+#ifdef CONFIG_COLDFIRE
|
|
+
|
|
+#define memset_io(a, b, c) memset((void *)(a), (b), (c))
|
|
+#define memcpy_fromio(a, b, c) memcpy((a), (void *)(b), (c))
|
|
+#define memcpy_toio(a, b, c) memcpy((void *)(a), (b), (c))
|
|
+#if !defined(readb)
|
|
+#define readb(addr) \
|
|
+ ({ unsigned char __v = (*(volatile unsigned char *) (addr)); __v; })
|
|
+#define readw(addr) \
|
|
+ ({ unsigned short __v = (*(volatile unsigned short *) (addr)); __v; })
|
|
+#define readl(addr) \
|
|
+ ({ unsigned int __v = (*(volatile unsigned int *) (addr)); __v; })
|
|
+#define writeb(b, addr) (void)((*(volatile unsigned char *) (addr)) = (b))
|
|
+#define writew(b, addr) (void)((*(volatile unsigned short *) (addr)) = (b))
|
|
+#define writel(b, addr) (void)((*(volatile unsigned int *) (addr)) = (b))
|
|
+#endif /* readb */
|
|
+#endif /* CONFIG_COLDFIRE */
|
|
+
|
|
#endif /* _IO_H */
|
|
--- a/include/asm-m68k/irq.h
|
|
+++ b/include/asm-m68k/irq.h
|
|
@@ -11,7 +11,10 @@
|
|
* Currently the Atari has 72 and the Amiga 24, but if both are
|
|
* supported in the kernel it is better to make room for 72.
|
|
*/
|
|
-#if defined(CONFIG_VME) || defined(CONFIG_SUN3) || defined(CONFIG_SUN3X)
|
|
+#if defined(CONFIG_COLDFIRE)
|
|
+#define SYS_IRQS 256
|
|
+#define NR_IRQS SYS_IRQS
|
|
+#elif defined(CONFIG_VME) || defined(CONFIG_SUN3) || defined(CONFIG_SUN3X)
|
|
#define NR_IRQS 200
|
|
#elif defined(CONFIG_ATARI) || defined(CONFIG_MAC)
|
|
#define NR_IRQS 72
|
|
--- a/include/asm-m68k/machdep.h
|
|
+++ b/include/asm-m68k/machdep.h
|
|
@@ -32,4 +32,11 @@ extern void (*mach_heartbeat) (int);
|
|
extern void (*mach_l2_flush) (int);
|
|
extern void (*mach_beep) (unsigned int, unsigned int);
|
|
|
|
+#ifdef CONFIG_COLDFIRE
|
|
+extern void __init config_coldfire(void);
|
|
+extern void __init mmu_context_init(void);
|
|
+extern irq_handler_t mach_default_handler;
|
|
+extern void (*mach_tick)(void);
|
|
+#endif
|
|
+
|
|
#endif /* _M68K_MACHDEP_H */
|
|
--- a/include/asm-m68k/mmu_context.h
|
|
+++ b/include/asm-m68k/mmu_context.h
|
|
@@ -7,7 +7,7 @@ static inline void enter_lazy_tlb(struct
|
|
{
|
|
}
|
|
|
|
-#ifndef CONFIG_SUN3
|
|
+#if !defined(CONFIG_SUN3) && !defined(CONFIG_COLDFIRE)
|
|
|
|
#include <asm/setup.h>
|
|
#include <asm/page.h>
|
|
@@ -102,7 +102,7 @@ static inline void activate_mm(struct mm
|
|
switch_mm_0460(next_mm);
|
|
}
|
|
|
|
-#else /* CONFIG_SUN3 */
|
|
+#elif defined(CONFIG_SUN3)
|
|
#include <asm/sun3mmu.h>
|
|
#include <linux/sched.h>
|
|
|
|
@@ -150,5 +150,83 @@ static inline void activate_mm(struct mm
|
|
activate_context(next_mm);
|
|
}
|
|
|
|
-#endif
|
|
+#else /* CONFIG_COLDFIRE */
|
|
+
|
|
+#include <asm/atomic.h>
|
|
+#include <asm/bitops.h>
|
|
+#include <asm/mmu.h>
|
|
+
|
|
+#define NO_CONTEXT 256
|
|
+#define LAST_CONTEXT 255
|
|
+#define FIRST_CONTEXT 1
|
|
+
|
|
+extern void set_context(mm_context_t context, pgd_t *pgd);
|
|
+extern unsigned long context_map[];
|
|
+extern mm_context_t next_mmu_context;
|
|
+
|
|
+extern atomic_t nr_free_contexts;
|
|
+extern struct mm_struct *context_mm[LAST_CONTEXT+1];
|
|
+extern void steal_context(void);
|
|
+
|
|
+static inline void get_mmu_context(struct mm_struct *mm)
|
|
+{
|
|
+ mm_context_t ctx;
|
|
+
|
|
+ if (mm->context != NO_CONTEXT)
|
|
+ return;
|
|
+ while (atomic_dec_and_test_lt(&nr_free_contexts)) {
|
|
+ atomic_inc(&nr_free_contexts);
|
|
+ steal_context();
|
|
+ }
|
|
+ ctx = next_mmu_context;
|
|
+ while (test_and_set_bit(ctx, context_map)) {
|
|
+ ctx = find_next_zero_bit(context_map, LAST_CONTEXT+1, ctx);
|
|
+ if (ctx > LAST_CONTEXT)
|
|
+ ctx = 0;
|
|
+ }
|
|
+ next_mmu_context = (ctx + 1) & LAST_CONTEXT;
|
|
+ mm->context = ctx;
|
|
+ context_mm[ctx] = mm;
|
|
+}
|
|
+
|
|
+/*
|
|
+ * Set up the context for a new address space.
|
|
+ */
|
|
+#define init_new_context(tsk, mm) (((mm)->context = NO_CONTEXT), 0)
|
|
+
|
|
+/*
|
|
+ * We're finished using the context for an address space.
|
|
+ */
|
|
+static inline void destroy_context(struct mm_struct *mm)
|
|
+{
|
|
+ if (mm->context != NO_CONTEXT) {
|
|
+ clear_bit(mm->context, context_map);
|
|
+ mm->context = NO_CONTEXT;
|
|
+ atomic_inc(&nr_free_contexts);
|
|
+ }
|
|
+}
|
|
+
|
|
+static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
|
|
+ struct task_struct *tsk)
|
|
+{
|
|
+ get_mmu_context(tsk->mm);
|
|
+ set_context(tsk->mm->context, next->pgd);
|
|
+}
|
|
+
|
|
+/*
|
|
+ * After we have set current->mm to a new value, this activates
|
|
+ * the context for the new mm so we see the new mappings.
|
|
+ */
|
|
+static inline void activate_mm(struct mm_struct *active_mm,
|
|
+ struct mm_struct *mm)
|
|
+{
|
|
+ get_mmu_context(mm);
|
|
+ set_context(mm->context, mm->pgd);
|
|
+}
|
|
+
|
|
+#define deactivate_mm(tsk, mm) do { } while (0)
|
|
+
|
|
+extern void mmu_context_init(void);
|
|
+
|
|
+#endif /* CONFIG_COLDFIRE */
|
|
#endif
|
|
--- a/include/asm-m68k/page.h
|
|
+++ b/include/asm-m68k/page.h
|
|
@@ -4,7 +4,7 @@
|
|
#include <linux/const.h>
|
|
|
|
/* PAGE_SHIFT determines the page size */
|
|
-#ifndef CONFIG_SUN3
|
|
+#if !defined(CONFIG_SUN3) && !defined(CONFIG_COLDFIRE)
|
|
#define PAGE_SHIFT (12)
|
|
#else
|
|
#define PAGE_SHIFT (13)
|
|
@@ -116,10 +116,23 @@ typedef struct page *pgtable_t;
|
|
|
|
extern unsigned long m68k_memoffset;
|
|
|
|
-#ifndef CONFIG_SUN3
|
|
+#if !defined(CONFIG_SUN3)
|
|
|
|
#define WANT_PAGE_VIRTUAL
|
|
|
|
+#if defined(CONFIG_COLDFIRE)
|
|
+static inline unsigned long ___pa(void *vaddr)
|
|
+{
|
|
+ return (((unsigned long)vaddr & 0x0fffffff) + CONFIG_SDRAM_BASE);
|
|
+}
|
|
+#define __pa(vaddr) ___pa((void *)(vaddr))
|
|
+
|
|
+static inline void *__va(unsigned long paddr)
|
|
+{
|
|
+ return (void *)((paddr & 0x0fffffff) + PAGE_OFFSET);
|
|
+}
|
|
+
|
|
+#else
|
|
static inline unsigned long ___pa(void *vaddr)
|
|
{
|
|
unsigned long paddr;
|
|
@@ -141,6 +154,7 @@ static inline void *__va(unsigned long p
|
|
: "0" (paddr), "i" (m68k_fixup_memoffset));
|
|
return vaddr;
|
|
}
|
|
+#endif
|
|
|
|
#else /* !CONFIG_SUN3 */
|
|
/* This #define is a horrible hack to suppress lots of warnings. --m */
|
|
@@ -172,6 +186,8 @@ static inline void *__va(unsigned long x
|
|
* memory node, but we have no highmem, so that works for now.
|
|
* TODO: implement (fast) pfn<->pgdat_idx conversion functions, this makes lots
|
|
* of the shifts unnecessary.
|
|
+ *
|
|
+ * PFNs are used to map physical pages. So PFN[0] maps to the base phys addr.
|
|
*/
|
|
#define virt_to_pfn(kaddr) (__pa(kaddr) >> PAGE_SHIFT)
|
|
#define pfn_to_virt(pfn) __va((pfn) << PAGE_SHIFT)
|
|
--- a/include/asm-m68k/page_offset.h
|
|
+++ b/include/asm-m68k/page_offset.h
|
|
@@ -1,8 +1,11 @@
|
|
|
|
/* This handles the memory map.. */
|
|
-#ifndef CONFIG_SUN3
|
|
+#if !defined(CONFIG_SUN3) && !defined(CONFIG_COLDFIRE)
|
|
#define PAGE_OFFSET_RAW 0x00000000
|
|
-#else
|
|
+#elif defined(CONFIG_SUN3)
|
|
#define PAGE_OFFSET_RAW 0x0E000000
|
|
+#else /* CONFIG_COLDFIRE */
|
|
+#define PAGE_OFFSET_RAW 0xC0000000
|
|
+#define PHYS_OFFSET 0x40000000
|
|
#endif
|
|
|
|
--- a/include/asm-m68k/pci.h
|
|
+++ b/include/asm-m68k/pci.h
|
|
@@ -1,57 +1,86 @@
|
|
-#ifndef _ASM_M68K_PCI_H
|
|
-#define _ASM_M68K_PCI_H
|
|
-
|
|
/*
|
|
- * asm-m68k/pci_m68k.h - m68k specific PCI declarations.
|
|
+ * asm-m68k/pci.h - m68k specific PCI declarations.
|
|
*
|
|
- * Written by Wout Klaren.
|
|
+ * Coldfire Implementation Copyright (c) 2007 Freescale Semiconductor, Inc.
|
|
+ * Kurt Mahan <kmahan@freescale.com>
|
|
*/
|
|
+#ifndef _ASM_M68K_PCI_H
|
|
+#define _ASM_M68K_PCI_H
|
|
|
|
-#include <asm/scatterlist.h>
|
|
+#ifdef CONFIG_PCI
|
|
|
|
-struct pci_ops;
|
|
+#include <asm-generic/pci-dma-compat.h>
|
|
|
|
/*
|
|
- * Structure with hardware dependent information and functions of the
|
|
- * PCI bus.
|
|
+ * The PCI address space does equal the physical memory
|
|
+ * address space. The networking and block device layers use
|
|
+ * this boolean for bounce buffer decisions.
|
|
*/
|
|
+#define PCI_DMA_BUS_IS_PHYS (1)
|
|
|
|
-struct pci_bus_info
|
|
-{
|
|
- /*
|
|
- * Resources of the PCI bus.
|
|
- */
|
|
-
|
|
- struct resource mem_space;
|
|
- struct resource io_space;
|
|
+#define PCIBIOS_MIN_IO 0x00004000
|
|
+#define PCIBIOS_MIN_MEM 0x02000000
|
|
|
|
- /*
|
|
- * System dependent functions.
|
|
- */
|
|
+#define pcibios_assign_all_busses() 0
|
|
+#define pcibios_scan_all_fns(a, b) 0
|
|
|
|
- struct pci_ops *m68k_pci_ops;
|
|
+static inline void
|
|
+pcibios_set_master(struct pci_dev *dev)
|
|
+{
|
|
+ /* no special bus mastering setup handling */
|
|
+}
|
|
|
|
- void (*fixup)(int pci_modify);
|
|
- void (*conf_device)(struct pci_dev *dev);
|
|
-};
|
|
+static inline void
|
|
+pcibios_penalize_isa_irq(int irq, int active)
|
|
+{
|
|
+ /* no dynamic PCI IRQ allocation */
|
|
+}
|
|
|
|
-#define pcibios_assign_all_busses() 0
|
|
-#define pcibios_scan_all_fns(a, b) 0
|
|
+static inline void
|
|
+pcibios_add_platform_entries(struct pci_dev *dev)
|
|
+{
|
|
+ /* no special handling */
|
|
+}
|
|
|
|
-static inline void pcibios_set_master(struct pci_dev *dev)
|
|
+static inline void
|
|
+pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
|
|
+ struct resource *res)
|
|
{
|
|
- /* No special bus mastering setup handling */
|
|
+#ifdef CONFIG_M54455
|
|
+ if ((res->start == 0xa0000000) || (res->start == 0xa8000000)) {
|
|
+ /* HACK! FIX! kludge to fix bridge mapping */
|
|
+ region->start = res->start & 0x0fffffff;
|
|
+ region->end = res->end & 0x0fffffff;
|
|
+ } else {
|
|
+ region->start = res->start;
|
|
+ region->end = res->end;
|
|
+ }
|
|
+#else
|
|
+ region->start = res->start;
|
|
+ region->end = res->end;
|
|
+#endif
|
|
}
|
|
|
|
-static inline void pcibios_penalize_isa_irq(int irq, int active)
|
|
+static inline void
|
|
+pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
|
|
+ struct pci_bus_region *region)
|
|
{
|
|
- /* We don't do dynamic PCI IRQ allocation */
|
|
+ res->start = region->start;
|
|
+ res->end = region->end;
|
|
}
|
|
|
|
-/* The PCI address space does equal the physical memory
|
|
- * address space. The networking and block device layers use
|
|
- * this boolean for bounce buffer decisions.
|
|
- */
|
|
-#define PCI_DMA_BUS_IS_PHYS (1)
|
|
+static inline struct resource *
|
|
+pcibios_select_root(struct pci_dev *pdev, struct resource *res)
|
|
+{
|
|
+ struct resource *root = NULL;
|
|
+
|
|
+ if (res->flags & IORESOURCE_IO)
|
|
+ root = &ioport_resource;
|
|
+ if (res->flags & IORESOURCE_MEM)
|
|
+ root = &iomem_resource;
|
|
+
|
|
+ return root;
|
|
+}
|
|
|
|
+#endif /* CONFIG_PCI */
|
|
#endif /* _ASM_M68K_PCI_H */
|
|
--- a/include/asm-m68k/pgalloc.h
|
|
+++ b/include/asm-m68k/pgalloc.h
|
|
@@ -8,8 +8,10 @@
|
|
#include <asm/virtconvert.h>
|
|
|
|
|
|
-#ifdef CONFIG_SUN3
|
|
+#if defined(CONFIG_SUN3)
|
|
#include <asm/sun3_pgalloc.h>
|
|
+#elif defined(CONFIG_COLDFIRE)
|
|
+#include <asm/cf_pgalloc.h>
|
|
#else
|
|
#include <asm/motorola_pgalloc.h>
|
|
#endif
|
|
--- a/include/asm-m68k/pgtable.h
|
|
+++ b/include/asm-m68k/pgtable.h
|
|
@@ -40,6 +40,8 @@
|
|
/* PGDIR_SHIFT determines what a third-level page table entry can map */
|
|
#ifdef CONFIG_SUN3
|
|
#define PGDIR_SHIFT 17
|
|
+#elif defined(CONFIG_COLDFIRE)
|
|
+#define PGDIR_SHIFT 22
|
|
#else
|
|
#define PGDIR_SHIFT 25
|
|
#endif
|
|
@@ -54,6 +56,10 @@
|
|
#define PTRS_PER_PTE 16
|
|
#define PTRS_PER_PMD 1
|
|
#define PTRS_PER_PGD 2048
|
|
+#elif defined(CONFIG_COLDFIRE)
|
|
+#define PTRS_PER_PTE 512
|
|
+#define PTRS_PER_PMD 1
|
|
+#define PTRS_PER_PGD 1024
|
|
#else
|
|
#define PTRS_PER_PTE 1024
|
|
#define PTRS_PER_PMD 8
|
|
@@ -66,6 +72,9 @@
|
|
#ifdef CONFIG_SUN3
|
|
#define KMAP_START 0x0DC00000
|
|
#define KMAP_END 0x0E000000
|
|
+#elif defined(CONFIG_COLDFIRE)
|
|
+#define KMAP_START 0xe0000000
|
|
+#define KMAP_END 0xf0000000
|
|
#else
|
|
#define KMAP_START 0xd0000000
|
|
#define KMAP_END 0xf0000000
|
|
@@ -130,6 +139,8 @@ static inline void update_mmu_cache(stru
|
|
|
|
#ifdef CONFIG_SUN3
|
|
#include <asm/sun3_pgtable.h>
|
|
+#elif defined(CONFIG_COLDFIRE)
|
|
+#include <asm/cf_pgtable.h>
|
|
#else
|
|
#include <asm/motorola_pgtable.h>
|
|
#endif
|
|
@@ -140,6 +151,9 @@ static inline void update_mmu_cache(stru
|
|
/*
|
|
* Macro to mark a page protection value as "uncacheable".
|
|
*/
|
|
+#ifdef CONFIG_COLDFIRE
|
|
+# define pgprot_noncached(prot) (__pgprot(pgprot_val(prot) | CF_PAGE_NOCACHE))
|
|
+#else /* CONFIG_COLDFIRE */
|
|
#ifdef SUN3_PAGE_NOCACHE
|
|
# define __SUN3_PAGE_NOCACHE SUN3_PAGE_NOCACHE
|
|
#else
|
|
@@ -154,6 +168,7 @@ static inline void update_mmu_cache(stru
|
|
? (__pgprot((pgprot_val(prot) & _CACHEMASK040) | _PAGE_NOCACHE_S)) \
|
|
: (prot)))
|
|
|
|
+#endif /* CONFIG_COLDFIRE */
|
|
#endif /* !__ASSEMBLY__ */
|
|
|
|
/*
|
|
--- a/include/asm-m68k/processor.h
|
|
+++ b/include/asm-m68k/processor.h
|
|
@@ -22,24 +22,38 @@ static inline unsigned long rdusp(void)
|
|
{
|
|
unsigned long usp;
|
|
|
|
+#ifndef CONFIG_COLDFIRE
|
|
__asm__ __volatile__("move %/usp,%0" : "=a" (usp));
|
|
+#else
|
|
+ __asm__ __volatile__("movel %/usp,%0" : "=a" (usp));
|
|
+#endif
|
|
return usp;
|
|
}
|
|
|
|
static inline void wrusp(unsigned long usp)
|
|
{
|
|
+#ifndef CONFIG_COLDFIRE
|
|
__asm__ __volatile__("move %0,%/usp" : : "a" (usp));
|
|
+#else
|
|
+ __asm__ __volatile__("movel %0,%/usp" : : "a" (usp));
|
|
+#endif
|
|
}
|
|
|
|
/*
|
|
* User space process size: 3.75GB. This is hardcoded into a few places,
|
|
* so don't change it unless you know what you are doing.
|
|
*/
|
|
-#ifndef CONFIG_SUN3
|
|
+#if !defined(CONFIG_SUN3) && !defined(CONFIG_COLDFIRE)
|
|
#define TASK_SIZE (0xF0000000UL)
|
|
+#elif defined(CONFIG_COLDFIRE)
|
|
+#define TASK_SIZE (0xC0000000UL)
|
|
+#else /* CONFIG_SUN3 */
|
|
+#ifdef __ASSEMBLY__
|
|
+#define TASK_SIZE (0x0E000000)
|
|
#else
|
|
#define TASK_SIZE (0x0E000000UL)
|
|
#endif
|
|
+#endif
|
|
|
|
#ifdef __KERNEL__
|
|
#define STACK_TOP TASK_SIZE
|
|
@@ -49,9 +63,11 @@ static inline void wrusp(unsigned long u
|
|
/* This decides where the kernel will search for a free chunk of vm
|
|
* space during mmap's.
|
|
*/
|
|
-#ifndef CONFIG_SUN3
|
|
-#define TASK_UNMAPPED_BASE 0xC0000000UL
|
|
-#else
|
|
+#if !defined(CONFIG_SUN3) && !defined(CONFIG_COLDFIRE)
|
|
+#define TASK_UNMAPPED_BASE 0xC0000000UL
|
|
+#elif defined(CONFIG_COLDFIRE)
|
|
+#define TASK_UNMAPPED_BASE 0x80000000UL
|
|
+#else /* CONFIG_SUN3 */
|
|
#define TASK_UNMAPPED_BASE 0x0A000000UL
|
|
#endif
|
|
#define TASK_UNMAPPED_ALIGN(addr, off) PAGE_ALIGN(addr)
|
|
@@ -60,7 +76,11 @@ struct thread_struct {
|
|
unsigned long ksp; /* kernel stack pointer */
|
|
unsigned long usp; /* user stack pointer */
|
|
unsigned short sr; /* saved status register */
|
|
+#ifndef CONFIG_COLDFIRE
|
|
unsigned short fs; /* saved fs (sfc, dfc) */
|
|
+#else
|
|
+ mm_segment_t fs;
|
|
+#endif
|
|
unsigned long crp[2]; /* cpu root pointer */
|
|
unsigned long esp0; /* points to SR of stack frame */
|
|
unsigned long faddr; /* info about last fault */
|
|
@@ -81,6 +101,7 @@ struct thread_struct {
|
|
/*
|
|
* Do necessary setup to start up a newly executed thread.
|
|
*/
|
|
+#ifndef CONFIG_COLDFIRE
|
|
static inline void start_thread(struct pt_regs * regs, unsigned long pc,
|
|
unsigned long usp)
|
|
{
|
|
@@ -91,6 +112,23 @@ static inline void start_thread(struct p
|
|
regs->sr &= ~0x2000;
|
|
wrusp(usp);
|
|
}
|
|
+#else
|
|
+/*
|
|
+ * Do necessary setup to start up a newly executed thread.
|
|
+ *
|
|
+ * pass the data segment into user programs if it exists,
|
|
+ * it can't hurt anything as far as I can tell
|
|
+ */
|
|
+#define start_thread(_regs, _pc, _usp) \
|
|
+do { \
|
|
+ set_fs(USER_DS); /* reads from user space */ \
|
|
+ (_regs)->pc = (_pc); \
|
|
+ if (current->mm) \
|
|
+ (_regs)->d5 = current->mm->start_data; \
|
|
+ (_regs)->sr &= ~0x2000; \
|
|
+ wrusp(_usp); \
|
|
+} while (0)
|
|
+#endif
|
|
|
|
/* Forward declaration, a strange C thing */
|
|
struct task_struct;
|
|
--- a/include/asm-m68k/ptrace.h
|
|
+++ b/include/asm-m68k/ptrace.h
|
|
@@ -38,10 +38,21 @@ struct pt_regs {
|
|
long d0;
|
|
long orig_d0;
|
|
long stkadj;
|
|
+#ifndef CONFIG_COLDFIRE
|
|
unsigned short sr;
|
|
unsigned long pc;
|
|
unsigned format : 4; /* frame format specifier */
|
|
unsigned vector : 12; /* vector offset */
|
|
+#else
|
|
+ unsigned long mmuar;
|
|
+ unsigned long mmusr;
|
|
+ unsigned format : 4; /* frame format specifier */
|
|
+ unsigned fs2 : 2;
|
|
+ unsigned vector: 8;
|
|
+ unsigned fs1 : 2;
|
|
+ unsigned short sr;
|
|
+ unsigned long pc;
|
|
+#endif
|
|
};
|
|
|
|
/*
|
|
--- a/include/asm-m68k/raw_io.h
|
|
+++ b/include/asm-m68k/raw_io.h
|
|
@@ -77,6 +77,7 @@ static inline void raw_outsb(volatile u8
|
|
out_8(port, *buf++);
|
|
}
|
|
|
|
+#ifndef CONFIG_COLDFIRE
|
|
static inline void raw_insw(volatile u16 __iomem *port, u16 *buf, unsigned int nr)
|
|
{
|
|
unsigned int tmp;
|
|
@@ -342,6 +343,63 @@ static inline void raw_outsw_swapw(volat
|
|
: "d0", "a0", "a1", "d6");
|
|
}
|
|
|
|
+
|
|
+#else /*CONFIG_COLDFIRE */
|
|
+
|
|
+static inline void raw_insw(volatile u16 *port, u16 *buf, unsigned int nr)
|
|
+{
|
|
+ unsigned int i;
|
|
+
|
|
+ for (i = 0; i < nr; i++)
|
|
+ *buf++ = raw_inw(port);
|
|
+}
|
|
+
|
|
+static inline void raw_outsw(volatile u16 *port, const u16 *buf,
|
|
+ unsigned int nr)
|
|
+{
|
|
+ unsigned int i;
|
|
+
|
|
+ for (i = 0; i < nr; i++, buf++)
|
|
+ raw_outw(*buf, port);
|
|
+}
|
|
+
|
|
+static inline void raw_insl(volatile u32 *port, u32 *buf, unsigned int nr)
|
|
+{
|
|
+ unsigned int i;
|
|
+
|
|
+ for (i = 0; i < nr; i++)
|
|
+ *buf++ = raw_inl(port);
|
|
+}
|
|
+
|
|
+static inline void raw_outsl(volatile u32 *port, const u32 *buf,
|
|
+ unsigned int nr)
|
|
+{
|
|
+ unsigned int i;
|
|
+
|
|
+ for (i = 0; i < nr; i++, buf++)
|
|
+ raw_outl(*buf, port);
|
|
+}
|
|
+
|
|
+static inline void raw_insw_swapw(volatile u16 *port, u16 *buf,
|
|
+ unsigned int nr)
|
|
+{
|
|
+ unsigned int i;
|
|
+
|
|
+ for (i = 0; i < nr; i++)
|
|
+ *buf++ = in_le16(port);
|
|
+
|
|
+}
|
|
+
|
|
+static inline void raw_outsw_swapw(volatile u16 __iomem *port, const u16 *buf,
|
|
+ unsigned int nr)
|
|
+{
|
|
+ unsigned int i;
|
|
+
|
|
+ for (i = 0; i < nr; i++, buf++)
|
|
+ out_le16(port, *buf);
|
|
+}
|
|
+#endif /*CONFIG_COLDFIRE */
|
|
+
|
|
#endif /* __KERNEL__ */
|
|
|
|
#endif /* _RAW_IO_H */
|
|
--- a/include/asm-m68k/segment.h
|
|
+++ b/include/asm-m68k/segment.h
|
|
@@ -29,6 +29,7 @@ typedef struct {
|
|
* Get/set the SFC/DFC registers for MOVES instructions
|
|
*/
|
|
|
|
+#ifndef CONFIG_COLDFIRE
|
|
static inline mm_segment_t get_fs(void)
|
|
{
|
|
mm_segment_t _v;
|
|
@@ -50,6 +51,15 @@ static inline void set_fs(mm_segment_t v
|
|
: /* no outputs */ : "r" (val.seg) : "memory");
|
|
}
|
|
|
|
+#else /* CONFIG_COLDFIRE */
|
|
+
|
|
+#include <asm/current.h>
|
|
+#define get_fs() (current->thread.fs)
|
|
+#define set_fs(val) (current->thread.fs = (val))
|
|
+#define get_ds() (KERNEL_DS)
|
|
+
|
|
+#endif /* CONFIG_COLDFIRE */
|
|
+
|
|
#define segment_eq(a,b) ((a).seg == (b).seg)
|
|
|
|
#endif /* __ASSEMBLY__ */
|
|
--- a/include/asm-m68k/setup.h
|
|
+++ b/include/asm-m68k/setup.h
|
|
@@ -40,6 +40,7 @@
|
|
#define MACH_HP300 9
|
|
#define MACH_Q40 10
|
|
#define MACH_SUN3X 11
|
|
+#define MACH_CFMMU 12
|
|
|
|
#define COMMAND_LINE_SIZE 256
|
|
|
|
@@ -189,6 +190,14 @@ extern unsigned long m68k_machtype;
|
|
# define MACH_TYPE (MACH_SUN3X)
|
|
#endif
|
|
|
|
+#if !defined(CONFIG_COLDFIRE)
|
|
+# define MACH_IS_COLDFIRE (0)
|
|
+#else
|
|
+# define CONFIG_COLDFIRE_ONLY
|
|
+# define MACH_IS_COLDFIRE (1)
|
|
+# define MACH_TYPE (MACH_CFMMU)
|
|
+#endif
|
|
+
|
|
#ifndef MACH_TYPE
|
|
# define MACH_TYPE (m68k_machtype)
|
|
#endif
|
|
@@ -211,23 +220,31 @@ extern unsigned long m68k_machtype;
|
|
#define CPUB_68030 1
|
|
#define CPUB_68040 2
|
|
#define CPUB_68060 3
|
|
+#define CPUB_CFV4E 4
|
|
|
|
#define CPU_68020 (1<<CPUB_68020)
|
|
#define CPU_68030 (1<<CPUB_68030)
|
|
#define CPU_68040 (1<<CPUB_68040)
|
|
#define CPU_68060 (1<<CPUB_68060)
|
|
+#define CPU_CFV4E (1<<CPUB_CFV4E)
|
|
|
|
#define FPUB_68881 0
|
|
#define FPUB_68882 1
|
|
#define FPUB_68040 2 /* Internal FPU */
|
|
#define FPUB_68060 3 /* Internal FPU */
|
|
#define FPUB_SUNFPA 4 /* Sun-3 FPA */
|
|
+#define FPUB_CFV4E 5
|
|
|
|
#define FPU_68881 (1<<FPUB_68881)
|
|
#define FPU_68882 (1<<FPUB_68882)
|
|
#define FPU_68040 (1<<FPUB_68040)
|
|
#define FPU_68060 (1<<FPUB_68060)
|
|
#define FPU_SUNFPA (1<<FPUB_SUNFPA)
|
|
+#ifndef CONFIG_M54455
|
|
+#define FPU_CFV4E (1<<FPUB_CFV4E)
|
|
+#else
|
|
+#define FPU_CFV4E 0
|
|
+#endif
|
|
|
|
#define MMUB_68851 0
|
|
#define MMUB_68030 1 /* Internal MMU */
|
|
@@ -235,6 +252,7 @@ extern unsigned long m68k_machtype;
|
|
#define MMUB_68060 3 /* Internal MMU */
|
|
#define MMUB_APOLLO 4 /* Custom Apollo */
|
|
#define MMUB_SUN3 5 /* Custom Sun-3 */
|
|
+#define MMUB_CFV4E 6
|
|
|
|
#define MMU_68851 (1<<MMUB_68851)
|
|
#define MMU_68030 (1<<MMUB_68030)
|
|
@@ -242,6 +260,7 @@ extern unsigned long m68k_machtype;
|
|
#define MMU_68060 (1<<MMUB_68060)
|
|
#define MMU_SUN3 (1<<MMUB_SUN3)
|
|
#define MMU_APOLLO (1<<MMUB_APOLLO)
|
|
+#define MMU_CFV4E (1<<MMUB_CFV4E)
|
|
|
|
#ifdef __KERNEL__
|
|
|
|
@@ -341,6 +360,14 @@ extern int m68k_is040or060;
|
|
# endif
|
|
#endif
|
|
|
|
+#if !defined(CONFIG_CFV4E)
|
|
+# define CPU_IS_COLDFIRE (0)
|
|
+#else
|
|
+# define CPU_IS_COLDFIRE (1)
|
|
+# define CPU_IS_CFV4E (1)
|
|
+# define MMU_IS_CFV4E (1)
|
|
+#endif
|
|
+
|
|
#define CPU_TYPE (m68k_cputype)
|
|
|
|
#ifdef CONFIG_M68KFPU_EMU
|
|
--- a/include/asm-m68k/signal.h
|
|
+++ b/include/asm-m68k/signal.h
|
|
@@ -150,6 +150,7 @@ typedef struct sigaltstack {
|
|
#ifdef __KERNEL__
|
|
#include <asm/sigcontext.h>
|
|
|
|
+#ifndef CONFIG_COLDFIRE
|
|
#define __HAVE_ARCH_SIG_BITOPS
|
|
|
|
static inline void sigaddset(sigset_t *set, int _sig)
|
|
@@ -200,6 +201,10 @@ static inline int sigfindinword(unsigned
|
|
|
|
struct pt_regs;
|
|
extern void ptrace_signal_deliver(struct pt_regs *regs, void *cookie);
|
|
+#else
|
|
+
|
|
+#define ptrace_signal_deliver(regs, cookie) do { } while (0)
|
|
+#endif /* CONFIG_COLDFIRE */
|
|
|
|
#endif /* __KERNEL__ */
|
|
|
|
--- a/include/asm-m68k/string.h
|
|
+++ b/include/asm-m68k/string.h
|
|
@@ -93,6 +93,7 @@ static inline char *strchr(const char *s
|
|
return (char *)s - 1;
|
|
}
|
|
|
|
+#ifndef CONFIG_COLDFIRE
|
|
#define __HAVE_ARCH_STRCMP
|
|
static inline int strcmp(const char *cs, const char *ct)
|
|
{
|
|
@@ -110,6 +111,7 @@ static inline int strcmp(const char *cs,
|
|
: "+a" (cs), "+a" (ct), "=d" (res));
|
|
return res;
|
|
}
|
|
+#endif
|
|
|
|
#define __HAVE_ARCH_MEMSET
|
|
extern void *memset(void *, int, __kernel_size_t);
|
|
--- a/include/asm-m68k/system.h
|
|
+++ b/include/asm-m68k/system.h
|
|
@@ -63,16 +63,25 @@ asmlinkage void resume(void);
|
|
#define smp_read_barrier_depends() ((void)0)
|
|
|
|
/* interrupt control.. */
|
|
-#if 0
|
|
-#define local_irq_enable() asm volatile ("andiw %0,%%sr": : "i" (ALLOWINT) : "memory")
|
|
-#else
|
|
#include <linux/hardirq.h>
|
|
+#ifndef CONFIG_COLDFIRE
|
|
#define local_irq_enable() ({ \
|
|
if (MACH_IS_Q40 || !hardirq_count()) \
|
|
asm volatile ("andiw %0,%%sr": : "i" (ALLOWINT) : "memory"); \
|
|
})
|
|
-#endif
|
|
#define local_irq_disable() asm volatile ("oriw #0x0700,%%sr": : : "memory")
|
|
+#else /* CONFIG_COLDFIRE */
|
|
+#define local_irq_enable() \
|
|
+ asm volatile ("move.w %%sr, %%d0\n\t" \
|
|
+ "andil #0xf8ff,%%d0\n\t" \
|
|
+ "move.w %%d0, %%sr\n" \
|
|
+ : : : "cc", "d0", "memory")
|
|
+#define local_irq_disable() \
|
|
+ asm volatile ("move %/sr,%%d0\n\t" \
|
|
+ "ori.l #0x0700,%%d0\n\t" \
|
|
+ "move %%d0,%/sr\n" \
|
|
+ : : : "cc", "%d0", "memory")
|
|
+#endif
|
|
#define local_save_flags(x) asm volatile ("movew %%sr,%0":"=d" (x) : : "memory")
|
|
#define local_irq_restore(x) asm volatile ("movew %0,%%sr": :"d" (x) : "memory")
|
|
|
|
--- a/include/asm-m68k/thread_info.h
|
|
+++ b/include/asm-m68k/thread_info.h
|
|
@@ -58,5 +58,6 @@ struct thread_info {
|
|
#define TIF_DELAYED_TRACE 14 /* single step a syscall */
|
|
#define TIF_SYSCALL_TRACE 15 /* syscall trace active */
|
|
#define TIF_MEMDIE 16
|
|
+#define TIF_FREEZE 17 /* freezing processes */
|
|
|
|
#endif /* _ASM_M68K_THREAD_INFO_H */
|
|
--- a/include/asm-m68k/tlbflush.h
|
|
+++ b/include/asm-m68k/tlbflush.h
|
|
@@ -2,7 +2,7 @@
|
|
#define _M68K_TLBFLUSH_H
|
|
|
|
|
|
-#ifndef CONFIG_SUN3
|
|
+#if !defined(CONFIG_SUN3) && !defined(CONFIG_COLDFIRE)
|
|
|
|
#include <asm/current.h>
|
|
|
|
@@ -92,7 +92,12 @@ static inline void flush_tlb_kernel_rang
|
|
flush_tlb_all();
|
|
}
|
|
|
|
-#else
|
|
+static inline void flush_tlb_pgtables(struct mm_struct *mm,
|
|
+ unsigned long start, unsigned long end)
|
|
+{
|
|
+}
|
|
+
|
|
+#elif defined(CONFIG_SUN3)
|
|
|
|
|
|
/* Reserved PMEGs. */
|
|
@@ -214,6 +219,13 @@ static inline void flush_tlb_kernel_page
|
|
sun3_put_segmap (addr & ~(SUN3_PMEG_SIZE - 1), SUN3_INVALID_PMEG);
|
|
}
|
|
|
|
+static inline void flush_tlb_pgtables(struct mm_struct *mm,
|
|
+ unsigned long start, unsigned long end)
|
|
+{
|
|
+}
|
|
+
|
|
+#else /* CONFIG_COLDFIRE */
|
|
+#include <asm/cf_tlbflush.h>
|
|
#endif
|
|
|
|
#endif /* _M68K_TLBFLUSH_H */
|
|
--- a/include/asm-m68k/uaccess.h
|
|
+++ b/include/asm-m68k/uaccess.h
|
|
@@ -1,6 +1,9 @@
|
|
#ifndef __M68K_UACCESS_H
|
|
#define __M68K_UACCESS_H
|
|
|
|
+#ifdef CONFIG_COLDFIRE
|
|
+#include <asm/cf_uaccess.h>
|
|
+#else
|
|
/*
|
|
* User space memory access functions
|
|
*/
|
|
@@ -367,4 +370,5 @@ unsigned long __clear_user(void __user *
|
|
|
|
#define strlen_user(str) strnlen_user(str, 32767)
|
|
|
|
+#endif /* CONFIG_COLDFIRE */
|
|
#endif /* _M68K_UACCESS_H */
|