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

#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;
    int flag = disable_interrupts();

    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));

    if (flag)
	enable_interrupts();

    return ret;
}

#endif
