#!/usr/bin/env python
# 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 .

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

import sys, os, IProcUtil
from optparse import OptionParser

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

def error( s ):
   print >> sys.stderr, s
   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 xrange( addr, addr + (n * 4), 4 ):
         if ( count % 8 ) == 0:
            print "%08x:" % addr,
         print "%08x" % iproc.read32( addr ),
         if ( count % 8 ) == 7:
            print
         count += 1
      if ( count % 8 ) > 0:
         print
   else:
      error( 'Use iprocread32, iprocwrite32 or iprocdump instead' )

except ValueError, e:
   error( e )
