📄 dloadarm.c
字号:
word cmd_len
/* Number of bytes received in the command packet */
)
{
extern unsigned long long chk_security_code_ptr;
byte *security_code;
int i;
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
if (cmd_len < UNLOCK_SIZ) /* Make sure at least the header arrived */
{
transmit_response(NAK_EARLY_END); /* Nope, packet ended early */
return;
}
/* If secure functions are already unlocked, bypass
validity check of received security code */
if (sec_code_unlocked)
{
transmit_response(ACK);
return;
}
/* Compare 64-bit security code in the received packet
with the security code stored in flash */
/* point to beginning of security code */
security_code = (byte *) &chk_security_code_ptr;
/* code is 64 bits long */
/* scan through security code */
for (i = 0; i < 8; i++)
{
/* received invalid security code */
/* NAK the command and power-off the phone */
if (security_code[i] != cmd_buf[i+1])
{
sec_code_unlocked = FALSE;
transmit_response(NAK_BAD_SEC_CODE);
/* now powerdown the phone */
boot_hw_powerdown();
return;
}
}
/* The received security code matches the stored code, so
set SECURITY_CODE_STATUS to unlock secure operations */
sec_code_unlocked = TRUE;
} /* unlock_cmd() */
/*===========================================================================
FUNCTION nop_cmd
DESCRIPTION
This function processes a no-op command packet.
DEPENDENCIES
None.
RETURN VALUE
None.
SIDE EFFECTS
None.
===========================================================================*/
static void nop_cmd(void)
{
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
/* (The whole packet must have arrived, since it's only one byte long.) */
transmit_response(ACK); /* Nothing can go wrong. Send an ACK. */
} /* nop_cmd() */
/*===========================================================================
FUNCTION preq_cmd
DESCRIPTION
This function processes a parameter request command packet.
DEPENDENCIES
None.
RETURN VALUE
None.
SIDE EFFECTS
None.
===========================================================================*/
static void preq_cmd(void)
{
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
/* Packet we'll build and send in response */
pkt_buffer_type params_buf;
/* Model number of the phone hardware */
extern word boot_mob_model;
word mob_model;
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
/* (The whole packet must have arrived, since it's only one byte long.) */
/* Copy the mob_model number out of flash */
mob_model = boot_mob_model;
/* If the real value can't be determined, we use the unknown value code */
if ((mob_model == MOB_MODEL_NOP_VAL) || (mob_model == MOB_MODEL_ERASED_VAL))
mob_model = MOB_MODEL_UNKNOWN_VAL;
/* Build the packet. */
START_BUILDING_PACKET(params_buf);
ADD_BYTE_TO_PACKET(params_buf, CMD_PARAMS);
ADD_BYTE_TO_PACKET(params_buf, PROTOCOL_ID);
ADD_BYTE_TO_PACKET(params_buf, MIN_PROTOCOL_ID);
ADD_WORD_TO_PACKET(params_buf, MAX_WRITE_SIZE);
ADD_BYTE_TO_PACKET(params_buf, mob_model);
ADD_BYTE_TO_PACKET(params_buf, DUMMY);
ADD_BYTE_TO_PACKET(params_buf, DUMMY);
FINISH_BUILDING_PACKET(params_buf);
/* Send the requested parameters response */
transmit_packet(¶ms_buf);
} /* preq_cmd() */
/*===========================================================================
FUNCTION reset_cmd
DESCRIPTION
This function processes a reset command packet by resetting the
phone (after the command is acknowledged).
DEPENDENCIES
None.
RETURN VALUE
Does not return.
SIDE EFFECTS
None.
===========================================================================*/
static void reset_cmd(void)
{
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
/* (The whole packet must have arrived, since it's only one byte long.) */
transmit_response(ACK); /* Nothing can go wrong. Send an ACK. */
uart_drain(); /* Make sure the response gets out. */
for (;;) /* Do nothing until the watchdog resets the machine. */
{
}
} /* reset_cmd() */
/*===========================================================================
FUNCTION dload_str_len
DESCRIPTION
This function returns the number of characters in the given string, not
counting the terminating NULL character. The returned length is never
more than 20, to accomodate a limitation of the dload protocol.
DEPENDENCIES
The string should be NULL terminated. If it is not, only the first 20
characters will matter.
RETURN VALUE
The length of the string, not counting the terminating NULL. The value
never exceeds 20.
SIDE EFFECTS
None.
===========================================================================*/
static byte dload_str_len(const char* str)
{
byte count = 0;
char* ptr;
/* count every non-null character, but don't go beyond 20 characters */
for (ptr = (char*)str; *ptr != '\0' && count < 20; ptr++)
count++;
return count;
}
/*===========================================================================
FUNCTION verreq_cmd
DESCRIPTION
This function processes a software version request command packet.
DEPENDENCIES
None.
RETURN VALUE
None.
SIDE EFFECTS
None.
===========================================================================*/
static void verreq_cmd(void)
{
pkt_buffer_type verrsp_buf;
/* Buffer where we'll build the response packet. */
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
/* (The whole packet must have arrived, since it's only one byte long.) */
START_BUILDING_PACKET(verrsp_buf);
ADD_BYTE_TO_PACKET(verrsp_buf, CMD_VERRSP);
/* mob_sw_rev is defined in mobile.c */
ADD_BYTE_TO_PACKET(verrsp_buf, dload_str_len(mob_sw_rev));
ADD_STRING_TO_PACKET(verrsp_buf, mob_sw_rev);
FINISH_BUILDING_PACKET(verrsp_buf);
transmit_packet(&verrsp_buf);
/* Send the requested version response */
} /* verreq_cmd() */
/*===========================================================================
FUNCTION pwroff_cmd
DESCRIPTION
This function processes a Turn Phone Power Off command packet by
turning off power to the phone (after the command is acknowledged).
DEPENDENCIES
None.
RETURN VALUE
Does not return.
SIDE EFFECTS
None.
===========================================================================*/
void pwroff_cmd(void)
{
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
/* (The whole packet must have arrived, since it's only one byte long.) */
transmit_response(ACK); /* Nothing can go wrong. Send an ACK. */
uart_drain(); /* Make sure the response gets out. */
/* now powerdown the phone */
boot_hw_powerdown();
} /* pwroff_cmd() */
/*===========================================================================
FUNCTION process_packets
DESCRIPTION
This function is the main loop implementing the DMSS Async Download
Protocol. It loops forever, processing packets as they arrive.
DEPENDENCIES
All necessary initialization for normal CPU operation must have
been performed, and the UART must have been initialized, before
entering this function.
RETURN VALUE
This function does not return.
SIDE EFFECTS
None.
===========================================================================*/
void process_packets(void)
{
byte *pkt_buf;
/* pointer to buffer for receiving a packet */
word len;
/* Length of the packet received. Guaranteed to be at least
MIN_PACKET_LEN. */
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
/* set pointer to base of buffer area */
pkt_buf = (byte*)PKT_BUFFER_BASE;
/* Loop forever processing packets */
for (;;)
{
len = rcv_packet(pkt_buf); /* Get a packet from the UART */
/* Process the packet according to its command code */
switch(pkt_buf[0])
{
case CMD_WRITE:
write_cmd(pkt_buf, len);
break;
case CMD_ERASE:
erase_cmd(pkt_buf, len);
break;
case CMD_GO:
go_cmd(pkt_buf, len);
break;
case CMD_NOP:
nop_cmd();
break;
case CMD_PREQ:
preq_cmd();
break;
case CMD_RESET:
reset_cmd();
break;
case CMD_UNLOCK:
unlock_cmd(pkt_buf, len);
break;
case CMD_VERREQ:
verreq_cmd();
break;
case CMD_PWROFF:
pwroff_cmd();
break;
default:
transmit_response(NAK_INVALID_CMD);
break;
}/* switch on packet command code */
/* we've processed the command - reset pointer to base of buffer area */
pkt_buf = (byte*)PKT_BUFFER_BASE;
}/* for (;;) */
}/* process_packets() */
/*============================================================================
FUNCTION SECURITY CODE INIT
DESCRIPTION
Initialize the phone security code status. If erased, there is no security
code, and all operations are unlocked. If a security code exists, an unlock
packet with matching security code must be received, prior to performing
any protected operations (read/write/go).
FORMAL ARGUMENTS
None
DEPENDENCIES
None
RETURN VALUE
None
SIDE EFFECTS
Sets the security code status. If locked, an unlock command with correct
security code must be received.
============================================================================*/
void security_code_init()
{
extern unsigned long long chk_security_code_ptr;
byte *security_code;
int i;
/* point to beginning of security code */
security_code = (byte*) &chk_security_code_ptr;
/* scan through security code */
for (i = 0; i < 8; i++)
/* if the security code is not the erased value */
if (security_code[i] != 0xFF)
{
/* then the code was written, and so we're currently locked */
sec_code_unlocked = FALSE;
return;
}
/* part is erased, so unlock for all protected operations */
sec_code_unlocked = TRUE;
}
/*============================================================================
FUNCTION BOOT_DOWNLOADER
DESCRIPTION
Do a bootstrap download. Initialize the UART and perform memory
operations at the direction of an external agent via the UART.
FORMAL ARGUMENTS
None
DEPENDENCIES
Called from the Diagnostic Task during offline mode, or as a part of
the Boot modules error recovery.
RETURN VALUE
This routine does not return. It may branch to a new program loaded
into RAM.
SIDE EFFECTS
The watchdog timer is reset, interrupts are disabled. The timeout
counter is initialized and timeout checking is enabled/disabled.
============================================================================*/
void
boot_downloader(void)
{
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
/* Turn of the PAs */
outpw( PA_ON_CTL_WB, 0x0000 );
/* Armprog expects TCXO so switch MCLK source to TCXO */
#if defined(FEATURE_MCLK_43TCXO)
MCLK_SWITCH_TO_NORM();
#elif defined(T_MSM_5100)
#error code not present
#endif /*FEATURE_MCLK_43TCXO*/
//boot_hw_ctrl_init(); /* restore clock and memory config to original setting */
uart_drain(); /* drain UART */
dload_uart_init(UART_1152K_BPS); /* Hardware initialization */
security_code_init(); /* initialize the security code */
process_packets(); /* Process the protocol (forever) */
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -