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

Commit f119f67

Browse files
author
ALTracer
committed
riscv32: Compose the progbuf read/write instructions via macros, drop arrays
1 parent ad71a76 commit f119f67

1 file changed

Lines changed: 47 additions & 36 deletions

File tree

src/target/riscv32.c

Lines changed: 47 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -578,42 +578,65 @@ static void riscv32_sysbus_mem_write(
578578
riscv32_sysbus_mem_adjusted_write(hart, address, data, remainder, native_access_width, native_access_length);
579579
}
580580

581+
#define RV_OPCODE 0x0000007fU
582+
#define RV_FUNCT3 0x00003000U
583+
#define RV_RS1_MASK 0x000f8000U
584+
#define RV_LOAD_RD 0x00000f80U
585+
#define RV_LOAD_IMM12 0xfff00000U
586+
#define RV_STORE_RS2 0x01f00000U
587+
#define RV_STORE_IMM12 0xfe000f70U
588+
589+
#define RV_LOAD_BYTE 0x00000003U
590+
#define RV_LOAD_HALF 0x00001003U
591+
#define RV_LOAD_WORD 0x00002003U
592+
#define RV_STORE_BYTE 0x00000023U
593+
#define RV_STORE_HALF 0x00001023U
594+
#define RV_STORE_WORD 0x00002023U
595+
596+
#define RV_RS1_A0 0x00050000U
597+
#define RV_RS2_A1 0x00b00000U
598+
#define RV_RD_A0 0x00000500U
599+
#define RV_RD_A1 0x00000580U
600+
601+
/* RV32I opcodes: load word/half/byte from address A0 into A1 (clobber) */
602+
#define RV_LW_A1_A0 (RV_LOAD_WORD | RV_RD_A1 | RV_RS1_A0) // 0x00052583U // lw a1, 0(a0)
603+
#define RV_LH_A1_A0 (RV_LOAD_HALF | RV_RD_A1 | RV_RS1_A0) // 0x00051583U // lh a1, 0(a0)
604+
#define RV_LB_A1_A0 (RV_LOAD_BYTE | RV_RD_A1 | RV_RS1_A0) // 0x00050583U // lb a1, 0(a0)
605+
/* RV32I opcodes: store word/half/byte in a1 into address pointed-by a0 */
606+
#define RV_SW_A1_A0 (RV_STORE_WORD | RV_RS2_A1 | RV_RS1_A0) // 0x00b52023U // sw a1, 0(a0)
607+
#define RV_SH_A1_A0 (RV_STORE_HALF | RV_RS2_A1 | RV_RS1_A0) // 0x00b51023U // sh a1, 0(a0)
608+
#define RV_SB_A1_A0 (RV_STORE_BYTE | RV_RS2_A1 | RV_RS1_A0) // 0x00b50023U // sb a1, 0(a0)
609+
610+
#if 0
611+
#define RV_ADDI 0x00000013U
612+
#define RV_IMM12(x) ((x << 20U) & RV_LOAD_IMM12)
613+
/* RV32I opcodes: load word/half/byte from address A0 into A1 (clobber), postincrement A0 */
614+
#define RV_ADDI_A0_A0_4 (RV_ADDI | RV_RD_A0 | RV_RS1_A0 | RV_IMM12(4U)) // 0x00450513U // addi a0, a0, 4
615+
#endif
616+
581617
static void riscv32_progbuf_mem_read(
582618
riscv_hart_s *const hart, void *const dest, const target_addr_t src, const size_t len)
583619
{
584620
/* Figure out the maximal width of access to perform, up to the bitness of the target */
585621
const uint8_t access_width = riscv_mem_access_width(hart, src, len);
586622
const uint8_t access_length = 1U << access_width;
587623

588-
/* RV32I opcodes: load word/half/byte from address A0 into A1 (clobber), postincrement A0 */
589-
static const uint32_t progbuf_read32[2] = {
590-
0x00052583U, // lw a1, 0(a0)
591-
0x00450513U, // addi a0, a0, 4
592-
};
593-
static const uint32_t progbuf_read16[2] = {
594-
0x00051583U, // lh a1, 0(a0)
595-
0x00450513U, // addi a0, a0, 4
596-
};
597-
static const uint32_t progbuf_read8[2] = {
598-
0x00050583U, // lb a1, 0(a0)
599-
0x00450513U, // addi a0, a0, 4
600-
};
601-
const uint32_t *progbuf_read = progbuf_read32;
624+
uint32_t progbuf_read = RV_LOAD_BYTE;
602625
switch (access_width) {
603626
case RV_MEM_ACCESS_8_BIT:
604-
progbuf_read = progbuf_read8;
627+
progbuf_read = RV_LB_A1_A0;
605628
break;
606629
case RV_MEM_ACCESS_16_BIT:
607-
progbuf_read = progbuf_read16;
630+
progbuf_read = RV_LH_A1_A0;
608631
break;
609632
case RV_MEM_ACCESS_32_BIT:
610-
progbuf_read = progbuf_read32;
633+
progbuf_read = RV_LW_A1_A0;
611634
break;
612635
default:
613636
return;
614637
}
615638
/* Fill the program buffer */
616-
if (!riscv_dm_write(hart->dbg_module, RV_DM_PROGBUF_BASE, progbuf_read[0]))
639+
if (!riscv_dm_write(hart->dbg_module, RV_DM_PROGBUF_BASE, progbuf_read))
617640
return;
618641
/* Append literal ebreak (if impebreak is not reached) */
619642
if (hart->progbuf_size > 1) {
@@ -656,35 +679,23 @@ static void riscv32_progbuf_mem_write(
656679
/* Figure out the maxmial width of access to perform, up to the bitness of the target */
657680
const uint8_t access_width = riscv_mem_access_width(hart, dest, len);
658681
const uint8_t access_length = 1U << access_width;
659-
/* RV32I opcodes: store word/half/byte in a1 into address pointed-by a0 */
660-
static const uint32_t progbuf_write32[] = {
661-
0x00b52023U, // sw a1, 0(a0)
662-
0x00450513U, // addi a0, a0, 4
663-
};
664-
static const uint32_t progbuf_write16[] = {
665-
0x00b51023U, // sh a1, 0(a0)
666-
0x00450513U, // addi a0, a0, 4
667-
};
668-
static const uint32_t progbuf_write8[] = {
669-
0x00b50023U, // sb a1, 0(a0)
670-
0x00450513U, // addi a0, a0, 4
671-
};
672-
const uint32_t *progbuf_write = progbuf_write32;
682+
683+
uint32_t progbuf_write = RV_STORE_BYTE;
673684
switch (access_width) {
674685
case RV_MEM_ACCESS_8_BIT:
675-
progbuf_write = progbuf_write8;
686+
progbuf_write = RV_SB_A1_A0;
676687
break;
677688
case RV_MEM_ACCESS_16_BIT:
678-
progbuf_write = progbuf_write16;
689+
progbuf_write = RV_SH_A1_A0;
679690
break;
680691
case RV_MEM_ACCESS_32_BIT:
681-
progbuf_write = progbuf_write32;
692+
progbuf_write = RV_SW_A1_A0;
682693
break;
683694
default:
684695
return;
685696
}
686697
/* Fill the program buffer */
687-
if (!riscv_dm_write(hart->dbg_module, RV_DM_PROGBUF_BASE, progbuf_write[0]))
698+
if (!riscv_dm_write(hart->dbg_module, RV_DM_PROGBUF_BASE, progbuf_write))
688699
return;
689700
/* Append literal ebreak (if impebreak is not reached) */
690701
if (hart->progbuf_size > 1) {

0 commit comments

Comments
 (0)