Posts by fsiegle

    Hi Evan,

    For now, I did the following (which feels a bit hacked but seems to work):

    • After memory write access: Executing a fence.i and fence instruction. In my implementation, fence.i invalidates the instruction cache and fence flushes the data cache. This is mainly required to ensure that software breakpoints are visible to the CPU.
    • Before memory read access: Executing a fence instruction to ensure that the debugger reads fresh data from memory when looking at memory content. I added a check to see if the CPU is halted or not because it seems the hook is also called when doing background memory reads using the SBA.

    Hello,

    I have a J-Link EDU Mini, which I believe should be capable of reaching a maximum JTAG speed of 4 MHz.

    Connecting to J-Link via USB...O.K.
    Firmware: J-Link EDU Mini V1 compiled Feb 20 2025 16:27:02
    Hardware version: V1.00
    J-Link uptime (since boot): 0d 06h 07m 14s
    S/N: 801055125
    License(s): FlashBP, GDB
    USB speed mode: Full speed (12 MBit/s)
    VTref=3.299V

    Connecting at 2 MHz works fine but fails at 4 MHz.

    I took two screenshots in my logic analyzer and it is clearly visible that the duty cycle gets worse with higher frequency (it looks ~50/50 at lower frequencies such as 400 kHz). In addition, TCK for 4 MHz setting measures as 3.33 MHz.

    I just wanted to check if this is expected behavior.

    Many thanks for your help,
    Felix

    Hello,

    I'm working on a debug unit for a custom RISC-V CPU and would like to get it working with the SEGGER J-Link debug probe and tools. Currently, the debug unit works fine with OpenOCD + GDB. Also with JLinkExe, I can successfully connect, downloading files, halt the CPU, and step through code. Setting breakpoints and more complicated operations don't work or are buggy and it appears that the reason might be the fact that the data cache is not flushed and that the instruction cache is not invalidated after memory writes. I know that there is no standardized way of doing this, e.g., OpenOCD uses a combination of fence and fence.i instructions.

    I'm just curious how the SEGGER debugger is handling caches in general and how I could add the flush/invalidation myself. This must be quite a common problem for other RISC-V CPUs as well, so maybe there is an elegant way to handle this.

    Thank you!