#!/bin/bash
#****************************************************************************
# Copyright (c) 2024 xFusion Digital Technologies Co., Ltd. All rights reserved.
# Description: A script to simulate various fault scenarios for kernel testing.
# Author: xFusion Digital Technologies Co., Ltd.
# Create: 2024-10-18
#****************************************************************************

# Custom fault code list
FCODE_LIST=(
    "1001) OS_PC_NMI_INTER"
    "1002) OS_PC_ACCESS_NPTR"
    "1003) OS_PC_DIVIDE_ERR_FAULT"
    "1004) OS_PC_OVERFLOW_TRAP"
    "1005) OS_PC_BR_EXCEEDED_FAULT"
    "1006) OS_PC_INVALID_OP_FAULT"
    "1007) OS_PC_COPR_SEG_OVERRUN_FAULT"
    "1008) OS_PC_INVALID_TSS_FAULT"
    "1009) OS_PC_SEG_NPRESENT_FAULT"
    "1010) OS_PC_STACK_SEG_FAULT"
    "1011) OS_PC_GENERAL_PROT_FAULT"
    "1012) OS_PC_ALIGNMENT_CHK_FAULT"

    "2001) OS_IC_NMI_INTER"
    "2002) OS_IC_ACCESS_NPTR"
    "2003) OS_IC_DIVIDE_ERR_FAULT"
    "2004) OS_IC_OVERFLOW_TRAP"
    "2005) OS_IC_BR_EXCEEDED_FAULT"
    "2006) OS_IC_INVALID_OP_FAULT"
    "2007) OS_IC_COPR_SEG_OVERRUN_FAULT"
    "2008) OS_IC_INVALID_TSS_FAULT"
    "2009) OS_IC_SEG_NPRESENT_FAULT"
    "2010) OS_IC_STACK_SEG_FAULT"
    "2011) OS_IC_GENERAL_PROT_FAULT"
    "2012) OS_IC_ALIGNMENT_CHK_FAULT"
    "2013) OS_IC_CALL_PANIC"
    "2014) OS_IC_CALL_PANIC_MASK_INT"

    "3001) OS_DEAD_KERNEL_LOOP_FAULT"
    "3002) OS_DEAD_R_LOCK_FAULT"
    "3003) OS_DEAD_D_LOCK_FAULT"

    "8001) OS_MACHINE_EMERGE_RESTART"
    "8002) OS_KERNEL_POWER_OFF"
    "8003) OS_KERNEL_RESTART"
    "8004) OS_KERNEL_HALT"
    "8005) OS_EMERGE_RESTART"
    "8006) OS_CALL_PANIC"
    "8007) OS_SERI_CALL_PANIC"
    "8008) OS_SERI_PANIC_KERNEL_RESTART"
    "8009) OS_SERI_MACHINE_EMERGE_RESTART"
    "8010) OS_SERI_KERNEL_POWER_OFF"
    "8011) OS_SERI_KERNEL_RESTART"
    "8012) OS_SERI_KERNEL_HALT"
    "8013) OS_SERI_EMERGE_RESTART"
    "8014) OS_OOM"
    "8015) OS_SERI_OOM"
    "8016) OS_PARA_PANIC"
    "8017) OS_PARA_PANIC_OOM"
    "8018) OS_SERI_PANIC_OOM"
    "8019) OS_PARA_OOM"
    "8020) OS_PARA_RESTART"
    "8021) OS_PARA_RESTART_OOM"
    "8022) OS_PARA_RESTART_PANIC"
    "8023) OS_PRINTK_MANYMESSAGE"
    "8024) OS_SHOW_REGITERS"
    "8025) OS_SERI_OOPS"
    "8026) OS_PARA_OOPS"
    "8027) OS_PARA_OOPS_PANIC"
    "8028) OS_PARA_OOPS_OOM"
    "8029) OS_PARA_OOPS_RESTART"
    "8030) OS_PARA_OOPS_SAME_CPU"
    "8031) OS_PARA_OOM_SAME_CPU"
    "8032) OS_PARA_OOPS_PANIC_SAME_CPU"
    "8033) OS_PARA_OOM_PANIC_SAME_CPU"
    "8034) OS_PARA_EMERGE_PANIC_SAME_CPU"
    "8035) OS_PARA_EMERGE_OOPS_SAME_CPU"
    "8036) OS_PARA_OOPS_SAME_CPU_I"
    "8037) OS_PARA_OOM_SAME_CPU_I"
    "8038) OS_PARA_OOPS_PANIC_SAME_CPU_I"
    "8039) OS_PARA_OOM_PANIC_SAME_CPU_I"
    "8040) OS_PARA_EMERGE_PANIC_SAME_CPU_I"
    "8041) OS_PARA_EMERGE_OOPS_SAME_CPU_I"
    "8042) OS_PARA_OOPS_OOPS_I"
    "8043) OS_PARA_OOPS_PANIC_I"
    "8044) OS_PARA_PANIC_PANIC_I"
    "8045) OS_PARA_OOPS_SAME_CPU_PANIC"
    "8046) OS_PARA_OOM_SAME_CPU_PANIC"
    "8047) OS_PARA_OOM_OOPS_PANIC"
    "8055) OS_DISABLE_IRQ"
    "8056) OS_DISABLE_SCHED"
    "8059) OS_VMALLOC_OOM"
    "8060) OS_KMALLOC_OOM"
    "8061) OS_OUT_OF_STACK_OOPS_1"
    "8062) OS_OUT_OF_STACK_OOPS_2"
    "8063) OS_NMI_WATCHDOG_PANIC"
    "8064) OS_EMERGE_RESTART_INT"
)

# Function to display the custom list of fault codes
show_codes()
{
    for code in "${FCODE_LIST[@]}"; do
        echo "$code"
    done
}

DEV_NAME="/dev/kpgen"
kpgen_adm_alarm_id=1032
# Function to simulate the fault for a given error code
send_code()
{
    local code=$1
    if [[ -c "$DEV_NAME" ]]; then
        echo $code > $DEV_NAME
        command -v sendalarm &> /dev/null && \
            sendalarm -i $kpgen_adm_alarm_id -t event -l 4 -m "kpgen_adm: send code=$code" -e "$0"
    fi
}

# Function to display help information
show_help()
{
    echo "Usage: $1 [OPTION]"
    echo "Options:"
    echo "  -l    Display list of code names."
    echo "  -e <code> Simulate the fault for a given error code (1000-9000)."
    echo "  -h    Display this help message."
}

# Main script logic
if [[ $# -le 1 && x$1 != x"-l" && x$1 != x"-h" ]]; then
    show_help $0
    exit 1
fi

while getopts "le:h" opt; do
    case $opt in
        l)
            show_codes
            ;;
        e)
            send_code $OPTARG
            ;;
        h)
            show_help $0
            ;;
        *)
            show_help $0
            exit 1
            ;;
    esac
done
