     [file gdb-cfg.texi not included]

This file documents the GNU debugger GDBN when used with OpenRISC 1000 processors.

This is the First Edition, of Debugging the OpenRISC 1000
GDBN for GDBN Version GDBVN.

Copyright (C) 2008 Embecosm Limited

Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 3 or any later version published by the Free Software Foundation; with the Front-Cover Texts being ``Debugging the OpenRISC 1000 with GDB by Jeremy Bennett'' and with the Back-Cover Texts being ``You are free to copy and modify this Manual.''

Debugging the OpenRISC 1000 with GDBN
*************************************

This file describes GDBN, the GNU symbolic debugger for use with the OpenRISC 1000 processor architecture.

This is the First Edition, for GDBN Version GDBVN.

Copyright (C) 2008 Embecosm Limited

Summary of GDBN with OpenRISC 1000
**********************************

GDBN is described well in its user manual, ``Debugging with GDB: The GNU Source-Level Debugger''.

This manual describes how to use GDBN to debug C programs cross compiled for and running on processors using the OpenRISC 1000 architecture. In general GDBN does not run on the actual target, but on a separate host processor. It communicates with the target via a custom remote protocol, which drives the JTAG interface on the OpenRISC 1000.

This is provided by adding a special target, ``jtag'' to GDBN, allowing the debugger to connect via the JTAG interface. See Connecting to the Target.

In addition the info command is extended to allow inspection of OpenRISC 1000 Special Purpose registers, and a new command ``spr'' is added to set the value of a Special Purpose Register. See OpenRISC 1000 Specific Commands.

All the normal GDB commands should work, although hardware watchpoints are not tested at present. The info registers command will show the 32 general purpose registers, while the info registers all command will add the program counter, supervision register and exception program counter register.

For those who like their debugging graphical, the gdbtui command  is available (typically as or32-uclinux-gdbtui). GDBN for OpenRISC 1000 can also be run under ddd as follows:

     ddd --debugger=or32-uclinux-gdb --gdb

Contributors to GDBN for the OpenRISC 1000
==========================================

The pantheon of contributors to GDB over the years is recorded in the main user manual, `Debugging with GDB: The GNU Source-Level Debugger''.

There is no official history of contributors to the OpenRISC 1000 version. However the current author believes the original GDB 5.0 and 5.3 ports were the work of:

  * Ivan Guzvinec and Johan Rydverg at OpenCores, who wrote the Binary File Descriptor library;

  * Alessandro Forin at Carnegie-Mellon University and Per Bothner at the University of Wisconsin who wrote the main GDB interface; and

  * Mark Mlinar at Cygnus Support and Chris Ziomkowski at ASICS.ws,who wrote the OpenRISC JTAG interface.

The port to GDBN GDBVN is the work of Jeremy Bennett of Embecosm Limited (jeremy.bennett@embecosm.com).

     Plea. If you know of anyone who has been omitted from this list, please email the current author, so the omission can be corrected, and credit given where it is due.

Connecting to an OpenRISC 1000 Target
*************************************

There are two ways to connect to an OpenRISC 1000 target with GDB.

 1. To hardware directly connected via a JP1 header linked to the parallel port.

 2. Via a TCP/IP socket to a machine which has the hardware connected, or is running the architectural simulator

Both are achieved via the GDB command

     target jtag

Direct connection via a JTAG JP1 Interface
==========================================

In this case the the device to which the JP1 header is connected must be specifed to the target jtag command. Typically that will be the parallel printer port, so the command would be:

     target jtag /dev/lp

Warning. The current author is not aware of anyone using the JP1 interface. As a result this code has not been tested in the port to GDBN version GDBVN. Modern hardware connections are usually via interfaces such as USB, for which the OpenRISC Remote Interface can be used (see Remote JTAG Connection).

Connection via the OpenRISC 1000 Remote JTAG Interface
======================================================

The more common mode of operation is through the OpenRISC 1000 Remote JTAG Interface. This communicates to the target through a TCP/IP socket. The target must then implement the client side of the interface to drive either physical hardware (for example through a USB/JTAG connector) or a simulation of the hardware (such as the OpenRISC Architectural Simulator).

Although referred to as the remote interface, the target may actually be on the same machine, just running in a separate process, with its own terminal window.

For example, to connect to the OpenRISC 1000 Architectural simulator, which is running on machine ``thomas'' and has been configured to talk to GDBN on port 50000, I could use the command:

     target jtag jtag://thomas:50000

The target machine is specified after the jtag:// and separated from the target port by a colon. If the architectural simulator was running on the same machine, just locahost would suffice as the machine name, thus:

     target jtag jtag://localhost:50000

Unfortunately there are now two different flavours of the JTAG interface used with OpenRISC 1000. The original version was created for use with the OpenRISC 1000 System-on-Chip, ORPSoC. A new (smaller and simpler) JTAG interface was developed by Igor Mohor in 2004, which is used on some designs.

The default behavior of GDBN is to use the original ORPSoC version of the interface for backwards compatibility. GDBN can use the Igor Mohor version by specifying for example:

     target jtag jtag_mohor://localhost:50000

This interface is only available with remote JTAG connections, since all modern interfaces are based on the remote connection. For completeness

     target jtag jtag_orpsoc://localhost:50000

is provided as a synonym for:

     target jtag jtag://localhost:50000

By default, establishing a connection does not reset the target. This allows debugging to resume a partially complete program on connection. If a reset is required, the keyworkd RESET (case insensitive) may be added at the end of the target command. For example:

     target jtag jtag://localhost:50000 reset

Warning. GDBN version GDBVN requires a patch to the architectural simulator. This should be available on the OpenCores website, or contact the author directly.

Warning. The OpenRISC remote JTAG interface is not particularly robust. In particular dropping and reconnecting sessions does not seem to work well. Eventually this interface will be replaced by the generic GDBN Remote Serial Interface.

Commands just for the OpenRISC 1000
***********************************

The OpenRISC 1000 has one particular feature that is difficult for GDBN. GDBN models target processors with a register bank and a block of memory. The internals of GDBN assume that there are not a huge number of registers in total.

The OpenRISC 1000 Special Purpose Registers (SPR) do not really fit well into this structure. There are too many of them (12 groups each with 2000+ entries so far, with up to 32 groups permitted) to be implemented as ordinary registers in GDBN. Think what this would mean for the command info
registers all. However they cannot be considered memory, since they do not reside in the main memory map.

The solution is to add two new commands to GDBN to see the value of a particular SPR and to set the value of a particular SPR.

 1. info spr is used to show the value of a SPR or group of SPRs.

 2. spr is used to set the value of an individual SPR.

Using the info spr Command
==========================

The value of an SPR is read by specifying either the unique name of the SPR, or the its group and index in that group. For example the Debug Reason Register (DRR, register 21 in group 6 (Debug)) can be read using any of the following commands:

     info spr DRR
     info spr debug DRR
     info spr debug 21
     info spr 6 DRR
     info spr 6 21

In each case the output will be:

     DEBUG.DRR = SPR6_21 = 0 (0x0)

It is also possible to inspect all the registers in a group. For example to look at all the Programmable Interrupt Controller registers (group 9), either of the following commands could be used:

     info spr PIC
     info spr 9

And the output would be:

     PIC.PICMR = SPR9_0 = 0 (0x9)
     PIC.PICSR = SPR9_2 = 0 (0x8)

Indicating that interrupts 0 and 4 are enabled and interrupt 4 is pending.

Using the spr Command
=====================

The value of an SPR is written by specifying the unique name of the SPR or its group and index in the same manner as for the info spr command. An additional argument specifies the value to be written. So for example the Programmable Interrupt Controller mask register could be changed to enable interrupts 5 and 3 only by any of the following commands.

     spr PICMR 0x24
     spr PIC PICMR 0x24
     spr PIC 0 0x24
     spr 9 PICMR 0x24
     spr 9 2 0x24

Small and Large Examples
************************

Two examples are given:

 1. A simple ``Hello World'' program (what else) to show the basics

 2. Linux 2.6.19 kernel, as an example of a large program.

Both use the OpenRISC 1000 architectural simulator, Or1ksim.

A ``Hello World'' program
=========================

This is the cannonical small program. Here is the main program and its two subprograms (added to demonstrate a meaningful backtrace).

     void level2() {
       simexit( 0 );
     }

     void level1() {
       level2();
     }

     main()
     {
       int  i;
       int  j;

       simputs( "Hello World!\n" );
       level1();
     }

It is linked with a program providing the utility functions simexit, simputc and simprints.

     void  simexit( int  rc )
     {
       __asm__ __volatile__ ( "\tl.nop\t%0" : : "K"( NOP_EXIT ));

     }	/* simexit() */

     void  simputc( int  c )
     {
       __asm__ __volatile__ ( "\tl.nop\t%0" : : "K"( NOP_PUTC ));

     }	/* simputc() */

     void  simputs( char *str )
     {
       int  i;

       for( i = 0; str[i] != '\0' ; i++ ) {
         simputc( (int)(str[i]) );
       }
     }	/* simputs() */

Finally, a small bootloader is needed, which will be placed at the OpenRISC reset vector location (0x100) to set up a stack and jump to the main program.

             .org    0x100           # The reset routine goes at 0x100
             .global _start
     _start:
             l.addi  r1,r0,0x7f00    # Set SP to value 0x7f00
             l.addi  r2,r1,0x0       # FP and SP are the same
             l.mfspr r3,r0,17        # Get SR value
             l.ori   r3,r3,0x10      # Set exception enable bit
             l.jal   _main           # Jump to main routine
             l.mtspr r0,r3,17        # Enable exceptions (DELAY SLOT)

             .org    0xFFC
             l.nop                   # Guarantee the exception vector space
                                     # does not have general purpose code

This is compiled and linked with the OpenRISC 1000 GNU toolchain. Note that the linking must specify the bootloader first and use the -Ttext 0x0 argument.

The Or1ksim architectural simulator is configured with memory starting at location 0x0. The debugging interface is enabled by using a debug section.

     section debug
       enabled         =          1
       gdb_enabled     =          1
       server_port     =      50000
     end

The architectural simulator is started in its own terminal window. If the configuration is in debug.cfg, then the command might be:

     or32-uclinux-sim -f debug.cfg
     Reading script file from 'debug.cfg'...
     Building automata... done, num uncovered: 0/213.
     Parsing operands data... done.
     JTAG Proxy server started on port 50000
     Resetting PIC.

Note that no program is specified - that will be loaded from GDBN.

In a separate window start up GDBN.

     or32-uclinux-gdb

A local copy of the symbol table is needed, specified with the file command.

     Building automata... done, num uncovered: 0/216.
     Parsing operands data... done.
     GNU gdb 6.8
     Copyright (C) 2008 Free Software Foundation, Inc.
     License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
     This is free software: you are free to change and redistribute it.
     There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
     and "show warranty" for details.
     This GDB was configured as "--host=i686-pc-linux-gnu --target=or32-uclinux".
     (gdb) file hello
     Reading symbols from /home/jeremy/svntrunk/GNU/gdb-6.8/progs_or32/hello...done.
     (gdb)

The connection to the target (the architectural simulator) is then established, using the port number given in the configuration file.

     (gdb) target jtag jtag://localhost:50000
     0x00000104 in _start ()
     (gdb)

The program of interest can now be loaded:

     (gdb) load hello
     Loading section .text, size 0x1290 lma 0x0
     Loading section .rodata, size 0xe lma 0x1290
     Start address 0x100, load size 4766
     Transfer rate: 38128 bits in <1 sec, 2383 bytes/write.
     (gdb)

The program does not immediately start running, since on opening the connection to the target, GDB stalls the processor via the JTAG interface.

All the GDB commands (including the SPR commands are available). For example

     (gdb) bt
     #0  0x00000104 in _start ()
     (gdb) info spr 0 17
     SYS.SR = SPR0_17 = 32769 (0x8001)
     (gdb)

The Supervision Register shows the target is in Supervisor Mode and that SPRs have User Mode read access.

Note. The supervision register is used to provide the value for the GDBN $ps processor status variable, so can also be accessed as:

     (gdb) print $ps
     $1 = 32769
     (gdb)

For this example set a breakpoint at the start of main and then run the program

     (gdb) break main
     Breakpoint 1 at 0x1264: file hello.c, line 41.
     (gdb) run
     Starting program: /home/jeremy/svntrunk/GNU/gdb-6.8/progs_or32/hello
     [Switching to process -1]

     Breakpoint 1, main () at hello.c:44
     41        simputs( "Hello World!\n" );
     (gdb)

Note. Since the connection is to the native code on the OpenRISC 1000 target, there is no concept of a process number. Thus process number -1 is used throughout.

It is now possible to step through the code:

     (gdb) step
     simputs (str=0x1290 "Hello World!\n") at utils.c:90
     90        for( i = 0; str[i] != '\0' ; i++ ) {
     (gdb) step
     91          simputc( (int)(str[i]) );
     (gdb) step
     58        __asm__ __volatile__ ( "\tl.nop\t%0" : : "K"( NOP_PUTC ));
     (gdb)

At this point a backtrace will show where the code has reached:

     (gdb) bt
     #0  simputc (c=72) at utils.c:58
     #1  0x000011cc in simputs (str=0x1290 "Hello World!\n") at utils.c:91
     #2  0x00001274 in main () at hello.c:41
     #3  0x00000118 in _start ()
     (gdb)

One more step completes the call to the character output routine. Inspecting the terminal running the Or1ksim simulation, shows the output appearing:

     JTAG Proxy server started on port 50000
     Resetting PIC.
     H

Let the program run to completion by giving GDBN the continue command:

     (gdb) cont
     Continuing.

     Program exited normally.
     (gdb)

With completion of the program, the terminal running Or1ksim shows its final output:

     Resetting PIC.
     Hello World!
     exit(0)
     @reset : cycles 0, insn #0
     @exit  : cycles 215892308, insn #215891696
      diff  : cycles 215892308, insn #215891696

When execution exits (by execution of a l.nop 1), the connection to the target is automatically broken.

However it is perfectly possible to re-establish a connection to the target, either in the current GDBN session or in a separate session.

If the session is new, the symbols will need to be reloaded with the file command. Re-establish the connection using the remote jtag command:

     (gdb) target jtag jtag://localhost:50000

     Program exited normally.
     (gdb)

The connection is re-established. Since the last instruction executed was l.nop 1, GDBN reports that the program executed normally.

To rerun the program, the program counter must be placed somewhere appropriate. The reset vector (0x100) is appropriate, and the program can then be rerun.

     (gdb) set $pc = 0x100
     (gdb) run
     Starting program: /home/jeremy/svntrunk/GNU/gdb-6.8/progs_or32/hello

     Program exited normally.
     (gdb)

Linux 2.6.19 Kernel Boot
========================

In this example, a Linux 2.6.19 Kernel is booted under control of GDB. The kernel should be built using the OpenRISC 1000 toolchain as described on the OpenCores website (www.opencores.org) or Embecosm Application Note #2 (www.embecosm.com/download.html). Once again the target is the Or1ksim architectural simulator.

Start the architectural simulator with a configuration suitable for Linux and with debugging enabled on port 50000:

     $ or32-uclinux-sim -f linux_debug.cfg
     Reading script file from '/home/jeremy/svntrunk/GNU/gdb-6.8/linux_debug.cfg'...
     WARNING: config: Unknown section: tick; ignoring.
     WARNING: config: Unknown section: pic; ignoring.
     Building automata... done, num uncovered: 0/213.
     Parsing operands data... done.
     JTAG Proxy server started on port 50000
     WARNING: Unable to open RX file stream.
     Resetting memory controller.
     Resetting PIC.

If using the configuration suggested on the OpenCores website or the Embecosm application note, this will open up a xterm to be used as the Linux console.

In a separate terminal start GDBN use the file command to get the symbols, connect to the target via JTAG and load the Linux image.

     $ or32-uclinux-gdb
     Building automata... done, num uncovered: 0/216.
     Parsing operands data... done.
     GNU gdb 6.8
     Copyright (C) 2008 Free Software Foundation, Inc.
     License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
     This is free software: you are free to change and redistribute it.
     There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
     and "show warranty" for details.
     This GDB was configured as "--host=i686-pc-linux-gnu --target=or32-uclinux".
     (gdb) file vmlinux
     Reading symbols from /home/jeremy/projects/openrisc/linux-2.6.19/vmlinux...done.
     (gdb) target jtag jtag://localhost:50000
     esp4_fini () at net/ipv4/esp4.c:466
     466             if (xfrm_unregister_type(&esp_type, AF_INET) < 0)
     (gdb) load vmlinux
     Loading section .text, size 0x227d74 lma 0xf0000000
     Loading section .rodata, size 0x23694 lma 0xf0228000
     Loading section __param, size 0x258 lma 0xf024b694
     Loading section __ex_table, size 0xbf8 lma 0xf024c000
     Loading section .data, size 0x1950c lma 0xf024e000
     Loading section .data.cacheline_aligned, size 0xd0 lma 0xf0267520
     Loading section .data.init_task, size 0x2000 lma 0xf0268000
     Loading section .init.text, size 0x17018 lma 0xf026a000
     Loading section .init.data, size 0x704 lma 0xf0281018
     Loading section .init.setup, size 0x1ec lma 0xf0281720
     Loading section .initcall.init, size 0x168 lma 0xf028190c
     Loading section .con_initcall.init, size 0xc lma 0xf0281a74
     Loading section .init.ramfs, size 0x2000 lma 0xf0282000
     Loading section .initrd, size 0x200000 lma 0xf0284000
     Start address 0xc0000000, load size 4723376
     Transfer rate: 25068 KB/sec, 337384 bytes/write.
     (gdb)

Using run at this point will not work, since loading the Linux kernel has specified an entry point (0xc0000000) at the start of the ROM image:

     (gdb) x/i $pc
     0xc0000000:     l.j 0x0
     (gdb)

This can be corrected, and then the program will run:

     (gdb) set $pc = 0x100
     (gdb) run
     Starting program: /home/jeremy/projects/openrisc/linux-2.6.19/vmlinux

The initial message will appear on the console output xterm as Linux copies itself from ROM to main memory:

     Copying Linux... Ok, booting the kernel.

Little else appears for some time, since the serial driver is not yet initialized. However the terminal running the architectural simulator will be reflecting the progress:

     Resetting PIC.

     Copying Linux... Ok, booting the kernel.
     ****************** counters reset ******************
     cycles 340441616, insn #29500690
     ****************** counters reset ******************
     <5>Linux version 2.6.19-or32 (jeremy@thomas) (gcc version 3.4.4) #3 Sat Jun 28 19:30:06 BST 2008
     Detecting Processor units:
       Signed 0x391
     Setting up paging and PTEs.
     write protecting ro sections (0xc0002000 - 0xc024c000)
     Setting up identical mapping (0x80000000 - 0x90000000)
     Setting up identical mapping (0x92000000 - 0x92002000)
     Setting up identical mapping (0xb8070000 - 0xb8072000)
     Setting up identical mapping (0x97000000 - 0x97002000)
     Setting up identical mapping (0x99000000 - 0x9a000000)
     Setting up identical mapping (0x93000000 - 0x93002000)
     Setting up identical mapping (0xa6000000 - 0xa6100000)
     Setting up identical mapping (0x1e50000 - 0x1fa0000)
     <7>On node 0 totalpages: 3968
     <7>  DMA zone: 0 pages used for memmap
     <7>  Normal zone: 15 pages used for memmap
     <7>  Normal zone: 3953 pages, LIFO batch:0
     dtlb_miss_handler c00040c8
     itlb_miss_handler c00041a8
     Built 1 zonelists.  Total pages: 3953
     <5>Kernel command line: root=/dev/ram console=ttyS0

Eventually the serial port driver is initialized and the Linux console xterm will show the Linux output, eventually giving the console prompt:

     VFS: Mounted root (ext2 filesystem) readonly.
     Freeing unused kernel memory: 104k freed
     init started:  BusyBox v1.4.1 (2007-03-22 18:53:56 EST) multi-call binary
     init started:  BusyBox v1.4.1 (2007-03-22 18:53:56 EST) multi-call binary
     Starting pid 22, console /dev/ttyS0: '/etc/init.d/rcS'

     Please press Enter to activate this console.

     Starting pid 25, console /dev/ttyS0: '/bin/sh'

     BusyBox v1.4.1 (2007-03-22 18:53:56 EST) Built-in shell (ash)
     Enter 'help' for a list of built-in commands.

     #

The full range of GDB debugging facilities are then available to debug the kernel:

Warning. Linux is loaded into ROM at address 0xf0000000, then relocated by copying into main memory at adress 0x00000000, but with a virtual memory start address of 0xc0000000 (as recorded in the image). Plain GDBN for OpenRISC 1000 is designed for bare metal debugging, and does not cope well with the virtual memory and relocation in the Linux kernel. In addition, the architectural simulator does not handle virtual addresses read and written through the debug interface correctly. Hardware breakpoints will work correctly (they are not changed by copying), but examining the data and restarting will fail. For Linux kernel debugging, KGDB should be used. This is derived from GDBN, but at present a port for GDBN GDBVN has not been completed.

Known Problems
**************

There are some known problems with the current implementation

 1. If the OpenRISC 1000 Architecture supports hardware watchpoints, GDBN will use them to implement hardware breakpoints and watchpoints. GDBN is not perfect in handling of watchpoints. It is possible to allocate hardware watchpoints and not discover until running that sufficient watchpoints are not available. It is also possible that GDB will report watchpoints being hit spuriously. This can be down to the assembly code having additional memory accesses that are not obviously reflected in the source code.

 2. The remote JTAG connection is not robust to being interrupted, or reconnecting. If the connection is lost due to error, then you must restart GDB and the target server (for example the Or1ksim architectural simulator). Moving to the Remote Serial Protocol is intended to remedy this problem in the future.

 3. The OpenRISC 1000 architecture has evolved since the port of GDB 5.3 in 2001. In particular the structure of the Unit Present register has changed and the CPU Configuration register has been added. The port of GDBN version GDBVN uses the current specification of the OpenRISC 1000. This means that old clients that talk to the debugger may not work. In particular the Or1ksim Architectural simulator requires a patch to work.

 4. The handling of watchpoints in the Or1ksim architectural simulator was incorrect. To work with GDBN GDBVN, a patch is required to fix this problem. This is combined with the patch changing the structure of the Unit Present and CPU Configuration registers.

 5. The OpenRISC 1000 architecture uses its General Purpose Register (GPR) 2 as a frame pointer register. However the $fp variable in GDBN is not currently implemented, and will return the value of the stack pointer (GPR 1) instead.

Reports of bugs are much welcomed. Please report problems through the OpenCORES tracker at www.opencores.org/ptracker.cgi/list/or1k.
     [file gpl.texi not included]

     [file fdl.texi not included]