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>