]>
Commit | Line | Data |
---|---|---|
cb323159 A |
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 | } |