diff --git a/src/Makefile b/src/Makefile index c06fa287237..03f0db19691 100644 --- a/src/Makefile +++ b/src/Makefile @@ -61,6 +61,7 @@ SRC = \ stm32l4.c \ stm32g0.c \ target.c \ + target_probe.c include $(PLATFORM_DIR)/Makefile.inc diff --git a/src/target/adiv5.c b/src/target/adiv5.c index 5df0a430df2..15a87c9d402 100644 --- a/src/target/adiv5.c +++ b/src/target/adiv5.c @@ -28,6 +28,7 @@ #include "general.h" #include "target.h" #include "target_internal.h" +#include "target_probe.h" #include "adiv5.h" #include "cortexm.h" #include "exception.h" @@ -274,8 +275,6 @@ static const struct { #define SAMX5X_DSU_CTRLSTAT 0x41002100U #define SAMX5X_STATUSB_PROT (1U << 16U) -extern bool cortexa_probe(ADIv5_AP_t *apb, uint32_t debug_base); - void adiv5_ap_ref(ADIv5_AP_t *ap) { if (ap->refcnt == 0) @@ -677,7 +676,7 @@ static void rp_rescue_setup(ADIv5_DP_t *dp) return; } ap->dp = dp; - extern void rp_rescue_probe(ADIv5_AP_t *); + rp_rescue_probe(ap); return; } @@ -809,13 +808,9 @@ void adiv5_dp_init(ADIv5_DP_t *dp) return; } last_base = ap->base; - extern void kinetis_mdm_probe(ADIv5_AP_t *); - kinetis_mdm_probe(ap); - extern void nrf51_mdm_probe(ADIv5_AP_t *); + kinetis_mdm_probe(ap); nrf51_mdm_probe(ap); - - extern void efm32_aap_probe(ADIv5_AP_t *); efm32_aap_probe(ap); /* Halt the device and release from reset if reset is active!*/ diff --git a/src/target/adiv5.h b/src/target/adiv5.h index 2d6547eae06..7e162dbce24 100644 --- a/src/target/adiv5.h +++ b/src/target/adiv5.h @@ -23,6 +23,10 @@ #include "jtag_scan.h" +#if PC_HOSTED == 1 +#include "platform.h" +#endif + #define ADIV5_APnDP 0x100U #define ADIV5_DP_REG(x) (x) #define ADIV5_AP_REG(x) (ADIV5_APnDP | (x)) diff --git a/src/target/cortexm.c b/src/target/cortexm.c index 4012b00f206..45321d992b0 100644 --- a/src/target/cortexm.c +++ b/src/target/cortexm.c @@ -32,6 +32,7 @@ #include "adiv5.h" #include "target.h" #include "target_internal.h" +#include "target_probe.h" #include "cortexm.h" #include "command.h" #include "gdb_packet.h" diff --git a/src/target/cortexm.h b/src/target/cortexm.h index 2502ffed815..6ca9a4848fd 100644 --- a/src/target/cortexm.h +++ b/src/target/cortexm.h @@ -185,7 +185,6 @@ enum cortexm_types { #define CPUID_REVISION_MASK 0x00f00000 #define CPUID_PATCH_MASK 0xf -bool cortexm_probe(ADIv5_AP_t *ap); ADIv5_AP_t *cortexm_ap(target *t); bool cortexm_attach(target *t); diff --git a/src/target/efm32.c b/src/target/efm32.c index 47e552fc510..4a3f0392240 100644 --- a/src/target/efm32.c +++ b/src/target/efm32.c @@ -944,13 +944,13 @@ struct efm32_aap_priv_s { char aap_driver_string[42]; }; -void efm32_aap_probe(ADIv5_AP_t *ap) +bool efm32_aap_probe(ADIv5_AP_t *ap) { if ((ap->idr & EFM32_APP_IDR_MASK) == EFM32_AAP_IDR) { /* It's an EFM32 AAP! */ DEBUG_INFO("EFM32: Found EFM32 AAP\n"); } else - return; + return false; /* Both revsion 1 and revision 2 devices seen in the wild */ uint16_t aap_revision = (uint16_t)((ap->idr & 0xF0000000) >> 28); @@ -958,7 +958,7 @@ void efm32_aap_probe(ADIv5_AP_t *ap) /* New target */ target *t = target_new(); if (!t) { - return; + return false; } t->mass_erase = efm32_aap_mass_erase; @@ -974,6 +974,8 @@ void efm32_aap_probe(ADIv5_AP_t *ap) sprintf(priv_storage->aap_driver_string, "EFM32 Authentication Access Port rev.%hu", aap_revision); t->driver = priv_storage->aap_driver_string; t->regs_size = 4; + + return true; } static bool efm32_aap_mass_erase(target *t) diff --git a/src/target/kinetis.c b/src/target/kinetis.c index 22c546783fd..2a0756194e9 100644 --- a/src/target/kinetis.c +++ b/src/target/kinetis.c @@ -531,19 +531,19 @@ enum target_halt_reason mdm_halt_poll(target *t, const target_addr *const watch) return TARGET_HALT_REQUEST; } -void kinetis_mdm_probe(ADIv5_AP_t *ap) +bool kinetis_mdm_probe(ADIv5_AP_t *ap) { switch (ap->idr) { case KINETIS_MDM_IDR_KZ03: /* Also valid for KE04, no way to check! */ case KINETIS_MDM_IDR_K22F: break; default: - return; + return false; } target *t = target_new(); if (!t) { - return; + return false; } t->mass_erase = kinetis_mdm_mass_erase; @@ -554,6 +554,8 @@ void kinetis_mdm_probe(ADIv5_AP_t *ap) t->driver = "Kinetis Recovery (MDM-AP)"; t->regs_size = 4; target_add_commands(t, kinetis_mdm_cmd_list, t->driver); + + return true; } /* This is needed as a separate command, as there's no way to * diff --git a/src/target/nrf51.c b/src/target/nrf51.c index 0ea8503edc8..9d8a552813b 100644 --- a/src/target/nrf51.c +++ b/src/target/nrf51.c @@ -438,18 +438,18 @@ static bool nrf51_mdm_mass_erase(target *t); #define MDM_CONTROL ADIV5_AP_REG(0x04) #define MDM_PROT_EN ADIV5_AP_REG(0x0C) -void nrf51_mdm_probe(ADIv5_AP_t *ap) +bool nrf51_mdm_probe(ADIv5_AP_t *ap) { switch(ap->idr) { case NRF52_MDM_IDR: break; default: - return; + return false; } target *t = target_new(); if (!t) { - return; + return false; } t->mass_erase = nrf51_mdm_mass_erase; @@ -464,6 +464,8 @@ void nrf51_mdm_probe(ADIv5_AP_t *ap) else t->driver = "Nordic nRF52 Access Port (protected)"; t->regs_size = 4; + + return true; } static bool nrf51_mdm_mass_erase(target *t) diff --git a/src/target/rp.c b/src/target/rp.c index e889c4c1bae..cdc4d5bdd8f 100644 --- a/src/target/rp.c +++ b/src/target/rp.c @@ -531,11 +531,11 @@ static bool rp_rescue_do_reset(target *t) * * Attach to this DP will do the reset, but will fail to attach! */ -void rp_rescue_probe(ADIv5_AP_t *ap) +bool rp_rescue_probe(ADIv5_AP_t *ap) { target *t = target_new(); if (!t) { - return; + return false; } adiv5_ap_ref(ap); @@ -543,4 +543,6 @@ void rp_rescue_probe(ADIv5_AP_t *ap) t->priv = ap; t->priv_free = (void *)adiv5_ap_unref; t->driver = "Raspberry RP2040 Rescue (Attach to reset!)"; + + return true; } diff --git a/src/target/target_internal.h b/src/target/target_internal.h index f2f3f9d1e2b..d6d0e32bc67 100644 --- a/src/target/target_internal.h +++ b/src/target/target_internal.h @@ -181,33 +181,4 @@ int tc_gettimeofday(target *t, target_addr tv, target_addr tz); int tc_isatty(target *t, int fd); int tc_system(target *t, target_addr cmd, size_t cmdlen); -/* Probe for various targets. - * Actual functions implemented in their respective drivers. - */ -bool ch32f1_probe(target *t); // will catch all the clones -bool gd32f1_probe(target *t); -bool stm32f1_probe(target *t); -bool stm32f4_probe(target *t); -bool stm32h7_probe(target *t); -bool stm32l0_probe(target *t); -bool stm32l1_probe(target *t); -bool stm32l4_probe(target *t); -bool stm32g0_probe(target *t); -bool lmi_probe(target *t); -bool lpc11xx_probe(target *t); -bool lpc15xx_probe(target *t); -bool lpc17xx_probe(target *t); -bool lpc43xx_probe(target *t); -bool lpc546xx_probe(target *t); -bool samx7x_probe(target *t); -bool sam3x_probe(target *t); -bool sam4l_probe(target *t); -bool nrf51_probe(target *t); -bool samd_probe(target *t); -bool samx5x_probe(target *t); -bool kinetis_probe(target *t); -bool efm32_probe(target *t); -bool msp432_probe(target *t); -bool ke04_probe(target *t); -bool rp_probe(target *t); #endif diff --git a/src/target/target_probe.c b/src/target/target_probe.c new file mode 100644 index 00000000000..0245b0b9c9a --- /dev/null +++ b/src/target/target_probe.c @@ -0,0 +1,84 @@ +/* + * This file is part of the Black Magic Debug project. + * + * Copyright (C) 2022 Rafael Silva + * + * 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 + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "target_probe.h" + +#define CORTEXA_PROBE_WEAK_NOP __attribute__((weak, alias("cortexa_probe_nop"))) +#define CORTEXM_PROBE_WEAK_NOP __attribute__((weak, alias("cortexm_probe_nop"))) +#define TARGET_PROBE_WEAK_NOP __attribute__((weak, alias("target_probe_nop"))) + +static inline bool cortexa_probe_nop(ADIv5_AP_t *apb, uint32_t debug_base) +{ + (void)apb; + (void)debug_base; + return false; +} + +static inline bool cortexm_probe_nop(ADIv5_AP_t *ap) +{ + (void)ap; + return false; +} + +static inline bool target_probe_nop(target *t) +{ + (void)t; + return false; +} + +/* + * nop alias functions to allow suport for target probe methods + * to be disabled by not compiling/linking them in. + */ + +bool cortexa_probe(ADIv5_AP_t *apb, uint32_t debug_base) CORTEXA_PROBE_WEAK_NOP; + +bool cortexm_probe(ADIv5_AP_t *ap) CORTEXM_PROBE_WEAK_NOP; + +bool kinetis_mdm_probe(ADIv5_AP_t *ap) CORTEXM_PROBE_WEAK_NOP; +bool nrf51_mdm_probe(ADIv5_AP_t *ap) CORTEXM_PROBE_WEAK_NOP; +bool efm32_aap_probe(ADIv5_AP_t *ap) CORTEXM_PROBE_WEAK_NOP; +bool rp_rescue_probe(ADIv5_AP_t *ap) CORTEXM_PROBE_WEAK_NOP; + +bool ch32f1_probe(target *t) TARGET_PROBE_WEAK_NOP; +bool gd32f1_probe(target *t) TARGET_PROBE_WEAK_NOP; +bool stm32f1_probe(target *t) TARGET_PROBE_WEAK_NOP; +bool stm32f4_probe(target *t) TARGET_PROBE_WEAK_NOP; +bool stm32h7_probe(target *t) TARGET_PROBE_WEAK_NOP; +bool stm32l0_probe(target *t) TARGET_PROBE_WEAK_NOP; +bool stm32l1_probe(target *t) TARGET_PROBE_WEAK_NOP; +bool stm32l4_probe(target *t) TARGET_PROBE_WEAK_NOP; +bool stm32g0_probe(target *t) TARGET_PROBE_WEAK_NOP; +bool lmi_probe(target *t) TARGET_PROBE_WEAK_NOP; +bool lpc11xx_probe(target *t) TARGET_PROBE_WEAK_NOP; +bool lpc15xx_probe(target *t) TARGET_PROBE_WEAK_NOP; +bool lpc17xx_probe(target *t) TARGET_PROBE_WEAK_NOP; +bool lpc43xx_probe(target *t) TARGET_PROBE_WEAK_NOP; +bool lpc546xx_probe(target *t) TARGET_PROBE_WEAK_NOP; +bool samx7x_probe(target *t) TARGET_PROBE_WEAK_NOP; +bool sam3x_probe(target *t) TARGET_PROBE_WEAK_NOP; +bool sam4l_probe(target *t) TARGET_PROBE_WEAK_NOP; +bool nrf51_probe(target *t) TARGET_PROBE_WEAK_NOP; +bool samd_probe(target *t) TARGET_PROBE_WEAK_NOP; +bool samx5x_probe(target *t) TARGET_PROBE_WEAK_NOP; +bool kinetis_probe(target *t) TARGET_PROBE_WEAK_NOP; +bool efm32_probe(target *t) TARGET_PROBE_WEAK_NOP; +bool msp432_probe(target *t) TARGET_PROBE_WEAK_NOP; +bool ke04_probe(target *t) TARGET_PROBE_WEAK_NOP; +bool rp_probe(target *t) TARGET_PROBE_WEAK_NOP; diff --git a/src/target/target_probe.h b/src/target/target_probe.h new file mode 100644 index 00000000000..aa76054796c --- /dev/null +++ b/src/target/target_probe.h @@ -0,0 +1,66 @@ +/* + * This file is part of the Black Magic Debug project. + * + * Copyright (C) 2022 Rafael Silva + * + * 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 + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __TARGET_PROBE_H +#define __TARGET_PROBE_H + +#include "target.h" +#include "adiv5.h" + +/* Probe for various targets. + * Actual functions implemented in their respective drivers. + */ + +bool cortexa_probe(ADIv5_AP_t *apb, uint32_t debug_base); + +bool cortexm_probe(ADIv5_AP_t *ap); + +bool kinetis_mdm_probe(ADIv5_AP_t *ap); +bool nrf51_mdm_probe(ADIv5_AP_t *ap); +bool efm32_aap_probe(ADIv5_AP_t *ap); +bool rp_rescue_probe(ADIv5_AP_t *ap); + +bool ch32f1_probe(target *t); // will catch all the clones +bool gd32f1_probe(target *t); +bool stm32f1_probe(target *t); +bool stm32f4_probe(target *t); +bool stm32h7_probe(target *t); +bool stm32l0_probe(target *t); +bool stm32l1_probe(target *t); +bool stm32l4_probe(target *t); +bool stm32g0_probe(target *t); +bool lmi_probe(target *t); +bool lpc11xx_probe(target *t); +bool lpc15xx_probe(target *t); +bool lpc17xx_probe(target *t); +bool lpc43xx_probe(target *t); +bool lpc546xx_probe(target *t); +bool samx7x_probe(target *t); +bool sam3x_probe(target *t); +bool sam4l_probe(target *t); +bool nrf51_probe(target *t); +bool samd_probe(target *t); +bool samx5x_probe(target *t); +bool kinetis_probe(target *t); +bool efm32_probe(target *t); +bool msp432_probe(target *t); +bool ke04_probe(target *t); +bool rp_probe(target *t); + +#endif /* __TARGET_PROBE_H */