xref: /OK3568_Linux_fs/u-boot/tools/rknand.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /*
2  * Copyright (c) 2017 Paweł Jarosz <paweljarosz3691@gmail.com>
3  *
4  * SPDX-License-Identifier:     GPL-2.0+
5  */
6 
7 #include "imagetool.h"
8 #include <image.h>
9 #include <rc4.h>
10 #include "mkimage.h"
11 #include "rkcommon.h"
12 
13 #define DIV_ROUND_UP(n, d)	(((n) + (d) - 1) / (d))
14 
15 enum {
16 	RKNAND_SECT_LEN = RK_BLK_SIZE * 4,
17 };
18 
19 struct rknand_info {
20 	uint32_t pagesize;
21 	uint32_t itersize;
22 	uint32_t tplsplsize;
23 };
24 
25 struct rknand_info ninfo;
26 
rknand_set_header(void * buf,struct stat * sbuf,int ifd,struct image_tool_params * params)27 static void rknand_set_header(void *buf, struct stat *sbuf, int ifd,
28 			     struct image_tool_params *params)
29 {
30 	int sector;
31 	unsigned int size;
32 
33 	size = params->orig_file_size;
34 
35 	rkcommon_set_header(buf, sbuf, ifd, params);
36 
37 	/*
38 	 * Spread the image out so we only use the first 2KB of each pagesize
39 	 * region. This is a feature of the NAND format required by the Rockchip
40 	 * boot ROM.
41 	 */
42 	if (params->vflag)
43 		fprintf(stderr, "Spreading nand image from %u to %u\n",
44 			size, params->file_size);
45 
46 	for (sector = ninfo.tplsplsize / ninfo.itersize - 1; sector >= 0;
47 	     sector--) {
48 		memmove(buf + ninfo.pagesize + sector * ninfo.itersize,
49 			buf + RK_SPL_HDR_START + sector * RKNAND_SECT_LEN,
50 			RKNAND_SECT_LEN);
51 
52 		memset(buf + ninfo.pagesize + sector * ninfo.itersize +
53 		       RKNAND_SECT_LEN, 0xFF,
54 		       ninfo.itersize - RKNAND_SECT_LEN);
55 	}
56 
57 	/* Fill up padded area of the header. */
58 	memset(buf + RK_SPL_HDR_START, 0xFF, ninfo.pagesize - RK_SPL_HDR_START);
59 }
60 
rknand_check_image_type(uint8_t type)61 static int rknand_check_image_type(uint8_t type)
62 {
63 	if (type == IH_TYPE_RKNAND)
64 		return EXIT_SUCCESS;
65 	else
66 		return EXIT_FAILURE;
67 }
68 
rknand_vrec_header(struct image_tool_params * params,struct image_type_params * tparams)69 static int rknand_vrec_header(struct image_tool_params *params,
70 			     struct image_type_params *tparams)
71 {
72 	int tplsplsize;
73 	uint32_t skippages;
74 	int ret;
75 
76 	rkcommon_vrec_header(params, tparams);
77 
78 	ret = sscanf(params->extraparams, "%u,%u", &ninfo.pagesize, &skippages);
79 	if (ret != 2 || (ninfo.pagesize % RKNAND_SECT_LEN)) {
80 		fprintf(stderr, "%s: Wrong nand params\n", params->cmdname);
81 		exit(EXIT_FAILURE);
82 	}
83 
84 	ninfo.itersize = ninfo.pagesize * (skippages + 1);
85 
86 	tplsplsize = params->file_size - RK_SPL_HDR_START;
87 	ninfo.tplsplsize =
88 		DIV_ROUND_UP(tplsplsize, RKNAND_SECT_LEN) * ninfo.itersize;
89 
90 	/* Padded file size = padded header + padded tpl & spl. */
91 	params->file_size = ninfo.pagesize + ninfo.tplsplsize;
92 
93 	return 0;
94 }
95 
96 /*
97  * rknand parameters
98  */
99 U_BOOT_IMAGE_TYPE(
100 	rknand,
101 	"Rockchip NAND Boot Image support",
102 	0,
103 	NULL,
104 	rkcommon_check_params,
105 	/* TODO: Support rknand in there helpers */
106 	NULL, //rkcommon_verify_header,
107 	NULL, //rkcommon_print_header,
108 	rknand_set_header,
109 	NULL,
110 	rknand_check_image_type,
111 	NULL,
112 	rknand_vrec_header
113 );
114