riscv-openocd icon indicating copy to clipboard operation
riscv-openocd copied to clipboard

read_memory_abstract uses data1 even when datacount == 1

Open allexoll opened this issue 4 years ago • 4 comments

when trying to debug a DM with only one abstract data register (data0), read_memory_abstract uses data1 (@05) even though it reads datacount to be 1 (only implementing data0, but implementing progbufsize=2) and does not signal an error.

Debug: 1883 10708 riscv-013.c:407 scan():  ->  progbufsize=2 datacount=1
Debug: 1884 10708 riscv-013.c:1495 register_read_direct(): {0} mstatus = 0x1808
Debug: 1885 10708 riscv.c:3193 riscv_get_register_on_hart(): {0} mstatus: 1808
Debug: 1886 10708 riscv.c:1414 riscv_mmu(): SATP/MMU ignored in Machine mode (mstatus=0x1808).
Debug: 1887 10708 riscv-013.c:2626 read_memory_abstract(): reading 16 words of 4 bytes from 0x80000300
Debug: 1888 10716 riscv-013.c:397 scan(): 66b w 80000300 @05 -> + 02000801 @16; 0i
Debug: 1889 10716 riscv-013.c:407 scan():  ->  progbufsize=2 datacount=1
Debug: 1890 10720 riscv-013.c:397 scan(): 66b - 00000000 @05 -> + 00000000 @05; 0i
Debug: 1891 10720 riscv-013.c:790 execute_abstract_command(): command=0x2280000
Debug: 1892 10724 riscv-013.c:397 scan(): 66b w 02280000 @17 -> + 00000000 @05; 0i

allexoll avatar Oct 15 '21 18:10 allexoll

same for write_memory_abstact:

Debug: 2162 11533 riscv-013.c:407 scan():  ->  progbufsize=2 datacount=1
Debug: 2163 11533 riscv-013.c:1495 register_read_direct(): {0} dcsr = 0x40000e43
Debug: 2164 11533 riscv.c:3193 riscv_get_register_on_hart(): {0} priv: 3
Debug: 2165 11533 riscv.c:3177 riscv_get_register_on_hart(): {0} mstatus: 1808 (cached)
Debug: 2166 11533 riscv.c:1414 riscv_mmu(): SATP/MMU ignored in Machine mode (mstatus=0x1808).
Debug: 2167 11533 riscv-013.c:2686 write_memory_abstract(): writing 1051 words of 4 bytes from 0x80000000
Debug: 2168 11537 riscv-013.c:397 scan(): 66b w 800000b7 @04 -> + 02000801 @16; 0i
Debug: 2169 11537 riscv-013.c:407 scan():  ->  progbufsize=2 datacount=1
Debug: 2170 11541 riscv-013.c:397 scan(): 66b - 00000000 @04 -> + 80000690 @04; 0i
Debug: 2171 11547 riscv-013.c:397 scan(): 66b w 80000000 @05 -> + 80000690 @04; 0i
Debug: 2172 11551 riscv-013.c:397 scan(): 66b - 00000000 @05 -> + 00000000 @05; 0i

allexoll avatar Oct 15 '21 18:10 allexoll

Hi @allexoll,

thank you for reporting this.

Correct, on a RV32 core, as in your case, at least two data registers are required to perform the abstract memory access. (So that both arg0=data, arg1=address can be stored.)

OpenOCD should honor the datacount. So we can fix the code by:

    1. Not attempting abstract memory access when the number of data registers in the debug module is clearly insufficient
    1. Adding error checks when accessing data registers (read_abstract_arg(), write_abstract_arg())

JanMatCodasip avatar Oct 18 '21 06:10 JanMatCodasip

I think the first option would make more sense, and not try to access data1 when datacount<2. either we should check it, or maybe disable memory access using abstract commands in that situation.

i'm not completely sure but i think that openocd was falling back to that because the progbufsize was too small (2, and impbreak = 0), which did not satisfy the progbufsize + impbreak >= 3. It would still be possible to do memory write with this: save x1, save x2, abstract memory write data to x1, abstract memory write address to x2, write sw x1, x2 to progbuf[0] and ebreak to progbuf[1] and restore x1/x2 at the end. That would make that datacount/progbufsize/impbreak work, even if it would be pretty slow.

If there is no intention of supporting that config, the second option would work.

allexoll avatar Oct 18 '21 09:10 allexoll

I think the first option would make more sense,

I would prefer implementing both the items i. and ii. I'll have time to submit the change within approx. a week.

i'm not completely sure but i think that openocd was falling back to that because the progbufsize was too small (2, and impbreak = 0), which did not satisfy the progbufsize + impbreak >= 3.

You're right, the current implementation of memory access via program buffer requires progbuf capacity of at least 3 items (or 2 in case of impebreak).

As you mention, it is possible to access memory with just progbufsize=1, at the cost of performance, it is however not implemented in OpenOCD at the moment. Functionality to riscv-openocd is being added "lazily" - as needed. Feel free to create your own pull request :)

JanMatCodasip avatar Oct 18 '21 10:10 JanMatCodasip