summaryrefslogtreecommitdiff
path: root/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h
blob: b44b6f89afd80782812d7bfdec91c88a1f5b1c44 (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
/* 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_END		0xFE
#define PHASE_RESET		0xFF
#define PHASE_DO_RESET		0x1FF

#define DEFAULT_ADDRESS		0xFFFFFFFF

enum stm32prog_target {
	STM32PROG_NONE,
};

enum stm32prog_link_t {
	LINK_USB,
	LINK_UNDEFINED,
};

struct image_header_s {
	bool	present;
	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;
	/* list of partition for this device / ordered in offset */
	struct list_head	part_list;
};

/* 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;

	/* information on associated device */
	struct stm32prog_dev_t	*dev;		/* pointer to device */
	u16			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 */

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

	/* STM32 header information */
	struct raw_header_s	*header_data;
	struct image_header_s	header;
};

extern struct stm32prog_data *stm32prog_data;

/* generic part*/
u8 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; \
		pr_err("Error: %s\n", data->error); } \
	}

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

#endif