2 # Copyright (c) 2011-2013, ARM Limited. All rights reserved.
4 # SPDX-License-Identifier: BSD-2-Clause-Patent
13 # Reload external classes
14 reload(firmware_volume
)
18 def readMem32(executionContext
, address
):
19 bytes
= executionContext
.getMemoryService().read(address
, 4, 32)
20 return struct
.unpack('<I',bytes
)[0]
22 def dump_fv(ec
, fv_base
, fv_size
):
23 fv
= firmware_volume
.FirmwareVolume(ec
,
24 int(build
.PCDs
['gArmTokenSpaceGuid']['PcdFvBaseAddress'][0],16),
25 int(build
.PCDs
['gArmTokenSpaceGuid']['PcdFvSize'][0],16))
27 ffs
= fv
.get_next_ffs()
31 section
= ffs
.get_next_section()
32 while section
!= None:
33 print "\t%s" % section
35 print "\t\t- %s" % section
.get_debug_filepath()
38 section
= ffs
.get_next_section(section
)
40 ffs
= fv
.get_next_ffs(ffs
)
42 def dump_system_table(ec
, mem_base
, mem_size
):
43 st
= system_table
.SystemTable(ec
, mem_base
, mem_size
)
45 debug_info_table_base
= st
.get_configuration_table(system_table
.DebugInfoTable
.CONST_DEBUG_INFO_TABLE_GUID
)
47 debug_info_table
= system_table
.DebugInfoTable(ec
, debug_info_table_base
)
48 debug_info_table
.dump()
50 def load_symbol_from_file(ec
, filename
, address
, verbose
= False):
52 print "Add symbols of %s at 0x%x" % (filename
, address
)
55 ec
.getImageService().addSymbols(filename
, address
)
58 # We could get an exception if the symbols are already loaded
59 ec
.getImageService().unloadSymbols(filename
)
60 ec
.getImageService().addSymbols(filename
, address
)
62 print "Warning: not possible to load symbols from %s at 0x%x" % (filename
, address
)
67 # Try to access a Aarch64 specific register
68 ec
.getRegisterService().getValue('X0')
74 def __init__(self
, sysmembase
=None, sysmemsize
=None, fvs
={}):
75 self
.sysmembase
= sysmembase
76 self
.sysmemsize
= sysmemsize
79 class ArmPlatformDebugger
:
83 REGION_TYPE_SYSMEM
= 1
87 def __init__(self
, ec
, report_log
, regions
, verbose
= False):
89 self
.verbose
= verbose
94 if report_log
and os
.path
.isfile(report_log
):
96 self
.build
= build_report
.BuildReport(report_log
)
98 raise IOError(2, 'Report \'%s\' is not valid' % report_log
)
100 # Generate list of supported Firmware Volumes
101 if self
.build
.PCDs
['gArmTokenSpaceGuid'].has_key('PcdFvSize') and int(self
.build
.PCDs
['gArmTokenSpaceGuid']['PcdFvSize'][0],16) != 0:
102 fvs
.append((int(self
.build
.PCDs
['gArmTokenSpaceGuid']['PcdFvBaseAddress'][0],16),int(self
.build
.PCDs
['gArmTokenSpaceGuid']['PcdFvSize'][0],16)))
103 if self
.build
.PCDs
['gArmTokenSpaceGuid'].has_key('PcdSecureFvSize') and int(self
.build
.PCDs
['gArmTokenSpaceGuid']['PcdSecureFvSize'][0],16) != 0:
104 fvs
.append((int(self
.build
.PCDs
['gArmTokenSpaceGuid']['PcdSecureFvBaseAddress'][0],16),int(self
.build
.PCDs
['gArmTokenSpaceGuid']['PcdSecureFvSize'][0],16)))
105 if self
.build
.PCDs
['gArmTokenSpaceGuid'].has_key('PcdHypFvSize') and int(self
.build
.PCDs
['gArmTokenSpaceGuid']['PcdHypFvSize'][0],16) != 0:
106 fvs
.append((int(self
.build
.PCDs
['gArmTokenSpaceGuid']['PcdHypFvBaseAddress'][0],16),int(self
.build
.PCDs
['gArmTokenSpaceGuid']['PcdHypFvSize'][0],16)))
108 sysmem_base
= int(self
.build
.PCDs
['gArmTokenSpaceGuid']['PcdSystemMemoryBase'][0],16)
109 sysmem_size
= int(self
.build
.PCDs
['gArmTokenSpaceGuid']['PcdSystemMemorySize'][0],16)
111 for region
in regions
:
112 if region
[0] == ArmPlatformDebugger
.REGION_TYPE_SYSMEM
:
113 sysmem_base
= region
[1]
114 sysmem_size
= region
[2]
115 elif region
[0] == ArmPlatformDebugger
.REGION_TYPE_FV
:
116 fvs
.append((region
[1],region
[2]))
117 elif region
[0] == ArmPlatformDebugger
.REGION_TYPE_ROM
:
118 for base
in xrange(region
[1], region
[1] + region
[2], 0x400000):
119 signature
= struct
.unpack("cccc", self
.ec
.getMemoryService().read(base
, 4, 32))
120 if signature
== FirmwareVolume
.CONST_FV_SIGNATURE
:
123 print "Region type '%d' Not Supported" % region
[0]
125 self
.platform
= ArmPlatform(sysmem_base
, sysmem_size
, fvs
)
127 def in_sysmem(self
, addr
):
128 return (self
.platform
.sysmembase
is not None) and (self
.platform
.sysmembase
<= addr
) and (addr
< self
.platform
.sysmembase
+ self
.platform
.sysmemsize
)
130 def in_fv(self
, addr
):
131 return (self
.get_fv_at(addr
) != None)
133 def get_fv_at(self
, addr
):
134 for fv
in self
.platform
.fvs
:
135 if (fv
[0] <= addr
) and (addr
< fv
[0] + fv
[1]):
139 def load_current_symbols(self
):
140 pc
= int(self
.ec
.getRegisterService().getValue('PC')) & 0xFFFFFFFF
144 (fv_base
, fv_size
) = self
.get_fv_at(pc
)
146 if self
.firmware_volumes
.has_key(fv_base
) == False:
147 self
.firmware_volumes
[fv_base
] = firmware_volume
.FirmwareVolume(self
.ec
, fv_base
, fv_size
)
149 stack_frame
= self
.ec
.getTopLevelStackFrame()
150 info
= self
.firmware_volumes
[fv_base
].load_symbols_at(int(stack_frame
.getRegisterService().getValue('PC')) & 0xFFFFFFFF, self
.verbose
)
151 debug_infos
.append(info
)
152 while stack_frame
.next() is not None:
153 stack_frame
= stack_frame
.next()
155 # Stack frame attached to 'PC'
156 pc
= int(stack_frame
.getRegisterService().getValue('PC')) & 0xFFFFFFFF
158 # Check if the symbols for this stack frame have already been loaded
160 for debug_info
in debug_infos
:
161 if (pc
>= debug_info
[0]) and (pc
< debug_info
[0] + debug_info
[1]):
164 info
= self
.firmware_volumes
[fv_base
].load_symbols_at(pc
)
165 debug_infos
.append(info
)
167 #self.firmware_volumes[fv_base].load_symbols_at(pc)
168 elif self
.in_sysmem(pc
):
171 if self
.system_table
is None:
172 # Find the System Table
173 self
.system_table
= system_table
.SystemTable(self
.ec
, self
.platform
.sysmembase
, self
.platform
.sysmemsize
)
175 # Find the Debug Info Table
176 debug_info_table_base
= self
.system_table
.get_configuration_table(system_table
.DebugInfoTable
.CONST_DEBUG_INFO_TABLE_GUID
)
177 self
.debug_info_table
= system_table
.DebugInfoTable(self
.ec
, debug_info_table_base
)
179 stack_frame
= self
.ec
.getTopLevelStackFrame()
180 info
= self
.debug_info_table
.load_symbols_at(int(stack_frame
.getRegisterService().getValue('PC')) & 0xFFFFFFFF, self
.verbose
)
181 debug_infos
.append(info
)
182 while stack_frame
.next() is not None:
183 stack_frame
= stack_frame
.next()
185 # Stack frame attached to 'PC'
186 pc
= int(stack_frame
.getRegisterService().getValue('PC')) & 0xFFFFFFFF
188 # Check if the symbols for this stack frame have already been loaded
190 for debug_info
in debug_infos
:
191 if (pc
>= debug_info
[0]) and (pc
< debug_info
[0] + debug_info
[1]):
195 info
= self
.debug_info_table
.load_symbols_at(pc
)
196 debug_infos
.append(info
)
200 #self.debug_info_table.load_symbols_at(pc)
202 raise Exception('ArmPlatformDebugger', "Not supported region")
204 def load_all_symbols(self
):
205 # Load all the XIP symbols attached to the Firmware Volume
206 for (fv_base
, fv_size
) in self
.platform
.fvs
:
207 if self
.firmware_volumes
.has_key(fv_base
) == False:
208 self
.firmware_volumes
[fv_base
] = firmware_volume
.FirmwareVolume(self
.ec
, fv_base
, fv_size
)
209 self
.firmware_volumes
[fv_base
].load_all_symbols(self
.verbose
)
212 # Load all symbols of module loaded into System Memory
213 if self
.system_table
is None:
214 # Find the System Table
215 self
.system_table
= system_table
.SystemTable(self
.ec
, self
.platform
.sysmembase
, self
.platform
.sysmemsize
)
218 # Find the Debug Info Table
219 debug_info_table_base
= self
.system_table
.get_configuration_table(system_table
.DebugInfoTable
.CONST_DEBUG_INFO_TABLE_GUID
)
220 self
.debug_info_table
= system_table
.DebugInfoTable(self
.ec
, debug_info_table_base
)
222 self
.debug_info_table
.load_all_symbols(self
.verbose
)
224 # Debugger exception could be excepted if DRAM has not been initialized or if we have not started to run from DRAM yet
225 print "Note: no symbols have been found in System Memory (possible cause: the UEFI permanent memory has not been installed yet)"