|
|
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: # 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
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.