#!/usr/bin/env python
# Copyright (c) 2006 Arastra, Inc.  All rights reserved.
# Arastra, Inc. Confidential and Proprietary.

# Note: this script is installed with six symlinks, named:
#   /usr/bin/pciread8
#   /usr/bin/pciread16
#   /usr/bin/pciread32
#   /usr/bin/pciwrite8
#   /usr/bin/pciwrite16
#   /usr/bin/pciwrite32

import sys, os, PciUtil

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 )

progname = os.path.basename( sys.argv[ 0 ] )
if progname == 'pciread8':
   command = 'read'
   size = 8
elif progname == 'pciread16':
   command = 'read'
   size = 16
elif progname == 'pciread32':
   command = 'read'
   size = 32
elif progname == 'pciwrite8':
   command = 'write'
   size = 8
elif progname == 'pciwrite16':
   command = 'write'
   size = 16
elif progname == 'pciwrite32':
   command = 'write'
   size = 32
else:
   error( 'Use pciread8, pciread16, pciread32, pciwrite8, pciwrite16 or pciwrite32 '
          'instead' )

if command == 'read':
   if len( sys.argv ) != 4:
      error( 'Usage: %s <bus:device.function> <resource> <address>' % progname )
else:
   if len( sys.argv ) != 5:
      error( 'Usage: %s <bus:device.function> <resource> <address> <value>' 
               % progname )

try:
   pciId = sys.argv[ 1 ]
   addr = PciUtil.strToInt( sys.argv[ 3 ] )

   if sys.argv[ 2 ] == 'config':
      resource = 'config'
   else:
      resource = int( sys.argv[ 2 ] )

   if command == 'read':
      if size == 8:
         value = PciUtil.read8( pciId, resource, addr )
         print "%#04x ==" % value, binary( value, 1 )
      elif size == 16:
         value = PciUtil.read16( pciId, resource, addr )
         print "%#06x ==" % value, binary( value, 2 )
      else:
         value = PciUtil.read32( pciId, resource, addr )
         print "%#010x ==" % value, binary( value, 4 )

   else:
      value = PciUtil.strToInt( sys.argv[ 4 ] )
      if size == 8:
         PciUtil.write8( pciId, resource, addr, value )
      elif size == 16:
         PciUtil.write16( pciId, resource, addr, value )
      else:
         PciUtil.write32( pciId, resource, addr, value )

except ValueError, e:
   error( e )
