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

import Tac, seeprom, twoByteAddrShimSeeprom
import optparse, sys

usage = """
idseeprom [options] read
  Read idprom contents and write to stdout, in binary

idseeprom [options] test
  Write/read destructive test
  
  All numeric arguments can be specified in decimal, hex (prefixed by '0x'),
  or binary (prefixed by '0b')."""

parser = optparse.OptionParser(usage=usage)
parser.add_option( "-v", "--verbose", action="store_true",
                   help="enable verbose output" )
parser.add_option( "--debug", action="store_true",
                   help="enable debugging" )
parser.add_option( "-d", "--device", action="append",
                   help="specify device (bus.address)" )
parser.add_option( "-o", "--offset", action="store",
                   help="offset within seeprom to start from", default='0' )
parser.add_option( "-l", "--length", action="store",
                   help="length, in bytes, to read" )
parser.add_option( "-i", "--iterations", action="store", type="int",
                   help="number of iterations" )
parser.add_option( "-u", "--unlock", action="store_true",
                   help="unlock the mac seeprom" )
parser.add_option("--cpu", action="store", default='napa',
                  help="The cpu system")
parser.add_option( "--twoByteAddrShim", action="store_true", default=False,
                   help="use two-byte addressing for seeprom access. by default"
                   " will only read prefdl" )
( options, args ) = parser.parse_args()
if len( args ) < 1:
   parser.error( "Too few arguments" )

if not options.device:
   parser.error( "Mandatory device missing." )
deviceList = []
if options.device == ["all"]:
   for bank in xrange(80, 88):
      deviceList = deviceList + [ ( 1, bank ) ]
else:
   for device in options.device:
      (busId, seepromId) = device.split(".")
      deviceList = deviceList + [ ( seeprom.strToInt( busId ),
                                    seeprom.strToInt( seepromId ) ) ]

op = args[0]
l = len( args )

if options.offset: 
   offset = seeprom.strToInt( options.offset )
else: 
   offset = 0

if options.length:
   length = seeprom.strToInt( options.length )
else:
   length = 256

if options.iterations and op != "test":
   parser.error( "'iterations' can only be specified with the 'test' operation" )

def readSeeprom( busNum, seepromAddr, readOffset, readLength ):
   if options.twoByteAddrShim:
      return twoByteAddrShimSeeprom.doRead( busNum, seepromAddr, readOffset,
                                            readLength, prefdl=True )
   else:
      return seeprom.doRead( busNum, seepromAddr, readOffset, readLength )

try:
   if op == "read":
      if l != 1:
         parser.error( "Too many arguments" )
      if offset + length > 256:
         parser.error( "offset + length exceeds 256" )
      try:
         for (busId, seepromId ) in deviceList:
            if options.verbose:
               print "reading bus", busId, "device", seepromId, "offset", \
                   offset, "length", length
            sys.stdout.write( readSeeprom( busId, seepromId, offset, length ) )
      except Tac.SystemCommandError, e:
         sys.stdout.write( "Read Error: %s  (Invalid device?)\n" % e )
   else:
      parser.error( "Unknown operation: '" + op + "'" )
finally:
   pass

sys.exit( 0 )

