1 /*
2  * Copyright (c) 2021-2022, STMicroelectronics - All Rights Reserved
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include <limits.h>
8 #include <string.h>
9 
10 #include <common/debug.h>
11 #include <drivers/st/bsec.h>
12 #include <drivers/st/stm32mp1_usb.h>
13 #include <drivers/usb_device.h>
14 
15 #include <platform_def.h>
16 #include <stm32cubeprogrammer.h>
17 #include <stm32mp_common.h>
18 #include <usb_dfu.h>
19 
20 /*  String size (1 byte) + type (1 byte) + 24 UTF16 characters: 2 bytes each */
21 #define SIZ_STRING_SERIAL		U(24)
22 #define USB_SIZ_STRING_SERIAL		(1U + 1U + (SIZ_STRING_SERIAL * 2U))
23 #define USBD_MAX_STR_DESC_SIZ		0x100
24 #define USBD_VID			0x0483
25 #define USBD_PID			0xDF11
26 #define USBD_LANGID_STRING		0x409
27 #define USBD_MANUFACTURER_STRING	"STMicroelectronics"
28 #define USBD_CONFIGURATION_STRING	"DFU Config"
29 #define USBD_INTERFACE_STRING		"DFU Interface"
30 
31 #if STM32MP13
32 #define USB_DFU_ITF_NUM			2
33 #endif
34 #if STM32MP15
35 #define USB_DFU_ITF_NUM			6
36 #endif
37 
38 #define USB_DFU_CONFIG_DESC_SIZ		USB_DFU_DESC_SIZ(USB_DFU_ITF_NUM)
39 
40 /* DFU devices */
41 static struct usb_dfu_handle usb_dfu_handle;
42 
43 /* USB Standard Device Descriptor */
44 static const uint8_t usb_stm32mp1_desc[USB_LEN_DEV_DESC] = {
45 	USB_LEN_DEV_DESC,           /* bLength */
46 	USB_DESC_TYPE_DEVICE,       /* bDescriptorType */
47 	0x00,                       /* bcdUSB */
48 	0x02,                       /* version */
49 	0x00,                       /* bDeviceClass */
50 	0x00,                       /* bDeviceSubClass */
51 	0x00,                       /* bDeviceProtocol */
52 	USB_MAX_EP0_SIZE,           /* bMaxPacketSize */
53 	LOBYTE(USBD_VID),           /* idVendor */
54 	HIBYTE(USBD_VID),           /* idVendor */
55 	LOBYTE(USBD_PID),           /* idVendor */
56 	HIBYTE(USBD_PID),           /* idVendor */
57 	0x00,                       /* bcdDevice rel. 2.00 */
58 	0x02,
59 	USBD_IDX_MFC_STR,           /* Index of manufacturer string */
60 	USBD_IDX_PRODUCT_STR,       /* Index of product string */
61 	USBD_IDX_SERIAL_STR,        /* Index of serial number string */
62 	USBD_MAX_NUM_CONFIGURATION  /* bNumConfigurations */
63 }; /* USB_DeviceDescriptor */
64 
65 /* USB Standard String Descriptor */
66 static const uint8_t usb_stm32mp1_lang_id_desc[USB_LEN_LANGID_STR_DESC] = {
67 	USB_LEN_LANGID_STR_DESC,
68 	USB_DESC_TYPE_STRING,
69 	LOBYTE(USBD_LANGID_STRING),
70 	HIBYTE(USBD_LANGID_STRING),
71 };
72 
73 /* USB Standard Device Descriptor */
74 static const uint8_t
75 usbd_stm32mp1_qualifier_desc[USB_LEN_DEV_QUALIFIER_DESC] = {
76 	USB_LEN_DEV_QUALIFIER_DESC,
77 	USB_DESC_TYPE_DEVICE_QUALIFIER,
78 	0x00,
79 	0x02,
80 	0x00,
81 	0x00,
82 	0x00,
83 	0x40,
84 	0x01,
85 	0x00,
86 };
87 
88 /* USB serial number: build dynamically */
89 static uint8_t usb_stm32mp1_serial[USB_SIZ_STRING_SERIAL + 1];
90 
91 /* USB DFU device Configuration Descriptor */
92 static const uint8_t usb_stm32mp1_config_desc[USB_DFU_CONFIG_DESC_SIZ] = {
93 	0x09, /* bLength: Configuration Descriptor size */
94 	USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */
95 	USB_DFU_CONFIG_DESC_SIZ, /* wTotalLength: Bytes returned */
96 	0x00,
97 	0x01, /* bNumInterfaces: 1 interface */
98 	0x01, /* bConfigurationValue: Configuration value */
99 	0x02, /* iConfiguration: Index of string descriptor for configuration */
100 	0xC0, /* bmAttributes: bus powered and Supprts Remote Wakeup */
101 	0x32, /* MaxPower 100 mA: this current is used for detecting Vbus */
102 
103 	/* Descriptor of DFU interface 0 Alternate setting 0..N */
104 	USBD_DFU_IF_DESC(0),
105 	USBD_DFU_IF_DESC(1),
106 #if USB_DFU_ITF_NUM > 2
107 	USBD_DFU_IF_DESC(2),
108 #endif
109 #if USB_DFU_ITF_NUM > 3
110 	USBD_DFU_IF_DESC(3),
111 #endif
112 #if USB_DFU_ITF_NUM > 4
113 	USBD_DFU_IF_DESC(4),
114 #endif
115 #if USB_DFU_ITF_NUM > 5
116 	USBD_DFU_IF_DESC(5),
117 #endif
118 	/* DFU Functional Descriptor */
119 	0x09, /* blength = 9 Bytes */
120 	DFU_DESCRIPTOR_TYPE, /* DFU Functional Descriptor */
121 	DFU_BM_ATTRIBUTE, /* bmAttribute for DFU */
122 	0xFF, /* DetachTimeOut = 255 ms */
123 	0x00,
124 	TRANSFER_SIZE_BYTES(USBD_DFU_XFER_SIZE), /* TransferSize = 1024 Byte */
125 	((USB_DFU_VERSION >> 0) & 0xFF), /* bcdDFUVersion */
126 	((USB_DFU_VERSION >> 8) & 0xFF)
127 };
128 
129 /* The user strings: one by alternate as defined in USBD_DFU_IF_DESC */
130 #if STM32MP13
131 const char *const if_desc_string[USB_DFU_ITF_NUM] = {
132 	"@SSBL /0x03/1*16Me",
133 	"@virtual /0xF1/1*512Ba"
134 };
135 #endif
136 #if STM32MP15
137 const char *const if_desc_string[USB_DFU_ITF_NUM] = {
138 	"@Partition0 /0x00/1*256Ke",
139 	"@FSBL /0x01/1*1Me",
140 	"@Partition2 /0x02/1*1Me",
141 	"@Partition3 /0x03/1*16Me",
142 	"@Partition4 /0x04/1*16Me",
143 	"@virtual /0xF1/1*512Ba"
144 };
145 #endif
146 
147 /* Buffer to build the unicode string provided to USB device stack */
148 static uint8_t usb_str_dec[USBD_MAX_STR_DESC_SIZ];
149 
150 /*
151  * Convert Ascii string into unicode one
152  * desc : descriptor buffer
153  * unicode : Formatted string buffer (unicode)
154  * len : descriptor length
155  */
stm32mp1_get_string(const char * desc,uint8_t * unicode,uint16_t * len)156 static void stm32mp1_get_string(const char *desc, uint8_t *unicode, uint16_t *len)
157 {
158 	uint8_t idx = 0U;
159 
160 	if (desc == NULL) {
161 		return;
162 	}
163 
164 	*len =  strlen(desc) * 2U + 2U;
165 	unicode[idx++] = *len;
166 	unicode[idx++] =  USB_DESC_TYPE_STRING;
167 
168 	while (*desc != '\0') {
169 		unicode[idx++] = *desc++;
170 		unicode[idx++] =  0x00U;
171 	}
172 }
173 
174 /*
175  * Create the serial number string descriptor
176  */
update_serial_num_string(void)177 static void update_serial_num_string(void)
178 {
179 	uint8_t i;
180 	char serial_string[SIZ_STRING_SERIAL + 2U];
181 	/* serial number is set to 0 */
182 	uint32_t deviceserial[UID_WORD_NB] = {0U, 0U, 0U};
183 	uint32_t otp;
184 	uint32_t len;
185 	uint16_t length;
186 
187 	if (stm32_get_otp_index(UID_OTP, &otp, &len) != 0) {
188 		ERROR("BSEC: Get UID_OTP number Error\n");
189 		return;
190 	}
191 
192 	if ((len / __WORD_BIT) != UID_WORD_NB) {
193 		ERROR("BSEC: Get UID_OTP length Error\n");
194 		return;
195 	}
196 
197 	for (i = 0; i < UID_WORD_NB; i++) {
198 		if (bsec_shadow_read_otp(&deviceserial[i], i + otp) !=
199 		    BSEC_OK) {
200 			ERROR("BSEC: UID%d Error\n", i);
201 			return;
202 		}
203 	}
204 	/* build serial number with OTP value as in ROM code */
205 	snprintf(serial_string, sizeof(serial_string), "%08X%08X%08X",
206 		 deviceserial[0], deviceserial[1], deviceserial[2]);
207 
208 	length = USB_SIZ_STRING_SERIAL;
209 	stm32mp1_get_string(serial_string, usb_stm32mp1_serial, &length);
210 }
211 
212 /*
213  * Return Device Qualifier descriptor
214  * length : pointer data length
215  * return : pointer to descriptor buffer
216  */
stm32mp1_get_qualifier_desc(uint16_t * length)217 static uint8_t *stm32mp1_get_qualifier_desc(uint16_t *length)
218 {
219 	*length = sizeof(usbd_stm32mp1_qualifier_desc);
220 
221 	return (uint8_t *)usbd_stm32mp1_qualifier_desc;
222 }
223 
224 /*
225  * Return configuration descriptor
226  * length : pointer data length
227  * return : pointer to descriptor buffer
228  */
stm32mp1_get_config_desc(uint16_t * length)229 static uint8_t *stm32mp1_get_config_desc(uint16_t *length)
230 {
231 	*length = sizeof(usb_stm32mp1_config_desc);
232 
233 	return (uint8_t *)usb_stm32mp1_config_desc;
234 }
235 
236 /*
237  * Returns the device descriptor.
238  * length: Pointer to data length variable
239  * return : Pointer to descriptor buffer
240  */
stm32mp1_device_desc(uint16_t * length)241 static uint8_t *stm32mp1_device_desc(uint16_t *length)
242 {
243 	*length = sizeof(usb_stm32mp1_desc);
244 
245 	return (uint8_t *)usb_stm32mp1_desc;
246 }
247 
248 /*
249  * Returns the LangID string descriptor.
250  * length: Pointer to data length variable
251  * return : Pointer to descriptor buffer
252  */
stm32mp1_lang_id_desc(uint16_t * length)253 static uint8_t *stm32mp1_lang_id_desc(uint16_t *length)
254 {
255 	*length = sizeof(usb_stm32mp1_lang_id_desc);
256 
257 	return (uint8_t *)usb_stm32mp1_lang_id_desc;
258 }
259 
260 /*
261  *  Returns the product string descriptor.
262  * length: Pointer to data length variable
263  * return : Pointer to descriptor buffer
264  */
stm32mp1_product_desc(uint16_t * length)265 static uint8_t *stm32mp1_product_desc(uint16_t *length)
266 {
267 	char name[STM32_SOC_NAME_SIZE];
268 	char product[128];
269 	uint32_t chip_id;
270 	uint32_t chip_version;
271 
272 	stm32mp_get_soc_name(name);
273 	chip_id = stm32mp_get_chip_dev_id();
274 	chip_version = stm32mp_get_chip_version();
275 
276 	snprintf(product, sizeof(product),
277 		 "DFU @Device ID /0x%03X, @Revision ID /0x%04X, @Name /%s,",
278 		 chip_id, chip_version, name);
279 
280 	stm32mp1_get_string(product, usb_str_dec, length);
281 
282 	return usb_str_dec;
283 }
284 
285 /*
286  * Returns the manufacturer string descriptor.
287  * length: Pointer to data length variable
288  * return : Pointer to descriptor buffer
289  */
stm32mp1_manufacturer_desc(uint16_t * length)290 static uint8_t *stm32mp1_manufacturer_desc(uint16_t *length)
291 {
292 	stm32mp1_get_string(USBD_MANUFACTURER_STRING, usb_str_dec, length);
293 
294 	return usb_str_dec;
295 }
296 
297 /*
298  * Returns the serial number string descriptor.
299  * length: Pointer to data length variable
300  * return : Pointer to descriptor buffer
301  */
stm32mp1_serial_desc(uint16_t * length)302 static uint8_t *stm32mp1_serial_desc(uint16_t *length)
303 {
304 	*length = USB_SIZ_STRING_SERIAL;
305 
306 	return (uint8_t *)usb_stm32mp1_serial;
307 }
308 
309 /*
310  * Returns the configuration string descriptor.
311  * length: Pointer to data length variable
312  * return : Pointer to descriptor buffer
313  */
stm32mp1_config_desc(uint16_t * length)314 static uint8_t *stm32mp1_config_desc(uint16_t *length)
315 {
316 	stm32mp1_get_string(USBD_CONFIGURATION_STRING, usb_str_dec, length);
317 
318 	return usb_str_dec;
319 }
320 
321 /*
322  * Returns the interface string descriptor.
323  * length : Pointer to data length variable
324  * return : Pointer to descriptor buffer
325  */
stm32mp1_interface_desc(uint16_t * length)326 static uint8_t *stm32mp1_interface_desc(uint16_t *length)
327 {
328 	stm32mp1_get_string(USBD_INTERFACE_STRING, usb_str_dec, length);
329 
330 	return usb_str_dec;
331 }
332 
333 /*
334  * Manages the transfer of memory interfaces string descriptors.
335  * index: descriptor index
336  * length : pointer data length
337  * return : pointer to the descriptor table or NULL if the descriptor
338  *          is not supported.
339  */
stm32mp1_get_usr_desc(uint8_t index,uint16_t * length)340 static uint8_t *stm32mp1_get_usr_desc(uint8_t index, uint16_t *length)
341 {
342 	if (index >= ARRAY_SIZE(if_desc_string)) {
343 		return NULL;
344 	}
345 
346 	stm32mp1_get_string(if_desc_string[index], usb_str_dec, length);
347 
348 	return usb_str_dec;
349 }
350 
351 static const struct usb_desc dfu_desc = {
352 	.get_device_desc = stm32mp1_device_desc,
353 	.get_lang_id_desc = stm32mp1_lang_id_desc,
354 	.get_manufacturer_desc = stm32mp1_manufacturer_desc,
355 	.get_product_desc = stm32mp1_product_desc,
356 	.get_configuration_desc = stm32mp1_config_desc,
357 	.get_serial_desc = stm32mp1_serial_desc,
358 	.get_interface_desc = stm32mp1_interface_desc,
359 	.get_usr_desc = stm32mp1_get_usr_desc,
360 	.get_config_desc = stm32mp1_get_config_desc,
361 	.get_device_qualifier_desc = stm32mp1_get_qualifier_desc,
362 	/* only HS is supported, as ROM code */
363 	.get_other_speed_config_desc = NULL,
364 };
365 
366 static struct usb_handle usb_core_handle;
367 static struct pcd_handle pcd_handle;
368 
usb_dfu_plat_init(void)369 struct usb_handle *usb_dfu_plat_init(void)
370 {
371 	/* Prepare USB Driver */
372 	pcd_handle.in_ep[0].maxpacket = USB_MAX_EP0_SIZE;
373 	pcd_handle.out_ep[0].maxpacket = USB_MAX_EP0_SIZE;
374 	stm32mp1_usb_init_driver(&usb_core_handle, &pcd_handle,
375 				 (uint32_t *)USB_OTG_BASE);
376 
377 #if STM32MP15
378 	/* STM32MP15 = keep the configuration from ROM code */
379 	usb_core_handle.ep0_state = USBD_EP0_DATA_IN;
380 	usb_core_handle.dev_state = USBD_STATE_CONFIGURED;
381 #endif
382 
383 	/* Update the serial number string descriptor from the unique ID */
384 	update_serial_num_string();
385 
386 	/* Prepare USB DFU stack */
387 	usb_dfu_register(&usb_core_handle, &usb_dfu_handle);
388 
389 	/* Register DFU descriptor in USB stack */
390 	register_platform(&usb_core_handle, &dfu_desc);
391 
392 	return &usb_core_handle;
393 }
394 
395 /* Link between USB alternate and STM32CubeProgramer phase */
usb_dfu_get_phase(uint8_t alt)396 uint8_t usb_dfu_get_phase(uint8_t alt)
397 {
398 	uint8_t ret;
399 
400 	switch (alt) {
401 #if STM32MP13
402 	case 0:
403 		ret = PHASE_SSBL;
404 		break;
405 	case 1:
406 		ret = PHASE_CMD;
407 		break;
408 #endif
409 #if STM32MP15
410 	case 3:
411 		ret = PHASE_SSBL;
412 		break;
413 	case 5:
414 		ret = PHASE_CMD;
415 		break;
416 #endif
417 	default:
418 		ret = PHASE_RESET;
419 		break;
420 	}
421 
422 	return ret;
423 }
424