Source code for pyfabil.plugins.tpm.cpld

from __future__ import division
from builtins import str
from builtins import hex
from builtins import range
__author__ = 'lessju'

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


[docs] class TpmCpld(FirmwareBlock): """ FirmwareBlock tests class """ @compatibleboards(BoardMake.TpmBoard) @friendlyname('tpm_cpld') @maxinstances(1) def __init__(self, board, **kwargs): """ TpmCpld initialiser :param board: Pointer to board instance """ super(TpmCpld, self).__init__(board) self.board_type = kwargs.get('board_type', 'XTPM') self._cpld_fw_date_add = 0x30000000 #######################################################################################
[docs] def get_version(self): version = hex(self.board[self._cpld_fw_date_add]) return version
[docs] def cpld_flash_read(self, bitfile="cpld_dump.bit"): """ Read CPLD FLASH """ dump = [] self.board[0x90000000 + 0x70 * 4] = 0x80 # enable wishbone connection self.cpld_efb_wr(0x74) # self.cpld_efb_wr(0x08) # self.cpld_efb_wr(0x00) # self.cpld_efb_wr(0x00) # self.board[0x90000000 + 0x70 * 4] = 0x0 # disable wishbone connection while self.board[0x90000000 + 0x72 * 4] & 0x20 == 0: pass time.sleep(0.001) self.board[0x90000000 + 0x70 * 4] = 0x80 # enable wishbone connection self.cpld_efb_wr(0x46) self.cpld_efb_wr(0x00) self.cpld_efb_wr(0x00) self.cpld_efb_wr(0x00) self.board[0x90000000 + 0x70 * 4] = 0x0 # disable wishbone connection while self.board[0x90000000 + 0x72 * 4] & 0x20 == 0: pass for n in range(9212): self.board[0x90000000 + 0x70 * 4] = 0x80 # enable wishbone connection self.cpld_efb_wr(0x73) self.cpld_efb_wr(0x10) self.cpld_efb_wr(0x00) self.cpld_efb_wr(0x00) while self.board[0x90000000 + 0x72 * 4] & 0x20 == 0: pass while self.board[0x90000000 + 0x72 * 4] & 0x8 == 0x8: pass for m in range(16): while True: rd = self.board[0x90000000 + 0x72 * 4] if rd & 0x8 != 0: pass else: break dump.append(self.board[0x90000000 + 0x73 * 4]) while self.board[0x90000000 + 0x72 * 4] & 0x20 == 0: pass self.board[0x90000000 + 0x70 * 4] = 0x0 # disable wishbone connection if n % 1000 == 0: logging.info("Reading CPLD config frame {}/9212".format(str(n))) self.board[0x90000000 + 0x70 * 4] = 0x80 # enable wishbone connection self.cpld_efb_wr(0x26) self.cpld_efb_wr(0x00) self.cpld_efb_wr(0x00) self.board[0x90000000 + 0x70 * 4] = 0x0 # disable wishbone connection while self.board[0x90000000 + 0x72 * 4] & 0x20 == 0: pass self.board[0x90000000 + 0x70 * 4] = 0x80 # enable wishbone connection self.cpld_efb_wr(0xFF) # self.cpld_efb_wr(0xFF) # self.cpld_efb_wr(0xFF) # self.cpld_efb_wr(0xFF) # self.board[0x90000000 + 0x70 * 4] = 0x0 # disable wishbone connection while self.board[0x90000000 + 0x72 * 4] & 0x20 == 0: pass # Save flash contents to file with open(bitfile, "wb") as f: f.write(bytearray(dump)) return bytearray(dump)
[docs] def cpld_flash_write(self, bitfile): """ Write bitfile to CPLD FLASH """ logging.info("Writing {} to CPLD flash".format(bitfile)) with open(bitfile, "rb") as f: dump = bytearray(f.read()) start_idx = -1 for n in range(len(dump) - 8): if dump[n] == 0xFF and dump[n + 1] == 0xFF and dump[n + 2] == 0xBD and dump[n + 3] == 0xB3: start_idx = n break if start_idx == -1: logging.error("Invalid CPLD bitfile. Start word not found!") return False if start_idx > 0: dump = dump[start_idx:] dump = dump[:10] + dump[10 + 8:] if len(dump) % 16 != 0: dump = dump + bytearray([0xFF] * (16 - len(dump) % 16)) # Enable configuration access logging.info("Enabling CPLD configuration access") self.board[0x90000000 + 0x70 * 4] = 0x80 # enable wishbone connection self.cpld_efb_wr(0x74) # self.cpld_efb_wr(0x08) # self.cpld_efb_wr(0x00) # self.cpld_efb_wr(0x00) # self.board[0x90000000 + 0x70 * 4] = 0x0 # disable wishbone connection while self.board[0x90000000 + 0x72 * 4] & 0x20 == 0: pass time.sleep(0.001) # Erase flash logging.info("Erasing Flash") self.board[0x90000000 + 0x70 * 4] = 0x80 # enable wishbone connection self.cpld_efb_wr(0x0E) # self.cpld_efb_wr(0x04) # self.cpld_efb_wr(0x00) # self.cpld_efb_wr(0x00) # self.board[0x90000000 + 0x70 * 4] = 0x0 # disable wishbone connection # FLASH status check while True: self.board[0x90000000 + 0x70 * 4] = 0x80 # enable wishbone connection self.cpld_efb_wr(0xF0) # self.cpld_efb_wr(0x00) # self.cpld_efb_wr(0x00) # self.cpld_efb_wr(0x00) # while self.board[0x90000000 + 0x72 * 4] & 0x20 == 0: pass rd = self.board[0x90000000 + 0x73 * 4] self.board[0x90000000 + 0x70 * 4] = 0x0 # disable wishbone connection if rd == 0: break else: logging.info("CPLD status register: {}".format(hex(rd))) time.sleep(0.2) # Init Address self.board[0x90000000 + 0x70 * 4] = 0x80 # enable wishbone connection self.cpld_efb_wr(0x46) self.cpld_efb_wr(0x00) self.cpld_efb_wr(0x00) self.cpld_efb_wr(0x00) self.board[0x90000000 + 0x70 * 4] = 0x0 # disable wishbone connection while self.board[0x90000000 + 0x72 * 4] & 0x20 == 0: pass nof_frame = len(dump) // 16 idx = 0 logging.info("Write configuration flash") for n in range(nof_frame): self.board[0x90000000 + 0x70 * 4] = 0x80 # enable wishbone connection self.cpld_efb_wr(0x70) self.cpld_efb_wr(0x00) self.cpld_efb_wr(0x00) self.cpld_efb_wr(0x00) for m in range(16): self.cpld_efb_wr(dump[idx]) idx += 1 self.board[0x90000000 + 0x70 * 4] = 0x0 # disable wishbone connection if n % 1000 == 0: logging.info("Writing CPLD config frame {}/{}".format(n, nof_frame)) while True: # status check self.board[0x90000000 + 0x70 * 4] = 0x80 # enable wishbone connection self.cpld_efb_wr(0xF0) # self.cpld_efb_wr(0x00) # self.cpld_efb_wr(0x00) # self.cpld_efb_wr(0x00) # while self.board[0x90000000 + 0x72 * 4] & 0x20 == 0: pass rd = self.board[0x90000000 + 0x73 * 4] self.board[0x90000000 + 0x70 * 4] = 0x0 # disable wishbone connection if rd == 0: break else: logging.info("CPLD status register: {}".format(hex(rd))) time.sleep(0.2) # Program done logging.info("Programming Done") self.board[0x90000000 + 0x70 * 4] = 0x80 # enable wishbone connection self.cpld_efb_wr(0x5E) self.cpld_efb_wr(0x00) self.cpld_efb_wr(0x00) self.cpld_efb_wr(0x00) self.board[0x90000000 + 0x70 * 4] = 0x0 # disable wishbone connection while self.board[0x90000000 + 0x72 * 4] & 0x20 == 0: pass time.sleep(0.01) # disable configuration access logging.info("Disable CPLD configuration access") self.board[0x90000000 + 0x70 * 4] = 0x80 # enable wishbone connection self.cpld_efb_wr(0x26) self.cpld_efb_wr(0x00) self.cpld_efb_wr(0x00) self.board[0x90000000 + 0x70 * 4] = 0x0 # disable wishbone connection while self.board[0x90000000 + 0x72 * 4] & 0x20 == 0: pass # Bypass self.board[0x90000000 + 0x70 * 4] = 0x80 # enable wishbone connection self.cpld_efb_wr(0xFF) # self.cpld_efb_wr(0xFF) # self.cpld_efb_wr(0xFF) # self.cpld_efb_wr(0xFF) # self.board[0x90000000 + 0x70 * 4] = 0x0 # disable wishbone connection while self.board[0x90000000 + 0x72 * 4] & 0x20 == 0: pass # Verify bitstream readback_dump = self.cpld_flash_read() for n in range(len(dump)): if readback_dump[n] != dump[n]: logging.error("CPLD Verify Flash error! Address {}".format(str(n))) logging.error("CPLD doesn't have a good bitstream, it will not boot!") logging.error( "Write a valid bistream into the Flash before rebooting, otherwise you will need to use then JTAG!") os.remove("cpld_dump.bit") return False # Remove temporary file os.remove("cpld_dump.bit") # Refresh self.board[0x90000000 + 0x70 * 4] = 0x80 # enable wishbone connection self.cpld_efb_wr(0x79) self.cpld_efb_wr(0x00) self.cpld_efb_wr(0x00) self.cpld_efb_wr(0x00) # This command will refresh the board so there will be no reply. Catch # execption and ignore try: self.board[0x90000000 + 0x70 * 4] = 0x0 # disable wishbone connection except: pass # Give the board some time to reset sleep(1) while self.board[0x90000000 + 0x72 * 4] & 0x20 == 0: pass # Check CPLD firmware version, if it's that of the golden firmware then # this did not work properly (or bitfile is invalid) if self.board[0x30000000] == 0xDEAD0001: raise PluginError("TpmCpld: CPLD firmware download failed, golden firmware loaded") logging.info("CPLD bitstream update done!") return True
[docs] def cpld_efb_wr(self, dat): """ CPLD EFB write """ while self.board[0x90000000 + 0x72 * 4] & 0x10 == 0x10: pass self.board[0x90000000 + 0x71 * 4] = dat
[docs] def eep_rd8(self, offset): """ Read 8-bit value from EEP ROM """ i2c_data = offset & 0xFF return self.board.tpm_i2c.read(i2c_add=0xA0, nof_wr_byte=1, nof_rd_byte=1, wr_data=i2c_data)
[docs] def eep_wr8(self, offset, data): """ Write 8-bit value to EEP ROM """ i2c_data = (data & 0xFF) << 8 + (offset & 0xFF) self.board.tpm_i2c.read(i2c_add=0xA0, nof_wr_byte=2, nof_rd_byte=0, wr_data=i2c_data) return
[docs] def eep_rd32(self, offset): """ Read 32-bit value from EEP ROM """ rd = 0 for n in range(4): rd = rd << 8 rd = rd | self.eep_rd8(offset + n) return rd
[docs] def eep_wr32(self, offset, data): """ Write 32-bit value to EEP ROM """ for n in range(4): self.eep_wr8(offset + n, (data >> 8 * (3 - n)) & 0xFF) return
##################### Superclass method implementations ###############################
[docs] def initialise(self): """ Initialise TpmCpld """ logging.info("TpmCpld has been initialised") return True
[docs] def status_check(self): """ Perform status check :return: Status """ logging.info("TpmCpld : Checking status") return Status.OK
[docs] def clean_up(self): """ Perform cleanup :return: Success """ logging.info("TpmCpld : Cleaning up") return True