?? download.c
字號:
/*----------------------------------------------------------------------------* Copyright (c) 2006 by Hifn, Inc, Los Gatos, CA, U.S.A. All Rights Reserved. This software is furnished to licensee under a software license agreement and may be used and copied only in accordance with the terms and conditions of such license and with the inclusion of the above Copyright Notice. This software or any other copies thereof may not be provided or otherwise made available to any other person. No title to and ownership of the software is hereby transferred and licensee is subject to all confidentiality provisions set forth in the software license agreement. The information in this software is subject to change without notice.*-----------------------------------------------------------------------------*/static char const hftc_id[] = "$Id: @(#) download.c 1.20@(#) $";/*----------------------------------------------------------------------------* * @file download.c * @brief Download of a cdl file. * * This is part of the download and configuration example program. * This code is very similar to that in the download_file utility, found in * tools/download_file/src. * *----------------------------------------------------------------------------*//* @defgroup CD_API_UTIL *//*------------------------------------* * Header Include *------------------------------------*//* Standard includes */#include <stdio.h>#include <string.h>#include <stdlib.h>#include <unistd.h> /* for close */#include "hftc_pub_common.h"#include "hftc_pub_types.h"#include "hftc_pub_errors.h"#include "hftc_pub_download.h"#include "hftc_pub_base.h"#include "hftc_pub_os_common.h"#include "hftc_pub_translate_enums.h"#include "hftc_pub_service.h" /* For Viper Reset Patch */#include "hftc_pub_app_utils.h" /* For reading of esc unit table file */#include "download_configure.h"#include "load_config_params.h" /* For indicies into esc unit table *//*------------------------------------* * Constants and Types *------------------------------------*/#define DL_DEBUG 0 /* Set = 1 to get debug output, 0 for none. *//* This is used intenally for exchangeFrames to determine if we are doing a Code download (.cdl) or Data download (.ddl).*/typedef enum{ CodeDownLoad = 0, DataDownLoad = 1} DownloadType_t;/*------------------------------------* * External Variables *------------------------------------*//*------------------------------------* * File-Scope Variables *------------------------------------*/static HFTC_socket_t socket_fd_fs = HFTC_INVALID_SOCKET_FD;static HFTC_sockaddr_t socket_addr_fs;/* This is used as a temporary workaround until the status of the Viper respin or not is known. This is used to store off the PCI Device ID of the chip, to know if the Viper soft reset workaround patch needs to be applied. A value of 0 is not currently a valid HFTC_DEVICE_ID value, therefore it is used here to signify that the device id hasn't been set. The value gets saved in doInfoGathering.*/static uint32_t PCIDeviceID = 0; /* 0 is unset *//* This is used to signal if we need to apply the HFTC_MII_LENGTH_ADJUST macro to adjust the length of a frame transmitted to the MII port on a 83x0 or 43x0. We assume this is the case until proven otherwise.*/static HFTC_Boolean_t MIIAdjust = HFTC_TRUE;/* This is used to catch resets that occur on images that aren't the first image being downloaded. There was a bug where the DPU appeared to be in a BOOT ROM state, yet the eSC was running code. While downloading the DPU worked, download configure issued a reset when downloading the second image (an eSC image), which then put the DPU into a reset state. By catching this case, we can warn the user they need to force a reset via the --force-reset flag.*/static uint32_t imagesLoaded = 0;/*------------------------------------* * Local Function Prototypes *------------------------------------*//*------------------------------------* * Implementation *------------------------------------*//*----------------------------------------------------------------------------* * exchangeFrames *----------------------------------------------------------------------------* * @ingroup CD_API_UTIL * @brief Transmit a frame, and receive a frame (and check its response) * * Does the common inner exchange of transmit, receive, check response * The logic in pseudo code is as follows: * * do * transmit frame * do * receive frame * check response * while pass another * while timeout && time < RETRANSMIT_RETRY_SECONDS * * @param unit RO: Unit number of target being downloaded. * @param frameLen RO: Maximum received frame length in bytes. * @param sendFrameLen RO: Length in bytes of frame being sent. * @param downloadType WO: Type of download (cdl or ddl) * @param sframe RO: Pointer to buffer with frame to send. * @param rframe WO: Pointer to buffer where frame is received. * * @par Externals: * None. * * @return * * @par Errors: * None. * * @par Assumptions: * Assumes parameters are valid. * *----------------------------------------------------------------------------*/staticHFTC_Status_t exchangeFrames(HFTC_Unit_t unit, uint32_t frameLen, uint32_t sendFrameLen, DownloadType_t downloadType, HFTC_Buffer_t *sframe, HFTC_Buffer_t *rframe){ HFTC_Status_t status = HFTC_STATUS_OK; HFTC_Status_t tstatus = HFTC_STATUS_OK; HFTC_Status_t retransmitStatus = HFTC_STATUS_OK; uint32_t numRetransmits = 0; uint32_t current_seconds; uint32_t current_milliseconds; uint32_t end_seconds; uint32_t end_milliseconds; uint32_t recvFrameLen; uint32_t bytesSent; /* Get the current time. We are only going to retry for a limited amount of clock time, so we need to know how much time has passed. */ status = HFTC_get_time(¤t_seconds, ¤t_milliseconds); if (status != HFTC_STATUS_OK) { printf("** ERROR: In %s HFTC_get_time problem, " "status = %s (%d)\n", __func__, HFTC_Status_t_text(status), status); return status; } end_seconds = current_seconds + RETRANSMIT_RETRY_SECONDS; end_milliseconds = current_milliseconds; do { /* Transmit the frame */ if (MIIAdjust == HFTC_TRUE) { HFTC_MII_LENGTH_ADJUST(sendFrameLen); } status = HFTC_socket_sendto(socket_fd_fs, sframe, sendFrameLen, &socket_addr_fs, &bytesSent); if (status != HFTC_STATUS_OK || bytesSent != sendFrameLen) { printf("** ERROR: Transmit failed! Status = %s (%d).\n", HFTC_Status_t_text(status), status); status = HFTC_SOCKET_ERROR; break; } do { /* receive frame check response */ status = HFTC_socket_recvfrom(socket_fd_fs, rframe, frameLen, &socket_addr_fs, &recvFrameLen); if (status == HFTC_STATUS_OK) { if (downloadType == CodeDownLoad) { status = HFTC_CD_CheckCodeResponse(unit, recvFrameLen, rframe); } else { status = HFTC_DD_CheckCfgDataResponse(unit, recvFrameLen, rframe); } } } while (status == HFTC_PASS_ANOTHER_RESPONSE); if (status == HFTC_TIMEOUT) { ++numRetransmits; if (numRetransmits == NUM_RETRANSMITS) { printf("Timeout occurred; retrying...\n"); } if (downloadType == CodeDownLoad) { retransmitStatus = HFTC_CD_CodeRetransmit(unit); } else { retransmitStatus = HFTC_DD_CfgDataRetransmit(unit); } if (retransmitStatus != HFTC_STATUS_OK) { printf("Code retransmit failed! Status = %s (%d).\n", HFTC_Status_t_text(retransmitStatus), status); break; } } /* If RETRANSMIT_RETRY_SECONDS have passed, exit with a timeout. */ tstatus = HFTC_get_time(¤t_seconds, ¤t_milliseconds); if (tstatus != HFTC_STATUS_OK) { status = tstatus; printf("** ERROR: In %s HFTC_get_time problem, status = %s (%d)\n", __func__, HFTC_Status_t_text(status), status); break; } if (current_seconds > end_seconds || (current_seconds == end_seconds && current_milliseconds >= end_milliseconds)) { /* Status is already set. */ break; } } while (status == HFTC_TIMEOUT); return status;} /* End exchangeFrames *//*----------------------------------------------------------------------------* * doInitCodeDownload *----------------------------------------------------------------------------* * @ingroup CD_API_UTIL * @brief Do the HFTC_CD_InitCodeDownload call in the non error path. * * The logic in this routine is similar to that in doCodeDownload. One * notable difference is that since the call to HFTC_CD_InitCodeDownload * doesn't take any internal data, we have no backing up to do. * Furthermore, it will handle any retransmit that is needed. Thus, we * loop for not only a return value of HFTC_CALL_AGAIN, but also for a * return value of HFTC_RESULT_UNKNOWN, where the API will do its own * retransmit (transparently to us.) * * @param unit RO: Unit number of target being downloaded. * @param resetState RW: A Boolean value indicating if this is the first * call to HFTC_CD_InitCodeDownload. * @param param_p RO: Pointer to initialization parameters for download * @param frameLen RO: The maximum length of a frame, the size of the * sframe buffer and rframe buffer. * @param sframe WO: Pointer to buffer for frame to send. * @param rframe WO: Pointer to buffer where frame is received. * * @par Externals: * None. * * @return * * @par Errors: * None. * * @par Assumptions: * None. * *----------------------------------------------------------------------------*/staticHFTC_Status_t doInitCodeDownload(HFTC_Unit_t unit, HFTC_Boolean_t resetState, download_param_t *param_p, uint32_t frameLen, HFTC_Buffer_t *sframe, HFTC_Buffer_t *rframe){ HFTC_Status_t status = HFTC_STATUS_OK; uint32_t sendFrameLen; HFTC_PPCIAddress_t destPPCIAddr; /* Program Download Config Variables If not documented, then the value is arbitrary. We don't support authentication at this time. */ HFTC_Boolean_t authenticate = HFTC_FALSE; HFTC_AuthData_t authData = {0}; if (DL_DEBUG) { printf("-->%s resetState=%s\n", __func__, (resetState == HFTC_TRUE) ? "TRUE" : "FALSE"); } /* Do the initCodeDownload call. Loop until we have nothing left to do. */ do { /* Set the destination PPCI address according to our processor type. */ destPPCIAddr = param_p->destPPCIAddrDpu; if (param_p->processorType == HFTC_ESC) { destPPCIAddr = param_p->destPPCIAddrEsc; } /* We may get a result unknown (especially on the first transmit) due to a sequence number error. */ sendFrameLen = frameLen; status = HFTC_CD_InitCodeDownload(unit, resetState, param_p->forceDownload, param_p->processorType, param_p->srcMACAddr, param_p->destMACAddr, param_p->srcPPCIAddr, destPPCIAddr, authenticate, &authData, &sendFrameLen, sframe); if (status != HFTC_STATUS_OK) { break; } else { resetState = HFTC_FALSE; } /* Exchange frames */ status = exchangeFrames(unit, frameLen, sendFrameLen, CodeDownLoad, sframe, rframe); /* If a HFTC_INCONSISTENT error is returned it is probably from an an old frame that may have been around from before this download started). So, we try again with another init code download. We also loop if we are told to call again, or if we get a result unknown which occurs when a response has been dropped. */ } while ( (status == HFTC_CALL_AGAIN) || (status == HFTC_RESULT_UNKNOWN) || (status == HFTC_INCONSISTENT) ); if (DL_DEBUG) { printf("<--%s status = %s; resetState = %s\n", __func__, HFTC_Status_t_text(status), HFTC_Boolean_t_text(resetState)); } return status;} /* End doInitCodeDownload *//*----------------------------------------------------------------------------* * doSoftBootReset *----------------------------------------------------------------------------* * @ingroup CD_API_UTIL * @brief Do the HFTC_CD_SoftBootReset call in the non error path.
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -