#!/usr/bin/env python3
# Copyright (c) 2014 Arista Networks, Inc.  All rights reserved.
# Arista Networks, Inc. Confidential and Proprietary.
#
# Read and Write Broadcom iProc chip addresses.
# Like pciutil for iProc .

# pylint: disable=consider-using-f-string

# Note: this script is installed with symlinks:
#   /usr/bin/iprocread32
#   /usr/bin/iprocwrite32
#   /usr/bin/iprocdump

import sys, os, IProcUtil
from optparse import OptionParser # pylint: disable=deprecated-module

def binary( integerValue, nbytes=4 ):
   return "".join( [ ( ( integerValue>>_n & 1 ) and "1" or "0" ) +
      ( ( _n % 4 == 0 ) and " " or "" )
      for _n in range( nbytes*8-1,-1,-1 ) ] )

def error( s ):
   print( s, file=sys.stderr )
   sys.exit( 1 )

usage = '''%prog [ options ] <pci-device-id> <iproc_bus_address> [ args ]'''

cmd = os.path.basename( sys.argv[ 0 ] )

parser = OptionParser( usage=usage )
parser.add_option( "--subwin", type="int",
   help="BAR0 subwindow number to use (0-7)",
   default=5 )

( opts, args ) = parser.parse_args()

if len( args) < 2:
   error( 'Usage: %s <pci-device-id> <address> ..' % cmd )

try:
   pcidev = args[ 0 ]
   addr = int( args[ 1 ], 0 )

   iproc = IProcUtil.IProc( pcidev, subwin=opts.subwin )

   if cmd == 'iprocread32':
      if len( args) != 2:
         error( 'Usage: %s <pci-device-id> <address>' % cmd )
      value = iproc.read32( addr )
      print( "%#010x ==" % value, binary( value, 4 ) )
   elif cmd == 'iprocwrite32':
      if len( args) != 3:
         error( 'Usage: %s <pci-device-id> <address> <value>' % cmd )
      value = int( args[ 2 ], 0 )
      iproc.write32( addr, value )
   elif cmd == 'iprocdump':
      if len( args) != 3:
         error( 'Usage: %s <pci-device-id> <address> <length>' % cmd )
      n = int( args[ 2 ], 0 )
      count = 0
      for addr in range( addr, addr + ( n * 4 ), 4 ):
         if ( count % 8 ) == 0:
            print( "%08x:" % addr, end=' ' )
         print( "%08x" % iproc.read32( addr ), end=' ' )
         if ( count % 8 ) == 7:
            print()
         count += 1
      if ( count % 8 ) > 0:
         print()
   else:
      error( 'Use iprocread32, iprocwrite32 or iprocdump instead' )

except ValueError as e:
   error( e )
