Example #1
0
def dump_estimate_cache(dump_path, rpm, memory, debug_info):
    est_cache_immediate_address = debug_info.variables[
        'rpm_estimate_cache_immediate'].address
    est_cache_immediate_type = debug_info.variables[
        'rpm_estimate_cache_immediate'].vartype
    rpm_estimate_cache_immediate = decode_object(
        'rpm_estimate_cache_immediate', est_cache_immediate_address,
        est_cache_immediate_type, memory, debug_info)

    est_cache_address = debug_info.variables['rpm_estimate_cache'].address
    est_cache_type = debug_info.variables['rpm_estimate_cache'].vartype
    rpm_estimate_cache = decode_object('rpm_estimate_cache', est_cache_address,
                                       est_cache_type, memory, debug_info)

    with open(os.path.join(dump_path, 'estimate_cache.txt'), 'w') as f:
        print('\n*** rpm_estimate_cache_immediate (Active -> Sleep) ***\n',
              file=f)
        for idx in range(rpm_estimate_cache_immediate.cacheSize_):
            systemTag = rpm_estimate_cache_immediate.cache_[idx].systemTag
            actionTag = rpm_estimate_cache_immediate.cache_[idx].actionTag
            resultState = rpm_estimate_cache_immediate.cache_[idx].resultState
            estimate = rpm_estimate_cache_immediate.cache_[idx].estimate
            usedSeq = rpm_estimate_cache_immediate.cache_[idx].usedSeq
            print('\tsystemTag = 0x%0.8x, actionTag = 0x%0.8x, resultState = 0x%0.8x, estimate = %d, usedSeq = %d\n' \
                  % (systemTag, actionTag, resultState, estimate, usedSeq), file=f)

        print('\n*** rpm_estimate_cache (Sleep -> Active) ***\n', file=f)
        for idx in range(rpm_estimate_cache.cacheSize_):
            systemTag = rpm_estimate_cache.cache_[idx].systemTag
            actionTag = rpm_estimate_cache.cache_[idx].actionTag
            resultState = rpm_estimate_cache.cache_[idx].resultState
            estimate = rpm_estimate_cache.cache_[idx].estimate
            usedSeq = rpm_estimate_cache.cache_[idx].usedSeq
            print('\tsystemTag = 0x%0.8x, actionTag = 0x%0.8x, resultState = 0x%0.8x, estimate = %d, usedSeq = %d\n' \
                  % (systemTag, actionTag, resultState, estimate, usedSeq), file=f)
Example #2
0
def dump(dump_path, memory, debug_info):
    address = locate_core_dump(memory, debug_info)
    dump_type = debug_info.variables['rpm_core_dump'].vartype
    rpm_core_dump = decode_object('rpm_core_dump', address, dump_type, memory,
                                  debug_info)
    dev_num = rpm_core_dump.hw_version.parts.device_number

    rpm = cast(rpm_core_dump.rpmserver_state, 'SystemData', memory, debug_info)

    if 'rpm_image_section_array' not in debug_info.variables:
        print_p('\t rpm_image_section_array not found in debug')

    else:
        try:
            rbcpr_type = debug_info.variables['rbcpr_stats_header'].vartype
            rbcpr_address = debug_info.variables[
                'rpm_image_section_array'].address
            rbcpr_address = rbcpr_address + 24
            rbcpr_stats = decode_object('rbcpr_stats', rbcpr_address,
                                        rbcpr_type, memory, debug_info)
        except:
            rbcpr_die = debug_info.variables['rbcpr_stats_header'].die
            rbcpr_address = debug_info.variables[
                'rpm_image_section_array'].address
            rbcpr_address = rbcpr_address + 24
            rbcpr_stats = decode_object('rbcpr_stats',
                                        rbcpr_address,
                                        None,
                                        memory,
                                        debug_info,
                                        die=rbcpr_die)

    dump_rbcpr(dump_path, rpm, rbcpr_stats, memory, debug_info, dev_num)
Example #3
0
def dump(dump_path, memory, debug_info):
    address = locate_core_dump(memory, debug_info)
    dump_type = debug_info.variables['rpm_core_dump'].vartype
    rpm_core_dump = decode_object('rpm_core_dump', address, dump_type, memory, debug_info)

    npa_type = debug_info.variables['npa'].vartype
    npa_state = rpm_core_dump.npa_state.address
    npa = decode_object('npa', npa_state, npa_type, memory, debug_info)

    dump_file = open(os.path.join(dump_path, 'npa-dump.txt'), 'w')

    link = npa.resources
    while link.address != 0:
        dump_link(dump_file, link)
        link = link.next
Example #4
0
def dump(dump_path, memory, debug_info, target_family):
    global ee_names
    ee_names = ee_names_family[target_family]
    address = locate_core_dump(memory, debug_info)
    dump_type = debug_info.variables['rpm_core_dump'].vartype
    rpm_core_dump = decode_object('rpm_core_dump', address, dump_type, memory,
                                  debug_info)

    #import pdb; pdb.set_trace()
    rpm = cast(rpm_core_dump.rpmserver_state, 'SystemData', memory, debug_info)
    '''
    rpm_type = rpm_core_dump._find_basic_type(debug_info.variables['rpm'].die)
    rpm_type = rpm_core_dump._unwrap(rpm_type) # "dereference" the type--rpm_core_dump already points at the state itself
    rpm_type = rpm_core_dump._find_basic_type(rpm_type)
    rpm_state = rpm_core_dump.rpmserver_state.address
    rpm = decode_object('rpm', rpm_state, None, memory, debug_info, die=rpm_type)
    '''

    #save_logger_level = logging.getLogger('dwarf').getEffectiveLevel()
    #logging.getLogger('dwarf').setLevel(logging.DEBUG)
    dump_ee_status(dump_path, rpm, memory, debug_info)
    #logging.getLogger('dwarf').setLevel(save_logger_level)
    dump_ee_requests(dump_path, rpm, memory, debug_info)
    dump_resource_requests(dump_path, rpm, memory, debug_info)
    dump_lookup_table(dump_path, rpm, memory, debug_info)
    dump_estimate_cache(dump_path, rpm, memory, debug_info)
Example #5
0
def cast(obj, typename, memory, debug_info):
    type_die = debug_info.types[typename]
    return decode_object(obj._name,
                         obj.address,
                         None,
                         memory,
                         debug_info,
                         die=type_die)
Example #6
0
def dump(debug_data):  #dump_path, memory, debug_info):
    memory = debug_data['rpm_memory']
    debug_info = debug_data['debug_info']
    dump_path = debug_data['dump_path']

    debug_data['printer'].p("Dumping sleep stats...")

    address = locate_core_dump(memory, debug_info)
    dump_type = debug_info.variables['aop_core_dump'].vartype
    aop_core_dump = decode_object('aop_core_dump', address, dump_type, memory,
                                  debug_info)

    rpm = 0  #cast(aop_core_dump.rpmserver_state, 'SystemData', memory, debug_info)

    if (check_member('sleep_stats', aop_core_dump)):
        #sleep_stats in in core dump
        sleep = aop_core_dump.sleep_stats
        sleep = cast(sleep, 'sleep_stats_type', memory, debug_info)
    else:
        try:
            sleep_type = debug_info.variables['sleep_stats'].die
        except:
            sleep_file_name = os.path.join(dump_path, 'sleep_stats.txt')
            with open(sleep_file_name, 'w') as sleep_file:
                print(
                    "\n !!! SLEEP_STATS DOES NOT EXIST, SLEEP IS LIKELY NOT ENABLED !!! \n",
                    file=sleep_file)
            return
        try:
            #not in core dump, but elf is close enough to provide a correct pointer
            sleep_address = debug_info.variables[
                'sleep_stats'].address  # FIXME: get right address by magic
            sleep = decode_object('sleep_stats',
                                  sleep_address,
                                  None,
                                  memory,
                                  debug_info,
                                  die=sleep_type)
        except:
            sleep_file_name = os.path.join(dump_path, 'sleep_stats.txt')
            with open(sleep_file_name, 'w') as sleep_file:
                print(
                    "\n !!! SLEEP_STATS DOES NOT EXIST, SLEEP IS LIKELY NOT ENABLED !!! \n",
                    file=sleep_file)
            return
    dump_sleep(dump_path, rpm, sleep, memory, debug_info)
Example #7
0
def cast(obj, typename, memory, debug_info, address=None):
    type_die = debug_info.types[typename]
    if hasattr(obj, '_name'):
        return decode_object(obj._name,
                             obj.address,
                             None,
                             memory,
                             debug_info,
                             die=type_die)
    elif address:
        return decode_object('',
                             address,
                             None,
                             memory,
                             debug_info,
                             die=type_die)
    else:
        return decode_object('', 0, None, memory, debug_info, die=type_die)
Example #8
0
def dump(dump_path, memory, debug_info):
    address = locate_core_dump(memory, debug_info)
    dump_type = debug_info.variables['rpm_core_dump'].vartype
    rpm_core_dump = decode_object('rpm_core_dump', address, dump_type, memory,
                                  debug_info)

    rpm = cast(rpm_core_dump.rpmserver_state, 'SystemData', memory, debug_info)

    if (check_member('sleep_stats', rpm_core_dump)):
        #sleep_stats in in core dump
        sleep = rpm_core_dump.sleep_stats
        sleep = cast(sleep, 'sleep_stats_type', memory, debug_info)
    else:
        try:
            #not in core dump, but elf is close enough to provide a correct pointer
            sleep_type = debug_info.variables['sleep_stats'].die
            sleep_address = debug_info.variables[
                'sleep_stats'].address  # FIXME: get right address by magic
            sleep = decode_object('sleep_stats',
                                  sleep_address,
                                  None,
                                  memory,
                                  debug_info,
                                  die=sleep_type)
        except:
            #not correct in elf, find absolute address (very hacky)
            sleep_type = debug_info.variables['sleep_stats'].die
            sleep_address = find_value(0x0019DBA0, 4, 0x00190000, 0x0019FFFF,
                                       memory)
            sleep = decode_object('sleep_stats',
                                  sleep_address,
                                  None,
                                  memory,
                                  debug_info,
                                  die=sleep_type)
    '''
    print(debug_info.variables['sleep_stats'].die)
    #sleep_address = 0x0019DBA0
    sleep_address = debug_info.variables['sleep_stats'].address
    sleep = decode_object('sleep_stats', sleep_address, sleep_type, memory, debug_info)
    '''

    #save_logger_level = update_logger(logging.DEBUG, logging)
    dump_sleep(dump_path, rpm, sleep, memory, debug_info)
Example #9
0
def dump(dump_path, memory, debug_info, ocimem_load, pmic_rtc_load):
    address = locate_core_dump(memory, debug_info)
    dump_type = debug_info.variables['rpm_core_dump'].vartype
    rpm_core_dump = decode_object('rpm_core_dump', address, dump_type, memory, debug_info)

    #import pdb; pdb.set_trace()
    rpm = cast(rpm_core_dump.rpmserver_state, 'SystemData', memory, debug_info)

    #save_logger_level = update_logger(logging.DEBUG, logging)
    dump_wdog(dump_path, rpm, memory, debug_info, ocimem_load, pmic_rtc_load)
Example #10
0
def dump(dump_path, memory, debug_info):
    address = locate_core_dump(memory, debug_info)
    dump_type = debug_info.variables['rpm_core_dump'].vartype
    rpm_core_dump = decode_object('rpm_core_dump', address, dump_type, memory, debug_info)

    #import pdb; pdb.set_trace()
    rpm = cast(rpm_core_dump.rpmserver_state, 'SystemData', memory, debug_info)

    #save_logger_level = logging.getLogger('dwarf').getEffectiveLevel()
    #print(save_logger_level)
    #logging.getLogger('dwarf').setLevel(logging.DEBUG)
    #print(logging.getLogger('dwarf').getEffectiveLevel())
    dump_railway(dump_path, rpm, memory, debug_info)
Example #11
0
def dump(debug_data):  #dump_path, memory, debug_info, fill_char):
    global dump_error

    dump_error = 0
    memory = debug_data['rpm_memory']
    debug_info = debug_data['debug_info']
    fill_char = debug_data['args'].fill_char
    dump_path = debug_data['dump_path']
    target = debug_data['target']

    debug_data['printer'].p("Dumping Task Details...")

    try:

        task_file_name = os.path.join(dump_path, 'task_info.txt')

        with open(task_file_name, 'w') as task_file:

            print('{0: <20}'.format("Thread Name") +
                  '{0: <10}'.format("Priority") + '{0: <10}'.format("Wait") +
                  '{0: <10}'.format("Sigs") + '{0: <5}'.format("Suspended"),
                  file=task_file)
            print(
                "-------------------------------------------------------------------",
                file=task_file)

            for task_name in task_list:
                tcb_address = debug_info.variables[task_name].address
                tcb_type = debug_info.variables[task_name].die
                tcb = decode_object(task_name,
                                    tcb_address,
                                    None,
                                    memory,
                                    debug_info,
                                    die=tcb_type)

                print('{0: <20}'.format(task_name) +
                      '{0: <10}'.format(str(tcb.pri)) +
                      '{0: <10}'.format(str(hex(tcb.wait))) +
                      '{0: <10}'.format(str(hex(tcb.sigs))) +
                      '{0: <5}'.format(str(bool(tcb.suspended))),
                      file=task_file)
    except:
        dump_error = 1

    if dump_error != 0:
        debug_data['printer'].p(
            "\t...Non-critical errors occured in processing dump, continuing")
    else:
        debug_data['printer'].p("\t...DONE")
Example #12
0
def dump(debug_data):  #dump_path, memory, debug_info, fill_char):
    global dump_error

    dump_error = 0
    memory = debug_data['rpm_memory']
    debug_info = debug_data['debug_info']
    fill_char = debug_data['args'].fill_char
    dump_path = debug_data['dump_path']
    target = debug_data['target']

    debug_data['printer'].p("Dumping AOP Logs from MSGRAM...")

    try:
        aop_log_file_name = os.path.join(dump_path, 'aop_log_msgram6.txt')

        with open(aop_log_file_name, 'w') as aop_log_file:

            print('{0: <20}'.format("Timestamp") +
                  '{0: <20}'.format("Message") + '{0: <20}'.format("Data"),
                  file=aop_log_file)
            print(
                "-------------------------------------------------------------------",
                file=aop_log_file)

            log_address = debug_info.variables['aop_log_data'].address
            #print(hex(log_address))
            log_type = debug_info.variables['aop_log_data'].die
            log = decode_object('aop_log_data',
                                log_address,
                                None,
                                memory,
                                debug_info,
                                die=log_type)

            for log_num in range(0, 60):
                print('{0: <20}'.format(hex(log[log_num].timestamp_lo)) +
                      '{0: <20}'.format(
                          conhexToAscii(hex(log[log_num].message[0])) +
                          conhexToAscii(hex(log[log_num].message[1]))) + "  " +
                      '{0: <20}'.format(hex(log[log_num].data)),
                      file=aop_log_file)

    except:
        dump_error = 1

    if dump_error != 0:
        debug_data['printer'].p(
            "\t...Non-critical errors occured in processing dump, continuing")
    else:
        debug_data['printer'].p("\t...DONE")
Example #13
0
def dump(debug_data): #dump_path, memory, debug_info):
    memory = debug_data['rpm_memory']
    debug_info = debug_data['debug_info']
    dump_path = debug_data['dump_path']

    debug_data['printer'].p("Dumping Frequency switch info...")

    address = locate_core_dump(memory, debug_info)
    dump_type = debug_info.variables['aop_core_dump'].vartype
    aop_core_dump = decode_object('aop_core_dump', address, dump_type, memory, debug_info)

    rpm = 0#cast(aop_core_dump.rpmserver_state, 'SystemData', memory, debug_info)

    if (check_member('freq_switch_table_ptr ', aop_core_dump)):
        #freq_switch_table_ptr in in core dump
        freq_switch = aop_core_dump.freq_switch_table_ptr
        freq_switch = cast(freq_switch, 'ddr_stats_type', memory, debug_info)
    else:
        try:
            freq_switch_type = debug_info.variables['freq_switch_table_ptr'].die
        except:
            freq_switch_file_name = os.path.join(dump_path, 'ddr_stats.txt')
            with open(freq_switch_file_name, 'a') as freq_switch_file:
                print("\n !!! FREQ SWITCH INFO DOES NOT EXIST !!! \n", file=freq_switch_file)
            return
        try:
            #not in core dump, but elf is close enough to provide a correct pointer
            freq_switch_address = debug_info.variables['freq_switch_table_ptr'].address # FIXME: get right address by magic
            freq_switch = decode_object('freq_switch_table_ptr', freq_switch_address, None, memory, debug_info, die=freq_switch_type)
        except:
            freq_switch_file_name = os.path.join(dump_path, 'ddr_stats.txt')
            with open(freq_switch_file_name, 'a') as freq_switch_file:
                print("\n !!! FREQ SWITCH INFO DOES NOT EXIST !!! \n", file=freq_switch_file)
            return
	
	#import pdb; pdb.set_trace()
	dump_ddr(dump_path, rpm, freq_switch, memory, debug_info)
Example #14
0
def dump(debug_data):  #dump_path, memory, debug_info):
    global dump_error
    dump_error = 0
    memory = debug_data['rpm_memory']
    debug_info = debug_data['debug_info']
    dump_path = debug_data['dump_path']
    reclaim = debug_data['reclaim_pool']

    debug_data['printer'].p("Dumping NPA state...")

    address = locate_core_dump(memory, debug_info)
    dump_type = debug_info.variables['aop_core_dump'].vartype
    aop_core_dump = decode_object('aop_core_dump', address, dump_type, memory,
                                  debug_info)

    unpa_type = debug_info.variables['unpa'].die
    unpa_address = debug_info.variables['unpa'].address
    unpa = decode_object('unpa',
                         unpa_address,
                         None,
                         memory,
                         debug_info,
                         die=unpa_type)

    dump_file = open(os.path.join(dump_path, 'npa-dump.txt'), 'w')

    link = unpa.resources
    while link.address != 0:
        dump_link(dump_file, link, reclaim)
        link = link.next

    if dump_error != 0:
        debug_data['printer'].p(
            "\t...Non-critical errors occured in processing dump, continuing")
    else:
        debug_data['printer'].p("\t...DONE")
Example #15
0
def dump(debug_data):  #dump_path, memory, debug_info, fill_char):
    global dump_error
    global ARC_votetable, ARC_votetable2
    global no_rm
    global no_drv, g_res
    global vt_base_address, rm_blk_enb_base_addr, rm_ol_base_addr, rm_seq_base_addr
    dump_error = 0
    memory = debug_data['rpm_memory']
    debug_info = debug_data['debug_info']
    fill_char = debug_data['args'].fill_char
    dump_path = debug_data['dump_path']
    target = debug_data['target']
    target_ver = target + '-' + str(chip_version)
    if target_ver in targ_spec_config:
        target = target_ver
    debug_data['printer'].p("Dumping ARC Vote table registers...")

    vt_base_address = targ_spec_config[target]['arc']['vt_base_address']
    rm_blk_enb_base_addr = targ_spec_config[target]['arc']['rm_enb_base_addr']
    rm_ol_base_addr = targ_spec_config[target]['arc']['rm_ol_base_addr']
    rm_seq_base_addr = targ_spec_config[target]['arc']['rm_seq_base_addr']
    no_rm = targ_spec_config[target]['arc']['no_rm']
    no_drv = targ_spec_config[target]['arc']['no_drv']
    ARC_votetable = [[0 for i in range(no_drv)] for j in range(no_rm)]
    ARC_votetable2 = [[0 for i in range(no_drv)] for j in range(no_rm)]

    try:
        ver_data = memory.read(rm_ol_base_addr, 4)
    except:
        debug_data['printer'].p("\tARC registers bin is not recovered...")
        return

    g_res_type = debug_info.variables['g_res'].die
    g_res_address = debug_info.variables['g_res'].address
    g_res = decode_object('g_res',
                          g_res_address,
                          None,
                          memory,
                          debug_info,
                          die=g_res_type)
    #import pdb; pdb.set_trace()
    dump_arc_summary(dump_path, memory, target, g_res, debug_info, fill_char)

    if dump_error != 0:
        debug_data['printer'].p(
            "\t...Non-critical errors occured in processing dump, continuing")
    else:
        debug_data['printer'].p("\t...DONE")
Example #16
0
def dump_struct(address, memory, debug_info, struct_type, raw_size):
    try:
        obj = decode_object('request',
                            address,
                            None,
                            memory,
                            debug_info,
                            die=debug_info.types[struct_type])
    except Exception as e:
        logger.info(
            'Failed to parse data via magic structure parsing of %s -> (%s); falling back to dump mode.'
            % (struct_type, e))
        return hexlify(memory.read(address, raw_size))

    if type(obj) != Structure:
        return str(obj)

    out_lines = ['\n\t{']
    for member_name, member_value in obj.members():
        out_lines.append('\t\t%s : %s,' % (member_name, member_value))
    out_lines.append('\t}')
    return '\n'.join(out_lines)
Example #17
0
def dump(debug_data):  #dump_path, memory, debug_info):
    memory = debug_data['rpm_memory']
    debug_info = debug_data['debug_info']
    dump_path = debug_data['dump_path']

    debug_data['printer'].p("Dumping DDR stats...")

    address = locate_core_dump(memory, debug_info)
    dump_type = debug_info.variables['aop_core_dump'].vartype
    aop_core_dump = decode_object('aop_core_dump', address, dump_type, memory,
                                  debug_info)

    if (check_member('ddr_stats', aop_core_dump)):
        #ddr_stats in in core dump
        ddr = aop_core_dump.ddr_stats
        ddr = cast(ddr, 'ddr_stats_type', memory, debug_info)
    else:
        try:
            freq_switch_address = debug_info.variables['ddr_stats'].die
        except:
            ddr_file_name = os.path.join(dump_path, 'ddr_stats.txt')
            with open(ddr_file_name, 'w') as ddr_file:
                print("\n !!! DDR_STATS DOES NOT EXIST !!! \n", file=ddr_file)
            return
        try:
            #not in core dump, but elf is close enough to provide a correct pointer
            ddr_address = debug_info.variables[
                'ddr_stats'].address  # FIXME: get right address by magic
            ddr = decode_object('ddr_stats',
                                ddr_address,
                                None,
                                memory,
                                debug_info,
                                die=freq_switch_address)
        except:
            #not correct in elf, find absolute address (very hacky)
            with open(ddr_file_name, 'w') as ddr_file:
                print("\n !!! DDR_STATS DOES NOT EXIST !!! \n", file=ddr_file)
            return
################################################################################################################################
#import pdb; pdb.set_trace()
        if (check_member('ddr_status', aop_core_dump)):
            #ddr_status in in core dump
            ddr_status = aop_core_dump.ddr_status
            ddr_status = cast(ddr_status, 'ddr_state', memory,
                              debug_info)  ###################################
        else:
            try:
                freq_switch_address = debug_info.variables[
                    'ddr_status'].die  ###################################
            except:
                ddr_file_name = os.path.join(dump_path, 'ddr_stats.txt')
                with open(ddr_file_name, 'w') as ddr_file:
                    print("\n !!! DDR_STATUS DOES NOT EXIST !!! \n",
                          file=ddr_file)
                return
            try:
                #not in core dump, but elf is close enough to provide a correct pointer
                ddr_status_address = debug_info.variables[
                    'ddr_status'].address  # FIXME: get right address by magic
                ddr_status = decode_object('ddr_status',
                                           ddr_status_address,
                                           None,
                                           memory,
                                           debug_info,
                                           die=freq_switch_address)
            except:
                #not correct in elf, find absolute address (very hacky)
                with open(ddr_file_name, 'w') as ddr_file:
                    print("\n !!! DDR_STATUS DOES NOT EXIST !!! \n",
                          file=ddr_file)
                return


################################################################################################################################
    if (check_member('global_ddr_cfg ', aop_core_dump)):
        #global_ddr_cfg  in in core dump
        ddr_cfg = aop_core_dump.global_ddr_cfg
        ddr_cfg = cast(ddr_cfg, 'DDRCfgType', memory, debug_info)
    else:
        try:
            ddr_cfg_address = debug_info.variables['global_ddr_cfg'].die
        except:
            ddr_file_name = os.path.join(dump_path, 'ddr_stats.txt')
            with open(ddr_file_name, 'w') as ddr_file:
                print("\n !!! DDR_CFG DOES NOT EXIST !!! \n", file=ddr_file)
            return
        try:
            #not in core dump, but elf is close enough to provide a correct pointer
            ddr_gbl_address = debug_info.variables[
                'global_ddr_cfg'].address  # FIXME: get right address by magic
            ddr_cfg = decode_object('global_ddr_cfg',
                                    ddr_gbl_address,
                                    None,
                                    memory,
                                    debug_info,
                                    die=ddr_cfg_address)
        except:
            #not correct in elf, find absolute address (very hacky)
            with open(ddr_file_name, 'w') as ddr_file:
                print("\n !!! DDR_cfg DOES NOT EXIST !!! \n", file=ddr_file)
            return

    #import pdb; pdb.set_trace()
    #save_logger_level = update_logger(logging.DEBUG, logging)
    dump_ddr(dump_path, ddr_cfg, ddr, ddr_status, memory, debug_info)
Example #18
0
def dump_ee_requests(dump_path, rpm, memory, debug_info):
    dump_path = os.path.join(dump_path, 'reqs_by_master')
    if not os.path.exists(dump_path):
        os.makedirs(dump_path)

    est_address = debug_info.variables['rpm_estimator'].address
    est_type = debug_info.variables['rpm_estimator'].vartype
    rpm_estimator = decode_object('rpm_estimator', est_address, est_type,
                                  memory, debug_info)
    cpu_kHz = rpm_estimator.clockFreqkHz_

    for ee in range(rpm.num_ees):
        ee_reqs_file_name = os.path.join(dump_path, ee_names[ee] + '.txt')
        with open(ee_reqs_file_name, 'w') as ee_reqs_file:
            ee_reqs = []

            print('\n\tcpu_kHz : [%d, %d]' % (cpu_kHz[0], cpu_kHz[1]),
                  file=ee_reqs_file)

            for idx in range(rpm.supported_resources):
                resource = rpm.resources[idx]
                if resource.current_state.address == 0:
                    logger.debug(
                        '[dump_ee_requests]: Skipping unused resource idx %d' %
                        idx)
                    continue

                rcd = rpm.classes[resource.class_idx]

                #import pdb; pdb.set_trace()
                if (resource.ees.address == 0):
                    logger.debug(
                        '[dump_ee_requests]: Skipping NULL resource idx %d for ee %d'
                        % (idx, ee))
                    continue

                if (True == check_member('ee_id', resource.ees)):
                    #New memory saving EEClient structure
                    ee_client = resource.ees
                    while (ee_client.ee_id != ee):
                        if ee_client.next.address == 0:
                            ee_reqs.append({
                                'rcd': rcd,
                                'type': rcd.type,
                                'id': resource.id,
                                'estimates': resource.estimates,
                                'selected_type': 'NO_REQUEST',
                                'selected_request': 'n/a',
                                'spare_type': 'NO_REQUEST',
                                'spare_request': 'n/a',
                                'message': '{not allocated}',
                            })
                            break
                        ee_client = ee_client.next
                    if (ee_client.ee_id != ee and ee_client.next.address == 0):
                        continue
                else:
                    #Old EEClient structure
                    ee_client = resource.ees[ee]

                selected = ee_client.selected
                selected_type = ee_client.req_type[selected]
                selected_request = ee_client.request[selected].address

                spare = 1 ^ selected
                spare_type = ee_client.req_type[spare]
                spare_request = ee_client.request[spare].address

                ee_reqs.append({
                    'rcd': rcd,
                    'type': rcd.type,
                    'id': resource.id,
                    'estimates': resource.estimates,
                    'selected_type': selected_type,
                    'selected_request': selected_request,
                    'spare_type': spare_type,
                    'spare_request': spare_request,
                    'message': '',
                })

            for request in sorted(ee_reqs,
                                  key=lambda req: (req['type'], req['id'])):
                rcd = request['rcd']
                rtype = type_to_str(request['type'])
                rid = request['id']
                msg = request['message']
                ests = request['estimates']
                print('\n*** %s %d ***' % (rtype, rid), file=ee_reqs_file)

                if (request['selected_type']
                        == 'NO_REQUEST') and (request['spare_type']
                                              == 'NO_REQUEST'):
                    continue

                print('\testimates: [%d, %d]' % (ests[0], ests[1]),
                      file=ee_reqs_file)

                selected_request = 'n/a' if request[
                    'selected_type'] == 'NO_REQUEST' else format_request(
                        request['selected_request'], rcd, memory, debug_info)
                print('\n\tselected request [%s] -> %s %s' %
                      (request['selected_type'], selected_request, msg),
                      file=ee_reqs_file)

                spare_request = 'n/a' if request[
                    'spare_type'] == 'NO_REQUEST' else format_request(
                        request['spare_request'], rcd, memory, debug_info)
                print('\n\tspare request [%s] -> %s %s\n' %
                      (request['spare_type'], spare_request, msg),
                      file=ee_reqs_file)
Example #19
0
def dump_bcm_vts(dump_path, memory, target, debug_info, fill_char,
                 bcm_json_dir):

    address = locate_core_dump(memory, debug_info)
    dump_type = debug_info.variables['aop_core_dump'].vartype
    aop_core_dump = decode_object('aop_core_dump', address, dump_type, memory,
                                  debug_info)
    json_file_name = os.path.join(bcm_json_dir, str(target) + "/VCD.json")

    with open(json_file_name, 'r') as data_file:
        data = json.load(data_file)
####################################################################################################################

    if (check_member('global_ddr_cfg ', aop_core_dump)):
        ddr_cfg = aop_core_dump.global_ddr_cfg
        ddr_cfg = cast(ddr_cfg, 'DDRCfgType', memory, debug_info)
    else:
        try:
            ddr_cfg_address = debug_info.variables['global_ddr_cfg'].die
        except:
            ddr_file_name = os.path.join(dump_path, 'ddr_stats.txt')
            with open(ddr_file_name, 'w') as ddr_file:
                print("\n !!! DDR_CFG DOES NOT EXIST !!! \n", file=ddr_file)

        try:
            #not in core dump, but elf is close enough to provide a correct pointer
            ddr_gbl_address = debug_info.variables[
                'global_ddr_cfg'].address  # FIXME: get right address by magic
            ddr_cfg = decode_object('global_ddr_cfg',
                                    ddr_gbl_address,
                                    None,
                                    memory,
                                    debug_info,
                                    die=ddr_cfg_address)
        except:
            #not correct in elf, find absolute address (very hacky)
            with open(ddr_file_name, 'w') as ddr_file:
                print("\n !!! DDR_cfg DOES NOT EXIST !!! \n", file=ddr_file)
    ####################################################################################################################
    if (check_member('ddr_status', aop_core_dump)):
        #ddr_status in in core dump
        ddr_status = aop_core_dump.ddr_status
        ddr_status = cast(ddr_status, 'ddr_state', memory,
                          debug_info)  ###################################
    else:
        try:
            freq_switch_address = debug_info.variables[
                'ddr_status'].die  ###################################
        except:
            ddr_file_name = os.path.join(dump_path, 'ddr_stats.txt')
            with open(ddr_file_name, 'w') as ddr_file:
                print("\n !!! DDR_STATUS DOES NOT EXIST !!! \n", file=ddr_file)
            return
        try:
            #not in core dump, but elf is close enough to provide a correct pointer
            ddr_status_address = debug_info.variables[
                'ddr_status'].address  # FIXME: get right address by magic
            ddr_status = decode_object('ddr_status',
                                       ddr_status_address,
                                       None,
                                       memory,
                                       debug_info,
                                       die=freq_switch_address)
        except:
            #not correct in elf, find absolute address (very hacky)
            with open(ddr_file_name, 'w') as ddr_file:
                print("\n !!! DDR_STATUS DOES NOT EXIST !!! \n", file=ddr_file)
            ####################################################################################################################

    dump_path = os.path.join(dump_path, 'reqs_for_resources')
    if not os.path.exists(dump_path):
        os.makedirs(dump_path)
    bcm_file_name = os.path.join(dump_path, 'bcm_vt.txt')
    summary_file_name = os.path.join(dump_path, 'rpmh_summary.txt')

    with open(bcm_file_name, 'w') as bcm_file, open(summary_file_name,
                                                    'a') as summary_file:

        print("\n\t~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~",
              file=bcm_file)
        print("\t| VCD |                  Nodes                  |",
              file=bcm_file)
        print("\t~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~",
              file=bcm_file)
        for x in range(0, no_vcds):
            print("\t|{0:>5d}|{1:>41s}|".format(x, vcd_map_table[x]),
                  file=bcm_file)
        print("\t~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~",
              file=bcm_file)

        print("\n ~~BCM Status Front End~~", file=bcm_file)
        print(
            "\n\t~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~",
            file=bcm_file)
        print(
            "\t|       VCD             | AGG_BW | Final_CP | AGG_CP | DDR MGR Override AGG_CP |                   Freq_khz                     |",
            file=bcm_file)
        print(
            "\t~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~",
            file=bcm_file)
        for x in range(0, no_vcds):
            address = bcm_status_fe + (0x4 * x)
            fe_data = memory.read(address, 4)
            fe_status = struct.unpack('<L', fe_data)[0]
            agg_cp = fe_status & 0xF
            final_cp = ((fe_status >> 4) & 0xF)
            agg_bw = ((fe_status >> 16) & 0x3FFF)

            # if x==0: #mc
            # for x in range(0, ddr_cfg.nNumMCStates):
            # if (ddr_cfg.pMCCfg[x].clk_idx==agg_cp):
            # frq=ddr_cfg.pMCCfg[x].freq_khz

            # elif x==1: #shub
            # for y in range(0, ddr_cfg.nNumSHUBStates):
            # if (ddr_cfg.pSHUBCfg[y].clk_idx==agg_cp):
            # frq=ddr_cfg.pSHUBCfg[y].freq_khz

            ddr_mc_cp = hex(ddr_status.current_mc_cp)
            ddr_shub_cp = hex(ddr_status.current_shub_cp)

            flag = 0
            for key, value in data.items():
                if (data[key]["VCD Index"] == x):
                    if (x == 0):
                        v5 = str(ddr_mc_cp)
                        if (ddr_mc_cp != 0x0):
                            flag = 1
                            var_print = key
                            v1 = hex(agg_bw)
                            v2 = hex(final_cp)
                            v3 = hex(agg_cp)
                            v4 = str(x) + ":"
                            for y in data[key]["Clock Domains"]:
                                print(
                                    "\t|{0:3s}{1:>20s}|{2:>8s}|{3:>10s}|{4:>8s}|{5:>25s}|{6:30s}: {7:>17s}|"
                                    .format(v4, var_print, v1, v2, v3, v5,
                                            y["domain"], (str(y["freq"][int(
                                                ddr_mc_cp,
                                                16)]).split(":")[1])[3:-2]),
                                    file=bcm_file)
                                var_print = ""
                                v1 = ""
                                v2 = ""
                                v3 = ""
                                v4 = ""
                                v5 = ""

                    elif (x == 1):
                        v5 = str(ddr_shub_cp)
                        if (ddr_shub_cp != 0x0):
                            flag = 1
                            var_print = key
                            v1 = hex(agg_bw)
                            v2 = hex(final_cp)
                            v3 = hex(agg_cp)
                            v4 = str(x) + ":"
                            for y in data[key]["Clock Domains"]:
                                print(
                                    "\t|{0:3s}{1:>20s}|{2:>8s}|{3:>10s}|{4:>8s}|{5:>25s}|{6:30s}: {7:>17s}|"
                                    .format(v4, var_print, v1, v2, v3, v5,
                                            y["domain"], (str(y["freq"][int(
                                                ddr_shub_cp,
                                                16)]).split(":")[1])[3:-2]),
                                    file=bcm_file)
                                var_print = ""
                                v1 = ""
                                v2 = ""
                                v3 = ""
                                v4 = ""
                                v5 = ""
                    else:
                        v5 = "NA"
                        if (agg_cp != 0):
                            flag = 1
                            var_print = key
                            v1 = hex(agg_bw)
                            v2 = hex(final_cp)
                            v3 = hex(agg_cp)
                            v4 = str(x) + ":"
                            for y in data[key]["Clock Domains"]:
                                print(
                                    "\t|{0:3s}{1:>20s}|{2:>8s}|{3:>10s}|{4:>8s}|{5:>25s}|{6:30s}: {7:>17s}|"
                                    .format(
                                        v4, var_print, v1, v2, v3, v5,
                                        y["domain"],
                                        (str(y["freq"][agg_cp]).split(":")[1]
                                         )[3:-2]),
                                    file=bcm_file)
                                var_print = ""
                                v1 = ""
                                v2 = ""
                                v3 = ""
                                v4 = ""
                                v5 = ""

            if (flag == 0):
                v6 = str(x) + ":"
                print("\t|{0:<23s}|{1:>8s}|{2:>10s}|{3:>8s}|{4:>25s}|{5:50s}|".
                      format(v6, hex(agg_bw), hex(final_cp), hex(agg_cp), "NA",
                             ""),
                      file=bcm_file)
            print(
                "\t~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~",
                file=bcm_file)

        print("\n ~~BCM Status Back End~~", file=bcm_file)
        print(
            "\n\t~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~",
            file=bcm_file)
        print(
            "\t| VCD | Clk_dest_state | Combined_CP | SW_CP_SNAP | Written_CP | CURR_CP |",
            file=bcm_file)
        print(
            "\t~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~",
            file=bcm_file)
        for x in range(0, no_vcds):
            address = bcm_status_be + (0x4 * x)
            fe_data = memory.read(address, 4)
            fe_status = struct.unpack('<L', fe_data)[0]
            curr_cp = fe_status & 0xF
            written_cp = ((fe_status >> 4) & 0xF)
            sw_cp = ((fe_status >> 8) & 0xF)
            combined_cp = ((fe_status >> 12) & 0xF)
            clk_dest = ((fe_status >> 16) & 0xF)
            print("\t|{0:>5d}|{1:>16s}|{2:>13s}|{3:>12s}|{4:>12s}|{5:>9s}|".
                  format(x, hex(clk_dest), hex(combined_cp), hex(sw_cp),
                         hex(written_cp), hex(curr_cp)),
                  file=bcm_file)
        print(
            "\t~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~",
            file=bcm_file)

        print("\n ~~BCM Back End Sequencer~~", file=bcm_file)
        print("\n ~~BCM Status~~", file=summary_file)
        print("\n\t~~~~~~~~~~~~~~~~~~~~~~~~~~~~", file=bcm_file)
        print("\t| VCD | SEQ_CURR_PC | IDLE |", file=bcm_file)
        print("\t~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~", file=bcm_file)
        for x in range(0, no_vcds):
            address = bcm_status_be_seq + (0x4 * x)
            fe_data = memory.read(address, 4)
            fe_status = struct.unpack('<L', fe_data)[0]
            seq_state = fe_status & 0x1
            curr_pc = ((fe_status >> 8) & 0xFF)
            print("\t|{0:>5d}|{1:>8s}|{2:>10s}|".format(
                x, hex(curr_pc), hex(seq_state)),
                  file=bcm_file)
            if seq_state:
                print("\tVCD %d is Idle" % (x), file=summary_file)
            else:
                print("\tVCD %d is Busy" % (x), file=summary_file)
        print("\t~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~", file=bcm_file)

        print("\n\n ~~BCM Resource Summary~~", file=bcm_file)
        #import pdb; pdb.set_trace()
        for regs in range(0, no_regs):
            if bcm_map_table[regs] == ' ':
                continue
            print('\n\n\t BCM [%d] : %s ' % (regs, bcm_map_table[regs]),
                  file=bcm_file)
            print("\t\t~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~",
                  file=bcm_file)
            print("\t\t|    DRV   | ID | Valid |   AB   |   IB   |",
                  file=bcm_file)
            print("\t\t~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~",
                  file=bcm_file)

            for drv in range(0, no_drv):
                address = vt_base_address + (0x10000 * drv) + (0x4 * regs)
                bcm_data = memory.read(address, 4)
                bcm_vt = struct.unpack('<L', bcm_data)[0]
                vote_valid = ((bcm_vt >> 29) & 0x1)
                vote_x = ((bcm_vt >> 14) & 0x3FFF)
                vote_y = (bcm_vt & 0x3FFF)
                if bcm_vt != 0:
                    print("\t\t|{0:>10s}|{1:>4d}|{2:>7d}|{3:>8s}|{4:>8s}|".
                          format((targ_spec_config[target]['drv'][drv]), drv,
                                 vote_valid, hex(vote_x), hex(vote_y)),
                          file=bcm_file)
                BCM_votetable[regs][drv] = [vote_valid, vote_x, vote_y]
Example #20
0
def dump_resource_requests(dump_path, rpm, memory, debug_info):
    dump_path = os.path.join(dump_path, 'reqs_by_resource')

    est_address = debug_info.variables['rpm_estimator'].address
    est_type = debug_info.variables['rpm_estimator'].vartype
    rpm_estimator = decode_object('rpm_estimator', est_address, est_type,
                                  memory, debug_info)
    cpu_kHz = rpm_estimator.clockFreqkHz_

    resources = []
    for idx in range(rpm.supported_resources):
        resource = rpm.resources[idx]
        if resource.current_state.address == 0:
            logger.debug(
                '[dump_resource_requests]: Skipping unused resource idx %d' %
                idx)
            continue

        rcd = rpm.classes[resource.class_idx]
        rtype = type_to_str(rcd.type)

        rdir = os.path.join(dump_path, rtype)
        if not os.path.exists(rdir):
            os.makedirs(rdir)
        rpath = os.path.join(rdir, '%d.txt' % resource.id)

        with open(rpath, 'w') as f:
            status = format_request(resource.current_state.address, rcd,
                                    memory, debug_info)
            print('\nStatus -> %s\n' % status, file=f)

            print('cpu_kHz ->\n\t[%d, %d]\n' % (cpu_kHz[0], cpu_kHz[1]),
                  file=f)
            print('estimates ->\n\t[%d, %d]\n' %
                  (resource.estimates[0], resource.estimates[1]),
                  file=f)
            print('settling estimate ->\n\t%d\n' % (rcd.settling_estimate),
                  file=f)

            print('-=| External Requests (from other processors) |=-', file=f)
            for ee in range(rpm.num_ees):
                if (resource.ees.address == 0):
                    logger.debug(
                        '[dump_resource_requests]: Skipping NULL resource idx %d for ee %d'
                        % (idx, ee))
                    continue
                if (True == check_member('ee_id', resource.ees)):
                    #New memory saving EEClient structure
                    ee_client = resource.ees
                    while (ee_client.ee_id != ee):
                        if ee_client.next.address == 0:
                            print('\n*** %s ***' % ee_names[ee], file=f)
                            print(
                                '\tselected request [%s] -> %s {not allocated}'
                                % ('NO_REQUEST', 'n/a'),
                                file=f)
                            print(
                                '\n\tspare request [%s] -> %s {not allocated}\n'
                                % ('NO_REQUEST', 'n/a'),
                                file=f)
                            break
                        ee_client = ee_client.next
                    if (ee_client.ee_id != ee and ee_client.next.address == 0):
                        continue
                else:
                    #Old EEClient structure
                    ee_client = resource.ees[ee]

                print('\n*** %s ***' % ee_names[ee], file=f)

                selected = ee_client.selected
                selected_type = ee_client.req_type[selected]
                selected_request = ee_client.request[selected].address
                selected_request = 'n/a' if selected_type == 'NO_REQUEST' else format_request(
                    selected_request, rcd, memory, debug_info)
                print('\tselected request [%s] -> %s' %
                      (selected_type, selected_request),
                      file=f)

                spare = 1 ^ selected
                spare_type = ee_client.req_type[spare]
                spare_request = ee_client.request[spare].address
                spare_request = 'n/a' if spare_type == 'NO_REQUEST' else format_request(
                    spare_request, rcd, memory, debug_info)
                print('\n\tspare request [%s] -> %s\n' %
                      (spare_type, spare_request),
                      file=f)

            if 0 == resource.num_ics:
                continue

            print('\n\n-=| Internal Requests (from RPM software) |=-\n\n',
                  file=f)
            for ic in range(resource.num_ics):
                client = resource.ics[ic]
                client_type = client.type

                if client_type == 0:
                    client_size = rcd.inrep_size
                else:
                    client_size = None
                    #import pdb; pdb.set_trace()
                    ict = rcd.internal_types
                    while ict.address != 0:
                        if ict.client_type == client_type:
                            client_size = ict.inrep_size
                            break
                        ict = ict.next
                    if client_size is None:
                        print(
                            '\tWARNING: broken internal client #%d [0x%0.8x] -- no matching internal client type'
                            % (ic, client.address),
                            file=f)
                        continue

                # We don't have a good way of knowing how internal clients are
                # interpreted, but here's a heuristic that seems to work for
                # now: if the inresp_size and the client_size match, parse like
                # a normal request.
                if rcd.inrep_size == client_size:
                    print('\tClient #%d -> %s' %
                          (ic,
                           format_request(client.request.address, rcd, memory,
                                          debug_info)),
                          file=f)
                else:
                    print('\tWARNING: parsing may be incorrect', file=f)
                    print('\traw hex:', file=f)
                    print('\t\tClient #%d -> %s' %
                          (ic,
                           hexlify(
                               memory.read(client.request.address,
                                           client_size))),
                          file=f)
                    print('\tAttempted parsing:', file=f)
                    print('\tClient #%d -> %s' %
                          (ic,
                           format_request(client.request.address, rcd, memory,
                                          debug_info)),
                          file=f)
Example #21
0
def dump(debug_data
         ):  #dump_path, parse_path, memory, debug_info, target, branch):
    memory = debug_data['rpm_memory']
    debug_info = debug_data['debug_info']
    dump_path = debug_data['dump_path']
    parse_path = debug_data['args'].parser
    target = debug_data['target']
    branch = debug_data['branch']
    parse_tbl = debug_data['parser_tbl']
    debug_data['printer'].p("Dumping ulogs...")

    address = locate_core_dump(memory, debug_info)
    dump_type = debug_info.variables['aop_core_dump'].vartype
    aop_core_dump = decode_object('aop_core_dump', address, dump_type, memory,
                                  debug_info)

    rpm_ulogContext_type = debug_info.variables['rpm_ulogContext'].vartype
    ulog_state = aop_core_dump.ulog_state.address
    rpm_ulogContext = decode_object('rpm_ulogContext', ulog_state,
                                    rpm_ulogContext_type, memory, debug_info)

    log = rpm_ulogContext.logHead
    if log.address == 0:
        logger.error(
            'Failed to find any RPM ulogs (rpm_ulogContext.logHead == NULL)!')
        return

    if log.version != 0x1000:
        logger.error(
            'This script only knows how to dump RPM ULog version 0x1000 (Originating July 2012)'
        )
        if log.version in [2, 3, 4]:
            logger.error('It appears your logs are version %d' % log.version)
        else:
            logger.error(
                'Your log version (%d) is unknown to this script.  Is your log corrupted?'
                % log.version)
        return

    while log.address != 0:
        log_name = ''.join(
            itertools.takewhile(lambda c: c != '\0',
                                (chr(c) for c in log.name)))

        log_enabled = (log.logStatus & 0x2) != 0
        if not log_enabled:
            logger.debug('Not dumping ulog (disabled): %d' % log_name)
            continue

        use_64_bit_timestamps = (log.feature_flags1 & 0x1) != 0

        logger.debug('Dumping ulog: %s' % log_name)
        log_file_name = os.path.join(dump_path, '%s.ulog' % log_name)
        with open(log_file_name, 'w') as log_file:
            log_buffer = log.buffer
            log_size = log.bufSize
            log_mask = log.bufSizeMask
            read = log.readWriter
            readers_read = log.read
            write = log.write
            bytes_in_log = write - read

            if bytes_in_log > log_size:
                logger.warning(
                    'While parsing ulog "%s" -> reported log size %d bigger than the expected log size %d'
                    % (log_name, bytes_in_log, log_size))
                logger.warning(
                    'The most common cause of this is memory corruption, under-voltage, or writes to unpowered RAM.'
                )
                logger.warning(
                    'Will try to continue with this ULog decode, but results may be unpredictable.'
                )

            while read < write:
                # Advance past the message format value
                read = read + 2

                # Read the number of bytes in this message
                msg_length = log_buffer[read & log_mask] + (log_buffer[
                    (read + 1) & log_mask] << 8)

                # Back up to the format for later
                read = read - 2

                # Handle the current ULog message
                dump_ulog_msg(log_file, log_buffer, log_mask, read, msg_length)

                # Move our read pointer past the message we just finished (and 4 byte align it)
                read = read + ((msg_length + 3) & 0xFFFFFFFC)

        log = log.next

    # Now run the second-stage parsing script, if applicable.
    rpm_external_log = os.path.join(dump_path, 'AOP External Log.ulog')
    if os.path.exists(rpm_external_log):
        print_p('\t\tPost-processing the AOP "external" log...')
        parser = parse_path + 'aop_log_hfam.py'
        parser2 = parse_tbl + 'tracer_event_tbl.h'
        parser_params = [
            'python', parser, '-f', rpm_external_log, '-t', target, '-tbl',
            parser2
        ]  #, '-b', branch]

        try:
            pretty_output = subprocess.check_output(parser_params)
            pretty_output = pretty_output.replace('\r\n', '\n')
        except subprocess.CalledProcessError:
            pretty_output = '<failed to run log parser>\n'
        with open(os.path.join(dump_path, 'aop-rawts.txt'), 'w') as pretty_log:
            pretty_log.write(pretty_output)

        try:
            parser_params = parser_params + ['-p']
            raw_output = subprocess.check_output(parser_params)
            raw_output = raw_output.replace('\r\n', '\n')
        except subprocess.CalledProcessError:
            raw_output = '<failed to run log parser>\n'
        with open(os.path.join(dump_path, 'aop-log.txt'), 'w') as raw_log:
            raw_log.write(raw_output)

    #import pdb; pdb.set_trace()
    # Now run the second-stage parsing script, if applicable.
    ddr_external_log = os.path.join(dump_path, 'AOP DDR Log.ulog')
    if os.path.exists(rpm_external_log):
        print_p('\t\tPost-processing the AOP "DDR" log...')
        parser = parse_path + 'aop_log_hfam.py'
        parser2 = parse_tbl + 'tracer_event_tbl.h'
        parser_params = [
            'python', parser, '-f', ddr_external_log, '-t', target, '-tbl',
            parser2
        ]  #, '-b', branch]

        try:
            pretty_output = subprocess.check_output(parser_params)
            pretty_output = pretty_output.replace('\r\n', '\n')
        except subprocess.CalledProcessError:
            pretty_output = '<failed to run log parser>\n'
        with open(os.path.join(dump_path, 'ddr-rawts.txt'), 'w') as pretty_log:
            pretty_log.write(pretty_output)

        try:
            parser_params = parser_params + ['-p']
            raw_output = subprocess.check_output(parser_params)
            raw_output = raw_output.replace('\r\n', '\n')
        except subprocess.CalledProcessError:
            raw_output = '<failed to run log parser>\n'
        with open(os.path.join(dump_path, 'ddr-log.txt'), 'w') as raw_log:
            raw_log.write(raw_output)
Example #22
0
def dump(debug_data):  #dump_path, memory, debug_info, fill_char):
    dump_error = 0
    global vrm_map, no_regs, other_vrm_rsc, bcm_reg_map, bcm_vcd_map
    memory = debug_data['rpm_memory']
    debug_info = debug_data['debug_info']
    fill_char = debug_data['args'].fill_char
    dump_path = debug_data['dump_path']
    target = debug_data['target']
    target_ver = target + '-' + str(chip_version)
    if target_ver in targ_spec_config:
        target = target_ver
    debug_data['printer'].p("Dumping CMD_DB data...")

    no_regs = vrm[target]['no_regs']
    vrm_map = ['' for i in range(0, no_regs)]

    no_vcds = bcm[target]['no_vcds']
    no_bcm_regs = bcm[target]['no_regs']
    bcm_reg_map = ['' for i in range(0, no_bcm_regs)]
    bcm_vcd_map = ['' for i in range(0, no_vcds)]

    try:
        ver_data = memory.read(0x65FE0000, 4)
    except:
        debug_data['printer'].p("\tCPRF registers bin is not recovered...")
        return

    #import pdb; pdb.set_trace()
    smem_db_addr_die = debug_info.variables['smem_db'].die
    smem_db_addr_addr = debug_info.variables['smem_db'].address
    smem_db = decode_object('smem_db',
                            smem_db_addr_addr,
                            None,
                            memory,
                            debug_info,
                            die=smem_db_addr_die)

    cmddb_file_name = os.path.join(dump_path, 'cmd_db.txt')
    with open(cmddb_file_name, 'w') as cmd_db_file:

        smem_db_data_addr = 0x65FE0090

        for x in range(0, 8):
            if smem_db.slv_id_info[x].slv_id != 0:
                if smem_db.slv_id_info[x].slv_id == 3:
                    struct_name = 'arc_db_headers'
                    slv_name = 'ARC'
                    print('\n SLV_TYPE: %s, SLV_ID: %d' %
                          (slv_name, smem_db.slv_id_info[x].slv_id),
                          file=cmd_db_file)
                    print("\n\t| Resource | Address |", file=cmd_db_file)
                    cmd_db_header_die = debug_info.variables[struct_name].die
                    cmd_db_header_addr = smem_db_data_addr + smem_db.slv_id_info[
                        x].header_offset
                    cmd_db_header_data = decode_object(struct_name,
                                                       cmd_db_header_addr,
                                                       None,
                                                       memory,
                                                       debug_info,
                                                       die=cmd_db_header_die)
                    for cnt in range(0, smem_db.slv_id_info[x].cnt):
                        res_id = convert_hex_to_ascii(
                            cmd_db_header_data[cnt].res_id)
                        res_addr = hex(cmd_db_header_data[cnt].addr)
                        print('\t|{0:>10s}|{1:>9s}|'.format(res_id, res_addr),
                              file=cmd_db_file)
                    print("\n\t---------------------", file=cmd_db_file)

                elif smem_db.slv_id_info[x].slv_id == 5:
                    struct_name = 'bcm_db_headers'
                    slv_name = 'BCM'
                    print('\n SLV_TYPE: %s, SLV_ID: %d' %
                          (slv_name, smem_db.slv_id_info[x].slv_id),
                          file=cmd_db_file)
                    print("\n\t| Resource | Address |", file=cmd_db_file)
                    cmd_db_header_die = debug_info.variables[struct_name].die
                    cmd_db_header_addr = smem_db_data_addr + smem_db.slv_id_info[
                        x].header_offset
                    cmd_db_header_data = decode_object(struct_name,
                                                       cmd_db_header_addr,
                                                       None,
                                                       memory,
                                                       debug_info,
                                                       die=cmd_db_header_die)

                    bcm_data_die = debug_info.variables['bcm_aux'].die
                    bcm_data_addr = smem_db_data_addr + smem_db.slv_id_info[
                        x].data_offset
                    bcm_data = decode_object(struct_name,
                                             bcm_data_addr,
                                             None,
                                             memory,
                                             debug_info,
                                             die=bcm_data_die)

                    for cnt in range(0, smem_db.slv_id_info[x].cnt):
                        res_id = convert_hex_to_ascii(
                            cmd_db_header_data[cnt].res_id)
                        res_addr = cmd_db_header_data[cnt].addr
                        vcd = bcm_data[cnt].clk_id
                        bcm_vcd_map[vcd] += res_id + ','
                        bcm_idx = ((res_addr & 0xffff) / 0x4)
                        bcm_reg_map[bcm_idx] += res_id
                        print('\t|{0:>10s}|{1:>9s}|'.format(
                            res_id, hex(res_addr)),
                              file=cmd_db_file)
                    print("\n\t---------------------", file=cmd_db_file)

                elif smem_db.slv_id_info[x].slv_id == 4:
                    struct_name = 'bcm_db_headers'
                    slv_name = 'VRM'
                    print('\n SLV_TYPE: %s, SLV_ID: %d' %
                          (slv_name, smem_db.slv_id_info[x].slv_id),
                          file=cmd_db_file)
                    print("\n\t| Resource | Address |", file=cmd_db_file)
                    cmd_db_header_die = debug_info.variables[struct_name].die
                    for cnt in range(0, smem_db.slv_id_info[x].cnt):
                        cmd_db_header_addr = smem_db_data_addr + smem_db.slv_id_info[
                            x].header_offset + 24 * cnt
                        cmd_db_header_data = decode_object(
                            struct_name,
                            cmd_db_header_addr,
                            None,
                            memory,
                            debug_info,
                            die=cmd_db_header_die)
                        res_id = convert_hex_to_ascii(
                            cmd_db_header_data[0].res_id)
                        res_addr = cmd_db_header_data[0].addr
                        vrm_idx = ((res_addr & 0xffff) / 0x100)
                        try:
                            vrm_map[vrm_idx] += res_id + ': '
                        except:
                            other_vrm_rsc += res_id + ' '
                        print('\t|{0:>10s}|{1:>9s}|'.format(
                            res_id, hex(res_addr)),
                              file=cmd_db_file)

        if smem_db == 0:
            print("\n !!! Unable to retrive CMD_DB ADDRESS !!! \n",
                  file=cmd_db_file)
            return
Example #23
0
def dump_railway(dump_path, rpm, memory, debug_info):
    ee_status_file_name = os.path.join(dump_path, 'railway.txt')
    
    rail_config_data_type = debug_info.variables['RAILWAY_CONFIG_DATA'].die
    rail_config_data_address = debug_info.variables['RAILWAY_CONFIG_DATA'].address
    rail_config_data = decode_object('rail_config_data', rail_config_data_address, None, memory, debug_info, die=rail_config_data_type)
    
    num_rails = rail_config_data.num_rails
    
    with open(ee_status_file_name, 'w') as ee_status_file:
        railway_type = debug_info.variables['railway'].die
        railway_address = debug_info.variables['railway'].address
        railway = decode_object('railway', railway_address, None, memory, debug_info, die=railway_type)
        
        for rail_num in range(num_rails):
            try:
                rail = railway.rail_state[rail_num]
                rail_name = pointer_to_str(rail_config_data.rails[rail_num].vreg_name)
                print('\n\n ~~ RAIL %s ~~' % rail_name, file=ee_status_file)
                
                print('\tCURRENT ACTIVE:', file=ee_status_file)
                print('\t\tmode:                 %s' % rail.current_active.mode, file=ee_status_file)
                print('\t\tmicrovolts:           %d' % rail.current_active.microvolts, file=ee_status_file)
                if check_member("off_corner", rail.current_active):
                    print('\t\toff_corner:           %s' % rail.current_active.off_corner, file=ee_status_file)
                else:
                    print('\t\toff_corner:           value not present', file=ee_status_file)
                
                print('\tUNCONSTRAINED TARGET:', file=ee_status_file)
                print('\t\tmode:                 %s' % rail.unconstrained_target.mode, file=ee_status_file)
                print('\t\tmicrovolts:           %d' % rail.unconstrained_target.microvolts, file=ee_status_file)
                if check_member("off_corner", rail.unconstrained_target):
                    print('\t\toff_corner:           %s' % rail.unconstrained_target.off_corner, file=ee_status_file)
                else:
                    print('\t\toff_corner:           value not present', file=ee_status_file)
                
                print('\tCONSTRAINED TARGET:', file=ee_status_file)
                print('\t\tmode:                 %s' % rail.constrained_target.mode, file=ee_status_file)
                print('\t\tmicrovolts:           %d' % rail.constrained_target.microvolts, file=ee_status_file)
                if check_member("off_corner", rail.constrained_target):
                    print('\t\toff_corner:           %s' % rail.constrained_target.off_corner, file=ee_status_file)
                else:
                    print('\t\toff_corner:           value not present', file=ee_status_file)
                
                print('\tVOTER LIST:', file=ee_status_file)
                voter = rail.voter_list_head
                voter = cast(voter, 'railway_voter_s', memory, debug_info)
                tabs = "\t\t"
                while(voter.address != 0):
                    try:
                        print('%svoltage_corner:          %s' % (tabs, voter.voltage_corner), file=ee_status_file)
                        print('%sactive_floor:            %s' % (tabs, voter.active_floor), file=ee_status_file)
                        print('%sexplicite_voltage_in_uv: %d' % (tabs, voter.explicit_voltage_in_uv), file=ee_status_file)
                        print('%ssuppressible:            %s' % (tabs, voter.suppressible), file=ee_status_file)
                        print('%sid:                      %s' % (tabs, voter.id), file=ee_status_file)
                        print('%srail:                    %d' % (tabs, voter.rail), file=ee_status_file)
                        print('%ssw_enable:               %s' % (tabs, voter.sw_enable), file=ee_status_file)
                        print('%s-------------' % tabs, file=ee_status_file)
                        voter = voter.voter_link
                        voter = cast(voter, 'railway_voter_s', memory, debug_info)
                        tabs+="\t"
                    except:
                        break
            except:
                print('\t Failed to parse current state of rail #%d' % rail_num, file=ee_status_file)
Example #24
0
def dump(debug_data): #dump_path, memory, debug_info, base_address):
    memory = debug_data['rpm_memory']
    debug_info = debug_data['debug_info']
    dump_path = debug_data['dump_path']
    base_address = debug_data['image_strings_addr']
    global chip_version 
    dump = open(os.path.join(dump_path, 'aop-summary.txt'), 'w')

    try:
        chipFamilyNum_die = debug_info.variables['chipFamilyNum'].die
        chipDeviceNum_die = debug_info.variables['chipDeviceNum'].die
        chipMinor_die = debug_info.variables['chipMinor'].die
        chipMajor_die = debug_info.variables['chipMajor'].die		
    except:
        print("\n !!! ChipInfoCtxt DOES NOT EXIST !!! \n", file=ddr_file)
        return
    try:
        #not in core dump, but elf is close enough to provide a correct pointer
        chipFamilyNum_address = debug_info.variables['chipFamilyNum'].address # FIXME: get right address by magic
        chipFamilyNum = decode_object('chipFamilyNum', chipFamilyNum_address, None, memory, debug_info, die=chipFamilyNum_die)

        chipDeviceNum_address = debug_info.variables['chipDeviceNum'].address # FIXME: get right address by magic
        chipDeviceNum = decode_object('chipDeviceNum', chipDeviceNum_address, None, memory, debug_info, die=chipDeviceNum_die)

        chipMinor_address = debug_info.variables['chipMinor'].address # FIXME: get right address by magic
        chipMinor = decode_object('chipMinor', chipMinor_address, None, memory, debug_info, die=chipMinor_die)

        chipMajor_address = debug_info.variables['chipMajor'].address # FIXME: get right address by magic
        chipMajor = decode_object('chipMajor', chipMajor_address, None, memory, debug_info, die=chipMajor_die)
    except:
        print("\n !!! ChipInfoCtxt DOES NOT EXIST !!! \n", file=ddr_file)
        return
    chip_version = chipMajor
	
    version_address_start = base_address + 0x0
    version_address_end   = version_address_start + 0x1000
    
    #regex to match the RPM branch name:
    regex = '^AOP\.HO\.\d\.\d.*(?=-)'
    


    address = locate_core_dump(memory, debug_info)
    dump_type = debug_info.variables['aop_core_dump'].vartype
    aop_core_dump = decode_object('aop_core_dump', address, dump_type, memory, debug_info)

    
    chip_name = '<unknown device -> family %d device %d>' % (chipFamilyNum, chipDeviceNum)
    target_chip = chips.get(chipFamilyNum, {}).get(chipDeviceNum, {})
    chip_name = target_chip.get('MSM_ID', chip_name)
    print('\nCollected from %s %d.%d\n' % (chip_name, chipMajor, chipMinor), file=dump)
    
    rpm_ver_type = debug_info.variables['aop_core_dump'].vartype
    
    #rpm_build_date_type = debug_info.variables['gBuildDate'].die
    #rpm_build_date_address = debug_info.variables['gBuildDate'].address
    #rpm_build_time_type = debug_info.variables['gBuildTime'].die
    #rpm_build_time_address = debug_info.variables['gBuildTime'].address
    #rpm_build_date = decode_object('gBuildDate', rpm_build_date_address, None, memory, debug_info, die=rpm_build_date_type)
    #rpm_build_time = decode_object('gBuildTime', rpm_build_time_address, None, memory, debug_info, die=rpm_build_time_type)
    #
    #QC_IMAGE_VERSION = find_version_info("QC_IMAGE_VERSION_STRING=",version_address_start, version_address_end, memory)
    #print("QC_IMAGE_VERSION_STRING:  %s" % QC_IMAGE_VERSION, file=dump)
    #print("IMAGE_VARIANT_STRING:     %s" % find_version_info("IMAGE_VARIANT_STRING=",version_address_start, version_address_end, memory), file=dump)
    #print("OEM_IMAGE_VERSION_STRING: %s" % find_version_info("OEM_IMAGE_VERSION_STRING=",version_address_start, version_address_end, memory), file=dump)
    #
    #print("\nBuild Date: %s" % pointer_to_str(rpm_build_date), file=dump)
    #print("Build Time: %s" % pointer_to_str(rpm_build_time), file=dump)
    
    if aop_core_dump.dumped_at == 0:
        print('\nThe AOP is ok.', file=dump)
        # return chip name and RPM branch
        return [target_chip.get('num', '????')]#, re.compile(regex).match(QC_IMAGE_VERSION).group()]
    
    print('\nThe AOP crashed (@ time = 0x%x)' % aop_core_dump.dumped_at, file=dump)
    xpsr = aop_core_dump.registers.xPSR
    
    ipsr = xpsr & 0xff
    if ipsr == 0:
        print('\tNot in an exception context; vanilla fatal error scenario.', file=dump)
    elif ipsr < 16:
        fault_types = {
            2  : 'NMI',
            3  : 'Hard Fault',
            4  : 'Memory Management Fault',
            5  : 'Bus Fault',
            6  : 'Usage Fault',
            11 : 'SVCall',
            12 : 'Debug Monitor',
            14 : 'PendSV',
            15 : 'SysTick',
        }
        print('\tIn a fault context -> %s' % fault_types[ipsr], file=dump)
    else:
        print('\tFatal error inside ISR #%d' % (ipsr - 16), file=dump)
    
    
    def decode_bitfield(name, bit_definitions, data, joiner = ' | '):
        known_bits = 0
        for id in bit_definitions:
            known_bits |= (1 << id)
        unknown_data = data - (data & known_bits)
        string = joiner.join(['[' + bit_definitions[x] + ']' for x in bit_definitions if (1 << x) & data])
        if unknown_data:
            if string:
                string += ' ...and '
            multi_or_single = ''
            if log(unknown_data, 2) != int(log(unknown_data, 2)):
                multi_or_single = 's'
            string += 'unknown %s%s 0x%0.8x' % (name, multi_or_single, unknown_data)
        return string
    
    
    fault_regs = aop_core_dump.fault_detail
    
    shcas_bits = {
        0  : 'Memory fault in progress',
        1  : 'Bus fault in progress',
        3  : 'Usage fault in progress',
        7  : 'SVCall in progress',
        8  : 'Debug Monitor in progress',
        10 : 'PendSV in progress',
        11 : 'SysTick in progress',
        12 : 'Usage fault pended',
        13 : 'Memory management fault pended',
        14 : 'Bus fault pended',
        15 : 'SVCall pended',
        16 : 'Memory management fault enabled (this is not a problem)',
        17 : 'Bus fault enabled (this is not a problem)',
        18 : 'Usage fault enabled (this is not a problem)',
    }
    
    print('\nSystem handler status {\n\t%s\n}' % decode_bitfield('bits', shcas_bits, fault_regs.SystemHandlerCtrlAndState, '\n\t'), file=dump)
    
    cfs_bits = {
        0  : 'Attempt to fetch an instruction from a non-executable region.',
        1  : 'Attempt to load or store a location that does not permit it.',
        3  : 'Unstacking from an exception return has caused one or more access violations.',
        4  : 'Stacking for an exception has caused one or more access violations.',
        7  : 'Memory manage address register (MMAR) is valid.',
        8  : 'Instruction bus error.',
        9  : 'Precise data bus error.',
        10 : 'Imprecise data bus error.',
        11 : 'Unstack from exception has caused one or more bus errors.',
        12 : 'Stacking for exception has caused one or more bus errors.',
        15 : 'Bus fault address register (BFAR) is valid.',
        16 : 'Undefined instruction exception.',
        17 : 'Invalid state exception.',
        18 : 'Illegal attempt to load EXC_RETURN into PC.',
        19 : 'Attempt to use a coprocessor instruction.',
        24 : 'Unaligned memory access.',
        25 : 'Divide by zero.',
    }
    
    print('\nConfigurable fault status {\n\t%s\n}' % decode_bitfield('bits', cfs_bits, fault_regs.ConfigurableFaultStatus, '\n\t'), file=dump)
    
    hfs_bits = {
        0  : 'Fault on vector table read during exception processing.',
        30 : 'Hard Fault activated because a configurable fault was received and cannot activate because of priority or it is disabled.',
        31 : 'Fault related to debug.',
    }
    
    print('\nHard fault status {\n\t%s\n}' % decode_bitfield('bits', hfs_bits, fault_regs.HardFaultStatus, '\n\t'), file=dump)
        
    dfs_bits = {
        0  : 'Halt requested by NVIC.',
        1  : 'BKPT instruction execution.',
        2  : 'DWT match.',
        3  : 'Vector fetch occurred.',
        4  : 'EDBGRQ signal asserted.',
    }
    
    print('\nDebug fault status {\n\t%s\n}' % decode_bitfield('bits', hfs_bits, fault_regs.DebugFaultStatus, '\n\t'), file=dump)
    
    if 0 != (fault_regs.ConfigurableFaultStatus & (1 << 7)):
        print('\nMemory manage fault address: 0x%0.8x' % fault_regs.MemManageAddress, file=dump)
    
    if 0 != (fault_regs.ConfigurableFaultStatus & (1 << 15)):
        print('\nMemory manage fault address: 0x%0.8x' % fault_regs.BusFaultAddress, file=dump)
    
    print('\nAuxilary fault address register: 0x%0.8x' % fault_regs.AuxFaultStatus, file=dump)
    dump.close()
    
    # return chip name and RPM branch
    return [target_chip.get('num', '????')]#, re.compile(regex).match(QC_IMAGE_VERSION).group()]
Example #25
0
def dump_wdog(dump_path, rpm, memory, debug_info, ocimem_load, pmic_rtc_load):
    wdog_file_name = os.path.join(dump_path, 'wdogs.txt')
    with open(wdog_file_name, 'w') as wdog_file:
        
        print("\n ~~RPM Watchdog Info~~", file=wdog_file)
        print("\n\t Stats:", file=wdog_file)
        rpm_dog_stats_type = debug_info.variables['dog_stats'].die
        rpm_dog_stats_address = debug_info.variables['dog_stats'].address
        rpm_dog_stats = decode_object('dog_stats', rpm_dog_stats_address, None, memory, debug_info, die=rpm_dog_stats_type)
        
        current_index = rpm_dog_stats.index-1
        if current_index < 0:
            current_index = 3
        
        for index_num in range(4):
            event = rpm_dog_stats.entries[index_num].dog_event
            esource = rpm_dog_stats.entries[index_num].dog_event_source
            timestamp = rpm_dog_stats.entries[index_num].timestamp
            if index_num == current_index:
                print("\t\t Entry %i [Last event]"%(index_num), file=wdog_file)
            else:
                print("\t\t Entry %i"%(index_num), file=wdog_file)
            print("\t\t\t\t-> dog event: %s"%event, file=wdog_file)
            print("\t\t\t\t-> dog event source: %s"%esource, file=wdog_file)
            print("\t\t\t\t-> timestamp: %#x"%timestamp, file=wdog_file)
        
        
        print("\n ~~PMIC Watchdog Info~~", file=wdog_file)
        
        try:
            pmic_dog_stats_type = debug_info.variables['pmic_dog_stats'].die
            pmic_dog_stats_address = debug_info.variables['pmic_dog_stats'].address
            pmic_dog_stats = decode_object('pmic_dog_stats', pmic_dog_stats_address, None, memory, debug_info, die=pmic_dog_stats_type)
        except:
            print("\t\tFailed to find pmic_dog_stats, RPM build likely does not have this feature.", file=wdog_file)
            return
            
        try:
            pmic_wdog_enable_type = debug_info.variables['pmic_wdog_enable'].die
            pmic_wdog_enable_address = debug_info.variables['pmic_wdog_enable'].address
            pmic_wdog_enable = decode_object('pmic_wdog_enable', pmic_wdog_enable_address, None, memory, debug_info, die=pmic_wdog_enable_type)
        except:
            print("\t\tFailed to find pmic_wdog_enable, RPM build likely does not have this feature.", file=wdog_file)
            return
            
        if pmic_wdog_enable == 0:
            print("\t\tPMIC wdog was disabled when dumps were taken. PMIC wdog likely not enabled on this target.", file=wdog_file)
            
        print("\n\t Stats:", file=wdog_file)
        current_index = pmic_dog_stats.index-1
        if current_index < 0:
            current_index = 3
        
        for index_num in range(4):
            event = pmic_dog_stats.entries[index_num].dog_event
            esource = pmic_dog_stats.entries[index_num].dog_event_source
            timestamp = pmic_dog_stats.entries[index_num].timestamp
            if index_num == current_index:
                print("\t\t Entry %i [Last event]"%(index_num), file=wdog_file)
            else:
                print("\t\t Entry %i"%(index_num), file=wdog_file)
            print("\t\t\t\t-> dog event: %s"%event, file=wdog_file)
            print("\t\t\t\t-> dog event source: %s"%esource, file=wdog_file)
            print("\t\t\t\t-> timestamp: %#x"%timestamp, file=wdog_file)
            
        try:
            pmic_timestamp_type = debug_info.variables['PMIC_timestamp'].die
            pmic_timestamp_address = debug_info.variables['PMIC_timestamp'].address
            pmic_timestamp = decode_object('PMIC_timestamp', pmic_timestamp_address, None, memory, debug_info, die=pmic_timestamp_type)
        except:
            print("\t\tFailed to find PMIC_timestamp, RPM build likely does not have this feature.", file=wdog_file)
            return
        
        print("\t\t RTC data:", file=wdog_file)
        pm_time = pmic_timestamp.pm_time
        rpm_time = pmic_timestamp.rpm_time
        print("\t\t\t -> PMIC RTC value: %u [hex: %#x] sec"%(pm_time,pm_time), file=wdog_file)
        print("\t\t\t -> RPM timestamp: %#x"%(rpm_time), file=wdog_file)
        rpm_start = pmic_timestamp.rpm_time
        rpm_end = pmic_dog_stats.entries[current_index].timestamp
        rpm_delta = (rpm_end-rpm_start)/19200000
        final_rtc = rpm_delta+pmic_timestamp.pm_time
        print("\t\t\t -> estimated PMIC RTC time at final PMIC wdog pet: %u sec"%final_rtc, file=wdog_file)
        
        # This is very experimental... warn that information may not be acurrate
        print("\n\t PMIC wdog fault parsing", file=wdog_file)
        print("\t\t WARNING: This parsing assumes that the PMIC RTC value is stored during the reboot following the PMIC wdog bite", file=wdog_file)
        
        from struct import unpack
        SDI_PMIC_RTC = 0
        SDI_PMIC_RTC_v2 = 0
        if ocimem_load == 1:
            try:
                SDI_PMIC_RTC = unpack('<I',memory.read(0x5774, 4))[0]
            except:
                print("\t\t WARNING: OCIMEM.BIN not loaded.", file=wdog_file)
                ocimem_load = 0
        
        if pmic_rtc_load == 1:
            try:
                SDI_PMIC_RTC_v2 = unpack('<I',memory.read(0x0, 4))[0]
            except:
                if OCIMEM == "fail":
                    print("\t\t ERRROR: PMIC_RTC.BIN not loaded, cannot read PMIC RTC value recorded by SDI.", file=wdog_file)
                    return
                pmic_rtc_load = 0
        
        print_RTC = 0
        
        if SDI_PMIC_RTC != SDI_PMIC_RTC_v2 and SDI_PMIC_RTC_v2 >= pmic_timestamp.pm_time:
            if pmic_rtc_load == 1 and ocimem_load == 1:
                print("\t\t WARNING: OCIMEM.BIN[0x5774] and PMIC_RTC.BIN report different PMIC RTC counter values on reboot.", file=wdog_file)
                print_RTC = 1
            elif ocimem_load == 0 and pmic_rtc_load == 1:
                # Use the value from PMIC_RTC if OCIMEM couldn't be loaded
                SDI_PMIC_RTC = SDI_PMIC_RTC_v2
                print_RTC = 1
        
        if SDI_PMIC_RTC < pmic_timestamp.pm_time:
            print("\t\t ERROR: Either SDI did not run, or PMIC RTC reading is not present in this SDI build", file=wdog_file)
            return
        
        if ocimem_load == 1:
            print("\n\t\t -> SDI RTC value[0x5774 in OCIMEM.BIN]: %u [hex: %#x] sec"%(SDI_PMIC_RTC, SDI_PMIC_RTC), file=wdog_file)
            crash_delta = SDI_PMIC_RTC-final_rtc
            print("\t\t -> Delta between last RPM PMIC pet and SDI run: %s [hex: %#x] sec"%(crash_delta,crash_delta), file=wdog_file)
        
        if print_RTC == 1:
            print("\n\t\t Using value from PMIC_RTC.bin", file=wdog_file)
            print("\t\t -> SDI RTC value[0x0 in PMIC_RTC.BIN]: %u [hex: %#x] sec"%(SDI_PMIC_RTC_v2, SDI_PMIC_RTC_v2), file=wdog_file)
            crash_delta = SDI_PMIC_RTC_v2-final_rtc
            print("\t\t -> Delta between last RPM PMIC pet and SDI run: %s [hex: %#x] sec"%(crash_delta,crash_delta), file=wdog_file)