blob: 04a899ee11849250ecfa2fa3bc7704479940bd86 [file] [log] [blame]
Patrick Delaunay7daa91d2020-03-18 09:24:49 +01001/* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */
2/*
3 * Copyright (C) 2020, STMicroelectronics - All Rights Reserved
4 */
5
6#ifndef _STM32PROG_H_
7#define _STM32PROG_H_
8
9/* - phase defines ------------------------------------------------*/
10#define PHASE_FLASHLAYOUT 0x00
11#define PHASE_FIRST_USER 0x10
12#define PHASE_LAST_USER 0xF0
13#define PHASE_CMD 0xF1
Patrick Delaunay1d96b182020-03-18 09:24:58 +010014#define PHASE_OTP 0xF2
Patrick Delaunay541c7de2020-03-18 09:24:59 +010015#define PHASE_PMIC 0xF4
Patrick Delaunay7daa91d2020-03-18 09:24:49 +010016#define PHASE_END 0xFE
17#define PHASE_RESET 0xFF
18#define PHASE_DO_RESET 0x1FF
19
20#define DEFAULT_ADDRESS 0xFFFFFFFF
21
Patrick Delaunaybd577492021-07-05 09:39:01 +020022#define CMD_SIZE 512
Patrick Delaunay9a699b72022-09-06 18:53:20 +020023/* SMC is only supported in SPMIN for STM32MP15x */
24#ifdef CONFIG_STM32MP15x
Patrick Delaunay8da5df92022-03-28 19:25:28 +020025#define OTP_SIZE_SMC 1024
Patrick Delaunay9a699b72022-09-06 18:53:20 +020026#else
27#define OTP_SIZE_SMC 0
28#endif
Patrick Delaunay8da5df92022-03-28 19:25:28 +020029#define OTP_SIZE_TA 776
Patrick Delaunay541c7de2020-03-18 09:24:59 +010030#define PMIC_SIZE 8
Patrick Delaunay1d96b182020-03-18 09:24:58 +010031
Patrick Delaunay7daa91d2020-03-18 09:24:49 +010032enum stm32prog_target {
33 STM32PROG_NONE,
Patrick Delaunay7aae1e32020-03-18 09:24:51 +010034 STM32PROG_MMC,
Patrick Delaunay6ab74962020-03-18 09:24:54 +010035 STM32PROG_NAND,
36 STM32PROG_NOR,
Patrick Delaunay41e6ace2020-03-18 09:25:03 +010037 STM32PROG_SPI_NAND,
38 STM32PROG_RAM
Patrick Delaunay7daa91d2020-03-18 09:24:49 +010039};
40
41enum stm32prog_link_t {
Patrick Delaunayb823d992020-03-18 09:25:00 +010042 LINK_SERIAL,
Patrick Delaunay7daa91d2020-03-18 09:24:49 +010043 LINK_USB,
44 LINK_UNDEFINED,
45};
46
Patrick Delaunay19676ef2021-04-02 14:05:17 +020047enum stm32prog_header_t {
48 HEADER_NONE,
49 HEADER_STM32IMAGE,
Patrick Delaunay953d8bf2022-03-28 19:25:29 +020050 HEADER_STM32IMAGE_V2,
Patrick Delaunay19676ef2021-04-02 14:05:17 +020051 HEADER_FIP,
52};
53
Patrick Delaunay7daa91d2020-03-18 09:24:49 +010054struct image_header_s {
Patrick Delaunay19676ef2021-04-02 14:05:17 +020055 enum stm32prog_header_t type;
Patrick Delaunay7daa91d2020-03-18 09:24:49 +010056 u32 image_checksum;
57 u32 image_length;
Patrick Delaunay953d8bf2022-03-28 19:25:29 +020058 u32 length;
Patrick Delaunay7daa91d2020-03-18 09:24:49 +010059};
60
Patrick Delaunay953d8bf2022-03-28 19:25:29 +020061struct stm32_header_v1 {
Patrick Delaunay7daa91d2020-03-18 09:24:49 +010062 u32 magic_number;
Patrick Delaunay953d8bf2022-03-28 19:25:29 +020063 u8 image_signature[64];
Patrick Delaunay7daa91d2020-03-18 09:24:49 +010064 u32 image_checksum;
65 u32 header_version;
66 u32 image_length;
67 u32 image_entry_point;
68 u32 reserved1;
69 u32 load_address;
70 u32 reserved2;
71 u32 version_number;
72 u32 option_flags;
73 u32 ecdsa_algorithm;
Patrick Delaunay953d8bf2022-03-28 19:25:29 +020074 u8 ecdsa_public_key[64];
75 u8 padding[83];
76 u8 binary_type;
Patrick Delaunay7daa91d2020-03-18 09:24:49 +010077};
78
Patrick Delaunay953d8bf2022-03-28 19:25:29 +020079struct stm32_header_v2 {
80 u32 magic_number;
81 u8 image_signature[64];
82 u32 image_checksum;
83 u32 header_version;
84 u32 image_length;
85 u32 image_entry_point;
86 u32 reserved1;
87 u32 load_address;
88 u32 reserved2;
89 u32 version_number;
90 u32 extension_flags;
91 u32 extension_headers_length;
92 u32 binary_type;
93 u8 padding[16];
94 u32 extension_header_type;
95 u32 extension_header_length;
96 u8 extension_padding[376];
97};
Patrick Delaunay7daa91d2020-03-18 09:24:49 +010098
99/* partition type in flashlayout file */
100enum stm32prog_part_type {
101 PART_BINARY,
Patrick Delaunay8dc57682022-03-28 19:25:30 +0200102 PART_FIP,
Patrick Delaunay7daa91d2020-03-18 09:24:49 +0100103 PART_SYSTEM,
104 PART_FILESYSTEM,
Patrick Delaunay8dc57682022-03-28 19:25:30 +0200105 RAW_IMAGE,
Patrick Delaunay7daa91d2020-03-18 09:24:49 +0100106};
107
108/* device information */
109struct stm32prog_dev_t {
110 enum stm32prog_target target;
111 char dev_id;
Patrick Delaunay7aae1e32020-03-18 09:24:51 +0100112 u32 erase_size;
113 struct mmc *mmc;
Patrick Delaunay6ab74962020-03-18 09:24:54 +0100114 struct mtd_info *mtd;
Patrick Delaunay7daa91d2020-03-18 09:24:49 +0100115 /* list of partition for this device / ordered in offset */
116 struct list_head part_list;
Patrick Delaunay5ce50062020-03-18 09:24:53 +0100117 bool full_update;
Patrick Delaunay7daa91d2020-03-18 09:24:49 +0100118};
119
120/* partition information build from FlashLayout and device */
121struct stm32prog_part_t {
122 /* FlashLayout information */
123 int option;
124 int id;
125 enum stm32prog_part_type part_type;
126 enum stm32prog_target target;
127 char dev_id;
128
129 /* partition name
130 * (16 char in gpt, + 1 for null terminated string
131 */
132 char name[16 + 1];
133 u64 addr;
134 u64 size;
Patrick Delaunay851d6f32020-03-18 09:24:56 +0100135 enum stm32prog_part_type bin_nb; /* SSBL repeatition */
Patrick Delaunay7daa91d2020-03-18 09:24:49 +0100136
137 /* information on associated device */
138 struct stm32prog_dev_t *dev; /* pointer to device */
Patrick Delaunay6915b492020-03-18 09:24:52 +0100139 s16 part_id; /* partition id in device */
Patrick Delaunay7daa91d2020-03-18 09:24:49 +0100140 int alt_id; /* alt id in usb/dfu */
141
142 struct list_head list;
143};
144
145#define STM32PROG_MAX_DEV 5
146struct stm32prog_data {
147 /* Layout information */
148 int dev_nb; /* device number*/
149 struct stm32prog_dev_t dev[STM32PROG_MAX_DEV]; /* array of device */
150 int part_nb; /* nb of partition */
151 struct stm32prog_part_t *part_array; /* array of partition */
Patrick Delaunayc5112242020-03-18 09:24:55 +0100152 bool fsbl_nor_detected;
Patrick Delaunay7daa91d2020-03-18 09:24:49 +0100153
154 /* command internal information */
155 unsigned int phase;
156 u32 offset;
157 char error[255];
158 struct stm32prog_part_t *cur_part;
Patrick Delaunay21ea4ef2022-09-06 18:53:19 +0200159 void *otp_part;
Patrick Delaunay541c7de2020-03-18 09:24:59 +0100160 u8 pmic_part[PMIC_SIZE];
Patrick Delaunay7daa91d2020-03-18 09:24:49 +0100161
Patrick Delaunayb823d992020-03-18 09:25:00 +0100162 /* SERIAL information */
163 u32 cursor;
164 u32 packet_number;
Patrick Delaunayb823d992020-03-18 09:25:00 +0100165 u8 *buffer; /* size = USART_RAM_BUFFER_SIZE*/
166 int dfu_seq;
167 u8 read_phase;
Patrick Delaunay41e6ace2020-03-18 09:25:03 +0100168
169 /* bootm information */
Patrick Delaunay21ea4ef2022-09-06 18:53:19 +0200170 uintptr_t uimage;
171 uintptr_t dtb;
172 uintptr_t initrd;
173 size_t initrd_size;
Patrick Delaunay8da5df92022-03-28 19:25:28 +0200174
Patrick Delaunay21ea4ef2022-09-06 18:53:19 +0200175 uintptr_t script;
Patrick Delaunayb9ef46b2022-03-28 19:25:32 +0200176
Patrick Delaunay8da5df92022-03-28 19:25:28 +0200177 /* OPTEE PTA NVMEM */
178 struct udevice *tee;
179 u32 tee_session;
Patrick Delaunay7daa91d2020-03-18 09:24:49 +0100180};
181
182extern struct stm32prog_data *stm32prog_data;
183
Patrick Delaunay1d96b182020-03-18 09:24:58 +0100184/* OTP access */
185int stm32prog_otp_write(struct stm32prog_data *data, u32 offset,
186 u8 *buffer, long *size);
187int stm32prog_otp_read(struct stm32prog_data *data, u32 offset,
188 u8 *buffer, long *size);
189int stm32prog_otp_start(struct stm32prog_data *data);
190
Patrick Delaunay541c7de2020-03-18 09:24:59 +0100191/* PMIC access */
192int stm32prog_pmic_write(struct stm32prog_data *data, u32 offset,
193 u8 *buffer, long *size);
194int stm32prog_pmic_read(struct stm32prog_data *data, u32 offset,
195 u8 *buffer, long *size);
196int stm32prog_pmic_start(struct stm32prog_data *data);
197
Patrick Delaunay7daa91d2020-03-18 09:24:49 +0100198/* generic part*/
Patrick Delaunay953d8bf2022-03-28 19:25:29 +0200199void stm32prog_header_check(uintptr_t raw_header, struct image_header_s *header);
Patrick Delaunay7daa91d2020-03-18 09:24:49 +0100200int stm32prog_dfu_init(struct stm32prog_data *data);
201void stm32prog_next_phase(struct stm32prog_data *data);
202void stm32prog_do_reset(struct stm32prog_data *data);
203
204char *stm32prog_get_error(struct stm32prog_data *data);
205
206#define stm32prog_err(args...) {\
207 if (data->phase != PHASE_RESET) { \
208 sprintf(data->error, args); \
209 data->phase = PHASE_RESET; \
Patrick Delaunay2b15af52020-11-06 19:01:30 +0100210 log_err("Error: %s\n", data->error); } \
Patrick Delaunay7daa91d2020-03-18 09:24:49 +0100211 }
212
213/* Main function */
Patrick Delaunay21ea4ef2022-09-06 18:53:19 +0200214int stm32prog_init(struct stm32prog_data *data, uintptr_t addr, ulong size);
Patrick Delaunay29b2e2e2021-02-25 13:37:01 +0100215void stm32prog_clean(struct stm32prog_data *data);
216
217#ifdef CONFIG_CMD_STM32PROG_SERIAL
Patrick Delaunayb823d992020-03-18 09:25:00 +0100218int stm32prog_serial_init(struct stm32prog_data *data, int link_dev);
219bool stm32prog_serial_loop(struct stm32prog_data *data);
Patrick Delaunay29b2e2e2021-02-25 13:37:01 +0100220#else
221static inline int stm32prog_serial_init(struct stm32prog_data *data, int link_dev)
222{
223 return -ENOSYS;
224}
225
226static inline bool stm32prog_serial_loop(struct stm32prog_data *data)
227{
228 return false;
229}
230#endif
231
232#ifdef CONFIG_CMD_STM32PROG_USB
Patrick Delaunay7daa91d2020-03-18 09:24:49 +0100233bool stm32prog_usb_loop(struct stm32prog_data *data, int dev);
Patrick Delaunay29b2e2e2021-02-25 13:37:01 +0100234#else
235static inline bool stm32prog_usb_loop(struct stm32prog_data *data, int dev)
236{
237 return false;
238}
239#endif
Patrick Delaunay7daa91d2020-03-18 09:24:49 +0100240
241#endif