Debugging multiple hardware harts with GDB

1,570 views
Skip to first unread message

raghu ram

unread,
Jan 4, 2017, 12:35:05 AM1/4/17
to RISC-V Debug Group

Hi All,

   In spec, it is mentioned like it supports upto 1024 harts and at anytime we can debug only one hart.
   My question is, if I have 4 cores and want to debug each hart through GDB, do i have to open 4 GDB's and connect them through same OPENOCD-JTAG interface or use only single GDB and switch back and forth between harts.

Thanks & Regards,
Ram

Michael Chapman

unread,
Jan 4, 2017, 3:51:19 AM1/4/17
to de...@groups.riscv.org

We use openOCD + GDB for debugging multicore systems.

For SMP configurations, we have one GDB which sees a thread/process for each core. The cores can be only slightly different. I.e. they must be the same base instruction set, but things such as coprocessors can be different.

For non SMP configurations, we have a GDB per core (and the memory maps can be different for each core, so memory has to be read/written using the context of the right core). The cores can be very different - even different architectures from different manufacturers.

In both cases, the same openOCD and same JTAG interface is used.

In both cases the complications come from shared memory - e.g. a breakpoint which is placed in memory for one core actually causes a different core to stop. This can be avoided with HW breakpoints, and also by a software workaround in openOCD (just resume the "wrong" core - which involves stopping/holding all the other cores while the "wrong" core is stepped over the break point and the break point written back to memory).

Regards,
Mike
--
You received this message because you are subscribed to the Google Groups "RISC-V Debug Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to debug+un...@groups.riscv.org.
To post to this group, send email to de...@groups.riscv.org.
Visit this group at https://groups.google.com/a/groups.riscv.org/group/debug/.
To view this discussion on the web visit https://groups.google.com/a/groups.riscv.org/d/msgid/debug/57e19da7-ac63-4491-ae33-5698c6623211%40groups.riscv.org.

raghu ram

unread,
Jan 4, 2017, 12:01:51 PM1/4/17
to RISC-V Debug Group
Hi Mike,
  
    Thanks for the reply. Sorry for extending my doubt. I just want to be clear without assumptions.
    If we use single OpenOCD+JTAG interface for debugging multicores, then how the user communicates with cores from GDB.
    For example,if we have 2 different programs running on 2 separate risc-v cores and if we open 2 GDB's and load the programs.
    In this case, how the GDB identifies on which hart the current program is running or will this connection be done in OpenOCD.
    Please let us know if you have any open source links for this type of use case.
    
Regards,
Ram

Michael Chapman

unread,
Jan 4, 2017, 4:34:01 PM1/4/17
to de...@groups.riscv.org

In the case of two separate cores (whatever they might be - they do not even have to be the same), then the two GDBs will connect to two different TCP/IP ports on openOCD (sequential, by default 3333 and 3334)

No further identification is done. The set up for openOCD sets up how openOCD will find and communicate with each core.

Each GDB has its core and is totally oblivious of the other GDB (which can be a for a different architecture and may well be running on a different desktop machine - it is easier to have a screen and keyboard per debugger!).

Here is an example set up for this case two non RISC-V cpu's with two separate debuggers. Note that almost all the configuration is actually provided by this configuration file (although most just sets the values to default values anyway). No configuration information is read from the target itself. In this particular case the debug logic is shared, but the JTAG data register has a field which identifies which core is being targeted.

This is what is going on with the configuration lines
cpu1 configure -dr-cpu-id 0
and
cpu2 configure -dr-cpu-id 1

#
# Evaluation kit on Digilent Spartan3 1000K board
# with two cpus with no RTOS
#

# Set the instruction set.
#
# ISA must be set to one of
#    apsv1  (all v1 cores such as aps1, aps3r, aps5, fps6 etc)
#    apsv2  (all v2 cores such as aps23, aps25, fps26, fps29 etc)
#    aps3cd (aps3cd core)
#
# By default we use apsv1
#

if { [info exists ISA] } {
} else {
  set ISA apsv1
}

transport select jtag

jtag newtap eval sflash -irlen 8 -expected-id 0x05046093
jtag newtap eval fpga   -irlen 6 -expected-id 0x11428093

target create cpu1 cortus -chain-position eval.fpga -coreid 0

# This has to be defined before we do 'init'
# The parameters are:-
#    the name of the driver:  test
#    start address:           0x80000000
#    size:                    0x40000
#    module width in bytes:   4
#    bus width in bytes:      4
#    name of target to use to program
#    (from target command):   cpu1
# For a SMP configuration we could use either
# cpu to do the actual programming operation
#flash bank flash test 0x80000000 0x40000 4 4 cpu1

# No RTOS
cpu1 configure -rtos none

# default value is apsv1
cpu1 configure -isa $ISA
puts "Set ISA to $ISA"

# Enable the debugger to see the mac registers
#cpu configure -has-mac 1

# default value is 0x02
cpu1 configure -ir-debug-opcode 0x02

# default value is same as coreid
cpu1 configure -dr-cpu-id 0

# default value is 0x50000000 + coreid * 0x100
cpu1 configure -hw-brkpt-box-ad 0x50000000

# default value is 3
cpu1 configure -nr-hw-brkpts 3

# default value is 0x20 + coreid * 0x48
cpu1 configure -dbg-info-ad 0x20

# default value is 0 (false)
cpu1 configure -word-only-writes 0

# Allow 8 tck cycles after write operation for operation to
# complete before starting new one
cpu1 configure -memaccess-tck 8

target create cpu2 cortus -chain-position eval.fpga -coreid 1

# Enable this if cpus are working in SMP mode (only one GDB)
# If not enabled we will have two GDBs on ports 3333 and 3334
#target smp cpu1 cpu2

# No RTOS
cpu2 configure -rtos none

# default value is apsv1
cpu2 configure -isa $ISA

# default value is 0x02
cpu2 configure -ir-debug-opcode 0x02

# default value is same as coreid
cpu2 configure -dr-cpu-id 1

# default value is 0x50000000 + coreid * 0x100
cpu2 configure -hw-brkpt-box-ad 0x50000100

# default value is 3
cpu2 configure -nr-hw-brkpts 3

# default value is 0x20 + coreid * 0x48
cpu2 configure -dbg-info-ad 0x68

# default value is 0 (false)
cpu2 configure -word-only-writes 0

# Allow 8 tck cycles after write operation for operation to
# complete before starting new one
cpu2 configure -memaccess-tck 8

gdb_target_description enable
gdb_flash_program enable

cpu1 configure -event gdb-attach {
      echo "Gdb has connected"
      # Reset and halt the board on attach
      # alternatively just halt without resetting
      reset halt
      echo "Processor has been reset and is halted"
}
cpu1 configure -event gdb-detach {
      echo "Gdb has disconnected"
      shutdown
}
cpu1 configure -event gdb-flash-erase-start {
      echo "Erasing flash...."
}
cpu1 configure -event gdb-flash-erase-end {
      echo "Finished erasing flash."
}
cpu1 configure -event gdb-flash-write-start {
      echo "Programming flash...."
}
cpu1 configure -event gdb-flash-write-end {
      echo "Finished programming flash."
}
cpu2 configure -event gdb-attach {
      echo "Gdb has connected"
      # Reset and halt the board on attach
      # alternatively just halt without resetting
      reset halt
      echo "Processor has been reset and is halted"
}
cpu2 configure -event gdb-detach {
      echo "Gdb has disconnected"
      shutdown
}

init
reset halt
echo "Target ready..."

Reply all
Reply to author
Forward
0 new messages