/****************************************************************************** * Copyright (c) 2011-12 Texas Instruments Incorporated - http://www.ti.com * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the * distribution. * * Neither the name of Texas Instruments Incorporated nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * *****************************************************************************/ #include #include "platform.h" #include "types.h" #include "post.h" #include "target.h" #include "pscapi.h" #if !(defined(_EVMC6657L_)) #include "net.h" #include "cpmacdrv.h" #include "qm_api.h" #include "cpdma_api.h" #else #include "evmc665x_phy.h" #include "evmc665x_emac.h" #endif /* CSL EMAC include */ #if !(defined(_EVMC6657L_)) #include #include #include #include #include #else #include #include #endif #include /* BootCfg module include */ #include #include /* The version string */ #pragma DATA_SECTION(post_version, ".version") #pragma DATA_ALIGN(post_version, 16) char post_version[] = POST_VERSION; /* OSAL functions for Platform Library */ uint8_t *Osal_platformMalloc (uint32_t num_bytes, uint32_t alignment) { return malloc(num_bytes); } void Osal_platformFree (uint8_t *dataPtr, uint32_t num_bytes) { /* Free up the memory */ if (dataPtr) { free(dataPtr); } } /****************************************************************************** * Function: post_display_led_error ******************************************************************************/ void post_display_led_error ( POST_TEST_ID test_id ) { uint8_t led_status[POST_MAX_NUM_LED]; uint32_t i; memset(led_status, POST_LED_ON, POST_MAX_NUM_LED); while (TRUE) { for (i = 0; i < POST_MAX_NUM_LED; i++) { if (post_led_status[test_id][i] == POST_LED_BLINK) { if (led_status[i] == POST_LED_ON) { led_status[i] = POST_LED_OFF; } else { led_status[i] = POST_LED_ON; } platform_led(i, (PLATFORM_LED_OP)led_status[i], PLATFORM_USER_LED_CLASS); } else { platform_led(i, (PLATFORM_LED_OP)post_led_status[test_id][i], PLATFORM_USER_LED_CLASS); } } platform_delay(POST_LED_BLINK_DELAY); /* POST in the while(1) loop to display the LED error status */ } } /****************************************************************************** * Function: post_write_uart ******************************************************************************/ Bool post_write_uart ( char* msg ) { uint32_t i; uint32_t msg_len = strlen(msg); /* Write the message to the UART */ for (i = 0; i < msg_len; i++) { if (platform_uart_write(msg[i]) != Platform_EOK) { return FALSE; } } return TRUE; } /****************************************************************************** * Function: post_display_status ******************************************************************************/ void post_display_status ( POST_TEST_ID test_id, POST_TEST_RESULT test_result ) { uint32_t i; char *msg; char msg1[40] = "\r\n\rPOST "; char msg2[] = " test passed!"; char msg3[] = " test failed!"; char msg4[] = " test started!"; msg = strcat(msg1, post_status[test_id]); switch (test_id) { case POST_TEST_IN_PROGRESS: case POST_TEST_COMPLETE: /* Form the POST status message to write to the UART */ if (post_write_uart(msg) != TRUE) { post_display_led_error(POST_TEST_UART); /* Never return from this function */ } for (i = 0; i < POST_MAX_NUM_LED; i++) { if (platform_led(i, (PLATFORM_LED_OP)post_led_status[test_id][i], PLATFORM_USER_LED_CLASS) != Platform_EOK) { post_write_uart("POST LED test failed \r\n"); } } break; default: /* Form the POST status message to write to the UART */ if (test_result == POST_TEST_RESULT_PASSED) { msg = strcat(msg, msg2); if (post_write_uart(msg) != TRUE) { post_display_led_error(POST_TEST_UART); /* Never return from this function */ } } else if (test_result == POST_TEST_RESULT_FAILED) { msg = strcat(msg, msg3); if (post_write_uart(msg) != TRUE) { post_display_led_error(POST_TEST_UART); /* Never return from this function */ } post_display_led_error(test_id); /* Never return from this function */ } else { msg = strcat(msg, msg4); if (post_write_uart(msg) != TRUE) { post_display_led_error(POST_TEST_UART); /* Never return from this function */ } } break; } } /****************************************************************************** * Function: post_test_external_memory ******************************************************************************/ POST_TEST_RESULT post_test_external_memory ( void ) { POST_TEST_RESULT test_result = POST_TEST_RESULT_PASSED; if(platform_external_memory_test(0, 0) != Platform_EOK) { test_result = POST_TEST_RESULT_FAILED; } return test_result; } /****************************************************************************** * Function: post_test_eeprom ******************************************************************************/ POST_TEST_RESULT post_test_eeprom ( void ) { uint8_t test_buf[POST_EEPROM_TEST_READ_LENGTH]; POST_TEST_RESULT test_result = POST_TEST_RESULT_PASSED; PLATFORM_DEVICE_info *p_device; p_device = platform_device_open(POST_EEPROM_TEST_DEVICE_ID, 0); if (p_device == NULL) { return POST_TEST_RESULT_FAILED; } if(platform_device_read(p_device->handle, POST_EEPROM_TEST_READ_ADDRESS, test_buf, POST_EEPROM_TEST_READ_LENGTH) != Platform_EOK) { test_result = POST_TEST_RESULT_FAILED; } platform_device_close(p_device->handle); return test_result; } /****************************************************************************** * Function: post_test_nand ******************************************************************************/ POST_TEST_RESULT post_test_nand ( void ) { uint8_t test_buf[POST_NAND_TEST_READ_LENGTH]; POST_TEST_RESULT test_result = POST_TEST_RESULT_PASSED; uint32_t addr; PLATFORM_DEVICE_info *p_device; p_device = platform_device_open(POST_NAND_TEST_DEVICE_ID, 0); if (p_device == NULL) { return POST_TEST_RESULT_FAILED; } addr = (POST_NAND_TEST_READ_BLOCK_NUM * p_device->page_count + POST_NAND_TEST_READ_PAGE_NUM) * p_device->page_size; if(platform_device_read(p_device->handle, addr, test_buf, POST_NAND_TEST_READ_LENGTH) != Platform_EOK) { test_result = POST_TEST_RESULT_FAILED; } platform_device_close(p_device->handle); return test_result; } /****************************************************************************** * Function: post_test_nor ******************************************************************************/ POST_TEST_RESULT post_test_nor ( void ) { uint8_t test_buf[POST_NOR_TEST_READ_LENGTH]; POST_TEST_RESULT test_result = POST_TEST_RESULT_PASSED; PLATFORM_DEVICE_info *p_device; p_device = platform_device_open(POST_NOR_TEST_DEVICE_ID, 0); if (p_device == NULL) { return POST_TEST_RESULT_FAILED; } if(platform_device_read(p_device->handle, POST_NOR_TEST_READ_ADDR, test_buf, POST_NOR_TEST_READ_LENGTH) != Platform_EOK) { test_result = POST_TEST_RESULT_FAILED; } platform_device_close(p_device->handle); return test_result; } #if !(defined(_EVMC6657L_)) /** Number of ports in the ethernet subsystem */ #define NUM_PORTS 3u /** Number of MAC/GMII ports in the ethernet switch */ #define NUM_MAC_PORTS 2u #else /** Number of ports in the ethernet subsystem */ #define NUM_PORTS 1u /** Number of MAC/GMII ports in the ethernet switch */ #define NUM_MAC_PORTS 1u #endif /*Define LoopBack Mode for C6657*/ #define MAC_LOOPBACK (1 << 0) #define EXT_COPPER_LOOPBACK (1 << 3) #define EXT_FIBER_LOOPBACK (1 << 4) /* Define LoopBack modes for C6678 & C6670*/ #define CPSW_LOOPBACK_NONE 0 #define CPSW_LOOPBACK_INTERNAL 1 #define CPSW_LOOPBACK_EXTERNAL 2 #ifdef SIMULATOR_SUPPORT int32_t cpswSimTest = 1; int32_t cpswLpbkMode = CPSW_LOOPBACK_EXTERNAL; #else int32_t LpbkMode = EXT_COPPER_LOOPBACK; int32_t cpswSimTest = 0; int32_t cpswLpbkMode = CPSW_LOOPBACK_INTERNAL; #endif int32_t cpswEvm6678 = 0; #if !(defined(_EVMC6657L_)) /** ============================================================================ * @n@b Init_SGMII * * @b Description * @n SGMII peripheral initialization code. * * @param[in] * @n macPortNum MAC port number for which the SGMII port setup must * be performed. * * @return * @n None * ============================================================================= */ int32_t Init_sgmii (uint32_t macPortNum) { CSL_SGMII_ADVABILITY sgmiiCfg; CSL_SGMII_STATUS sgmiiStatus; if ((macPortNum == 0) && (cpswEvm6678)) { /* EVM6678 back end: MAC-to-MAC force link */ /* Reset the port before configuring it */ CSL_SGMII_doSoftReset (macPortNum); while (CSL_SGMII_getSoftResetStatus (macPortNum) != 0); /* Hold the port in soft reset and set up * the SGMII control register: * (1) Enable Master Mode (default) */ CSL_SGMII_startRxTxSoftReset (macPortNum); CSL_SGMII_enableMasterMode (macPortNum); if (cpswLpbkMode != CPSW_LOOPBACK_NONE) { CSL_SGMII_enableLoopback (macPortNum); } /* Setup the Advertised Ability register for this port: * (1) Enable Full duplex mode * (2) Speed = 1000M * (3) Force the Link */ sgmiiCfg.bLinkUp = 1; sgmiiCfg.linkSpeed = CSL_SGMII_1000_MBPS; sgmiiCfg.duplexMode = CSL_SGMII_FULL_DUPLEX; CSL_SGMII_setAdvAbility (macPortNum, &sgmiiCfg); CSL_SGMII_endRxTxSoftReset (macPortNum); /* Wait for SGMII Link */ do { CSL_SGMII_getStatus(macPortNum, &sgmiiStatus); } while (sgmiiStatus.bIsLinkUp != 1); } else { /* Reset the port before configuring it */ CSL_SGMII_doSoftReset (macPortNum); while (CSL_SGMII_getSoftResetStatus (macPortNum) != 0); /* Hold the port in soft reset and set up * the SGMII control register: * (1) Enable Master Mode (default) * (2) Enable Auto-negotiation */ CSL_SGMII_startRxTxSoftReset (macPortNum); if (cpswLpbkMode == CPSW_LOOPBACK_NONE) { CSL_SGMII_disableMasterMode (macPortNum); } else { CSL_SGMII_enableMasterMode (macPortNum); if (cpswLpbkMode == CPSW_LOOPBACK_INTERNAL) { CSL_SGMII_enableLoopback (macPortNum); } } /* Setup the Advertised Ability register for this port: * (1) Enable Full duplex mode * (2) Enable Auto Negotiation */ sgmiiCfg.linkSpeed = CSL_SGMII_1000_MBPS; sgmiiCfg.duplexMode = CSL_SGMII_FULL_DUPLEX; CSL_SGMII_setAdvAbility (macPortNum, &sgmiiCfg); CSL_SGMII_enableAutoNegotiation (macPortNum); CSL_SGMII_endRxTxSoftReset (macPortNum); /* Wait for SGMII Link */ if (!cpswSimTest) { do { CSL_SGMII_getStatus(macPortNum, &sgmiiStatus); } while (sgmiiStatus.bIsLinkUp != 1); /* Wait for SGMII Autonegotiation to complete without error */ do { CSL_SGMII_getStatus(macPortNum, &sgmiiStatus); if (sgmiiStatus.bIsAutoNegError != 0) return -1; } while (sgmiiStatus.bIsAutoNegComplete != 1); } } /* All done with configuration. Return Now. */ return 0; } int Init_MAC (uint32_t macPortNum, uint8_t macAddress[6], uint32_t mtu) { /* Reset MAC Sliver 0 */ CSL_CPGMAC_SL_resetMac (macPortNum); while (CSL_CPGMAC_SL_isMACResetDone (macPortNum) != TRUE); /* Setup the MAC Control Register for this port: * (1) Enable Full duplex * (2) Enable GMII * (3) Enable Gigabit * (4) Enable External Configuration. This enables * the "Full duplex" and "Gigabit" settings to be * controlled externally from SGMII * (5) Don't enable any control/error/short frames */ CSL_CPGMAC_SL_enableFullDuplex (macPortNum); CSL_CPGMAC_SL_enableGMII (macPortNum); CSL_CPGMAC_SL_enableGigabit (macPortNum); CSL_CPGMAC_SL_enableExtControl (macPortNum); /* Configure the MAC address for this port */ CSL_CPSW_3GF_setPortMACAddress (macPortNum, macAddress); /* Configure VLAN ID/CFI/Priority. * * For now, we are not using VLANs so just configure them * to all zeros. */ CSL_CPSW_3GF_setPortVlanReg (macPortNum, 0, 0, 0); /* Configure the Receive Maximum length on this port, * i.e., the maximum size the port can receive without * any errors. * * Set the Rx Max length to the MTU configured for the * interface. */ CSL_CPGMAC_SL_setRxMaxLen (macPortNum, mtu); /* Done setting up the MAC port */ return 0; } void Init_Switch (uint32_t mtu) { CSL_CPSW_3GF_PORTSTAT portStatCfg; /* Enable the CPPI port, i.e., port 0 that does all * the data streaming in/out of EMAC. */ CSL_CPSW_3GF_enablePort0 (); CSL_CPSW_3GF_disableVlanAware (); CSL_CPSW_3GF_setPort0VlanReg (0, 0, 0); CSL_CPSW_3GF_setPort0RxMaxLen (mtu); /* Enable statistics on both the port groups: * * MAC Sliver ports - Port 1, Port 2 * CPPI Port - Port 0 */ portStatCfg.p0AStatEnable = 1; portStatCfg.p0BStatEnable = 1; portStatCfg.p1StatEnable = 1; portStatCfg.p2StatEnable = 1; CSL_CPSW_3GF_setPortStatsEnableReg (&portStatCfg); /* Setup the Address Lookup Engine (ALE) Configuration: * (1) Enable ALE. * (2) Clear stale ALE entries. * (3) Disable VLAN Aware lookups in ALE since * we are not using VLANs by default. * (4) No Flow control * (5) Configure the Unknown VLAN processing * properties for the switch, i.e., which * ports to send the packets to. */ CSL_CPSW_3GF_enableAle (); CSL_CPSW_3GF_clearAleTable (); CSL_CPSW_3GF_disableAleVlanAware (); CSL_CPSW_3GF_disableAleTxRateLimit (); CSL_CPSW_3GF_setAlePrescaleReg (125000000u/1000u); CSL_CPSW_3GF_setAleUnkownVlanReg (7, 3, 3, 7); if(cpswLpbkMode != CPSW_LOOPBACK_NONE) CSL_CPSW_3GF_enableAleBypass(); /* Done with switch configuration */ return; } int Switch_update_addr (uint32_t portNum, uint8_t macAddress[6], Uint16 add) { uint32_t i; CSL_CPSW_3GF_ALE_PORTCONTROL alePortControlCfg; CSL_CPSW_3GF_ALE_UNICASTADDR_ENTRY ucastAddrCfg; /* Configure the address in "Learning"/"Forward" state */ alePortControlCfg.portState = ALE_PORTSTATE_FORWARD; alePortControlCfg.dropUntaggedEnable = 0; alePortControlCfg.vidIngressCheckEnable = 0; alePortControlCfg.noLearnModeEnable = (cpswLpbkMode != CPSW_LOOPBACK_NONE)?1:0; alePortControlCfg.mcastLimit = 0; alePortControlCfg.bcastLimit = 0; CSL_CPSW_3GF_setAlePortControlReg (portNum, &alePortControlCfg); if (cpswLpbkMode != CPSW_LOOPBACK_NONE) { /* Program the ALE with the MAC address. * * The ALE entries determine the switch port to which any * matching received packet must be forwarded to. */ /* Get the next free ALE entry to program */ for (i = 0; i < CSL_CPSW_3GF_NUMALE_ENTRIES; i++) { if (CSL_CPSW_3GF_getALEEntryType (i) == ALE_ENTRYTYPE_FREE) { /* Found a free entry */ break; } } if (i == CSL_CPSW_3GF_NUMALE_ENTRIES) { /* No free ALE entry found. return error. */ return -1; } else { /* Found a free ALE entry to program our MAC address */ memcpy (ucastAddrCfg.macAddress, macAddress, 6); // Set the MAC address ucastAddrCfg.ucastType = ALE_UCASTTYPE_UCAST_NOAGE; // Add a permanent unicast address entryALE_UCASTTYPE_UCAST_NOAGE. ucastAddrCfg.secureEnable = FALSE; ucastAddrCfg.blockEnable = FALSE; ucastAddrCfg.portNumber = portNum; // Add the ALE entry for this port /* Setup the ALE entry for this port's MAC address */ CSL_CPSW_3GF_setAleUnicastAddrEntry (i, &ucastAddrCfg); } } /* Done with upading address */ return 0; } int32_t Init_SGMII_SERDES(void) { if (cpswSimTest) { /* Unlock the chip configuration registers to allow SGMII SERDES registers to * be written */ CSL_BootCfgUnlockKicker(); CSL_BootCfgSetSGMIIConfigPLL (0x00000041); CSL_BootCfgSetSGMIIRxConfig (0, 0x00700621); CSL_BootCfgSetSGMIITxConfig (0, 0x000108A1); CSL_BootCfgSetSGMIIRxConfig (1, 0x00700621); CSL_BootCfgSetSGMIITxConfig (1, 0x000108A1); /* Re-lock the chip configuration registers to prevent unintentional writes */ CSL_BootCfgLockKicker(); } /* SGMII SERDES Configuration complete. Return. */ return 0; } int32_t Init_Cpsw (void) { uint32_t macPortNum, mtu = 1518; uint8_t mac_address[6]; uint8_t sw_port0_mac_addr[6] = {0x10, 0x11, 0x12, 0x13, 0x14, 0x15}; /* Initialize the SERDES modules */ Init_SGMII_SERDES(); platform_get_macaddr(PLATFORM_MAC_TYPE_EFUSE, mac_address); /* Initialize the SGMII/Sliver submodules for the * two corresponding MAC ports. */ for (macPortNum = 0; macPortNum < NUM_MAC_PORTS; macPortNum++) { if (Init_sgmii (macPortNum)) return -1; mac_address[5] += macPortNum; Init_MAC (macPortNum, mac_address, mtu); mac_address[5] -= macPortNum; } /* Setup the Ethernet switch finally. */ Init_Switch (mtu); Switch_update_addr(0, sw_port0_mac_addr, 0); Switch_update_addr(1, mac_address, 0); mac_address[5] += 1; Switch_update_addr(2, mac_address, 0); /* CPSW subsystem setup done. Return success */ return 0; } #endif /****************************************************************************** * Function: post_test_emac_loopback ******************************************************************************/ POST_TEST_RESULT post_test_emac_loopback ( void ) { uint8_t test_buf[POST_EMAC_TEST_PKT_LENGTH+14]; #if (defined(_EVMC6657L_)) SGMII_Config config; uint8_t mac_address[6]; #endif #if !(defined(_EVMC6657L_)) uint8_t sw_port0_mac_addr[6] = {0x10, 0x11, 0x12, 0x13, 0x14, 0x15}; uint8_t mac_address[6]; uint8_t ret; NET_DRV_DEVICE nDevice; #endif #if !(defined(_EVMC6657L_)) int modNum = 8; if (modNum == TARGET_PWR_ETH(x)) { ret = (int32_t)pscEnableModule (TARGET_PWR_PA); if (ret != 0) return (POST_TEST_RESULT_FAILED); } #endif #if !(defined(_EVMC6657L_)) Init_Cpsw(); /* Queue manager configuration */ hwQmSetup ((qmConfig_t *)(targetGetQmConfig())); targetInitQs (); /* Cpdma configuration. */ hwCpdmaRxConfig ((cpdmaRxCfg_t *)targetGetCpdmaRxConfig()); hwCpdmaTxConfig ((cpdmaTxCfg_t *)targetGetCpdmaTxConfig()); /* Packet accelerator configuration. If PA is not present this statement is defined * to void in target.h */ targetPaConfig(sw_port0_mac_addr); /* Streaming switch configuration. If not present this statement is defined to void * in target.h. If present this is usually defined to a series of register writes */ hwConfigStreamingSwitch(); /* Initialize the network device driver */ memset (&nDevice, 0, sizeof(nDevice)); /* Start the networking device */ if (cpmac_drv_start(&nDevice) < 0) { return POST_TEST_RESULT_FAILED; } /* Get the MAC address from efuse */ platform_get_macaddr(PLATFORM_MAC_TYPE_EFUSE, mac_address); /* Set the dest MAC address to be broadcast, so that PA firmware will not filter out */ memset(test_buf, 0xff, 6); memcpy(&test_buf[6], sw_port0_mac_addr, 6); /* set the payload length to 256 bytes */ test_buf[12] = 0x01; test_buf[13] = 0x00; /* Send the Ethernet packet */ if (cpmac_drv_send (&nDevice, test_buf, POST_EMAC_TEST_PKT_LENGTH+14) < 0) { return POST_TEST_RESULT_FAILED; } platform_delay(100); /* Receive the loopback packet */ if (ret = cpmac_drv_receive (&nDevice, test_buf) < 0) { return POST_TEST_RESULT_FAILED; } #else sgmii_init(); EMAC_init(); config.loopbackEn = 1; SGMII_config(&config); platform_get_macaddr(PLATFORM_MAC_TYPE_EFUSE, mac_address); /* Set the dest MAC address to be broadcast, so that PA firmware will not filter out */ memset(test_buf, 0xff, 6); memcpy(&test_buf[6], mac_address, 6); /* set the payload length to 256 bytes */ test_buf[12] = 0x01; test_buf[13] = 0x00; if(EMAC_Send(test_buf, POST_EMAC_TEST_PKT_LENGTH+14) < 0) { return POST_TEST_RESULT_FAILED; } platform_delay(1000); if(EMAC_Recv(test_buf) < 0) { return POST_TEST_RESULT_FAILED; } #endif return POST_TEST_RESULT_PASSED; } void post_hex_to_string ( uint32_t hex, uint32_t nibbles, char *msg ) { int32_t i; uint8_t nibble; for (i = (nibbles-1); i >= 0; i--) { nibble = hex & 0xf; if (nibble <= 0x9) { nibble += '0'; } else { nibble += ('A' - 0xa); } msg[i] = nibble; hex = hex >> 4; } msg[nibbles] = 0; } Bool post_serial_num_isvalid ( char c ) { if ( ((c >= '0') && (c <= '9')) || ((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z')) ) { return TRUE; } else { return FALSE; } } /****************************************************************************** * Function: post_write_serial_no ******************************************************************************/ void post_write_serial_no ( void ) { uint32_t i, j; uint8_t msg[20], msg2[2]; PLATFORM_DEVICE_info *p_device; /* Check if user key in the passcode "ti" to enter board serial number */ if (platform_uart_read(msg, POST_UART_READ_TIMEOUT) != Platform_EOK) { return; } if (msg[0] != 't') { return; } if (platform_uart_read(msg, POST_UART_READ_TIMEOUT) != Platform_EOK) { return; } if (msg[0] != 'i') { return; } /* Passcode verified, prompt the user to enter serial number */ p_device = platform_device_open(PLATFORM_DEVID_EEPROM50, 0); if (p_device == NULL) { return; } post_write_uart("\r\n\r\nPlease enter the 10 digit serial number for this board, and then press ENTER key:\r\n\r\n"); i = 0; msg2[1] = 0; while (TRUE) { if (platform_uart_read(&msg[i], POST_UART_READ_TIMEOUT) != Platform_EOK) { platform_device_close(p_device->handle); post_write_uart("\r\n\r\nSerial number input time out!"); return; } if (msg[i] == '\r') { break; } if ((i < POST_MAX_SN_SIZE) && post_serial_num_isvalid(msg[i])) { msg2[0] = msg[i]; post_write_uart((char *)msg2); i++; } } if (i < POST_MAX_SN_SIZE) { for (j = i; j < POST_MAX_SN_SIZE; j++) { msg[j] = 0xff; } } if(platform_device_write(p_device->handle, POST_SERIAL_NUM_ADDR, msg, 16) == Platform_EOK) { post_write_uart("\r\n\r\nSerial number programmed to EEPROM successfully! "); } else { post_write_uart("\r\n\r\nFailed to program the serial number to EEPROM!"); } platform_device_close(p_device->handle); } /****************************************************************************** * Function: post_dump_register_val ******************************************************************************/ void post_dump_register_val ( uint32_t reg_addr, char* desc_string ) { char msg[10]; uint32_t reg_val; reg_val = *(volatile uint32_t *)reg_addr; post_write_uart(desc_string); post_hex_to_string(reg_val, 8, msg); msg[8] = ' '; msg[9] = 0; post_write_uart(msg); } /****************************************************************************** * Function: main function for POST ******************************************************************************/ void main ( void ) { platform_init_flags init_flags; platform_init_config init_config; POST_TEST_ID test_id = POST_TEST_IN_PROGRESS; POST_TEST_RESULT test_result; uint32_t reset_type; int32_t i; char msg[9]; uint8_t mac_addr[6]; platform_info info; #if !(defined(_EVMC6657L_)||defined(_EVMC6655L_)) uint32_t sa_enable; #endif uint32_t acc_fail; extern uint32_t platform_init_return_code; /* Turn on all the platform initialize flags */ memset(&init_config, 0, sizeof(platform_init_config)); memset(&init_flags, 0x01, sizeof(platform_init_flags)); init_flags.phy = 1; acc_fail = 0; /* Initialize the platform */ if (platform_init(&init_flags, &init_config) != Platform_EOK) { switch (platform_errno) { case PLATFORM_ERRNO_PLL_SETUP: test_id = POST_TEST_PLL_INIT; break; case PLATFORM_ERRNO_NAND: test_id = POST_TEST_NAND_INIT; break; case PLATFORM_ERRNO_NOR: test_id = POST_TEST_NOR_INIT; break; default: test_id = POST_TEST_GENERAL; break; } test_result = POST_TEST_RESULT_FAILED; } if (test_result == POST_TEST_RESULT_FAILED) { acc_fail++; } platform_uart_init(); platform_uart_set_baudrate(POST_UART_BAUDRATE); if (test_id != POST_TEST_PLL_INIT) { if (post_write_uart("\r\n\r\n") != TRUE) { post_display_led_error(POST_TEST_UART); /* Never return from this function */ } platform_get_info(&info); /* Display the board name */ post_write_uart(info.board_name); /* Display the POST version */ post_write_uart(POST_EVM_VERSION_MSG); post_write_uart(post_version); post_write_uart("\r\n\r------------------------------------------"); post_write_uart("\r\n\rSOC Information"); post_hex_to_string(info.board_rev, 4, msg); post_write_uart("\r\n\r\nFPGA Version: "); post_write_uart(msg); if (info.serial_nbr[0] != 0) { post_write_uart("\r\n\rBoard Serial Number: "); post_write_uart(info.serial_nbr); } /* Display the EFUSE MAC address */ platform_get_macaddr(PLATFORM_MAC_TYPE_EFUSE, mac_addr); post_write_uart("\r\n\rEFUSE MAC ID is: "); for (i = 0; i < 6; i++) { post_hex_to_string(info.emac.efuse_mac_address[i], 2, msg); msg[2] = ' '; msg[3] = 0; post_write_uart(msg); } #if !(defined(_EVMC6657L_)||defined(_EVMC6655L_)) sa_enable = *(volatile uint32_t *)0x20c0004; sa_enable &= 0x1; if (sa_enable) { post_write_uart("\r\n\rSA is enabled on this board."); } else { post_write_uart("\r\n\rSA is disabled on this board."); } #endif /* Read the PLL Reset Type Status register and display on UART */ reset_type = PLL_CTRL_REG_RSTYPE; post_hex_to_string(reset_type, 8, msg); post_write_uart("\r\n\rPLL Reset Type Status Register: 0x"); post_write_uart(msg); /* Dump Additional Information */ post_dump_register_val ((uint32_t)&platform_init_return_code, "\r\n\rPlatform init return code: 0x"); post_write_uart("\r\n\rAdditional Information: "); post_dump_register_val (0x02350014, "\r\n\r (0x02350014) :"); post_dump_register_val (0x02350624, "\r\n\r (0x02350624) :"); post_dump_register_val (0x02350678, "\r\n\r (0x02350678) :"); post_dump_register_val (0x0235063C, "\r\n\r (0x0235063C) :"); post_dump_register_val (0x02350640, "\r\n\r (0x02350640) :"); post_dump_register_val (0x02350644, "\r\n\r (0x02350644) :"); post_dump_register_val (0x02350648, "\r\n\r (0x02350648) :"); post_dump_register_val (0x0235064C, "\r\n\r (0x0235064C) :"); post_dump_register_val (0x02350650, "\r\n\r (0x02350650) :"); post_dump_register_val (0x02350654, "\r\n\r (0x02350654) :"); post_dump_register_val (0x02350658, "\r\n\r (0x02350658) :"); post_dump_register_val (0x0235065C, "\r\n\r (0x0235065C) :"); post_dump_register_val (0x02350660, "\r\n\r (0x02350660) :"); post_dump_register_val (0x02350668, "\r\n\r (0x02350668) :"); post_dump_register_val (0x02350670, "\r\n\r (0x02350670) :"); post_dump_register_val (0x02620008, "\r\n\r (0x02620008) :"); post_dump_register_val (0x0262000c, "\r\n\r (0x0262000c) :"); post_dump_register_val (0x02620010, "\r\n\r (0x02620010) :"); post_dump_register_val (0x02620014, "\r\n\r (0x02620014) :"); post_dump_register_val (0x02620018, "\r\n\r (0x02620018) :"); post_dump_register_val (0x02620180, "\r\n\r (0x02620180) :"); post_write_uart("\r\n\r------------------------------------------"); } post_write_uart("\r\n\r\nPower On Self Test\n"); /* Display test in progress UART/LED status or init error */ post_display_status(test_id, POST_TEST_RESULT_STARTED); post_display_status(POST_TEST_EEPROM, POST_TEST_RESULT_STARTED); test_result = post_test_eeprom(); if (test_result == POST_TEST_RESULT_FAILED) { acc_fail++; } post_display_status(POST_TEST_EEPROM, test_result); post_display_status(POST_TEST_NOR, POST_TEST_RESULT_STARTED); test_result = post_test_nor(); if (test_result == POST_TEST_RESULT_FAILED) { acc_fail++; } post_display_status(POST_TEST_NOR, test_result); post_display_status(POST_TEST_NAND, POST_TEST_RESULT_STARTED); test_result = post_test_nand(); if (test_result == POST_TEST_RESULT_FAILED) { acc_fail++; } post_display_status(POST_TEST_NAND, test_result); post_display_status(POST_TEST_EMAC_LOOPBACK, POST_TEST_RESULT_STARTED); test_result = post_test_emac_loopback(); if (test_result == POST_TEST_RESULT_FAILED) { acc_fail++; } post_display_status(POST_TEST_EMAC_LOOPBACK, test_result); post_display_status(POST_TEST_DDR, POST_TEST_RESULT_STARTED); test_result = post_test_external_memory(); if (test_result == POST_TEST_RESULT_FAILED) { acc_fail++; } post_display_status(POST_TEST_DDR, test_result); post_display_status(POST_TEST_COMPLETE, POST_TEST_RESULT_PASSED); if (acc_fail == 0) { post_write_uart("\r\n\r\nPOST result: PASS"); } else { post_write_uart("\r\n\r\nPOST result: FAIL"); } post_write_serial_no(); }