Esempio n. 1
0
    def _get_heap_config_str(self, processor_number):
        """Get string representation of the heap configurations.

            In other words is the to string function for processor
            configuration.

        Args:
            processor_number

        Returns:
            processor configuration string.
        """
        return_str = ""
        total_size = 0
        for heap_num in range(self.max_num_heaps):
            (available, heap_size, heap_start, heap_end) = \
                self._get_heap_config(processor_number, heap_num)

            if available:
                return_str += "%-15s : " % self.heap_names[heap_num]
                return_str += "%s at 0x%08x - 0x%08x\n" % (
                    cu.mem_size_to_string(heap_size), heap_start, heap_end)

            total_size += heap_size

        return_str += "%-15s : %s" % ("Total size",
                                      cu.mem_size_to_string(total_size))

        return return_str
Esempio n. 2
0
    def get_data_pm(self, address, length=0):
        """Get data from PM.

        This method works in the exactly the same way as method, but it
        returns data from PM region instead of DM.

        Args:
            address
            length (int, optional)
        """
        try:
            address = int(address, 16)
        except TypeError:
            pass
        address = cu.get_correct_addr(address, Arch.addr_per_word)
        if length == 0:
            return self.pm[address]

        # note: Even the PM RAM is saved in self.pm data section.
        rawdata = []
        length = cu.convert_byte_len_word(length, Arch.addr_per_word)
        for i in range(0, length, Arch.addr_per_word):
            if address + i in self.pm:
                rawdata.append(self.pm[address + i])
            else:
                if i == 0:
                    raise KeyError("Key " + hex(address + i) + " is invalid")
                else:
                    raise OutOfRangeError(
                        "Key " + hex(address + i) + " is invalid",
                        address + i - Arch.addr_per_word)
        return tuple(rawdata)
Esempio n. 3
0
    def read_kip_requests(self, display_all=False):
        '''
        @brief This method shows kip request for ipc. If True is passed as an
            argument, all requests are displayed. If not, then only reasonable
            amount of them will be displayed
        @param[in] self Pointer to the current object
        '''
        # Look up the debug information, unless we already have.
        if self._do_debuginfo_lookup:
            self._lookup_debuginfo()
            self._do_debuginfo_lookup = False

        self.formatter.section_start('KIP requests')
        # kip requests are held in linked list, thus read these entries
        kip_requests = [
            req for req in self.parse_linked_list('L_kip_first_req', 'next')
        ]
        if not kip_requests:
            self.formatter.output('No KIP request present')
        else:
            # there might be lots of kip requests, thus display reasonable
            # number of them, unless ser asked to display all of them
            self.formatter.output('Pending KIP requests:\n')
            kip_str = ''
            max_to_display = 10
            displayed = 0
            apology = ''
            for req in kip_requests:
                kip_str += 'Connection ID: {0}\n'.format(
                    cu.hex(req.get_member('con_id').value))
                msg = self.debuginfo.get_enum(
                    'KIP_MSG_ID',
                    req.get_member('msg_id').value)[0].replace(
                        'KIP_MSG_ID_', "")
                kip_str += 'Message ID: {0}\n'.format(msg)
                kip_str += 'Sequence number: {0}\n'.format(
                    cu.hex(req.get_member('seq_nr').value))
                req_context = req.get_member('context').value
                if req_context != 0:
                    try:
                        module_name = self.debuginfo.get_source_info(
                            req_context).module_name
                    except ct.BundleMissingError:
                        module_name = ("No source information. " +
                                       "Bundle is missing.")
                    kip_str += 'Context: {0}\n'.format(module_name)
                kip_str += '\n'
                displayed += 1
                if displayed == max_to_display and not display_all:
                    apology = (
                        '\n...\n{0} more requests. '
                        'Pass True to the method to display '
                        'all requests'.format(len(kip_requests) - displayed))

            self.formatter.output(kip_str + apology)

        self.formatter.section_end()

        if self.chipdata.is_volatile():
            self._do_debuginfo_lookup = True
Esempio n. 4
0
    def __str__(self):
        """
        @brief Returns a tidy string representation of a timer object
        @param[in] self Pointer to the current object
        """
        tf_str = "Timer " + cu.hex(self.id) + "\n"
        tf_str = tf_str + "Type: " + self.type + "\n"

        if self.type == 'strict':
            tf_str = tf_str + "Expiry time: " + cu.hex(self.latest_time) + "\n"
        else:
            tf_str = tf_str + "Earliest expiry: " + cu.hex(self.earliest_time)
            tf_str = tf_str + ", latest expiry: " + \
                cu.hex(self.latest_time) + "\n"

        tf_str = tf_str + "Data pointer: " + cu.hex(self.data_pointer) + "\n"

        if self.timed_event_function is not None:
            tf_str = tf_str + "EventFunction: \n"
            temp_str = '    ' + str(self.timed_event_function)  # Indent
            tf_str = tf_str + string.replace(temp_str, '\n',
                                             '\n    ')  # Indent
            tf_str = tf_str[:-4]  # Remove indent from final newline

        return tf_str
    def get_data_pm(self, address, length=0):
        """Get data from PM.

        This method works in the exactly the same way as get_data(self,
        address, length = 0) method, but it returns data from PM region
        instead of DM.

        Args:
            address
            length (int, optional)
        """
        # We helpfully accept address as either a hex string or an integer
        try:
            # Try to convert address from a hex string to an integer
            address = int(address, 16)
        except TypeError:
            # Probably means address was already an integer
            pass

        address = cu.get_correct_addr(address, Arch.addr_per_word)

        if length == 0:
            mem_region = Arch.get_pm_region(address)
        else:
            mem_region = Arch.get_pm_region(
                address +
                cu.convert_byte_len_word(length, Arch.addr_per_word) -
                Arch.addr_per_word)
        try:
            if ('PMRAM' in mem_region or 'PMCACHE' in mem_region
                    or 'SLT' in mem_region):
                if length == 0:
                    return self.pm[address:address + Arch.addr_per_word][0]

                return tuple([
                    int(x) for x in self.
                    pm[address:address +
                       cu.convert_byte_len_word(length, Arch.addr_per_word)]
                ])
            else:
                if length == 0:
                    raise KeyError(
                        "Key " + hex(address + Arch.addr_per_word) +
                        " is not a valid PM RAM address",
                        address + Arch.addr_per_word)

                raise OutOfRangeError(
                    "Key " +
                    hex(address +
                        cu.convert_byte_len_word(length, Arch.addr_per_word) -
                        Arch.addr_per_word) + " is not a valid PM RAM address",
                    address +
                    cu.convert_byte_len_word(length, Arch.addr_per_word) -
                    Arch.addr_per_word)
        except Exception as exception:
            if "Transport failure (Unable to read)" in exception:
                sys.stderr.write(str(exception))
                raise ChipNotPoweredError
            else:
                raise exception
Esempio n. 6
0
    def _get_heap_config_str(self, processor_number):
        """
        @brief Returns the string representation of the heap configuration .
            In other words is the to string function for processor
            configuration.
        @param[in] self Pointer to the current object
        @param[in] processor_number
        @param[out] processor configuration string.
        """
        return_str = ""
        total_size = 0
        for heap_num in range(self.max_num_heaps):
            (available, heap_size, heap_start, heap_end) = \
                self._get_heap_config(processor_number, heap_num)

            if available:
                return_str += "%-15s : " % self.heap_names[heap_num]
                return_str += "%s at 0x%08x - 0x%08x\n" % (
                    cu.mem_size_to_string(heap_size),
                    heap_start,
                    heap_end
                )

            total_size += heap_size

        return_str += "%-15s : " % "Total size" + cu.mem_size_to_string(total_size)
        return return_str
Esempio n. 7
0
    def analyse_all_mmr(self):
        """
        @brief This prints out all of the memory-mapped registers. Reg names are not
        precise (i.e. they are guesses), so this should only really be used
        in Interactive mode.
        @param[in] self Pointer to the current object
        """
        # The whole memory-mapped register range
        mmr_range = list(
            range(Arch.dRegions['MMR'][0], Arch.dRegions['MMR'][1]))
        mmr_list = []
        for i in mmr_range:
            try:
                # Tuple containing (address, register name, register contents)
                mmr_list.append((i, self.chipdata.get_reg_strict(i).name,
                                 self.chipdata.get_reg_strict(i).value))
            except BaseException:
                # Not found
                pass

        self.formatter.section_start('All memory-mapped registers')
        for i in mmr_list:
            self.formatter.output(
                cu.hex(i[0]) + " " + i[1] + " " + cu.hex(i[2]))
        self.formatter.section_end()
Esempio n. 8
0
    def _get_free_space(self):
        """Get total size of free blocks.

            This method reads the free blocks for all heaps and returns a
            string which contains a list with the total size of those free
            blocks.
        """
        # Look up the debug information.
        self._lookup_debuginfo()
        output_str = ""
        total_size = 0
        for heap_num in range(self.max_num_heaps):
            (available, heap_size, heap_start, _, heap_free_start) = \
                self._get_heap_property(heap_num)

            if available:
                free_blocks = self._free_blocks(heap_free_start,
                                                heap_start,
                                                heap_size,
                                                memory_type=self.memory_type)
                # display the heap name
                output_str += "%-15s : " % self.heap_names[heap_num]
                free_block_size = free_blocks.total_size
                if self.pmalloc_debug_enabled:
                    # Two words are used for guard.
                    free_block_size -= 2 * Arch.addr_per_word
                output_str += cu.mem_size_to_string(free_block_size)
                total_size += free_block_size

                output_str += "\n"

        output_str += "%-15s : %s\n" % ("Total size",
                                        cu.mem_size_to_string(total_size))

        return output_str
Esempio n. 9
0
    def get_watermarks(self):
        """Displays the memory statistics.

        Shows the minimum available memory for the total, the free and the
        minimum free memories.
        """
        total_size, current_free, min_free, pools_statistic = \
            self.ret_get_watermarks()

        output_str = ""
        for pool_statistic in pools_statistic:
            output_str += (
                "pools with size %2d words, total size,   %3d blocks\n" %
                (pool_statistic[0], pool_statistic[1][0]))
            output_str += (
                "pools with size %2d words, current free, %3d blocks\n" %
                (pool_statistic[0], pool_statistic[1][1]))
            output_str += (
                "pools with size %2d words, minimum free, %3d blocks\n" %
                (pool_statistic[0], pool_statistic[1][2]))
            output_str += "\n"

        output_str += ("entire pool memory, total size,   " +
                       cu.mem_size_to_string(total_size * Arch.addr_per_word) +
                       "\n")
        output_str += (
            "entire pool memory, current free, " +
            cu.mem_size_to_string(current_free * Arch.addr_per_word) + "\n")
        output_str += ("entire pool memory, minimum free, " +
                       cu.mem_size_to_string(min_free * Arch.addr_per_word) +
                       "\n")
        # use output_raw to keep the spaces.
        self.formatter.output_raw(output_str)
Esempio n. 10
0
 def title_str(self):
     """
     @brief Returns the title string of the object.
     @param[in] self Pointer to the current object
     """
     return 'Operator ' + cu.hex(self.id) + ', ep_op_id ' + \
         cu.hex(self.op_ep_id) + ', ' + self.cap_data.name
Esempio n. 11
0
 def __str__(self):
     """
     @brief To string function of the class.
     """
     out_str = '{0:<20}{1:<10}{2:<15}{3:<15}\n'.format(
         cu.hex(self.device_address), self.length,
         cu.hex(self.file_address), cu.hex(self.file_id))
     return out_str
Esempio n. 12
0
    def _create_streams_html(self, operators, graph):
        """Creates and opens an html file which will display the streams.

        This html will include the graph, operators, endpoints and
        transforms.

        Args:
            operators: available operators.
            graph: Graphviz object.
        """
        # analyse the buffer with buffers_analysis
        buffers_analysis = self.interpreter.get_analysis(
            "buffers", self.chipdata.processor)
        # create a temporary file
        temp_file = tempfile.NamedTemporaryFile(mode="w",
                                                prefix="ACAT_",
                                                suffix=".html",
                                                delete=False)
        file_lication = temp_file.name
        temp_file.close()
        # create a temporary html formatter
        formtter_temp = HtmlFormatter(file_lication)
        # Display the graph
        formtter_temp.section_start("Streams")
        formtter_temp.output_svg(str(graph.pipe(format='svg')))
        formtter_temp.section_end()
        # display all the operators
        formtter_temp.section_start("Operators")
        for operaor in operators:
            formtter_temp.section_start(operaor.title_str)
            formtter_temp.output(operaor.desc_str)
            formtter_temp.section_end()
        formtter_temp.section_end()
        # display all the endpoints
        formtter_temp.section_start("Endpoints")
        for endpoint in self.endpoints:
            formtter_temp.section_start(endpoint.title_str)
            formtter_temp.output(endpoint.desc_str)
            formtter_temp.section_end()
        formtter_temp.section_end()
        # display all the transforms
        formtter_temp.section_start("Transforms")
        for transform in self.transforms:
            formtter_temp.section_start(transform.title_str)
            formtter_temp.output(transform.desc_str)
            formtter_temp.output(
                buffers_analysis.inspect_cbuffer(transform.buffer, True))
            formtter_temp.section_end()
        formtter_temp.section_end()
        # write the data to the html file
        formtter_temp.flush()
        # finally, open the html file
        self.formatter.output(" Opening " + file_lication)
        cu.open_file_with_default_app(file_lication)
Esempio n. 13
0
    def desc_str(self):
        """
        @brief Returns the description string of the endpoint.
        @param[in] self Pointer to the current object
        """
        ep_str = "Address: " + cu.hex(self.address) + "\n"
        ep_str = ep_str + "Key: " + cu.hex(self.key) + "\n"
        # it's enough to check with one variable that it's the AudioEP
        if self.instance is not None:
            ep_str += "Device: " + str(self.hardware) + "\n"
            ep_str += "Instance: " + str(self.instance) + "\n"
            ep_str += "Channel: " + str(self.channel) + "\n"

        ep_str = ep_str + "is_real: " + \
            str(self.is_real) + " can_be_closed: " + \
            str(self.can_be_closed) + "\n"
        ep_str = ep_str + "can_be_destroyed: " + \
            str(self.can_be_destroyed) + " destroy_on_disconnect: " + \
            str(self.destroy_on_disconnect) + "\n"
        if self.con_id is not None:
            ep_str = ep_str + "Connection ID: " + str(self.con_id) + "\n"

        ep_str = ep_str + "connected_to: "
        try:
            connected_to = self.connected_to
            if connected_to is None:
                ep_str += "NULL\n"
            else:
                ep_str += cu.hex(connected_to.id) + \
                    "(" + connected_to.compact_name() + ") \n"
        except AttributeError:
            ep_str += (
                "0x%08x is not a valid endpoint address\n" % self._connected_to
            )

        ep_str += "ep_to_kick: "
        try:
            endpoint_to_kick = self.ep_to_kick
            if endpoint_to_kick is None:
                ep_str += "NULL\n"
            else:
                ep_str += cu.hex(endpoint_to_kick.id) + \
                    "(" + endpoint_to_kick.compact_name() + ") \n"
        except AttributeError:
            ep_str += (
                "0x%08x is not a valid endpoint address\n" % self._ep_to_kick
            )
        ep_str = ep_str + str(self.cbops)

        if self.is_state_type_equal_to_name:
            ep_str = ep_str + \
                str(getattr(self, self.name))

        return ep_str
Esempio n. 14
0
    def var_to_str(self, depth=0):
        """
        @brief function used to convert a structure to a base_name: value \\n string
        @param[in] self Pointer to the current object
        @param[in] depth = 0
        """
        depth_str = "  " * depth
        fv_str = ""

        if depth == 0:
            fv_str += "0x%08x " % self.address

        if self.members:
            if self.base_name == "":
                # Probably it was a pointer to something
                fv_str += (depth_str + self.name + ":\n")
            else:
                fv_str += (depth_str + self.base_name + ":\n")
            for member in self.members:
                fv_str += member.var_to_str(depth + 1)
        else:
            part_of_array = False
            if self.parent and \
                    isinstance(self.parent.array_len, int):
                # this member is an element of an array.
                part_of_array = True
                fv_str += (depth_str + "[" +
                           str(self.parent.members.index(self)) + "]")
                # no need to add additional depth string.
                depth_str = ""

            if self.type_name in self.integer_names:
                # display integers in hex
                if not part_of_array:
                    fv_str += (depth_str + self.base_name)
                fv_str += (": " + cu.hex(self.value) + "\n")
            elif "bool" in self.type_name:
                # buleans are displayed as true (1) or false (0).
                fv_str += (depth_str + self.base_name + ": ")
                if self.value != 0:
                    fv_str += ("True\n")
                else:
                    fv_str += ("False\n")
            elif "enum " in self.type_name:
                fv_str += depth_str + self._get_enum_name()
            else:
                # This is probably a pointer to something.
                if not part_of_array:
                    if self.base_name != "":
                        fv_str += (depth_str + self.base_name)
                    else:
                        fv_str += (depth_str + self.name)
                fv_str += (": " + cu.hex(self.value) + "\n")
        return fv_str
Esempio n. 15
0
    def print_message_queue(self, msg_queue_var, display_buffer,
                            display_messages):
        '''
        @brief Displays the message queue.
        @param[in] self Pointer to the current object
        @param[in] msg_queue_var Pointer to a message queue variable.
        @param[in] display_buffer Flag to indicate if the underlying buffer
            should be further analysed.
        @param[in] display_messages Flag to indicate if message information is
            needed.
        '''
        # buffers are used to store messages, this import buffer analysis for
        # analysing it
        if display_buffer:
            buffer_analysis = self.interpreter.get_analysis(
                "buffers", self.chipdata.processor)

        self.formatter.output('Queue ID: {0}'.format(
            msg_queue_var.get_member('queue_id').value))
        self.formatter.output('Read counter: {0}'.format(
            msg_queue_var.get_member('message_read_counter').value))
        self.formatter.output('Next message counter: {0}'.format(
            msg_queue_var.get_member('next_message_counter').value))
        try:
            module_name = self.debuginfo.get_source_info(
                msg_queue_var.get_member('callback').value).module_name
        except ct.BundleMissingError:
            module_name = ("No source information. Bundle is missing.")
        self.formatter.output('Callback: {0}'.format(module_name))

        buffer_pointer = msg_queue_var.get_member('cbuffer').value
        buffer_var = self.chipdata.cast(buffer_pointer, 'tCbuffer')
        self.formatter.output('Messages are stored in buffer at: {0}\n'.format(
            cu.hex(buffer_var.get_member('base_addr').value)))

        if display_messages:
            messages = self._get_buffer_messages(buffer_var)
            msg_str = 'Messages: \n'
            for (header, msg_id) in messages:
                if header == VALID_MSG_HEADER_EXT:
                    msg_str += ('  External message with ID: {0}\n'.format(
                        cu.hex(msg_id)))
                elif header == VALID_MSG_HEADER_INT:
                    msg_str += ('  Internal message with ID: {0}\n'.format(
                        cu.hex(msg_id)))
            self.formatter.output(msg_str + '\n')

        # if asked, print out the buffer associated with the queue
        if display_buffer:
            if msg_queue_var.get_member('cbuffer').value != 0:
                buffer_analysis.analyse_cbuffer(buffer_pointer)
            else:
                self.formatter.output('Message queue buffer is null \n')
Esempio n. 16
0
 def __str__(self):
     """
     @brief To string function of the class.
     """
     # update the table before printing.
     self._update_table()
     out_str = '\nIdentify:  {0}  Entries: {1}\n'.format(
         cu.hex(self.identify_field), self.num_of_entries)
     out_str += '{0:<20}{1:<10}{2:<15}{3:<15}\n'.format(
         'Device address', 'length', 'file address', 'file elf_id')
     for entry in self.entries:
         out_str += str(entry)
     out_str += 'Checksum: {0}\n'.format(cu.hex(self.checksum))
     return out_str
Esempio n. 17
0
    def __str__(self):
        # Special rule since you can't call hex() on None
        if self.address is not None:
            hex_addr = cu.hex(self.address)
        else:
            hex_addr = 'None'

        if self.value is not None:
            hex_val = cu.hex(self.value)
        else:
            hex_val = 'None'

        # Using str(x) here since it copes with the value being None
        return ('Name: ' + str(self.name) + '\n' + 'Address: ' + hex_addr +
                '\n' + 'Value: ' + hex_val + '\n')
Esempio n. 18
0
    def overview(self):
        """
        @brief This method displays an overview of the available heaps.
        @param[in] self Pointer to the current object
        """
        output_str = self._get_overview_str(detailed=True)

        self.formatter.section_start(
            'Heap %s memory usage' % (self.memory_type.upper())
            )
        # use output_raw to keep the spaces.

        # display memory used by patches for PM Heap
        if self.memory_type.upper() == "PM":
            try:
                patch_analysis = self.interpreter.get_analysis("patches", self.chipdata.processor)
                if patch_analysis.get_patch_level() > 0:
                    patch_address_start = self.debuginfo.get_constant_strict(
                        '$PM_RAM_P0_CODE_START'
                    ).value
                    self.formatter.output_raw(
                        "\nPatch size : " +
                        cu.mem_size_to_string(patch_analysis.get_patch_size(), "o") +
                        " at address: 0x{0:0>8x}".format(patch_address_start) + "\n"
                    )
            except KeyError:
                # Patch analysis is not released to customers.
                pass

        self.formatter.output_raw(output_str)
        self.formatter.section_end()
Esempio n. 19
0
    def analyse_aux_states(self):
        '''
        @brief This method analyses the stated at which processors are at the
            time.
        @param[in] self Pointer to the current object
        '''

        # Look up the debug information, unless we already have.
        if self._do_debuginfo_lookup:
            self._lookup_debuginfo()
            self._do_debuginfo_lookup = False

        self.formatter.section_start('Aux states')

        if self.aux_states_p == 0:
            self.formatter.output('No aux states information')
            self.formatter.section_end()
            if self.chipdata.is_volatile():
                self._do_debuginfo_lookup = True
            return

        aux_states_array = self.chipdata.cast(
            self.aux_states_p, 'IPC_AUX_STATES').get_member('aux')
        all_states = self.debuginfo.get_enum('_IPC_SETUP_STATE', None)
        # This is states for every processor used, and it will be an array
        for processor in range(aux_states_array.array_len):
            aux_state = aux_states_array.__getitem__(processor)
            setup_state = aux_state.get_member('setup_state').value
            wakeup_time = aux_state.get_member('wakeup_time').value
            # Status state represents several possible flags. Find these flags
            # now
            if setup_state == 0x0000:
                active_states = ['SETUP_NONE']
            else:
                active_states = []
                for state, flag in all_states.items():
                    if state == 'IPC_SETUP_NONE':
                        continue
                    mask = 0x000F
                    for _ in range(4):
                        current_flag = setup_state & mask
                        if current_flag == flag:
                            active_states.append(state.replace("IPC_", ""))
                        mask = mask << 4

            state_str = ''
            for state in sorted(active_states):
                state_str += state + ', '
            state_str = state_str[:-2]  # remove last space and comma

            self.formatter.output(
                'Aux state for processor p{0}:'.format(processor))
            self.formatter.output('    Setup state: {0} - {1}'.format(
                cu.hex(setup_state), state_str))
            self.formatter.output('    Wake-up time: {0}'.format(wakeup_time))

        self.formatter.section_end()

        if self.chipdata.is_volatile():
            self._do_debuginfo_lookup = True
Esempio n. 20
0
    def mem_print(self, address, words, processor=0, words_per_line=8):
        """
        @brief Get a slice of DM, starting from address and prints out the
        result in a nicely formatted manner.
        @param[in] address Address to start from.
        @param[in] words Number of words to read from the memory.
        @param[in] processor Processor to use. Default is processor 0.
        @param[in] words_per_line Number of words to print out. Default value
                                 is 8 words.
        """
        if processor == 0:
            content = self.p0.chipdata.get_data(
                address, words * Arch.addr_per_word
            )
        else:
            content = self.p1.chipdata.get_data(
                address, words * Arch.addr_per_word
            )

        # convert the memory content to an ordered dictionary
        mem_content = OrderedDict()
        for offset, value in enumerate(content):
            current_address = address + offset * Arch.addr_per_word
            mem_content[current_address] = value

        self.formatter.output(
            cu.mem_dict_to_string(
                mem_content,
                words_per_line))
Esempio n. 21
0
    def desc_str(self):
        """
        @brief Returns the description string of the endpoint.
        @param[in] self Pointer to the current object
        """
        # Call the base class property function cannot be done otherwise
        ep_str = Endpoint.desc_str.fget(self)  # pylint: disable=no-member

        tp_ptr_var = self.audio.get_member("timed_playback")
        if tp_ptr_var:
            # timed playback is enabled in the build
            timed_playback_ptr = tp_ptr_var.value

            if timed_playback_ptr != 0:
                # the endpoint has a timed playback instance.
                timed_playback_var = self.stream.chipdata.cast(
                    addr=timed_playback_ptr,
                    type_def="TIMED_PLAYBACK",
                    elf_id=self.stream.debuginfo.get_kymera_debuginfo().elf_id
                )
                ep_str = ep_str.replace(
                    "timed_playback: " + cu.hex(timed_playback_ptr),
                    str(timed_playback_var).replace("\n", "\n  ")
                )

        return ep_str
Esempio n. 22
0
    def analyse_interrupt_stack_frames(self):
        """
        @brief Prints out information about any interrupt frames on the stack.
        @param[in] self Pointer to the current object
        """
        if self.stack_overflow_occurred():
            raise ct.AnalysisError(
                "Can't analyse_interrupt_stack_frames(): a stack overflow has occurred."
            )

        # Do a stack trace in order to refresh our memory
        # about what's on the stack. This will set self.interrupt_frames.
        self.get_stack_trace()

        for frame in self.interrupt_frames:
            self.formatter.section_start('Interrupt stack frame')
            isf = []  # list of strings
            for idx, entry in enumerate(frame):
                # Reverse the order again
                isf.insert(0, (self.int_frame_descriptors[idx].ljust(15) +
                               " - " + cu.hex(entry)))
            self.formatter.output_list(isf)

            # Sanity check the frame.
            # Check that rintlink is valid.
            frame_saved_rintlink = frame[6]
            # rintlink could point to anywhere (not just a call instruction)
            # so calling is_saved_rlink() won't work.
            try:
                self.debuginfo.get_source_info(frame_saved_rintlink)
            except ct.InvalidPmAddress:
                self.formatter.alert(
                    'Saved rintlink in interrupt frame does not point to a '
                    'code address - we may have been executing from cache!')
            self.formatter.section_end()
Esempio n. 23
0
    def get_oplist(self, mode='id'):
        """
        @brief Returns a list of all operators in opmgr's oplist.
        'Mode' selects which information to return:
          'entry' - a list of op_entry elements
          'id' - a list of operator IDs
          'object' - a list of Operator objects (NB: could be slow)
          'name' - a list of operator names and their ids
        @param[in] self Pointer to the current object
        @param[in] mode = 'id'
        """
        op_entries = self._read_raw_oplist()

        if mode == 'entry':
            return op_entries
        elif mode == 'id':
            return [operator.get_member('id').value for operator in op_entries]
        elif mode == 'object':
            return [
                operator_factory(operator, self) for operator in op_entries
            ]
        elif mode == 'name':
            return_list = []
            for operator in op_entries:
                operator = operator_factory(operator, self)
                return_list.append(operator.cap_data.name + " " +
                                   cu.hex(operator.op_ep_id))
            return return_list
        else:
            raise ct.Usage('Invalid oplist mode')
Esempio n. 24
0
    def _analyse_overflow_stack(self):
        """Method to display a stack overflow."""
        if self.chipdata.is_volatile():
            self._display_alert(
                "Warning: connected to live chip -- "
                "The stack can be corrupted."
            )
        self._display_alert('Stack overflow has occurred!')

        # Try to work out when we overflowed. STACK_OVERFLOW_PC
        # should be set.
        overflow_pc = self._get_stack_overflow_pc()

        try:
            # a SourceInfo object
            culprit = self.debuginfo.get_source_info(overflow_pc)
            self.formatter.output('\nOverflow occurred in:')
            self.formatter.output(cu.add_indentation(str(culprit), 4))
        except InvalidPmAddressError:
            # overflow_pc.value was not a code address. Give up.
            self.formatter.output(
                'STACK_OVERFLOW_PC is 0x%08x - no help there! ' % overflow_pc
            )
        except BundleMissingError:
            self.formatter.output(
                "No source information for "
                "overflow PC 0x%08X. Bundle is missing." % (overflow_pc)
            )
Esempio n. 25
0
    def var_to_str(self, depth=0):
        """
        @brief function used to convert a structure to a base_name: value \\n string
        @param[in] self Pointer to the current object
        @param[in] depth = 0
        """
        depth_str = "  " * depth
        fv_str = ""

        if depth == 0:
            fv_str += "0x%08x " % self.address

        if (self.members is not None) and (self.members):
            if self.base_name == "":
                # Probably it was a pointer to something
                fv_str += (depth_str + self.name + ":\n")
            else:
                fv_str += (depth_str + self.base_name + ":\n")
            for member in self.members:
                fv_str += member.var_to_str(depth + 1)
        else:
            if "uint32" in self.type_name or \
                "uint16" in self.type_name or \
                    "uint8" in self.type_name:
                fv_str += (depth_str + self.base_name + ": " +
                           cu.hex(self.value) + "\n")
            elif "bool" in self.type_name:
                fv_str += (depth_str + self.base_name + ": ")
                if self.value != 0:
                    fv_str += ("True\n")
                else:
                    fv_str += ("False\n")
            elif self.parent and \
                    isinstance(self.parent.array_len, int):  # vector
                fv_str += (depth_str + "[" +
                           str(self.parent.members.index(self)) + "]: " +
                           cu.hex(self.value) + "\n")
            elif "enum " in self.type_name:
                fv_str += depth_str + self._get_enum_name()
            else:
                if self.base_name != "":
                    fv_str += (depth_str + self.base_name + ": " +
                               cu.hex(self.value) + "\n")
                else:
                    fv_str += (depth_str + self.name + ": " +
                               cu.hex(self.value) + "\n")
        return fv_str
Esempio n. 26
0
    def _analyse_fifo(self, signal_block):
        '''
        @brief This method shows content of fifo, if any pending actions are
            stored
        @param[in] self Pointer to the current object
        @param[in] signal_block - signal block that this fifo belongs to
        '''

        self.formatter.section_start('FIFO information')
        fifo_p_array = signal_block.get_member('fifo').value
        # different fifo's are for different priority messages, but not all of
        # them might be  used, thus only display those which had messages in
        # them at some point, which is indicated by the counter of maximum slots
        # taken
        for fifo_p in fifo_p_array:
            priority = fifo_p_array.index(fifo_p)
            fifo = self.chipdata.cast(fifo_p, 'IPC_SIGNAL_FIFO')
            if fifo.get_member('max').value == 0:
                self.formatter.output(
                    'FIFO of priority {0} have not been used'.format(priority))
                # Nothing to do here anymore
                continue
            else:
                max_entries = fifo.get_member('entry').array_len
                self.formatter.output(
                    'FIFO of priority {0} information:\n'.format(priority))
                numelts = fifo.get_member('numelts').value
                self.formatter.output(
                    ' ' * 2 +
                    'Number of elements currently stored: {0}'.format(numelts))
                self.formatter.output(' ' * 2 +
                                      'Maximum number stored: {0}'.format(
                                          fifo.get_member('max').value))
                if numelts > 0:
                    # display pending elements
                    read_idx_initial = fifo.get_member('rdidx').value
                    for element_nr in range(numelts):
                        read_idx = (read_idx_initial +
                                    element_nr) % max_entries
                        element = fifo.get_member('entry').__getitem__(
                            read_idx)
                        self.formatter.output(
                            ' ' * 4 +
                            'Fifo entry at position: {0}'.format(read_idx))
                        self.formatter.output(
                            ' ' * 6 + 'Signal channel: {0}'.format(
                                element.get_member('sigchan').value))
                        self.formatter.output(' ' * 6 + 'Sender: {0}'.format(
                            element.get_member('sender').value))
                        self.formatter.output(
                            ' ' * 6 + 'Signal ID: {0}'.format(
                                element.get_member('sigid').value))
                        signal_ptr = element.get_member('sigreq').get_member(
                            'signal_ptr').value
                        self.formatter.output(
                            ' ' * 6 +
                            'Signal pointer: {0}'.format(cu.hex(signal_ptr)))

        self.formatter.section_end()
Esempio n. 27
0
    def analyse_messages(self, display_buffer=True, display_messages=False):
        '''
        @brief this method analyses information about messages of ipc and prints
            them to formatter. if True parameter is passed to the function,
            buffer containing messages is analysed as well
        @param[in] self Pointer to the current object
        @param[in] display_buffer Flag to indicate if the underlying buffer
            should be further analysed.
        @param[in] display_messages Flag to indicate if message information is
            needed.
        '''
        # Look up the debug information, unless we already have.
        if self._do_debuginfo_lookup:
            self._lookup_debuginfo()
            self._do_debuginfo_lookup = False

        self.formatter.section_start('IPC Messages Information')
        if self.ipc_msg_block_p == 0:
            self.formatter.output('No message information')
            self.formatter.section_end()
            if self.chipdata.is_volatile():
                self._do_debuginfo_lookup = True
            return

        msg_block = self.chipdata.cast(self.ipc_msg_block_p,
                                       'IPC_MESSAGE_BLOCK')
        self.formatter.output('Number of message channels used: {0}'.format(
            msg_block.get_member('number_of_channels').value))
        self.formatter.output('Maximum message size: {0}'.format(
            msg_block.get_member('max_msg_sz').value))
        self.formatter.output('Maximum number of messages: {0}'.format(
            msg_block.get_member('max_msgs').value))

        # there will be array of msg channels, so read messages from them
        msg_cannel_p_array = msg_block.get_member('ipc_message_channel')
        self.formatter.output('IPC message channels:')
        # there might be more than one channel if more processors are used
        for msg_channel_p in msg_cannel_p_array:
            msg_channel = self.chipdata.cast(msg_channel_p.value,
                                             'IPC_MESSAGE_CHANNEL')
            self.formatter.output('  Channel ID: {0}\n'.format(
                cu.hex(msg_channel.get_member('channel_id').value)))

            p0_to_px_msq_q = msg_channel.get_member('p0_2_px_message_queue')
            self.formatter.section_start('P0 to Px message queue:')
            self.print_message_queue(p0_to_px_msq_q, display_buffer,
                                     display_messages)
            self.formatter.section_end()

            px_to_p0_msg_q = msg_channel.get_member('px_2_p0_message_queue')
            self.formatter.section_start('Px to P0 message queue:')
            self.print_message_queue(px_to_p0_msg_q, display_buffer,
                                     display_messages)
            self.formatter.section_end()

        self.formatter.section_end()

        if self.chipdata.is_volatile():
            self._do_debuginfo_lookup = True
Esempio n. 28
0
    def get_watermarks(self):
        """
        @brief Returns the minimum available memory for the total, the free
        and the minimum free memories.
        @param[in] self Pointer to the current object
        """
        total_heap, free_heap, min_free_heap = self.ret_get_watermarks()

        output_str = ""
        output_str += ("entire heap memory, total size,   " +
                       cu.mem_size_to_string(total_heap) + "\n")
        output_str += ("entire heap memory, current free, " +
                       cu.mem_size_to_string(free_heap) + "\n")
        output_str += ("entire heap memory, minimum free, " +
                       cu.mem_size_to_string(min_free_heap) + "\n")
        # use output_raw to keep the spaces.
        self.formatter.output_raw(output_str)
Esempio n. 29
0
    def compact_name(self):
        """
        @brief Returns a tidy and short string representation of an endpoint object
        @param[in] self Pointer to the current object
        """
        ep_str = self.name.title() + " " + self.direction + " " + cu.hex(self.id)

        return ep_str
Esempio n. 30
0
 def output(self, string_to_output):
     """
     @brief Normal body text. Lists/dictionaries will be compacted.
     @param[in] self Pointer to the current object
     @param[in] string_to_output
     """
     with self.lock:
         self._log(cu.hex(string_to_output))