linux-tegra.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCHv2 00/11] tegrarcm: T124 and new command support
@ 2013-09-16 22:24 Allen Martin
       [not found] ` <1379370298-20404-1-git-send-email-amartin-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
  0 siblings, 1 reply; 13+ messages in thread
From: Allen Martin @ 2013-09-16 22:24 UTC (permalink / raw)
  To: swarren-3lzwWm7+Weoh9ZMKESR00Q
  Cc: linux-tegra-u79uwXL29TY76Z2rM5mHXA, Allen Martin

This patch series adds T124 support to tegrarcm, tested on laguna.  It
also adds support for new commands for ripping a BCT from a live
system, and for passing in the miniloader from a file.  Also fixed up
some of the error handling so now USB commands will time out instead
of hanging, and attempt to bring up nv3p even if RCM is unresponsive.

Changes:
v2:
 - Removed odmdata option
 - Renamed ripbct to readbct and made it a command not an option
 - Added missing SKUs, made default SKU be the chip family name
 - Removed some left over debug prints, whitespace errors

Allen Martin (11):
  tegrarcm: Change NVIDIA license to apply to all miniloader files
  tegrarcm: Add missing SKU information
  tegrarcm: Add support for RCM protocol version 40
  tegrarcm: Add Tegra124 miniloader
  tegrarcm: Add Tegra124 support
  tegrarcm: Add timeout to USB xfers
  tegrarcm: Assume nv3p server is running if RCM doesn't respond
  tegrarcm: Clean up usage info
  tegrarcm: Add readbct support
  tegrarcm: Add command to pass miniloader in from file
  tegrarcm: Bump version to 1.5

 LICENSE                              |    4 +-
 README                               |    4 +
 configure.ac                         |    2 +-
 src/Makefile.am                      |    1 +
 src/main.c                           |  416 +-
 src/miniloader/tegra124-miniloader.h | 8570 ++++++++++++++++++++++++++++++++++
 src/nv3p.c                           |   10 +-
 src/nv3p.h                           |   22 +
 src/rcm.c                            |   74 +
 src/rcm.h                            |   58 +-
 src/tegrarcm.1.in                    |   27 +-
 src/usb.c                            |   10 +-
 src/usb.h                            |    1 +
 13 files changed, 9058 insertions(+), 141 deletions(-)
 create mode 100644 src/miniloader/tegra124-miniloader.h

-- 
1.8.1.5

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCHv2 01/11] tegrarcm: Change NVIDIA license to apply to all miniloader files
       [not found] ` <1379370298-20404-1-git-send-email-amartin-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
@ 2013-09-16 22:24   ` Allen Martin
  2013-09-16 22:24   ` [PATCHv2 02/11] tegrarcm: Add missing SKU information Allen Martin
                     ` (9 subsequent siblings)
  10 siblings, 0 replies; 13+ messages in thread
From: Allen Martin @ 2013-09-16 22:24 UTC (permalink / raw)
  To: swarren-3lzwWm7+Weoh9ZMKESR00Q
  Cc: linux-tegra-u79uwXL29TY76Z2rM5mHXA, Allen Martin

Change the LICENSE file to make it clear that the NVIDIA proprietary
license applies to all miniloader files, not just the ones explicitly
listed.

Signed-off-by: Allen Martin <amartin-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
---
 LICENSE | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/LICENSE b/LICENSE
index e126375..10d0211 100644
--- a/LICENSE
+++ b/LICENSE
@@ -26,8 +26,8 @@
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 
-The files tegra20-miniloader.h and tegra30-miniloader.h are provided
-pursuant to the following license agreement:
+The files in the directory src/miniloader are provided pursuant to the
+following license agreement:
 
 License For Use of NVIDIA Software
 
-- 
1.8.1.5

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCHv2 02/11] tegrarcm: Add missing SKU information
       [not found] ` <1379370298-20404-1-git-send-email-amartin-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
  2013-09-16 22:24   ` [PATCHv2 01/11] tegrarcm: Change NVIDIA license to apply to all miniloader files Allen Martin
@ 2013-09-16 22:24   ` Allen Martin
  2013-09-16 22:24   ` [PATCHv2 03/11] tegrarcm: Add support for RCM protocol version 40 Allen Martin
                     ` (8 subsequent siblings)
  10 siblings, 0 replies; 13+ messages in thread
From: Allen Martin @ 2013-09-16 22:24 UTC (permalink / raw)
  To: swarren-3lzwWm7+Weoh9ZMKESR00Q
  Cc: linux-tegra-u79uwXL29TY76Z2rM5mHXA, Allen Martin

Sync up SKU numbers with TOT tegra u-boot.  Also change the default
SKU print to just use the chip family name so it's more resistant to
being out of sync in the future.

Signed-off-by: Allen Martin <amartin-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
---
 src/main.c | 27 +++++++++++++++------------
 src/nv3p.h |  3 +++
 2 files changed, 18 insertions(+), 12 deletions(-)

diff --git a/src/main.c b/src/main.c
index 960eb4a..ef0c7e9 100644
--- a/src/main.c
+++ b/src/main.c
@@ -460,26 +460,29 @@ static void dump_platform_info(nv3p_platform_info_t *info)
 	char *chip_name = NULL;
 	if (info->chip_id.id == 0x20) {
 		switch (info->sku) {
-		case TEGRA2_CHIP_SKU_AP20:   chip_name = "ap20"; break;
-		case TEGRA2_CHIP_SKU_T20:    chip_name = "t20"; break;
+		case TEGRA2_CHIP_SKU_AP20:   chip_name = "ap20";  break;
 		case TEGRA2_CHIP_SKU_T25SE:  chip_name = "t25se"; break;
-		case TEGRA2_CHIP_SKU_AP25:   chip_name = "ap25"; break;
-		case TEGRA2_CHIP_SKU_T25:    chip_name = "t25"; break;
+		case TEGRA2_CHIP_SKU_AP25:   chip_name = "ap25";  break;
+		case TEGRA2_CHIP_SKU_T25:    chip_name = "t25";   break;
 		case TEGRA2_CHIP_SKU_AP25E:  chip_name = "ap25e"; break;
-		case TEGRA2_CHIP_SKU_T25E:   chip_name = "t25e"; break;
-		default: chip_name = "unknown"; break;
+		case TEGRA2_CHIP_SKU_T25E:   chip_name = "t25e";  break;
+		case TEGRA2_CHIP_SKU_T20:
+		case TEGRA2_CHIP_SKU_T20_7:
+		default: chip_name = "t20"; break;
 		}
 	} else if (info->chip_id.id == 0x30) {
 		switch (info->sku) {
-		case TEGRA3_CHIP_SKU_AP30:   chip_name = "ap30"; break;
-		case TEGRA3_CHIP_SKU_T30:    chip_name = "t30"; break;
-		case TEGRA3_CHIP_SKU_T30S:   chip_name = "t30s"; break;
-		default: chip_name = "unknown"; break;
+		case TEGRA3_CHIP_SKU_AP30:   chip_name = "ap30";  break;
+		case TEGRA3_CHIP_SKU_T30S:   chip_name = "t30s";  break;
+		case TEGRA3_CHIP_SKU_T33:    chip_name = "t33";   break;
+		case TEGRA3_CHIP_SKU_T30:
+		default: chip_name = "t30"; break;
 		}
 	} else if (info->chip_id.id == 0x35) {
 		switch (info->sku) {
-		case TEGRA114_CHIP_SKU_T114: chip_name = "t114"; break;
-		default: chip_name = "unknown"; break;
+		case TEGRA114_CHIP_SKU_T114:
+		case TEGRA114_CHIP_SKU_T114_1:
+		default: chip_name = "t114"; break;
 		}
 	} else {
 		chip_name = "unknown";
diff --git a/src/nv3p.h b/src/nv3p.h
index 20cb93b..13d0e0b 100644
--- a/src/nv3p.h
+++ b/src/nv3p.h
@@ -53,6 +53,7 @@ typedef struct nv3p_state *nv3p_handle_t;
 
 // tegra2 chip sku
 #define TEGRA2_CHIP_SKU_AP20     0x01
+#define TEGRA2_CHIP_SKU_T20_7    0x07
 #define TEGRA2_CHIP_SKU_T20      0x08
 #define TEGRA2_CHIP_SKU_T25SE    0x14
 #define TEGRA2_CHIP_SKU_AP25     0x17
@@ -64,9 +65,11 @@ typedef struct nv3p_state *nv3p_handle_t;
 #define TEGRA3_CHIP_SKU_AP30     0x87
 #define TEGRA3_CHIP_SKU_T30      0x81
 #define TEGRA3_CHIP_SKU_T30S     0x83
+#define TEGRA3_CHIP_SKU_T33      0X80
 
 // tegra114 chip sku
 #define TEGRA114_CHIP_SKU_T114   0x00
+#define TEGRA114_CHIP_SKU_T114_1 0x01
 
 // boot device type
 #define NV3P_DEV_TYPE_NAND              0x1
-- 
1.8.1.5

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCHv2 03/11] tegrarcm: Add support for RCM protocol version 40
       [not found] ` <1379370298-20404-1-git-send-email-amartin-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
  2013-09-16 22:24   ` [PATCHv2 01/11] tegrarcm: Change NVIDIA license to apply to all miniloader files Allen Martin
  2013-09-16 22:24   ` [PATCHv2 02/11] tegrarcm: Add missing SKU information Allen Martin
@ 2013-09-16 22:24   ` Allen Martin
  2013-09-16 22:24   ` [PATCHv2 05/11] tegrarcm: Add Tegra124 support Allen Martin
                     ` (7 subsequent siblings)
  10 siblings, 0 replies; 13+ messages in thread
From: Allen Martin @ 2013-09-16 22:24 UTC (permalink / raw)
  To: swarren-3lzwWm7+Weoh9ZMKESR00Q
  Cc: linux-tegra-u79uwXL29TY76Z2rM5mHXA, Allen Martin

RCM protocol 40 is required for Tegra124

Signed-off-by: Allen Martin <amartin-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
---
 src/rcm.c | 74 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/rcm.h | 58 ++++++++++++++++++++++++++++++++-----------------
 2 files changed, 112 insertions(+), 20 deletions(-)

diff --git a/src/rcm.c b/src/rcm.c
index c5b3aac..cb53d8f 100644
--- a/src/rcm.c
+++ b/src/rcm.c
@@ -36,6 +36,7 @@
 static int rcm_sign_msg(uint8_t *buf);
 static int rcm1_sign_msg(uint8_t *buf);
 static int rcm35_sign_msg(uint8_t *buf);
+static int rcm40_sign_msg(uint8_t *buf);
 static void rcm_init_msg(
 	uint8_t *buf,
 	uint32_t msg_len,
@@ -57,6 +58,13 @@ static void rcm35_init_msg(
 	void *args,
 	uint32_t args_len,
 	uint32_t payload_len);
+static void rcm40_init_msg(
+	uint8_t *buf,
+	uint32_t msg_len,
+	uint32_t opcode,
+	void *args,
+	uint32_t args_len,
+	uint32_t payload_len);
 static uint8_t *rcm_get_msg_payload(uint8_t *buf);
 static void rcm_msg_pad(uint8_t *data, uint32_t len);
 static uint32_t rcm_get_pad_len(uint32_t payload_len);
@@ -79,6 +87,11 @@ int rcm_init(uint32_t version)
 		message_size = sizeof(rcm35_msg_t);
 		ret = 0;
 	}
+	else if (version == RCM_VERSION_40) {
+		rcm_version = version;
+		message_size = sizeof(rcm40_msg_t);
+		ret = 0;
+	}
 	return ret;
 }
 
@@ -88,6 +101,8 @@ uint32_t rcm_get_msg_len(uint8_t *msg)
 		return ((rcm1_msg_t*)msg)->len_insecure;
 	else if (rcm_version == RCM_VERSION_35)
 		return ((rcm35_msg_t*)msg)->len_insecure;
+	else if (rcm_version == RCM_VERSION_40)
+		return ((rcm40_msg_t*)msg)->len_insecure;
 	else
 		return 0;
 }
@@ -139,6 +154,8 @@ static int rcm_sign_msg(uint8_t *buf)
 {
 	if (rcm_version == RCM_VERSION_35)
 		return rcm35_sign_msg(buf);
+	else if (rcm_version == RCM_VERSION_40)
+		return rcm40_sign_msg(buf);
 	else if (rcm_version == RCM_VERSION_1)
 		return rcm1_sign_msg(buf);
 	else
@@ -184,6 +201,26 @@ static int rcm35_sign_msg(uint8_t *buf)
 	return 0;
 }
 
+static int rcm40_sign_msg(uint8_t *buf)
+{
+	rcm40_msg_t *msg;
+	uint32_t crypto_len;
+
+	msg = (rcm40_msg_t*)buf;
+
+	// signing does not include the len_insecure, modulus
+	// and object signature at the beginning of the message
+	crypto_len = msg->len_insecure - sizeof(msg->len_insecure) -
+		sizeof(msg->modulus) -
+		sizeof(msg->object_sig);
+	if (crypto_len % RCM_AES_BLOCK_SIZE) {
+		return -EMSGSIZE;
+	}
+
+	cmac_hash(msg->reserved, crypto_len, msg->object_sig.cmac_hash);
+	return 0;
+}
+
 static uint32_t rcm_get_msg_buf_len(uint32_t payload_len)
 {
 	return message_size + payload_len +
@@ -215,6 +252,9 @@ static void rcm_init_msg(
 	if (rcm_version == RCM_VERSION_35)
 		rcm35_init_msg(buf, msg_len, opcode, args,
 			       args_len, payload_len);
+	else if (rcm_version == RCM_VERSION_40)
+		rcm40_init_msg(buf, msg_len, opcode, args,
+			       args_len, payload_len);
 	else if (rcm_version == RCM_VERSION_1)
 		rcm1_init_msg(buf, msg_len, opcode, args,
 			      args_len, payload_len);
@@ -254,6 +294,40 @@ static void rcm35_init_msg(
 	rcm_msg_pad(buf + sizeof(rcm35_msg_t) + payload_len, padding_len);
 }
 
+static void rcm40_init_msg(
+	uint8_t *buf,
+	uint32_t msg_len,
+	uint32_t opcode,
+	void *args,
+	uint32_t args_len,
+	uint32_t payload_len)
+{
+	uint32_t padding_len;
+	rcm40_msg_t *msg;
+
+	msg = (rcm40_msg_t *)buf;
+
+	padding_len = rcm_get_pad_len(payload_len);
+
+	msg->len_insecure = sizeof(rcm40_msg_t) + payload_len +
+		padding_len;
+
+	memset(&msg->object_sig.cmac_hash, 0x0, sizeof(msg->object_sig.cmac_hash));
+	memset(&msg->reserved, 0x0, sizeof(msg->reserved));
+
+	msg->opcode         = opcode;
+	msg->len_secure     = msg->len_insecure;
+	msg->payload_len    = payload_len;
+	msg->rcm_version    = RCM_VERSION_40;
+
+	if (args_len)
+		memcpy(msg->args, args, args_len);
+	memset(msg->args + args_len, 0x0, sizeof(msg->args) - args_len);
+
+	rcm_msg_pad(msg->padding, sizeof(msg->padding));
+	rcm_msg_pad(buf + sizeof(rcm40_msg_t) + payload_len, padding_len);
+}
+
 static void rcm1_init_msg(
 	uint8_t *buf,
 	uint32_t msg_len,
diff --git a/src/rcm.h b/src/rcm.h
index 1aeca9f..505547c 100644
--- a/src/rcm.h
+++ b/src/rcm.h
@@ -36,6 +36,7 @@
 #define NVBOOT_VERSION(a,b) ((((a)&0xffff) << 16) | ((b)&0xffff))
 #define RCM_VERSION_1 (NVBOOT_VERSION(1, 0))
 #define RCM_VERSION_35 (NVBOOT_VERSION(0x35, 1))
+#define RCM_VERSION_40 (NVBOOT_VERSION(0x40, 1))
 #define RCM_VERSION_MAJOR(ver) ((ver) >> 16)
 #define RCM_VERSION_MINOR(ver) ((ver) & 0xffff)
 
@@ -58,34 +59,51 @@
  *     padding
  */
 typedef struct {
-	uint32_t len_insecure;
-	uint8_t cmac_hash[RCM_AES_BLOCK_SIZE];
-	uint8_t reserved[16];
-	uint32_t opcode;
-	uint32_t len_secure;
-	uint32_t payload_len;
-	uint32_t rcm_version;
-	uint8_t args[48];
-	uint8_t padding[16];
+	uint32_t len_insecure;		// 000-003
+	uint8_t cmac_hash[RCM_AES_BLOCK_SIZE];	// 004-013
+	uint8_t reserved[16];		// 014-023
+	uint32_t opcode;		// 024-027
+	uint32_t len_secure;		// 028-02b
+	uint32_t payload_len;		// 02c-02f
+	uint32_t rcm_version;		// 030-033
+	uint8_t args[48];		// 034-063
+	uint8_t padding[16];		// 064-073
 } rcm1_msg_t;
 
 typedef struct {
-	uint32_t len_insecure;
-	uint8_t modulus[2048 / 8];
+	uint32_t len_insecure;		// 000-003
+	uint8_t modulus[2048 / 8];	// 004-103
 	union {
 		uint8_t cmac_hash[RCM_AES_BLOCK_SIZE];
 		uint8_t rsa_pss_sig[2048 / 8];
-	} object_sig;
-	uint8_t reserved[16];
-	uint32_t ecid[4];
-	uint32_t opcode;
-	uint32_t len_secure;
-	uint32_t payload_len;
-	uint32_t rcm_version;
-	uint8_t args[48];
-	uint8_t padding[16];
+	} object_sig;			// 104-203
+	uint8_t reserved[16];		// 204-213
+	uint32_t ecid[4];		// 214-223
+	uint32_t opcode;		// 224-227
+	uint32_t len_secure;		// 228-22b
+	uint32_t payload_len;		// 22c-22f
+	uint32_t rcm_version;		// 230-233
+	uint8_t args[48];		// 234-263
+	uint8_t padding[16];		// 264-273
 } rcm35_msg_t;
 
+typedef struct {
+	uint32_t len_insecure;		// 000-003
+	uint8_t modulus[2048 / 8];	// 004-103
+	struct {
+		uint8_t cmac_hash[RCM_AES_BLOCK_SIZE];
+		uint8_t rsa_pss_sig[2048 / 8];
+	} object_sig;			// 104-213
+	uint8_t reserved[16];		// 214-223
+	uint32_t ecid[4];		// 224-233
+	uint32_t opcode;		// 234-237
+	uint32_t len_secure;		// 238-23b
+	uint32_t payload_len;		// 23c-23f
+	uint32_t rcm_version;		// 240-243
+	uint8_t args[48];		// 244-273
+	uint8_t padding[16];		// 274-283
+} rcm40_msg_t;
+
 // security operating modes
 #define RCM_OP_MODE_PRE_PRODUCTION  0x1
 #define RCM_OP_MODE_DEVEL           0x3
-- 
1.8.1.5

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCHv2 05/11] tegrarcm: Add Tegra124 support
       [not found] ` <1379370298-20404-1-git-send-email-amartin-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
                     ` (2 preceding siblings ...)
  2013-09-16 22:24   ` [PATCHv2 03/11] tegrarcm: Add support for RCM protocol version 40 Allen Martin
@ 2013-09-16 22:24   ` Allen Martin
  2013-09-16 22:24   ` [PATCHv2 06/11] tegrarcm: Add timeout to USB xfers Allen Martin
                     ` (6 subsequent siblings)
  10 siblings, 0 replies; 13+ messages in thread
From: Allen Martin @ 2013-09-16 22:24 UTC (permalink / raw)
  To: swarren-3lzwWm7+Weoh9ZMKESR00Q
  Cc: linux-tegra-u79uwXL29TY76Z2rM5mHXA, Allen Martin

Add Tegra124 USB device id, miniloader, and chip SKU information.

Signed-off-by: Allen Martin <amartin-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
---
 src/main.c        | 15 +++++++++++++++
 src/nv3p.h        |  3 +++
 src/tegrarcm.1.in |  4 +++-
 src/usb.c         |  3 ++-
 src/usb.h         |  1 +
 5 files changed, 24 insertions(+), 2 deletions(-)

diff --git a/src/main.c b/src/main.c
index ef0c7e9..fa3ea6c 100644
--- a/src/main.c
+++ b/src/main.c
@@ -57,6 +57,9 @@
 // tegra114 miniloader
 #include "miniloader/tegra114-miniloader.h"
 
+// tegra124 miniloader
+#include "miniloader/tegra124-miniloader.h"
+
 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,
@@ -208,6 +211,9 @@ int main(int argc, char **argv)
 	} else if ((devid & 0xff) == USB_DEVID_NVIDIA_TEGRA114) {
 		dprintf("initializing RCM version 35\n");
 		ret = rcm_init(RCM_VERSION_35);
+	} else if ((devid & 0xff) == USB_DEVID_NVIDIA_TEGRA124) {
+		dprintf("initializing RCM version 40\n");
+		ret = rcm_init(RCM_VERSION_40);
 	} else {
 		error(1, ENODEV, "unknown tegra device: 0x%x", devid);
 	}
@@ -249,6 +255,10 @@ int main(int argc, char **argv)
 		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 {
 		error(1, ENODEV, "unknown tegra device: 0x%x", devid);
 	}
@@ -484,6 +494,11 @@ static void dump_platform_info(nv3p_platform_info_t *info)
 		case TEGRA114_CHIP_SKU_T114_1:
 		default: chip_name = "t114"; break;
 		}
+	} else if (info->chip_id.id == 0x40) {
+		switch (info->sku) {
+		case TEGRA124_CHIP_SKU_T124:
+		default: chip_name = "t124"; break;
+		}
 	} else {
 		chip_name = "unknown";
 	}
diff --git a/src/nv3p.h b/src/nv3p.h
index 13d0e0b..2f4c94e 100644
--- a/src/nv3p.h
+++ b/src/nv3p.h
@@ -71,6 +71,9 @@ typedef struct nv3p_state *nv3p_handle_t;
 #define TEGRA114_CHIP_SKU_T114   0x00
 #define TEGRA114_CHIP_SKU_T114_1 0x01
 
+// tegra124 chip sku
+#define TEGRA124_CHIP_SKU_T124   0x00
+
 // boot device type
 #define NV3P_DEV_TYPE_NAND              0x1
 #define NV3P_DEV_TYPE_EMMC              0x2
diff --git a/src/tegrarcm.1.in b/src/tegrarcm.1.in
index 4b9200d..011d169 100644
--- a/src/tegrarcm.1.in
+++ b/src/tegrarcm.1.in
@@ -24,6 +24,8 @@ device.
 .B Tegra30
 .IP \(bu
 .B Tegra114
+.IP \(bu
+.B Tegra124
 
 .SS How to use
 .IP \(em
@@ -53,7 +55,7 @@ the firmware file that will be downloaded and executed.
 .B \-\-loadaddr \fIloadaddr\fP
 Specify the address the bootloader will be loaded at.  This should be
 specified in hex and is typically 0x108000 for a Tegra20 device or
-0x80108000 for a Tegra30 or Tegra114 device.
+0x80108000 for a Tegra30, Tegra114, or Tegra124 device.
 .TP
 .B \-\-entryaddr \fIentryaddr\fP
 Specify the entry address that control will be passed to after the
diff --git a/src/usb.c b/src/usb.c
index 0b33de9..16f3d90 100644
--- a/src/usb.c
+++ b/src/usb.c
@@ -155,7 +155,8 @@ usb_device_t *usb_open(uint16_t venid, uint16_t *devid)
 		if (usb_match(device, venid, devid)) {
 			if ((*devid & 0xff) == USB_DEVID_NVIDIA_TEGRA20 ||
 			    (*devid & 0xff) == USB_DEVID_NVIDIA_TEGRA30 ||
-			    (*devid & 0xff) == USB_DEVID_NVIDIA_TEGRA114) {
+			    (*devid & 0xff) == USB_DEVID_NVIDIA_TEGRA114 ||
+			    (*devid & 0xff) == USB_DEVID_NVIDIA_TEGRA124) {
 				found = device;
 				break;
 			} else {
diff --git a/src/usb.h b/src/usb.h
index 03ba18c..a7b36af 100644
--- a/src/usb.h
+++ b/src/usb.h
@@ -35,6 +35,7 @@
 #define USB_DEVID_NVIDIA_TEGRA20 0x20
 #define USB_DEVID_NVIDIA_TEGRA30 0x30
 #define USB_DEVID_NVIDIA_TEGRA114 0x35
+#define USB_DEVID_NVIDIA_TEGRA124 0x40
 
 typedef struct {
 	libusb_device_handle *handle;
-- 
1.8.1.5

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCHv2 06/11] tegrarcm: Add timeout to USB xfers
       [not found] ` <1379370298-20404-1-git-send-email-amartin-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
                     ` (3 preceding siblings ...)
  2013-09-16 22:24   ` [PATCHv2 05/11] tegrarcm: Add Tegra124 support Allen Martin
@ 2013-09-16 22:24   ` Allen Martin
  2013-09-16 22:24   ` [PATCHv2 07/11] tegrarcm: Assume nv3p server is running if RCM doesn't respond Allen Martin
                     ` (5 subsequent siblings)
  10 siblings, 0 replies; 13+ messages in thread
From: Allen Martin @ 2013-09-16 22:24 UTC (permalink / raw)
  To: swarren-3lzwWm7+Weoh9ZMKESR00Q
  Cc: linux-tegra-u79uwXL29TY76Z2rM5mHXA, Allen Martin

This prevents tegrarcm from just hanging in the event that the target
gets in some bad state and stops responding to USB (like downloading a
bad BCT).  Set default timeout to 1s which should be plenty long
enough for the max xfer size of 4096 bytes.

Signed-off-by: Allen Martin <amartin-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
---
 src/usb.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/src/usb.c b/src/usb.c
index 16f3d90..450bc80 100644
--- a/src/usb.c
+++ b/src/usb.c
@@ -34,6 +34,9 @@
 #include "usb.h"
 #include "debug.h"
 
+// USB xfer timeout in ms
+#define USB_TIMEOUT 1000
+
 #define USB_XFER_MAX 4096
 
 //
@@ -225,7 +228,7 @@ int usb_write(usb_device_t *usb, uint8_t *buf, int len)
 	while (len) {
 		chunk_size = MIN(len, USB_XFER_MAX);
 		ret = libusb_bulk_transfer(usb->handle, usb->endpt_out, buf,
-					   chunk_size, &actual_chunk, 0);
+					   chunk_size, &actual_chunk, USB_TIMEOUT);
 		if (ret != LIBUSB_SUCCESS) {
 			dprintf("write failure: %d\n", ret);
 			return EIO;
@@ -252,7 +255,7 @@ int usb_read(usb_device_t *usb, uint8_t *buf, int len, int *actual_len)
 	while (len) {
 		chunk_size = MIN(len, USB_XFER_MAX);
 		ret = libusb_bulk_transfer(usb->handle, usb->endpt_in, buf,
-					   chunk_size, &actual_chunk, 0);
+					   chunk_size, &actual_chunk, USB_TIMEOUT);
 		if (ret != LIBUSB_SUCCESS) {
 			dprintf("read failure: %d\n", ret);
 			return EIO;
-- 
1.8.1.5

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCHv2 07/11] tegrarcm: Assume nv3p server is running if RCM doesn't respond
       [not found] ` <1379370298-20404-1-git-send-email-amartin-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
                     ` (4 preceding siblings ...)
  2013-09-16 22:24   ` [PATCHv2 06/11] tegrarcm: Add timeout to USB xfers Allen Martin
@ 2013-09-16 22:24   ` Allen Martin
  2013-09-16 22:24   ` [PATCHv2 08/11] tegrarcm: Clean up usage info Allen Martin
                     ` (4 subsequent siblings)
  10 siblings, 0 replies; 13+ messages in thread
From: Allen Martin @ 2013-09-16 22:24 UTC (permalink / raw)
  To: swarren-3lzwWm7+Weoh9ZMKESR00Q
  Cc: linux-tegra-u79uwXL29TY76Z2rM5mHXA, Allen Martin

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-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
---
 src/main.c | 160 +++++++++++++++++++++++++++++++++++--------------------------
 1 file 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;
 }
-- 
1.8.1.5

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCHv2 08/11] tegrarcm: Clean up usage info
       [not found] ` <1379370298-20404-1-git-send-email-amartin-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
                     ` (5 preceding siblings ...)
  2013-09-16 22:24   ` [PATCHv2 07/11] tegrarcm: Assume nv3p server is running if RCM doesn't respond Allen Martin
@ 2013-09-16 22:24   ` Allen Martin
  2013-09-16 22:24   ` [PATCHv2 09/11] tegrarcm: Add readbct support Allen Martin
                     ` (3 subsequent siblings)
  10 siblings, 0 replies; 13+ messages in thread
From: Allen Martin @ 2013-09-16 22:24 UTC (permalink / raw)
  To: swarren-3lzwWm7+Weoh9ZMKESR00Q
  Cc: linux-tegra-u79uwXL29TY76Z2rM5mHXA, Allen Martin

Added --help and --version commands to usage.  Made it more clear that
--entryaddr is optional.

Signed-off-by: Allen Martin <amartin-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
---
 src/main.c | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/src/main.c b/src/main.c
index a6c2bf0..80de04c 100644
--- a/src/main.c
+++ b/src/main.c
@@ -87,9 +87,16 @@ static void print_version(char *progname)
 
 static void usage(char *progname)
 {
-	fprintf(stderr, "usage: %s --bct=bctfile --bootloader=blfile --loadaddr=<loadaddr> --entryaddr=<entryaddr>\n", progname);
+	fprintf(stderr, "usage: %s [options] --bct=bctfile --bootloader=blfile --loadaddr=<loadaddr>\n", progname);
 	fprintf(stderr, "\n");
-	fprintf(stderr, "\tIf entryaddr is not specified, it's assumed to be the same as loadaddr\n");
+	fprintf(stderr, "Options:\n");
+	fprintf(stderr, "\t--entryaddr=<entryaddr>\n");
+	fprintf(stderr, "\t\tSpecify the entry point for the bootloader, if this option is\n");
+	fprintf(stderr, "\t\tnot provided, it is assumed to be loadaddr\n");
+	fprintf(stderr, "\t--help\n");
+	fprintf(stderr, "\t\tPrint this help information\n");
+	fprintf(stderr, "\t--version\n");
+	fprintf(stderr, "\t\tPrint version information and exit\n");
 	fprintf(stderr, "\n");
 }
 
-- 
1.8.1.5

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCHv2 09/11] tegrarcm: Add readbct support
       [not found] ` <1379370298-20404-1-git-send-email-amartin-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
                     ` (6 preceding siblings ...)
  2013-09-16 22:24   ` [PATCHv2 08/11] tegrarcm: Clean up usage info Allen Martin
@ 2013-09-16 22:24   ` Allen Martin
       [not found]     ` <1379370298-20404-10-git-send-email-amartin-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
  2013-09-16 22:24   ` [PATCHv2 10/11] tegrarcm: Add command to pass miniloader in from file Allen Martin
                     ` (2 subsequent siblings)
  10 siblings, 1 reply; 13+ messages in thread
From: Allen Martin @ 2013-09-16 22:24 UTC (permalink / raw)
  To: swarren-3lzwWm7+Weoh9ZMKESR00Q
  Cc: linux-tegra-u79uwXL29TY76Z2rM5mHXA, Allen Martin

Add a new command "readbct" which will read the BCT from the target
system and write it to bctfile.

Signed-off-by: Allen Martin <amartin-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
---
 src/main.c        | 119 ++++++++++++++++++++++++++++++++++++++++++++++--------
 src/nv3p.c        |  10 +++--
 src/nv3p.h        |  16 ++++++++
 src/tegrarcm.1.in |  17 +++++++-
 4 files changed, 141 insertions(+), 21 deletions(-)

diff --git a/src/main.c b/src/main.c
index 80de04c..cf55748 100644
--- a/src/main.c
+++ b/src/main.c
@@ -69,6 +69,7 @@ static void dump_platform_info(nv3p_platform_info_t *info);
 static int download_bct(nv3p_handle_t h3p, char *filename);
 static int download_bootloader(nv3p_handle_t h3p, char *filename,
 			       uint32_t entry, uint32_t loadaddr);
+static int read_bct(nv3p_handle_t h3p, char *filename);
 
 enum cmdline_opts {
 	OPT_BCT,
@@ -88,6 +89,14 @@ static void print_version(char *progname)
 static void usage(char *progname)
 {
 	fprintf(stderr, "usage: %s [options] --bct=bctfile --bootloader=blfile --loadaddr=<loadaddr>\n", progname);
+	fprintf(stderr, "       %s [options] --bct=bctfile readbct\n", progname);
+	fprintf(stderr, "\n");
+	fprintf(stderr, "Commands:\n");
+	fprintf(stderr, "\treadbct\n");
+	fprintf(stderr, "\t\tRead the BCT from the target device and write to bctfile\n");
+	fprintf(stderr, "\n");
+	fprintf(stderr, "\tDefault operation if no command is specified will download BCT and\n");
+	fprintf(stderr, "\tbootloader to device and start execution of bootloader\n");
 	fprintf(stderr, "\n");
 	fprintf(stderr, "Options:\n");
 	fprintf(stderr, "\t--entryaddr=<entryaddr>\n");
@@ -116,6 +125,7 @@ int main(int argc, char **argv)
 	uint32_t loadaddr = 0;
 	uint32_t entryaddr = 0;
 	uint16_t devid;
+	int do_read = 0;
 
 	static struct option long_options[] = {
 		[OPT_BCT]        = {"bct", 1, 0, 0},
@@ -152,6 +162,7 @@ int main(int argc, char **argv)
 			case OPT_VERSION:
 				print_version(argv[0]);
 				exit(0);
+				break;
 			case OPT_HELP:
 			default:
 				usage(argv[0]);
@@ -165,29 +176,43 @@ int main(int argc, char **argv)
 		}
 	}
 
+	while (optind < argc) {
+		if (!(strcmp(argv[optind], "readbct")))
+			do_read = 1;
+		else {
+			fprintf(stderr, "%s: Unknown command line argument: %s\n",
+				argv[0], argv[optind]);
+			usage(argv[0]);
+			exit(EXIT_FAILURE);
+		}
+		optind++;
+	}
+
 	if (bctfile == NULL) {
 		fprintf(stderr, "BCT file must be specified\n");
 		usage(argv[0]);
 		exit(EXIT_FAILURE);
 	}
-	if (blfile == NULL) {
-		fprintf(stderr, "bootloader file must be specified\n");
-		usage(argv[0]);
-		exit(EXIT_FAILURE);
-	}
-	if (loadaddr == 0) {
-		fprintf(stderr, "loadaddr must be specified\n");
-		usage(argv[0]);
-		exit(EXIT_FAILURE);
-	}
-	if (entryaddr == 0) {
-		entryaddr = loadaddr;
-	}
-
 	printf("bct file: %s\n", bctfile);
-	printf("booloader file: %s\n", blfile);
-	printf("load addr 0x%x\n", loadaddr);
-	printf("entry addr 0x%x\n", entryaddr);
+
+	if (!do_read) {
+		if (blfile == NULL) {
+			fprintf(stderr, "bootloader file must be specified\n");
+			usage(argv[0]);
+			exit(EXIT_FAILURE);
+		}
+		if (loadaddr == 0) {
+			fprintf(stderr, "loadaddr must be specified\n");
+			usage(argv[0]);
+			exit(EXIT_FAILURE);
+		}
+		if (entryaddr == 0) {
+			entryaddr = loadaddr;
+		}
+		printf("booloader file: %s\n", blfile);
+		printf("load addr 0x%x\n", loadaddr);
+		printf("entry addr 0x%x\n", entryaddr);
+	}
 
 	usb = usb_open(USB_VENID_NVIDIA, &devid);
 	if (!usb)
@@ -219,6 +244,16 @@ int main(int argc, char **argv)
 	if (ret)
 		error(1, errno, "3p open failed");
 
+	// read the BCT
+	if (do_read) {
+		printf("reading BCT from system, writing to %s...", bctfile);
+		ret = read_bct(h3p, bctfile);
+		if (ret)
+			error(1, errno, "error reading bct");
+		printf("done!\n");
+		exit(0);
+	}
+
 	// get platform info and dump it
 	ret = nv3p_cmd_send(h3p, NV3P_CMD_GET_PLATFORM_INFO, (uint8_t *)&info);
 	if (ret)
@@ -595,6 +630,56 @@ static int download_bct(nv3p_handle_t h3p, char *filename)
 }
 
 
+static int read_bct(nv3p_handle_t h3p, char *filename)
+{
+	int ret;
+	nv3p_bct_info_t bct_info;
+	uint8_t *bct_data;
+	int fd;
+	uint8_t *buf;
+
+	ret = nv3p_cmd_send(h3p, NV3P_CMD_GET_BCT, (uint8_t *)&bct_info);
+	if (ret) {
+		dprintf("error sending get bct command\n");
+		return ret;
+	}
+	ret = wait_status(h3p);
+	if (ret) {
+		dprintf("error waiting for status after get bct\n");
+		return ret;
+	}
+
+	bct_data = (uint8_t *)malloc(bct_info.length);
+	ret = nv3p_data_recv(h3p, bct_data, bct_info.length);
+	if (ret) {
+		dprintf("error retreiving bct data\n");
+		return ret;
+	}
+
+	fd = open(filename, O_WRONLY | O_CREAT, 0644);
+	if (fd < 0) {
+		dprintf("error opening %s for reading\n", filename);
+		return errno;
+	}
+
+	buf = bct_data;
+	while(bct_info.length > 0) {
+		ssize_t written = write(fd, buf, bct_info.length);
+		if (written == -1) {
+			if (errno == EINTR)
+				continue;
+			dprintf("error writing to %s\n", filename);
+			return errno;
+		}
+		buf += written;
+		bct_info.length -= written;
+	}
+
+	free(bct_data);
+	close(fd);
+	return 0;
+}
+
 static int download_bootloader(nv3p_handle_t h3p, char *filename,
 			       uint32_t entry, uint32_t loadaddr)
 {
diff --git a/src/nv3p.c b/src/nv3p.c
index b3f6045..b2dff42 100644
--- a/src/nv3p.c
+++ b/src/nv3p.c
@@ -123,7 +123,7 @@ typedef struct nv3p_state {
  * double the currently-largest command size, just to have some wiggle-room
  * (updates to commands without fixing this on accident, etc.)
  */
-#define NV3P_MAX_COMMAND_SIZE  128
+#define NV3P_MAX_COMMAND_SIZE  (2 << 12)
 
 #define NV3P_MAX_ACK_SIZE \
     NV3P_PACKET_SIZE_BASIC + \
@@ -209,7 +209,6 @@ static int nv3p_recv_hdr(nv3p_handle_t h3p, nv3p_header_t *hdr,
 			 uint32_t *checksum );
 static int nv3p_drain_packet(nv3p_handle_t h3p, nv3p_header_t *hdr );
 static void nv3p_nack(nv3p_handle_t h3p, uint32_t code);
-static int nv3p_data_recv(nv3p_handle_t h3p, uint8_t *data, uint32_t length);
 static int nv3p_read(usb_device_t *usb, uint8_t *buf, int len);
 static int nv3p_get_args(nv3p_handle_t h3p, uint32_t command, void **args,
 			 uint8_t *packet );
@@ -321,6 +320,7 @@ static void nv3p_write_cmd(nv3p_handle_t h3p, uint32_t command, void *args,
 
 	switch(command) {
 	case NV3P_CMD_GET_PLATFORM_INFO:
+	case NV3P_CMD_GET_BCT:
 		// no args or output only
 		*length = 0;
 		WRITE32(tmp, *length);
@@ -418,6 +418,9 @@ static int nv3p_get_cmd_return(nv3p_handle_t h3p, uint32_t command, void *args)
 	case NV3P_CMD_GET_PLATFORM_INFO:
 		length = sizeof(nv3p_platform_info_t);
 		break;
+	case NV3P_CMD_GET_BCT:
+		length = sizeof(nv3p_bct_info_t);
+		break;
 	case NV3P_CMD_DL_BCT:
 	case NV3P_CMD_DL_BL:
 		break;
@@ -467,7 +470,7 @@ static int nv3p_recv_hdr(nv3p_handle_t h3p, nv3p_header_t *hdr,
 	return 0;
 }
 
-static int nv3p_data_recv(nv3p_handle_t h3p, uint8_t *data, uint32_t length)
+int nv3p_data_recv(nv3p_handle_t h3p, uint8_t *data, uint32_t length)
 {
 	int ret;
 	uint8_t *tmp;
@@ -629,6 +632,7 @@ static int nv3p_get_args(nv3p_handle_t h3p, uint32_t command, void **args,
 
 	switch(command) {
 	case NV3P_CMD_GET_PLATFORM_INFO:
+	case NV3P_CMD_GET_BCT:
 		// output only
 		break;
 	case NV3P_CMD_STATUS:
diff --git a/src/nv3p.h b/src/nv3p.h
index 2f4c94e..e3498bc 100644
--- a/src/nv3p.h
+++ b/src/nv3p.h
@@ -39,6 +39,7 @@
 
 // commands
 #define NV3P_CMD_GET_PLATFORM_INFO       0x01
+#define NV3P_CMD_GET_BCT                 0x02
 #define NV3P_CMD_DL_BCT                  0x04
 #define NV3P_CMD_DL_BL                   0x06
 #define NV3P_CMD_STATUS                  0x0a
@@ -155,6 +156,20 @@ typedef struct {
 
 
 /*
+ * nv3p_bct_info_t: holds information about BCT size
+ */
+typedef struct {
+	uint32_t length;
+} nv3p_bct_info_t;
+
+/*
+ * nv3p_cmd_get_bct_t: retrieves the BCT from the device
+ */
+typedef struct {
+	uint32_t length;
+} nv3p_cmd_get_bct_t;
+
+/*
  * nv3p_cmd_dl_bct_t: downloads the system's BCT.
  */
 typedef struct {
@@ -176,5 +191,6 @@ int nv3p_cmd_send(nv3p_handle_t h3p, uint32_t command, void *args);
 int nv3p_cmd_recv(nv3p_handle_t h3p, uint32_t *command,	void **args);
 int nv3p_data_send(nv3p_handle_t h3p, uint8_t *data, uint32_t length);
 void nv3p_ack(nv3p_handle_t h3p);
+int nv3p_data_recv(nv3p_handle_t h3p, uint8_t *data, uint32_t length);
 
 #endif // NV3P_H
diff --git a/src/tegrarcm.1.in b/src/tegrarcm.1.in
index 011d169..7993110 100644
--- a/src/tegrarcm.1.in
+++ b/src/tegrarcm.1.in
@@ -40,6 +40,11 @@ Build some firmware for your device (such as u-boot)
 .IP \(em
 Run tegrarcm to download the firmware
 
+.SH COMMANDS
+.TP
+.B readbct
+Read the BCT from the target device and write it to \fIbctfile\fP.
+
 .SH OPTIONS
 .TP
 .B \-\-bct \fIbctfile\fP
@@ -67,8 +72,9 @@ Print the version number and exit.
 .TP
 .B \-\-help
 Print help text and exit.
+.TP
 
-.SH EXAMPLE
+.SH EXAMPLES
 To download u-boot firmware to a Tegra20 seaboard:
 
 .nf
@@ -101,6 +107,15 @@ sending file: u-boot.bin
 u-boot.bin sent successfully
 .fi
 
+To read the BCT from a system:
+
+.nf
+$ sudo tegrarcm --bct ventana.bct readbct
+bct file: ventana.bct
+device id: 0x7820
+reading BCT from system, writing to ventana.bct...done!
+.fi
+
 .SH RETURN VALUE
 If any error occurs a non zero exit status is returned.
 
-- 
1.8.1.5

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCHv2 10/11] tegrarcm: Add command to pass miniloader in from file
       [not found] ` <1379370298-20404-1-git-send-email-amartin-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
                     ` (7 preceding siblings ...)
  2013-09-16 22:24   ` [PATCHv2 09/11] tegrarcm: Add readbct support Allen Martin
@ 2013-09-16 22:24   ` Allen Martin
  2013-09-16 22:24   ` [PATCHv2 11/11] tegrarcm: Bump version to 1.5 Allen Martin
  2013-09-17 21:21   ` [PATCHv2 00/11] tegrarcm: T124 and new command support Stephen Warren
  10 siblings, 0 replies; 13+ messages in thread
From: Allen Martin @ 2013-09-16 22:24 UTC (permalink / raw)
  To: swarren-3lzwWm7+Weoh9ZMKESR00Q
  Cc: linux-tegra-u79uwXL29TY76Z2rM5mHXA, Allen Martin

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-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
---
 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 cf55748..f50006f 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:
-- 
1.8.1.5

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCHv2 11/11] tegrarcm: Bump version to 1.5
       [not found] ` <1379370298-20404-1-git-send-email-amartin-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
                     ` (8 preceding siblings ...)
  2013-09-16 22:24   ` [PATCHv2 10/11] tegrarcm: Add command to pass miniloader in from file Allen Martin
@ 2013-09-16 22:24   ` Allen Martin
  2013-09-17 21:21   ` [PATCHv2 00/11] tegrarcm: T124 and new command support Stephen Warren
  10 siblings, 0 replies; 13+ messages in thread
From: Allen Martin @ 2013-09-16 22:24 UTC (permalink / raw)
  To: swarren-3lzwWm7+Weoh9ZMKESR00Q
  Cc: linux-tegra-u79uwXL29TY76Z2rM5mHXA, Allen Martin

Update README with change log for version 1.5, and bump version
number.

Signed-off-by: Allen Martin <amartin-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
---
 README       | 4 ++++
 configure.ac | 2 +-
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/README b/README
index 4dde32b..764aecf 100644
--- a/README
+++ b/README
@@ -56,6 +56,10 @@ u-boot.bin sent successfully
 
 
 Changes (see git logs for complete list):
+V1.5 - Added support for RCM protocol version 40
+     - Added Tegra124 support
+     - Added support for readbct command
+     - Added support for passing in miniloader from a file
 V1.4 - Added --version command
      - Updated T114 miniloader to fix SPI boot problem
      - Added --help command to man page
diff --git a/configure.ac b/configure.ac
index 487666a..19285c9 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2,7 +2,7 @@
 # Process this file with autoconf to produce a configure script.
 
 AC_PREREQ([2.67])
-AC_INIT([tegrarcm], [1.4], [amartin-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org])
+AC_INIT([tegrarcm], [1.5], [amartin-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org])
 AM_INIT_AUTOMAKE
 AC_CONFIG_SRCDIR([src/main.c])
 AC_CONFIG_HEADERS([config.h])
-- 
1.8.1.5

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* Re: [PATCHv2 09/11] tegrarcm: Add readbct support
       [not found]     ` <1379370298-20404-10-git-send-email-amartin-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
@ 2013-09-17 21:19       ` Stephen Warren
  0 siblings, 0 replies; 13+ messages in thread
From: Stephen Warren @ 2013-09-17 21:19 UTC (permalink / raw)
  To: Allen Martin; +Cc: linux-tegra-u79uwXL29TY76Z2rM5mHXA

On 09/16/2013 04:24 PM, Allen Martin wrote:
> Add a new command "readbct" which will read the BCT from the target
> system and write it to bctfile.

> diff --git a/src/main.c b/src/main.c

> +static int read_bct(nv3p_handle_t h3p, char *filename)

> +	buf = bct_data;
> +	while(bct_info.length > 0) {
> +		ssize_t written = write(fd, buf, bct_info.length);
> +		if (written == -1) {
> +			if (errno == EINTR)
> +				continue;
> +			dprintf("error writing to %s\n", filename);
> +			return errno;

"ret = errno; goto out;" might be more appropriate there ...

> +		}
> +		buf += written;
> +		bct_info.length -= written;
> +	}

> +
> +	free(bct_data);
> +	close(fd);
> +	return 0;

and that could be:

	ret = 0;
out:
	free(bct_data);
	close(fd);
	return ret;

That way, everything gets closed/freed in the error paths to, albeit
it's not too relevant since the app will just immediately exit anyway.

Perhaps some of the other error paths also skip cleanup; I didn't check.

Feel free to fix this up as you apply or as a separate patch later.

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCHv2 00/11] tegrarcm: T124 and new command support
       [not found] ` <1379370298-20404-1-git-send-email-amartin-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
                     ` (9 preceding siblings ...)
  2013-09-16 22:24   ` [PATCHv2 11/11] tegrarcm: Bump version to 1.5 Allen Martin
@ 2013-09-17 21:21   ` Stephen Warren
  10 siblings, 0 replies; 13+ messages in thread
From: Stephen Warren @ 2013-09-17 21:21 UTC (permalink / raw)
  To: Allen Martin; +Cc: linux-tegra-u79uwXL29TY76Z2rM5mHXA

On 09/16/2013 04:24 PM, Allen Martin wrote:
> This patch series adds T124 support to tegrarcm, tested on laguna.  It
> also adds support for new commands for ripping a BCT from a live
> system, and for passing in the miniloader from a file.  Also fixed up
> some of the error handling so now USB commands will time out instead
> of hanging, and attempt to bring up nv3p even if RCM is unresponsive.

The series,
Reviewed-by: Stephen Warren <swarren-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2013-09-17 21:21 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-09-16 22:24 [PATCHv2 00/11] tegrarcm: T124 and new command support Allen Martin
     [not found] ` <1379370298-20404-1-git-send-email-amartin-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2013-09-16 22:24   ` [PATCHv2 01/11] tegrarcm: Change NVIDIA license to apply to all miniloader files Allen Martin
2013-09-16 22:24   ` [PATCHv2 02/11] tegrarcm: Add missing SKU information Allen Martin
2013-09-16 22:24   ` [PATCHv2 03/11] tegrarcm: Add support for RCM protocol version 40 Allen Martin
2013-09-16 22:24   ` [PATCHv2 05/11] tegrarcm: Add Tegra124 support Allen Martin
2013-09-16 22:24   ` [PATCHv2 06/11] tegrarcm: Add timeout to USB xfers Allen Martin
2013-09-16 22:24   ` [PATCHv2 07/11] tegrarcm: Assume nv3p server is running if RCM doesn't respond Allen Martin
2013-09-16 22:24   ` [PATCHv2 08/11] tegrarcm: Clean up usage info Allen Martin
2013-09-16 22:24   ` [PATCHv2 09/11] tegrarcm: Add readbct support Allen Martin
     [not found]     ` <1379370298-20404-10-git-send-email-amartin-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2013-09-17 21:19       ` Stephen Warren
2013-09-16 22:24   ` [PATCHv2 10/11] tegrarcm: Add command to pass miniloader in from file Allen Martin
2013-09-16 22:24   ` [PATCHv2 11/11] tegrarcm: Bump version to 1.5 Allen Martin
2013-09-17 21:21   ` [PATCHv2 00/11] tegrarcm: T124 and new command support Stephen Warren

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).