From b09a522f373585e1752aa39b2317ad0e0caca84f Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Thu, 27 Apr 2017 19:00:15 +0200 Subject: [PATCH 1/2] STM32F103: Use flash size from device for DFU string. Complements #204. STLinkV2-1 has F103CB on board! F103C8 on older Stlinks can use upper flash with hopefully acceptable error rate. For F103C8 devices, user has to give the force option to dfu-utils. --- src/platforms/f4discovery/platform.h | 2 -- src/platforms/hydrabus/platform.h | 1 - src/platforms/native/platform.h | 1 - src/platforms/stlink/platform.h | 1 - src/platforms/stm32/dfucore.c | 42 +++++++++++++++++++++++++--- src/platforms/swlink/platform.h | 1 - 6 files changed, 38 insertions(+), 10 deletions(-) diff --git a/src/platforms/f4discovery/platform.h b/src/platforms/f4discovery/platform.h index d1260da..e274a38 100644 --- a/src/platforms/f4discovery/platform.h +++ b/src/platforms/f4discovery/platform.h @@ -33,9 +33,7 @@ #define PLATFORM_HAS_TRACESWO #define BOARD_IDENT "Black Magic Probe (F4Discovery), (Firmware " FIRMWARE_VERSION ")" -#define BOARD_IDENT_DFU "Black Magic (Upgrade) for F4Discovery, (Firmware " FIRMWARE_VERSION ")" #define DFU_IDENT "Black Magic Firmware Upgrade (F4Discovery" -#define DFU_IFACE_STRING "@Internal Flash /0x08000000/1*016Ka,3*016Kg,1*064Kg,7*128Kg" /* Important pin mappings for STM32 implementation: * diff --git a/src/platforms/hydrabus/platform.h b/src/platforms/hydrabus/platform.h index b340f97..d0ba61a 100644 --- a/src/platforms/hydrabus/platform.h +++ b/src/platforms/hydrabus/platform.h @@ -36,7 +36,6 @@ #define BOARD_IDENT "Black Magic Probe (HydraBus), (Firmware " FIRMWARE_VERSION ")" #define BOARD_IDENT_DFU "Black Magic (Upgrade) for HydraBus, (Firmware " FIRMWARE_VERSION ")" #define DFU_IDENT "Black Magic Firmware Upgrade (HydraBus)" -#define DFU_IFACE_STRING "@Internal Flash /0x08000000/1*016Ka,3*016Kg,1*064Kg,7*128Kg" /* Important pin mappings for STM32 implementation: * diff --git a/src/platforms/native/platform.h b/src/platforms/native/platform.h index 397dd8c..c18a8c8 100644 --- a/src/platforms/native/platform.h +++ b/src/platforms/native/platform.h @@ -38,7 +38,6 @@ #define BOARD_IDENT_DFU "Black Magic Probe (Upgrade)" #define BOARD_IDENT_UPD "Black Magic Probe (DFU Upgrade)" #define DFU_IDENT "Black Magic Firmware Upgrade" -#define DFU_IFACE_STRING "@Internal Flash /0x08000000/8*001Ka,120*001Kg" #define UPD_IFACE_STRING "@Internal Flash /0x08000000/8*001Kg" /* Important pin mappings for STM32 implementation: diff --git a/src/platforms/stlink/platform.h b/src/platforms/stlink/platform.h index ef03054..54125a9 100644 --- a/src/platforms/stlink/platform.h +++ b/src/platforms/stlink/platform.h @@ -37,7 +37,6 @@ #define BOARD_IDENT_DFU "Black Magic (Upgrade) for STLink/Discovery, (Firmware " FIRMWARE_VERSION ")" #define BOARD_IDENT_UPD "Black Magic (DFU Upgrade) for STLink/Discovery, (Firmware " FIRMWARE_VERSION ")" #define DFU_IDENT "Black Magic Firmware Upgrade (STLINK)" -#define DFU_IFACE_STRING "@Internal Flash /0x08000000/8*001Ka,56*001Kg" #define UPD_IFACE_STRING "@Internal Flash /0x08000000/8*001Kg" /* Important pin mappings for STM32 implementation: diff --git a/src/platforms/stm32/dfucore.c b/src/platforms/stm32/dfucore.c index bfe4f3a..f020e61 100644 --- a/src/platforms/stm32/dfucore.c +++ b/src/platforms/stm32/dfucore.c @@ -22,10 +22,11 @@ #include #if defined(STM32F1) # include -#elif defined(STM32F2) -# include +# define DFU_IFACE_STRING "@Internal Flash /0x08000000/8*001Ka,000*001Kg" +# define DFU_IFACE_STRING_OFFSET 38 #elif defined(STM32F4) # include +# define DFU_IFACE_STRING "/0x08000000/1*016Ka,3*016Kg,1*064Kg,7*128Kg" #endif #include #include @@ -113,13 +114,14 @@ const struct usb_config_descriptor config = { }; static char serial_no[9]; +static char if_string[] = DFU_IFACE_STRING; static const char *usb_strings[] = { "Black Sphere Technologies", BOARD_IDENT_DFU, serial_no, /* This string is used by ST Microelectronics' DfuSe utility */ - DFU_IFACE_STRING, + if_string, }; static const char *usb_strings_upd[] = { @@ -297,6 +299,33 @@ void dfu_main(void) usbd_poll(usbdev); } +#if defined(DFU_IFACE_STRING_OFFSET) +static void set_dfu_iface_string(uint32_t size) +{ + uint32_t res; + char *p = if_string + DFU_IFACE_STRING_OFFSET; + /* We do not want the whole printf library in the bootloader. + * Fill the size digits by hand. + */ + res = size / 100; + if (res > 9) { + *p++ = '9'; + *p++ = '9'; + *p++ = '9'; + return; + } else { + *p++ = res + '0'; + size -= res * 100; + } + res = size / 10; + *p++ = res + '0'; + size -= res * 10; + *p++ = size + '0'; +} +#else +# define set_dfu_iface_string() +#endif + static char *get_dev_unique_id(char *s) { #if defined(STM32F4) || defined(STM32F2) @@ -317,10 +346,15 @@ static char *get_dev_unique_id(char *s) *(unique_id_p + 1) + *(unique_id_p + 2); int i; + uint32_t fuse_flash_size; /* Calculated the upper flash limit from the exported data in theparameter block*/ - max_address = (*(uint32_t *) FLASH_SIZE_R) <<10; + fuse_flash_size = *(uint32_t *) FLASH_SIZE_R & 0xfff; + set_dfu_iface_string(fuse_flash_size - 8); + if (fuse_flash_size == 0x40) /* Handle F103x8 as F103xC! */ + fuse_flash_size = 0x80; + max_address = FLASH_BASE + (fuse_flash_size << 10); /* Fetch serial number from chip's unique ID */ for(i = 0; i < 8; i++) { s[7-i] = ((unique_id >> (4*i)) & 0xF) + '0'; diff --git a/src/platforms/swlink/platform.h b/src/platforms/swlink/platform.h index 74bb787..dbe4207 100644 --- a/src/platforms/swlink/platform.h +++ b/src/platforms/swlink/platform.h @@ -33,7 +33,6 @@ #define BOARD_IDENT_DFU "Black Magic (Upgrade), STM8S Discovery, (Firmware " FIRMWARE_VERSION ")" #define BOARD_IDENT_UPD "Black Magic (DFU Upgrade), STM8S Discovery, (Firmware " FIRMWARE_VERSION ")" #define DFU_IDENT "Black Magic Firmware Upgrade (SWLINK)" -#define DFU_IFACE_STRING "@Internal Flash /0x08000000/8*001Ka,56*001Kg" #define UPD_IFACE_STRING "@Internal Flash /0x08000000/8*001Kg" /* Pin mappings: From b7235da97fd5141ce1f0ea963237a8fb71e71930 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Fri, 28 Apr 2017 20:18:20 +0200 Subject: [PATCH 2/2] dfucore.c: Announce no writable bootloader pages when device is read proteced or bootloader is write protected. Device read protection or write protection on first 4 bootloader pages can only be removed by mass erase. Triggering mass erase with a program running from flash is doomed for failure. User can force bootloader update, at their own risk to brick the device. --- src/platforms/stm32/dfucore.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/platforms/stm32/dfucore.c b/src/platforms/stm32/dfucore.c index f020e61..61cfd04 100644 --- a/src/platforms/stm32/dfucore.c +++ b/src/platforms/stm32/dfucore.c @@ -124,12 +124,13 @@ static const char *usb_strings[] = { if_string, }; +static char upd_if_string[] = UPD_IFACE_STRING; static const char *usb_strings_upd[] = { "Black Sphere Technologies", BOARD_IDENT_UPD, serial_no, /* This string is used by ST Microelectronics' DfuSe utility */ - UPD_IFACE_STRING, + upd_if_string, }; static uint32_t get_le32(const void *vp) @@ -355,6 +356,12 @@ static char *get_dev_unique_id(char *s) if (fuse_flash_size == 0x40) /* Handle F103x8 as F103xC! */ fuse_flash_size = 0x80; max_address = FLASH_BASE + (fuse_flash_size << 10); + /* If bootloader pages are write protected or device is read + * protected, deny bootloader update. + * User can still force updates, at his own risk! + */ + if (((FLASH_WRPR & 0x03) != 0x03) || (FLASH_OBR & FLASH_OBR_RDPRT_EN)) + upd_if_string[30] = '0'; /* Fetch serial number from chip's unique ID */ for(i = 0; i < 8; i++) { s[7-i] = ((unique_id >> (4*i)) & 0xF) + '0';