@@ -569,34 +569,26 @@ static void riscv32_sysbus_mem_write(
569569
570570#define RV_DM_PROGBUF_BASE 0x20U
571571
572+ #define RV_GPR_A0 0x100aU
573+
574+ #define RV_EBREAK 0x00100073U
575+
572576static void riscv32_progbuf_mem_read (
573577 riscv_hart_s * const hart , void * const dest , const target_addr_t src , const size_t len )
574578{
575579 /* Figure out the maximal width of access to perform, up to the bitness of the target */
576580 const uint8_t access_width = riscv_mem_access_width (hart , src , len );
577581 const uint8_t access_length = 1U << access_width ;
578582
579- /* RV32I opcodes: extract ptr32 from data1, load word/half/byte, store back to data0 */
580- static const uint32_t progbuf_read32 [5 ] = {
581- 0x38000513U , // li a0, 0x380
582- 0x00452583U , // lw a1, 4(a0)
583- 0x0005a583U , // lw a1, 0(a1)
584- 0x00b52023U , // sw a1, 0(a0)
585- 0x00100073U
583+ /* RV32I opcodes: load word/half/byte from address A0 into A0 (clobber) */
584+ static const uint32_t progbuf_read32 [1 ] = {
585+ 0x00052503U , // lw a0, 0(a0)
586586 };
587- static const uint32_t progbuf_read16 [5 ] = {
588- 0x38000513U , // li a0, 0x380
589- 0x00452583U , // lw a1, 4(a0)
590- 0x00059583U , // lh a1, 0(a1)
591- 0x00b51023U , // sh a1, 0(a0)
592- 0x00100073U
587+ static const uint32_t progbuf_read16 [1 ] = {
588+ 0x00051503U , // lh a0, 0(a0)
593589 };
594- static const uint32_t progbuf_read8 [5 ] = {
595- 0x38000513U , // li a0, 0x380
596- 0x00452583U , // lw a1, 4(a0)
597- 0x00058583U , // lb a1, 0(a1)
598- 0x00b50023U , // sb a1, 0(a0)
599- 0x00100073U
590+ static const uint32_t progbuf_read8 [1 ] = {
591+ 0x00050503U , // lb a0, 0(a0)
600592 };
601593 const uint32_t * progbuf_read = progbuf_read32 ;
602594 switch (access_width ) {
@@ -612,35 +604,62 @@ static void riscv32_progbuf_mem_read(
612604 default :
613605 return ;
614606 }
607+ #if 0
608+ /* assume ptr is in A0, load word/half/byte to A1 (clobber), postincrement A0 */
609+ static const uint32_t progbuf_read32_autoexec [2 ] = {
610+ 0x00052583U , // lw a1, 0(a0)
611+ 0x00450513U , // addi a0, a0, 4
612+ }
613+ DEBUG_TARGET ("%s: 0x%08x+%lu width %u\n" , __func__ , src , len , access_width );
614+ #endif
615615 /* Fill the program buffer */
616- for (int i = 0 ; i < 5 ; i ++ ) {
617- if (!riscv_dm_write (hart -> dbg_module , RV_DM_PROGBUF_BASE + i , progbuf_read [i ]))
616+ if (!riscv_dm_write (hart -> dbg_module , RV_DM_PROGBUF_BASE , progbuf_read [0 ]))
617+ return ;
618+ /* Append literal ebreak (if impebreak is not reached) */
619+ if (hart -> progbuf_size > 1 ) {
620+ if (!riscv_dm_write (hart -> dbg_module , RV_DM_PROGBUF_BASE + 1 , RV_EBREAK ))
618621 return ;
619622 }
620623
621624 uint32_t a0_save = 0 ;
622- uint32_t a1_save = 0 ;
623- riscv_csr_read (hart , RV_GPR_BASE + 10 , & a0_save );
624- riscv_csr_read (hart , RV_GPR_BASE + 11 , & a1_save );
625+ // uint32_t a1_save = 0;
626+ riscv_csr_read (hart , RV_GPR_A0 , & a0_save );
627+ // riscv_csr_read(hart, RV_GPR_A0 + 11, &a1_save);
625628
626629 uint8_t * const data = (uint8_t * )dest ;
627630 for (size_t offset = 0 ; offset < len ; offset += access_length ) {
628- /* Write the address to read to arg1 */
629- if (!riscv_dm_write (hart -> dbg_module , RV_DM_DATA1 , src + offset ))
631+ /* Write the source address to DATA0 */
632+ if (!riscv_dm_write (hart -> dbg_module , RV_DM_DATA0 , src + offset ))
630633 return ;
631- /* Execute progbuf: postexec only, no reg transfer */
632- if (!riscv_dm_write (hart -> dbg_module , RV_DM_ABST_COMMAND , RV_ABST_POSTEXEC ) ||
633- !riscv_command_wait_complete (hart ))
634+ /* Copy the source address from DATA0 to GPR A0 and launch the progbuf postexec */
635+ const uint32_t abstract_command1 = RV_DM_ABST_CMD_ACCESS_REG | RV_ABST_WRITE | RV_REG_XFER | RV_ABST_POSTEXEC |
636+ RV_REG_ACCESS_32_BIT | RV_GPR_A0 ;
637+ bool result = riscv_dm_write (hart -> dbg_module , RV_DM_ABST_COMMAND , abstract_command1 );
638+ /* Wait for both the register write and progbuf execution to complete */
639+ result &= riscv_command_wait_complete (hart );
640+ if (!result )
634641 return ;
635- /* Extract back the data from arg0 */
642+ #if 1
643+ /* Copy the read value from GPR A0 to DATA0 */
644+ const uint32_t abstract_command2 =
645+ RV_DM_ABST_CMD_ACCESS_REG | RV_ABST_READ | RV_REG_XFER | RV_REG_ACCESS_32_BIT | RV_GPR_A0 ;
646+ result = riscv_dm_write (hart -> dbg_module , RV_DM_ABST_COMMAND , abstract_command2 );
647+ result &= riscv_command_wait_complete (hart );
648+ if (!result )
649+ return ;
650+ /* Extract the read value from DATA0 */
636651 uint32_t value = 0 ;
637652 if (!riscv_dm_read (hart -> dbg_module , RV_DM_DATA0 , & value ))
638653 return ;
654+ #else
655+ uint32_t value = 0 ;
656+ riscv_csr_read (hart , RV_GPR_A0 , & value );
657+ #endif
639658 riscv32_unpack_data (data + offset , value , access_width );
640659 }
641660
642- riscv_csr_write (hart , RV_GPR_BASE + 10 , & a0_save );
643- riscv_csr_write (hart , RV_GPR_BASE + 11 , & a1_save );
661+ riscv_csr_write (hart , RV_GPR_A0 , & a0_save );
662+ // riscv_csr_write(hart, RV_GPR_A0 + 1 , &a1_save);
644663}
645664
646665static void riscv32_progbuf_mem_write (
@@ -649,27 +668,18 @@ static void riscv32_progbuf_mem_write(
649668 /* Figure out the maxmial width of access to perform, up to the bitness of the target */
650669 const uint8_t access_width = riscv_mem_access_width (hart , dest , len );
651670 const uint8_t access_length = 1U << access_width ;
652- /* RV32I opcodes: extract ptr32 from data1 and val from data0, store word/half/byte */
653- static const uint32_t progbuf_write32 [5 ] = {
654- 0x38000513U , // li a0, 0x380
655- 0x00452583U , // lw a1, 4(a0)
656- 0x00052603U , // lw a2, 0(a0)
657- 0x00c5a023U , // sw a2, 0(a1)
658- 0x00100073U
671+ /* RV32I opcodes: store word/half/byte in a1 into address pointed-by a0 */
672+ static const uint32_t progbuf_write32 [] = {
673+ 0x00b52023U , // sw a1, 0(a0)
674+ 0x00450513U , // addi a0, a0, 4
659675 };
660- static const uint32_t progbuf_write16 [5 ] = {
661- 0x38000513U , // li a0, 0x380
662- 0x00452583U , // lw a1, 4(a0)
663- 0x00051603U , // lh a2, 0(a0)
664- 0x00c59023U , // sh a2, 0(a1)
665- 0x00100073U
676+ static const uint32_t progbuf_write16 [] = {
677+ 0x00b51023U , // sh a1, 0(a0)
678+ 0x00450513U , // addi a0, a0, 4
666679 };
667- static const uint32_t progbuf_write8 [5 ] = {
668- 0x38000513U , // li a0, 0x380
669- 0x00452583U , // lw a1, 4(a0)
670- 0x00050603U , // lb a2, 0(a0)
671- 0x00c58023U , // sb a2, 0(a1)
672- 0x00100073U
680+ static const uint32_t progbuf_write8 [] = {
681+ 0x00b50023U , // sb a1, 0(a0)
682+ 0x00450513U , // addi a0, a0, 4
673683 };
674684 const uint32_t * progbuf_write = progbuf_write32 ;
675685 switch (access_width ) {
@@ -686,36 +696,49 @@ static void riscv32_progbuf_mem_write(
686696 return ;
687697 }
688698 /* Fill the program buffer */
689- for (int i = 0 ; i < 5 ; i ++ ) {
690- if (!riscv_dm_write (hart -> dbg_module , RV_DM_PROGBUF_BASE + i , progbuf_write [i ]))
699+ if (!riscv_dm_write (hart -> dbg_module , RV_DM_PROGBUF_BASE , progbuf_write [0 ]))
700+ return ;
701+ /* Append literal ebreak (if impebreak is not reached) */
702+ if (hart -> progbuf_size > 1 ) {
703+ if (!riscv_dm_write (hart -> dbg_module , RV_DM_PROGBUF_BASE + 1 , RV_EBREAK ))
691704 return ;
692705 }
693706
694707 uint32_t a0_save = 0 ;
695708 uint32_t a1_save = 0 ;
696- uint32_t a2_save = 0 ;
697- riscv_csr_read (hart , RV_GPR_BASE + 10 , & a0_save );
698- riscv_csr_read (hart , RV_GPR_BASE + 11 , & a1_save );
699- riscv_csr_read (hart , RV_GPR_BASE + 12 , & a2_save );
709+ riscv_csr_read (hart , RV_GPR_A0 , & a0_save );
710+ riscv_csr_read (hart , RV_GPR_A0 + 1 , & a1_save );
700711
701712 const uint8_t * const data = (const uint8_t * )src ;
702713 for (size_t offset = 0 ; offset < len ; offset += access_length ) {
703- /* Write the address to write to arg1 */
704- if (!riscv_dm_write (hart -> dbg_module , RV_DM_DATA1 , dest + offset ))
714+ /* Copy the destination address from DATA0 to GPR A0 */
715+ if (!riscv_dm_write (hart -> dbg_module , RV_DM_DATA0 , dest + offset ))
705716 return ;
706- /* Pack the data to write into arg0 */
717+ /* Copy the source address from DATA0 to GPR A0 */
718+ const uint32_t abstract_command1 =
719+ RV_DM_ABST_CMD_ACCESS_REG | RV_ABST_WRITE | RV_REG_XFER | RV_REG_ACCESS_32_BIT | RV_GPR_A0 ;
720+ bool result = riscv_dm_write (hart -> dbg_module , RV_DM_ABST_COMMAND , abstract_command1 );
721+ result &= riscv_command_wait_complete (hart );
722+ if (!result )
723+ return ;
724+ //riscv_csr_write(hart, RV_GPR_A0, dest + offset);
725+
726+ /* Pack the data to write into GPR A1 */
707727 uint32_t value = riscv32_pack_data (data + offset , access_width );
708728 if (!riscv_dm_write (hart -> dbg_module , RV_DM_DATA0 , value ))
709729 return ;
710- /* Execute progbuf: postexec only, no reg transfer */
711- if (!riscv_dm_write (hart -> dbg_module , RV_DM_ABST_COMMAND , RV_ABST_POSTEXEC ) ||
712- !riscv_command_wait_complete (hart ))
730+ /* Copy the write value from DATA0 to GPR A1 and launch the progbuf postexec */
731+ const uint32_t abstract_command2 = RV_DM_ABST_CMD_ACCESS_REG | RV_ABST_WRITE | RV_REG_XFER | RV_ABST_POSTEXEC |
732+ RV_REG_ACCESS_32_BIT | (RV_GPR_A0 + 1 );
733+ result = riscv_dm_write (hart -> dbg_module , RV_DM_ABST_COMMAND , abstract_command2 );
734+ result &= riscv_command_wait_complete (hart );
735+ if (!result )
713736 return ;
737+ //riscv_csr_write(hart, RV_GPR_A1, value);
714738 }
715739
716- riscv_csr_write (hart , RV_GPR_BASE + 10 , & a0_save );
717- riscv_csr_write (hart , RV_GPR_BASE + 11 , & a1_save );
718- riscv_csr_write (hart , RV_GPR_BASE + 12 , & a2_save );
740+ riscv_csr_write (hart , RV_GPR_A0 , & a0_save );
741+ riscv_csr_write (hart , RV_GPR_A0 + 1 , & a1_save );
719742}
720743
721744void riscv32_mem_read (target_s * const target , void * const dest , const target_addr64_t src , const size_t len )
0 commit comments