Skip to content

Commit

Permalink
!experimental! DO NOT MERGE
Browse files Browse the repository at this point in the history
  • Loading branch information
perigoso authored and rg-silva committed Dec 15, 2023
1 parent e6ded5e commit 828ef60
Show file tree
Hide file tree
Showing 5 changed files with 308 additions and 64 deletions.
170 changes: 161 additions & 9 deletions src/target/riscv32.c
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,7 @@ static int riscv32_breakwatch_clear(target_s *target, breakwatch_s *breakwatch);
bool riscv32_probe(target_s *const target)
{
/* Finish setting up the target structure with generic rv32 functions */
target->core = "rv32";
/* Provide the length of a suitable registers structure */
target->regs_size = sizeof(riscv32_regs_s);
target->regs_size = sizeof(riscv32_regs_s); /* Provide the length of a suitable registers structure */
target->regs_read = riscv32_regs_read;
target->regs_write = riscv32_regs_write;
target->reg_write = riscv32_reg_write;
Expand Down Expand Up @@ -517,6 +515,140 @@ static void riscv32_sysbus_mem_write(
riscv32_sysbus_mem_adjusted_write(hart, address, data, access_width, native_access_width, native_access_length);
}

static void riscv32_abstract_progbuf_mem_read(
riscv_hart_s *const hart, void *const dest, const target_addr_t src, const size_t len)
{
if (!(hart->extensions & RV_ISA_EXT_COMPRESSED)) {
DEBUG_ERROR("This target does not implement the compressed ISA extension\n");
return;
}

DEBUG_TARGET("Performing %zu byte read of %08" PRIx32 " using PROGBUF\n", len, src);

/* Figure out the maxmial width of access to perform, up to the bitness of the target */
const uint8_t access_width = riscv_mem_access_width(hart, src, len);
// const uint8_t access_length = 1U << access_width;
// /* Build the access command */
// const uint32_t command = RV_DM_ABST_CMD_ACCESS_MEM | RV_ABST_READ | (access_width << RV_ABST_MEM_ACCESS_SHIFT) |
// (access_length < len ? RV_ABST_MEM_ADDR_POST_INC : 0U);
// /* Write the address to read to arg1 */
// if (!riscv_dm_write(hart->dbg_module, RV_DM_DATA1, src))
// return;
// uint8_t *const data = (uint8_t *)dest;
// for (size_t offset = 0; offset < len; offset += access_length) {
// /* Execute the read */
// if (!riscv_dm_write(hart->dbg_module, RV_DM_ABST_COMMAND, command) || !riscv_command_wait_complete(hart))
// return;
// /* Extract back the data from arg0 */
// uint32_t value = 0;
// if (!riscv_dm_read(hart->dbg_module, RV_DM_DATA0, &value))
// return;
// riscv32_unpack_data(data + offset, value, access_width);
// }

/* Disable auto-exec */
// if (!riscv_dm_write(hart->dbg_module, RV_DM_ABST_AUTO, 0))
// return;

/*
* progbuf 0
* c.lw x8,0(x11) // Pull the address from DATA1
* c.lw x9,0(x8) // Read the data at that location
*/
if (!riscv_dm_write(hart->dbg_module, RV_DM_PROGBUF0, 0x40044180U))
return;

/*
* progbuf 1
* c.nop // alternately, `c.addi x8, 4` , for auto-increment (0xc1040411)
* c.sw x9, 0(x10) // Write back to DATA0
*/
if (!riscv_dm_write(hart->dbg_module, RV_DM_PROGBUF1, 0xc1040001U))
return;

/*
* progbuf 2
* c.sw x8, 0(x11) // Write addy to DATA1
* c.ebreak
*/
if (!riscv_dm_write(hart->dbg_module, RV_DM_PROGBUF2, 0x9002c180U))
return;

/* StaticUpdatePROGBUFRegs */
uint32_t rr;
if (!riscv_dm_read(hart->dbg_module, 0x12, &rr)) {
DEBUG_ERROR("Could not get hart info\n");
return;
}
DEBUG_INFO("rr: %08" PRIx32 "\n", rr);
const uint32_t data0_offset = 0xe0000000U | (rr & 0x7ffU);
if (!riscv_dm_write(hart->dbg_module, RV_DM_DATA0, data0_offset)) // DATA0's location in memory.
return;
if (!riscv_dm_write(hart->dbg_module, RV_DM_ABST_COMMAND, 0x0023100aU)) // Copy data to x10
return;
if (!riscv_dm_write(hart->dbg_module, RV_DM_DATA0, data0_offset + 4U)) // DATA1's location in memory.
return;
if (!riscv_dm_write(hart->dbg_module, RV_DM_ABST_COMMAND, 0x0023100bU)) // Copy data to x11
return;
// if (!riscv_dm_write(hart->dbg_module, RV_DM_DATA0, 0x40022010U)) // FLASH->CTLR
// return;
// if (!riscv_dm_write(hart->dbg_module, RV_DM_ABST_COMMAND, 0x0023100cU)) // Copy data to x12
// return;
// #define CR_PAGE_PG ((uint32_t)0x00010000)
// #define CR_BUF_LOAD ((uint32_t)0x00040000)
// if (!riscv_dm_write(hart->dbg_module, RV_DM_DATA0, CR_PAGE_PG | CR_BUF_LOAD))
// return;
// if (!riscv_dm_write(hart->dbg_module, RV_DM_ABST_COMMAND, 0x0023100dU)) // Copy data to x13
// return;

/* Enable auto-exec */
// if (!riscv_dm_write(hart->dbg_module, RV_DM_ABST_AUTO, 1U))
// return;

if (!riscv_dm_write(hart->dbg_module, RV_DM_DATA1, src))
return;
if (!riscv_dm_write(hart->dbg_module, RV_DM_ABST_COMMAND, 0x00241000U) || !riscv_command_wait_complete(hart))
return;

/* Extract back the data from arg0 */
uint32_t value = 0;
if (!riscv_dm_read(hart->dbg_module, RV_DM_DATA0, &value))
return;

riscv32_unpack_data(dest, value, access_width);
}

static void riscv32_abstract_progbuf_mem_write(
riscv_hart_s *const hart, const target_addr_t dest, const void *const src, const size_t len)
{
DEBUG_TARGET("Performing %zu byte write of %08" PRIx32 " using PROGBUF\n", len, dest);

(void)hart;
(void)dest;
(void)src;
(void)len;

// /* Figure out the maxmial width of access to perform, up to the bitness of the target */
// const uint8_t access_width = riscv_mem_access_width(hart, dest, len);
// const uint8_t access_length = 1U << access_width;
// /* Build the access command */
// const uint32_t command = RV_DM_ABST_CMD_ACCESS_MEM | RV_ABST_WRITE | (access_width << RV_ABST_MEM_ACCESS_SHIFT) |
// (access_length < len ? RV_ABST_MEM_ADDR_POST_INC : 0U);
// /* Write the address to write to arg1 */
// if (!riscv_dm_write(hart->dbg_module, RV_DM_DATA1, dest))
// return;
// const uint8_t *const data = (const uint8_t *)src;
// for (size_t offset = 0; offset < len; offset += access_length) {
// /* Pack the data to write into arg0 */
// uint32_t value = riscv32_pack_data(data + offset, access_width);
// if (!riscv_dm_write(hart->dbg_module, RV_DM_DATA0, value))
// return;
// /* Execute the write */
// if (!riscv_dm_write(hart->dbg_module, RV_DM_ABST_COMMAND, command) || !riscv_command_wait_complete(hart))
// return;
// }
}

static void riscv32_mem_read(target_s *const target, void *const dest, const target_addr_t src, const size_t len)
{
DEBUG_TARGET("Performing %zu byte read of %08" PRIx32 "\n", len, src);
Expand All @@ -525,9 +657,19 @@ static void riscv32_mem_read(target_s *const target, void *const dest, const tar
return;

riscv_hart_s *const hart = riscv_hart_struct(target);
if (hart->flags & RV_HART_FLAG_MEMORY_SYSBUS)
return riscv32_sysbus_mem_read(hart, dest, src, len);
return riscv32_abstract_mem_read(hart, dest, src, len);
if (hart->flags & RV_HART_FLAG_MEMORY_SYSBUS) {
riscv32_sysbus_mem_read(hart, dest, src, len);
return;
}
if (hart->flags & RV_HART_FLAG_MEMORY_ABSTRACT) {
riscv32_abstract_mem_read(hart, dest, src, len);
if (hart->status == RISCV_HART_NOT_SUPP) {
DEBUG_WARN("Abstract memory access not supported, falling back to prog buffer\n");
hart->flags &= (uint8_t)~RV_HART_FLAG_MEMORY_ABSTRACT;
} else
return;
}
riscv32_abstract_progbuf_mem_read(hart, dest, src, len);
}

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

riscv_hart_s *const hart = riscv_hart_struct(target);
if (hart->flags & RV_HART_FLAG_MEMORY_SYSBUS)
return riscv32_sysbus_mem_write(hart, dest, src, len);
return riscv32_abstract_mem_write(hart, dest, src, len);
if (hart->flags & RV_HART_FLAG_MEMORY_SYSBUS) {
riscv32_sysbus_mem_write(hart, dest, src, len);
return;
}
if (hart->flags & RV_HART_FLAG_MEMORY_ABSTRACT) {
riscv32_abstract_mem_write(hart, dest, src, len);
if (hart->status == RISCV_HART_NOT_SUPP) {
DEBUG_WARN("Abstract memory access not supported, falling back to prog buffer\n");
hart->flags &= (uint8_t)~RV_HART_FLAG_MEMORY_ABSTRACT;
} else
return;
}
riscv32_abstract_progbuf_mem_write(hart, dest, src, len);
}

/*
Expand Down
4 changes: 1 addition & 3 deletions src/target/riscv64.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,7 @@ static void riscv64_mem_read(target_s *target, void *dest, target_addr_t src, si
bool riscv64_probe(target_s *const target)
{
/* Finish setting up the target structure with generic rv64 functions */
target->core = "rv64";
/* Provide the length of a suitable registers structure */
target->regs_size = sizeof(riscv64_regs_s);
target->regs_size = sizeof(riscv64_regs_s); /* Provide the length of a suitable registers structure */
target->regs_read = riscv64_regs_read;
target->regs_write = riscv64_regs_write;
target->mem_read = riscv64_mem_read;
Expand Down
Loading

0 comments on commit 828ef60

Please sign in to comment.