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 <amartin@xxxxxxxxxx> --- src/main.c | 112 +++++++++++++++++++++++++++++++++++++++++------------- src/tegrarcm.1.in | 8 ++++ 2 files changed, 93 insertions(+), 27 deletions(-) diff --git a/src/main.c b/src/main.c index b3f3ef0..8a04161 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, @@ -81,6 +82,8 @@ enum cmdline_opts { OPT_VERSION, OPT_RIPBCT, OPT_ODMDATA, + OPT_MINILOADER, + OPT_MINIENTRY, OPT_END, }; @@ -103,6 +106,11 @@ static void usage(char *progname) fprintf(stderr, "\t\tPrint version information and exit\n"); fprintf(stderr, "\t--ripbct\n"); fprintf(stderr, "\t\tRead the BCT from the target device and write to bctfile\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=<mlentry>\n"); + fprintf(stderr, "\t\tSpecify the entry point for the miniloader\n"); fprintf(stderr, "\n"); } @@ -114,7 +122,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; @@ -124,6 +132,8 @@ int main(int argc, char **argv) uint16_t devid; int do_rip = 0; uint32_t odmdata = 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_VERSION] = {"version", 0, 0, 0}, [OPT_RIPBCT] = {"ripbct", 0, 0, 0}, [OPT_ODMDATA] = {"odmdata", 1, 0, 0}, + [OPT_MINILOADER] = {"miniloader", 1, 0, 0}, + [OPT_MINIENTRY] = {"miniloader_entry", 1, 0, 0}, [OPT_END] = {0, 0, 0, 0} }; @@ -168,6 +180,12 @@ int main(int argc, char **argv) case OPT_ODMDATA: odmdata = strtoul(optarg, NULL, 0); break; + case OPT_MINILOADER: + mlfile = optarg; + break; + case OPT_MINIENTRY: + mlentry = strtoul(optarg, NULL, 0); + break; case OPT_HELP: default: usage(argv[0]); @@ -221,8 +239,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); @@ -289,9 +314,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 || @@ -343,27 +365,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) { @@ -371,11 +431,9 @@ static int initialize_rcm(uint16_t devid, usb_device_t *usb) return ret; } printf("miniloader downloaded successfully\n"); - return 0; } - static int wait_status(nv3p_handle_t h3p) { int ret; diff --git a/src/tegrarcm.1.in b/src/tegrarcm.1.in index b972e95..8de9355 100644 --- a/src/tegrarcm.1.in +++ b/src/tegrarcm.1.in @@ -76,6 +76,14 @@ this option is specified, the --bootloader, --loadaddr, and .B \-\-odmdata Pass odmdata down to the miniloader. This is really only useful for miniloader debugging. +.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 EXAMPLE To download u-boot firmware to a Tegra20 seaboard: -- 1.8.1.5 -- To unsubscribe from this list: send the line "unsubscribe linux-tegra" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html