summaryrefslogtreecommitdiff
path: root/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h
blob: 240c5c44bcbee40db6cbe5b19815e10e4a312ae7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
/* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */
/*
 * Copyright (C) 2020, STMicroelectronics - All Rights Reserved
 */

#ifndef _STM32PROG_H_
#define _STM32PROG_H_

/* - phase defines ------------------------------------------------*/
#define PHASE_FLASHLAYOUT	0x00
#define PHASE_FIRST_USER	0x10
#define PHASE_LAST_USER		0xF0
#define PHASE_CMD		0xF1
#define PHASE_OTP		0xF2
#define PHASE_PMIC		0xF4
#define PHASE_END		0xFE
#define PHASE_RESET		0xFF
#define PHASE_DO_RESET		0x1FF

#define DEFAULT_ADDRESS		0xFFFFFFFF

#define CMD_SIZE		512
#define OTP_SIZE		1024
#define PMIC_SIZE		8

enum stm32prog_target {
	STM32PROG_NONE,
	STM32PROG_MMC,
	STM32PROG_NAND,
	STM32PROG_NOR,
	STM32PROG_SPI_NAND,
	STM32PROG_RAM
};

enum stm32prog_link_t {
	LINK_SERIAL,
	LINK_USB,
	LINK_UNDEFINED,
};

enum stm32prog_header_t {
	HEADER_NONE,
	HEADER_STM32IMAGE,
	HEADER_FIP,
};

struct image_header_s {
	enum stm32prog_header_t type;
	u32	image_checksum;
	u32	image_length;
};

struct raw_header_s {
	u32 magic_number;
	u32 image_signature[64 / 4];
	u32 image_checksum;
	u32 header_version;
	u32 image_length;
	u32 image_entry_point;
	u32 reserved1;
	u32 load_address;
	u32 reserved2;
	u32 version_number;
	u32 option_flags;
	u32 ecdsa_algorithm;
	u32 ecdsa_public_key[64 / 4];
	u32 padding[83 / 4];
	u32 binary_type;
};

#define BL_HEADER_SIZE	sizeof(struct raw_header_s)

/* partition type in flashlayout file */
enum stm32prog_part_type {
	PART_BINARY,
	PART_SYSTEM,
	PART_FILESYSTEM,
	RAW_IMAGE
};

/* device information */
struct stm32prog_dev_t {
	enum stm32prog_target	target;
	char			dev_id;
	u32			erase_size;
	struct mmc		*mmc;
	struct mtd_info		*mtd;
	/* list of partition for this device / ordered in offset */
	struct list_head	part_list;
	bool			full_update;
};

/* partition information build from FlashLayout and device */
struct stm32prog_part_t {
	/* FlashLayout information */
	int			option;
	int			id;
	enum stm32prog_part_type part_type;
	enum stm32prog_target	target;
	char			dev_id;

	/* partition name
	 * (16 char in gpt, + 1 for null terminated string
	 */
	char			name[16 + 1];
	u64			addr;
	u64			size;
	enum stm32prog_part_type bin_nb;	/* SSBL repeatition */

	/* information on associated device */
	struct stm32prog_dev_t	*dev;		/* pointer to device */
	s16			part_id;	/* partition id in device */
	int			alt_id;		/* alt id in usb/dfu */

	struct list_head	list;
};

#define STM32PROG_MAX_DEV 5
struct stm32prog_data {
	/* Layout information */
	int			dev_nb;		/* device number*/
	struct stm32prog_dev_t	dev[STM32PROG_MAX_DEV];	/* array of device */
	int			part_nb;	/* nb of partition */
	struct stm32prog_part_t	*part_array;	/* array of partition */
#ifdef CONFIG_STM32MP15x_STM32IMAGE
	bool			tee_detected;
#endif
	bool			fsbl_nor_detected;

	/* command internal information */
	unsigned int		phase;
	u32			offset;
	char			error[255];
	struct stm32prog_part_t	*cur_part;
	u32			*otp_part;
	u8			pmic_part[PMIC_SIZE];

	/* SERIAL information */
	u32	cursor;
	u32	packet_number;
	u8	*buffer; /* size = USART_RAM_BUFFER_SIZE*/
	int	dfu_seq;
	u8	read_phase;

	/* bootm information */
	u32	uimage;
	u32	dtb;
	u32	initrd;
	u32	initrd_size;
};

extern struct stm32prog_data *stm32prog_data;

/* OTP access */
int stm32prog_otp_write(struct stm32prog_data *data, u32 offset,
			u8 *buffer, long *size);
int stm32prog_otp_read(struct stm32prog_data *data, u32 offset,
		       u8 *buffer, long *size);
int stm32prog_otp_start(struct stm32prog_data *data);

/* PMIC access */
int stm32prog_pmic_write(struct stm32prog_data *data, u32 offset,
			 u8 *buffer, long *size);
int stm32prog_pmic_read(struct stm32prog_data *data, u32 offset,
			u8 *buffer, long *size);
int stm32prog_pmic_start(struct stm32prog_data *data);

/* generic part*/
void stm32prog_header_check(struct raw_header_s *raw_header,
			    struct image_header_s *header);
int stm32prog_dfu_init(struct stm32prog_data *data);
void stm32prog_next_phase(struct stm32prog_data *data);
void stm32prog_do_reset(struct stm32prog_data *data);

char *stm32prog_get_error(struct stm32prog_data *data);

#define stm32prog_err(args...) {\
	if (data->phase != PHASE_RESET) { \
		sprintf(data->error, args); \
		data->phase = PHASE_RESET; \
		log_err("Error: %s\n", data->error); } \
	}

/* Main function */
int stm32prog_init(struct stm32prog_data *data, ulong addr, ulong size);
void stm32prog_clean(struct stm32prog_data *data);

#ifdef CONFIG_CMD_STM32PROG_SERIAL
int stm32prog_serial_init(struct stm32prog_data *data, int link_dev);
bool stm32prog_serial_loop(struct stm32prog_data *data);
#else
static inline int stm32prog_serial_init(struct stm32prog_data *data, int link_dev)
{
	return -ENOSYS;
}

static inline bool stm32prog_serial_loop(struct stm32prog_data *data)
{
	return false;
}
#endif

#ifdef CONFIG_CMD_STM32PROG_USB
bool stm32prog_usb_loop(struct stm32prog_data *data, int dev);
#else
static inline bool stm32prog_usb_loop(struct stm32prog_data *data, int dev)
{
	return false;
}
#endif

#endif