Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: STM32MP15 Cortex-A support #1670

Merged
merged 9 commits into from
Nov 13, 2023
6 changes: 6 additions & 0 deletions src/target/cortexar.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions src/target/stm32f1.c
Original file line number Diff line number Diff line change
Expand Up @@ -537,6 +537,7 @@ bool stm32f1_probe(target_s *target)
break;

default: /* NONE */
target->mass_erase = NULL;
return false;
}

Expand Down
116 changes: 86 additions & 30 deletions src/target/stm32mp15.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
*
* Copyright (C) 2023 1BitSquared <[email protected]>
* Written by ALTracer <[email protected]>
* Modified by Rachel Mant <[email protected]>
*
* 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
Expand Down Expand Up @@ -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

Expand All @@ -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";
Expand All @@ -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;
Expand All @@ -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;
Expand Down
1 change: 1 addition & 0 deletions src/target/target_probe.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
1 change: 1 addition & 0 deletions src/target/target_probe.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down