/*
 * U-boot - bf533_string.c Contains library routines.
 *
 * Copyright (c) 2005 blackfin.uclinux.org
 *
 * (C) Copyright 2000-2004
 * Wolfgang Denk, DENX Software Engineering, wd@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 <asm/setup.h>
#include <asm/page.h>
#include <config.h>
#include <asm/blackfin.h>

extern void blackfin_icache_flush_range(const void *, const void *);
extern void blackfin_dcache_flush_range(const void *, const void *);
extern void *memcpy_ASM(void *dest, const void *src, size_t count);

void *dma_memcpy(void *, const void *, size_t);

char *strcpy(char *dest, const char *src)
{
	char *xdest = dest;
	char temp = 0;

	__asm__ __volatile__
	    ("1:\t%2 = B [%1++] (Z);\n\t"
	     "B [%0++] = %2;\n\t"
	     "CC = %2;\n\t"
	     "if cc jump 1b (bp);\n":"=a"(dest), "=a"(src), "=d"(temp)
	     :"0"(dest), "1"(src), "2"(temp):"memory");

	return xdest;
}

char *strncpy(char *dest, const char *src, size_t n)
{
	char *xdest = dest;
	char temp = 0;

	if (n == 0)
		return xdest;

	__asm__ __volatile__
	    ("1:\t%3 = B [%1++] (Z);\n\t"
	     "B [%0++] = %3;\n\t"
	     "CC = %3;\n\t"
	     "if ! cc jump 2f;\n\t"
	     "%2 += -1;\n\t"
	     "CC = %2 == 0;\n\t"
	     "if ! cc jump 1b (bp);\n"
	     "2:\n":"=a"(dest), "=a"(src), "=da"(n), "=d"(temp)
	     :"0"(dest), "1"(src), "2"(n), "3"(temp)
	     :"memory");

	return xdest;
}

int strcmp(const char *cs, const char *ct)
{
	char __res1, __res2;

	__asm__("1:\t%2 = B[%0++] (Z);\n\t"	/* get *cs */
		"%3 = B[%1++] (Z);\n\t"	/* get *ct */
		"CC = %2 == %3;\n\t"	/* compare a byte */
		"if ! cc jump 2f;\n\t"	/* not equal, break out */
		"CC = %2;\n\t"	/* at end of cs? */
		"if cc jump 1b (bp);\n\t"	/* no, keep going */
		"jump.s 3f;\n"	/* strings are equal */
		"2:\t%2 = %2 - %3;\n"	/* *cs - *ct */
      "3:\n":	"=a"(cs), "=a"(ct), "=d"(__res1), "=d"(__res2)
      :	"0"(cs), "1"(ct));

	return __res1;
}

int strncmp(const char *cs, const char *ct, size_t count)
{
	char __res1, __res2;

	if (!count)
		return 0;

	__asm__("1:\t%3 = B[%0++] (Z);\n\t"	/* get *cs */
		"%4 = B[%1++] (Z);\n\t"	/* get *ct */
		"CC = %3 == %4;\n\t"	/* compare a byte */
		"if ! cc jump 3f;\n\t"	/* not equal, break out */
		"CC = %3;\n\t"	/* at end of cs? */
		"if ! cc jump 4f;\n\t"	/* yes, all done */
		"%2 += -1;\n\t"	/* no, adjust count */
		"CC = %2 == 0;\n\t" "if ! cc jump 1b;\n"	/* more to do, keep going */
		"2:\t%3 = 0;\n\t"	/* strings are equal */
		"jump.s    4f;\n" "3:\t%3 = %3 - %4;\n"	/* *cs - *ct */
      "4:":	"=a"(cs), "=a"(ct), "=da"(count), "=d"(__res1),
		"=d"(__res2)
      :	"0"(cs), "1"(ct), "2"(count));

	return __res1;
}

/*
 * memcpy - Copy one area of memory to another
 * @dest: Where to copy to
 * @src: Where to copy from
 * @count: The size of the area.
 *
 * You should not use this function to access IO space, use memcpy_toio()
 * or memcpy_fromio() instead.
 */
void *memcpy(void *dest, const void *src, size_t count)
{
	char *tmp = (char *)dest, *s = (char *)src;

	/* L1_ISRAM can only be accessed via dma */
	if ((tmp >= (char *)L1_ISRAM) && (tmp < (char *)L1_ISRAM_END)) {
		/* L1 is the destination */
		dma_memcpy(dest, src, count);

		if (icache_status()) {
			blackfin_icache_flush_range(src, src + count);
		}
	} else if ((s >= (char *)L1_ISRAM) && (s < (char *)L1_ISRAM_END)) {
		/* L1 is the source */
		dma_memcpy(dest, src, count);

		if (icache_status()) {
			blackfin_icache_flush_range(dest, dest + count);
		}
		if (dcache_status()) {
			blackfin_dcache_flush_range(dest, dest + count);
		}
	} else {
		memcpy_ASM(dest, src, count);
	}
	return dest;
}

void *dma_memcpy(void *dest, const void *src, size_t count)
{
	*pMDMA_D0_IRQ_STATUS = DMA_DONE | DMA_ERR;

	/* Copy sram functions from sdram to sram */
	/* Setup destination start address */
	*pMDMA_D0_START_ADDR = (volatile void **)dest;
	/* Setup destination xcount */
	*pMDMA_D0_X_COUNT = count;
	/* Setup destination xmodify */
	*pMDMA_D0_X_MODIFY = 1;

	/* Setup Source start address */
	*pMDMA_S0_START_ADDR = (volatile void **)src;
	/* Setup Source xcount */
	*pMDMA_S0_X_COUNT = count;
	/* Setup Source xmodify */
	*pMDMA_S0_X_MODIFY = 1;

	/* Enable source DMA */
	*pMDMA_S0_CONFIG = (DMAEN);
	__builtin_bfin_ssync();

	*pMDMA_D0_CONFIG = (WNR | DMAEN);

	while (*pMDMA_D0_IRQ_STATUS & DMA_RUN) {
		*pMDMA_D0_IRQ_STATUS |= (DMA_DONE | DMA_ERR);
	}
	*pMDMA_D0_IRQ_STATUS |= (DMA_DONE | DMA_ERR);

	dest += count;
	src += count;
	return dest;
}
