diff options
Diffstat (limited to 'cmd')
| -rw-r--r-- | cmd/Kconfig | 7 | ||||
| -rw-r--r-- | cmd/Makefile | 1 | ||||
| -rw-r--r-- | cmd/bootefi.c | 17 | ||||
| -rw-r--r-- | cmd/bootm.c | 39 | ||||
| -rw-r--r-- | cmd/disk.c | 3 | ||||
| -rw-r--r-- | cmd/itest.c | 6 | ||||
| -rw-r--r-- | cmd/jffs2.c | 8 | ||||
| -rw-r--r-- | cmd/mmc.c | 62 | ||||
| -rw-r--r-- | cmd/nand.c | 189 | ||||
| -rw-r--r-- | cmd/qfw.c | 194 | ||||
| -rw-r--r-- | cmd/ubi.c | 38 |
11 files changed, 367 insertions, 197 deletions
diff --git a/cmd/Kconfig b/cmd/Kconfig index 93367521286..d51645c634e 100644 --- a/cmd/Kconfig +++ b/cmd/Kconfig @@ -593,6 +593,13 @@ config CMD_SOUND sound init - set up sound system sound play - play a sound +config CMD_QFW + bool "qfw" + select QFW + help + This provides access to the QEMU firmware interface. The main + feature is to allow easy loading of files passed to qemu-system + via -kernel / -initrd endmenu config CMD_BOOTSTAGE diff --git a/cmd/Makefile b/cmd/Makefile index e3e0c74ffc6..9ce7861f822 100644 --- a/cmd/Makefile +++ b/cmd/Makefile @@ -105,6 +105,7 @@ endif obj-y += pcmcia.o obj-$(CONFIG_CMD_PORTIO) += portio.o obj-$(CONFIG_CMD_PXE) += pxe.o +obj-$(CONFIG_CMD_QFW) += qfw.o obj-$(CONFIG_CMD_READ) += read.o obj-$(CONFIG_CMD_REGINFO) += reginfo.o obj-$(CONFIG_CMD_REISER) += reiser.o diff --git a/cmd/bootefi.c b/cmd/bootefi.c index 7f552fc0d4d..216906527fe 100644 --- a/cmd/bootefi.c +++ b/cmd/bootefi.c @@ -197,11 +197,22 @@ static unsigned long do_bootefi_exec(void *efi, void *fdt) #ifdef CONFIG_LCD efi_gop_register(); #endif +#ifdef CONFIG_NET + void *nethandle = loaded_image_info.device_handle; + efi_net_register(&nethandle); - /* Call our payload! */ -#ifdef DEBUG_EFI - printf("%s:%d Jumping to 0x%lx\n", __func__, __LINE__, (long)entry); + if (!memcmp(bootefi_device_path[0].str, "N\0e\0t", 6)) + loaded_image_info.device_handle = nethandle; #endif + + /* Call our payload! */ + debug("%s:%d Jumping to 0x%lx\n", __func__, __LINE__, (long)entry); + + if (setjmp(&loaded_image_info.exit_jmp)) { + efi_status_t status = loaded_image_info.exit_status; + return status == EFI_SUCCESS ? 0 : -EINVAL; + } + return entry(&loaded_image_info, &systab); } diff --git a/cmd/bootm.c b/cmd/bootm.c index 1bca6fa920e..f5e91f40a9b 100644 --- a/cmd/bootm.c +++ b/cmd/bootm.c @@ -372,8 +372,8 @@ next_bank: ; #endif #if defined(CONFIG_CMD_IMLS_NAND) -static int nand_imls_legacyimage(nand_info_t *nand, int nand_dev, loff_t off, - size_t len) +static int nand_imls_legacyimage(struct mtd_info *mtd, int nand_dev, + loff_t off, size_t len) { void *imgdata; int ret; @@ -386,8 +386,7 @@ static int nand_imls_legacyimage(nand_info_t *nand, int nand_dev, loff_t off, return -ENOMEM; } - ret = nand_read_skip_bad(nand, off, &len, - imgdata); + ret = nand_read_skip_bad(mtd, off, &len, imgdata); if (ret < 0 && ret != -EUCLEAN) { free(imgdata); return ret; @@ -413,8 +412,8 @@ static int nand_imls_legacyimage(nand_info_t *nand, int nand_dev, loff_t off, return 0; } -static int nand_imls_fitimage(nand_info_t *nand, int nand_dev, loff_t off, - size_t len) +static int nand_imls_fitimage(struct mtd_info *mtd, int nand_dev, loff_t off, + size_t len) { void *imgdata; int ret; @@ -427,8 +426,7 @@ static int nand_imls_fitimage(nand_info_t *nand, int nand_dev, loff_t off, return -ENOMEM; } - ret = nand_read_skip_bad(nand, off, &len, - imgdata); + ret = nand_read_skip_bad(mtd, off, &len, imgdata); if (ret < 0 && ret != -EUCLEAN) { free(imgdata); return ret; @@ -449,7 +447,7 @@ static int nand_imls_fitimage(nand_info_t *nand, int nand_dev, loff_t off, static int do_imls_nand(void) { - nand_info_t *nand; + struct mtd_info *mtd; int nand_dev = nand_curr_device; size_t len; loff_t off; @@ -463,20 +461,20 @@ static int do_imls_nand(void) printf("\n"); for (nand_dev = 0; nand_dev < CONFIG_SYS_MAX_NAND_DEVICE; nand_dev++) { - nand = &nand_info[nand_dev]; - if (!nand->name || !nand->size) + mtd = nand_info[nand_dev]; + if (!mtd->name || !mtd->size) continue; - for (off = 0; off < nand->size; off += nand->erasesize) { + for (off = 0; off < mtd->size; off += mtd->erasesize) { const image_header_t *header; int ret; - if (nand_block_isbad(nand, off)) + if (nand_block_isbad(mtd, off)) continue; len = sizeof(buffer); - ret = nand_read(nand, off, &len, (u8 *)buffer); + ret = nand_read(mtd, off, &len, (u8 *)buffer); if (ret < 0 && ret != -EUCLEAN) { printf("NAND read error %d at offset %08llX\n", ret, off); @@ -489,13 +487,13 @@ static int do_imls_nand(void) header = (const image_header_t *)buffer; len = image_get_image_size(header); - nand_imls_legacyimage(nand, nand_dev, off, len); + nand_imls_legacyimage(mtd, nand_dev, off, len); break; #endif #if defined(CONFIG_FIT) case IMAGE_FORMAT_FIT: len = fit_get_size(buffer); - nand_imls_fitimage(nand, nand_dev, off, len); + nand_imls_fitimage(mtd, nand_dev, off, len); break; #endif } @@ -655,6 +653,7 @@ static int booti_setup(bootm_headers_t *images) { struct Image_header *ih; uint64_t dst; + uint64_t image_size; ih = (struct Image_header *)map_sysmem(images->ep, 0); @@ -665,14 +664,16 @@ static int booti_setup(bootm_headers_t *images) if (ih->image_size == 0) { puts("Image lacks image_size field, assuming 16MiB\n"); - ih->image_size = (16 << 20); + image_size = 16 << 20; + } else { + image_size = le64_to_cpu(ih->image_size); } /* * If we are not at the correct run-time location, set the new * correct location and then move the image there. */ - dst = gd->bd->bi_dram[0].start + le32_to_cpu(ih->text_offset); + dst = gd->bd->bi_dram[0].start + le64_to_cpu(ih->text_offset); unmap_sysmem(ih); @@ -683,7 +684,7 @@ static int booti_setup(bootm_headers_t *images) src = (void *)images->ep; images->ep = dst; - memmove((void *)dst, src, le32_to_cpu(ih->image_size)); + memmove((void *)dst, src, image_size); } return 0; diff --git a/cmd/disk.c b/cmd/disk.c index fcc41231271..92de3af8a5c 100644 --- a/cmd/disk.c +++ b/cmd/disk.c @@ -13,7 +13,8 @@ int common_diskboot(cmd_tbl_t *cmdtp, const char *intf, int argc, char *const argv[]) { - int dev, part; + __maybe_unused int dev; + int part; ulong addr = CONFIG_SYS_LOAD_ADDR; ulong cnt; disk_partition_t info; diff --git a/cmd/itest.c b/cmd/itest.c index fb4d797e43d..60626c7fe9c 100644 --- a/cmd/itest.c +++ b/cmd/itest.c @@ -65,13 +65,13 @@ static long evalexp(char *s, int w) } switch (w) { case 1: - l = (long)(*(unsigned char *)buf); + l = (long)(*(u8 *)buf); break; case 2: - l = (long)(*(unsigned short *)buf); + l = (long)(*(u16 *)buf); break; case 4: - l = (long)(*(unsigned long *)buf); + l = (long)(*(u32 *)buf); break; } unmap_physmem(buf, w); diff --git a/cmd/jffs2.c b/cmd/jffs2.c index 0b2eefa1954..f00d53a6c83 100644 --- a/cmd/jffs2.c +++ b/cmd/jffs2.c @@ -167,7 +167,7 @@ static int mtd_device_validate(u8 type, u8 num, u32 *size) } else if (type == MTD_DEV_TYPE_NAND) { #if defined(CONFIG_JFFS2_NAND) && defined(CONFIG_CMD_NAND) if (num < CONFIG_SYS_MAX_NAND_DEVICE) { - *size = nand_info[num].size; + *size = nand_info[num]->size; return 0; } @@ -242,11 +242,11 @@ static int mtd_id_parse(const char *id, const char **ret_id, u8 *dev_type, u8 *d static inline u32 get_part_sector_size_nand(struct mtdids *id) { #if defined(CONFIG_JFFS2_NAND) && defined(CONFIG_CMD_NAND) - nand_info_t *nand; + struct mtd_info *mtd; - nand = &nand_info[id->num]; + mtd = nand_info[id->num]; - return nand->erasesize; + return mtd->erasesize; #else BUG(); return 0; diff --git a/cmd/mmc.c b/cmd/mmc.c index eb4a547a970..b2761e934bd 100644 --- a/cmd/mmc.c +++ b/cmd/mmc.c @@ -11,66 +11,6 @@ #include <mmc.h> static int curr_device = -1; -#ifndef CONFIG_GENERIC_MMC -int do_mmc (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) -{ - int dev; - - if (argc < 2) - return CMD_RET_USAGE; - - if (strcmp(argv[1], "init") == 0) { - if (argc == 2) { - if (curr_device < 0) - dev = 1; - else - dev = curr_device; - } else if (argc == 3) { - dev = (int)simple_strtoul(argv[2], NULL, 10); - } else { - return CMD_RET_USAGE; - } - - if (mmc_legacy_init(dev) != 0) { - puts("No MMC card found\n"); - return 1; - } - - curr_device = dev; - printf("mmc%d is available\n", curr_device); - } else if (strcmp(argv[1], "device") == 0) { - if (argc == 2) { - if (curr_device < 0) { - puts("No MMC device available\n"); - return 1; - } - } else if (argc == 3) { - dev = (int)simple_strtoul(argv[2], NULL, 10); - -#ifdef CONFIG_SYS_MMC_SET_DEV - if (mmc_set_dev(dev) != 0) - return 1; -#endif - curr_device = dev; - } else { - return CMD_RET_USAGE; - } - - printf("mmc%d is current device\n", curr_device); - } else { - return CMD_RET_USAGE; - } - - return 0; -} - -U_BOOT_CMD( - mmc, 3, 1, do_mmc, - "MMC sub-system", - "init [dev] - init MMC sub system\n" - "mmc device [dev] - show or set current device" -); -#else /* !CONFIG_GENERIC_MMC */ static void print_mmcinfo(struct mmc *mmc) { @@ -881,5 +821,3 @@ U_BOOT_CMD( "display MMC info", "- display info of the current MMC device" ); - -#endif /* !CONFIG_GENERIC_MMC */ diff --git a/cmd/nand.c b/cmd/nand.c index a6b67e29f1c..583a18f341a 100644 --- a/cmd/nand.c +++ b/cmd/nand.c @@ -38,7 +38,8 @@ int find_dev_and_part(const char *id, struct mtd_device **dev, u8 *part_num, struct part_info **part); #endif -static int nand_dump(nand_info_t *nand, ulong off, int only_oob, int repeat) +static int nand_dump(struct mtd_info *mtd, ulong off, int only_oob, + int repeat) { int i; u_char *datbuf, *oobbuf, *p; @@ -46,32 +47,32 @@ static int nand_dump(nand_info_t *nand, ulong off, int only_oob, int repeat) int ret = 0; if (repeat) - off = last + nand->writesize; + off = last + mtd->writesize; last = off; - datbuf = memalign(ARCH_DMA_MINALIGN, nand->writesize); + datbuf = memalign(ARCH_DMA_MINALIGN, mtd->writesize); if (!datbuf) { puts("No memory for page buffer\n"); return 1; } - oobbuf = memalign(ARCH_DMA_MINALIGN, nand->oobsize); + oobbuf = memalign(ARCH_DMA_MINALIGN, mtd->oobsize); if (!oobbuf) { puts("No memory for page buffer\n"); ret = 1; goto free_dat; } - off &= ~(nand->writesize - 1); + off &= ~(mtd->writesize - 1); loff_t addr = (loff_t) off; struct mtd_oob_ops ops; memset(&ops, 0, sizeof(ops)); ops.datbuf = datbuf; ops.oobbuf = oobbuf; - ops.len = nand->writesize; - ops.ooblen = nand->oobsize; + ops.len = mtd->writesize; + ops.ooblen = mtd->oobsize; ops.mode = MTD_OPS_RAW; - i = mtd_read_oob(nand, addr, &ops); + i = mtd_read_oob(mtd, addr, &ops); if (i < 0) { printf("Error (%d) reading page %08lx\n", i, off); ret = 1; @@ -80,7 +81,7 @@ static int nand_dump(nand_info_t *nand, ulong off, int only_oob, int repeat) printf("Page %08lx dump:\n", off); if (!only_oob) { - i = nand->writesize >> 4; + i = mtd->writesize >> 4; p = datbuf; while (i--) { @@ -94,7 +95,7 @@ static int nand_dump(nand_info_t *nand, ulong off, int only_oob, int repeat) } puts("OOB:\n"); - i = nand->oobsize >> 3; + i = mtd->oobsize >> 3; p = oobbuf; while (i--) { printf("\t%02x %02x %02x %02x %02x %02x %02x %02x\n", @@ -115,7 +116,7 @@ free_dat: static int set_dev(int dev) { if (dev < 0 || dev >= CONFIG_SYS_MAX_NAND_DEVICE || - !nand_info[dev].name) { + !nand_info[dev]->name) { puts("No such device\n"); return -1; } @@ -123,12 +124,12 @@ static int set_dev(int dev) if (nand_curr_device == dev) return 0; - printf("Device %d: %s", dev, nand_info[dev].name); + printf("Device %d: %s", dev, nand_info[dev]->name); puts("... is now current device\n"); nand_curr_device = dev; #ifdef CONFIG_SYS_NAND_SELECT_DEVICE - board_nand_select_device(nand_info[dev].priv, dev); + board_nand_select_device(nand_info[dev]->priv, dev); #endif return 0; @@ -152,32 +153,32 @@ static void print_status(ulong start, ulong end, ulong erasesize, int status) ((status & NAND_LOCK_STATUS_UNLOCK) ? "UNLOCK " : "")); } -static void do_nand_status(nand_info_t *nand) +static void do_nand_status(struct mtd_info *mtd) { ulong block_start = 0; ulong off; int last_status = -1; - struct nand_chip *nand_chip = nand->priv; + struct nand_chip *nand_chip = mtd_to_nand(mtd); /* check the WP bit */ - nand_chip->cmdfunc(nand, NAND_CMD_STATUS, -1, -1); + nand_chip->cmdfunc(mtd, NAND_CMD_STATUS, -1, -1); printf("device is %swrite protected\n", - (nand_chip->read_byte(nand) & 0x80 ? - "NOT " : "")); + (nand_chip->read_byte(mtd) & 0x80 ? + "NOT " : "")); - for (off = 0; off < nand->size; off += nand->erasesize) { - int s = nand_get_lock_status(nand, off); + for (off = 0; off < mtd->size; off += mtd->erasesize) { + int s = nand_get_lock_status(mtd, off); /* print message only if status has changed */ if (s != last_status && off != 0) { - print_status(block_start, off, nand->erasesize, + print_status(block_start, off, mtd->erasesize, last_status); block_start = off; } last_status = s; } /* Print the last block info */ - print_status(block_start, off, nand->erasesize, last_status); + print_status(block_start, off, mtd->erasesize, last_status); } #endif @@ -188,10 +189,10 @@ int do_nand_env_oob(cmd_tbl_t *cmdtp, int argc, char *const argv[]) { int ret; uint32_t oob_buf[ENV_OFFSET_SIZE/sizeof(uint32_t)]; - nand_info_t *nand = &nand_info[0]; + struct mtd_info *mtd = nand_info[0]; char *cmd = argv[1]; - if (CONFIG_SYS_MAX_NAND_DEVICE == 0 || !nand->name) { + if (CONFIG_SYS_MAX_NAND_DEVICE == 0 || !mtd->name) { puts("no devices available\n"); return 1; } @@ -199,7 +200,7 @@ int do_nand_env_oob(cmd_tbl_t *cmdtp, int argc, char *const argv[]) set_dev(0); if (!strcmp(cmd, "get")) { - ret = get_nand_env_oob(nand, &nand_env_oob_offset); + ret = get_nand_env_oob(mtd, &nand_env_oob_offset); if (ret) return 1; @@ -215,7 +216,7 @@ int do_nand_env_oob(cmd_tbl_t *cmdtp, int argc, char *const argv[]) /* We don't care about size, or maxsize. */ if (mtd_arg_off(argv[2], &idx, &addr, &maxsize, &maxsize, - MTD_DEV_TYPE_NAND, nand_info[idx].size)) { + MTD_DEV_TYPE_NAND, nand_info[idx]->size)) { puts("Offset or partition name expected\n"); return 1; } @@ -229,15 +230,15 @@ int do_nand_env_oob(cmd_tbl_t *cmdtp, int argc, char *const argv[]) return 1; } - if (nand->oobavail < ENV_OFFSET_SIZE) { + if (mtd->oobavail < ENV_OFFSET_SIZE) { printf("Insufficient available OOB bytes:\n" "%d OOB bytes available but %d required for " "env.oob support\n", - nand->oobavail, ENV_OFFSET_SIZE); + mtd->oobavail, ENV_OFFSET_SIZE); return 1; } - if ((addr & (nand->erasesize - 1)) != 0) { + if ((addr & (mtd->erasesize - 1)) != 0) { printf("Environment offset must be block-aligned\n"); return 1; } @@ -249,15 +250,15 @@ int do_nand_env_oob(cmd_tbl_t *cmdtp, int argc, char *const argv[]) ops.oobbuf = (void *) oob_buf; oob_buf[0] = ENV_OOB_MARKER; - oob_buf[1] = addr / nand->erasesize; + oob_buf[1] = addr / mtd->erasesize; - ret = nand->write_oob(nand, ENV_OFFSET_SIZE, &ops); + ret = mtd->write_oob(mtd, ENV_OFFSET_SIZE, &ops); if (ret) { printf("Error writing OOB block 0\n"); return ret; } - ret = get_nand_env_oob(nand, &nand_env_oob_offset); + ret = get_nand_env_oob(mtd, &nand_env_oob_offset); if (ret) { printf("Error reading env offset in OOB\n"); return ret; @@ -283,29 +284,29 @@ usage: static void nand_print_and_set_info(int idx) { - nand_info_t *nand = &nand_info[idx]; - struct nand_chip *chip = nand->priv; + struct mtd_info *mtd = nand_info[idx]; + struct nand_chip *chip = mtd_to_nand(mtd); printf("Device %d: ", idx); if (chip->numchips > 1) printf("%dx ", chip->numchips); printf("%s, sector size %u KiB\n", - nand->name, nand->erasesize >> 10); - printf(" Page size %8d b\n", nand->writesize); - printf(" OOB size %8d b\n", nand->oobsize); - printf(" Erase size %8d b\n", nand->erasesize); + mtd->name, mtd->erasesize >> 10); + printf(" Page size %8d b\n", mtd->writesize); + printf(" OOB size %8d b\n", mtd->oobsize); + printf(" Erase size %8d b\n", mtd->erasesize); printf(" subpagesize %8d b\n", chip->subpagesize); printf(" options 0x%8x\n", chip->options); printf(" bbt options 0x%8x\n", chip->bbt_options); /* Set geometry info */ - setenv_hex("nand_writesize", nand->writesize); - setenv_hex("nand_oobsize", nand->oobsize); - setenv_hex("nand_erasesize", nand->erasesize); + setenv_hex("nand_writesize", mtd->writesize); + setenv_hex("nand_oobsize", mtd->oobsize); + setenv_hex("nand_erasesize", mtd->erasesize); } -static int raw_access(nand_info_t *nand, ulong addr, loff_t off, ulong count, - int read) +static int raw_access(struct mtd_info *mtd, ulong addr, loff_t off, + ulong count, int read) { int ret = 0; @@ -313,18 +314,18 @@ static int raw_access(nand_info_t *nand, ulong addr, loff_t off, ulong count, /* Raw access */ mtd_oob_ops_t ops = { .datbuf = (u8 *)addr, - .oobbuf = ((u8 *)addr) + nand->writesize, - .len = nand->writesize, - .ooblen = nand->oobsize, + .oobbuf = ((u8 *)addr) + mtd->writesize, + .len = mtd->writesize, + .ooblen = mtd->oobsize, .mode = MTD_OPS_RAW }; if (read) { - ret = mtd_read_oob(nand, off, &ops); + ret = mtd_read_oob(mtd, off, &ops); } else { - ret = mtd_write_oob(nand, off, &ops); + ret = mtd_write_oob(mtd, off, &ops); if (!ret) - ret = nand_verify_page_oob(nand, &ops, off); + ret = nand_verify_page_oob(mtd, &ops, off); } if (ret) { @@ -333,8 +334,8 @@ static int raw_access(nand_info_t *nand, ulong addr, loff_t off, ulong count, break; } - addr += nand->writesize + nand->oobsize; - off += nand->writesize; + addr += mtd->writesize + mtd->oobsize; + off += mtd->writesize; } return ret; @@ -348,18 +349,18 @@ static void adjust_size_for_badblocks(loff_t *size, loff_t offset, int dev) /* We grab the nand info object here fresh because this is usually * called after arg_off_size() which can change the value of dev. */ - nand_info_t *nand = &nand_info[dev]; + struct mtd_info *mtd = nand_info[dev]; loff_t maxoffset = offset + *size; int badblocks = 0; /* count badblocks in NAND from offset to offset + size */ - for (; offset < maxoffset; offset += nand->erasesize) { - if (nand_block_isbad(nand, offset)) + for (; offset < maxoffset; offset += mtd->erasesize) { + if (nand_block_isbad(mtd, offset)) badblocks++; } /* adjust size if any bad blocks found */ if (badblocks) { - *size -= badblocks * nand->erasesize; + *size -= badblocks * mtd->erasesize; printf("size adjusted to 0x%llx (%d bad blocks)\n", (unsigned long long)*size, badblocks); } @@ -371,7 +372,7 @@ static int do_nand(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) ulong addr; loff_t off, size, maxsize; char *cmd, *s; - nand_info_t *nand; + struct mtd_info *mtd; #ifdef CONFIG_SYS_NAND_QUIET int quiet = CONFIG_SYS_NAND_QUIET; #else @@ -398,7 +399,7 @@ static int do_nand(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) putc('\n'); for (i = 0; i < CONFIG_SYS_MAX_NAND_DEVICE; i++) { - if (nand_info[i].name) + if (nand_info[i]->name) nand_print_and_set_info(i); } return 0; @@ -433,16 +434,16 @@ static int do_nand(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) * for another device is to be used. */ if (dev < 0 || dev >= CONFIG_SYS_MAX_NAND_DEVICE || - !nand_info[dev].name) { + !nand_info[dev]->name) { puts("\nno devices available\n"); return 1; } - nand = &nand_info[dev]; + mtd = nand_info[dev]; if (strcmp(cmd, "bad") == 0) { printf("\nDevice %d bad blocks:\n", dev); - for (off = 0; off < nand->size; off += nand->erasesize) - if (nand_block_isbad(nand, off)) + for (off = 0; off < mtd->size; off += mtd->erasesize) + if (nand_block_isbad(mtd, off)) printf(" %08llx\n", (unsigned long long)off); return 0; } @@ -496,13 +497,13 @@ static int do_nand(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) /* skip first two or three arguments, look for offset and size */ if (mtd_arg_off_size(argc - o, argv + o, &dev, &off, &size, &maxsize, MTD_DEV_TYPE_NAND, - nand_info[dev].size) != 0) + nand_info[dev]->size) != 0) return 1; if (set_dev(dev)) return 1; - nand = &nand_info[dev]; + mtd = nand_info[dev]; memset(&opts, 0, sizeof(opts)); opts.offset = off; @@ -524,7 +525,7 @@ static int do_nand(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) } } } - ret = nand_erase_opts(nand, &opts); + ret = nand_erase_opts(mtd, &opts); printf("%s\n", ret ? "ERROR" : "OK"); return ret == 0 ? 0 : 1; @@ -535,7 +536,7 @@ static int do_nand(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) goto usage; off = (int)simple_strtoul(argv[2], NULL, 16); - ret = nand_dump(nand, off, !strcmp(&cmd[4], ".oob"), repeat); + ret = nand_dump(mtd, off, !strcmp(&cmd[4], ".oob"), repeat); return ret == 0 ? 1 : 0; } @@ -561,30 +562,30 @@ static int do_nand(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) if (mtd_arg_off(argv[3], &dev, &off, &size, &maxsize, MTD_DEV_TYPE_NAND, - nand_info[dev].size)) + nand_info[dev]->size)) return 1; if (set_dev(dev)) return 1; - nand = &nand_info[dev]; + mtd = nand_info[dev]; if (argc > 4 && !str2long(argv[4], &pagecount)) { printf("'%s' is not a number\n", argv[4]); return 1; } - if (pagecount * nand->writesize > size) { + if (pagecount * mtd->writesize > size) { puts("Size exceeds partition or device limit\n"); return -1; } - rwsize = pagecount * (nand->writesize + nand->oobsize); + rwsize = pagecount * (mtd->writesize + mtd->oobsize); } else { if (mtd_arg_off_size(argc - 3, argv + 3, &dev, &off, &size, &maxsize, MTD_DEV_TYPE_NAND, - nand_info[dev].size) != 0) + nand_info[dev]->size) != 0) return 1; if (set_dev(dev)) @@ -596,16 +597,16 @@ static int do_nand(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) rwsize = size; } - nand = &nand_info[dev]; + mtd = nand_info[dev]; if (!s || !strcmp(s, ".jffs2") || !strcmp(s, ".e") || !strcmp(s, ".i")) { if (read) - ret = nand_read_skip_bad(nand, off, &rwsize, + ret = nand_read_skip_bad(mtd, off, &rwsize, NULL, maxsize, (u_char *)addr); else - ret = nand_write_skip_bad(nand, off, &rwsize, + ret = nand_write_skip_bad(mtd, off, &rwsize, NULL, maxsize, (u_char *)addr, WITH_WR_VERIFY); @@ -615,7 +616,7 @@ static int do_nand(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) printf("Unknown nand command suffix '%s'\n", s); return 1; } - ret = nand_write_skip_bad(nand, off, &rwsize, NULL, + ret = nand_write_skip_bad(mtd, off, &rwsize, NULL, maxsize, (u_char *)addr, WITH_DROP_FFS | WITH_WR_VERIFY); #endif @@ -628,11 +629,11 @@ static int do_nand(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) }; if (read) - ret = mtd_read_oob(nand, off, &ops); + ret = mtd_read_oob(mtd, off, &ops); else - ret = mtd_write_oob(nand, off, &ops); + ret = mtd_write_oob(mtd, off, &ops); } else if (raw) { - ret = raw_access(nand, addr, off, pagecount, read); + ret = raw_access(mtd, addr, off, pagecount, read); } else { printf("Unknown nand command suffix '%s'.\n", s); return 1; @@ -655,8 +656,8 @@ static int do_nand(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) } printf("\nNAND torture: device %d offset 0x%llx size 0x%x\n", - dev, off, nand->erasesize); - ret = nand_torture(nand, off); + dev, off, mtd->erasesize); + ret = nand_torture(mtd, off); printf(" %s\n", ret ? "Failed" : "Passed"); return ret == 0 ? 0 : 1; @@ -673,7 +674,7 @@ static int do_nand(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) while (argc > 0) { addr = simple_strtoul(*argv, NULL, 16); - if (mtd_block_markbad(nand, addr)) { + if (mtd_block_markbad(mtd, addr)) { printf("block 0x%08lx NOT marked " "as bad! ERROR %d\n", addr, ret); @@ -705,9 +706,9 @@ static int do_nand(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) status = 1; } if (status) { - do_nand_status(nand); + do_nand_status(mtd); } else { - if (!nand_lock(nand, tight)) { + if (!nand_lock(mtd, tight)) { puts("NAND flash successfully locked\n"); } else { puts("Error locking NAND flash\n"); @@ -727,13 +728,13 @@ static int do_nand(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) if (mtd_arg_off_size(argc - 2, argv + 2, &dev, &off, &size, &maxsize, MTD_DEV_TYPE_NAND, - nand_info[dev].size) < 0) + nand_info[dev]->size) < 0) return 1; if (set_dev(dev)) return 1; - if (!nand_unlock(&nand_info[dev], off, size, allexcept)) { + if (!nand_unlock(nand_info[dev], off, size, allexcept)) { puts("NAND flash successfully unlocked\n"); } else { puts("Error unlocking NAND flash, " @@ -801,7 +802,7 @@ U_BOOT_CMD( "NAND sub-system", nand_help_text ); -static int nand_load_image(cmd_tbl_t *cmdtp, nand_info_t *nand, +static int nand_load_image(cmd_tbl_t *cmdtp, struct mtd_info *mtd, ulong offset, ulong addr, char *cmd) { int r; @@ -822,11 +823,11 @@ static int nand_load_image(cmd_tbl_t *cmdtp, nand_info_t *nand, return 1; } - printf("\nLoading from %s, offset 0x%lx\n", nand->name, offset); + printf("\nLoading from %s, offset 0x%lx\n", mtd->name, offset); - cnt = nand->writesize; - r = nand_read_skip_bad(nand, offset, &cnt, NULL, nand->size, - (u_char *)addr); + cnt = mtd->writesize; + r = nand_read_skip_bad(mtd, offset, &cnt, NULL, mtd->size, + (u_char *)addr); if (r) { puts("** Read error\n"); bootstage_error(BOOTSTAGE_ID_NAND_HDR_READ); @@ -860,8 +861,8 @@ static int nand_load_image(cmd_tbl_t *cmdtp, nand_info_t *nand, } bootstage_mark(BOOTSTAGE_ID_NAND_TYPE); - r = nand_read_skip_bad(nand, offset, &cnt, NULL, nand->size, - (u_char *)addr); + r = nand_read_skip_bad(mtd, offset, &cnt, NULL, mtd->size, + (u_char *)addr); if (r) { puts("** Read error\n"); bootstage_error(BOOTSTAGE_ID_NAND_READ); @@ -914,7 +915,7 @@ static int do_nandboot(cmd_tbl_t *cmdtp, int flag, int argc, addr = simple_strtoul(argv[1], NULL, 16); else addr = CONFIG_SYS_LOAD_ADDR; - return nand_load_image(cmdtp, &nand_info[dev->id->num], + return nand_load_image(cmdtp, nand_info[dev->id->num], part->offset, addr, argv[0]); } } @@ -957,14 +958,14 @@ usage: idx = simple_strtoul(boot_device, NULL, 16); - if (idx < 0 || idx >= CONFIG_SYS_MAX_NAND_DEVICE || !nand_info[idx].name) { + if (idx < 0 || idx >= CONFIG_SYS_MAX_NAND_DEVICE || !nand_info[idx]->name) { printf("\n** Device %d not available\n", idx); bootstage_error(BOOTSTAGE_ID_NAND_AVAILABLE); return 1; } bootstage_mark(BOOTSTAGE_ID_NAND_AVAILABLE); - return nand_load_image(cmdtp, &nand_info[idx], offset, addr, argv[0]); + return nand_load_image(cmdtp, nand_info[idx], offset, addr, argv[0]); } U_BOOT_CMD(nboot, 4, 1, do_nandboot, diff --git a/cmd/qfw.c b/cmd/qfw.c new file mode 100644 index 00000000000..12436ec9b4e --- /dev/null +++ b/cmd/qfw.c @@ -0,0 +1,194 @@ +/* + * (C) Copyright 2015 Miao Yan <[email protected]> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <command.h> +#include <errno.h> +#include <qfw.h> + +/* + * This function prepares kernel for zboot. It loads kernel data + * to 'load_addr', initrd to 'initrd_addr' and kernel command + * line using qemu fw_cfg interface. + */ +static int qemu_fwcfg_setup_kernel(void *load_addr, void *initrd_addr) +{ + char *data_addr; + uint32_t setup_size, kernel_size, cmdline_size, initrd_size; + + qemu_fwcfg_read_entry(FW_CFG_SETUP_SIZE, 4, &setup_size); + qemu_fwcfg_read_entry(FW_CFG_KERNEL_SIZE, 4, &kernel_size); + + if (setup_size == 0 || kernel_size == 0) { + printf("warning: no kernel available\n"); + return -1; + } + + data_addr = load_addr; + qemu_fwcfg_read_entry(FW_CFG_SETUP_DATA, + le32_to_cpu(setup_size), data_addr); + data_addr += le32_to_cpu(setup_size); + + qemu_fwcfg_read_entry(FW_CFG_KERNEL_DATA, + le32_to_cpu(kernel_size), data_addr); + data_addr += le32_to_cpu(kernel_size); + + data_addr = initrd_addr; + qemu_fwcfg_read_entry(FW_CFG_INITRD_SIZE, 4, &initrd_size); + if (initrd_size == 0) { + printf("warning: no initrd available\n"); + } else { + qemu_fwcfg_read_entry(FW_CFG_INITRD_DATA, + le32_to_cpu(initrd_size), data_addr); + data_addr += le32_to_cpu(initrd_size); + } + + qemu_fwcfg_read_entry(FW_CFG_CMDLINE_SIZE, 4, &cmdline_size); + if (cmdline_size) { + qemu_fwcfg_read_entry(FW_CFG_CMDLINE_DATA, + le32_to_cpu(cmdline_size), data_addr); + /* + * if kernel cmdline only contains '\0', (e.g. no -append + * when invoking qemu), do not update bootargs + */ + if (*data_addr != '\0') { + if (setenv("bootargs", data_addr) < 0) + printf("warning: unable to change bootargs\n"); + } + } + + printf("loading kernel to address %p size %x", load_addr, + le32_to_cpu(kernel_size)); + if (initrd_size) + printf(" initrd %p size %x\n", + initrd_addr, + le32_to_cpu(initrd_size)); + else + printf("\n"); + + return 0; +} + +static int qemu_fwcfg_list_firmware(void) +{ + int ret; + struct fw_cfg_file_iter iter; + struct fw_file *file; + + /* make sure fw_list is loaded */ + ret = qemu_fwcfg_read_firmware_list(); + if (ret) + return ret; + + + for (file = qemu_fwcfg_file_iter_init(&iter); + !qemu_fwcfg_file_iter_end(&iter); + file = qemu_fwcfg_file_iter_next(&iter)) { + printf("%-56s\n", file->cfg.name); + } + + return 0; +} + +static int qemu_fwcfg_do_list(cmd_tbl_t *cmdtp, int flag, + int argc, char * const argv[]) +{ + if (qemu_fwcfg_list_firmware() < 0) + return CMD_RET_FAILURE; + + return 0; +} + +static int qemu_fwcfg_do_cpus(cmd_tbl_t *cmdtp, int flag, + int argc, char * const argv[]) +{ + int ret = qemu_fwcfg_online_cpus(); + if (ret < 0) { + printf("QEMU fw_cfg interface not found\n"); + return CMD_RET_FAILURE; + } + + printf("%d cpu(s) online\n", qemu_fwcfg_online_cpus()); + + return 0; +} + +static int qemu_fwcfg_do_load(cmd_tbl_t *cmdtp, int flag, + int argc, char * const argv[]) +{ + char *env; + void *load_addr; + void *initrd_addr; + + env = getenv("loadaddr"); + load_addr = env ? + (void *)simple_strtoul(env, NULL, 16) : +#ifdef CONFIG_LOADADDR + (void *)CONFIG_LOADADDR; +#else + NULL; +#endif + + env = getenv("ramdiskaddr"); + initrd_addr = env ? + (void *)simple_strtoul(env, NULL, 16) : +#ifdef CONFIG_RAMDISK_ADDR + (void *)CONFIG_RAMDISK_ADDR; +#else + NULL; +#endif + + if (argc == 2) { + load_addr = (void *)simple_strtoul(argv[0], NULL, 16); + initrd_addr = (void *)simple_strtoul(argv[1], NULL, 16); + } else if (argc == 1) { + load_addr = (void *)simple_strtoul(argv[0], NULL, 16); + } + + if (!load_addr || !initrd_addr) { + printf("missing load or initrd address\n"); + return CMD_RET_FAILURE; + } + + return qemu_fwcfg_setup_kernel(load_addr, initrd_addr); +} + +static cmd_tbl_t fwcfg_commands[] = { + U_BOOT_CMD_MKENT(list, 0, 1, qemu_fwcfg_do_list, "", ""), + U_BOOT_CMD_MKENT(cpus, 0, 1, qemu_fwcfg_do_cpus, "", ""), + U_BOOT_CMD_MKENT(load, 2, 1, qemu_fwcfg_do_load, "", ""), +}; + +static int do_qemu_fw(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + int ret; + cmd_tbl_t *fwcfg_cmd; + + if (!qemu_fwcfg_present()) { + printf("QEMU fw_cfg interface not found\n"); + return CMD_RET_USAGE; + } + + fwcfg_cmd = find_cmd_tbl(argv[1], fwcfg_commands, + ARRAY_SIZE(fwcfg_commands)); + argc -= 2; + argv += 2; + if (!fwcfg_cmd || argc > fwcfg_cmd->maxargs) + return CMD_RET_USAGE; + + ret = fwcfg_cmd->cmd(fwcfg_cmd, flag, argc, argv); + + return cmd_process_error(fwcfg_cmd, ret); +} + +U_BOOT_CMD( + qfw, 4, 1, do_qemu_fw, + "QEMU firmware interface", + "<command>\n" + " - list : print firmware(s) currently loaded\n" + " - cpus : print online cpu number\n" + " - load <kernel addr> <initrd addr> : load kernel and initrd (if any), and setup for zboot\n" +) diff --git a/cmd/ubi.c b/cmd/ubi.c index 753a4dba3d7..4a92d840b6c 100644 --- a/cmd/ubi.c +++ b/cmd/ubi.c @@ -443,14 +443,8 @@ static int ubi_dev_scan(struct mtd_info *info, char *ubidev, return 0; } -int ubi_part(char *part_name, const char *vid_header_offset) +int ubi_detach(void) { - int err = 0; - char mtd_dev[16]; - struct mtd_device *dev; - struct part_info *part; - u8 pnum; - if (mtdparts_init() != 0) { printf("Error initializing mtdparts!\n"); return 1; @@ -466,17 +460,28 @@ int ubi_part(char *part_name, const char *vid_header_offset) cmd_ubifs_umount(); #endif - /* todo: get dev number for NAND... */ - ubi_dev.nr = 0; - /* * Call ubi_exit() before re-initializing the UBI subsystem */ if (ubi_initialized) { ubi_exit(); del_mtd_partitions(ubi_dev.mtd_info); + ubi_initialized = 0; } + ubi_dev.selected = 0; + return 0; +} + +int ubi_part(char *part_name, const char *vid_header_offset) +{ + int err = 0; + char mtd_dev[16]; + struct mtd_device *dev; + struct part_info *part; + u8 pnum; + + ubi_detach(); /* * Search the mtd device number where this partition * is located @@ -517,6 +522,15 @@ static int do_ubi(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) if (argc < 2) return CMD_RET_USAGE; + + if (strcmp(argv[1], "detach") == 0) { + if (argc < 2) + return CMD_RET_USAGE; + + return ubi_detach(); + } + + if (strcmp(argv[1], "part") == 0) { const char *vid_header_offset = NULL; @@ -661,7 +675,9 @@ static int do_ubi(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) U_BOOT_CMD( ubi, 6, 1, do_ubi, "ubi commands", - "part [part] [offset]\n" + "detach" + " - detach ubi from a mtd partition\n" + "ubi part [part] [offset]\n" " - Show or set current partition (with optional VID" " header offset)\n" "ubi info [l[ayout]]" |
