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
)
72 def __init__(self
, sysmembase
=None, sysmemsize
=None, fvs
={}):
73 self
.sysmembase
= sysmembase
74 self
.sysmemsize
= sysmemsize
77 class ArmPlatformDebugger
:
81 REGION_TYPE_SYSMEM
= 1
85 def __init__(self
, ec
, report_log
, regions
, verbose
= False):
87 self
.verbose
= verbose
92 if report_log
and os
.path
.isfile(report_log
):
94 self
.build
= build_report
.BuildReport(report_log
)
96 raise IOError(2, 'Report \'%s\' is not valid' % report_log
)
98 # Generate list of supported Firmware Volumes
99 if self
.build
.PCDs
['gArmTokenSpaceGuid'].has_key('PcdFvSize') and int(self
.build
.PCDs
['gArmTokenSpaceGuid']['PcdFvSize'][0],16) != 0:
100 fvs
.append((int(self
.build
.PCDs
['gArmTokenSpaceGuid']['PcdFvBaseAddress'][0],16),int(self
.build
.PCDs
['gArmTokenSpaceGuid']['PcdFvSize'][0],16)))
101 if self
.build
.PCDs
['gArmTokenSpaceGuid'].has_key('PcdSecureFvSize') and int(self
.build
.PCDs
['gArmTokenSpaceGuid']['PcdSecureFvSize'][0],16) != 0:
102 fvs
.append((int(self
.build
.PCDs
['gArmTokenSpaceGuid']['PcdSecureFvBaseAddress'][0],16),int(self
.build
.PCDs
['gArmTokenSpaceGuid']['PcdSecureFvSize'][0],16)))
103 if self
.build
.PCDs
['gArmTokenSpaceGuid'].has_key('PcdHypFvSize') and int(self
.build
.PCDs
['gArmTokenSpaceGuid']['PcdHypFvSize'][0],16) != 0:
104 fvs
.append((int(self
.build
.PCDs
['gArmTokenSpaceGuid']['PcdHypFvBaseAddress'][0],16),int(self
.build
.PCDs
['gArmTokenSpaceGuid']['PcdHypFvSize'][0],16)))
106 sysmem_base
= int(self
.build
.PCDs
['gArmTokenSpaceGuid']['PcdSystemMemoryBase'][0],16)
107 sysmem_size
= int(self
.build
.PCDs
['gArmTokenSpaceGuid']['PcdSystemMemorySize'][0],16)
109 for region
in regions
:
110 if region
[0] == ArmPlatformDebugger
.REGION_TYPE_SYSMEM
:
111 sysmem_base
= region
[1]
112 sysmem_size
= region
[2]
113 elif region
[0] == ArmPlatformDebugger
.REGION_TYPE_FV
:
114 fvs
.append((region
[1],region
[2]))
115 elif region
[0] == ArmPlatformDebugger
.REGION_TYPE_ROM
:
116 for base
in xrange(region
[1], region
[1] + region
[2], 0x400000):
117 signature
= struct
.unpack("cccc", self
.ec
.getMemoryService().read(base
, 4, 32))
118 if signature
== FirmwareVolume
.CONST_FV_SIGNATURE
:
121 print "Region type '%d' Not Supported" % region
[0]
123 self
.platform
= ArmPlatform(sysmem_base
, sysmem_size
, fvs
)
125 def in_sysmem(self
, addr
):
126 return (self
.platform
.sysmembase
is not None) and (self
.platform
.sysmembase
<= addr
) and (addr
< self
.platform
.sysmembase
+ self
.platform
.sysmemsize
)
128 def in_fv(self
, addr
):
129 return (self
.get_fv_at(addr
) != None)
131 def get_fv_at(self
, addr
):
132 for fv
in self
.platform
.fvs
:
133 if (fv
[0] <= addr
) and (addr
< fv
[0] + fv
[1]):
137 def load_current_symbols(self
):
138 pc
= int(self
.ec
.getRegisterService().getValue('PC')) & 0xFFFFFFFF
142 (fv_base
, fv_size
) = self
.get_fv_at(pc
)
144 if self
.firmware_volumes
.has_key(fv_base
) == False:
145 self
.firmware_volumes
[fv_base
] = firmware_volume
.FirmwareVolume(self
.ec
, fv_base
, fv_size
)
147 stack_frame
= self
.ec
.getTopLevelStackFrame()
148 info
= self
.firmware_volumes
[fv_base
].load_symbols_at(int(stack_frame
.getRegisterService().getValue('PC')) & 0xFFFFFFFF, self
.verbose
)
149 debug_infos
.append(info
)
150 while stack_frame
.next() is not None:
151 stack_frame
= stack_frame
.next()
153 # Stack frame attached to 'PC'
154 pc
= int(stack_frame
.getRegisterService().getValue('PC')) & 0xFFFFFFFF
156 # Check if the symbols for this stack frame have already been loaded
158 for debug_info
in debug_infos
:
159 if (pc
>= debug_info
[0]) and (pc
< debug_info
[0] + debug_info
[1]):
162 info
= self
.firmware_volumes
[fv_base
].load_symbols_at(pc
)
163 debug_infos
.append(info
)
165 #self.firmware_volumes[fv_base].load_symbols_at(pc)
166 elif self
.in_sysmem(pc
):
169 if self
.system_table
is None:
170 # Find the System Table
171 self
.system_table
= system_table
.SystemTable(self
.ec
, self
.platform
.sysmembase
, self
.platform
.sysmemsize
)
173 # Find the Debug Info Table
174 debug_info_table_base
= self
.system_table
.get_configuration_table(system_table
.DebugInfoTable
.CONST_DEBUG_INFO_TABLE_GUID
)
175 self
.debug_info_table
= system_table
.DebugInfoTable(self
.ec
, debug_info_table_base
)
177 stack_frame
= self
.ec
.getTopLevelStackFrame()
178 info
= self
.debug_info_table
.load_symbols_at(int(stack_frame
.getRegisterService().getValue('PC')) & 0xFFFFFFFF, self
.verbose
)
179 debug_infos
.append(info
)
180 while stack_frame
.next() is not None:
181 stack_frame
= stack_frame
.next()
183 # Stack frame attached to 'PC'
184 pc
= int(stack_frame
.getRegisterService().getValue('PC')) & 0xFFFFFFFF
186 # Check if the symbols for this stack frame have already been loaded
188 for debug_info
in debug_infos
:
189 if (pc
>= debug_info
[0]) and (pc
< debug_info
[0] + debug_info
[1]):
192 info
= self
.debug_info_table
.load_symbols_at(pc
)
193 debug_infos
.append(info
)
195 #self.debug_info_table.load_symbols_at(pc)
197 raise Exception('ArmPlatformDebugger', "Not supported region")
199 def load_all_symbols(self
):
200 # Load all the XIP symbols attached to the Firmware Volume
201 for (fv_base
, fv_size
) in self
.platform
.fvs
:
202 if self
.firmware_volumes
.has_key(fv_base
) == False:
203 self
.firmware_volumes
[fv_base
] = firmware_volume
.FirmwareVolume(self
.ec
, fv_base
, fv_size
)
204 self
.firmware_volumes
[fv_base
].load_all_symbols(self
.verbose
)
207 # Load all symbols of module loaded into System Memory
208 if self
.system_table
is None:
209 # Find the System Table
210 self
.system_table
= system_table
.SystemTable(self
.ec
, self
.platform
.sysmembase
, self
.platform
.sysmemsize
)
213 # Find the Debug Info Table
214 debug_info_table_base
= self
.system_table
.get_configuration_table(system_table
.DebugInfoTable
.CONST_DEBUG_INFO_TABLE_GUID
)
215 self
.debug_info_table
= system_table
.DebugInfoTable(self
.ec
, debug_info_table_base
)
217 self
.debug_info_table
.load_all_symbols(self
.verbose
)
219 # Debugger exception could be excepted if DRAM has not been initialized or if we have not started to run from DRAM yet
220 print "Note: no symbols have been found in System Memory (possible cause: the UEFI permanent memory has been installed yet)"