From dd1b4bcbf2276093417c05255f72be3fe6078d0e Mon Sep 17 00:00:00 2001 From: Allen Martin Date: Mon, 19 Aug 2013 22:27:07 -0700 Subject: tegrarcm: Add command to pass miniloader in from file Add --miniloader and --miniloader_entry commands which allow passing in the miniloader from a file and specifying the miniloader entry address from the command line instead of using built-in miniloader. Signed-off-by: Allen Martin Reviewed-by: Stephen Warren --- src/main.c | 110 +++++++++++++++++++++++++++++++++++++++++------------- src/tegrarcm.1.in | 6 +++ 2 files changed, 91 insertions(+), 25 deletions(-) diff --git a/src/main.c b/src/main.c index 46db14c..fe29df0 100644 --- a/src/main.c +++ b/src/main.c @@ -61,6 +61,7 @@ #include "miniloader/tegra124-miniloader.h" static int initialize_rcm(uint16_t devid, usb_device_t *usb); +static int initialize_miniloader(uint16_t devid, usb_device_t *usb, char *mlfile, uint32_t mlentry); static int wait_status(nv3p_handle_t h3p); static int send_file(nv3p_handle_t h3p, const char *filename); static int download_miniloader(usb_device_t *usb, uint8_t *miniloader, @@ -78,6 +79,8 @@ enum cmdline_opts { OPT_ENTRYADDR, OPT_HELP, OPT_VERSION, + OPT_MINILOADER, + OPT_MINIENTRY, OPT_END, }; @@ -106,6 +109,11 @@ static void usage(char *progname) fprintf(stderr, "\t\tPrint this help information\n"); fprintf(stderr, "\t--version\n"); fprintf(stderr, "\t\tPrint version information and exit\n"); + fprintf(stderr, "\t--miniloader=mlfile\n"); + fprintf(stderr, "\t\tRead the miniloader from file instead of using built-in\n"); + fprintf(stderr, "\t\tminiloader\n"); + fprintf(stderr, "\t--miniloader_entry=\n"); + fprintf(stderr, "\t\tSpecify the entry point for the miniloader\n"); fprintf(stderr, "\n"); } @@ -117,7 +125,7 @@ int main(int argc, char **argv) usb_device_t *usb; nv3p_platform_info_t info; nv3p_handle_t h3p; - int ret; + int ret, ret2; int c; int option_index = 0; char *bctfile = NULL; @@ -126,6 +134,8 @@ int main(int argc, char **argv) uint32_t entryaddr = 0; uint16_t devid; int do_read = 0; + char *mlfile = NULL; + uint32_t mlentry = 0; static struct option long_options[] = { [OPT_BCT] = {"bct", 1, 0, 0}, @@ -134,6 +144,8 @@ int main(int argc, char **argv) [OPT_ENTRYADDR] = {"entryaddr", 1, 0, 0}, [OPT_HELP] = {"help", 0, 0, 0}, [OPT_VERSION] = {"version", 0, 0, 0}, + [OPT_MINILOADER] = {"miniloader", 1, 0, 0}, + [OPT_MINIENTRY] = {"miniloader_entry", 1, 0, 0}, [OPT_END] = {0, 0, 0, 0} }; @@ -163,6 +175,12 @@ int main(int argc, char **argv) print_version(argv[0]); exit(0); break; + case OPT_MINILOADER: + mlfile = optarg; + break; + case OPT_MINIENTRY: + mlentry = strtoul(optarg, NULL, 0); + break; case OPT_HELP: default: usage(argv[0]); @@ -229,8 +247,15 @@ int main(int argc, char **argv) else error(1, errno, "USB read truncated"); - // initialize rcm and download the miniloader to start nv3p - initialize_rcm(devid, usb); + // initialize rcm + ret2 = initialize_rcm(devid, usb); + if (ret2) + error(1, errno, "error initializing RCM protocol"); + + // download the miniloader to start nv3p + ret2 = initialize_miniloader(devid, usb, mlfile, mlentry); + if (ret2) + error(1, errno, "error initializing miniloader"); // device may have re-enumerated, so reopen USB usb_close(usb); @@ -293,9 +318,6 @@ static int initialize_rcm(uint16_t devid, usb_device_t *usb) int msg_len; uint32_t status; int actual_len; - uint8_t *miniloader; - uint32_t miniloader_size; - uint32_t miniloader_entry; // initialize RCM if ((devid & 0xff) == USB_DEVID_NVIDIA_TEGRA20 || @@ -347,27 +369,65 @@ static int initialize_rcm(uint16_t devid, usb_device_t *usb) printf("RCM version: %d.%d\n", RCM_VERSION_MAJOR(status), RCM_VERSION_MINOR(status)); - printf("downloading miniloader to target...\n"); - if ((devid & 0xff) == USB_DEVID_NVIDIA_TEGRA20) { - miniloader = miniloader_tegra20; - miniloader_size = sizeof(miniloader_tegra20); - miniloader_entry = TEGRA20_MINILOADER_ENTRY; - } else if ((devid & 0xff) == USB_DEVID_NVIDIA_TEGRA30) { - miniloader = miniloader_tegra30; - miniloader_size = sizeof(miniloader_tegra30); - miniloader_entry = TEGRA30_MINILOADER_ENTRY; - } else if ((devid & 0xff) == USB_DEVID_NVIDIA_TEGRA114) { - miniloader = miniloader_tegra114; - miniloader_size = sizeof(miniloader_tegra114); - miniloader_entry = TEGRA114_MINILOADER_ENTRY; - } else if ((devid & 0xff) == USB_DEVID_NVIDIA_TEGRA124) { - miniloader = miniloader_tegra124; - miniloader_size = sizeof(miniloader_tegra124); - miniloader_entry = TEGRA124_MINILOADER_ENTRY; + return 0; +} + +static int initialize_miniloader(uint16_t devid, usb_device_t *usb, char *mlfile, uint32_t mlentry) +{ + int fd; + struct stat sb; + int ret; + uint8_t *miniloader; + uint32_t miniloader_size; + uint32_t miniloader_entry; + + // use prebuilt miniloader if not loading from a file + if (mlfile) { + fd = open(mlfile, O_RDONLY, 0); + if (fd < 0) { + dprintf("error opening %s for reading\n", mlfile); + return errno; + } + ret = fstat(fd, &sb); + if (ret) { + dprintf("error on fstat of %s\n", mlfile); + return ret; + } + miniloader_size = sb.st_size; + miniloader = (uint8_t *)malloc(miniloader_size); + if (!miniloader) { + dprintf("error allocating %d bytes for miniloader\n", miniloader_size); + return errno; + } + if (read(fd, miniloader, miniloader_size) != miniloader_size) { + dprintf("error reading from miniloader file"); + return errno; + } + miniloader_entry = mlentry; } else { - fprintf(stderr, "unknown tegra device: 0x%x\n", devid); - return ENODEV; + if ((devid & 0xff) == USB_DEVID_NVIDIA_TEGRA20) { + miniloader = miniloader_tegra20; + miniloader_size = sizeof(miniloader_tegra20); + miniloader_entry = TEGRA20_MINILOADER_ENTRY; + } else if ((devid & 0xff) == USB_DEVID_NVIDIA_TEGRA30) { + miniloader = miniloader_tegra30; + miniloader_size = sizeof(miniloader_tegra30); + miniloader_entry = TEGRA30_MINILOADER_ENTRY; + } else if ((devid & 0xff) == USB_DEVID_NVIDIA_TEGRA114) { + miniloader = miniloader_tegra114; + miniloader_size = sizeof(miniloader_tegra114); + miniloader_entry = TEGRA114_MINILOADER_ENTRY; + } else if ((devid & 0xff) == USB_DEVID_NVIDIA_TEGRA124) { + miniloader = miniloader_tegra124; + miniloader_size = sizeof(miniloader_tegra124); + miniloader_entry = TEGRA124_MINILOADER_ENTRY; + } else { + fprintf(stderr, "unknown tegra device: 0x%x\n", devid); + return ENODEV; + } } + printf("downloading miniloader to target at address 0x%x (%d bytes)...\n", + miniloader_entry, miniloader_size); ret = download_miniloader(usb, miniloader, miniloader_size, miniloader_entry); if (ret) { diff --git a/src/tegrarcm.1.in b/src/tegrarcm.1.in index 7993110..f747fd8 100644 --- a/src/tegrarcm.1.in +++ b/src/tegrarcm.1.in @@ -73,6 +73,12 @@ Print the version number and exit. .B \-\-help Print help text and exit. .TP +.B \-\-miniloader \fImlfile\fP +Read the miniloader from the specified file instead of using the +built-in one. +.TP +.B \-\-miniloader_entry \fImlentry\fP +Specify the entry address of the miniloader. .SH EXAMPLES To download u-boot firmware to a Tegra20 seaboard: -- cgit v1.2.1