Ejemplo n.º 1
0
    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')
Ejemplo n.º 2
0
    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)
Ejemplo n.º 3
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)