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