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