dl_proc.c
来自「在高通的手机平台下,一个下载手机.bin文件到手机的flash中的工具,包含PC」· C语言 代码 · 共 1,215 行 · 第 1/3 页
C
1,215 行
switch(state) /* Process according to which state */
{
/*lint -esym(788,HDLC_PACKET_RCVD) No need to deal with HDLC_PACKET_RCVD
since we're in a loop that guarantees we're not in that state. */
case HDLC_HUNT_FOR_FLAG: /* We're looking for a flag ... */
if (chr == ASYNC_HDLC_FLAG) /* and we got one ... */
{
state = HDLC_GOT_FLAG; /* so go on to the next step. */
}
break;
/*- - - - - - - - - - - - - - - - - - -*/
case HDLC_GOT_FLAG: /* Had a flag, now expect a packet */
if (chr == ASYNC_HDLC_FLAG) /* Oops, another flag. No change. */
{
break;
}
else
{ /* Ah, we can really begin a packet */
len = 0; /* The packet starts out empty */
crc = CRC_16_L_SEED; /* and the CRC in its initial state */
state = HDLC_GATHER; /* and we begin to gather a packet */
/* Fall through */ /* (starting with this byte) */
}
/*- - - - - - - - - - - - - - - - - - -*/
case HDLC_GATHER: /* We're gathering a packet */
if (chr == ASYNC_HDLC_FLAG) /* We've reached the end */
{
if (len < MIN_PACKET_LEN) /* Reject any too-short packets */
{
transmit_response(NAK_EARLY_END); /* Send NAK */
state = HDLC_HUNT_FOR_FLAG; /* Start over */
}
else if (crc != CRC_16_L_OK_NEG) /* Reject any with bad CRC */
{
transmit_response(NAK_INVALID_FCS); /* Send NAK */
state = HDLC_HUNT_FOR_FLAG; /* Start over */
}
else /* Yay, it's a good packet! */
{
state = HDLC_PACKET_RCVD; /* Done for now */
}
break; /* However it turned out, this packet is over. */
}
/* It wasn't a flag, so we're still inside the packet. */
if (chr == ASYNC_HDLC_ESC) /* If it was an ESC */
{
chr = uart_receive_byte(); /* Get the escaped byte */
if (chr == UART_RX_ERR) /* If there was an error, */
{
state = HDLC_HUNT_FOR_FLAG; /* Start over */
break;
}
chr ^= ASYNC_HDLC_ESC_MASK; /* Otherwise, de-mask it */
/* No break; process the de-masked byte normally */
}
if (len >= MAX_PACKET_LEN) /* Make sure there's room */
{
transmit_response(NAK_TOO_LARGE); /* Oops, buffer too full */
state = HDLC_HUNT_FOR_FLAG; /* Start over */
}
else
{
buf[len++] = (byte) chr; /* Add byte to buffer */
crc = CRC_16_L_STEP(crc, (word) chr); /* Update the CRC */
}
break;
/*- - - - - - - - - - - - - - - - - - -*/
default: /* Shouldn't happen with an enum, but for safety ... */
state = HDLC_HUNT_FOR_FLAG; /* Start over */
break;
}/* switch on state */
}/* for (packet not found) */
return len;
} /* rcv_packet() */
/*===========================================================================
FUNCTION flash_write_cmd
DESCRIPTION
This function processes a write command packet. Pending a valid address
range, the data is written to Code or Data Flash.
DEPENDENCIES
None.
RETURN VALUE
None.
SIDE EFFECTS
None.
===========================================================================*/
static void write_flash_cmd(byte *cmd_buf,dword cmd_len, boolean code)
{
dword addr; /* destination address for write */
dword len; /* number of bytes to write */
response_code_type rsp;
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
B_PTR(addr)[3] = cmd_buf[1]; /* Extract destination address from packet */
B_PTR(addr)[2] = cmd_buf[2];
B_PTR(addr)[1] = cmd_buf[3];
B_PTR(addr)[0] = cmd_buf[4];
B_PTR(len)[3] = cmd_buf[5]; /* Extract write length from packet */
B_PTR(len)[2] = cmd_buf[6];
B_PTR(len)[1] = cmd_buf[7];
B_PTR(len)[0] = cmd_buf[8];
if(code == TRUE)
//rsp = do_flash_write( cmd_buf+9, 0, addr, len );
rsp = current_flash_device->write_flash(cmd_buf+9, 0, addr, len);
else
rsp = do_write_data(cmd_buf+9,addr,len);
/* everything ok */
transmit_response(rsp);
} /* write_code_cmd() */
/*===========================================================================
FUNCTION flash_erase_cmd
DESCRIPTION
This function processes an erase command packet. Pending a valid address
range, the specified area is erased.
DEPENDENCIES
None.
RETURN VALUE
None.
SIDE EFFECTS
None.
===========================================================================*/
static void erase_flash_cmd
(
byte *cmd_buf,
/* Pointer to the received command packet */
dword cmd_len,
/* Number of bytes received in the command packet */
boolean code
)
{
dword addr; /* destination address */
dword len; /* number of bytes to erase */
response_code_type rsp;
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
B_PTR(addr)[3] = cmd_buf[1]; /* Extract destination address from packet */
B_PTR(addr)[2] = cmd_buf[2];
B_PTR(addr)[1] = cmd_buf[3];
B_PTR(addr)[0] = cmd_buf[4];
B_PTR(len)[3] = cmd_buf[5]; /* Extract write length from packet */
B_PTR(len)[2] = cmd_buf[6];
B_PTR(len)[1] = cmd_buf[7];
B_PTR(len)[0] = cmd_buf[8];
if( code == TRUE)
//rsp = do_flash_erase(0, addr, len);
rsp = current_flash_device->erase_flash(0, addr, len);
else
rsp = do_erase_data(addr, len);
/* everything ok */
transmit_response(rsp);
} /* erase_flash_cmd() */
/*===========================================================================
FUNCTION ChangeBaudRate_CMD
DESCRIPTION
This function processes a ChangeBaudRate command packet
===========================================================================*/
static void change_baudrate_cmd
(
byte *cmd_buf,
/* Pointer to the received command packet */
word cmd_len
/* Number of bytes received in the command packet */
)
{
int i;
transmit_response(ACK); /* Have to send the ACK before GOing. */
//clk_busy_wait(1000); /*must delay for some time,otherwise PC wouldn't get ACK */
for (i=0;i<2000;i++)
BOOTHW_KICK_WATCHDOG();
switch(cmd_buf[1])
{
case UART_1152K_BPS:
dload_uart_init(UART_1152K_BPS);
break;
case UART_2304K_BPS:
dload_uart_init(UART_2304K_BPS);
break;
case UART_4608K_BPS:
dload_uart_init(UART_4608K_BPS);
break;
default:
dload_uart_init(UART_1152K_BPS);
}
}
/*===========================================================================
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)
{
word len;
//byte pkt_buf[MAX_PACKET_LEN];
int color;
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
color=0;
//mclk_reinit();
//dload_uart_init(UART_1152K_BPS);
/* Loop forever processing packets */
/*wufei.lin add to probe the current flash device*/
current_flash_device = amd_flash_probe(0);
if(current_flash_device == (flash_device_type*)NULL)
{
current_flash_device = intel_flash_probe(0);
if(current_flash_device == (flash_device_type*)NULL )
{
transmit_response(NAK_FAILED);
boot_hw_powerdown();
}
}
for (;;)
{
len = rcv_packet(pkt_buf); /* Get a packet from the UART */
disp_state(color);
color=(color+1)&3;
/* Process the packet according to its command code */
switch (pkt_buf[0])
{
case CMD_ERASE_CODE_FLASH:
erase_flash_cmd(pkt_buf, len, TRUE);
break;
case CMD_WRITE_CODE_FLASH:
write_flash_cmd(pkt_buf, len, TRUE);
break;
case CMD_PWROFF:
disp_state(Black);
transmit_response(ACK);
uart_drain(); /* Make sure the response gets out */
boot_hw_powerdown();
break;
case CMD_RESET:
disp_state(Black);
transmit_response(ACK);
uart_drain(); /* Make sure the response gets out */
for(;;)
{
}
break;
case CMD_ERASE_DATA_FLASH:
erase_flash_cmd(pkt_buf, len, FALSE);
break;
case CMD_WRITE_DATA_FLASH:
write_flash_cmd(pkt_buf, len, FALSE);
break;
case CMD_CHANGE_BAUD_RATE:
change_baudrate_cmd(pkt_buf, len);
break;
default:
transmit_response(NAK_INVALID_CMD);
break;
}/* switch on packet command code */
}/* for (;;) */
}/* process_packets() */
/*wufei.lin add to initialize to memory*/
__global_reg(1) dword *dst32;
__global_reg(2) dword *src32;
__global_reg(3) dword *stop_point;
/*
* Pointers to the base and length of CODE segments
*
* These symbols are generated by the linker with $'s instead of _'s. We
* re-name the symbol to use _'s to make valid C identifiers. We embed
* those symbols in bootsys.s so that we have them in the flash.
*/
extern byte *Image__CODE__Base;
extern byte *Image__CODE__Length;
extern byte *Load__CODE__Base;
extern byte *Image__CODE__ZI__Base;
extern byte *Image__CODE__ZI__Length;
void
boot_ram_init()
{
/* kick watchdog at least every 426 ms. */
BOOTHW_KICK_WATCHDOG();
/* Copy initialized data segment for the boot block
*
* This copies data from Load__CODE__Base to Image__CODE__Base
* for the length Image__CODE__Length. This is accomplished by
* running two pointers in parallel -- one points to the flash area
* where the data is stored, and the other points to the RAM. We
* stop when the destination pointer reaches the end of the
* initialized segment (Base + Length). We pre-calculate this point
* and store it in a register for effeciency.
*/
stop_point = (dword *) ( (dword) Image__CODE__Base +
(dword) Image__CODE__Length);
for( src32 = (dword *) Load__CODE__Base,
dst32 = (dword *) Image__CODE__Base;
dst32 < stop_point;
src32++, dst32++ )
{
*dst32 = *src32;
}
/* kick watchdog at least every 426 ms. */
BOOTHW_KICK_WATCHDOG();
/* Zero out the zero-init data segment of the boot block
*
* This writes zeros into the RAM in the zero-init section of the
* boot block ram. This area starts at Image__CODE__ZI_Base and
* continues for Image__CODE__ZI_Length dwords.
*/
stop_point = (dword *) ( (dword) Image__CODE__ZI__Base +
(dword) Image__CODE__ZI__Length);
for( dst32=(dword *) Image__CODE__ZI__Base;
dst32 < stop_point;
dst32++ )
{
*dst32 = 0;
}
/* kick watchdog at least every 426 ms. */
BOOTHW_KICK_WATCHDOG();
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?