uboot/post/lib_powerpc/b.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2002
   3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
   4 *
   5 * See file CREDITS for list of people who contributed to this
   6 * project.
   7 *
   8 * This program is free software; you can redistribute it and/or
   9 * modify it under the terms of the GNU General Public License as
  10 * published by the Free Software Foundation; either version 2 of
  11 * the License, or (at your option) any later version.
  12 *
  13 * This program is distributed in the hope that it will be useful,
  14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16 * GNU General Public License for more details.
  17 *
  18 * You should have received a copy of the GNU General Public License
  19 * along with this program; if not, write to the Free Software
  20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  21 * MA 02111-1307 USA
  22 */
  23
  24#include <common.h>
  25
  26/*
  27 * CPU test
  28 * Branch instructions:         b, bl, bc
  29 *
  30 * The first 2 instructions (b, bl) are verified by jumping
  31 * to a fixed address and checking whether control was transfered
  32 * to that very point. For the bl instruction the value of the
  33 * link register is checked as well (using mfspr).
  34 * To verify the bc instruction various combinations of the BI/BO
  35 * fields, the CTR and the condition register values are
  36 * checked. The list of such combinations is pre-built and
  37 * linked in U-Boot at build time.
  38 */
  39
  40#include <post.h>
  41#include "cpu_asm.h"
  42
  43#if CONFIG_POST & CONFIG_SYS_POST_CPU
  44
  45extern void cpu_post_exec_11 (ulong *code, ulong *res, ulong op1);
  46extern void cpu_post_exec_31 (ulong *code, ulong *ctr, ulong *lr, ulong *jump,
  47    ulong cr);
  48
  49static int cpu_post_test_bc (ulong cmd, ulong bo, ulong bi,
  50    int pjump, int decr, int link, ulong pctr, ulong cr)
  51{
  52    int ret = 0;
  53    ulong lr = 0;
  54    ulong ctr = pctr;
  55    ulong jump;
  56
  57    unsigned long code[] =
  58    {
  59        ASM_MTCR(6),
  60        ASM_MFLR(6),
  61        ASM_MTCTR(3),
  62        ASM_MTLR(4),
  63        ASM_LI(5, 1),
  64        ASM_3O(cmd, bo, bi, 8),
  65        ASM_LI(5, 0),
  66        ASM_MFCTR(3),
  67        ASM_MFLR(4),
  68        ASM_MTLR(6),
  69        ASM_BLR,
  70    };
  71
  72    cpu_post_exec_31 (code, &ctr, &lr, &jump, cr);
  73
  74    if (ret == 0)
  75        ret = pjump == jump ? 0 : -1;
  76    if (ret == 0)
  77    {
  78        if (decr)
  79            ret = pctr == ctr + 1 ? 0 : -1;
  80        else
  81            ret = pctr == ctr ? 0 : -1;
  82    }
  83    if (ret == 0)
  84    {
  85        if (link)
  86            ret = lr == (ulong) code + 24 ? 0 : -1;
  87        else
  88            ret = lr == 0 ? 0 : -1;
  89    }
  90
  91    return ret;
  92}
  93
  94int cpu_post_test_b (void)
  95{
  96    int ret = 0;
  97    unsigned int i;
  98    int flag = disable_interrupts();
  99
 100    if (ret == 0)
 101    {
 102        ulong code[] =
 103        {
 104           ASM_MFLR(4),
 105           ASM_MTLR(3),
 106           ASM_B(4),
 107           ASM_MFLR(3),
 108           ASM_MTLR(4),
 109           ASM_BLR,
 110        };
 111        ulong res;
 112
 113        cpu_post_exec_11 (code, &res, 0);
 114
 115        ret = res == 0 ? 0 : -1;
 116
 117        if (ret != 0)
 118        {
 119            post_log ("Error at b1 test !\n");
 120        }
 121    }
 122
 123    if (ret == 0)
 124    {
 125        ulong code[] =
 126        {
 127           ASM_MFLR(4),
 128           ASM_MTLR(3),
 129           ASM_BL(4),
 130           ASM_MFLR(3),
 131           ASM_MTLR(4),
 132           ASM_BLR,
 133        };
 134        ulong res;
 135
 136        cpu_post_exec_11 (code, &res, 0);
 137
 138        ret = res == (ulong)code + 12 ? 0 : -1;
 139
 140        if (ret != 0)
 141        {
 142            post_log ("Error at b2 test !\n");
 143        }
 144    }
 145
 146    if (ret == 0)
 147    {
 148        ulong cc, cd;
 149        int cond;
 150        ulong ctr;
 151        int link;
 152
 153        i = 0;
 154
 155        for (cc = 0; cc < 4 && ret == 0; cc++)
 156        {
 157            for (cd = 0; cd < 4 && ret == 0; cd++)
 158            {
 159                for (link = 0; link <= 1 && ret == 0; link++)
 160                {
 161                    for (cond = 0; cond <= 1 && ret == 0; cond++)
 162                    {
 163                        for (ctr = 1; ctr <= 2 && ret == 0; ctr++)
 164                        {
 165                            int decr = cd < 2;
 166                            int cr = cond ? 0x80000000 : 0x00000000;
 167                            int jumpc = cc >= 2 ||
 168                                        (cc == 0 && !cond) ||
 169                                        (cc == 1 && cond);
 170                            int jumpd = cd >= 2 ||
 171                                        (cd == 0 && ctr != 1) ||
 172                                        (cd == 1 && ctr == 1);
 173                            int jump = jumpc && jumpd;
 174
 175                            ret = cpu_post_test_bc (link ? OP_BCL : OP_BC,
 176                                (cc << 3) + (cd << 1), 0, jump, decr, link,
 177                                ctr, cr);
 178
 179                            if (ret != 0)
 180                            {
 181                                post_log ("Error at b3 test %d !\n", i);
 182                            }
 183
 184                            i++;
 185                        }
 186                    }
 187                }
 188            }
 189        }
 190    }
 191
 192    if (flag)
 193        enable_interrupts();
 194
 195    return ret;
 196}
 197
 198#endif
 199