]>
git.ipfire.org Git - people/ms/u-boot.git/blob - post/post.c
b74e7623169d562c3e69ece9c99790ff7302df7f
3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
5 * See file CREDITS for list of people who contributed to this
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.
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.
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,
25 #include <stdio_dev.h>
29 #ifdef CONFIG_LOGBUFFER
33 DECLARE_GLOBAL_DATA_PTR
;
35 #define POST_MAX_NUMBER 32
37 #define BOOTMODE_MAGIC 0xDEAD0000
39 int post_init_f (void)
44 for (i
= 0; i
< post_list_size
; i
++) {
45 struct post_test
*test
= post_list
+ i
;
47 if (test
->init_f
&& test
->init_f()) {
52 gd
->post_init_f_time
= post_time_ms(0);
53 if (!gd
->post_init_f_time
)
55 printf("post/post.c: post_time_ms seems not to be implemented\n");
61 void post_bootmode_init (void)
63 int bootmode
= post_bootmode_get (0);
66 if (post_hotkeys_pressed() && !(bootmode
& POST_POWERTEST
)) {
67 newword
= BOOTMODE_MAGIC
| POST_SLOWTEST
;
68 } else if (bootmode
== 0) {
69 newword
= BOOTMODE_MAGIC
| POST_POWERON
;
70 } else if (bootmode
== POST_POWERON
|| bootmode
== POST_SLOWTEST
) {
71 newword
= BOOTMODE_MAGIC
| POST_NORMAL
;
74 newword
= post_word_load () & ~POST_COLDBOOT
;
79 /* We are booting after power-on */
80 newword
|= POST_COLDBOOT
;
83 post_word_store (newword
);
85 /* Reset activity record */
86 gd
->post_log_word
= 0;
89 int post_bootmode_get (unsigned int *last_test
)
91 unsigned long word
= post_word_load ();
94 if ((word
& 0xFFFF0000) != BOOTMODE_MAGIC
) {
98 bootmode
= word
& 0x7F;
100 if (last_test
&& (bootmode
& POST_POWERTEST
)) {
101 *last_test
= (word
>> 8) & 0xFF;
107 /* POST tests run before relocation only mark status bits .... */
108 static void post_log_mark_start ( unsigned long testid
)
110 gd
->post_log_word
|= (testid
)<<16;
113 static void post_log_mark_succ ( unsigned long testid
)
115 gd
->post_log_word
|= testid
;
118 /* ... and the messages are output once we are relocated */
119 void post_output_backlog ( void )
123 for (j
= 0; j
< post_list_size
; j
++) {
124 if (gd
->post_log_word
& (post_list
[j
].testid
<<16)) {
125 post_log ("POST %s ", post_list
[j
].cmd
);
126 if (gd
->post_log_word
& post_list
[j
].testid
)
127 post_log ("PASSED\n");
129 post_log ("FAILED\n");
130 show_boot_progress (-31);
136 static void post_bootmode_test_on (unsigned int last_test
)
138 unsigned long word
= post_word_load ();
140 word
|= POST_POWERTEST
;
142 word
|= (last_test
& 0xFF) << 8;
144 post_word_store (word
);
147 static void post_bootmode_test_off (void)
149 unsigned long word
= post_word_load ();
151 word
&= ~POST_POWERTEST
;
153 post_word_store (word
);
156 static void post_get_flags (int *test_flags
)
158 int flag
[] = { POST_POWERON
, POST_NORMAL
, POST_SLOWTEST
,
160 char *var
[] = { "post_poweron", "post_normal", "post_slowtest",
162 int varnum
= sizeof (var
) / sizeof (var
[0]);
163 char list
[128]; /* long enough for POST list */
169 for (j
= 0; j
< post_list_size
; j
++) {
170 test_flags
[j
] = post_list
[j
].flags
;
173 for (i
= 0; i
< varnum
; i
++) {
174 if (getenv_r (var
[i
], list
, sizeof (list
)) <= 0)
177 for (j
= 0; j
< post_list_size
; j
++) {
178 test_flags
[j
] &= ~flag
[i
];
184 while (*name
&& *name
== ' ')
189 while (*s
&& *s
!= ' ')
196 for (j
= 0; j
< post_list_size
; j
++) {
197 if (strcmp (post_list
[j
].cmd
, name
) == 0) {
198 test_flags
[j
] |= flag
[i
];
203 if (j
== post_list_size
) {
204 printf ("No such test: %s\n", name
);
211 for (j
= 0; j
< post_list_size
; j
++) {
212 if (test_flags
[j
] & POST_POWERON
) {
213 test_flags
[j
] |= POST_SLOWTEST
;
218 static int post_run_single (struct post_test
*test
,
219 int test_flags
, int flags
, unsigned int i
)
221 if ((flags
& test_flags
& POST_ALWAYS
) &&
222 (flags
& test_flags
& POST_MEM
)) {
225 if (!(flags
& POST_REBOOT
)) {
226 if ((test_flags
& POST_REBOOT
) && !(flags
& POST_MANUAL
)) {
227 post_bootmode_test_on (
228 (gd
->flags
& GD_FLG_POSTFAIL
) ?
229 POST_FAIL_SAVE
| i
: i
);
232 if (test_flags
& POST_PREREL
)
233 post_log_mark_start ( test
->testid
);
235 post_log ("POST %s ", test
->cmd
);
238 if (test_flags
& POST_PREREL
) {
239 if ((*test
->test
) (flags
) == 0)
240 post_log_mark_succ ( test
->testid
);
242 if (test_flags
& POST_CRITICAL
)
243 gd
->flags
|= GD_FLG_POSTFAIL
;
244 if (test_flags
& POST_STOP
)
245 gd
->flags
|= GD_FLG_POSTSTOP
;
248 if ((*test
->test
) (flags
) != 0) {
249 post_log ("FAILED\n");
250 show_boot_progress (-32);
251 if (test_flags
& POST_CRITICAL
)
252 gd
->flags
|= GD_FLG_POSTFAIL
;
253 if (test_flags
& POST_STOP
)
254 gd
->flags
|= GD_FLG_POSTSTOP
;
257 post_log ("PASSED\n");
260 if ((test_flags
& POST_REBOOT
) && !(flags
& POST_MANUAL
)) {
261 post_bootmode_test_off ();
270 int post_run (char *name
, int flags
)
273 int test_flags
[POST_MAX_NUMBER
];
275 post_get_flags (test_flags
);
280 if (gd
->flags
& GD_FLG_POSTSTOP
)
283 if (post_bootmode_get (&last
) & POST_POWERTEST
) {
284 if (last
& POST_FAIL_SAVE
) {
285 last
&= ~POST_FAIL_SAVE
;
286 gd
->flags
|= GD_FLG_POSTFAIL
;
288 if (last
< post_list_size
&&
289 (flags
& test_flags
[last
] & POST_ALWAYS
) &&
290 (flags
& test_flags
[last
] & POST_MEM
)) {
292 post_run_single (post_list
+ last
,
294 flags
| POST_REBOOT
, last
);
296 for (i
= last
+ 1; i
< post_list_size
; i
++) {
297 if (gd
->flags
& GD_FLG_POSTSTOP
)
299 post_run_single (post_list
+ i
,
305 for (i
= 0; i
< post_list_size
; i
++) {
306 if (gd
->flags
& GD_FLG_POSTSTOP
)
308 post_run_single (post_list
+ i
,
316 for (i
= 0; i
< post_list_size
; i
++) {
317 if (strcmp (post_list
[i
].cmd
, name
) == 0)
321 if (i
< post_list_size
) {
323 return post_run_single (post_list
+ i
,
332 static int post_info_single (struct post_test
*test
, int full
)
334 if (test
->flags
& POST_MANUAL
) {
337 " %s\n", test
->cmd
, test
->name
, test
->desc
);
339 printf (" %-15s - %s\n", test
->cmd
, test
->name
);
347 int post_info (char *name
)
352 for (i
= 0; i
< post_list_size
; i
++) {
353 post_info_single (post_list
+ i
, 0);
358 for (i
= 0; i
< post_list_size
; i
++) {
359 if (strcmp (post_list
[i
].cmd
, name
) == 0)
363 if (i
< post_list_size
) {
364 return post_info_single (post_list
+ i
, 1);
371 int post_log (char *format
, ...)
375 char printbuffer
[CONFIG_SYS_PBSIZE
];
377 va_start (args
, format
);
379 /* For this to work, printbuffer must be larger than
380 * anything we ever want to print.
382 i
= vsprintf (printbuffer
, format
, args
);
385 #ifdef CONFIG_LOGBUFFER
386 /* Send to the logbuffer */
387 logbuff_log (printbuffer
);
389 /* Send to the stdout file */
396 #ifndef CONFIG_RELOC_FIXUP_WORKS
397 void post_reloc (void)
402 * We have to relocate the test table manually
404 for (i
= 0; i
< post_list_size
; i
++) {
406 struct post_test
*test
= post_list
+ i
;
409 addr
= (ulong
) (test
->name
) + gd
->reloc_off
;
410 test
->name
= (char *) addr
;
414 addr
= (ulong
) (test
->cmd
) + gd
->reloc_off
;
415 test
->cmd
= (char *) addr
;
419 addr
= (ulong
) (test
->desc
) + gd
->reloc_off
;
420 test
->desc
= (char *) addr
;
424 addr
= (ulong
) (test
->test
) + gd
->reloc_off
;
425 test
->test
= (int (*)(int flags
)) addr
;
429 addr
= (ulong
) (test
->init_f
) + gd
->reloc_off
;
430 test
->init_f
= (int (*)(void)) addr
;
434 addr
= (ulong
) (test
->reloc
) + gd
->reloc_off
;
435 test
->reloc
= (void (*)(void)) addr
;
445 * Some tests (e.g. SYSMON) need the time when post_init_f started,
446 * but we cannot use get_timer() at this point.
448 * On PowerPC we implement it using the timebase register.
450 unsigned long post_time_ms (unsigned long base
)
453 return (unsigned long)(get_ticks () / (get_tbclk () / CONFIG_SYS_HZ
)) - base
;
455 #warning "Not implemented yet"
456 return 0; /* Not implemented yet */