]> Git Repo - J-u-boot.git/blob - tools/sfspl.c
global: Rename SPL_ to XPL_
[J-u-boot.git] / tools / sfspl.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Copyright Heinrich Schuchardt <[email protected]>
4  *
5  * The StarFive JH7110 requires to prepend a header to u-boot-spl.bin describing
6  * the payload length and CRC32.
7  *
8  * This module implements support in mkimage and dumpimage for this file format.
9  *
10  * StarFive's spl_tool available under GPL-2.0-and-later at
11  * https://github.com/starfive-tech/Tools implements writing the same file
12  * format and served as a reference.
13  */
14
15 #include <compiler.h>
16 #include <fcntl.h>
17 #include <u-boot/crc.h>
18 #include <unistd.h>
19 #include "imagetool.h"
20
21 #define DEFAULT_VERSION 0x01010101
22 #define DEFAULT_BACKUP 0x200000U
23 #define DEFAULT_OFFSET 0x240
24
25 /**
26  * struct spl_hdr - header for SPL on JH7110
27  *
28  * All fields are low-endian.
29  */
30 struct spl_hdr {
31         /** @offset:    offset to SPL header (0x240) */
32         unsigned int offset;
33         /** @bkp_offs:  address of backup SPL, defaults to DEFAULT_BACKUP */
34         unsigned int bkp_offs;
35         /** @zero1:     set to zero */
36         unsigned int zero1[159];
37         /** @version:   header version, defaults to DEFAULT_VERSION */
38         unsigned int version;
39         /** @file_size: file size */
40         unsigned int file_size;
41         /** @hdr_size:  size of the file header (0x400) */
42         unsigned int hdr_size;
43         /** @crc32:     CRC32 */
44         unsigned int crc32;
45         /** @zero2:     set to zero */
46         unsigned int zero2[91];
47 };
48
49 static int sfspl_check_params(struct image_tool_params *params)
50 {
51         /* Only the RISC-V architecture is supported */
52         if (params->Aflag && params->arch != IH_ARCH_RISCV)
53                 return EXIT_FAILURE;
54
55         return EXIT_SUCCESS;
56 }
57
58 static int sfspl_verify_header(unsigned char *buf, int size,
59                                struct image_tool_params *params)
60 {
61         struct spl_hdr *hdr = (void *)buf;
62         unsigned int hdr_size = le32_to_cpu(hdr->hdr_size);
63         unsigned int file_size = le32_to_cpu(hdr->file_size);
64         unsigned int crc = le32_to_cpu(hdr->crc32);
65         unsigned int crc_check;
66
67         if (size < 0 ||
68             (size_t)size < sizeof(struct spl_hdr) ||
69             (size_t)size < hdr_size + file_size) {
70                 printf("Truncated file\n");
71                 return EXIT_FAILURE;
72         }
73         if (hdr->version != DEFAULT_VERSION) {
74                 printf("Unknown file format version\n");
75                 return EXIT_FAILURE;
76         }
77         crc_check = crc32(0, &buf[hdr_size], size - hdr_size);
78         if (crc_check != crc) {
79                 printf("Incorrect CRC32\n");
80                 return EXIT_FAILURE;
81         }
82
83         return EXIT_SUCCESS;
84 }
85
86 static void sfspl_print_header(const void *buf,
87                                struct image_tool_params *params)
88 {
89         struct spl_hdr *hdr = (void *)buf;
90         unsigned int hdr_size = le32_to_cpu(hdr->hdr_size);
91         unsigned int file_size = le32_to_cpu(hdr->file_size);
92
93         printf("Header size: %u\n", hdr_size);
94         printf("Payload size: %u\n", file_size);
95 }
96
97 static int sfspl_image_extract_subimage(void *ptr,
98                                         struct image_tool_params *params)
99 {
100         struct spl_hdr *hdr = (void *)ptr;
101         unsigned char *buf = ptr;
102         int fd, ret = EXIT_SUCCESS;
103         unsigned int hdr_size = le32_to_cpu(hdr->hdr_size);
104         unsigned int file_size = le32_to_cpu(hdr->file_size);
105
106         if (params->pflag) {
107                 printf("Invalid image index %d\n", params->pflag);
108                 return EXIT_FAILURE;
109         }
110
111         fd = open(params->outfile, O_WRONLY | O_CREAT | O_TRUNC, 0644);
112         if (fd == -1) {
113                 perror("Cannot open file");
114                 return EXIT_FAILURE;
115         }
116         if (write(fd, &buf[hdr_size], file_size) != file_size) {
117                 perror("Cannot write file");
118                 ret = EXIT_FAILURE;
119         }
120         close(fd);
121
122         return ret;
123 }
124
125 static int sfspl_check_image_type(uint8_t type)
126 {
127         if (type == IH_TYPE_STARFIVE_SPL)
128                 return EXIT_SUCCESS;
129
130         return EXIT_FAILURE;
131 }
132
133 static void sfspl_set_header(void *buf, struct stat *sbuf, int infd,
134                              struct image_tool_params *params)
135 {
136         struct spl_hdr *hdr = buf;
137         unsigned int file_size;
138         unsigned int crc;
139
140         file_size = params->file_size - sizeof(struct spl_hdr);
141         crc = crc32(0, &((unsigned char *)buf)[sizeof(struct spl_hdr)],
142                     file_size);
143
144         hdr->offset = cpu_to_le32(DEFAULT_OFFSET);
145         hdr->bkp_offs = cpu_to_le32(DEFAULT_BACKUP);
146         hdr->version = cpu_to_le32(DEFAULT_VERSION);
147         hdr->file_size = cpu_to_le32(file_size);
148         hdr->hdr_size = cpu_to_le32(sizeof(struct spl_hdr));
149         hdr->crc32 = cpu_to_le32(crc);
150 }
151
152 static int sfspl_vrec_header(struct image_tool_params *params,
153                              struct image_type_params *tparams)
154 {
155         tparams->hdr = calloc(sizeof(struct spl_hdr), 1);
156
157         /* No padding */
158         return 0;
159 }
160
161 U_BOOT_IMAGE_TYPE(
162         sfspl, /* id */
163         "StarFive SPL Image", /* name */
164         sizeof(struct spl_hdr), /* header_size */
165         NULL, /* header */
166         sfspl_check_params, /* check_params */
167         sfspl_verify_header, /* verify header */
168         sfspl_print_header, /* print header */
169         sfspl_set_header, /* set header */
170         sfspl_image_extract_subimage, /* extract_subimage */
171         sfspl_check_image_type, /* check_image_type */
172         NULL, /* fflag_handle */
173         sfspl_vrec_header /* vrec_header */
174 );
This page took 0.031924 seconds and 4 git commands to generate.