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)
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)
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
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)
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)
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)
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)
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)
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)
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)
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")
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")
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)
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")
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")
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)
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)
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)
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]
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)
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)
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
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)
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()]
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)