Next: , Previous: , Up: Top   [Contents][Index]

11 CPU Configuration

This chapter discusses how to set up GDB debug targets for CPUs. You can also access these targets without GDB (see Architecture and Core Commands, and Target State handling) and through various kinds of NAND and NOR flash commands. If you have multiple CPUs you can have multiple such targets.

We’ll start by looking at how to examine the targets you have, then look at how to add one more target and how to configure it.

11.1 Target List

All targets that have been set up are part of a list, where each member has a name. That name should normally be the same as the TAP name. You can display the list with the targets (plural!) command. This display often has only one CPU; here’s what it might look like with more than one:

    TargetName         Type       Endian TapName            State
--  ------------------ ---------- ------ ------------------ ------------
 0* at91rm9200.cpu     arm920t    little at91rm9200.cpu     running
 1  MyTarget           cortex_m   little         tap-disabled

One member of that list is the current target, which is implicitly referenced by many commands. It’s the one marked with a * near the target name. In particular, memory addresses often refer to the address space seen by that current target. Commands like mdw (memory display words) and flash erase_address (erase NOR flash blocks) are examples; and there are many more.

Several commands let you examine the list of targets:

Command: target current

Returns the name of the current target.

Command: target names

Lists the names of all current targets in the list.

foreach t [target names] {
    puts [format "Target: %s\n" $t]
Command: targets [name]

Note: the name of this command is plural. Other target command names are singular.

With no parameter, this command displays a table of all known targets in a user friendly form.

With a parameter, this command sets the current target to the given target with the given name; this is only relevant on boards which have more than one target.

11.2 Target CPU Types

Each target has a CPU type, as shown in the output of the targets command. You need to specify that type when calling target create. The CPU type indicates more than just the instruction set. It also indicates how that instruction set is implemented, what kind of debug support it integrates, whether it has an MMU (and if so, what kind), what core-specific commands may be available (see Architecture and Core Commands), and more.

It’s easy to see what target types are supported, since there’s a command to list them.

Command: target types

Lists all supported target types. At this writing, the supported CPU types are:

To avoid being confused by the variety of ARM based cores, remember this key point: ARM is a technology licencing company. (See: The CPU name used by OpenOCD will reflect the CPU design that was licenced, not a vendor brand which incorporates that design. Name prefixes like arm7, arm9, arm11, and cortex reflect design generations; while names like ARMv4, ARMv5, ARMv6, and ARMv7 reflect an architecture version implemented by a CPU design.

11.3 Target Configuration

Before creating a “target”, you must have added its TAP to the scan chain. When you’ve added that TAP, you will have a which is used to set up the CPU support. The chip-specific configuration file will normally configure its CPU(s) right after it adds all of the chip’s TAPs to the scan chain.

Although you can set up a target in one step, it’s often clearer if you use shorter commands and do it in two steps: create it, then configure optional parts. All operations on the target after it’s created will use a new command, created as part of target creation.

The two main things to configure after target creation are a work area, which usually has target-specific defaults even if the board setup code overrides them later; and event handlers (see Target Events), which tend to be much more board-specific. The key steps you use might look something like this

target create MyTarget cortex_m -chain-position mychip.cpu
$MyTarget configure -work-area-phys 0x08000 -work-area-size 8096
$MyTarget configure -event reset-deassert-pre { jtag_rclk 5 }
$MyTarget configure -event reset-init { myboard_reinit }

You should specify a working area if you can; typically it uses some on-chip SRAM. Such a working area can speed up many things, including bulk writes to target memory; flash operations like checking to see if memory needs to be erased; GDB memory checksumming; and more.

Warning: On more complex chips, the work area can become inaccessible when application code (such as an operating system) enables or disables the MMU. For example, the particular MMU context used to acess the virtual address will probably matter ... and that context might not have easy access to other addresses needed. At this writing, OpenOCD doesn’t have much MMU intelligence.

It’s often very useful to define a reset-init event handler. For systems that are normally used with a boot loader, common tasks include updating clocks and initializing memory controllers. That may be needed to let you write the boot loader into flash, in order to “de-brick” your board; or to load programs into external DDR memory without having run the boot loader.

Command: target create target_name type configparams...

This command creates a GDB debug target that refers to a specific JTAG tap. It enters that target into a list, and creates a new command (target_name) which is used for various purposes including additional configuration.

Command: $target_name configure configparams...

The options accepted by this command may also be specified as parameters to target create. Their values can later be queried one at a time by using the $target_name cget command.

Warning: changing some of these after setup is dangerous. For example, moving a target from one TAP to another; and changing its endianness.

11.4 Other $target_name Commands

The Tcl/Tk language has the concept of object commands, and OpenOCD adopts that same model for targets.

A good Tk example is a on screen button. Once a button is created a button has a name (a path in Tk terms) and that name is useable as a first class command. For example in Tk, one can create a button and later configure it like this:

# Create
button .foobar -background red -command { foo }
# Modify
.foobar configure -foreground blue
# Query
set x [.foobar cget -background]
# Report
puts [format "The button is %s" $x]

In OpenOCD’s terms, the “target” is an object just like a Tcl/Tk button, and its object commands are invoked the same way.

str912.cpu    mww 0x1234 0x42
omap3530.cpu  mww 0x5555 123

The commands supported by OpenOCD target objects are:

Command: $target_name arp_examine allow-defer
Command: $target_name arp_halt
Command: $target_name arp_poll
Command: $target_name arp_reset
Command: $target_name arp_waitstate

Internal OpenOCD scripts (most notably startup.tcl) use these to deal with specific reset cases. They are not otherwise documented here.

Command: $target_name array2mem arrayname width address count
Command: $target_name mem2array arrayname width address count

These provide an efficient script-oriented interface to memory. The array2mem primitive writes bytes, halfwords, or words; while mem2array reads them. In both cases, the TCL side uses an array, and the target side uses raw memory.

The efficiency comes from enabling the use of bulk JTAG data transfer operations. The script orientation comes from working with data values that are packaged for use by TCL scripts; mdw type primitives only print data they retrieve, and neither store nor return those values.

Command: $target_name cget queryparm

Each configuration parameter accepted by $target_name configure can be individually queried, to return its current value. The queryparm is a parameter name accepted by that command, such as -work-area-phys. There are a few special cases:

For example, if you wanted to summarize information about all the targets you might use something like this:

foreach name [target names] {
    set y [$name cget -endian]
    set z [$name cget -type]
    puts [format "Chip %d is %s, Endian: %s, type: %s" \
                 $x $name $y $z]
Command: $target_name curstate

Displays the current target state: debug-running, halted, reset, running, or unknown. (Also, see Event Polling.)

Command: $target_name eventlist

Displays a table listing all event handlers currently associated with this target. See Target Events.

Command: $target_name invoke-event event_name

Invokes the handler for the event named event_name. (This is primarily intended for use by OpenOCD framework code, for example by the reset code in startup.tcl.)

Command: $target_name mdw addr [count]
Command: $target_name mdh addr [count]
Command: $target_name mdb addr [count]

Display contents of address addr, as 32-bit words (mdw), 16-bit halfwords (mdh), or 8-bit bytes (mdb). If count is specified, displays that many units. (If you want to manipulate the data instead of displaying it, see the mem2array primitives.)

Command: $target_name mww addr word
Command: $target_name mwh addr halfword
Command: $target_name mwb addr byte

Writes the specified word (32 bits), halfword (16 bits), or byte (8-bit) pattern, at the specified address addr.

11.5 Target Events

At various times, certain things can happen, or you want them to happen. For example:

All of the above items can be addressed by target event handlers. These are set up by $target_name configure -event or target create ... -event.

The programmer’s model matches the -command option used in Tcl/Tk buttons and events. The two examples below act the same, but one creates and invokes a small procedure while the other inlines it.

proc my_attach_proc { } {
    echo "Reset..."
    reset halt
mychip.cpu configure -event gdb-attach my_attach_proc
mychip.cpu configure -event gdb-attach {
    echo "Reset..."
    # To make flash probe and gdb load to flash work
    # we need a reset init.
    reset init

The following target events are defined:

Next: , Previous: , Up: Top   [Contents][Index]