From f208ce3b132e1b2f741cf2c34ae4e60dd7472e81 Mon Sep 17 00:00:00 2001 From: dragonmux Date: Thu, 9 Feb 2023 11:09:06 +0000 Subject: [PATCH 1/4] stm32f1: Implemented a probe routine for GD32VF1 --- src/target/stm32f1.c | 25 +++++++++++++++++++++++++ src/target/target_probe.c | 1 + src/target/target_probe.h | 1 + 3 files changed, 27 insertions(+) diff --git a/src/target/stm32f1.c b/src/target/stm32f1.c index bd3209b7b52..1b70914eb67 100644 --- a/src/target/stm32f1.c +++ b/src/target/stm32f1.c @@ -181,6 +181,31 @@ bool gd32f1_probe(target_s *target) return true; } +/* Identify RISC-V GD32VF1 chips */ +bool gd32vf1_probe(target_s *const target) +{ + 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) diff --git a/src/target/target_probe.c b/src/target/target_probe.c index 06f6ba99048..4c3e13790e3 100644 --- a/src/target/target_probe.c +++ b/src/target/target_probe.c @@ -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) diff --git a/src/target/target_probe.h b/src/target/target_probe.h index 788f7821e09..23faa2e6b77 100644 --- a/src/target/target_probe.h +++ b/src/target/target_probe.h @@ -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); From 104615dc4b89a8f7695ceee6f98b47720265db7c Mon Sep 17 00:00:00 2001 From: dragonmux Date: Thu, 9 Feb 2023 11:09:47 +0000 Subject: [PATCH 2/4] riscv32: Implemented probing for the GD32VF1 --- src/target/jep106.h | 5 +++++ src/target/riscv32.c | 13 +++++++++++++ 2 files changed, 18 insertions(+) diff --git a/src/target/jep106.h b/src/target/jep106.h index 83317b9f9dd..bc410a982ec 100644 --- a/src/target/jep106.h +++ b/src/target/jep106.h @@ -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 diff --git a/src/target/riscv32.c b/src/target/riscv32.c index b044a6c6e2c..5f2ce004ed4 100644 --- a/src/target/riscv32.c +++ b/src/target/riscv32.c @@ -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]; @@ -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; } From b8452ada00356534cc883bce632bb875eb4e29eb Mon Sep 17 00:00:00 2001 From: dragonmux Date: Thu, 9 Feb 2023 11:38:44 +0000 Subject: [PATCH 3/4] riscv_debug: Populated target->cpuid and made use of it in gd32vf1_probe() for an even more positive part identification Co-Authored-By: Rafael Silva --- src/target/riscv_debug.c | 1 + src/target/stm32f1.c | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/src/target/riscv_debug.c b/src/target/riscv_debug.c index 13b4eb9e4a7..44ec9e42c8b 100644 --- a/src/target/riscv_debug.c +++ b/src/target/riscv_debug.c @@ -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); diff --git a/src/target/stm32f1.c b/src/target/stm32f1.c index 1b70914eb67..48c34e98ed6 100644 --- a/src/target/stm32f1.c +++ b/src/target/stm32f1.c @@ -184,6 +184,10 @@ bool gd32f1_probe(target_s *target) /* 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 */ From b37d375b473a02ec7b9cf3bb938c146903de941d Mon Sep 17 00:00:00 2001 From: dragonmux Date: Sat, 11 Feb 2023 05:52:53 +0000 Subject: [PATCH 4/4] stm32f1: Modified the Flash routines to work with GD32VF103 parts too --- src/target/stm32f1.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/target/stm32f1.c b/src/target/stm32f1.c index 48c34e98ed6..46f651959cd 100644 --- a/src/target/stm32f1.c +++ b/src/target/stm32f1.c @@ -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); @@ -640,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)) @@ -654,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))