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: WCH RISC-V support #1399

Draft
wants to merge 24 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
7a2134c
hosted: barebones wch-link implementation
perigoso Aug 10, 2023
b5dfd7d
hosted/wchlink: implement DMI transfer
perigoso Aug 11, 2023
3556898
riscv_debug: expose DMI operation and status defines
perigoso Aug 11, 2023
4fb98cf
jep106: add BMD internal flag
perigoso Jul 31, 2023
272ef44
jep106: add internal WCH non-jep106 code
perigoso Feb 23, 2023
41bf986
riscv_jtag_dtm: move RV_DMI_TOO_SOON handling one level up
perigoso Aug 11, 2023
a8feda2
hosted/wchlink: implement RISC-V DTM handler
perigoso Aug 11, 2023
63a22bd
command: add rvswd scan routine command
perigoso Aug 11, 2023
85d9f8e
hosted/wchlink: implement RVSWD scan
perigoso Aug 11, 2023
ec2d85a
riscv32: add ch32v3 target probe
perigoso Feb 23, 2023
49e9466
ch32vx: implement electronic signature (ESIG) register handling
perigoso Aug 11, 2023
094201b
riscv32: add ch32v003 target probe
perigoso Oct 5, 2023
145de4c
buffer_utils: add write_char util
perigoso Jan 15, 2024
3e5c646
riscv_debug: formally parse the ISA subset
perigoso Jan 15, 2024
40206d0
riscv_debug: use the ISA subset as the target core name
perigoso Jan 15, 2024
b71af18
riscv_debug: fix typo
perigoso Jan 15, 2024
628ffc5
riscv64: fix typo
perigoso Jan 15, 2024
8124471
riscv_debug: update RV_CSR macros
perigoso Jan 15, 2024
7679460
!experimental! riscv32: add hacky fallback memory access using the pr…
perigoso Jan 15, 2024
c643d81
rvswd: gate rvswd functionality behind platform define
perigoso Jan 17, 2024
223a1ad
experimental: start working towards a native implementation
perigoso Jan 17, 2024
1f2d949
gdb_packet: add note on gdb remote protocol debugging
perigoso Dec 19, 2024
d1b2b5a
riscv32: fix RV32E register count and respective size
perigoso Dec 19, 2024
80725c5
rvswd: experimental native implementation (does not work yet!)
perigoso Dec 19, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 63 additions & 1 deletion src/command.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ static bool cmd_help(target_s *target, int argc, const char **argv);

static bool cmd_jtag_scan(target_s *target, int argc, const char **argv);
static bool cmd_swd_scan(target_s *target, int argc, const char **argv);
#ifdef PLATFORM_HAS_RVSWD
static bool cmd_rvswd_scan(target_s *target, int argc, const char **argv);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should probably be defined contingent on ENABLE_RISCV and we'd suggest that, at least for now, this be limited to BMDA. Iff we can figure out how to implement the protocol in the firmware we can then de-restrict it by removing the suggested check for PC_HOSTED.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That makes sense, I will consider how to gate this when it's more complete, there will still be a native implementation

#endif
static bool cmd_auto_scan(target_s *target, int argc, const char **argv);
static bool cmd_frequency(target_s *target, int argc, const char **argv);
static bool cmd_targets(target_s *target, int argc, const char **argv);
Expand Down Expand Up @@ -94,6 +97,9 @@ const command_s cmd_list[] = {
{"jtag_scan", cmd_jtag_scan, "Scan JTAG chain for devices"},
{"swd_scan", cmd_swd_scan, "Scan SWD interface for devices: [TARGET_ID]"},
{"swdp_scan", cmd_swd_scan, "Deprecated: use swd_scan instead"},
#ifdef PLATFORM_HAS_RVSWD
{"rvswd_scan", cmd_rvswd_scan, "Scan RVSWD for devices"},
#endif
{"auto_scan", cmd_auto_scan, "Automatically scan all chain types for devices"},
{"frequency", cmd_frequency, "set minimum high and low times: [FREQ]"},
{"targets", cmd_targets, "Display list of available targets"},
Expand Down Expand Up @@ -316,6 +322,52 @@ bool cmd_swd_scan(target_s *target, int argc, const char **argv)
return true;
}

#ifdef PLATFORM_HAS_RVSWD
bool cmd_rvswd_scan(target_s *target, int argc, const char **argv)
{
(void)target;
(void)argc;
(void)argv;

if (platform_target_voltage())
gdb_outf("Target voltage: %s\n", platform_target_voltage());

if (connect_assert_nrst)
platform_nrst_set_val(true); /* will be deasserted after attach */

bool scan_result = false;
TRY (EXCEPTION_ALL) {
#if CONFIG_BMDA == 1
scan_result = bmda_rvswd_scan();
#else
scan_result = rvswd_scan();
#endif
}
CATCH () {
case EXCEPTION_TIMEOUT:
gdb_outf("Timeout during scan. Is target stuck in WFI?\n");
break;
case EXCEPTION_ERROR:
gdb_outf("Exception: %s\n", exception_frame.msg);
break;
default:
break;
}

if (!scan_result) {
platform_target_clk_output_enable(false);
platform_nrst_set_val(false);
gdb_out("RVSWD scan failed!\n");
return false;
}

cmd_targets(NULL, 0, NULL);
platform_target_clk_output_enable(false);
morse(NULL, false);
return true;
}
#endif

bool cmd_auto_scan(target_s *target, int argc, const char **argv)
{
(void)target;
Expand All @@ -342,8 +394,18 @@ bool cmd_auto_scan(target_s *target, int argc, const char **argv)
#else
scan_result = adiv5_swd_scan(0);
#endif
if (!scan_result)
if (!scan_result) {
gdb_out("SWD scan found no devices.\n");
#ifdef PLATFORM_HAS_RVSWD
#if CONFIG_BMDA == 1
scan_result = bmda_rvswd_scan();
#else
scan_result = rvswd_scan();
#endif
if (!scan_result)
gdb_out("RVSWD scan found no devices.\n");
#endif
}
}
}
CATCH () {
Expand Down
4 changes: 4 additions & 0 deletions src/gdb_packet.c
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,10 @@ void gdb_set_noackmode(bool enable)
}

#ifndef DEBUG_GDB_IS_NOOP
/*
* To see what packets GDB is seeing you can enable remote protocol debugging with:
* `(gdb) set debug remote 1`
*/
static void gdb_packet_debug(const char *const func, const gdb_packet_s *const packet)
{
/* Log packet for debugging */
Expand Down
7 changes: 7 additions & 0 deletions src/include/buffer_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,4 +84,11 @@ static inline uint64_t read_be8(const uint8_t *const buffer, const size_t offset
((uint64_t)buffer[offset + 6] << 8U) | buffer[offset + 7];
}

static inline size_t write_char(char *const buffer, const size_t buffer_size, const size_t offset, const char c)
{
if (buffer && offset < buffer_size)
buffer[offset] = c;
return offset + 1U;
}

#endif /*INCLUDE_BUFFER_UTILS_H*/
44 changes: 44 additions & 0 deletions src/include/rvswd.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* This file is part of the Black Magic Debug project.
*
* Copyright (C) 2011 Black Sphere Technologies Ltd.
* Written by Gareth McMullin <[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
* 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 <http://www.gnu.org/licenses/>.
*/

#ifndef INCLUDE_RVSWD_H
#define INCLUDE_RVSWD_H

#include <stdint.h>
#include <stddef.h>
#include <stdbool.h>

/* Functions interface talking RVSWD */
typedef struct rvswd_proc {
/* Perform a start condition */
void (*start)(void);
/* Perform a start condition */
void (*stop)(void);
/* Perform a clock_cycles read */
uint32_t (*seq_in)(size_t clock_cycles);
/* Perform a clock_cycles write with the provided data */
void (*seq_out)(uint32_t dio_states, size_t clock_cycles);
} rvswd_proc_s;

extern rvswd_proc_s rvswd_proc;

void rvswd_init(void);

#endif /* INCLUDE_RVSWD_H */
4 changes: 4 additions & 0 deletions src/include/target.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,13 @@ typedef struct target_controller target_controller_s;
#if CONFIG_BMDA == 1
bool bmda_swd_scan(uint32_t targetid);
bool bmda_jtag_scan(void);
bool bmda_rvswd_scan(void);
#endif
bool adiv5_swd_scan(uint32_t targetid);
bool jtag_scan(void);
// #ifdef PLATFORM_HAS_RVSWD
bool rvswd_scan(void);
// #endif

size_t target_foreach(void (*callback)(size_t index, target_s *target, void *context), void *context);
void target_list_free(void);
Expand Down
1 change: 1 addition & 0 deletions src/platforms/common/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ platform_common_sources = files(
'aux_serial.c',
'jtagtap.c',
'swdptap.c',
'rvswd.c',
'usb.c',
'usb_dfu_stub.c',
'usb_serial.c',
Expand Down
Loading
Loading