def __init__(self, coredump_lines, processor): ChipData.ChipData.__init__(self) self.coredump_lines = coredump_lines self.chip_id = None # Global chip version (e.g. 12280000) # string containing one of "Bluecore" or Hydra" self.chip_architecture = None self.kalimba_architecture = None # integer, e.g. 3, 4, 5. self.chip_revision = None # the coredump must be read twice from each processors' perspective self.processor = processor self.firmware_id = 0 # Firmware ID integer. self.firmware_id_string = "" # Firmware ID string. # Dictionary that will contain PM RAM (if it is tagged as 'PM' in the # coredump) self.pm = {} # Dictionary that will contain all of the data from the coredump self.data = {} # (stuff marked as 'data' or memory-mapped registers; this could # be DM-mapped PM in the case of HydraCore chips). self.registers = {} # Dictionary that holds all processor registers self.banked_registers = [] # addr_per_word is 1 for all the supported chips, except Crescendo self.addr_per_word = 1 self.is_banked_register = False self.ignore_processor = False # parse the coredump self._read_xcd_file(iter(self.coredump_lines)) # Finished parsing the audio section. Set the chip architecture # for the rest of the tool. Arch.chip_select( self.kalimba_architecture, self.chip_architecture, self.chip_id, self.chip_revision ) # Now we do some complicated things to accommodate # architecture-specific stuff. if (self.kalimba_architecture in (4, 5) and self.chip_architecture == "Hydra"): # The DM1 RAM range is also aliased at the DM2 range # Only the DM1 data is in the coredump, so make a copy for easy # analysis dm2 = {} for addr in self.data: if Arch.get_dm_region(addr) == "DM1RAM": dm2[addr + Arch.dRegions['DM2RAM'][0]] = self.data[addr] self.data.update(dm2) logger.info('Coredump parsed')
def __init__(self, kal, spi_trans, processor, wait_for_proc_to_start): LiveChip.LiveChip.__init__(self) self.kal = kal self.dm = kal.dm self.spi_trans = spi_trans # Throttle the memory read to avoid audio stalls. This is a workaround # to avoid the exhaustion of the transaction bridge. old_read_dm_block = self.dm.__dict__['_reader'] def throttled_read_dm_block(address, words_to_fetch): """Slows the memory read. This happens by fragmenting the memory read to "maximum_read" words. Args: address words_to_fetch """ maximum_read = 32 # When the number of words to fetch is large, we have to split # it into chunks of maximum_read sizes. values = [] while words_to_fetch: if words_to_fetch < maximum_read: fetch_words = words_to_fetch else: fetch_words = maximum_read values.extend(old_read_dm_block(address, fetch_words)) # Re calculate the address and outstanding words to fetch address += fetch_words * Arch.addr_per_word words_to_fetch -= fetch_words return values self.dm.__dict__['_reader'] = throttled_read_dm_block self.pm = kal.pm self.processor = processor version = "" try: version = kal.get_matching_kalimbalab() except AttributeError: # 24 or older Kalimbalabs does not have # get_matching_kalimbalab methods Fist element form the list # is the kal version. version = "pre 24b " + kal.get_version()[0] logger.info("Initialising connection with KalAccess %s", version) # Try and connect without providing a subsys or processor ID. # This should Just Work on Bluecore chips, and Hydra chips if using a # version of KalimbaLab older than 22a. If it doesn't work, things # get a bit harder. # Connect to the chip. self.reconnect() if wait_for_proc_to_start: # Wait until the chip is booted up otherwise ACAT will fail # anyways. Just checking if the processor is running is not # enough to tell if the processor was booted. However, reading # form the PM ram region gives error if the chip wasn't # booted. message_displayed = False while True: try: self.pm[0] break # proc booted exit now except BaseException: if not message_displayed: print("Waiting for the audio subsystem to boot...") message_displayed = True time.sleep(0.1) print("Audio subsystem booted.") # If we get here, we must have connected ok. We need to call # chip_select to pick the correct memory map for the chip we're # attached to. try: if self.kal.arch.is_hydra(): chip_arch = "Hydra" # KaArch.is_bluecore() only exists from KalimaLab23 onwards. elif self.kal.arch.is_bluecore(): chip_arch = "Bluecore" else: # Raise StandardError to deal with chips that are no # hydra/Bluecore family. raise Exception except AttributeError: raise Exception("Could not detect the arch or chip name") except Exception: # Dealing with non-Hydra/Bluecore chips. if self.kal.arch.get_chip_name() == "marco": chip_arch = "KAS" # Napier audio added on kal-python tools 1.1.2 elif self.kal.arch.get_chip_name() == "napier_audio": chip_arch = "Napier" else: raise Exception("Could not detect the arch or chip name") # From KalimaLab23 onwards, we can read the chip ID. If we can't # get it, just pass in zero so that any compatibility issue # becomes obvious. try: Arch.chip_select(self.kal.arch.get_arch(), chip_arch, self.kal.arch.get_global_chip_version(), self._get_chip_revision()) except AttributeError: Arch.chip_select(self.kal.arch.get_arch(), chip_arch, 0)
def __init__(self, kal, spi_trans, processor, wait_for_proc_to_start): """ @brief Constructor Starts a spi connection to a chip @param[in] self Pointer to the current object @param[in] kal @param[in] spi_trans @param[in] processor """ LiveChip.LiveChip.__init__(self) self.kal = kal self.dm = kal.dm # Throttle the memory read to avoid audio stalls. This is a workaround # to avoid the exhaustion of the transaction bridge. old_read_dm_block = self.dm.__dict__['_reader'] def throttled_read_dm_block(address, words_to_fetch): """ This functions slow the memory read by fragmeting the memory read to "maximum_read" words. """ # Adjust this if the reads are still too fast. maximum_read = 32 if words_to_fetch < maximum_read: return old_read_dm_block(address, words_to_fetch) retval = [] for _ in range(words_to_fetch / maximum_read): retval += old_read_dm_block(address, maximum_read) address += maximum_read * Arch.addr_per_word words_to_fetch -= maximum_read if words_to_fetch: # read the remaining words retval += old_read_dm_block(address, words_to_fetch) return retval self.dm.__dict__['_reader'] = throttled_read_dm_block self.pm = kal.pm self.processor = processor version = "" try: version = kal.get_matching_kalimbalab() except AttributeError: # 24 or older Kalimbalabs does not have get_matching_kalimbalab methods # Fist element form the list is the kal version. version = "pre 24b " + kal.get_version()[0] cu.debug_log("Initialising connection with KalAccess %s" % version) # Try and connect without providing a subsys or processor ID. # This should Just Work on Bluecore chips, and Hydra chips if using a # version of KalimbaLab older than 22a. If it doesn't work, things # get a bit harder. # Support connect_with_uri transport format if spi_trans.startswith("device://"): spi_trans += "/audio/p{}".format(str(processor)) connect_func = self.kal.connect_with_uri else: connect_func = self.kal.connect try: connect_func(spi_trans) except Exception as exception: if re.search("Could not connect", str(exception)): raise else: # Assume a compatibility problem and try again. # Supply defaults for mul(-1) and ignore_fw (0), we don't care about them. # Audio is always subsystem 3 on a Hydra chip, now and for the # forseeable future. connect_func(spi_trans, -1, 0, 3, processor) if wait_for_proc_to_start: # Wait until the chip is booted up otherwise ACAT will fail anyways. # Just checking if the processor is running is not enough to tell # if the processor was booted. However, reading form the PM ram # region gives error if the chip wasn't booted. message_displayed = False while True: try: self.pm[0] break # proc booted exit now except BaseException: if not message_displayed: print("Waiting for the audio subsystem to boot...") message_displayed = True time.sleep(0.1) print("Audio subsystem booted.") # If we get here, we must have connected ok. We need to call chip_select to # pick the correct memory map for the chip we're attached to. try: if self.kal.arch.is_hydra(): chip_arch = "Hydra" # KaArch.is_bluecore() only exists from KalimaLab23 onwards. elif self.kal.arch.is_bluecore(): chip_arch = "Bluecore" else: # Raise StandardError to deal with chips that are no # hydra/Bluecore family. raise Exception except AttributeError: raise Exception("Could not detect the arch or chip name") except Exception: # Dealing with non-Hydra/Bluecore chips. if self.kal.arch.get_chip_name() == "marco": chip_arch = "KAS" # Napier audio added on kal-python tools 1.1.2 elif self.kal.arch.get_chip_name() == "napier_audio": chip_arch = "Napier" else: raise Exception("Could not detect the arch or chip name") # From KalimaLab23 onwards, we can read the chip ID. If we can't get it, just pass in # zero so that any compatibility issue becomes obvious. try: Arch.chip_select(self.kal.arch.get_arch(), chip_arch, self.kal.arch.get_global_chip_version(), self._get_chip_revision()) except AttributeError: Arch.chip_select(self.kal.arch.get_arch(), chip_arch, 0)