/*
 * (C) Copyright 2002
 * 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>

/*
 * CPU test
 * Condition register istructions:	mtcr, mfcr, mcrxr,
 *					crand, crandc, cror, crorc, crxor,
 *					crnand, crnor, creqv, mcrf
 *
 * The mtcrf/mfcr instructions is tested by loading different
 * values into the condition register (mtcrf), moving its value
 * to a general-purpose register (mfcr) and comparing this value
 * with the expected one.
 * The mcrxr instruction is tested by loading a fixed value
 * into the XER register (mtspr), moving XER value to the
 * condition register (mcrxr), moving it to a general-purpose
 * register (mfcr) and comparing the value of this register with
 * the expected one.
 * The rest of instructions is tested by loading a fixed
 * value into the condition register (mtcrf), executing each
 * instruction several times to modify all 4-bit condition
 * fields, moving the value of the conditional register to a
 * general-purpose register (mfcr) and comparing it with the
 * expected one.
 */

#ifdef CONFIG_POST

#include <post.h>
#include "cpu_asm.h"

#if CONFIG_POST & CFG_POST_CPU

extern void cpu_post_exec_11 (ulong *code, ulong *res, ulong op1);
extern void cpu_post_exec_21x (ulong *code, ulong *op1, ulong *op2, ulong op3);

static ulong cpu_post_cr_table1[] =
{
    0xaaaaaaaa,
    0x55555555,
};
static unsigned int cpu_post_cr_size1 =
    sizeof (cpu_post_cr_table1) / sizeof (ulong);

static struct cpu_post_cr_s2 {
    ulong xer;
    ulong cr;
} cpu_post_cr_table2[] =
{
    {
	0xa0000000,
	1
    },
    {
	0x40000000,
	5
    },
};
static unsigned int cpu_post_cr_size2 =
    sizeof (cpu_post_cr_table2) / sizeof (struct cpu_post_cr_s2);

static struct cpu_post_cr_s3 {
    ulong cr;
    ulong cs;
    ulong cd;
    ulong res;
} cpu_post_cr_table3[] =
{
    {
	0x01234567,
	0,
	4,
	0x01230567
    },
    {
	0x01234567,
	7,
	0,
	0x71234567
    },
};
static unsigned int cpu_post_cr_size3 =
    sizeof (cpu_post_cr_table3) / sizeof (struct cpu_post_cr_s3);

static struct cpu_post_cr_s4 {
    ulong cmd;
    ulong cr;
    ulong op1;
    ulong op2;
    ulong op3;
    ulong res;
} cpu_post_cr_table4[] =
{
    {
	OP_CRAND,
	0x0000ffff,
	0,
	16,
	0,
	0x0000ffff
    },
    {
	OP_CRAND,
	0x0000ffff,
	16,
	17,
	0,
	0x8000ffff
    },
    {
	OP_CRANDC,
	0x0000ffff,
	0,
	16,
	0,
	0x0000ffff
    },
    {
	OP_CRANDC,
	0x0000ffff,
	16,
	0,
	0,
	0x8000ffff
    },
    {
	OP_CROR,
	0x0000ffff,
	0,
	16,
	0,
	0x8000ffff
    },
    {
	OP_CROR,
	0x0000ffff,
	0,
	1,
	0,
	0x0000ffff
    },
    {
	OP_CRORC,
	0x0000ffff,
	0,
	16,
	0,
	0x0000ffff
    },
    {
	OP_CRORC,
	0x0000ffff,
	0,
	0,
	0,
	0x8000ffff
    },
    {
	OP_CRXOR,
	0x0000ffff,
	0,
	0,
	0,
	0x0000ffff
    },
    {
	OP_CRXOR,
	0x0000ffff,
	0,
	16,
	0,
	0x8000ffff
    },
    {
	OP_CRNAND,
	0x0000ffff,
	0,
	16,
	0,
	0x8000ffff
    },
    {
	OP_CRNAND,
	0x0000ffff,
	16,
	17,
	0,
	0x0000ffff
    },
    {
	OP_CRNOR,
	0x0000ffff,
	0,
	16,
	0,
	0x0000ffff
    },
    {
	OP_CRNOR,
	0x0000ffff,
	0,
	1,
	0,
	0x8000ffff
    },
    {
	OP_CREQV,
	0x0000ffff,
	0,
	0,
	0,
	0x8000ffff
    },
    {
	OP_CREQV,
	0x0000ffff,
	0,
	16,
	0,
	0x0000ffff
    },
};
static unsigned int cpu_post_cr_size4 =
    sizeof (cpu_post_cr_table4) / sizeof (struct cpu_post_cr_s4);

int cpu_post_test_cr (void)
{
    int ret = 0;
    unsigned int i;
    unsigned long cr_sav;

    asm ( "mfcr %0" : "=r" (cr_sav) : );

    for (i = 0; i < cpu_post_cr_size1 && ret == 0; i++)
    {
	ulong cr = cpu_post_cr_table1[i];
	ulong res;

	unsigned long code[] =
	{
	    ASM_MTCR(3),
	    ASM_MFCR(3),
	    ASM_BLR,
	};

	cpu_post_exec_11 (code, &res, cr);

	ret = res == cr ? 0 : -1;

	if (ret != 0)
	{
	    post_log ("Error at cr1 test %d !\n", i);
	}
    }

    for (i = 0; i < cpu_post_cr_size2 && ret == 0; i++)
    {
	struct cpu_post_cr_s2 *test = cpu_post_cr_table2 + i;
	ulong res;
	ulong xer;

	unsigned long code[] =
	{
	    ASM_MTXER(3),
	    ASM_MCRXR(test->cr),
	    ASM_MFCR(3),
	    ASM_MFXER(4),
	    ASM_BLR,
	};

	cpu_post_exec_21x (code, &res, &xer, test->xer);

	ret = xer == 0 && ((res << (4 * test->cr)) & 0xe0000000) == test->xer ?
	      0 : -1;

	if (ret != 0)
	{
	    post_log ("Error at cr2 test %d !\n", i);
	}
    }

    for (i = 0; i < cpu_post_cr_size3 && ret == 0; i++)
    {
	struct cpu_post_cr_s3 *test = cpu_post_cr_table3 + i;
	ulong res;

	unsigned long code[] =
	{
	    ASM_MTCR(3),
	    ASM_MCRF(test->cd, test->cs),
	    ASM_MFCR(3),
	    ASM_BLR,
	};

	cpu_post_exec_11 (code, &res, test->cr);

	ret = res == test->res ? 0 : -1;

	if (ret != 0)
	{
	    post_log ("Error at cr3 test %d !\n", i);
	}
    }

    for (i = 0; i < cpu_post_cr_size4 && ret == 0; i++)
    {
	struct cpu_post_cr_s4 *test = cpu_post_cr_table4 + i;
	ulong res;

	unsigned long code[] =
	{
	    ASM_MTCR(3),
	    ASM_12F(test->cmd, test->op3, test->op1, test->op2),
	    ASM_MFCR(3),
	    ASM_BLR,
	};

	cpu_post_exec_11 (code, &res, test->cr);

	ret = res == test->res ? 0 : -1;

	if (ret != 0)
	{
	    post_log ("Error at cr4 test %d !\n", i);
	}
    }

    asm ( "mtcr %0" : : "r" (cr_sav));

    return ret;
}

#endif
#endif
