Skip to content
This repository was archived by the owner on Mar 7, 2026. It is now read-only.

Commit 828ef60

Browse files
perigosorg-silva
authored andcommitted
!experimental! DO NOT MERGE
1 parent e6ded5e commit 828ef60

5 files changed

Lines changed: 308 additions & 64 deletions

File tree

src/target/riscv32.c

Lines changed: 161 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -81,9 +81,7 @@ static int riscv32_breakwatch_clear(target_s *target, breakwatch_s *breakwatch);
8181
bool riscv32_probe(target_s *const target)
8282
{
8383
/* Finish setting up the target structure with generic rv32 functions */
84-
target->core = "rv32";
85-
/* Provide the length of a suitable registers structure */
86-
target->regs_size = sizeof(riscv32_regs_s);
84+
target->regs_size = sizeof(riscv32_regs_s); /* Provide the length of a suitable registers structure */
8785
target->regs_read = riscv32_regs_read;
8886
target->regs_write = riscv32_regs_write;
8987
target->reg_write = riscv32_reg_write;
@@ -517,6 +515,140 @@ static void riscv32_sysbus_mem_write(
517515
riscv32_sysbus_mem_adjusted_write(hart, address, data, access_width, native_access_width, native_access_length);
518516
}
519517

518+
static void riscv32_abstract_progbuf_mem_read(
519+
riscv_hart_s *const hart, void *const dest, const target_addr_t src, const size_t len)
520+
{
521+
if (!(hart->extensions & RV_ISA_EXT_COMPRESSED)) {
522+
DEBUG_ERROR("This target does not implement the compressed ISA extension\n");
523+
return;
524+
}
525+
526+
DEBUG_TARGET("Performing %zu byte read of %08" PRIx32 " using PROGBUF\n", len, src);
527+
528+
/* Figure out the maxmial width of access to perform, up to the bitness of the target */
529+
const uint8_t access_width = riscv_mem_access_width(hart, src, len);
530+
// const uint8_t access_length = 1U << access_width;
531+
// /* Build the access command */
532+
// const uint32_t command = RV_DM_ABST_CMD_ACCESS_MEM | RV_ABST_READ | (access_width << RV_ABST_MEM_ACCESS_SHIFT) |
533+
// (access_length < len ? RV_ABST_MEM_ADDR_POST_INC : 0U);
534+
// /* Write the address to read to arg1 */
535+
// if (!riscv_dm_write(hart->dbg_module, RV_DM_DATA1, src))
536+
// return;
537+
// uint8_t *const data = (uint8_t *)dest;
538+
// for (size_t offset = 0; offset < len; offset += access_length) {
539+
// /* Execute the read */
540+
// if (!riscv_dm_write(hart->dbg_module, RV_DM_ABST_COMMAND, command) || !riscv_command_wait_complete(hart))
541+
// return;
542+
// /* Extract back the data from arg0 */
543+
// uint32_t value = 0;
544+
// if (!riscv_dm_read(hart->dbg_module, RV_DM_DATA0, &value))
545+
// return;
546+
// riscv32_unpack_data(data + offset, value, access_width);
547+
// }
548+
549+
/* Disable auto-exec */
550+
// if (!riscv_dm_write(hart->dbg_module, RV_DM_ABST_AUTO, 0))
551+
// return;
552+
553+
/*
554+
* progbuf 0
555+
* c.lw x8,0(x11) // Pull the address from DATA1
556+
* c.lw x9,0(x8) // Read the data at that location
557+
*/
558+
if (!riscv_dm_write(hart->dbg_module, RV_DM_PROGBUF0, 0x40044180U))
559+
return;
560+
561+
/*
562+
* progbuf 1
563+
* c.nop // alternately, `c.addi x8, 4` , for auto-increment (0xc1040411)
564+
* c.sw x9, 0(x10) // Write back to DATA0
565+
*/
566+
if (!riscv_dm_write(hart->dbg_module, RV_DM_PROGBUF1, 0xc1040001U))
567+
return;
568+
569+
/*
570+
* progbuf 2
571+
* c.sw x8, 0(x11) // Write addy to DATA1
572+
* c.ebreak
573+
*/
574+
if (!riscv_dm_write(hart->dbg_module, RV_DM_PROGBUF2, 0x9002c180U))
575+
return;
576+
577+
/* StaticUpdatePROGBUFRegs */
578+
uint32_t rr;
579+
if (!riscv_dm_read(hart->dbg_module, 0x12, &rr)) {
580+
DEBUG_ERROR("Could not get hart info\n");
581+
return;
582+
}
583+
DEBUG_INFO("rr: %08" PRIx32 "\n", rr);
584+
const uint32_t data0_offset = 0xe0000000U | (rr & 0x7ffU);
585+
if (!riscv_dm_write(hart->dbg_module, RV_DM_DATA0, data0_offset)) // DATA0's location in memory.
586+
return;
587+
if (!riscv_dm_write(hart->dbg_module, RV_DM_ABST_COMMAND, 0x0023100aU)) // Copy data to x10
588+
return;
589+
if (!riscv_dm_write(hart->dbg_module, RV_DM_DATA0, data0_offset + 4U)) // DATA1's location in memory.
590+
return;
591+
if (!riscv_dm_write(hart->dbg_module, RV_DM_ABST_COMMAND, 0x0023100bU)) // Copy data to x11
592+
return;
593+
// if (!riscv_dm_write(hart->dbg_module, RV_DM_DATA0, 0x40022010U)) // FLASH->CTLR
594+
// return;
595+
// if (!riscv_dm_write(hart->dbg_module, RV_DM_ABST_COMMAND, 0x0023100cU)) // Copy data to x12
596+
// return;
597+
// #define CR_PAGE_PG ((uint32_t)0x00010000)
598+
// #define CR_BUF_LOAD ((uint32_t)0x00040000)
599+
// if (!riscv_dm_write(hart->dbg_module, RV_DM_DATA0, CR_PAGE_PG | CR_BUF_LOAD))
600+
// return;
601+
// if (!riscv_dm_write(hart->dbg_module, RV_DM_ABST_COMMAND, 0x0023100dU)) // Copy data to x13
602+
// return;
603+
604+
/* Enable auto-exec */
605+
// if (!riscv_dm_write(hart->dbg_module, RV_DM_ABST_AUTO, 1U))
606+
// return;
607+
608+
if (!riscv_dm_write(hart->dbg_module, RV_DM_DATA1, src))
609+
return;
610+
if (!riscv_dm_write(hart->dbg_module, RV_DM_ABST_COMMAND, 0x00241000U) || !riscv_command_wait_complete(hart))
611+
return;
612+
613+
/* Extract back the data from arg0 */
614+
uint32_t value = 0;
615+
if (!riscv_dm_read(hart->dbg_module, RV_DM_DATA0, &value))
616+
return;
617+
618+
riscv32_unpack_data(dest, value, access_width);
619+
}
620+
621+
static void riscv32_abstract_progbuf_mem_write(
622+
riscv_hart_s *const hart, const target_addr_t dest, const void *const src, const size_t len)
623+
{
624+
DEBUG_TARGET("Performing %zu byte write of %08" PRIx32 " using PROGBUF\n", len, dest);
625+
626+
(void)hart;
627+
(void)dest;
628+
(void)src;
629+
(void)len;
630+
631+
// /* Figure out the maxmial width of access to perform, up to the bitness of the target */
632+
// const uint8_t access_width = riscv_mem_access_width(hart, dest, len);
633+
// const uint8_t access_length = 1U << access_width;
634+
// /* Build the access command */
635+
// const uint32_t command = RV_DM_ABST_CMD_ACCESS_MEM | RV_ABST_WRITE | (access_width << RV_ABST_MEM_ACCESS_SHIFT) |
636+
// (access_length < len ? RV_ABST_MEM_ADDR_POST_INC : 0U);
637+
// /* Write the address to write to arg1 */
638+
// if (!riscv_dm_write(hart->dbg_module, RV_DM_DATA1, dest))
639+
// return;
640+
// const uint8_t *const data = (const uint8_t *)src;
641+
// for (size_t offset = 0; offset < len; offset += access_length) {
642+
// /* Pack the data to write into arg0 */
643+
// uint32_t value = riscv32_pack_data(data + offset, access_width);
644+
// if (!riscv_dm_write(hart->dbg_module, RV_DM_DATA0, value))
645+
// return;
646+
// /* Execute the write */
647+
// if (!riscv_dm_write(hart->dbg_module, RV_DM_ABST_COMMAND, command) || !riscv_command_wait_complete(hart))
648+
// return;
649+
// }
650+
}
651+
520652
static void riscv32_mem_read(target_s *const target, void *const dest, const target_addr_t src, const size_t len)
521653
{
522654
DEBUG_TARGET("Performing %zu byte read of %08" PRIx32 "\n", len, src);
@@ -525,9 +657,19 @@ static void riscv32_mem_read(target_s *const target, void *const dest, const tar
525657
return;
526658

527659
riscv_hart_s *const hart = riscv_hart_struct(target);
528-
if (hart->flags & RV_HART_FLAG_MEMORY_SYSBUS)
529-
return riscv32_sysbus_mem_read(hart, dest, src, len);
530-
return riscv32_abstract_mem_read(hart, dest, src, len);
660+
if (hart->flags & RV_HART_FLAG_MEMORY_SYSBUS) {
661+
riscv32_sysbus_mem_read(hart, dest, src, len);
662+
return;
663+
}
664+
if (hart->flags & RV_HART_FLAG_MEMORY_ABSTRACT) {
665+
riscv32_abstract_mem_read(hart, dest, src, len);
666+
if (hart->status == RISCV_HART_NOT_SUPP) {
667+
DEBUG_WARN("Abstract memory access not supported, falling back to prog buffer\n");
668+
hart->flags &= (uint8_t)~RV_HART_FLAG_MEMORY_ABSTRACT;
669+
} else
670+
return;
671+
}
672+
riscv32_abstract_progbuf_mem_read(hart, dest, src, len);
531673
}
532674

533675
static void riscv32_mem_write(target_s *const target, const target_addr_t dest, const void *const src, const size_t len)
@@ -538,9 +680,19 @@ static void riscv32_mem_write(target_s *const target, const target_addr_t dest,
538680
return;
539681

540682
riscv_hart_s *const hart = riscv_hart_struct(target);
541-
if (hart->flags & RV_HART_FLAG_MEMORY_SYSBUS)
542-
return riscv32_sysbus_mem_write(hart, dest, src, len);
543-
return riscv32_abstract_mem_write(hart, dest, src, len);
683+
if (hart->flags & RV_HART_FLAG_MEMORY_SYSBUS) {
684+
riscv32_sysbus_mem_write(hart, dest, src, len);
685+
return;
686+
}
687+
if (hart->flags & RV_HART_FLAG_MEMORY_ABSTRACT) {
688+
riscv32_abstract_mem_write(hart, dest, src, len);
689+
if (hart->status == RISCV_HART_NOT_SUPP) {
690+
DEBUG_WARN("Abstract memory access not supported, falling back to prog buffer\n");
691+
hart->flags &= (uint8_t)~RV_HART_FLAG_MEMORY_ABSTRACT;
692+
} else
693+
return;
694+
}
695+
riscv32_abstract_progbuf_mem_write(hart, dest, src, len);
544696
}
545697

546698
/*

src/target/riscv64.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,7 @@ static void riscv64_mem_read(target_s *target, void *dest, target_addr_t src, si
4949
bool riscv64_probe(target_s *const target)
5050
{
5151
/* Finish setting up the target structure with generic rv64 functions */
52-
target->core = "rv64";
53-
/* Provide the length of a suitable registers structure */
54-
target->regs_size = sizeof(riscv64_regs_s);
52+
target->regs_size = sizeof(riscv64_regs_s); /* Provide the length of a suitable registers structure */
5553
target->regs_read = riscv64_regs_read;
5654
target->regs_write = riscv64_regs_write;
5755
target->mem_read = riscv64_mem_read;

0 commit comments

Comments
 (0)