Annotation of qemu/roms/SLOF/board-js2x/slof/u4-mem.fs, revision 1.1.1.1

1.1       root        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: 
                     14: \ U4 DDR2 memory controller.
                     15: 
                     16: cr .( Setting up memory controller...)
                     17: 
                     18: 
                     19: \ First, I2C access to the SPDs.
                     20: 
                     21: : >i2c  f8001000 + ;
                     22: : i2c@  >i2c rl@ ;
                     23: : i2c!  >i2c rl! ;
                     24: 
                     25: : .i2c  80 0 DO i i2c@ . 10 +LOOP ;
                     26: 
                     27: : i2c-addr ( addr -- )  50 i2c!  2 10 i2c!  BEGIN 30 i2c@ 2 and UNTIL ;
                     28: : i2c-addr-subaddr ( addr suba -- )  60 i2c! i2c-addr ;
                     29: : i2c-stop ( -- )  BEGIN 30 i2c@ dup 30 i2c! 4 and UNTIL ;
                     30: : i2c-nak? ( -- failed? )  20 i2c@ 2 and 0= dup IF i2c-stop THEN ;
                     31: : i2c-short? ( -- failed? )  30 i2c@ 4 and 0<> dup IF 0 10 i2c! i2c-stop THEN ;
                     32: : i2c-aak-if-more ( n -- )  1 <> 1 and 10 i2c! ;
                     33: 
                     34: : i2c-sub-read ( buf len addr suba -- error? )
                     35:   c 0 i2c!  >r 1 or r> i2c-addr-subaddr  i2c-nak? IF 2drop true EXIT THEN
                     36:   dup i2c-aak-if-more  2 30 i2c!
                     37:   BEGIN
                     38:   30 i2c@ 1 and IF
                     39:     1- >r 70 i2c@ over c! char+ r>
                     40:     dup 0= IF i2c-stop 2drop false EXIT THEN
                     41:     dup i2c-aak-if-more 1 30 i2c! THEN
                     42:   i2c-short? IF 2drop true EXIT THEN
                     43:   AGAIN ;
                     44: 
                     45: 
                     46: \ What slots are filled with working memory (bitmask).
                     47: 
                     48: f VALUE dimms-valid
                     49: : dimm-invalid  1 swap lshift invert dimms-valid and to dimms-valid ;
                     50: : dimm-invalid  dup dimm-invalid 2 xor dimm-invalid ; \ DIMMs are paired
                     51: : dimm-valid?  1 swap lshift dimms-valid and ;
                     52: : dimm(  +comp postpone 4 postpone 0 postpone DO
                     53:                postpone i postpone dimm-valid? postpone IF ; immediate
                     54: : )dimm  postpone THEN postpone LOOP -comp ; immediate
                     55: 
                     56: 
                     57: \ The data from the SPDs.
                     58: 
                     59: CREATE spds 100 allot
                     60: : spd@ ( dimm# off -- value ) swap 40 * + spds + c@ ;
                     61: 
                     62: CREATE addresses a0 c, a4 c, a2 c, a6 c,
                     63: dimm( spds i 40 * + 40 addresses i + c@ 0 i2c-sub-read IF i dimm-invalid THEN )dimm
                     64: 
                     65: 
                     66: \ Accessors.
                     67: 
                     68: : spd>rows  3 spd@ ;
                     69: : spd>cols  4 spd@ ;
                     70: : spd>ranks 5 spd@ 7 and 1+ ;
                     71: : spd>width d spd@ ;
                     72: : spd>banks 11 spd@ ;
                     73: : spd>cas   12 spd@ ; \ bit mask of allowable CAS latencies
                     74: : spd>trp   1b spd@ ; \ in units of 0.25 ns
                     75: : spd>trrd  1c spd@ ; \ in units of 0.25 ns
                     76: : spd>trcd  1d spd@ ; \ in units of 0.25 ns
                     77: : spd>tras  1e spd@ ; \ in units of 1 ns
                     78: : spd>twr   24 spd@ ; \ in units of 0.25 ns
                     79: : spd>twtr  25 spd@ ; \ in units of 0.25 ns
                     80: : spd>trtp  26 spd@ ; \ in units of 0.25 ns
                     81: : spd>trc   29 spd@ ; \ in units of 1 ns  XXX: should also look at byte 28
                     82: : spd>trfc  2a spd@ ; \ in units of 1 ns  XXX: should also look at byte 28
                     83: 
                     84: cr .( rows cols ranks width banks trp trrd trcd tras twr twtr trtp trc trfc)
                     85: cr .( =====================================================================)
                     86: decimal
                     87: dimm( cr
                     88: i spd>rows  4 .r  i spd>cols  5 .r  i spd>ranks 6 .r  i spd>width 6 .r
                     89: i spd>banks 6 .r  i spd>trp   4 .r  i spd>trrd  5 .r  i spd>trcd  5 .r
                     90: i spd>tras  5 .r  i spd>twr   4 .r  i spd>twtr  5 .r  i spd>trtp  5 .r
                     91: i spd>trc   4 .r  i spd>trfc  5 .r
                     92: )dimm
                     93: hex
                     94: 
                     95: ff dimm( i spd>cas and )dimm CONSTANT cl-supported
                     96: : max-cl  -1 swap 8 0 DO dup 1 and IF nip i swap THEN u2/ LOOP drop ;
                     97: cl-supported max-cl VALUE cl
                     98: 
                     99: : tck>60*ns dup f and swap 4 rshift a * over + 6 * swap CASE
                    100:             a OF 2d - ENDOF b OF 2e - ENDOF c OF 20 - ENDOF d OF 21 - ENDOF
                    101:             ENDCASE ;
                    102: : cl>tck  0 spd>cas max-cl swap -
                    103:           CASE 0 OF 9 ENDOF 1 OF 17 ENDOF 2 OF 19 ENDOF
                    104:           true ABORT" No supported CAS latency for this DIMM" ENDCASE
                    105:           0 swap spd@ tck>60*ns ;
                    106: 
                    107: : spd>min-tck  dup spd>cas max-cl cl -
                    108:                CASE 0 OF 9 ENDOF 1 OF 17 ENDOF 2 OF 19 ENDOF
                    109:                true ABORT" No supported CAS latency for this DIMM" ENDCASE
                    110:                spd@ tck>60*ns ;
                    111: : spd>max-tck  2b spd@ tck>60*ns ;
                    112: 
                    113: : .tck  base @ >r decimal dup d# 60 / 0 .r [char] . emit
                    114:         d# 60 mod d# 1000 * d# 60 / 3 0.r ." ns" r> base ! ;
                    115: 
                    116: cr .( CAS latencies supported: )
                    117: 8 0 DO cl-supported 1 i lshift and IF i . THEN LOOP
                    118: 
                    119: \ Find the lowest CL at the highest tCK.
                    120: 8 0 DO cl-supported 1 i lshift and IF cl cl>tck i cl>tck = IF
                    121:        i to cl LEAVE THEN THEN LOOP
                    122: 
                    123: .( -- using ) cl .
                    124: 
                    125: 
                    126: 0 dimm( i spd>min-tck max )dimm  CONSTANT tck
                    127: dimm( i spd>max-tck tck < IF i dimm-invalid THEN )dimm
                    128: cr .( tCK is ) tck .tck
                    129: 
                    130: 
                    131: 0 CONSTANT al
                    132: cl al + CONSTANT rl
                    133: rl 1- CONSTANT wl
                    134: 
                    135: : //  dup >r 1- + r> / ; \ round up
                    136: 0 spd>tras d# 60 * tck // CONSTANT tras
                    137: 0 spd>trtp d# 15 * tck // CONSTANT trtp
                    138: 0 spd>twr  d# 15 * tck // CONSTANT twr
                    139: 0 spd>trp  d# 15 * tck // CONSTANT trp
                    140: 0 spd>trrd d# 15 * tck // CONSTANT trrd
                    141: 0 spd>trrd d# 60 * tck // CONSTANT 4*trrd
                    142: 0 spd>trcd d# 15 * tck // CONSTANT trcd
                    143: 0 spd>trc  d# 60 * tck // CONSTANT trc
                    144: 0 spd>twtr d# 15 * tck // CONSTANT twtr
                    145: 
                    146: : spd>memmd
                    147:   >r r@ spd>rows r@ spd>cols +
                    148:   r@ spd>banks 2log + 4 * r> spd>width 2log 3 * + 6c - ;
                    149: : dimm-group-size ( dimm# -- size )
                    150:   >r r@ spd>rows r@ spd>cols + 1 swap lshift
                    151:   r@ spd>banks * r> spd>ranks * 10 * ;
                    152: VARIABLE start-address
                    153: VARIABLE was-prev-big
                    154: : assign-dimm-group ( dimm# -- config-value )
                    155:   dup dimm-valid? 0= IF drop 0 EXIT THEN
                    156:   \ MemMd, enable, single-sided or not
                    157:   dup spd>memmd c lshift 1 or over spd>ranks 1 = IF 2 or THEN 
                    158: cr ." ---> " dup .
                    159: >r
                    160:   dimm-group-size start-address @ 2dup + rot ( start end size )
                    161:   80000000 > IF
                    162:     dup 1000000000 < IF dup 4 rshift ELSE 08000000 THEN r> or >r \ Add2G
                    163:     over 0<>        IF over c rshift ELSE 00080000 THEN r> or >r \ Sub2G
                    164:     was-prev-big on
                    165:   ELSE
                    166:     was-prev-big @ IF 80000000 + swap 80000000 + swap THEN r> 08080000 or >r
                    167:     was-prev-big off
                    168:   THEN
                    169:   swap 18 rshift r> or >r \ start address
                    170:   dup 80000000 = IF drop 100000000 THEN start-address ! r> ;
                    171: 
                    172: 
                    173: \ Now set the frequency in the memory controller
                    174: d# 1800 tck / 4 - 12 lshift 33c or f8000800 rl!
                    175: f8000860 rl@ 80000000 or f8000860 rl!  10000 0 DO LOOP
                    176: 
                    177: : mc!  f8002000 + rl! ;
                    178: : mc@  f8002000 + rl@ ;
                    179: 
                    180: 
                    181: \ memory timing regs (state machine)
                    182: 
                    183: tras 2-
                    184: 5 lshift al trtp + 2- or
                    185: 5 lshift wl twr + or
                    186: 5 lshift trp 2- or
                    187: 5 lshift trp 2- 0 spd>banks 8 = IF 1+ THEN or
                    188: 7 lshift 030 mc!
                    189: 
                    190: al trtp + trp + 2-
                    191: 5 lshift cl al + twr + trp + 1- or
                    192: 5 lshift trrd 2- or
                    193: 5 lshift trc 2- or
                    194: 5 lshift trcd 2- or
                    195: 5 lshift 4*trrd or
                    196: 2 lshift 040 mc!
                    197: 
                    198: 0
                    199: 5 lshift 1 or
                    200: 5 lshift 1 or
                    201: 5 lshift cl 1- twtr + or
                    202: 5 lshift 1 or
                    203: 5 lshift 1 or
                    204: 2 lshift 050 mc!
                    205: 
                    206: 0
                    207: 5 lshift 1 or
                    208: 5 lshift 1 or
                    209: 5 lshift 2 or
                    210: 5 lshift 2 or
                    211: 5 lshift 2 or
                    212: 2 lshift 060 mc! \ XXX joerg has different setting
                    213: 
                    214: cl 3 = IF 30801800 ( 30800d00 ) 070 mc! \ XXX memory refresh
                    215: ELSE 41002000 070 mc! THEN
                    216: 
                    217: \ memory size regs
                    218: 
                    219: 1 dimm-group-size 0 dimm-group-size > 1 0 rot IF swap THEN \ biggest first
                    220: assign-dimm-group 200 mc!
                    221: assign-dimm-group 210 mc!
                    222: 0 220 mc! 0 230 mc!
                    223: 
                    224: 
                    225: 
                    226: 
                    227: 
                    228: \ arbiter tunables
                    229: \ 40041040 270 mc!
                    230: 04041040 270 mc!
                    231: 50000000 280 mc!
                    232: \ a0a00000 290 mc! \ a0000000 might be faster
                    233: 00000000 290 mc!
                    234: \ 20020820 2a0 mc!
                    235: 04020822 2a0 mc!
                    236: 00000000 2b0 mc!
                    237: \ 30413cc7 2c0 mc! \ have to calculate the low five bits
                    238: 30413dc5 2c0 mc!
                    239: \ cl 3 = IF 76000050 2d0 mc!  70000000 2e0 mc! ELSE
                    240: cl 3 = IF 75000050 2d0 mc!  70000000 2e0 mc! ELSE
                    241:     b8002080 2d0 mc!  b0000000 2e0 mc! THEN
                    242: \ Should test for something else really
                    243: 
                    244: 
                    245: 
                    246: cl 3 = IF 00006000 890 mc!  00006000 8a0 mc! ELSE
                    247:           00006500 890 mc!  00006500 8a0 mc! THEN
                    248: 
                    249: cl 3 = IF 1e008a8a ELSE 31000000 THEN
                    250: dup 800 mc! dup 810 mc! dup 820 mc! dup 830 mc!
                    251: dup 900 mc! dup 910 mc! dup 920 mc! dup 930 mc! dup 980 mc!
                    252: dup a00 mc! dup a10 mc! dup a20 mc! dup a30 mc!
                    253: dup b00 mc! dup b10 mc! dup b20 mc! dup b30 mc!     b80 mc!
                    254: 
                    255: \ 0 8d0 mc!  0 9d0 mc!  0 ad0 mc!  0 bd0 mc!
                    256: 61630000 8d0 mc!
                    257: 61630000 9d0 mc!
                    258: 52510000 ad0 mc!
                    259: 434e0000 bd0 mc!
                    260: 
                    261: a0200400 100 mc!
                    262: 80020000 110 mc!
                    263: 80030000 120 mc!
                    264: 80010404 130 mc!
                    265: cl 3 = IF
                    266: 8000153a 140 mc! ELSE
                    267: 8000174a 140 mc! THEN
                    268: a0200400 150 mc!
                    269: \ 92000000 160 mc!
                    270: \ 92000000 170 mc!
                    271: \ 91300000 160 mc!
                    272: \ 91300000 170 mc!
                    273: 91800000 160 mc!
                    274: 91800000 170 mc!
                    275: cl 3 = IF
                    276: 8ff0143a 180 mc! ELSE
                    277: 8ff0164a 180 mc! THEN
                    278: 80010784 190 mc!
                    279: 80010404 1a0 mc!
                    280: 0 1b0 mc!  0 1c0 mc!  0 1d0 mc!  0 1e0 mc!  0 1f0 mc!
                    281: 
                    282: cl 3 = IF
                    283: 143a 0c0 mc! ELSE
                    284: 164a 0c0 mc! THEN
                    285: 0404 0d0 mc!
                    286: 
                    287: \ after this point, setup is common for all speeds and sizes of dimms (sort of)
                    288: 
                    289: 60000000 3a0 mc!
                    290: 
                    291: 0 840 mc!  0 850 mc!  0 860 mc!  0 870 mc!
                    292: 0 940 mc!  0 950 mc!  0 960 mc!  0 970 mc!  0 990 mc!
                    293: 0 a40 mc!  0 a50 mc!  0 a60 mc!  0 a70 mc!
                    294: 0 b40 mc!  0 b50 mc!  0 b60 mc!  0 b70 mc!  0 b90 mc!
                    295: 
                    296: 0 880 mc!
                    297: 
                    298: 001a4000 9a0 mc!
                    299: 
                    300: 84800000 500 mc!
                    301: 
                    302: 10000 0 DO LOOP
                    303: 
                    304: 80000000 b0 mc!  BEGIN b0 mc@ 40000000 and UNTIL
                    305: 
                    306: 0 300 mc!  0 310 mc!
                    307: 
                    308: 80000000 440 mc!
                    309: 0 410 mc!  27fffffc 420 mc!
                    310: fedcba98 430 mc!
                    311: c0000000 400 mc!  BEGIN 400 mc@ c0000000 and 0= UNTIL
                    312: 
                    313: cr .( mem done)

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.