stm32wxxx: CPU2 needs wake-up call and has unexpected PIDR4 in AP1

"Single" core  STM32WLE still sees AP1 but on first scan aborts gracefully
after some errors and on later runs sees AP1 as unusable. Fixes #832.

Decode the Cross trigger interface found on CPU2 on STM32WBxx.
This commit is contained in:
Uwe Bonnes 2022-06-25 15:06:35 +02:00 committed by Rachel Mant
parent 471ba19a77
commit 80c98df2f9
4 changed files with 43 additions and 3 deletions

View File

@ -232,6 +232,7 @@ static const struct {
{0x975, 0x13, 0x4a13, aa_nosupport, cidc_unknown, PIDR_PN_BIT_STRINGS("Cortex-M7 ETM", "(Embedded Trace)")},
{0x9a0, 0x00, 0, aa_nosupport, cidc_unknown, PIDR_PN_BIT_STRINGS("CoreSight PMU", "(Performance Monitoring Unit)")},
{0x9a1, 0x11, 0, aa_nosupport, cidc_unknown, PIDR_PN_BIT_STRINGS("Cortex-M4 TPIU", "(Trace Port Interface Unit)")},
{0x9a6, 0x14, 0x1a14, aa_nosupport, cidc_dc, PIDR_PN_BIT_STRINGS("Cortex-M0+ CTI", "(Cross Trigger Interface)")},
{0x9a9, 0x11, 0, aa_nosupport, cidc_unknown, PIDR_PN_BIT_STRINGS("Cortex-M7 TPIU", "(Trace Port Interface Unit)")},
{0x9a5, 0x00, 0, aa_nosupport, cidc_unknown, PIDR_PN_BIT_STRINGS("Cortex-A5 ETM", "(Embedded Trace)")},
{0x9a7, 0x16, 0, aa_nosupport, cidc_unknown, PIDR_PN_BIT_STRINGS("Cortex-A7 PMU", "(Performance Monitor Unit)")},

View File

@ -95,6 +95,15 @@
#define AP_DESIGNER_TEXAS 0x017
#define AP_DESIGNER_ATMEL 0x01f
#define AP_DESIGNER_STM 0x020
/* CPU2 for STM32W(L|B) uses ARM JEDEC continuation (4) and
* not STM ARM JEDEC continuation (0) as for CPU1.
* See RM0453
* https://www.st.com/resource/en/reference_manual/rm0453-stm32wl5x-advanced-armbased-32bit-mcus-with-subghz-radio-solution-stmicroelectronics.pdf :
* 38.8.2 CPU1 ROM CoreSight peripheral identity register 4 (ROM_PIDR4)
* vs
* 38.13.2 CPU2 ROM1 CoreSight peripheral identity register 4 (C2ROM1_PIDR4)
*/
#define AP_DESIGNER_STM32WX 0x420
#define AP_DESIGNER_CYPRESS 0x034
#define AP_DESIGNER_INFINEON 0x041
#define AP_DESIGNER_NORDIC 0x244

View File

@ -395,6 +395,9 @@ bool cortexm_probe(ADIv5_AP_t *ap)
case AP_DESIGNER_GIGADEVICE:
PROBE(gd32f1_probe);
break;
case AP_DESIGNER_STM32WX:
PROBE(stm32l4_probe);
break;
case AP_DESIGNER_STM:
PROBE(stm32f1_probe);
PROBE(stm32f4_probe);

View File

@ -1,7 +1,7 @@
/*
* This file is part of the Black Magic Debug project.
*
* Copyright (C) 2015, 2017 - 2021 Uwe Bonnes
* Copyright (C) 2015, 2017 - 2022 Uwe Bonnes
* <bon@elektron.ikp.physik.tu-darmstadt.de>
*
* This program is free software: you can redistribute it and/or modify
@ -29,6 +29,9 @@
* ARM®-based 32-bit MCUs Rev.3
* RM0432 STM32L4Rxxx and STM32L4Sxxx advanced Arm®-based 32-bit MCU. Rev 1
* RM0440 STM32G4 Series advanced Arm®-based 32-bit MCU. Rev 6
* RM0434 Multiprotocol wireless 32-bit MCU Arm®-based Cortex®-M4 with
* FPU, Bluetooth® Low-Energy and 802.15.4 radio solution
* RM0453 STM32WL5x advanced Arm®-based 32-bit MCUswith sub-GHz radio solution
*
*
*/
@ -63,6 +66,10 @@ static int stm32l4_flash_write(struct target_flash *f,
#define L5_FLASH_OPTR_TZEN (1 << 31)
#define FLASH_OPTR_ESE (1 << 8)
#define PWR_CR4 0x5800040C
#define PWR_CR4_C2BOOT (1 << 15)
#define FLASH_CR_PG (1 << 0)
#define FLASH_CR_PER (1 << 1)
#define FLASH_CR_MER1 (1 << 2)
@ -309,7 +316,7 @@ static struct stm32l4_info const L4info[] = {
.idcode = ID_STM32WLXX,
.family = FAM_STM32WLxx,
.designator = "STM32WLxx",
.sram1 = 64,
.sram1 = 32,
.sram2 = 32,
.flags = 2,
.flash_regs_map = stm32wl_flash_regs_map,
@ -524,7 +531,24 @@ bool stm32l4_probe(target *t)
if( !chip->idcode ) /* Not found */
return false;
t->driver = chip->designator;
switch (idcode) {
case ID_STM32WLXX:
case ID_STM32WBXX:
if ((stm32l4_flash_read32(t, FLASH_OPTR)) & FLASH_OPTR_ESE) {
DEBUG_WARN("STM32W security enabled\n");
t->driver = (idcode == ID_STM32WLXX) ?
"STM32WLxx(secure)" : "STM32WBxx(secure)";
}
if (ap->apsel == 0) {
/* Enable CPU2 from CPU1.
* CPU2 does not boot after reset w/o C2BOOT set.
* RM0453/RM0434, 6.6.4. PWR control register 4 (PWR_CR4)*/
uint32_t pwr_cr4 = target_mem_read32(t, PWR_CR4);
pwr_cr4 |= PWR_CR4_C2BOOT;
target_mem_write32(t, PWR_CR4, pwr_cr4);
}
break;
case ID_STM32L55:
if ((stm32l4_flash_read32(t, FLASH_OPTR)) & L5_FLASH_OPTR_TZEN) {
DEBUG_WARN("STM32L5 Trust Zone enabled\n");
@ -532,7 +556,6 @@ bool stm32l4_probe(target *t)
break;
}
}
t->driver = chip->designator;
t->attach = stm32l4_attach;
t->detach = stm32l4_detach;
target_add_commands(t, stm32l4_cmd_list, chip->designator);
@ -725,6 +748,10 @@ static bool stm32l4_cmd_option(target *t, int argc, char *argv[])
tc_printf(t, "STM32WBxx options not implemented!\n");
return false;
}
if (t->idcode == ID_STM32WLXX) {
tc_printf(t, "STM32WLxx options not implemented!\n");
return false;
}
static const uint32_t g4_values[11] = {
/* SEC_SIZE1 occupies 9 bits on G49/G4A (cat 4),
* 8 bits on cat 3 and 7 bits on cat 2.