~ubuntu-branches/ubuntu/wily/slof/wily

« back to all changes in this revision

Viewing changes to board-js2x/llfw/startup.S

  • Committer: Package Import Robot
  • Author(s): Aurelien Jarno
  • Date: 2012-09-16 23:05:23 UTC
  • Revision ID: package-import@ubuntu.com-20120916230523-r2ynulqmp2tyu2e5
Tags: upstream-20120217+dfsg
ImportĀ upstreamĀ versionĀ 20120217+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/******************************************************************************
 
2
 * Copyright (c) 2004, 2008 IBM Corporation
 
3
 * All rights reserved.
 
4
 * This program and the accompanying materials
 
5
 * are made available under the terms of the BSD License
 
6
 * which accompanies this distribution, and is available at
 
7
 * http://www.opensource.org/licenses/bsd-license.php
 
8
 *
 
9
 * Contributors:
 
10
 *     IBM Corporation - initial implementation
 
11
 *****************************************************************************/
 
12
 
 
13
# SLOF for JS20/JS21 -- ROM boot code.
 
14
# Initial entry point, copy code from flash to cache, memory setup.
 
15
# Also sets up serial console and optimizes some settings.
 
16
 
 
17
#include "termctrl.h"
 
18
#include <product.h>
 
19
#include <xvect.h>
 
20
#include <cpu.h>
 
21
#include <macros.h>
 
22
#include <southbridge.h>
 
23
 
 
24
        .text
 
25
        .globl __start
 
26
__start:
 
27
        /* put rombase in sprg1 ***********************/
 
28
 
 
29
        bl      postHeader
 
30
        .long 0xDEADBEE0
 
31
        .long 0x0       /* size */ 
 
32
        .long 0x0       /* crc  */
 
33
        .long relTag - __start
 
34
postHeader:
 
35
        mflr    r3
 
36
        li      r4, 0x7fff
 
37
        not     r4, r4
 
38
        and     r3, r3, r4
 
39
        mtsprg  1, r3      /* romfs base */
 
40
        bl      _start
 
41
 
 
42
        .org 0x150 - 0x100
 
43
__startSlave:
 
44
        bl setup_cpu
 
45
        bl set_ci_bit
 
46
#       b slaveWithNumber
 
47
        b slave
 
48
 
 
49
        .org 0x180 - 0x100
 
50
__startMaster:
 
51
        li 3,0
 
52
        mtsprg  1, r3      /* romfs base */
 
53
        bl setup_cpu
 
54
        bl set_ci_bit
 
55
        b master
 
56
 
 
57
 
 
58
        /* FIXME: Also need 0280, 0380, 0f20, etc. */
 
59
 
 
60
        .irp i, 0x0100,0x0180,0x0200,0x0280,0x0300,0x0380,0x0400,0x0500,0x0600,0x0700, \
 
61
                0x0800,0x0900,0x0a00,0x0b00,0x0c00,0x0d00,0x0e00,0x0f00, \
 
62
                0x1000,0x1100,0x1200,0x1300,0x1400,0x1500,0x1600,0x1700, \
 
63
                0x1800,0x1900,0x1a00,0x1b00,0x1c00,0x1d00,0x1e00,0x1f00, \
 
64
                0x2000,0x2100,0x2200,0x2300,0x2400,0x2500,0x2600,0x2700, \
 
65
                0x2800,0x2900,0x2a00,0x2b00,0x2c00,0x2d00,0x2e00
 
66
        . = \i
 
67
 
 
68
        /* enable this if you get exceptions before the console works    */
 
69
        /* this will allow using the hardware debugger to see where      */
 
70
        /* it traps, and with what register values etc.                  */
 
71
        // b    $
 
72
 
 
73
        mtsprg  0, r0
 
74
        mfctr   r0
 
75
        mtsprg  2,r0
 
76
        mflr    r0
 
77
// 10
 
78
        mtsprg  3,r0
 
79
        ld      r0, (\i + 0x160)(0)
 
80
        mtctr   r0
 
81
        li      r0, \i + 0x100
 
82
// 20
 
83
        bctr
 
84
 
 
85
        . = \i + 0x60
 
86
 
 
87
        .quad intHandler2C
 
88
 
 
89
        .endr
 
90
 
 
91
 
 
92
        . = XVECT_M_HANDLER - 0x100
 
93
        .quad 0x00
 
94
        . = XVECT_S_HANDLER - 0x100
 
95
 
 
96
        .quad 0
 
97
 
 
98
 
 
99
 
 
100
        .org 0x4000 - 0x100
 
101
_start:
 
102
        # optimize HID register settings
 
103
        bl setup_cpu
 
104
        bl set_ci_bit
 
105
 
 
106
        # read semaphore, run as slave if not the first to do so
 
107
        li 3,0 ; oris 3,3,0xf800 ; lwz 3,0x60(3) ; andi. 3,3,1 ; beq slave
 
108
master:
 
109
        # setup flash, serial
 
110
        bl setup_sio
 
111
 
 
112
        # early greet
 
113
        li      r3, 10
 
114
        bl      putc
 
115
        li 3,13 ; bl putc ; li 3,10 ; bl putc ; li 3,'S' ; bl putc
 
116
 
 
117
 
 
118
        #do we run from ram ?
 
119
        mfsprg  r3, 1   /* rombase */
 
120
        cmpdi   r3,0    /* rombase is 0 when running from RAM */
 
121
 
 
122
        bne copy_to_cache
 
123
 
 
124
        # wait a bit, start scripts are slow...  need to get all cores running!
 
125
        lis 3,0x4000 ; mtctr 3 ; bdnz $
 
126
 
 
127
        # copy 4MB from 0 to temp memory
 
128
   lis 4,0x8 ; mtctr 4 ; lis 4,0x200  ; li 3,0 ; addi 4,4,-8 ; addi 3,3,-8
 
129
0:      ldu 5,8(3) ; stdu 5,8(4) ; bdnz 0b
 
130
 
 
131
        lis 4,0x200
 
132
        mtsprg  1, r4
 
133
 
 
134
        lis 4,0x1
 
135
        lis 3,0x20 ; addi 3,3,0x200-8 ;
 
136
        FLUSH_CACHE(r3, r4)
 
137
 
 
138
        lis 4,0x200
 
139
        addi 4,4,copy_to_cache@l
 
140
        mtctr 4
 
141
        bctr
 
142
 
 
143
# make all data accesses cache-inhibited
 
144
set_ci_bit:
 
145
        SETCI(r0)
 
146
        blr
 
147
 
 
148
# make all data accesses cacheable
 
149
clr_ci_bit:
 
150
        CLRCI(r0)
 
151
        blr
 
152
 
 
153
# write a character to the serial port
 
154
putc:
 
155
# always write to serial1
 
156
0:      lbz 0,5(13) ; andi. 0,0,0x20 ; beq 0b ; stb 3,0(13) ; eieio
 
157
 
 
158
# read ID register: only if it is a PC87427 (JS21) also use serial2
 
159
        li 4,0 ; oris 4,4,0xf400
 
160
        li 5,0x20 ; stb 5,0x2e(4) ; lbz 5,0x2f(4); cmpdi 5,0xf2 ; bne 1f
 
161
 
 
162
        addi 4,4,0x2f8
 
163
0:      lbz 0,5(4) ; andi. 0,0,0x20 ; beq 0b ; stb 3,0(4) ; eieio
 
164
 
 
165
1:      blr
 
166
 
 
167
# transfer from running from flash to running from cache
 
168
return_cacheable:
 
169
        # find and set address to start running from cache, set msr value 
 
170
        mflr 3 ; rldicl 3,3,0,44 
 
171
jump_cacheable:
 
172
        mtsrr0 3 ; 
 
173
        mfmsr 3 ; ori 3,3,0x1000 ; mtsrr1 3 # enable MCE, as well
 
174
 
 
175
        # set cacheable insn fetches, jump to cache
 
176
        mfspr 3,HID1 ; rldicl 3,3,32,0 ; oris 3,3,0x0020 ; rldicl 3,3,32,0
 
177
        sync ; mtspr HID1,3 ; mtspr HID1,3 ; rfid ; b .
 
178
 
 
179
 
 
180
 
 
181
 
 
182
copy_to_cache:
 
183
        # zero the whole cache
 
184
        # also, invalidate the insn cache, to clear parity errors
 
185
        # 128kB @ 0MB (boot code and vectors from 0x0 up to 0x20000)
 
186
        li 4,0x400 ; mtctr 4 ; li 5,0x0 ; bl clr_ci_bit
 
187
0:      dcbz 0,5 ; sync ; icbi 0,5 ; sync ; isync ; addi 5,5,0x80 ; bdnz 0b
 
188
 
 
189
        # 0x2000 to 0x100000/0x80000 (smaller on 970/970FX)
 
190
        li 4,0x1C00 ; mfpvr 0 ; srdi 0,0,16 ; cmpdi 0,0x0044 ; bge 0f ; li 4,0xC00
 
191
0:
 
192
        mtctr 4 ; li 5,0x2000
 
193
0:      dcbz 0,5 ; sync ; isync ; addi 5,5,0x80 ; bdnz 0b ; bl set_ci_bit
 
194
 
 
195
        # find base address
 
196
        bcl 20,31,$+4 ; mflr 31 ; rldicr 31,31,0,43
 
197
 
 
198
        # copy 1kB from 0x4000
 
199
        li 4,0x80 ; mtctr 4 ; 
 
200
        li      5,0x3ff8
 
201
        addi 3,31,0x3ff8
 
202
0:      ldu 4,8(3) ; bl clr_ci_bit ; stdu 4,8(5) ; bl set_ci_bit ; bdnz 0b
 
203
        # now start executing from cache -- insn cache is huge speed boost
 
204
 
 
205
        bl return_cacheable
 
206
 
 
207
        li 3,'L' ; bl putc
 
208
 
 
209
        # copy 128kB of flash to cache
 
210
        li 4,0x800 ; mtctr 4 ; li 5,0x200-64 ; addi 3,31,0x200-64 ; 
 
211
0:      ldu 16,64(3) ; ld 17,8(3) ; ld 18,16(3) ; ld 19,24(3)
 
212
        ld 20,32(3) ; ld 21,40(3) ; ld 22,48(3) ; ld 23,56(3)
 
213
        bl clr_ci_bit
 
214
        stdu 16,64(5) ; std 17,8(5) ; std 18,16(5) ; std 19,24(5)
 
215
        std 20,32(5) ; std 21,40(5) ; std 22,48(5) ; std 23,56(5)
 
216
        icbi 0,5 ; bl set_ci_bit ; bdnz 0b ; isync
 
217
 
 
218
 
 
219
        li 3,'O' ; bl putc
 
220
 
 
221
        lis 4,0x20
 
222
        mfsprg  r3,1
 
223
        cmpd r3,r4
 
224
        beq 1f
 
225
 
 
226
        // at 0xf8000000 we decide if it is u3 or u4
 
227
        li 4,0 ; oris 4,4,0xf800 ; lwz 3,0(4) ; srdi 3,3,4 ; cmpdi 3,3 ; bne 0f
 
228
        bl setup_mem_u3
 
229
        bl setup_mem_size
 
230
        b 1f
 
231
0:
 
232
 
 
233
1:
 
234
        li 3,'F' ; bl putc
 
235
 
 
236
        # setup nvram logging only when not running from RAM
 
237
        mfsprg  r3, 1   /* rombase */
 
238
        cmpdi   r3, 0   /* rombase is 0 when running from RAM */
 
239
        beq     0f
 
240
 
 
241
        // at 0xf8000000 we decide if it is u3 or u4
 
242
        li      r4, 0
 
243
        oris    r4, r4, 0xf800
 
244
        lwz     r3, 0(r4)
 
245
        srdi    r3, r3, 4
 
246
        cmpdi   r3, 3   /* 3 means js20; no nvram logging on js20 */
 
247
        beq     0f
 
248
 
 
249
        bl      io_log_init
 
250
0:
 
251
 
 
252
        #bl print_mem
 
253
 
 
254
        # data is cacheable by default from now on
 
255
        bl clr_ci_bit
 
256
 
 
257
 
 
258
        /* give live sign *****************************/
 
259
        bl      0f
 
260
        .ascii  TERM_CTRL_RESET
 
261
        .ascii  TERM_CTRL_CRSOFF
 
262
        .ascii  " **********************************************************************"
 
263
        .ascii  "\r\n"
 
264
        .ascii  TERM_CTRL_BRIGHT
 
265
        .ascii  PRODUCT_NAME
 
266
        .ascii  " Starting\r\n"
 
267
        .ascii  TERM_CTRL_RESET
 
268
        .ascii  " Build Date = ", __DATE__, " ", __TIME__
 
269
        .ascii  "\r\n"
 
270
        .ascii  " FW Version = " , RELEASE
 
271
        .ascii  "\r\n\0"
 
272
        .align  2
 
273
0:      mflr    r3
 
274
        bl      io_print
 
275
 
 
276
        # go!
 
277
        li      r3,__startC@l
 
278
        mtctr   r3
 
279
        mfsprg  r10, 1
 
280
        bctrl
 
281
 
 
282
relTag:
 
283
        .ascii  RELEASE
 
284
        .ascii  "\0"
 
285
        .align  2
 
286
 
 
287
slave:
 
288
 
 
289
        # get cpu number
 
290
        li 3,0 ; oris 3,3,0xf800 ; lwz 28,0x50(3)
 
291
 
 
292
slaveWithNumber:
 
293
        # create our slave loop address
 
294
        sldi 3,28,24 ; oris 3,3,0x3000
 
295
 
 
296
        # invalidate the insn cache, to clear parity errors
 
297
        # clear the L2 cache as well, to get ECC right
 
298
        li 4,0x2000 ; mfpvr 0 ; srdi 0,0,16 ; cmpdi 0,0x0044 ; bge 0f ; li 4,0x1000
 
299
0:      mtctr 4 ; mr 5,3 ; bl clr_ci_bit
 
300
 
 
301
0:      dcbz 0,5 ; sync ; icbi 0,5 ; sync ; isync ; addi 5,5,0x80 ; bdnz 0b
 
302
 
 
303
 
 
304
        # write a "b $" insn in there
 
305
        lis 4,0x4800 ; stw 4,0(3)
 
306
/*
 
307
        mr 5,3
 
308
 
 
309
        # jump there
 
310
        bl set_ci_bit
 
311
        li 13,0 ; oris 13,13,0xf400
 
312
        # device address
 
313
        addi 13,13,0x2f8
 
314
        li 3,'O' ; add 3,3,28 ; bl putc
 
315
        bl clr_ci_bit
 
316
        mr 3,5
 
317
*/
 
318
        b jump_cacheable
 
319
 
 
320
 
 
321
 
 
322
 
 
323
# allow the flash chip to be accessed faster
 
324
# initialize the 16550-compatible uart on serial port 1 of the sio
 
325
setup_sio:
 
326
 
 
327
        # i/o base address
 
328
        li 3,0 ; oris 3,3,0xf400
 
329
 
 
330
        # i/o base address
 
331
        li 3,0 ; oris 3,3,0xf400
 
332
 
 
333
        # put x-bus in turbo mode
 
334
        li 4,0xf1 ; stb 4,0x400(3) ; eieio
 
335
 
 
336
 
 
337
        # select sio serial1
 
338
        li 4,7 ; stb 4,0x2e(3) ; eieio ; li 4,3 ; stb 4,0x2f(3) ; eieio
 
339
 
 
340
        # set base address to 3f8
 
341
        li 4,0x60 ; stb 4,0x2e(3) ; eieio ; li 4,3 ; stb 4,0x2f(3) ; eieio
 
342
 
 
343
        # enable device
 
344
        li 4,0x30 ; stb 4,0x2e(3) ; eieio ; li 4,1 ; stb 4,0x2f(3) ; eieio
 
345
 
 
346
        # read ID register: only if it is a PC87427, enable serial2
 
347
        li 4,0x20 ; stb 4,0x2e(3) ; eieio ; lbz 4,0x2f(3) ; cmpdi 4,0xf2 ; bne 0f
 
348
 
 
349
        # select sio serial2
 
350
        li 4,7 ; stb 4,0x2e(3) ; eieio ; li 4,2 ; stb 4,0x2f(3) ; eieio
 
351
 
 
352
        # set base address to 2f8
 
353
        li 4,0x60 ; stb 4,0x2e(3) ; eieio ; li 4,2 ; stb 4,0x2f(3) ; eieio
 
354
 
 
355
        # enable device
 
356
        li 4,0x30 ; stb 4,0x2e(3) ; eieio ; li 4,1 ; stb 4,0x2f(3) ; eieio
 
357
 
 
358
        # uart @0x2f8
 
359
        addi 3,3,0x2f8
 
360
 
 
361
        # disable interrupts, fifo off
 
362
        li 4,0 ; stb 4,1(3) ; eieio ; stb 4,2(3) ; eieio
 
363
 
 
364
        # set serial speed
 
365
        li 4,0x80 ; stb 4,3(3) ; eieio
 
366
        li 4,115200/19200 ; stb 4,0(3) ; eieio ; li 4,0 ; stb 4,1(3) ; eieio
 
367
 
 
368
        # set 8-N-1, set RTS and DTR
 
369
        li 4,3 ; stb 4,3(3) ; eieio ; stb 4,4(3) ; eieio
 
370
 
 
371
        eieio
 
372
 
 
373
        addi 3,3,-0x2f8
 
374
 
 
375
        # uart @0x3f8
 
376
0:      addi 3,3,0x3f8
 
377
 
 
378
        # disable interrupts, fifo off
 
379
        li 4,0 ; stb 4,1(3) ; eieio ; stb 4,2(3) ; eieio
 
380
 
 
381
        # set serial speed
 
382
        li 4,0x80 ; stb 4,3(3) ; eieio
 
383
        li 4,115200/19200 ; stb 4,0(3) ; eieio ; li 4,0 ; stb 4,1(3) ; eieio
 
384
 
 
385
        # set 8-N-1, set RTS and DTR
 
386
        li 4,3 ; stb 4,3(3) ; eieio ; stb 4,4(3) ; eieio
 
387
 
 
388
        eieio
 
389
 
 
390
        # save UART base for putc routine
 
391
0:      mr 13,3
 
392
 
 
393
        blr
 
394
 
 
395
 
 
396
 
 
397
 
 
398
# set the HID registers of the 970 for optimally executing from flash
 
399
setup_cpu:
 
400
 
 
401
        /* clear all the HV cruft */
 
402
        li      r0, 0
 
403
        sync
 
404
        mtspr   HID4, r0
 
405
        isync
 
406
 
 
407
        /* enable dpm, disable attn insn, enable external mce
 
408
         * first, try external time base; if clock doesn't run, switch to
 
409
         * internal */
 
410
        li      r0, 1                   /* do the setup for external timebase */
 
411
        rldicl  r0, r0, 44, 0           /* bit 19 has to be set */
 
412
        oris    r0, r0, 0x8000          /* Enable external machine check */
 
413
                                        /* interrupts (preferred state */
 
414
                                        /* equals `1'). */
 
415
        sync
 
416
        mtspr   HID0, r0
 
417
        isync
 
418
 
 
419
        mftb    r3                      /* read the timebase */
 
420
        li      r1, 0x4000              /* wait long enough for the external */
 
421
        mtctr   r1                      /* timebase (14MHz) to tick a bit */
 
422
        bdnz    $                       /* 0x4000 seems to be enough (for now) */
 
423
        mftb    r4                      /* read the timebase a second time */
 
424
        cmpld   r3, r4                  /* see if it changed */
 
425
        bne     0f
 
426
        /* timebase did not change, do the setup for internal */
 
427
        rldicl  r0, r0, 19, 1
 
428
        rldicl  r0, r0, 45, 0
 
429
        sync
 
430
        mtspr   HID0, r0
 
431
        isync
 
432
 
 
433
0:
 
434
        /* enable insn prefetch, speculative table walks */
 
435
        mfspr   r0, HID1
 
436
        rldicl  r0, r0, 20, 0
 
437
        ori     r0, r0, 0x1002
 
438
        mfsprg  r3, 1                   /* read rombase */
 
439
        cmpdi   r3, 0                   /* check if running from ram */
 
440
        bne     0f
 
441
        /* running from ram */
 
442
        /* Enable instruction fetch cacheability control */
 
443
        ori     r0, r0, 0x200
 
444
0:
 
445
        rldicl  r0, r0, 44, 0
 
446
        sync
 
447
        mtspr   HID1, r0
 
448
        isync
 
449
 
 
450
        /* enable cache parity */
 
451
        mfspr   r0, HID4
 
452
        oris    r0, r0, 0xfff0
 
453
        xoris   r0, r0, 0xfff0
 
454
        sync
 
455
        mtspr   HID4, r0
 
456
        isync
 
457
 
 
458
        /* exception offset at 0 */
 
459
        li      r3, 0
 
460
        mtspr   HIOR, r3
 
461
 
 
462
        blr
 
463
 
 
464
C_ENTRY(proceedInterrupt)
 
465
 
 
466
        ld      r3,exception_stack_frame@got(r2)
 
467
        ld      r1,0(r3)
 
468
 
 
469
        .irp i, 2,3,4,5,6,7,8,9,10,11,12,13,14,15,16, \
 
470
                17, 18, 19, 20, 21, 22, 23, 24, 25, 26, \
 
471
                27, 28, 29, 30, 31
 
472
        ld      r\i, 0x30+\i*8 (r1)
 
473
        .endr
 
474
 
 
475
        ld      r14,0x138(r1);
 
476
        mtsrr0  r14
 
477
 
 
478
        ld      r14,0x140(r1);
 
479
        mtsrr1  r14
 
480
 
 
481
        ld      r14,0x148(r1);
 
482
        mtcr    r14
 
483
 
 
484
 
 
485
        ld 0,XVECT_M_HANDLER(0)
 
486
        mtctr 0
 
487
 
 
488
        ld      r0,0x30(r1); # restore vector number
 
489
        ld      r1,0x38(r1);
 
490
 
 
491
        bctr
 
492
 
 
493
intHandler2C:
 
494
        mtctr   r1 # save old stack pointer
 
495
        lis     r1,0x4
 
496
        stdu    r1, -0x160(r1)
 
497
        .irp i, 2,3,4,5,6,7,8,9,10,11,12,13,14,15,16, \
 
498
                17, 18, 19, 20, 21, 22, 23, 24, 25, 26, \
 
499
                27, 28, 29, 30, 31
 
500
        std     r\i, 0x30+\i*8 (r1)
 
501
        .endr
 
502
 
 
503
        std     r0,0x30(r1);  # save vector number
 
504
 
 
505
        mfctr   r14
 
506
        std     r14,0x38(r1); # save old r1
 
507
 
 
508
        mfsrr0  r14
 
509
        std     r14,0x138(r1);
 
510
 
 
511
        mfsrr1  r14
 
512
        std     r14,0x140(r1);
 
513
 
 
514
        mfcr    r14
 
515
        std     r14,0x148(r1);
 
516
 
 
517
        mfxer   r14
 
518
        std     r14,0x150(r1);
 
519
 
 
520
        bl toc_init
 
521
 
 
522
        ld      r3,exception_stack_frame@got(r2)
 
523
        std     r1,0(r3)
 
524
 
 
525
 
 
526
        mr      r3,r0
 
527
        bl .c_interrupt
 
528
 
 
529
        ld      r14,0x138(r1);
 
530
        mtsrr0  r14
 
531
 
 
532
        ld      r14,0x140(r1);
 
533
        mtsrr1  r14
 
534
 
 
535
        ld      r14,0x148(r1);
 
536
        mtcr    r14
 
537
 
 
538
        ld      r14,0x150(r1);
 
539
        mtxer   r14
 
540
 
 
541
 
 
542
        .irp i, 2,3,4,5,6,7,8,9,10,11,12,13,14,15,16, \
 
543
                17, 18, 19, 20, 21, 22, 23, 24, 25, 26, \
 
544
                27, 28, 29, 30, 31
 
545
        ld      r\i, 0x30+\i*8 (r1)
 
546
        .endr
 
547
 
 
548
        ld      r1,0x38(r1);
 
549
 
 
550
        mfsprg  r0,2
 
551
        mtctr   r0
 
552
        mfsprg  r0,3
 
553
        mtlr    r0
 
554
        mfsprg  r0,0
 
555
        rfid
 
556
 
 
557
/* Set exception handler for given exception vector.  
 
558
        r3:     exception vector offset
 
559
        r4:     exception handler
 
560
*/
 
561
        .globl .set_exception
 
562
.set_exception:
 
563
        .globl set_exception
 
564
set_exception:
 
565
    ld r4,0x0(r4)
 
566
        .globl .set_exception_asm
 
567
.set_exception_asm:
 
568
        .globl set_exception_asm
 
569
set_exception_asm:
 
570
        std     r4, 0x60(r3)    # fixme diff 1f - 0b
 
571
        blr
 
572
 
 
573
 
 
574
setup_mem_u3:
 
575
        li 4,0x2000 ; oris 4,4,0xf800
 
576
 
 
577
        # MemTimingParam -- CAS lat 2.5 / 4 (read-to-read / read-to-write)
 
578
        lis 3,0x49e1 ; ori 3,3,0xa000 ; stw 3,0x50(4)
 
579
 
 
580
        # MRSRegCntl -- CAS lat 2.5
 
581
        li 3,0x6a ; stw 3,0xf0(4)
 
582
 
 
583
        # MemBusConfig -- 128 bit bus
 
584
        lis 3,0x8500 ; stw 3,0x190(4)
 
585
 
 
586
        # CKDelAdj -- clock delay 75
 
587
        lis 3,0x12c3 ; ori 3,3,0x30cc ; stw 3,0x520(4)
 
588
 
 
589
        # IOModeCntl -- no termination on differential and 3-state drivers
 
590
        lis 3,0x0350 ; stw 3,0x530(4)
 
591
 
 
592
        li 3,18 ; mtctr 3 ; addi 5,4,0x5f0
 
593
0:      # DQSDelAdj -- read delay offset -10
 
594
        lis 3,0x3d8f ; ori 3,3,0x6000 ; stwu 3,0x10(5)
 
595
 
 
596
        # DQSDataDelAdj -- write delay offset -32, write data delay offset +15
 
597
        lis 3,0x380e ; ori 3,3,0x003c ; stwu 3,0x10(5)
 
598
        bdnz 0b
 
599
 
 
600
        # MemProgCntl -- set all
 
601
        lis 3,0xc000 ; stw 3,0xe0(4)
 
602
 
 
603
        eieio
 
604
 
 
605
        blr
 
606
 
 
607
 
 
608
# read dimm SPDs, program memory size and type
 
609
setup_mem_size:
 
610
        mflr 14
 
611
 
 
612
        li 15,0 ; oris 15,15,0xf800 ; li 17,0
 
613
        li 3,0xa0 ; li 4,3 ; li 5,3 ; bl i2c_read
 
614
        mr 16,4 ; cmpdi 3,0 ; beq 0f ; li 16,0
 
615
0:      li 3,0xa2 ; li 4,3 ; li 5,3 ; bl i2c_read
 
616
        cmpd 16,4 ; bne 0f ; cmpdi 3,0 ; beq 1f
 
617
0:      li 16,0x1e00
 
618
1:      #li 3,0xd ; bl print_byte ; li 3,0xa ; bl print_byte
 
619
        #mr 3,16 ; bl print_hex
 
620
 
 
621
        #li 3,0x20 ; bl print_byte
 
622
        sldi 3,16,7 ; add 3,3,16 ; rlwinm 3,3,10,0,6 ; subis 3,3,0x3c00
 
623
        stw 3,0x21c0(15) ; andi. 0,16,2 ; beq 0f ; stw 3,0x21e0(15)
 
624
0:      #bl print_hex
 
625
        sldi 3,16,8 ; add 3,3,16 ; rldicl 3,3,48,56 ; li 0,8 ; slw 3,0,3
 
626
                # slw, not sld, so that empty/bad banks translate into size 0
 
627
        stw 17,0x21d0(15) ; bl add17173 ; stw 17,0x21f0(15)
 
628
        andi. 0,16,2 ; beq 0f ; bl add17173
 
629
0:      #bl print_hex
 
630
 
 
631
        li 3,0xa4 ; li 4,3 ; li 5,3 ; bl i2c_read
 
632
        mr 16,4 ; cmpdi 3,0 ; beq 0f ; li 16,0
 
633
0:      li 3,0xa6 ; li 4,3 ; li 5,3 ; bl i2c_read
 
634
        cmpd 16,4 ; bne 0f ; cmpdi 3,0 ; beq 1f
 
635
0:      li 16,0x1e00
 
636
1:      #li 3,0xd ; bl print_byte ; li 3,0xa ; bl print_byte
 
637
        #mr 3,16 ; bl print_hex
 
638
 
 
639
        #li 3,0x20 ; bl print_byte
 
640
        sldi 3,16,7 ; add 3,3,16 ; rlwinm 3,3,10,0,6 ; subis 3,3,0x3c00
 
641
        stw 3,0x2200(15) ; andi. 0,16,2 ; beq 0f ; stw 3,0x2220(15)
 
642
0:      #bl print_hex
 
643
        sldi 3,16,8 ; add 3,3,16 ; rldicl 3,3,48,56 ; li 0,8 ; slw 3,0,3
 
644
        stw 17,0x2210(15) ; bl add17173 ; stw 17,0x2230(15)
 
645
        andi. 0,16,2 ; beq 0f ; bl add17173
 
646
0:      #bl print_hex
 
647
        #mr 3,17 ; bl print_hex
 
648
        stw 17,0x2250(15) ; stw 17,0x2270(15)
 
649
        stw 17,0x2290(15) ; stw 17,0x22b0(15)
 
650
 
 
651
        mtlr 14
 
652
        blr
 
653
 
 
654
 
 
655
 
 
656
 
 
657
# print GPR3 as 8-digit hex.  uses GPR18,19
 
658
print_hex:
 
659
        mflr 18 ; mr 19,3 ; li 3,8 ; mtctr 3
 
660
1:      rlwinm 3,19,4,28,31 ; sldi 19,19,4
 
661
        cmpdi 3,0xa ; blt 0f ; addi 3,3,0x27
 
662
0:      addi 3,3,0x30 ; bl putc
 
663
        bdnz 1b ; mtlr 18 ; blr
 
664
 
 
665
 
 
666
# i2c stuff uses GPR20..GPR24
 
667
 
 
668
# terminate any i2c transaction, at any point during that transaction
 
669
i2c_stop:
 
670
0:      lwz 3,0x30(20) ; stw 3,0x30(20) ; andi. 3,3,4 ; beq 0b
 
671
        mr 3,21 ; mr 4,22 ; mtlr 24 ; eieio ; blr
 
672
 
 
673
# do a combined-mode read
 
674
# in: GPR3 = addr, GPR4 = subaddr, GPR5 = len
 
675
# out: GPR3 = error, GPR4 = result (right-aligned, msb)
 
676
i2c_read:
 
677
        mflr 24
 
678
        li 20,0x1000 ; oris 20,20,0xf800        # uni-n i2c base
 
679
        mr 21,3 ; mr 22,4 ; mr 23,5             # save params
 
680
        li 4,0xc ; stw 4,0(20)                  # set mode (combined)
 
681
        ori 4,21,1 ; stw 4,0x50(20)             # set addr, read
 
682
        stw 22,0x60(20)                         # set subaddr
 
683
        li 4,2 ; stw 4,0x10(20) ; eieio         # start address phase
 
684
        li 21,1                                 # error
 
685
        li 22,0                                 # result accumulator
 
686
0:      lwz 3,0x30(20) ; andi. 3,3,2 ; beq 0b   # wait until sent
 
687
        lwz 3,0x20(20) ; andi. 3,3,2 ; beq i2c_stop # check result
 
688
        li 4,1 ; cmpdi 23,1 ; bne 0f ; li 4,0
 
689
0:      stw 4,0x10(20)                          # AAK for next byte (or not)
 
690
        li 4,2 ; stw 4,0x30(20) ; eieio         # ack address phase
 
691
i2c_read_loop:
 
692
        lwz 3,0x30(20) ; andi. 3,3,1 ; beq 1f   # if byte recv'd:
 
693
        subi 23,23,1 ; sldi 22,22,8             # shift byte accum
 
694
        lwz 3,0x70(20) ; rlwimi 22,3,0,24,31    # get byte
 
695
        cmpdi 23,0 ; bne 0f ; li 21,0 ; b i2c_stop # all done
 
696
0:      li 4,1 ; cmpdi 23,1 ; bne 0f ; li 4,0
 
697
0:      stw 4,0x10(20)                          # AAK for next byte (or not)
 
698
        li 4,1 ; stw 4,0x30(20) ; eieio         # ack data phase
 
699
1:      lwz 3,0x30(20) ; andi. 3,3,4 ; beq i2c_read_loop
 
700
        li 4,0 ; stw 4,0x10(20) ; eieio ; b i2c_stop # stop bit received
 
701
 
 
702
add17173: # add GPR3 into GPR17; if passing 2GB (0x10000000), add another 2GB.
 
703
        lis 0,0x1000 ; cmpld 17,0 ; add 17,17,3 ; bgtlr
 
704
        cmpld 17,0 ; blelr ; add 17,17,0 ; blr
 
705
 
 
706
io_log_init:
 
707
        LOAD64(r3, SB_NVRAM_adr)
 
708
        b checkinitLog