Home | History | Annotate | Download | only in Ds5
      1 #

      2 #  Copyright (c) 2011-2013, ARM Limited. All rights reserved.

      3 #

      4 #  This program and the accompanying materials

      5 #  are licensed and made available under the terms and conditions of the BSD License

      6 #  which accompanies this distribution.  The full text of the license may be found at

      7 #  http://opensource.org/licenses/bsd-license.php

      8 #

      9 #  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

     10 #  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

     11 #

     12 
     13 import os
     14 
     15 import firmware_volume
     16 import build_report
     17 import system_table
     18 
     19 # Reload external classes

     20 reload(firmware_volume)
     21 reload(build_report)
     22 reload(system_table)
     23 
     24 def readMem32(executionContext, address):
     25     bytes = executionContext.getMemoryService().read(address, 4, 32)
     26     return struct.unpack('<I',bytes)[0]
     27 
     28 def dump_fv(ec, fv_base, fv_size):
     29     fv = firmware_volume.FirmwareVolume(ec,
     30                                         int(build.PCDs['gArmTokenSpaceGuid']['PcdFvBaseAddress'][0],16),
     31                                         int(build.PCDs['gArmTokenSpaceGuid']['PcdFvSize'][0],16))
     32 
     33     ffs = fv.get_next_ffs()
     34     while ffs != None:
     35         print "# %s" % ffs
     36 
     37         section = ffs.get_next_section()
     38         while section != None:
     39             print "\t%s" % section
     40             try:
     41                 print "\t\t- %s" % section.get_debug_filepath()
     42             except Exception:
     43                 pass
     44             section = ffs.get_next_section(section)
     45 
     46         ffs = fv.get_next_ffs(ffs)
     47 
     48 def dump_system_table(ec, mem_base, mem_size):
     49     st = system_table.SystemTable(ec, mem_base, mem_size)
     50 
     51     debug_info_table_base = st.get_configuration_table(system_table.DebugInfoTable.CONST_DEBUG_INFO_TABLE_GUID)
     52 
     53     debug_info_table = system_table.DebugInfoTable(ec, debug_info_table_base)
     54     debug_info_table.dump()
     55 
     56 def load_symbol_from_file(ec, filename, address, verbose = False):
     57     if verbose:
     58         print "Add symbols of %s at 0x%x" % (filename, address)
     59 
     60     try:
     61         ec.getImageService().addSymbols(filename, address)
     62     except:
     63         try:
     64             # We could get an exception if the symbols are already loaded

     65             ec.getImageService().unloadSymbols(filename)
     66             ec.getImageService().addSymbols(filename, address)
     67         except:
     68             print "Warning: not possible to load symbols from %s at 0x%x" % (filename, address)
     69 
     70 def is_aarch64(ec):
     71     success = True
     72     try:
     73         # Try to access a Aarch64 specific register

     74         ec.getRegisterService().getValue('X0')
     75     except:
     76         success = False
     77     return success
     78 
     79 class ArmPlatform:
     80     def __init__(self, sysmembase=None, sysmemsize=None, fvs={}):
     81         self.sysmembase = sysmembase
     82         self.sysmemsize = sysmemsize
     83         self.fvs = fvs
     84 
     85 class ArmPlatformDebugger:
     86     system_table = None
     87     firmware_volumes = {}
     88 
     89     REGION_TYPE_SYSMEM = 1
     90     REGION_TYPE_ROM    = 2
     91     REGION_TYPE_FV     = 3
     92 
     93     def __init__(self, ec, report_log, regions, verbose = False):
     94         self.ec = ec
     95         self.verbose = verbose
     96         fvs = []
     97         sysmem_base = None
     98         sysmem_size = None
     99 
    100         if report_log and os.path.isfile(report_log):
    101             try:
    102                 self.build = build_report.BuildReport(report_log)
    103             except IOError:
    104                 raise IOError(2, 'Report \'%s\' is not valid' % report_log)
    105 
    106             # Generate list of supported Firmware Volumes

    107             if self.build.PCDs['gArmTokenSpaceGuid'].has_key('PcdFvSize') and int(self.build.PCDs['gArmTokenSpaceGuid']['PcdFvSize'][0],16) != 0:
    108                 fvs.append((int(self.build.PCDs['gArmTokenSpaceGuid']['PcdFvBaseAddress'][0],16),int(self.build.PCDs['gArmTokenSpaceGuid']['PcdFvSize'][0],16)))
    109             if self.build.PCDs['gArmTokenSpaceGuid'].has_key('PcdSecureFvSize') and int(self.build.PCDs['gArmTokenSpaceGuid']['PcdSecureFvSize'][0],16) != 0:
    110                 fvs.append((int(self.build.PCDs['gArmTokenSpaceGuid']['PcdSecureFvBaseAddress'][0],16),int(self.build.PCDs['gArmTokenSpaceGuid']['PcdSecureFvSize'][0],16)))
    111             if self.build.PCDs['gArmTokenSpaceGuid'].has_key('PcdHypFvSize') and int(self.build.PCDs['gArmTokenSpaceGuid']['PcdHypFvSize'][0],16) != 0:
    112                 fvs.append((int(self.build.PCDs['gArmTokenSpaceGuid']['PcdHypFvBaseAddress'][0],16),int(self.build.PCDs['gArmTokenSpaceGuid']['PcdHypFvSize'][0],16)))
    113 
    114             sysmem_base = int(self.build.PCDs['gArmTokenSpaceGuid']['PcdSystemMemoryBase'][0],16)
    115             sysmem_size = int(self.build.PCDs['gArmTokenSpaceGuid']['PcdSystemMemorySize'][0],16)
    116         else:
    117             for region in regions:
    118                 if region[0] == ArmPlatformDebugger.REGION_TYPE_SYSMEM:
    119                     sysmem_base = region[1]
    120                     sysmem_size = region[2]
    121                 elif region[0] == ArmPlatformDebugger.REGION_TYPE_FV:
    122                     fvs.append((region[1],region[2]))
    123                 elif region[0] == ArmPlatformDebugger.REGION_TYPE_ROM:
    124                     for base in xrange(region[1], region[1] + region[2], 0x400000):
    125                         signature = struct.unpack("cccc", self.ec.getMemoryService().read(base, 4, 32))
    126                         if signature == FirmwareVolume.CONST_FV_SIGNATURE:
    127                             fvs.append((base,0))
    128                 else:
    129                     print "Region type '%d' Not Supported" % region[0]
    130 
    131         self.platform = ArmPlatform(sysmem_base, sysmem_size, fvs)
    132 
    133     def in_sysmem(self, addr):
    134         return (self.platform.sysmembase is not None) and (self.platform.sysmembase <= addr) and (addr < self.platform.sysmembase + self.platform.sysmemsize)
    135 
    136     def in_fv(self, addr):
    137         return (self.get_fv_at(addr) != None)
    138 
    139     def get_fv_at(self, addr):
    140         for fv in self.platform.fvs:
    141             if (fv[0] <= addr) and (addr < fv[0] + fv[1]):
    142                 return fv
    143         return None
    144 
    145     def load_current_symbols(self):
    146         pc = int(self.ec.getRegisterService().getValue('PC')) & 0xFFFFFFFF
    147         if self.in_fv(pc):
    148             debug_infos = []
    149 
    150             (fv_base, fv_size) = self.get_fv_at(pc)
    151 
    152             if self.firmware_volumes.has_key(fv_base) == False:
    153                 self.firmware_volumes[fv_base] = firmware_volume.FirmwareVolume(self.ec, fv_base, fv_size)
    154 
    155             stack_frame = self.ec.getTopLevelStackFrame()
    156             info = self.firmware_volumes[fv_base].load_symbols_at(int(stack_frame.getRegisterService().getValue('PC')) & 0xFFFFFFFF, self.verbose)
    157             debug_infos.append(info)
    158             while stack_frame.next() is not None:
    159                 stack_frame = stack_frame.next()
    160 
    161                 # Stack frame attached to 'PC'

    162                 pc = int(stack_frame.getRegisterService().getValue('PC')) & 0xFFFFFFFF
    163 
    164                 # Check if the symbols for this stack frame have already been loaded

    165                 found = False
    166                 for debug_info in debug_infos:
    167                     if (pc >= debug_info[0]) and (pc < debug_info[0] + debug_info[1]):
    168                         found = True
    169                 if found == False:
    170                     info = self.firmware_volumes[fv_base].load_symbols_at(pc)
    171                     debug_infos.append(info)
    172 
    173             #self.firmware_volumes[fv_base].load_symbols_at(pc)

    174         elif self.in_sysmem(pc):
    175             debug_infos = []
    176 
    177             if self.system_table is None:
    178                 # Find the System Table

    179                 self.system_table = system_table.SystemTable(self.ec, self.platform.sysmembase, self.platform.sysmemsize)
    180 
    181                 # Find the Debug Info Table

    182                 debug_info_table_base = self.system_table.get_configuration_table(system_table.DebugInfoTable.CONST_DEBUG_INFO_TABLE_GUID)
    183                 self.debug_info_table = system_table.DebugInfoTable(self.ec, debug_info_table_base)
    184 
    185             stack_frame = self.ec.getTopLevelStackFrame()
    186             info = self.debug_info_table.load_symbols_at(int(stack_frame.getRegisterService().getValue('PC')) & 0xFFFFFFFF, self.verbose)
    187             debug_infos.append(info)
    188             while stack_frame.next() is not None:
    189                 stack_frame = stack_frame.next()
    190 
    191                 # Stack frame attached to 'PC'

    192                 pc = int(stack_frame.getRegisterService().getValue('PC')) & 0xFFFFFFFF
    193 
    194                 # Check if the symbols for this stack frame have already been loaded

    195                 found = False
    196                 for debug_info in debug_infos:
    197                     if (pc >= debug_info[0]) and (pc < debug_info[0] + debug_info[1]):
    198                         found = True
    199                 if found == False:
    200                     try:
    201                         info = self.debug_info_table.load_symbols_at(pc)
    202                         debug_infos.append(info)
    203                     except:
    204                         pass
    205 
    206             #self.debug_info_table.load_symbols_at(pc)

    207         else:
    208             raise Exception('ArmPlatformDebugger', "Not supported region")
    209 
    210     def load_all_symbols(self):
    211         # Load all the XIP symbols attached to the Firmware Volume

    212         for (fv_base, fv_size) in self.platform.fvs:
    213             if self.firmware_volumes.has_key(fv_base) == False:
    214                 self.firmware_volumes[fv_base] = firmware_volume.FirmwareVolume(self.ec, fv_base, fv_size)
    215             self.firmware_volumes[fv_base].load_all_symbols(self.verbose)
    216 
    217         try:
    218             # Load all symbols of module loaded into System Memory

    219             if self.system_table is None:
    220                 # Find the System Table

    221                 self.system_table = system_table.SystemTable(self.ec, self.platform.sysmembase, self.platform.sysmemsize)
    222 
    223 
    224                 # Find the Debug Info Table

    225                 debug_info_table_base = self.system_table.get_configuration_table(system_table.DebugInfoTable.CONST_DEBUG_INFO_TABLE_GUID)
    226                 self.debug_info_table = system_table.DebugInfoTable(self.ec, debug_info_table_base)
    227 
    228             self.debug_info_table.load_all_symbols(self.verbose)
    229         except:
    230             # Debugger exception could be excepted if DRAM has not been initialized or if we have not started to run from DRAM yet

    231             print "Note: no symbols have been found in System Memory (possible cause: the UEFI permanent memory has been installed yet)"
    232