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: GD32VF1 support #1665

Merged
merged 4 commits into from
Oct 31, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
5 changes: 5 additions & 0 deletions src/target/jep106.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,11 @@
#define JEP106_MANUFACTURER_RASPBERRY 0x913U /* Raspberry Pi */
#define JEP106_MANUFACTURER_RENESAS 0x423U /* Renesas */
#define JEP106_MANUFACTURER_XILINX 0x309U /* Xilinx */
/*
* This JEP code should belong to "Andes Technology Corporation", but is used on RISC-V by GigaDevice,
* so in the unlikely event we need to support chips by them, here be dragons.
*/
#define JEP106_MANUFACTURER_RV_GIGADEVICE 0x61eU

/*
* This code is not listed in the JEP106 standard, but is used by some stm32f1 clones
Expand Down
13 changes: 13 additions & 0 deletions src/target/riscv32.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,9 @@
#include "target.h"
#include "target_internal.h"
#include "target_probe.h"
#include "jep106.h"
#include "riscv_debug.h"
#include "gdb_packet.h"

typedef struct riscv32_regs {
uint32_t gprs[32];
Expand Down Expand Up @@ -91,6 +93,17 @@ bool riscv32_probe(target_s *const target)
target->breakwatch_set = riscv32_breakwatch_set;
target->breakwatch_clear = riscv32_breakwatch_clear;

switch (target->designer_code) {
case JEP106_MANUFACTURER_RV_GIGADEVICE:
PROBE(gd32vf1_probe);
break;
}

#if PC_HOSTED == 0
gdb_outf("Please report unknown device with Designer 0x%x\n", target->designer_code);
#else
DEBUG_WARN("Please report unknown device with Designer 0x%x\n", target->designer_code);
#endif
return false;
}

Expand Down
1 change: 1 addition & 0 deletions src/target/riscv_debug.c
Original file line number Diff line number Diff line change
Expand Up @@ -380,6 +380,7 @@ static bool riscv_hart_init(riscv_hart_s *const hart)

/* If the hart implements mvendorid, this gives us the JEP-106, otherwise use the DTM designer code */
target->designer_code = hart->vendorid ? hart->vendorid : hart->dbg_module->dmi_bus->designer_code;
target->cpuid = hart->archid;

riscv_hart_discover_triggers(hart);

Expand Down
42 changes: 40 additions & 2 deletions src/target/stm32f1.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
#include "target.h"
#include "target_internal.h"
#include "cortexm.h"
#include "jep106.h"

static bool stm32f1_cmd_option(target_s *target, int argc, const char **argv);

Expand Down Expand Up @@ -181,6 +182,35 @@ bool gd32f1_probe(target_s *target)
return true;
}

/* Identify RISC-V GD32VF1 chips */
bool gd32vf1_probe(target_s *const target)
{
/* Make sure the architecture ID matches */
if (target->cpuid != 0x80000022U)
return false;
/* Then read out the device ID */
const uint16_t device_id = target_mem_read32(target, DBGMCU_IDCODE) & 0xfffU;
switch (device_id) {
case 0x410U: /* GD32VF103 */
target->driver = "GD32VF1";
break;
default:
return false;
}

const uint32_t signature = target_mem_read32(target, GD32Fx_FLASHSIZE);
const uint16_t flash_size = signature & 0xffffU;
const uint16_t ram_size = signature >> 16U;

target->part_id = device_id;
target->mass_erase = stm32f1_mass_erase;
target_add_ram(target, 0x20000000, ram_size * 1024U);
stm32f1_add_flash(target, 0x8000000, (size_t)flash_size * 1024U, 0x400U);
target_add_commands(target, stm32f1_cmd_list, target->driver);

return true;
}

static bool at32f40_detect(target_s *target, const uint16_t part_id)
{
// Current driver supports only *default* memory layout (256 KB Flash / 96 KB SRAM)
Expand Down Expand Up @@ -611,7 +641,11 @@ static bool stm32f1_flash_write(target_flash_s *flash, target_addr_t dest, const
stm32f1_flash_clear_eop(target, FLASH_BANK1_OFFSET);

target_mem_write32(target, FLASH_CR, FLASH_CR_PG);
cortexm_mem_write_sized(target, dest, src, offset, ALIGN_16BIT);
/* Use the target API instead of a direct Cortex-M call for GD32VF103 parts */
if (target->designer_code == JEP106_MANUFACTURER_RV_GIGADEVICE && target->cpuid == 0x80000022U)
target_mem_write(target, dest, src, offset);
else
cortexm_mem_write_sized(target, dest, src, offset, ALIGN_16BIT);

/* Wait for completion or an error */
if (!stm32f1_flash_busy_wait(target, FLASH_BANK1_OFFSET, NULL))
Expand All @@ -625,7 +659,11 @@ static bool stm32f1_flash_write(target_flash_s *flash, target_addr_t dest, const
stm32f1_flash_clear_eop(target, FLASH_BANK2_OFFSET);

target_mem_write32(target, FLASH_CR + FLASH_BANK2_OFFSET, FLASH_CR_PG);
cortexm_mem_write_sized(target, dest + offset, data + offset, remainder, ALIGN_16BIT);
/* Use the target API instead of a direct Cortex-M call for GD32VF103 parts */
if (target->designer_code == JEP106_MANUFACTURER_RV_GIGADEVICE && target->cpuid == 0x80000022U)
target_mem_write(target, dest + offset, data + offset, remainder);
else
cortexm_mem_write_sized(target, dest + offset, data + offset, remainder, ALIGN_16BIT);

/* Wait for completion or an error */
if (!stm32f1_flash_busy_wait(target, FLASH_BANK2_OFFSET, NULL))
Expand Down
1 change: 1 addition & 0 deletions src/target/target_probe.c
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ CORTEXM_PROBE_WEAK_NOP(lpc55_dmap_probe)

TARGET_PROBE_WEAK_NOP(ch32f1_probe)
TARGET_PROBE_WEAK_NOP(gd32f1_probe)
TARGET_PROBE_WEAK_NOP(gd32vf1_probe)
TARGET_PROBE_WEAK_NOP(gd32f4_probe)
TARGET_PROBE_WEAK_NOP(stm32f1_probe)
TARGET_PROBE_WEAK_NOP(at32fxx_probe)
Expand Down
1 change: 1 addition & 0 deletions src/target/target_probe.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ bool at32f43x_probe(target_s *target);
bool mm32l0xx_probe(target_s *target);
bool mm32f3xx_probe(target_s *target);
bool gd32f1_probe(target_s *target);
bool gd32vf1_probe(target_s *target);
bool gd32f4_probe(target_s *target);
bool stm32f1_probe(target_s *target);
bool stm32f4_probe(target_s *target);
Expand Down