[U-Boot] [PATCH v2 1/4] Add support new arch: c6x

Dmitry Bondar
2012-06-23T11:11:07Z

C6X (C6000) is Texas Instruments architecture of fixed and floating-point DSPs.
This patch add basic support.
Many of code in arch/c6x/include/asm come from c6x-linux project (http://linux-c6x.org)

Signed-off-by: Dmitry Bondar <bond@inmys.ru>

Cc: Tom Rini <trini@ti.com>
---
arch/c6x/config.mk | 1 +
arch/c6x/include/asm/bitops.h | 88 ++++++++
arch/c6x/include/asm/byteorder.h | 1 +
arch/c6x/include/asm/cache.h | 29 +++
arch/c6x/include/asm/config.h | 3 +
arch/c6x/include/asm/errno.h | 1 +
arch/c6x/include/asm/global_data.h | 88 ++++++++
arch/c6x/include/asm/gpio.h | 2 +
arch/c6x/include/asm/io.h | 53 +++++
arch/c6x/include/asm/posix_types.h | 72 +++++++
arch/c6x/include/asm/processor.h | 4 +
arch/c6x/include/asm/ptrace.h | 302 ++++++++++++++++++++++++++
arch/c6x/include/asm/sizes.h | 51 +++++
arch/c6x/include/asm/string.h | 26 +++
arch/c6x/include/asm/types.h | 53 +++++
arch/c6x/include/asm/u-boot.h | 57 +++++
arch/c6x/include/asm/unaligned.h | 1 +
arch/c6x/lib/Makefile | 51 +++++
arch/c6x/lib/board.c | 201 ++++++++++++++++++
arch/c6x/lib/bootm.c | 59 +++++
arch/c6x/lib/csum_64plus.S | 408 ++++++++++++++++++++++++++++++++++++
arch/c6x/lib/delay.S | 39 ++++
arch/c6x/lib/divi.S | 54 +++++
arch/c6x/lib/divremi.S | 61 ++++++
arch/c6x/lib/divremu.S | 86 ++++++++
arch/c6x/lib/divu.S | 100 +++++++++
arch/c6x/lib/divull.c | 336 +++++++++++++++++++++++++++++
arch/c6x/lib/llshl.S | 36 ++++
arch/c6x/lib/llshr.S | 36 ++++
arch/c6x/lib/llshru.S | 36 ++++
arch/c6x/lib/memcmp.c | 24 ++
arch/c6x/lib/memcpy_64plus.S | 45 ++++
arch/c6x/lib/memmove.c | 30 +++
arch/c6x/lib/memset.c | 20 ++
arch/c6x/lib/mpyll.S | 47 ++++
arch/c6x/lib/negll.S | 29 +++
arch/c6x/lib/pop_rts.S | 30 +++
arch/c6x/lib/push_rts.S | 28 +++
arch/c6x/lib/remi.S | 78 +++++++
arch/c6x/lib/remu.S | 81 +++++++
arch/c6x/lib/strasgi.S | 88 ++++++++
arch/c6x/lib/strasgi_64plus.S | 37 ++++
arch/c6x/lib/unaligned.S | 117 ++++++++++
common/cmd_bdinfo.c | 5 +
common/image.c | 4 +
examples/standalone/stubs.c | 15 ++
46 files changed, 3013 insertions(+), 0 deletions(-)
create mode 100644 arch/c6x/config.mk
create mode 100644 arch/c6x/include/asm/bitops.h
create mode 100644 arch/c6x/include/asm/byteorder.h
create mode 100644 arch/c6x/include/asm/cache.h
create mode 100644 arch/c6x/include/asm/config.h
create mode 100644 arch/c6x/include/asm/errno.h
create mode 100644 arch/c6x/include/asm/global_data.h
create mode 100644 arch/c6x/include/asm/gpio.h
create mode 100644 arch/c6x/include/asm/io.h
create mode 100644 arch/c6x/include/asm/posix_types.h
create mode 100644 arch/c6x/include/asm/processor.h
create mode 100644 arch/c6x/include/asm/ptrace.h
create mode 100644 arch/c6x/include/asm/sizes.h
create mode 100644 arch/c6x/include/asm/string.h
create mode 100644 arch/c6x/include/asm/types.h
create mode 100644 arch/c6x/include/asm/u-boot.h
create mode 100644 arch/c6x/include/asm/unaligned.h
create mode 100644 arch/c6x/lib/Makefile
create mode 100644 arch/c6x/lib/board.c
create mode 100644 arch/c6x/lib/bootm.c
create mode 100644 arch/c6x/lib/csum_64plus.S
create mode 100644 arch/c6x/lib/delay.S
create mode 100644 arch/c6x/lib/divi.S
create mode 100644 arch/c6x/lib/divremi.S
create mode 100644 arch/c6x/lib/divremu.S
create mode 100644 arch/c6x/lib/divu.S
create mode 100644 arch/c6x/lib/divull.c
create mode 100644 arch/c6x/lib/llshl.S
create mode 100644 arch/c6x/lib/llshr.S
create mode 100644 arch/c6x/lib/llshru.S
create mode 100644 arch/c6x/lib/memcmp.c
create mode 100644 arch/c6x/lib/memcpy_64plus.S
create mode 100644 arch/c6x/lib/memmove.c
create mode 100644 arch/c6x/lib/memset.c
create mode 100644 arch/c6x/lib/mpyll.S
create mode 100644 arch/c6x/lib/negll.S
create mode 100644 arch/c6x/lib/pop_rts.S
create mode 100644 arch/c6x/lib/push_rts.S
create mode 100644 arch/c6x/lib/remi.S
create mode 100644 arch/c6x/lib/remu.S
create mode 100644 arch/c6x/lib/strasgi.S
create mode 100644 arch/c6x/lib/strasgi_64plus.S
create mode 100644 arch/c6x/lib/unaligned.S

diff --git a/arch/c6x/config.mk b/arch/c6x/config.mk
new file mode 100644
index 0000000..9cbddbc
--- /dev/null
+++ b/arch/c6x/config.mk
@@ -0,0 +1 @@
+CROSS_COMPILE ?= c6x-uclinux-
diff --git a/arch/c6x/include/asm/bitops.h b/arch/c6x/include/asm/bitops.h
new file mode 100644
index 0000000..5896b5e
--- /dev/null
+++ b/arch/c6x/include/asm/bitops.h
@@ -0,0 +1,88 @@
+/*
+ * linux/include/asm-c6x/bitops.h
+ *
+ * Port on Texas Instruments TMS320C6x architecture
+ *
+ * Copyright (C) 2004, 2009, 2010 Texas Instruments Incorporated
+ * Author: Aurelien Jacquiot (aurelien.jacquiot at jaluna.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef __ASM_C6X_BITOPS_H_
+#define __ASM_C6X_BITOPS_H_
+
+#ifdef __KERNEL__
+
+#include <linux/bitops.h>
+#include <asm/byteorder.h>
+
+/*
+ * We are lucky, DSP is perfect for bitops: do it in 3 cycles
+ */
+
+/**
+ * __ffs - find first bit in word.
+ * @word: The word to search
+ *
+ * Undefined if no bit exists, so code should check against 0 first.
+ * Note __ffs(0) = undef, __ffs(1) = 0, __ffs(0x80000000) = 31.
+ *
+ */
+static inline unsigned long __ffs(unsigned long x)
+{
+ asm (" bitr .M1 %0,%0\n"
+ " nop\n"
+ " lmbd .L1 1,%0,%0\n"
+ : "+a"(x));
+
+ return x;
+}
+
+/*
+ * ffz - find first zero in word.
+ * @word: The word to search
+ *
+ * Undefined if no zero exists, so code should check against ~0UL first.
+ */
+#define ffz(x) __ffs(~(x))
+
+/**
+ * fls - find last (most-significant) bit set
+ * @x: the word to search
+ *
+ * This is defined the same way as ffs.
+ * Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32.
+ */
+static inline unsigned long fls(unsigned long x)
+{
+ if (!x)
+ return 0;
+
+ asm (" lmbd .L1 1,%0,%0\n" : "+a"(x));
+
+ return 32 - x;
+}
+
+/**
+ * ffs - find first bit set
+ * @x: the word to search
+ *
+ * This is defined the same way as
+ * the libc and compiler builtin ffs routines, therefore
+ * differs in spirit from the above ffz (man ffs).
+ * Note ffs(0) = 0, ffs(1) = 1, ffs(0x80000000) = 32.
+ */
+static inline int ffs(int x)
+{
+ if (!x)
+ return 0;
+
+ return __ffs(x) + 1;
+}
+
+#define hweight8(x) generic_hweight8(x)
+
+#endif /* __KERNEL__ */
+#endif /* __ASM_C6X_BITOPS_H */
diff --git a/arch/c6x/include/asm/byteorder.h b/arch/c6x/include/asm/byteorder.h
new file mode 100644
index 0000000..9558416
--- /dev/null
+++ b/arch/c6x/include/asm/byteorder.h
@@ -0,0 +1 @@
+#include <linux/byteorder/little_endian.h>
diff --git a/arch/c6x/include/asm/cache.h b/arch/c6x/include/asm/cache.h
new file mode 100644
index 0000000..75b2043
--- /dev/null
+++ b/arch/c6x/include/asm/cache.h
@@ -0,0 +1,29 @@
+/*
+ * (C) Copyright 2011, Stefan Kristiansson <stefan.kristiansson@saunalahti.fi>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef __ASM_C6X_CACHE_H_
+#define __ASM_C6X_CACHE_H_
+
+#ifdef CONFIG_SYS_CACHELINE_SIZE
+#define ARCH_DMA_MINALIGN CONFIG_SYS_CACHELINE_SIZE
+#else
+#define ARCH_DMA_MINALIGN 128
+#endif
+
+#endif /* __ASM_C6X_CACHE_H_ */
diff --git a/arch/c6x/include/asm/config.h b/arch/c6x/include/asm/config.h
new file mode 100644
index 0000000..db59e8a
--- /dev/null
+++ b/arch/c6x/include/asm/config.h
@@ -0,0 +1,3 @@
+#ifndef _ASM_CONFIG_H_
+#define _ASM_CONFIG_H_
+#endif
diff --git a/arch/c6x/include/asm/errno.h b/arch/c6x/include/asm/errno.h
new file mode 100644
index 0000000..4c82b50
--- /dev/null
+++ b/arch/c6x/include/asm/errno.h
@@ -0,0 +1 @@
+#include <asm-generic/errno.h>
diff --git a/arch/c6x/include/asm/global_data.h b/arch/c6x/include/asm/global_data.h
new file mode 100644
index 0000000..1ffd781
--- /dev/null
+++ b/arch/c6x/include/asm/global_data.h
@@ -0,0 +1,88 @@
+/*
+ * (C) Copyright 2002-2010
+ * Wolfgang Denk, DENX Software Engineering, wd at denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef __ASM_GBL_DATA_H
+#define __ASM_GBL_DATA_H
+/*
+ * The following data structure is placed in some memory which is
+ * available very early after boot (like DPRAM on MPC8xx/MPC82xx, or
+ * some locked parts of the data cache) to allow for a minimum set of
+ * global variables during system initialization (until we have set
+ * up the memory controller so that we can use RAM).
+ *
+ * Keep it *SMALL* and remember to set GENERATED_GBL_DATA_SIZE > sizeof(gd_t)
+ */
+
+typedef struct global_data {
+ bd_t *bd;
+ unsigned long flags;
+ unsigned long baudrate;
+ unsigned long have_console; /* serial_init() was called */
+#ifdef CONFIG_PRE_CONSOLE_BUFFER
+ unsigned long precon_buf_idx; /* Pre-Console buffer index */
+#endif
+ unsigned long env_addr; /* Address of Environment struct */
+ unsigned long env_valid; /* Checksum of Environment valid? */
+ unsigned long fb_base; /* base address of frame buffer */
+
+ /* "static data" needed by most of timer.c (like on ARM platform) */
+ unsigned long timer_rate_hz;
+ unsigned long tbl;
+ unsigned long tbu;
+ unsigned long long timer_reset_value;
+ unsigned long lastinc;
+
+ phys_size_t ram_size; /* RAM size */
+#if 0
+ unsigned long relocaddr; /* Start address of U-Boot in RAM */
+ phys_size_t ram_size; /* RAM size */
+ unsigned long mon_len; /* monitor len */
+ unsigned long irq_sp; /* irq stack pointer */
+ unsigned long start_addr_sp; /* start_addr_stackpointer */
+ unsigned long reloc_off;
+#endif
+
+ void **jt; /* jump table */
+ char env_buf[32]; /* buffer for getenv() before reloc. */
+#if defined(CONFIG_POST) || defined(CONFIG_LOGBUFFER)
+ unsigned long post_log_word; /* Record POST activities */
+ unsigned long post_log_res; /* success of POST test */
+ unsigned long post_init_f_time; /* When post_init_f started */
+#endif
+} gd_t;
+
+/*
+ * Global Data Flags
+ */
+#define GD_FLG_RELOC 0x00001 /* Code was relocated to RAM */
+#define GD_FLG_DEVINIT 0x00002 /* Devices have been initialized */
+#define GD_FLG_SILENT 0x00004 /* Silent mode */
+#define GD_FLG_POSTFAIL 0x00008 /* Critical POST test failed */
+#define GD_FLG_POSTSTOP 0x00010 /* POST seqeunce aborted */
+#define GD_FLG_LOGINIT 0x00020 /* Log Buffer has been initialized */
+#define GD_FLG_DISABLE_CONSOLE 0x00040 /* Disable console (in & out) */
+#define GD_FLG_ENV_READY 0x00080 /* Environment imported into hash table */
+
+#define DECLARE_GLOBAL_DATA_PTR register volatile gd_t *gd asm ("B31")
+
+#endif /* __ASM_GBL_DATA_H */
diff --git a/arch/c6x/include/asm/gpio.h b/arch/c6x/include/asm/gpio.h
new file mode 100644
index 0000000..d49ad08
--- /dev/null
+++ b/arch/c6x/include/asm/gpio.h
@@ -0,0 +1,2 @@
+#include <asm/arch/gpio.h>
+#include <asm-generic/gpio.h>
diff --git a/arch/c6x/include/asm/io.h b/arch/c6x/include/asm/io.h
new file mode 100644
index 0000000..9afde27
--- /dev/null
+++ b/arch/c6x/include/asm/io.h
@@ -0,0 +1,53 @@
+/*
+ * linux/include/asm-c6x/io.h
+ *
+ * Port on Texas Instruments TMS320C6x architecture
+ *
+ * Copyright (C) 2004, 2009, 2010, 2011 Texas Instruments Incorporated
+ * Author: Aurelien Jacquiot (aurelien.jacquiot at jaluna.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+static inline unsigned char __readb(volatile unsigned char *addr) { return (*addr); }
+static inline unsigned short __readw(volatile unsigned short *addr) { return (*addr); }
+static inline unsigned long __readl(volatile unsigned int *addr) { return (*addr); }
+
+#define readb(addr) __readb((volatile unsigned char *) (addr))
+#define readw(addr) __readw((volatile unsigned short *) (addr))
+#define readl(addr) __readl((volatile unsigned int *) (addr))
+
+#define writeb(b,addr) ((*(volatile unsigned char *) (addr)) = (b))
+#define writew(b,addr) ((*(volatile unsigned short *) (addr)) = (b))
+#define writel(b,addr) ((*(volatile unsigned int *) (addr)) = (b))
+
+#define __raw_readb readb
+#define __raw_readw readw
+#define __raw_readl readl
+#define __raw_writeb writeb
+#define __raw_writew writew
+#define __raw_writel writel
+
+
+#define in_le16(addr) \
+ ({ unsigned short __v = le16_to_cpu(*(volatile unsigned short *) (addr)); __v; })
+#define in_le32(addr) \
+ ({ unsigned int __v = le32_to_cpu(*(volatile unsigned int *) (addr)); __v; })
+#define out_le16(addr,w) (void)((*(volatile unsigned short *) (addr)) = cpu_to_le16(w))
+#define out_le32(addr,l) (void)((*(volatile unsigned int *) (addr)) = cpu_to_le32(l))
+
+#define clrbits(type, addr, clear) \
+ out_##type((addr), in_##type(addr) & ~(clear))
+
+#define setbits(type, addr, set) \
+ out_##type((addr), in_##type(addr) | (set))
+
+#define clrsetbits(type, addr, clear, set) \
+ out_##type((addr), (in_##type(addr) & ~(clear)) | (set))
+
+#define clrbits_le32(addr, clear) clrbits(le32, addr, clear)
+#define setbits_le32(addr, set) setbits(le32, addr, set)
+#define clrsetbits_le32(addr, clear, set) clrsetbits(le32, addr, clear, set)
+
diff --git a/arch/c6x/include/asm/posix_types.h b/arch/c6x/include/asm/posix_types.h
new file mode 100644
index 0000000..d1fffe0
--- /dev/null
+++ b/arch/c6x/include/asm/posix_types.h
@@ -0,0 +1,72 @@
+/*
+ * Based on microblaze implementation:
+ * Copyright (C) 2003 John Williams <jwilliams@itee.uq.edu.au>
+ * Copyright (C) 2001,2002 NEC Corporation
+ * Copyright (C) 2001,2002 Miles Bader <miles@gnu.org>
+ *
+ * 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.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ * Microblaze port by John Williams
+ */
+
+#ifndef __ASM_OPENRISC_POSIX_TYPES_H
+#define __ASM_OPENRISC_POSIX_TYPES_H
+
+typedef unsigned int __kernel_dev_t;
+typedef unsigned long __kernel_ino_t;
+typedef unsigned long long __kernel_ino64_t;
+typedef unsigned int __kernel_mode_t;
+typedef unsigned int __kernel_nlink_t;
+typedef long __kernel_off_t;
+typedef long long __kernel_loff_t;
+typedef int __kernel_pid_t;
+typedef unsigned short __kernel_ipc_pid_t;
+typedef unsigned int __kernel_uid_t;
+typedef unsigned int __kernel_gid_t;
+typedef unsigned int __kernel_size_t;
+typedef int __kernel_ssize_t;
+typedef int __kernel_ptrdiff_t;
+typedef long __kernel_time_t;
+typedef long __kernel_suseconds_t;
+typedef long __kernel_clock_t;
+typedef int __kernel_daddr_t;
+typedef char *__kernel_caddr_t;
+typedef unsigned short __kernel_uid16_t;
+typedef unsigned short __kernel_gid16_t;
+typedef unsigned int __kernel_uid32_t;
+typedef unsigned int __kernel_gid32_t;
+
+typedef unsigned short __kernel_old_uid_t;
+typedef unsigned short __kernel_old_gid_t;
+
+
+typedef struct {
+#if defined(__KERNEL__) || defined(__USE_ALL)
+ int val[2];
+#else /* !defined(__KERNEL__) && !defined(__USE_ALL) */
+ int __val[2];
+#endif /* !defined(__KERNEL__) && !defined(__USE_ALL) */
+} __kernel_fsid_t;
+
+
+#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2)
+
+#undef __FD_SET
+#define __FD_SET(fd, fd_set) \
+ __set_bit(fd, (void *)&((__kernel_fd_set *)fd_set)->fds_bits)
+#undef __FD_CLR
+#define __FD_CLR(fd, fd_set) \
+ __clear_bit(fd, (void *)&((__kernel_fd_set *)fd_set)->fds_bits)
+#undef __FD_ISSET
+#define __FD_ISSET(fd, fd_set) \
+ __test_bit(fd, (void *)&((__kernel_fd_set *)fd_set)->fds_bits)
+#undef __FD_ZERO
+#define __FD_ZERO(fd_set) \
+ memset(fd_set, 0, sizeof(*(fd_set *)fd_set))
+
+#endif /* defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) */
+
+#endif /* __ASM_OPENRISC_POSIX_TYPES_H */
diff --git a/arch/c6x/include/asm/processor.h b/arch/c6x/include/asm/processor.h
new file mode 100644
index 0000000..ec98171
--- /dev/null
+++ b/arch/c6x/include/asm/processor.h
@@ -0,0 +1,4 @@
+#ifndef __ASM_C6X_PROCESSOR_H
+#define __ASM_C6X_PROCESSOR_H
+
+#endif
diff --git a/arch/c6x/include/asm/ptrace.h b/arch/c6x/include/asm/ptrace.h
new file mode 100644
index 0000000..5c4665e
--- /dev/null
+++ b/arch/c6x/include/asm/ptrace.h
@@ -0,0 +1,302 @@
+/*
+ * linux/include/asm-c6x/ptrace.h
+ *
+ * Port on Texas Instruments TMS320C6x architecture
+ *
+ * Copyright (C) 2004, 2006, 2009, 2010, 2011 Texas Instruments Incorporated
+ * Author: Aurelien Jacquiot (aurelien.jacquiot at jaluna.com)
+ *
+ * Updated for 2.6.34: Mark Salter <msalter@redhat.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef __ASM_C6X_PTRACE_H
+#define __ASM_C6X_PTRACE_H
+
+#if defined(__TMS320C6XPLUS__) || defined(_TMS320C6400_PLUS) || defined(__TMS320C66X__)
+#define BKPT_OPCODE 0x56454314 /* illegal opcode */
+#else
+#define BKPT_OPCODE 0x0000a122 /* BNOP .S2 0,5 */
+#endif
+
+#ifdef _BIG_ENDIAN
+#define PT_LO(odd,even) odd
+#define PT_HI(odd,even) even
+#else
+#define PT_LO(odd,even) even
+#define PT_HI(odd,even) odd
+#endif
+
+#if defined(__TMS320C6XPLUS__) || defined(_TMS320C6400_PLUS) || defined(__TMS320C66X__)
+
+#define PT_A4_ORG PT_LO(1,0)
+#define PT_TSR PT_HI(1,0)
+#define PT_ILC PT_LO(3,2)
+#define PT_RILC PT_HI(3,2)
+#define PT_CSR PT_LO(5,4)
+#define PT_PC PT_HI(5,4)
+#define PT_B16 PT_LO(7,6)
+#define PT_B17 PT_HI(7,6)
+#define PT_B18 PT_LO(9,8)
+#define PT_B19 PT_HI(9,8)
+#define PT_B20 PT_LO(11,10)
+#define PT_B21 PT_HI(11,10)
+#define PT_B22 PT_LO(13,12)
+#define PT_B23 PT_HI(13,12)
+#define PT_B24 PT_LO(15,14)
+#define PT_B25 PT_HI(15,14)
+#define PT_B26 PT_LO(17,16)
+#define PT_B27 PT_HI(17,16)
+#define PT_B28 PT_LO(19,18)
+#define PT_B29 PT_HI(19,18)
+#define PT_B30 PT_LO(21,20)
+#define PT_B31 PT_HI(21,20)
+#define PT_B0 PT_LO(23,22)
+#define PT_B1 PT_HI(23,22)
+#define PT_B2 PT_LO(25,24)
+#define PT_B3 PT_HI(25,24)
+#define PT_B4 PT_LO(27,26)
+#define PT_B5 PT_HI(27,26)
+#define PT_B6 PT_LO(29,28)
+#define PT_B7 PT_HI(29,28)
+#define PT_B8 PT_LO(31,30)
+#define PT_B9 PT_HI(31,30)
+#define PT_B10 PT_LO(33,32)
+#define PT_B11 PT_HI(33,32)
+#define PT_B12 PT_LO(35,34)
+#define PT_B13 PT_HI(35,34)
+#define PT_A16 PT_LO(37,36)
+#define PT_A17 PT_HI(37,36)
+#define PT_A18 PT_LO(39,38)
+#define PT_A19 PT_HI(39,38)
+#define PT_A20 PT_LO(41,40)
+#define PT_A21 PT_HI(41,40)
+#define PT_A22 PT_LO(43,42)
+#define PT_A23 PT_HI(43,42)
+#define PT_A24 PT_LO(45,44)
+#define PT_A25 PT_HI(45,44)
+#define PT_A26 PT_LO(47,46)
+#define PT_A27 PT_HI(47,46)
+#define PT_A28 PT_LO(49,48)
+#define PT_A29 PT_HI(49,48)
+#define PT_A30 PT_LO(51,50)
+#define PT_A31 PT_HI(51,50)
+#define PT_A0 PT_LO(53,52)
+#define PT_A1 PT_HI(53,52)
+#define PT_A2 PT_LO(55,54)
+#define PT_A3 PT_HI(55,54)
+#define PT_A4 PT_LO(57,56)
+#define PT_A5 PT_HI(57,56)
+#define PT_A6 PT_LO(59,58)
+#define PT_A7 PT_HI(59,58)
+#define PT_A8 PT_LO(61,60)
+#define PT_A9 PT_HI(61,60)
+#define PT_A10 PT_LO(63,62)
+#define PT_A11 PT_HI(63,62)
+#define PT_A12 PT_LO(65,64)
+#define PT_A13 PT_HI(65,64)
+#define PT_A14 PT_LO(67,66)
+#define PT_A15 PT_HI(67,66)
+#define PT_B14 PT_LO(69,68)
+#define PT_B15 PT_HI(69,68)
+
+#else /* defined(__TMS320C6XPLUS__) */
+
+#define PT_A4_ORG PT_LO(1,0)
+#define PT_STKADJ PT_HI(1,0)
+#define PT_CSR PT_LO(3,2)
+#define PT_PC PT_HI(3,2)
+#if defined(_TMS320C6400)
+#define PT_B16 PT_LO(5,4)
+#define PT_B17 PT_HI(5,4)
+#define PT_B18 PT_LO(7,6)
+#define PT_B19 PT_HI(7,6)
+#define PT_B20 PT_LO(9,8)
+#define PT_B21 PT_HI(9,8)
+#define PT_B22 PT_LO(11,10)
+#define PT_B23 PT_HI(11,10)
+#define PT_B24 PT_LO(13,12)
+#define PT_B25 PT_HI(13,12)
+#define PT_B26 PT_LO(15,14)
+#define PT_B27 PT_HI(15,14)
+#define PT_B28 PT_LO(17,16)
+#define PT_B29 PT_HI(17,16)
+#define PT_B30 PT_LO(19,18)
+#define PT_B31 PT_HI(19,18)
+#endif /* defined(_TMS320C6400) */
+#define PT_B0 PT_LO(21,20)
+#define PT_B1 PT_HI(21,20)
+#define PT_B2 PT_LO(23,22)
+#define PT_B3 PT_HI(23,22)
+#define PT_B4 PT_LO(25,24)
+#define PT_B5 PT_HI(25,24)
+#define PT_B6 PT_LO(27,26)
+#define PT_B7 PT_HI(27,26)
+#define PT_B8 PT_LO(29,28)
+#define PT_B9 PT_HI(29,28)
+#define PT_B10 PT_LO(31,30)
+#define PT_B11 PT_HI(31,30)
+#define PT_B12 PT_LO(33,32)
+#define PT_B13 PT_HI(33,32)
+#if defined(_TMS320C6400)
+#define PT_A16 PT_LO(35,34)
+#define PT_A17 PT_HI(35,34)
+#define PT_A18 PT_LO(37,36)
+#define PT_A19 PT_HI(37,36)
+#define PT_A20 PT_LO(39,38)
+#define PT_A21 PT_HI(39,38)
+#define PT_A22 PT_LO(41,40)
+#define PT_A23 PT_HI(41,40)
+#define PT_A24 PT_LO(43,42)
+#define PT_A25 PT_HI(43,42)
+#define PT_A26 PT_LO(45,44)
+#define PT_A27 PT_HI(45,44)
+#define PT_A28 PT_LO(47,46)
+#define PT_A29 PT_HI(47,46)
+#define PT_A30 PT_LO(49,48)
+#define PT_A31 PT_HI(49,48)
+#endif /* defined(_TMS320C6400) */
+#define PT_A0 PT_LO(51,50)
+#define PT_A1 PT_HI(51,50)
+#define PT_A2 PT_LO(53,52)
+#define PT_A3 PT_HI(53,52)
+#define PT_A4 PT_LO(55,54)
+#define PT_A5 PT_HI(55,54)
+#define PT_A6 PT_LO(57,56)
+#define PT_A7 PT_HI(57,56)
+#define PT_A8 PT_LO(59,58)
+#define PT_A9 PT_HI(59,58)
+#define PT_A10 PT_LO(61,60)
+#define PT_A11 PT_HI(61,60)
+#define PT_A12 PT_LO(63,62)
+#define PT_A13 PT_HI(63,62)
+#define PT_A14 PT_LO(65,64)
+#define PT_A15 PT_HI(65,64)
+#define PT_B14 PT_LO(67,66)
+#define PT_B15 PT_HI(67,66)
+
+#endif /* defined(__TMS320C6XPLUS__) */
+
+#define PT_DP PT_B14 /* Data Segment Pointer (B14) */
+#define PT_SP PT_B15 /* Stack Pointer (B15) */
+
+#ifndef __ASSEMBLY__
+
+#ifdef _BIG_ENDIAN
+#define REG_PAIR(odd,even) unsigned long odd; unsigned long even
+#else
+#define REG_PAIR(odd,even) unsigned long even; unsigned long odd
+#endif
+
+/*
+ * this struct defines the way the registers are stored on the
+ * stack during a system call. fields defined with REG_PAIR
+ * are saved and restored using double-word memory operations
+ * which means the word ordering of the pair depends on endianess.
+ */
+struct pt_regs {
+#if defined(__TMS320C6XPLUS__) || defined(_TMS320C6400_PLUS) || defined(__TMS320C66X__)
+ REG_PAIR(tsr,orig_a4);
+ REG_PAIR(rilc,ilc);
+#else
+ REG_PAIR(stkadj,orig_a4);
+#endif
+ REG_PAIR(pc,csr);
+
+#if defined(_TMS320C6400)
+ REG_PAIR(b17,b16);
+ REG_PAIR(b19,b18);
+ REG_PAIR(b21,b20);
+ REG_PAIR(b23,b22);
+ REG_PAIR(b25,b24);
+ REG_PAIR(b27,b26);
+ REG_PAIR(b29,b28);
+ REG_PAIR(b31,b30);
+#endif /* defined(_TMS320C6400) */
+
+ REG_PAIR(b1,b0);
+ REG_PAIR(b3,b2);
+ REG_PAIR(b5,b4);
+ REG_PAIR(b7,b6);
+ REG_PAIR(b9,b8);
+ REG_PAIR(b11,b10);
+ REG_PAIR(b13,b12);
+
+#if defined(_TMS320C6400)
+ REG_PAIR(a17,a16);
+ REG_PAIR(a19,a18);
+ REG_PAIR(a21,a20);
+ REG_PAIR(a23,a22);
+ REG_PAIR(a25,a24);
+ REG_PAIR(a27,a26);
+ REG_PAIR(a29,a28);
+ REG_PAIR(a31,a30);
+#endif /* defined(_TMS320C6400) */
+
+ REG_PAIR(a1,a0);
+ REG_PAIR(a3,a2);
+ REG_PAIR(a5,a4);
+ REG_PAIR(a7,a6);
+ REG_PAIR(a9,a8);
+ REG_PAIR(a11,a10);
+ REG_PAIR(a13,a12);
+
+ REG_PAIR(a15,a14);
+ REG_PAIR(sp,dp);
+};
+
+/*
+ * This is the extended stack used by the context switcher
+ */
+struct switch_stack {
+#if defined(__TMS320C6XPLUS__) || defined(_TMS320C6400_PLUS) || defined(__TMS320C66X__)
+ REG_PAIR(rilc,ilc);
+#endif
+ REG_PAIR(a11,a10);
+ REG_PAIR(a13,a12);
+ REG_PAIR(a15,a14);
+ REG_PAIR(b11,b10);
+ REG_PAIR(b13,b12);
+
+ unsigned long retpc;
+ unsigned long pad;
+};
+
+/*
+ * These are 'magic' values for PTRACE_PEEKUSR that return info about where a
+ * process is located in memory.
+ */
+#define PT_TEXT_ADDR 0x10000
+#define PT_DATA_ADDR 0x10004
+#define PT_TEXT_END_ADDR 0x10008
+
+/* Arbitrarily choose the same ptrace numbers as used by the Sparc code. */
+#define PTRACE_GETREGS 12
+#define PTRACE_SETREGS 13
+#define PTRACE_GETFPREGS 14
+#define PTRACE_SETFPREGS 15
+
+#define PTRACE_GETDSBT 31 /* get the ELF DSBT loadmap address */
+#define PTRACE_GETDSBT_EXEC 0 /* [addr] request the executable loadmap */
+#define PTRACE_GETDSBT_INTERP 1 /* [addr] request the interpreter loadmap */
+
+#ifdef __KERNEL__
+
+#define DEFAULT_CSR 0x0001 /* interrupt enable by default */
+ /* used in /include/asm/processor.h*/
+
+#if !defined(CONFIG_TMS320C64XPLUS) && !defined(CONFIG_TMS320C66X)
+extern unsigned long current_ksp;
+#define user_mode(regs) (((((regs)->sp) ^ current_ksp) >> PAGE_SHIFT) != 0)
+#else
+#define user_mode(regs) ((((regs)->tsr) & 0x40) != 0)
+#endif
+#define instruction_pointer(regs) ((regs)->pc)
+#define profile_pc(regs) instruction_pointer(regs)
+extern void show_regs(struct pt_regs *);
+
+#endif /* __KERNEL__ */
+#endif /* __ASSEMBLY__ */
+#endif /* __ASM_C6X_PTRACE_H */
diff --git a/arch/c6x/include/asm/sizes.h b/arch/c6x/include/asm/sizes.h
new file mode 100644
index 0000000..b0b4f6a
--- /dev/null
+++ b/arch/c6x/include/asm/sizes.h
@@ -0,0 +1,51 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+/* Size defintions
+ * Copyright (C) ARM Limited 1998. All rights reserved.
+ */
+
+#ifndef __sizes_h
+#define __sizes_h 1
+
+/* handy sizes */
+#define SZ_1K 0x00000400
+#define SZ_4K 0x00001000
+#define SZ_8K 0x00002000
+#define SZ_16K 0x00004000
+#define SZ_32K 0x00008000
+#define SZ_64K 0x00010000
+#define SZ_128K 0x00020000
+#define SZ_256K 0x00040000
+#define SZ_512K 0x00080000
+
+#define SZ_1M 0x00100000
+#define SZ_2M 0x00200000
+#define SZ_4M 0x00400000
+#define SZ_8M 0x00800000
+#define SZ_16M 0x01000000
+#define SZ_31M 0x01F00000
+#define SZ_32M 0x02000000
+#define SZ_64M 0x04000000
+#define SZ_128M 0x08000000
+#define SZ_256M 0x10000000
+#define SZ_512M 0x20000000
+
+#define SZ_1G 0x40000000
+#define SZ_2G 0x80000000
+
+#endif
+
+/* END */
diff --git a/arch/c6x/include/asm/string.h b/arch/c6x/include/asm/string.h
new file mode 100644
index 0000000..e9fa53a
--- /dev/null
+++ b/arch/c6x/include/asm/string.h
@@ -0,0 +1,26 @@
+/*
+ * linux/include/asm-c6x/string.h
+ *
+ * Port on Texas Instruments TMS320C6x architecture
+ *
+ * Copyright (C) 2004, 2009 Texas Instruments Incorporated
+ * Author: Aurelien Jacquiot (aurelien.jacquiot at jaluna.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef __ASM_C6X_STRING_H
+#define __ASM_C6X_STRING_H
+
+extern void * memcpy(void *to, const void *from, size_t n);
+extern void * memset(void *s, int c, size_t count);
+extern int memcmp(const void *cs, const void *ct, size_t count);
+extern void *memmove(void *s1, const void *s2, size_t n);
+
+#define __HAVE_ARCH_MEMCPY
+#define __HAVE_ARCH_MEMMOVE
+#define __HAVE_ARCH_MEMSET
+#define __HAVE_ARCH_MEMCMP
+
+#endif /* __ASM_C6X_STRING_H */
diff --git a/arch/c6x/include/asm/types.h b/arch/c6x/include/asm/types.h
new file mode 100644
index 0000000..857c792
--- /dev/null
+++ b/arch/c6x/include/asm/types.h
@@ -0,0 +1,53 @@
+#ifndef __ASM_C6X_TYPES_H
+#define __ASM_C6X_TYPES_H
+
+typedef unsigned short umode_t;
+
+/*
+ * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the
+ * header files exported to user space
+ */
+
+typedef __signed__ char __s8;
+typedef unsigned char __u8;
+
+typedef __signed__ short __s16;
+typedef unsigned short __u16;
+
+typedef __signed__ int __s32;
+typedef unsigned int __u32;
+
+#if defined(__GNUC__)
+__extension__ typedef __signed__ long long __s64;
+__extension__ typedef unsigned long long __u64;
+#endif
+
+/*
+ * These aren't exported outside the kernel to avoid name space clashes
+ */
+#ifdef __KERNEL__
+
+typedef signed char s8;
+typedef unsigned char u8;
+
+typedef signed short s16;
+typedef unsigned short u16;
+
+typedef signed int s32;
+typedef unsigned int u32;
+
+typedef signed long long s64;
+typedef unsigned long long u64;
+
+#define BITS_PER_LONG 32
+
+/* Dma addresses are 32-bits wide. */
+
+typedef u32 dma_addr_t;
+
+typedef unsigned long phys_addr_t;
+typedef unsigned long phys_size_t;
+
+#endif /* __KERNEL__ */
+
+#endif
diff --git a/arch/c6x/include/asm/u-boot.h b/arch/c6x/include/asm/u-boot.h
new file mode 100644
index 0000000..759d976
--- /dev/null
+++ b/arch/c6x/include/asm/u-boot.h
@@ -0,0 +1,57 @@
+/*
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Alex Zuepke <azu@sysgo.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ********************************************************************
+ * NOTE: This header file defines an interface to U-Boot. Including
+ * this (unmodified) header file in another file is considered normal
+ * use of U-Boot, and does *not* fall under the heading of "derived
+ * work".
+ ********************************************************************
+ */
+
+#ifndef _U_BOOT_H_
+#define _U_BOOT_H_ 1
+
+typedef struct bd_info {
+ int bi_baudrate; /* serial console baudrate */
+ unsigned long bi_ip_addr; /* IP Address */
+ ulong bi_arch_number; /* unique id for this board */
+ ulong bi_boot_params; /* where this board expects params */
+ unsigned long bi_arm_freq; /* arm frequency */
+ unsigned long bi_dsp_freq; /* dsp core frequency */
+ unsigned long bi_ddr_freq; /* ddr frequency */
+ struct /* RAM configuration */
+ {
+ ulong start;
+ ulong size;
+ } bi_dram[CONFIG_NR_DRAM_BANKS];
+} bd_t;
+
+/* For image.h:image_check_target_arch() */
+#define IH_ARCH_DEFAULT IH_ARCH_ARM
+
+#endif /* _U_BOOT_H_ */
diff --git a/arch/c6x/include/asm/unaligned.h b/arch/c6x/include/asm/unaligned.h
new file mode 100644
index 0000000..6cecbbb
--- /dev/null
+++ b/arch/c6x/include/asm/unaligned.h
@@ -0,0 +1 @@
+#include <asm-generic/unaligned.h>
diff --git a/arch/c6x/lib/Makefile b/arch/c6x/lib/Makefile
new file mode 100644
index 0000000..8214df7
--- /dev/null
+++ b/arch/c6x/lib/Makefile
@@ -0,0 +1,51 @@
+#
+# (C) Copyright 2000-2006
+# Wolfgang Denk, DENX Software Engineering, wd at denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB = $(obj)lib$(ARCH).o
+
+SOBJS-y += csum_64plus.o memcpy_64plus.o strasgi_64plus.o
+SOBJS-y += unaligned.o divu.o divi.o pop_rts.o push_rts.o remi.o remu.o \
+ strasgi.o llshru.o llshr.o llshl.o negll.o mpyll.o \
+ divremi.o divremu.o delay.o
+
+COBJS-y += memcmp.o memmove.o memset.o divull.o
+
+COBJS-y += board.o
+COBJS-y += bootm.o
+
+SRCS := $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c)
+OBJS := $(addprefix $(obj),$(SOBJS-y) $(COBJS-y))
+
+$(LIB): $(obj).depend $(OBJS)
+ $(call cmd_link_o_target, $(OBJS))
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/arch/c6x/lib/board.c b/arch/c6x/lib/board.c
new file mode 100644
index 0000000..5a8ddb5
--- /dev/null
+++ b/arch/c6x/lib/board.c
@@ -0,0 +1,201 @@
+/*
+ * (C) Copyright 2012 Dmitry Bondar <bond@inmys.ru>
+ *
+ * (C) Copyright 2011
+ * Julius Baxter, julius at opencores.org
+ *
+ * (C) Copyright 2003, Psyent Corporation <www.psyent.com>
+ * Scott McNutt <smcnutt@psyent.com>
+ *
+ * (C) Copyright 2000-2002
+ * Wolfgang Denk, DENX Software Engineering, wd at denx.de.
+ *
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <stdio_dev.h>
+#include <watchdog.h>
+#include <malloc.h>
+#include <mmc.h>
+#include <net.h>
+#ifdef CONFIG_STATUS_LED
+#include <status_led.h>
+#endif
+#ifdef CONFIG_CMD_NAND
+#include <nand.h> /* cannot even include nand.h if it isnt configured */
+#endif
+
+#include <timestamp.h>
+#include <version.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static int display_banner(void)
+{
+ printf("\n\n%s\n\n", version_string);
+ return 0;
+}
+
+#if defined(CONFIG_HARD_I2C) || defined(CONFIG_SOFT_I2C)
+static int init_func_i2c(void)
+{
+ puts("I2C: ");
+ i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
+ puts("ready\n");
+ return 0;
+}
+#endif
+
+
+/*
+ * Initialization sequence
+ */
+extern int print_cpuinfo(void);
+
+static int (* const init_sequence[])(void) = {
+#if defined(CONFIG_ARCH_CPU_INIT)
+ arch_cpu_init, /* basic arch cpu dependent setup */
+#endif
+#if defined(CONFIG_BOARD_EARLY_INIT_F)
+ board_early_init_f,
+#endif
+ timer_init, /* initialize timer */
+ env_init,
+ serial_init,
+ console_init_f,
+
+ display_banner, /* say that we are here */
+#if defined(CONFIG_DISPLAY_CPUINFO)
+ print_cpuinfo, /* display cpu info (and speed) */
+#endif
+#if defined(CONFIG_DISPLAY_BOARDINFO)
+ checkboard, /* display board info */
+#endif
+#if defined(CONFIG_HARD_I2C) || defined(CONFIG_SOFT_I2C)
+ init_func_i2c,
+#endif
+};
+
+
+extern ulong __bss_start;
+extern ulong __bss_end__;
+static int clear_bss(void)
+{
+ ulong dst_addr = (ulong)&__bss_start;
+ size_t len = (size_t)&__bss_end__ - (size_t)&__bss_start;
+ memset((void *)dst_addr, 0x00, len);
+ return 0;
+}
+
+/***********************************************************************/
+void board_init_f(ulong bootflag)
+{
+ bd_t *bd;
+ int i;
+
+ clear_bss();
+
+ gd = (gd_t *)CONFIG_SYS_GBL_DATA_ADDR;
+ __asm__ __volatile__("": : :"memory");
+ memset((void *)gd, 0, GENERATED_GBL_DATA_SIZE);
+
+ gd->bd = (bd_t *)(gd+1); /* At end of global data */
+ gd->baudrate = CONFIG_BAUDRATE;
+
+ bd = gd->bd;
+#ifndef CONFIG_SYS_NO_FLASH
+ bd->bi_flashstart = CONFIG_SYS_FLASH_BASE;
+#endif
+ bd->bi_baudrate = CONFIG_BAUDRATE;
+
+ for (i = 0; i < ARRAY_SIZE(init_sequence); i++) {
+ WATCHDOG_RESET();
+ if (init_sequence[i]())
+ hang();
+ }
+
+ WATCHDOG_RESET();
+
+ /* The Malloc area is immediately below the monitor copy in RAM */
+ mem_malloc_init(CONFIG_SYS_MALLOC_BASE, CONFIG_SYS_MALLOC_LEN);
+
+ board_init();
+
+#ifndef CONFIG_SYS_NO_FLASH
+ WATCHDOG_RESET();
+ bd->bi_flashsize = flash_init();
+#endif
+
+#ifdef CONFIG_CMD_NAND
+ puts("NAND: ");
+ nand_init();
+#endif
+
+#ifdef CONFIG_GENERIC_MMC
+ puts("MMC: ");
+ mmc_initialize(bd);
+#endif
+
+ WATCHDOG_RESET();
+ env_relocate();
+
+ WATCHDOG_RESET();
+ stdio_init();
+ jumptable_init();
+ console_init_r();
+
+ WATCHDOG_RESET();
+/* interrupt_init();*/
+
+#if defined(CONFIG_BOARD_LATE_INIT)
+ board_late_init();
+#endif
+
+#if defined(CONFIG_CMD_NET)
+ puts("NET: ");
+ eth_initialize(bd);
+#endif
+
+ /* main_loop */
+ for (;;) {
+ WATCHDOG_RESET();
+ main_loop();
+ }
+}
+
+
+/***********************************************************************/
+
+void hang(void)
+{
+ disable_interrupts();
+ puts("### ERROR ### Please reset board ###\n");
+
+ for (;;)
+ ;
+}
+
+int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+ reset_cpu(0);
+ return 0;
+}
+
diff --git a/arch/c6x/lib/bootm.c b/arch/c6x/lib/bootm.c
new file mode 100644
index 0000000..4a64ef6
--- /dev/null
+++ b/arch/c6x/lib/bootm.c
@@ -0,0 +1,59 @@
+/*
+ * (C) Copyright 2003, Psyent Corporation <www.psyent.com>
+ * Scott McNutt <smcnutt@psyent.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <command.h>
+
+int disable_interrupts()
+{
+ return 0;
+}
+
+void enable_interrupts()
+{
+}
+
+int do_bootm_linux(int flag, int argc, char * const argv[], bootm_headers_t *images)
+{
+ void (*kernel)() = (void *)images->ep;
+ char *commandline = getenv ("bootargs");
+ if (commandline) {
+ char *dst = (char *)images->ep + 0x1000;
+ strncpy(dst, commandline, 1023);
+ dst[1023] = 0;
+ }
+ {
+ unsigned int *ptr = (unsigned int *)0xc1f00000;
+ ptr[0] = 0x64000001; /*TAG_SOL*/
+ ptr[1] = 0; /*size SOL*/
+ ptr[2] = 0x64000002; /*TAG_EOL*/
+ ptr[3] = 0;
+ }
+ asm("MVKL .S1 0x54694265,A4");
+ asm("MVKH .S1 0x54694265,A4");
+ asm("MVKL .S2 0xc1f00000,B4");
+ asm("MVKH .S2 0xc1f00000,B4");
+ kernel();
+ printf("after kernel\n");
+ return 1;
+}
diff --git a/arch/c6x/lib/csum_64plus.S b/arch/c6x/lib/csum_64plus.S
new file mode 100644
index 0000000..db26ed4
--- /dev/null
+++ b/arch/c6x/lib/csum_64plus.S
@@ -0,0 +1,408 @@
+;
+; linux/arch/c6x/lib/csum_64plus.s
+;
+; Port on Texas Instruments TMS320C6x architecture
+;
+; Copyright (C) 2006, 2009, 2010 Texas Instruments Incorporated
+; Author: Aurelien Jacquiot (aurelien.jacquiot at jaluna.com)
+;
+; This program is free software; you can redistribute it and/or modify
+; it under the terms of the GNU General Public License version 2 as
+; published by the Free Software Foundation.
+;
+
+;
+;unsigned int csum_partial_copy(const char *src, char * dst,
+; int len, int sum)
+;
+; A4: src
+; B4: dst
+; A6: len
+; B6: sum
+; return csum in A4
+;
+
+ .global csum_partial_copy
+ .text
+
+csum_partial_copy:
+ MVC .S2 ILC,B30
+
+ MV .D1X B6,A31 ; given csum
+ ZERO .D1 A9 ; csum (a side)
+|| ZERO .D2 B9 ; csum (b side)
+|| SHRU .S2X A6,2,B5 ; len / 4
+
+ ;; Check alignment and size
+ AND .S1 3,A4,A1
+|| AND .S2 3,B4,B0
+ OR .L2X B0,A1,B0 ; non aligned condition
+|| MVC .S2 B5,ILC
+|| MVK .D2 1,B2
+|| MV .D1X B5,A1 ; words condition
+ [!A1] B .S1 L8
+ [B0] BNOP .S1 L6,5
+
+ SPLOOP 1
+
+ ;; Main loop for aligned words
+ LDW .D1T1 *A4++,A7
+ NOP 4
+ MV .S2X A7,B7
+|| EXTU .S1 A7,0,16,A16
+ STW .D2T2 B7,*B4++
+|| MPYU .M2 B7,B2,B8
+|| ADD .L1 A16,A9,A9
+ NOP
+ SPKERNEL 8,0
+|| ADD .L2 B8,B9,B9
+
+ ZERO .D1 A1
+|| ADD .L1X A9,B9,A9 ; add csum from a and b sides
+
+L6:
+ [!A1] BNOP .S1 L8,5
+
+ ;; Main loop for non-aligned words
+ SPLOOP 2
+ || MVK .L1 1,A2
+
+ LDNW .D1T1 *A4++,A7
+ NOP 3
+
+ NOP
+ MV .S2X A7,B7
+ || EXTU .S1 A7,0,16,A16
+ || MPYU .M1 A7,A2,A8
+
+ ADD .L1 A16,A9,A9
+ SPKERNEL 6,0
+ || STNW .D2T2 B7,*B4++
+ || ADD .L1 A8,A9,A9
+
+L8: AND .S2X 2,A6,B5
+ CMPGT .L2 B5,0,B0
+ [!B0] BNOP .S1 L82,4
+
+ ;; Manage half-word
+ ZERO .L1 A7
+|| ZERO .D1 A8
+
+#ifdef CONFIG_CPU_BIG_ENDIAN
+
+ LDBU .D1T1 *A4++,A7
+ LDBU .D1T1 *A4++,A8
+ NOP 3
+ SHL .S1 A7,8,A0
+ ADD .S1 A8,A9,A9
+ STB .D2T1 A7,*B4++
+|| ADD .S1 A0,A9,A9
+ STB .D2T1 A8,*B4++
+
+#else
+
+ LDBU .D1T1 *A4++,A7
+ LDBU .D1T1 *A4++,A8
+ NOP 3
+ ADD .S1 A7,A9,A9
+ SHL .S1 A8,8,A0
+
+ STB .D2T1 A7,*B4++
+|| ADD .S1 A0,A9,A9
+ STB .D2T1 A8,*B4++
+
+#endif
+
+ ;; Manage eventually the last byte
+L82: AND .S2X 1,A6,B0
+ [!B0] BNOP .S1 L9,5
+
+|| ZERO .L1 A7
+
+L83: LDBU .D1T1 *A4++,A7
+ NOP 4
+
+ MV .L2X A7,B7
+
+#ifdef CONFIG_CPU_BIG_ENDIAN
+
+ STB .D2T2 B7,*B4++
+|| SHL .S1 A7,8,A7
+ ADD .S1 A7,A9,A9
+
+#else
+
+ STB .D2T2 B7,*B4++
+|| ADD .S1 A7,A9,A9
+
+#endif
+
+ ;; Fold the csum
+L9: SHRU .S2X A9,16,B0
+ [!B0] BNOP .S1 L10,5
+
+L91: SHRU .S2X A9,16,B4
+|| EXTU .S1 A9,16,16,A3
+ ADD .D1X A3,B4,A9
+
+ SHRU .S1 A9,16,A0
+ [A0] BNOP .S1 L91,5
+
+L10: ADD .D1 A31,A9,A9
+ MV .D1 A9,A4
+
+ BNOP .S2 B3,4
+ MVC .S2 B30,ILC
+
+ .global csum_partial_copy_old
+ .text
+
+;
+;unsigned short
+;ip_fast_csum(unsigned char *iph, unsigned int ihl)
+;{
+; unsigned int checksum = 0;
+; unsigned short *tosum = (unsigned short *) iph;
+; int len;
+;
+; len = ihl*4;
+;
+; if (len <= 0)
+; return 0;
+;
+; while(len) {
+; len -= 2;
+; checksum += *tosum++;
+; }
+; if (len & 1)
+; checksum += *(unsigned char*) tosum;
+;
+; while(checksum >> 16)
+; checksum = (checksum & 0xffff) + (checksum >> 16);
+;
+; return ~checksum;
+;}
+;
+; A4: iph
+; B4: ihl
+; return checksum in A4
+;
+
+ .global ip_fast_csum
+ .text
+
+ip_fast_csum:
+ ZERO .D1 A5
+ || MVC .S2 ILC,B30
+ SHL .S2 B4,2,B0
+ CMPGT .L2 B0,0,B1
+ [!B1] BNOP .S1 L15,4
+ [!B1] ZERO .D1 A3
+
+ [!B0] B .S1 L12
+ SHRU .S2 B0,1,B0
+ MVC .S2 B0,ILC
+ NOP 3
+
+ SPLOOP 1
+ LDHU .D1T1 *A4++,A3
+ NOP 3
+ NOP
+ SPKERNEL 5,0
+ || ADD .L1 A3,A5,A5
+
+L12: SHRU .S1 A5,16,A0
+ [!A0] BNOP .S1 L14,5
+
+L13: SHRU .S2X A5,16,B4
+ EXTU .S1 A5,16,16,A3
+ ADD .D1X A3,B4,A5
+ SHRU .S1 A5,16,A0
+ [A0] BNOP .S1 L13,5
+
+L14: NOT .D1 A5,A3
+ EXTU .S1 A3,16,16,A3
+
+L15: BNOP .S2 B3,3
+ MVC .S2 B30,ILC
+ MV .D1 A3,A4
+
+;
+;unsigned short
+;do_csum(unsigned char *buff, unsigned int len)
+;{
+; int odd, count;
+; unsigned int result = 0;
+;
+; if (len <= 0)
+; goto out;
+; odd = 1 & (unsigned long) buff;
+; if (odd) {
+;#ifdef __LITTLE_ENDIAN
+; result += (*buff << 8);
+;#else
+; result = *buff;
+;#endif
+; 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 int carry = 0;
+; do {
+; unsigned int w = *(unsigned int *) 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)
+;#ifdef __LITTLE_ENDIAN
+; result += *buff;
+;#else
+; result += (*buff << 8);
+;#endif
+; result = (result & 0xffff) + (result >> 16);
+; /* add up carry.. */
+; result = (result & 0xffff) + (result >> 16);
+; if (odd)
+; result = ((result >> 8) & 0xff) | ((result & 0xff) << 8);
+;out:
+; return result;
+;}
+;
+; A4: buff
+; B4: len
+; return checksum in A4
+;
+ .global do_csum
+ .text
+do_csum:
+ CMPGT .L2 B4,0,B0
+ [!B0] BNOP .S1 L26,3
+ EXTU .S1 A4,31,31,A0
+
+ MV .L1 A0,A3
+|| MV .S1X B3,A5
+|| MV .L2 B4,B3
+|| ZERO .D1 A1
+
+#ifdef CONFIG_CPU_BIG_ENDIAN
+ [A0] SUB .L2 B3,1,B3
+|| [A0] LDBU .D1T1 *A4++,A1
+#else
+ [!A0] BNOP .S1 L21,5
+|| [A0] LDBU .D1T1 *A4++,A0
+ SUB .L2 B3,1,B3
+|| SHL .S1 A0,8,A1
+L21:
+#endif
+ SHR .S2 B3,1,B0
+ [!B0] BNOP .S1 L24,3
+ MVK .L1 2,A0
+ AND .L1 A4,A0,A0
+
+ [!A0] BNOP .S1 L22,5
+|| [A0] LDHU .D1T1 *A4++,A0
+ SUB .L2 B0,1,B0
+|| SUB .S2 B3,2,B3
+|| ADD .L1 A0,A1,A1
+L22:
+ SHR .S2 B0,1,B0
+|| ZERO .L1 A0
+
+ [!B0] BNOP .S1 L23,5
+|| [B0] MVC .S2 B0,ILC
+
+ SPLOOP 3
+ SPMASK L1
+|| MV .L1 A1,A2
+|| LDW .D1T1 *A4++,A1
+
+ NOP 4
+ ADD .L1 A0,A1,A0
+ ADD .L1 A2,A0,A2
+
+ SPKERNEL 1,2
+|| CMPGTU .L1 A1,A2,A0
+
+ ADD .L1 A0,A2,A6
+ EXTU .S1 A6,16,16,A7
+ SHRU .S2X A6,16,B0
+ NOP 1
+ ADD .L1X A7,B0,A1
+L23:
+ MVK .L2 2,B0
+ AND .L2 B3,B0,B0
+ [B0] LDHU .D1T1 *A4++,A0
+ NOP 4
+ [B0] ADD .L1 A0,A1,A1
+L24:
+ EXTU .S2 B3,31,31,B0
+#ifdef CONFIG_CPU_BIG_ENDIAN
+ [!B0] BNOP .S1 L25,4
+|| [B0] LDBU .D1T1 *A4,A0
+ SHL .S1 A0,8,A0
+ ADD .L1 A0,A1,A1
+L25:
+#else
+ [B0] LDBU .D1T1 *A4,A0
+ NOP 4
+ [B0] ADD .L1 A0,A1,A1
+#endif
+ EXTU .S1 A1,16,16,A0
+ SHRU .S2X A1,16,B0
+ NOP 1
+ ADD .L1X A0,B0,A0
+ SHRU .S1 A0,16,A1
+ ADD .L1 A0,A1,A0
+ EXTU .S1 A0,16,16,A1
+ EXTU .S1 A1,16,24,A2
+
+ EXTU .S1 A1,24,16,A0
+|| MV .L2X A3,B0
+
+ [B0] OR .L1 A0,A2,A1
+L26:
+ NOP 1
+ BNOP .S2X A5,4
+ MV .L1 A1,A4
+
+;__wsum csum_partial(const void *buff, int len, __wsum wsum)
+;{
+; unsigned int sum = (__force unsigned int)wsum;
+; unsigned int result = do_csum(buff, len);
+;
+; /* add in old sum, and carry.. */
+; result += sum;
+; if (sum > result)
+; result += 1;
+; return (__force __wsum)result;
+;}
+;
+ .global csum_partial
+csum_partial:
+ MV .L1X B3,A9
+|| CALLP .S2 do_csum,B3
+|| MV .S1 A6,A8
+ BNOP .S2X A9,2
+ ADD .L1 A8,A4,A1
+ CMPGTU .L1 A8,A1,A0
+ ADD .L1 A1,A0,A4
diff --git a/arch/c6x/lib/delay.S b/arch/c6x/lib/delay.S
new file mode 100644
index 0000000..44f2a7f
--- /dev/null
+++ b/arch/c6x/lib/delay.S
@@ -0,0 +1,39 @@
+;
+; linux/arch/c6x/lib/delay.s
+;
+; Port on Texas Instruments TMS320C6x architecture
+;
+; Copyright (C) 2004, 2009, 2010 Texas Instruments Incorporated
+; Author: Aurelien Jacquiot (aurelien.jacquiot at jaluna.com)
+;
+; This program is free software; you can redistribute it and/or modify
+; it under the terms of the GNU General Public License version 2 as
+; published by the Free Software Foundation.
+;
+ .sect ".text"
+ .global _c6x_delay
+
+_c6x_delay:
+ bdec .s1 _c6x_delay,A4
+ nop 5
+ b .s2 B3
+ nop 5
+
+#ifdef CONFIG_TI_C6X_COMPILER
+ ;; this is inlined with gcc
+
+ .global _c6x_tickdelay
+_c6x_tickdelay:
+ mvc .s2 TSCL,B1
+ add .s2x B1,A4,B1
+ || mvk .l2 1,B0
+$0:
+ [B0] b .s2 $0
+ mvc .s2 TSCL,B0
+ sub .s2 B0,B1,B0
+ cmpgt .l2 0,B0,B0
+ nop
+ nop
+ b .s2 B3
+ nop 5
+#endif
diff --git a/arch/c6x/lib/divi.S b/arch/c6x/lib/divi.S
new file mode 100644
index 0000000..cfa1e4c
--- /dev/null
+++ b/arch/c6x/lib/divi.S
@@ -0,0 +1,54 @@
+;; Copyright 2010 Free Software Foundation, Inc.
+;; Contributed by Bernd Schmidt <bernds@codesourcery.com>.
+;;
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2 of the License, or
+;; (at your option) any later version.
+;;
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program; if not, write to the Free Software
+;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ ;; ABI considerations for the divide functions
+ ;; The following registers are call-used:
+ ;; __c6xabi_divi A0,A1,A2,A4,A6,B0,B1,B2,B4,B5
+ ;; __c6xabi_divu A0,A1,A2,A4,A6,B0,B1,B2,B4
+ ;; __c6xabi_remi A1,A2,A4,A5,A6,B0,B1,B2,B4
+ ;; __c6xabi_remu A1,A4,A5,A7,B0,B1,B2,B4
+ ;;
+ ;; In our implementation, divu and remu are leaf functions,
+ ;; while both divi and remi call into divu.
+ ;; A0 is not clobbered by any of the functions.
+ ;; divu does not clobber B2 either, which is taken advantage of
+ ;; in remi.
+ ;; divi uses B5 to hold the original return address during
+ ;; the call to divu.
+ ;; remi uses B2 and A5 to hold the input values during the
+ ;; call to divu. It stores B3 in on the stack.
+
+#ifdef CONFIG_TI_C6X_COMPILER
+ .ref __c6xabi_divu
+#endif
+ .text
+ .global __c6xabi_divi
+__c6xabi_divi:
+ call .s2 __c6xabi_divu
+|| mv .d2 B3, B5
+|| cmpgt .l1 0, A4, A1
+|| cmpgt .l2 0, B4, B1
+
+ [A1] neg .l1 A4, A4
+|| [B1] neg .l2 B4, B4
+|| xor .s1x A1, B1, A1
+ [A1] addkpc .s2 _divu_ret, B3, 4
+_divu_ret:
+ neg .l1 A4, A4
+|| mv .l2 B3,B5
+|| ret .s2 B5
+ nop 5
diff --git a/arch/c6x/lib/divremi.S b/arch/c6x/lib/divremi.S
new file mode 100644
index 0000000..b7664c3
--- /dev/null
+++ b/arch/c6x/lib/divremi.S
@@ -0,0 +1,61 @@
+;; Copyright 2010 Free Software Foundation, Inc.
+;; Contributed by Bernd Schmidt <bernds@codesourcery.com>.
+;;
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2 of the License, or
+;; (at your option) any later version.
+;;
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program; if not, write to the Free Software
+;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+#ifdef CONFIG_TI_C6X_COMPILER
+ .ref __c6xabi_divu
+#endif
+ .text
+ .global __c6xabi_divremi
+
+__c6xabi_divremi:
+ stw .d2t2 B3, *B15--[2]
+|| cmpgt .l1 0, A4, A1
+|| cmpgt .l2 0, B4, B2
+|| mv .s1 A4, A5
+|| call .s2 __c6xabi_divu
+
+ [A1] neg .l1 A4, A4
+|| [B2] neg .l2 B4, B4
+|| xor .s2x B2, A1, B0
+|| mv .d2 B4, B2
+
+ [B0] addkpc .s2 _divu_ret_1, B3, 1
+ [!B0] addkpc .s2 _divu_ret_2, B3, 1
+ nop 2
+_divu_ret_1:
+ neg .l1 A4, A4
+_divu_ret_2:
+ ldw .d2t2 *++B15[2], B3
+
+#if defined(CONFIG_TMS320C64XPLUS) || defined(CONFIG_TMS320C66X)
+ mpy32 .m1x A4, B2, A6
+ nop 3
+ ret .s2 B3
+ sub .l1 A5, A6, A5
+ nop 4
+#else
+ mpyu .m1x A4, B2, A1
+ nop 1
+ mpylhu .m1x A4, B2, A6
+|| mpylhu .m2x B2, A4, B2
+|| ret .s2 B3
+ nop 1
+ add .l1x A6, B2, A6
+ shl .s1 A6, 16, A6
+ add .d1 A6, A1, A6
+ sub .l1 A5, A6, A5
+#endif
diff --git a/arch/c6x/lib/divremu.S b/arch/c6x/lib/divremu.S
new file mode 100644
index 0000000..83e2bb7
--- /dev/null
+++ b/arch/c6x/lib/divremu.S
@@ -0,0 +1,86 @@
+;; Copyright 2011 Free Software Foundation, Inc.
+;; Contributed by Bernd Schmidt <bernds@codesourcery.com>.
+;;
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2 of the License, or
+;; (at your option) any later version.
+;;
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program; if not, write to the Free Software
+;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ .text
+ .global __c6xabi_divremu
+
+__c6xabi_divremu:
+ ;; We use a series of up to 31 subc instructions. First, we find
+ ;; out how many leading zero bits there are in the divisor. This
+ ;; gives us both a shift count for aligning (shifting) the divisor
+ ;; to the, and the number of times we have to execute subc.
+
+ ;; At the end, we have both the remainder and most of the quotient
+ ;; in A4. The top bit of the quotient is computed first and is
+ ;; placed in A2.
+
+ ;; Return immediately if the dividend is zero. Setting B4 to 1
+ ;; is a trick to allow us to leave the following insns in the jump
+ ;; delay slot without affecting the result.
+ mv .s2x A4, B1
+
+[b1] lmbd .l2 1, B4, B1
+||[!b1] b .s2 B3 ; RETURN A
+||[!b1] mvk .d2 1, B4
+
+||[!b1] zero .s1 A5
+ mv .l1x B1, A6
+|| shl .s2 B4, B1, B4
+
+ ;; The loop performs a maximum of 28 steps, so we do the
+ ;; first 3 here.
+ cmpltu .l1x A4, B4, A2
+[!A2] sub .l1x A4, B4, A4
+|| shru .s2 B4, 1, B4
+|| xor .s1 1, A2, A2
+
+ shl .s1 A2, 31, A2
+|| [b1] subc .l1x A4,B4,A4
+|| [b1] add .s2 -1, B1, B1
+[b1] subc .l1x A4,B4,A4
+|| [b1] add .s2 -1, B1, B1
+
+ ;; RETURN A may happen here (note: must happen before the next branch)
+0:
+ cmpgt .l2 B1, 7, B0
+|| [b1] subc .l1x A4,B4,A4
+|| [b1] add .s2 -1, B1, B1
+[b1] subc .l1x A4,B4,A4
+|| [b1] add .s2 -1, B1, B1
+|| [b0] b .s1 0b
+[b1] subc .l1x A4,B4,A4
+|| [b1] add .s2 -1, B1, B1
+[b1] subc .l1x A4,B4,A4
+|| [b1] add .s2 -1, B1, B1
+[b1] subc .l1x A4,B4,A4
+|| [b1] add .s2 -1, B1, B1
+[b1] subc .l1x A4,B4,A4
+|| [b1] add .s2 -1, B1, B1
+[b1] subc .l1x A4,B4,A4
+|| [b1] add .s2 -1, B1, B1
+ ;; loop backwards branch happens here
+
+ ret .s2 B3
+|| mvk .s1 32, A1
+ sub .l1 A1, A6, A6
+|| extu .s1 A4, A6, A5
+ shl .s1 A4, A6, A4
+ shru .s1 A4, 1, A4
+|| sub .l1 A6, 1, A6
+ or .l1 A2, A4, A4
+ shru .s1 A4, A6, A4
+ nop
diff --git a/arch/c6x/lib/divu.S b/arch/c6x/lib/divu.S
new file mode 100644
index 0000000..340b536
--- /dev/null
+++ b/arch/c6x/lib/divu.S
@@ -0,0 +1,100 @@
+;; Copyright 2010 Free Software Foundation, Inc.
+;; Contributed by Bernd Schmidt <bernds@codesourcery.com>.
+;;
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2 of the License, or
+;; (at your option) any later version.
+;;
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program; if not, write to the Free Software
+;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ ;; ABI considerations for the divide functions
+ ;; The following registers are call-used:
+ ;; __c6xabi_divi A0,A1,A2,A4,A6,B0,B1,B2,B4,B5
+ ;; __c6xabi_divu A0,A1,A2,A4,A6,B0,B1,B2,B4
+ ;; __c6xabi_remi A1,A2,A4,A5,A6,B0,B1,B2,B4
+ ;; __c6xabi_remu A1,A4,A5,A7,B0,B1,B2,B4
+ ;;
+ ;; In our implementation, divu and remu are leaf functions,
+ ;; while both divi and remi call into divu.
+ ;; A0 is not clobbered by any of the functions.
+ ;; divu does not clobber B2 either, which is taken advantage of
+ ;; in remi.
+ ;; divi uses B5 to hold the original return address during
+ ;; the call to divu.
+ ;; remi uses B2 and A5 to hold the input values during the
+ ;; call to divu. It stores B3 in on the stack.
+
+#ifdef CONFIG_TI_C6X_COMPILER
+ .def __c6xabi_divu
+#endif
+ .text
+ .global __c6xabi_divu
+__c6xabi_divu:
+ ;; We use a series of up to 31 subc instructions. First, we find
+ ;; out how many leading zero bits there are in the divisor. This
+ ;; gives us both a shift count for aligning (shifting) the divisor
+ ;; to the, and the number of times we have to execute subc.
+
+ ;; At the end, we have both the remainder and most of the quotient
+ ;; in A4. The top bit of the quotient is computed first and is
+ ;; placed in A2.
+
+ ;; Return immediately if the dividend is zero.
+ mv .s2x A4, B1
+ [B1] lmbd .l2 1, B4, B1
+|| [!B1] b .s2 B3 ; RETURN A
+|| [!B1] mvk .d2 1, B4
+ mv .l1x B1, A6
+|| shl .s2 B4, B1, B4
+
+ ;; The loop performs a maximum of 28 steps, so we do the
+ ;; first 3 here.
+ cmpltu .l1x A4, B4, A2
+ [!A2] sub .l1x A4, B4, A4
+|| shru .s2 B4, 1, B4
+|| xor .s1 1, A2, A2
+
+ shl .s1 A2, 31, A2
+|| [B1] subc .l1x A4,B4,A4
+|| [B1] add .s2 -1, B1, B1
+ [B1] subc .l1x A4,B4,A4
+|| [B1] add .s2 -1, B1, B1
+
+ ;; RETURN A may happen here (note: must happen before the next branch)
+_divu_loop:
+ cmpgt .l2 B1, 7, B0
+|| [B1] subc .l1x A4,B4,A4
+|| [B1] add .s2 -1, B1, B1
+ [B1] subc .l1x A4,B4,A4
+|| [B1] add .s2 -1, B1, B1
+|| [B0] b .s1 _divu_loop
+ [B1] subc .l1x A4,B4,A4
+|| [B1] add .s2 -1, B1, B1
+ [B1] subc .l1x A4,B4,A4
+|| [B1] add .s2 -1, B1, B1
+ [B1] subc .l1x A4,B4,A4
+|| [B1] add .s2 -1, B1, B1
+ [B1] subc .l1x A4,B4,A4
+|| [B1] add .s2 -1, B1, B1
+ [B1] subc .l1x A4,B4,A4
+|| [B1] add .s2 -1, B1, B1
+ ;; loop backwards branch happens here
+
+ ret .s2 B3
+|| mvk .s1 32, A1
+ sub .l1 A1, A6, A6
+ shl .s1 A4, A6, A4
+ shru .s1 A4, 1, A4
+|| sub .l1 A6, 1, A6
+ or .l1 A2, A4, A4
+ shru .s1 A4, A6, A4
+ nop
+
diff --git a/arch/c6x/lib/divull.c b/arch/c6x/lib/divull.c
new file mode 100644
index 0000000..8c00edc
--- /dev/null
+++ b/arch/c6x/lib/divull.c
@@ -0,0 +1,336 @@
+/* Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+ 2000, 2001, 2002 Free Software Foundation, Inc.
+
+This code was pulled from an old (GPLv2) libgcc.
+
+This program is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free Software
+Foundation; either version 2, or (at your option) any later version.
+
+In addition to the permissions in the GNU General Public License, the
+Free Software Foundation gives you unlimited permission to link the
+compiled version of this file into combinations with other programs,
+and to distribute those combinations without any restriction coming
+from the use of this file. (The General Public License restrictions
+do apply in other respects; for example, they cover modification of
+the file, and distribution when not linked into a combine
+executable.)
+
+This program is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+#include <linux/types.h>
+#include <linux/bitops.h>
+
+#ifdef CONFIG_TI_C6X_COMPILER
+#define count_leading_zeros(count, x) (count) = _lmbd(1, (x))
+#else
+static inline unsigned __clz(unsigned x)
+{
+ asm(" lmbd .l1 1,%0,%0\n" : "+a"(x));
+ return x;
+}
+#define count_leading_zeros(count, x) (count) = __clz(x)
+#endif
+
+#define W_TYPE_SIZE 32
+
+#define __BITS4 (W_TYPE_SIZE / 4)
+#define __ll_B ((uint32_t) 1 << (W_TYPE_SIZE / 2))
+#define __ll_lowpart(t) ((uint32_t) (t) & (__ll_B - 1))
+#define __ll_highpart(t) ((uint32_t) (t) >> (W_TYPE_SIZE / 2))
+
+
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ do { \
+ uint32_t __x; \
+ __x = (al) - (bl); \
+ (sh) = (ah) - (bh) - (__x > (al)); \
+ (sl) = __x; \
+ } while (0)
+
+#define umul_ppmm(w1, w0, u, v) \
+ do { \
+ uint32_t __x0, __x1, __x2, __x3; \
+ uint16_t __ul, __vl, __uh, __vh; \
+ \
+ __ul = __ll_lowpart(u); \
+ __uh = __ll_highpart(u); \
+ __vl = __ll_lowpart(v); \
+ __vh = __ll_highpart(v); \
+ \
+ __x0 = (uint32_t) __ul * __vl; \
+ __x1 = (uint32_t) __ul * __vh; \
+ __x2 = (uint32_t) __uh * __vl; \
+ __x3 = (uint32_t) __uh * __vh; \
+ \
+ __x1 += __ll_highpart(__x0);/* this can't give carry */ \
+ __x1 += __x2; /* but this indeed can */ \
+ if (__x1 < __x2) /* did we get it? */ \
+ __x3 += __ll_B; /* yes, add it in the proper pos. */ \
+ \
+ (w1) = __x3 + __ll_highpart(__x1); \
+ (w0) = __ll_lowpart(__x1) * __ll_B + __ll_lowpart(__x0); \
+ } while (0)
+
+#define __udiv_qrnnd_c(q, r, n1, n0, d) \
+ do { \
+ uint32_t __d1, __d0, __q1, __q0; \
+ uint32_t __r1, __r0, __m; \
+ __d1 = __ll_highpart(d); \
+ __d0 = __ll_lowpart(d); \
+ \
+ __r1 = (n1) % __d1; \
+ __q1 = (n1) / __d1; \
+ __m = (uint32_t) __q1 * __d0; \
+ __r1 = __r1 * __ll_B | __ll_highpart(n0); \
+ if (__r1 < __m) { \
+ __q1--, __r1 += (d); \
+ /* i.e. we didn't get carry when adding to __r1 */ \
+ if (__r1 >= (d)) \
+ if (__r1 < __m) \
+ __q1--, __r1 += (d); \
+ } \
+ __r1 -= __m; \
+ \
+ __r0 = __r1 % __d1; \
+ __q0 = __r1 / __d1; \
+ __m = (uint32_t) __q0 * __d0; \
+ __r0 = __r0 * __ll_B | __ll_lowpart(n0); \
+ if (__r0 < __m) { \
+ __q0--, __r0 += (d); \
+ if (__r0 >= (d)) \
+ if (__r0 < __m) \
+ __q0--, __r0 += (d); \
+ } \
+ __r0 -= __m; \
+ \
+ (q) = (uint32_t) __q1 * __ll_B | __q0; \
+ (r) = __r0; \
+ } while (0)
+
+#define UDIV_NEEDS_NORMALIZATION 1
+#define udiv_qrnnd __udiv_qrnnd_c
+
+struct llstruct {
+#ifdef CONFIG_CPU_BIG_ENDIAN
+ uint32_t high;
+ uint32_t low;
+#else
+ uint32_t low;
+ uint32_t high;
+#endif
+};
+
+typedef union {
+ struct llstruct s;
+ int64_t ll;
+} llunion_t;
+
+static inline uint64_t __udivmoddi4(uint64_t n, uint64_t d, uint64_t *rp)
+{
+ llunion_t ww;
+ llunion_t nn, dd;
+ llunion_t rr;
+ uint32_t d0, d1, n0, n1, n2;
+ uint32_t q0, q1;
+ uint32_t b, bm;
+
+ nn.ll = n;
+ dd.ll = d;
+
+ d0 = dd.s.low;
+ d1 = dd.s.high;
+ n0 = nn.s.low;
+ n1 = nn.s.high;
+
+#if !UDIV_NEEDS_NORMALIZATION
+ if (d1 == 0) {
+ if (d0 > n1) {
+ /* 0q = nn / 0D */
+
+ udiv_qrnnd(q0, n0, n1, n0, d0);
+ q1 = 0;
+
+ /* Remainder in n0. */
+ } else {
+ /* qq = NN / 0d */
+
+ if (d0 == 0)
+ d0 = 1 / d0; /* Divide intentionally by zero. */
+
+ udiv_qrnnd(q1, n1, 0, n1, d0);
+ udiv_qrnnd(q0, n0, n1, n0, d0);
+
+ /* Remainder in n0. */
+ }
+
+ if (rp != 0) {
+ rr.s.low = n0;
+ rr.s.high = 0;
+ *rp = rr.ll;
+ }
+ }
+
+#else /* UDIV_NEEDS_NORMALIZATION */
+
+ if (d1 == 0) {
+ if (d0 > n1) {
+ /* 0q = nn / 0D */
+
+ count_leading_zeros(bm, d0);
+
+ if (bm != 0) {
+ /* Normalize, i.e. make the most significant
+ bit of the denominator set. */
+
+ d0 = d0 << bm;
+ n1 = (n1 << bm) | (n0 >> (W_TYPE_SIZE - bm));
+ n0 = n0 << bm;
+ }
+
+ udiv_qrnnd(q0, n0, n1, n0, d0);
+ q1 = 0;
+
+ /* Remainder in n0 >> bm. */
+ } else {
+ /* qq = NN / 0d */
+
+ if (d0 == 0)
+ d0 = 1 / d0; /* Divide intentionally by zero. */
+
+ count_leading_zeros(bm, d0);
+
+ if (bm == 0) {
+ /* From (n1 >= d0) /\ (the most significant bit
+ of d0 is set), conclude (the most significant
+ bit of n1 is set) /\ (the leading quotient
+ digit q1 = 1).
+
+ This special case is necessary, not an
+ optimization. (Shifts counts of W_TYPE_SIZE
+ are undefined.) */
+
+ n1 -= d0;
+ q1 = 1;
+ } else {
+ /* Normalize. */
+
+ b = W_TYPE_SIZE - bm;
+
+ d0 = d0 << bm;
+ n2 = n1 >> b;
+ n1 = (n1 << bm) | (n0 >> b);
+ n0 = n0 << bm;
+
+ udiv_qrnnd(q1, n1, n2, n1, d0);
+ }
+
+ /* n1 != d0... */
+
+ udiv_qrnnd(q0, n0, n1, n0, d0);
+
+ /* Remainder in n0 >> bm. */
+ }
+
+ if (rp != 0) {
+ rr.s.low = n0 >> bm;
+ rr.s.high = 0;
+ *rp = rr.ll;
+ }
+ }
+#endif /* UDIV_NEEDS_NORMALIZATION */
+
+ else {
+ if (d1 > n1) {
+ /* 00 = nn / DD */
+
+ q0 = 0;
+ q1 = 0;
+
+ /* Remainder in n1n0. */
+ if (rp != 0) {
+ rr.s.low = n0;
+ rr.s.high = n1;
+ *rp = rr.ll;
+ }
+ } else {
+ /* 0q = NN / dd */
+
+ count_leading_zeros(bm, d1);
+ if (bm == 0) {
+ /* From (n1 >= d1) /\ (the most significant bit
+ of d1 is set), conclude (the most significant
+ bit of n1 is set) /\ (the quotient digit
+ q0 = 0 or 1).
+
+ This special case is necessary, not an
+ optimization. */
+
+ /* The condition on the next line takes
+ advantage of that n1 >= d1 (true due to
+ program flow). */
+ if (n1 > d1 || n0 >= d0) {
+ q0 = 1;
+ sub_ddmmss(n1, n0, n1, n0, d1, d0);
+ } else
+ q0 = 0;
+
+ q1 = 0;
+
+ if (rp != 0) {
+ rr.s.low = n0;
+ rr.s.high = n1;
+ *rp = rr.ll;
+ }
+ } else {
+ uint32_t m1, m0;
+ /* Normalize. */
+
+ b = W_TYPE_SIZE - bm;
+
+ d1 = (d1 << bm) | (d0 >> b);
+ d0 = d0 << bm;
+ n2 = n1 >> b;
+ n1 = (n1 << bm) | (n0 >> b);
+ n0 = n0 << bm;
+
+ udiv_qrnnd(q0, n1, n2, n1, d1);
+ umul_ppmm(m1, m0, q0, d0);
+
+ if (m1 > n1 || (m1 == n1 && m0 > n0)) {
+ q0--;
+ sub_ddmmss(m1, m0, m1, m0, d1, d0);
+ }
+
+ q1 = 0;
+
+ /* Remainder in (n1n0 - m1m0) >> bm. */
+ if (rp != 0) {
+ sub_ddmmss(n1, n0, n1, n0, m1, m0);
+ rr.s.low = (n1 << b) | (n0 >> bm);
+ rr.s.high = n1 >> bm;
+ *rp = rr.ll;
+ }
+ }
+ }
+ }
+
+ ww.s.low = q0;
+ ww.s.high = q1;
+ return ww.ll;
+}
+
+uint64_t
+__c6xabi_divull(uint64_t n, uint64_t d)
+{
+ return __udivmoddi4(n, d, (uint64_t *)0);
+}
+
diff --git a/arch/c6x/lib/llshl.S b/arch/c6x/lib/llshl.S
new file mode 100644
index 0000000..99b739e
--- /dev/null
+++ b/arch/c6x/lib/llshl.S
@@ -0,0 +1,36 @@
+;; Copyright (C) 2010 Texas Instruments Incorporated
+;; Contributed by Mark Salter <msalter@redhat.com>.
+;;
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2 of the License, or
+;; (at your option) any later version.
+;;
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program; if not, write to the Free Software
+;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+;; uint64_t __c6xabi_llshl(uint64_t val, uint shift)
+
+ .text
+ .global __c6xabi_llshl
+__c6xabi_llshl:
+ mv .l1x B4,A1
+ [!A1] b .s2 B3 ; just return if zero shift
+ mvk .s1 32,A0
+ sub .d1 A0,A1,A0
+ cmplt .l1 0,A0,A2
+ [A2] shru .s1 A4,A0,A0
+ [!A2] neg .l1 A0,A5
+|| [A2] shl .s1 A5,A1,A5
+ [!A2] shl .s1 A4,A5,A5
+|| [A2] or .d1 A5,A0,A5
+|| [!A2] mvk .l1 0,A4
+ [A2] shl .s1 A4,A1,A4
+ bnop .s2 B3,5
+
diff --git a/arch/c6x/lib/llshr.S b/arch/c6x/lib/llshr.S
new file mode 100644
index 0000000..989feed
--- /dev/null
+++ b/arch/c6x/lib/llshr.S
@@ -0,0 +1,36 @@
+;; Copyright (C) 2010 Texas Instruments Incorporated
+;; Contributed by Mark Salter <msalter@redhat.com>.
+;;
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2 of the License, or
+;; (at your option) any later version.
+;;
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program; if not, write to the Free Software
+;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+;; uint64_t __c6xabi_llshr(uint64_t val, uint shift)
+
+ .text
+ .global __c6xabi_llshr
+__c6xabi_llshr:
+ mv .l1x B4,A1
+ [!A1] b .s2 B3 ; return if zero shift count
+ mvk .s1 32,A0
+ sub .d1 A0,A1,A0
+ cmplt .l1 0,A0,A2
+ [A2] shl .s1 A5,A0,A0
+ nop
+ [!A2] neg .l1 A0,A4
+|| [A2] shru .s1 A4,A1,A4
+ [!A2] shr .s1 A5,A4,A4
+|| [A2] or .d1 A4,A0,A4
+ [!A2] shr .s1 A5,0x1f,A5
+ [A2] shr .s1 A5,A1,A5
+ bnop .s2 B3,5
diff --git a/arch/c6x/lib/llshru.S b/arch/c6x/lib/llshru.S
new file mode 100644
index 0000000..07a4631
--- /dev/null
+++ b/arch/c6x/lib/llshru.S
@@ -0,0 +1,36 @@
+;; Copyright (C) 2010 Texas Instruments Incorporated
+;; Contributed by Mark Salter <msalter@redhat.com>.
+;;
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2 of the License, or
+;; (at your option) any later version.
+;;
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program; if not, write to the Free Software
+;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+;; uint64_t __c6xabi_llshru(uint64_t val, uint shift)
+
+ .text
+ .global __c6xabi_llshru
+__c6xabi_llshru:
+ mv .l1x B4,A1
+ [!A1] b .s2 B3 ; return if zero shift count
+ mvk .s1 32,A0
+ sub .d1 A0,A1,A0
+ cmplt .l1 0,A0,A2
+ [A2] shl .s1 A5,A0,A0
+ nop
+ [!A2] neg .l1 A0,A4
+|| [A2] shru .s1 A4,A1,A4
+ [!A2] shru .s1 A5,A4,A4
+|| [A2] or .d1 A4,A0,A4
+|| [!A2] mvk .l1 0,A5
+ [A2] shru .s1 A5,A1,A5
+ bnop .s2 B3,5
diff --git a/arch/c6x/lib/memcmp.c b/arch/c6x/lib/memcmp.c
new file mode 100644
index 0000000..e3a98bc
--- /dev/null
+++ b/arch/c6x/lib/memcmp.c
@@ -0,0 +1,24 @@
+/*
+ * linux/arch/c6x/lib/memcmp.c
+ *
+ * Port on Texas Instruments TMS320C6x architecture
+ *
+ * Copyright (C) 2004, 2009 Texas Instruments Incorporated
+ * Author: Aurelien Jacquiot (aurelien.jacquiot at jaluna.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/types.h>
+
+int memcmp(const void *cs, const void *ct, size_t count)
+{
+ const unsigned char *su1, *su2;
+
+ for (su1 = cs, su2 = ct; 0 < count; ++su1, ++su2, count--)
+ if (*su1 != *su2)
+ return (*su1 < *su2) ? -1 : 1;
+ return 0;
+}
+
diff --git a/arch/c6x/lib/memcpy_64plus.S b/arch/c6x/lib/memcpy_64plus.S
new file mode 100644
index 0000000..ce1d7c6
--- /dev/null
+++ b/arch/c6x/lib/memcpy_64plus.S
@@ -0,0 +1,45 @@
+; Port on Texas Instruments TMS320C6x architecture
+;
+; Copyright (C) 2006, 2009, 2010 Texas Instruments Incorporated
+; Author: Aurelien Jacquiot (aurelien.jacquiot at jaluna.com)
+;
+; This program is free software; you can redistribute it and/or modify
+; it under the terms of the GNU General Public License version 2 as
+; published by the Free Software Foundation.
+;
+
+ .global memcpy
+ .text
+
+memcpy:
+ AND .L1 0x1,A6,A0
+ || AND .S1 0x2,A6,A1
+ || AND .L2X 0x4,A6,B0
+ || MV .D1 A4,A3
+ || MVC .S2 ILC,B2
+
+ [A0] LDB .D2T1 *B4++,A5
+ [A1] LDB .D2T1 *B4++,A7
+ [A1] LDB .D2T1 *B4++,A8
+ [B0] LDNW .D2T1 *B4++,A9
+ || SHRU .S2X A6,0x3,B1
+ [!B1] BNOP .S2 B3,1
+
+ [A0] STB .D1T1 A5,*A3++
+ ||[B1] MVC .S2 B1,ILC
+ [A1] STB .D1T1 A7,*A3++
+ [A1] STB .D1T1 A8,*A3++
+ [B0] STNW .D1T1 A9,*A3++ ; return when len < 8
+
+ SPLOOP 2
+
+ LDNDW .D2T1 *B4++,A9:A8
+ NOP 3
+
+ NOP
+ SPKERNEL 0,0
+ || STNDW .D1T1 A9:A8,*A3++
+
+ BNOP .S2 B3,4
+ MVC .S2 B2,ILC
+
diff --git a/arch/c6x/lib/memmove.c b/arch/c6x/lib/memmove.c
new file mode 100644
index 0000000..5672937
--- /dev/null
+++ b/arch/c6x/lib/memmove.c
@@ -0,0 +1,30 @@
+/*
+ * linux/arch/c6x/lib/memmove.c
+ *
+ * Port on Texas Instruments TMS320C6x architecture
+ *
+ * Copyright (C) 2005, 2009 Texas Instruments Incorporated
+ * Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/types.h>
+#include <linux/string.h>
+
+void *memmove(void *s1, const void *s2, size_t n)
+{
+ register char *s = (char *) s1;
+ register const char *p = (const char *) s2;
+
+ if (p >= s) {
+ return memcpy(s, p, n);
+ } else {
+ while (n) {
+ --n;
+ s[n] = p[n];
+ }
+ }
+ return s1;
+}
diff --git a/arch/c6x/lib/memset.c b/arch/c6x/lib/memset.c
new file mode 100644
index 0000000..da4275b
--- /dev/null
+++ b/arch/c6x/lib/memset.c
@@ -0,0 +1,20 @@
+/*
+ * linux/arch/c6x/lib/memcmp.c
+ *
+ * Port on Texas Instruments TMS320C6x architecture
+ *
+ * Copyright (C) 2004, 2009 Texas Instruments Incorporated
+ * Author: Aurelien Jacquiot (aurelien.jacquiot at jaluna.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/types.h>
+void *memset(void *mem, register int ch, register size_t length)
+{
+ register char *m = (char *)mem - 1;
+ while (length--)
+ *++m = ch;
+ return mem;
+}
diff --git a/arch/c6x/lib/mpyll.S b/arch/c6x/lib/mpyll.S
new file mode 100644
index 0000000..8da8417
--- /dev/null
+++ b/arch/c6x/lib/mpyll.S
@@ -0,0 +1,47 @@
+;; Copyright (C) 2010 Texas Instruments Incorporated
+;; Contributed by Mark Salter <msalter@redhat.com>.
+;;
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2 of the License, or
+;; (at your option) any later version.
+;;
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program; if not, write to the Free Software
+;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ ;; uint64_t __c6xabi_mpyll(uint64_t x, uint64_t y)
+ ;;
+ ;; 64x64 multiply
+ ;; First compute partial results using 32-bit parts of x and y:
+ ;;
+ ;; b63 b32 b31 b0
+ ;; -----------------------------
+ ;; | 1 | 0 |
+ ;; -----------------------------
+ ;;
+ ;; P0 = X0*Y0
+ ;; P1 = X0*Y1 + X1*Y0
+ ;; P2 = X1*Y1
+ ;;
+ ;; result = (P2 << 64) + (P1 << 32) + P0
+ ;;
+ ;; Since the result is also 64-bit, we can skip the P2 term.
+
+ .text
+ .global __c6xabi_mpyll
+__c6xabi_mpyll:
+ mpy32u .m1x A4,B4,A1:A0 ; X0*Y0
+ b .s2 B3
+ || mpy32u .m2x B5,A4,B1:B0 ; X0*Y1 (don't need upper 32-bits)
+ || mpy32u .m1x A5,B4,A3:A2 ; X1*Y0 (don't need upper 32-bits)
+ nop
+ nop
+ mv .s1 A0,A4
+ add .l1x A2,B0,A5
+ add .s1 A1,A5,A5
diff --git a/arch/c6x/lib/negll.S b/arch/c6x/lib/negll.S
new file mode 100644
index 0000000..7747521
--- /dev/null
+++ b/arch/c6x/lib/negll.S
@@ -0,0 +1,29 @@
+;; Copyright (C) 2010 Texas Instruments Incorporated
+;; Contributed by Mark Salter <msalter@redhat.com>.
+;;
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2 of the License, or
+;; (at your option) any later version.
+;;
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program; if not, write to the Free Software
+;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+;; int64_t __c6xabi_negll(int64_t val)
+
+ .text
+ .global __c6xabi_negll
+__c6xabi_negll:
+ b .s2 B3
+ mvk .l1 0,A0
+ subu .l1 A0,A4,A3:A2
+ sub .l1 A0,A5,A0
+|| ext .s1 A3,24,24,A5
+ add .l1 A5,A0,A5
+ mv .s1 A2,A4
diff --git a/arch/c6x/lib/pop_rts.S b/arch/c6x/lib/pop_rts.S
new file mode 100644
index 0000000..e1847fb
--- /dev/null
+++ b/arch/c6x/lib/pop_rts.S
@@ -0,0 +1,30 @@
+;; Copyright 2010 Free Software Foundation, Inc.
+;; Contributed by Bernd Schmidt <bernds@codesourcery.com>.
+;;
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2 of the License, or
+;; (at your option) any later version.
+;;
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program; if not, write to the Free Software
+;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ .text
+ .global __c6xabi_pop_rts
+
+__c6xabi_pop_rts:
+ lddw .d2t2 *++B15, B3:B2
+ lddw .d2t1 *++B15, A11:A10
+ lddw .d2t2 *++B15, B11:B10
+ lddw .d2t1 *++B15, A13:A12
+ lddw .d2t2 *++B15, B13:B12
+ lddw .d2t1 *++B15, A15:A14
+|| b .s2 B3
+ ldw .d2t2 *++B15[2], B14
+ nop 4
diff --git a/arch/c6x/lib/push_rts.S b/arch/c6x/lib/push_rts.S
new file mode 100644
index 0000000..637d56a
--- /dev/null
+++ b/arch/c6x/lib/push_rts.S
@@ -0,0 +1,28 @@
+;; Copyright 2010 Free Software Foundation, Inc.
+;; Contributed by Bernd Schmidt <bernds@codesourcery.com>.
+;;
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2 of the License, or
+;; (at your option) any later version.
+;;
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program; if not, write to the Free Software
+;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ .text
+ .global __c6xabi_push_rts
+__c6xabi_push_rts:
+ stw .d2t2 B14, *B15--[2]
+ stdw .d2t1 A15:A14, *B15--
+|| b .s2x A3
+ stdw .d2t2 B13:B12, *B15--
+ stdw .d2t1 A13:A12, *B15--
+ stdw .d2t2 B11:B10, *B15--
+ stdw .d2t1 A11:A10, *B15--
+ stdw .d2t2 B3:B2, *B15--
diff --git a/arch/c6x/lib/remi.S b/arch/c6x/lib/remi.S
new file mode 100644
index 0000000..2760d77
--- /dev/null
+++ b/arch/c6x/lib/remi.S
@@ -0,0 +1,78 @@
+;; Copyright 2010, 2011 Free Software Foundation, Inc.
+;; Contributed by Bernd Schmidt <bernds@codesourcery.com>.
+;;
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2 of the License, or
+;; (at your option) any later version.
+;;
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program; if not, write to the Free Software
+;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ ;; ABI considerations for the divide functions
+ ;; The following registers are call-used:
+ ;; __c6xabi_divi A0,A1,A2,A4,A6,B0,B1,B2,B4,B5
+ ;; __c6xabi_divu A0,A1,A2,A4,A6,B0,B1,B2,B4
+ ;; __c6xabi_remi A1,A2,A4,A5,A6,B0,B1,B2,B4
+ ;; __c6xabi_remu A1,A4,A5,A7,B0,B1,B2,B4
+ ;;
+ ;; In our implementation, divu and remu are leaf functions,
+ ;; while both divi and remi call into divu.
+ ;; A0 is not clobbered by any of the functions.
+ ;; divu does not clobber B2 either, which is taken advantage of
+ ;; in remi.
+ ;; divi uses B5 to hold the original return address during
+ ;; the call to divu.
+ ;; remi uses B2 and A5 to hold the input values during the
+ ;; call to divu. It stores B3 in on the stack.
+
+#ifdef CONFIG_TI_C6X_COMPILER
+ .ref __c6xabi_divu
+#endif
+ .text
+ .global __c6xabi_remi
+
+__c6xabi_remi:
+ stw .d2t2 B3, *B15--[2]
+|| cmpgt .l1 0, A4, A1
+|| cmpgt .l2 0, B4, B2
+|| mv .s1 A4, A5
+|| call .s2 __c6xabi_divu
+
+ [A1] neg .l1 A4, A4
+|| [B2] neg .l2 B4, B4
+|| xor .s2x B2, A1, B0
+|| mv .d2 B4, B2
+
+ [B0] addkpc .s2 _divu_ret_1, B3, 1
+ [!B0] addkpc .s2 _divu_ret_2, B3, 1
+ nop 2
+_divu_ret_1:
+ neg .l1 A4, A4
+_divu_ret_2:
+ ldw .d2t2 *++B15[2], B3
+
+#if defined(CONFIG_TMS320C64XPLUS) || defined(CONFIG_TMS320C66X)
+ mpy32 .m1x A4, B2, A6
+ nop 3
+ ret .s2 B3
+ sub .l1 A5, A6, A4
+ nop 4
+#else
+ mpyu .m1x A4, B2, A1
+ nop 1
+ mpylhu .m1x A4, B2, A6
+|| mpylhu .m2x B2, A4, B2
+|| ret .s2 B3
+ nop 1
+ add .l1x A6, B2, A6
+ shl .s1 A6, 16, A6
+ add .d1 A6, A1, A6
+ sub .l1 A5, A6, A4
+#endif
diff --git a/arch/c6x/lib/remu.S b/arch/c6x/lib/remu.S
new file mode 100644
index 0000000..e1d9f30
--- /dev/null
+++ b/arch/c6x/lib/remu.S
@@ -0,0 +1,81 @@
+;; Copyright 2010 Free Software Foundation, Inc.
+;; Contributed by Bernd Schmidt <bernds@codesourcery.com>.
+;;
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2 of the License, or
+;; (at your option) any later version.
+;;
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program; if not, write to the Free Software
+;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ ;; ABI considerations for the divide functions
+ ;; The following registers are call-used:
+ ;; __c6xabi_divi A0,A1,A2,A4,A6,B0,B1,B2,B4,B5
+ ;; __c6xabi_divu A0,A1,A2,A4,A6,B0,B1,B2,B4
+ ;; __c6xabi_remi A1,A2,A4,A5,A6,B0,B1,B2,B4
+ ;; __c6xabi_remu A1,A4,A5,A7,B0,B1,B2,B4
+ ;;
+ ;; In our implementation, divu and remu are leaf functions,
+ ;; while both divi and remi call into divu.
+ ;; A0 is not clobbered by any of the functions.
+ ;; divu does not clobber B2 either, which is taken advantage of
+ ;; in remi.
+ ;; divi uses B5 to hold the original return address during
+ ;; the call to divu.
+ ;; remi uses B2 and A5 to hold the input values during the
+ ;; call to divu. It stores B3 in on the stack.
+
+
+ .text
+ .global __c6xabi_remu
+
+__c6xabi_remu:
+ ;; The ABI seems designed to prevent these functions calling each other,
+ ;; so we duplicate most of the divsi3 code here.
+ mv .s2x A4, B1
+ lmbd .l2 1, B4, B1
+|| [!B1] b .s2 B3 ; RETURN A
+|| [!B1] mvk .d2 1, B4
+
+ mv .l1x B1, A7
+|| shl .s2 B4, B1, B4
+
+ cmpltu .l1x A4, B4, A1
+ [!A1] sub .l1x A4, B4, A4
+ shru .s2 B4, 1, B4
+
+_remu_loop:
+ cmpgt .l2 B1, 7, B0
+|| [B1] subc .l1x A4,B4,A4
+|| [B1] add .s2 -1, B1, B1
+ ;; RETURN A may happen here (note: must happen before the next branch)
+ [B1] subc .l1x A4,B4,A4
+|| [B1] add .s2 -1, B1, B1
+|| [B0] b .s1 _remu_loop
+ [B1] subc .l1x A4,B4,A4
+|| [B1] add .s2 -1, B1, B1
+ [B1] subc .l1x A4,B4,A4
+|| [B1] add .s2 -1, B1, B1
+ [B1] subc .l1x A4,B4,A4
+|| [B1] add .s2 -1, B1, B1
+ [B1] subc .l1x A4,B4,A4
+|| [B1] add .s2 -1, B1, B1
+ [B1] subc .l1x A4,B4,A4
+|| [B1] add .s2 -1, B1, B1
+ ;; loop backwards branch happens here
+
+ ret .s2 B3
+ [B1] subc .l1x A4,B4,A4
+|| [B1] add .s2 -1, B1, B1
+ [B1] subc .l1x A4,B4,A4
+
+ extu .s1 A4, A7, A4
+ nop 2
+
diff --git a/arch/c6x/lib/strasgi.S b/arch/c6x/lib/strasgi.S
new file mode 100644
index 0000000..6861e25
--- /dev/null
+++ b/arch/c6x/lib/strasgi.S
@@ -0,0 +1,88 @@
+;; Copyright 2010 Free Software Foundation, Inc.
+;; Contributed by Bernd Schmidt <bernds@codesourcery.com>.
+;;
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2 of the License, or
+;; (at your option) any later version.
+;;
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program; if not, write to the Free Software
+;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ .text
+ .global __c6xabi_strasgi
+
+__c6xabi_strasgi:
+
+ ;; This is essentially memcpy, with alignment known to be at least
+ ;; 4, and the size a multiple of 4 greater than or equal to 28.
+ ldw .d2t1 *B4++, A0
+|| mvk .s2 16, B1
+ ldw .d2t1 *B4++, A1
+|| mvk .s2 20, B2
+|| sub .d1 A6, 24, A6
+ ldw .d2t1 *B4++, A5
+ ldw .d2t1 *B4++, A7
+|| mv .l2x A6, B7
+ ldw .d2t1 *B4++, A8
+ ldw .d2t1 *B4++, A9
+|| mv .s2x A0, B5
+|| cmpltu .l2 B2, B7, B0
+
+_strasgi_loop:
+ stw .d1t2 B5, *A4++
+|| [B0] ldw .d2t1 *B4++, A0
+|| mv .s2x A1, B5
+|| mv .l2 B7, B6
+
+ [B0] sub .d2 B6, 24, B7
+|| [B0] b .s2 _strasgi_loop
+|| cmpltu .l2 B1, B6, B0
+
+ [B0] ldw .d2t1 *B4++, A1
+|| stw .d1t2 B5, *A4++
+|| mv .s2x A5, B5
+|| cmpltu .l2 12, B6, B0
+
+ [B0] ldw .d2t1 *B4++, A5
+|| stw .d1t2 B5, *A4++
+|| mv .s2x A7, B5
+|| cmpltu .l2 8, B6, B0
+
+ [B0] ldw .d2t1 *B4++, A7
+|| stw .d1t2 B5, *A4++
+|| mv .s2x A8, B5
+|| cmpltu .l2 4, B6, B0
+
+ [B0] ldw .d2t1 *B4++, A8
+|| stw .d1t2 B5, *A4++
+|| mv .s2x A9, B5
+|| cmpltu .l2 0, B6, B0
+
+ [B0] ldw .d2t1 *B4++, A9
+|| stw .d1t2 B5, *A4++
+|| mv .s2x A0, B5
+|| cmpltu .l2 B2, B7, B0
+
+ ;; loop back branch happens here
+
+ cmpltu .l2 B1, B6, B0
+|| ret .s2 b3
+
+ [B0] stw .d1t1 A1, *A4++
+|| cmpltu .l2 12, B6, B0
+ [B0] stw .d1t1 A5, *A4++
+|| cmpltu .l2 8, B6, B0
+ [B0] stw .d1t1 A7, *A4++
+|| cmpltu .l2 4, B6, B0
+ [B0] stw .d1t1 A8, *A4++
+|| cmpltu .l2 0, B6, B0
+ [B0] stw .d1t1 A9, *A4++
+
+ ;; return happens here
diff --git a/arch/c6x/lib/strasgi_64plus.S b/arch/c6x/lib/strasgi_64plus.S
new file mode 100644
index 0000000..cbeab22
--- /dev/null
+++ b/arch/c6x/lib/strasgi_64plus.S
@@ -0,0 +1,37 @@
+;; Copyright 2010 Free Software Foundation, Inc.
+;; Contributed by Bernd Schmidt <bernds@codesourcery.com>.
+;;
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2 of the License, or
+;; (at your option) any later version.
+;;
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program; if not, write to the Free Software
+;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ .text
+ .global __c6xabi_strasgi_64plus
+
+__c6xabi_strasgi_64plus:
+ shru .s2x a6, 2, b31
+|| mv .s1 a4, a30
+|| mv .d2 b4, b30
+
+ add .s2 -4, b31, b31
+
+ sploopd 1
+|| mvc .s2 b31, ilc
+ ldw .d2t2 *b30++, b31
+ nop 4
+ mv .s1x b31,a31
+ spkernel 6, 0
+|| stw .d1t1 a31, *a30++
+
+ ret .s2 b3
+ nop 5
diff --git a/arch/c6x/lib/unaligned.S b/arch/c6x/lib/unaligned.S
new file mode 100644
index 0000000..a825b4d
--- /dev/null
+++ b/arch/c6x/lib/unaligned.S
@@ -0,0 +1,117 @@
+;
+; arch/c6x/kernel/unaligned.S
+;
+; Port on Texas Instruments TMS320C6x architecture
+;
+; Copyright (C) 2010 Texas Instruments Incorporated
+; Author: Mark Salter (msalter at redhat.com)
+;
+; This program is free software; you can redistribute it and/or modify
+; it under the terms of the GNU General Public License version 2 as
+; published by the Free Software Foundation.
+;
+
+ .text
+ .global get_unaligned_le64
+ .global get_unaligned_be64
+ .global get_unaligned_le32
+ .global get_unaligned_be32
+ .global put_unaligned_le64
+ .global put_unaligned_be64
+ .global put_unaligned_le32
+ .global put_unaligned_be32
+
+; u64 get_unaligned_le64(void *ptr);
+; u64 get_unaligned_be64(void *ptr);
+;
+#ifdef CONFIG_CPU_BIG_ENDIAN
+get_unaligned_le64:
+#else
+get_unaligned_be64:
+#endif
+ LDNDW .D1T1 *A4,A5:A4
+ NOP 2
+ BNOP .S2 B3,1
+ MV .D2X A4,B0
+ SWAP2 .S2 B0,B1
+ || SWAP2 .S1 A5,A0
+ SWAP4 .L2 B1,B0
+ || SWAP4 .L1 A0,A4
+ MV .D1X B0,A5
+
+#ifdef CONFIG_CPU_BIG_ENDIAN
+get_unaligned_be64:
+#else
+get_unaligned_le64:
+#endif
+ BNOP .S2 B3,5
+ || LDNDW .D1T1 *A4,A5:A4
+
+; u32 get_unaligned_le32(void *ptr, int size);
+; u32 get_unaligned_be32(void *ptr, int size);
+;
+#ifdef CONFIG_CPU_BIG_ENDIAN
+get_unaligned_le32:
+#else
+get_unaligned_be32:
+#endif
+ LDNW .D1T1 *A4,A4
+ BNOP .S2 B3,3
+ SWAP2 .S1 A4,A0
+ SWAP4 .L1 A0,A4
+
+#ifdef CONFIG_CPU_BIG_ENDIAN
+get_unaligned_be32:
+#else
+get_unaligned_le32:
+#endif
+ BNOP .S2 B3,5
+ || LDNW .D1T1 *A4,A4
+
+
+; void put_unaligned_le64(u64 val, void *ptr);
+; void put_unaligned_be64(u64 val, void *ptr);
+;
+#ifdef CONFIG_CPU_BIG_ENDIAN
+put_unaligned_le64:
+#else
+put_unaligned_be64:
+#endif
+ B .S2 B3
+ MV .D2X A4,B0
+ SWAP2 .S2 B0,B1
+ || SWAP2 .S1 A5,A0
+ SWAP4 .L2 B1,B0
+ || SWAP4 .L1 A0,A4
+ MV .D1X B0,A5
+ STNDW .D2T1 A5:A4,*B4
+
+#ifdef CONFIG_CPU_BIG_ENDIAN
+put_unaligned_be64:
+#else
+put_unaligned_le64:
+#endif
+ BNOP .S2 B3,5
+ || STNDW .D2T1 A5:A4,*B4
+
+; void put_unaligned_le32(u32 val, void *ptr);
+; void put_unaligned_be32(u32 val, void *ptr);
+;
+#ifdef CONFIG_CPU_BIG_ENDIAN
+put_unaligned_le32:
+#else
+put_unaligned_be32:
+#endif
+ BNOP .S2 B3,2
+ SWAP2 .S1 A4,A5
+ SWAP4 .L1 A5,A4
+ STNW .D2T1 A4,*B4
+
+#ifdef CONFIG_CPU_BIG_ENDIAN
+put_unaligned_be32:
+#else
+put_unaligned_le32:
+#endif
+ BNOP .S2 B3,5
+ || STNW .D2T1 A4,*B4
+
diff --git a/common/cmd_bdinfo.c b/common/cmd_bdinfo.c
index 42f08fd..faf534b 100644
--- a/common/cmd_bdinfo.c
+++ b/common/cmd_bdinfo.c
@@ -513,6 +513,11 @@ int do_bdinfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])

return 0;
}
+#elif defined(CONFIG_C6X)
+int do_bdinfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+ return 0;
+}

#else
#error "a case for this architecture does not exist!"
diff --git a/common/image.c b/common/image.c
index 91954ac..0fff687 100644
--- a/common/image.c
+++ b/common/image.c
@@ -456,8 +456,12 @@ phys_size_t getenv_bootm_size(void)
#if defined(CONFIG_ARM)
return gd->bd->bi_dram[0].size - tmp;
#else
+#if defined(CONFIG_C6X)
+ return gd->bd->bi_dram[0].size - tmp;
+#else
return gd->bd->bi_memsize - tmp;
#endif
+#endif
}

phys_size_t getenv_bootm_mapsize(void)
diff --git a/examples/standalone/stubs.c b/examples/standalone/stubs.c
index 15e9afc..c9e0819 100644
--- a/examples/standalone/stubs.c
+++ b/examples/standalone/stubs.c
@@ -195,6 +195,21 @@ gd_t *global_data;
" l.jr r13\n" \
" l.nop\n" \
: : "i"(offsetof(gd_t, jt)), "i"(XF_ ## x * sizeof(void *)) : "r13");
+
+#elif defined(CONFIG_C6X)
+/*
+ * b31 holds the pointer to the global_data, a0 is a call-clobbered
+ * register
+ */
+#define EXPORT_FUNC(x) \
+ asm volatile ( \
+" .globl " #x "\n" \
+#x ":\n" \
+" B .S2X A0\n" \
+" NOP 3\n" \
+ : : "i"(offsetof(gd_t, jt)), "i"(XF_ ## x * sizeof(void *)) : "A0");
+
+
#else
/*" addi $sp, $sp, -24\n" \
" br $r16\n" \*/
--
1.7.2.5