diff --git a/src/target/adiv5.c b/src/target/adiv5.c index 961af57..dbd8512 100644 --- a/src/target/adiv5.c +++ b/src/target/adiv5.c @@ -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)")}, diff --git a/src/target/adiv5.h b/src/target/adiv5.h index 189869b..10fc93a 100644 --- a/src/target/adiv5.h +++ b/src/target/adiv5.h @@ -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 diff --git a/src/target/cortexm.c b/src/target/cortexm.c index a738205..3f25b77 100644 --- a/src/target/cortexm.c +++ b/src/target/cortexm.c @@ -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); diff --git a/src/target/stm32l4.c b/src/target/stm32l4.c index b0f7f81..2e49328 100644 --- a/src/target/stm32l4.c +++ b/src/target/stm32l4.c @@ -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 * * * 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.