]> git.saurik.com Git - apple/xnu.git/blob - tools/lldbmacros/sysreg.py
xnu-6153.121.1.tar.gz
[apple/xnu.git] / tools / lldbmacros / sysreg.py
1 """ Please make sure you read the README file COMPLETELY BEFORE reading anything below.
2 It is very critical that you read coding guidelines in Section E in README file.
3 """
4
5 """ Note for adding new register support:
6
7 1. Add target register to "supported registers" in the docstring of DecodeSysreg
8 2. Populate _SYSREG_TO_DECODE_FUNC_MAP with your implementation, optionally using
9 _SYSREG_TO_DOCNAME_MAP
10 3. Populate _SUPPORTED_SYSREGS list with target register
11
12 """
13
14 from xnu import *
15 import os
16 import sys
17 import xml.etree.ElementTree as ET
18
19 GREEN = '\033[0;32m'
20 RED = '\033[0;31m'
21 NC = '\033[0m'
22
23 _SUPPORTED_SYSREGS = ['ESR_EL1']
24
25 _SYSREG_DOC_PATH = os.path.dirname(os.path.abspath(__file__)) + '/sysregdoc/'
26
27 _SYSREG_TO_DOCNAME_MAP = {
28 'ESR_EL1': 'AArch64-esr_el1.xml'
29 }
30
31 ## Actual definition at the bottom of the file
32 _SYSREG_TO_DECODE_FUNC_MAP = None
33
34 # Macro: decode_sysreg
35 @lldb_command('decode_sysreg')
36 def DecodeSysreg(cmd_args=None):
37 """ Print out human-understandable explanation of a system register value
38 usage: decode_sysreg <sysreg> <value>
39 example: decode_sysreg esr_el1 0x96000021
40
41 supported registers:
42 ESR_EL1
43 """
44
45 ## For now, require exactly 2 arguments
46 if not cmd_args or len(cmd_args) != 2:
47 raise ArgumentError("Missing arguments.")
48
49 reg_name = cmd_args[0].upper()
50 reg_value = int(cmd_args[1], 0)
51
52 if reg_name not in _SUPPORTED_SYSREGS:
53 raise ArgumentError("{} is not supported".format(reg_name))
54
55 _SYSREG_TO_DECODE_FUNC_MAP[reg_name](reg_value)
56 # EndMacro: decode_sysreg
57
58
59 lldb_alias('decode_esr', 'decode_sysreg esr_el1')
60
61
62 def PrintEsrEl1Explanation(regval):
63 """ Print out a detailed explanation of regval regarded as the value of
64 ESR_EL1, by parsing ARM machine readable specification
65 """
66 xmlfilename = _SYSREG_DOC_PATH + _SYSREG_TO_DOCNAME_MAP['ESR_EL1']
67 tree = ET.parse(xmlfilename)
68 root = tree.getroot()
69
70 ec = (regval >> 26) & ((1 << 6) - 1)
71 ecstring = '0b{:06b}'.format(ec)
72
73 print _Colorify(VT.Green, 'EC == ' + ecstring)
74
75 ecxpath = './registers/register/reg_fieldsets/fields/field[@id="EC_31_26"]/field_values/field_value_instance[field_value="{}"]/field_value_description//para'.format(ecstring)
76 ec_desc_paras = root.findall(ecxpath)
77
78 if ec_desc_paras is None or len(ec_desc_paras) == 0:
79 print 'EC not defined.'
80 print '\r\n'
81
82 for para in ec_desc_paras:
83 sys.stdout.write(para.text)
84 for child in para:
85 sys.stdout.write(_GetParaChildrenStr(child))
86 sys.stdout.write(child.tail)
87 print '\r\n'
88 print '\r\n'
89
90 iss = regval & ((1 << 25) - 1);
91 issstring = '0x{:07x}'.format(iss)
92 print _Colorify(VT.Green, 'ISS == ' + issstring)
93 print '\r\n'
94
95 iss_condition_xpath = './registers/register/reg_fieldsets/fields/field[@id="EC_31_26"]/field_values/field_value_instance[field_value="{}"]/field_value_links_to'.format(ecstring)
96 iss_condition = root.find(iss_condition_xpath)
97 iss_condition_str = iss_condition.attrib['linked_field_condition']
98
99 iss_fields_xpath = './registers/register/reg_fieldsets/fields/field[@id="ISS_24_0"]/partial_fieldset/fields[fields_instance="{}"]//field'.format(iss_condition_str)
100 iss_fields = root.findall(iss_fields_xpath)
101
102 for field in iss_fields:
103 _PrintEsrIssField(field, regval)
104
105
106 def _GetParaChildrenStr(elem):
107 """ Convert child tags of <para> element into text for printing
108 """
109
110 if elem.tag == 'binarynumber':
111 return elem.text
112 if elem.tag == 'arm-defined-word':
113 return elem.text
114 elif elem.tag == 'xref':
115 return elem.attrib['browsertext'].encode('utf-8')
116 elif elem.tag == 'register_link':
117 return elem.text
118 else:
119 return _Colorify(VT.Red, '*unsupported text*')
120
121
122 def _PrintEsrIssField(elem, regval):
123 """ Print detailed explanation of the ISS field of ESR
124 """
125
126 field_name_str = elem.find('field_name').text
127 field_msb = int(elem.find('field_msb').text)
128 field_lsb = int(elem.find('field_lsb').text)
129 fd_before_paras = elem.findall('./field_description[@order="before"]//para')
130 fd_after_paras = elem.findall('./field_description[@order="after"]//para')
131
132 field_bits = field_msb - field_lsb + 1
133 field_value = (regval >> field_lsb) & ((1 << field_bits) - 1)
134 field_value_string = ('0b{:0' + '{}'.format(field_bits) + 'b}').format(field_value)
135
136 print _Colorify(VT.Green, _GetIndentedString(2, field_name_str) + ' == ' + field_value_string)
137
138 fv_desc_paras = elem.findall('./field_values/field_value_instance[field_value="{}"]/field_value_description//para'.format(field_value_string))
139
140 if fv_desc_paras and len(fv_desc_paras):
141 for para in fv_desc_paras:
142 sys.stdout.write(_GetIndentedString(2, ''))
143 sys.stdout.write(para.text)
144 for child in para:
145 sys.stdout.write(_GetParaChildrenStr(child))
146 sys.stdout.write((child.tail))
147 print '\r\n'
148 print '\r\n'
149 else:
150 print _Colorify(VT.Red, _GetIndentedString(2, '(No matching value, dumping out full description)'))
151 for para in fd_before_paras:
152 sys.stdout.write(_GetIndentedString(2, ''))
153 sys.stdout.write(para.text)
154 for child in para:
155 sys.stdout.write(_GetParaChildrenStr(child))
156 sys.stdout.write(child.tail)
157 print '\r\n'
158 print '\r\n'
159
160 ## Dump all possible values
161 all_field_values = elem.findall('./field_values/field_value_instance//field_value')
162 all_field_values_str = [fv.text for fv in all_field_values]
163 if all_field_values_str != []:
164 print _GetIndentedString(2, ', '.join(all_field_values_str))
165
166 for para in fd_after_paras:
167 sys.stdout.write(_GetIndentedString(2, ''))
168 sys.stdout.write(para.text)
169 for child in para:
170 sys.stdout.write(_GetParaChildrenStr(child))
171 sys.stdout.write(child.tail)
172 print '\r\n'
173 print '\r\n'
174
175
176 def _GetIndentedString(indentation, msg):
177 """ Return `msg` indented by `indentation` number of spaces
178 """
179 return ' ' * indentation + msg
180
181
182 def _Colorify(color, msg):
183 """ Return `msg` enclosed by color codes
184 """
185 return color + msg + VT.Reset
186
187
188 _SYSREG_TO_DECODE_FUNC_MAP = {
189 'ESR_EL1': PrintEsrEl1Explanation
190 }