From fa7c81c6df5fdc1a17ffebbf431cb57ac84d79d0 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Thu, 12 Jun 2008 00:50:10 -0400 Subject: [PATCH] X86: Change what the microop chks does. Instead of computing the segment descriptor address, this now checks if a selector value/descriptor are legal for a particular purpose. --- src/arch/x86/isa/microasm.isa | 5 ++++ src/arch/x86/isa/microops/regop.isa | 42 ++++++++++++++++++++++++++++- src/arch/x86/isa/operands.isa | 3 ++- 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 "ient, 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) }}; -- 2.30.2