소스 검색

tools: kwbimage: Add support for DATA command also for v1 images

The DATA command is already supported by mkimage for v0 images, but not
for v1 images.

BootROM code which executes v1 images also supports DATA command via an
optional extended v1 header OPT_HDR_V1_REGISTER_TYPE.

Implement support for DATA command for v1 images.

Signed-off-by: Pali Rohár <pali@kernel.org>
Reviewed-by: Marek Behún <marek.behun@nic.cz>
Reviewed-by: Chris Packham <judge.packham@gmail.com>
Reviewed-by: Stefan Roese <sr@denx.de>
Tested-by: Chris Packham <judge.packham@gmail.com>
Pali Rohár 2 년 전
부모
커밋
02ba70ad68
2개의 변경된 파일58개의 추가작업 그리고 1개의 파일을 삭제
  1. 31 1
      tools/kwbimage.c
  2. 27 0
      tools/kwbimage.h

+ 31 - 1
tools/kwbimage.c

@@ -933,6 +933,7 @@ static void *image_create_v0(size_t *imagesz, struct image_tool_params *params,
 static size_t image_headersz_v1(int *hasext)
 static size_t image_headersz_v1(int *hasext)
 {
 {
 	struct image_cfg_element *binarye;
 	struct image_cfg_element *binarye;
+	unsigned int count;
 	size_t headersz;
 	size_t headersz;
 	int cfgi;
 	int cfgi;
 
 
@@ -942,6 +943,10 @@ static size_t image_headersz_v1(int *hasext)
 	 */
 	 */
 	headersz = sizeof(struct main_hdr_v1);
 	headersz = sizeof(struct main_hdr_v1);
 
 
+	count = image_count_options(IMAGE_CFG_DATA);
+	if (count > 0)
+		headersz += sizeof(struct register_set_hdr_v1) + 8 * count + 4;
+
 	for (cfgi = 0; cfgi < cfgn; cfgi++) {
 	for (cfgi = 0; cfgi < cfgn; cfgi++) {
 		int ret;
 		int ret;
 		struct stat s;
 		struct stat s;
@@ -1188,6 +1193,7 @@ static void *image_create_v1(size_t *imagesz, struct image_tool_params *params,
 {
 {
 	struct image_cfg_element *e;
 	struct image_cfg_element *e;
 	struct main_hdr_v1 *main_hdr;
 	struct main_hdr_v1 *main_hdr;
+	struct register_set_hdr_v1 *register_set_hdr;
 #if defined(CONFIG_KWB_SECURE)
 #if defined(CONFIG_KWB_SECURE)
 	struct secure_hdr_v1 *secure_hdr = NULL;
 	struct secure_hdr_v1 *secure_hdr = NULL;
 #endif
 #endif
@@ -1195,7 +1201,7 @@ static void *image_create_v1(size_t *imagesz, struct image_tool_params *params,
 	uint8_t *image, *cur;
 	uint8_t *image, *cur;
 	int hasext = 0;
 	int hasext = 0;
 	uint8_t *next_ext = NULL;
 	uint8_t *next_ext = NULL;
-	int cfgi;
+	int cfgi, datai, size;
 
 
 	/*
 	/*
 	 * Calculate the size of the header and the size of the
 	 * Calculate the size of the header and the size of the
@@ -1279,6 +1285,30 @@ static void *image_create_v1(size_t *imagesz, struct image_tool_params *params,
 	}
 	}
 #endif
 #endif
 
 
+	datai = 0;
+	register_set_hdr = (struct register_set_hdr_v1 *)cur;
+	for (cfgi = 0; cfgi < cfgn; cfgi++) {
+		e = &image_cfg[cfgi];
+		if (e->type != IMAGE_CFG_DATA)
+			continue;
+		register_set_hdr->data[datai].entry.address =
+			cpu_to_le32(e->regdata.raddr);
+		register_set_hdr->data[datai].entry.value =
+			cpu_to_le32(e->regdata.rdata);
+		datai++;
+	}
+	if (datai != 0) {
+		size = sizeof(struct register_set_hdr_v1) + 8 * datai + 4;
+		register_set_hdr->headertype = OPT_HDR_V1_REGISTER_TYPE;
+		register_set_hdr->headersz_lsb = cpu_to_le16(size & 0xFFFF);
+		register_set_hdr->headersz_msb = size >> 16;
+		/* Set delay to the smallest possible value 1ms. */
+		register_set_hdr->data[datai].last_entry.delay = 1;
+		cur += size;
+		*next_ext = 1;
+		next_ext = &register_set_hdr->data[datai].last_entry.next;
+	}
+
 	for (cfgi = 0; cfgi < cfgn; cfgi++) {
 	for (cfgi = 0; cfgi < cfgn; cfgi++) {
 		e = &image_cfg[cfgi];
 		e = &image_cfg[cfgi];
 		if (e->type != IMAGE_CFG_BINARY)
 		if (e->type != IMAGE_CFG_BINARY)

+ 27 - 0
tools/kwbimage.h

@@ -148,6 +148,33 @@ struct secure_hdr_v1 {
 	uint16_t reserved5;		/* 0x25E2 - 0x25E3 */
 	uint16_t reserved5;		/* 0x25E2 - 0x25E3 */
 };
 };
 
 
+/*
+ * Structure of register set
+ */
+struct register_set_hdr_v1 {
+	uint8_t  headertype;		/* 0x0 */
+	uint8_t  headersz_msb;		/* 0x1 */
+	uint16_t headersz_lsb;		/* 0x2 - 0x3 */
+	union {
+		struct {
+			uint32_t address;	/* 0x4+8*N - 0x7+8*N */
+			uint32_t value;		/* 0x8+8*N - 0xB+8*N */
+		} entry;
+		struct {
+			uint8_t  next;		/* 0xC+8*N */
+			uint8_t  delay;		/* 0xD+8*N */
+			uint16_t reserved;	/* 0xE+8*N - 0xF+8*N */
+		} last_entry;
+	} data[];
+};
+
+/*
+ * Value 0 in register_set_hdr_v1 delay field is special.
+ * Instead of delay it setup SDRAM Controller.
+ */
+#define REGISTER_SET_HDR_OPT_DELAY_SDRAM_SETUP 0
+#define REGISTER_SET_HDR_OPT_DELAY_MS(val) ((val) ?: 1)
+
 /*
 /*
  * Various values for the opt_hdr_v1->headertype field, describing the
  * Various values for the opt_hdr_v1->headertype field, describing the
  * different types of optional headers. The "secure" header contains
  * different types of optional headers. The "secure" header contains