Thursday 10 January 2013

Setup JTAG ICE for Linux kernel debugging

1) Setup PEEDI JTAG ICE for MPC8315 for Linux kernel debugging

The information of PEEDI JTAG ICE is available at:
http://www.ronetix.at/peedi.html

The steps to be performed are:
  • Download insight 6.8-1 to linux host
  • Build insight on linux host
configure  –target=powerpc-linux  –enable-sim-powerpc  –enable-sim-hostendian=little  --prefix=/home/vic/insight
  • In mpc8315.cfg
Set CORE0_BREAKMODE to hard
Comment out CORE0_INIT parameter
  • Download the cfg file from linux host to PEEDI
On PEEDI prompt, do the transfer from linux host to a SD card
tftp://192.168.xxx.xxx/mpc8315.cfg eep://mpc8315.cfg
  • In linux "make menuconfig" on linux host
Enable Kernel hacking->Compile the kernel with debug info
           Kernel hacking->Kernel debugging
  • Start “insight vmlinux” in linux build directory on linux host
In the insight window, do the following:
  • File ->Target Settings
  • Run->Connect to Target
  • Setup the breakpoint
(gdb) hb start_kernel  ; hardware breakpoint is used because the MMU is still not active


  •        set the program counter
(gdb) set $pc = 0x208000
  •  to run the linux kernel
(gdb) c

After this, you can step through the linux kernel.


A sample mpc8315.cfg
;--------------------------------------------------------------------------
;
; PEEDI target configuration file for PowerPC MPC8315 processor
;
; Ronetix
;
; Supported devices : MPC8315
;
; Board : MPC8315 board
;
; Revision : 1.0
;
; The file is delivered "AS IS" without warranty or condition of any
; kind, either express, implied or statutory. This includes without
; limitation any warranty or condition with respect to merchantability or
; fitness for any particular purpose, or against the infringements of
; intellectual property rights of others.
;
;--------------------------------------------------------------------------

[DEBUGGER]
PROTOCOL        = gdb_remote
REMOTE_PORT = 2000 ; TCP/IP port
DROP_ON_RESET = NO

[TARGET]
PLATFORM     = MPC8300 ; platform is Freescale MPC8300

[PLATFORM_MPC8300]
JTAG_CHAIN  = 8 ; list of IR lenght of all TAP controller in JTAG chain
JTAG_CLOCK = 20000 ; JTAG Clock in kHz - 10kHz jtag clock for init operations and 20MHz for normal work
JTAG_TDO_DELAY = 0
TRST_TYPE              = PUSHPULL ; type of TRST output: OPENDRAIN or PUSHPULL
RESET_TIME            = 500 ; lenght of RESET pulse in ms; 0 means no RESET
WAKEUP_TIME       = 500

CORE0 = MPC8313 ; TAP is PowerPC CPU
;CORE0_INIT = INIT_MPC8315
;CORE0_INIT = INIT_MPC8315_LINUX
CORE0_STARTUP_MODE = reset
CORE0_BOOT_ADDR = 0xFFF00100

; Reset Configuration words: Hi, Lo registers
; The bit order differs from the Freescale's User Manual:
; arg1 bit31 - PCIHOST
; arg1 bit30 - PCI64
; arg1 bit29 - PCIARB
; ....................
; arg2 bit31 - LBCM
; arg2 bit30 - DDRCM
; ..................
;
; If you want to set RCWHR bit-0 (PCIHOST) and RCWLR bit-1 (DDRCM) regarding
; the Freescale's User Manual, you should use: CORE0_RCW = 0x80000000, 0x40000000
;
CORE0_RCW = 0xA4146C00, 0x42060000 ;override reset configuration words
;CORE0_MMU_PTBASE = 0x000000F0
CORE0_BREAKMODE = hard ; breakpoint mode:
;CORE0_BREAKMODE = soft ; breakpoint mode:
CORE0_ENDIAN = big ; core is little endian
CORE0_FLASH0 = FLASH_NAND
CORE0_WORKSPACE = 0, 0x11000 ; workspace for flash programmer

; Default path to be used if only a file name (without the full path) is
; provided to a PEEDI command or for the FILE parameter in the Flash sections
; Examples:
; In a console:
; "flash prog tftp://192.168.3.1/image.elf"
; is equal to
; "flash prog image.elf"
;
; In a Flash Profile:
; FILE="tftp://192.168.3.1/image.bin", BIN, 0
; is equal to
; FILE="image.bin", BIN, 0
;
CORE0_PATH = "tftp://192.168.3.1"
;CORE0_PATH = "card://"
CORE0_FILE = "myfile.bin", BIN, 0x2000000    ; default file

[INIT_MPC8315_LINUX]
break add hard 0xC01AE4C8 ; hardware breakpoint at start_kernel()
go ; start U-boot which eventually will start Linux
wait 30000 stop ; wait until the kernel halts on the break
beep 3000 100 ; beep to signal we are ready for debug

[INIT_MPC8315]

set SPR 311 0xFF400000

; change internal MMR base from 0xff400000 (reset value) to 0xe0000000
mem write 0xff400000 0xe0000000 ; IMMRBAR = 0xe0000000

;setMMRBaseAddr 0xe0000000
set SPR 311 0xe0000000

mem write 0xe0000204 0xffff0000 ;SWCRR: disable watchdog
mem write 0xe0000110 0x00400000 ;SPCR : enable timebase unit
mem write 0xe00050d4 0x00010002 ;LCRR : CLKDIV = 4

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; System Configuration - Local Access Windows
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;; Local Bus Local Access Windows
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; WINDOW 0 - NAND Flash
mem write 0xe0000020 0xf8000000 ; LBLAWBAR1 - begining at 0xf8000000
mem write 0xe0000024 0x80000018 ; LBLAWAR1 - enable, size = 32MB

;; DDR Local Access Windows
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; WINDOW 0 - 1st DDR SODIMM
mem write 0xe00000a0 0x00000000 ; DDRLAWBAR0 - begining at 0x00000000
mem write 0xe00000a4 0x8000001a ; DDRLAWAR0 - enable, size = 128MB

mem write 0xe00000e0 0x08000000 ; DDRLAWBAR0 - begining at 0x08000000
mem write 0xe00000e4 0x8000001a ; DDRLAWAR0 - enable, size = 128MB

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; ; DDR Controllers Configuration
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;DDRCDR
mem write 0xE0000128 0x73000002

;;*********************************
;; DDR2 Controller Registers
;;*********************************

;; DDR_SDRAM_CLK_CNTL
; CLK_ADJST = b'010' ; 2 Clocks
mem write 0xE0002130 0x02000000

; CS0_BNDS
; SA0 = b'000000000000'
; EA0 = b'000000000111'

mem write 0xE0002000 0x00000007 ;; 128MB

; CS0_CONFIG
; CS_0_EN = b'1'
; AP_0_EN = b'1'
; ODT_RD_CFG = b'0'
; ODT_WR_CFG = b'1'
; BA_BITS_CS_0 = b'00'
; ROW_BITS_CS_0 = b'001' ; 13 row bits
; COL_BITS_CS_0 = b'010' ; 10 columns bits

mem write 0xE0002080 0x80840102

; TIMING_CFG_3
; EXT_REFREC = b'000' ; 0 Clocks

mem write 0xE0002100 0x00000000

; TIMING_CONFIG_1

; bit 1-3 = 2 - PRETOACT precharge activate interval 2 clock cycles
; bit 4-7 = 6 - ACTTOPRE activate to precharge interval 6 clock cycles
; bit 9-11 = 2 = ACTTORW activate to r/w interval 2 clock cycles
; bit 13 - 15 = 5 - CASLAT CAS latency 3 clock cycles
; bit 16 - 19 = 6 - REFREC refresh recovery time 14 clock cycles
; bit 21 - 23 = 2 - WRREC data to precharge interval 2 clock cycles
; bit 25 - 27 = 2 - ACTTOACT activate to activate interval 2 clock cycles
; bit 29 - 31 = 2 - WRTORD write data to read command interval 2 clock cycles

mem write 0xe0002108 0x26256222

; TIMING_CONFIG_2
; bit 19-21 = b010 - WR_DATA_DELAY - 1/2 DRAM clock delay

mem write 0xe000210C 0x0f9028c7

; TIMING_CFG_0
; RWT = b'00' ; 0 Clocks
; WRT = b'00' ; 0 Clocks
; RRT = b'00' ; 0 Clocks
; WWT = b'00' ; 0 Clocks
; ACT_PD_EXIT = b'010' ; 2 Clocks
; PRE_PD_EXIT = b'010' ; 2 Clocks
; ODT_PD_EXIT = b'1000' ; 8 Clocks
; MRS_CYC = b'0010' ; 2 Clocks

mem write 0xE0002104 0x00220802

; DDR_SDRAM_CFG
; MEM_EN = b'0'
; SREN = b'1'
; RD_EN = b'0'
; SDRAM_TYPE = b'011'
; DYN_PWR = b'0'
; 32_BE = b'1'
; 8_BE = b'0'
; NCAP = b'0'
; 2T_EN = b'0'
; x32_EN = b'0'
; PCHB8 = b'0'
; HSE = b'0'
; MEM_HALT = b'0'
; BI = b'0'

mem write 0xE0002110 0x43080000

; DDR_SDRAM_CFG_2
; FRC_SR = b'0'
; DQS_CFG = b'00'
; ODT_CFG = b'10'
; NUM_PR = b'0001'
; D_INIT = b'0'

mem write 0xE0002114 0x00401000

; DDR_SDRAM_MODE
; Extended Mode Register: Outputs=0 or 1?
; Mode Register

mem write 0xE0002118 0x44400232

; DDR_SDRAM_MODE_2
; Extended Mode Register 2
; Extended Mode Register 3

mem write 0xE000211C 0x8000c000

; DDR_SDRAM_INTERVAL
; REFINT = 800 Clocks
; BSTOPRE = 100 Clocks

mem write 0xE0002124 0x03200064

; DDR_SDRAM_MD_CNTL (0xE0002120)
; DDR_DATA_INIT (0xE0002128)
; DDR_INIT_ADDRESS (0xE0002148)
; DDR_INIT_EXT_ADDRESS (0xE000214c)

; DDR_IP_REV1 - Read-Only

; md 0xE0002BF8
; DDR_IP_REV2 - Read-Only
; md 0xE0002BFC

;delay before enable
wait 300

;Enable: DDR_SDRAM_CFG
mem write 0xE0002110 0xc3080000

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Local Bus Interface (LBIU) Configuration
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;; CS0 - NAND FLASH
mem write 0xe0005000 0xf8000C21 ; BR1 base address at 0xF8000000, port size 8 bit, FCM, valid
mem write 0xe0005004 0xFFFF8076 ; OR1 32kB

;; LBCR - local bus enable
mem write 0xe00050d0 0x00000000

;; LCRR
;; bit 14 - 15 = 0b11 - EADC - 3 external address delay cycles
;; bit 28 - 31 = 0x0010 - CLKDIV - system clock:memory bus clock = 2
mem write 0xe00050d4 0x00030002

mem write 0xE0000800 0x00000000 ; ACR - Enable Core
;mem write 0xfa000000 0x00000000 ; write board LEDs

;; MRTPR - refresh timer prescaler
mem write 0xe0005084 0x20000000

[FLASH_NAND]
CHIP = NAND_FLASH
CPU = MPC83XX
CMD_BASE = 0xE0000000 ; IMMRBAR
DATA_BASE = 0xF8000000 ; FCM address
ADDR_BASE = 0 ; NAND chip select
OOB_INFO = FF
FILE = "test.bin", 0x0

[SERIAL] ; serial port configuration
BAUD = 115200
STOP_BITS = 1
PARITY = NONE
TCP_PORT = 0

[TELNET]
PROMPT = "mpc8315> " ; telnet prompt
;BACKSPACE = 127 ; comment out for autodetect

2) Setup ARM RealView JTAG ICE for ARM926EJ-S for Linux kernel debugging

Hardware target board has to provide the JTAG connection. The pull-up/pull-down resistors on one particular target board:

  • TDO, TDI, TMS pull-up
  • nTRST pull-up
  • RTCK n/c
  • TCK pull-down


In Linux, the ARM RealView JTAG ICE only supports TCP/IP mode, USB mode is not supported.

Firstly, we need to setup the ARM RealView ICE for TCP/IP mode. We need to run "RVI Config IP" to find the IP address of the ARM RealView. Then we need to run "RVConfig" to configure and save the configuration in a rvc file. Then we need to run the rvigdbconfig from the command line.

$ rvigdbconfig -f ~/.rvdebug/4.0/RVI_0.rvc

Secondly, run gdb from command line:

arm-none-linux-gnueabi-gdb vmlinux

(gdb) target remote 192.168.1.2:4000

the port number 4000 is the TCP port number in ARM Real View ICE

(gdb) info registers -- check the $pc value, it must be 0x0, if not, re-run the rvigdbconfig

(gdb) hb start_kernel

(gdb) x/10i $pc

(gdb) c

At UART terminal of U-Boot, load Image (kernel image) and initramfs.gz (rootfs), and run. Then, observe that the linux loading is stopped. So the Jtag debugging is successful.

Extra gdb commands:

(gdb) file vmlinux

(gdb) list start_kernel

(gdb) p/x $pc

(gdb) set $pc = 208000

(gdb) b *0x10

To do memory dump with gdb:

(gdb) dump binary memory <filename> <mem_start_addr> <mem_ending_addr>