예제 #1
0
파일: flash.c 프로젝트: 0s4l/u-boot-xlnx
/*-----------------------------------------------------------------------
 * Set protection status for monitor sectors
 *
 * The monitor is always located in the _first_ Flash bank.
 * If necessary you have to map the second bank at lower addresses.
 */
void
flash_protect (int flag, ulong from, ulong to, flash_info_t *info)
{
	ulong b_end;
	short s_end;
	int i;

	/* Do nothing if input data is bad. */
	if (!info || info->sector_count == 0 || info->size == 0 || to < from) {
		return;
	}

	s_end = info->sector_count - 1;	/* index of last sector */
	b_end = info->start[0] + info->size - 1;	/* bank end address */

	debug ("flash_protect %s: from 0x%08lX to 0x%08lX\n",
		(flag & FLAG_PROTECT_SET) ? "ON" :
			(flag & FLAG_PROTECT_CLEAR) ? "OFF" : "???",
		from, to);

	/* There is nothing to do if we have no data about the flash
	 * or the protect range and flash range don't overlap.
	 */
	if (info->flash_id == FLASH_UNKNOWN ||
	    to < info->start[0] || from > b_end) {
		return;
	}

	for (i=0; i<info->sector_count; ++i) {
		ulong end;		/* last address in current sect	*/

		end = (i == s_end) ? b_end : info->start[i + 1] - 1;

		/* Update protection if any part of the sector
		 * is in the specified range.
		 */
		if (from <= end && to >= info->start[i]) {
			if (flag & FLAG_PROTECT_CLEAR) {
#if defined(CONFIG_SYS_FLASH_PROTECTION)
				flash_real_protect(info, i, 0);
#else
				info->protect[i] = 0;
#endif	/* CONFIG_SYS_FLASH_PROTECTION */
				debug ("protect off %d\n", i);
			}
			else if (flag & FLAG_PROTECT_SET) {
#if defined(CONFIG_SYS_FLASH_PROTECTION)
				flash_real_protect(info, i, 1);
#else
				info->protect[i] = 1;
#endif	/* CONFIG_SYS_FLASH_PROTECTION */
				debug ("protect on %d\n", i);
			}
		}
	}
}
예제 #2
0
/*-----------------------------------------------------------------------
 */
int flash_real_protect(flash_info_t * info, long sector, int prot)
{
	int retcode = 0;

	flash_write_cmd(info, sector, 0, FLASH_CMD_CLEAR_STATUS);
	flash_write_cmd(info, sector, 0, FLASH_CMD_PROTECT);
	if (prot)
		flash_write_cmd(info, sector, 0, FLASH_CMD_PROTECT_SET);
	else
		flash_write_cmd(info, sector, 0, FLASH_CMD_PROTECT_CLEAR);

	if ((retcode =
	     flash_full_status_check(info, sector, info->erase_blk_tout,
				     prot ? "protect" : "unprotect")) == 0) {

		info->protect[sector] = prot;
		/* Intel's unprotect unprotects all locking */
		if (prot == 0) {
			int i;
			for (i = 0; i < info->sector_count; i++) {
				if (info->protect[i])
					flash_real_protect(info, i, 1);
			}
		}
	}

	return retcode;
}
예제 #3
0
/*-----------------------------------------------------------------------
 */
unsigned long flash_init(void)
{
	unsigned long size;
	int i;
	unsigned long address;

	/* The flash is positioned back to back, with the demultiplexing of the chip
	 * based on the A24 address line.
	 *
	 */

	address = CONFIG_SYS_FLASH_BASE;
	size = 0;

	/* Init: no FLASHes known */
	for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; ++i) {
		flash_info[i].flash_id = FLASH_UNKNOWN;
		size += flash_info[i].size = flash_get_size(address, i);
		address += CONFIG_SYS_FLASH_INCREMENT;
		if (flash_info[i].flash_id == FLASH_UNKNOWN) {
			printf
			    ("## Unknown FLASH on Bank %d - Size = 0x%08lx = %ld MB\n",
			     i, flash_info[0].size, flash_info[i].size << 20);
		}
	}

#if 0				/* test-only */
	/* Monitor protection ON by default */
#if (CONFIG_SYS_MONITOR_BASE >= CONFIG_SYS_FLASH_BASE)
	for (i = 0;
	     flash_info[0].start[i] < CONFIG_SYS_MONITOR_BASE + monitor_flash_len - 1;
	     i++)
		(void)flash_real_protect(&flash_info[0], i, 1);
#endif
#endif

	return (size);
}
예제 #4
0
int do_protect (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
#ifndef CONFIG_SYS_NO_FLASH
	flash_info_t *info;
	ulong bank;
	int i, n, sect_first, sect_last;
#endif /* CONFIG_SYS_NO_FLASH */
#if !defined(CONFIG_SYS_NO_FLASH) || defined(CONFIG_HAS_DATAFLASH)
	ulong addr_first, addr_last;
#endif
#if defined(CONFIG_CMD_JFFS2) && defined(CONFIG_CMD_MTDPARTS)
	struct mtd_device *dev;
	struct part_info *part;
	u8 dev_type, dev_num, pnum;
#endif
#ifdef CONFIG_HAS_DATAFLASH
	int status;
#endif
	int p;
	int rcode = 0;

	if (argc < 3) {
		cmd_usage(cmdtp);
		return 1;
	}

	if (strcmp(argv[1], "off") == 0) {
		p = 0;
	} else if (strcmp(argv[1], "on") == 0) {
		p = 1;
	} else {
		cmd_usage(cmdtp);
		return 1;
	}

#ifdef CONFIG_HAS_DATAFLASH
	if ((strcmp(argv[2], "all") != 0) && (strcmp(argv[2], "bank") != 0)) {
		addr_first = simple_strtoul(argv[2], NULL, 16);
		addr_last  = simple_strtoul(argv[3], NULL, 16);

		if (addr_dataflash(addr_first) && addr_dataflash(addr_last)) {
			status = dataflash_real_protect(p,addr_first,addr_last);
			if (status < 0){
				puts ("Bad DataFlash sector specification\n");
				return 1;
			}
			printf("%sProtect %d DataFlash Sectors\n",
				p ? "" : "Un-", status);
			return 0;
		}
	}
#endif

#ifndef CONFIG_SYS_NO_FLASH
	if (strcmp(argv[2], "all") == 0) {
		for (bank=1; bank<=CONFIG_SYS_MAX_FLASH_BANKS; ++bank) {
			info = &flash_info[bank-1];
			if (info->flash_id == FLASH_UNKNOWN) {
				continue;
			}
			printf ("%sProtect Flash Bank # %ld\n",
				p ? "" : "Un-", bank);

			for (i=0; i<info->sector_count; ++i) {
#if defined(CONFIG_SYS_FLASH_PROTECTION)
				if (flash_real_protect(info, i, p))
					rcode = 1;
				putc ('.');
#else
				info->protect[i] = p;
#endif	/* CONFIG_SYS_FLASH_PROTECTION */
			}
#if defined(CONFIG_SYS_FLASH_PROTECTION)
			if (!rcode) puts (" done\n");
#endif	/* CONFIG_SYS_FLASH_PROTECTION */
		}
		return rcode;
	}

	if ((n = abbrev_spec(argv[2], &info, &sect_first, &sect_last)) != 0) {
		if (n < 0) {
			puts ("Bad sector specification\n");
			return 1;
		}
		printf("%sProtect Flash Sectors %d-%d in Bank # %zu\n",
			p ? "" : "Un-", sect_first, sect_last,
			(info-flash_info)+1);
		for (i = sect_first; i <= sect_last; i++) {
#if defined(CONFIG_SYS_FLASH_PROTECTION)
			if (flash_real_protect(info, i, p))
				rcode =  1;
			putc ('.');
#else
			info->protect[i] = p;
#endif	/* CONFIG_SYS_FLASH_PROTECTION */
		}

#if defined(CONFIG_SYS_FLASH_PROTECTION)
		if (!rcode) puts (" done\n");
#endif	/* CONFIG_SYS_FLASH_PROTECTION */

		return rcode;
	}

#if defined(CONFIG_CMD_JFFS2) && defined(CONFIG_CMD_MTDPARTS)
	/* protect on/off <part-id> */
	if ((argc == 3) && (mtd_id_parse(argv[2], NULL, &dev_type, &dev_num) == 0)) {
		mtdparts_init();
		if (find_dev_and_part(argv[2], &dev, &pnum, &part) == 0) {
			if (dev->id->type == MTD_DEV_TYPE_NOR) {
				bank = dev->id->num;
				info = &flash_info[bank];
				addr_first = part->offset + info->start[0];
				addr_last = addr_first + part->size - 1;

				printf ("%sProtect Flash Partition %s, "
						"bank %ld, 0x%08lx - 0x%08lx\n",
						p ? "" : "Un", argv[1],
						bank, addr_first, addr_last);

				rcode = flash_sect_protect (p, addr_first, addr_last);
				return rcode;
			}

			printf("cannot %sprotect, not a NOR device\n",
					p ? "" : "un");
			return 1;
		}
	}
#endif

	if (argc != 4) {
		cmd_usage(cmdtp);
		return 1;
	}

	if (strcmp(argv[2], "bank") == 0) {
		bank = simple_strtoul(argv[3], NULL, 16);
		if ((bank < 1) || (bank > CONFIG_SYS_MAX_FLASH_BANKS)) {
			printf ("Only FLASH Banks # 1 ... # %d supported\n",
				CONFIG_SYS_MAX_FLASH_BANKS);
			return 1;
		}
		printf ("%sProtect Flash Bank # %ld\n",
			p ? "" : "Un-", bank);
		info = &flash_info[bank-1];

		if (info->flash_id == FLASH_UNKNOWN) {
			puts ("missing or unknown FLASH type\n");
			return 1;
		}
		for (i=0; i<info->sector_count; ++i) {
#if defined(CONFIG_SYS_FLASH_PROTECTION)
			if (flash_real_protect(info, i, p))
				rcode =  1;
			putc ('.');
#else
			info->protect[i] = p;
#endif	/* CONFIG_SYS_FLASH_PROTECTION */
		}

#if defined(CONFIG_SYS_FLASH_PROTECTION)
		if (!rcode) puts (" done\n");
#endif	/* CONFIG_SYS_FLASH_PROTECTION */

		return rcode;
	}

	if (addr_spec(argv[2], argv[3], &addr_first, &addr_last) < 0){
		printf("Bad address format\n");
		return 1;
	}

	if (addr_first >= addr_last) {
		cmd_usage(cmdtp);
		return 1;
	}
	rcode = flash_sect_protect (p, addr_first, addr_last);
#endif /* CONFIG_SYS_NO_FLASH */
	return rcode;
}
예제 #5
0
int do_protect (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
	flash_info_t *info;
	ulong bank, addr_first, addr_last;
	int i, p, n, sect_first, sect_last;
	int rcode = 0;
#ifdef CONFIG_HAS_DATAFLASH
	int status;
#endif
	if (argc < 3) {
		printf ("Usage:\n%s\n", cmdtp->usage);
		return 1;
	}

	if (strcmp(argv[1], "off") == 0) {
		p = 0;
	} else if (strcmp(argv[1], "on") == 0) {
		p = 1;
	} else {
		printf ("Usage:\n%s\n", cmdtp->usage);
		return 1;
	}

#ifdef CONFIG_HAS_DATAFLASH
	if ((strcmp(argv[2], "all") != 0) && (strcmp(argv[2], "bank") != 0)) {
		addr_first = simple_strtoul(argv[2], NULL, 16);
		addr_last  = simple_strtoul(argv[3], NULL, 16);

		if (addr_dataflash(addr_first) && addr_dataflash(addr_last)) {
			status = dataflash_real_protect(p,addr_first,addr_last);
			if (status < 0){
				puts ("Bad DataFlash sector specification\n");
				return 1;
			}
			printf("%sProtect %d DataFlash Sectors\n",
				p ? "" : "Un-", status);
			return 0;
		}
	}
#endif

	if (strcmp(argv[2], "all") == 0) {
		for (bank=1; bank<=CFG_MAX_FLASH_BANKS; ++bank) {
			info = &flash_info[bank-1];
			if (info->flash_id == FLASH_UNKNOWN) {
				continue;
			}
			printf ("%sProtect Flash Bank # %ld\n",
				p ? "" : "Un-", bank);

			for (i=0; i<info->sector_count; ++i) {
#if defined(CFG_FLASH_PROTECTION)
				if (flash_real_protect(info, i, p))
					rcode = 1;
				putc ('.');
#else
				info->protect[i] = p;
#endif	/* CFG_FLASH_PROTECTION */
			}
		}

#if defined(CFG_FLASH_PROTECTION)
		if (!rcode) puts (" done\n");
#endif	/* CFG_FLASH_PROTECTION */

		return rcode;
	}

	if ((n = abbrev_spec(argv[2], &info, &sect_first, &sect_last)) != 0) {
		if (n < 0) {
			puts ("Bad sector specification\n");
			return 1;
		}
		printf("%sProtect Flash Sectors %d-%d in Bank # %d\n",
			p ? "" : "Un-", sect_first, sect_last,
			(info-flash_info)+1);
		for (i = sect_first; i <= sect_last; i++) {
#if defined(CFG_FLASH_PROTECTION)
			if (flash_real_protect(info, i, p))
				rcode =  1;
			putc ('.');
#else
			info->protect[i] = p;
#endif	/* CFG_FLASH_PROTECTION */
		}

#if defined(CFG_FLASH_PROTECTION)
		if (!rcode) puts (" done\n");
#endif	/* CFG_FLASH_PROTECTION */

		return rcode;
	}

	if (argc != 4) {
		printf ("Usage:\n%s\n", cmdtp->usage);
		return 1;
	}

	if (strcmp(argv[2], "bank") == 0) {
		bank = simple_strtoul(argv[3], NULL, 16);
		if ((bank < 1) || (bank > CFG_MAX_FLASH_BANKS)) {
			printf ("Only FLASH Banks # 1 ... # %d supported\n",
				CFG_MAX_FLASH_BANKS);
			return 1;
		}
		printf ("%sProtect Flash Bank # %ld\n",
			p ? "" : "Un-", bank);
		info = &flash_info[bank-1];

		if (info->flash_id == FLASH_UNKNOWN) {
			puts ("missing or unknown FLASH type\n");
			return 1;
		}
		for (i=0; i<info->sector_count; ++i) {
#if defined(CFG_FLASH_PROTECTION)
			if (flash_real_protect(info, i, p))
				rcode =  1;
			putc ('.');
#else
			info->protect[i] = p;
#endif	/* CFG_FLASH_PROTECTION */
		}

#if defined(CFG_FLASH_PROTECTION)
		if (!rcode) puts (" done\n");
#endif	/* CFG_FLASH_PROTECTION */

		return rcode;
	}

	addr_first = simple_strtoul(argv[2], NULL, 16);
	addr_last  = simple_strtoul(argv[3], NULL, 16);

	if (addr_first >= addr_last) {
		printf ("Usage:\n%s\n", cmdtp->usage);
		return 1;
	}
	rcode = flash_sect_protect (p, addr_first, addr_last);
	return rcode;
}
예제 #6
0
static int update_flash_protect(int prot, ulong addr_first, ulong addr_last)
{
	uchar *sp_info_ptr;
	ulong s;
	int i, bank, cnt;
	flash_info_t *info;

	sp_info_ptr = NULL;

	if (prot == 0) {
		saved_prot_info =
			calloc(CONFIG_SYS_MAX_FLASH_BANKS * CONFIG_SYS_MAX_FLASH_SECT, 1);
		if (!saved_prot_info)
			return 1;
	}

	for (bank = 0; bank < CONFIG_SYS_MAX_FLASH_BANKS; ++bank) {
		cnt = 0;
		info = &flash_info[bank];

		/* Nothing to do if the bank doesn't exist */
		if (info->sector_count == 0)
			return 0;

		/* Point to current bank protection information */
		sp_info_ptr = saved_prot_info + (bank * CONFIG_SYS_MAX_FLASH_SECT);

		/*
		 * Adjust addr_first or addr_last if we are on bank boundary.
		 * Address space between banks must be continuous for other
		 * flash functions (like flash_sect_erase or flash_write) to
		 * succeed. Banks must also be numbered in correct order,
		 * according to increasing addresses.
		 */
		if (addr_last > info->start[0] + info->size - 1)
			addr_last = info->start[0] + info->size - 1;
		if (addr_first < info->start[0])
			addr_first = info->start[0];

		for (i = 0; i < info->sector_count; i++) {
			/* Save current information about protected sectors */
			if (prot == 0) {
				s = info->start[i];
				if ((s >= addr_first) && (s <= addr_last))
					sp_info_ptr[i] = info->protect[i];

			}

			/* Protect/unprotect sectors */
			if (sp_info_ptr[i] == 1) {
#if defined(CONFIG_SYS_FLASH_PROTECTION)
				if (flash_real_protect(info, i, prot))
					return 1;
#else
				info->protect[i] = prot;
#endif
				cnt++;
			}
		}

		if (cnt) {
			printf("%sProtected %d sectors\n",
						prot ? "": "Un-", cnt);
		}
	}

	if((prot == 1) && saved_prot_info)
		free(saved_prot_info);

	return 0;
}