-
Notifications
You must be signed in to change notification settings - Fork 146
/
Copy pathSYSTEM.cpp
104 lines (85 loc) · 2.84 KB
/
SYSTEM.cpp
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
/*
* Copyright (c) 2017 Trail of Bits, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
namespace {
DEF_SEM(CallSupervisor, I32 imm) {
HYPER_CALL = AsyncHyperCall::kAArch64SupervisorCall;
HYPER_CALL_VECTOR = Read(imm);
return memory;
}
DEF_SEM(Breakpoint, I32 imm) {
HYPER_CALL_VECTOR = Read(imm);
return __remill_sync_hyper_call(state, memory,
SyncHyperCall::kAArch64Breakpoint);
}
DEF_SEM(DoMRS_RS_SYSTEM_FPSR, R64W dest) {
auto fpsr = state.fpsr;
fpsr.ixc = state.sr.ixc;
fpsr.ofc = state.sr.ofc;
fpsr.ufc = state.sr.ufc;
//fpsr.idc = state.sr.idc; // TODO(garret): fix the saving of the idc bit before reenabling (issue #188)
fpsr.ioc = state.sr.ioc;
WriteZExt(dest, fpsr.flat);
return memory;
}
DEF_SEM(DoMSR_SR_SYSTEM_FPSR, R64 src) {
FPSR fpsr;
WriteZExt(fpsr.flat, Read(src));
fpsr._res0 = 0;
fpsr._res1 = 0;
state.fpsr = fpsr;
state.sr.ioc = fpsr.ioc;
state.sr.ofc = fpsr.ofc;
state.sr.ixc = fpsr.ixc;
state.sr.ufc = fpsr.ufc;
//state.sr.idc = fpsr.idc; // TODO(garret): fix the saving of the idc bit before reenabling (issue #188)
return memory;
}
DEF_SEM(DoMRS_RS_SYSTEM_FPCR, R64W dest) {
auto fpcr = state.fpcr;
WriteZExt(dest, fpcr.flat);
return memory;
}
DEF_SEM(DoMSR_SR_SYSTEM_FPCR, R64 src) {
FPCR fpcr;
WriteZExt(fpcr.flat, Read(src));
fpcr._res0 = 0;
fpcr._res1 = 0;
state.fpcr = fpcr;
return memory;
}
DEF_SEM(DoMRS_RS_SYSTEM_TPIDR_EL0, R64W dest) {
WriteZExt(dest, Read(state.sr.tpidr_el0));
return memory;
}
DEF_SEM(DoMSR_SR_SYSTEM_TPIDR_EL0, R64 src) {
WriteZExt(state.sr.tpidr_el0.qword, Read(src));
return memory;
}
DEF_SEM(DataMemoryBarrier) {
// TODO(pag): Full-system data memory barrier probably requires a synchronous
// hypercall if it behaves kind of like Linux's `sys_membarrier`.
return __remill_barrier_store_store(memory);
}
} // namespace
DEF_ISEL(SVC_EX_EXCEPTION) = CallSupervisor;
DEF_ISEL(BRK_EX_EXCEPTION) = Breakpoint;
DEF_ISEL(MRS_RS_SYSTEM_FPSR) = DoMRS_RS_SYSTEM_FPSR;
DEF_ISEL(MSR_SR_SYSTEM_FPSR) = DoMSR_SR_SYSTEM_FPSR;
DEF_ISEL(MRS_RS_SYSTEM_FPCR) = DoMRS_RS_SYSTEM_FPCR;
DEF_ISEL(MSR_SR_SYSTEM_FPCR) = DoMSR_SR_SYSTEM_FPCR;
DEF_ISEL(MRS_RS_SYSTEM_TPIDR_EL0) = DoMRS_RS_SYSTEM_TPIDR_EL0;
DEF_ISEL(MSR_SR_SYSTEM_TPIDR_EL0) = DoMSR_SR_SYSTEM_TPIDR_EL0;
DEF_ISEL(DMB_BO_SYSTEM) = DataMemoryBarrier;