📄 hawksmc.c
字号:
register UINT baseAddr; /* Base Address variable */ UINT *pSdramAttr; /* Pointer to the SDRAM attribute */ UINT *pSdramBase; /* Pointer to the SDRAM base */ UINT attribute; /* Attribute of a single bank */ baseAddr = 0x00000000; pSmcReg->sdramBaseA = 0; pSmcReg->sdramBaseE = 0; /* * Starting with the greatest SDRAM block size down to the smallest * SDRAM block size, load the attributes for each bank and compare. * If the attribute of the bank is equal to the block size set the * base address for that bank equal to the next possible base address. */ for (sizeCode = SDRAM_SIZE_512_64MX4; sizeCode != SDRAM_SIZE_0; sizeCode--) { for (bank = 0; bank < HAWK_SDRAM_BANKS; bank++) { /* * The Hawk SMC has 2 seperate registers for both the attribute and * the base address. The HAWK SDRAM attributes registers are not * contiguous. Banks A,B,C,D are at FEF80010 and Banks E,F,G,H are * at FEF800C0. */ pSdramAttr = (bank < 4 ? &pSmcReg->sdramAttrA : &pSmcReg->sdramAttrE); pSdramBase = (bank < 4 ? &pSmcReg->sdramBaseA : &pSmcReg->sdramBaseE); /* * Compute the shift value for the byte attribute of the * appropriate bank in the SDRAM registers */ shift = ((3 - (bank % 4)) * 8); /* * if the attribute matches the block size then set the base * address equal to the 8 most significant bits of the base * address. Increment the current base address. */ attribute = ((*pSdramAttr & (SDRAM_SIZE_MASK << shift)) >> shift); if (attribute == sizeCode) { *pSdramBase |= (((baseAddr >> SDRAM_BASE_ASHIFT) << shift) & (SDRAM_BASE_MASK << shift)); if (sizeCode == SDRAM_SIZE_32_4MX16) baseAddr += 0x02000000; /* 32MB */ else if ((sizeCode == SDRAM_SIZE_64_8MX16) || (sizeCode == SDRAM_SIZE_64_8MX8)) baseAddr += 0x04000000; /* 64MB */ else if ((sizeCode == SDRAM_SIZE_128_16MX16) || (sizeCode == SDRAM_SIZE_128_16MX8) || (sizeCode == SDRAM_SIZE_128_16MX4)) baseAddr += 0x08000000; /* 128MB */ else if ((sizeCode == SDRAM_SIZE_256_32MX8) || (sizeCode == SDRAM_SIZE_256_32MX4)) baseAddr += 0x10000000; /* 256MB */ else if (sizeCode == SDRAM_SIZE_512_64MX4) baseAddr += 0x20000000; /* 512MB */ } } } return (baseAddr); } /******************************************************************************** calcBankSize - calculate the size of a sdram bank** This function calculates the Hawk bank size code for a sdram bank using the* spd info.** RETURNS: Hawk SMC bank size code or 0 if invalid bank size.**/LOCAL UINT32 calcBankSize ( UCHAR *spdData /* pointer to SPD buffer for current bank */ ) { UINT32 bankSize; /* calculated size of current bank in bytes */ UINT32 sdramSize; /* SMC size code for current bank */ UINT32 devWidth; /* width of the devices in the current bank */ /* * Calculate the SDRAM Bank Size using the formula: * BankSize = (Total Row Addresses * Total Column Addresses * * Number Device Banks * Data Width in Bytes); */ bankSize = ((1 << spdData[SPD_ROW_ADDR_INDEX]) * (1 << spdData[SPD_COL_ADDR_INDEX]) * spdData[SPD_DEV_BANKS_INDEX] * 8); /* * Get the Primary Device Width from the SDRAM SPD (Byte 13). * Use it to determine the device width attributes required by * the Hawk specification. */ devWidth = spdData[SPD_DEV_WIDTH_INDEX]; /* * use the bank size and device width to select the proper smc bank size * code. NOTE: A switch statement cannot be used because the absolute * addresses entered into the resulting jump table resolve to RAM addresses * and this code is executed before the image has been moved to RAM. the * nested if-else structure produces PC-relative branches which will always * work. */ if (bankSize == 0x02000000) /* 32 Meg */ if (devWidth == 16) sdramSize = SDRAM_SIZE_32_4MX16; else sdramSize = SDRAM_SIZE_0; /* invalid */ else if (bankSize == 0x4000000) /* 64 Meg */ if (devWidth == 8) sdramSize = SDRAM_SIZE_64_8MX8; else if (devWidth == 16) sdramSize = SDRAM_SIZE_64_8MX16; else sdramSize = SDRAM_SIZE_0; /* invalid */ else if (bankSize == 0x8000000) /* 128 Meg */ if (devWidth == 4) sdramSize = SDRAM_SIZE_128_16MX4; else if (devWidth == 8) sdramSize = SDRAM_SIZE_128_16MX8; else if (devWidth == 16) sdramSize = SDRAM_SIZE_128_16MX16; else sdramSize = SDRAM_SIZE_0; /* invalid */ else if (bankSize == 0x10000000) /* 256 Meg */ if (devWidth == 4) sdramSize = SDRAM_SIZE_256_32MX4; else if (devWidth == 8) sdramSize = SDRAM_SIZE_256_32MX8; else sdramSize = SDRAM_SIZE_0; /* invalid */ else if (bankSize == 0x20000000) /* 512 Meg */ if (devWidth == 4) sdramSize = SDRAM_SIZE_512_64MX4; else sdramSize = SDRAM_SIZE_0; /* invalid */ else sdramSize = SDRAM_SIZE_0; /* invalid */ return (sdramSize); }/******************************************************************************** sysHawkSdramSizeInit - initialize the SDRAM Size Attributes** This function's purpose is to determine the correct size attributes* for all banks and to set the ram enable for banks consisting of* a valid memory configuration.** RETURNS: N/A**/LOCAL void sysHawkSdramSizeInit ( hawkSmc *pSmcReg, /* points to caller's SMC register storage area */ UCHAR * spdArray[] /* array of pointers to SPD buffers */ /* (odd entries not used) */ ) { UCHAR * pData; /* SPD pointer for current bank */ register int bank; /* Bank index counter */ register int block; /* Block index counter */ register int shift; /* Shift index to register */ register int dimmBank; /* DimmBank index counter */ int validSpd; /* SPD Validity flag */ UINT numDimmBanks; /* Number of DIMM Banks supported */ UINT sdramSize; /* SDRAM Size for the bank */ UINT *pSdramAttr; /* Pointer to the attributes register */ validSpd = FALSE; pSmcReg->sdramAttrA = 0; pSmcReg->sdramAttrE = 0; /* * Fill the attributes registers with bank data from the SPD devices. */ for (bank = 0; bank < HAWK_SDRAM_BANKS; bank += 2) { if ((pData = spdArray[bank]) != NULL) { validSpd = TRUE; /* * Get the number of DIMM banks supported by this SPD. The * Hawk supports upto 2 DIMM Banks for each SPD. Any number * other than 1 or 2 should be considered erroneous and reset * to 1 for this device. */ numDimmBanks = pData[SPD_NUM_DIMMBANKS_INDEX]; if (numDimmBanks < 1 || numDimmBanks > 2) numDimmBanks = 1; /* * Get the size attributes for the Bank. */ sdramSize = calcBankSize(pData); /* * Load the SDRAM Attributes and set the bank enable for any block * with a size greater than Zero. The Hawk has two 32 bit registers * to store the 8 possible blocks of data. Banks 0 to 3 go in the * first register and Banks 4 to 7 go in the second register. */ pSdramAttr = (bank < 4) ? &pSmcReg->sdramAttrA : &pSmcReg->sdramAttrE; /* * Update the Hawk register for the number of DIMM Banks * supported by this size attribute information. */ for (dimmBank = 0; dimmBank < numDimmBanks; dimmBank++) { block = ((bank % 4) + dimmBank); shift = ((3 - block) * 8); *pSdramAttr |= (((SDRAM_EN | sdramSize) & SDRAM_ATTR_MASK) << shift); } } } /* * Verify that we were able to read SDRAM size information from an * SPD device. If unable then reset the registers to the pre-init * values and continue. */ if (!validSpd) { pSmcReg->sdramAttrA = *((UINT32 *)HAWK_SMC_SDRAM_ATTR_AD); pSmcReg->sdramAttrE = *((UINT32 *)HAWK_SMC_SDRAM_ATTR_EH); } }/******************************************************************************** getSpdData - read and validate the spd information.** This function reads the contents of the caller specified serial presence* detect EEPROM and validates the checksum.** RETURNS: TRUE if the SPD contents are valid, FALSE if not.**/STATUS sysGetSpdData ( UCHAR spdAddr, /* SROM address for current bank */ UCHAR offset, /* first byte of SROM to read */ UINT16 dataSize, /* number of SROM bytes to read */ UCHAR *spdData /* address of caller's SPD buffer */ ) { register UCHAR checksum = 0; /* running checksum */ register int index; /* index into SPD data buffer */ if ( sysHawkI2cRangeRead (spdAddr, offset, dataSize, spdData) == OK) { for (index = 0; index < SPD_CHECKSUM_INDEX; index++) checksum += spdData[index]; checksum %= 256; if (checksum == spdData[SPD_CHECKSUM_INDEX]) return (OK); } return (ERROR); }/******************************************************************************** sysHawkParamConfig - calculate the proper hawk smc initialization values.** This function reads the serial presence detect EEPROM(s) and calculates the* proper values for configuring the hawk smc.** RETURNS: Size of memory configured.**/UINT32 sysHawkParamConfig ( hawkSmc *pSmcReg /* points to caller's SMC register storage area */ ) { /* * note: the hawk banks are arranged in pairs with one spd device per * bank pair. therefore only the even numbered entries in the spdPtrs * array are used. */ UCHAR * spdPtrs[HAWK_SDRAM_BANKS]; /* spd buffer ptrs */ register int spd; /* Spd index counter */#ifndef BYPASS_SPD UCHAR spdData[HAWK_SDRAM_BANKS / 2 * SPD_SIZE]; /* spd data */ UCHAR * pBfr = &spdData[0]; /* temp buffer ptr */#endif /* loop through each spd device */ for (spd = 0; spd < HAWK_SDRAM_BANKS; spd +=2) { spdPtrs[spd] = NULL;#ifndef BYPASS_SPD /* read the spd data into the current buffer and validate */ if (sysGetSpdData (SPD_EEPROM_ADRS + spd, 0, SPD_SIZE, pBfr) == OK) { /* save current buffer address and advance to the next buffer */ spdPtrs[spd] = pBfr; pBfr += SPD_SIZE; }#endif } /* calculate the smc intialization parameters */ sysHawkSdramSpeedInit (pSmcReg, &spdPtrs[0]); sysHawkSdramSizeInit (pSmcReg, &spdPtrs[0]); return (sysHawkSdramBaseInit (pSmcReg)); }/******************************************************************************** sysSetRomStartError - Set a RomStartup error bit.** This routine sets one or more error flags in the RomStartup error registers.* The error registers are the 4 general purpose registers available in the* Hawk's Pci-Host Bridge (PHB). This mechanism allows low-level code to save any* errors detected before a debug console is available. Once the debug console* has been configured, these error flags are logged to the debug console to aid* in system debug.** RETURNS: N/A**/void sysSetRomStartError ( UINT32 offset, /* offset of the selected Hawk register */ UINT32 value /* bit(s) to merge into register contents */ ) { UINT32 * adrs; adrs = (UINT32 *)(HAWK_PHB_BASE_ADRS + offset); *adrs |= value; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -