Source code for pyfabil.plugins.tpm_1_6.eep

__author__ = 'gabriele.sorrenti'

from pyfabil.base.definitions import *
from pyfabil.base.utils import *
from pyfabil.plugins.firmwareblock import FirmwareBlock
import logging

MAX_RETRY = 6000


[docs] class Tpm_1_6_EEP(FirmwareBlock): """ Tpm_1_6_EEP tests class """ @compatibleboards(BoardMake.Tpm16Board) @friendlyname('tpm_eep') @maxinstances(1) def __init__(self, board, **kwargs): """ Tpm_1_6_EEP initialiser :param board: Pointer to board instance """ super(Tpm_1_6_EEP, self).__init__(board) self.phy_addr = 0xA0 # self.ba = 0x40000000 #self.board["board.i2c"] # I2C IF Base Add self.i2c_shadow = 0x90000270 self.i2c_req_reg = 0x50 self.i2c_ack_reg = 0x54 self.ticket_num = None self.eep_sec = { "ip_address": {"offset": 0x00, "size": 4, "name": "ip_address", "type": "ip", "protected": False}, "netmask": {"offset": 0x04, "size": 4, "name": "netmask", "type": "ip", "protected": False}, "gateway": {"offset": 0x08, "size": 4, "name": "gateway", "type": "ip", "protected": False}, "password": {"offset": 0x0c, "size": 3, "name": "password", "type": "bytearray", "protected": False}, "pre_adu_0": {"offset": 0x10, "size": 16, "name": "pre_adu_0", "type": "bytearray", "protected": False}, "pre_adu_1": {"offset": 0x20, "size": 16, "name": "pre_adu_1", "type": "bytearray", "protected": False}, "SN": {"offset": 0x40, "size": 16, "name": "SN", "type": "string", "protected": True}, "PN": {"offset": 0x50, "size": 16, "name": "PN", "type": "string", "protected": True}, "BOARD_MODE": {"offset": 0x60, "size": 1, "name": "BOARD_MODE", "type": "uint", "protected": True}, # 0 ada,0xff no-ada "HARDWARE_REV": {"offset": 0x61, "size": 3, "name": "HARDWARE_REV", "type": "bytearray", "protected": True}, # v00.00.00 "PCB_REV": {"offset": 0x64, "size": 1, "name": "PCB_REV", "type": "string", "protected": True}, "DDR_SIZE_GB": {"offset": 0x65, "size": 1, "name": "DDR_SIZE_GB", "type": "uint", "protected": True}, "CABINET_LOCATION": {"offset": 0x66, "size": 2, "name": "CABINET_LOCATION", "type": "uint", "protected": False}, "SUBRACK_LOCATION": {"offset": 0x68, "size": 1, "name": "SUBRACK_LOCATION", "type": "uint", "protected": False}, "SLOT_LOCATION": {"offset": 0x69, "size": 1, "name": "SLOT_LOCATION", "type": "uint", "protected": False}, "pre_adu_0_rev": {"offset": 0x70, "size": 1, "name": "pre_adu_0_rev", "type": "uint", "protected": False}, "pre_adu_1_rev": {"offset": 0x71, "size": 1, "name": "pre_adu_1_rev", "type": "uint", "protected": False}, "MAC": {"offset": 0xFA, "size": 6, "name": "MAC", "type": "bytearray", "protected": True}, # READ-ONLY } #######################################################################################
[docs] def poll_reg(self, reg, exit_condition, exception_val): retry = 0 while True: if (self.board[reg]) == exit_condition: break else: time.sleep(0.001) retry = retry + 1 if self.ticket_num is not None: self.board["board.lock.lock_i2c"] = self.ticket_num if retry >= MAX_RETRY: logging.error("EEP Polling Reg timeout: ", exception_val) raise LibraryError(exception_val)
[docs] def rd8(self, offset, use_password=False): """ Read 8-bit value from EEP ROM """ if self.board.i2c_old_mode: self.set_passwd() add = self.phy_addr >> 1 nof_rd_byte = 1 nof_wr_byte = 1 cmd = (nof_rd_byte << 12) + (nof_wr_byte << 8) + add self.board["board.i2c.transmit"] = offset & 0xFF self.board["board.i2c.command"] = cmd while self.board["board.i2c.status"] != 0: pass self.remove_passwd() return self.board["board.i2c.receive"] else: # Lock I2C interface to avoid MCU access conflict logging.debug("I2C Read: Locking I2C interface to avoid MCU access conflict ") locked = False retry = 150 ticket_num = self.board["board.lock.queue_number"] while retry > 0: self.board["board.lock.lock_i2c"] = ticket_num if self.board["board.lock.lock_i2c"] != ticket_num: retry = retry-1 time.sleep(0.007) else: locked = True self.ticket_num = ticket_num break if locked is False: logging.error("ERROR: Can't Lock I2C interface") raise LibraryError("ERROR: Can't Lock I2C interface") # else: # logging.info("I2C interface Locked") if self.board[self.i2c_shadow + self.i2c_req_reg] == 1: logging.warning("Detected Incomplete Previous I2C operation") self.board[self.i2c_shadow + self.i2c_req_reg] = 0 self.poll_reg(self.i2c_shadow + self.i2c_ack_reg, 0, "I2C/EEP not ready!") self.set_passwd() add = self.phy_addr >> 1 nof_rd_byte = 1 nof_wr_byte = 1 cmd = (nof_rd_byte << 12) + (nof_wr_byte << 8) + add self.board[self.i2c_shadow + 0x4] = offset & 0xFF self.board[self.i2c_shadow + 0x0] = cmd # send request self.board[self.i2c_shadow+self.i2c_req_reg] = 1 # wait req acknowledge logging.debug("i2c read wait req acknowledge") self.poll_reg(self.i2c_shadow+self.i2c_ack_reg, 1, "I2C/EEP request not accepted!") # check passwd logging.debug("i2c read check passwd") self.check_passwd() # check i2c op status: 0 ok, 1 busy, 2 NACK logging.debug("i2c read check status") self.poll_reg(self.i2c_shadow + 0xC, 0, "I2C/EEP busy or not acknoledge!") read_data = self.board[self.i2c_shadow + 0x8] # self.remove_passwd() # self.board[self.i2c_shadow+self.i2c_ack_reg] = 0 self.board[self.i2c_shadow + self.i2c_req_reg] = 0 logging.debug("i2c read check end operation") self.poll_reg(self.i2c_shadow + self.i2c_ack_reg, 0, "I2C/EEP operation complete not detected!") # Unlock I2C interface self.board["board.lock.lock_i2c"] = 0 self.ticket_num = None time.sleep(0.020) return read_data
def rd16(self, offset): rd = 0 for n in range(2): rd = rd << 8 rd = rd | self.rd8(offset+n) return rd def rd32(self, offset): """ Read 32-bit value from EEP ROM """ rd = 0 for n in range(4): rd = rd << 8 rd = rd | self.rd8(offset + n) return rd
[docs] def wr8(self, offset, data): """ Write 8-bit value to EEP ROM """ if self.board.i2c_old_mode: self.set_passwd() add = self.phy_addr >> 1 nof_rd_byte = 0 nof_wr_byte = 2 cmd = (nof_rd_byte << 12) + (nof_wr_byte << 8) + add while True: self.board["board.i2c.transmit"] = ((data & 0xFF) << 8) + (offset & 0xFF) self.board["board.i2c.command"] = cmd while True: rd = self.board["board.i2c.status"] if rd == 2: time.sleep(0.1) break elif rd == 0: time.sleep(0.005) self.remove_passwd() return else: time.sleep(0.1) else: # Lock I2C interface to avoid MCU access conflict logging.debug("I2C Write: Locking I2C interface to avoid MCU access conflict ") locked = False retry = 15 ticket_num = self.board["board.lock.queue_number"] while retry > 0: self.board["board.lock.lock_i2c"] = ticket_num if self.board["board.lock.lock_i2c"] != ticket_num: retry = retry-1 time.sleep(0.01) else: locked = True self.ticket_num = ticket_num break if locked is False: logging.error("ERROR: Can't Lock I2C interface") raise LibraryError("ERROR: Can't Lock I2C interface") # else: # logging.info("I2C interface Locked") if self.board[self.i2c_shadow + self.i2c_req_reg] == 1: logging.warning("Detected Incomplete Previous I2C operation") self.board[self.i2c_shadow + self.i2c_req_reg] = 0 self.poll_reg(self.i2c_shadow + self.i2c_ack_reg, 0, "I2C/EEP not ready!") self.set_passwd() add = self.phy_addr >> 1 nof_rd_byte = 0 nof_wr_byte = 2 cmd = (nof_rd_byte << 12) + (nof_wr_byte << 8) + add self.board[self.i2c_shadow + 0x4] = ((data & 0xFF) << 8) + (offset & 0xFF) self.board[self.i2c_shadow + 0x0] = cmd # send request self.board[self.i2c_shadow + self.i2c_req_reg] = 1 # wait req acknowledge logging.debug("wait req acknowledge") self.poll_reg(self.i2c_shadow + self.i2c_ack_reg, 1, "I2C/EEP request not accepted!") # check passwd logging.debug("check passwd") self.check_passwd() # check i2c op status: 0 ok, 1 busy, 2 NACK logging.debug("check status") self.poll_reg(self.i2c_shadow + 0xC, 0, "I2C/EEP busy or not acknoledge!") # read_data = self.board[self.i2c_shadow + 0x8] # self.remove_passwd() self.board[self.i2c_shadow + self.i2c_req_reg] = 0 logging.debug("check end operation") self.poll_reg(self.i2c_shadow + self.i2c_ack_reg, 0, "I2C/EEP operation complete not detected!") # Unlock I2C interface self.board["board.lock.lock_i2c"] = 0 self.ticket_num = None time.sleep(0.020)
[docs] def rd16(self, offset): rd = 0 for n in range(2): rd = rd << 8 rd = rd | self.rd8(offset+n) return rd
[docs] def rd32(self, offset): rd = 0 for n in range(4): rd = rd << 8 rd = rd | self.rd8(offset+n) return rd
[docs] def wr32(self, offset, data): for n in range(4): self.wr8(offset+n, (data >> 8*(3-n)) & 0xFF) return
[docs] def wr_string(self, partition, string): return self._wr_string(partition["offset"], string, partition["size"])
def _wr_string(self, offset, string, max_len=16): addr = offset for i in range(len(string)): self.wr8(addr, ord(string[i])) addr += 1 if addr >= offset + max_len: break if addr < offset + max_len: self.wr8(addr, ord("\n"))
[docs] def rd_string(self, partition): return self._rd_string(partition["offset"], partition["size"])
def _rd_string(self, offset, max_len=16): addr = offset string = "" for i in range(max_len): byte = self.rd8(addr) if byte == ord("\n") or byte == 0xff: break string += chr(byte) addr += 1 return string
[docs] def set_passwd(self): if self.board.i2c_old_mode: rd = self.board["board.i2c.mac_hi"] self.board["board.i2c.password"] = rd rd = self.board["board.i2c.mac_lo"] self.board["board.i2c.password_lo"] = rd rd = self.board["board.i2c.password"] if rd & 0x10000 == 0: raise LibraryError("I2C/EEP password not accepted!") else: rd = self.board["board.i2c.mac_hi"] self.board[self.i2c_shadow+0x3C] = rd rd = self.board["board.i2c.mac_lo"] self.board[self.i2c_shadow+0x38] = rd
[docs] def check_passwd(self): rd = self.board[self.i2c_shadow+0x3C] if (rd & 0x10000) != 0x10000: logging.error("I2C/EEP password not accepted!") raise LibraryError("I2C/EEP password not accepted!")
[docs] def remove_passwd(self): if self.board.i2c_old_mode: self.board["board.i2c.password"] = 0 self.board["board.i2c.password_lo"] = 0 else: self.board[self.i2c_shadow+0x3C] = 0 self.board[self.i2c_shadow+0x38] = 0
[docs] def get_field(self, key): if self.eep_sec[key]["type"] == "ip": return long2ip(self.rd32(self.eep_sec[key]["offset"])) elif self.eep_sec[key]["type"] == "bytearray": arr = bytearray() for offset in range(self.eep_sec[key]["size"]): arr.append(self.rd8(self.eep_sec[key]["offset"]+offset)) return arr elif self.eep_sec[key]["type"] == "string": return self.rd_string(self.eep_sec[key]) elif self.eep_sec[key]["type"] == "uint": val = 0 for offset in range(self.eep_sec[key]["size"]): val = val * 256 + self.rd8(self.eep_sec[key]["offset"]+offset) return val
[docs] def set_field(self, key, value, override_protected=False): if self.eep_sec[key]["protected"] is False or override_protected: if self.eep_sec[key]["type"] == "ip": self.wr32(self.eep_sec[key]["offset"], ip2long(value)) elif self.eep_sec[key]["type"] == "bytearray": for offset in range(self.eep_sec[key]["size"]): self.wr8(self.eep_sec[key]["offset"] + offset, ((value & (0xff << (8*(self.eep_sec[key]["size"]-1-offset)))) >> (8*(self.eep_sec[key]["size"]-1-offset))) & 0xff) elif self.eep_sec[key]["type"] == "string": self.wr_string(self.eep_sec[key], value) elif self.eep_sec[key]["type"] == "uint": val = value for offset in range(self.eep_sec[key]["size"]): self.wr8(self.eep_sec[key]["offset"]+offset, val & 0xff) val = val >> 8 else: raise LibraryError("Writing attempt on protected sector %s" % key)