uboot/post/lib_powerpc/b.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * (C) Copyright 2002
   4 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
   5 */
   6
   7#include <common.h>
   8
   9/*
  10 * CPU test
  11 * Branch instructions:         b, bl, bc
  12 *
  13 * The first 2 instructions (b, bl) are verified by jumping
  14 * to a fixed address and checking whether control was transferred
  15 * to that very point. For the bl instruction the value of the
  16 * link register is checked as well (using mfspr).
  17 * To verify the bc instruction various combinations of the BI/BO
  18 * fields, the CTR and the condition register values are
  19 * checked. The list of such combinations is pre-built and
  20 * linked in U-Boot at build time.
  21 */
  22
  23#include <post.h>
  24#include "cpu_asm.h"
  25
  26#if CONFIG_POST & CONFIG_SYS_POST_CPU
  27
  28extern void cpu_post_exec_11 (ulong *code, ulong *res, ulong op1);
  29extern void cpu_post_exec_31 (ulong *code, ulong *ctr, ulong *lr, ulong *jump,
  30    ulong cr);
  31
  32static int cpu_post_test_bc (ulong cmd, ulong bo, ulong bi,
  33    int pjump, int decr, int link, ulong pctr, ulong cr)
  34{
  35    int ret = 0;
  36    ulong lr = 0;
  37    ulong ctr = pctr;
  38    ulong jump;
  39
  40    unsigned long code[] =
  41    {
  42        ASM_MTCR(6),
  43        ASM_MFLR(6),
  44        ASM_MTCTR(3),
  45        ASM_MTLR(4),
  46        ASM_LI(5, 1),
  47        ASM_3O(cmd, bo, bi, 8),
  48        ASM_LI(5, 0),
  49        ASM_MFCTR(3),
  50        ASM_MFLR(4),
  51        ASM_MTLR(6),
  52        ASM_BLR,
  53    };
  54
  55    cpu_post_exec_31 (code, &ctr, &lr, &jump, cr);
  56
  57    if (ret == 0)
  58        ret = pjump == jump ? 0 : -1;
  59    if (ret == 0)
  60    {
  61        if (decr)
  62            ret = pctr == ctr + 1 ? 0 : -1;
  63        else
  64            ret = pctr == ctr ? 0 : -1;
  65    }
  66    if (ret == 0)
  67    {
  68        if (link)
  69            ret = lr == (ulong) code + 24 ? 0 : -1;
  70        else
  71            ret = lr == 0 ? 0 : -1;
  72    }
  73
  74    return ret;
  75}
  76
  77int cpu_post_test_b (void)
  78{
  79    int ret = 0;
  80    unsigned int i;
  81    int flag = disable_interrupts();
  82
  83    if (ret == 0)
  84    {
  85        ulong code[] =
  86        {
  87           ASM_MFLR(4),
  88           ASM_MTLR(3),
  89           ASM_B(4),
  90           ASM_MFLR(3),
  91           ASM_MTLR(4),
  92           ASM_BLR,
  93        };
  94        ulong res;
  95
  96        cpu_post_exec_11 (code, &res, 0);
  97
  98        ret = res == 0 ? 0 : -1;
  99
 100        if (ret != 0)
 101        {
 102            post_log ("Error at b1 test !\n");
 103        }
 104    }
 105
 106    if (ret == 0)
 107    {
 108        ulong code[] =
 109        {
 110           ASM_MFLR(4),
 111           ASM_MTLR(3),
 112           ASM_BL(4),
 113           ASM_MFLR(3),
 114           ASM_MTLR(4),
 115           ASM_BLR,
 116        };
 117        ulong res;
 118
 119        cpu_post_exec_11 (code, &res, 0);
 120
 121        ret = res == (ulong)code + 12 ? 0 : -1;
 122
 123        if (ret != 0)
 124        {
 125            post_log ("Error at b2 test !\n");
 126        }
 127    }
 128
 129    if (ret == 0)
 130    {
 131        ulong cc, cd;
 132        int cond;
 133        ulong ctr;
 134        int link;
 135
 136        i = 0;
 137
 138        for (cc = 0; cc < 4 && ret == 0; cc++)
 139        {
 140            for (cd = 0; cd < 4 && ret == 0; cd++)
 141            {
 142                for (link = 0; link <= 1 && ret == 0; link++)
 143                {
 144                    for (cond = 0; cond <= 1 && ret == 0; cond++)
 145                    {
 146                        for (ctr = 1; ctr <= 2 && ret == 0; ctr++)
 147                        {
 148                            int decr = cd < 2;
 149                            int cr = cond ? 0x80000000 : 0x00000000;
 150                            int jumpc = cc >= 2 ||
 151                                        (cc == 0 && !cond) ||
 152                                        (cc == 1 && cond);
 153                            int jumpd = cd >= 2 ||
 154                                        (cd == 0 && ctr != 1) ||
 155                                        (cd == 1 && ctr == 1);
 156                            int jump = jumpc && jumpd;
 157
 158                            ret = cpu_post_test_bc (link ? OP_BCL : OP_BC,
 159                                (cc << 3) + (cd << 1), 0, jump, decr, link,
 160                                ctr, cr);
 161
 162                            if (ret != 0)
 163                            {
 164                                post_log ("Error at b3 test %d !\n", i);
 165                            }
 166
 167                            i++;
 168                        }
 169                    }
 170                }
 171            }
 172        }
 173    }
 174
 175    if (flag)
 176        enable_interrupts();
 177
 178    return ret;
 179}
 180
 181#endif
 182