Пример #1
0
int
nand_spl_load_image(uint32_t offs, unsigned int size, void *dest)
{
    struct sunxi_nand * const nand = (struct sunxi_nand *)SUNXI_NFC_BASE;
    dma_addr_t dst_block;
    dma_addr_t dst_end;
    phys_addr_t addr = offs;

    dst_end = ((dma_addr_t) dest) + size;

    memset((void *)dest, 0x0, size);
    ecc_errors = 0;
    for (dst_block = (dma_addr_t) dest; dst_block < dst_end;
            dst_block += CONFIG_NAND_SUNXI_ECC_STEP,
            addr += CONFIG_NAND_SUNXI_ECC_STEP) {
        /* syndrome read first 4MiB to match Allwinner BootROM */
        nand_read_block(nand, addr, dst_block, addr < 0x400000);
    }

    if (ecc_errors)
        printf("Error: %d ECC failures detected\n", ecc_errors);
    return ecc_errors == 0;
}
Пример #2
0
void start_armboot (void)
{
  	init_fnc_t **init_fnc_ptr;
 	int i;
	uchar *buf;
	char boot_dev_name[8];
	u32 boot_device = 0;
 
   	for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
		if ((*init_fnc_ptr)() != 0) {
			hang ();
		}
	}
#ifdef START_LOADB_DOWNLOAD
	strcpy(boot_dev_name, "UART");
	do_load_serial_bin (CFG_LOADADDR, 115200);
#else
	/* Read boot device from saved scratch pad */
	boot_device = __raw_readl(0x480029c0) & 0xff;
	buf = (uchar*) CFG_LOADADDR;

	switch(boot_device) {
	case 0x03:
		strcpy(boot_dev_name, "ONENAND");
#if defined(CFG_ONENAND)
		for (i = ONENAND_START_BLOCK; i < ONENAND_END_BLOCK; i++) {
			if (!onenand_read_block(buf, i))
				buf += ONENAND_BLOCK_SIZE;
			else
				goto error;
		}
#endif
		break;
	case 0x02:
	default:
		strcpy(boot_dev_name, "NAND");
#if defined(CFG_NAND)
		for (i = NAND_UBOOT_START; i < NAND_UBOOT_END;
				i+= NAND_BLOCK_SIZE) {
			if (!nand_read_block(buf, i))
				buf += NAND_BLOCK_SIZE; /* advance buf ptr */
		}
#endif
		break;
	case 0x05:
		strcpy(boot_dev_name, "EMMC");
#if defined(CONFIG_MMC)
		if (mmc_read_bootloader(1, 0) != 0)
			goto error;
#else
		goto error;
#endif
		break;
	case 0x06:
		strcpy(boot_dev_name, "MMC/SD1");
#if defined(CONFIG_MMC) && defined(CFG_CMD_FAT)
		if (mmc_read_bootloader(0, 1) != 0)
			goto error;
#else
		goto error;
#endif
		break;
	};
#endif
	/* go run U-Boot and never return */
	printf("Starting OS Bootloader from %s ...\n", boot_dev_name);
 	((init_fnc_t *)CFG_LOADADDR)();

	/* should never come here */
#if defined(CFG_ONENAND) || defined(CONFIG_MMC)
error:
#endif
	printf("Could not read bootloader!\n");
	hang();
}
Пример #3
0
void start_armboot (void)
{
  	init_fnc_t **init_fnc_ptr;
 	int i;
	uchar *buf;

   	for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
		if ((*init_fnc_ptr)() != 0) {
			hang ();
		}
	}

	misc_init_r();
	buf =  (uchar*) CFG_LOADADDR;

	/* Always first try mmc without checking boot pins */
#ifndef CONFIG_OMAP3_BEAGLE
	if ((get_mem_type() == MMC_ONENAND) || (get_mem_type() == MMC_NAND))
#endif	/* CONFIG_OMAP3_BEAGLE */
		buf += mmc_boot(buf);

	if (buf == (uchar *)CFG_LOADADDR) {
		if (get_mem_type() == GPMC_NAND){
#ifdef CFG_PRINTF
			printf("Booting from nand . . .\n");
#endif
			for (i = NAND_UBOOT_START; i < NAND_UBOOT_END; i+= NAND_BLOCK_SIZE){
				if (!nand_read_block(buf, i))
					buf += NAND_BLOCK_SIZE; /* advance buf ptr */
			}
		}

		if (get_mem_type() == GPMC_ONENAND){
#ifdef CFG_PRINTF
			printf("Booting from onenand . . .\n");
#endif
			for (i = ONENAND_START_BLOCK; i < ONENAND_END_BLOCK; i++){
				if (!onenand_read_block(buf, i))
					buf += ONENAND_BLOCK_SIZE;
			}
		}
	}

#if defined (CONFIG_AM3517EVM)
	/*
	 * FIXME: Currently coping uboot image,
	 * ideally we should leverage XIP feature here
	 */
	if (get_mem_type() == GPMC_NOR) {
		int size;
		printf("Booting from NOR Flash...\n");
		size = nor_read_boot(buf);
		if (size > 0)
			buf += size;
	}
#endif

	if (buf == (uchar *)CFG_LOADADDR)
		hang();

	/* go run U-Boot and never return */
  	printf("Starting OS Bootloader...\n");
 	((init_fnc_t *)CFG_LOADADDR)();

	/* should never come here */
}
Пример #4
0
void start_armboot (void)
{
  	init_fnc_t **init_fnc_ptr;
	uchar *buf;
	char boot_dev_name[8];
	u32 si_type, omap4_rev;
	int len = 0;
	u8 val = SWITCH_OFF;
	image_type image;
 
   	for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
		if ((*init_fnc_ptr)() != 0) {
			hang ();
		}
	}

	image.image = 2;
        image.val =99;

	omap4_rev = omap_revision();
	if (omap4_rev >= OMAP4460_ES1_0) {
		omap_temp_sensor_check();
		if (omap4_rev == OMAP4470_ES1_0) {
			writel(((TSHUT_HIGH_ADC_CODE << 16) |
			TSHUT_COLD_ADC_CODE), CORE_TSHUT_THRESHOLD);
			MV1(WK(CONTROL_SPARE_RW) , (M1));
		}
		si_type = omap4_silicon_type();
		if (si_type == PROD_ID_1_SILICON_TYPE_HIGH_PERF)
			printf("OMAP4470: 1.5 GHz capable SOM\n");
		else if (si_type == PROD_ID_1_SILICON_TYPE_STD_PERF)
			printf("OMAP4470: 1.3 GHz capable SOM\n");
	}
#ifdef CONFIG_USBBOOT_ERASER
	/* Erase mlo and poweroff */
	mlo_erase();
#else

#ifdef CONFIG_USBBOOT
	/*usb boot does not check power button */
	printf("boot_device=0x%x boot_mode=0x%x\n", get_boot_device(), get_boot_mode());
	printf("id_code=%08x\n", readl(CONTROL_ID_CODE));
#endif

#ifdef CONFIG_USBOOT_MEMTEST
	/* the device will power off after the test */
	mem_test();
	/*power off  PMIC */
	printf("Memtest done, powering off!\n");
	select_bus(CFG_I2C_BUS, CFG_I2C_SPEED);
	val = SWITCH_OFF;
	i2c_write(TWL6030_PMC_ID, PHOENIX_DEV_ON, 1, &val, 1);
	/* we should never get here */
	hang();
#endif

#ifdef START_LOADB_DOWNLOAD
	strcpy(boot_dev_name, "UART");
	do_load_serial_bin (CFG_LOADADDR, 115200);
#else
	buf = (uchar *) (CFG_LOADADDR - 0x120);
	image.data = (uchar *) (CFG_LOADADDR - 0x120);

	switch (get_boot_device()) {
#ifdef CONFIG_USBBOOT
	case 0x45:
		printf("boot_dev=USB\n");
		strcpy(boot_dev_name, "USB");
		/* read data from usb and write to sdram */
		if (usb_read_bootloader(&len) != 0) {
			hang();
		}
		printf("usb read len=%d\n", len);
		break;
#else
	case 0x03:
		strcpy(boot_dev_name, "ONENAND");
#if defined(CFG_ONENAND)
		for (i = ONENAND_START_BLOCK; i < ONENAND_END_BLOCK; i++) {
			if (!onenand_read_block(buf, i))
				buf += ONENAND_BLOCK_SIZE;
			else
				goto error;
		}
#endif
		break;
	case 0x02:
	default:
		strcpy(boot_dev_name, "NAND");
#if defined(CFG_NAND)
		for (i = NAND_UBOOT_START; i < NAND_UBOOT_END;
				i+= NAND_BLOCK_SIZE) {
			if (!nand_read_block(buf, i))
				buf += NAND_BLOCK_SIZE; /* advance buf ptr */
		}
#endif
		break;
	case 0x05:
		strcpy(boot_dev_name, "MMC/SD1");
#if defined(CONFIG_MMC)
		if (mmc_read_bootloader(0) != 0)
			goto error;
#endif
		break;
	case 0x06:
		strcpy(boot_dev_name, "EMMC");
#if defined(CONFIG_MMC)
		if (mmc_read_bootloader(1) != 0)
			goto error;
#endif
		break;
#endif	/* CONFIG_USBBOOT */
	};
#endif
	SEC_ENTRY_Std_Ppa_Call ( PPA_SERV_HAL_BN_CHK , 1 , &image );
 
	if ( image.val == 0 ) {
		/* go run U-Boot and never return */
		printf("Starting OS Bootloader from %s ...\n", boot_dev_name);
		((init_fnc_t *)CFG_LOADADDR)();
	}

	/* should never come here */
#if defined(CFG_ONENAND) || defined(CONFIG_MMC)
error:
#endif
	printf("Could not read bootloader!\n");
	hang();
#endif   /* CONFIG_USBBOOT_ERASER */	
}
Пример #5
0
void start_armboot (void)
{
  	init_fnc_t **init_fnc_ptr;
	uchar *buf;
	char boot_dev_name[8];
	u32 si_type, omap4_rev;
 
   	for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
		if ((*init_fnc_ptr)() != 0) {
			hang ();
		}
	}

	omap4_rev = omap_revision();
	if (omap4_rev >= OMAP4460_ES1_0) {
		omap_temp_sensor_check();
		if (omap4_rev == OMAP4470_ES1_0) {
			writel(((TSHUT_HIGH_ADC_CODE << 16) |
			TSHUT_COLD_ADC_CODE), CORE_TSHUT_THRESHOLD);
			MV1(WK(CONTROL_SPARE_RW) , (M1));
		}
		si_type = omap4_silicon_type();
		if (si_type == PROD_ID_1_SILICON_TYPE_HIGH_PERF)
			printf("OMAP4460: 1.5 GHz capable SOM\n");
		else if (si_type == PROD_ID_1_SILICON_TYPE_STD_PERF)
			printf("OMAP4460: 1.2 GHz capable SOM\n");
	}
#ifdef START_LOADB_DOWNLOAD
	strcpy(boot_dev_name, "UART");
	do_load_serial_bin (CFG_LOADADDR, 115200);
#else
	buf = (uchar *) CFG_LOADADDR;

	switch (get_boot_device()) {
	case 0x03:
		strcpy(boot_dev_name, "ONENAND");
#if defined(CFG_ONENAND)
		for (i = ONENAND_START_BLOCK; i < ONENAND_END_BLOCK; i++) {
			if (!onenand_read_block(buf, i))
				buf += ONENAND_BLOCK_SIZE;
			else
				goto error;
		}
#endif
		break;
	case 0x02:
	default:
		strcpy(boot_dev_name, "NAND");
#if defined(CFG_NAND)
		for (i = NAND_UBOOT_START; i < NAND_UBOOT_END;
				i+= NAND_BLOCK_SIZE) {
			if (!nand_read_block(buf, i))
				buf += NAND_BLOCK_SIZE; /* advance buf ptr */
		}
#endif
		break;
	case 0x05:
		strcpy(boot_dev_name, "MMC/SD1");
#if defined(CONFIG_MMC)
		if (mmc_read_bootloader(0) != 0)
			goto error;
#endif
		break;
	case 0x06:
		strcpy(boot_dev_name, "EMMC");
#if defined(CONFIG_MMC)
		if (mmc_read_bootloader(1) != 0)
			goto error;
#endif
		break;
	};
#endif
	/* go run U-Boot and never return */
	printf("Starting OS Bootloader from %s ...\n", boot_dev_name);
 	((init_fnc_t *)CFG_LOADADDR)();

	/* should never come here */
#if defined(CFG_ONENAND) || defined(CONFIG_MMC)
error:
#endif
	printf("Could not read bootloader!\n");
	hang();
}
Пример #6
0
static void command_request(struct udc_ep *ep, struct udc_req *req)
{
	if (req->status)
		return;

	char *buf = (char *)req->buf;
	buf[req->actual] = '\0';

	char group[9], command[9];
	u32 n1, n2, n3, n4;
	int ret;

	ret = sscanf(buf, "%8s %8s %8x %8x %8x %8x", group, command, &n1, &n2, &n3, &n4);
	if (ret < 2)
		goto requeue;

	if (strcmp(group, "buffer") == 0) {
		if (strcmp(command, "read") == 0) {
			if (ret != 4)
				goto requeue;

			/* buffer offset */
			u32 offset = n1 & (BUFFER_SIZE - 1) & ~1;
			buffer_req.buf = (u16 *)(BUFFER_START + offset);

			/* read size */
			buffer_req.length = min(BUFFER_START - offset,
					n2 & ~1);

			ep->ops->queue(tx_ep, &buffer_req);
			return;
		} 
		if (strcmp(command, "write") == 0) {
			if (ret != 4)
				goto requeue;

			/* buffer offset */
			u32 offset = n1 & (BUFFER_SIZE - 1) & ~1;
			buffer_req.buf = (u16 *)(BUFFER_START + offset);

			/* write size */
			buffer_req.length = min(BUFFER_START - offset,
					n2 & ~1);

			ep->ops->queue(rx_ep, &buffer_req);
			return;
		}
		goto requeue;
	}

	if (strcmp(group, "nand") == 0) {
		if (strcmp(command, "select") == 0) {
			if (ret != 3)
				goto requeue;

			/* chip number */
			if (n1 >= NAND_MAX_CHIPS)
				goto requeue;

			nand_select_chip(n1);
			goto requeue;
		}
		if (strcmp(command, "info") == 0) {
			if (ret != 2)
				goto requeue;

			if (!nand_chip)
				goto requeue;

			req->buf = &nand_chip->info;
			req->length = sizeof(struct nand_info);
			req->complete = command_response;

			tx_ep->ops->queue(tx_ep, req);
			return;
		}
		if (strcmp(command, "bad") == 0) {
			if (ret != 2)
				goto requeue;

			if (!nand_chip)
				goto requeue;

			req->buf = nand_chip->bbt;
			req->length = nand_chip->num_blocks / 4;
			req->complete = command_response;

			tx_ep->ops->queue(tx_ep, req);
			return;
		}
		if (strcmp(command, "read") == 0) {
			if (ret != 4)
				goto requeue;

			if (!nand_chip)
				goto requeue;

			/* block number */
			if (n1 >= nand_chip->num_blocks)
				goto requeue;
			int block = n1;

			/* buffer offset */
			u32 offset = n2 & (BUFFER_SIZE - 1) & ~3;
			void *mem = (void *)(BUFFER_START + offset);
			
			nand_read_block(block, mem);
			goto requeue;
		}
		if (strcmp(command, "erase") == 0) {
			if (ret != 3)
				goto requeue;

			if (!nand_chip)
				goto requeue;

			/* block number */
			if (n1 >= nand_chip->num_blocks)
				goto requeue;
			int block = n1;

			((u16 *)req->buf)[0] = nand_erase_block(block);
			req->length = 2;
			req->complete = command_response;

			tx_ep->ops->queue(tx_ep, req);
			return;
		}
		if (strcmp(command, "write") == 0) {
			if (ret != 4)
				goto requeue;

			if (!nand_chip)
				goto requeue;

			/* block number */
			if (n1 >= nand_chip->num_blocks)
				goto requeue;
			int block = n1;

			/* buffer offset */
			u32 offset = n2 & (BUFFER_SIZE - 1) & ~3;
			void *mem = (void *)(BUFFER_START + offset);
			
			((u16 *)req->buf)[0] = nand_write_block(block, mem);
			req->length = 2;
			req->complete = command_response;

			tx_ep->ops->queue(tx_ep, req);
			return;
		}
		if (strcmp(command, "mark") == 0) {
			if (ret != 4)
				goto requeue;

			if (!nand_chip)
				goto requeue;

			/* block number */
			if (n1 >= nand_chip->num_blocks)
				goto requeue;
			int block = n1;

			/* mark */
			u8 mark = (u8)n2 & 0x3;

			int byte_num = block >> 2;
			int shift = (block & 0x3) * 2;

			nand_chip->bbt[byte_num] &= ~(0x3 << shift);
			nand_chip->bbt[byte_num] |= mark << shift;

			goto requeue;
		}
		goto requeue;
	}

requeue:
	ep->ops->queue(ep, req);
}