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 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 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 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