diff --git a/src/target/cortexar.c b/src/target/cortexar.c index 3abe83cbeb2..a88ba6063c1 100644 --- a/src/target/cortexar.c +++ b/src/target/cortexar.c @@ -808,6 +808,12 @@ bool cortexa_probe(adiv5_access_port_s *const ap, const target_addr_t base_addre if (!target) return false; + switch (target->designer_code) { + case JEP106_MANUFACTURER_STM: + PROBE(stm32mp15_ca7_probe); + break; + } + #if PC_HOSTED == 0 gdb_outf("Please report unknown device with Designer 0x%x Part ID 0x%x\n", target->designer_code, target->part_id); #else diff --git a/src/target/stm32f1.c b/src/target/stm32f1.c index 46f651959cd..ca539b3a547 100644 --- a/src/target/stm32f1.c +++ b/src/target/stm32f1.c @@ -537,6 +537,7 @@ bool stm32f1_probe(target_s *target) break; default: /* NONE */ + target->mass_erase = NULL; return false; } diff --git a/src/target/stm32mp15.c b/src/target/stm32mp15.c index ae11884486c..32e8d732e35 100644 --- a/src/target/stm32mp15.c +++ b/src/target/stm32mp15.c @@ -3,6 +3,7 @@ * * Copyright (C) 2023 1BitSquared * Written by ALTracer + * Modified by Rachel Mant * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -33,25 +34,31 @@ #include "cortexm.h" /* Memory map constants for STM32MP15x */ -#define STM32MP15_CM4_RETRAM_BASE 0x00000000U -#define STM32MP15_RETRAM_SIZE 0x00001000U /* RETRAM, 64 KiB */ -#define STM32MP15_CM4_AHBSRAM_BASE 0x10000000U -#define STM32MP15_AHBSRAM_SIZE 0x00060000U /* AHB SRAM 1+2+3+4, 128+128+64+64 KiB */ +#define STM32MP15_CM4_RETRAM_BASE 0x00000000U +#define STM32MP15_CA7_RETRAM_BASE 0x38000000U +#define STM32MP15_RETRAM_SIZE 0x00010000U /* RETRAM, 64 KiB */ +#define STM32MP15_AHBSRAM_BASE 0x10000000U +#define STM32MP15_CA7_AHBSRAM_ALIAS_BASE 0x30000000U +#define STM32MP15_AHBSRAM_SIZE 0x00060000U /* AHB SRAM 1+2+3+4, 128+128+64+64 KiB */ +#define STM32MP15_SYSRAM_BASE 0x2ffc0000U +#define STM32MP15_SYSRAM_SIZE 0x00040000U +#define STM32MP15_CAN_SRAM_BASE 0x44011000U +#define STM32MP15_CAN_SRAM_SIZE 0x00002800U /* Access from processor address space. * Access via the debug APB is at 0xe0081000 over AP1. */ #define STM32MP15_DBGMCU_BASE 0x50081000U #define STM32MP15_UID_BASE 0x5c005234U -#define DBGMCU_IDCODE (STM32MP15_DBGMCU_BASE + 0U) -#define DBGMCU_CTRL (STM32MP15_DBGMCU_BASE + 4U) +#define DBGMCU_IDCODE (STM32MP15_DBGMCU_BASE + 0x000U) +#define DBGMCU_CTRL (STM32MP15_DBGMCU_BASE + 0x004U) #define DBGMCU_CTRL_DBGSLEEP (1U << 0U) #define DBGMCU_CTRL_DBGSTOP (1U << 1U) #define DBGMCU_CTRL_DBGSTBY (1U << 2U) /* Taken from DP_TARGETID.TPARTNO = 0x5000 in §66.8.3 of RM0436 rev 6, pg3669 */ /* Taken from DBGMCU_IDC.DEV_ID = 0x500 in §66.10.9 of RM0436 rev 6, pg3825 */ -#define ID_STM32MP15x 0x5000U +#define ID_STM32MP15x 0x500U /* Taken from CM4ROM_PIDRx in 2.3.21 of ES0438 rev 7, pg18 */ #define ID_STM32MP15x_ERRATA 0x450U @@ -68,31 +75,30 @@ const command_s stm32mp15_cmd_list[] = { {NULL, NULL, NULL}, }; -static bool stm32mp15_attach(target_s *target) -{ - if (!cortexm_attach(target)) - return false; - - /* Save DBGMCU_CR to restore it when detaching */ - stm32mp15_priv_s *const priv = (stm32mp15_priv_s *)target->target_storage; - priv->dbgmcu_ctrl = target_mem_read32(target, DBGMCU_CTRL); - - /* Disable C-Sleep, C-Stop, C-Standby for debugging */ - target_mem_write32(target, DBGMCU_CTRL, DBGMCU_CTRL_DBGSLEEP | DBGMCU_CTRL_DBGSTOP | DBGMCU_CTRL_DBGSTBY); - - return true; -} +static bool stm32mp15_attach(target_s *target); +static void stm32mp15_detach(target_s *target); -static void stm32mp15_detach(target_s *target) +static bool stm32mp15_ident(target_s *const target, const bool cortexm) { - stm32mp15_priv_s *priv = (stm32mp15_priv_s *)target->target_storage; - target_mem_write32(target, DBGMCU_CTRL, priv->dbgmcu_ctrl); - cortexm_detach(target); + const adiv5_access_port_s *const ap = cortex_ap(target); + /* Check if the part's a STM32MP15 */ + if (ap->partno != ID_STM32MP15x) { + /* If it's not a Cortex-M core or it doesn't match the errata ID code, return false */ + if (!cortexm || ap->partno != ID_STM32MP15x_ERRATA) + return false; + } + /* + * We now know the part is either a Cortex-M core with the errata code, or matched the main ID code. + * Copy the correct (AP) part number over to the target structure to handle the difference between + * JTAG and SWD as ST has a different ID in the DP TARGETID register vs the ROM tables, which needs ignoring. + */ + target->part_id = ap->partno; + return true; } -bool stm32mp15_cm4_probe(target_s *target) +bool stm32mp15_cm4_probe(target_s *const target) { - if (target->part_id != ID_STM32MP15x && target->part_id != ID_STM32MP15x_ERRATA) + if (!stm32mp15_ident(target, true)) return false; target->driver = "STM32MP15"; @@ -102,20 +108,70 @@ bool stm32mp15_cm4_probe(target_s *target) /* Allocate private storage */ stm32mp15_priv_s *priv = calloc(1, sizeof(*priv)); + if (!priv) { /* calloc failed: heap exhaustion */ + DEBUG_ERROR("calloc: failed in %s\n", __func__); + return false; + } target->target_storage = priv; /* Figure 4. Memory map from §2.5.2 in RM0436 rev 6, pg158 */ target_add_ram(target, STM32MP15_CM4_RETRAM_BASE, STM32MP15_RETRAM_SIZE); - target_add_ram(target, STM32MP15_CM4_AHBSRAM_BASE, STM32MP15_AHBSRAM_SIZE); + target_add_ram(target, STM32MP15_AHBSRAM_BASE, STM32MP15_AHBSRAM_SIZE); + + return true; +} + +#ifdef ENABLE_CORTEXAR +bool stm32mp15_ca7_probe(target_s *const target) +{ + if (!stm32mp15_ident(target, false)) + return false; + + target->driver = "STM32MP15"; + target_add_commands(target, stm32mp15_cmd_list, target->driver); + /* Figure 4. Memory map from §2.5.2 in RM0436 rev 6, pg158 */ + target_add_ram(target, STM32MP15_CA7_RETRAM_BASE, STM32MP15_RETRAM_SIZE); + target_add_ram(target, STM32MP15_AHBSRAM_BASE, STM32MP15_AHBSRAM_SIZE); + /* + * The SRAM appears twice in the map as it's mapped to both the main SRAM + * window and the alias window on the Cortex-A7 cores. + * (Unlike the RETRAM which only appears in the alias window) + */ + target_add_ram(target, STM32MP15_CA7_AHBSRAM_ALIAS_BASE, STM32MP15_AHBSRAM_SIZE); + target_add_ram(target, STM32MP15_SYSRAM_BASE, STM32MP15_SYSRAM_SIZE); + target_add_ram(target, STM32MP15_CAN_SRAM_BASE, STM32MP15_CAN_SRAM_SIZE); return true; } +#endif + +static bool stm32mp15_attach(target_s *const target) +{ + if (!cortexm_attach(target)) + return false; + + /* Save DBGMCU_CR to restore it when detaching */ + stm32mp15_priv_s *const priv = (stm32mp15_priv_s *)target->target_storage; + priv->dbgmcu_ctrl = target_mem_read32(target, DBGMCU_CTRL); + + /* Disable C-Sleep, C-Stop, C-Standby for debugging */ + target_mem_write32(target, DBGMCU_CTRL, DBGMCU_CTRL_DBGSLEEP | DBGMCU_CTRL_DBGSTOP | DBGMCU_CTRL_DBGSTBY); + + return true; +} + +static void stm32mp15_detach(target_s *const target) +{ + stm32mp15_priv_s *priv = (stm32mp15_priv_s *)target->target_storage; + target_mem_write32(target, DBGMCU_CTRL, priv->dbgmcu_ctrl); + cortexm_detach(target); +} /* * Print the Unique device ID. * Can be reused for other STM32 devices with uid as parameter. */ -static bool stm32mp15_uid(target_s *target, int argc, const char **argv) +static bool stm32mp15_uid(target_s *const target, const int argc, const char **const argv) { (void)argc; (void)argv; @@ -138,7 +194,7 @@ static const struct { {0x2001U, 'Z'}, }; -static bool stm32mp15_cmd_rev(target_s *target, int argc, const char **argv) +static bool stm32mp15_cmd_rev(target_s *const target, const int argc, const char **const argv) { (void)argc; (void)argv; diff --git a/src/target/target_probe.c b/src/target/target_probe.c index 4c3e13790e3..741c686b1e2 100644 --- a/src/target/target_probe.c +++ b/src/target/target_probe.c @@ -94,6 +94,7 @@ TARGET_PROBE_WEAK_NOP(stm32f4_probe) TARGET_PROBE_WEAK_NOP(stm32h5_probe) TARGET_PROBE_WEAK_NOP(stm32h7_probe) TARGET_PROBE_WEAK_NOP(stm32mp15_cm4_probe) +TARGET_PROBE_WEAK_NOP(stm32mp15_ca7_probe) TARGET_PROBE_WEAK_NOP(stm32l0_probe) TARGET_PROBE_WEAK_NOP(stm32l1_probe) TARGET_PROBE_WEAK_NOP(stm32l4_probe) diff --git a/src/target/target_probe.h b/src/target/target_probe.h index 23faa2e6b77..dafda11a3be 100644 --- a/src/target/target_probe.h +++ b/src/target/target_probe.h @@ -64,6 +64,7 @@ bool stm32f4_probe(target_s *target); bool stm32h5_probe(target_s *target); bool stm32h7_probe(target_s *target); bool stm32mp15_cm4_probe(target_s *target); +bool stm32mp15_ca7_probe(target_s *target); bool stm32l0_probe(target_s *target); bool stm32l1_probe(target_s *target); bool stm32l4_probe(target_s *target);