source: SVN/rincon/u-boot/board/w7o/post1.S @ 55

Last change on this file since 55 was 55, checked in by Tim Harvey, 22 months ago

rincon: added latest u-boot source

restored form server backup

Signed-off-by: Tim Harvey <tharvey@…>

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