void env_relocate_spec(void)
{
	DECLARE_GLOBAL_DATA_PTR;
	unsigned long env_addr;
	int use_default = 0;
	int retlen;

	env_addr = CFG_ENV_ADDR;
	env_addr -= (unsigned long)onenand_chip.base;

	/* Check OneNAND exist */
	if (onenand_mtd.oobblock)
		/* Ignore read fail */
		onenand_read(&onenand_mtd, env_addr, onenand_mtd.oobblock,
			     &retlen, (u_char *) env_ptr);
	else
		onenand_mtd.oobblock = MAX_ONENAND_PAGESIZE;

	if (crc32(0, env_ptr->data, ONENAND_ENV_SIZE(onenand_mtd)) !=
	    env_ptr->crc)
		use_default = 1;

	if (use_default) {
		memcpy(env_ptr->data, default_environment,
		       ONENAND_ENV_SIZE(onenand_mtd));
		env_ptr->crc =
		    crc32(0, env_ptr->data, ONENAND_ENV_SIZE(onenand_mtd));
	}

	gd->env_addr = (ulong) & env_ptr->data;
	gd->env_valid = 1;
}
Example #2
0
void env_relocate_spec(void)
{
    unsigned long env_addr;
    int use_default = 0;
    size_t retlen;

    env_addr = CFG_ENV_ADDR;

    /* Check OneNAND exist */
    if (onenand_mtd.writesize)
        /* Ignore read fail */
        onenand_read(&onenand_mtd, env_addr, onenand_mtd.writesize,
                     &retlen, (u_char *) env_ptr);
    else
        onenand_mtd.writesize = MAX_ONENAND_PAGESIZE;

    if (crc32(0, env_ptr->data, ONENAND_ENV_SIZE(onenand_mtd)) !=
            env_ptr->crc)
        use_default = 1;

    if (use_default) {
        memcpy(env_ptr->data, default_environment,
               ONENAND_ENV_SIZE(onenand_mtd));
        env_ptr->crc =
            crc32(0, env_ptr->data, ONENAND_ENV_SIZE(onenand_mtd));
    }

    gd->env_addr = (ulong) & env_ptr->data;
    gd->env_valid = 1;
}
Example #3
0
void env_relocate_spec_onenand(void)
{
	struct mtd_info *onenand;

	/* the following commands operate on the current device */
	if (onenand_curr_device < 0 ||
		onenand_curr_device >= CFG_MAX_ONENAND_DEVICE ||
		!onenand_info[onenand_curr_device].name) {
			puts("\nno devices available\n");
			return 1;
	}
		onenand = &onenand_info[onenand_curr_device];
#if !defined(ENV_IS_EMBEDDED)
	size_t total;
	int ret, i;
	u_char *data;

	data = (u_char*)malloc(CFG_ENV_SIZE);
	total = CFG_ENV_SIZE;
	for (i = 0; i < CFG_MAX_NAND_DEVICE; i++) {
		if (onenand_scan(&onenand_info[i], 1) == 0) {
			ret = onenand_read(onenand, CFG_ENV_OFFSET, &total, (u_char*)data);
			env_ptr = data;
			if (ret || total != CFG_ENV_SIZE)
				return use_default();
			if (crc32(0, env_ptr->data, ENV_SIZE) != env_ptr->crc)
				return use_default();
		} else {
			printf("no devices available\n");
			return use_default();
		}
	}
/*	
*/
#endif /* ! ENV_IS_EMBEDDED */
}
Example #4
0
int do_onenand(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
	int ret = 0;

	switch (argc) {
	case 0:
	case 1:
		printf("Usage:\n%s\n", cmdtp->usage);
		return 1;

	case 2:
		onenand_print_device_info(onenand_chip.device_id, 1);
		return 0;

	default:
		/* At least 4 args */
		if (strncmp(argv[1], "erase", 5) == 0) {
			struct erase_info instr;
			ulong start, end;
			char *endtail;
			ulong block;

			if (strncmp(argv[2], "block", 5) == 0) {
				start = simple_strtoul(argv[3], NULL, 10);
				endtail = strchr(argv[3], '-');
				end = simple_strtoul(endtail+1, NULL, 10);
			} else {
				start = simple_strtoul(argv[2], NULL, 10);
				end = simple_strtoul(argv[3], NULL, 10);
				start -= (unsigned long) onenand_chip.base;
				end -= (unsigned long) onenand_chip.base;
			}

			if (!end || end < 0)
				end = start;

			printf("Erase block from %d to %d\n", start, end);

			for (block = start; block <= end; block++) {
				instr.addr = block << onenand_chip.erase_shift;
				instr.len = 1 << onenand_chip.erase_shift;
				ret = onenand_erase(&onenand_mtd, &instr);
				if (ret) {
					printf("erase failed %d\n", block);
					break;
				}
			}

			return 0;
		}

		if (strncmp(argv[1], "read", 4) == 0) {
			ulong addr = simple_strtoul(argv[2], NULL, 16);
			ulong ofs  = simple_strtoul(argv[3], NULL, 16);
			size_t len = simple_strtoul(argv[4], NULL, 16);
			size_t retlen = 0;
			int oob = strncmp(argv[1], "read.oob", 8) ? 0 : 1;


			if (oob)
				onenand_read_oob(&onenand_mtd, ofs, len, &retlen, (u_char *) addr);
			else
				onenand_read(&onenand_mtd, ofs, len, &retlen, (u_char *) addr);
			printf("Done\n");

			return 0;
		}

		if (strncmp(argv[1], "write", 5) == 0) {
			int ret ;
			ulong addr = simple_strtoul(argv[2], NULL, 16);
			ulong ofs  = simple_strtoul(argv[3], NULL, 16);
			size_t len = simple_strtoul(argv[4], NULL, 16);
			size_t retlen = 0;

			printf("onenadwrite: addr = 0x%x, ofs = 0x%x, len = 0x%x\n", addr, ofs, len);
			ret = onenand_write(&onenand_mtd, ofs, len, &retlen, (u_char *) addr);
			if (ret)
				printf("Error writing oneNAND: ret = %d\n", ret);
			else
				printf("Done. ret = %d\n", ret);

			return 0;
		}

		if (strncmp(argv[1], "block", 5) == 0) {
			ulong addr = simple_strtoul(argv[2], NULL, 16);
			ulong block = simple_strtoul(argv[3], NULL, 10);
			ulong page = simple_strtoul(argv[4], NULL, 10);
			size_t len = simple_strtol(argv[5], NULL, 10);
			size_t retlen = 0;
			ulong ofs;
			int oob = strncmp(argv[1], "block.oob", 9) ? 0 : 1;

			ofs = block << onenand_chip.erase_shift;
			if (page)
				ofs += page << onenand_chip.page_shift;

			if (!len) {
				if (oob)
					len = 64;
				else
					len = 512;
			}

			if (oob)
				onenand_read_oob(&onenand_mtd, ofs, len, &retlen, (u_char *) addr);
			else
				onenand_read(&onenand_mtd, ofs, len, &retlen, (u_char *) addr);
			return 0;
		}

		if (strncmp(argv[1], "unlock", 6) == 0) {
			ulong start = simple_strtoul(argv[2], NULL, 10);
			ulong ofs = simple_strtoul(argv[3], NULL, 10);

			if (!ofs)
				ofs = (1 << onenand_chip.erase_shift);

			start = start << onenand_chip.erase_shift;
			printf("start = 0x%08x, ofs = 0x%08x\n",
				start, ofs);
			onenand_unlock(&onenand_mtd, start, start + ofs);
				
			return 0;
		}

		if (strncmp(argv[1], "save", 4) == 0 &&
		    strncmp(argv[2], "bootloader", 10) == 0) {
			ulong addr = simple_strtoul(argv[3], NULL, 16);
			struct erase_info instr;
			int ofs = 0;
			int len = 0x20000;
			size_t retlen;

			printf("save bootloader...\n");

			if (!addr)
				break;

			onenand_unlock(&onenand_mtd, ofs, len);

			instr.addr = 0 << onenand_chip.erase_shift;
			instr.len = 1 << onenand_chip.erase_shift;
			onenand_erase(&onenand_mtd, &instr);

			onenand_write(&onenand_mtd, ofs, len, &retlen, (u_char *) addr);
			onenand_unlock(&onenand_mtd, CFG_ENV_ADDR, onenand_mtd.size - CFG_ENV_ADDR);
			return 0;
		}

		break;
	}

	return 0;
}
Example #5
0
int saveenv_onenand(void)
{
        size_t total;
        int ret = 0, i;
        u32 erasebase;
        u32 eraselength;
        u32 eraseblock;
        u32 erasesize = onenand_info[0].erasesize;
        uint8_t *data;
		struct mtd_info *onenand;

        puts("Erasing Onenand...\n");
		
			/* the following commands operate on the current device */
		if (onenand_curr_device < 0 ||
				onenand_curr_device >= CFG_MAX_ONENAND_DEVICE ||
				!onenand_info[onenand_curr_device].name) {
			puts("\nno devices available\n");
			return 1;
		}
		onenand = &onenand_info[onenand_curr_device];
        /* If the value of CFG_ENV_OFFSET is not a NAND block boundary, the
         * NAND erase operation will fail. So first check if the CFG_ENV_OFFSET
         * is equal to a NAND block boundary
         */
        if ((CFG_ENV_OFFSET % (erasesize - 1)) != 0 ) {
                /* CFG_ENV_OFFSET is not equal to block boundary address. So, read
                 * the read the NAND block (in which ENV has to be stored), and
                 * copy the ENV data into the copied block data.
                 */

                /* Step 1: Find out the starting address of the NAND block to
                 * be erased. Also allocate memory whose size is equal to tbe
                 * NAND block size (NAND erasesize).
                 */
                eraseblock = CFG_ENV_OFFSET / erasesize;
                erasebase = eraseblock * erasesize;
				printf("the baseaddr is 0x%08x ...\n", erasebase);
                data = (uint8_t*)malloc(erasesize);
                if (data == NULL) {
                        printf("Could not save enviroment variables\n");
                        return 1;
                }

                /* Step 2: Read the NAND block into which the ENV data has
                 * to be copied
                 */
                total = erasesize;
				printf("the total is 0x%08x ...\n", total);
		for (i = 0; i < CFG_MAX_NAND_DEVICE; i++) {
			if (onenand_scan(&onenand_info[i], 1) == 0) {
				ret = onenand_read(onenand, erasebase, &total, data);
			} else {
				printf("no devices available\n");
				return 1;
			}
		}
                if (ret || total != erasesize) {
                        printf("Could not save enviroment variables %d\n",ret);
                        return 1;
                }
				
                /* Step 3: Copy the ENV data into the local copy of the block
                 * contents.
                 */
                memcpy((data + (CFG_ENV_OFFSET - erasebase)), (void*)env_ptr, CFG_ENV_SIZE);
        } else {
                /* CFG_ENV_OFFSET is equal to a NAND block boundary. So
                 * no special care is required when erasing and writing NAND
                 * block
                 */
                data = env_ptr;
                erasebase = CFG_ENV_OFFSET;
                erasesize = CFG_ENV_SIZE;
        }

        /* Erase the NAND block which will hold the ENV data */
        if (onenand_erase(onenand, erasebase, erasesize))
                return 1;

        puts("Writing to onenand... \n");
        total = erasesize;

        /* Write the ENV data to the NAND block */
		printf("the baseaddr is 0x%08x ...\n", erasebase);
		printf("the baseaddr is 0x%08x ...\n", total);
        ret = onenand_write(onenand, erasebase, &total, (u_char*)data);
        if (ret || total != erasesize) {
                printf("Could not save enviroment variables\n");
                return 1;
        }

         if ((CFG_ENV_OFFSET % (erasesize - 1)) != 0 )
                free(data);

        puts("Saved enviroment variables\n");
        return ret;
        return 1;
}