2 # Copyright (c) 2011-2013, ARM Limited. All rights reserved.
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
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.
15 import firmware_volume
19 # Reload external classes
20 reload(firmware_volume
)
24 def readMem32(executionContext
, address
):
25 bytes
= executionContext
.getMemoryService().read(address
, 4, 32)
26 return struct
.unpack('<I',bytes
)[0]
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))
33 ffs
= fv
.get_next_ffs()
37 section
= ffs
.get_next_section()
38 while section
!= None:
39 print "\t%s" % section
41 print "\t\t- %s" % section
.get_debug_filepath()
44 section
= ffs
.get_next_section(section
)
46 ffs
= fv
.get_next_ffs(ffs
)
48 def dump_system_table(ec
, mem_base
, mem_size
):
49 st
= system_table
.SystemTable(ec
, mem_base
, mem_size
)
51 debug_info_table_base
= st
.get_configuration_table(system_table
.DebugInfoTable
.CONST_DEBUG_INFO_TABLE_GUID
)
53 debug_info_table
= system_table
.DebugInfoTable(ec
, debug_info_table_base
)
54 debug_info_table
.dump()
56 def load_symbol_from_file(ec
, filename
, address
, verbose
= False):
58 print "Add symbols of %s at 0x%x" % (filename
, address
)
61 ec
.getImageService().addSymbols(filename
, address
)
64 # We could get an exception if the symbols are already loaded
65 ec
.getImageService().unloadSymbols(filename
)
66 ec
.getImageService().addSymbols(filename
, address
)
68 print "Warning: not possible to load symbols from %s at 0x%x" % (filename
, address
)
73 # Try to access a Aarch64 specific register
74 ec
.getRegisterService().getValue('X0')
80 def __init__(self
, sysmembase
=None, sysmemsize
=None, fvs
={}):
81 self
.sysmembase
= sysmembase
82 self
.sysmemsize
= sysmemsize
85 class ArmPlatformDebugger
:
89 REGION_TYPE_SYSMEM
= 1
93 def __init__(self
, ec
, report_log
, regions
, verbose
= False):
95 self
.verbose
= verbose
100 if report_log
and os
.path
.isfile(report_log
):
102 self
.build
= build_report
.BuildReport(report_log
)
104 raise IOError(2, 'Report \'%s\' is not valid' % report_log
)
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)))
114 sysmem_base
= int(self
.build
.PCDs
['gArmTokenSpaceGuid']['PcdSystemMemoryBase'][0],16)
115 sysmem_size
= int(self
.build
.PCDs
['gArmTokenSpaceGuid']['PcdSystemMemorySize'][0],16)
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
:
129 print "Region type '%d' Not Supported" % region
[0]
131 self
.platform
= ArmPlatform(sysmem_base
, sysmem_size
, fvs
)
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
)
136 def in_fv(self
, addr
):
137 return (self
.get_fv_at(addr
) != None)
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]):
145 def load_current_symbols(self
):
146 pc
= int(self
.ec
.getRegisterService().getValue('PC')) & 0xFFFFFFFF
150 (fv_base
, fv_size
) = self
.get_fv_at(pc
)
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
)
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()
161 # Stack frame attached to 'PC'
162 pc
= int(stack_frame
.getRegisterService().getValue('PC')) & 0xFFFFFFFF
164 # Check if the symbols for this stack frame have already been loaded
166 for debug_info
in debug_infos
:
167 if (pc
>= debug_info
[0]) and (pc
< debug_info
[0] + debug_info
[1]):
170 info
= self
.firmware_volumes
[fv_base
].load_symbols_at(pc
)
171 debug_infos
.append(info
)
173 #self.firmware_volumes[fv_base].load_symbols_at(pc)
174 elif self
.in_sysmem(pc
):
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
)
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
)
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()
191 # Stack frame attached to 'PC'
192 pc
= int(stack_frame
.getRegisterService().getValue('PC')) & 0xFFFFFFFF
194 # Check if the symbols for this stack frame have already been loaded
196 for debug_info
in debug_infos
:
197 if (pc
>= debug_info
[0]) and (pc
< debug_info
[0] + debug_info
[1]):
201 info
= self
.debug_info_table
.load_symbols_at(pc
)
202 debug_infos
.append(info
)
206 #self.debug_info_table.load_symbols_at(pc)
208 raise Exception('ArmPlatformDebugger', "Not supported region")
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
)
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
)
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
)
228 self
.debug_info_table
.load_all_symbols(self
.verbose
)
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)"