1
0
mirror of git://projects.qi-hardware.com/openwrt-xburst.git synced 2024-12-27 10:31:10 +02:00
openwrt-xburst/target/linux/coldfire/patches-2.6.31/001-coldfire_support.patch
kaloz 12a0868f92 [coldfire]: 2.6.31 support (WiP)
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@24087 3c298f89-4303-0410-b956-a3cf2f4a3e73
2010-11-22 13:29:58 +00:00

4001 lines
105 KiB
Diff

--- a/arch/m68k/include/asm/atomic_mm.h
+++ b/arch/m68k/include/asm/atomic_mm.h
@@ -20,12 +20,20 @@
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)
@@ -45,6 +53,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;
@@ -155,7 +171,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/arch/m68k/include/asm/bitops_mm.h
+++ b/arch/m68k/include/asm/bitops_mm.h
@@ -8,6 +8,10 @@
* for more details.
*/
+#ifdef CONFIG_COLDFIRE
+#include <asm/cf_bitops.h>
+#else
+
#ifndef _LINUX_BITOPS_H
#error only <linux/bitops.h> can be included directly
#endif
@@ -461,4 +465,6 @@ static inline int ext2_find_next_bit(con
#endif /* __KERNEL__ */
+#endif /* CONFIG_COLDFIRE */
+
#endif /* _M68K_BITOPS_H */
--- a/arch/m68k/include/asm/bootinfo.h
+++ b/arch/m68k/include/asm/bootinfo.h
@@ -25,6 +25,51 @@
#define _M68K_BOOTINFO_H
+#ifndef __ASSEMBLY__
+/*
+ * UBoot Support
+ *
+ * bd_info structure from uboot1.3.2/arch/m68k/include/asm/u-boot.h
+ */
+
+struct bd_info {
+ unsigned long bi_memstart; /* start of DRAM memory */
+ unsigned long bi_memsize; /* size of DRAM memory in bytes */
+ unsigned long bi_flashstart; /* start of FLASH memory */
+ unsigned long bi_flashsize; /* size of FLASH memory */
+ unsigned long bi_flashoffset; /* reserved area for startup monitor */
+ unsigned long bi_sramstart; /* start of SRAM memory */
+ unsigned long bi_sramsize; /* size of SRAM memory */
+ unsigned long bi_mbar_base; /* base of internal registers */
+ unsigned long bi_bootflags; /* boot / reboot flag (for LynxOS) */
+ unsigned long bi_boot_params; /* where this board expects params */
+ unsigned long bi_ip_addr; /* IP Address */
+ unsigned char bi_enet0addr[6]; /* Ethernet 0 mac address */
+ unsigned short bi_ethspeed; /* Ethernet speed in Mbps */
+ unsigned long bi_intfreq; /* Internal Freq, in MHz */
+ unsigned long bi_busfreq; /* Bus Freq, in MHz */
+#ifdef UBOOT_EXTRA_CLOCK
+ unsigned long bi_inpfreq; /* input Freq in MHz */
+ unsigned long bi_vcofreq; /* vco Freq in MHz */
+ unsigned long bi_flbfreq; /* Flexbus Freq in MHz */
+#endif
+ unsigned long bi_baudrate; /* Console Baudrate */
+ unsigned char bi_enet1addr[6]; /* eth1 mac address */
+ unsigned char bi_enet2addr[6]; /* eth2 mac address */
+ unsigned char bi_enet3addr[6]; /* eth3 mac address */
+};
+
+struct uboot_record {
+ struct bd_info *bdi;
+ unsigned long initrd_start;
+ unsigned long initrd_end;
+ unsigned long cmd_line_start;
+ unsigned long cmd_line_stop;
+};
+
+#endif /* __ASSEMBLY__ */
+
+
/*
* Bootinfo definitions
*
--- a/arch/m68k/include/asm/cacheflush_mm.h
+++ b/arch/m68k/include/asm/cacheflush_mm.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/arch/m68k/include/asm/checksum_mm.h
+++ b/arch/m68k/include/asm/checksum_mm.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/arch/m68k/include/asm/coldfire.h
+++ b/arch/m68k/include/asm/coldfire.h
@@ -5,6 +5,9 @@
*
* (C) Copyright 1999-2006, Greg Ungerer (gerg@snapgear.com)
* (C) Copyright 2000, Lineo (www.lineo.com)
+ *
+ * Shrek Wu b16972@freescale.com
+ * Copyright Freescale Semiconductor, Inc. 2009
*/
/****************************************************************************/
@@ -19,25 +22,78 @@
* here. Also the peripheral clock (bus clock) divide ratio is set
* at config time too.
*/
+/*FIXME Jason*/
+#if 0
#ifdef CONFIG_CLOCK_SET
#define MCF_CLK CONFIG_CLOCK_FREQ
#define MCF_BUSCLK (CONFIG_CLOCK_FREQ / CONFIG_CLOCK_DIV)
#else
#error "Don't know what your ColdFire CPU clock frequency is??"
#endif
+#endif
+
+
+#define MCF_CLK CONFIG_MCFCLK
+#define MCF_BUSCLK (CONFIG_MCFCLK/2)
+
+
+#if defined(CONFIG_M520x)
+#define MCF_IPSBAR 0xFC000000
+#else
+#define MCF_IPSBAR 0x40000000
+#endif
+#if defined(CONFIG_M5445X)
+#define MCF_MBAR 0x0
+/*
+ * Even though RAMBAR1 macro should be in the 0x8xxxxxxx range,
+ * here set the CONFIG_SDRAM_BASE value to it to use
+ * SDRAM memory, not SRAM memory.
+ */
+#define MCF_RAMBAR1 (CONFIG_SDRAM_BASE)
+#elif defined(CONFIG_M547X_8X)
+#define MCF_MBAR 0xF0000000
+#define MCF_MMUBAR 0xF1000000
+#define MCF_RAMBAR0 0xF3000000
+#define MCF_RAMBAR1 0xF3001000
+#else
/*
* Define the processor support peripherals base address.
* This is generally setup by the boards start up code.
*/
#define MCF_MBAR 0x10000000
#define MCF_MBAR2 0x80000000
-#if defined(CONFIG_M520x)
-#define MCF_IPSBAR 0xFC000000
-#else
-#define MCF_IPSBAR 0x40000000
#endif
+#ifdef __ASSEMBLY__
+#define REG32
+#define REG16
+#define REG08
+#else /* __ASSEMBLY__ */
+#define REG32(x) ((volatile unsigned long *)(x))
+#define REG16(x) ((volatile unsigned short *)(x))
+#define REG08(x) ((volatile unsigned char *)(x))
+
+#define MCF_REG32(x) *(volatile unsigned long *)(MCF_MBAR+(x))
+#define MCF_REG16(x) *(volatile unsigned short *)(MCF_MBAR+(x))
+#define MCF_REG08(x) *(volatile unsigned char *)(MCF_MBAR+(x))
+
+void cacr_set(unsigned long);
+unsigned long cacr_get(void);
+
+#define coldfire_enable_irq0(irq) MCF_INTC0_CIMR = (irq);
+
+#define coldfire_enable_irq1(irq) MCF_INTC1_CIMR = (irq);
+
+#define coldfire_disable_irq0(irq) MCF_INTC0_SIMR = (irq);
+
+#define coldfire_disable_irq1(irq) MCF_INTC1_SIMR = (irq);
+
+#define getiprh() MCF_INTC0_IPRH
+
+#endif /* __ASSEMBLY__ */
+
+
#if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) || \
defined(CONFIG_M520x)
#undef MCF_MBAR
--- a/arch/m68k/include/asm/delay_mm.h
+++ b/arch/m68k/include/asm/delay_mm.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/arch/m68k/include/asm/div64.h
+++ b/arch/m68k/include/asm/div64.h
@@ -1,7 +1,7 @@
#ifndef _M68K_DIV64_H
#define _M68K_DIV64_H
-#ifdef CONFIG_MMU
+#if defined(CONFIG_MMU) && !defined(CONFIG_COLDFIRE)
#include <linux/types.h>
--- a/arch/m68k/include/asm/dma_mm.h
+++ b/arch/m68k/include/asm/dma_mm.h
@@ -4,13 +4,126 @@
/* it's useless on the m68k, but unfortunately needed by the new
bootmem allocator (but this should do it for this) */
+/*#ifdef CONFIG_COLDFIRE*/
+#if defined(CONFIG_M5445X) || defined(CONFIG_M547X_8X)
+#define MAX_DMA_ADDRESS 0xefffffff
+#else
#define MAX_DMA_ADDRESS PAGE_OFFSET
+#endif
+#ifndef CONFIG_COLDFIRE
#define MAX_DMA_CHANNELS 8
extern int request_dma(unsigned int dmanr, const char * device_id); /* reserve a DMA channel */
extern void free_dma(unsigned int dmanr); /* release it again */
+#else /* not (defined(CONFIG_MCF5474) || defined(CONFIG_MCF5484)
+ || defined(CONFIG_MCF5475) || defined(CONFIG_MCF5485)) */
+/************************************************
+ * Multichannel DMA definitions *
+ ************************************************/
+#ifdef CONFIG_MCD_DMA
+#include <asm/MCD_dma.h>
+#include <asm/m5485dma.h>
+
+struct scatterlist;
+
+#define MAX_DMA_CHANNELS NCHANNELS
+/*
+ * identifiers for each initiator/requestor
+ */
+#define DMA_ALWAYS (0)
+#define DMA_DSPI_RX (1)
+#define DMA_DSPI_TX (2)
+#define DMA_DREQ0 (3)
+#define DMA_PSC0_RX (4)
+#define DMA_PSC0_TX (5)
+#define DMA_USBEP0 (6)
+#define DMA_USBEP1 (7)
+#define DMA_USBEP2 (8)
+#define DMA_USBEP3 (9)
+#define DMA_PCI_TX (10)
+#define DMA_PCI_RX (11)
+#define DMA_PSC1_RX (12)
+#define DMA_PSC1_TX (13)
+#define DMA_I2C_RX (14)
+#define DMA_I2C_TX (15)
+#define DMA_FEC0_RX (16)
+#define DMA_FEC0_TX (17)
+#define DMA_FEC1_RX (18)
+#define DMA_FEC1_TX (19)
+#define DMA_DREQ1 (20)
+#define DMA_CTM0 (21)
+#define DMA_CTM1 (22)
+#define DMA_CTM2 (23)
+#define DMA_CTM3 (24)
+#define DMA_CTM4 (25)
+#define DMA_CTM5 (26)
+#define DMA_CTM6 (27)
+#define DMA_CTM7 (28)
+#define DMA_USBEP4 (29)
+#define DMA_USBEP5 (30)
+#define DMA_USBEP6 (31)
+#define DMA_PSC2_RX (32)
+#define DMA_PSC2_TX (33)
+#define DMA_PSC3_RX (34)
+#define DMA_PSC3_TX (35)
+#define DMA_FEC_RX(x) ((x == 0) ? DMA_FEC0_RX : DMA_FEC1_RX)
+#define DMA_FEC_TX(x) ((x == 0) ? DMA_FEC0_TX : DMA_FEC1_TX)
+
+int dma_set_initiator(int);
+unsigned int dma_get_initiator(int);
+void dma_remove_initiator(int);
+int dma_set_channel(int);
+int dma_get_channel(int);
+void dma_remove_channel(int);
+int dma_set_channel_fec(int requestor);
+int dma_connect(int channel, int address);
+int dma_disconnect(int channel);
+void dma_remove_channel_by_number(int channel);
+int dma_init(void);
+#endif /* CONFIG_MCD_DMA */
+
+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);
+}
+
+
+/*
+ * Linux standard DMA stuff
+ */
+#if 0
+int request_dma(unsigned int channel, const char * device_id);
+void free_dma(unsigned int channel);
+void enable_dma(unsigned int channel);
+void disable_dma(unsigned int channel);
+int dma_channel_active(unsigned int channel);
+void set_dma_sg(unsigned int channel, struct scatterlist *sg, int nr_sg);
+void set_dma_page(unsigned int channel, char pagenr);
+void set_dma_addr(unsigned int channel, unsigned long physaddr);
+void set_dma_count(unsigned int channel, unsigned long count);
+void set_dma_mode(unsigned int channel, unsigned int mode);
+void set_dma_speed(unsigned int channel, int cycle_ns);
+int get_dma_residue(unsigned int channel);
+#endif
+#define clear_dma_ff(channel)
+
+#endif
+
+#ifdef CONFIG_PCI
+extern int isa_dma_bridge_buggy;
+#else
#define isa_dma_bridge_buggy (0)
+#endif
#endif /* _M68K_DMA_H */
--- a/arch/m68k/include/asm/elf.h
+++ b/arch/m68k/include/asm/elf.h
@@ -35,6 +35,27 @@
#define R_68K_JMP_SLOT 21
#define R_68K_RELATIVE 22
+/* TLS static relocations */
+#define R_68K_TLS_GD32 25
+#define R_68K_TLS_GD16 26
+#define R_68K_TLS_GD8 27
+#define R_68K_TLS_LDM32 28
+#define R_68K_TLS_LDM16 29
+#define R_68K_TLS_LDM8 30
+#define R_68K_TLS_LDO32 31
+#define R_68K_TLS_LDO16 32
+#define R_68K_TLS_LDO8 33
+#define R_68K_TLS_IE32 34
+#define R_68K_TLS_IE16 35
+#define R_68K_TLS_IE8 36
+#define R_68K_TLS_LE32 37
+#define R_68K_TLS_LE16 38
+#define R_68K_TLS_LE8 39
+/* TLS dynamic relocations */
+#define R_68K_TLS_DTPMOD32 40
+#define R_68K_TLS_DTPREL32 41
+#define R_68K_TLS_TPREL32 42
+
typedef unsigned long elf_greg_t;
#define ELF_NGREG (sizeof(struct user_regs_struct) / sizeof(elf_greg_t))
@@ -60,7 +81,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
@@ -71,8 +92,10 @@ typedef struct user_m68kfp_struct elf_fp
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. */
-#ifndef CONFIG_SUN3
+#if !defined(CONFIG_SUN3) && !defined(CONFIG_COLDFIRE)
#define ELF_ET_DYN_BASE 0xD0000000UL
+#elif defined(CONFIG_COLDFIRE)
+#define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE + 0x10000000)
#else
#define ELF_ET_DYN_BASE 0x0D800000UL
#endif
@@ -116,4 +139,35 @@ typedef struct user_m68kfp_struct elf_fp
#define SET_PERSONALITY(ex) set_personality(PER_LINUX)
+/*
+ * VDSO
+ */
+#ifdef CONFIG_VDSO
+extern unsigned int vdso_enabled;
+
+#define VDSO_BASE ((unsigned long)current->mm->context.vdso)
+#define VDSO_SYM(x) (VDSO_BASE + (unsigned long)(x))
+
+#define VDSO_AUX_ENT \
+ if (vdso_enabled) \
+ NEW_AUX_ENT(AT_SYSINFO_EHDR, VDSO_BASE);
+
+/* additional pages */
+#define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1
+
+struct linux_binprm;
+extern int arch_setup_additional_pages(struct linux_binprm *bprm,
+ int executable_stack);
+
+#else
+/* no VDSO_AUX_ENT */
+#define VDSO_AUX_ENT
+#endif
+
+#define ARCH_DLINFO \
+do { \
+ /* vdso entry */ \
+ VDSO_AUX_ENT; \
+} while (0);
+
#endif
--- a/arch/m68k/include/asm/io_mm.h
+++ b/arch/m68k/include/asm/io_mm.h
@@ -7,17 +7,24 @@
* - added skeleton for GG-II and Amiga PCMCIA
* 2/3/01 RZ: - moved a few more defs into raw_io.h
*
- * inX/outX should not be used by any driver unless it does
- * ISA access. Other drivers should use function defined in raw_io.h
+ * inX/outX/readX/writeX should not be used by any driver unless it does
+ * ISA or PCI access. Other drivers should use function defined in raw_io.h
* or define its own macros on top of these.
*
- * inX(),outX() are for ISA I/O
+ * inX(),outX() are for PCI and ISA I/O
+ * readX(),writeX() are for PCI memory
* isa_readX(),isa_writeX() are for ISA memory
+ *
+ * moved mem{cpy,set}_*io inside CONFIG_PCI
*/
#ifndef _IO_H
#define _IO_H
+#ifdef CONFIG_COLDFIRE
+#include <asm/cf_io.h>
+#else
+
#ifdef __KERNEL__
#include <linux/compiler.h>
@@ -88,20 +95,20 @@ extern unsigned long gg2_isa_base;
#undef MULTI_ISA
#endif
-#define ISA_TYPE_Q40 (1)
-#define ISA_TYPE_GG2 (2)
-#define ISA_TYPE_AG (3)
+#define Q40_ISA (1)
+#define GG2_ISA (2)
+#define AG_ISA (3)
#if defined(CONFIG_Q40) && !defined(MULTI_ISA)
-#define ISA_TYPE ISA_TYPE_Q40
+#define ISA_TYPE Q40_ISA
#define ISA_SEX 0
#endif
#if defined(CONFIG_AMIGA_PCMCIA) && !defined(MULTI_ISA)
-#define ISA_TYPE ISA_TYPE_AG
+#define ISA_TYPE AG_ISA
#define ISA_SEX 1
#endif
#if defined(CONFIG_GG2) && !defined(MULTI_ISA)
-#define ISA_TYPE ISA_TYPE_GG2
+#define ISA_TYPE GG2_ISA
#define ISA_SEX 0
#endif
@@ -123,13 +130,13 @@ static inline u8 __iomem *isa_itb(unsign
switch(ISA_TYPE)
{
#ifdef CONFIG_Q40
- case ISA_TYPE_Q40: return (u8 __iomem *)Q40_ISA_IO_B(addr);
+ case Q40_ISA: return (u8 __iomem *)Q40_ISA_IO_B(addr);
#endif
#ifdef CONFIG_GG2
- case ISA_TYPE_GG2: return (u8 __iomem *)GG2_ISA_IO_B(addr);
+ case GG2_ISA: return (u8 __iomem *)GG2_ISA_IO_B(addr);
#endif
#ifdef CONFIG_AMIGA_PCMCIA
- case ISA_TYPE_AG: return (u8 __iomem *)AG_ISA_IO_B(addr);
+ case AG_ISA: return (u8 __iomem *)AG_ISA_IO_B(addr);
#endif
default: return NULL; /* avoid warnings, just in case */
}
@@ -139,13 +146,13 @@ static inline u16 __iomem *isa_itw(unsig
switch(ISA_TYPE)
{
#ifdef CONFIG_Q40
- case ISA_TYPE_Q40: return (u16 __iomem *)Q40_ISA_IO_W(addr);
+ case Q40_ISA: return (u16 __iomem *)Q40_ISA_IO_W(addr);
#endif
#ifdef CONFIG_GG2
- case ISA_TYPE_GG2: return (u16 __iomem *)GG2_ISA_IO_W(addr);
+ case GG2_ISA: return (u16 __iomem *)GG2_ISA_IO_W(addr);
#endif
#ifdef CONFIG_AMIGA_PCMCIA
- case ISA_TYPE_AG: return (u16 __iomem *)AG_ISA_IO_W(addr);
+ case AG_ISA: return (u16 __iomem *)AG_ISA_IO_W(addr);
#endif
default: return NULL; /* avoid warnings, just in case */
}
@@ -155,7 +162,7 @@ static inline u32 __iomem *isa_itl(unsig
switch(ISA_TYPE)
{
#ifdef CONFIG_AMIGA_PCMCIA
- case ISA_TYPE_AG: return (u32 __iomem *)AG_ISA_IO_W(addr);
+ case AG_ISA: return (u32 __iomem *)AG_ISA_IO_W(addr);
#endif
default: return 0; /* avoid warnings, just in case */
}
@@ -165,13 +172,13 @@ static inline u8 __iomem *isa_mtb(unsign
switch(ISA_TYPE)
{
#ifdef CONFIG_Q40
- case ISA_TYPE_Q40: return (u8 __iomem *)Q40_ISA_MEM_B(addr);
+ case Q40_ISA: return (u8 __iomem *)Q40_ISA_MEM_B(addr);
#endif
#ifdef CONFIG_GG2
- case ISA_TYPE_GG2: return (u8 __iomem *)GG2_ISA_MEM_B(addr);
+ case GG2_ISA: return (u8 __iomem *)GG2_ISA_MEM_B(addr);
#endif
#ifdef CONFIG_AMIGA_PCMCIA
- case ISA_TYPE_AG: return (u8 __iomem *)addr;
+ case AG_ISA: return (u8 __iomem *)addr;
#endif
default: return NULL; /* avoid warnings, just in case */
}
@@ -181,13 +188,13 @@ static inline u16 __iomem *isa_mtw(unsig
switch(ISA_TYPE)
{
#ifdef CONFIG_Q40
- case ISA_TYPE_Q40: return (u16 __iomem *)Q40_ISA_MEM_W(addr);
+ case Q40_ISA: return (u16 __iomem *)Q40_ISA_MEM_W(addr);
#endif
#ifdef CONFIG_GG2
- case ISA_TYPE_GG2: return (u16 __iomem *)GG2_ISA_MEM_W(addr);
+ case GG2_ISA: return (u16 __iomem *)GG2_ISA_MEM_W(addr);
#endif
#ifdef CONFIG_AMIGA_PCMCIA
- case ISA_TYPE_AG: return (u16 __iomem *)addr;
+ case AG_ISA: return (u16 __iomem *)addr;
#endif
default: return NULL; /* avoid warnings, just in case */
}
@@ -201,30 +208,29 @@ static inline u16 __iomem *isa_mtw(unsig
#define isa_outw(val,port) (ISA_SEX ? out_be16(isa_itw(port),(val)) : out_le16(isa_itw(port),(val)))
#define isa_outl(val,port) (ISA_SEX ? out_be32(isa_itl(port),(val)) : out_le32(isa_itl(port),(val)))
-#define isa_readb(p) in_8(isa_mtb((unsigned long)(p)))
-#define isa_readw(p) \
- (ISA_SEX ? in_be16(isa_mtw((unsigned long)(p))) \
- : in_le16(isa_mtw((unsigned long)(p))))
-#define isa_writeb(val,p) out_8(isa_mtb((unsigned long)(p)),(val))
-#define isa_writew(val,p) \
- (ISA_SEX ? out_be16(isa_mtw((unsigned long)(p)),(val)) \
- : out_le16(isa_mtw((unsigned long)(p)),(val)))
-
+#define isa_readb(p) in_8(isa_mtb(p))
+#define isa_readw(p) (ISA_SEX ? in_be16(isa_mtw(p)) : in_le16(isa_mtw(p)))
+#define isa_writeb(val,p) out_8(isa_mtb(p),(val))
+#define isa_writew(val,p) (ISA_SEX ? out_be16(isa_mtw(p),(val)) : out_le16(isa_mtw(p),(val)))
static inline void isa_delay(void)
{
- switch(ISA_TYPE)
- {
+ switch (ISA_TYPE) {
#ifdef CONFIG_Q40
- case ISA_TYPE_Q40: isa_outb(0,0x80); break;
+ case Q40_ISA:
+ isa_outb(0, 0x80);
+ break;
#endif
#ifdef CONFIG_GG2
- case ISA_TYPE_GG2: break;
+ case GG2_ISA:
+ break;
#endif
#ifdef CONFIG_AMIGA_PCMCIA
- case ISA_TYPE_AG: break;
+ case AG_ISA:
+ break;
#endif
- default: break; /* avoid warnings */
- }
+ default:
+ break; /* avoid warnings */
+ }
}
#define isa_inb_p(p) ({u8 v=isa_inb(p);isa_delay();v;})
@@ -253,7 +259,10 @@ static inline void isa_delay(void)
(ISA_SEX ? raw_outsl(isa_itl(port), (u32 *)(buf), (nr)) : \
raw_outsw_swapw(isa_itw(port), (u16 *)(buf), (nr)<<1))
+#endif /* CONFIG_ISA */
+
+#if defined(CONFIG_ISA) && !defined(CONFIG_PCI)
#define inb isa_inb
#define inb_p isa_inb_p
#define outb isa_outb
@@ -276,9 +285,80 @@ static inline void isa_delay(void)
#define readw isa_readw
#define writeb isa_writeb
#define writew isa_writew
+#endif /* CONFIG_ISA */
+
+#if defined(CONFIG_PCI)
+
+#define readl(addr) in_le32(addr)
+#define writel(val, addr) out_le32((addr), (val))
+
+/* those can be defined for both ISA and PCI - it won't work though */
+#define readb(addr) in_8(addr)
+#define readw(addr) in_le16(addr)
+#define writeb(val, addr) out_8((addr), (val))
+#define writew(val, addr) out_le16((addr), (val))
+
+#define readb_relaxed(addr) readb(addr)
+#define readw_relaxed(addr) readw(addr)
+#define readl_relaxed(addr) readl(addr)
+
+#ifndef CONFIG_ISA
+#define inb(port) in_8(port)
+#define outb(val, port) out_8((port), (val))
+#define inw(port) in_le16(port)
+#define outw(val, port) out_le16((port), (val))
+#define inl(port) in_le32(port)
+#define outl(val, port) out_le32((port), (val))
+#define insb(port, buf, nr) \
+ raw_insb((u8 *)(port), (u8 *)(buf), (nr))
+#define outsb(port, buf, nr) \
+ raw_outsb((u8 *)(port), (u8 *)(buf), (nr))
+#define insw(port, buf, nr) \
+ raw_insw_swapw((u16 *)(port), (u16 *)(buf), (nr))
+#define outsw(port, buf, nr) \
+ raw_outsw_swapw((u16 *)(port), (u16 *)(buf), (nr))
+#define insl(port, buf, nr) \
+ raw_insw_swapw((u16 *)(port), (u16 *)(buf), (nr)<<1)
+#define outsl(port, buf, nr) \
+ raw_outsw_swapw((u16 *)(port), (u16 *)(buf), (nr)<<1)
+
+#define __raw_readb readb
+#define __raw_readw readw
+#define __raw_readl readl
+#define __raw_writeb writeb
+#define __raw_writew writew
+#define __raw_writel writel
-#else /* CONFIG_ISA */
+#else
+/*
+ * kernel with both ISA and PCI compiled in, those have
+ * conflicting defs for in/out. Simply consider port < 1024
+ * ISA and everything else PCI. read,write not defined
+ * in this case
+ */
+#define inb(port) ((port) < 1024 ? isa_inb(port) : in_8(port))
+#define inb_p(port) ((port) < 1024 ? isa_inb_p(port) : in_8(port))
+#define inw(port) ((port) < 1024 ? isa_inw(port) : in_le16(port))
+#define inw_p(port) ((port) < 1024 ? isa_inw_p(port) : in_le16(port))
+#define inl(port) ((port) < 1024 ? isa_inl(port) : in_le32(port))
+#define inl_p(port) ((port) < 1024 ? isa_inl_p(port) : in_le32(port))
+
+#define outb(val, port) (((port) < 1024) ? isa_outb((val), (port))
+ : out_8((port), (val)))
+#define outb_p(val, port) (((port) < 1024) ? isa_outb_p((val), (port))
+ : out_8((port), (val)))
+#define outw(val, port) (((port) < 1024) ? isa_outw((val), (port))
+ : out_le16((port), (val)))
+#define outw_p(val, port) (((port) < 1024) ? isa_outw_p((val), (port))
+ : out_le16((port), (val)))
+#define outl(val, port) (((port) < 1024) ? isa_outl((val), (port))
+ : out_le32((port), (val)))
+#define outl_p(val, port) (((port) < 1024) ? isa_outl_p((val), (port))
+ : out_le32((port), (val)))
+#endif
+#endif /* CONFIG_PCI */
+#if !defined(CONFIG_ISA) && !defined(CONFIG_PCI)
/*
* We need to define dummy functions for GENERIC_IOMAP support.
*/
@@ -305,11 +385,11 @@ static inline void isa_delay(void)
#define writeb(val,addr) out_8((addr),(val))
#define readw(addr) in_le16(addr)
#define writew(val,addr) out_le16((addr),(val))
-
-#endif /* CONFIG_ISA */
-
+#endif
+#if !defined(CONFIG_PCI)
#define readl(addr) in_le32(addr)
#define writel(val,addr) out_le32((addr),(val))
+#endif
#define mmiowb()
@@ -345,10 +425,10 @@ 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
+#else
+#define IO_SPACE_LIMIT 0xffff
#endif
#endif /* __KERNEL__ */
@@ -366,4 +446,5 @@ static inline void memcpy_toio(volatile
*/
#define xlate_dev_kmem_ptr(p) p
+#endif /* CONFIG_COLDFIRE */
#endif /* _IO_H */
--- a/arch/m68k/include/asm/irq_mm.h
+++ b/arch/m68k/include/asm/irq_mm.h
@@ -12,7 +12,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/arch/m68k/include/asm/machdep_mm.h
+++ b/arch/m68k/include/asm/machdep_mm.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/arch/m68k/include/asm/mcfsim.h
+++ b/arch/m68k/include/asm/mcfsim.h
@@ -39,6 +39,25 @@
#include <asm/m5407sim.h>
#endif
+#if defined(CONFIG_COLDFIRE)
+#include <asm/coldfire.h>
+#endif
+
+#if defined(CONFIG_M5445X)
+#include <asm/mcf5445x_intc.h>
+#include <asm/mcf5445x_gpio.h>
+#include <asm/mcf5445x_ccm.h>
+#include <asm/mcf5445x_eport.h>
+#include <asm/mcf5445x_fbcs.h>
+#include <asm/mcf5445x_xbs.h>
+#include <asm/mcf5445x_dtim.h>
+#include <asm/mcf5445x_rtc.h>
+#include <asm/mcf5445x_scm.h>
+#elif defined(CONFIG_M547X_8X)
+#include <asm/m5485sim.h>
+#include <asm/m5485gpio.h>
+#include <asm/m5485gpt.h>
+#endif
/*
* Define the base address of the SIM within the MBAR address space.
--- a/arch/m68k/include/asm/mmu_context.h
+++ b/arch/m68k/include/asm/mmu_context.h
@@ -8,7 +8,7 @@ static inline void enter_lazy_tlb(struct
}
#ifdef CONFIG_MMU
-#ifndef CONFIG_SUN3
+#if !defined(CONFIG_SUN3) && !defined(CONFIG_COLDFIRE)
#include <asm/setup.h>
#include <asm/page.h>
@@ -103,7 +103,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>
@@ -151,7 +151,179 @@ static inline void activate_mm(struct mm
activate_context(next_mm);
}
+#else /* CONFIG_COLDFIRE */
+
+#include <asm/coldfire.h>
+#include <asm/atomic.h>
+#include <asm/bitops.h>
+#include <asm/mmu.h>
+
+#define NO_CONTEXT 256
+#define LAST_CONTEXT 255
+#define FIRST_CONTEXT 1
+
+#ifdef CONFIG_VDSO
+#define cpu_context(mm) ((mm)->context.id)
+#else
+#define cpu_context(mm) ((mm)->context)
+#endif
+
+#ifdef CONFIG_VDSO
+extern void set_context(unsigned long context, pgd_t *pgd);
+#else
+extern void set_context(mm_context_t context, pgd_t *pgd);
+#endif
+extern unsigned long context_map[];
+#ifdef CONFIG_VDSO
+extern unsigned long next_mmu_context;
+#else
+extern mm_context_t next_mmu_context;
+#endif
+
+
+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)
+{
+#ifdef CONFIG_VDSO
+ unsigned long ctx;
+#else
+ mm_context_t ctx;
#endif
+
+ if (cpu_context(mm) != 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;
+ cpu_context(mm) = ctx;
+ context_mm[ctx] = mm;
+}
+
+/*
+ * Set up the context for a new address space.
+ */
+#define init_new_context(tsk, mm) ((cpu_context(mm) = NO_CONTEXT), 0)
+/* #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 (cpu_context(mm) != NO_CONTEXT) {
+ clear_bit(cpu_context(mm), context_map);
+ cpu_context(mm) = 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(cpu_context(tsk->mm), 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(cpu_context(mm), mm->pgd);
+}
+
+#define deactivate_mm(tsk, mm) do { } while (0)
+
+extern void mmu_context_init(void);
+#if defined(CONFIG_M547X_8X)
+#define prepare_arch_switch(next) load_ksp_mmu(next)
+
+static inline void load_ksp_mmu(struct task_struct *task)
+{
+ int flags;
+ struct mm_struct *mm;
+ int asid;
+ pgd_t *pgd;
+ pmd_t *pmd;
+ pte_t *pte;
+ unsigned long mmuar;
+
+ local_irq_save(flags);
+ mmuar = task->thread.ksp;
+
+ /* Search for a valid TLB entry, if one is found, don't remap */
+ *MMUAR = mmuar;
+ *MMUOR = MMUOR_STLB | MMUOR_ADR;
+ if ((*MMUSR) & MMUSR_HIT)
+ goto end;
+
+ if (mmuar >= PAGE_OFFSET) {
+ mm = &init_mm;
+ } else {
+ printk(KERN_INFO "load_ksp_mmu: non-kernel"
+ " mm found: 0x%08x\n", (unsigned int) task->mm);
+ mm = task->mm;
+ }
+
+ if (!mm)
+ goto bug;
+
+ pgd = pgd_offset(mm, mmuar);
+ if (pgd_none(*pgd))
+ goto bug;
+
+ pmd = pmd_offset(pgd, mmuar);
+ if (pmd_none(*pmd))
+ goto bug;
+
+ pte = (mmuar >= PAGE_OFFSET) ? pte_offset_kernel(pmd, mmuar)
+ : pte_offset_map(pmd, mmuar);
+ if (pte_none(*pte) || !pte_present(*pte))
+ goto bug;
+
+ set_pte(pte, pte_mkyoung(*pte));
+ asid = cpu_context(mm) & 0xff;
+ if (!pte_dirty(*pte) && mmuar <= PAGE_OFFSET)
+ set_pte(pte, pte_wrprotect(*pte));
+
+ *MMUTR = (mmuar & PAGE_MASK) | (asid << CF_ASID_MMU_SHIFT)
+ | (((int)(pte->pte) & (int)CF_PAGE_MMUTR_MASK)
+ >> CF_PAGE_MMUTR_SHIFT)
+ | MMUTR_V;
+
+ *MMUDR = (pte_val(*pte) & PAGE_MASK)
+ | ((pte->pte) & CF_PAGE_MMUDR_MASK)
+ | MMUDR_SZ8K | MMUDR_X;
+
+ *MMUOR = MMUOR_ACC | MMUOR_UAA;
+ asm ("nop");
+
+ goto end;
+
+bug:
+ printk(KERN_ERR "ksp load failed: mm=0x%08x ksp=0x%08x\n",
+ (unsigned int) mm, (unsigned int) mmuar);
+end:
+ local_irq_restore(flags);
+}
+#endif /* CONFIG_M547X_8X */
+
+#endif /* CONFIG_COLDFIRE */
+
#else /* !CONFIG_MMU */
static inline int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
--- a/arch/m68k/include/asm/page_mm.h
+++ b/arch/m68k/include/asm/page_mm.h
@@ -1,10 +1,15 @@
#ifndef _M68K_PAGE_H
#define _M68K_PAGE_H
+/*#if defined(CONFIG_COLDFIRE)*/
+#if defined(CONFIG_M5445X) || defined(CONFIG_M547X_8X)
+#include <asm/cf_page.h>
+#else
+
#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)
@@ -113,10 +118,31 @@ 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)
+{
+#if CONFIG_SDRAM_BASE != PAGE_OFFSET
+ return (((unsigned long)vaddr & 0x0fffffff) + CONFIG_SDRAM_BASE);
+#else
+ return (unsigned long)vaddr;
+#endif
+}
+#define __pa(vaddr) ___pa((void *)(vaddr))
+
+static inline void *__va(unsigned long paddr)
+{
+#if CONFIG_SDRAM_BASE != PAGE_OFFSET
+ return (void *)((paddr & 0x0fffffff) + PAGE_OFFSET);
+#else
+ return (void *)paddr;
+#endif
+}
+
+#else
static inline unsigned long ___pa(void *vaddr)
{
unsigned long paddr;
@@ -138,6 +164,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 */
@@ -169,6 +196,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)
@@ -225,4 +254,10 @@ static inline __attribute_const__ int __
#include <asm-generic/getorder.h>
+#ifdef CONFIG_VDSO
+/* vDSO support */
+#define __HAVE_ARCH_GATE_AREA
+#endif
+
+#endif /* !CONFIG_COLDFIRE */
#endif /* _M68K_PAGE_H */
--- a/arch/m68k/include/asm/page_offset.h
+++ b/arch/m68k/include/asm/page_offset.h
@@ -1,10 +1,13 @@
/* This handles the memory map.. */
#ifdef CONFIG_MMU
-#ifndef CONFIG_SUN3
-#define PAGE_OFFSET_RAW 0x00000000
-#else
+#if defined(CONFIG_SUN3)
#define PAGE_OFFSET_RAW 0x0E000000
+#elif defined(CONFIG_M5445X) || defined(CONFIG_M547X_8X)
+#define PHYS_OFFSET CONFIG_SDRAM_BASE
+#define PAGE_OFFSET_RAW (PHYS_OFFSET)
+#else
+#define PAGE_OFFSET_RAW 0x00000000
#endif
#else
#define PAGE_OFFSET_RAW CONFIG_RAMBASE
--- a/arch/m68k/include/asm/pgalloc.h
+++ b/arch/m68k/include/asm/pgalloc.h
@@ -7,8 +7,10 @@
#ifdef CONFIG_MMU
#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/arch/m68k/include/asm/pgtable_mm.h
+++ b/arch/m68k/include/asm/pgtable_mm.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,11 @@
#ifdef CONFIG_SUN3
#define KMAP_START 0x0DC00000
#define KMAP_END 0x0E000000
+#elif defined(CONFIG_COLDFIRE)
+#define VMALLOC_START 0xc0000000
+#define VMALLOC_END 0xcfffffff
+#define KMAP_START (VMALLOC_END + 1)
+#define KMAP_END 0xe8000000
#else
#define KMAP_START 0xd0000000
#define KMAP_END 0xf0000000
@@ -79,9 +90,11 @@
* The vmalloc() routines leaves a hole of 4kB between each vmalloced
* area for the same reason. ;)
*/
+#if !defined(CONFIG_COLDFIRE)
#define VMALLOC_OFFSET (8*1024*1024)
#define VMALLOC_START (((unsigned long) high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
#define VMALLOC_END KMAP_START
+#endif
#else
extern unsigned long vmalloc_end;
#define VMALLOC_START 0x0f800000
@@ -130,6 +143,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
@@ -138,6 +153,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
@@ -152,6 +170,7 @@ static inline void update_mmu_cache(stru
? (__pgprot((pgprot_val(prot) & _CACHEMASK040) | _PAGE_NOCACHE_S)) \
: (prot)))
+#endif /* CONFIG_COLDFIRE */
#include <asm-generic/pgtable.h>
#endif /* !__ASSEMBLY__ */
--- a/arch/m68k/include/asm/processor_mm.h
+++ b/arch/m68k/include/asm/processor_mm.h
@@ -2,6 +2,7 @@
* include/asm-m68k/processor.h
*
* Copyright (C) 1995 Hamish Macdonald
+ * Copyright 2007-2009 Freescale Semiconductor, Inc. All Rights Reserved.
*/
#ifndef __ASM_M68K_PROCESSOR_H
@@ -22,24 +23,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 +64,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 0x60000000UL
+#else /* CONFIG_SUN3 */
#define TASK_UNMAPPED_BASE 0x0A000000UL
#endif
#define TASK_UNMAPPED_ALIGN(addr, off) PAGE_ALIGN(addr)
@@ -60,7 +77,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 +102,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 +113,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/arch/m68k/include/asm/ptrace.h
+++ b/arch/m68k/include/asm/ptrace.h
@@ -39,10 +39,21 @@ struct pt_regs {
long orig_d0;
long stkadj;
#ifdef CONFIG_COLDFIRE
+#if 0
unsigned format : 4; /* frame format specifier */
unsigned vector : 12; /* vector offset */
unsigned short sr;
unsigned long pc;
+#endif
+/*FROM BSP*/
+ 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;
#else
unsigned short sr;
unsigned long pc;
@@ -71,6 +82,8 @@ struct switch_stack {
#define PTRACE_GETFPREGS 14
#define PTRACE_SETFPREGS 15
+#define PTRACE_GET_THREAD_AREA 25
+
#ifdef __KERNEL__
#ifndef PS_S
--- a/arch/m68k/include/asm/raw_io.h
+++ b/arch/m68k/include/asm/raw_io.h
@@ -8,6 +8,10 @@
#ifndef _RAW_IO_H
#define _RAW_IO_H
+#ifdef CONFIG_COLDFIRE
+#include <asm/cf_raw_io.h>
+#else
+
#ifdef __KERNEL__
#include <asm/types.h>
@@ -60,6 +64,9 @@ extern void __iounmap(void *addr, unsign
#define __raw_writew(val,addr) out_be16((addr),(val))
#define __raw_writel(val,addr) out_be32((addr),(val))
+#define swap_inw(port) in_le16((port))
+#define swap_outw(val,port) out_le16((port),(val))
+
static inline void raw_insb(volatile u8 __iomem *port, u8 *buf, unsigned int len)
{
unsigned int i;
@@ -344,4 +351,6 @@ static inline void raw_outsw_swapw(volat
#endif /* __KERNEL__ */
+#endif /* CONFIG_COLDFIRE */
+
#endif /* _RAW_IO_H */
--- a/arch/m68k/include/asm/segment.h
+++ b/arch/m68k/include/asm/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)
{
#ifdef CONFIG_MMU
@@ -56,6 +57,15 @@ static inline void set_fs(mm_segment_t v
#endif
}
+#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/arch/m68k/include/asm/setup.h
+++ b/arch/m68k/include/asm/setup.h
@@ -2,6 +2,7 @@
** asm/setup.h -- Definition of the Linux/m68k setup information
**
** Copyright 1992 by Greg Harp
+ * Copyright 2007-2009 Freescale Semiconductor, Inc. All Rights Reserved.
**
** This file is subject to the terms and conditions of the GNU General Public
** License. See the file COPYING in the main directory of this archive
@@ -40,6 +41,7 @@
#define MACH_HP300 9
#define MACH_Q40 10
#define MACH_SUN3X 11
+#define MACH_CFMMU 12
#define COMMAND_LINE_SIZE 256
@@ -189,6 +191,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 +221,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)
+#ifdef CONFIG_M547X_8X
+#define FPU_CFV4E (1<<FPUB_CFV4E)
+#else
+#define FPU_CFV4E 0
+#endif
#define MMUB_68851 0
#define MMUB_68030 1 /* Internal MMU */
@@ -235,6 +253,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 +261,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 +361,14 @@ extern int m68k_is040or060;
# endif
#endif
+#if !defined(CONFIG_CFV4E)
+# define CPU_IS_COLDFIRE (0)
+#else
+# define CPU_IS_COLDFIRE (m68k_cputype & CPU_CFV4E)
+# define CPU_IS_CFV4E (m68k_cputype & CPU_CFV4E)
+# define MMU_IS_CFV4E (m68k_mmutype & MMU_CFV4E)
+#endif
+
#define CPU_TYPE (m68k_cputype)
#ifdef CONFIG_M68KFPU_EMU
@@ -371,6 +399,14 @@ extern int m68k_realnum_memory; /* real
extern struct mem_info m68k_memory[NUM_MEMINFO];/* memory description */
#endif
+#ifdef CONFIG_CFV4E
+#define QCHIP_RESTORE_DIRECTIVE ".chip 547x"
+#define CHIP_RESTORE_DIRECTIVE .chip 547x
+#else
+#define QCHIP_RESTORE_DIRECTIVE ".chip 68k"
+#define CHIP_RESTORE_DIRECTIVE .chip 68k
+#endif
+
#endif /* __KERNEL__ */
#endif /* _M68K_SETUP_H */
--- a/arch/m68k/include/asm/sigcontext.h
+++ b/arch/m68k/include/asm/sigcontext.h
@@ -15,9 +15,15 @@ struct sigcontext {
unsigned long sc_pc;
unsigned short sc_formatvec;
#ifndef __uClinux__
+# ifdef __mcoldfire__
+ unsigned long sc_fpregs[2][2]; /* room for two fp registers */
+ unsigned long sc_fpcntl[3];
+ unsigned char sc_fpstate[16+6*8];
+# else
unsigned long sc_fpregs[2*3]; /* room for two fp registers */
unsigned long sc_fpcntl[3];
unsigned char sc_fpstate[216];
+# endif
#endif
};
--- a/arch/m68k/include/asm/siginfo.h
+++ b/arch/m68k/include/asm/siginfo.h
@@ -29,7 +29,8 @@ typedef struct siginfo {
struct {
timer_t _tid; /* timer id */
int _overrun; /* overrun count */
- char _pad[sizeof( __ARCH_SI_UID_T) - sizeof(int)];
+ char _pad[sizeof( __ARCH_SI_UID_T) - sizeof(int)
+ + sizeof(__kernel_uid_t)];
sigval_t _sigval; /* same as below */
int _sys_private; /* not to be passed to user */
} _timer;
@@ -38,18 +39,18 @@ typedef struct siginfo {
struct {
__kernel_pid_t _pid; /* sender's pid */
__kernel_uid_t _uid; /* backwards compatibility */
- sigval_t _sigval;
__kernel_uid32_t _uid32; /* sender's uid */
+ sigval_t _sigval;
} _rt;
/* SIGCHLD */
struct {
__kernel_pid_t _pid; /* which child */
__kernel_uid_t _uid; /* backwards compatibility */
- int _status; /* exit code */
+ __kernel_uid32_t _uid32; /* sender's uid */
clock_t _utime;
clock_t _stime;
- __kernel_uid32_t _uid32; /* sender's uid */
+ int _status; /* exit code */
} _sigchld;
/* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
--- a/arch/m68k/include/asm/signal.h
+++ b/arch/m68k/include/asm/signal.h
@@ -150,7 +150,8 @@ typedef struct sigaltstack {
#ifdef __KERNEL__
#include <asm/sigcontext.h>
-#ifndef __uClinux__
+//#ifndef __uClinux__
+#ifndef CONFIG_COLDFIRE /*FIXME Jason*/
#define __HAVE_ARCH_SIG_BITOPS
static inline void sigaddset(sigset_t *set, int _sig)
@@ -201,7 +202,6 @@ static inline int sigfindinword(unsigned
struct pt_regs;
extern void ptrace_signal_deliver(struct pt_regs *regs, void *cookie);
-
#else
#undef __HAVE_ARCH_SIG_BITOPS
--- a/arch/m68k/include/asm/string_mm.h
+++ b/arch/m68k/include/asm/string_mm.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/arch/m68k/include/asm/swab.h
+++ b/arch/m68k/include/asm/swab.h
@@ -4,7 +4,7 @@
#include <linux/types.h>
#include <linux/compiler.h>
-#define __SWAB_64_THRU_32__
+/*#define __SWAB_64_THRU_32__
#if defined (__mcfisaaplus__) || defined (__mcfisac__)
static inline __attribute_const__ __u32 __arch_swab32(__u32 val)
@@ -23,5 +23,29 @@ static inline __attribute_const__ __u32
}
#define __arch_swab32 __arch_swab32
#endif
+*/
+#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));
+ return val;
+}
+#define __arch__swab32(x) ___arch__swab32(x)
+
+#endif
+#endif
+
+#if defined(__GNUC__) && !defined(__STRICT_ANSI__) || defined(__KERNEL__)
+# define __BYTEORDER_HAS_U64__
+# define __SWAB_64_THRU_32__
+#endif
#endif /* _M68K_SWAB_H */
--- a/arch/m68k/include/asm/system_mm.h
+++ b/arch/m68k/include/asm/system_mm.h
@@ -5,9 +5,24 @@
#include <linux/kernel.h>
#include <asm/segment.h>
#include <asm/entry.h>
+#include <asm/cfcache.h>
#ifdef __KERNEL__
+#ifdef CONFIG_COLDFIRE
+#define FLUSH_BC (0x00040000)
+
+#define finish_arch_switch(prev) do { \
+ unsigned long tmpreg; \
+ asm volatile ( "move.l %2,%0\n" \
+ "orl %1,%0\n" \
+ "movec %0,%%cacr" \
+ : "=&d" (tmpreg) \
+ : "id" (FLUSH_BC), "m" (shadow_cacr)); \
+ } while(0)
+
+#endif
+
/*
* switch_to(n) should switch tasks to task ptr, first checking that
* ptr isn't the current task, in which case it does nothing. This
@@ -63,16 +78,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/arch/m68k/include/asm/thread_info_mm.h
+++ b/arch/m68k/include/asm/thread_info_mm.h
@@ -10,6 +10,7 @@ struct thread_info {
struct exec_domain *exec_domain; /* execution domain */
int preempt_count; /* 0 => preemptable, <0 => BUG */
__u32 cpu; /* should always be 0 on m68k */
+ unsigned long tp_value;
struct restart_block restart_block;
};
--- a/arch/m68k/include/asm/tlbflush.h
+++ b/arch/m68k/include/asm/tlbflush.h
@@ -2,7 +2,7 @@
#define _M68K_TLBFLUSH_H
#ifdef CONFIG_MMU
-#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,15 @@ 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
#else /* !CONFIG_MMU */
--- a/arch/m68k/include/asm/uaccess_mm.h
+++ b/arch/m68k/include/asm/uaccess_mm.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
*/
@@ -371,4 +374,5 @@ unsigned long __clear_user(void __user *
#define strlen_user(str) strnlen_user(str, 32767)
+#endif /* CONFIG_COLDFIRE */
#endif /* _M68K_UACCESS_H */
--- a/arch/m68k/include/asm/ucontext.h
+++ b/arch/m68k/include/asm/ucontext.h
@@ -7,7 +7,11 @@ typedef greg_t gregset_t[NGREG];
typedef struct fpregset {
int f_fpcntl[3];
+#ifdef __mcoldfire__
+ int f_fpregs[8][2];
+#else
int f_fpregs[8*3];
+#endif
} fpregset_t;
struct mcontext {
--- a/arch/m68k/include/asm/unistd.h
+++ b/arch/m68k/include/asm/unistd.h
@@ -336,10 +336,14 @@
#define __NR_pwritev 330
#define __NR_rt_tgsigqueueinfo 331
#define __NR_perf_counter_open 332
+#define __NR_read_tp 333
+#define __NR_write_tp 334
+#define __NR_atomic_cmpxchg_32 335
+#define __NR_atomic_barrier 336
#ifdef __KERNEL__
-#define NR_syscalls 333
+#define NR_syscalls 337
#define __ARCH_WANT_IPC_PARSE_VERSION
#define __ARCH_WANT_OLD_READDIR
--- a/arch/m68k/include/asm/virtconvert.h
+++ b/arch/m68k/include/asm/virtconvert.h
@@ -1,6 +1,10 @@
#ifndef __VIRT_CONVERT__
#define __VIRT_CONVERT__
+#ifdef CONFIG_COLDFIRE
+#include <asm/cf_virtconvert.h>
+#else
+
/*
* Macros used for converting between virtual and physical mappings.
*/
@@ -46,3 +50,4 @@ static inline void *phys_to_virt(unsigne
#endif
#endif
+#endif
--- a/arch/m68k/Kconfig
+++ b/arch/m68k/Kconfig
@@ -12,6 +12,14 @@ config MMU
bool
default y
+config GENERIC_TIME
+ bool "Enable generic timer"
+ default n
+
+config GENERIC_CLOCKEVENTS
+ bool "Enable generic clockevents"
+ default n
+
config RWSEM_GENERIC_SPINLOCK
bool
default y
@@ -37,7 +45,7 @@ config GENERIC_CALIBRATE_DELAY
config TIME_LOW_RES
bool
- default y
+ default n
config GENERIC_IOMAP
bool
@@ -49,7 +57,7 @@ config ARCH_MAY_HAVE_PC_FDC
default y
config NO_IOPORT
- def_bool y
+ def_bool !(M5445X || M547X_8X)
config NO_DMA
def_bool SUN3
@@ -107,6 +115,35 @@ config PCMCIA
To compile this driver as modules, choose M here: the
modules will be called pcmcia_core and ds.
+config COLDFIRE
+ bool "ColdFire V4e support"
+ default y
+ select CFV4E
+ help
+ Say Y if you want to build a kernel to run on one of the ColdFire
+ V4e boards.
+
+config CFV4E
+ bool
+ depends on COLDFIRE
+ select MMU_CFV4E if MMU
+ default y
+
+config FPU
+ bool "ColdFire V4e FPU support"
+ default n
+ help
+ This enables support for CFV4E FPU feature.
+
+config MCD_DMA
+ bool "ColdFire MCD DMA support"
+ depends on M547X_8X
+ default y
+ help
+ This enables support for the ColdFire 547x/548x family
+ multichannel DMA support. Many drivers need it.
+ If you want it, say Y
+
config AMIGA
bool "Amiga support"
select MMU_MOTOROLA if MMU
@@ -124,6 +161,16 @@ config ATARI
this kernel on an Atari, say Y here and browse the material
available in <file:Documentation/m68k>; otherwise say N.
+config PCI
+ bool "PCI bus support"
+ depends on M54455 || M547X_8X
+ default n
+ help
+ Find out whether you have a PCI motherboard. PCI is the name of a
+ bus system, i.e. the way the CPU talks to the other stuff inside
+ your box. Other bus systems are ISA, EISA, MicroChannel (MCA) or
+ VESA. If you have PCI, say Y, otherwise N.
+
config MAC
bool "Macintosh support"
select MMU_MOTOROLA if MMU
@@ -278,6 +325,118 @@ config M68060
If you anticipate running this kernel on a computer with a MC68060
processor, say Y. Otherwise, say N.
+config M5445X
+ bool "MCF5445x support"
+ depends on COLDFIRE
+ select GENERIC_TIME
+ select USB_EHCI_FSL
+ select HAVE_FSL_USB_DR
+ help
+ This option will add support for the MCF544x processor with mmu.
+
+config M54451
+ bool
+ depends on M5445X
+ default n
+
+config M54455
+ bool
+ depends on M5445X
+ default n
+
+choice
+ prompt "Model"
+ depends on M5445X
+ default M54451EVB
+ config M54451EVB
+ bool "M54451EVB"
+ select M54451
+ config M54455EVB
+ bool "M54455EVB"
+ select M54455
+endchoice
+
+config HAVE_FSL_USB_DR
+ bool
+ default n
+
+config M547X_8X
+ bool "MCF547x/MCF548x support"
+ depends on COLDFIRE
+ help
+ This option will add support for the MCF547x/MCF548x processor with mmu.
+
+config M547X
+ bool
+ depends on M547X_8X
+ default n
+
+config M548X
+ bool
+ depends on M547X_8X
+ default n
+
+choice
+ prompt "Model"
+ depends on M547X_8X
+ default M5485CFE
+
+config M5475AFE
+ bool "MCF5475AFE"
+ select M547X
+config M5475BFE
+ bool "MCF5475BFE"
+ select M547X
+config M5475CFE
+ bool "MCF5475CFE"
+ select M547X
+config M5475DFE
+ bool "MCF5475DFE"
+ select M547X
+config M5475EFE
+ bool "MCF5475EFE"
+ select M547X
+config M5475FFE
+ bool "MCF5475FFE"
+ select M547X
+config M5485AFE
+ bool "MCF5485AFE"
+ select M548X
+config M5485BFE
+ bool "MCF5485BFE"
+ select M548X
+config M5485CFE
+ bool "MCF5485CFE"
+ select M548X
+config M5485DFE
+ bool "MCF5485DFE"
+ select M548X
+config M5485EFE
+ bool "MCF5485EFE"
+ select M548X
+config M5485FFE
+ bool "MCF5485FFE"
+ select M548X
+
+endchoice
+
+
+config MCFCLK
+ int
+ default 240000000 if M54451EVB
+ default 266666666 if M54455EVB
+ default 266000000 if M547X
+ default 200000000 if M548X
+ help
+ Coldfire System clock.
+
+config MCF_USER_HALT
+ bool "Coldfire User Halt Enable"
+ depends on M5445X || M547X_8X
+ default n
+ help
+ Enables the HALT instruction in User Mode.
+
config MMU_MOTOROLA
bool
@@ -285,6 +444,70 @@ config MMU_SUN3
bool
depends on MMU && !MMU_MOTOROLA
+config MMU_CFV4E
+ bool
+
+config SDRAM_BASE
+ hex
+ depends on COLDFIRE
+ default 0x40000000 if M5445X
+ default 0x00000000 if M547X_8X
+
+config SDRAM_SIZE
+ hex
+ depends on COLDFIRE
+ default 0x08000000 if M54451EVB
+ default 0x10000000 if M54455EVB
+ default 0x04000000 if M547X_8X
+
+config NOR_FLASH_BASE
+ hex "NOR Flash Base Address"
+ depends on COLDFIRE
+ default 0x00000000 if M54451EVB
+ default 0x00000000 if M54455EVB
+ default 0xE0000000 if M547X_8X
+
+config DMA_BASE
+ hex
+ depends on COLDFIRE
+ default 0xef000000
+
+config DMA_SIZE
+ hex
+ depends on COLDFIRE
+ default 0x1000000 if M5445X
+ default 0x800000 if M547X_8X
+
+config SRAM
+ bool "SRAM allocation APIs support on mcfv4 platform"
+ depends on COLDFIRE && M5445X
+ default y
+ select GENERIC_ALLOCATOR
+
+config SRAM_BASE
+ hex
+ depends on COLDFIRE && SRAM
+ default 0x8ff00000 if M5445X
+
+config SRAM_SIZE
+ hex
+ depends on COLDFIRE && SRAM
+ default 0x8000 if M5445X
+
+config SRAM_ALLOC_GRANULARITY
+ hex
+ depends on SRAM
+ default 0x200 if M5445X
+
+config VDSO
+ bool "Support VDSO page"
+ depends on MMU
+ default n
+ help
+ This will enable support for the kernel mapping a vDSO page
+ in process space, and subsequently handing down the entry point
+ to the libc through the ELF auxiliary vector.
+
config M68KFPU_EMU
bool "Math emulation support (EXPERIMENTAL)"
depends on EXPERIMENTAL
@@ -451,6 +674,14 @@ config ZONE_DMA
source "drivers/pci/Kconfig"
source "drivers/zorro/Kconfig"
+endmenu
+
+menu "Power management options"
+
+config PM
+ bool "Power Management support"
+ help
+ Support processor power management modes
endmenu
@@ -589,7 +820,7 @@ config DN_SERIAL
config SERIAL_CONSOLE
bool "Support for serial port console"
- depends on (AMIGA || ATARI || MAC || SUN3 || SUN3X || VME || APOLLO) && (ATARI_MFPSER=y || ATARI_MIDI=y || MAC_SCC=y || AMIGA_BUILTIN_SERIAL=y || GVPIOEXT=y || MULTIFACE_III_TTY=y || SERIAL=y || MVME147_SCC || SERIAL167 || MVME162_SCC || BVME6000_SCC || DN_SERIAL)
+ depends on (AMIGA || ATARI || MAC || SUN3 || SUN3X || VME || APOLLO || COLDFIRE) && (ATARI_MFPSER=y || ATARI_MIDI=y || MAC_SCC=y || AMIGA_BUILTIN_SERIAL=y || GVPIOEXT=y || MULTIFACE_III_TTY=y || SERIAL=y || MVME147_SCC || SERIAL167 || MVME162_SCC || BVME6000_SCC || DN_SERIAL || SERIAL_COLDFIRE)
---help---
If you say Y here, it will be possible to use a serial port as the
system console (the system console is the device which receives all
@@ -612,6 +843,8 @@ config SERIAL_CONSOLE
endmenu
+source "kernel/time/Kconfig"
+
source "fs/Kconfig"
source "arch/m68k/Kconfig.debug"
--- a/arch/m68k/kernel/asm-offsets.c
+++ b/arch/m68k/kernel/asm-offsets.c
@@ -2,6 +2,11 @@
* This program is used to generate definitions needed by
* assembly language modules.
*
+ * Copyright Freescale Semiconductor, Inc. 2008-2009
+ * Jason Jin Jason.Jin@freescale.com
+ * Shrek Wu B16972@freescale.com
+ * Add Codlfire support
+ *
* We use the technique used in the OSF Mach kernel code:
* generate asm statements containing #defines,
* compile this file to assembler, and then extract the
@@ -56,8 +61,15 @@ int main(void)
DEFINE(PT_A2, offsetof(struct pt_regs, a2));
DEFINE(PT_PC, offsetof(struct pt_regs, pc));
DEFINE(PT_SR, offsetof(struct pt_regs, sr));
+#ifdef CONFIG_COLDFIRE
+ /* Need to get the context out of struct mm for ASID setting */
+ DEFINE(MM_CONTEXT, offsetof(struct mm_struct, context));
+ /* Coldfire exception frame has vector *before* pc */
+ DEFINE(PT_VECTOR, offsetof(struct pt_regs, pc) - 4);
+#else
/* bitfields are a bit difficult */
DEFINE(PT_VECTOR, offsetof(struct pt_regs, pc) + 4);
+#endif
/* offsets into the irq_handler struct */
DEFINE(IRQ_HANDLER, offsetof(struct irq_node, handler));
--- a/arch/m68k/kernel/dma.c
+++ b/arch/m68k/kernel/dma.c
@@ -1,4 +1,7 @@
/*
+ * Copyright Freescale Semiconductor, Inc. 2008, 2009
+ * Jason Jin Jason.Jin@freescale.com
+ * Shrek Wu B16972@freescale.com
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file COPYING in the main directory of this archive
* for more details.
@@ -11,12 +14,24 @@
#include <linux/kernel.h>
#include <linux/scatterlist.h>
#include <linux/vmalloc.h>
-
+#include <linux/pci.h>
#include <asm/pgalloc.h>
void *dma_alloc_coherent(struct device *dev, size_t size,
dma_addr_t *handle, gfp_t flag)
{
+#if defined(CONFIG_M5445X) | defined(CONFIG_M547X_8X)
+ /*
+ * On the M5445x platform the memory allocated with GFP_DMA
+ * is guaranteed to be DMA'able.
+ */
+ void *addr;
+
+ size = PAGE_ALIGN(size);
+ addr = kmalloc(size, GFP_DMA);
+ *handle = virt_to_phys(addr);
+ return addr;
+#else
struct page *page, **map;
pgprot_t pgprot;
void *addr;
@@ -55,6 +70,7 @@ void *dma_alloc_coherent(struct device *
kfree(map);
return addr;
+#endif
}
EXPORT_SYMBOL(dma_alloc_coherent);
@@ -62,7 +78,11 @@ void dma_free_coherent(struct device *de
void *addr, dma_addr_t handle)
{
pr_debug("dma_free_coherent: %p, %x\n", addr, handle);
+#if defined(CONFIG_M5445X) | defined(CONFIG_M547X_8X)
+ kfree(addr);
+#else
vfree(addr);
+#endif
}
EXPORT_SYMBOL(dma_free_coherent);
@@ -88,9 +108,16 @@ void dma_sync_sg_for_device(struct devic
enum dma_data_direction dir)
{
int i;
+#ifdef CONFIG_COLDFIRE
+ struct scatterlist *_sg;
+ for_each_sg(sg, _sg, nents, i)
+ dma_sync_single_for_device(dev, _sg->dma_address,
+ _sg->length, dir);
+#else
for (i = 0; i < nents; sg++, i++)
dma_sync_single_for_device(dev, sg->dma_address, sg->length, dir);
+#endif
}
EXPORT_SYMBOL(dma_sync_sg_for_device);
@@ -119,10 +146,19 @@ int dma_map_sg(struct device *dev, struc
enum dma_data_direction dir)
{
int i;
-
+#ifdef CONFIG_COLDFIRE
+ struct scatterlist *_sg;
+#endif
+#ifndef CONFIG_COLDFIRE
for (i = 0; i < nents; sg++, i++) {
sg->dma_address = sg_phys(sg);
dma_sync_single_for_device(dev, sg->dma_address, sg->length, dir);
+#else
+ for_each_sg(sg, _sg, nents, i) {
+ _sg->dma_address = sg_phys(_sg);
+ dma_sync_single_for_device(dev, _sg->dma_address,
+ _sg->length, dir);
+#endif
}
return nents;
}
--- a/arch/m68k/kernel/Makefile
+++ b/arch/m68k/kernel/Makefile
@@ -2,16 +2,26 @@
# Makefile for the linux kernel.
#
-ifndef CONFIG_SUN3
- extra-y := head.o
+ifdef CONFIG_SUN3
+ extra-y := sun3-head.o vmlinux.lds
+ obj-y := entry.o signal.o ints.o time.o
else
- extra-y := sun3-head.o
+ifndef CONFIG_COLDFIRE
+ extra-y := head.o vmlinux.lds
+ obj-y := entry.o signal.o traps.o ints.o time.o
+else # CONFIG_COLDFIRE
+ extra-y := vmlinux.lds
+ ifdef CONFIG_M547X_8X
+ obj-$(CONFIG_PCI) += bios32_mcf548x.o
+ endif
+endif
endif
-extra-y += vmlinux.lds
-obj-y := entry.o process.o traps.o ints.o signal.o ptrace.o module.o \
- sys_m68k.o time.o setup.o m68k_ksyms.o devres.o
+obj-y += process.o ptrace.o module.o \
+ sys_m68k.o setup.o m68k_ksyms.o devres.o# semaphore.o
devres-y = ../../../kernel/irq/devres.o
obj-y$(CONFIG_MMU_SUN3) += dma.o # no, it's not a typo
+
+EXTRA_AFLAGS := -traditional
--- a/arch/m68k/kernel/process.c
+++ b/arch/m68k/kernel/process.c
@@ -4,6 +4,11 @@
* Copyright (C) 1995 Hamish Macdonald
*
* 68060 fixes by Jesper Skov
+ *
+ * Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Kurt.Mahan@freescale.com
+ * Jason Jin Jason.Jin@freescale.com
+ * Shrek Wu B16972@freescale.com
*/
/*
@@ -186,12 +191,21 @@ EXPORT_SYMBOL(kernel_thread);
void flush_thread(void)
{
unsigned long zero = 0;
+#if !defined(CONFIG_COLDFIRE)
set_fs(USER_DS);
current->thread.fs = __USER_DS;
if (!FPU_IS_EMU)
asm volatile (".chip 68k/68881\n\t"
"frestore %0@\n\t"
".chip 68k" : : "a" (&zero));
+#else
+ set_fs(USER_DS);
+ current->thread.fs = USER_DS;
+#if defined(CONFIG_FPU)
+ if (!FPU_IS_EMU)
+ asm volatile ("frestore %0@\n\t" : : "a" (&zero));
+#endif
+#endif
}
/*
@@ -251,10 +265,15 @@ int copy_thread(unsigned long clone_flag
p->thread.usp = usp;
p->thread.ksp = (unsigned long)childstack;
+
+ if (clone_flags & CLONE_SETTLS)
+ task_thread_info(p)->tp_value = regs->d5;
+
/*
* Must save the current SFC/DFC value, NOT the value when
* the parent was last descheduled - RGH 10-08-96
*/
+#if !defined(CONFIG_COLDFIRE)
p->thread.fs = get_fs().seg;
if (!FPU_IS_EMU) {
@@ -266,9 +285,34 @@ int copy_thread(unsigned long clone_flag
"fmoveml %/fpiar/%/fpcr/%/fpsr,%1"
: : "m" (p->thread.fp[0]), "m" (p->thread.fpcntl[0])
: "memory");
+#else
+ p->thread.fs = get_fs();
+
+#if defined(CONFIG_FPU)
+ if (!FPU_IS_EMU) {
+ /* Copy the current fpu state */
+ asm volatile ("fsave %0" : : "m" (p->thread.fpstate[0])
+ : "memory");
+
+ if (p->thread.fpstate[0]) {
+ asm volatile ("fmovemd %/fp0-%/fp7,%0"
+ : : "m" (p->thread.fp[0])
+ : "memory");
+ asm volatile ("fmovel %/fpiar,%0"
+ : : "m" (p->thread.fpcntl[0])
+ : "memory");
+ asm volatile ("fmovel %/fpcr,%0"
+ : : "m" (p->thread.fpcntl[1])
+ : "memory");
+ asm volatile ("fmovel %/fpsr,%0"
+ : : "m" (p->thread.fpcntl[2])
+ : "memory");
+ }
/* Restore the state in case the fpu was busy */
asm volatile ("frestore %0" : : "m" (p->thread.fpstate[0]));
}
+#endif
+#endif
return 0;
}
@@ -277,7 +321,9 @@ int copy_thread(unsigned long clone_flag
int dump_fpu (struct pt_regs *regs, struct user_m68kfp_struct *fpu)
{
+#if !defined(CONFIG_COLDFIRE) || defined(CONFIG_FPU)
char fpustate[216];
+#endif
if (FPU_IS_EMU) {
int i;
@@ -294,6 +340,7 @@ int dump_fpu (struct pt_regs *regs, stru
}
/* First dump the fpu context to avoid protocol violation. */
+#if !defined(CONFIG_COLDFIRE)
asm volatile ("fsave %0" :: "m" (fpustate[0]) : "memory");
if (!CPU_IS_060 ? !fpustate[0] : !fpustate[2])
return 0;
@@ -304,6 +351,25 @@ int dump_fpu (struct pt_regs *regs, stru
asm volatile ("fmovemx %/fp0-%/fp7,%0"
:: "m" (fpu->fpregs[0])
: "memory");
+#elif defined(CONFIG_FPU)
+ asm volatile ("fsave %0" :: "m" (fpustate[0]) : "memory");
+ if (!CPU_IS_060 ? !fpustate[0] : !fpustate[2])
+ return 0;
+
+ asm volatile ("fmovel %/fpiar,%0"
+ : : "m" (fpu->fpcntl[0])
+ : "memory");
+ asm volatile ("fmovel %/fpcr,%0"
+ : : "m" (fpu->fpcntl[1])
+ : "memory");
+ asm volatile ("fmovel %/fpsr,%0"
+ : : "m" (fpu->fpcntl[2])
+ : "memory");
+ asm volatile ("fmovemd %/fp0-%/fp7,%0"
+ : : "m" (fpu->fpregs[0])
+ : "memory");
+#endif
+
return 1;
}
EXPORT_SYMBOL(dump_fpu);
--- a/arch/m68k/kernel/ptrace.c
+++ b/arch/m68k/kernel/ptrace.c
@@ -265,6 +265,11 @@ long arch_ptrace(struct task_struct *chi
ret = -EFAULT;
break;
+ case PTRACE_GET_THREAD_AREA:
+ ret = put_user(task_thread_info(child)->tp_value,
+ (unsigned long __user *) data);
+ break;
+
default:
ret = ptrace_request(child, request, addr, data);
break;
--- a/arch/m68k/kernel/setup.c
+++ b/arch/m68k/kernel/setup.c
@@ -2,6 +2,9 @@
* linux/arch/m68k/kernel/setup.c
*
* Copyright (C) 1995 Hamish Macdonald
+ * Copyright Freescale Semiconductor, Inc. 2008, 2009
+ * Jason Jin Jason.Jin@freescale.com
+ * Shrek Wu B16972@freescale.com
*/
/*
@@ -75,13 +78,24 @@ EXPORT_SYMBOL(m68k_memory);
struct mem_info m68k_ramdisk;
+#if !defined(CONFIG_COLDFIRE)
static char m68k_command_line[CL_SIZE];
+#else
+char m68k_command_line[CL_SIZE];
+unsigned long uboot_info_stk;
+EXPORT_SYMBOL(uboot_info_stk);
+#endif
void (*mach_sched_init) (irq_handler_t handler) __initdata = NULL;
/* machine dependent irq functions */
void (*mach_init_IRQ) (void) __initdata = NULL;
void (*mach_get_model) (char *model);
void (*mach_get_hardware_list) (struct seq_file *m);
+
+#ifdef CONFIG_COLDFIRE
+void (*mach_tick)(void);
+#endif
+
/* machine dependent timer functions */
unsigned long (*mach_gettimeoffset) (void);
int (*mach_hwclk) (int, struct rtc_time*);
@@ -137,13 +151,17 @@ extern void config_hp300(void);
extern void config_q40(void);
extern void config_sun3x(void);
+#ifdef CONFIG_COLDFIRE
+void coldfire_sort_memrec(void);
+#endif
+
#define MASK_256K 0xfffc0000
extern void paging_init(void);
static void __init m68k_parse_bootinfo(const struct bi_record *record)
{
- while (record->tag != BI_LAST) {
+ while ((record->tag != BI_LAST)) {
int unknown = 0;
const unsigned long *data = record->data;
@@ -203,6 +221,10 @@ static void __init m68k_parse_bootinfo(c
record->size);
}
+#ifdef CONFIG_COLDFIRE
+ coldfire_sort_memrec();
+#endif
+
m68k_realnum_memory = m68k_num_memory;
#ifdef CONFIG_SINGLE_MEMORY_CHUNK
if (m68k_num_memory > 1) {
@@ -215,8 +237,11 @@ static void __init m68k_parse_bootinfo(c
void __init setup_arch(char **cmdline_p)
{
- int i;
+#if !defined(CONFIG_SUN3)
+ int i;
+#endif
+
/* The bootinfo is located right after the kernel bss */
m68k_parse_bootinfo((const struct bi_record *)_end);
@@ -230,9 +255,10 @@ void __init setup_arch(char **cmdline_p)
* We should really do our own FPU check at startup.
* [what do we do with buggy 68LC040s? if we have problems
* with them, we should add a test to check_bugs() below] */
-#ifndef CONFIG_M68KFPU_EMU_ONLY
+#if !defined(CONFIG_M68KFPU_EMU_ONLY) && defined(CONFIG_FPU)
/* clear the fpu if we have one */
- if (m68k_fputype & (FPU_68881|FPU_68882|FPU_68040|FPU_68060)) {
+ if (m68k_fputype & (FPU_68881|FPU_68882|FPU_68040|FPU_68060|
+ FPU_CFV4E)) {
volatile int zero = 0;
asm volatile ("frestore %0" : : "m" (zero));
}
@@ -320,13 +346,18 @@ void __init setup_arch(char **cmdline_p)
config_sun3x();
break;
#endif
+#ifdef CONFIG_COLDFIRE
+ case MACH_CFMMU:
+ config_coldfire();
+ break;
+#endif
default:
panic("No configuration setup");
}
paging_init();
-#ifndef CONFIG_SUN3
+#if !defined(CONFIG_SUN3)
for (i = 1; i < m68k_num_memory; i++)
free_bootmem_node(NODE_DATA(i), m68k_memory[i].addr,
m68k_memory[i].size);
@@ -353,6 +384,10 @@ void __init setup_arch(char **cmdline_p)
#endif /* !CONFIG_SUN3 */
+#ifdef CONFIG_COLDFIRE
+ mmu_context_init();
+#endif
+
/* set ISA defs early as possible */
#if defined(CONFIG_ISA) && defined(MULTI_ISA)
if (MACH_IS_Q40) {
@@ -383,6 +418,7 @@ static int show_cpuinfo(struct seq_file
#define LOOP_CYCLES_68030 (8)
#define LOOP_CYCLES_68040 (3)
#define LOOP_CYCLES_68060 (1)
+#define LOOP_CYCLES_COLDFIRE (2)
if (CPU_IS_020) {
cpu = "68020";
@@ -396,6 +432,9 @@ static int show_cpuinfo(struct seq_file
} else if (CPU_IS_060) {
cpu = "68060";
clockfactor = LOOP_CYCLES_68060;
+ } else if (CPU_IS_CFV4E) {
+ cpu = "ColdFire V4e";
+ clockfactor = LOOP_CYCLES_COLDFIRE;
} else {
cpu = "680x0";
clockfactor = 0;
@@ -414,6 +453,8 @@ static int show_cpuinfo(struct seq_file
fpu = "68060";
else if (m68k_fputype & FPU_SUNFPA)
fpu = "Sun FPA";
+ else if (m68k_fputype & FPU_CFV4E)
+ fpu = "ColdFire V4e";
else
fpu = "none";
#endif
@@ -430,6 +471,8 @@ static int show_cpuinfo(struct seq_file
mmu = "Sun-3";
else if (m68k_mmutype & MMU_APOLLO)
mmu = "Apollo";
+ else if (m68k_mmutype & MMU_CFV4E)
+ mmu = "ColdFire";
else
mmu = "unknown";
@@ -512,7 +555,7 @@ module_init(proc_hardware_init);
void check_bugs(void)
{
-#ifndef CONFIG_M68KFPU_EMU
+#if !defined(CONFIG_M68KFPU_EMU) && !defined(CONFIG_M5445X)
if (m68k_fputype == 0) {
printk(KERN_EMERG "*** YOU DO NOT HAVE A FLOATING POINT UNIT, "
"WHICH IS REQUIRED BY LINUX/M68K ***\n");
--- a/arch/m68k/kernel/sys_m68k.c
+++ b/arch/m68k/kernel/sys_m68k.c
@@ -1,5 +1,8 @@
/*
* linux/arch/m68k/kernel/sys_m68k.c
+ * Copyright Freescale Semiconductor, Inc. 2008-2009
+ * Jason Jin Jason.Jin@freescale.com
+ * Shrek Wu B16972@freescale.com
*
* This file contains various random system calls that
* have a non-standard calling sequence on the Linux/m68k
@@ -29,6 +32,14 @@
#include <asm/traps.h>
#include <asm/page.h>
#include <asm/unistd.h>
+#include <linux/elf.h>
+#include <asm/tlb.h>
+#ifdef CONFIG_COLDFIRE
+#include <asm/cacheflush.h>
+#endif
+
+asmlinkage int do_page_fault(struct pt_regs *regs, unsigned long address,
+ unsigned long error_code);
/* common code for old and new mmaps */
static inline long do_mmap2(
@@ -240,6 +251,7 @@ asmlinkage int sys_ipc (uint call, int f
return -EINVAL;
}
+#ifndef CONFIG_COLDFIRE
/* Convert virtual (user) address VADDR to physical address PADDR */
#define virt_to_phys_040(vaddr) \
({ \
@@ -563,6 +575,7 @@ cache_flush_060 (unsigned long addr, int
}
return 0;
}
+#endif /* CONFIG_COLDFIRE */
/* sys_cacheflush -- flush (part of) the processor cache. */
asmlinkage int
@@ -595,6 +608,7 @@ sys_cacheflush (unsigned long addr, int
goto out;
}
+#ifndef CONFIG_COLDFIRE
if (CPU_IS_020_OR_030) {
if (scope == FLUSH_SCOPE_LINE && len < 256) {
unsigned long cacr;
@@ -639,6 +653,16 @@ sys_cacheflush (unsigned long addr, int
ret = cache_flush_060 (addr, scope, cache, len);
}
}
+#else /* CONFIG_COLDFIRE */
+ if ((cache & FLUSH_CACHE_INSN) && (cache & FLUSH_CACHE_DATA))
+ flush_bcache();
+ else if (cache & FLUSH_CACHE_INSN)
+ flush_icache();
+ else
+ flush_dcache();
+
+ ret = 0;
+#endif /* CONFIG_COLDFIRE */
out:
unlock_kernel();
return ret;
@@ -663,3 +687,79 @@ int kernel_execve(const char *filename,
: "d" (__a), "d" (__b), "d" (__c));
return __res;
}
+
+asmlinkage unsigned long
+sys_read_tp(void)
+{
+ return current_thread_info()->tp_value;
+}
+
+asmlinkage int
+sys_write_tp(unsigned long tp)
+{
+ current_thread_info()->tp_value = tp;
+ return 0;
+}
+
+/* This syscall gets its arguments in A0 (mem), D2 (oldval) and
+ D1 (newval). */
+asmlinkage int
+sys_atomic_cmpxchg_32(unsigned long newval, int oldval, int d3, int d4, int d5,
+ unsigned long __user *mem)
+{
+ /* This was borrowed from ARM's implementation. */
+ for (;;) {
+ struct mm_struct *mm = current->mm;
+ pgd_t *pgd; pmd_t *pmd; pte_t *pte;
+ spinlock_t *ptl;
+ unsigned long mem_value;
+
+ down_read(&mm->mmap_sem);
+ pgd = pgd_offset(mm, (unsigned long)mem);
+ if (!pgd_present(*pgd))
+ goto bad_access;
+ pmd = pmd_offset(pgd, (unsigned long)mem);
+ if (!pmd_present(*pmd))
+ goto bad_access;
+ pte = pte_offset_map_lock(mm, pmd, (unsigned long)mem, &ptl);
+ if (!pte_present(*pte) || !pte_dirty(*pte)) {
+ pte_unmap_unlock(pte, ptl);
+ goto bad_access;
+ }
+
+ mem_value = *mem;
+ if (mem_value == oldval)
+ *mem = newval;
+
+ pte_unmap_unlock(pte, ptl);
+ up_read(&mm->mmap_sem);
+ return mem_value;
+
+bad_access:
+ up_read(&mm->mmap_sem);
+ /* This is not necessarily a bad access, we can get here if
+ a memory we're trying to write to should be copied-on-write.
+ Make the kernel do the necessary page stuff, then re-iterate.
+ Simulate a write access fault to do that. */
+ {
+ /* The first argument of the function corresponds to
+ D1, which is the first field of struct pt_regs. */
+ struct pt_regs *fp = (struct pt_regs *)&newval;
+
+ /* '3' is an RMW flag. */
+ if (do_page_fault(fp, (unsigned long)mem, 3))
+ /* If the do_page_fault() failed, we don't
+ have anything meaningful to return.
+ There should be a SIGSEGV pending for
+ the process. */
+ return 0xdeadbeef;
+ }
+ }
+}
+
+asmlinkage int
+sys_atomic_barrier(void)
+{
+ /* no code needed for uniprocs */
+ return 0;
+}
--- a/arch/m68k/kernel/time.c
+++ b/arch/m68k/kernel/time.c
@@ -2,6 +2,9 @@
* linux/arch/m68k/kernel/time.c
*
* Copyright (C) 1991, 1992, 1995 Linus Torvalds
+ * Copyright Freescale Semiconductor, Inc. 2008-2009
+ * Jason Jin Jason.Jin@freescale.com
+ * Shrek Wu B16972@freescale.com
*
* This file contains the m68k-specific time handling details.
* Most of the stuff is located in the machine specific files.
@@ -41,6 +44,11 @@ static inline int set_rtc_mmss(unsigned
*/
static irqreturn_t timer_interrupt(int irq, void *dummy)
{
+#ifdef CONFIG_COLDFIRE
+ /* kick hardware timer if necessary */
+ if (mach_tick)
+ mach_tick();
+#endif
do_timer(1);
#ifndef CONFIG_SMP
update_process_times(user_mode(get_irq_regs()));
--- a/arch/m68k/kernel/vmlinux.lds.S
+++ b/arch/m68k/kernel/vmlinux.lds.S
@@ -1,10 +1,13 @@
PHDRS
{
- text PT_LOAD FILEHDR PHDRS FLAGS (7);
+ headers PT_PHDR PHDRS ;
+ text PT_LOAD FILEHDR PHDRS FLAGS (5);
data PT_LOAD FLAGS (7);
}
#ifdef CONFIG_SUN3
#include "vmlinux-sun3.lds"
+#elif CONFIG_COLDFIRE
+#include "vmlinux-cf.lds"
#else
#include "vmlinux-std.lds"
#endif
--- a/arch/m68k/lib/checksum.c
+++ b/arch/m68k/lib/checksum.c
@@ -30,6 +30,10 @@
* 1998/8/31 Andreas Schwab:
* Zero out rest of buffer on exception in
* csum_partial_copy_from_user.
+ *
+ * Copyright Freescale Semiconductor, Inc. 2008-2009
+ * Jason Jin Jason.Jin@freescale.com
+ * Shrek Wu B16972@freescale.com
*/
#include <linux/module.h>
@@ -39,8 +43,131 @@
* computes a partial checksum, e.g. for TCP/UDP fragments
*/
+#ifdef CONFIG_COLDFIRE
+
+static inline unsigned short from32to16(unsigned long x)
+{
+ /* add up 16-bit and 16-bit for 16+c bit */
+ x = (x & 0xffff) + (x >> 16);
+ /* add up carry.. */
+ x = (x & 0xffff) + (x >> 16);
+ return x;
+}
+
+static unsigned long do_csum(const unsigned char *buff, int len)
+{
+ int odd, count;
+ unsigned long result = 0;
+
+ if (len <= 0)
+ goto out;
+ odd = 1 & (unsigned long) buff;
+ if (odd) {
+ result = *buff;
+ len--;
+ buff++;
+ }
+ count = len >> 1; /* nr of 16-bit words.. */
+ if (count) {
+ if (2 & (unsigned long) buff) {
+ result += *(unsigned short *) buff;
+ count--;
+ len -= 2;
+ buff += 2;
+ }
+ count >>= 1; /* nr of 32-bit words.. */
+ if (count) {
+ unsigned long carry = 0;
+ do {
+ unsigned long w = *(unsigned long *) buff;
+ count--;
+ buff += 4;
+ result += carry;
+ result += w;
+ carry = (w > result);
+ } while (count);
+ result += carry;
+ result = (result & 0xffff) + (result >> 16);
+ }
+ if (len & 2) {
+ result += *(unsigned short *) buff;
+ buff += 2;
+ }
+ }
+ if (len & 1)
+ result += (*buff << 8);
+ result = from32to16(result);
+ if (odd)
+ result = ((result >> 8) & 0xff) | ((result & 0xff) << 8);
+out:
+ return result;
+}
+
+/*
+ * This is a version of ip_compute_csum() optimized for IP headers,
+ * which always checksum on 4 octet boundaries.
+ */
+__sum16 ip_fast_csum(const void *iph, unsigned int ihl)
+{
+ return ~do_csum(iph, ihl*4);
+}
+EXPORT_SYMBOL(ip_fast_csum);
+
+/*
+ * 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
+ */
__wsum csum_partial(const void *buff, int len, __wsum sum)
{
+ unsigned int result = do_csum(buff, len);
+
+ /* add in old sum, and carry.. */
+ result += sum;
+ if (sum > result)
+ result += 1;
+ return result;
+}
+EXPORT_SYMBOL(csum_partial);
+
+/*
+ * copy from fs while checksumming, otherwise like csum_partial
+ */
+
+__wsum
+csum_partial_copy_from_user(const void __user *src, void *dst, int len,
+ __wsum sum, int *csum_err)
+{
+ if (csum_err) *csum_err = 0;
+ memcpy(dst, src, len);
+ return csum_partial(dst, len, sum);
+}
+EXPORT_SYMBOL(csum_partial_copy_from_user);
+
+/*
+ * copy from ds while checksumming, otherwise like csum_partial
+ */
+
+__wsum
+csum_partial_copy_nocheck(const void *src, void *dst, int len, __wsum sum)
+{
+ memcpy(dst, src, len);
+ return csum_partial(dst, len, sum);
+}
+EXPORT_SYMBOL(csum_partial_copy_nocheck);
+
+#else /* !CONFIG_COLDFIRE */
+
+unsigned int
+csum_partial(const unsigned char *buff, int len, unsigned int sum)
+{
unsigned long tmp1, tmp2;
/*
* Experiments with ethernet and slip connections show that buff
@@ -423,3 +550,4 @@ csum_partial_copy_nocheck(const void *sr
return(sum);
}
EXPORT_SYMBOL(csum_partial_copy_nocheck);
+#endif /* CONFIG_COLDFIRE */
--- a/arch/m68k/lib/muldi3.c
+++ b/arch/m68k/lib/muldi3.c
@@ -1,6 +1,9 @@
/* muldi3.c extracted from gcc-2.7.2.3/libgcc2.c and
gcc-2.7.2.3/longlong.h which is: */
/* Copyright (C) 1989, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
+ Copyright Freescale Semiconductor, Inc. 2008-2009
+ Jason Jin Jason.Jin@freescale.com
+ Shrek Wu B16972@freescale.com
This file is part of GNU CC.
@@ -21,12 +24,22 @@ Boston, MA 02111-1307, USA. */
#define BITS_PER_UNIT 8
+#ifdef CONFIG_COLDFIRE
+#define umul_ppmm(w1, w0, u, v) \
+ do { \
+ unsigned long long x; \
+ x = (unsigned long long)u * v; \
+ w0 = (unsigned long)(x & 0x00000000ffffffff); \
+ w1 = (unsigned long)(x & 0xffffffff00000000) >> 32; \
+ } while (0)
+#else /* CONFIG_COLDFIRE */
#define umul_ppmm(w1, w0, u, v) \
__asm__ ("mulu%.l %3,%1:%0" \
: "=d" ((USItype)(w0)), \
"=d" ((USItype)(w1)) \
: "%0" ((USItype)(u)), \
"dmi" ((USItype)(v)))
+#endif /* CONFIG_COLDFIRE */
#define __umulsidi3(u, v) \
({DIunion __w; \
--- a/arch/m68k/lib/string.c
+++ b/arch/m68k/lib/string.c
@@ -1,4 +1,8 @@
/*
+ * Copyright Freescale Semiconductor, Inc. 2008-2009
+ * * Jason Jin Jason.Jin@freescale.com
+ * Shrek Wu B16972@freescale.com
+ *
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file COPYING in the main directory of this archive
* for more details.
@@ -21,6 +25,7 @@ char *strcat(char *dest, const char *src
}
EXPORT_SYMBOL(strcat);
+#ifndef CONFIG_COLDFIRE
void *memset(void *s, int c, size_t count)
{
void *xs = s;
@@ -149,6 +154,69 @@ void *memcpy(void *to, const void *from,
}
EXPORT_SYMBOL(memcpy);
+#else /* CONFIG_COLDFIRE */
+
+void *memset(void *s, int c, size_t count)
+{
+ unsigned long x;
+ void *originalTo = s;
+
+ for (x = 0; x < count; x++)
+ *(unsigned char *)s++ = (unsigned char)c;
+
+ return originalTo;
+}
+EXPORT_SYMBOL(memset);
+
+void *memcpy(void *to, const void *from, size_t n)
+{
+ void *xto = to;
+ size_t temp;
+
+ if (!n)
+ return xto;
+ if ((long) to & 1) {
+ char *cto = to;
+ const char *cfrom = from;
+ *cto++ = *cfrom++;
+ to = cto;
+ from = cfrom;
+ n--;
+ }
+ if (n > 2 && (long) to & 2) {
+ short *sto = to;
+ const short *sfrom = from;
+ *sto++ = *sfrom++;
+ to = sto;
+ from = sfrom;
+ n -= 2;
+ }
+ temp = n >> 2;
+ if (temp) {
+ long *lto = to;
+ const long *lfrom = from;
+ for (; temp; temp--)
+ *lto++ = *lfrom++;
+ to = lto;
+ from = lfrom;
+ }
+ if (n & 2) {
+ short *sto = to;
+ const short *sfrom = from;
+ *sto++ = *sfrom++;
+ to = sto;
+ from = sfrom;
+ }
+ if (n & 1) {
+ char *cto = to;
+ const char *cfrom = from;
+ *cto = *cfrom;
+ }
+ return xto;
+}
+EXPORT_SYMBOL(memcpy);
+#endif /* CONFIG_COLDFIRE */
+
void *memmove(void *dest, const void *src, size_t n)
{
void *xdest = dest;
--- a/arch/m68k/lib/uaccess.c
+++ b/arch/m68k/lib/uaccess.c
@@ -1,10 +1,15 @@
/*
+ * Copyright Freescale Semiconductor, Inc. 2008-2009
+ * Jason Jin Jason.Jin@freescale.com
+ * Shrek Wu B16972@freescale.com
+ *
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file COPYING in the main directory of this archive
* for more details.
*/
#include <linux/module.h>
+#ifndef CONFIG_COLDFIRE
#include <asm/uaccess.h>
unsigned long __generic_copy_from_user(void *to, const void __user *from,
@@ -220,3 +225,244 @@ unsigned long __clear_user(void __user *
return res;
}
EXPORT_SYMBOL(__clear_user);
+
+#else /* CONFIG_COLDFIRE */
+
+#include <asm/cf_uaccess.h>
+
+unsigned long __generic_copy_from_user(void *to, const void *from,
+ unsigned long n)
+{
+ unsigned long tmp;
+ __asm__ __volatile__
+ (" tstl %2\n"
+ " jeq 2f\n"
+ "1: movel (%1)+,%3\n"
+ " movel %3,(%0)+\n"
+ " subql #1,%2\n"
+ " jne 1b\n"
+ "2: movel %4,%2\n"
+ " bclr #1,%2\n"
+ " jeq 4f\n"
+ "3: movew (%1)+,%3\n"
+ " movew %3,(%0)+\n"
+ "4: bclr #0,%2\n"
+ " jeq 6f\n"
+ "5: moveb (%1)+,%3\n"
+ " moveb %3,(%0)+\n"
+ "6:\n"
+ ".section .fixup,\"ax\"\n"
+ " .even\n"
+ "7: movel %2,%%d0\n"
+ "71:clrl (%0)+\n"
+ " subql #1,%%d0\n"
+ " jne 71b\n"
+ " lsll #2,%2\n"
+ " addl %4,%2\n"
+ " btst #1,%4\n"
+ " jne 81f\n"
+ " btst #0,%4\n"
+ " jne 91f\n"
+ " jra 6b\n"
+ "8: addql #2,%2\n"
+ "81:clrw (%0)+\n"
+ " btst #0,%4\n"
+ " jne 91f\n"
+ " jra 6b\n"
+ "9: addql #1,%2\n"
+ "91:clrb (%0)+\n"
+ " jra 6b\n"
+ ".previous\n"
+ ".section __ex_table,\"a\"\n"
+ " .align 4\n"
+ " .long 1b,7b\n"
+ " .long 3b,8b\n"
+ " .long 5b,9b\n"
+ ".previous"
+ : "=a"(to), "=a"(from), "=d"(n), "=&d"(tmp)
+ : "d"(n & 3), "0"(to), "1"(from), "2"(n/4)
+ : "d0", "memory");
+ return n;
+}
+EXPORT_SYMBOL(__generic_copy_from_user);
+
+
+unsigned long __generic_copy_to_user(void *to, const void *from,
+ unsigned long n)
+{
+ unsigned long tmp;
+ __asm__ __volatile__
+ (" tstl %2\n"
+ " jeq 3f\n"
+ "1: movel (%1)+,%3\n"
+ "22:movel %3,(%0)+\n"
+ "2: subql #1,%2\n"
+ " jne 1b\n"
+ "3: movel %4,%2\n"
+ " bclr #1,%2\n"
+ " jeq 4f\n"
+ " movew (%1)+,%3\n"
+ "24:movew %3,(%0)+\n"
+ "4: bclr #0,%2\n"
+ " jeq 5f\n"
+ " moveb (%1)+,%3\n"
+ "25:moveb %3,(%0)+\n"
+ "5:\n"
+ ".section .fixup,\"ax\"\n"
+ " .even\n"
+ "60:addql #1,%2\n"
+ "6: lsll #2,%2\n"
+ " addl %4,%2\n"
+ " jra 5b\n"
+ "7: addql #2,%2\n"
+ " jra 5b\n"
+ "8: addql #1,%2\n"
+ " jra 5b\n"
+ ".previous\n"
+ ".section __ex_table,\"a\"\n"
+ " .align 4\n"
+ " .long 1b,60b\n"
+ " .long 22b,6b\n"
+ " .long 2b,6b\n"
+ " .long 24b,7b\n"
+ " .long 3b,60b\n"
+ " .long 4b,7b\n"
+ " .long 25b,8b\n"
+ " .long 5b,8b\n"
+ ".previous"
+ : "=a"(to), "=a"(from), "=d"(n), "=&d"(tmp)
+ : "r"(n & 3), "0"(to), "1"(from), "2"(n / 4)
+ : "memory");
+ return n;
+}
+EXPORT_SYMBOL(__generic_copy_to_user);
+
+/*
+ * Copy a null terminated string from userspace.
+ */
+
+long strncpy_from_user(char *dst, const char *src, long count)
+{
+ long res = -EFAULT;
+ if (!(access_ok(VERIFY_READ, src, 1))) /* --tym-- */
+ return res;
+ if (count == 0) return count;
+ __asm__ __volatile__
+ ("1: moveb (%2)+,%%d0\n"
+ "12:moveb %%d0,(%1)+\n"
+ " jeq 2f\n"
+ " subql #1,%3\n"
+ " jne 1b\n"
+ "2: subl %3,%0\n"
+ "3:\n"
+ ".section .fixup,\"ax\"\n"
+ " .even\n"
+ "4: movel %4,%0\n"
+ " jra 3b\n"
+ ".previous\n"
+ ".section __ex_table,\"a\"\n"
+ " .align 4\n"
+ " .long 1b,4b\n"
+ " .long 12b,4b\n"
+ ".previous"
+ : "=d"(res), "=a"(dst), "=a"(src), "=d"(count)
+ : "i"(-EFAULT), "0"(count), "1"(dst), "2"(src), "3"(count)
+ : "d0", "memory");
+ return res;
+}
+EXPORT_SYMBOL(strncpy_from_user);
+
+/*
+ * Return the size of a string (including the ending 0)
+ *
+ * Return 0 on exception, a value greater than N if too long
+ */
+long strnlen_user(const char *src, long n)
+{
+ long res = -EFAULT;
+ if (!(access_ok(VERIFY_READ, src, 1))) /* --tym-- */
+ return res;
+
+ res = -(long)src;
+ __asm__ __volatile__
+ ("1:\n"
+ " tstl %2\n"
+ " jeq 3f\n"
+ "2: moveb (%1)+,%%d0\n"
+ "22:\n"
+ " subql #1,%2\n"
+ " tstb %%d0\n"
+ " jne 1b\n"
+ " jra 4f\n"
+ "3:\n"
+ " addql #1,%0\n"
+ "4:\n"
+ " addl %1,%0\n"
+ "5:\n"
+ ".section .fixup,\"ax\"\n"
+ " .even\n"
+ "6: moveq %3,%0\n"
+ " jra 5b\n"
+ ".previous\n"
+ ".section __ex_table,\"a\"\n"
+ " .align 4\n"
+ " .long 2b,6b\n"
+ " .long 22b,6b\n"
+ ".previous"
+ : "=d"(res), "=a"(src), "=d"(n)
+ : "i"(0), "0"(res), "1"(src), "2"(n)
+ : "d0");
+ return res;
+}
+EXPORT_SYMBOL(strnlen_user);
+
+
+/*
+ * Zero Userspace
+ */
+
+unsigned long __clear_user(void *to, unsigned long n)
+{
+ __asm__ __volatile__
+ (" tstl %1\n"
+ " jeq 3f\n"
+ "1: movel %3,(%0)+\n"
+ "2: subql #1,%1\n"
+ " jne 1b\n"
+ "3: movel %2,%1\n"
+ " bclr #1,%1\n"
+ " jeq 4f\n"
+ "24:movew %3,(%0)+\n"
+ "4: bclr #0,%1\n"
+ " jeq 5f\n"
+ "25:moveb %3,(%0)+\n"
+ "5:\n"
+ ".section .fixup,\"ax\"\n"
+ " .even\n"
+ "61:addql #1,%1\n"
+ "6: lsll #2,%1\n"
+ " addl %2,%1\n"
+ " jra 5b\n"
+ "7: addql #2,%1\n"
+ " jra 5b\n"
+ "8: addql #1,%1\n"
+ " jra 5b\n"
+ ".previous\n"
+ ".section __ex_table,\"a\"\n"
+ " .align 4\n"
+ " .long 1b,61b\n"
+ " .long 2b,6b\n"
+ " .long 3b,61b\n"
+ " .long 24b,7b\n"
+ " .long 4b,7b\n"
+ " .long 25b,8b\n"
+ " .long 5b,8b\n"
+ ".previous"
+ : "=a"(to), "=d"(n)
+ : "r"(n & 3), "d"(0), "0"(to), "1"(n/4));
+ return n;
+}
+EXPORT_SYMBOL(__clear_user);
+
+#endif /* CONFIG_COLDFIRE */
+
--- a/arch/m68k/Makefile
+++ b/arch/m68k/Makefile
@@ -1,6 +1,8 @@
#
# m68k/Makefile
#
+# Copyright 2007-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+#
# This file is included by the global makefile so that you can add your own
# architecture-specific flags and dependencies. Remember to do have actions
# for "archclean" and "archdep" for cleaning up and making dependencies for
@@ -10,13 +12,13 @@
# License. See the file "COPYING" in the main directory of this archive
# for more details.
#
-# Copyright (C) 1994 by Hamish Macdonald
-#
-KBUILD_DEFCONFIG := multi_defconfig
+KBUILD_DEFCONFIG := amiga_defconfig#multi_defconfig
# override top level makefile
+ifndef CONFIG_COLDFIRE
AS += -m68020
+endif
LDFLAGS := -m m68kelf
LDFLAGS_MODULE += -T $(srctree)/arch/m68k/kernel/module.lds
ifneq ($(SUBARCH),$(ARCH))
@@ -30,12 +32,18 @@ ifdef CONFIG_SUN3
LDFLAGS_vmlinux = -N
endif
+ifdef CONFIG_COLDFIRE
+OBJCOPYFLAGS := -O binary -R .note -R .note.gnu.build-id -R .comment -S
+# LDFLAGS_vmlinux = --verbose
+endif
+
CHECKFLAGS += -D__mc68000__
# without -fno-strength-reduce the 53c7xx.c driver fails ;-(
KBUILD_CFLAGS += -pipe -fno-strength-reduce -ffixed-a2
# enable processor switch if compiled only for a single cpu
+ifndef CONFIG_COLDFIRE
ifndef CONFIG_M68020
ifndef CONFIG_M68030
@@ -49,6 +57,17 @@ endif
endif
endif
+endif
+
+ifdef CONFIG_M5445X
+KBUILD_CFLAGS += -march=isac -mcpu=54455 -msoft-float -g
+KBUILD_AFLAGS += -march=isac -mcpu=54455 -msoft-float
+endif
+
+ifdef CONFIG_M547X_8X
+KBUILD_CFLAGS += -mcfv4e -g
+KBUILD_AFLAGS += -mcfv4e
+endif
ifdef CONFIG_KGDB
# If configured for kgdb support, include debugging infos and keep the
@@ -57,8 +76,12 @@ KBUILD_CFLAGS := $(subst -fomit-frame-po
endif
ifndef CONFIG_SUN3
+ifndef CONFIG_COLDFIRE
head-y := arch/m68k/kernel/head.o
else
+head-y := arch/m68k/coldfire/common/head.o
+endif
+else
head-y := arch/m68k/kernel/sun3-head.o
endif
@@ -79,7 +102,20 @@ core-$(CONFIG_SUN3) += arch/m68k/sun3/
core-$(CONFIG_M68040) += arch/m68k/fpsp040/
core-$(CONFIG_M68060) += arch/m68k/ifpsp060/
core-$(CONFIG_M68KFPU_EMU) += arch/m68k/math-emu/
+core-$(CONFIG_COLDFIRE) += arch/m68k/coldfire/
+
+ifdef CONFIG_COLDFIRE
+boot := arch/m68k/boot
+
+all: uImage
+
+zImage zImage.srec uImage uImage.srec vmlinux.srec: vmlinux
+ $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
+archclean:
+ $(Q)$(MAKE) $(clean)=$(boot)
+
+else
all: zImage
lilo: vmlinux
@@ -117,6 +153,7 @@ endif
archclean:
rm -f vmlinux.gz vmlinux.bz2
+endif
install:
sh $(srctree)/arch/m68k/install.sh $(KERNELRELEASE) vmlinux.gz System.map "$(INSTALL_PATH)"
--- a/arch/m68k/mm/cache.c
+++ b/arch/m68k/mm/cache.c
@@ -4,13 +4,20 @@
* Instruction cache handling
*
* Copyright (C) 1995 Hamish Macdonald
+ * Copyright Freescale Semiconductor, Inc. 2008-2009
+ * Jason Jin Jason.Jin@freescale.com
+ * Shrek Wu B16972@freescale.com
*/
#include <linux/module.h>
#include <asm/pgalloc.h>
#include <asm/traps.h>
+#ifdef CONFIG_COLDFIRE
+#include <asm/cfcache.h>
+#endif /* CONFIG_COLDFIRE */
+#ifndef CONFIG_COLDFIRE
static unsigned long virt_to_phys_slow(unsigned long vaddr)
{
if (CPU_IS_060) {
@@ -69,11 +76,18 @@ static unsigned long virt_to_phys_slow(u
}
return 0;
}
+#endif /* CONFIG_COLDFIRE */
+
/* Push n pages at kernel virtual address and clear the icache */
/* RZ: use cpush %bc instead of cpush %dc, cinv %ic */
void flush_icache_range(unsigned long address, unsigned long endaddr)
{
+#ifdef CONFIG_COLDFIRE
+// JKM -- hack until new cpushl stuff is in
+// cf_icache_flush_range(address, endaddr);
+ flush_icache();
+#else /* !CONFIG_COLDFIRE */
if (CPU_IS_040_OR_060) {
address &= PAGE_MASK;
@@ -94,9 +108,11 @@ void flush_icache_range(unsigned long ad
: "=&d" (tmp)
: "di" (FLUSH_I));
}
+#endif /* CONFIG_COLDFIRE */
}
EXPORT_SYMBOL(flush_icache_range);
+#ifndef CONFIG_COLDFIRE
void flush_icache_user_range(struct vm_area_struct *vma, struct page *page,
unsigned long addr, int len)
{
@@ -115,4 +131,5 @@ void flush_icache_user_range(struct vm_a
: "di" (FLUSH_I));
}
}
+#endif /* CONFIG_COLDFIRE */
--- a/arch/m68k/mm/hwtest.c
+++ b/arch/m68k/mm/hwtest.c
@@ -12,6 +12,10 @@
* them here complete with the comments from the original atari
* config.c...
* -- PMM <pmaydell@chiark.greenend.org.uk>, 05/1998
+ *
+ * Copyright Freescale Semiconductor, Inc. 2008-2009
+ * Jason Jin Jason.Jin@freescale.com
+ * Shrek Wu B16972@freescale.com
*/
/* This function tests for the presence of an address, specially a
@@ -25,6 +29,7 @@
#include <linux/module.h>
+#ifndef CONFIG_COLDFIRE
int hwreg_present( volatile void *regp )
{
int ret = 0;
@@ -82,4 +87,5 @@ int hwreg_write( volatile void *regp, un
return( ret );
}
EXPORT_SYMBOL(hwreg_write);
+#endif
--- a/arch/m68k/mm/init.c
+++ b/arch/m68k/mm/init.c
@@ -2,6 +2,9 @@
* linux/arch/m68k/mm/init.c
*
* Copyright (C) 1995 Hamish Macdonald
+ * Copyright Freescale Semiconductor, Inc. 2008-2009
+ * Jason Jin Jason.Jin@freescale.com
+ * Shrek Wu B16972@freescale.com
*
* Contains common initialization routines, specific init code moved
* to motorola.c and sun3mmu.c
@@ -31,6 +34,10 @@
#include <asm/sections.h>
#include <asm/tlb.h>
+#ifdef CONFIG_VDSO
+int vdso_init(void);
+#endif
+
DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
pg_data_t pg_data_map[MAX_NUMNODES];
@@ -88,7 +95,6 @@ void __init mem_init(void)
if (MACH_IS_ATARI)
atari_stram_mem_init_hook();
#endif
-
/* this will put all memory onto the freelists */
totalram_pages = num_physpages = 0;
for_each_online_pgdat(pgdat) {
@@ -112,7 +118,7 @@ void __init mem_init(void)
}
}
-#ifndef CONFIG_SUN3
+#if !defined(CONFIG_SUN3) && !defined(CONFIG_COLDFIRE)
/* insert pointer tables allocated so far into the tablelist */
init_pointer_table((unsigned long)kernel_pg_dir);
for (i = 0; i < PTRS_PER_PGD; i++) {
@@ -131,6 +137,11 @@ void __init mem_init(void)
codepages << (PAGE_SHIFT-10),
datapages << (PAGE_SHIFT-10),
initpages << (PAGE_SHIFT-10));
+
+#ifdef CONFIG_VDSO
+ /* init the vdso page */
+ vdso_init();
+#endif
}
#ifdef CONFIG_BLK_DEV_INITRD
--- a/arch/m68k/mm/kmap.c
+++ b/arch/m68k/mm/kmap.c
@@ -2,6 +2,9 @@
* linux/arch/m68k/mm/kmap.c
*
* Copyright (C) 1997 Roman Hodek
+ * Copyright Freescale Semiconductor, Inc. 2008, 2009
+ * Jason Jin Jason.Jin@freescale.com
+ * Shrek Wu B16972@freescale.com
*
* 10/01/99 cleaned up the code and changing to the same interface
* used by other architectures /Roman Zippel
@@ -24,7 +27,11 @@
#undef DEBUG
+#ifndef CONFIG_COLDFIRE
#define PTRTREESIZE (256*1024)
+#else
+#define PTRTREESIZE PAGE_SIZE
+#endif
/*
* For 040/060 we can use the virtual memory area like other architectures,
@@ -50,7 +57,11 @@ static inline void free_io_area(void *ad
#else
+#ifdef CONFIG_COLDFIRE
+#define IO_SIZE PAGE_SIZE
+#else
#define IO_SIZE (256*1024)
+#endif
static struct vm_struct *iolist;
@@ -127,8 +138,41 @@ void __iomem *__ioremap(unsigned long ph
}
#endif
+#ifdef CONFIG_M5445X
+ if (physaddr >= 0xf0000000) {
+ /*
+ * On the M5445x processors an ACR is setup to map
+ * the 0xF0000000 range into kernel memory as
+ * non-cacheable.
+ */
+ return (void __iomem *)physaddr;
+ }
+ if ((physaddr >= KMAP_START) && (physaddr <= KMAP_END)) {
+ /* if physaddr belongs to virtual address range for ioremap,
+ * then return physaddr because it has been ioremapped
+ */
+ return (void __iomem *)physaddr;
+ }
+#endif
+#ifdef CONFIG_M547X_8X
+ if (physaddr >= 0xf0000000) {
+ /*
+ * On the M547x/M548x processors an ACR is setup to map
+ * the 0xF0000000 range into kernel memory as
+ * non-cacheable.
+ */
+ return (void __iomem *)physaddr;
+ }
+
+ if ((physaddr >= 0xd0000000) && (physaddr + size < 0xd800ffff)) {
+ printk(KERN_ERR "ioremap:PCI 0x%lx,0x%lx(%d)"
+ " - PCI area hit\n", physaddr, size, cacheflag);
+ return (void *)physaddr;
+ }
+#endif
#ifdef DEBUG
- printk("ioremap: 0x%lx,0x%lx(%d) - ", physaddr, size, cacheflag);
+ printk(KERN_ERR "ioremap: paddr=0x%lx,size=0x%lx(%d) - ",
+ physaddr, size, cacheflag);
#endif
/*
* Mappings have to be aligned
@@ -147,7 +191,8 @@ void __iomem *__ioremap(unsigned long ph
virtaddr = (unsigned long)area->addr;
retaddr = virtaddr + offset;
#ifdef DEBUG
- printk("0x%lx,0x%lx,0x%lx", physaddr, virtaddr, retaddr);
+ printk(KERN_ERR " paddr=0x%lx,vaddr=0x%lx,retaddr=0x%lx",
+ physaddr, virtaddr, retaddr);
#endif
/*
@@ -172,7 +217,12 @@ void __iomem *__ioremap(unsigned long ph
break;
}
} else {
+#ifndef CONFIG_COLDFIRE
physaddr |= (_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_DIRTY);
+#else
+ physaddr |= (_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_DIRTY | \
+ _PAGE_READWRITE);
+#endif
switch (cacheflag) {
case IOMAP_NOCACHE_SER:
case IOMAP_NOCACHE_NONSER:
@@ -252,6 +302,13 @@ void __iounmap(void *addr, unsigned long
pmd_t *pmd_dir;
pte_t *pte_dir;
+#ifdef CONFIG_M547X_8X
+ if ((addr >= (void *)0xd0000000)
+ && (addr + size < (void *)0xd800ffff)) {
+ printk(KERN_ERR "%s: PCI address\n", __func__);
+ return;
+ }
+#endif
while ((long)size > 0) {
pgd_dir = pgd_offset_k(virtaddr);
if (pgd_bad(*pgd_dir)) {
--- a/arch/m68k/mm/Makefile
+++ b/arch/m68k/mm/Makefile
@@ -6,3 +6,5 @@ obj-y := cache.o init.o fault.o hwtest.
obj-$(CONFIG_MMU_MOTOROLA) += kmap.o memory.o motorola.o
obj-$(CONFIG_MMU_SUN3) += sun3kmap.o sun3mmu.o
+obj-$(CONFIG_MMU_CFV4E) += cf-mmu.o kmap.o memory.o
+obj-$(CONFIG_SRAM) += cf-sram.o
--- a/arch/m68k/mm/memory.c
+++ b/arch/m68k/mm/memory.c
@@ -2,6 +2,10 @@
* linux/arch/m68k/mm/memory.c
*
* Copyright (C) 1995 Hamish Macdonald
+ * Copyright Freescale Semiconductor, Inc. 2008-2009
+ * Jason Jin Jason.Jin@freescale.com
+ * Shrek Wu B16972@freescale.com
+ *
*/
#include <linux/module.h>
@@ -127,6 +131,7 @@ int free_pointer_table (pmd_t *ptable)
return 0;
}
+#ifndef CONFIG_COLDFIRE
/* invalidate page in both caches */
static inline void clear040(unsigned long paddr)
{
@@ -173,6 +178,7 @@ static inline void pushcl040(unsigned lo
clear040(paddr);
local_irq_restore(flags);
}
+#endif /* CONFIG_COLDFIRE */
/*
* 040: Hit every page containing an address in the range paddr..paddr+len-1.
@@ -203,6 +209,11 @@ static inline void pushcl040(unsigned lo
void cache_clear (unsigned long paddr, int len)
{
+#ifdef CONFIG_COLDFIRE
+// JKM -- revise to use proper caching
+// cf_cache_clear(paddr, len);
+ flush_bcache();
+#else
if (CPU_IS_040_OR_060) {
int tmp;
@@ -237,6 +248,7 @@ void cache_clear (unsigned long paddr, i
if(mach_l2_flush)
mach_l2_flush(0);
#endif
+#endif /* CONFIG_COLDFIRE */
}
EXPORT_SYMBOL(cache_clear);
@@ -250,6 +262,11 @@ EXPORT_SYMBOL(cache_clear);
void cache_push (unsigned long paddr, int len)
{
+#ifdef CONFIG_COLDFIRE
+// JKM -- revise to use proper caching
+// cf_cache_push(paddr, len);
+ flush_bcache();
+#else
if (CPU_IS_040_OR_060) {
int tmp = PAGE_SIZE;
@@ -290,6 +307,7 @@ void cache_push (unsigned long paddr, in
if(mach_l2_flush)
mach_l2_flush(1);
#endif
+#endif /* CONFIG_COLDFIRE */
}
EXPORT_SYMBOL(cache_push);
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -3,6 +3,10 @@
*
* (C) Copyright Al Viro 2000, 2001
* Released under GPL v2.
+ * (c) Copyright Freescale Semiconductor, Inc. 2008, 2009
+ * Change to align on page size for coldfire
+ * Jason Jin Jason.Jin@freescale.com
+ * Shrek Wu B16972@freescale.com
*
* Based on code from fs/super.c, copyright Linus Torvalds and others.
* Heavily rewritten.
@@ -1858,7 +1862,11 @@ int copy_mount_options(const void __user
/* copy_from_user cannot cross TASK_SIZE ! */
size = TASK_SIZE - (unsigned long)data;
if (size > PAGE_SIZE)
+#ifndef CONFIG_COLDFIRE
size = PAGE_SIZE;
+#else
+ size = PAGE_SIZE - ((unsigned long)data & ~PAGE_MASK);
+#endif
i = size - exact_copy_from_user((void *)page, data, size);
if (!i) {
--- a/include/linux/fsl_devices.h
+++ b/include/linux/fsl_devices.h
@@ -6,7 +6,7 @@
*
* Maintainer: Kumar Gala <galak@kernel.crashing.org>
*
- * Copyright 2004 Freescale Semiconductor, Inc
+ * Copyright 2004-2008 Freescale Semiconductor, Inc
*
* 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
@@ -18,6 +18,7 @@
#define _FSL_DEVICE_H_
#include <linux/types.h>
+#include <linux/interrupt.h>
/*
* Some conventions on how we handle peripherals on Freescale chips
@@ -58,11 +59,42 @@ enum fsl_usb2_phy_modes {
FSL_USB2_PHY_SERIAL,
};
+struct platform_device;
struct fsl_usb2_platform_data {
/* board specific information */
enum fsl_usb2_operating_modes operating_mode;
enum fsl_usb2_phy_modes phy_mode;
unsigned int port_enables;
+
+ char *name; /* pretty print */
+ int (*platform_init) (struct platform_device *);
+ void (*platform_uninit) (struct fsl_usb2_platform_data *);
+ void __iomem *regs; /* ioremap'd register base */
+ u32 xcvr_type; /* PORTSC_PTS_* */
+ char *transceiver; /* transceiver name */
+ unsigned power_budget; /* for hcd->power_budget */
+ struct platform_device *pdev;
+ struct fsl_xcvr_ops *xcvr_ops;
+ int (*gpio_usb_active) (void);
+ void (*gpio_usb_inactive) (void);
+ unsigned big_endian_mmio : 1;
+ unsigned big_endian_desc : 1;
+ unsigned es : 1; /* need USBMODE:ES */
+ unsigned have_sysif_regs : 1;
+ unsigned le_setup_buf : 1;
+ unsigned suspended : 1;
+ unsigned already_suspended : 1;
+
+ /* register save area for suspend/resume */
+ u32 pm_command;
+ u32 pm_status;
+ u32 pm_intr_enable;
+ u32 pm_frame_index;
+ u32 pm_segment;
+ u32 pm_frame_list;
+ u32 pm_async_next;
+ u32 pm_configured_flag;
+ u32 pm_portsc;
};
/* Flags in fsl_usb2_mph_platform_data */
@@ -92,4 +124,30 @@ struct mpc8xx_pcmcia_ops {
*/
int fsl_deep_sleep(void);
+struct fsl_ata_platform_data {
+#ifdef CONFIG_FSL_PATA_USE_DMA
+ int udma_mask; /* UDMA modes h/w can handle */
+ int fifo_alarm; /* value for fifo_alarm reg */
+ int max_sg; /* longest sglist h/w can handle */
+#endif
+ int (*init)(struct platform_device *pdev);
+ void (*exit)(void);
+ int (*get_clk_rate)(void);
+};
+
+struct coldfire_fec_platform_data {
+ int hash_table;
+ unsigned int *fec_hw;
+ void (*request_intrs)(struct net_device *dev,
+ irqreturn_t (*)(int, void *),
+ void *irq_privatedata);
+ void (*set_mii)(struct net_device *dev);
+ void (*get_mac)(struct net_device *dev);
+ void (*enable_phy_intr)(void);
+ void (*disable_phy_intr)(void);
+ void (*phy_ack_intr)(void);
+ void (*localhw_setup)(void);
+ void (*uncache)(unsigned long addr);
+ void (*platform_flush_cache)(void);
+};
#endif /* _FSL_DEVICE_H_ */