forked from M-Labs/nac3
211 lines
4.7 KiB
INI
211 lines
4.7 KiB
INI
#
|
|
# Xilinx Zynq 7000 SoC
|
|
#
|
|
# Chris Johns <chrisj@rtems.org>
|
|
#
|
|
# 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
|
|
}
|
|
} |