1033c1033,1035
< SegSelector selector = psrc1;
---
> SegSelector selector = DestReg;
> SegDescriptor desc = SrcReg1;
> HandyM5Reg m5reg = M5Reg;
1047c1049,1062
< panic("SS selector checks not implemented.\\n");
---
> if (selector.si || selector.ti) {
> if (!desc.p) {
> //FIXME This needs to also push the selector.
> return new StackFault;
> }
> } else {
> if ((m5reg.mode != SixtyFourBitMode || m5reg.cpl == 3) ||
> !(desc.s == 1 &&
> desc.type.codeOrData == 0 && desc.type.w) ||
> (desc.dpl != m5reg.cpl) ||
> (selector.rpl != m5reg.cpl)) {
> return new GeneralProtection(psrc1 & 0xFFFF);
> }
> }
1051,1052c1066,1070
< SegAttr csAttr = CSAttr;
< if (!selector.si && !selector.ti)
---
> if ((!selector.si && !selector.ti) ||
> (selector.rpl < m5reg.cpl) ||
> !(desc.s == 1 && desc.type.codeOrData == 1) ||
> (!desc.type.c && desc.dpl != selector.rpl) ||
> (desc.type.c && desc.dpl > selector.rpl))
1054,1055c1072,1073
< if (selector.rpl < csAttr.dpl)
< return new GeneralProtection(psrc1 & 0xFFFF);
---
> if (!desc.p)
> return new SegmentNotPresent;
1065,1079d1082
<
< // Compute the address of the descriptor and set DestReg to it.
< if (selector.ti) {
< // A descriptor in the LDT
< Addr target = (selector.si << 3) + LDTRBase;
< if (!LDTRSel || (selector.si << 3) + dataSize > LDTRLimit)
< fault = new GeneralProtection(selector & mask(16));
< DestReg = target;
< } else {
< // A descriptor in the GDT
< Addr target = (selector.si << 3) + GDTRBase;
< if ((selector.si << 3) + dataSize > GDTRLimit)
< fault = new GeneralProtection(selector & mask(16));
< DestReg = target;
< }
1111,1114c1114,1143
< SegAttr attr = 0;
< attr.dpl = desc.dpl;
< attr.defaultSize = desc.d;
< if (!desc.s) {
---
> SegSelector selector = SrcReg2;
> if (selector.si || selector.ti) {
> SegAttr attr = 0;
> attr.dpl = desc.dpl;
> attr.defaultSize = desc.d;
> if (!desc.s) {
> SegBaseDest = SegBaseDest;
> SegLimitDest = SegLimitDest;
> SegAttrDest = SegAttrDest;
> panic("System segment encountered.\\n");
> } else {
> if (!desc.p)
> panic("Segment not present.\\n");
> if (desc.type.codeOrData) {
> attr.readable = desc.type.r;
> attr.longMode = desc.l;
> } else {
> attr.expandDown = desc.type.e;
> attr.readable = 1;
> attr.writable = desc.type.w;
> }
> Addr base = desc.baseLow | (desc.baseHigh << 24);
> Addr limit = desc.limitLow | (desc.limitHigh << 16);
> if (desc.g)
> limit = (limit << 12) | mask(12);
> SegBaseDest = base;
> SegLimitDest = limit;
> SegAttrDest = attr;
> }
> } else {
1118,1136d1146
< panic("System segment encountered.\\n");
< } else {
< if (!desc.p)
< panic("Segment not present.\\n");
< if (desc.type.codeOrData) {
< attr.readable = desc.type.r;
< attr.longMode = desc.l;
< } else {
< attr.expandDown = desc.type.e;
< attr.readable = 1;
< attr.writable = desc.type.w;
< }
< Addr base = desc.baseLow | (desc.baseHigh << 24);
< Addr limit = desc.limitLow | (desc.limitHigh << 16);
< if (desc.g)
< limit = (limit << 12) | mask(12);
< SegBaseDest = base;
< SegLimitDest = limit;
< SegAttrDest = attr;