📄 asm_init.s
字号:
lwz r5,SD_STATUS(r4) andi. r5,r5,0x0001 /* wait until SDRAM initialization is complete */ beq wait_init_complete /* Map SDRAM into the processor bus address space */ ori r4,r29,TSI108_PB_REG_OFFSET /* Setup BARs associated with direct path PB<->SDRAM */ /* PB_SDRAM_BAR1: * provides a direct path to the main system memory (cacheable SDRAM) */ /* BA=0,Size=512MB, ENable, No Addr.Translation */ LOAD_U32(r5, 0x00000011) stw r5,PB_SDRAM_BAR1(r4) sync /* Make sure that PB_SDRAM_BAR1 decoder is set * (to allow following immediate read from SDRAM) */ lwz r5,PB_SDRAM_BAR1(r4) sync /* PB_SDRAM_BAR2: * provides non-cacheable alias (via the direct path) to main * system memory. * Size = 512MB, ENable, Addr.Translation - ON, * BA = 0x0_40000000, TA = 0x0_00000000 */ LOAD_U32(r5, 0x40010011) stw r5,PB_SDRAM_BAR2(r4) sync /* Make sure that PB_SDRAM_BAR2 decoder is set * (to allow following immediate read from SDRAM) */ lwz r5,PB_SDRAM_BAR2(r4) syncinit_done: /* All done. Restore LR and return. */ mtlr r19 blr#if (0) /* * init_cpu1 * This routine enables CPU1 on the dual-processor system. * Now there is only one processor in the system */ .global enable_cpu1enable_cpu1: lis r3,Tsi108_Base@ha /* Get Grendel CSR Base Addr */ addi r3,r3,Tsi108_Base@l lwz r3,0(r3) /* R3 = CSR Base Addr */ ori r4,r3,TSI108_PB_REG_OFFSET lwz r3,PB_ARB_CTRL(r4) /* Read PB Arbiter Control Register */ ori r3,r3,0x0200 /* Set M1_EN bit */ stw r3,PB_ARB_CTRL(r4) blr#endif /* * enable_EI * Enable CPU core external interrupt */ .global enable_EIenable_EI: mfmsr r3 ori r3,r3,0x8000 /* set EE bit */ mtmsr r3 blr /* * disable_EI * Disable CPU core external interrupt */ .global disable_EIdisable_EI: mfmsr r3 li r4,-32768 /* aka "li r4,0x8000" */ andc r3,r3,r4 /* clear EE bit */ mtmsr r3 blr#ifdef ENABLE_SDRAM_ECC /* enables SDRAM ECC */ .global enable_ECCenable_ECC: ori r4,r29,TSI108_SD_REG_OFFSET lwz r3,SD_ECC_CTRL(r4) /* Read SDRAM ECC Control Register */ ori r3,r3,0x0001 /* Set ECC_EN bit */ stw r3,SD_ECC_CTRL(r4) blr /* * clear_ECC_err * Clears all pending SDRAM ECC errors * (normally after SDRAM scrubbing/initialization) */ .global clear_ECC_errclear_ECC_err: ori r4,r29,TSI108_SD_REG_OFFSET ori r3,r0,0x0030 /* ECC_UE_INT + ECC_CE_INT bits */ stw r3,SD_INT_STATUS(r4) blr#endif /* ENABLE_SDRAM_ECC */#ifndef SDC_HARDCODED_INIT /* SDRAM SPD Support */#define SD_I2C_CTRL1 (0x400)#define SD_I2C_CTRL2 (0x404)#define SD_I2C_RD_DATA (0x408)#define SD_I2C_WR_DATA (0x40C) /* * SDRAM SPD Support Macros */#define SPD_DIMM0 (0x00000100)#define SPD_DIMM1 (0x00000200) /* SPD_DIMM1 was 0x00000000 */#define SPD_RDIMM (0x01)#define SPD_UDIMM (0x02)#define SPD_CAS_3 0x8#define SPD_CAS_4 0x10#define SPD_CAS_5 0x20#define ERR_NO_DIMM_FOUND (0xdb0)#define ERR_TRAS_FAIL (0xdb1)#define ERR_TRCD_FAIL (0xdb2)#define ERR_TRP_FAIL (0xdb3)#define ERR_TWR_FAIL (0xdb4)#define ERR_UNKNOWN_PART (0xdb5)#define ERR_NRANK_INVALID (0xdb6)#define ERR_DIMM_SIZE (0xdb7)#define ERR_ADDR_MODE (0xdb8)#define ERR_RFRSH_RATE (0xdb9)#define ERR_DIMM_TYPE (0xdba)#define ERR_CL_VALUE (0xdbb)#define ERR_TRFC_FAIL (0xdbc)/* READ_SPD requirements: * byte - byte address in SPD device (0 - 255) * r3 = will return data read from I2C Byte location * r4 - unchanged (SDC base addr) * r5 - clobbered in routine (I2C status) * r10 - number of DDR slot where first SPD device is detected */#define READ_SPD(byte_num) \ addis r3, 0, byte_num@l; \ or r3, r3, r10; \ ori r3, r3, 0x0A; \ stw r3, SD_I2C_CTRL1(r4); \ li r3, I2C_CNTRL2_START; \ stw r3, SD_I2C_CTRL2(r4); \ eieio; \ sync; \ li r3, 0x100; \1:; \ addic. r3, r3, -1; \ bne 1b; \2:; \ lwz r5, SD_I2C_CTRL2(r4); \ rlwinm. r3,r5,0,23,23; \ bne 2b; \ rlwinm. r3,r5,0,3,3; \ lwz r3,SD_I2C_RD_DATA(r4)#define SPD_MIN_RFRSH (0x80)#define SPD_MAX_RFRSH (0x85)refresh_rates: /* in nSec */ .long 15625 /* Normal (0x80) */ .long 3900 /* Reduced 0.25x (0x81) */ .long 7800 /* Reduced 0.5x (0x82) */ .long 31300 /* Extended 2x (0x83) */ .long 62500 /* Extended 4x (0x84) */ .long 125000 /* Extended 8x (0x85) *//* * tsi108_sdram_spd * * Inittializes SDRAM Controller using DDR2 DIMM Serial Presence Detect data * Uses registers: r4 - SDC base address (not changed) * r9 - SDC clocking period in nSec * Changes registers: r3,r5,r6,r7,r8,r10,r11 */tsi108_sdram_spd: li r10,SPD_DIMM0 xor r11,r11,r11 /* DIMM Base Address: starts from 0 */do_first_dimm: /* Program Refresh Rate Register */ READ_SPD(12) /* get Refresh Rate */ beq check_next_slot li r5, ERR_RFRSH_RATE cmpi 0,0,r3,SPD_MIN_RFRSH ble spd_fail cmpi 0,0,r3,SPD_MAX_RFRSH bgt spd_fail addi r3,r3,-SPD_MIN_RFRSH rlwinm r3,r3,2,0,31 lis r5,refresh_rates@h ori r5,r5,refresh_rates@l lwzx r5,r5,r3 /* get refresh rate in nSec */ divwu r5,r5,r9 /* calculate # of SDC clocks */ stw r5,SD_REFRESH(r4) /* Set refresh rate */ sync /* Program SD Timing Register */ li r7, 0 /* clear r7 prior parameter collection */ READ_SPD(20) /* get DIMM type: Registered or Unbuffered */ beq spd_read_fail li r5, ERR_DIMM_TYPE cmpi 0,0,r3,SPD_UDIMM beq do_cl cmpi 0,0,r3,SPD_RDIMM bne spd_fail oris r7,r7,0x1000 /* set SD_TIMING[DIMM_TYPE] bit */do_cl: READ_SPD(18) /* Get CAS Latency */ beq spd_read_fail li r5,ERR_CL_VALUE andi. r6,r3,SPD_CAS_3 beq cl_4 li r6,3 b set_clcl_4: andi. r6,r3,SPD_CAS_4 beq cl_5 li r6,4 b set_clcl_5: andi. r6,r3,SPD_CAS_5 beq spd_fail li r6,5set_cl: rlwimi r7,r6,24,5,7 READ_SPD(30) /* Get tRAS */ beq spd_read_fail divwu r6,r3,r9 mullw r8,r6,r9 subf. r8,r8,r3 beq set_tras addi r6,r6,1set_tras: li r5,ERR_TRAS_FAIL cmpi 0,0,r6,0x0F /* max supported value */ bgt spd_fail rlwimi r7,r6,16,12,15 READ_SPD(29) /* Get tRCD */ beq spd_read_fail /* right shift tRCD by 2 bits as per DDR2 spec */ rlwinm r3,r3,30,2,31 divwu r6,r3,r9 mullw r8,r6,r9 subf. r8,r8,r3 beq set_trcd addi r6,r6,1set_trcd: li r5,ERR_TRCD_FAIL cmpi 0,0,r6,0x07 /* max supported value */ bgt spd_fail rlwimi r7,r6,12,17,19 READ_SPD(27) /* Get tRP value */ beq spd_read_fail rlwinm r3,r3,30,2,31 /* right shift tRP by 2 bits as per DDR2 spec */ divwu r6,r3,r9 mullw r8,r6,r9 subf. r8,r8,r3 beq set_trp addi r6,r6,1set_trp: li r5,ERR_TRP_FAIL cmpi 0,0,r6,0x07 /* max supported value */ bgt spd_fail rlwimi r7,r6,8,21,23 READ_SPD(36) /* Get tWR value */ beq spd_read_fail rlwinm r3,r3,30,2,31 /* right shift tWR by 2 bits as per DDR2 spec */ divwu r6,r3,r9 mullw r8,r6,r9 subf. r8,r8,r3 beq set_twr addi r6,r6,1set_twr: addi r6,r6,-1 /* Tsi108 SDC always gives one extra clock */ li r5,ERR_TWR_FAIL cmpi 0,0,r6,0x07 /* max supported value */ bgt spd_fail rlwimi r7,r6,5,24,26 READ_SPD(42) /* Get tRFC */ beq spd_read_fail li r5, ERR_TRFC_FAIL /* Tsi108 spec: tRFC=(tRFC + 1)/2 */ addi r3,r3,1 rlwinm. r3,r3,31,1,31 /* divide by 2 */ beq spd_fail divwu r6,r3,r9 mullw r8,r6,r9 subf. r8,r8,r3 beq set_trfc addi r6,r6,1set_trfc: cmpi 0,0,r6,0x1F /* max supported value */ bgt spd_fail rlwimi r7,r6,0,27,31 stw r7,SD_TIMING(r4) sync /* * The following two registers are set on per-DIMM basis. * The SD_REFRESH and SD_TIMING settings are common for both DIMMS */do_each_dimm: /* Program SDRAM DIMM Control Register */ li r7, 0 /* clear r7 prior parameter collection */ READ_SPD(13) /* Get Primary SDRAM Width */ beq spd_read_fail cmpi 0,0,r3,4 /* Check for 4-bit SDRAM */ beq do_nbank oris r7,r7,0x0010 /* Set MEM_WIDTH bit */do_nbank: READ_SPD(17) /* Get Number of banks on SDRAM device */ beq spd_read_fail /* Grendel only distinguish betw. 4 or 8-bank memory parts */ li r5,ERR_UNKNOWN_PART /* non-supported memory part */ cmpi 0,0,r3,4 beq do_nrank cmpi 0,0,r3,8 bne spd_fail ori r7,r7,0x1000do_nrank: READ_SPD(5) /* Get # of Ranks */ beq spd_read_fail li r5,ERR_NRANK_INVALID andi. r6,r3,0x7 /* Use bits [2..0] only */ beq do_addr_mode cmpi 0,0,r6,1 bgt spd_fail rlwimi r7,r6,8,23,23do_addr_mode: READ_SPD(4) /* Get # of Column Addresses */ beq spd_read_fail li r5, ERR_ADDR_MODE andi. r3,r3,0x0f /* cut off reserved bits */ cmpi 0,0,r3,8 ble spd_fail cmpi 0,0,r3,15 bgt spd_fail addi r6,r3,-8 /* calculate ADDR_MODE parameter */ rlwimi r7,r6,4,24,27 /* set ADDR_MODE field */set_dimm_ctrl:#ifdef SDC_AUTOPRECH_EN oris r7,r7,0x0001 /* set auto precharge EN bit */#endif ori r7,r7,1 /* set ENABLE bit */ cmpi 0,0,r10,SPD_DIMM0 bne 1f stw r7,SD_D0_CTRL(r4) sync b set_dimm_bar1: stw r7,SD_D1_CTRL(r4) sync /* Program SDRAM DIMMx Base Address Register */set_dimm_bar: READ_SPD(5) /* get # of Ranks */ beq spd_read_fail andi. r7,r3,0x7 addi r7,r7,1 READ_SPD(31) /* Read DIMM rank density */ beq spd_read_fail rlwinm r5,r3,27,29,31 rlwinm r6,r3,3,24,28 or r5,r6,r5 /* r5 = Normalized Rank Density byte */ lis r8, 0x0080 /* 128MB >> 4 */ mullw r8,r8,r5 /* r8 = (rank_size >> 4) */ mullw r8,r8,r7 /* r8 = (DIMM_size >> 4) */ neg r7,r8 rlwinm r7,r7,28,4,31 or r7,r7,r11 /* set ADDR field */ rlwinm r8,r8,12,20,31 add r11,r11,r8 /* set Base Addr for next DIMM */ cmpi 0,0,r10,SPD_DIMM0 bne set_dimm1_size stw r7,SD_D0_BAR(r4) sync li r10,SPD_DIMM1 READ_SPD(0) bne do_each_dimm b spd_doneset_dimm1_size: stw r7,SD_D1_BAR(r4) syncspd_done: blrcheck_next_slot: cmpi 0,0,r10,SPD_DIMM1 beq spd_read_fail li r10,SPD_DIMM1 b do_first_dimmspd_read_fail: ori r3,r0,0xdead b err_hungspd_fail: li r3,0x0bad syncerr_hung: /* hang here for debugging */ nop nop b err_hung#endif /* !SDC_HARDCODED_INIT */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -