⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dloadarm.c

📁 在高通的手机平台下,一个下载手机.bin文件到手机的flash中的工具,包含PC端的程序代码和运行在基带处理器中的代码.
💻 C
📖 第 1 页 / 共 4 页
字号:
/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*

                  D O W N L O A D  P A C K E T   P R O C E S S I N G

GENERAL DESCRIPTION
  This module handles the DMSS Async Download Protocol to download
  code using simple generic UART services.  This consists of an
  infinite loop of receiving a command packet through the UART,
  acting on it, and returning a response packet.

EXTERNALIZED FUNCTIONS
  process_packets
    Runs the packet protocol (forever).

INITIALIZATION AND SEQUENCING REQUIREMENTS
  All necessary initialization for normal CPU operation must have
  been performed, and the UART must have been initialized, before
  entering this module.

Copyright (c) 1998,1999 by QUALCOMM Incorporated.
All Rights Reserved.
*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/

/*===========================================================================

                           EDIT HISTORY FOR FILE
  This section contains comments describing changes made to the module.
  Notice that changes are listed in reverse chronological order.

$Header:   L:/src/asw/MSM5105/vcs/dloadarm.c_v   1.4   09 May 2001 15:08:54   robertom  $

when       who     what, where, why
--------   ---     ----------------------------------------------------------
12/26/05   wufei.lin crear file for msm6000_bt
--------   ---     ----------------------------------------------------------
05/09/01   rmd     Moved the definition of pkt_buf into process_packets().
03/21/01   rmd     In boot_downloader, changed the location of micro clock switching 
                   code to make sure that the wait states get updated at the right time.
08/27/00   rmd     Replaced KICK_WATCHDOG with BOOTHW_KICK_WATCHDOG.
08/25/00   jcw     Merge for MSM5105
06/30/00   rmd     Added boot_downloader_clk_init to init MSM clk and Memory/IO
                   wait states to old configuration. This done before code is download 
                   into the phone to prevent any old software to init incorrectly the MSM.
12/07/99   jc      Minor cleanup to reduce confusion                   
11/03/99   mk      Transmit Power Amplifier (PA/PA2) will be turned off after
                   hitting an error fatal.
08/27/99   jwh     Merged with the MSM3000 merge with SS baseline.
08/20/99   mk      ARM2.5 compiler update.
03/17/99    ms     Removed bb_ prefix for Virtual Boot Block.
                   Now calling dload_uart_init instead of bb_uart_init.
12/15/98   jc      Merge from et0400
11/05/98   jtg     Shortened line to 80 chars.
10/14/98   hcg     Removed <string.h> and replaced with memory.h for global
                   memcpy() solution.
09/13/98   hcg     General mods for MSM3000 support.  Implemented security
                   feature, changed parameter response message.
08/08/98   hcg     Added #include file - Cleaned up comments/removed unused code.
08/03/98   hcg     Fixed bug for offset into cmd_buf for security feature
07/30/98   hcg     Phone powers down after failure to unlock security feature
07/30/98   hcg     Implemented security feature
07/26/98   hcg     Revised for coding standard, removed unused code
06/01/98   hcg     Ported from Flashprg by ptw

===========================================================================*/

/*===========================================================================

                     INCLUDE FILES FOR MODULE

===========================================================================*/

#include "dloadarm.h"

#include "dloaduart.h"


/*===========================================================================

            LOCAL DEFINITIONS AND DECLARATIONS FOR MODULE

This section contains local definitions for constants, macros, types,
variables and other items needed by this module.

===========================================================================*/
#define NOTICE_TYPE       const char
NOTICE_TYPE mob_sw_rev[] = "KS3.4.101PAT";

/* The Download Protocol is enhanced from time to time.  This value defines
   the version number of the protocol supported by this implementation. */
#define  PROTOCOL_ID          4

/* Someday the change might not be backwards compatible.  When that happens,
   this value will define the earliest protocol spec with which this
   implementation is compatible.  So far, all versions are compatible, so
   this value is 1, which indicates that it is compatible with all versions. */
#define  MIN_PROTOCOL_ID      1

/* The protocol allows the implementation to place an arbitrary limit on
   how large a data write packet can be.  This value shouldn't be too
   small, for efficiency reasons, but can't be bigger than the memory
   buffer we can allocate.  Here we pick a nice, arbitrary value of
   4K bytes. */
#define  MAX_WRITE_SIZE       (0x1000)

/* These variables are generated by the linker, which give the locations
   of memory for which the phone code resides.  This serves as a base for which
   we can zero out memory and use as a packet buffer, as well as code
   downloading */
extern byte *Image__BB_RAM__Base;

/* area for download packet, etc. = 8K */
#define  PKT_BUF_SIZE           (0x2000)

//#if defined(LT_BOOTLOADER)
//byte PKT_BUFFER_BASE[PKT_BUF_SIZE];
//#else
/* Start of packet buffer */
#define  PKT_BUFFER_BASE      (Image__BB_RAM__Base-PKT_BUF_SIZE)
//#endif

/* Start of download area */
#define  DLOAD_BASE           RAM_BASE
//#if defined(LT_BOOTLOADER)
//#//define  DLOAD_LIMIT          ((dword)PKT_BUFFER_BASE)
//#else
#define  DLOAD_LIMIT          (Image__BB_RAM__Base-PKT_BUF_SIZE)
//#endif

/* offset to convert from hex file address to ARM mechanism */
#define  DLOAD_OFFSET         (DLOAD_BASE)


/*-------------------------------------------------------------------------*/

/* We determine what phone model we're running on by checking a magic
   location in the boot block.  Before the boot block was implemented,
   this location was always filled with NOP op-codes. */
#define  MOB_MODEL_NOP_VAL          0x9090      /* Old value: NOP opcodes.
                                                   Model unknown.  */

#define  MOB_MODEL_ERASED_VAL       0xFFFF      /* Value when blank, due to
                                                   the bootblock being
                                                   erased.  Model unknown. */

#define  MOB_MODEL_UNKNOWN_VAL      0x0000      /* Return this value when the
                                                   model is unknown. */

      /* MOB_MODEL_UNKNOWN_VAL is 0x0000 because that is the one and only
         value that can always be attained by writing to the location,
         no matter what is there presently, without erasing the block.
         This makes it possible to recover from corruption of this byte. */

#define  DUMMY                      0x0000

/*-------------------------------------------------------------------------*/



/* Flag indicates whether a valid security code has been received yet */
boolean sec_code_unlocked=FALSE;


//extern  NOTICE_TYPE mob_sw_rev[] ;


/*-------------------------------------------------------------------------*/

/* Async HDLC achieves data transparency at the byte level by using
   two special values. The first is a flag value which begins and ends
   every packet: */
#define  ASYNC_HDLC_FLAG      0x7e

/* The flag value might appear in the data.  If it does, it is sent as
   a two-byte sequence consisting of a special escape value followed by
   the flag value XORed with 0x20.  This gives a special meaning to the
   escape character, so if it appears in the data it is itself escaped
   in the same way. */
#define  ASYNC_HDLC_ESC       0x7d
#define  ASYNC_HDLC_ESC_MASK  0x20

/*-------------------------------------------------------------------------*/

/* Each packet sent or received in this download protocol begins with a
   one-byte command code chosen from the following list.  Each packet
   type is either received by the phone or transmitted by the phone, but
   not both. */

/*lint -e749  Some values in this local enum are not used in this program. */
/*lint -esym(751,cmd_code_type) and in fact this enum itself is not used. */

typedef PACKED   enum
   {
   CMD_WRITE  = 0x01,   /* Write a block of data to memory (received)    */
   CMD_ACK    = 0x02,   /* Acknowledge receiving a packet  (transmitted) */
   CMD_NAK    = 0x03,   /* Acknowledge a bad packet        (transmitted) */
   CMD_ERASE  = 0x04,   /* Erase a block of memory         (received)    */
   CMD_GO     = 0x05,   /* Begin execution at an address   (received)    */
   CMD_NOP    = 0x06,   /* No operation, for debug         (received)    */
   CMD_PREQ   = 0x07,   /* Request implementation info     (received)    */
   CMD_PARAMS = 0x08,   /* Provide implementation info     (transmitted) */
   CMD_DUMP   = 0x09,   /* Debug: dump a block of memory   (received)    */
   CMD_RESET  = 0x0A,   /* Reset the phone                 (received)    */
   CMD_UNLOCK = 0x0B,   /* Unlock access to secured ops    (received)    */
   CMD_VERREQ = 0x0C,   /* Request software version info   (received)    */
   CMD_VERRSP = 0x0D,   /* Provide software version info   (transmitted) */
   CMD_PWROFF = 0x0E    /* Turn phone power off            (received)    */
   } cmd_code_type;


/*-------------------------------------------------------------------------*/

/* For the received packets, we need the minimum length of a valid packet
   of that type (except where the packet is only a command code). Note,
   size is in bytes */

#define  WRITE_SIZ   8  /* Minimum size of the Write packet */
#define  ERASE_SIZ   9  /* Total size of the Erase packet   */
#define  GO_SIZ      7  /* Total size of the Go packet      */
#define  UNLOCK_SIZ  9  /* Total size of the unlock packet  */

/*-------------------------------------------------------------------------*/

   /* Maximum size of a received packet. */

#define  MAX_PACKET_LEN    PKT_BUF_SIZE 

   /* Minimum size of a received packet. */
#define  MIN_PACKET_LEN    3        /* 2 bytes CRC + 1 byte command code */


/*-------------------------------------------------------------------------*/

/* These packets are the same every time they are transmitted by the phone,
   so we can use pre-computed "canned" messages.  All byte-stuffing required
   by the protocol for transparency has already been done.  Each packet ends
   with a flag, which is both transmitted and used as the termination
   indicator for these arrays. */

static const byte rsp_ack[] =                   /* ACK */
  {
  CMD_ACK,             /* ACK type */
  0x6a,                /* CRC, MSB */
  0xd3,                /* CRC, LSB */
  ASYNC_HDLC_FLAG
  };

static const byte rsp_nak_invalid_fcs[] =       /* NAK_INVALID_FCS */
  {
  CMD_NAK,             /* NACK type */
  0x00,                /* Reason code, MSB */
  0x01,                /* Reason code, LSB */
  0x21,                /* CRC, MSB */
  0x38,                /* CRC, LSB */
  ASYNC_HDLC_FLAG
  };

static const byte rsp_nak_invalid_dest[] =      /* NAK_INVALID_DEST */
  {
  CMD_NAK,             /* NACK type */
  0x00,                /* Reason code, MSB */
  0x02,                /* Reason code, LSB */
  0xba,                /* CRC, MSB */
  0x0a,                /* CRC, LSB */
  ASYNC_HDLC_FLAG
  };

static const byte rsp_nak_invalid_len[] =       /* NAK_INVALID_LEN */
  {
  CMD_NAK,             /* NACK type */
  0x00,                /* Reason code, MSB */
  0x03,                /* Reason code, LSB */
  0x33,                /* CRC, MSB */
  0x1b,                /* CRC, LSB */
  ASYNC_HDLC_FLAG
  };

static const byte rsp_nak_early_end[] =         /* NAK_EARLY_END */
  {
  CMD_NAK,             /* NACK type */
  0x00,                /* Reason code, MSB */
  0x04,                /* Reason code, LSB */
  0x8c,                /* CRC, MSB */
  0x6f,                /* CRC, LSB */
  ASYNC_HDLC_FLAG
  };

static const byte rsp_nak_too_large[] =         /* NAK_TOO_LARGE */
  {
  CMD_NAK,                      /* NACK type */
  0x00,                         /* Reason code, MSB */
  0x05,                         /* Reason code, LSB */
  0x05,                         /* CRC, MSB */
  ASYNC_HDLC_ESC,
  0x7e ^ ASYNC_HDLC_ESC_MASK,   /* CRC, LSB */
  ASYNC_HDLC_FLAG
  };

static const byte rsp_nak_invalid_cmd[] =       /* NAK_INVALID_CMD */
  {
  CMD_NAK,             /* NACK type */
  0x00,                /* Reason code, MSB */
  0x06,                /* Reason code, LSB */
  0x9e,                /* CRC, MSB */
  0x4c,                /* CRC, LSB */
  ASYNC_HDLC_FLAG
  };

static const byte rsp_nak_failed[] =            /* NAK_FAILED */
  {
  CMD_NAK,             /* NACK type */
  0x00,                /* Reason code, MSB */
  0x07,                /* Reason code, LSB */
  0x17,                /* CRC, MSB */
  0x5d,                /* CRC, LSB */
  ASYNC_HDLC_FLAG
  };

static const byte rsp_nak_wrong_iid[] =         /* NAK_WRONG_IID */
  {
  CMD_NAK,             /* NACK type */
  0x00,                /* Reason code, MSB */
  0x08,                /* Reason code, LSB */
  0xe0,                /* CRC, MSB */
  0xa5,                /* CRC, LSB */
  ASYNC_HDLC_FLAG
  };

static const byte rsp_nak_bad_vpp[] =           /* NAK_BAD_VPP */
  {
  CMD_NAK,             /* NACK type */
  0x00,                /* Reason code, MSB */
  0x09,                /* Reason code, LSB */
  0x69,                /* CRC, MSB */
  0xb4,                /* CRC, LSB */
  ASYNC_HDLC_FLAG
  };

static const byte rsp_nak_verify_failed[] =     /* NAK_VERIFY_FAILED */
  {
  CMD_NAK,             /* NACK type */
  0x00,                /* Reason code, MSB */
  0x0a,                /* Reason code, LSB */
  0xf2,                /* CRC, MSB */
  0x86,                /* CRC, LSB */
  ASYNC_HDLC_FLAG
  };


static const byte rsp_nak_no_sec_code[] =          /* NAK_NO_SEC_CODE */
  {
  CMD_NAK,    /* NACK type */
  0x000,      /* Reason code, MSB */
  0x00B,      /* Reason code, LSB */
  0x07B,      /* CRC, MSB */
  0x097,      /* CRC, LSB */
  ASYNC_HDLC_FLAG
  };

static const byte rsp_nak_bad_sec_code[] =        /* NAK_BAD_SEC_CODE */
  {
  CMD_NAK,    /* NACK type */
  0x000,      /* Reason code, MSB */
  0x00C,      /* Reason code, LSB */
  0x0C4,      /* CRC, MSB */
  0x0E3,      /* CRC, LSB */
  ASYNC_HDLC_FLAG
  };

/*-------------------------------------------------------------------------*/

/* This table translates a response code into a pointer to a canned
   response packet.  The table must be in the same order as the
   response_code_type enum. */

static const byte * const response_table[] =
  {
  rsp_ack,
  rsp_nak_invalid_fcs,
  rsp_nak_invalid_dest,
  rsp_nak_invalid_len,
  rsp_nak_early_end,
  rsp_nak_too_large,
  rsp_nak_invalid_cmd,
  rsp_nak_failed,
  rsp_nak_wrong_iid,
  rsp_nak_bad_vpp,
  rsp_nak_verify_failed,
  rsp_nak_no_sec_code,
  rsp_nak_bad_sec_code
  };


/*-------------------------------------------------------------------------*/

   /* Other packets must be built up on the fly.  This data type and the
      associated macros support dynamic construction of a packet.  */

/* According to the protocol spec, a version string can be at most 20 bytes */
#define  MAX_VERSTRING_LEN    (20)

#define  ROOM_FOR_CRC   (4)         /* Allow this much room for the CRC,
                                       including worst-case expansion due
                                       to byte-stuffing */
#define  ROOM_FOR_FLAG  (1)         /* Allow this much room for trailing flag */

/* The buffer size for response packets.  Based on the longest possible
   packet, the Software Version acknowledgement. */
#define  MAX_RESPONSE_LEN  (1+2+MAX_VERSTRING_LEN+ROOM_FOR_CRC+ROOM_FOR_FLAG)
                           /* 1 = command code
                              2 = fixed fields of packet, version and len */

typedef PACKED struct
  {
  word      length;                 /* Length of packet so far */
  boolean   broken;                 /* Set if the packet can't be built */
  byte      buf[MAX_RESPONSE_LEN];  /* The packet under construction */
  } pkt_buffer_type;



/*===========================================================================

MACRO START_BUILDING_PACKET

DESCRIPTION
  This macro initializes the process of dynamically building a packet.

PARAMETERS
  pkt     A pkt_buffer_type struct in which the packet will be built.

DEPENDENCIES
  None.

RETURN VALUE
  None.

SIDE EFFECTS
  pkt is evaluated twice within this macro.
  This macro is not an expression, nor is it a single statement.  It
  must be called with a trailing semicolon.

===========================================================================*/

#define  START_BUILDING_PACKET(pkt)          \
               pkt.length = 0;               \
               pkt.broken = FALSE


/*===========================================================================

MACRO ADD_BYTE_TO_PACKET

DESCRIPTION
  This macro adds a single byte to a packet being built dynamically.

PARAMETERS
  pkt     A pkt_buffer_type struct in which the packet will be built.
  val     The byte to be added to the packet.

DEPENDENCIES
  START_BUILDING_PACKET must have been called on pkt before calling
  this macro.

RETURN VALUE
  None.

SIDE EFFECTS
  None.

===========================================================================*/

#define  ADD_BYTE_TO_PACKET(pkt,val)         \
               add_byte_to_packet(&pkt, val)


/*===========================================================================

MACRO ADD_WORD_TO_PACKET

DESCRIPTION
  This macro adds a word (most significant byte first) to a packet

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -