1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * (C) Copyright 2015 Google, Inc 4 * Written by Simon Glass <sjg@chromium.org> 5 * 6 * See README.rockchip for details of the rkspi format 7 */ 8 9 #include "imagetool.h" 10 #include <image.h> 11 #include <rc4.h> 12 #include "mkimage.h" 13 #include "rkcommon.h" 14 15 enum { 16 RKSPI_SECT_LEN = RK_BLK_SIZE * 4, 17 }; 18 19 static void rkspi_set_header(void *buf, struct stat *sbuf, int ifd, 20 struct image_tool_params *params) 21 { 22 int sector; 23 unsigned int size; 24 int ret; 25 26 size = params->orig_file_size; 27 ret = rkcommon_set_header(buf, size, params); 28 debug("size %x\n", size); 29 if (ret) { 30 /* TODO(sjg@chromium.org): This method should return an error */ 31 printf("Warning: SPL image is too large (size %#x) and will " 32 "not boot\n", size); 33 } 34 35 /* 36 * Spread the image out so we only use the first 2KB of each 4KB 37 * region. This is a feature of the SPI format required by the Rockchip 38 * boot ROM. Its rationale is unknown. 39 */ 40 for (sector = size / RKSPI_SECT_LEN - 1; sector >= 0; sector--) { 41 debug("sector %u\n", sector); 42 memmove(buf + sector * RKSPI_SECT_LEN * 2, 43 buf + sector * RKSPI_SECT_LEN, 44 RKSPI_SECT_LEN); 45 memset(buf + sector * RKSPI_SECT_LEN * 2 + RKSPI_SECT_LEN, 46 '\0', RKSPI_SECT_LEN); 47 } 48 } 49 50 static int rkspi_check_image_type(uint8_t type) 51 { 52 if (type == IH_TYPE_RKSPI) 53 return EXIT_SUCCESS; 54 else 55 return EXIT_FAILURE; 56 } 57 58 /* 59 * The SPI payload needs to be padded out to make space for odd half-sector 60 * layout used in flash (i.e. only the first 2K of each 4K sector is used). 61 */ 62 static int rkspi_vrec_header(struct image_tool_params *params, 63 struct image_type_params *tparams) 64 { 65 int padding = rkcommon_vrec_header(params, tparams, RK_INIT_SIZE_ALIGN); 66 /* 67 * The file size has not been adjusted at this point (our caller will 68 * eventually add the header/padding to the file_size), so we need to 69 * add up the header_size, file_size and padding ourselves. 70 */ 71 int padded_size = tparams->header_size + params->file_size + padding; 72 73 /* 74 * We need to store the original file-size (i.e. before padding), as 75 * imagetool does not set this during its adjustment of file_size. 76 */ 77 params->orig_file_size = padded_size; 78 79 /* 80 * Converting to the SPI format (i.e. splitting each 4K page into two 81 * 2K subpages and then padding these 2K pages up to take a complete 82 * 4K sector again) will will double the image size. 83 * 84 * Thus we return the padded_size as an additional padding requirement 85 * (be sure to add this to the padding returned from the common code). 86 */ 87 return padded_size + padding; 88 } 89 90 /* 91 * rk_spi parameters 92 */ 93 U_BOOT_IMAGE_TYPE( 94 rkspi, 95 "Rockchip SPI Boot Image support", 96 0, 97 NULL, 98 rkcommon_check_params, 99 rkcommon_verify_header, 100 rkcommon_print_header, 101 rkspi_set_header, 102 NULL, 103 rkspi_check_image_type, 104 NULL, 105 rkspi_vrec_header 106 ); 107