#!/bin/bash
# name: multi_func_regs_dump
# description: shell for ZTE Dinghai RDMA debug tool
# set -x
interface=""

write32_reg() {
  local reg_addr="$1"
  local reg_value="$2"

  dhtool regsmem "$interface" rdma addr "$reg_addr" "$reg_value" > /dev/null 2>&1

  if [ $? -ne 0 ]; then
    echo "Error: write32_reg $reg_addr to $reg_value failed."
    exit 1
  fi
}

write32_reg_bits() {
  local reg_addr="$1"
  local low_bit="$2"
  local high_bit="$3"
  local bit_value="$4"

  reg_value=$(dhtool_regsmem "$reg_addr")
  mask=$(( (1 << (high_bit - low_bit + 1)) - 1 ))
  mask=$(( mask << low_bit ))
  mask=$(( ~mask ))
  reg_value=$(( reg_value & mask ))
  bit_value=$(( bit_value << low_bit ))
  updated_reg_value=$(( reg_value | bit_value ))

  write32_reg "$reg_addr" "$updated_reg_value"
}


dhtool_regsmem() {
  local reg_addr="$1"
  local output
  local reg_value

  output=$(dhtool regsmem "$interface" rdma addr "$reg_addr")
  reg_value=$(echo "$output" | grep -oP "0x[0-9a-fA-F]+$")
  echo "$reg_value"
}

read32_reg() {
  local reg_addr="$1"
  local reg_value

  reg_value=$(dhtool_regsmem "$reg_addr")
  printf "0x%X: 0x%X\n" "$reg_addr" "$reg_value"
}


multi_func_regs_dump() {
  local input_interface="$1"

  interface="$input_interface"
  read_reg_value=0x6206708090

  write32_reg 0x6206708068 0x0
  read32_reg "$read_reg_value"

  write32_reg 0x6206708068 0x20
  read32_reg "$read_reg_value"

  write32_reg 0x6206708068 0x40
  read32_reg "$read_reg_value"

  write32_reg 0x6206708068 0x1a0
  read32_reg "$read_reg_value"

  write32_reg 0x6206708068 0x1c0
  read32_reg "$read_reg_value"

  write32_reg 0x6206708068 0x1e0
  read32_reg "$read_reg_value"
  
  write32_reg 0x62065f0100 0x1
  read32_reg 0x62065f0aa4
  read32_reg 0x62065f0918
  read32_reg 0x62065f09d0
  read32_reg 0x62065f0a2c
  read32_reg 0x62065f0b94
  read32_reg 0x62065f0804
  write32_reg 0x62065f0100 0x0

  read_reg_value=$(read32_reg 0x62065f0100 > /dev/null 2>&1)
  write32_reg_bits 0x62065f0100 0 0 0x1
  read32_reg 0x62065F0b58
  read32_reg 0x62065F0ae0
  read32_reg 0x62065F07b8
  read32_reg 0x62065F0824
  read32_reg 0x62065F0880
  read32_reg 0x62065F08dc
  read32_reg 0x62065F0938
  read32_reg 0x62065F0994
  read32_reg 0x62065F0a68
  write32_reg 0x62065f0100 $read_reg_value

  read_reg_value=$(read32_reg 0x62065f0100 > /dev/null 2>&1)
  write32_reg_bits 0x62065f0100 4 4 0x0
  read32_reg 0x62065f0f0c
  read32_reg 0x62065f0f10
  write32_reg 0x62065f0100 $read_reg_value

  read_reg_value=$(read32_reg 0x62065f0100 > /dev/null 2>&1)
  write32_reg_bits 0x62065f0100 4 4 0x1
  read32_reg 0x62065f0f1c
  read32_reg 0x62065f0f24
  read32_reg 0x62065f0f0c
  read32_reg 0x62065f0f14 
  read32_reg 0x62065f0f18
  read32_reg 0x62065f0f24
  read32_reg 0x62065f0f28
  write32_reg 0x62065f0100 $read_reg_value

  read_reg_value=$(read32_reg 0x62065f0100 > /dev/null 2>&1)
  write32_reg_bits 0x62065f0100 5 5 0x1
  read32_reg 0x62065f10F8
  read32_reg 0x62065f10FC
  write32_reg 0x62065f0100 $read_reg_value

  read_reg_value=$(read32_reg 0x62065f0100 > /dev/null 2>&1)
  write32_reg_bits 0x62065f0100 0 0 0x1
  read32_reg 0x62065f09F0
  write32_reg 0x62065f0100 $read_reg_value

# Started by AICoder, pid:re455m77cdqc3ef14fd4081410ad472ce7488f60
  output=$(zxdh_get_active_vhca_gqps)
  num_vhcas=$(echo "$output" | grep -c 'vhca:')
  total_gqps=0
  while IFS= read -r line; do
    gqps=$(echo "$line" | grep -oP '(?<=gqps: \[)[^\]]*')
    if [ -z "$gqps" ]; then
      num_gqps=0
    else
      num_gqps=$(echo "$gqps" | tr ',' '\n' | wc -l)
    fi
    total_gqps=$((total_gqps + num_gqps))
  done <<< "$output"

  echo "gqp_num: $total_gqps"
  echo "$output" | while IFS= read -r line; do
    gqps=$(echo "$line" | sed -n 's/.*gqps: \[\(0x[0-9a-fA-F,]*\)\].*/\1/p')
    IFS=',' read -ra gqps_array <<< "$gqps"

    for gqp in "${gqps_array[@]}"; do
      read_reg_value=$(read32_reg 0x620662327c > /dev/null 2>&1)
      write32_reg_bits 0x620662327c 16 26 $gqp
      read32_reg 0x620662327c
      read32_reg 0x62066232e4
      write32_reg_bits 0x6206623298 16 26 1
      read32_reg 0x62066232e4
      write32_reg 0x620662327c $read_reg_value
    done
  done
# Ended by AICoder, pid:re455m77cdqc3ef14fd4081410ad472ce7488f60

  echo "vhca_num: $num_vhcas"
  if [ "$num_vhcas" -gt 0 ]; then
    echo "$output" | while IFS= read -r line; do
      read_reg_value=$(read32_reg 0x6206623328 > /dev/null 2>&1)
      vhca=$(echo "$line" | sed -n 's/.*vhca: \(0x*[0-9a-fA-F]*\).*/\1/p')
      write32_reg_bits 0x6206623328 0 9 "$vhca"
      read32_reg 0x6206623328
      read32_reg 0x6206623338
      write32_reg 0x6206623328 $read_reg_value
    done
  fi
  write32_reg_bits 0x62066232d4 8 9 0x2
  read32_reg 0x62066232e8
  read32_reg 0x62066232f4

  write32_reg_bits 0x62066232d4 8 9 0x3
  read32_reg 0x62066232f0
  read32_reg 0x62066232f4

  write32_reg 0x620660b3d0 0xa0202c0b
  read32_reg 0x620660b240
  write32_reg 0x620660b3d0 0xa0202c00

  write32_reg 0x620660b3d0 0xa0202c0d
  read32_reg  0x620660b248
  write32_reg 0x620660b3d0 0xa0202c00

  write32_reg 0x620660b3d0 0xa0202c0f
  read32_reg 0x620660b250
  write32_reg 0x620660b3d0 0xa0202c00

  write32_reg 0x620660b3d0 0xa0202c11
  read32_reg 0x620660b258
  write32_reg 0x620660b3d0 0xa0202c00

  write32_reg 0x620660b3d0 0xa0202c13
  read32_reg 0x620660b26c
  write32_reg 0x620660b3d0 0xa0202c00

  read_reg_value=$(read32_reg 0x62065f0100 > /dev/null 2>&1)
  write32_reg_bits 0x62065f0100 1 1 0x0
  read32_reg 0x62065f0f5c
  read32_reg 0x62065f0f60
  write32_reg 0x62065f0100 $read_reg_value

  write32_reg_bits 0x62066232d4 8 9 0x2
  read32_reg 0x62066232f0
}
# Started by AICoder, pid:mb1a1pe0ce4bcd314f1c0b74706d562735c93e29
main() {
  if [ -z "$1" ]; then
    echo "Error: Missing arguments for multi_func_regs_dump"
    echo "Usage: $0 multi_func_regs_dump <interface>"
    exit 1
  fi
  command -v dhtool >/dev/null 2>&1 || { echo "dhtool is not available in PATH."; exit 1; }
  multi_func_regs_dump "$1"
}

if [ "$0" = "$BASH_SOURCE" ]; then
  main "$@" 
fi

# Ended by AICoder, pid:mb1a1pe0ce4bcd314f1c0b74706d562735c93e29
