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));}'
+
+