Skip to content

Commit

Permalink
fixup! Use two versions of openocd.
Browse files Browse the repository at this point in the history
  • Loading branch information
lmbollen committed Feb 20, 2025
1 parent dbe08e0 commit ca872da
Show file tree
Hide file tree
Showing 6 changed files with 79 additions and 15 deletions.
2 changes: 1 addition & 1 deletion bittide-instances/data/openocd/start.sh
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,6 @@ mkdir -p "${stderr_dir}"
OPENOCD_STDERR_LOG="$(realpath ${OPENOCD_STDERR_LOG})"

cd $(dirname $0)
exec ${OPENOCD_BIN} -f ports.tcl -f sipeed.tcl -f vexriscv_init.tcl $@ \
exec ${OPENOCD_INVOCATION} $@ \
> >(tee "${OPENOCD_STDOUT_LOG}") \
2> >(tee "${OPENOCD_STDERR_LOG}" >&2)
59 changes: 59 additions & 0 deletions bittide-instances/data/openocd/vexriscv_init_custom.tcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# SPDX-FileCopyrightText: 2024 Google LLC
#
# SPDX-License-Identifier: Apache-2.0
set _ENDIAN little
set _TAP_TYPE 1234

if { [info exists CPUTAPID] } {
set _CPUTAPID $CPUTAPID
} else {
# set useful default
set _CPUTAPID 0x10001fff
}

set _CHIPNAME vexrisc_ocd

# The JTAG TAP itself is given the name "bridge", because it refers to the
# JtagBridge that's part of the VexRiscv/SpinalHDL debug infrastructure.
# In the example design, there is the JtagBridge controls a single CPU, but
# the capability is there for 1 JTAG TAP + JtagBridge to control multiple
# VexRiscv CPUs.
jtag newtap $_CHIPNAME bridge -expected-id $_CPUTAPID -irlen 5

# There is 1 CPU controlled by the "bridge" JTAG TAP, "cpu0"
target create $_CHIPNAME.cpu0 vexriscv -endian $_ENDIAN -chain-position $_CHIPNAME.bridge

# The JtagBridge/SystemDebugger receives commands in a serialized way. It gets synchronized into
# a parallel bus, and a response is received. Along the way, there may be various clock domain
# crossings or pipeline delays.
# readWaitCycles instructs OpenOCD to insert idle JTAG clock cycles before shifting out
# the response.
# There aren't many transactions where read-back throughput is important, so there's little
# points in lowballing this number.
vexriscv readWaitCycles 10

# When the Verilog of a SpinalHDL design with one or more VexRiscv CPUs is created, the system
# also creates a .yaml file with information that's sideband information that's important for
# OpenOCD to control the CPU correctly.
# A good example of this are the number of hardware breakpoints that are supported by the CPU.
set git_top_level [string trim [exec git rev-parse --show-toplevel]]
vexriscv cpuConfigFile [file join $git_top_level clash-vexriscv clash-vexriscv example-cpu ExampleCpu.yaml]

# The rate at which OpenOCD polls active JTAG TAPs to check if there has been a notable
# event. (E.g. to check if the CPU has hit a breakpoint.)
# For some reason, making this number really low has an impact on the CPU while semihosting is
# enabled?
poll_period 50

# Initialize all JTAG TAPs and targets.
init

echo "Halting processor"

# Halts the CPU
halt

# If you also want to reset the CPU, use:
# soft_reset_halt

sleep 1000
Original file line number Diff line number Diff line change
Expand Up @@ -86,9 +86,9 @@ driverFunc testName targets = do
putStrLn "Starting OpenOCD..."
(ocd, ocdPh, ocdClean1) <-
startOpenOcdWithEnv
OpenOcdVexRiscv
[ ("OPENOCD_STDOUT_LOG", ocdStdout)
, ("OPENOCD_STDERR_LOG", ocdStderr)
, ("OPENOCD_BIN", "openocd-vexriscv")
]
d.usbAdapterLocation
gdbPort
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ driverFunc _name targets = do
-- even though this is just pre-process step, the CPU is reset until
-- the test_start signal is asserted and cannot be accessed via GDB otherwise
updateVio "vioHitlt" [("probe_test_start", "1")]
liftIO $ withOpenOcdWithEnv openocdEnv deviceInfo.usbAdapterLocation gdbPort 6666 4444 $ \ocd -> do
liftIO $ withOpenOcdWithEnv OpenOcdRiscv openocdEnv deviceInfo.usbAdapterLocation gdbPort 6666 4444 $ \ocd -> do
-- make sure OpenOCD is started properly
hSetBuffering ocd.stderrHandle LineBuffering
expectLine ocd.stderrHandle openOcdWaitForHalt
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ driverFunc _name [(hwT, dI)] = do

initHwDevice

withOpenOcdWithEnv openocdEnv dI.usbAdapterLocation 3333 6666 4444 $ \ocd -> do
withOpenOcdWithEnv OpenOcdRiscv openocdEnv dI.usbAdapterLocation 3333 6666 4444 $ \ocd -> do
liftIO $ do
hSetBuffering ocd.stderrHandle LineBuffering
putStr "Waiting for OpenOCD to halt..."
Expand Down
27 changes: 16 additions & 11 deletions bittide-instances/src/Bittide/Instances/Hitl/Utils/Program.hs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ awaitProcessTermination name h (Just t) = do

withOpenOcd ::
(MonadMask m, MonadIO m) =>
-- | Which OpenOcd to use
OpenOcdVersion ->
-- | USB device location
String ->
-- | GDB port
Expand All @@ -67,10 +69,12 @@ withOpenOcd ::
-- | Action to run with OpenOCD
(ProcessStdIoHandles -> m a) ->
m a
withOpenOcd = withOpenOcdWithEnv []
withOpenOcd ocdVersion = withOpenOcdWithEnv ocdVersion []

withOpenOcdWithEnv ::
(MonadMask m, MonadIO m) =>
-- | Which OpenOcd to use
OpenOcdVersion ->
-- | Extra environment variables to pass to OpenOCD in form (name, value)
[(String, String)] ->
-- | USB device location
Expand All @@ -84,12 +88,15 @@ withOpenOcdWithEnv ::
-- | Action to run with OpenOCD
(ProcessStdIoHandles -> m a) ->
m a
withOpenOcdWithEnv extraEnv usbLoc gdbPort tclPort telnetPort action = do
withOpenOcdWithEnv ocdVersion extraEnv usbLoc gdbPort tclPort telnetPort action = do
(ocd, _handle, clean) <-
liftIO $ startOpenOcdWithEnv extraEnv usbLoc gdbPort tclPort telnetPort
liftIO $ startOpenOcdWithEnv ocdVersion extraEnv usbLoc gdbPort tclPort telnetPort
finally (action ocd) (liftIO clean)

data OpenOcdVersion = OpenOcdRiscv | OpenOcdVexRiscv
startOpenOcdWithEnv ::
-- | Which OpenOcd to use
OpenOcdVersion ->
-- | Extra environment variables to pass to OpenOCD in form (name, value)
[(String, String)] ->
-- | USB device location
Expand All @@ -101,13 +108,10 @@ startOpenOcdWithEnv ::
-- | Telnet port
Int ->
IO (ProcessStdIoHandles, ProcessHandle, IO ())
startOpenOcdWithEnv extraEnv0 usbLoc gdbPort tclPort telnetPort = do
-- Check if OPENOCD_BIN is set. If not, append ("OPENOCD_BIN", "openocd") to the environment.
-- This is necessary because swCcTopologiesTest relies on the custom OpenOCD binary.
let extraEnv1
| any ((== "OPENOCD_BIN") . fst) extraEnv0 = extraEnv0
| otherwise = ("OPENOCD_BIN", "openocd") : extraEnv0

startOpenOcdWithEnv ocdVersion extraEnv usbLoc gdbPort tclPort telnetPort = do
let invocation = case ocdVersion of
OpenOcdRiscv -> "\"openocd-riscv -f ports.tcl -f sipeed.tcl -f vexriscv_init.tcl\""
OpenOcdVexRiscv -> "\"openocd-vexriscv -f ports.tcl -f sipeed.tcl -f vexriscv_init_custom.tcl\""
startOpenOcdPath <- getOpenOcdStartPath
currentEnv <- getEnvironment
let
Expand All @@ -119,11 +123,12 @@ startOpenOcdWithEnv extraEnv0 usbLoc gdbPort tclPort telnetPort = do
, env =
Just
( currentEnv
<> extraEnv1
<> extraEnv
<> [ ("USB_DEVICE", usbLoc)
, ("GDB_PORT", show gdbPort)
, ("TCL_PORT", show tclPort)
, ("TELNET_PORT", show telnetPort)
, ("OPENOCD_INVOCATION", invocation)
]
)
}
Expand Down

0 comments on commit ca872da

Please sign in to comment.