summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAllen Martin <amartin@nvidia.com>2013-08-19 22:27:07 -0700
committerAllen Martin <amartin@nvidia.com>2013-09-20 13:02:47 -0700
commitdd1b4bcbf2276093417c05255f72be3fe6078d0e (patch)
tree5f909f6bbc6e57f6187d747a5488d5a4819f92a8
parent20ba26c645da700119ec5009872d854688a45a6d (diff)
downloadtegrarcm-dd1b4bcbf2276093417c05255f72be3fe6078d0e.tar.gz
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 <amartin@nvidia.com> Reviewed-by: Stephen Warren <swarren@nvidia.com>
-rw-r--r--src/main.c110
-rw-r--r--src/tegrarcm.1.in6
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=<mlentry>\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: