📄 dloadarm.c
字号:
/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
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 + -