mirror of
https://github.com/Stichting-MINIX-Research-Foundation/u-boot.git
synced 2025-08-21 04:36:18 -04:00
Merge with /home/sr/git/u-boot/nand-ladis
This commit is contained in:
commit
d9831893ab
@ -27,7 +27,7 @@ DECLARE_GLOBAL_DATA_PTR;
|
|||||||
int board_init(void)
|
int board_init(void)
|
||||||
{
|
{
|
||||||
/* arch number of NetStar board */
|
/* arch number of NetStar board */
|
||||||
gd->bd->bi_arch_number = 692;
|
gd->bd->bi_arch_number = MACH_TYPE_NETSTAR;
|
||||||
|
|
||||||
/* adress of boot parameters */
|
/* adress of boot parameters */
|
||||||
gd->bd->bi_boot_params = 0x10000100;
|
gd->bd->bi_boot_params = 0x10000100;
|
||||||
|
@ -28,8 +28,7 @@ int board_init(void)
|
|||||||
*((volatile unsigned char *) VOICEBLUE_LED_REG) = 0xaa;
|
*((volatile unsigned char *) VOICEBLUE_LED_REG) = 0xaa;
|
||||||
|
|
||||||
/* arch number of VoiceBlue board */
|
/* arch number of VoiceBlue board */
|
||||||
/* TODO: use define from asm/mach-types.h */
|
gd->bd->bi_arch_number = MACH_TYPE_VOICEBLUE;
|
||||||
gd->bd->bi_arch_number = 218;
|
|
||||||
|
|
||||||
/* adress of boot parameters */
|
/* adress of boot parameters */
|
||||||
gd->bd->bi_boot_params = 0x10000100;
|
gd->bd->bi_boot_params = 0x10000100;
|
||||||
|
@ -1300,7 +1300,7 @@ static void list_partitions(void)
|
|||||||
* Given partition identifier in form of <dev_type><dev_num>,<part_num> find
|
* Given partition identifier in form of <dev_type><dev_num>,<part_num> find
|
||||||
* corresponding device and verify partition number.
|
* corresponding device and verify partition number.
|
||||||
*
|
*
|
||||||
* @param id string describing device and partition
|
* @param id string describing device and partition or partition name
|
||||||
* @param dev pointer to the requested device (output)
|
* @param dev pointer to the requested device (output)
|
||||||
* @param part_num verified partition number (output)
|
* @param part_num verified partition number (output)
|
||||||
* @param part pointer to requested partition (output)
|
* @param part pointer to requested partition (output)
|
||||||
@ -1309,11 +1309,23 @@ static void list_partitions(void)
|
|||||||
int find_dev_and_part(const char *id, struct mtd_device **dev,
|
int find_dev_and_part(const char *id, struct mtd_device **dev,
|
||||||
u8 *part_num, struct part_info **part)
|
u8 *part_num, struct part_info **part)
|
||||||
{
|
{
|
||||||
|
struct list_head *dentry, *pentry;
|
||||||
u8 type, dnum, pnum;
|
u8 type, dnum, pnum;
|
||||||
const char *p;
|
const char *p;
|
||||||
|
|
||||||
DEBUGF("--- find_dev_and_part ---\nid = %s\n", id);
|
DEBUGF("--- find_dev_and_part ---\nid = %s\n", id);
|
||||||
|
|
||||||
|
list_for_each(dentry, &devices) {
|
||||||
|
*part_num = 0;
|
||||||
|
*dev = list_entry(dentry, struct mtd_device, link);
|
||||||
|
list_for_each(pentry, &(*dev)->parts) {
|
||||||
|
*part = list_entry(pentry, struct part_info, link);
|
||||||
|
if (strcmp((*part)->name, id) == 0)
|
||||||
|
return 0;
|
||||||
|
(*part_num)++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
p = id;
|
p = id;
|
||||||
*dev = NULL;
|
*dev = NULL;
|
||||||
*part = NULL;
|
*part = NULL;
|
||||||
|
@ -36,6 +36,15 @@
|
|||||||
#include <jffs2/jffs2.h>
|
#include <jffs2/jffs2.h>
|
||||||
#include <nand.h>
|
#include <nand.h>
|
||||||
|
|
||||||
|
#if (CONFIG_COMMANDS & CFG_CMD_JFFS2) && defined(CONFIG_JFFS2_CMDLINE)
|
||||||
|
|
||||||
|
/* parition handling routines */
|
||||||
|
int mtdparts_init(void);
|
||||||
|
int id_parse(const char *id, const char **ret_id, u8 *dev_type, u8 *dev_num);
|
||||||
|
int find_dev_and_part(const char *id, struct mtd_device **dev,
|
||||||
|
u8 *part_num, struct part_info **part);
|
||||||
|
#endif
|
||||||
|
|
||||||
extern nand_info_t nand_info[]; /* info for NAND chips */
|
extern nand_info_t nand_info[]; /* info for NAND chips */
|
||||||
|
|
||||||
static int nand_dump_oob(nand_info_t *nand, ulong off)
|
static int nand_dump_oob(nand_info_t *nand, ulong off)
|
||||||
@ -83,50 +92,75 @@ static int nand_dump(nand_info_t *nand, ulong off)
|
|||||||
|
|
||||||
/* ------------------------------------------------------------------------- */
|
/* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
static void
|
static inline int str2long(char *p, ulong *num)
|
||||||
arg_off_size(int argc, char *argv[], ulong *off, ulong *size, ulong totsize)
|
|
||||||
{
|
{
|
||||||
*off = 0;
|
char *endptr;
|
||||||
*size = 0;
|
|
||||||
|
|
||||||
#if defined(CONFIG_JFFS2_NAND) && defined(CFG_JFFS_CUSTOM_PART)
|
*num = simple_strtoul(p, &endptr, 16);
|
||||||
if (argc >= 1 && strcmp(argv[0], "partition") == 0) {
|
return (*p != '\0' && *endptr == '\0') ? 1 : 0;
|
||||||
int part_num;
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
arg_off_size(int argc, char *argv[], nand_info_t *nand, ulong *off, ulong *size)
|
||||||
|
{
|
||||||
|
int idx = nand_curr_device;
|
||||||
|
#if (CONFIG_COMMANDS & CFG_CMD_JFFS2) && defined(CONFIG_JFFS2_CMDLINE)
|
||||||
|
struct mtd_device *dev;
|
||||||
struct part_info *part;
|
struct part_info *part;
|
||||||
const char *partstr;
|
u8 pnum;
|
||||||
|
|
||||||
if (argc >= 2)
|
if (argc >= 1 && !(str2long(argv[0], off))) {
|
||||||
partstr = argv[1];
|
if ((mtdparts_init() == 0) &&
|
||||||
else
|
(find_dev_and_part(argv[0], &dev, &pnum, &part) == 0)) {
|
||||||
partstr = getenv("partition");
|
if (dev->id->type != MTD_DEV_TYPE_NAND) {
|
||||||
|
puts("not a NAND device\n");
|
||||||
if (partstr)
|
return -1;
|
||||||
part_num = (int)simple_strtoul(partstr, NULL, 10);
|
|
||||||
else
|
|
||||||
part_num = 0;
|
|
||||||
|
|
||||||
part = jffs2_part_info(part_num);
|
|
||||||
if (part == NULL) {
|
|
||||||
printf("\nInvalid partition %d\n", part_num);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
*off = part->offset;
|
||||||
|
if (argc >= 2) {
|
||||||
|
if (!(str2long(argv[1], size))) {
|
||||||
|
printf("'%s' is not a number\n", argv[1]);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (*size > part->size)
|
||||||
*size = part->size;
|
*size = part->size;
|
||||||
*off = (ulong)part->offset;
|
} else {
|
||||||
} else
|
*size = part->size;
|
||||||
|
}
|
||||||
|
idx = dev->id->num;
|
||||||
|
*nand = nand_info[idx];
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
{
|
|
||||||
if (argc >= 1)
|
if (argc >= 1) {
|
||||||
*off = (ulong)simple_strtoul(argv[0], NULL, 16);
|
if (!(str2long(argv[0], off))) {
|
||||||
else
|
printf("'%s' is not a number\n", argv[0]);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
*off = 0;
|
*off = 0;
|
||||||
|
|
||||||
if (argc >= 2)
|
|
||||||
*size = (ulong)simple_strtoul(argv[1], NULL, 16);
|
|
||||||
else
|
|
||||||
*size = totsize - *off;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (argc >= 2) {
|
||||||
|
if (!(str2long(argv[1], size))) {
|
||||||
|
printf("'%s' is not a number\n", argv[1]);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
*size = nand->size - *off;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if (CONFIG_COMMANDS & CFG_CMD_JFFS2) && defined(CONFIG_JFFS2_CMDLINE)
|
||||||
|
out:
|
||||||
|
#endif
|
||||||
|
printf("device %d ", idx);
|
||||||
|
if (*size == nand->size)
|
||||||
|
puts("whole chip\n");
|
||||||
|
else
|
||||||
|
printf("offset 0x%x, size 0x%x\n", *off, *size);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
|
int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
|
||||||
@ -213,36 +247,23 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Syntax is:
|
||||||
|
* 0 1 2 3 4
|
||||||
|
* nand erase [clean] [off size]
|
||||||
|
*/
|
||||||
if (strcmp(cmd, "erase") == 0 || strcmp(cmd, "scrub") == 0) {
|
if (strcmp(cmd, "erase") == 0 || strcmp(cmd, "scrub") == 0) {
|
||||||
nand_erase_options_t opts;
|
nand_erase_options_t opts;
|
||||||
int clean = argc >= 3 && !strcmp("clean", argv[2]);
|
/* "clean" at index 2 means request to write cleanmarker */
|
||||||
int rest_argc = argc - 2;
|
int clean = argc > 2 && !strcmp("clean", argv[2]);
|
||||||
char **rest_argv = argv + 2;
|
int o = clean ? 3 : 2;
|
||||||
int scrub = !strcmp(cmd, "scrub");
|
int scrub = !strcmp(cmd, "scrub");
|
||||||
|
|
||||||
if (clean) {
|
printf("\nNAND %s: ", scrub ? "scrub" : "erase");
|
||||||
rest_argc--;
|
/* skip first two or three arguments, look for offset and size */
|
||||||
rest_argv++;
|
if (arg_off_size(argc - o, argv + o, nand, &off, &size) != 0)
|
||||||
}
|
|
||||||
|
|
||||||
if (rest_argc == 0) {
|
|
||||||
|
|
||||||
printf("\nNAND %s: device %d whole chip\n",
|
|
||||||
cmd,
|
|
||||||
nand_curr_device);
|
|
||||||
|
|
||||||
off = size = 0;
|
|
||||||
} else {
|
|
||||||
arg_off_size(rest_argc, rest_argv, &off, &size,
|
|
||||||
nand->size);
|
|
||||||
|
|
||||||
if (off == 0 && size == 0)
|
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
printf("\nNAND %s: device %d offset 0x%x, size 0x%x\n",
|
|
||||||
cmd, nand_curr_device, off, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(&opts, 0, sizeof(opts));
|
memset(&opts, 0, sizeof(opts));
|
||||||
opts.offset = off;
|
opts.offset = off;
|
||||||
opts.length = size;
|
opts.length = size;
|
||||||
@ -250,7 +271,7 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
|
|||||||
opts.quiet = quiet;
|
opts.quiet = quiet;
|
||||||
|
|
||||||
if (scrub) {
|
if (scrub) {
|
||||||
printf("Warning: "
|
puts("Warning: "
|
||||||
"scrub option will erase all factory set "
|
"scrub option will erase all factory set "
|
||||||
"bad blocks!\n"
|
"bad blocks!\n"
|
||||||
" "
|
" "
|
||||||
@ -260,13 +281,12 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
|
|||||||
"if you\n"
|
"if you\n"
|
||||||
" "
|
" "
|
||||||
"are sure of what you are doing!\n"
|
"are sure of what you are doing!\n"
|
||||||
"\nReally scrub this NAND flash? <y/N>\n"
|
"\nReally scrub this NAND flash? <y/N>\n");
|
||||||
);
|
|
||||||
|
|
||||||
if (getc() == 'y' && getc() == '\r') {
|
if (getc() == 'y' && getc() == '\r') {
|
||||||
opts.scrub = 1;
|
opts.scrub = 1;
|
||||||
} else {
|
} else {
|
||||||
printf("scrub aborted\n");
|
puts("scrub aborted\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -301,13 +321,10 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
|
|||||||
|
|
||||||
addr = (ulong)simple_strtoul(argv[2], NULL, 16);
|
addr = (ulong)simple_strtoul(argv[2], NULL, 16);
|
||||||
|
|
||||||
arg_off_size(argc - 3, argv + 3, &off, &size, nand->size);
|
|
||||||
if (off == 0 && size == 0)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
read = strncmp(cmd, "read", 4) == 0; /* 1 = read, 0 = write */
|
read = strncmp(cmd, "read", 4) == 0; /* 1 = read, 0 = write */
|
||||||
printf("\nNAND %s: device %d offset %u, size %u ... ",
|
printf("\nNAND %s: ", read ? "read" : "write");
|
||||||
read ? "read" : "write", nand_curr_device, off, size);
|
if (arg_off_size(argc - 3, argv + 3, nand, &off, &size) != 0)
|
||||||
|
return 1;
|
||||||
|
|
||||||
s = strchr(cmd, '.');
|
s = strchr(cmd, '.');
|
||||||
if (s != NULL &&
|
if (s != NULL &&
|
||||||
@ -334,14 +351,12 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
|
|||||||
opts.quiet = quiet;
|
opts.quiet = quiet;
|
||||||
ret = nand_write_opts(nand, &opts);
|
ret = nand_write_opts(nand, &opts);
|
||||||
}
|
}
|
||||||
printf("%s\n", ret ? "ERROR" : "OK");
|
} else {
|
||||||
return ret == 0 ? 0 : 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (read)
|
if (read)
|
||||||
ret = nand_read(nand, off, &size, (u_char *)addr);
|
ret = nand_read(nand, off, &size, (u_char *)addr);
|
||||||
else
|
else
|
||||||
ret = nand_write(nand, off, &size, (u_char *)addr);
|
ret = nand_write(nand, off, &size, (u_char *)addr);
|
||||||
|
}
|
||||||
|
|
||||||
printf(" %d bytes %s: %s\n", size,
|
printf(" %d bytes %s: %s\n", size,
|
||||||
read ? "read" : "written", ret ? "ERROR" : "OK");
|
read ? "read" : "written", ret ? "ERROR" : "OK");
|
||||||
@ -412,9 +427,9 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!nand_lock(nand, tight)) {
|
if (!nand_lock(nand, tight)) {
|
||||||
printf ("NAND flash successfully locked\n");
|
puts("NAND flash successfully locked\n");
|
||||||
} else {
|
} else {
|
||||||
printf ("Error locking NAND flash. \n");
|
puts("Error locking NAND flash\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -422,19 +437,14 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(cmd, "unlock") == 0) {
|
if (strcmp(cmd, "unlock") == 0) {
|
||||||
if (argc == 2) {
|
if (arg_off_size(argc - 2, argv + 2, nand, &off, &size) < 0)
|
||||||
off = 0;
|
return 1;
|
||||||
size = nand->size;
|
|
||||||
} else {
|
|
||||||
arg_off_size(argc - 2, argv + 2, &off, &size,
|
|
||||||
nand->size);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!nand_unlock(nand, off, size)) {
|
if (!nand_unlock(nand, off, size)) {
|
||||||
printf("NAND flash successfully unlocked\n");
|
puts("NAND flash successfully unlocked\n");
|
||||||
} else {
|
} else {
|
||||||
printf("Error unlocking NAND flash. "
|
puts("Error unlocking NAND flash, "
|
||||||
"Write and erase will probably fail\n");
|
"write and erase will probably fail\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@ -449,8 +459,8 @@ U_BOOT_CMD(nand, 5, 1, do_nand,
|
|||||||
"nand - NAND sub-system\n",
|
"nand - NAND sub-system\n",
|
||||||
"info - show available NAND devices\n"
|
"info - show available NAND devices\n"
|
||||||
"nand device [dev] - show or set current device\n"
|
"nand device [dev] - show or set current device\n"
|
||||||
"nand read[.jffs2] - addr off size\n"
|
"nand read[.jffs2] - addr off|partition size\n"
|
||||||
"nand write[.jffs2] - addr off size - read/write `size' bytes starting\n"
|
"nand write[.jffs2] - addr off|partiton size - read/write `size' bytes starting\n"
|
||||||
" at offset `off' to/from memory address `addr'\n"
|
" at offset `off' to/from memory address `addr'\n"
|
||||||
"nand erase [clean] [off size] - erase `size' bytes from\n"
|
"nand erase [clean] [off size] - erase `size' bytes from\n"
|
||||||
" offset `off' (entire device if not specified)\n"
|
" offset `off' (entire device if not specified)\n"
|
||||||
@ -462,15 +472,92 @@ U_BOOT_CMD(nand, 5, 1, do_nand,
|
|||||||
"nand lock [tight] [status] - bring nand to lock state or display locked pages\n"
|
"nand lock [tight] [status] - bring nand to lock state or display locked pages\n"
|
||||||
"nand unlock [offset] [size] - unlock section\n");
|
"nand unlock [offset] [size] - unlock section\n");
|
||||||
|
|
||||||
|
static int nand_load_image(cmd_tbl_t *cmdtp, nand_info_t *nand,
|
||||||
|
ulong offset, ulong addr, char *cmd)
|
||||||
|
{
|
||||||
|
int r;
|
||||||
|
char *ep;
|
||||||
|
ulong cnt;
|
||||||
|
image_header_t *hdr;
|
||||||
|
|
||||||
|
printf("\nLoading from %s, offset 0x%lx\n", nand->name, offset);
|
||||||
|
|
||||||
|
cnt = nand->oobblock;
|
||||||
|
r = nand_read(nand, offset, &cnt, (u_char *) addr);
|
||||||
|
if (r) {
|
||||||
|
puts("** Read error\n");
|
||||||
|
SHOW_BOOT_PROGRESS(-1);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
hdr = (image_header_t *) addr;
|
||||||
|
|
||||||
|
if (ntohl(hdr->ih_magic) != IH_MAGIC) {
|
||||||
|
printf("\n** Bad Magic Number 0x%x **\n", hdr->ih_magic);
|
||||||
|
SHOW_BOOT_PROGRESS(-1);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
print_image_hdr(hdr);
|
||||||
|
|
||||||
|
cnt = (ntohl(hdr->ih_size) + sizeof (image_header_t));
|
||||||
|
|
||||||
|
r = nand_read(nand, offset, &cnt, (u_char *) addr);
|
||||||
|
if (r) {
|
||||||
|
puts("** Read error\n");
|
||||||
|
SHOW_BOOT_PROGRESS(-1);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Loading ok, update default load address */
|
||||||
|
|
||||||
|
load_addr = addr;
|
||||||
|
|
||||||
|
/* Check if we should attempt an auto-start */
|
||||||
|
if (((ep = getenv("autostart")) != NULL) && (strcmp(ep, "yes") == 0)) {
|
||||||
|
char *local_args[2];
|
||||||
|
extern int do_bootm(cmd_tbl_t *, int, int, char *[]);
|
||||||
|
|
||||||
|
local_args[0] = cmd;
|
||||||
|
local_args[1] = NULL;
|
||||||
|
|
||||||
|
printf("Automatic boot of image at addr 0x%08lx ...\n", addr);
|
||||||
|
|
||||||
|
do_bootm(cmdtp, 0, 1, local_args);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int do_nandboot(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
|
int do_nandboot(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
|
||||||
{
|
{
|
||||||
char *boot_device = NULL;
|
char *boot_device = NULL;
|
||||||
char *ep;
|
int idx;
|
||||||
int dev;
|
ulong addr, offset = 0;
|
||||||
int r;
|
#if (CONFIG_COMMANDS & CFG_CMD_JFFS2) && defined(CONFIG_JFFS2_CMDLINE)
|
||||||
ulong addr, cnt, offset = 0;
|
struct mtd_device *dev;
|
||||||
image_header_t *hdr;
|
struct part_info *part;
|
||||||
nand_info_t *nand;
|
u8 pnum;
|
||||||
|
|
||||||
|
if (argc >= 2) {
|
||||||
|
char *p = (argc == 2) ? argv[1] : argv[2];
|
||||||
|
if (!(str2long(p, &addr)) && (mtdparts_init() == 0) &&
|
||||||
|
(find_dev_and_part(p, &dev, &pnum, &part) == 0)) {
|
||||||
|
if (dev->id->type != MTD_DEV_TYPE_NAND) {
|
||||||
|
puts("Not a NAND device\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (argc > 3)
|
||||||
|
goto usage;
|
||||||
|
if (argc == 3)
|
||||||
|
addr = simple_strtoul(argv[2], NULL, 16);
|
||||||
|
else
|
||||||
|
addr = CFG_LOAD_ADDR;
|
||||||
|
return nand_load_image(cmdtp, &nand_info[dev->id->num],
|
||||||
|
part->offset, addr, argv[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
switch (argc) {
|
switch (argc) {
|
||||||
case 1:
|
case 1:
|
||||||
@ -491,6 +578,9 @@ int do_nandboot(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
|
|||||||
offset = simple_strtoul(argv[3], NULL, 16);
|
offset = simple_strtoul(argv[3], NULL, 16);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
#if (CONFIG_COMMANDS & CFG_CMD_JFFS2) && defined(CONFIG_JFFS2_CMDLINE)
|
||||||
|
usage:
|
||||||
|
#endif
|
||||||
printf("Usage:\n%s\n", cmdtp->usage);
|
printf("Usage:\n%s\n", cmdtp->usage);
|
||||||
SHOW_BOOT_PROGRESS(-1);
|
SHOW_BOOT_PROGRESS(-1);
|
||||||
return 1;
|
return 1;
|
||||||
@ -502,68 +592,20 @@ int do_nandboot(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
dev = simple_strtoul(boot_device, &ep, 16);
|
idx = simple_strtoul(boot_device, NULL, 16);
|
||||||
|
|
||||||
if (dev < 0 || dev >= CFG_MAX_NAND_DEVICE || !nand_info[dev].name) {
|
if (idx < 0 || idx >= CFG_MAX_NAND_DEVICE || !nand_info[idx].name) {
|
||||||
printf("\n** Device %d not available\n", dev);
|
printf("\n** Device %d not available\n", idx);
|
||||||
SHOW_BOOT_PROGRESS(-1);
|
SHOW_BOOT_PROGRESS(-1);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
nand = &nand_info[dev];
|
return nand_load_image(cmdtp, &nand_info[idx], offset, addr, argv[0]);
|
||||||
printf("\nLoading from device %d: %s (offset 0x%lx)\n",
|
|
||||||
dev, nand->name, offset);
|
|
||||||
|
|
||||||
cnt = nand->oobblock;
|
|
||||||
r = nand_read(nand, offset, &cnt, (u_char *) addr);
|
|
||||||
if (r) {
|
|
||||||
printf("** Read error on %d\n", dev);
|
|
||||||
SHOW_BOOT_PROGRESS(-1);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
hdr = (image_header_t *) addr;
|
|
||||||
|
|
||||||
if (ntohl(hdr->ih_magic) != IH_MAGIC) {
|
|
||||||
printf("\n** Bad Magic Number 0x%x **\n", hdr->ih_magic);
|
|
||||||
SHOW_BOOT_PROGRESS(-1);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
print_image_hdr(hdr);
|
|
||||||
|
|
||||||
cnt = (ntohl(hdr->ih_size) + sizeof (image_header_t));
|
|
||||||
|
|
||||||
r = nand_read(nand, offset, &cnt, (u_char *) addr);
|
|
||||||
if (r) {
|
|
||||||
printf("** Read error on %d\n", dev);
|
|
||||||
SHOW_BOOT_PROGRESS(-1);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Loading ok, update default load address */
|
|
||||||
|
|
||||||
load_addr = addr;
|
|
||||||
|
|
||||||
/* Check if we should attempt an auto-start */
|
|
||||||
if (((ep = getenv("autostart")) != NULL) && (strcmp(ep, "yes") == 0)) {
|
|
||||||
char *local_args[2];
|
|
||||||
extern int do_bootm(cmd_tbl_t *, int, int, char *[]);
|
|
||||||
|
|
||||||
local_args[0] = argv[0];
|
|
||||||
local_args[1] = NULL;
|
|
||||||
|
|
||||||
printf("Automatic boot of image at addr 0x%08lx ...\n", addr);
|
|
||||||
|
|
||||||
do_bootm(cmdtp, 0, 1, local_args);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
U_BOOT_CMD(nboot, 4, 1, do_nandboot,
|
U_BOOT_CMD(nboot, 4, 1, do_nandboot,
|
||||||
"nboot - boot from NAND device\n", "loadAddr dev\n");
|
"nboot - boot from NAND device\n",
|
||||||
|
"[partition] | [[[loadAddr] dev] offset]\n");
|
||||||
|
|
||||||
#endif /* (CONFIG_COMMANDS & CFG_CMD_NAND) */
|
#endif /* (CONFIG_COMMANDS & CFG_CMD_NAND) */
|
||||||
|
|
||||||
|
@ -25,40 +25,6 @@
|
|||||||
#include <command.h>
|
#include <command.h>
|
||||||
#include <arm925t.h>
|
#include <arm925t.h>
|
||||||
|
|
||||||
ushort gpioreserved;
|
|
||||||
|
|
||||||
void gpioreserve(ushort mask)
|
|
||||||
{
|
|
||||||
gpioreserved |= mask;
|
|
||||||
}
|
|
||||||
|
|
||||||
void gpiosetdir(ushort mask, ushort in)
|
|
||||||
{
|
|
||||||
*(ushort *)GPIO_DIR_CONTROL_REG = (*(ushort *)GPIO_DIR_CONTROL_REG & ~mask) | (in & mask);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void gpiosetout(ushort mask, ushort out)
|
|
||||||
{
|
|
||||||
ushort *r_ptr, r_val;
|
|
||||||
|
|
||||||
r_ptr = (ushort *)GPIO_DATA_OUTPUT_REG; /* set pointer */
|
|
||||||
r_val = *r_ptr & ~mask; /* get previous val, clear bits we want to change */
|
|
||||||
r_val |= (out & mask); /* set specified bits in value + plus origional ones */
|
|
||||||
*r_ptr = r_val; /* write it out */
|
|
||||||
/*
|
|
||||||
* gcc screwed this one up :(.
|
|
||||||
*
|
|
||||||
* *(ushort *)GPIO_DATA_OUTPUT_REG = (*(ushort *)GPIO_DATA_OUTPUT_REG & ~mask) | (out & mask);
|
|
||||||
*/
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void gpioinit(void)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#define MIF_CONFIG_REG 0xFFFECC0C
|
#define MIF_CONFIG_REG 0xFFFECC0C
|
||||||
#define FLASH_GLOBAL_CTRL_NWP 1
|
#define FLASH_GLOBAL_CTRL_NWP 1
|
||||||
|
|
||||||
|
@ -34,14 +34,19 @@ Commands:
|
|||||||
nand device num
|
nand device num
|
||||||
Make device `num' the current device and print information about it.
|
Make device `num' the current device and print information about it.
|
||||||
|
|
||||||
nand erase off size
|
nand erase off|partition size
|
||||||
nand erase clean [off size]
|
nand erase clean [off|partition size]
|
||||||
Erase `size' bytes starting at offset `off'. Only complete erase
|
Erase `size' bytes starting at offset `off'. Alternatively partition
|
||||||
blocks can be erased.
|
name can be specified, in this case size will be eventually limited
|
||||||
|
to not exceed partition size (this behaviour applies also to read
|
||||||
|
and write commands). Only complete erase blocks can be erased.
|
||||||
|
|
||||||
|
If `erase' is specified without an offset or size, the entire flash
|
||||||
|
is erased. If `erase' is specified with partition but without an
|
||||||
|
size, the entire partition is erased.
|
||||||
|
|
||||||
If `clean' is specified, a JFFS2-style clean marker is written to
|
If `clean' is specified, a JFFS2-style clean marker is written to
|
||||||
each block after it is erased. If `clean' is specified without an
|
each block after it is erased.
|
||||||
offset or size, the entire flash is erased.
|
|
||||||
|
|
||||||
This command will not erase blocks that are marked bad. There is
|
This command will not erase blocks that are marked bad. There is
|
||||||
a debug option in cmd_nand.c to allow bad blocks to be erased.
|
a debug option in cmd_nand.c to allow bad blocks to be erased.
|
||||||
@ -51,28 +56,28 @@ Commands:
|
|||||||
nand info
|
nand info
|
||||||
Print information about all of the NAND devices found.
|
Print information about all of the NAND devices found.
|
||||||
|
|
||||||
nand read addr ofs size
|
nand read addr ofs|partition size
|
||||||
Read `size' bytes from `ofs' in NAND flash to `addr'. If a page
|
Read `size' bytes from `ofs' in NAND flash to `addr'. If a page
|
||||||
cannot be read because it is marked bad or an uncorrectable data
|
cannot be read because it is marked bad or an uncorrectable data
|
||||||
error is found the command stops with an error.
|
error is found the command stops with an error.
|
||||||
|
|
||||||
nand read.jffs2 addr ofs size
|
nand read.jffs2 addr ofs|partition size
|
||||||
Like `read', but the data for blocks that are marked bad is read as
|
Like `read', but the data for blocks that are marked bad is read as
|
||||||
0xff. This gives a readable JFFS2 image that can be processed by
|
0xff. This gives a readable JFFS2 image that can be processed by
|
||||||
the JFFS2 commands such as ls and fsload.
|
the JFFS2 commands such as ls and fsload.
|
||||||
|
|
||||||
nand read.oob addr ofs size
|
nand read.oob addr ofs|partition size
|
||||||
Read `size' bytes from the out-of-band data area corresponding to
|
Read `size' bytes from the out-of-band data area corresponding to
|
||||||
`ofs' in NAND flash to `addr'. This is limited to the 16 bytes of
|
`ofs' in NAND flash to `addr'. This is limited to the 16 bytes of
|
||||||
data for one 512-byte page or 2 256-byte pages. There is no check
|
data for one 512-byte page or 2 256-byte pages. There is no check
|
||||||
for bad blocks or ECC errors.
|
for bad blocks or ECC errors.
|
||||||
|
|
||||||
nand write addr ofs size
|
nand write addr ofs|partition size
|
||||||
Write `size' bytes from `addr' to `ofs' in NAND flash. If a page
|
Write `size' bytes from `addr' to `ofs' in NAND flash. If a page
|
||||||
cannot be written because it is marked bad or the write fails the
|
cannot be written because it is marked bad or the write fails the
|
||||||
command stops with an error.
|
command stops with an error.
|
||||||
|
|
||||||
nand write.jffs2 addr ofs size
|
nand write.jffs2 addr ofs|partition size
|
||||||
Like `write', but blocks that are marked bad are skipped and the
|
Like `write', but blocks that are marked bad are skipped and the
|
||||||
is written to the next block instead. This allows writing writing
|
is written to the next block instead. This allows writing writing
|
||||||
a JFFS2 image, as long as the image is short enough to fit even
|
a JFFS2 image, as long as the image is short enough to fit even
|
||||||
@ -80,7 +85,7 @@ Commands:
|
|||||||
produced by mkfs.jffs2 should work well, but loading an image copied
|
produced by mkfs.jffs2 should work well, but loading an image copied
|
||||||
from another flash is going to be trouble if there are any bad blocks.
|
from another flash is going to be trouble if there are any bad blocks.
|
||||||
|
|
||||||
nand write.oob addr ofs size
|
nand write.oob addr ofs|partition size
|
||||||
Write `size' bytes from `addr' to the out-of-band data area
|
Write `size' bytes from `addr' to the out-of-band data area
|
||||||
corresponding to `ofs' in NAND flash. This is limited to the 16 bytes
|
corresponding to `ofs' in NAND flash. This is limited to the 16 bytes
|
||||||
of data for one 512-byte page or 2 256-byte pages. There is no check
|
of data for one 512-byte page or 2 256-byte pages. There is no check
|
||||||
|
@ -83,15 +83,8 @@ int nand_erase_opts(nand_info_t *meminfo, const nand_erase_options_t *opts)
|
|||||||
|
|
||||||
erase.mtd = meminfo;
|
erase.mtd = meminfo;
|
||||||
erase.len = meminfo->erasesize;
|
erase.len = meminfo->erasesize;
|
||||||
if (opts->offset == 0 && opts->length == 0) {
|
|
||||||
/* erase complete chip */
|
|
||||||
erase.addr = 0;
|
|
||||||
erase_length = meminfo->size;
|
|
||||||
} else {
|
|
||||||
/* erase specified region */
|
|
||||||
erase.addr = opts->offset;
|
erase.addr = opts->offset;
|
||||||
erase_length = opts->length;
|
erase_length = opts->length;
|
||||||
}
|
|
||||||
|
|
||||||
isNAND = meminfo->type == MTD_NANDFLASH ? 1 : 0;
|
isNAND = meminfo->type == MTD_NANDFLASH ? 1 : 0;
|
||||||
|
|
||||||
|
@ -6,10 +6,6 @@
|
|||||||
#ifndef __ARM925T_H__
|
#ifndef __ARM925T_H__
|
||||||
#define __ARM925T_H__
|
#define __ARM925T_H__
|
||||||
|
|
||||||
void gpioreserve(ushort mask);
|
|
||||||
void gpiosetdir(ushort mask, ushort in);
|
|
||||||
void gpiosetout(ushort mask, ushort out);
|
|
||||||
void gpioinit(void);
|
|
||||||
void archflashwp(void *archdata, int wp);
|
void archflashwp(void *archdata, int wp);
|
||||||
|
|
||||||
#endif /*__ARM925T_H__*/
|
#endif /*__ARM925T_H__*/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user