summaryrefslogtreecommitdiff
path: root/src/arch/x86/regs
diff options
context:
space:
mode:
authorGabe Black <gabeblack@google.com>2018-01-29 17:49:07 -0800
committerGabe Black <gabeblack@google.com>2018-03-15 00:54:42 +0000
commit8b66b56b12664211e76fc1bc880f1a13cb88bc06 (patch)
tree268a90b07c4dd25ff8406a89fe0d6a5c06fc7417 /src/arch/x86/regs
parent497ebfe98578b71d22f979b848c4b873f05ec6ee (diff)
downloadgem5-8b66b56b12664211e76fc1bc880f1a13cb88bc06.tar.xz
x86: Add bitfields which can gather/scatter bases and limits.
Add bitfields which can gather/scatter base and limit fields within "normal" segment descriptors, and in TSS descriptors which have the same bitfields in the same positions for those two values. This centralizes the code which manages those bitfields and makes it less likely that a local implementation will be buggy. Change-Id: I9809aa626fc31388595c3d3b225c25a0ec6a1275 Reviewed-on: https://gem5-review.googlesource.com/7661 Reviewed-by: Gabe Black <gabeblack@google.com> Maintainer: Gabe Black <gabeblack@google.com>
Diffstat (limited to 'src/arch/x86/regs')
-rw-r--r--src/arch/x86/regs/misc.hh49
1 files changed, 49 insertions, 0 deletions
diff --git a/src/arch/x86/regs/misc.hh b/src/arch/x86/regs/misc.hh
index 48f7d974d..3f3730e32 100644
--- a/src/arch/x86/regs/misc.hh
+++ b/src/arch/x86/regs/misc.hh
@@ -43,6 +43,7 @@
#include "arch/x86/regs/segment.hh"
#include "arch/x86/x86_traits.hh"
#include "base/bitunion.hh"
+#include "base/logging.hh"
//These get defined in some system headers (at least termbits.h). That confuses
//things here significantly.
@@ -867,9 +868,54 @@ namespace X86ISA
* Segment Descriptors
*/
+ class SegDescriptorBase
+ {
+ public:
+ uint32_t
+ getter(const uint64_t &storage) const
+ {
+ return (bits(storage, 63, 56) << 24) | bits(storage, 39, 16);
+ }
+
+ void
+ setter(uint64_t &storage, uint32_t base)
+ {
+ replaceBits(storage, 63, 56, bits(base, 31, 24));
+ replaceBits(storage, 39, 16, bits(base, 23, 0));
+ }
+ };
+
+ class SegDescriptorLimit
+ {
+ public:
+ uint32_t
+ getter(const uint64_t &storage) const
+ {
+ uint32_t limit = (bits(storage, 51, 48) << 16) |
+ bits(storage, 15, 0);
+ if (bits(storage, 55))
+ limit = (limit << 12) | mask(12);
+ return limit;
+ }
+
+ void
+ setter(uint64_t &storage, uint32_t limit)
+ {
+ bool g = (bits(limit, 31, 24) != 0);
+ panic_if(g && bits(limit, 11, 0) != mask(12),
+ "Inlimitid segment limit %#x", limit);
+ if (g)
+ limit = limit >> 12;
+ replaceBits(storage, 51, 48, bits(limit, 23, 16));
+ replaceBits(storage, 15, 0, bits(limit, 15, 0));
+ replaceBits(storage, 55, g ? 1 : 0);
+ }
+ };
+
BitUnion64(SegDescriptor)
Bitfield<63, 56> baseHigh;
Bitfield<39, 16> baseLow;
+ BitfieldType<SegDescriptorBase> base;
Bitfield<55> g; // Granularity
Bitfield<54> d; // Default Operand Size
Bitfield<54> b; // Default Operand Size
@@ -877,6 +923,7 @@ namespace X86ISA
Bitfield<52> avl; // Available To Software
Bitfield<51, 48> limitHigh;
Bitfield<15, 0> limitLow;
+ BitfieldType<SegDescriptorLimit> limit;
Bitfield<47> p; // Present
Bitfield<46, 45> dpl; // Descriptor Privilege-Level
Bitfield<44> s; // System
@@ -904,10 +951,12 @@ namespace X86ISA
BitUnion64(TSSlow)
Bitfield<63, 56> baseHigh;
Bitfield<39, 16> baseLow;
+ BitfieldType<SegDescriptorBase> base;
Bitfield<55> g; // Granularity
Bitfield<52> avl; // Available To Software
Bitfield<51, 48> limitHigh;
Bitfield<15, 0> limitLow;
+ BitfieldType<SegDescriptorLimit> limit;
Bitfield<47> p; // Present
Bitfield<46, 45> dpl; // Descriptor Privilege-Level
SubBitUnion(type, 43, 40)