/*
 * (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
