# # Xilinx Zynq 7000 SoC # # Chris Johns # # Setup # ----- # # Create a user configuration following the "Configuration Basics" in the user # documentation. In the file have: # # source [find interface/ftdi/flyswatter2.cfg] # source [find board/zynq-zc706-eval.cfg] # adapter_khz 2000 # init # if { [info exists CHIPNAME] } { global _CHIPNAME set _CHIPNAME $CHIPNAME } else { global _CHIPNAME set _CHIPNAME zynq } if { [info exists ENDIAN] } { set _ENDIAN $ENDIAN } else { # this defaults to a bigendian set _ENDIAN little } if { [info exists SMP] } { global _SMP set _SMP 1 } else { global _SMP set _SMP 0 } # # PL Tap. # # See ug585 ZYNQ-7000 TRM PSS_IDCODE for how this number is constructed. # 0x03731093 - ZC706 Eval board 1.1 # 0x23731093 - ?? # 0x23727093 - Zedboard Rev. C and D # # Set in your configuration file or board specific file. # if { [info exists PL_TAPID] } { set _PL_TAPID $PL_TAPID } else { set _PL_TAPID 0x03731093 } jtag newtap $_CHIPNAME tap -irlen 6 -ircapture 0x001 -irmask 0x003 \ -expected-id $_PL_TAPID # # CoreSight Debug Access Port # if { [info exists DAP_TAPID] } { set _DAP_TAPID $DAP_TAPID } else { set _DAP_TAPID 0x4ba00477 } jtag newtap $_CHIPNAME dap -irlen 4 -ircapture 0x01 -irmask 0x03 \ -expected-id $_DAP_TAPID # # GDB target: Cortex-A9, using DAP, configuring only one core # Base addresses of cores: # core 0 - 0xF8890000 # core 1 - 0xF8892000 # # Read from the ROM table with the patch to read the nested table. # set _TARGETNAME_0 $_CHIPNAME.cpu.0 set _TARGETNAME_1 $_CHIPNAME.cpu.1 target create $_TARGETNAME_0 cortex_a -coreid 0 \ -endian $_ENDIAN \ -chain-position $_CHIPNAME.dap \ -dbgbase 0x80090000 if { $_SMP } { echo "Zynq CPU1." target create $_TARGETNAME_1 cortex_a -coreid 1 \ -endian $_ENDIAN \ -chain-position $_CHIPNAME.dap \ -dbgbase 0x80092000 target smp $_TARGETNAME_0 $_TARGETNAME_1 } # # Hack to get the registers into a stable state when first booting a zynq in # JTAG mode. If r11 is pointing to an invalid address and you use gdb to set a # register the write will fail because gdb attempts to scan or unwind the # current frame and the bad address seems to lock the bus up. This code puts # the registers into the OCM and hopefull safe. # proc zynq_clear_registers { target } { echo "Zynq-7000 Series setup: $target" set _OCM_END 0x0003FFF0 mww phys 0xF8007000 0x4E00E07F reg r0 0 reg r1 0 reg r2 0 reg r3 0 reg r4 0 reg r5 0 reg r6 0 reg r7 0 reg r8 0 reg r9 0 reg r10 0 reg r11 $_OCM_END reg sp_svc $_OCM_END reg lr_svc $_OCM_END reg sp_abt $_OCM_END reg lr_abt $_OCM_END reg sp_und $_OCM_END reg lr_und $_OCM_END } proc zynq_disable_mmu_and_caches { target } { # arm mcr pX op1 CRn CRm op2 value echo "Disable MMU and caches" # Invalidate caches catch { $target arm mcr 15 0 7 5 0 0 $target arm mcr 15 0 7 7 0 0 # Invalidate all TLBs $target arm mcr 15 0 8 5 0 0 $target arm mcr 15 0 8 6 0 0 $target arm mcr 15 0 8 7 0 0 $target arm mcr 15 4 8 3 0 0 $target arm mcr 15 4 8 7 0 0 set cp [$target arm mrc 15 0 1 0 0] echo "SCTRL => [format 0x%x $cp]" set mask [expr 1 << 29 | 1 << 12 | 1 << 11 | 1 << 2 | 1 << 1 | 1 << 0] set cp [expr ($cp & ~$mask)] $target arm mcr 15 0 1 0 0 $cp echo "SCTRL <= [format 0x%x $cp]" } } proc zynq_boot_ocm_setup { } { # # Enable the OCM # echo "Zynq Boot OCM setup" catch { mww phys 0xF8000008 0xDF0D mww phys 0xF8000238 0 mww phys 0xF8000910 0xC } } proc zynq_rtems_setup { } { cache_config l2x 0xF8F02000 8 cortex_a maskisr on } proc zynq_restart { wait } { global _SMP global _TARGETNAME_0 global _TARGETNAME_1 set target0 $_TARGETNAME_0 set target1 $_TARGETNAME_1 echo "Zynq reset, resetting the board ... " poll off # # Issue the reset via the SLCR # catch { mww phys 0xF8000008 0xDF0D mww phys 0xF8000200 1 } echo "Zynq reset waiting for $wait msecs ... " sleep $wait # # Reconnect the DAP etc due to the reset. # $target0 cortex_a dbginit $target0 arm core_state arm if { $_SMP } { $target1 arm core_state arm $target1 cortex_a dbginit cortex_a smp_off } poll on # # We can now halt the core. # if { $_SMP } { targets $target1 halt } targets $target0 halt zynq_rtems_setup } proc zynq_gdb_attach { target } { catch { halt } }