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

"""This script writes the contents of the specified PCI memory resource to standard
output.  It is intended to be used with an output filter such as 'hexdump'."""

import sys, Pci, mmap

def roundToPageSize( addr ):
   ret = ( addr // mmap.PAGESIZE ) * mmap.PAGESIZE
   return ret


def strToInt( s ):
   try:                   
      i = int( s )
   except ValueError:
      i = int( s, 16 )
   return i

if not ( 3 <= len( sys.argv ) <= 5 ): # pylint: disable=superfluous-parens
   print( 'Usage: pcicat <bus:device.function> <resource> [<offset> [<length>]]',
      file=sys.stderr )
   sys.exit( 1 )

try:
   pciId = sys.argv[ 1 ]
   if len( sys.argv ) > 3:
      offset = strToInt( sys.argv[ 3 ] )
   else:
      offset = 0

   if len( sys.argv ) > 4:
      length = strToInt( sys.argv[ 4 ] )
   else:
      length = None

   start = 0
   if sys.argv[ 2 ] == 'config':
      mm = Pci.Device( pciId ).config( readOnly=True ).mmap()
   else:
      resourceNum = int( sys.argv[ 2 ] )
      start = roundToPageSize( offset )
      if length is None:
         end = None
      else:
         end = offset + length
      mm = Pci.Device( pciId ).resource( resourceNum, readOnly=True, 
            startOffset=start, endOffset=end ).mmap()

   newOffset = offset - start
   if length is None:
      sys.stdout.write( mm[ newOffset: ] )
   else:
      sys.stdout.write( mm[ newOffset : newOffset + length ] )

except ValueError as e:
   print( e, file=sys.stderr )
   sys.exit( 1 )

