Skip to content

Commit c94ceed

Browse files
perigosorg-silva
authored andcommitted
experimental: start working towards a native implementation
1 parent 73b673e commit c94ceed

File tree

10 files changed

+583
-1
lines changed

10 files changed

+583
-1
lines changed

src/command.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -308,7 +308,7 @@ bool cmd_rvswd_scan(target_s *target, int argc, const char **argv)
308308
#if PC_HOSTED == 1
309309
scan_result = bmda_rvswd_scan();
310310
#else
311-
scan_result = false;
311+
scan_result = rvswd_scan();
312312
#endif
313313
}
314314
switch (e.type) {

src/include/rvswd.h

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/*
2+
* This file is part of the Black Magic Debug project.
3+
*
4+
* Copyright (C) 2011 Black Sphere Technologies Ltd.
5+
* Written by Gareth McMullin <gareth@blacksphere.co.nz>
6+
*
7+
* This program is free software: you can redistribute it and/or modify
8+
* it under the terms of the GNU General Public License as published by
9+
* the Free Software Foundation, either version 3 of the License, or
10+
* (at your option) any later version.
11+
*
12+
* This program is distributed in the hope that it will be useful,
13+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
* GNU General Public License for more details.
16+
*
17+
* You should have received a copy of the GNU General Public License
18+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
19+
*/
20+
21+
#ifndef INCLUDE_RVSWD_H
22+
#define INCLUDE_RVSWD_H
23+
24+
#include <stdint.h>
25+
#include <stddef.h>
26+
#include <stdbool.h>
27+
28+
/* Functions interface talking RVSWD */
29+
typedef struct rvswd_proc {
30+
/* Perform a clock_cycles read */
31+
uint32_t (*seq_in)(size_t clock_cycles);
32+
/* Perform a clock_cycles read + parity */
33+
bool (*seq_in_parity)(uint32_t *ret, size_t clock_cycles);
34+
/* Perform a clock_cycles write with the provided data */
35+
void (*seq_out)(uint32_t tms_states, size_t clock_cycles);
36+
/* Perform a clock_cycles write + parity with the provided data */
37+
void (*seq_out_parity)(uint32_t tms_states, size_t clock_cycles);
38+
} rvswd_proc_s;
39+
40+
extern rvswd_proc_s rvswd_proc;
41+
42+
void rvswd_init(void);
43+
44+
#endif /* INCLUDE_RVSWD_H */

src/include/target.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,9 @@ bool bmda_rvswd_scan(void);
4747
#endif
4848
bool adiv5_swd_scan(uint32_t targetid);
4949
bool jtag_scan(void);
50+
// #ifdef PLATFORM_HAS_RVSWD
51+
bool rvswd_scan(void);
52+
// #endif
5053

5154
size_t target_foreach(void (*callback)(size_t index, target_s *target, void *context), void *context);
5255
void target_list_free(void);

src/platforms/common/meson.build

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ platform_common_sources = files(
3434
'aux_serial.c',
3535
'jtagtap.c',
3636
'swdptap.c',
37+
'rvswd.c',
3738
'usb.c',
3839
'usb_dfu_stub.c',
3940
'usb_serial.c',

src/platforms/common/rvswd.c

Lines changed: 197 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,197 @@
1+
/*
2+
* This file is part of the Black Magic Debug project.
3+
*
4+
* Copyright (C) 2011 Black Sphere Technologies Ltd.
5+
* Written by Gareth McMullin <gareth@blacksphere.co.nz>
6+
*
7+
* This program is free software: you can redistribute it and/or modify
8+
* it under the terms of the GNU General Public License as published by
9+
* the Free Software Foundation, either version 3 of the License, or
10+
* (at your option) any later version.
11+
*
12+
* This program is distributed in the hope that it will be useful,
13+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
* GNU General Public License for more details.
16+
*
17+
* You should have received a copy of the GNU General Public License
18+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
19+
*/
20+
21+
/* This file implements the SW-DP interface. */
22+
23+
#include "general.h"
24+
#include "platform.h"
25+
#include "timing.h"
26+
#include "rvswd.h"
27+
#include "maths_utils.h"
28+
29+
// FIXME: reusing the SWD macros for now
30+
#if !defined(SWDIO_IN_PORT)
31+
#define SWDIO_IN_PORT SWDIO_PORT
32+
#endif
33+
#if !defined(SWDIO_IN_PIN)
34+
#define SWDIO_IN_PIN SWDIO_PIN
35+
#endif
36+
37+
// typedef enum swdio_status_e {
38+
// SWDIO_STATUS_FLOAT = 0,
39+
// SWDIO_STATUS_DRIVE
40+
// } swdio_status_t;
41+
42+
rvswd_proc_s rvswd_proc;
43+
44+
// static void swdptap_turnaround(swdio_status_t dir) __attribute__((optimize(3)));
45+
// static uint32_t swdptap_seq_in(size_t clock_cycles) __attribute__((optimize(3)));
46+
// static bool swdptap_seq_in_parity(uint32_t *ret, size_t clock_cycles) __attribute__((optimize(3)));
47+
// static void swdptap_seq_out(uint32_t tms_states, size_t clock_cycles) __attribute__((optimize(3)));
48+
// static void swdptap_seq_out_parity(uint32_t tms_states, size_t clock_cycles) __attribute__((optimize(3)));
49+
50+
void rvswd_init(void)
51+
{
52+
// rvswd_proc.seq_in = swdptap_seq_in;
53+
// rvswd_proc.seq_in_parity = swdptap_seq_in_parity;
54+
// rvswd_proc.seq_out = swdptap_seq_out;
55+
// rvswd_proc.seq_out_parity = swdptap_seq_out_parity;
56+
}
57+
58+
// static void swdptap_turnaround(const swdio_status_t dir)
59+
// {
60+
// static swdio_status_t olddir = SWDIO_STATUS_FLOAT;
61+
// /* Don't turnaround if direction not changing */
62+
// if (dir == olddir)
63+
// return;
64+
// olddir = dir;
65+
66+
// #ifdef DEBUG_SWD_BITS
67+
// DEBUG_INFO("%s", dir ? "\n-> " : "\n<- ");
68+
// #endif
69+
70+
// if (dir == SWDIO_STATUS_FLOAT) {
71+
// SWDIO_MODE_FLOAT();
72+
// } else
73+
// gpio_clear(SWCLK_PORT, SWCLK_PIN);
74+
75+
// for (volatile uint32_t counter = target_clk_divider + 1; counter > 0; --counter)
76+
// continue;
77+
78+
// gpio_set(SWCLK_PORT, SWCLK_PIN);
79+
// for (volatile uint32_t counter = target_clk_divider + 1; counter > 0; --counter)
80+
// continue;
81+
82+
// if (dir == SWDIO_STATUS_DRIVE) {
83+
// gpio_clear(SWCLK_PORT, SWCLK_PIN);
84+
// SWDIO_MODE_DRIVE();
85+
// }
86+
// }
87+
88+
// static uint32_t swdptap_seq_in_clk_delay(size_t clock_cycles) __attribute__((optimize(3)));
89+
90+
// static uint32_t swdptap_seq_in_clk_delay(const size_t clock_cycles)
91+
// {
92+
// uint32_t value = 0;
93+
// for (size_t cycle = 0; cycle < clock_cycles; ++cycle) {
94+
// gpio_clear(SWCLK_PORT, SWCLK_PIN);
95+
// value |= gpio_get(SWDIO_IN_PORT, SWDIO_IN_PIN) ? 1U << cycle : 0U;
96+
// for (volatile uint32_t counter = target_clk_divider; counter > 0; --counter)
97+
// continue;
98+
// gpio_set(SWCLK_PORT, SWCLK_PIN);
99+
// for (volatile uint32_t counter = target_clk_divider; counter > 0; --counter)
100+
// continue;
101+
// }
102+
// gpio_clear(SWCLK_PORT, SWCLK_PIN);
103+
// return value;
104+
// }
105+
106+
// static uint32_t swdptap_seq_in_no_delay(size_t clock_cycles) __attribute__((optimize(3)));
107+
108+
// static uint32_t swdptap_seq_in_no_delay(const size_t clock_cycles)
109+
// {
110+
// uint32_t value = 0;
111+
// for (size_t cycle = 0; cycle < clock_cycles; ++cycle) {
112+
// gpio_clear(SWCLK_PORT, SWCLK_PIN);
113+
// value |= gpio_get(SWDIO_IN_PORT, SWDIO_IN_PIN) ? 1U << cycle : 0U;
114+
// gpio_set(SWCLK_PORT, SWCLK_PIN);
115+
// __asm__("nop");
116+
// }
117+
// gpio_clear(SWCLK_PORT, SWCLK_PIN);
118+
// return value;
119+
// }
120+
121+
// static uint32_t swdptap_seq_in(size_t clock_cycles)
122+
// {
123+
// swdptap_turnaround(SWDIO_STATUS_FLOAT);
124+
// if (target_clk_divider != UINT32_MAX)
125+
// return swdptap_seq_in_clk_delay(clock_cycles);
126+
// else // NOLINT(readability-else-after-return)
127+
// return swdptap_seq_in_no_delay(clock_cycles);
128+
// }
129+
130+
// static bool swdptap_seq_in_parity(uint32_t *ret, size_t clock_cycles)
131+
// {
132+
// const uint32_t result = swdptap_seq_in(clock_cycles);
133+
// for (volatile uint32_t counter = target_clk_divider + 1; counter > 0; --counter)
134+
// continue;
135+
136+
// const bool parity = calculate_odd_parity(result);
137+
// const bool bit = gpio_get(SWDIO_IN_PORT, SWDIO_IN_PIN);
138+
139+
// gpio_set(SWCLK_PORT, SWCLK_PIN);
140+
// for (volatile uint32_t counter = target_clk_divider + 1; counter > 0; --counter)
141+
// continue;
142+
143+
// *ret = result;
144+
// /* Terminate the read cycle now */
145+
// swdptap_turnaround(SWDIO_STATUS_DRIVE);
146+
// return parity != bit;
147+
// }
148+
149+
// static void swdptap_seq_out_clk_delay(uint32_t tms_states, size_t clock_cycles) __attribute__((optimize(3)));
150+
151+
// static void swdptap_seq_out_clk_delay(const uint32_t tms_states, const size_t clock_cycles)
152+
// {
153+
// for (size_t cycle = 0; cycle < clock_cycles; ++cycle) {
154+
// gpio_clear(SWCLK_PORT, SWCLK_PIN);
155+
// gpio_set_val(SWDIO_PORT, SWDIO_PIN, tms_states & (1 << cycle));
156+
// for (volatile uint32_t counter = target_clk_divider; counter > 0; --counter)
157+
// continue;
158+
// gpio_set(SWCLK_PORT, SWCLK_PIN);
159+
// for (volatile uint32_t counter = target_clk_divider; counter > 0; --counter)
160+
// continue;
161+
// }
162+
// gpio_clear(SWCLK_PORT, SWCLK_PIN);
163+
// }
164+
165+
// static void swdptap_seq_out_no_delay(uint32_t tms_states, size_t clock_cycles) __attribute__((optimize(3)));
166+
167+
// static void swdptap_seq_out_no_delay(const uint32_t tms_states, const size_t clock_cycles)
168+
// {
169+
// for (size_t cycle = 0; cycle < clock_cycles; ++cycle) {
170+
// gpio_clear(SWCLK_PORT, SWCLK_PIN);
171+
// gpio_set_val(SWDIO_PORT, SWDIO_PIN, tms_states & (1 << cycle));
172+
// gpio_set(SWCLK_PORT, SWCLK_PIN);
173+
// }
174+
// gpio_clear(SWCLK_PORT, SWCLK_PIN);
175+
// }
176+
177+
// static void swdptap_seq_out(const uint32_t tms_states, const size_t clock_cycles)
178+
// {
179+
// swdptap_turnaround(SWDIO_STATUS_DRIVE);
180+
// if (target_clk_divider != UINT32_MAX)
181+
// swdptap_seq_out_clk_delay(tms_states, clock_cycles);
182+
// else
183+
// swdptap_seq_out_no_delay(tms_states, clock_cycles);
184+
// }
185+
186+
// static void swdptap_seq_out_parity(const uint32_t tms_states, const size_t clock_cycles)
187+
// {
188+
// const bool parity = calculate_odd_parity(tms_states);
189+
// swdptap_seq_out(tms_states, clock_cycles);
190+
// gpio_set_val(SWDIO_PORT, SWDIO_PIN, parity);
191+
// for (volatile uint32_t counter = target_clk_divider + 1; counter > 0; --counter)
192+
// continue;
193+
// gpio_set(SWCLK_PORT, SWCLK_PIN);
194+
// for (volatile uint32_t counter = target_clk_divider + 1; counter > 0; --counter)
195+
// continue;
196+
// gpio_clear(SWCLK_PORT, SWCLK_PIN);
197+
// }

src/platforms/hosted/platform.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
#include "platform.h"
3232
#include "jtagtap.h"
3333
#include "swd.h"
34+
#include "rvswd.h"
3435
#include "target.h"
3536
#include "target_internal.h"
3637
#include "adiv5.h"
@@ -58,6 +59,7 @@ bmda_probe_s bmda_probe_info;
5859

5960
jtag_proc_s jtag_proc;
6061
swd_proc_s swd_proc;
62+
rvswd_proc_s rvswd_proc;
6163

6264
static bmda_cli_options_s cl_opts;
6365

src/platforms/native/platform.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929

3030
#define PLATFORM_HAS_TRACESWO
3131
#define PLATFORM_HAS_POWER_SWITCH
32+
#define PLATFORM_HAS_RVSWD
3233

3334
#if ENABLE_DEBUG == 1
3435
#define PLATFORM_HAS_DEBUG

src/target/meson.build

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ target_common_sources = files(
3737
'gdb_reg.c',
3838
'jtag_devs.c',
3939
'jtag_scan.c',
40+
'rvswd_scan.c',
4041
'semihosting.c',
4142
'sfdp.c',
4243
'spi.c',

0 commit comments

Comments
 (0)