~pmdj/ubuntu/trusty/qemu/2.9+applesmc+fadtv3

« back to all changes in this revision

Viewing changes to roms/u-boot/board/w7o/post1.S

  • Committer: Phil Dennis-Jordan
  • Date: 2017-07-21 08:03:43 UTC
  • mfrom: (1.1.1)
  • Revision ID: phil@philjordan.eu-20170721080343-2yr2vdj7713czahv
New upstream release 2.9.0.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * (C) Copyright 2001
 
3
 * Bill Hunter, Wave 7 Optics, william.hunter@mediaone.net
 
4
 *  and
 
5
 * Erik Theisen, Wave 7 Optics, etheisen@mindspring.com
 
6
 *
 
7
 * SPDX-License-Identifier:     GPL-2.0+
 
8
 */
 
9
/*
 
10
 * Description:
 
11
 *      Routine to exercise memory for the bringing up of our boards.
 
12
 */
 
13
#include <config.h>
 
14
#include <asm/ppc4xx.h>
 
15
 
 
16
#include <ppc_asm.tmpl>
 
17
#include <ppc_defs.h>
 
18
 
 
19
#include <asm/cache.h>
 
20
#include <asm/mmu.h>
 
21
 
 
22
#include <watchdog.h>
 
23
 
 
24
#include "errors.h"
 
25
 
 
26
#define _ASMLANGUAGE
 
27
 
 
28
        .globl  test_sdram
 
29
        .globl  test_led
 
30
        .globl  log_stat
 
31
        .globl  log_warn
 
32
        .globl  log_err
 
33
        .globl  temp_uart_init
 
34
        .globl  post_puts
 
35
        .globl  disp_hex
 
36
 
 
37
/*****************************************************
 
38
*******   Text Strings for low level printing   ******
 
39
*******          In section got2               *******
 
40
*****************************************************/
 
41
 
 
42
/*
 
43
 * Define the text strings for errors and warnings.
 
44
 * Switch to .data section.
 
45
 */
 
46
        .section ".data"
 
47
err_str:        .asciz "*** POST ERROR   = "
 
48
warn_str:       .asciz "*** POST WARNING = "
 
49
end_str:  .asciz "\r\n"
 
50
 
 
51
/*
 
52
 * Enter the labels in Global Entry Table (GOT).
 
53
 * Switch to .got2 section.
 
54
 */
 
55
        START_GOT
 
56
        GOT_ENTRY(err_str)
 
57
        GOT_ENTRY(warn_str)
 
58
        GOT_ENTRY(end_str)
 
59
        END_GOT
 
60
 
 
61
/*
 
62
 * Switch  back to .text section.
 
63
 */
 
64
        .text
 
65
 
 
66
/****************************************
 
67
 ****************************************
 
68
 ********    LED register test   ********
 
69
 ****************************************
 
70
 ***************************************/
 
71
test_led:
 
72
        /* save the return info on stack */
 
73
        mflr    r0                      /* Get link register */
 
74
        stwu    r1, -12(r1)             /* Save back chain and move SP */
 
75
        stw     r0, +16(r1)             /* Save link register */
 
76
        stw     r4, +8(r1)              /* save R4 */
 
77
 
 
78
        WATCHDOG_RESET                  /* Reset the watchdog */
 
79
 
 
80
        addi    r3, 0, ERR_FF           /* first test value is ffff */
 
81
        addi    r4, r3, 0               /* save copy of pattern */
 
82
        bl      set_led                 /* store first test value */
 
83
        bl      get_led                 /* read it back */
 
84
        xor.    r4, r4, r3              /* compare to original */
 
85
#if defined(CONFIG_W7OLMC)
 
86
        andi.   r4, r4, 0x00ff          /* lmc has 8 bits */
 
87
#else
 
88
        andi.   r4, r4, 0xffff          /* lmg has 16 bits */
 
89
#endif
 
90
        beq     LED2                    /* next test */
 
91
        addi    r3, 0, ERR_LED          /* error code = 1 */
 
92
        bl      log_err                 /* display error and halt */
 
93
LED2:   addi    r3, 0, ERR_00           /* 2nd test value is 0000 */
 
94
        addi    r4, r3, 0               /* save copy of pattern */
 
95
        bl      set_led                 /* store first test value */
 
96
        bl      get_led                 /* read it back */
 
97
        xor.    r4, r4, r3              /* compare to original */
 
98
#if defined(CONFIG_W7OLMC)
 
99
        andi.   r4, r4, 0x00ff          /* lmc has 8 bits */
 
100
#else
 
101
        andi.   r4, r4, 0xffff          /* lmg has 16 bits */
 
102
#endif
 
103
        beq     LED3                    /* next test */
 
104
        addi    r3, 0, ERR_LED          /* error code = 1 */
 
105
        bl      log_err                 /* display error and halt */
 
106
 
 
107
LED3:   /* restore stack and return */
 
108
        lwz     r0, +16(r1)             /* Get saved link register */
 
109
        mtlr    r0                      /* Restore link register */
 
110
        lwz     r4, +8(r1)              /* restore r4 */
 
111
        addi    r1, r1, +12             /* Remove frame from stack */
 
112
        blr                             /* Return to calling function */
 
113
 
 
114
/****************************************
 
115
 ****************************************
 
116
 ********     SDRAM TESTS        ********
 
117
 ****************************************
 
118
 ***************************************/
 
119
test_sdram:
 
120
        /* called with mem size in r3 */
 
121
        /* save the return info on stack */
 
122
        mflr    r0                      /* Get link register */
 
123
        stwu    r1, -16(r1)             /* Save back chain and move SP */
 
124
        stw     r0, +20(r1)             /* Save link register */
 
125
        stmw    r30, +8(r1)             /* save R30,R31 */
 
126
                                        /* r30 is log2(mem size) */
 
127
                                        /* r31 is mem size */
 
128
 
 
129
        /* take log2 of total mem size */
 
130
        addi    r31, r3, 0              /* save total mem size */
 
131
        addi    r30, 0, 0               /* clear r30 */
 
132
l2_loop:
 
133
        srwi.   r31, r31, 1             /* shift right 1 */
 
134
        addi    r30, r30, 1             /* count shifts */
 
135
        bne     l2_loop                 /* loop till done */
 
136
        addi    r30, r30, -1            /* correct for over count */
 
137
        addi    r31, r3, 0              /* save original size */
 
138
 
 
139
        /* now kick the dog and test the mem */
 
140
        WATCHDOG_RESET                  /* Reset the watchdog */
 
141
        bl      Data_Buster             /* test crossed/shorted data lines */
 
142
        addi    r3, r30, 0              /* get log2(memsize) */
 
143
        addi    r4, r31, 0              /* get memsize */
 
144
        bl      Ghost_Buster            /* test crossed/shorted addr lines */
 
145
        addi    r3, r31, 0              /* get mem size */
 
146
        bl      Bit_Buster              /* check for bad internal bits */
 
147
 
 
148
        /* restore stack and return */
 
149
        lmw     r30, +8(r1)             /* Restore r30, r31 */
 
150
        lwz     r0, +20(r1)             /* Get saved link register */
 
151
        mtlr    r0                      /* Restore link register */
 
152
        addi    r1, r1, +16             /* Remove frame from stack */
 
153
        blr                             /* Return to calling function */
 
154
 
 
155
 
 
156
/****************************************
 
157
 ********  sdram data bus test   ********
 
158
 ***************************************/
 
159
Data_Buster:
 
160
        /* save the return info on stack */
 
161
        mflr    r0                      /* Get link register */
 
162
        stwu    r1, -24(r1)             /* Save back chain and move SP */
 
163
        stw     r0, +28(r1)             /* Save link register */
 
164
        stmw    r28, 8(r1)              /* save r28 - r31 on stack */
 
165
                                        /* r31 i/o register */
 
166
                                        /* r30 sdram base address */
 
167
                                        /* r29 5555 syndrom */
 
168
                                        /* r28 aaaa syndrom */
 
169
 
 
170
        /* set up led register for this test */
 
171
        addi    r3, 0, ERR_RAMG         /* set led code to 1 */
 
172
        bl      log_stat                /* store test value */
 
173
        /* now test the dram data bus */
 
174
        xor     r30, r30, r30           /* load r30 with base addr of sdram */
 
175
        addis   r31, 0, 0x5555          /* load r31 with test value */
 
176
        ori     r31, r31, 0x5555
 
177
        stw     r31,0(r30)              /* sto the value */
 
178
        lwz     r29,0(r30)              /* read it back */
 
179
        xor     r29,r31,r29             /* compare it to original */
 
180
        addis   r31, 0, 0xaaaa          /* load r31 with test value */
 
181
        ori     r31, r31, 0xaaaa
 
182
        stw     r31,0(r30)              /* sto the value */
 
183
        lwz     r28,0(r30)              /* read it back */
 
184
        xor     r28,r31,r28             /* compare it to original */
 
185
        or      r3,r28,r29              /* or together both error terms */
 
186
        /*
 
187
         * Now that we have the error bits,
 
188
         * we have to decide which part they are in.
 
189
         */
 
190
        bl      get_idx                 /* r5 is now index to error */
 
191
        addi    r3, r3, ERR_RAMG
 
192
        cmpwi   r3, ERR_RAMG            /* check for errors */
 
193
        beq     db_done                 /* skip if no errors */
 
194
        bl      log_err                 /* log the error */
 
195
 
 
196
db_done:
 
197
        lmw     r28, 8(r1)              /* restore r28 - r31 from stack */
 
198
        lwz     r0, +28(r1)             /* Get saved link register */
 
199
        addi    r1, r1, +24             /* Remove frame from stack */
 
200
        mtlr    r0                      /* Restore link register */
 
201
        blr                             /* Return to calling function */
 
202
 
 
203
 
 
204
/****************************************************
 
205
 ********  test for address ghosting in dram ********
 
206
 ***************************************************/
 
207
 
 
208
Ghost_Buster:
 
209
        /* save the return info on stack */
 
210
        mflr    r0                      /* Get link register */
 
211
        stwu    r1, -36(r1)             /* Save back chain and move SP */
 
212
        stw     r0, +40(r1)             /* Save link register */
 
213
        stmw    r25, 8(r1)              /* save r25 - r31 on stack */
 
214
                                        /* r31 = scratch register */
 
215
                                        /* r30 is main referance loop counter,
 
216
                                           0 to 23 */
 
217
                                        /* r29 is ghost loop count, 0 to 22 */
 
218
                                        /* r28 is referance address */
 
219
                                        /* r27 is ghost address */
 
220
                                        /* r26 is log2 (mem size) =
 
221
                                             number of byte addr bits */
 
222
                                        /* r25 is mem size */
 
223
 
 
224
        /* save the log2(mem size) and mem size */
 
225
        addi    r26, r3, 0              /* r26 is number of byte addr bits */
 
226
        addi    r25, r4, 0              /* r25 is mem size in bytes */
 
227
 
 
228
        /* set the leds for address ghost test */
 
229
        addi    r3, 0, ERR_ADDG
 
230
        bl      set_led
 
231
 
 
232
        /* first fill memory with zeros */
 
233
        srwi    r31, r25, 2             /* convert bytes to longs */
 
234
        mtctr   r31                     /* setup byte counter */
 
235
        addi    r28, 0, 0               /* start at address at 0 */
 
236
        addi    r31, 0, 0               /* data value = 0 */
 
237
clr_loop:
 
238
        stw     r31, 0(r28)             /* Store zero value */
 
239
        addi    r28, r28, 4             /* Increment to next word */
 
240
        andi.   r27, r28, 0xffff        /* check for 2^16 loops */
 
241
        bne     clr_skip                /* if not there, then skip */
 
242
        WATCHDOG_RESET                  /* kick the dog every now and then */
 
243
clr_skip:
 
244
        bdnz    clr_loop                /* Round and round... */
 
245
 
 
246
        /* now do main test */
 
247
        addi    r30, 0, 0               /* start referance counter at 0 */
 
248
outside:
 
249
        /*
 
250
         * Calculate the referance address
 
251
         *   the referance address is calculated by setting the (r30-1)
 
252
         *   bit of the base address
 
253
         * when r30=0, the referance address is the base address.
 
254
         * thus the sequence 0,1,2,4,8,..,2^(n-1)
 
255
         * setting the bit is done with the following shift functions.
 
256
         */
 
257
        WATCHDOG_RESET                  /* Reset the watchdog */
 
258
 
 
259
        addi    r31, 0, 1               /* r31 = 1 */
 
260
        slw     r28, r31, r30           /* set bit coresponding to loop cnt */
 
261
        srwi    r28, r28, 1             /* then shift it right one so  */
 
262
                                        /*   we start at location 0 */
 
263
        /* fill referance address with Fs */
 
264
        addi    r31, 0, 0x00ff          /* r31 = one byte of set bits */
 
265
        stb     r31,0(r28)              /* save ff in referance address */
 
266
 
 
267
        /* ghost (inner) loop, now check all posible ghosted addresses */
 
268
        addi    r29, 0, 0               /* start ghosted loop counter at 0 */
 
269
inside:
 
270
        /*
 
271
         * Calculate the ghost address by flipping one
 
272
         *  bit of referance address.  This gives the
 
273
         *  sequence 1,2,4,8,...,2^(n-1)
 
274
         */
 
275
        addi    r31, 0, 1               /* r31 = 1 */
 
276
        slw     r27, r31, r29           /* set  bit coresponding to loop cnt */
 
277
        xor     r27, r28, r27           /* ghost address = ref addr with
 
278
                                             bit flipped*/
 
279
 
 
280
        /* now check for ghosting */
 
281
        lbz     r31,0(r27)              /* get content of ghost addr */
 
282
        cmpwi   r31, 0                  /* compare read value to 0 */
 
283
        bne     Casper                  /*   we found a ghost! */
 
284
 
 
285
        /* now close ghost ( inner ) loop */
 
286
        addi    r29, r29, 1             /* increment inner loop counter */
 
287
        cmpw    r29, r26                /* check for last inner loop */
 
288
        blt             inside          /* do more inner loops */
 
289
 
 
290
        /* now close referance ( outer ) loop */
 
291
        addi    r31, 0, 0               /* r31 = zero */
 
292
        stb     r31, 0(28)              /* zero out the altered address loc. */
 
293
        /*
 
294
         * Increment and check for end, count is zero based.
 
295
         * With the ble, this gives us one more loops than
 
296
         * address bits for sequence 0,1,2,4,8,...2^(n-1)
 
297
        */
 
298
        addi    r30, r30, 1             /* increment outer loop counter */
 
299
        cmpw    r30, r26                /* check for last inner loop */
 
300
        ble     outside                 /* do more outer loops */
 
301
 
 
302
        /* were done, lets go home */
 
303
        b       gb_done
 
304
Casper:                                 /* we found a ghost !! */
 
305
        addi    r3, 0, ERR_ADDF         /* get indexed error message */
 
306
        bl      log_err                 /* log error led error code */
 
307
gb_done: /*  pack your bags, and go home */
 
308
        lmw     r25, 8(r1)              /* restore r25 - r31 from stack */
 
309
        lwz     r0, +40(r1)             /* Get saved link register */
 
310
        addi    r1, r1, +36             /* Remove frame from stack */
 
311
        mtlr    r0                      /* Restore link register */
 
312
        blr                             /* Return to calling function */
 
313
 
 
314
/****************************************************
 
315
 ********      SDRAM data fill tests       **********
 
316
 ***************************************************/
 
317
Bit_Buster:
 
318
        /* called with mem size in r3 */
 
319
        /* save the return info on stack */
 
320
        mflr    r0                      /* Get link register */
 
321
        stwu    r1, -16(r1)             /* Save back chain and move SP */
 
322
        stw     r0, +20(r1)             /* Save link register */
 
323
        stw     r4, +8(r1)              /* save R4 */
 
324
        stw     r5, +12(r1)             /* save r5 */
 
325
 
 
326
        addis   r5, r3, 0               /* save mem size */
 
327
 
 
328
        /* Test 55555555 */
 
329
        addi    r3, 0, ERR_R55G         /* set up error code in case we fail */
 
330
        bl      log_stat                /* store test value */
 
331
        addis   r4, 0, 0x5555
 
332
        ori     r4, r4, 0x5555
 
333
        bl      fill_test
 
334
 
 
335
        /* Test aaaaaaaa  */
 
336
        addi    r3, 0, ERR_RAAG         /* set up error code in case we fail */
 
337
        bl      log_stat                /* store test value */
 
338
        addis   r4, 0, 0xAAAA
 
339
        ori     r4, r4, 0xAAAA
 
340
        bl      fill_test
 
341
 
 
342
        /* Test 00000000  */
 
343
        addi    r3, 0, ERR_R00G         /* set up error code in case we fail */
 
344
        bl      log_stat                /* store test value */
 
345
        addis   r4, 0, 0
 
346
        ori     r4, r4, 0
 
347
        bl      fill_test
 
348
 
 
349
        /* restore stack and return */
 
350
        lwz     r5, +12(r1)             /* restore r4 */
 
351
        lwz     r4, +8(r1)              /* restore r4 */
 
352
        lwz     r0, +20(r1)             /* Get saved link register */
 
353
        addi    r1, r1, +16             /* Remove frame from stack */
 
354
        mtlr    r0                      /* Restore link register */
 
355
        blr                             /* Return to calling function */
 
356
 
 
357
 
 
358
/****************************************************
 
359
 ********             fill test              ********
 
360
 ***************************************************/
 
361
/*      tests memory by filling with value, and reading back */
 
362
/*      r5 = Size of memory in bytes */
 
363
/*      r4 = Value to write */
 
364
/*      r3 = Error code */
 
365
fill_test:
 
366
        mflr    r0                      /* Get link register */
 
367
        stwu    r1, -32(r1)             /* Save back chain and move SP */
 
368
        stw     r0, +36(r1)             /* Save link register */
 
369
        stmw    r27, 8(r1)              /* save r27 - r31 on stack */
 
370
                                        /* r31 - scratch register */
 
371
                                        /* r30 - memory address */
 
372
        mr      r27, r3
 
373
        mr      r28, r4
 
374
        mr      r29, r5
 
375
 
 
376
        WATCHDOG_RESET                  /* Reset the watchdog */
 
377
 
 
378
        /* first fill memory with Value */
 
379
        srawi   r31, r29, 2             /* convert bytes to longs */
 
380
        mtctr   r31                     /* setup counter */
 
381
        addi    r30, 0, 0               /* Make r30 = addr 0 */
 
382
ft_0:   stw     r28, 0(r30)             /* Store value */
 
383
        addi    r30, r30, 4             /* Increment to next word */
 
384
        andi.   r31, r30, 0xffff        /* check for 2^16 loops */
 
385
        bne     ft_0a                   /* if not there, then skip */
 
386
        WATCHDOG_RESET                  /* kick the dog every now and then */
 
387
ft_0a:  bdnz    ft_0                    /* Round and round... */
 
388
 
 
389
        WATCHDOG_RESET                  /* Reset the watchdog */
 
390
 
 
391
        /* Now confirm Value is in memory */
 
392
        srawi   r31, r29, 2             /* convert bytes to longs */
 
393
        mtctr   r31                     /* setup counter */
 
394
        addi    r30, 0, 0               /* Make r30 = addr 0 */
 
395
ft_1:   lwz     r31, 0(r30)             /* get value from memory */
 
396
        xor.    r31, r31, r28           /* Writen = Read ? */
 
397
        bne     ft_err                  /* If bad, than halt */
 
398
        addi    r30, r30, 4             /* Increment to next word */
 
399
        andi.   r31, r30, 0xffff        /* check for 2^16 loops*/
 
400
        bne     ft_1a                   /* if not there, then skip */
 
401
        WATCHDOG_RESET                  /* kick the dog every now and then */
 
402
ft_1a:  bdnz    ft_1                    /* Round and round... */
 
403
 
 
404
        WATCHDOG_RESET                  /* Reset the watchdog */
 
405
 
 
406
        b       fill_done               /* restore and return */
 
407
 
 
408
ft_err: addi    r29, r27, 0             /* save current led code */
 
409
        addi    r27, r31, 0             /* get pattern in r27 */
 
410
        bl      get_idx                 /* get index from r27 */
 
411
        add     r27, r27, r29           /* add index to old led code */
 
412
        bl      log_err                 /* output led err code, halt CPU */
 
413
 
 
414
fill_done:
 
415
        lmw     r27, 8(r1)              /* restore r27 - r31 from stack */
 
416
        lwz     r0, +36(r1)             /* Get saved link register */
 
417
        addi    r1, r1, +32             /* Remove frame from stack */
 
418
        mtlr    r0                      /* Restore link register */
 
419
        blr                             /* Return to calling function */
 
420
 
 
421
 
 
422
/****************************************************
 
423
 *******  get error index from r3 pattern    ********
 
424
 ***************************************************/
 
425
get_idx:                                /* r3 = (MSW(r3) !=0)*2 +
 
426
                                            (LSW(r3) !=0) */
 
427
        /* save the return info on stack */
 
428
        mflr    r0                      /* Get link register */
 
429
        stwu    r1, -12(r1)             /* Save back chain and move SP */
 
430
        stw     r0, +16(r1)             /* Save link register */
 
431
        stw     r4, +8(r1)              /* save R4 */
 
432
 
 
433
        andi.   r4, r3, 0xffff          /* check for lower bits */
 
434
        beq     gi2                     /* skip if no bits set */
 
435
        andis.  r4, r3, 0xffff          /* check for upper bits */
 
436
        beq     gi3                     /* skip if no bits set */
 
437
        addi    r3, 0, 3                /* both upper and lower bits set */
 
438
        b       gi_done
 
439
gi2:    andis.  r4, r3, 0xffff          /* check for upper bits*/
 
440
        beq     gi4                     /* skip if no bits set */
 
441
        addi    r3, 0, 2                /* only upper bits set */
 
442
        b       gi_done
 
443
gi3:    addi    r3, 0, 1                /* only lower bits set */
 
444
        b       gi_done
 
445
gi4:    addi    r3, 0, 0                /* no bits set */
 
446
gi_done:
 
447
        /* restore stack and return */
 
448
        lwz     r0, +16(r1)             /* Get saved link register */
 
449
        mtlr    r0                      /* Restore link register */
 
450
        lwz     r4, +8(r1)              /* restore r4 */
 
451
        addi    r1, r1, +12             /* Remove frame from stack */
 
452
        blr                             /* Return to calling function */
 
453
 
 
454
/****************************************************
 
455
 ********       set LED to R5 and hang       ********
 
456
 ***************************************************/
 
457
log_stat:                               /* output a led code and continue */
 
458
set_led:
 
459
        /* save the return info on stack */
 
460
        mflr    r0                      /* Get link register */
 
461
        stwu    r1, -12(r1)             /* Save back chain and move SP */
 
462
        stw     r0, +16(r1)             /* Save link register */
 
463
        stw     r4, +8(r1)              /* save R4 */
 
464
 
 
465
        addis   r4, 0, 0xfe00           /* LED buffer is at 0xfe000000 */
 
466
#if defined(CONFIG_W7OLMG)              /* only on gateway, invert outputs */
 
467
        xori    r3,r3, 0xffff           /* complement led code, active low */
 
468
        sth     r3, 0(r4)               /* store first test value */
 
469
        xori    r3,r3, 0xffff           /* complement led code, active low */
 
470
#else                                   /* if not gateway, then don't invert */
 
471
        sth     r3, 0(r4)               /* store first test value */
 
472
#endif
 
473
 
 
474
        /* restore stack and return */
 
475
        lwz     r0, +16(r1)             /* Get saved link register */
 
476
        mtlr    r0                      /* Restore link register */
 
477
        lwz     r4, +8(r1)              /* restore r4 */
 
478
        addi    r1, r1, +12             /* Remove frame from stack */
 
479
        blr                             /* Return to calling function */
 
480
 
 
481
get_led:
 
482
        /* save the return info on stack */
 
483
        mflr    r0                      /* Get link register */
 
484
        stwu    r1, -12(r1)             /* Save back chain and move SP */
 
485
        stw     r0, +16(r1)             /* Save link register */
 
486
        stw     r4, +8(r1)              /* save R4 */
 
487
 
 
488
        addis   r4, 0, 0xfe00           /* LED buffer is at 0xfe000000 */
 
489
        lhz     r3, 0(r4)               /* store first test value */
 
490
#if defined(CONFIG_W7OLMG)              /* only on gateway, invert inputs */
 
491
        xori    r3,r3, 0xffff           /* complement led code, active low */
 
492
#endif
 
493
 
 
494
        /* restore stack and return */
 
495
        lwz     r0, +16(r1)             /* Get saved link register */
 
496
        mtlr    r0                      /* Restore link register */
 
497
        lwz     r4, +8(r1)              /* restore r4 */
 
498
        addi    r1, r1, +12             /* Remove frame from stack */
 
499
        blr                             /* Return to calling function */
 
500
 
 
501
log_err:        /* output the error and hang the board ( for now ) */
 
502
        /* save the return info on stack */
 
503
        mflr    r0                      /* Get link register */
 
504
        stwu    r1, -12(r1)             /* Save back chain and move SP */
 
505
        stw     r0, +16(r1)             /* Save link register */
 
506
        stw     r3, +8(r1)              /* save a copy of error code */
 
507
        bl      set_led                 /* set the led pattern */
 
508
        GET_GOT                         /* get GOT address in r14 */
 
509
        lwz     r3,GOT(err_str)         /* get address of string */
 
510
        bl      post_puts               /* output the warning string */
 
511
        lwz     r3, +8(r1)              /* get error code */
 
512
        addi    r4, 0, 2                /* set disp length to 2 nibbles */
 
513
        bl      disp_hex                /* output the error code */
 
514
        lwz     r3,GOT(end_str)         /* get address of string */
 
515
        bl      post_puts               /* output the warning string */
 
516
halt:
 
517
        b       halt                    /* hang */
 
518
 
 
519
        /* restore stack and return */
 
520
        lwz     r0, +16(r1)             /* Get saved link register */
 
521
        mtlr    r0                      /* Restore link register */
 
522
        addi    r1, r1, +12             /* Remove frame from stack */
 
523
        blr                             /* Return to calling function */
 
524
 
 
525
log_warn:       /* output a warning, then continue with operations */
 
526
        /* save the return info on stack */
 
527
        mflr    r0                      /* Get link register */
 
528
        stwu    r1, -16(r1)             /* Save back chain and move SP */
 
529
        stw     r0, +20(r1)             /* Save link register */
 
530
        stw     r3, +8(r1)              /* save a copy of error code */
 
531
        stw     r14, +12(r1)            /* save a copy of r14 (used by GOT) */
 
532
 
 
533
        bl      set_led                 /* set the led pattern */
 
534
        GET_GOT                         /* get GOT address in r14 */
 
535
        lwz     r3,GOT(warn_str)        /* get address of string */
 
536
        bl      post_puts               /* output the warning string */
 
537
        lwz     r3, +8(r1)              /* get error code */
 
538
        addi    r4, 0, 2                /* set disp length to 2 nibbles */
 
539
        bl      disp_hex                /* output the error code */
 
540
        lwz     r3,GOT(end_str)         /* get address of string */
 
541
        bl      post_puts               /* output the warning string */
 
542
 
 
543
        addis   r3, 0, 64               /* has a long delay */
 
544
        mtctr   r3
 
545
log_2:
 
546
        WATCHDOG_RESET                  /* this keeps dog from barking, */
 
547
                                        /*   and takes time */
 
548
        bdnz    log_2                   /* loop till time expires */
 
549
 
 
550
        /* restore stack and return */
 
551
        lwz     r0, +20(r1)             /* Get saved link register */
 
552
        lwz     r14, +12(r1)            /* restore r14 */
 
553
        mtlr    r0                      /* Restore link register */
 
554
        addi    r1, r1, +16             /* Remove frame from stack */
 
555
        blr                             /* Return to calling function */
 
556
 
 
557
/*******************************************************************
 
558
 *      temp_uart_init
 
559
 *      Temporary UART initialization routine
 
560
 *      Sets up UART0 to run at 9600N81 off of the internal clock.
 
561
 *      R3-R4 are used.
 
562
 ******************************************************************/
 
563
temp_uart_init:
 
564
        /* save the return info on stack */
 
565
        mflr    r0                      /* Get link register */
 
566
        stwu    r1, -8(r1)              /* Save back chain and move SP */
 
567
        stw     r0, +12(r1)             /* Save link register */
 
568
 
 
569
        addis   r3, 0, 0xef60
 
570
        ori     r3, r3, 0x0303          /* r3 = UART0_LCR */
 
571
        addi    r4, 0, 0x83             /* n81 format, divisor regs enabled */
 
572
        stb     r4, 0(r3)
 
573
 
 
574
        /* set baud rate to use internal clock,
 
575
           baud = (200e6/16)/31/42 = 9600 */
 
576
 
 
577
        addis   r3, 0, 0xef60           /* Address of baud divisor reg */
 
578
        ori     r3, r3, 0x0300          /*   UART0_DLM */
 
579
        addi    r4, 0, +42              /* uart baud divisor LSB = 93 */
 
580
        stb     r4, 0(r3)               /* baud = (200 /16)/14/93 */
 
581
 
 
582
        addi    r3, r3, 0x0001          /* uart baud divisor addr */
 
583
        addi    r4, 0, 0
 
584
        stb     r4, 0(r3)               /* Divisor Latch MSB = 0 */
 
585
 
 
586
        addis   r3, 0, 0xef60
 
587
        ori     r3, r3, 0x0303          /* r3 = UART0_LCR */
 
588
        addi    r4, 0, 0x03             /* n81 format, tx/rx regs enabled */
 
589
        stb     r4, 0(r3)
 
590
 
 
591
        /* output a few line feeds */
 
592
        addi    r3, 0, '\n'             /* load line feed */
 
593
        bl      post_putc               /* output the char */
 
594
        addi    r3, 0, '\n'             /* load line feed */
 
595
        bl      post_putc               /* output the char */
 
596
 
 
597
        /* restore stack and return */
 
598
        lwz     r0, +12(r1)             /* Get saved link register */
 
599
        mtlr    r0                      /* Restore link register */
 
600
        addi    r1, r1, +8              /* Remove frame from stack */
 
601
        blr                             /* Return to calling function */
 
602
 
 
603
/**********************************************************************
 
604
 **     post_putc
 
605
 **     outputs charactor in R3
 
606
 **     r3 returns the error code ( -1 if there is an error )
 
607
 *********************************************************************/
 
608
 
 
609
post_putc:
 
610
 
 
611
        /* save the return info on stack */
 
612
        mflr    r0                      /* Get link register */
 
613
        stwu    r1, -20(r1)             /* Save back chain and move SP */
 
614
        stw     r0, +24(r1)             /* Save link register */
 
615
        stmw    r29, 8(r1)              /* save r29 - r31 on stack
 
616
                                           r31 - uart base address
 
617
                                           r30 - delay counter
 
618
                                           r29 - scratch reg */
 
619
 
 
620
     addis   r31, 0, 0xef60             /* Point to uart base */
 
621
     ori     r31, r31, 0x0300
 
622
     addis   r30, 0, 152                /* Load about 10,000,000 ticks. */
 
623
pputc_lp:
 
624
        lbz     r29, 5(r31)             /* Read Line Status Register */
 
625
        andi.   r29, r29, 0x20          /* Check THRE status */
 
626
        bne     thre_set                /* Branch if FIFO empty */
 
627
        addic.  r30, r30, -1            /* Decrement and check if empty. */
 
628
        bne     pputc_lp                /* Try, try again */
 
629
        addi    r3, 0, -1               /* Load error code for timeout */
 
630
        b       pputc_done              /* Bail out with error code set */
 
631
thre_set:
 
632
        stb     r3, 0(r31)              /* Store character to UART */
 
633
        addi    r3, 0, 0                /* clear error code */
 
634
pputc_done:
 
635
        lmw     r29, 8(r1)              /*restore r29 - r31 from stack */
 
636
        lwz     r0, +24(r1)             /* Get saved link register */
 
637
        addi    r1, r1, +20             /* Remove frame from stack */
 
638
        mtlr    r0                      /* Restore link register */
 
639
        blr                             /* Return to calling function */
 
640
 
 
641
 
 
642
/****************************************************************
 
643
    post_puts
 
644
    Accepts a null-terminated string pointed to by R3
 
645
    Outputs to the serial port until 0x00 is found.
 
646
    r3 returns the error code ( -1 if there is an error )
 
647
*****************************************************************/
 
648
post_puts:
 
649
 
 
650
        /* save the return info on stack */
 
651
        mflr    r0                      /* Get link register */
 
652
        stwu    r1, -12(r1)             /* Save back chain and move SP */
 
653
        stw     r0, +16(r1)             /* Save link register */
 
654
        stw     r31, 8(r1)              /* save r31 - char pointer */
 
655
 
 
656
        addi    r31, r3, 0              /* move pointer to R31 */
 
657
pputs_nxt:
 
658
        lbz     r3, 0(r31)              /* Get next character */
 
659
        addic.  r3, r3, 0               /* Check for zero */
 
660
        beq     pputs_term              /* bail out if zero */
 
661
        bl      post_putc               /* output the char */
 
662
        addic.  r3, r3, 0               /* check for error */
 
663
        bne     pputs_err
 
664
        addi    r31, r31, 1             /* point to next char */
 
665
        b       pputs_nxt               /* loop till term */
 
666
pputs_err:
 
667
        addi    r3, 0, -1               /* set error code */
 
668
        b       pputs_end               /* were outa here */
 
669
pputs_term:
 
670
        addi    r3, 0, 1                /* set success code */
 
671
        /* restore stack and return */
 
672
pputs_end:
 
673
        lwz     r31, 8(r1)              /* restore r27 - r31 from stack */
 
674
        lwz     r0, +16(r1)             /* Get saved link register */
 
675
        addi    r1, r1, +12             /* Remove frame from stack */
 
676
        mtlr    r0                      /* Restore link register */
 
677
        blr                             /* Return to calling function */
 
678
 
 
679
 
 
680
/********************************************************************
 
681
 *****  disp_hex
 
682
 *****  Routine to display a hex value from a register.
 
683
 *****  R3 is value to display
 
684
 *****  R4 is number of nibbles to display ie 2 for byte 8 for (long)word
 
685
 *****  Returns -1 in R3 if there is an error ( ie serial port hangs )
 
686
 *****  Returns 0 in R3 if no error
 
687
 *******************************************************************/
 
688
disp_hex:
 
689
        /* save the return info on stack */
 
690
        mflr    r0                      /* Get link register */
 
691
        stwu    r1, -16(r1)             /* Save back chain and move SP */
 
692
        stw     r0, +20(r1)             /* Save link register */
 
693
        stmw    r30, 8(r1)              /* save r30 - r31 on stack */
 
694
                                        /* r31 output char */
 
695
                                        /* r30 uart base address */
 
696
        addi    r30, 0, 8               /* Go through 8 nibbles. */
 
697
        addi    r31, r3, 0
 
698
pputh_nxt:
 
699
        rlwinm  r31, r31, 4, 0, 31      /* Rotate next nibble into position */
 
700
        andi.   r3, r31, 0x0f           /* Get nibble. */
 
701
        addi    r3, r3, 0x30            /* Add zero's ASCII code. */
 
702
        cmpwi   r3, 0x03a
 
703
        blt     pputh_out
 
704
        addi    r3, r3, 0x07            /* 0x27 for lower case. */
 
705
pputh_out:
 
706
        cmpw    r30, r4
 
707
        bgt     pputh_skip
 
708
        bl      post_putc
 
709
        addic.  r3, r3, 0               /* check for error */
 
710
        bne     pputh_err
 
711
pputh_skip:
 
712
        addic.  r30, r30, -1
 
713
        bne     pputh_nxt
 
714
        xor     r3, r3, r3              /* Clear error code */
 
715
        b       pputh_done
 
716
pputh_err:
 
717
        addi    r3, 0, -1               /* set error code */
 
718
pputh_done:
 
719
        /* restore stack and return */
 
720
        lmw     r30, 8(r1)              /*  restore r30 - r31 from stack */
 
721
        lwz     r0, +20(r1)             /* Get saved link register */
 
722
        addi    r1, r1, +16             /* Remove frame from stack */
 
723
        mtlr    r0                      /* Restore link register */
 
724
        blr                             /* Return to calling function */