summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAllen Martin <amartin@nvidia.com>2013-08-02 10:12:35 -0700
committerAllen Martin <amartin@nvidia.com>2013-09-20 13:02:35 -0700
commitaf893aa85cfbd14d7c99447f1181e771b90d70b4 (patch)
treead5defbc7e4e4f23f3295f6f3da84e1ce2e08d22
parent18ff730d529ae9060921693a85a3491794c2c8f9 (diff)
downloadtegrarcm-af893aa85cfbd14d7c99447f1181e771b90d70b4.tar.gz
tegrarcm: Assume nv3p server is running if RCM doesn't respond
Change the initialization logic so that if RCM protocol isn't repsonding but a tegra recovery USB is reported, assume the nv3p server is already running. This allows things like enumeration of devices via nv3p without having to reset into RCM mode to talk to the device again. Signed-off-by: Allen Martin <amartin@nvidia.com> Reviewed-by: Stephen Warren <swarren@nvidia.com>
-rw-r--r--src/main.c160
1 files changed, 93 insertions, 67 deletions
diff --git a/src/main.c b/src/main.c
index fa3ea6c..a6c2bf0 100644
--- a/src/main.c
+++ b/src/main.c
@@ -60,6 +60,7 @@
// tegra124 miniloader
#include "miniloader/tegra124-miniloader.h"
+static int initialize_rcm(uint16_t devid, usb_device_t *usb);
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,
@@ -95,11 +96,9 @@ static void usage(char *progname)
int main(int argc, char **argv)
{
// discover devices
- uint8_t *msg_buff;
uint64_t uid[2];
int actual_len;
usb_device_t *usb;
- uint32_t status;
nv3p_platform_info_t info;
nv3p_handle_t h3p;
int ret;
@@ -110,10 +109,6 @@ int main(int argc, char **argv)
uint32_t loadaddr = 0;
uint32_t entryaddr = 0;
uint16_t devid;
- uint8_t *miniloader;
- uint32_t miniloader_size;
- uint32_t miniloader_entry;
- int msg_len;
static struct option long_options[] = {
[OPT_BCT] = {"bct", 1, 0, 0},
@@ -193,15 +188,72 @@ int main(int argc, char **argv)
printf("device id: 0x%x\n", devid);
ret = usb_read(usb, (uint8_t *)uid, sizeof(uid), &actual_len);
+ if (!ret) {
+ if (actual_len == 8)
+ printf("uid: 0x%016" PRIx64 "\n", uid[0]);
+ else if (actual_len == 16)
+ printf("uid: 0x%016" PRIx64 "%016" PRIx64 "\n",
+ uid[1], uid[0]);
+ else
+ error(1, errno, "USB read truncated");
+
+ // initialize rcm and download the miniloader to start nv3p
+ initialize_rcm(devid, usb);
+
+ // device may have re-enumerated, so reopen USB
+ usb_close(usb);
+ usb = usb_open(USB_VENID_NVIDIA, &devid);
+ if (!usb)
+ error(1, errno, "could not open USB device");
+ }
+
+ // now that miniloader is up, start nv3p protocol
+ ret = nv3p_open(&h3p, usb);
+ if (ret)
+ error(1, errno, "3p open failed");
+
+ // get platform info and dump it
+ ret = nv3p_cmd_send(h3p, NV3P_CMD_GET_PLATFORM_INFO, (uint8_t *)&info);
+ if (ret)
+ error(1, errno, "retreiving platform info");
+ ret = wait_status(h3p);
if (ret)
- error(1, ret, "USB transfer failure");
- if (actual_len == 8)
- printf("uid: 0x%016" PRIx64 "\n", uid[0]);
- else if (actual_len == 16)
- printf("uid: 0x%016" PRIx64 "%016" PRIx64 "\n",
- uid[1], uid[0]);
- else
- error(1, errno, "USB read truncated");
+ error(1, errno, "wait status after platform info");
+ dump_platform_info(&info);
+
+ if (info.op_mode != RCM_OP_MODE_DEVEL &&
+ info.op_mode != RCM_OP_MODE_ODM_OPEN &&
+ info.op_mode != RCM_OP_MODE_PRE_PRODUCTION)
+ error(1, ENODEV, "device is not in developer, open, "
+ "or pre-production mode, cannot flash");
+
+ // download the BCT
+ ret = download_bct(h3p, bctfile);
+ if (ret) {
+ error(1, ret, "error downloading bct: %s", bctfile);
+ }
+
+ // download the bootloader
+ ret = download_bootloader(h3p, blfile, entryaddr, loadaddr);
+ if (ret)
+ error(1, ret, "error downloading bootloader: %s", blfile);
+
+ nv3p_close(h3p);
+ usb_close(usb);
+
+ return 0;
+}
+
+static int initialize_rcm(uint16_t devid, usb_device_t *usb)
+{
+ int ret;
+ uint8_t *msg_buff;
+ 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 ||
@@ -215,30 +267,41 @@ int main(int argc, char **argv)
dprintf("initializing RCM version 40\n");
ret = rcm_init(RCM_VERSION_40);
} else {
- error(1, ENODEV, "unknown tegra device: 0x%x", devid);
+ fprintf(stderr, "unknown tegra device: 0x%x\n", devid);
+ return errno;
+ }
+ if (ret) {
+ fprintf(stderr, "RCM initialize failed\n");
+ return ret;
}
- if (ret)
- error(1, errno, "RCM initialize failed");
// create query version message
rcm_create_msg(RCM_CMD_QUERY_RCM_VERSION, NULL, 0, NULL, 0, &msg_buff);
// write query version message to device
msg_len = rcm_get_msg_len(msg_buff);
- if (msg_len == 0)
- error(1, EINVAL, "unknown message length");
+ if (msg_len == 0) {
+ fprintf(stderr, "write RCM query version: unknown message length\n");
+ return EINVAL;
+ }
ret = usb_write(usb, msg_buff, msg_len);
- if (ret)
- error(1, errno, "write query version - USB transfer failure");
+ if (ret) {
+ fprintf(stderr, "write RCM query version: USB transfer failure\n");
+ return ret;
+ }
free(msg_buff);
msg_buff = NULL;
// read response
ret = usb_read(usb, (uint8_t *)&status, sizeof(status), &actual_len);
- if (ret)
- error(1, ret, "read query version - USB transfer failure");
- if (actual_len < sizeof(status))
- error(1, EIO, "read query version - USB read truncated");
+ if (ret) {
+ fprintf(stderr, "read RCM query version: USB transfer failure\n");
+ return ret;
+ }
+ if (actual_len < sizeof(status)) {
+ fprintf(stderr, "read RCM query version: USB read truncated\n");
+ return EIO;
+ }
printf("RCM version: %d.%d\n", RCM_VERSION_MAJOR(status),
RCM_VERSION_MINOR(status));
@@ -260,53 +323,16 @@ int main(int argc, char **argv)
miniloader_size = sizeof(miniloader_tegra124);
miniloader_entry = TEGRA124_MINILOADER_ENTRY;
} else {
- error(1, ENODEV, "unknown tegra device: 0x%x", devid);
+ fprintf(stderr, "unknown tegra device: 0x%x\n", devid);
+ return ENODEV;
}
ret = download_miniloader(usb, miniloader, miniloader_size,
miniloader_entry);
- if (ret)
- error(1, ret, "Error downloading miniloader");
- printf("miniloader downloaded successfully\n");
-
- // device may have re-enumerated, so reopen USB
- usb_close(usb);
- usb = usb_open(USB_VENID_NVIDIA, &devid);
- if (!usb)
- error(1, errno, "could not open USB device");
-
- // now that miniloader is up, start nv3p protocol
- ret = nv3p_open(&h3p, usb);
- if (ret)
- error(1, errno, "3p open failed");
-
- // get platform info and dump it
- ret = nv3p_cmd_send(h3p, NV3P_CMD_GET_PLATFORM_INFO, (uint8_t *)&info);
- if (ret)
- error(1, errno, "retreiving platform info");
- ret = wait_status(h3p);
- if (ret)
- error(1, errno, "wait status after platform info");
- dump_platform_info(&info);
-
- if (info.op_mode != RCM_OP_MODE_DEVEL &&
- info.op_mode != RCM_OP_MODE_ODM_OPEN &&
- info.op_mode != RCM_OP_MODE_PRE_PRODUCTION)
- error(1, ENODEV, "device is not in developer, open, "
- "or pre-production mode, cannot flash");
-
- // download the BCT
- ret = download_bct(h3p, bctfile);
if (ret) {
- error(1, ret, "error downloading bct: %s", bctfile);
+ fprintf(stderr, "Error downloading miniloader\n");
+ return ret;
}
-
- // download the bootloader
- ret = download_bootloader(h3p, blfile, entryaddr, loadaddr);
- if (ret)
- error(1, ret, "error downloading bootloader: %s", blfile);
-
- nv3p_close(h3p);
- usb_close(usb);
+ printf("miniloader downloaded successfully\n");
return 0;
}