/*
 * (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
 * Branch instructions:		b, bl, bc
 *
 * The first 2 instructions (b, bl) are verified by jumping
 * to a fixed address and checking whether control was transfered
 * to that very point. For the bl instruction the value of the
 * link register is checked as well (using mfspr).
 * To verify the bc instruction various combinations of the BI/BO
 * fields, the CTR and the condition register values are
 * checked. The list of such combinations is pre-built and
 * linked in U-Boot at build time.
 */

#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_31 (ulong *code, ulong *ctr, ulong *lr, ulong *jump,
    ulong cr);

static int cpu_post_test_bc (ulong cmd, ulong bo, ulong bi,
    int pjump, int decr, int link, ulong pctr, ulong cr)
{
    int ret = 0;
    ulong lr = 0;
    ulong ctr = pctr;
    ulong jump;

    unsigned long code[] =
    {
	ASM_MTCR(6),
	ASM_MFLR(6),
	ASM_MTCTR(3),
	ASM_MTLR(4),
	ASM_LI(5, 1),
	ASM_3O(cmd, bo, bi, 8),
	ASM_LI(5, 0),
	ASM_MFCTR(3),
	ASM_MFLR(4),
	ASM_MTLR(6),
	ASM_BLR,
    };

    cpu_post_exec_31 (code, &ctr, &lr, &jump, cr);

    if (ret == 0)
	ret = pjump == jump ? 0 : -1;
    if (ret == 0)
    {
	if (decr)
	    ret = pctr == ctr + 1 ? 0 : -1;
	else
	    ret = pctr == ctr ? 0 : -1;
    }
    if (ret == 0)
    {
	if (link)
	    ret = lr == (ulong) code + 24 ? 0 : -1;
	else
	    ret = lr == 0 ? 0 : -1;
    }

    return ret;
}

int cpu_post_test_b (void)
{
    int ret = 0;
    unsigned int i;

    if (ret == 0)
    {
	ulong code[] =
	{
	   ASM_MFLR(4),
	   ASM_MTLR(3),
	   ASM_B(4),
	   ASM_MFLR(3),
	   ASM_MTLR(4),
	   ASM_BLR,
	};
	ulong res;

	cpu_post_exec_11 (code, &res, 0);

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

	if (ret != 0)
	{
	    post_log ("Error at b1 test !\n");
	}
    }

    if (ret == 0)
    {
	ulong code[] =
	{
	   ASM_MFLR(4),
	   ASM_MTLR(3),
	   ASM_BL(4),
	   ASM_MFLR(3),
	   ASM_MTLR(4),
	   ASM_BLR,
	};
	ulong res;

	cpu_post_exec_11 (code, &res, 0);

	ret = res == (ulong)code + 12 ? 0 : -1;

	if (ret != 0)
	{
	    post_log ("Error at b2 test !\n");
	}
    }

    if (ret == 0)
    {
	ulong cc, cd;
	int cond;
	ulong ctr;
	int link;

	i = 0;

	for (cc = 0; cc < 4 && ret == 0; cc++)
	{
	    for (cd = 0; cd < 4 && ret == 0; cd++)
	    {
		for (link = 0; link <= 1 && ret == 0; link++)
		{
		    for (cond = 0; cond <= 1 && ret == 0; cond++)
		    {
			for (ctr = 1; ctr <= 2 && ret == 0; ctr++)
			{
			    int decr = cd < 2;
			    int cr = cond ? 0x80000000 : 0x00000000;
			    int jumpc = cc >= 2 ||
					(cc == 0 && !cond) ||
					(cc == 1 && cond);
			    int jumpd = cd >= 2 ||
					(cd == 0 && ctr != 1) ||
					(cd == 1 && ctr == 1);
			    int jump = jumpc && jumpd;

			    ret = cpu_post_test_bc (link ? OP_BCL : OP_BC,
				(cc << 3) + (cd << 1), 0, jump, decr, link,
				ctr, cr);

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

			    i++;
			}
		    }
		}
	    }
	}
    }

    return ret;
}

#endif
#endif
