This repository has been archived by the owner on Jan 18, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
/
esr_el1
executable file
·147 lines (138 loc) · 5.28 KB
/
esr_el1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
#!/usr/bin/env ruby
# D12.2.36 ESR_EL1, Exception Syndrome Register (EL1)
# page D12-2770
class Accessor
def initialize(size, value)
@bits = value.to_s(2).rjust(size, "0").chars.reverse.join
end
def [](range)
return @bits[range].to_i if range.is_a? Integer
raise "inclusive ranges only" if range.exclude_end?
raise "use high..low like the ARM docs" if range.begin < range.end
@bits[range.end..range.begin].chars.reverse.join.to_i 2
end
end
def ins_data_common(fsc_name, bits)
fsc = bits[5..0]
if (set = bits[12..11]) != 0
puts "SET non-zero"
puts "unimpl"
exit 1
end
if fsc == 0b010000
fnv = bits[10]
if fnv == 0
puts "FnV: 0b0 -- FAR is valid"
else
puts "FnV: 0b1 -- FAR is not valid"
end
end
if (s1ptw = bits[7]) != 0
puts "S1PTW: 0b1 -- fault on the stage 2 translation of an access for a stage 1 translation table walk"
end
puts "#{fsc_name}: 0b#{fsc.to_s(2).rjust(6, "0")}"
case fsc
when 0b000000; puts "Address size fault, level 0 of translation or translation table base register."
when 0b000001; puts "Address size fault, level 1."
when 0b000010; puts "Address size fault, level 2."
when 0b000011; puts "Address size fault, level 3."
when 0b000100; puts "Translation fault, level 0."
when 0b000101; puts "Translation fault, level 1."
when 0b000110; puts "Translation fault, level 2."
when 0b000111; puts "Translation fault, level 3."
when 0b001001; puts "Access flag fault, level 1."
when 0b001010; puts "Access flag fault, level 2."
when 0b001011; puts "Access flag fault, level 3."
when 0b001101; puts "Permission fault, level 1."
when 0b001110; puts "Permission fault, level 2."
when 0b001111; puts "Permission fault, level 3."
when 0b010000; puts "Synchronous External abort, not on translation table walk."
when 0b010001; puts "Synchronous Tag Check fail"
when 0b010100; puts "Synchronous External abort, on translation table walk, level 0."
when 0b010101; puts "Synchronous External abort, on translation table walk, level 1."
when 0b010110; puts "Synchronous External abort, on translation table walk, level 2."
when 0b010111; puts "Synchronous External abort, on translation table walk, level 3."
when 0b011000; puts "Synchronous parity or ECC error on memory access, not on translation table walk."
when 0b011100; puts "Synchronous parity or ECC error on memory access on translation table walk, level 0."
when 0b011101; puts "Synchronous parity or ECC error on memory access on translation table walk, level 1."
when 0b011110; puts "Synchronous parity or ECC error on memory access on translation table walk, level 2."
when 0b011111; puts "Synchronous parity or ECC error on memory access on translation table walk, level 3."
when 0b100001; puts "Alignment fault."
when 0b110000; puts "TLB conflict abort."
when 0b110001; puts "Unsupported atomic hardware update fault, if the implementation includes ARMv8.1-TTHM. Otherwise reserved."
when 0b110100; puts "IMPLEMENTATION DEFINED fault (Lockdown)."
when 0b110101; puts "IMPLEMENTATION DEFINED fault (Unsupported Exclusive or Atomic access)."
when 0b111101; puts "Section Domain Fault, used only for faults reported in the PAR_EL1."
when 0b111110; puts "Page Domain Fault, used only for faults reported in the PAR_EL1."
end
end
def ins_abort(bits)
# D12-2790
ins_data_common("IFSC", bits)
end
def fp_trap_abort(bits)
cv = bits[24]
cond = bits[23..20]
if cv == 1
puts "COND field valid"
case cond
when 0b1110
puts "taken from AArch64"
else
printf "? %04b\n", cond
end
else
puts "COND field invalid"
end
end
def data_abort(bits)
# D12-2792
dfsc = bits[5..0]
if (isv = bits[24]) == 1
puts "Instruction syndrome valid"
puts "unimpl"
exit 1
end
if (vncr = bits[13]) == 1
puts "VNCR: 0b1 -- fault generated by use of VNCR_EL2, by MRS or MSR at EL1"
end
if (cm = bits[8]) != 0
puts "CM: 0b1 -- data abort generated by cache maintenance/address translation instruction"
end
if dfsc != 0b110101 and dfsc != 0b110001
wnr = bits[6]
if wnr == 0
puts "WnR: 0b0 -- abort caused by instruction reading from a memory location"
else
puts "WnR: 0b1 -- abort caused by instruction writing to a memory location"
end
end
ins_data_common("DFSC", bits)
end
if ARGV.length == 0
arg = Integer(`pbpaste`)
puts "ESR_EL1: 0x#{arg.to_s(16).rjust(16, "0")}"
else
arg = Integer(ARGV[0])
end
bits = Accessor.new(64, arg)
ec = bits[31..26]
il = bits[25]
iss = bits[24..0]
printf "EC: 0b%06b\n", ec
printf "IL: 0b%b\n", il
printf "ISS: 0b%025b\n", iss
case ec
when 0b000111
puts "Access to SVE, Advanced SIMD, or floating-point functionality trapped by CPACR_EL1.FPEN, CPTR_EL2.FPEN, CPTR_EL2.TFP, or CPTR_EL3.TFP control."
fp_trap_abort(bits)
when 0b100001
puts "Instruction Abort taken without a change in Exception level"
ins_abort(bits)
when 0b100101
puts "Data Abort taken without a change in Exception level"
data_abort(bits)
else
printf "unimpl EC\n"
exit 1
end