]> git.sur5r.net Git - u-boot/blob - post/cpu/ppc4xx/spr.c
Merge branch 'master' of git://www.denx.de/git/u-boot-mpc85xx
[u-boot] / post / cpu / ppc4xx / spr.c
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 #ifdef CONFIG_POST
39
40 #include <post.h>
41
42 #if CONFIG_POST & CFG_POST_SPR
43
44 #include <asm/processor.h>
45
46 #ifdef CONFIG_4xx_DCACHE
47 #include <asm/mmu.h>
48
49 DECLARE_GLOBAL_DATA_PTR;
50 #endif
51
52 static struct {
53         int number;
54         char * name;
55         unsigned long mask;
56         unsigned long value;
57 } spr_test_list [] = {
58         /* Standard Special-Purpose Registers */
59
60         {0x001, "XER",          0x00000000,     0x00000000},
61         {0x008, "LR",           0x00000000,     0x00000000},
62         {0x009, "CTR",          0x00000000,     0x00000000},
63         {0x016, "DEC",          0x00000000,     0x00000000},
64         {0x01a, "SRR0",         0x00000000,     0x00000000},
65         {0x01b, "SRR1",         0x00000000,     0x00000000},
66         {0x110, "SPRG0",        0x00000000,     0x00000000},
67         {0x111, "SPRG1",        0x00000000,     0x00000000},
68         {0x112, "SPRG2",        0x00000000,     0x00000000},
69         {0x113, "SPRG3",        0x00000000,     0x00000000},
70         {0x11f, "PVR",          0x00000000,     0x00000000},
71
72         /* Additional Special-Purpose Registers.
73          * The values must match the initialization
74          * values from cpu/ppc4xx/start.S
75          */
76         {0x30,  "PID",          0x00000000,     0x00000000},
77         {0x3a,  "CSRR0",        0x00000000,     0x00000000},
78         {0x3b,  "CSRR1",        0x00000000,     0x00000000},
79         {0x3d,  "DEAR",         0x00000000,     0x00000000},
80         {0x3e,  "ESR",          0x00000000,     0x00000000},
81         {0x3f,  "IVPR",         0xffff0000,     0x00000000},
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
159 static int spr_test_list_size =
160                 sizeof (spr_test_list) / sizeof (spr_test_list[0]);
161
162 int 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 & CFG_POST_SPR */
202 #endif /* CONFIG_POST */