arch-x86: Implement real mode far call.
Change-Id: I720a0b0e4aa227171c59804d899baba64b8d320b Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/55623 Reviewed-by: Gabe Black <gabe.black@gmail.com> Maintainer: Gabe Black <gabe.black@gmail.com> Tested-by: kokoro <noreply+kokoro@google.com>
This commit is contained in:
@@ -305,6 +305,7 @@
|
||||
0x1: CQO(rAv,rDv);
|
||||
0x2: decode MODE_SUBMODE {
|
||||
0x0: UD2();
|
||||
0x4: CALL_FAR_REAL(Iz);
|
||||
default: WarnUnimpl::call_far_Ap();
|
||||
}
|
||||
0x3: WarnUnimpl::fwait(); //aka wait
|
||||
@@ -568,7 +569,10 @@
|
||||
0x0: INC(Ev);
|
||||
0x1: DEC(Ev);
|
||||
0x2: CALL_NEAR(Ev);
|
||||
0x3: WarnUnimpl::call_far_Mp();
|
||||
0x3: decode MODE_SUBMODE {
|
||||
0x4: CALL_FAR_REAL(Mz);
|
||||
default: WarnUnimpl::call_far_Mp();
|
||||
}
|
||||
0x4: JMP(Ev);
|
||||
0x5: decode MODE_SUBMODE {
|
||||
0x0: JMP_FAR(Mz);
|
||||
|
||||
@@ -92,6 +92,77 @@ def macroop CALL_NEAR_P
|
||||
subi rsp, rsp, dsz, dataSize=ssz
|
||||
wripi t1, 0
|
||||
};
|
||||
|
||||
def macroop CALL_FAR_REAL_I {
|
||||
.function_call
|
||||
.control_indirect
|
||||
|
||||
limm t1, imm, dataSize=8
|
||||
|
||||
# Multiply the data size by 8 to get the size of the offset in bits.
|
||||
limm t3, dsz, dataSize=8
|
||||
slli t3, t3, 3, dataSize=8
|
||||
|
||||
# Extract the selector from the far pointer.
|
||||
srl t2, t1, t3, dataSize=8
|
||||
zexti t2, t2, 15, dataSize=8
|
||||
# Extract the offset from the far pointer.
|
||||
zext t1, t1, t3, dataSize=8
|
||||
|
||||
# Compute the base.
|
||||
slli t3, t2, 4, dataSize=8
|
||||
|
||||
# Make sure pushing the RIP will work after we push cs.
|
||||
cda ss, [1, t0, rsp], "-env.dataSize * 2", addressSize=ssz
|
||||
|
||||
# Push CS.
|
||||
rdsel t4, cs, dataSize=8
|
||||
st t4, ss, [1, t0, rsp], "-env.dataSize", addressSize=ssz
|
||||
# Push RIP.
|
||||
rdip t7
|
||||
st t7, ss, [1, t0, rsp], "-env.dataSize * 2", addressSize=ssz
|
||||
subi rsp, rsp, "env.dataSize * 2", dataSize=ssz
|
||||
|
||||
# Install the new selector, base and RIP values.
|
||||
wrsel cs, t2, dataSize=2
|
||||
wrbase cs, t3, dataSize=8
|
||||
wrip t1, t0
|
||||
};
|
||||
|
||||
def macroop CALL_FAR_REAL_M {
|
||||
.function_call
|
||||
.control_indirect
|
||||
|
||||
lea t1, seg, sib, disp, dataSize=asz
|
||||
# Load the selector.
|
||||
ld t2, seg, [1, t0, t1], dsz, dataSize=2
|
||||
# Load the offset.
|
||||
ld t1, seg, [1, t0, t1]
|
||||
|
||||
# Compute the base.
|
||||
zexti t3, t2, 15, dataSize=8
|
||||
slli t3, t3, 4, dataSize=8
|
||||
|
||||
# Make sure pushing the RIP will work after we push cs.
|
||||
cda ss, [1, t0, rsp], "-env.dataSize * 2", addressSize=ssz
|
||||
|
||||
# Push CS.
|
||||
rdsel t4, cs, dataSize=8
|
||||
st t4, ss, [1, t0, rsp], "-env.dataSize", addressSize=ssz
|
||||
# Push RIP.
|
||||
rdip t7
|
||||
st t7, ss, [1, t0, rsp], "-env.dataSize * 2", addressSize=ssz
|
||||
subi rsp, rsp, "env.dataSize * 2", dataSize=ssz
|
||||
|
||||
# Install the new selector, base and RIP values.
|
||||
wrsel cs, t2, dataSize=2
|
||||
wrbase cs, t3, dataSize=8
|
||||
wrip t1, t0
|
||||
};
|
||||
|
||||
def macroop CALL_FAR_REAL_P {
|
||||
panic "Far call in real mode doesn't support RIP addressing."
|
||||
};
|
||||
'''
|
||||
#let {{
|
||||
# class CALL(Inst):
|
||||
|
||||
Reference in New Issue
Block a user