Exemple #1
0
void target_init(void)
{
	unsigned offset;
	struct flash_info *flash_info;
	int i;

	dprintf(INFO, "target_init()\n");

#if (!ENABLE_NANDWRITE)
	keys_init();
	keypad_init();
#endif

	if (target_is_emmc_boot())
		return;

	ptable_init(&flash_ptable);
	smem_ptable_init();

	flash_init();
	flash_info = flash_get_info();
	ASSERT(flash_info);

	offset = smem_get_apps_flash_start();
	if (offset == 0xffffffff)
	        while(1);

	for (i = 0; i < num_parts; i++) {
		struct ptentry *ptn = &board_part_list[i];
		unsigned len = ptn->length;

		if ((len == 0) && (i == num_parts - 1))
			len = flash_info->num_blocks - offset - ptn->start;
		ptable_add(&flash_ptable, ptn->name, offset + ptn->start,
			   len, ptn->flags);
	}

	ptable_dump(&flash_ptable);
	flash_set_ptable(&flash_ptable);
}
Exemple #2
0
void target_init(void)
{
	unsigned offset;
	struct flash_info *flash_info;
	struct ptentry *board_part_list;
	unsigned total_num_of_blocks;
	unsigned next_ptr_start_adr = 0;
	unsigned blocks_per_1MB = 8; /* Default value of 2k page size on 256MB flash drive*/
	int i;

	dprintf(INFO, "target_init()\n");

#if (!ENABLE_NANDWRITE)
	keys_init();
	keypad_init();
#endif

	/* Display splash screen if enabled */
#if DISPLAY_SPLASH_SCREEN
	display_init();
	dprintf(SPEW, "Diplay initialized\n");
	display_image_on_screen();
#endif

	if (target_is_emmc_boot())
	{
		/* Must wait for modem-up before we can intialize MMC.
		 */
		while (readl(MSM_SHARED_BASE + 0x14) != 1);

		if(mmc_boot_main(MMC_SLOT, MSM_SDC3_BASE))
		{
			dprintf(CRITICAL, "mmc init failed!");
			ASSERT(0);
		}
		return;
	}

	ptable_init(&flash_ptable);
	smem_ptable_init();

	flash_init();
	flash_info = flash_get_info();
	ASSERT(flash_info);

	offset = smem_get_apps_flash_start();
	if (offset == 0xffffffff)
			while(1);

	total_num_of_blocks = flash_info->num_blocks;
	blocks_per_1MB = (1 << 20) / (flash_info->block_size);

	if (flash_ecc_bch_enabled())
		board_part_list = board_part_list_bchecc;
	else
		board_part_list = board_part_list_default;

	for (i = 0; i < num_parts; i++) {
		struct ptentry *ptn = &board_part_list[i];
		unsigned len = ((ptn->length) * blocks_per_1MB);

		if(ptn->start != 0)
				ASSERT(ptn->start == DIFF_START_ADDR);

		ptn->start = next_ptr_start_adr;

		if(ptn->length == VARIABLE_LENGTH)
		{
			unsigned length_for_prt = 0;
			unsigned j;
			for (j = i+1; j < num_parts; j++)
			{
					struct ptentry *temp_ptn = &board_part_list[j];
					ASSERT(temp_ptn->length != VARIABLE_LENGTH);
					length_for_prt += ((temp_ptn->length) * blocks_per_1MB);
			}
				len = (total_num_of_blocks - 1) - (offset + ptn->start + length_for_prt);
			ASSERT(len >= 0);
		}
		next_ptr_start_adr = ptn->start + len;
		ptable_add(&flash_ptable, ptn->name, offset + ptn->start,
			   len, ptn->flags, TYPE_APPS_PARTITION, PERM_WRITEABLE);
	}

	smem_add_modem_partitions(&flash_ptable);

	ptable_dump(&flash_ptable);
	flash_set_ptable(&flash_ptable);
}
Exemple #3
0
void target_init(void)
{
#if defined(NAND_BOOT_INCLUDE)
	ASSERT(NAND_MTD_PARTITION_NUM == num_parts);
		
	unsigned	offset;	
	unsigned	total_num_of_blocks;
	unsigned	blocks_per_megabytes;
	unsigned	next_ptr_start_adr = 0;
	int		 	ret, i;

	struct 		flash_info *flash_info;
	bool  		start_addr_changed = false;
	
	unsigned long long			nMTDReserved_Num=0;			// total number of MTD Reserved Area
	TNFTL_MTDBadBlkInfo			MTDBadBlkInfo[num_parts];

	/////////////////////////////////////////////////////////////////////////////////////////////	
	unsigned long long	nROAreaSize, nPartitionSize = 0;
	unsigned long int	nBlockSize, nBlockSize_MB;
	unsigned int		nDevPBpV, nDevBBpZ, nDevBBpV, nRervRate;
	unsigned int		j, nUserDataArea = 0;
	struct ptable 		sPartition_List;
			

	memset( MTDBadBlkInfo, 0, sizeof(TNFTL_MTDBadBlkInfo) * num_parts );

	edi_init();
#endif
	dprintf(ALWAYS, "target_init()\n");

	keys_init();
	keypad_init();

#if defined(BOOTSD_INCLUDE)

	if (target_is_emmc_boot())
	{
		emmc_boot_main();
		return ;

	}
#endif

#if defined(NAND_BOOT_INCLUDE)
#if defined(TNFTL_V8_INCLUDE)
	if (check_fwdn_mode()) {
		fwdn_start();
		return;
	}

	flash_boot_main();

#else
	if ( ( flash_get_ptable() == NULL ) ) {

		ptable_init(&flash_ptable);
		
		flash_set_partnum( num_parts );
		flash_init();
		flash_info = flash_get_info();
		ASSERT(flash_info);

		if ( (flash_info->num_blocks) && (!flash_check_table()) ) 
		{

			memcpy( sPartition_List.parts, board_part_list, sizeof( struct ptentry ) * num_parts );

			flash_get_DevPBpV( &nDevPBpV, &nDevBBpZ, &nMTDReserved_Num );

			nROAreaSize		= (unsigned long long)( nMTDReserved_Num << 20 );		
			nBlockSize		= flash_info->page_size << flash_info->ShiftPpB;			// Set Block Size ( Byte Size ) 
			//nROAreaSize		=	flash_info->num_blocks * nBlockSize;					// Set Total ROArea Size ( Byte Size )
			nBlockSize_MB	=	nBlockSize / ( 1 << 20 );								
			if( nBlockSize_MB > 1 )					// If Block is over the 1MB. Block must aligned. 
			{										// ex) Block Size 2MB, If Partition Size is 3MB. Partition Block Number must be 2. not 1.
			
				if( nBlockSize_MB == 2 )			// If Block Size 2MB.
				{
					for( i = 0; i < num_parts; i++ )
					{
						if( sPartition_List.parts[i].length & 0x01 )
							sPartition_List.parts[i].length++;
					}
				}
				else if ( nBlockSize_MB == 4 )		// If Block Size 4MB 
				{
					unsigned int nDiff_Val;
						
					for( i = 0; i < num_parts; i++ )
					{
						nDiff_Val = sPartition_List.parts[i].length & 0x03;
						if( nDiff_Val )
							sPartition_List.parts[i].length += ( 4 - nDiff_Val );
					}
				}
				
			}			

			nMTDReserved_Num 	= 	( nMTDReserved_Num << 20 ) / nBlockSize;

			nDevBBpV			=	( nDevPBpV / 1024 ) * nDevBBpZ;
			nRervRate			=	( nMTDReserved_Num * 100 ) / nDevPBpV;
			nDevBBpV			=	( nDevBBpV * nRervRate ) / 100;

			if( nRervRate != 0 )
				nRervRate			= 	( 100 / nRervRate );

			nMTDReserved_Num	=	nRervRate + nDevBBpV;								// Setup ROArea Reserved Block 

			if(nMTDReserved_Num == 0) 
				nMTDReserved_Num = 2;
			else if ( nMTDReserved_Num & 0x01 )
				nMTDReserved_Num++;

			if( flash_info->ExtInterrupt == TRUE )
				nMTDReserved_Num = nMTDReserved_Num << 1;

			for( i = 0; i < num_parts; i++ )
			{
				if( sPartition_List.parts[i].length != VARIABLE_LENGTH )
				{
					sPartition_List.parts[i].length  = (unsigned long long)(sPartition_List.parts[i].length << 20); 	// Convert Length Unit. MByte -> Byte	
					nPartitionSize					+= sPartition_List.parts[i].length;

					//ND_TRACE("sPartition_List.parts[%d].length:%lld [nPartitionSize:%d]\n", i, sPartition_List.parts[i].length, nPartitionSize);
				}
				else
				{
					nUserDataArea	=	i;
				}
			}

			if( nUserDataArea != 0 )
			{
				sPartition_List.parts[nUserDataArea].length	= nROAreaSize - nPartitionSize;			// Calculate UserDataArea Size ( include Rerv Block )
				//ND_TRACE("sPartition_List.parts[5].length:%lld [nPartitionSize:%d]\n", i, sPartition_List.parts[5].length, nPartitionSize);
				//sPartition_List.parts[nUserDataArea].length	-= (nMTDReserved_Num * nBlockSize ); 	// UserDataArea Size. Reverved Block Removed
			}	

			i = 1;
			sPartition_List.parts[0].length		/= nBlockSize;									// Partition 0 Length ( Block Unit )
			MTDBadBlkInfo[0].PartBlkNum			 =	sPartition_List.parts[0].length;			// Set Block Number Each Partition
			
			do
			{
				sPartition_List.parts[i].length /= nBlockSize;									// Partition i Length ( Block Unit )
				sPartition_List.parts[i].start	 = sPartition_List.parts[i-1].start + sPartition_List.parts[i-1].length;

				MTDBadBlkInfo[i].PartBlkNum		 = sPartition_List.parts[i].length;				// Set Block Number Each Partition

				++i;
				
			} while( i < num_parts );

			flash_set_rervnum( nMTDReserved_Num );				// Set Reserved Block Number
			flash_set_badblkinfo( MTDBadBlkInfo );				// Set Bad Block Table Info. About Block Number Each Partition
			

			for( i = 0; i < num_parts; i++ )
			{
				ptable_add(&flash_ptable, sPartition_List.parts[i].name, flash_info->offset + sPartition_List.parts[i].start,
						   				  sPartition_List.parts[i].length, sPartition_List.parts[i].flags);
			}

			ND_TRACE("\n-------------- [ Partition Table ] --------------\n");		          
			for( i = 0; i < num_parts; i++ )
			{
			ND_TRACE(" [Part %2d.%9s] [Start:%4d] [Length:%4d]\n", i, sPartition_List.parts[i].name ,sPartition_List.parts[i].start + flash_info->offset, sPartition_List.parts[i].length );	
			}
			ND_TRACE("-------------------------------------------------\n");
			
			dprintf(INFO, "[NAND        ] [Maker:0x%02x ][Device:0x%02x][Page_size:%d]\n",
				flash_info->vendor, flash_info->device, flash_info->page_size);
			dprintf(INFO, "               [Spare_Size:%d][Block_Size:%d][MTD_TotalBlock:%d]\n",
				flash_info->spare_size, flash_info->block_size, flash_info->num_blocks);
			//dprintf(INFO, "               [Spare_Size:%d][Block_Size:%d][MTD_Block:%d][Rerv_Block:%d]\n",
			//	flash_info->spare_size, flash_info->block_size, flash_info->num_blocks - (U32)nMTDReserved_Num, (U32)nMTDReserved_Num);
		
			//ptable_dump(&flash_ptable);
			flash_set_ptable(&flash_ptable);

			ret = flash_set_badblktable();

			if( ret != SUCCESS )
			{
				dprintf(INFO, " !!! Fail Create Bad Block Table. [func:%s] [line:%d] !!! \n", __func__, __LINE__ );
				ASSERT(-1);
			}
			
			flash_set_tablestatus(TRUE);
			
		}
	}
#endif
#endif
}
Exemple #4
0
void target_init(void)
{
	unsigned offset;
	struct flash_info *flash_info;
	unsigned total_num_of_blocks;
	unsigned next_ptr_start_adr = 0;
	unsigned blocks_per_1MB = 8; /* Default value of 2k page size on 256MB flash drive*/
	unsigned base_addr;
	unsigned char slot;
	int i;

	dprintf(INFO, "target_init()\n");

#if (!ENABLE_NANDWRITE)
	keys_init();
	keypad_init();
#endif

	if (target_is_emmc_boot())
	{
		/* Trying Slot 2 first */
		slot = 2;
		base_addr = mmc_sdc_base[slot-1];
		if(mmc_boot_main(slot, base_addr))
		{
			/* Trying Slot 4 next */
			slot = 4;
			base_addr = mmc_sdc_base[slot-1];
			if(mmc_boot_main(slot, base_addr))
			{
				dprintf(CRITICAL, "mmc init failed!");
				ASSERT(0);
			}
		}
		return;
	}

	ptable_init(&flash_ptable);
	smem_ptable_init();

	flash_init();
	flash_info = flash_get_info();
	ASSERT(flash_info);
	enable_interleave_mode(target_is_interleaved_mode());

	offset = smem_get_apps_flash_start();
	if (offset == 0xffffffff)
	        while(1);

	total_num_of_blocks = flash_info->num_blocks;
	blocks_per_1MB = (1 << 20) / (flash_info->block_size);

	for (i = 0; i < num_parts; i++) {
		struct ptentry *ptn = &board_part_list[i];
		unsigned len = ((ptn->length) * blocks_per_1MB);

		if(ptn->start != 0)
		        ASSERT(ptn->start == DIFF_START_ADDR);

		ptn->start = next_ptr_start_adr;

		if(ptn->length == VARIABLE_LENGTH)
		{
			unsigned length_for_prt = 0;
			unsigned j;
			for (j = i+1; j < num_parts; j++)
			{
			        struct ptentry *temp_ptn = &board_part_list[j];
			        ASSERT(temp_ptn->length != VARIABLE_LENGTH);
			        length_for_prt += ((temp_ptn->length) * blocks_per_1MB);
			}
		        len = (total_num_of_blocks - 1) - (offset + ptn->start + length_for_prt);
			ASSERT(len >= 0);
		}
		next_ptr_start_adr = ptn->start + len;
		if(target_is_interleaved_mode()) {
		        ptable_add(&flash_ptable, ptn->name, offset + (ptn->start / 2),
				   (len / 2), ptn->flags, TYPE_APPS_PARTITION, PERM_WRITEABLE);
		}
		else {
		        ptable_add(&flash_ptable, ptn->name, offset + ptn->start,
				   len, ptn->flags, TYPE_APPS_PARTITION, PERM_WRITEABLE);
		}
	}

	smem_add_modem_partitions(&flash_ptable);

	ptable_dump(&flash_ptable);
	flash_set_ptable(&flash_ptable);
}
Exemple #5
0
void target_init(void)
{
	unsigned offset;
	struct flash_info *flash_info;
	unsigned total_num_of_blocks;
	bool  start_addr_changed = false;
	unsigned next_ptr_start_adr = 0;
	int i;

	dprintf(INFO, "target_init()\n");

#if (!ENABLE_NANDWRITE)
	keys_init();
	keypad_init();
#endif

	if (target_is_emmc_boot())
		return;

	ptable_init(&flash_ptable);
	smem_ptable_init();

	flash_init();
	flash_info = flash_get_info();
	ASSERT(flash_info);

	offset = smem_get_apps_flash_start();
	if (offset == 0xffffffff)
	        while(1);

	total_num_of_blocks = (flash_info->block_size)/NUM_PAGES_PER_BLOCK;

	for (i = 0; i < num_parts; i++) {
		struct ptentry *ptn = &board_part_list[i];
		unsigned len = ptn->length;

		if(len == VARIABLE_LENGTH)
		{
		        start_addr_changed = true;
			unsigned length_for_prt = 0;
			unsigned j;
			for (j = i+1; j < num_parts; j++)
			{
			        struct ptentry *temp_ptn = &board_part_list[j];
			        ASSERT(temp_ptn->length != VARIABLE_LENGTH);
			        length_for_prt += temp_ptn->length;
			}
		        len = (total_num_of_blocks - 1) - (offset + ptn->start + length_for_prt);
			ASSERT(len >= 0);
		        next_ptr_start_adr = ptn->start + len;
		}
		if((ptn->start == DIFF_START_ADDR) && (start_addr_changed))
		{
		        ASSERT(next_ptr_start_adr);
			ptn->start = next_ptr_start_adr;
			next_ptr_start_adr = ptn->start + ptn->length;
		}
		ptable_add(&flash_ptable, ptn->name, offset + ptn->start,
			   len, ptn->flags);
	}

	ptable_dump(&flash_ptable);
	flash_set_ptable(&flash_ptable);
}
void target_init(void)
{
	unsigned offset;
	struct flash_info *flash_info;
	unsigned total_num_of_blocks;
	unsigned next_ptr_start_adr = 0;
	unsigned blocks_per_1MB = 8; /* Default value of 2k page size on 256MB flash drive*/
	int i;

	dprintf(INFO, "target_init()\n");

#if (!ENABLE_NANDWRITE)
	keys_init();
	keypad_init();
#endif

	if (target_is_emmc_boot())
		return;

	ptable_init(&flash_ptable);
	smem_ptable_init();

	flash_init();
	flash_info = flash_get_info();
	ASSERT(flash_info);

	offset = smem_get_apps_flash_start();
	if (offset == 0xffffffff)
	        while(1);

	total_num_of_blocks = flash_info->num_blocks;
	blocks_per_1MB = (1 << 20) / (flash_info->block_size);

	for (i = 0; i < num_parts; i++) {
		struct ptentry *ptn = &board_part_list[i];
		unsigned len = ((ptn->length) * blocks_per_1MB);

		if(ptn->start != 0)
		        ASSERT(ptn->start == DIFF_START_ADDR);

		ptn->start = next_ptr_start_adr;

		if(ptn->length == VARIABLE_LENGTH)
		{
			unsigned length_for_prt = 0;
			unsigned j;
			for (j = i+1; j < num_parts; j++)
			{
			        struct ptentry *temp_ptn = &board_part_list[j];
			        ASSERT(temp_ptn->length != VARIABLE_LENGTH);
			        length_for_prt += ((temp_ptn->length) * blocks_per_1MB);
			}
		        len = (total_num_of_blocks - 1) - (offset + ptn->start + length_for_prt);
			ASSERT(len >= 0);
		}
		next_ptr_start_adr = ptn->start + len;
		ptable_add(&flash_ptable, ptn->name, offset + ptn->start,
			   len, ptn->flags, TYPE_APPS_PARTITION, PERM_WRITEABLE);
	}

	smem_add_modem_partitions(&flash_ptable);

	ptable_dump(&flash_ptable);
	flash_set_ptable(&flash_ptable);
}
Exemple #7
0
static void zybo_common_target_init(uint level)
{
    status_t err;

    /* zybo has a spiflash on qspi */
    spiflash_detect();

    bdev_t *spi = bio_open("spi0");
    if (spi) {
        /* find or create a partition table at the start of flash */
        if (ptable_scan(spi, 0) < 0) {
            ptable_create_default(spi, 0);
        }

        struct ptable_entry entry = { 0 };

        /* find and recover sysparams */
        if (ptable_find("sysparam", &entry) < 0) {
            /* didn't find sysparam partition, create it */
            ptable_add("sysparam", 0x1000, 0x1000, 0);
            ptable_find("sysparam", &entry);
        }

        if (entry.length > 0) {
            sysparam_scan(spi, entry.offset, entry.length);

#if SYSPARAM_ALLOW_WRITE
            /* for testing purposes, put at least one sysparam value in */
            if (sysparam_add("dummy", "value", sizeof("value")) >= 0) {
                sysparam_write();
            }
#endif

            sysparam_dump(true);
        }

        /* create bootloader partition if it does not exist */
        ptable_add("bootloader", 0x20000, 0x40000, 0);

        printf("flash partition table:\n");
        ptable_dump();
    }

    /* recover boot arguments */
    const char *cmdline = bootargs_get_command_line();
    if (cmdline) {
        printf("command line: '%s'\n", cmdline);
    }

    /* see if we came from a bootimage */
    uintptr_t bootimage_phys;
    size_t bootimage_size;
    if (bootargs_get_bootimage_pointer(&bootimage_phys, &bootimage_size) >= 0) {
        printf("our bootimage is at phys 0x%lx, size %zx\n", bootimage_phys, bootimage_size);

        void *ptr = paddr_to_kvaddr(bootimage_phys);
        if (ptr) {
            bootimage_t *bi;
            if (bootimage_open(ptr, bootimage_size, &bi) >= 0) {
                /* we have a valid bootimage, find the fpga section */
                const void *fpga_ptr;
                size_t fpga_len;

                if (bootimage_get_file_section(bi, TYPE_FPGA_IMAGE, &fpga_ptr, &fpga_len) >= 0) {
                    /* we have a fpga image */

                    /* lookup the physical address of the bitfile */
                    paddr_t pa = kvaddr_to_paddr((void *)fpga_ptr);
                    if (pa != 0) {
                        /* program the fpga with it*/
                        printf("loading fpga image at %p (phys 0x%lx), len %zx\n", fpga_ptr, pa, fpga_len);
                        zynq_reset_fpga();
                        err = zynq_program_fpga(pa, fpga_len);
                        if (err < 0) {
                            printf("error %d loading fpga\n", err);
                        }
                        printf("fpga image loaded\n");
                    }
                }
            }
        }
    }

#if WITH_LIB_MINIP
    /* pull some network stack related params out of the sysparam block */
    uint8_t mac_addr[6];
    uint32_t ip_addr = IPV4_NONE;
    uint32_t ip_mask = IPV4_NONE;
    uint32_t ip_gateway = IPV4_NONE;

    if (sysparam_read("net0.mac_addr", mac_addr, sizeof(mac_addr)) < (ssize_t)sizeof(mac_addr)) {
        /* couldn't find eth address, make up a random one */
        for (size_t i = 0; i < sizeof(mac_addr); i++) {
            mac_addr[i] = rand() & 0xff;
        }

        /* unicast and locally administered */
        mac_addr[0] &= ~(1<<0);
        mac_addr[0] |= (1<<1);
    }

    uint8_t use_dhcp = 0;
    sysparam_read("net0.use_dhcp", &use_dhcp, sizeof(use_dhcp));
    sysparam_read("net0.ip_addr", &ip_addr, sizeof(ip_addr));
    sysparam_read("net0.ip_mask", &ip_mask, sizeof(ip_mask));
    sysparam_read("net0.ip_gateway", &ip_gateway, sizeof(ip_gateway));

    minip_set_macaddr(mac_addr);
    gem_set_macaddr(mac_addr);

    if (!use_dhcp && ip_addr != IPV4_NONE) {
        minip_init(gem_send_raw_pkt, NULL, ip_addr, ip_mask, ip_gateway);
    } else {
        /* Configure IP stack and hook to the driver */
        minip_init_dhcp(gem_send_raw_pkt, NULL);
    }
    gem_set_callback(minip_rx_driver_callback);
#endif
}
Exemple #8
0
// return NULL for success, error string for failure
int lkb_handle_command(lkb_t *lkb, const char *cmd, const char *arg, size_t len, const char **result)
{
    *result = NULL;

    struct lkb_command *lcmd;
    for (lcmd = lkb_cmd_list; lcmd; lcmd = lcmd->next) {
        if (!strcmp(lcmd->name, cmd)) {
            *result = lcmd->handler(lkb, arg, len, lcmd->cookie);
            return 0;
        }
    }

    if (!strcmp(cmd, "flash") || !strcmp(cmd, "erase")) {
        struct ptable_entry entry;
        bdev_t *bdev;

        if (ptable_find(arg, &entry) < 0) {
            size_t plen = len;
            /* doesn't exist, make one */
            if (ptable_add(arg, plen, 0) < 0) {
                *result = "error creating partition";
                return -1;
            }

            if (ptable_find(arg, &entry) < 0) {
                *result = "couldn't find partition after creating it";
                return -1;
            }
        }
        if (len > entry.length) {
            *result = "partition too small";
            return -1;
        }

        if (!(bdev = ptable_get_device())) {
            *result = "ptable_get_device failed";
            return -1;
        }

        printf("lkboot: erasing partition of size %llu\n", entry.length);
        if (bio_erase(bdev, entry.offset, entry.length) != (ssize_t)entry.length) {
            *result = "bio_erase failed";
            return -1;
        }

        if (!strcmp(cmd, "flash")) {
            printf("lkboot: writing to partition\n");

            void *buf = malloc(bdev->block_size);
            if (!buf) {
                *result = "memory allocation failed";
                return -1;
            }

            size_t pos = 0;
            while (pos < len) {
                size_t toread = MIN(len - pos, bdev->block_size);

                LTRACEF("offset %zu, toread %zu\n", pos, toread);

                if (lkb_read(lkb, buf, toread)) {
                    *result = "io error";
                    free(buf);
                    return -1;
                }

                if (bio_write(bdev, buf, entry.offset + pos, toread) != (ssize_t)toread) {
                    *result = "bio_write failed";
                    free(buf);
                    return -1;
                }

                pos += toread;
            }

            free(buf);
        }
    } else if (!strcmp(cmd, "remove")) {
        if (ptable_remove(arg) < 0) {
            *result = "remove failed";
            return -1;
        }
    } else if (!strcmp(cmd, "fpga")) {
#if PLATFORM_ZYNQ
        void *buf = malloc(len);
        if (!buf) {
            *result = "error allocating buffer";
            return -1;
        }

        /* translate to physical address */
        paddr_t pa = vaddr_to_paddr(buf);
        if (pa == 0) {
            *result = "error allocating buffer";
            free(buf);
            return -1;

        }

        if (lkb_read(lkb, buf, len)) {
            *result = "io error";
            free(buf);
            return -1;
        }

        /* make sure the cache is flushed for this buffer for DMA coherency purposes */
        arch_clean_cache_range((vaddr_t)buf, len);

        /* program the fpga */
        zynq_reset_fpga();
        zynq_program_fpga(pa, len);

        free(buf);
#else
        *result = "no fpga";
        return -1;
#endif
    } else if (!strcmp(cmd, "boot")) {
        return do_boot(lkb, len, result);
    } else if (!strcmp(cmd, "getsysparam")) {
        const void *ptr;
        size_t len;
        if (sysparam_get_ptr(arg, &ptr, &len) == 0) {
            lkb_write(lkb, ptr, len);
        }
    } else if (!strcmp(cmd, "reboot")) {
        thread_resume(thread_create("reboot", &do_reboot, NULL,
            DEFAULT_PRIORITY, DEFAULT_STACK_SIZE));
    } else {
        *result = "unknown command";
        return -1;
    }

    return 0;
}
Exemple #9
0
void target_init(void)
{
	struct flash_info *flash_info;
	unsigned start_block;
	unsigned blocks_per_plen = 1; //blocks per partition length
	unsigned nand_num_blocks;

	keys_init();
	keypad_init();

	uint16_t keys[] = {KEY_VOLUMEUP, KEY_VOLUMEDOWN, KEY_SOFT1, KEY_SEND, KEY_CLEAR, KEY_BACK, KEY_HOME};
	for(unsigned i=0; i< sizeof(keys)/sizeof(uint16_t); i++)
	if (keys_get_state(keys[i]) != 0)
	{
		display_init();
		display_lk_version();
		//dprintf(ALWAYS,"key %d pressed\n", i);
		break;
	}
	dprintf(INFO, "htcleo_init\n");

	if(get_boot_reason()==2) // booting for offmode charging, start recovery so kernel will charge phone
	{
		boot_into_recovery = 1;
		//dprintf(INFO, "reboot needed... \n");
		//reboot(0);
	}
	dprintf(ALWAYS, "load address %x\n", load_address);

	dprintf(INFO, "flash init\n");
	flash_init();
	flash_info = flash_get_info();
	ASSERT(flash_info);
	ASSERT(flash_info->num_blocks);
	nand_num_blocks = flash_info->num_blocks;

	ptable_init(&flash_ptable);

	if( strcmp(board_part_list[0].name,"PTABLE-BLK")==0 ) blocks_per_plen =1 ;
	else if( strcmp(board_part_list[0].name,"PTABLE-MB")==0 ) blocks_per_plen = (1024*1024)/flash_info->block_size;
	else panic("Invalid partition table\n");

	start_block = HTCLEO_FLASH_OFFSET;
	for (unsigned i = 1; i < num_parts; i++)
	{
		struct ptentry *ptn = &board_part_list[i];
		if( IS_PART_EMPTY(ptn) ) break;
		int len = ((ptn->length) * blocks_per_plen);

		if( ptn->start == 0 ) ptn->start = start_block;
		else if( ptn->start < start_block) panic("Partition %s start %x < %x\n", ptn->name, ptn->start, start_block);

		if(ptn->length == 0)
		{
			unsigned length_for_prt = 0;
			if( i<num_parts && !IS_PART_EMPTY((&board_part_list[i+1])) && board_part_list[i+1].start!=0)
			{
				length_for_prt =  board_part_list[i+1].start - ptn->start;
			}
			else
			{
				for (unsigned j = i+1; j < num_parts; j++)
				{
						struct ptentry *temp_ptn = &board_part_list[j];
						if( IS_PART_EMPTY(temp_ptn) ) break;
						if( temp_ptn->length==0 ) panic("partition %s and %s have variable length\n", ptn->name, temp_ptn->name);
						length_for_prt += ((temp_ptn->length) * blocks_per_plen);
				}
			}
			len = (nand_num_blocks - 1 - 186 - 4) - (ptn->start + length_for_prt);
			ASSERT(len >= 0);
		}

		start_block = ptn->start + len;
		ptable_add(&flash_ptable, ptn->name, ptn->start, len, ptn->flags, TYPE_APPS_PARTITION, PERM_WRITEABLE);
	}

	htcleo_ptable_dump(&flash_ptable);
	flash_set_ptable(&flash_ptable);
}
Exemple #10
0
void target_init(void)
{

	ASSERT(NAND_MTD_PARTITION_NUM == num_parts);

		
	unsigned	offset;	
	unsigned	total_num_of_blocks;
	unsigned	blocks_per_megabytes;
	unsigned	next_ptr_start_adr = 0;
	int		 	ret, i;

	struct 		flash_info *flash_info;
	bool  		start_addr_changed = false;
	
	unsigned int				nMTDReserved_Num=0;			// total number of MTD Reserved Area
	TNFTL_MTDBadBlkInfo			MTDBadBlkInfo[num_parts];

	/////////////////////////////////////////////////////////////////////////////////////////////	
	unsigned int  		nROAreaSize, nPartitionSize = 0;
	unsigned int		nBlockSize, nBlockSize_MB;
	unsigned int		nDevPBpV, nDevBBpZ, nDevBBpV, nRervRate;
	unsigned int		j, nUserDataArea = 0;
	struct ptable 		sPartition_List;
			

	memset( MTDBadBlkInfo, 0, sizeof(TNFTL_MTDBadBlkInfo) * num_parts );
	dprintf(ALWAYS, "target_init()\n");
	
#if _EMMC_BOOT_TCC	
	PARTITION PartitionArr[50]; 	 
	unsigned int nPartitionCnt = 0; 
#endif		

#ifdef TRIFLASH_INCLUDE
		ioctl_diskinfo_t	disk_info;
#endif	


#if (!ENABLE_NANDWRITE)
#ifdef BOARD_TCC930X_STB_DEMO

#else
	keys_init();
	keypad_init();
#endif
#endif

	if (target_is_emmc_boot())
	{
#if _EMMC_BOOT_TCC	
		dprintf(INFO, "target_init() emmc_boot\n");
 
		ptable_init(&flash_ptable);

		//SDMMC init  //MCC
		DISK_Ioctl(DISK_DEVICE_TRIFLASH, DEV_INITIALIZE, NULL );

		//get flash info?   //MCC
		DISK_Ioctl(DISK_DEVICE_TRIFLASH, DEV_GET_DISKINFO, (void *)&disk_info);

		dprintf(INFO, "disk info: head: %d cylinder: %d sector : %d  sector size: %d Total_sectors: %d \n",disk_info.head,disk_info.cylinder,disk_info.sector,disk_info.sector_size,disk_info.Total_sectors);

		//ptabel init			//MCC
//		offset = flash_info->offset;	
		offset = 0;     //fixme

//		total_num_of_blocks = flash_info->num_blocks;
		total_num_of_blocks=10000000;    // fixme
																					 
		memset(&PartitionArr, 0, sizeof(PARTITION) * 50);												 
		nPartitionCnt = GetLocalPartition(0, PartitionArr); 											 
																								   
		for(i=0; i<nPartitionCnt; i++)																	 
			PrintPartitionInfo(&PartitionArr[i], i);		


		/* convert partition size to block unit */  //512byte ?
		blocks_per_megabytes = 1024*1024 / (disk_info.sector_size);		
		ASSERT(blocks_per_megabytes);
		
		for (i = 0; i < num_parts; i++) {
			struct ptentry *ptn = &board_part_list[i];
			if (ptn->length != VARIABLE_LENGTH)
				ptn->length *= blocks_per_megabytes;
		}
		
		for (i = 0; i < num_parts; i++) {
			struct ptentry *ptn = &board_part_list[i];
			unsigned len = ptn->length;
	
			if (ptn->start != DIFF_START_ADDR)
			{			
				if(i==2)
				{
					ptn->start = PartitionArr[1].start;
				}
				else
				{
					ptn->start *= blocks_per_megabytes;
				}
			}	
			
			if (len == VARIABLE_LENGTH) {
				start_addr_changed = true;
				unsigned length_for_prt = ptn->start;
				unsigned j;
				for (j = i+1; j < num_parts; j++)
				{
						struct ptentry *temp_ptn = &board_part_list[j];
						ASSERT(temp_ptn->length != VARIABLE_LENGTH);
						length_for_prt += temp_ptn->length;
				}
				len = total_num_of_blocks - length_for_prt;
				ASSERT(len >= 0);
				next_ptr_start_adr = ptn->start + len;
			}
			if((ptn->start == DIFF_START_ADDR) && (start_addr_changed)) {
				ASSERT(next_ptr_start_adr);
				ptn->start = next_ptr_start_adr;
				next_ptr_start_adr = ptn->start + ptn->length;
			}
			ptable_add(&flash_ptable, ptn->name, offset + ptn->start,
				   len, ptn->flags);
		}
		ptable_dump(&flash_ptable);
		flash_set_ptable(&flash_ptable);		
#endif
		return;
	}

	if (flash_get_ptable() == NULL) {

		ptable_init(&flash_ptable);
		
		flash_set_partnum( num_parts );
		flash_init();
		flash_info = flash_get_info();
		ASSERT(flash_info);

		if ( (flash_info->num_blocks) && (!flash_check_table()) ) 
		{
			

			memcpy( sPartition_List.parts, board_part_list, sizeof( struct ptentry ) * num_parts );

			nBlockSize		=	flash_info->page_size << flash_info->ShiftPpB;			// Set Block Size ( Byte Size ) 
			nROAreaSize		=	flash_info->num_blocks * nBlockSize;					// Set Total ROArea Size ( Byte Size )
			nBlockSize_MB	=	nBlockSize / ( 1 << 20 );								
			
			if( nBlockSize_MB > 1 )					// If Block is over the 1MB. Block must aligned. 
			{										// ex) Block Size 2MB, If Partition Size is 3MB. Partition Block Number must be 2. not 1.
			
				if( nBlockSize_MB == 2 )			// If Block Size 2MB.
				{
					for( i = 0; i < num_parts; i++ )
					{
						if( sPartition_List.parts[i].length & 0x01 )
							sPartition_List.parts[i].length++;
					}
				}
				else if ( nBlockSize_MB == 4 )		// If Block Size 4MB 
				{
					unsigned int nDiff_Val;
						
					for( i = 0; i < num_parts; i++ )
					{
						nDiff_Val = sPartition_List.parts[i].length & 0x03;
						if( nDiff_Val )
							sPartition_List.parts[i].length += ( 4 - nDiff_Val );
					}
				}
				
			}
				
			flash_get_DevPBpV( &nDevPBpV, &nDevBBpZ, &nMTDReserved_Num );

			nMTDReserved_Num 	= 	( nMTDReserved_Num << 20 ) / nBlockSize;

			nDevBBpV			=	( nDevPBpV / 1024 ) * nDevBBpZ;
			nRervRate			=	( nMTDReserved_Num * 100 ) / nDevPBpV;
			nDevBBpV			=	( nDevBBpV * nRervRate ) / 100;
			nRervRate			= 	( 100 / nRervRate );

			nMTDReserved_Num	=	nRervRate + nDevBBpV;								// Setup ROArea Reserved Block 

			if( nMTDReserved_Num & 0x01 )
				nMTDReserved_Num++;

			if( flash_info->ExtInterrupt == TRUE )
				nMTDReserved_Num = nMTDReserved_Num << 1;

			for( i = 0; i < num_parts; i++ )
			{
				if( sPartition_List.parts[i].length != VARIABLE_LENGTH )
				{
					sPartition_List.parts[i].length  = sPartition_List.parts[i].length << 20; 	// Convert Length Unit. MByte -> Byte	
					nPartitionSize					+= sPartition_List.parts[i].length;
				}
				else
				{
					nUserDataArea	=	i;
				}
			}
		
			sPartition_List.parts[nUserDataArea].length	= nROAreaSize - nPartitionSize;			// Calculate UserDataArea Size ( include Rerv Block )
			sPartition_List.parts[nUserDataArea].length	-= (nMTDReserved_Num * nBlockSize ); 	// UserDataArea Size. Reverved Block Removed

			i = 1;
			sPartition_List.parts[0].length		/= nBlockSize;									// Partition 0 Length ( Block Unit )
			MTDBadBlkInfo[0].PartBlkNum			 =	sPartition_List.parts[0].length;			// Set Block Number Each Partition
			
			do
			{
				sPartition_List.parts[i].length /= nBlockSize;									// Partition i Length ( Block Unit )
				sPartition_List.parts[i].start	 = sPartition_List.parts[i-1].start + sPartition_List.parts[i-1].length;

				MTDBadBlkInfo[i].PartBlkNum		 = sPartition_List.parts[i].length;				// Set Block Number Each Partition

				++i;
				
			} while( i < num_parts );

			flash_set_rervnum( nMTDReserved_Num );				// Set Reserved Block Number
			flash_set_badblkinfo( MTDBadBlkInfo );				// Set Bad Block Table Info. About Block Number Each Partition
			

			for( i = 0; i < num_parts; i++ )
			{
				ptable_add(&flash_ptable, sPartition_List.parts[i].name, flash_info->offset + sPartition_List.parts[i].start,
						   				  sPartition_List.parts[i].length, sPartition_List.parts[i].flags);
			}

			ND_TRACE("\n-------------- [ Partition Table ] --------------\n");		          
			for( i = 0; i < num_parts; i++ )
			{
			ND_TRACE(" [Part %2d.%9s] [Start:%4d] [Length:%4d]\n", i, sPartition_List.parts[i].name ,sPartition_List.parts[i].start + flash_info->offset, sPartition_List.parts[i].length );	
			}
			ND_TRACE("-------------------------------------------------\n");
			
			dprintf(INFO, "[NAND        ] [Maker:0x%02x ][Device:0x%02x][Page_size:%d]\n",
				flash_info->vendor, flash_info->device, flash_info->page_size);
			dprintf(INFO, "               [Spare_Size:%d][Block_Size:%d][MTD_Block:%d][Rerv_Block:%d]\n",
				flash_info->spare_size, flash_info->block_size, flash_info->num_blocks - (U32)nMTDReserved_Num, (U32)nMTDReserved_Num);
		
			//ptable_dump(&flash_ptable);
			flash_set_ptable(&flash_ptable);

			ret = flash_set_badblktable();

			if( ret != SUCCESS )
			{
				dprintf(INFO, " !!! Fail Create Bad Block Table. [func:%s] [line:%d] !!! \n", __func__, __LINE__ );
				ASSERT(-1);
			}
			
			flash_set_tablestatus(TRUE);
			
		}
	}

}
Exemple #11
0
// return NULL for success, error string for failure
const char *lkb_handle_command(lkb_t *lkb, const char *cmd, const char *arg, unsigned len) {
	struct lkb_command *lcmd;
	for (lcmd = lkb_cmd_list; lcmd; lcmd = lcmd->next) {
		if (!strcmp(lcmd->name, cmd)) {
			return lcmd->handler(lkb, arg, len, lcmd->cookie);
		}
	}

	if (len > lkb_iobuffer_size) {
		return "buffer too small";
	}
	if (!strcmp(cmd, "flash") || !strcmp(cmd, "erase")) {
		struct ptable_entry entry;
		bdev_t *bdev;

		if (ptable_find(arg, &entry) < 0) {
			size_t plen = len;
			/* doesn't exist, make one */
#if PLATFORM_ZYNQ
			/* XXX not really the right place, should be in the ptable/bio layer */
			plen = ROUNDUP(plen, 256*1024);
#endif
			off_t off = ptable_allocate(plen, 0);
			if (off < 0) {
				return "no space to allocate partition";
			}

			if (ptable_add(arg, off, plen, 0) < 0) {
				return "error creating partition";
			}

			if (ptable_find(arg, &entry) < 0) {
				return "couldn't find partition after creating it";
			}
		}
		if (len > entry.length) {
			return "partition too small";
		}
		if (lkb_read(lkb, lkb_iobuffer, len)) {
			return "io error";
		}
		if (!(bdev = bio_open(bootdevice))) {
			return "bio_open failed";
		}
		if (bio_erase(bdev, entry.offset, entry.length) != (ssize_t)entry.length) {
			bio_close(bdev);
			return "bio_erase failed";
		}
		if (!strcmp(cmd, "flash")) {
			if (bio_write(bdev, lkb_iobuffer, entry.offset, len) != (ssize_t)len) {
				bio_close(bdev);
				return "bio_write failed";
			}
		}
		bio_close(bdev);
		return NULL;
	} else if (!strcmp(cmd, "remove")) {
		if (ptable_remove(arg) < 0) {
			return "remove failed";
		}

		return NULL;
	} else if (!strcmp(cmd, "fpga")) {
#if PLATFORM_ZYNQ
		unsigned *x = lkb_iobuffer;
		if (lkb_read(lkb, lkb_iobuffer, len)) {
			return "io error";
		}
		for (unsigned n = 0; n < len; n+= 4) {
			*x = SWAP_32(*x);
			x++;
		}
		zynq_reset_fpga();
		zynq_program_fpga(lkb_iobuffer_phys, len);
		return NULL;
#else
		return "no fpga";
#endif
	} else if (!strcmp(cmd, "boot")) {
		if (lkb_read(lkb, lkb_iobuffer, len)) {
			return "io error";
		}
		thread_resume(thread_create("boot", &do_boot, NULL,
			DEFAULT_PRIORITY, DEFAULT_STACK_SIZE));
		return NULL;
	} else if (!strcmp(cmd, "getsysparam")) {
		const void *ptr;
		size_t len;
		if (sysparam_get_ptr(arg, &ptr, &len) == 0) {
			lkb_write(lkb, ptr, len);
		}
		return NULL;	
	} else if (!strcmp(cmd, "reboot")) {
		thread_resume(thread_create("reboot", &do_reboot, NULL,
			DEFAULT_PRIORITY, DEFAULT_STACK_SIZE));
		return NULL;
	} else {
		return "unknown command";
	}
}