# SPDX-License-Identifier: GPL-2.0-or-later # # OpenOCD Target Configuration for Ampere Altra ("Quicksilver") and # Ampere Altra Max ("Mystique") processors # # Copyright (c) 2019-2022, Ampere Computing LLC # Command Line Argument Description # # SPLITSMP # Only used for dual socket systems. Do not use for a single socket setup. # Option pertains to the ARMv8 target core naming in a dual socket setup. # If specified, name all ARMv8 cores per socket as individual SMP sessions. # If not specified, name ARMv8 cores from both sockets as one SMP session. # This option is used in conjunction with the SMP_STR board file option. # Syntax: -c "set SPLITSMP {}" # # PHYS_IDX # Enable OpenOCD ARMv8 core target physical indexing. # If not specified, defaults to OpenOCD ARMv8 core target logical indexing. # Syntax: -c "set PHYS_IDX {}" # # CHIPNAME # Specifies the name of the chip. # Will typically be either qs, qs0, qs1, mq, mq0 or mq1. # If not specified, defaults to qs. # Syntax: -c "set CHIPNAME {qs}" # # SYSNAME # Specifies the name of the system. # Will typically be either qs or mq. # If not specified, defaults to qs. # Syntax: -c "set SYSNAME {qs}" # # Life-Cycle State (LCS) # If not specified, defaults to "Secure LCS". # LCS=0, "Secure LCS" # LCS=1, "Chip Manufacturing LCS" # Syntax: -c "set LCS {0}" # Syntax: -c "set LCS {1}" # # CORELIST # Specify available physical cores by number. # Example syntax to connect to physical cores 16 and 17. # Syntax: -c "set CORELIST {16 17}" # # COREMASK_LO # Specify available physical cores 0-63 by mask. # Example syntax to connect to physical cores 16 and 17. # Syntax: -c "set COREMASK_LO {0x0000000000030000}" # # COREMASK_HI # Specify available physical cores 64 and above by mask. # Example syntax to connect to physical cores 94 and 95. # Syntax: -c "set COREMASK_HI {0x00000000C0000000}" # # ARMV8_TAPID # Can override the ARMV8 TAPID default value if necessary. # Experimental Use. Most users will not use this option. # Syntax: -c "set ARMV8_TAPID {0x3BA06477}" # # SMPMPRO_TAPID # Can override the SMPMPRO TAPID default value if necessary. # Experimental Use. Most users will not use this option. # Syntax: -c "set SMPMPRO_TAPID {0x4BA00477}" # # # Board File Argument Description # These optional arguments are defined in the board file and # referenced by the target file. See the corresponding board # files for examples of their use. # # SMP_STR # This option is used primarily for a dual socket system and it is not # recommended for a single socket setup. This option configures whether # the SMP ARMv8 core grouping is maintained at the board or target cfg level. # Specify the option if the SMP core grouping is defined at the board level. # Do not specify if the SMP core grouping is defined at the chip level. # If not specified, defaults to SMP core grouping defined per socket. # If specified, "SMP_STR=target smp", the SMP core grouping is maintained # at the board cfg level. # Used in conjunction with the SPLITSMP option to group two chips into # a single SMP configuration or maintain as two separate SMP sessions. # # CORE_INDEX_OFFSET # Specifies the starting logical core index value. # Used for dual-socket systems. # For socket #0, set to 0. # For socket #1, set the starting logical core based from # the last logical core on socket #0. # If not specified, defaults to 0. # # # Configure defaults for target. # Can be overridden in board configuration file. # if { [info exists SMP_STR] } { # SMP configured at the dual socket board level set _SMP_STR $SMP_STR } else { # SMP configured at the single socket target level set _SMP_STR "target smp" } if { [info exists CHIPNAME] } { set _CHIPNAME $CHIPNAME } else { set _CHIPNAME qs } if { [info exists SYSNAME] } { set _SYSNAME $SYSNAME } else { set _SYSNAME qs } if { [info exists CORE_INDEX_OFFSET] } { set _CORE_INDEX_OFFSET $CORE_INDEX_OFFSET } else { set _CORE_INDEX_OFFSET 0 } if { [info exists ENDIAN] } { set _ENDIAN $ENDIAN } else { set _ENDIAN little } if { [info exists ARMV8_TAPID] } { set _ARMV8_TAPID $ARMV8_TAPID } else { if { [info exists MQ_ENABLE] } { # Configure for Mystique set _ARMV8_TAPID 0x3BA06477 set _MAX_CORE 128 } else { # Configure for Quicksilver set _ARMV8_TAPID 0x2BA06477 set _MAX_CORE 80 } } if { [info exists SMPMPRO_TAPID] } { set _SMPMPRO_TAPID $SMPMPRO_TAPID } else { set _SMPMPRO_TAPID 0x4BA00477 } if { [info exists CORELIST] } { set _CORELIST $CORELIST } else { if { [info exists COREMASK_LO] } { set _COREMASK_LO $COREMASK_LO } else { set _COREMASK_LO 0x0 } if { [info exists COREMASK_HI] } { set _COREMASK_HI $COREMASK_HI } else { set _COREMASK_HI 0x0 } set _CORELIST {} set _MASK 0x1 for {set i 0} {$i < 64} {incr i} { if { [expr {$_COREMASK_LO & $_MASK}] != 0x0 } { set _CORELIST "$_CORELIST $i" } set _MASK [expr {$_MASK << 0x1}] } set _MASK 0x1 for {} {$i < $_MAX_CORE} {incr i} { if { [expr {$_COREMASK_HI & $_MASK}] != 0x0 } { set _CORELIST "$_CORELIST $i" } set _MASK [expr {$_MASK << 0x1}] } } # # Definition of target names # set _TARGETNAME_PMPRO pmpro set _TARGETNAME_SMPRO smpro set _TARGETNAME_ARMV8 armv8 # # Configure JTAG TAPs - TAP chain declaration order is important # jtag newtap $_CHIPNAME pmpro.tap -irlen 4 -ircapture 0x1 -irmask 0x3 -expected-id $_SMPMPRO_TAPID set _TAPNAME_PMPRO $_CHIPNAME.$_TARGETNAME_PMPRO.tap jtag newtap $_CHIPNAME smpro.tap -irlen 4 -ircapture 0x1 -irmask 0x3 -expected-id $_SMPMPRO_TAPID set _TAPNAME_SMPRO $_CHIPNAME.$_TARGETNAME_SMPRO.tap jtag newtap $_CHIPNAME armv8.tap -irlen 4 -ircapture 0x1 -irmask 0x3 -expected-id $_ARMV8_TAPID set _TAPNAME_ARMV8 $_CHIPNAME.$_TARGETNAME_ARMV8.tap set _DAPNAME_PMPRO $_CHIPNAME.$_TARGETNAME_PMPRO.dap set _DAPNAME_SMPRO $_CHIPNAME.$_TARGETNAME_SMPRO.dap set _DAPNAME_ARMV8 $_CHIPNAME.$_TARGETNAME_ARMV8.dap set _AP_PMPRO_AHB 0 set _AP_SMPRO_AHB 0 set _AP_ARMV8_APB 0x00010000 set _AP_ARMV8_AXI 0x00020000 # # Configure JTAG DAPs # dap create $_DAPNAME_PMPRO -chain-position $_TAPNAME_PMPRO -adiv5 dap create $_DAPNAME_SMPRO -chain-position $_TAPNAME_SMPRO -adiv5 dap create $_DAPNAME_ARMV8 -chain-position $_TAPNAME_ARMV8 -adiv6 if { [info exists LCS] && [expr {"$LCS"!="0"}] } { # # Create the DAP AHB-AP MEM-AP target for the PMPRO CPU # target create $_CHIPNAME.$_TARGETNAME_PMPRO.ahb mem_ap -endian $_ENDIAN -dap $_DAPNAME_PMPRO -ap-num $_AP_PMPRO_AHB # # Configure target PMPRO CPU # target create $_CHIPNAME.$_TARGETNAME_PMPRO cortex_m -endian $_ENDIAN -dap $_DAPNAME_PMPRO -ap-num $_AP_PMPRO_AHB # # Create the DAP AHB-AP MEM-AP target for the SMPRO CPU # target create $_CHIPNAME.$_TARGETNAME_SMPRO.ahb mem_ap -endian $_ENDIAN -dap $_DAPNAME_SMPRO -ap-num $_AP_SMPRO_AHB # # Configure target SMPRO CPU # target create $_CHIPNAME.$_TARGETNAME_SMPRO cortex_m -endian $_ENDIAN -dap $_DAPNAME_SMPRO -ap-num $_AP_SMPRO_AHB } # Create the DAP APB-AP MEM-AP target for the ARMV8 cores target create $_CHIPNAME.$_TARGETNAME_ARMV8.apb mem_ap -endian $_ENDIAN -dap $_DAPNAME_ARMV8 -ap-num $_AP_ARMV8_APB # Create the DAP AXI-AP MEM-AP target for the ARMV8 cores target create $_CHIPNAME.$_TARGETNAME_ARMV8.axi mem_ap -endian $_ENDIAN -dap $_DAPNAME_ARMV8 -ap-num $_AP_ARMV8_AXI # Set CSW register value default correctly for AXI accessible device memory: # Select the correct Access Port Number $_DAPNAME_ARMV8 apsel $_AP_ARMV8_AXI # First set the CSW to OpenOCD's internal default $_DAPNAME_ARMV8 apcsw default # Set Domain[1:0]=b'11 (CSW[14:13]=b'11) # Set Cache[3:0]=b'0000 (CSW[27:24]=b'0000) # Porter Cfg registers require secure access, AxPROT[1] (CSW[29]) must be b'0'. # Set AxPROT[2:0]=b'000 (CSW[30:28]=b'000) for an Unpriveleged, Secure, Data access. $_DAPNAME_ARMV8 apcsw 0x00006000 0x7F006000 # # Configure target CPUs # set logical_index $_CORE_INDEX_OFFSET foreach physical_index $_CORELIST { if { [info exists PHYS_IDX] } { set logical_index [expr {$physical_index + $_CORE_INDEX_OFFSET}] } # Format a string to reference which CPU target to use if { [info exists SPLITSMP] } { eval "set _TARGETNAME $_CHIPNAME.${_TARGETNAME_ARMV8}_$logical_index" } else { eval "set _TARGETNAME $_SYSNAME.${_TARGETNAME_ARMV8}_$logical_index" } # Create and configure Cross Trigger Interface (CTI) - required for halt and resume set _CTINAME $_TARGETNAME.cti set _offset [expr {(0x00100000 * $physical_index) + (0x00200000 * ($physical_index>>1))}] cti create $_CTINAME -dap $_DAPNAME_ARMV8 -ap-num $_AP_ARMV8_APB -baseaddr [expr {0xA0220000 + $_offset}] # Create the target target create $_TARGETNAME aarch64 -endian $_ENDIAN \ -dap $_DAPNAME_ARMV8 -ap-num $_AP_ARMV8_APB -dbgbase [expr {0xA0210000 + $_offset}] \ -rtos hwthread -cti $_CTINAME -coreid $logical_index # Build string used to enable SMP mode for the ARMv8 CPU cores set _SMP_STR "$_SMP_STR $_TARGETNAME" # Clear CTI output/input enables that are not configured by OpenOCD for aarch64 $_TARGETNAME configure -event reset-init [subst { $_CTINAME write INEN0 0x00000000 $_CTINAME write INEN1 0x00000000 $_CTINAME write INEN2 0x00000000 $_CTINAME write INEN3 0x00000000 $_CTINAME write INEN4 0x00000000 $_CTINAME write INEN5 0x00000000 $_CTINAME write INEN6 0x00000000 $_CTINAME write INEN7 0x00000000 $_CTINAME write INEN8 0x00000000 $_CTINAME write OUTEN0 0x00000000 $_CTINAME write OUTEN1 0x00000000 $_CTINAME write OUTEN2 0x00000000 $_CTINAME write OUTEN3 0x00000000 $_CTINAME write OUTEN4 0x00000000 $_CTINAME write OUTEN5 0x00000000 $_CTINAME write OUTEN6 0x00000000 $_CTINAME write OUTEN7 0x00000000 $_CTINAME write OUTEN8 0x00000000 }] incr logical_index } if { [info exists SMP_STR] } { # Return updated SMP configuration string back to board level set SMP_STR $_SMP_STR } else { # For single socket per SMP configuration, evaluate the string eval $_SMP_STR } if { [info exists CORE_INDEX_OFFSET] } { # For multi-socket, return total number of cores back to board level set CORE_INDEX_OFFSET $logical_index }