X86: Reorganize segmentation and implement segment selector movs.
--HG-- extra : convert_revision : 553c3ffeda1f5312cf02493f602e7d4ba2fe66e8
This commit is contained in:
parent
a548067b01
commit
dc6f960171
13 changed files with 361 additions and 108 deletions
|
@ -94,8 +94,26 @@ namespace X86ISA
|
|||
case SEGMENT_REG_GS:
|
||||
ccprintf(os, "GS");
|
||||
break;
|
||||
case SEGMENT_REG_INT:
|
||||
ccprintf(os, "INT");
|
||||
case SEGMENT_REG_HS:
|
||||
ccprintf(os, "HS");
|
||||
break;
|
||||
case SEGMENT_REG_TSL:
|
||||
ccprintf(os, "TSL");
|
||||
break;
|
||||
case SEGMENT_REG_TSG:
|
||||
ccprintf(os, "TSG");
|
||||
break;
|
||||
case SEGMENT_REG_LS:
|
||||
ccprintf(os, "LS");
|
||||
break;
|
||||
case SEGMENT_REG_MS:
|
||||
ccprintf(os, "MS");
|
||||
break;
|
||||
case SYS_SEGMENT_REG_TR:
|
||||
ccprintf(os, "TR");
|
||||
break;
|
||||
case SYS_SEGMENT_REG_IDTR:
|
||||
ccprintf(os, "IDTR");
|
||||
break;
|
||||
default:
|
||||
panic("Unrecognized segment %d\n", segment);
|
||||
|
|
|
@ -292,9 +292,21 @@
|
|||
0x1: MOV(Ev,Gv);
|
||||
0x2: MOV(Gb,Eb);
|
||||
0x3: MOV(Gv,Ev);
|
||||
0x4: WarnUnimpl::mov_MwRv_Sw(); //What to do with this one?
|
||||
0x4: decode MODRM_REG {
|
||||
0x0, 0x1, 0x2,
|
||||
0x3, 0x4, 0x5: MOV(Ev,Sv);
|
||||
}
|
||||
0x5: LEA(Gv,M);
|
||||
0x6: WarnUnimpl::mov_Sw_MwRv();
|
||||
0x6: decode MODE_SUBMODE {
|
||||
0x3, 0x4: MOV_REAL(Sv,Ev);
|
||||
default: decode MODRM_REG {
|
||||
0x1: UD2(); // Moving to the CS selector is illegal.
|
||||
0x2: MOVSS(Sv,Ev);
|
||||
0x0, 0x3,
|
||||
0x4, 0x5: MOV(Sv,Ev);
|
||||
default: UD2();
|
||||
}
|
||||
}
|
||||
//0x7: group10_Ev();
|
||||
0x7: decode MODRM_REG {
|
||||
0x0: POP(Ev);
|
||||
|
|
|
@ -192,6 +192,108 @@ def macroop MOVZX_W_R_P {
|
|||
def macroop MOV_C_R {
|
||||
wrcr reg, regm
|
||||
};
|
||||
|
||||
def macroop MOV_R_S {
|
||||
rdsel reg, regm
|
||||
};
|
||||
|
||||
def macroop MOV_M_S {
|
||||
rdsel t1, reg
|
||||
st t1, seg, sib, disp, dataSize=2
|
||||
};
|
||||
|
||||
def macroop MOV_P_S {
|
||||
rdip t7
|
||||
rdsel t1, reg
|
||||
st t1, seg, riprel, disp, dataSize=2
|
||||
};
|
||||
|
||||
def macroop MOV_REAL_S_R {
|
||||
zext t2, regm, 15
|
||||
slli t3, t2, 2, dataSize=8
|
||||
wrsel reg, regm
|
||||
wrbase reg, t3
|
||||
};
|
||||
|
||||
def macroop MOV_REAL_S_M {
|
||||
ld t1, seg, sib, disp, dataSize=2
|
||||
zext t2, t1, 15
|
||||
slli t3, t2, 2, dataSize=8
|
||||
wrsel reg, t1
|
||||
wrbase reg, t3
|
||||
};
|
||||
|
||||
def macroop MOV_REAL_S_P {
|
||||
rdip t7
|
||||
ld t1, seg, riprel, disp, dataSize=2
|
||||
zext t2, t1, 15
|
||||
slli t3, t2, 2, dataSize=8
|
||||
wrsel reg, t1
|
||||
wrbase reg, t3
|
||||
};
|
||||
|
||||
def macroop MOV_S_R {
|
||||
chks t1, regm, flags=(EZF,), dataSize=8
|
||||
bri t0, label("end"), flags=(CEZF,)
|
||||
ld t2, flatseg, [1, t0, t1], addressSize=8, dataSize=8
|
||||
wrdl reg, t2, regm
|
||||
end:
|
||||
wrsel reg, regm
|
||||
};
|
||||
|
||||
def macroop MOV_S_M {
|
||||
ld t1, seg, sib, disp, dataSize=2
|
||||
chks t2, t1, flags=(EZF,), dataSize=8
|
||||
bri t0, label("end"), flags=(CEZF,)
|
||||
ld t2, flatseg, [1, t0, t1], addressSize=8, dataSize=8
|
||||
wrdl reg, t2, t1
|
||||
end:
|
||||
wrsel reg, t1
|
||||
};
|
||||
|
||||
def macroop MOV_S_P {
|
||||
rdip t7
|
||||
ld t1, seg, riprel, disp, dataSize=2
|
||||
chks t2, t1, flags=(EZF,), dataSize=8
|
||||
bri t0, label("end"), flags=(CEZF,)
|
||||
ld t2, flatseg, [1, t0, t1], addressSize=8, dataSize=8
|
||||
wrdl reg, t2, t1
|
||||
end:
|
||||
wrsel reg, t1
|
||||
};
|
||||
|
||||
def macroop MOVSS_S_R {
|
||||
chks t1, regm, flags=(EZF,), dataSize=8
|
||||
# This actually needs to use the selector as the error code, but it would
|
||||
# be hard to get that information into the instruction at the moment.
|
||||
fault "new GeneralProtection(0)", flags=(CEZF,)
|
||||
ld t2, flatseg, [1, t0, t1], addressSize=8, dataSize=8
|
||||
wrdl reg, t2, regm
|
||||
wrsel reg, regm
|
||||
};
|
||||
|
||||
def macroop MOVSS_S_M {
|
||||
ld t1, seg, sib, disp, dataSize=2
|
||||
chks t2, t1, flags=(EZF,), dataSize=8
|
||||
# This actually needs to use the selector as the error code, but it would
|
||||
# be hard to get that information into the instruction at the moment.
|
||||
fault "new GeneralProtection(0)", flags=(CEZF,)
|
||||
ld t2, flatseg, [1, t0, t1], addressSize=8, dataSize=8
|
||||
wrdl reg, t2, t1
|
||||
wrsel reg, t1
|
||||
};
|
||||
|
||||
def macroop MOVSS_S_P {
|
||||
rdip t7
|
||||
ld t1, seg, riprel, disp, dataSize=2
|
||||
chks t2, t1, flags=(EZF,), dataSize=8
|
||||
# This actually needs to use the selector as the error code, but it would
|
||||
# be hard to get that information into the instruction at the moment.
|
||||
fault "new GeneralProtection(0)", flags=(CEZF,)
|
||||
ld t2, flatseg, [1, t0, t1], addressSize=8, dataSize=8
|
||||
wrdl reg, t2, t1
|
||||
wrsel reg, t1
|
||||
};
|
||||
'''
|
||||
#let {{
|
||||
# class MOVD(Inst):
|
||||
|
|
|
@ -62,8 +62,8 @@ def macroop LGDT_M
|
|||
ld t1, seg, sib, disp, dataSize=2
|
||||
# Get the base
|
||||
ld t2, seg, sib, 'adjustedDisp + 2'
|
||||
wrbase gdtr, t2
|
||||
wrlimit gdtr, t1
|
||||
wrbase tsg, t2
|
||||
wrlimit tsg, t1
|
||||
};
|
||||
|
||||
def macroop LGDT_P
|
||||
|
@ -75,8 +75,8 @@ def macroop LGDT_P
|
|||
ld t1, seg, riprel, disp, dataSize=2
|
||||
# Get the base
|
||||
ld t2, seg, riprel, 'adjustedDisp + 2'
|
||||
wrbase gdtr, t2
|
||||
wrlimit gdtr, t1
|
||||
wrbase tsg, t2
|
||||
wrlimit tsg, t1
|
||||
};
|
||||
|
||||
#
|
||||
|
@ -93,8 +93,8 @@ def macroop LGDT_16_M
|
|||
# Get the base
|
||||
ld t2, seg, sib, 'adjustedDisp + 2', dataSize=4
|
||||
zexti t2, t2, 23
|
||||
wrbase gdtr, t2
|
||||
wrlimit gdtr, t1
|
||||
wrbase tsg, t2
|
||||
wrlimit tsg, t1
|
||||
};
|
||||
|
||||
def macroop LGDT_16_P
|
||||
|
@ -107,8 +107,8 @@ def macroop LGDT_16_P
|
|||
# Get the base
|
||||
ld t2, seg, riprel, 'adjustedDisp + 2', dataSize=4
|
||||
zexti t2, t2, 23
|
||||
wrbase gdtr, t2
|
||||
wrlimit gdtr, t1
|
||||
wrbase tsg, t2
|
||||
wrlimit tsg, t1
|
||||
};
|
||||
|
||||
def macroop LIDT_M
|
||||
|
|
|
@ -81,9 +81,12 @@ let {{
|
|||
for letter in ("C", "D", "E", "F", "G", "S"):
|
||||
assembler.symbols["%ss" % letter.lower()] = "SEGMENT_REG_%sS" % letter
|
||||
|
||||
for reg in ("LDTR", "TR", "GDTR", "IDTR"):
|
||||
for reg in ("TR", "IDTR"):
|
||||
assembler.symbols[reg.lower()] = "SYS_SEGMENT_REG_%s" % reg
|
||||
|
||||
for reg in ("TSL", "TSG"):
|
||||
assembler.symbols[reg.lower()] = "SEGMENT_REG_%s" % reg
|
||||
|
||||
# Miscellaneous symbols
|
||||
symbols = {
|
||||
"reg" : "env.reg",
|
||||
|
@ -112,7 +115,10 @@ let {{
|
|||
|
||||
# This segment selects an internal address space mapped to MSRs,
|
||||
# CPUID info, etc.
|
||||
assembler.symbols["intseg"] = "SEGMENT_REG_INT"
|
||||
assembler.symbols["intseg"] = "SEGMENT_REG_MS"
|
||||
# This segment always has base 0, and doesn't imply any special handling
|
||||
# like the internal segment above
|
||||
assembler.symbols["flatseg"] = "SEGMENT_REG_LS"
|
||||
|
||||
for reg in ('ax', 'bx', 'cx', 'dx', 'sp', 'bp', 'si', 'di'):
|
||||
assembler.symbols["r%s" % reg] = "INTREG_R%s" % reg.upper()
|
||||
|
|
|
@ -937,19 +937,100 @@ let {{
|
|||
}
|
||||
'''
|
||||
|
||||
class Wrbase(RegOp):
|
||||
# Microops for manipulating segmentation registers
|
||||
class SegOp(RegOp):
|
||||
abstract = True
|
||||
def __init__(self, dest, src1, flags=None, dataSize="env.dataSize"):
|
||||
super(Wrbase, self).__init__(dest, \
|
||||
super(SegOp, self).__init__(dest, \
|
||||
src1, "NUM_INTREGS", flags, dataSize)
|
||||
|
||||
class Wrbase(SegOp):
|
||||
code = '''
|
||||
SysSegBaseDest = psrc1;
|
||||
SegBaseDest = psrc1;
|
||||
'''
|
||||
|
||||
class Wrlimit(RegOp):
|
||||
def __init__(self, dest, src1, flags=None, dataSize="env.dataSize"):
|
||||
super(Wrlimit, self).__init__(dest, \
|
||||
src1, "NUM_INTREGS", flags, dataSize)
|
||||
class Wrlimit(SegOp):
|
||||
code = '''
|
||||
SysSegLimitDest = psrc1;
|
||||
SegLimitDest = psrc1;
|
||||
'''
|
||||
|
||||
class Wrsel(SegOp):
|
||||
code = '''
|
||||
SegSelDest = psrc1;
|
||||
'''
|
||||
|
||||
class Rdbase(SegOp):
|
||||
code = '''
|
||||
DestReg = SegBaseDest;
|
||||
'''
|
||||
|
||||
class Rdlimit(SegOp):
|
||||
code = '''
|
||||
DestReg = SegLimitSrc1;
|
||||
'''
|
||||
|
||||
class Rdsel(SegOp):
|
||||
code = '''
|
||||
DestReg = SegSelSrc1;
|
||||
'''
|
||||
|
||||
class Chks(SegOp):
|
||||
code = '''
|
||||
// The selector is in source 1.
|
||||
SegSelector selector = psrc1;
|
||||
|
||||
// Compute the address of the descriptor and set DestReg to it.
|
||||
if (selector.ti) {
|
||||
// A descriptor in the LDT
|
||||
Addr target = (selector.esi << 3) + LDTRBase;
|
||||
if (!LDTRSel || (selector.esi << 3) + dataSize > LDTRLimit)
|
||||
fault = new GeneralProtection(selector & mask(16));
|
||||
DestReg = target;
|
||||
} else {
|
||||
// A descriptor in the GDT
|
||||
Addr target = (selector.esi << 3) + GDTRBase;
|
||||
if ((selector.esi << 3) + dataSize > GDTRLimit)
|
||||
fault = new GeneralProtection(selector & mask(16));
|
||||
DestReg = target;
|
||||
}
|
||||
'''
|
||||
flag_code = '''
|
||||
// Check for a NULL selector and set ZF,EZF appropriately.
|
||||
ccFlagBits = ccFlagBits & ~(ext & (ZFBit | EZFBit));
|
||||
if (!selector.esi && !selector.ti)
|
||||
ccFlagBits = ccFlagBits | (ext & (ZFBit | EZFBit));
|
||||
'''
|
||||
|
||||
class Wrdh(RegOp):
|
||||
code = '''
|
||||
|
||||
'''
|
||||
|
||||
class Wrdl(RegOp):
|
||||
code = '''
|
||||
SegDescriptor desc = SrcReg1;
|
||||
SegAttr attr = 0;
|
||||
Addr base = 0, limit = 0;
|
||||
attr.dpl = desc.dpl;
|
||||
attr.defaultSize = desc.d;
|
||||
if (!desc.p)
|
||||
panic("Segment not present.\\n");
|
||||
if (!desc.s)
|
||||
panic("System segment encountered.\\n");
|
||||
if (desc.type.codeOrData) {
|
||||
panic("Code segment encountered with c = %d, r = %d, a = %d.\\n",
|
||||
desc.type.c, desc.type.r, desc.type.a);
|
||||
} else {
|
||||
attr.expandDown = desc.type.e;
|
||||
attr.readable = 1;
|
||||
attr.writable = desc.type.w;
|
||||
base = desc.baseLow | (desc.baseHigh << 24);
|
||||
limit = desc.limitLow | (desc.limitHigh << 16);
|
||||
if (desc.g)
|
||||
limit = (limit << 12) | mask(12);
|
||||
}
|
||||
SegBaseDest = base;
|
||||
SegLimitDest = limit;
|
||||
SegAttrDest = attr;
|
||||
'''
|
||||
}};
|
||||
|
|
|
@ -121,14 +121,30 @@ def operands {{
|
|||
# The TOP register should needs to be more protected so that later
|
||||
# instructions don't map their indexes with an old value.
|
||||
'TOP': ('ControlReg', 'ub', 'MISCREG_X87_TOP', None, 61),
|
||||
# The segment base as used by memory instructions.
|
||||
'SegBase': ('ControlReg', 'uqw', 'MISCREG_SEG_EFF_BASE(segment)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 70),
|
||||
'ControlDest': ('ControlReg', 'uqw', 'MISCREG_CR(dest)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 71),
|
||||
'ControlSrc1': ('ControlReg', 'uqw', 'MISCREG_CR(src1)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 72),
|
||||
'EferOp': ('ControlReg', 'uqw', 'MISCREG_EFER', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 73),
|
||||
'CR4Op': ('ControlReg', 'uqw', 'MISCREG_CR4', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 74),
|
||||
'CSBase': ('ControlReg', 'udw', 'MISCREG_CS_EFF_BASE', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 80),
|
||||
'SysSegBaseDest': ('ControlReg', 'uqw', 'MISCREG_SYSSEG_BASE(dest)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 75),
|
||||
'SysSegLimitDest': ('ControlReg', 'uqw', 'MISCREG_SYSSEG_LIMIT(dest)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 76),
|
||||
|
||||
'Mem': ('Mem', 'uqw', None, ('IsMemRef', 'IsLoad', 'IsStore'), 100)
|
||||
# Operands to get and set registers indexed by the operands of the
|
||||
# original instruction.
|
||||
'ControlDest': ('ControlReg', 'uqw', 'MISCREG_CR(dest)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 100),
|
||||
'ControlSrc1': ('ControlReg', 'uqw', 'MISCREG_CR(src1)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 101),
|
||||
'SegBaseDest': ('ControlReg', 'uqw', 'MISCREG_SEG_BASE(dest)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 102),
|
||||
'SegBaseSrc1': ('ControlReg', 'uqw', 'MISCREG_SEG_BASE(src1)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 103),
|
||||
'SegLimitDest': ('ControlReg', 'uqw', 'MISCREG_SEG_LIMIT(dest)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 104),
|
||||
'SegLimitSrc1': ('ControlReg', 'uqw', 'MISCREG_SEG_LIMIT(src1)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 105),
|
||||
'SegSelDest': ('ControlReg', 'uqw', 'MISCREG_SEG_SEL(dest)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 106),
|
||||
'SegSelSrc1': ('ControlReg', 'uqw', 'MISCREG_SEG_SEL(src1)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 107),
|
||||
'SegAttrDest': ('ControlReg', 'uqw', 'MISCREG_SEG_ATTR(dest)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 108),
|
||||
'SegAttrSrc1': ('ControlReg', 'uqw', 'MISCREG_SEG_ATTR(src1)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 109),
|
||||
|
||||
# Operands to access specific control registers directly.
|
||||
'EferOp': ('ControlReg', 'uqw', 'MISCREG_EFER', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 200),
|
||||
'CR4Op': ('ControlReg', 'uqw', 'MISCREG_CR4', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 201),
|
||||
'LDTRBase': ('ControlReg', 'uqw', 'MISCREG_TSL_BASE', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 202),
|
||||
'LDTRLimit': ('ControlReg', 'uqw', 'MISCREG_TSL_LIMIT', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 203),
|
||||
'LDTRSel': ('ControlReg', 'uqw', 'MISCREG_TSL', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 204),
|
||||
'GDTRBase': ('ControlReg', 'uqw', 'MISCREG_TSG_BASE', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 205),
|
||||
'GDTRLimit': ('ControlReg', 'uqw', 'MISCREG_TSG_LIMIT', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 206),
|
||||
'CSBase': ('ControlReg', 'udw', 'MISCREG_CS_EFF_BASE', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 207),
|
||||
'Mem': ('Mem', 'uqw', None, ('IsMemRef', 'IsLoad', 'IsStore'), 300)
|
||||
}};
|
||||
|
|
|
@ -154,12 +154,18 @@ let {{
|
|||
elif opType.tag == None or opType.size == None:
|
||||
raise Exception, "Problem parsing operand tag: %s" % opType.tag
|
||||
elif opType.tag == "C":
|
||||
# A control register indexed by the "reg" field
|
||||
env.addReg(ModRMRegIndex)
|
||||
Name += "_C"
|
||||
elif opType.tag == "D":
|
||||
# A debug register indexed by the "reg" field
|
||||
env.addReg(ModRMRegIndex)
|
||||
Name += "_D"
|
||||
elif opType.tag in ("G", "P", "S", "T", "V"):
|
||||
elif opType.tag == "S":
|
||||
# A segment selector register indexed by the "reg" field
|
||||
env.addReg(ModRMRegIndex)
|
||||
Name += "_S"
|
||||
elif opType.tag in ("G", "P", "T", "V"):
|
||||
# Use the "reg" field of the ModRM byte to select the register
|
||||
env.addReg(ModRMRegIndex)
|
||||
Name += "_R"
|
||||
|
|
|
@ -205,6 +205,31 @@ void MiscRegFile::setReg(int miscReg,
|
|||
}
|
||||
}
|
||||
}
|
||||
// These segments always actually use their bases, or in other words
|
||||
// their effective bases must stay equal to their actual bases.
|
||||
case MISCREG_FS:
|
||||
case MISCREG_GS:
|
||||
case MISCREG_HS:
|
||||
case MISCREG_TSL:
|
||||
case MISCREG_TSG:
|
||||
case MISCREG_TR:
|
||||
case MISCREG_IDTR:
|
||||
regVal[MISCREG_SEG_EFF_BASE(miscReg - MISCREG_SEG_SEL_BASE)] = val;
|
||||
break;
|
||||
// These segments ignore their bases in 64 bit mode.
|
||||
// their effective bases must stay equal to their actual bases.
|
||||
case MISCREG_ES:
|
||||
case MISCREG_CS:
|
||||
case MISCREG_SS:
|
||||
case MISCREG_DS:
|
||||
{
|
||||
Efer efer = regVal[MISCREG_EFER];
|
||||
SegAttr csAttr = regVal[MISCREG_CS_ATTR];
|
||||
if (!efer.lma || !csAttr.longMode) // Check for non 64 bit mode.
|
||||
regVal[MISCREG_SEG_EFF_BASE(miscReg -
|
||||
MISCREG_SEG_SEL_BASE)] = val;
|
||||
}
|
||||
break;
|
||||
}
|
||||
setRegNoEffect(miscReg, newVal);
|
||||
}
|
||||
|
|
|
@ -58,6 +58,7 @@
|
|||
#ifndef __ARCH_X86_MISCREGS_HH__
|
||||
#define __ARCH_X86_MISCREGS_HH__
|
||||
|
||||
#include "arch/x86/segmentregs.hh"
|
||||
#include "arch/x86/x86_traits.hh"
|
||||
#include "base/bitunion.hh"
|
||||
|
||||
|
@ -258,76 +259,83 @@ namespace X86ISA
|
|||
MISCREG_DS,
|
||||
MISCREG_FS,
|
||||
MISCREG_GS,
|
||||
MISCREG_INT, // This isn't actually used.
|
||||
MISCREG_HS,
|
||||
MISCREG_TSL,
|
||||
MISCREG_TSG,
|
||||
MISCREG_LS,
|
||||
MISCREG_MS,
|
||||
MISCREG_TR,
|
||||
MISCREG_IDTR,
|
||||
|
||||
// Hidden segment base field
|
||||
MISCREG_SEG_BASE_BASE = MISCREG_SEG_SEL_BASE + NumSegments,
|
||||
MISCREG_SEG_BASE_BASE = MISCREG_SEG_SEL_BASE + NUM_SEGMENTREGS,
|
||||
MISCREG_ES_BASE = MISCREG_SEG_BASE_BASE,
|
||||
MISCREG_CS_BASE,
|
||||
MISCREG_SS_BASE,
|
||||
MISCREG_DS_BASE,
|
||||
MISCREG_FS_BASE,
|
||||
MISCREG_GS_BASE,
|
||||
MISCREG_INT_BASE,
|
||||
MISCREG_HS_BASE,
|
||||
MISCREG_TSL_BASE,
|
||||
MISCREG_TSG_BASE,
|
||||
MISCREG_LS_BASE,
|
||||
MISCREG_MS_BASE,
|
||||
MISCREG_TR_BASE,
|
||||
MISCREG_IDTR_BASE,
|
||||
|
||||
// The effective segment base, ie what is actually added to an
|
||||
// address. In 64 bit mode this can be different from the above,
|
||||
// namely 0.
|
||||
MISCREG_SEG_EFF_BASE_BASE = MISCREG_SEG_BASE_BASE + NumSegments,
|
||||
MISCREG_SEG_EFF_BASE_BASE = MISCREG_SEG_BASE_BASE + NUM_SEGMENTREGS,
|
||||
MISCREG_ES_EFF_BASE = MISCREG_SEG_EFF_BASE_BASE,
|
||||
MISCREG_CS_EFF_BASE,
|
||||
MISCREG_SS_EFF_BASE,
|
||||
MISCREG_DS_EFF_BASE,
|
||||
MISCREG_FS_EFF_BASE,
|
||||
MISCREG_GS_EFF_BASE,
|
||||
MISCREG_INT_EFF_BASE,
|
||||
MISCREG_HS_EFF_BASE,
|
||||
MISCREG_TSL_EFF_BASE,
|
||||
MISCREG_TSG_EFF_BASE,
|
||||
MISCREG_LS_EFF_BASE,
|
||||
MISCREG_MS_EFF_BASE,
|
||||
MISCREG_TR_EFF_BASE,
|
||||
MISCREG_IDTR_EFF_BASE,
|
||||
|
||||
// Hidden segment limit field
|
||||
MISCREG_SEG_LIMIT_BASE = MISCREG_SEG_EFF_BASE_BASE + NumSegments,
|
||||
MISCREG_SEG_LIMIT_BASE = MISCREG_SEG_EFF_BASE_BASE + NUM_SEGMENTREGS,
|
||||
MISCREG_ES_LIMIT = MISCREG_SEG_LIMIT_BASE,
|
||||
MISCREG_CS_LIMIT,
|
||||
MISCREG_SS_LIMIT,
|
||||
MISCREG_DS_LIMIT,
|
||||
MISCREG_FS_LIMIT,
|
||||
MISCREG_GS_LIMIT,
|
||||
MISCREG_INT_LIMIT, // This isn't actually used.
|
||||
MISCREG_HS_LIMIT,
|
||||
MISCREG_TSL_LIMIT,
|
||||
MISCREG_TSG_LIMIT,
|
||||
MISCREG_LS_LIMIT,
|
||||
MISCREG_MS_LIMIT,
|
||||
MISCREG_TR_LIMIT,
|
||||
MISCREG_IDTR_LIMIT,
|
||||
|
||||
// Hidden segment limit attributes
|
||||
MISCREG_SEG_ATTR_BASE = MISCREG_SEG_LIMIT_BASE + NumSegments,
|
||||
MISCREG_SEG_ATTR_BASE = MISCREG_SEG_LIMIT_BASE + NUM_SEGMENTREGS,
|
||||
MISCREG_ES_ATTR = MISCREG_SEG_ATTR_BASE,
|
||||
MISCREG_CS_ATTR,
|
||||
MISCREG_SS_ATTR,
|
||||
MISCREG_DS_ATTR,
|
||||
MISCREG_FS_ATTR,
|
||||
MISCREG_GS_ATTR,
|
||||
MISCREG_INT_ATTR, // This isn't actually used.
|
||||
|
||||
// System segment selectors
|
||||
MISCREG_SYSSEG_SEL_BASE = MISCREG_SEG_ATTR_BASE + NumSegments,
|
||||
MISCREG_LDTR = MISCREG_SYSSEG_SEL_BASE,
|
||||
MISCREG_TR,
|
||||
|
||||
// Hidden system segment base field
|
||||
MISCREG_SYSSEG_BASE_BASE = MISCREG_SYSSEG_SEL_BASE + NumSysSegments,
|
||||
MISCREG_LDTR_BASE = MISCREG_SYSSEG_BASE_BASE,
|
||||
MISCREG_TR_BASE,
|
||||
MISCREG_GDTR_BASE,
|
||||
MISCREG_IDTR_BASE,
|
||||
|
||||
// Hidden system segment limit field
|
||||
MISCREG_SYSSEG_LIMIT_BASE = MISCREG_SYSSEG_BASE_BASE + NumSysSegments,
|
||||
MISCREG_LDTR_LIMIT = MISCREG_SYSSEG_LIMIT_BASE,
|
||||
MISCREG_TR_LIMIT,
|
||||
MISCREG_GDTR_LIMIT,
|
||||
MISCREG_IDTR_LIMIT,
|
||||
|
||||
// Hidden system segment attribute field
|
||||
MISCREG_SYSSEG_ATTR_BASE = MISCREG_SYSSEG_LIMIT_BASE + NumSysSegments,
|
||||
MISCREG_LDTR_ATTR = MISCREG_SYSSEG_ATTR_BASE,
|
||||
MISCREG_HS_ATTR,
|
||||
MISCREG_TSL_ATTR,
|
||||
MISCREG_TSG_ATTR,
|
||||
MISCREG_LS_ATTR,
|
||||
MISCREG_MS_ATTR,
|
||||
MISCREG_TR_ATTR,
|
||||
MISCREG_IDTR_ATTR,
|
||||
|
||||
// Floating point control registers
|
||||
MISCREG_X87_TOP = MISCREG_SYSSEG_ATTR_BASE + NumSysSegments,
|
||||
MISCREG_X87_TOP =
|
||||
MISCREG_SEG_ATTR_BASE + NUM_SEGMENTREGS,
|
||||
|
||||
//XXX Add "Model-Specific Registers"
|
||||
|
||||
|
@ -436,30 +444,6 @@ namespace X86ISA
|
|||
return (MiscRegIndex)(MISCREG_SEG_ATTR_BASE + index);
|
||||
}
|
||||
|
||||
static inline MiscRegIndex
|
||||
MISCREG_SYSSEG_SEL(int index)
|
||||
{
|
||||
return (MiscRegIndex)(MISCREG_SYSSEG_SEL_BASE + index);
|
||||
}
|
||||
|
||||
static inline MiscRegIndex
|
||||
MISCREG_SYSSEG_BASE(int index)
|
||||
{
|
||||
return (MiscRegIndex)(MISCREG_SYSSEG_BASE_BASE + index);
|
||||
}
|
||||
|
||||
static inline MiscRegIndex
|
||||
MISCREG_SYSSEG_LIMIT(int index)
|
||||
{
|
||||
return (MiscRegIndex)(MISCREG_SYSSEG_LIMIT_BASE + index);
|
||||
}
|
||||
|
||||
static inline MiscRegIndex
|
||||
MISCREG_SYSSEG_ATTR(int index)
|
||||
{
|
||||
return (MiscRegIndex)(MISCREG_SYSSEG_ATTR_BASE + index);
|
||||
}
|
||||
|
||||
/**
|
||||
* A type to describe the condition code bits of the RFLAGS register,
|
||||
* plus two flags, EZF and ECF, which are only visible to microcode.
|
||||
|
@ -729,6 +713,10 @@ namespace X86ISA
|
|||
* Segment Selector
|
||||
*/
|
||||
BitUnion64(SegSelector)
|
||||
// The following bitfield is not defined in the ISA, but it's useful
|
||||
// when checking selectors in larger data types to make sure they
|
||||
// aren't too large.
|
||||
Bitfield<63, 3> esi; // Extended selector
|
||||
Bitfield<15, 3> si; // Selector Index
|
||||
Bitfield<2> ti; // Table Indicator
|
||||
Bitfield<1, 0> rpl; // Requestor Privilege Level
|
||||
|
|
|
@ -68,19 +68,18 @@ namespace X86ISA
|
|||
SEGMENT_REG_DS,
|
||||
SEGMENT_REG_FS,
|
||||
SEGMENT_REG_GS,
|
||||
SEGMENT_REG_INT,
|
||||
|
||||
NUM_SEGMENTREGS
|
||||
};
|
||||
|
||||
enum SysSegmentRegIndex
|
||||
{
|
||||
SYS_SEGMENT_REG_LDTR,
|
||||
SEGMENT_REG_HS, // Temporary descriptor
|
||||
SEGMENT_REG_TSL, // Local descriptor table
|
||||
SEGMENT_REG_TSG, // Global descriptor table
|
||||
SEGMENT_REG_LS, // Flat segment
|
||||
SEGMENT_REG_MS, // Emulation memory
|
||||
// These shouldn't be used directly in a load or store since they
|
||||
// are likely accessed in other ways in a real machine. For instance,
|
||||
// they may be loaded into the temporary segment register on demand.
|
||||
SYS_SEGMENT_REG_TR,
|
||||
SYS_SEGMENT_REG_GDTR,
|
||||
SYS_SEGMENT_REG_IDTR,
|
||||
|
||||
NUM_SYSSEGMENTREGS
|
||||
NUM_SEGMENTREGS
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -176,14 +176,14 @@ TLB::translate(RequestPtr &req, ThreadContext *tc, bool write, bool execute)
|
|||
uint32_t flags = req->getFlags();
|
||||
bool storeCheck = flags & StoreCheck;
|
||||
|
||||
int seg = flags & mask(3);
|
||||
int seg = flags & mask(4);
|
||||
|
||||
//XXX Junk code to surpress the warning
|
||||
if (storeCheck);
|
||||
|
||||
// If this is true, we're dealing with a request to read an internal
|
||||
// value.
|
||||
if (seg == SEGMENT_REG_INT) {
|
||||
if (seg == SEGMENT_REG_MS) {
|
||||
DPRINTF(TLB, "Addresses references internal memory.\n");
|
||||
Addr prefix = vaddr & IntAddrPrefixMask;
|
||||
if (prefix == IntAddrPrefixCPUID) {
|
||||
|
|
|
@ -143,16 +143,16 @@ void initCPU(ThreadContext *tc, int cpuId)
|
|||
tc->readMiscReg(MISCREG_CS_BASE));
|
||||
tc->setNextPC(tc->readPC() + sizeof(MachInst));
|
||||
|
||||
tc->setMiscReg(MISCREG_GDTR_BASE, 0);
|
||||
tc->setMiscReg(MISCREG_GDTR_LIMIT, 0xffff);
|
||||
tc->setMiscReg(MISCREG_TSG_BASE, 0);
|
||||
tc->setMiscReg(MISCREG_TSG_LIMIT, 0xffff);
|
||||
|
||||
tc->setMiscReg(MISCREG_IDTR_BASE, 0);
|
||||
tc->setMiscReg(MISCREG_IDTR_LIMIT, 0xffff);
|
||||
|
||||
tc->setMiscReg(MISCREG_LDTR, 0);
|
||||
tc->setMiscReg(MISCREG_LDTR_BASE, 0);
|
||||
tc->setMiscReg(MISCREG_LDTR_LIMIT, 0xffff);
|
||||
tc->setMiscReg(MISCREG_LDTR_ATTR, 0);
|
||||
tc->setMiscReg(MISCREG_TSL, 0);
|
||||
tc->setMiscReg(MISCREG_TSL_BASE, 0);
|
||||
tc->setMiscReg(MISCREG_TSL_LIMIT, 0xffff);
|
||||
tc->setMiscReg(MISCREG_TSL_ATTR, 0);
|
||||
|
||||
tc->setMiscReg(MISCREG_TR, 0);
|
||||
tc->setMiscReg(MISCREG_TR_BASE, 0);
|
||||
|
@ -306,8 +306,8 @@ void startupCPU(ThreadContext *tc, int cpuId)
|
|||
uint64_t csDescVal = csDesc;
|
||||
physPort->writeBlob(GDTBase, (uint8_t *)(&csDescVal), 8);
|
||||
|
||||
tc->setMiscReg(MISCREG_GDTR_BASE, GDTBase);
|
||||
tc->setMiscReg(MISCREG_GDTR_LIMIT, 0xF);
|
||||
tc->setMiscReg(MISCREG_TSG_BASE, GDTBase);
|
||||
tc->setMiscReg(MISCREG_TSG_LIMIT, 0xF);
|
||||
|
||||
/*
|
||||
* Identity map the first 4GB of memory. In order to map this region
|
||||
|
|
Loading…
Reference in a new issue