diff --git a/src/Makefile b/src/Makefile index f95721ca..0d3cdf7e 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,6 +1,6 @@ PROBE_HOST ?= native PLATFORM_DIR = platforms/$(PROBE_HOST) -VPATH += $(PLATFORM_DIR) platforms/common target +VPATH += $(PLATFORM_DIR) target ENABLE_DEBUG ?= ifneq ($(V), 1) @@ -9,8 +9,8 @@ Q := @ endif CFLAGS += -Wall -Wextra -Werror -Wno-char-subscripts \ - -std=gnu99 -g3 -MD \ - -I. -Iinclude -Iplatforms/common -I$(PLATFORM_DIR) + -std=gnu99 -g3 -MD -I./target \ + -I. -Iinclude -I$(PLATFORM_DIR) ifeq ($(ENABLE_DEBUG), 1) CFLAGS += -DENABLE_DEBUG @@ -55,6 +55,7 @@ SRC = \ stm32h7.c \ stm32l0.c \ stm32l4.c \ + swdptap.c \ target.c \ include $(PLATFORM_DIR)/Makefile.inc @@ -72,7 +73,7 @@ SRC += jtagtap_generic.c swdptap_generic.c endif ifndef OWN_HL -SRC += jtag_scan.c jtagtap.c swdptap.c +SRC += jtag_scan.c jtagtap.c else CFLAGS += -DOWN_HL endif @@ -81,6 +82,8 @@ ifdef PC_HOSTED CFLAGS += -DPC_HOSTED=1 else CFLAGS += -DPC_HOSTED=0 +VPATH += platforms/common +CFLAGS += -Iplatforms/common endif OBJ = $(patsubst %.S,%.o,$(patsubst %.c,%.o,$(SRC))) diff --git a/src/include/swdptap.h b/src/include/swdptap.h index cdb69690..87cfe160 100644 --- a/src/include/swdptap.h +++ b/src/include/swdptap.h @@ -20,20 +20,17 @@ #ifndef __SWDPTAP_H #define __SWDPTAP_H +typedef struct swd_proc_s { + uint32_t (*swdptap_seq_in)(int ticks); + bool (*swdptap_seq_in_parity)(uint32_t *data, int ticks); + void (*swdptap_seq_out)(uint32_t MS, int ticks); + void (*swdptap_seq_out_parity)(uint32_t MS, int ticks); +} swd_proc_t; +extern swd_proc_t swd_proc; +# if PC_HOSTED == 1 +int platform_swdptap_init(void); +# else int swdptap_init(void); - -/* Primitive functions */ -bool swdptap_bit_in(void); -void swdptap_bit_out(bool val); - -/* Low level functions, provided in swdptap_generic.c from the primitives - (indicate NO_OWN_LL in the Makefile.inc or libopencm specific in - platforms/common*/ -uint32_t swdptap_seq_in(int ticks); -bool swdptap_seq_in_parity(uint32_t *data, int ticks); -void swdptap_seq_out(uint32_t MS, int ticks); -void swdptap_seq_out_parity(uint32_t MS, int ticks); - +# endif #endif - diff --git a/src/include/target.h b/src/include/target.h index b4b840c3..106ac273 100644 --- a/src/include/target.h +++ b/src/include/target.h @@ -34,16 +34,13 @@ typedef struct target_s target; typedef uint32_t target_addr; struct target_controller; -#if defined(PC_HOSTED) +#if PC_HOSTED == 1 int platform_adiv5_swdp_scan(void); int platform_jtag_scan(const uint8_t *lrlens); #endif int adiv5_swdp_scan(void); int jtag_scan(const uint8_t *lrlens); -int adiv5_swdp_scan(void); -int jtag_scan(const uint8_t *lrlens); - bool target_foreach(void (*cb)(int i, target *t, void *context), void *context); void target_list_free(void); diff --git a/src/platforms/common/timing.h b/src/include/timing.h similarity index 99% rename from src/platforms/common/timing.h rename to src/include/timing.h index cc7971e8..4a55f185 100644 --- a/src/platforms/common/timing.h +++ b/src/include/timing.h @@ -27,4 +27,3 @@ struct platform_timeout { uint32_t platform_time_ms(void); #endif /* __TIMING_H */ - diff --git a/src/platforms/common/swdptap.c b/src/platforms/common/swdptap.c index 9d9638de..95cc68d0 100644 --- a/src/platforms/common/swdptap.c +++ b/src/platforms/common/swdptap.c @@ -28,11 +28,6 @@ enum { SWDIO_STATUS_DRIVE }; -int swdptap_init(void) -{ - return 0; -} - static void swdptap_turnaround(int dir) { static int olddir = SWDIO_STATUS_FLOAT; @@ -54,26 +49,7 @@ static void swdptap_turnaround(int dir) SWDIO_MODE_DRIVE(); } -bool swdptap_bit_in(void) -{ - uint16_t ret; - - swdptap_turnaround(SWDIO_STATUS_FLOAT); - - ret = gpio_get(SWDIO_PORT, SWDIO_PIN); - gpio_set(SWCLK_PORT, SWCLK_PIN); - gpio_set(SWCLK_PORT, SWCLK_PIN); - gpio_clear(SWCLK_PORT, SWCLK_PIN); - -#ifdef DEBUG_SWD_BITS - DEBUG("%d", ret?1:0); -#endif - - return ret != 0; -} - -uint32_t -swdptap_seq_in(int ticks) +static uint32_t swdptap_seq_in(int ticks) { uint32_t index = 1; uint32_t ret = 0; @@ -97,8 +73,7 @@ swdptap_seq_in(int ticks) return ret; } -bool -swdptap_seq_in_parity(uint32_t *ret, int ticks) +static bool swdptap_seq_in_parity(uint32_t *ret, int ticks) { uint32_t index = 1; uint8_t parity = 0; @@ -130,22 +105,7 @@ swdptap_seq_in_parity(uint32_t *ret, int ticks) return parity; } -void swdptap_bit_out(bool val) -{ -#ifdef DEBUG_SWD_BITS - DEBUG("%d", val); -#endif - - swdptap_turnaround(SWDIO_STATUS_DRIVE); - - gpio_set_val(SWDIO_PORT, SWDIO_PIN, val); - gpio_clear(SWCLK_PORT, SWCLK_PIN); - gpio_set(SWCLK_PORT, SWCLK_PIN); - gpio_set(SWCLK_PORT, SWCLK_PIN); - gpio_clear(SWCLK_PORT, SWCLK_PIN); -} -void -swdptap_seq_out(uint32_t MS, int ticks) +static void swdptap_seq_out(uint32_t MS, int ticks) { int data = MS & 1; #ifdef DEBUG_SWD_BITS @@ -163,8 +123,7 @@ swdptap_seq_out(uint32_t MS, int ticks) } } -void -swdptap_seq_out_parity(uint32_t MS, int ticks) +static void swdptap_seq_out_parity(uint32_t MS, int ticks) { uint8_t parity = 0; int data = MS & 1; @@ -188,3 +147,15 @@ swdptap_seq_out_parity(uint32_t MS, int ticks) gpio_set(SWCLK_PORT, SWCLK_PIN); gpio_clear(SWCLK_PORT, SWCLK_PIN); } + +swd_proc_t swd_proc; + +int swdptap_init(void) +{ + swd_proc.swdptap_seq_in = swdptap_seq_in; + swd_proc.swdptap_seq_in_parity = swdptap_seq_in_parity; + swd_proc.swdptap_seq_out = swdptap_seq_out; + swd_proc.swdptap_seq_out_parity = swdptap_seq_out_parity; + + return 0; +} diff --git a/src/platforms/libftdi/swdptap.c b/src/platforms/libftdi/swdptap.c index a5c898c1..d710d453 100644 --- a/src/platforms/libftdi/swdptap.c +++ b/src/platforms/libftdi/swdptap.c @@ -35,7 +35,14 @@ static uint8_t olddir = 0; #define MPSSE_TMS_SHIFT (MPSSE_WRITE_TMS | MPSSE_LSB |\ MPSSE_BITMODE | MPSSE_WRITE_NEG) -int swdptap_init(void) +static bool swdptap_seq_in_parity(uint32_t *res, int ticks); +static uint32_t swdptap_seq_in(int ticks); +static void swdptap_seq_out(uint32_t MS, int ticks); +static void swdptap_seq_out_parity(uint32_t MS, int ticks); + +swd_proc_t swd_proc; + +int platform_swdptap_init(void) { if (!active_cable->bitbang_tms_in_pin) { DEBUG("SWD not possible or missing item in cable description.\n"); @@ -70,6 +77,11 @@ int swdptap_init(void) platform_buffer_write(ftdi_init, 9); platform_buffer_flush(); + swd_proc.swdptap_seq_in = swdptap_seq_in; + swd_proc.swdptap_seq_in_parity = swdptap_seq_in_parity; + swd_proc.swdptap_seq_out = swdptap_seq_out; + swd_proc.swdptap_seq_out_parity = swdptap_seq_out_parity; + return 0; } @@ -102,34 +114,7 @@ static void swdptap_turnaround(uint8_t dir) platform_buffer_write(cmd, index); } -bool swdptap_bit_in(void) -{ - swdptap_turnaround(1); - uint8_t cmd[4]; - int index = 0; - - cmd[index++] = active_cable->bitbang_tms_in_port_cmd; - cmd[index++] = MPSSE_TMS_SHIFT; - cmd[index++] = 0; - cmd[index++] = 0; - platform_buffer_write(cmd, index); - uint8_t data[1]; - platform_buffer_read(data, 1); - return (data[0] &= active_cable->bitbang_tms_in_pin); -} - -void swdptap_bit_out(bool val) -{ - swdptap_turnaround(0); - uint8_t cmd[3]; - - cmd[0] = MPSSE_TMS_SHIFT; - cmd[1] = 0; - cmd[2] = (val)? 1 : 0; - platform_buffer_write(cmd, 3); -} - -bool swdptap_seq_in_parity(uint32_t *res, int ticks) +static bool swdptap_seq_in_parity(uint32_t *res, int ticks) { int index = ticks + 1; uint8_t cmd[4]; @@ -158,7 +143,7 @@ bool swdptap_seq_in_parity(uint32_t *res, int ticks) return parity; } -uint32_t swdptap_seq_in(int ticks) +static uint32_t swdptap_seq_in(int ticks) { int index = ticks; uint8_t cmd[4]; @@ -182,7 +167,7 @@ uint32_t swdptap_seq_in(int ticks) return ret; } -void swdptap_seq_out(uint32_t MS, int ticks) +static void swdptap_seq_out(uint32_t MS, int ticks) { uint8_t cmd[15]; unsigned int index = 0; @@ -203,7 +188,7 @@ void swdptap_seq_out(uint32_t MS, int ticks) platform_buffer_write(cmd, index); } -void swdptap_seq_out_parity(uint32_t MS, int ticks) +static void swdptap_seq_out_parity(uint32_t MS, int ticks) { uint8_t parity = 0; int steps = ticks; diff --git a/src/platforms/pc-hosted/swdptap.c b/src/platforms/pc-hosted/swdptap.c index e63ed521..c62a1f99 100644 --- a/src/platforms/pc-hosted/swdptap.c +++ b/src/platforms/pc-hosted/swdptap.c @@ -30,7 +30,14 @@ #include "swdptap.h" #include "remote.h" -int swdptap_init(void) +static bool swdptap_seq_in_parity(uint32_t *res, int ticks); +static uint32_t swdptap_seq_in(int ticks); +static void swdptap_seq_out(uint32_t MS, int ticks); +static void swdptap_seq_out_parity(uint32_t MS, int ticks); + +swd_proc_t swd_proc; + +int platform_swdptap_init(void) { uint8_t construct[PLATFORM_MAX_MSG_SIZE]; @@ -46,11 +53,15 @@ int swdptap_init(void) exit(-1); } + swd_proc.swdptap_seq_in = swdptap_seq_in; + swd_proc.swdptap_seq_in_parity = swdptap_seq_in_parity; + swd_proc.swdptap_seq_out = swdptap_seq_out; + swd_proc.swdptap_seq_out_parity = swdptap_seq_out_parity; + return 0; } - -bool swdptap_seq_in_parity(uint32_t *res, int ticks) +static bool swdptap_seq_in_parity(uint32_t *res, int ticks) { uint8_t construct[PLATFORM_MAX_MSG_SIZE]; @@ -70,8 +81,7 @@ bool swdptap_seq_in_parity(uint32_t *res, int ticks) return (construct[0]!=REMOTE_RESP_OK); } - -uint32_t swdptap_seq_in(int ticks) +static uint32_t swdptap_seq_in(int ticks) { uint8_t construct[PLATFORM_MAX_MSG_SIZE]; int s; @@ -89,7 +99,7 @@ uint32_t swdptap_seq_in(int ticks) return remotehston(-1,(char *)&construct[1]); } -void swdptap_seq_out(uint32_t MS, int ticks) +static void swdptap_seq_out(uint32_t MS, int ticks) { uint8_t construct[PLATFORM_MAX_MSG_SIZE]; int s; @@ -106,7 +116,7 @@ void swdptap_seq_out(uint32_t MS, int ticks) } -void swdptap_seq_out_parity(uint32_t MS, int ticks) +static void swdptap_seq_out_parity(uint32_t MS, int ticks) { uint8_t construct[PLATFORM_MAX_MSG_SIZE]; int s; diff --git a/src/platforms/pc-stlinkv2/adiv5_swdp.c b/src/platforms/pc-stlinkv2/adiv5_swdp.c deleted file mode 100644 index 77fbbf65..00000000 --- a/src/platforms/pc-stlinkv2/adiv5_swdp.c +++ /dev/null @@ -1,49 +0,0 @@ -/* - * This file is part of the Black Magic Debug project. - * - * Copyright (C) 2011 Black Sphere Technologies Ltd. - * Written by Gareth McMullin - * Copyright (C) 2019 Uwe Bonnes (bon@elektron.ikp.physik.tu-darmstadt.de) - * - * 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 . - */ - -/* This file implements the SW-DP specific functions of the - * ARM Debug Interface v5 Architecure Specification, ARM doc IHI0031A. - */ - -#include "general.h" -#include "target.h" -#include "target_internal.h" -#include "adiv5.h" -#include "stlinkv2.h" - -int adiv5_swdp_scan(void) -{ - target_list_free(); - ADIv5_DP_t *dp = (void*)calloc(1, sizeof(*dp)); - if (stlink_enter_debug_swd()) - return 0; - dp->idcode = stlink_read_coreid(); - dp->dp_read = stlink_dp_read; - dp->error = stlink_dp_error; - dp->low_access = stlink_dp_low_access; - dp->abort = stlink_dp_abort; - - stlink_dp_error(dp); - adiv5_dp_init(dp); - - return target_list?1:0; - return 0; -} diff --git a/src/platforms/pc-stlinkv2/jtagtap.c b/src/platforms/pc-stlinkv2/jtagtap.c new file mode 100644 index 00000000..e69de29b diff --git a/src/platforms/pc-stlinkv2/platform.c b/src/platforms/pc-stlinkv2/platform.c index f594af17..eb8c6ebc 100644 --- a/src/platforms/pc-stlinkv2/platform.c +++ b/src/platforms/pc-stlinkv2/platform.c @@ -22,6 +22,7 @@ #include "platform.h" #include "target.h" #include "target_internal.h" +#include "swdptap.h" #include #include @@ -41,6 +42,13 @@ const char *platform_target_voltage(void) return stlink_target_voltage(); } +int platform_swdptap_init(void) +{ + return 0; +} + +swd_proc_t swd_proc; + static int adiv5_swdp_scan_stlinkv2(void) { target_list_free(); diff --git a/src/platforms/pc-stlinkv2/swdptap.c b/src/platforms/pc-stlinkv2/swdptap.c new file mode 100644 index 00000000..e69de29b diff --git a/src/remote.c b/src/remote.c index 354e1b6c..d152a456 100644 --- a/src/remote.c +++ b/src/remote.c @@ -115,27 +115,27 @@ void remotePacketProcessSWD(uint8_t i, char *packet) case REMOTE_IN_PAR: /* = In parity ================================== */ ticks=remotehston(2,&packet[2]); - badParity=swdptap_seq_in_parity(¶m, ticks); + badParity = swd_proc.swdptap_seq_in_parity(¶m, ticks); _respond(badParity?REMOTE_RESP_PARERR:REMOTE_RESP_OK,param); break; case REMOTE_IN: /* = In ========================================= */ ticks=remotehston(2,&packet[2]); - param=swdptap_seq_in(ticks); + param = swd_proc.swdptap_seq_in(ticks); _respond(REMOTE_RESP_OK,param); break; case REMOTE_OUT: /* = Out ======================================== */ ticks=remotehston(2,&packet[2]); param=remotehston(-1, &packet[4]); - swdptap_seq_out(param, ticks); + swd_proc.swdptap_seq_out(param, ticks); _respond(REMOTE_RESP_OK, 0); break; case REMOTE_OUT_PAR: /* = Out parity ================================= */ ticks=remotehston(2,&packet[2]); param=remotehston(-1, &packet[4]); - swdptap_seq_out_parity(param, ticks); + swd_proc.swdptap_seq_out_parity(param, ticks); _respond(REMOTE_RESP_OK, 0); break; diff --git a/src/target/adiv5_swdp.c b/src/target/adiv5_swdp.c index 6ac1d7b9..9cfdf493 100644 --- a/src/target/adiv5_swdp.c +++ b/src/target/adiv5_swdp.c @@ -53,24 +53,28 @@ int adiv5_swdp_scan(void) return -1; } +#if PC_HOSTED == 1 + if (platform_swdptap_init()) +#else if (swdptap_init()) +#endif return -1; /* Switch from JTAG to SWD mode */ - swdptap_seq_out(0xFFFFFFFF, 16); - swdptap_seq_out(0xFFFFFFFF, 32); - swdptap_seq_out(0xFFFFFFFF, 18); - swdptap_seq_out(0xE79E, 16); /* 0b0111100111100111 */ - swdptap_seq_out(0xFFFFFFFF, 32); - swdptap_seq_out(0xFFFFFFFF, 18); - swdptap_seq_out(0, 16); + swd_proc.swdptap_seq_out(0xFFFFFFFF, 16); + swd_proc.swdptap_seq_out(0xFFFFFFFF, 32); + swd_proc.swdptap_seq_out(0xFFFFFFFF, 18); + swd_proc.swdptap_seq_out(0xE79E, 16); /* 0b0111100111100111 */ + swd_proc.swdptap_seq_out(0xFFFFFFFF, 32); + swd_proc.swdptap_seq_out(0xFFFFFFFF, 18); + swd_proc.swdptap_seq_out(0, 16); /* Read the SW-DP IDCODE register to syncronise */ /* This could be done with adiv_swdp_low_access(), but this doesn't * allow the ack to be checked here. */ - swdptap_seq_out(0xA5, 8); - ack = swdptap_seq_in(3); - if((ack != SWDP_ACK_OK) || swdptap_seq_in_parity(&dp->idcode, 32)) { + swd_proc.swdptap_seq_out(0xA5, 8); + ack = swd_proc.swdptap_seq_in(3); + if((ack != SWDP_ACK_OK) || swd_proc.swdptap_seq_in_parity(&dp->idcode, 32)) { DEBUG("\n"); free(dp); return -1; @@ -143,8 +147,8 @@ static uint32_t adiv5_swdp_low_access(ADIv5_DP_t *dp, uint8_t RnW, platform_timeout_set(&timeout, 2000); do { - swdptap_seq_out(request, 8); - ack = swdptap_seq_in(3); + swd_proc.swdptap_seq_out(request, 8); + ack = swd_proc.swdptap_seq_in(3); } while (ack == SWDP_ACK_WAIT && !platform_timeout_is_expired(&timeout)); if (ack == SWDP_ACK_WAIT) @@ -159,10 +163,10 @@ static uint32_t adiv5_swdp_low_access(ADIv5_DP_t *dp, uint8_t RnW, raise_exception(EXCEPTION_ERROR, "SWDP invalid ACK"); if(RnW) { - if(swdptap_seq_in_parity(&response, 32)) /* Give up on parity error */ + if(swd_proc.swdptap_seq_in_parity(&response, 32)) /* Give up on parity error */ raise_exception(EXCEPTION_ERROR, "SWDP Parity error"); } else { - swdptap_seq_out_parity(value, 32); + swd_proc.swdptap_seq_out_parity(value, 32); /* RM0377 Rev. 8 Chapter 27.5.4 for STM32L0x1 states: * Because of the asynchronous clock domains SWCLK and HCLK, * two extra SWCLK cycles are needed after a write transaction @@ -173,7 +177,7 @@ static uint32_t adiv5_swdp_low_access(ADIv5_DP_t *dp, uint8_t RnW, * for a power-up request. If the next transaction (requiring * a power-up) occurs immediately, it will fail. */ - swdptap_seq_out(0, 2); + swd_proc.swdptap_seq_out(0, 2); } return response; diff --git a/src/platforms/common/timing.c b/src/timing.c similarity index 100% rename from src/platforms/common/timing.c rename to src/timing.c