Merge commit '98a4f8e31872d3f72e47aba8b01a167503144c1e' into sam-update

This commit is contained in:
Jason Kotzin 2022-08-01 18:31:06 -07:00
commit 4346fb2405
12 changed files with 139 additions and 32 deletions

View File

@ -33,9 +33,7 @@
#define PLATFORM_HAS_TRACESWO #define PLATFORM_HAS_TRACESWO
#define BOARD_IDENT "Black Magic Probe (F4Discovery), (Firmware " FIRMWARE_VERSION ")" #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_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: /* Important pin mappings for STM32 implementation:
* *

View File

@ -36,7 +36,6 @@
#define BOARD_IDENT "Black Magic Probe (HydraBus), (Firmware " FIRMWARE_VERSION ")" #define BOARD_IDENT "Black Magic Probe (HydraBus), (Firmware " FIRMWARE_VERSION ")"
#define BOARD_IDENT_DFU "Black Magic (Upgrade) for 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_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: /* Important pin mappings for STM32 implementation:
* *

View File

@ -38,7 +38,6 @@
#define BOARD_IDENT_DFU "Black Magic Probe (Upgrade)" #define BOARD_IDENT_DFU "Black Magic Probe (Upgrade)"
#define BOARD_IDENT_UPD "Black Magic Probe (DFU Upgrade)" #define BOARD_IDENT_UPD "Black Magic Probe (DFU Upgrade)"
#define DFU_IDENT "Black Magic Firmware 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" #define UPD_IFACE_STRING "@Internal Flash /0x08000000/8*001Kg"
/* Important pin mappings for STM32 implementation: /* Important pin mappings for STM32 implementation:

View File

@ -0,0 +1,39 @@
Announced versus available Flash size on F103
============================================
Up to Stlink V2, the CPU soldered on the board was a F103C8 with 64 kiByte
flash. Up to about version 280 of BMP, this limit was not hit when linked
against nanolib.
StlinkV2-1 has a STM32F103CB, like a genuine BMP.
However with more and more devices supported, BMP at about version 282 hit
this limit. There are two ways to work around:
- Branch STlink V2-1 as separate platform and and care for the original STlink
platform by restricting/ommitting features.
- Rely on uncertain upper flash on F103C8
The first option needs more care as an additional platform is introduced and
will restrict usage of older STlinks as BMPs.
However F103C8 and F103CB have the same chip and upper flash exists on F103C8.
This flash may have been tested bad, or not have been tested at all,
or, in the best case, was tested good but market requirements made STM sell
it as F103C8.
Ignoring the chip marking and using an F103C8 blindly as a F103Cb is done
already with few problems on many china boards (e.g. blue pill). Probably
this second approach will work for many of the older STLinks.
Use at your own risk!
With DFU upload available in the bootloader, you can verify by uploading the
binary from flash and comparing it against the binary downloaded.
- Download new BMP binary (if not already done)
dfu-util -s 0x08002000:leave:force -D blackmagic.bin
- Get length of binary
> ls -l blackmagic.bin
-rwxr-xr-x 1 bon users 57372 15. Apr 14:17 blackmagic.bin
- Upload binary from flash
> dfu-util -s 0x08002000:leave:force:57372 -U blackmagic.bin.1
- Compare
> diff blackmagic.bin*

View File

@ -37,7 +37,6 @@
#define BOARD_IDENT_DFU "Black Magic (Upgrade) for STLink/Discovery, (Firmware " FIRMWARE_VERSION ")" #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 BOARD_IDENT_UPD "Black Magic (DFU Upgrade) for STLink/Discovery, (Firmware " FIRMWARE_VERSION ")"
#define DFU_IDENT "Black Magic Firmware Upgrade (STLINK)" #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" #define UPD_IFACE_STRING "@Internal Flash /0x08000000/8*001Kg"
/* Important pin mappings for STM32 implementation: /* Important pin mappings for STM32 implementation:

View File

@ -77,11 +77,25 @@ void dfu_protect(dfu_mode_t mode)
} }
#endif #endif
} }
else if (mode == UPD_MODE) { /* There is no way we can update the bootloader with a programm running
* on the same device when the bootloader pages are write
* protected or the device is read protected!
*
* Erasing option bytes to remove write protection will make the
* device read protected. Read protection means that the first pages
* get write protected again (PM0075, 2.4.1 Read protection.)
*
* Removing read protection after option erase results in device mass
* erase, crashing the update (PM0075, 2.4.2, Unprotection, Case 1).
*/
#if 0
else if ((mode == UPD_MODE) && ((FLASH_WRPR & 0x03) != 0x03)) {
flash_unlock(); flash_unlock();
FLASH_CR = 0; FLASH_CR = 0;
flash_erase_option_bytes(); flash_erase_option_bytes();
flash_program_option_bytes(FLASH_OBP_RDP, FLASH_OBP_RDP_KEY);
} }
#endif
} }
void dfu_jump_app_if_valid(void) void dfu_jump_app_if_valid(void)

View File

@ -22,10 +22,11 @@
#include <string.h> #include <string.h>
#if defined(STM32F1) #if defined(STM32F1)
# include <libopencm3/stm32/f1/flash.h> # include <libopencm3/stm32/f1/flash.h>
#elif defined(STM32F2) # define DFU_IFACE_STRING "@Internal Flash /0x08000000/8*001Ka,000*001Kg"
# include <libopencm3/stm32/f2/flash.h> # define DFU_IFACE_STRING_OFFSET 38
#elif defined(STM32F4) #elif defined(STM32F4)
# include <libopencm3/stm32/f4/flash.h> # include <libopencm3/stm32/f4/flash.h>
# define DFU_IFACE_STRING "/0x08000000/1*016Ka,3*016Kg,1*064Kg,7*128Kg"
#endif #endif
#include <libopencm3/usb/usbd.h> #include <libopencm3/usb/usbd.h>
#include <libopencm3/usb/dfu.h> #include <libopencm3/usb/dfu.h>
@ -48,6 +49,7 @@ static struct {
uint32_t addr; uint32_t addr;
uint16_t blocknum; uint16_t blocknum;
} prog; } prog;
static uint8_t current_error;
const struct usb_device_descriptor dev = { const struct usb_device_descriptor dev = {
.bLength = USB_DT_DEVICE_SIZE, .bLength = USB_DT_DEVICE_SIZE,
@ -69,7 +71,7 @@ const struct usb_device_descriptor dev = {
const struct usb_dfu_descriptor dfu_function = { const struct usb_dfu_descriptor dfu_function = {
.bLength = sizeof(struct usb_dfu_descriptor), .bLength = sizeof(struct usb_dfu_descriptor),
.bDescriptorType = DFU_FUNCTIONAL, .bDescriptorType = DFU_FUNCTIONAL,
.bmAttributes = USB_DFU_CAN_DOWNLOAD | USB_DFU_WILL_DETACH, .bmAttributes = USB_DFU_CAN_DOWNLOAD | USB_DFU_CAN_UPLOAD | USB_DFU_WILL_DETACH,
.wDetachTimeout = 255, .wDetachTimeout = 255,
.wTransferSize = 1024, .wTransferSize = 1024,
.bcdDFUVersion = 0x011A, .bcdDFUVersion = 0x011A,
@ -112,21 +114,23 @@ const struct usb_config_descriptor config = {
}; };
static char serial_no[9]; static char serial_no[9];
static char if_string[] = DFU_IFACE_STRING;
static const char *usb_strings[] = { static const char *usb_strings[] = {
"Black Sphere Technologies", "Black Sphere Technologies",
BOARD_IDENT_DFU, BOARD_IDENT_DFU,
serial_no, serial_no,
/* This string is used by ST Microelectronics' DfuSe utility */ /* This string is used by ST Microelectronics' DfuSe utility */
DFU_IFACE_STRING, if_string,
}; };
static char upd_if_string[] = UPD_IFACE_STRING;
static const char *usb_strings_upd[] = { static const char *usb_strings_upd[] = {
"Black Sphere Technologies", "Black Sphere Technologies",
BOARD_IDENT_UPD, BOARD_IDENT_UPD,
serial_no, serial_no,
/* This string is used by ST Microelectronics' DfuSe utility */ /* This string is used by ST Microelectronics' DfuSe utility */
UPD_IFACE_STRING, upd_if_string,
}; };
static uint32_t get_le32(const void *vp) static uint32_t get_le32(const void *vp)
@ -149,7 +153,8 @@ static uint8_t usbdfu_getstatus(uint32_t *bwPollTimeout)
/* Device will reset when read is complete */ /* Device will reset when read is complete */
usbdfu_state = STATE_DFU_MANIFEST; usbdfu_state = STATE_DFU_MANIFEST;
return DFU_STATUS_OK; return DFU_STATUS_OK;
case STATE_DFU_ERROR:
return current_error;
default: default:
return DFU_STATUS_OK; return DFU_STATUS_OK;
} }
@ -159,23 +164,17 @@ static void
usbdfu_getstatus_complete(usbd_device *dev, struct usb_setup_data *req) usbdfu_getstatus_complete(usbd_device *dev, struct usb_setup_data *req)
{ {
(void)req; (void)req;
(void)dev;
switch(usbdfu_state) { switch(usbdfu_state) {
case STATE_DFU_DNBUSY: case STATE_DFU_DNBUSY:
flash_unlock(); flash_unlock();
if(prog.blocknum == 0) { if(prog.blocknum == 0) {
uint32_t addr = get_le32(prog.buf + 1); int32_t addr = get_le32(prog.buf + 1);
if ((addr < app_address) || (addr >= max_address)) {
flash_lock();
usbd_ep_stall_set(dev, 0, 1);
return;
}
switch(prog.buf[0]) { switch(prog.buf[0]) {
case CMD_ERASE: case CMD_ERASE:
dfu_check_and_do_sector_erase(addr); dfu_check_and_do_sector_erase(addr);
case CMD_SETADDR:
prog.addr = addr;
} }
} else { } else {
uint32_t baseaddr = prog.addr + uint32_t baseaddr = prog.addr +
@ -218,6 +217,15 @@ static int usbdfu_control_request(usbd_device *dev,
prog.blocknum = req->wValue; prog.blocknum = req->wValue;
prog.len = *len; prog.len = *len;
memcpy(prog.buf, *buf, *len); memcpy(prog.buf, *buf, *len);
if ((req->wValue == 0) && (prog.buf[0] == CMD_SETADDR)) {
uint32_t addr = get_le32(prog.buf + 1);
if ((addr < app_address) || (addr >= max_address)) {
current_error = DFU_STATUS_ERR_TARGET;
usbdfu_state = STATE_DFU_ERROR;
return 1;
} else
prog.addr = addr;
}
usbdfu_state = STATE_DFU_DNLOAD_SYNC; usbdfu_state = STATE_DFU_DNLOAD_SYNC;
return 1; return 1;
} }
@ -231,8 +239,22 @@ static int usbdfu_control_request(usbd_device *dev,
usbdfu_state = STATE_DFU_IDLE; usbdfu_state = STATE_DFU_IDLE;
return 1; return 1;
case DFU_UPLOAD: case DFU_UPLOAD:
/* Upload not supported for now */ if ((usbdfu_state == STATE_DFU_IDLE) ||
return 0; (usbdfu_state == STATE_DFU_DNLOAD_IDLE) ||
(usbdfu_state == STATE_DFU_UPLOAD_IDLE)) {
prog.blocknum = req->wValue;
usbdfu_state = STATE_DFU_UPLOAD_IDLE;
if(prog.blocknum > 1) {
uint32_t baseaddr = prog.addr +
((prog.blocknum - 2) *
dfu_function.wTransferSize);
memcpy(*buf, (void*)baseaddr, *len);
}
return 1;
} else {
usbd_ep_stall_set(dev, 0, 1);
return 0;
}
case DFU_GETSTATUS: { case DFU_GETSTATUS: {
uint32_t bwPollTimeout = 0; /* 24-bit integer in DFU class spec */ uint32_t bwPollTimeout = 0; /* 24-bit integer in DFU class spec */
@ -278,6 +300,33 @@ void dfu_main(void)
usbd_poll(usbdev); 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) static char *get_dev_unique_id(char *s)
{ {
#if defined(STM32F4) || defined(STM32F2) #if defined(STM32F4) || defined(STM32F2)
@ -298,10 +347,21 @@ static char *get_dev_unique_id(char *s)
*(unique_id_p + 1) + *(unique_id_p + 1) +
*(unique_id_p + 2); *(unique_id_p + 2);
int i; int i;
uint32_t fuse_flash_size;
/* Calculated the upper flash limit from the exported data /* Calculated the upper flash limit from the exported data
in theparameter block*/ 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);
/* 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 */ /* Fetch serial number from chip's unique ID */
for(i = 0; i < 8; i++) { for(i = 0; i < 8; i++) {
s[7-i] = ((unique_id >> (4*i)) & 0xF) + '0'; s[7-i] = ((unique_id >> (4*i)) & 0xF) + '0';

View File

@ -33,7 +33,6 @@
#define BOARD_IDENT_DFU "Black Magic (Upgrade), STM8S Discovery, (Firmware " FIRMWARE_VERSION ")" #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 BOARD_IDENT_UPD "Black Magic (DFU Upgrade), STM8S Discovery, (Firmware " FIRMWARE_VERSION ")"
#define DFU_IDENT "Black Magic Firmware Upgrade (SWLINK)" #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" #define UPD_IFACE_STRING "@Internal Flash /0x08000000/8*001Kg"
/* Pin mappings: /* Pin mappings:

View File

@ -33,7 +33,7 @@
#include "target.h" #include "target.h"
#include "target_internal.h" #include "target_internal.h"
static char cortexa_driver_str[] = "ARM Cortex-A"; static const char cortexa_driver_str[] = "ARM Cortex-A";
static bool cortexa_attach(target *t); static bool cortexa_attach(target *t);
static void cortexa_detach(target *t); static void cortexa_detach(target *t);

View File

@ -34,7 +34,7 @@
#include <unistd.h> #include <unistd.h>
static char cortexm_driver_str[] = "ARM Cortex-M"; static const char cortexm_driver_str[] = "ARM Cortex-M";
static bool cortexm_vector_catch(target *t, int argc, char *argv[]); static bool cortexm_vector_catch(target *t, int argc, char *argv[]);

View File

@ -32,11 +32,11 @@
struct jtag_dev_s jtag_devs[JTAG_MAX_DEVS+1]; struct jtag_dev_s jtag_devs[JTAG_MAX_DEVS+1];
int jtag_dev_count; int jtag_dev_count;
static struct jtag_dev_descr_s { static const struct jtag_dev_descr_s {
uint32_t idcode; const uint32_t idcode;
uint32_t idmask; const uint32_t idmask;
char *descr; const char * const descr;
void (*handler)(jtag_dev_t *dev); void (*const handler)(jtag_dev_t *dev);
} dev_descr[] = { } dev_descr[] = {
{.idcode = 0x0BA00477, .idmask = 0x0FFF0FFF, {.idcode = 0x0BA00477, .idmask = 0x0FFF0FFF,
.descr = "ARM Limited: ADIv5 JTAG-DP port.", .descr = "ARM Limited: ADIv5 JTAG-DP port.",

View File

@ -36,7 +36,7 @@ typedef struct jtag_dev_s {
uint8_t ir_postscan; uint8_t ir_postscan;
uint32_t idcode; uint32_t idcode;
char *descr; const char *descr;
uint32_t current_ir; uint32_t current_ir;