Library to get FIR address translation through HOST OS.
Resolves openbmc/openbmc-test-automation#1033
Change-Id: I33501fc9ba4a12b289096820f14874a50566c38c
Signed-off-by: Sridevi Ramesh <sridevra@in.ibm.com>
diff --git a/extended/test_host_ras.robot b/extended/test_host_ras.robot
index c002c63..8f6c0de 100755
--- a/extended/test_host_ras.robot
+++ b/extended/test_host_ras.robot
@@ -11,6 +11,8 @@
Library DateTime
Library OperatingSystem
+Library random
+Library Collections
Suite Setup RAS Suite Setup
Test Setup RAS Test Setup
@@ -44,7 +46,6 @@
Inject Recoverable Error With Threshold Limit Through Host
... ${value[0]} ${value[1]} 32 ${value[2]} ${err_log_path}
-
Verify Unrecoverable Callout Handling For MCA
[Documentation] Verify unrecoverable callout handling for MCACALIFIR.
[Tags] Verify_Unrecoverable_Callout_Handling_For_MCA
@@ -76,6 +77,15 @@
... ${value[0]} ${value[1]} 1 ${value[2]} ${err_log_path}
+Verify Unrecoverable Callout Handling For NXDMAENG
+ [Documentation] Verify unrecoverable callout handling for NXDMAENG.
+ [Tags] Verify_Unrecoverable_Callout_Handling_For_NXDMAENG
+
+ ${value}= Get From Dictionary ${ERROR_INJECT_DICT} NX_UE
+ ${err_log_path}= Catenate ${RAS_LOG_DIR_PATH}nxfir_ue
+ Inject Unrecoverable Error Through Host
+ ... ${value[0]} ${value[1]} 1 ${value[2]} ${err_log_path}
+
# CAPP accelerator (CXAFIR) related error injection.
Verify Recoverable Callout Handling For CXA With Threshold 5
@@ -162,9 +172,9 @@
... 1. Boot To HOST
... 2. Clear any existing gard records
... 3. Inject Error on processor/centaur
- [Arguments] ${fri} ${chip_address} ${threshold_limit}
+ [Arguments] ${fir} ${chip_address} ${threshold_limit}
# Description of argument(s):
- # fri FRI value (e.g. 2011400).
+ # fir FIR (Fault isolation register) value (e.g. 2011400).
# chip_address chip address (e.g 2000000000000000).
# threshold_limit Threshold limit (e.g 1, 5, 32).
@@ -173,13 +183,13 @@
Gard Operations On OS clear all
# Fetch processor chip IDs.
- ${chip_ids}= Get ChipID From OS Processor
+ ${chip_ids}= Get ProcChipId From OS Processor
${proc_ids}= Split String ${chip_ids}
${proc_id}= Get From List ${proc_ids} 1
${threshold_limit}= Convert To Integer ${threshold_limit}
:FOR ${i} IN RANGE ${threshold_limit}
- \ Run Keyword Putscom Through OS ${proc_id} ${fri} ${chip_address}
+ \ Run Keyword Putscom Operations On OS ${proc_id} ${fir} ${chip_address}
# Adding delay after each error injection.
\ Sleep 10s
# Adding delay to get error log after error injection.
@@ -188,7 +198,6 @@
Verify And Clear Gard Records On HOST
[Documentation] Verify And Clear gard records on HOST.
- Login To OS Host
${output}= Gard Operations On OS list
Should Not Contain ${output} 'No GARD entries to display'
Gard Operations On OS clear all
@@ -218,17 +227,17 @@
... 3. Check If HOST is running.
... 4. Verify error log entry & signature description.
... 4. Verify & clear gard records.
- [Arguments] ${fri} ${chip_address} ${threshold_limit}
+ [Arguments] ${fir} ${chip_address} ${threshold_limit}
... ${signature_desc} ${log_prefix}
# Description of argument(s):
- # fri FRI(Fault isolation register) value (e.g. 2011400).
+ # fir FIR (Fault isolation register) value (e.g. 2011400).
# chip_address Chip address (e.g 2000000000000000).
# threshold_limit Threshold limit (e.g 1, 5, 32).
# signature_desc Error log signature description.
# log_prefix Log path prefix.
Set Auto Reboot 1
- Inject Error Through HOST ${fri} ${chip_address} ${threshold_limit}
+ Inject Error Through HOST ${fir} ${chip_address} ${threshold_limit}
Is Host Running
${output}= Gard Operations On OS list
Should Contain ${output} No GARD
@@ -244,10 +253,10 @@
... 3. Check If HOST is rebooted.
... 4. Verify error log entry & signature description.
... 4. Verify & clear gard records.
- [Arguments] ${fri} ${chip_address} ${threshold_limit}
+ [Arguments] ${fir} ${chip_address} ${threshold_limit}
... ${signature_desc} ${log_prefix}
# Description of argument(s):
- # fri FRI value (e.g. 2011400).
+ # fir FIR (Fault isolation register) value (e.g. 2011400).
# chip_address Chip address (e.g 2000000000000000).
# threshold_limit Threshold limit (e.g 1, 5, 32).
# signature_desc Error Log signature description.
@@ -255,12 +264,34 @@
# log_prefix Log path prefix.
Set Auto Reboot 1
- Inject Error Through HOST ${fri} ${chip_address} ${threshold_limit}
+ Inject Error Through HOST ${fir} ${chip_address} ${threshold_limit}
Wait Until Keyword Succeeds 500 sec 20 sec Is Host Rebooted
Wait for OS
Verify And Clear Gard Records On HOST
Verify Error Log Entry ${signature_desc} ${log_prefix}
+Fetch FIR Address Translation Value
+ [Documentation] Fetch FIR address translation value through HOST.
+ [Arguments] ${proc_chip_id} ${fir} ${target_type}
+ # Description of argument(s):
+ # proc_chip_id Processor chip ID (e.g '0', '8').
+ # fir FIR (Fault isolation register) value (e.g. 2011400).
+ # core_id Core ID (e.g. 9).
+ # target_type Target type (e.g. 'EX', 'EQ', 'C').
+
+ Login To OS Host
+ Copy Address Translation Utils To HOST OS
+
+ ${core_ids}= Get Core IDs From OS 0
+ # Ignoring master core ID.
+ ${output}= Get Slice From List ${core_ids} 1
+ # Feth random non-master core ID.
+ ${core_ids_sub_list}= Evaluate random.sample(${core_ids}, 1) random
+ ${core_id}= Get From List ${core_ids_sub_list} 0
+ ${translated_fir_addr}= FIR Address Translation Through HOST
+ ... ${fir} ${core_id} ${target_type}
+
+ [Return] ${translated_fir_addr}
RAS Test SetUp
[Documentation] Validates input parameters.
@@ -273,8 +304,9 @@
... ${OS_PASSWORD} msg=You must provide OS host user password.
# Boot to OS.
-
REST Power On quiet=${1}
+ # Adding delay to after host bring up.
+ Sleep 60s
RAS Suite Setup
[Documentation] Create RAS log directory to store all RAS test logs.
@@ -292,5 +324,4 @@
# Boot to OS.
REST Power On quiet=${1}
Delete Error Logs
- Login To OS Host
Gard Operations On OS clear all
diff --git a/lib/ras/host_utils.robot b/lib/ras/host_utils.robot
index 1d332ee..ddfec43 100644
--- a/lib/ras/host_utils.robot
+++ b/lib/ras/host_utils.robot
@@ -2,6 +2,8 @@
Documentation This module is for OS checkstop opertions.
Resource ../../lib/rest_client.robot
Resource ../../lib/utils.robot
+Resource ../../lib/ras/variables.py
+Resource ../../lib/bmc_ssh_utils.py
Library OperatingSystem
*** Keywords ***
@@ -14,8 +16,7 @@
# input_cmd -l|--list-chips
# -c|--chip <chip-id> <addr>
- ${output} ${stderr}= Execute Command getscom ${input_cmd}
- ... return_stderr=True
+ ${output} ${stderr} ${rc}= OS Execute Command getscom ${input_cmd}
Should Be Empty ${stderr}
[Return] ${output}
@@ -26,36 +27,64 @@
# Description of arguments:
# input_cmd list/clear all/show <gard_record_id>
- ${output} ${stderr}= Execute Command opal-gard ${input_cmd}
- ... return_stderr=True
+ ${output} ${stderr} ${rc}= OS Execute Command opal-gard ${input_cmd}
Should Be Empty ${stderr}
[Return] ${output}
-Putscom Through OS
+Putscom Operations On OS
[Documentation] Executes putscom command on OS with the given
... input arguments.
- [Arguments] ${chip_id} ${fru} ${address}
+ [Arguments] ${proc_chip_id} ${fru} ${address}
# Description of arguments:
- # chip_id processor ID (e.g 00000000).
+ # proc_chip_id Processor ID (e.g '0', '8').
# fru FRU value (e.g. 2011400).
- # address chip address (e.g 4000000000000000).
+ # address Chip address (e.g 4000000000000000).
- ${cmd}= Catenate putscom -c 0x${chip_id} 0x${fru} 0x${address}
+ ${cmd}= Catenate putscom -c 0x${proc_chip_id} 0x${fru} 0x${address}
Start Command ${cmd}
-Get Cores Values From OS
- [Documentation] Check if cores present on HOST OS & return core values.
- ${cmd}= Catenate cat /sys/firmware/opal/msglog|grep -i chip|grep -i core
- ${output}= Execute Command ${cmd}
- Should Not Be Empty ${output}
- [Return] ${output}
-
-Get ChipID From OS
- [Documentation] Get chip ID values based on the input.
+Get ProcChipId From OS
+ [Documentation] Get processor chip ID values based on the input.
[Arguments] ${chip_type}
# Description of arguments:
# chip_type The chip type (Processor/Centaur).
${cmd}= Catenate -l | grep -i ${chip_type} | cut -c1-8
- ${chip_id}= Getscom Operations On OS ${cmd}
- [Return] ${chip_id}
+ ${proc_chip_id}= Getscom Operations On OS ${cmd}
+ # Example output:
+ # 00000008
+ # 00000000
+ [Return] ${proc_chip_id}
+
+Get Core IDs From OS
+ [Documentation] Get Core IDs corresponding to the input processor chip ID.
+ [Arguments] ${proc_chip_id}
+ # Description of argument(s):
+ # proc_chip_id Processor ID (e.g '0', '8').
+
+ ${cmd}= Catenate set -o pipefail ; ${probe_cpu_file_path}
+ ... | grep -i 'CHIP ID: ${proc_chip_id}' | cut -c21-22
+ ${output} ${stderr} ${rc}= OS Execute Command ${cmd}
+ Should Be Empty ${stderr}
+ ${core_ids}= Split String ${output}
+ # Example output:
+ # ['2', '3', '4', '5', '6']
+ [Return] ${core_ids}
+
+FIR Address Translation Through HOST
+ [Documentation] Do FIR address translation through host for given FIR,
+ ... core value & target type.
+ [Arguments] ${fir} ${core_id} ${target_type}
+ # Description of argument(s):
+ # fir FIR (Fault isolation register) value (e.g. 2011400).
+ # core_id Core ID (e.g. 9).
+ # target_type Target type (e.g. 'EQ', 'EX', 'C').
+
+ ${cmd}= Catenate set -o pipefail ; ${addr_translation_file_path} ${fir}
+ ... ${core_id} | grep -i ${target_type}
+ ${output} ${stderr} ${rc}= OS Execute Command ${cmd}
+ Should Be Empty ${stderr}
+ ${translated_addr}= Split String ${output} :${SPACE}0x
+ # Example output:
+ # 0x10010c00
+ [Return] ${translated_addr[1]}
diff --git a/lib/ras/variables.py b/lib/ras/variables.py
index cf5f100..bf69188 100644
--- a/lib/ras/variables.py
+++ b/lib/ras/variables.py
@@ -22,6 +22,17 @@
DES_NPU0_RECV32 = "'pu.n0p0.*NPU0FIR[^13].*CQ CTL/SM ASBE Array single'"
+DES_L2_RECV1 = "'L2FIR[^8].*L2 directory CE'"
+DES_L2_RECV32 = "'L2FIR[^6].*L2 directory read CE'"
+
+DES_L3_RECV1 = "'L3FIR[^17].*Received addr_error cresp'"
+DES_L3_RECV32 = "'L3FIR[^7].*L3 cache write data CE'"
+
+DES_OCC_RECV1 = "'OCCFIR[^45].*C405_ECC_CE'"
+DES_CME_RECV1 = "'CMEFIR[^7].*PPE SRAM Uncorrectable Err'"
+DES_EQ_RECV32 = "'EQ_LFIR[^0].*CFIR internal parity'"
+DES_NCU_RECV1 = "'NCUFIR[^8].*NCU Store Queue Data'"
+
# The following is an error injection dictionary with each entry consisting of:
# - field_name: Targettype_threshold_limit .
# - A list consisting of the following fields:
@@ -42,6 +53,20 @@
'CXA_RECV5': ['02010800', '0000000020000000', DES_CXA_RECV5],
'CXA_RECV32': ['02010800', '2000000000000000', DES_CXA_RECV32],
'OBUS_RECV32': ['0904000a', '8000000000000000', DES_OBUS_RECV32],
- 'NPU0_RECV32': ['05013C00', '0004000000000000', DES_NPU0_RECV32]
+ 'NPU0_RECV32': ['05013C00', '0004000000000000', DES_NPU0_RECV32],
+ 'L2FIR_RECV1': ['10010800', '0080000000000000', DES_L2_RECV1],
+ 'L2FIR_RECV32': ['10010800', '0200000000000000', DES_L2_RECV32],
+ 'L2FIR_UE': ['10010800', '4000000000000000', ''],
+ 'L3FIR_RECV1': ['10011800','0000400000000000', DES_L3_RECV1],
+ 'L3FIR_RECV32': ['10011800', '0100000000000000', DES_L3_RECV32],
+ 'L3FIR_UE': ['10011800', '0100000000000000', ''],
+ 'OCCFIR_RECV1': ['01010800', '0000000000040000', DES_OCC_RECV1],
+ 'CMEFIR_RECV1': ['10012000', '0100000000000000', DES_CME_RECV1],
+ 'EQFIR_RECV32': ['1004000A', '4000000000000000', DES_EQ_RECV32],
+ 'NCUFIR_RECV1': ['10011400', '0080000000000000', DES_NCU_RECV1],
+
}
+# Address translation files
+probe_cpu_file_path = '/root/probe_cpus.sh'
+addr_translation_file_path = '/root/scom_addr_p9.sh'
diff --git a/lib/utils.robot b/lib/utils.robot
index a341459..04ef793 100755
--- a/lib/utils.robot
+++ b/lib/utils.robot
@@ -13,6 +13,7 @@
Library bmc_ssh_utils.py
Library utils.py
Library var_funcs.py
+Library SCPLibrary WITH NAME scp
*** Variables ***
${pflash_cmd} /usr/sbin/pflash -r /dev/stdout -P VERSION
@@ -52,6 +53,10 @@
@{valid_power_policy_vars} RESTORE_LAST_STATE ALWAYS_POWER_ON
... ALWAYS_POWER_OFF
+${probe_cpu_tool_path} ${EXECDIR}/tools/ras/probe_cpus.sh
+${scom_addrs_tool_path} ${EXECDIR}/tools/ras/scom_addr_p9.sh
+${target_file_path} /root/
+
*** Keywords ***
Check BMC Performance
@@ -1180,7 +1185,6 @@
${valueDict}= Create Dictionary data=${setting}
Write Attribute ${SENSORS_URI}host/TurboAllowed value data=${valueDict}
-
Set Control Boot Mode
[Documentation] Set given boot mode on the boot object path attribute.
[Arguments] ${boot_path} ${boot_mode}
@@ -1196,3 +1200,16 @@
${valueDict}= Create Dictionary data=${boot_mode}
Write Attribute ${boot_path} BootMode data=${valueDict}
+
+Copy Address Translation Utils To HOST OS
+ [Documentation] Copy address translation utils to host OS.
+
+ OperatingSystem.File Should Exist ${probe_cpu_tool_path}
+ ... msg=${probe_cpu_tool_path} doesn't exist.
+ OperatingSystem.File Should Exist ${probe_cpu_tool_path}
+ ... msg=${probe_cpu_tool_path} doesn't exist.
+
+ scp.Open connection ${OS_HOST} username=${OS_USERNAME}
+ ... password=${OS_PASSWORD}
+ scp.Put File ${probe_cpu_tool_path} ${target_file_path}
+ scp.Put File ${scom_addrs_tool_path} ${target_file_path}
diff --git a/tools/ras/probe_cpus.sh b/tools/ras/probe_cpus.sh
new file mode 100755
index 0000000..33710ea
--- /dev/null
+++ b/tools/ras/probe_cpus.sh
@@ -0,0 +1,199 @@
+#!/bin/bash
+
+CPU_SYS_DIR=/sys/devices/system/cpu/
+NR_CPUS=0
+CPU=
+SHOW_LAYOUT=0
+
+
+function usage()
+{
+ echo "usage:"
+ echo " $0 [cpu] [-L]"
+ echo
+ echo "option:"
+ echo " [cpu]"
+ echo " Logical cpu id."
+ echo " -L"
+ echo " Show processor layout."
+ echo " -h"
+ echo " Show this help."
+ exit 1
+}
+
+function parse_args()
+{
+ while getopts "hL" OPTION
+ do
+ case $OPTION in
+ L)
+ SHOW_LAYOUT=1
+ ;;
+ *)
+ usage
+ exit 1
+ ;;
+ esac
+ done
+
+ CPU=${!OPTIND}
+}
+
+parse_args $*
+
+[ "$1" == "-h" ] && usage
+
+declare -a CPUS
+declare -a CPU_FILE
+declare -a CPU_PIR
+declare -a CORE_ID
+declare -a CHIP_ID
+
+declare -a CHIP_EQ
+declare -a CHIP_EX
+declare -a CHIP_CORES
+
+declare -A CORE_MATRIX
+
+for cpu_file in $(find $CPU_SYS_DIR -name "cpu[0-9]*")
+do
+ cpu=$(basename $cpu_file | tr -dc '0-9')
+ [ -n "$cpu" ] && NR_CPUS=$(expr $NR_CPUS + 1)
+
+ CPU_VALID[$cpu]=0
+ [ -n "$CPU" ] && [ $cpu != $CPU ] && continue
+ [ ! -e $cpu_file/pir ] && continue
+
+ CPU_VALID[$cpu]=1
+
+ CPU_FILE[$cpu]=$cpu_file
+ pir=$(cat $cpu_file/pir)
+ CPU_PIR[$cpu]=$pir
+ CORE_ID[$cpu]=$(perl -e '{ printf("%d", (0x'$pir' >> 2) & 0x3f); }')
+ CHIP_ID[$cpu]=$(perl -e '{ printf("%x", (0x'$pir' >> 8) & 0x7f); }')
+done
+
+i=0
+chip_id=-1
+core_id=-1
+prev_eq_id=-1
+prev_ex_id=-1
+num_threads=0
+CPU_LIST=" "
+while [ $i -lt $NR_CPUS ]
+do
+ [ ${CPU_VALID[$i]} -eq 0 ] && i=$(expr $i + 1) && continue
+
+ [ "$chip_id" != "${CHIP_ID[$i]}" ] && core_id=-1 && prev_eq_id=-1 && prev_ex_id=-1
+ chip_id=${CHIP_ID[$i]}
+ if [ "$core_id" != ${CORE_ID[$i]} ]
+ then
+ if [ $num_threads -ne 0 ]; then
+ echo "THREADS: $num_threads CPUs: $CPU_LIST"
+ CPU_LIST=" "
+ fi
+ CPU_LIST="$CPU_LIST$i "
+ echo -n "CHIP ID: ${CHIP_ID[$i]} "
+ echo -n "CORE ID: ${CORE_ID[$i]} "
+ CHIP_CORES[$chip_id]="${CHIP_CORES[$chip_id]},${CORE_ID[$i]}"
+ CORE_MATRIX[$chip_id,${CORE_ID[$i]}]=1
+ eq_id=$(perl -e '{ printf("%d", (('${CORE_ID[$i]}' & 0x1c) >> 2)); }')
+ if [ $eq_id != $prev_eq_id ]
+ then
+ CHIP_EQ[$chip_id]="${CHIP_EQ[$chip_id]},$eq_id"
+ prev_eq_id=$eq_id
+ fi
+ ex_id=$(perl -e '{ printf("%d", (('${CORE_ID[$i]}') >> 1)); }')
+ if [ $ex_id != $prev_ex_id ]
+ then
+ CHIP_EX[$chip_id]="${CHIP_EX[$chip_id]},$ex_id"
+ prev_ex_id=$ex_id
+ fi
+ num_threads=1
+ else
+ CPU_LIST="$CPU_LIST$i "
+ num_threads=$(expr $num_threads + 1)
+ fi
+ core_id=${CORE_ID[$i]}
+
+ i=$(expr $i + 1)
+done
+echo "THREADS: $num_threads CPUs: $CPU_LIST"
+
+echo
+echo "-----------------------------"
+for chip_id in ${!CHIP_CORES[@]}
+do
+ echo "p[$chip_id]"
+ CHIP_CORES[$chip_id]="$(echo ${CHIP_CORES[$chip_id]} | cut -c 2-)"
+ CHIP_EQ[$chip_id]="$(echo ${CHIP_EQ[$chip_id]} | cut -c 2-)"
+ CHIP_EX[$chip_id]="$(echo ${CHIP_EX[$chip_id]} | cut -c 2-)"
+ echo " eq[${CHIP_EQ[$chip_id]}]"
+ echo " ex[${CHIP_EX[$chip_id]}]"
+ echo " c[${CHIP_CORES[$chip_id]}]"
+done
+echo "-----------------------------"
+
+
+[ $SHOW_LAYOUT -eq 0 ] && exit
+
+# Print chip layout
+
+function print_header()
+{
+ local _row_=$1
+
+ for q in 0 2 4
+ do
+ quad=$(perl -e '{ printf("%02d", ('$q' + '$_row_')); }')
+ echo -n " +---EQ$quad----+ "
+ done
+ echo
+}
+
+function print_core_info()
+{
+ local _row_=$1
+ local _cpos_=$2 # Core position
+
+ for q in 0 2 4
+ do
+ quad=$(perl -e '{ printf("%02d", ('$q' + '$_row_')); }')
+ core_id=$(perl -e '{ printf("%d", ('$_cpos_' + ('$quad' * 4))); }')
+ core_id_str=$(perl -e '{ printf("%-2d", ('$_cpos_' + ('$quad' * 4))); }')
+ ex=$(perl -e '{ printf("%-2d", ('$core_id' >> 1)); }')
+ if [ -n "${CORE_MATRIX[$chip_id,$core_id]}" ]
+ then
+ echo -n " |EX-$ex C$core_id_str|"
+ else
+ echo -n " | |"
+ fi
+ done
+ echo
+ if [ $_cpos_ -eq 3 ]
+ then
+ echo " +-----------+ +-----------+ +-----------+"
+ else
+ echo " + - - - - - + + - - - - - + + - - - - - +"
+ fi
+}
+
+echo
+echo "----------Processor Layout-------------------"
+for chip_id in ${!CHIP_CORES[@]}
+do
+ echo "p[$chip_id]"
+
+ for row in 0 1
+ do
+ print_header $row
+ for core_pos in 0 1 2 3
+ do
+ print_core_info $row $core_pos
+ done
+ echo
+
+ done
+ echo
+
+done
diff --git a/tools/ras/scom_addr_p9.sh b/tools/ras/scom_addr_p9.sh
new file mode 100755
index 0000000..e0b8098
--- /dev/null
+++ b/tools/ras/scom_addr_p9.sh
@@ -0,0 +1,30 @@
+#!/bin/bash
+
+function usage()
+{
+ echo
+ echo "usage: $0: <scom_addr> <core-id>"
+ echo
+ echo " <scom_addr>:"
+ echo " SCOM address that needs transaltion."
+ echo " <core-id>:"
+ echo " Core id as obtained from probe_cpu.sh."
+ echo " Should be between 0-23."
+ exit 1
+}
+
+[ $# -lt 2 ] && usage
+
+SCOM_ADDR=$1
+SCOM_ADDR=$(echo $SCOM_ADDR | sed 's/^0x//')
+CORE_ID=$2
+CORE_ID=$(echo $CORE_ID | sed 's/^0x//')
+
+[ $CORE_ID -gt 23 ] && echo "<core-id> should be between 0-23" && exit
+
+# per Chip level
+perl -e '{printf("EQ[%2d]: 0x%x\n", ((('$CORE_ID' & 0x1c)) >> 2), 0x'$SCOM_ADDR' | ((('$CORE_ID' & 0x1c) + 0x40) << 22));}'
+perl -e '{printf("EX[%2d]: 0x%x\n", ((('$CORE_ID')) >> 1), (0x'$SCOM_ADDR' | (('$CORE_ID' & 2) << 9 )) | ((('$CORE_ID' & 0x1c) + 0x40) << 22));}'
+perl -e '{printf(" C[%2d]: 0x%x\n", '$CORE_ID', 0x'$SCOM_ADDR' | ((('$CORE_ID' & 0x1f) + 0x20) << 24));}'
+
+