Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

I get an error when calling the dm_write befor init #1180

Open
Alan-19950616 opened this issue Dec 3, 2024 · 17 comments
Open

I get an error when calling the dm_write befor init #1180

Alan-19950616 opened this issue Dec 3, 2024 · 17 comments

Comments

@Alan-19950616
Copy link

openocd.cfg

......
riscv set_mem_access sysbus
riscv dm_write 0x38 0x40000
riscv dm_write 0x39 0x80000000
riscv dm_write 0x3c 0x1234

init
......

The error log

Error: [riscv0.cpu] dmi_write is not implemented.
Error: [riscv0.cpu] Unsupported DTM version: -1
Error: [riscv0.cpu] Could not identify target type.
@en-sc
Copy link
Collaborator

en-sc commented Dec 3, 2024

@Alan-19950616, to access Debug Module Interface one needs to know it's version first (dtmcs.version) and the length of DMI address (dtmcs.abits). dtmcs is read during target examination (part of init). This is why you observe these error messages.

@Alan-19950616
Copy link
Author

@en-sc The CORE that is currently being debugged needs to be configured with the soc component using sysbus before it can be halted. how should this be handled at the moment?

@aap-sc
Copy link
Collaborator

aap-sc commented Dec 4, 2024

@Alan-19950616

The CORE that is currently being debugged needs to be configured with the soc component using sysbus before it can be halted

See here: #1172 and here #1038

@Alan-19950616
Copy link
Author

@aap-sc I was using dm_write to implement this function, after updating the code I realized that it doesn't work like that anymore, if you can confirm that all subsequent openocd will be modified in this direction, I will change to irscan/drscan to implement it!

By the way, in that case do commands like dm_write no longer apply “.mode = COMMAND_ANY”
https://github.com/riscv-collab/riscv-openocd/blob/riscv/src/target/riscv/riscv.c#L5437

@aap-sc
Copy link
Collaborator

aap-sc commented Dec 5, 2024

@Alan-19950616

if you can confirm that all subsequent openocd will be modified in this direction,

Hm...

For now we'd better to stick with irscan/drscan. Currently, reply by @en-sc provides a reason for that: #1180 (comment)

That being said I'd like to get some additional clarification from @en-sc first.

@en-sc I have a theoretical question, though. Do we really require to perform an invasive examine on a targets to figure out DM properties and relevant topology? I mean can we implement some command to figure out only DM properties without halting/resuming the target (we could mark targets as -defer-examine to avoid a full-blown examination procedure)?

By the way, in that case do commands like dm_write no longer apply “.mode = COMMAND_ANY”

yep. Currently this looks like a bug.

@en-sc
Copy link
Collaborator

en-sc commented Dec 9, 2024

Do we really require to perform an invasive examine on a targets to figure out DM properties and relevant topology?

No. Examining the DM can be done without affecting harts.

I mean can we implement some command to figure out only DM properties without halting/resuming the target (we could mark targets as -defer-examine to avoid a full-blown examination procedure)?

Yes, this is achievable, but I'd first prefer to better expose Debug Module. To be able to configure anything related to the DM we need to first be able to configure at least the Debug Transport Module's version.

I'd prefer if there were an explicit DM configuration and target-DM assignment, similar to how it's done for ARM DAPs.

@Alan-19950616
Copy link
Author

@en-sc @aap-sc

So you guys still recommend the irscan/drscan command?

@aap-sc
Copy link
Collaborator

aap-sc commented Dec 11, 2024

So you guys still recommend the irscan/drscan command?

Right now - yes. Looks like (according to answer from @en-sc) access to DM could be implemented in future - but this requires additional changes and may take some time

@Alan-19950616
Copy link
Author

@aap-sc
I tested based on the riscv branch and found that neither irscan/drscan can be used before init;
is there any other way I can do system configuration before init?

Error: The 'irscan' command must be used after 'init'.
.\SoC\ns_core0\Board\fpga_eval\openocd_ns_core0_all.cfg:54: Error: 
Traceback (most recent call last):
  File ".\SoC\ns_core0\Board\fpga_eval\openocd_ns_core0_all.cfg", line 54, in script
    irscan riscv0.cpu
Error: [riscv0.cpu] Unsupported DTM version: -1
Error: [riscv0.cpu] Could not identify target type.
Error: [riscv1.cpu] Unsupported DTM version: -1
Error: [riscv1.cpu] Could not identify target type.
Error: The 'drscan' command must be used after 'init'.
.\SoC\ns_core0\Board\fpga_eval\openocd_ns_core0_all.cfg:55: Error:
Traceback (most recent call last):
  File ".\SoC\ns_core0\Board\fpga_eval\openocd_ns_core0_all.cfg", line 55, in script
    drscan riscv0.cpu
Error: [riscv0.cpu] Unsupported DTM version: -1
Error: [riscv0.cpu] Could not identify target type.
Error: [riscv1.cpu] Unsupported DTM version: -1
Error: [riscv1.cpu] Could not identify target type.

@en-sc
Copy link
Collaborator

en-sc commented Feb 17, 2025

@Alan-19950616, you are not able to communicate with a tap before it is initialized during jtag_init as part of init. In general, any communication is done only after the init starts.

You can do something like:

<target name> configure -event examine-start {irscan [[target current] cget -chain-position] 0x11; <other scans>}'

@aap-sc
Copy link
Collaborator

aap-sc commented Feb 17, 2025

@Alan-19950616 another alternative (to the suggestion from @en-sc ) would be to either:

Option 1: do not create targets at all. That is you can just define taps and that's it. This approach works - we use in production.
Option 2: Use -defer-examine parameter when creating your targets. I personally haven't tested this, but from the documentation I conclude that this should work to.

@Alan-19950616
Copy link
Author

@en-sc I tried registering the explan-start callback function and it didn't actually write to memory;I'll try it again the way @aap-sc said it

It's worth noting that the 0x1c000000 address is normal to read and write via GDB

openocd.cfg

proc sysbus_write_u32 {target address data} {
  irscan $target 0x38
  drscan $target 32 0x50000
  irscan $target 0x39
  drscan $target 32 $address
  irscan $target 0x3c
  drscan $target 32 $data
  for {set i 0} {$i < 100} {set i [expr {$i + 1}]} {
    irscan $target 0x38
    if {([drscan $target 32 0x00] & 0x200000) == 0} {
      irscan $target 0x38
      drscan $target 32 0x50000
      irscan $target 0x39
      drscan $target 32 $address
      irscan $target 0x3c
      return [drscan $target 32 0x00]
    }
  }
  return -code 1 "Timed out"
}

$_TARGETNAME0 configure -event examine-start {
  # system bus write 0x1c000000 0x12345678
  set read_value [sysbus_write_u32 [[target current] cget -chain-position] 0x1c000000 0x12345678]
  puts "Read value is $read_value"
}

init

run log

Info : clock speed 1000 kHz
Info : JTAG tap: riscv0.cpu tap/device found: 0x10900a6d (mfg: 0x536 (Nuclei System Technology Co Ltd), part: 0x0900, ver: 0x1)
Read value is 00000000
Info : coreid=0, nuclei debug map reg 00: 0x10030, 16: 0x0, 32: 0x10040
Info : [riscv0.cpu] datacount=4 progbufsize=8
Info : [riscv0.cpu] Examined RISC-V core
Info : [riscv0.cpu]  XLEN=32, misa=0x40001105
[riscv0.cpu] Target successfully examined.
Info : [riscv0.cpu] Examination succeed
Info : [riscv0.cpu] starting gdb server on 3333
Info : Listening on port 3333 for gdb connections
riscv0.cpu halted due to undefined.
Info : Valid NUSPI on device Nuclei SoC SPI Flash at address 0x20000000 with spictrl regbase at 0x10180000
Info : Nuclei SPI controller version 0x00010207
Info : Found flash device 'win w25q256fv/jv' (ID 0x001940ef)
cleared protection for sectors 0 through 511 on flash bank 0
Info : Listening on port 6666 for tcl connections
Info : Listening on port 4444 for telnet connections

@en-sc en-sc closed this as completed Feb 18, 2025
@en-sc
Copy link
Collaborator

en-sc commented Feb 18, 2025

Sorry, misclick

@en-sc en-sc reopened this Feb 18, 2025
@en-sc
Copy link
Collaborator

en-sc commented Feb 18, 2025

@Alan-19950616, seems like the implementation of sysbus_write_u32() is incorrect. AFAIU there is a confusion between DMI address an JTAG IR.
In sysbus_write_u32() irscan is used to write a DMI address. This is not correct.
irscans should be used to select the dmi IR.
Then drscans should be used to access DMI registers.
E.g. to read sbcs register on a DM with base address 0x0 (DMI address 0x38):

irscan $tap_name 0x11 # Select DMI IR
drscan 2 1 32 0 $abits 0x38 # dmi.op = 1 (read) (2-bits wide), dmi.data = 0 (irrelevant on read) (32-bits wide), dmi.address = 0x38 (sbcs address) ($abits wide).

@en-sc
Copy link
Collaborator

en-sc commented Feb 18, 2025

On following DMI operations irscan can be omitted.
Also I'd suggest wrapping JTAG communications into

poll disable
...
poll enable

So that poll does not interrupt the script and mess up JTAG state (e.g. by selecting another IR).

@Alan-19950616
Copy link
Author

@Alan-19950616 another alternative (to the suggestion from @en-sc ) would be to either:

Option 1: do not create targets at all. That is you can just define taps and that's it. This approach works - we use in production. Option 2: Use -defer-examine parameter when creating your targets. I personally haven't tested this, but from the documentation I conclude that this should work to.

Option 1 Not well suited to current application scenarios.

Option2 Use -defer-examine parameter solved my problem nicely, thanks for providing ideas! @aap-sc

@Alan-19950616
Copy link
Author

@Alan-19950616, seems like the implementation of sysbus_write_u32() is incorrect. AFAIU there is a confusion between DMI address an JTAG IR. In sysbus_write_u32() irscan is used to write a DMI address. This is not correct. irscans should be used to select the dmi IR. Then drscans should be used to access DMI registers. E.g. to read sbcs register on a DM with base address 0x0 (DMI address 0x38):

irscan $tap_name 0x11 # Select DMI IR
drscan 2 1 32 0 $abits 0x38 # dmi.op = 1 (read) (2-bits wide), dmi.data = 0 (irrelevant on read) (32-bits wide), dmi.address = 0x38 (sbcs address) ($abits wide).

@en-sc I misunderstood before, I re-ran the test and the data was not actually written to the hardware

proc sysbus_write_u32 {target address data} {
  # irscan select dtmcs(0x10), get abits[4:9] from dtmcs
  irscan $target 0x10
  set dtmcs [drscan $target 32 0x00]
  set dtmcs_value [scan $dtmcs "%x"]
  set abits [expr {($dtmcs_value >> 4) & 0x3F}]

  # irscan select dmi(0x11)
  irscan $target 0x11

  # sysbus access: set op[0:1]=2(1/read;2/write), set data[2:33], set address[34:33+abits]
  # # 0x38 = 0x50000
  # drscan $target 2 2
  # drscan $target 32 0x50000
  # drscan $target $abits 0x38
  # # 0x39 = $address
  # drscan $target 2 2
  # drscan $target 32 $address
  # drscan $target $abits 0x39
  # # 0x3c = $data
  # drscan $target 2 2
  # drscan $target 32 $data
  # drscan $target $abits 0x3c

  # abstract access: set op[0:1]=2(1/read;2/write), set data[2:33], set address[34:33+abits]
  # 0x05 = $address
  drscan $target 2 2
  drscan $target 32 $address
  drscan $target $abits 0x05
  # 0x04 = $data
  drscan $target 2 2
  drscan $target 32 $data
  drscan $target $abits 0x04
  # 0x17 = 0x2210000
  drscan $target 2 2
  drscan $target 32 0x2210000
  drscan $target $abits 0x17
}

$_TARGETNAME0_0 configure -event examine-start {
  poll disable
  # system bus write 0x1c000000 0x12345678
  sysbus_write_u32 $_TARGETNAME0_0 0x1c000000 0x12345678
  poll enable
}

init

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants