#!/usr/bin/env python3
# Copyright (c) 2009-2011 Arista Networks, Inc.  All rights reserved.
# Arista Networks, Inc. Confidential and Proprietary.

import os, optparse, sys # pylint: disable=deprecated-module
import EntityManager, PciUtil

bytesToCheck = { 0: (1,2,3),
                 1: (0,2,3),
                 2: (0,1,3),
                 3: (0,1,2)
                }

# pylint: disable-next=redefined-builtin,redefined-outer-name
def mountEntity(sysdb,path,type,attr):
   mg = sysdb.mountGroup()
   entity = mg.mount(path,type,attr)
   mg.close(blocking=True)
   return entity

parser = optparse.OptionParser( usage="""
Checks the four one-hot byte enable lines from the Pci bridge to the scd""" )

parser.add_option("--sliceId", action="store", type=str,
                  help="Slice to check")

(options, args) = parser.parse_args()

if args:
   parser.error("unexpected arguments")
if options.sliceId is None:
   parser.error("Slice must be specified")

slice = str(options.sliceId)  # pylint: disable=redefined-builtin
sysname = os.environ.get( "SYSNAME", "ar" )

sysdb = EntityManager.Sysdb( sysname )

scdConfig = mountEntity( sysdb, "hardware/scd/config",
                         "Hardware::Scd::Config", 'r' )

scratchOffset = scdConfig.scdConfig[slice].scratchRegisterOffset
scdHam = scdConfig.scdConfig[slice].ham
scdAddress = scdHam.hamImpl.address

# pylint: disable-next=consider-using-f-string
pciAddr = "%04x:%02x:%02x.%x" % ( scdAddress.domain, scdAddress.bus, 
                                     scdAddress.slot, scdAddress.function )

if not scdHam.hamImpl.hardwarePresent:
   sys.exit(1)

if scdHam.hamImpl.data[scratchOffset] != 0:
   print( "Expected scratch register to be 0 at start" )
   sys.exit(1)

#Write one byte at a time and read back rest of the bytes to check
#that they haven't been written to
for byteToWrite in bytesToCheck: # pylint: disable=consider-using-dict-items
   PciUtil.write8( pciAddr, 0, scratchOffset + byteToWrite, 1)
   if PciUtil.read8( pciAddr, 0, scratchOffset + byteToWrite) != 1:
      # pylint: disable-next=consider-using-f-string
      print( "Write to byte %d in scratch register of halfdome failed " %
             byteToRead )
      sys.exit(1)
   for byteToRead in bytesToCheck[byteToWrite]:
      if PciUtil.read8( pciAddr, 0, scratchOffset + byteToRead):
         # pylint: disable-next=consider-using-f-string
         print( "Unexpected write to byte %d in scratch register of halfdome fpga" %(
            byteToRead ) )
         print( "Check byte enable lines on the Pci Bridge" )
         sys.exit(1)
   PciUtil.write32( pciAddr, 0, scratchOffset, 0)
   
sys.exit(0)
   



