uboot/post/cpu/ppc4xx/spr.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2007
   3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
   4 *
   5 * Author: Igor Lisitsin <igor@emcraft.com>
   6 *
   7 * See file CREDITS for list of people who contributed to this
   8 * project.
   9 *
  10 * This program is free software; you can redistribute it and/or
  11 * modify it under the terms of the GNU General Public License as
  12 * published by the Free Software Foundation; either version 2 of
  13 * the License, or (at your option) any later version.
  14 *
  15 * This program is distributed in the hope that it will be useful,
  16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18 * GNU General Public License for more details.
  19 *
  20 * You should have received a copy of the GNU General Public License
  21 * along with this program; if not, write to the Free Software
  22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  23 * MA 02111-1307 USA
  24 */
  25
  26#include <common.h>
  27
  28/*
  29 * SPR test
  30 *
  31 * The test checks the contents of Special Purpose Registers (SPR) listed
  32 * in the spr_test_list array below.
  33 * Each SPR value is read using mfspr instruction, some bits are masked
  34 * according to the table and the resulting value is compared to the
  35 * corresponding table value.
  36 */
  37
  38#include <post.h>
  39
  40#if CONFIG_POST & CONFIG_SYS_POST_SPR
  41
  42#include <asm/processor.h>
  43
  44#ifdef CONFIG_4xx_DCACHE
  45#include <asm/mmu.h>
  46
  47DECLARE_GLOBAL_DATA_PTR;
  48#endif
  49
  50static struct {
  51        int number;
  52        char * name;
  53        unsigned long mask;
  54        unsigned long value;
  55} spr_test_list [] = {
  56        /* Standard Special-Purpose Registers */
  57
  58        {0x001, "XER",          0x00000000,     0x00000000},
  59        {0x008, "LR",           0x00000000,     0x00000000},
  60        {0x009, "CTR",          0x00000000,     0x00000000},
  61        {0x016, "DEC",          0x00000000,     0x00000000},
  62        {0x01a, "SRR0",         0x00000000,     0x00000000},
  63        {0x01b, "SRR1",         0x00000000,     0x00000000},
  64        {0x110, "SPRG0",        0x00000000,     0x00000000},
  65        {0x111, "SPRG1",        0x00000000,     0x00000000},
  66        {0x112, "SPRG2",        0x00000000,     0x00000000},
  67        {0x113, "SPRG3",        0x00000000,     0x00000000},
  68        {0x11f, "PVR",          0x00000000,     0x00000000},
  69
  70        /* Additional Special-Purpose Registers.
  71         * The values must match the initialization
  72         * values from cpu/ppc4xx/start.S
  73         */
  74        {0x30,  "PID",          0x00000000,     0x00000000},
  75        {0x3a,  "CSRR0",        0x00000000,     0x00000000},
  76        {0x3b,  "CSRR1",        0x00000000,     0x00000000},
  77        {0x3d,  "DEAR",         0x00000000,     0x00000000},
  78        {0x3e,  "ESR",          0x00000000,     0x00000000},
  79#ifdef CONFIG_440
  80        {0x3f,  "IVPR",         0xffff0000,     0x00000000},
  81#endif
  82        {0x100, "USPRG0",       0x00000000,     0x00000000},
  83        {0x104, "SPRG4",        0x00000000,     0x00000000},
  84        {0x105, "SPRG5",        0x00000000,     0x00000000},
  85        {0x106, "SPRG6",        0x00000000,     0x00000000},
  86        {0x107, "SPRG7",        0x00000000,     0x00000000},
  87        {0x10c, "TBL",          0x00000000,     0x00000000},
  88        {0x10d, "TBU",          0x00000000,     0x00000000},
  89#ifdef CONFIG_440
  90        {0x11e, "PIR",          0x0000000f,     0x00000000},
  91#endif
  92        {0x130, "DBSR",         0x00000000,     0x00000000},
  93        {0x134, "DBCR0",        0x00000000,     0x00000000},
  94        {0x135, "DBCR1",        0x00000000,     0x00000000},
  95        {0x136, "DBCR2",        0x00000000,     0x00000000},
  96        {0x138, "IAC1",         0x00000000,     0x00000000},
  97        {0x139, "IAC2",         0x00000000,     0x00000000},
  98        {0x13a, "IAC3",         0x00000000,     0x00000000},
  99        {0x13b, "IAC4",         0x00000000,     0x00000000},
 100        {0x13c, "DAC1",         0x00000000,     0x00000000},
 101        {0x13d, "DAC2",         0x00000000,     0x00000000},
 102        {0x13e, "DVC1",         0x00000000,     0x00000000},
 103        {0x13f, "DVC2",         0x00000000,     0x00000000},
 104        {0x150, "TSR",          0x00000000,     0x00000000},
 105        {0x154, "TCR",          0x00000000,     0x00000000},
 106#ifdef CONFIG_440
 107        {0x190, "IVOR0",        0x0000fff0,     0x00000100},
 108        {0x191, "IVOR1",        0x0000fff0,     0x00000200},
 109        {0x192, "IVOR2",        0x0000fff0,     0x00000300},
 110        {0x193, "IVOR3",        0x0000fff0,     0x00000400},
 111        {0x194, "IVOR4",        0x0000fff0,     0x00000500},
 112        {0x195, "IVOR5",        0x0000fff0,     0x00000600},
 113        {0x196, "IVOR6",        0x0000fff0,     0x00000700},
 114        {0x197, "IVOR7",        0x0000fff0,     0x00000800},
 115        {0x198, "IVOR8",        0x0000fff0,     0x00000c00},
 116        {0x199, "IVOR9",        0x00000000,     0x00000000},
 117        {0x19a, "IVOR10",       0x0000fff0,     0x00000900},
 118        {0x19b, "IVOR11",       0x00000000,     0x00000000},
 119        {0x19c, "IVOR12",       0x00000000,     0x00000000},
 120        {0x19d, "IVOR13",       0x0000fff0,     0x00001300},
 121        {0x19e, "IVOR14",       0x0000fff0,     0x00001400},
 122        {0x19f, "IVOR15",       0x0000fff0,     0x00002000},
 123#endif
 124        {0x23a, "MCSRR0",       0x00000000,     0x00000000},
 125        {0x23b, "MCSRR1",       0x00000000,     0x00000000},
 126        {0x23c, "MCSR",         0x00000000,     0x00000000},
 127        {0x370, "INV0",         0x00000000,     0x00000000},
 128        {0x371, "INV1",         0x00000000,     0x00000000},
 129        {0x372, "INV2",         0x00000000,     0x00000000},
 130        {0x373, "INV3",         0x00000000,     0x00000000},
 131        {0x374, "ITV0",         0x00000000,     0x00000000},
 132        {0x375, "ITV1",         0x00000000,     0x00000000},
 133        {0x376, "ITV2",         0x00000000,     0x00000000},
 134        {0x377, "ITV3",         0x00000000,     0x00000000},
 135        {0x378, "CCR1",         0x00000000,     0x00000000},
 136        {0x390, "DNV0",         0x00000000,     0x00000000},
 137        {0x391, "DNV1",         0x00000000,     0x00000000},
 138        {0x392, "DNV2",         0x00000000,     0x00000000},
 139        {0x393, "DNV3",         0x00000000,     0x00000000},
 140        {0x394, "DTV0",         0x00000000,     0x00000000},
 141        {0x395, "DTV1",         0x00000000,     0x00000000},
 142        {0x396, "DTV2",         0x00000000,     0x00000000},
 143        {0x397, "DTV3",         0x00000000,     0x00000000},
 144#ifdef CONFIG_440
 145        {0x398, "DVLIM",        0x0fc1f83f,     0x0001f800},
 146        {0x399, "IVLIM",        0x0fc1f83f,     0x0001f800},
 147#endif
 148        {0x39b, "RSTCFG",       0x00000000,     0x00000000},
 149        {0x39c, "DCDBTRL",      0x00000000,     0x00000000},
 150        {0x39d, "DCDBTRH",      0x00000000,     0x00000000},
 151        {0x39e, "ICDBTRL",      0x00000000,     0x00000000},
 152        {0x39f, "ICDBTRH",      0x00000000,     0x00000000},
 153        {0x3b2, "MMUCR",        0x00000000,     0x00000000},
 154        {0x3b3, "CCR0",         0x00000000,     0x00000000},
 155        {0x3d3, "ICDBDR",       0x00000000,     0x00000000},
 156        {0x3f3, "DBDR",         0x00000000,     0x00000000},
 157};
 158
 159static int spr_test_list_size =
 160                sizeof (spr_test_list) / sizeof (spr_test_list[0]);
 161
 162int spr_post_test (int flags)
 163{
 164        int ret = 0;
 165        int i;
 166
 167        unsigned long code[] = {
 168                0x7c6002a6,                             /* mfspr r3,SPR */
 169                0x4e800020                              /* blr          */
 170        };
 171        unsigned long (*get_spr) (void) = (void *) code;
 172
 173#ifdef CONFIG_4xx_DCACHE
 174        /* disable cache */
 175        change_tlb(gd->bd->bi_memstart, gd->bd->bi_memsize, TLB_WORD2_I_ENABLE);
 176#endif
 177        for (i = 0; i < spr_test_list_size; i++) {
 178                int num = spr_test_list[i].number;
 179
 180                /* mfspr r3,num */
 181                code[0] = 0x7c6002a6 | ((num & 0x1F) << 16) | ((num & 0x3E0) << 6);
 182
 183                asm volatile ("isync");
 184
 185                if ((get_spr () & spr_test_list[i].mask) !=
 186                        (spr_test_list[i].value & spr_test_list[i].mask)) {
 187                        post_log ("The value of %s special register "
 188                                  "is incorrect: 0x%08X\n",
 189                                        spr_test_list[i].name, get_spr ());
 190                        ret = -1;
 191                }
 192        }
 193#ifdef CONFIG_4xx_DCACHE
 194        /* enable cache */
 195        change_tlb(gd->bd->bi_memstart, gd->bd->bi_memsize, 0);
 196#endif
 197
 198        return ret;
 199}
 200
 201#endif /* CONFIG_POST & CONFIG_SYS_POST_SPR */
 202