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 + -
显示快捷键?