-
-
Notifications
You must be signed in to change notification settings - Fork 776
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
perigoso
wants to merge
21
commits into
blackmagic-debug:main
Choose a base branch
from
perigoso:feature/wch-support
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Draft
Changes from all commits
Commits
Show all changes
21 commits
Select commit
Hold shift + click to select a range
06af671
hosted: barebones wch-link implementation
perigoso 466049b
hosted/wchlink: implement DMI transfer
perigoso de413af
riscv_debug: expose DMI operation and status defines
perigoso 0e75dde
jep106: add BMD internal flag
perigoso 50ffc29
jep106: add internal WCH non-jep106 code
perigoso 117562f
riscv_jtag_dtm: move RV_DMI_TOO_SOON handling one level up
perigoso 03441a8
hosted/wchlink: implement RISC-V DTM handler
perigoso ee4269f
command: add rvswd scan routine command
perigoso 7c15658
hosted/wchlink: implement RVSWD scan
perigoso 6fa3a98
riscv32: add ch32v3 target probe
perigoso 488dfcc
ch32vx: implement electronic signature (ESIG) register handling
perigoso 2c08951
riscv32: add ch32v003 target probe
perigoso d586014
buffer_utils: add write_char util
perigoso ab51224
riscv_debug: formally parse the ISA subset
perigoso 5b65fa6
riscv_debug: use the ISA subset as the target core name
perigoso b332e50
riscv_debug: fix typo
perigoso abd5766
riscv64: fix typo
perigoso b81e1a5
riscv_debug: update RV_CSR macros
perigoso 0d3768b
!experimental! riscv32: add hacky fallback memory access using the pr…
perigoso 1ce1332
rvswd: gate rvswd functionality behind platform define
perigoso 2a30df5
experimental: start working towards a native implementation
perigoso File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 clock_cycles read */ | ||
uint32_t (*seq_in)(size_t clock_cycles); | ||
/* Perform a clock_cycles read + parity */ | ||
bool (*seq_in_parity)(uint32_t *ret, size_t clock_cycles); | ||
/* Perform a clock_cycles write with the provided data */ | ||
void (*seq_out)(uint32_t tms_states, size_t clock_cycles); | ||
/* Perform a clock_cycles write + parity with the provided data */ | ||
void (*seq_out_parity)(uint32_t tms_states, size_t clock_cycles); | ||
} rvswd_proc_s; | ||
|
||
extern rvswd_proc_s rvswd_proc; | ||
|
||
void rvswd_init(void); | ||
|
||
#endif /* INCLUDE_RVSWD_H */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,197 @@ | ||
/* | ||
* 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/>. | ||
*/ | ||
|
||
/* This file implements the SW-DP interface. */ | ||
|
||
#include "general.h" | ||
#include "platform.h" | ||
#include "timing.h" | ||
#include "rvswd.h" | ||
#include "maths_utils.h" | ||
|
||
// FIXME: reusing the SWD macros for now | ||
#if !defined(SWDIO_IN_PORT) | ||
#define SWDIO_IN_PORT SWDIO_PORT | ||
#endif | ||
#if !defined(SWDIO_IN_PIN) | ||
#define SWDIO_IN_PIN SWDIO_PIN | ||
#endif | ||
|
||
// typedef enum swdio_status_e { | ||
// SWDIO_STATUS_FLOAT = 0, | ||
// SWDIO_STATUS_DRIVE | ||
// } swdio_status_t; | ||
|
||
rvswd_proc_s rvswd_proc; | ||
|
||
// static void swdptap_turnaround(swdio_status_t dir) __attribute__((optimize(3))); | ||
// static uint32_t swdptap_seq_in(size_t clock_cycles) __attribute__((optimize(3))); | ||
// static bool swdptap_seq_in_parity(uint32_t *ret, size_t clock_cycles) __attribute__((optimize(3))); | ||
// static void swdptap_seq_out(uint32_t tms_states, size_t clock_cycles) __attribute__((optimize(3))); | ||
// static void swdptap_seq_out_parity(uint32_t tms_states, size_t clock_cycles) __attribute__((optimize(3))); | ||
|
||
void rvswd_init(void) | ||
{ | ||
// rvswd_proc.seq_in = swdptap_seq_in; | ||
// rvswd_proc.seq_in_parity = swdptap_seq_in_parity; | ||
// rvswd_proc.seq_out = swdptap_seq_out; | ||
// rvswd_proc.seq_out_parity = swdptap_seq_out_parity; | ||
} | ||
|
||
// static void swdptap_turnaround(const swdio_status_t dir) | ||
// { | ||
// static swdio_status_t olddir = SWDIO_STATUS_FLOAT; | ||
// /* Don't turnaround if direction not changing */ | ||
// if (dir == olddir) | ||
// return; | ||
// olddir = dir; | ||
|
||
// #ifdef DEBUG_SWD_BITS | ||
// DEBUG_INFO("%s", dir ? "\n-> " : "\n<- "); | ||
// #endif | ||
|
||
// if (dir == SWDIO_STATUS_FLOAT) { | ||
// SWDIO_MODE_FLOAT(); | ||
// } else | ||
// gpio_clear(SWCLK_PORT, SWCLK_PIN); | ||
|
||
// for (volatile uint32_t counter = target_clk_divider + 1; counter > 0; --counter) | ||
// continue; | ||
|
||
// gpio_set(SWCLK_PORT, SWCLK_PIN); | ||
// for (volatile uint32_t counter = target_clk_divider + 1; counter > 0; --counter) | ||
// continue; | ||
|
||
// if (dir == SWDIO_STATUS_DRIVE) { | ||
// gpio_clear(SWCLK_PORT, SWCLK_PIN); | ||
// SWDIO_MODE_DRIVE(); | ||
// } | ||
// } | ||
|
||
// static uint32_t swdptap_seq_in_clk_delay(size_t clock_cycles) __attribute__((optimize(3))); | ||
|
||
// static uint32_t swdptap_seq_in_clk_delay(const size_t clock_cycles) | ||
// { | ||
// uint32_t value = 0; | ||
// for (size_t cycle = 0; cycle < clock_cycles; ++cycle) { | ||
// gpio_clear(SWCLK_PORT, SWCLK_PIN); | ||
// value |= gpio_get(SWDIO_IN_PORT, SWDIO_IN_PIN) ? 1U << cycle : 0U; | ||
// for (volatile uint32_t counter = target_clk_divider; counter > 0; --counter) | ||
// continue; | ||
// gpio_set(SWCLK_PORT, SWCLK_PIN); | ||
// for (volatile uint32_t counter = target_clk_divider; counter > 0; --counter) | ||
// continue; | ||
// } | ||
// gpio_clear(SWCLK_PORT, SWCLK_PIN); | ||
// return value; | ||
// } | ||
|
||
// static uint32_t swdptap_seq_in_no_delay(size_t clock_cycles) __attribute__((optimize(3))); | ||
|
||
// static uint32_t swdptap_seq_in_no_delay(const size_t clock_cycles) | ||
// { | ||
// uint32_t value = 0; | ||
// for (size_t cycle = 0; cycle < clock_cycles; ++cycle) { | ||
// gpio_clear(SWCLK_PORT, SWCLK_PIN); | ||
// value |= gpio_get(SWDIO_IN_PORT, SWDIO_IN_PIN) ? 1U << cycle : 0U; | ||
// gpio_set(SWCLK_PORT, SWCLK_PIN); | ||
// __asm__("nop"); | ||
// } | ||
// gpio_clear(SWCLK_PORT, SWCLK_PIN); | ||
// return value; | ||
// } | ||
|
||
// static uint32_t swdptap_seq_in(size_t clock_cycles) | ||
// { | ||
// swdptap_turnaround(SWDIO_STATUS_FLOAT); | ||
// if (target_clk_divider != UINT32_MAX) | ||
// return swdptap_seq_in_clk_delay(clock_cycles); | ||
// else // NOLINT(readability-else-after-return) | ||
// return swdptap_seq_in_no_delay(clock_cycles); | ||
// } | ||
|
||
// static bool swdptap_seq_in_parity(uint32_t *ret, size_t clock_cycles) | ||
// { | ||
// const uint32_t result = swdptap_seq_in(clock_cycles); | ||
// for (volatile uint32_t counter = target_clk_divider + 1; counter > 0; --counter) | ||
// continue; | ||
|
||
// const bool parity = calculate_odd_parity(result); | ||
// const bool bit = gpio_get(SWDIO_IN_PORT, SWDIO_IN_PIN); | ||
|
||
// gpio_set(SWCLK_PORT, SWCLK_PIN); | ||
// for (volatile uint32_t counter = target_clk_divider + 1; counter > 0; --counter) | ||
// continue; | ||
|
||
// *ret = result; | ||
// /* Terminate the read cycle now */ | ||
// swdptap_turnaround(SWDIO_STATUS_DRIVE); | ||
// return parity != bit; | ||
// } | ||
|
||
// static void swdptap_seq_out_clk_delay(uint32_t tms_states, size_t clock_cycles) __attribute__((optimize(3))); | ||
|
||
// static void swdptap_seq_out_clk_delay(const uint32_t tms_states, const size_t clock_cycles) | ||
// { | ||
// for (size_t cycle = 0; cycle < clock_cycles; ++cycle) { | ||
// gpio_clear(SWCLK_PORT, SWCLK_PIN); | ||
// gpio_set_val(SWDIO_PORT, SWDIO_PIN, tms_states & (1 << cycle)); | ||
// for (volatile uint32_t counter = target_clk_divider; counter > 0; --counter) | ||
// continue; | ||
// gpio_set(SWCLK_PORT, SWCLK_PIN); | ||
// for (volatile uint32_t counter = target_clk_divider; counter > 0; --counter) | ||
// continue; | ||
// } | ||
// gpio_clear(SWCLK_PORT, SWCLK_PIN); | ||
// } | ||
|
||
// static void swdptap_seq_out_no_delay(uint32_t tms_states, size_t clock_cycles) __attribute__((optimize(3))); | ||
|
||
// static void swdptap_seq_out_no_delay(const uint32_t tms_states, const size_t clock_cycles) | ||
// { | ||
// for (size_t cycle = 0; cycle < clock_cycles; ++cycle) { | ||
// gpio_clear(SWCLK_PORT, SWCLK_PIN); | ||
// gpio_set_val(SWDIO_PORT, SWDIO_PIN, tms_states & (1 << cycle)); | ||
// gpio_set(SWCLK_PORT, SWCLK_PIN); | ||
// } | ||
// gpio_clear(SWCLK_PORT, SWCLK_PIN); | ||
// } | ||
|
||
// static void swdptap_seq_out(const uint32_t tms_states, const size_t clock_cycles) | ||
// { | ||
// swdptap_turnaround(SWDIO_STATUS_DRIVE); | ||
// if (target_clk_divider != UINT32_MAX) | ||
// swdptap_seq_out_clk_delay(tms_states, clock_cycles); | ||
// else | ||
// swdptap_seq_out_no_delay(tms_states, clock_cycles); | ||
// } | ||
|
||
// static void swdptap_seq_out_parity(const uint32_t tms_states, const size_t clock_cycles) | ||
// { | ||
// const bool parity = calculate_odd_parity(tms_states); | ||
// swdptap_seq_out(tms_states, clock_cycles); | ||
// gpio_set_val(SWDIO_PORT, SWDIO_PIN, parity); | ||
// for (volatile uint32_t counter = target_clk_divider + 1; counter > 0; --counter) | ||
// continue; | ||
// gpio_set(SWCLK_PORT, SWCLK_PIN); | ||
// for (volatile uint32_t counter = target_clk_divider + 1; counter > 0; --counter) | ||
// continue; | ||
// gpio_clear(SWCLK_PORT, SWCLK_PIN); | ||
// } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
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 forPC_HOSTED
.There was a problem hiding this comment.
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