summaryrefslogtreecommitdiff
path: root/src/arch/x86
diff options
context:
space:
mode:
Diffstat (limited to 'src/arch/x86')
-rw-r--r--src/arch/x86/isa/microasm.isa5
-rw-r--r--src/arch/x86/isa/microops/regop.isa42
-rw-r--r--src/arch/x86/isa/operands.isa3
3 files changed, 48 insertions, 2 deletions
diff --git a/src/arch/x86/isa/microasm.isa b/src/arch/x86/isa/microasm.isa
index 18abdf09b..735a7722c 100644
--- a/src/arch/x86/isa/microasm.isa
+++ b/src/arch/x86/isa/microasm.isa
@@ -81,6 +81,11 @@ let {{
for letter in ("C", "D", "E", "F", "G", "S"):
assembler.symbols["%ss" % letter.lower()] = "SEGMENT_REG_%sS" % letter
+ # Add in symbols for the various checks of segment selectors.
+ for check in ("NoCheck", "CSCheck", "CallGateCheck",
+ "SSCheck", "IretCheck", "IntCSCheck"):
+ assembler.symbols[check] = "Seg%s" % check
+
for reg in ("TR", "IDTR"):
assembler.symbols[reg.lower()] = "SYS_SEGMENT_REG_%s" % reg
diff --git a/src/arch/x86/isa/microops/regop.isa b/src/arch/x86/isa/microops/regop.isa
index 48aecf138..6bd26608e 100644
--- a/src/arch/x86/isa/microops/regop.isa
+++ b/src/arch/x86/isa/microops/regop.isa
@@ -231,6 +231,11 @@ output header {{
void
divide(uint64_t dividend, uint64_t divisor,
uint64_t &quotient, uint64_t &remainder);
+
+ enum SegmentSelectorCheck {
+ SegNoCheck, SegCSCheck, SegCallGateCheck,
+ SegSSCheck, SegIretCheck, SegIntCSCheck
+ };
}};
output decoder {{
@@ -1018,11 +1023,46 @@ let {{
DestReg = SegSelSrc1;
'''
- class Chks(SegOp):
+ class Chks(RegOp):
+ def __init__(self, dest, src1, src2=0,
+ flags=None, dataSize="env.dataSize"):
+ super(Chks, self).__init__(dest,
+ src1, src2, flags, dataSize)
code = '''
// The selector is in source 1 and can be at most 16 bits.
SegSelector selector = psrc1;
+ switch (imm8)
+ {
+ case SegNoCheck:
+ break;
+ case SegCSCheck:
+ panic("CS checks for far calls/jumps not implemented.\\n");
+ break;
+ case SegCallGateCheck:
+ panic("CS checks for far calls/jumps through call gates"
+ "not implemented.\\n");
+ break;
+ case SegSSCheck:
+ panic("SS selector checks not implemented.\\n");
+ break;
+ case SegIretCheck:
+ {
+ SegAttr csAttr = CSAttr;
+ if (!selector.si && !selector.ti)
+ return new GeneralProtection(psrc1 & 0xFFFF);
+ if (selector.rpl < csAttr.dpl)
+ return new GeneralProtection(psrc1 & 0xFFFF);
+ break;
+ }
+ case SegIntCSCheck:
+ panic("CS selector checks for interrupts and exceptions"
+ "not implemented.\\n");
+ break;
+ default:
+ panic("Undefined segment check type.\\n");
+ }
+
// Compute the address of the descriptor and set DestReg to it.
if (selector.ti) {
// A descriptor in the LDT
diff --git a/src/arch/x86/isa/operands.isa b/src/arch/x86/isa/operands.isa
index b48e8759f..f002b2cea 100644
--- a/src/arch/x86/isa/operands.isa
+++ b/src/arch/x86/isa/operands.isa
@@ -149,6 +149,7 @@ def operands {{
'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),
- 'TscOp': ('ControlReg', 'udw', 'MISCREG_TSC', (None, None, ['IsSerializeAfter', 'IsSerializing', 'IsNonSpeculative']), 208),
+ 'CSAttr': ('ControlReg', 'udw', 'MISCREG_CS_ATTR', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 208),
+ 'TscOp': ('ControlReg', 'udw', 'MISCREG_TSC', (None, None, ['IsSerializeAfter', 'IsSerializing', 'IsNonSpeculative']), 209),
'Mem': ('Mem', 'uqw', None, ('IsMemRef', 'IsLoad', 'IsStore'), 300)
}};