Ejemplo n.º 1
0
/*
************************************************************************************************************
*
*                                             function
*
*    name          :
*
*    parmeters     :
*
*    return        :
*
*    note          :
*
*
************************************************************************************************************
*/
static void __oem_operation(char *operation)
{
	char response[68];
	char lock_info[64];
	int  lockflag;
	int  ret;

	memset(lock_info, 0, 64);
	memset(response, 0, 68);

	if(!strncmp(operation, "lock", 4))
	{
		lockflag = SUNXI_RELOCKING;
	}
	else if(!strncmp(operation, "unlock", 6))
	{
		lockflag = SUNXI_UNLOCK;
	}
	else
	{
		if(!strncmp(operation, "efex", 4))
		{
			strcpy(response, "OKAY");
			__sunxi_fastboot_send_status(response, strlen(response));

			sunxi_board_run_fel();
		}
		else
		{
			const char *info = "fastboot oem operation fail: unknown cmd";

			printf("%s\n", info);
			strcpy(response, "FAIL");
			strcat(response, info);

			__sunxi_fastboot_send_status(response, strlen(response));
		}

		return ;
	}

	ret = sunxi_oem_op_lock(lockflag, lock_info, 0);
	if(!ret)
	{
		strcpy(response, "OKAY");
	}
	else
	{
		strcpy(response, "FAIL");
	}
	strcat(response, lock_info);
	printf("%s\n", response);

	__sunxi_fastboot_send_status(response, strlen(response));

	return ;
}
Ejemplo n.º 2
0
/*
*******************************************************************************
*                     __erase_part
*
* Description:
*    void
*
* Parameters:
*    void
*
* Return value:
*    void
*
* note:
*    void
*
*******************************************************************************
*/
static int __erase_part(char *name)
{
	void *addr  = (void *)FASTBOOT_ERASE_BUFFER;
	u32   start, unerased_sectors;
	u32   nblock = FASTBOOT_ERASE_BUFFER_SIZE/512;
	char  response[68];

	start            = sunxi_partition_get_offset_byname(name);
	unerased_sectors = sunxi_partition_get_size_byname(name);

	if((!start) || (!unerased_sectors))
	{
		printf("sunxi fastboot erase FAIL: partition %s does not exist\n", name);
		sprintf(response, "FAILerase: partition %s does not exist", name);

		__sunxi_fastboot_send_status(response, strlen(response));

		return -1;
	}

	memset(addr, 0xff, FASTBOOT_ERASE_BUFFER_SIZE);
	while(unerased_sectors >= nblock)
	{
		if(!sunxi_flash_write(start, nblock, addr))
		{
			printf("sunxi fastboot erase FAIL: failed to erase partition %s \n", name);
			sprintf(response,"FAILerase: failed to erase partition %s", name);

			__sunxi_fastboot_send_status(response, strlen(response));

			return -1;
		}
		start += nblock;
		unerased_sectors -= nblock;
	}
	if(unerased_sectors)
	{
		if(!sunxi_flash_write(start, unerased_sectors, addr))
		{
			printf("sunxi fastboot erase FAIL: failed to erase partition %s \n", name);
			sprintf(response,"FAILerase: failed to erase partition %s", name);

			__sunxi_fastboot_send_status(response, strlen(response));

			return -1;
		}
	}

	printf("sunxi fastboot: partition '%s' erased\n", name);
	sprintf(response, "OKAY");

	__sunxi_fastboot_send_status(response, strlen(response));

	return 0;
}
Ejemplo n.º 3
0
/*
*******************************************************************************
*                     __flash_to_part
*
* Description:
*    void
*
* Parameters:
*    void
*
* Return value:
*    void
*
* note:
*    void
*
*******************************************************************************
*/
static void __flash_to_uboot(void)
{
	struct spare_boot_head_t * temp_buf = (struct spare_boot_head_t *)trans_data.base_recv_buffer;
	char  response[68];
	u32 uboot_length = 0;
	u32 align_size = 0;
	u32 old_uboot_length = 0;
	u32 old_total_length = 0;

	if(strcmp((char*)temp_buf->boot_head.magic,"uboot"))
	{
		printf("sunxi fastboot error: there is not uboot file\n");
		sprintf(response, "FAILdownload:there is not uboot file \n");
		__sunxi_fastboot_send_status(response, strlen(response));
		return ;
	}
	printf("ready to download bytes 0x%x\n", trans_data.try_to_recv);
	if(temp_buf->boot_head.uboot_length == 0)
	{
		printf("==== uboot.bin ====\n");
		memcpy((char *)temp_buf , (char *)CONFIG_SYS_TEXT_BASE ,sizeof(struct spare_boot_head_t));
		old_uboot_length = temp_buf->boot_head.uboot_length;
		old_total_length = temp_buf->boot_head.length ;
		debug("old_uboot_length = %x \n",old_uboot_length);
		debug("old_total_length = %x \n",old_total_length);
		//align uboot
		align_size = temp_buf->boot_head.align_size;
		printf("align_size is 0x%x \n",align_size);

		uboot_length = (trans_data.try_to_recv + align_size) & (~(align_size - 1));
		temp_buf->boot_head.uboot_length = uboot_length;
		//copy sys_config from old uboot
		memcpy((char *)temp_buf + uboot_length , (char *)CONFIG_SYS_TEXT_BASE + old_uboot_length,old_total_length - old_uboot_length);
		//make check_sum again
		temp_buf->boot_head.check_sum = STAMP_VALUE;
		temp_buf->boot_head.length     = uboot_length +old_total_length - old_uboot_length;
		temp_buf->boot_head.check_sum = add_sum((char *)temp_buf,temp_buf->boot_head.length);
	}
	printf("uboot checksum is 0x%x \n",temp_buf->boot_head.check_sum);
	printf("download uboot ing ....\n");
	sunxi_sprite_download_uboot((char *)temp_buf,uboot_spare_head.boot_data.storage_type ,1);
	printf("sunxi fastboot: successed in downloading uboot \n");
	sprintf(response, "OKAY");
	__sunxi_fastboot_send_status(response, strlen(response));

	return ;
}
Ejemplo n.º 4
0
/*
************************************************************************************************************
*
*                                             function
*
*    name          :
*
*    parmeters     :
*
*    return        :
*
*    note          :
*
*
************************************************************************************************************
*/
static void __unsupported_cmd(void)
{
	char response[32];

	memset(response, 0, 32);
	strcpy(response,"FAIL");

	__sunxi_fastboot_send_status(response, strlen(response));

	return;
}
Ejemplo n.º 5
0
/*
*******************************************************************************
*                     __fastboot_reboot
*
* Description:
*    void
*
* Parameters:
*    void
*
* Return value:
*    void
*
* note:
*    void
*
*******************************************************************************
*/
static int __fastboot_reboot(int word_mode)
{
	char response[8];

	sprintf(response,"OKAY");
	__sunxi_fastboot_send_status(response, strlen(response));
	__msdelay(1000); /* 1 sec */

	sunxi_board_restart(word_mode);

	return 0;
}
Ejemplo n.º 6
0
/*
************************************************************************************************************
*
*                                             function
*
*    name          :
*
*    parmeters     :
*
*    return        :
*
*    note          :
*
*
************************************************************************************************************
*/
static void __limited_fastboot(void)
{
	char response[64];

	memset(response, 0, 64);
	tick_printf("secure mode,fastboot limited used\n");

	strcpy(response,"FAIL:secure mode,fastboot limited used");

	__sunxi_fastboot_send_status(response, strlen(response));

	return;
}
Ejemplo n.º 7
0
/*
*******************************************************************************
*                     __get_var
*
* Description:
*    void
*
* Parameters:
*    void
*
* Return value:
*    void
*
* note:
*    void
*
*******************************************************************************
*/
static void __get_var(char *ver_name)
{
	char response[68];

	memset(response, 0, 68);
	strcpy(response,"OKAY");

	if(!strcmp(ver_name, "version"))
	{
		strcpy(response + 4, FASTBOOT_VERSION);
	}
	else if(!strcmp(ver_name, "product"))
	{
		strcpy(response + 4, SUNXI_FASTBOOT_DEVICE_PRODUCT);
	}
	else if(!strcmp(ver_name, "serialno"))
	{
		strcpy(response + 4, SUNXI_FASTBOOT_DEVICE_SERIAL_NUMBER);
	}
	else if(!strcmp(ver_name, "downloadsize"))
	{
		sprintf(response + 4, "0x%08x", SUNXI_USB_FASTBOOT_BUFFER_MAX);
		printf("response: %s\n", response);
	}
	else if(!strcmp(ver_name, "secure"))
	{
		strcpy(response + 4, "yes");
	}
	else if(!strcmp(ver_name, "max-download-size"))
	{
		sprintf(response + 4, "0x%08x", SUNXI_USB_FASTBOOT_BUFFER_MAX);
		printf("response: %s\n", response);
	}
	else
	{
		strcpy(response + 4, "not supported");
	}

	__sunxi_fastboot_send_status(response, strlen(response));

	return ;
}
Ejemplo n.º 8
0
/*
************************************************************************************************************
*
*                                             function
*
*    name          :
*
*    parmeters     :
*
*    return        :
*
*    note          :
*
*
************************************************************************************************************
*/
static void __continue(void)
{
	char response[32];

	memset(response, 0, 32);
	strcpy(response,"OKAY");

	__sunxi_fastboot_send_status(response, strlen(response));

	sunxi_usb_exit();

	if(uboot_spare_head.boot_data.storage_type)
	{
		setenv("bootcmd", "run setargs_mmc boot_normal");
	}
	else
	{
		setenv("bootcmd", "run setargs_nand boot_normal");
	}
	do_bootd(NULL, 0, 1, NULL);

	return;
}
Ejemplo n.º 9
0
/*
*******************************************************************************
*                     __flash_to_part
*
* Description:
*    void
*
* Parameters:
*    void
*
* Return value:
*    void
*
* note:
*    void
*
*******************************************************************************
*/
static int __flash_to_part(char *name)
{
	char *addr = trans_data.base_recv_buffer;
	u32   start, data_sectors;
	u32   part_sectors;
	u32   nblock = FASTBOOT_TRANSFER_BUFFER_SIZE/512;
	char  response[68];

	start        = sunxi_partition_get_offset_byname(name);
	part_sectors = sunxi_partition_get_size_byname(name);

	if((!start) || (!part_sectors))
	{
		uint  addr_in_hex;
		int   ret;

		printf("sunxi fastboot download FAIL: partition %s does not exist\n", name);
		printf("probe it as a dram address\n");

		ret = strict_strtoul((const char *)name, 16, (long unsigned int*)&addr_in_hex);
		if(ret)
		{
			printf("sunxi fatboot download FAIL: it is not a dram address\n");

			sprintf(response, "FAILdownload: partition %s does not exist", name);
			__sunxi_fastboot_send_status(response, strlen(response));

			return -1;
		}
		else
		{
			printf("ready to move data to 0x%x, bytes 0x%x\n", addr_in_hex, trans_data.try_to_recv);
			memcpy((void *)addr_in_hex, addr, trans_data.try_to_recv);
		}
	}
	else
	{
		int  format;

		printf("ready to download bytes 0x%x\n", trans_data.try_to_recv);
		format = unsparse_probe(addr, trans_data.try_to_recv, start);

		if(ANDROID_FORMAT_DETECT == format)
		{
			if(unsparse_direct_write(addr, trans_data.try_to_recv))
			{
				printf("sunxi fastboot download FAIL: failed to write partition %s \n", name);
				sprintf(response,"FAILdownload: write partition %s err", name);

				return -1;
			}
		}
		else
		{
		    data_sectors = (trans_data.try_to_recv + 511)/512;
		    if(data_sectors > part_sectors)
		    {
		    	printf("sunxi fastboot download FAIL: partition %s size 0x%x is smaller than data size 0x%x\n", name, trans_data.act_recv, data_sectors * 512);
				sprintf(response, "FAILdownload: partition size < data size");

				__sunxi_fastboot_send_status(response, strlen(response));

				return -1;
		    }
			while(data_sectors >= nblock)
			{
				if(!sunxi_flash_write(start, nblock, addr))
				{
					printf("sunxi fastboot download FAIL: failed to write partition %s \n", name);
					sprintf(response,"FAILdownload: write partition %s err", name);

					__sunxi_fastboot_send_status(response, strlen(response));

					return -1;
				}
				start += nblock;
				data_sectors -= nblock;
				addr  += FASTBOOT_TRANSFER_BUFFER_SIZE;
			}
			if(data_sectors)
			{
				if(!sunxi_flash_write(start, data_sectors, addr))
				{
					printf("sunxi fastboot download FAIL: failed to write partition %s \n", name);
					sprintf(response,"FAILdownload: write partition %s err", name);

					__sunxi_fastboot_send_status(response, strlen(response));

					return -1;
				}
			}
		}
	}

	printf("sunxi fastboot: successed in downloading partition '%s'\n", name);
	sprintf(response, "OKAY");

	__sunxi_fastboot_send_status(response, strlen(response));

	return 0;
}
Ejemplo n.º 10
0
/*
************************************************************************************************************
*
*                                             function
*
*    name          :
*
*    parmeters     :
*
*    return        :
*
*    note          :
*
*
************************************************************************************************************
*/
static int sunxi_fastboot_state_loop(void  *buffer)
{
	int ret;
	sunxi_ubuf_t *sunxi_ubuf = (sunxi_ubuf_t *)buffer;
	char  response[68];

	switch(sunxi_usb_fastboot_status)
	{
		case SUNXI_USB_FASTBOOT_IDLE:
			if(sunxi_ubuf->rx_ready_for_data == 1)
			{
				sunxi_usb_fastboot_status = SUNXI_USB_FASTBOOT_SETUP;
			}

			break;

		case SUNXI_USB_FASTBOOT_SETUP:

			tick_printf("SUNXI_USB_FASTBOOT_SETUP\n");

			tick_printf("fastboot command = %s\n", sunxi_ubuf->rx_req_buffer);

			sunxi_usb_fastboot_status = SUNXI_USB_FASTBOOT_IDLE;
			sunxi_ubuf->rx_ready_for_data = 0;
			if(memcmp(sunxi_ubuf->rx_req_buffer, "reboot-bootloader", strlen("reboot-bootloader")) == 0)
			{
				tick_printf("reboot-bootloader\n");
				__fastboot_reboot(PMU_PRE_FASTBOOT_MODE);
			}
            else if(memcmp(sunxi_ubuf->rx_req_buffer, "reboot", 6) == 0)
			{
				tick_printf("reboot\n");
				__fastboot_reboot(0);
			}
			else if(memcmp(sunxi_ubuf->rx_req_buffer, "erase:", 6) == 0)
			{
				tick_printf("erase\n");
				__erase_part((char *)(sunxi_ubuf->rx_req_buffer + 6));
			}
			else if(memcmp(sunxi_ubuf->rx_req_buffer, "flash:", 6) == 0)
			{
				tick_printf("flash\n");
				__flash_to_part((char *)(sunxi_ubuf->rx_req_buffer + 6));
			}
			else if(memcmp(sunxi_ubuf->rx_req_buffer, "download:", 9) == 0)
			{
				tick_printf("download\n");
				ret = __try_to_download((char *)(sunxi_ubuf->rx_req_buffer + 9), response);
				if(ret >= 0)
				{
					fastboot_data_flag = 1;
					sunxi_ubuf->rx_req_buffer  = (uchar *)trans_data.base_recv_buffer;
					sunxi_usb_fastboot_status  = SUNXI_USB_FASTBOOT_RECEIVE_DATA;
				}
				__sunxi_fastboot_send_status(response, strlen(response));
			}
			else if(memcmp(sunxi_ubuf->rx_req_buffer, "boot", 4) == 0)
			{
				tick_printf("boot\n");
				__boot();
			}
			else if(memcmp(sunxi_ubuf->rx_req_buffer, "getvar:", 7) == 0)
			{
				tick_printf("getvar\n");
				__get_var((char *)(sunxi_ubuf->rx_req_buffer + 7));
			}
			else if(memcmp(sunxi_ubuf->rx_req_buffer, "oem", 3) == 0)
			{
				tick_printf("oem operations\n");
				__oem_operation((char *)(sunxi_ubuf->rx_req_buffer + 4));
			}
			else if(memcmp(sunxi_ubuf->rx_req_buffer, "continue", 8) == 0)
			{
				tick_printf("continue\n");
				__continue();
			}
			else
			{
				tick_printf("not supported fastboot cmd\n");
				__unsupported_cmd();
			}

			break;

	  	case SUNXI_USB_FASTBOOT_SEND_DATA:

	  		tick_printf("SUNXI_USB_FASTBOOT_SEND_DATA\n");

	  		break;

	  	case SUNXI_USB_FASTBOOT_RECEIVE_DATA:

	  		//tick_printf("SUNXI_USB_FASTBOOT_RECEIVE_DATA\n");
	  		if((fastboot_data_flag == 1) && ((char *)sunxi_ubuf->rx_req_buffer == all_download_bytes + trans_data.base_recv_buffer))	//传输完毕
	  		{
	  			tick_printf("fastboot transfer finish\n");
	  			fastboot_data_flag = 0;
	  			sunxi_usb_fastboot_status  = SUNXI_USB_FASTBOOT_IDLE;

		  		sunxi_ubuf->rx_req_buffer = sunxi_ubuf->rx_base_buffer;

		  		sprintf(response,"OKAY");
		  		__sunxi_fastboot_send_status(response, strlen(response));
			}

	  		break;

	  	default:
	  		break;
	}

	return 0;
}