int reiserfs_on_disk_super_in_proc( char *buffer, char **start, off_t offset, int count, int *eof, void *data ) { struct super_block *sb; struct reiserfs_sb_info *sb_info; struct reiserfs_super_block *rs; int hash_code; int len = 0; sb = procinfo_prologue( ( kdev_t ) ( long ) data ); if( sb == NULL ) return -ENOENT; sb_info = &sb->u.reiserfs_sb; rs = sb_info -> s_rs; hash_code = DFL( s_hash_function_code ); len += sprintf( &buffer[ len ], "block_count: \t%i\n" "free_blocks: \t%i\n" "root_block: \t%i\n" "blocksize: \t%i\n" "oid_maxsize: \t%i\n" "oid_cursize: \t%i\n" "umount_state: \t%i\n" "magic: \t%10.10s\n" "fs_state: \t%i\n" "hash: \t%s\n" "tree_height: \t%i\n" "bmap_nr: \t%i\n" "version: \t%i\n" "reserved_for_journal: \t%i\n" "inode_generation: \t%i\n" "flags: \t%x[%s]\n", DFL( s_block_count ), DFL( s_free_blocks ), DFL( s_root_block ), DF( s_blocksize ), DF( s_oid_maxsize ), DF( s_oid_cursize ), DF( s_umount_state ), rs -> s_v1.s_magic, DF( s_fs_state ), hash_code == TEA_HASH ? "tea" : ( hash_code == YURA_HASH ) ? "rupasov" : ( hash_code == R5_HASH ) ? "r5" : ( hash_code == UNSET_HASH ) ? "unset" : "unknown", DF( s_tree_height ), DF( s_bmap_nr ), DF( s_version ), DF( s_reserved_for_journal ), DPL( s_inode_generation ), DPL( s_flags ), (DPL( s_flags ) & reiserfs_attrs_cleared ? "attrs_cleared" : "" )); procinfo_epilogue( sb ); return reiserfs_proc_tail( len, buffer, start, offset, count, eof ); }
static void i80286_data_descriptor_full(i80286_state *cpustate, int reg, UINT16 selector, int cpl, UINT32 trap, UINT16 offset, int size) { if (PM) { UINT16 desc[3]; UINT8 r; UINT32 addr; /* selector format 15..3 number/address in descriptor table 2: 0 global, 1 local descriptor table 1,0: requested privileg level must be higher or same as current privileg level in code selector */ if ((reg != SS) && !IDXTBL(selector)) { cpustate->sregs[reg]=0; cpustate->limit[reg]=0; cpustate->base[reg]=0; cpustate->rights[reg]=0; cpustate->valid[reg]=0; return; } if ((addr = i80286_selector_address(cpustate,selector)) == -1) throw trap; desc[0] = ReadWord(addr); desc[1] = ReadWord(addr+2); desc[2] = ReadWord(addr+4); r = RIGHTS(desc); if (!SEGDESC(r)) throw trap; if (reg == SS) { if (!IDXTBL(selector)) throw trap; if (DPL(r)!=cpl) throw trap; if (RPL(selector)!=cpl) throw trap; if (!RW(r) || CODE(r)) throw trap; if (!PRES(r)) throw TRAP(STACK_FAULT,(IDXTBL(selector)+(trap&1))); } else { if ((DPL(r) < PMAX(cpl,RPL(selector))) && (!CODE(r) || (CODE(r) && !CONF(r)))) throw trap; if (CODE(r) && !READ(r)) throw trap; if (!PRES(r)) throw TRAP(SEG_NOT_PRESENT,(IDXTBL(selector)+(trap&1))); } if (offset+size) { if ((CODE(r) || !EXPDOWN(r)) && ((offset+size-1) > LIMIT(desc))) throw (reg==SS)?TRAP(STACK_FAULT,(trap&1)):trap; if (!CODE(r) && EXPDOWN(r) && ((offset <= LIMIT(desc)) || ((offset+size-1) > 0xffff))) throw (reg==SS)?TRAP(STACK_FAULT,(trap&1)):trap; } SET_ACC(desc); WriteWord(addr+4, desc[2]); cpustate->sregs[reg]=selector; cpustate->limit[reg]=LIMIT(desc); cpustate->base[reg]=BASE(desc); cpustate->rights[reg]=RIGHTS(desc); } else { cpustate->sregs[reg]=selector; cpustate->base[reg]=selector<<4; } cpustate->valid[reg]=1; }
struct POINT GetInflectionPoint(int LorR) { int z; struct POINT tmpReturn; int tmp = 0; int max = 0; tmpReturn = edgePoint[LorR][edgeStartZ[LorR]]; edgeLimitLines[LorR] = LPP(crctr_BTX[LorR].head, crctr_BTX[LorR].tail); for (z = edgeStartZ[LorR]; z < C_activePoint[LorR]; z++) { tmp = DPL(edgePoint[LorR][z],edgeLimitLines[LorR]); tmp = ABS(tmp); if(tmp > max) { max = tmp; tmpReturn = edgePoint[LorR][z]; } } return tmpReturn; }
SCORE NWDASimple(const ProfPos *PA, unsigned uLengthA, const ProfPos *PB, unsigned uLengthB, PWPath &Path) { assert(uLengthB > 0 && uLengthA > 0); const unsigned uPrefixCountA = uLengthA + 1; const unsigned uPrefixCountB = uLengthB + 1; // Allocate DP matrices const size_t LM = uPrefixCountA*uPrefixCountB; SCORE *DPL_ = new SCORE[LM]; SCORE *DPM_ = new SCORE[LM]; SCORE *DPD_ = new SCORE[LM]; SCORE *DPE_ = new SCORE[LM]; SCORE *DPI_ = new SCORE[LM]; SCORE *DPJ_ = new SCORE[LM]; char *TBM_ = new char[LM]; char *TBD_ = new char[LM]; char *TBE_ = new char[LM]; char *TBI_ = new char[LM]; char *TBJ_ = new char[LM]; memset(TBM_, '?', LM); memset(TBD_, '?', LM); memset(TBE_, '?', LM); memset(TBI_, '?', LM); memset(TBJ_, '?', LM); DPM(0, 0) = 0; DPD(0, 0) = MINUS_INFINITY; DPE(0, 0) = MINUS_INFINITY; DPI(0, 0) = MINUS_INFINITY; DPJ(0, 0) = MINUS_INFINITY; DPM(1, 0) = MINUS_INFINITY; DPD(1, 0) = PA[0].m_scoreGapOpen; DPE(1, 0) = PA[0].m_scoreGapOpen2; TBD(1, 0) = 'D'; TBE(1, 0) = 'E'; DPI(1, 0) = MINUS_INFINITY; DPJ(1, 0) = MINUS_INFINITY; DPM(0, 1) = MINUS_INFINITY; DPD(0, 1) = MINUS_INFINITY; DPE(0, 1) = MINUS_INFINITY; DPI(0, 1) = PB[0].m_scoreGapOpen; DPJ(0, 1) = PB[0].m_scoreGapOpen2; TBI(0, 1) = 'I'; TBJ(0, 1) = 'J'; // Empty prefix of B is special case for (unsigned uPrefixLengthA = 2; uPrefixLengthA < uPrefixCountA; ++uPrefixLengthA) { DPM(uPrefixLengthA, 0) = MINUS_INFINITY; DPD(uPrefixLengthA, 0) = DPD(uPrefixLengthA - 1, 0) + g_scoreGapExtend.get(); DPE(uPrefixLengthA, 0) = DPE(uPrefixLengthA - 1, 0) + g_scoreGapExtend2.get(); TBD(uPrefixLengthA, 0) = 'D'; TBE(uPrefixLengthA, 0) = 'E'; DPI(uPrefixLengthA, 0) = MINUS_INFINITY; DPJ(uPrefixLengthA, 0) = MINUS_INFINITY; } // Empty prefix of A is special case for (unsigned uPrefixLengthB = 2; uPrefixLengthB < uPrefixCountB; ++uPrefixLengthB) { DPM(0, uPrefixLengthB) = MINUS_INFINITY; DPD(0, uPrefixLengthB) = MINUS_INFINITY; DPE(0, uPrefixLengthB) = MINUS_INFINITY; DPI(0, uPrefixLengthB) = DPI(0, uPrefixLengthB - 1) + g_scoreGapExtend.get(); DPJ(0, uPrefixLengthB) = DPJ(0, uPrefixLengthB - 1) + g_scoreGapExtend2.get(); TBI(0, uPrefixLengthB) = 'I'; TBJ(0, uPrefixLengthB) = 'J'; } // Special case to agree with NWFast, no D-I transitions so... DPD(uLengthA, 0) = MINUS_INFINITY; DPE(uLengthA, 0) = MINUS_INFINITY; // DPI(0, uLengthB) = MINUS_INFINITY; // DPJ(0, uLengthB) = MINUS_INFINITY; // ============ // Main DP loop // ============ SCORE scoreGapCloseB = MINUS_INFINITY; SCORE scoreGapClose2B = MINUS_INFINITY; for (unsigned uPrefixLengthB = 1; uPrefixLengthB < uPrefixCountB; ++uPrefixLengthB) { const ProfPos &PPB = PB[uPrefixLengthB - 1]; SCORE scoreGapCloseA = MINUS_INFINITY; SCORE scoreGapClose2A = MINUS_INFINITY; for (unsigned uPrefixLengthA = 1; uPrefixLengthA < uPrefixCountA; ++uPrefixLengthA) { const ProfPos &PPA = PA[uPrefixLengthA - 1]; { // Match M=LetterA+LetterB SCORE scoreLL = ScoreProfPos2(PPA, PPB); DPL(uPrefixLengthA, uPrefixLengthB) = scoreLL; SCORE scoreMM = DPM(uPrefixLengthA-1, uPrefixLengthB-1); SCORE scoreDM = DPD(uPrefixLengthA-1, uPrefixLengthB-1) + scoreGapCloseA; SCORE scoreEM = DPE(uPrefixLengthA-1, uPrefixLengthB-1) + scoreGapClose2A; SCORE scoreIM = DPI(uPrefixLengthA-1, uPrefixLengthB-1) + scoreGapCloseB; SCORE scoreJM = DPJ(uPrefixLengthA-1, uPrefixLengthB-1) + scoreGapClose2B; SCORE scoreBest; if (scoreMM >= scoreDM && scoreMM >= scoreEM && scoreMM >= scoreIM && scoreMM >= scoreJM) { scoreBest = scoreMM; TBM(uPrefixLengthA, uPrefixLengthB) = 'M'; } else if (scoreDM >= scoreMM && scoreDM >= scoreEM && scoreDM >= scoreIM && scoreDM >= scoreJM) { scoreBest = scoreDM; TBM(uPrefixLengthA, uPrefixLengthB) = 'D'; } else if (scoreEM >= scoreMM && scoreEM >= scoreDM && scoreEM >= scoreIM && scoreEM >= scoreJM) { scoreBest = scoreEM; TBM(uPrefixLengthA, uPrefixLengthB) = 'E'; } else if (scoreIM >= scoreMM && scoreIM >= scoreDM && scoreIM >= scoreEM && scoreIM >= scoreJM) { scoreBest = scoreIM; TBM(uPrefixLengthA, uPrefixLengthB) = 'I'; } else { assert(scoreJM >= scoreMM && scoreJM >= scoreDM && scoreJM >= scoreEM && scoreJM >= scoreIM); scoreBest = scoreJM; TBM(uPrefixLengthA, uPrefixLengthB) = 'J'; } DPM(uPrefixLengthA, uPrefixLengthB) = scoreBest + scoreLL; } { // Delete D=LetterA+GapB SCORE scoreMD = DPM(uPrefixLengthA-1, uPrefixLengthB) + PA[uPrefixLengthA-1].m_scoreGapOpen; SCORE scoreDD = DPD(uPrefixLengthA-1, uPrefixLengthB) + g_scoreGapExtend.get(); SCORE scoreBest; if (scoreMD >= scoreDD) { scoreBest = scoreMD; TBD(uPrefixLengthA, uPrefixLengthB) = 'M'; } else { assert(scoreDD >= scoreMD); scoreBest = scoreDD; TBD(uPrefixLengthA, uPrefixLengthB) = 'D'; } DPD(uPrefixLengthA, uPrefixLengthB) = scoreBest; } { // Delete E=LetterA+GapB SCORE scoreME = DPM(uPrefixLengthA-1, uPrefixLengthB) + PA[uPrefixLengthA-1].m_scoreGapOpen2; SCORE scoreEE = DPE(uPrefixLengthA-1, uPrefixLengthB) + g_scoreGapExtend2.get(); SCORE scoreBest; if (scoreME >= scoreEE) { scoreBest = scoreME; TBE(uPrefixLengthA, uPrefixLengthB) = 'M'; } else { assert(scoreEE >= scoreME); scoreBest = scoreEE; TBE(uPrefixLengthA, uPrefixLengthB) = 'E'; } DPE(uPrefixLengthA, uPrefixLengthB) = scoreBest; } // Insert I=GapA+LetterB { SCORE scoreMI = DPM(uPrefixLengthA, uPrefixLengthB-1) + PB[uPrefixLengthB - 1].m_scoreGapOpen; SCORE scoreII = DPI(uPrefixLengthA, uPrefixLengthB-1) + g_scoreGapExtend.get(); SCORE scoreBest; if (scoreMI >= scoreII) { scoreBest = scoreMI; TBI(uPrefixLengthA, uPrefixLengthB) = 'M'; } else { assert(scoreII > scoreMI); scoreBest = scoreII; TBI(uPrefixLengthA, uPrefixLengthB) = 'I'; } DPI(uPrefixLengthA, uPrefixLengthB) = scoreBest; } // Insert J=GapA+LetterB { SCORE scoreMJ = DPM(uPrefixLengthA, uPrefixLengthB-1) + PB[uPrefixLengthB - 1].m_scoreGapOpen2; SCORE scoreJJ = DPJ(uPrefixLengthA, uPrefixLengthB-1) + g_scoreGapExtend2.get(); SCORE scoreBest; if (scoreMJ >= scoreJJ) { scoreBest = scoreMJ; TBJ(uPrefixLengthA, uPrefixLengthB) = 'M'; } else { assert(scoreJJ > scoreMJ); scoreBest = scoreJJ; TBJ(uPrefixLengthA, uPrefixLengthB) = 'J'; } DPJ(uPrefixLengthA, uPrefixLengthB) = scoreBest; } scoreGapCloseA = PPA.m_scoreGapClose; scoreGapClose2A = PPA.m_scoreGapClose2; } scoreGapCloseB = PPB.m_scoreGapClose; scoreGapClose2B = PPB.m_scoreGapClose2; } #if TRACE Log("\n"); Log("DA Simple DPL:\n"); ListDP(DPL_, PA, PB, uPrefixCountA, uPrefixCountB); Log("\n"); Log("DA Simple DPM:\n"); ListDP(DPM_, PA, PB, uPrefixCountA, uPrefixCountB); Log("\n"); Log("DA Simple DPD:\n"); ListDP(DPD_, PA, PB, uPrefixCountA, uPrefixCountB); Log("\n"); Log("DA Simple DPE:\n"); ListDP(DPE_, PA, PB, uPrefixCountA, uPrefixCountB); Log("\n"); Log("DA Simple DPI:\n"); ListDP(DPI_, PA, PB, uPrefixCountA, uPrefixCountB); Log("\n"); Log("DA Simple DPJ:\n"); ListDP(DPJ_, PA, PB, uPrefixCountA, uPrefixCountB); Log("\n"); Log("DA Simple TBM:\n"); ListTB(TBM_, PA, PB, uPrefixCountA, uPrefixCountB); Log("\n"); Log("DA Simple TBD:\n"); ListTB(TBD_, PA, PB, uPrefixCountA, uPrefixCountB); Log("\n"); Log("DA Simple TBE:\n"); ListTB(TBE_, PA, PB, uPrefixCountA, uPrefixCountB); Log("\n"); Log("DA Simple TBI:\n"); ListTB(TBI_, PA, PB, uPrefixCountA, uPrefixCountB); Log("\n"); Log("DA Simple TBJ:\n"); ListTB(TBJ_, PA, PB, uPrefixCountA, uPrefixCountB); #endif // Trace-back // ========== Path.Clear(); // Find last edge SCORE M = DPM(uLengthA, uLengthB); SCORE D = DPD(uLengthA, uLengthB) + PA[uLengthA-1].m_scoreGapClose; SCORE E = DPE(uLengthA, uLengthB) + PA[uLengthA-1].m_scoreGapClose2; SCORE I = DPI(uLengthA, uLengthB) + PB[uLengthB-1].m_scoreGapClose; SCORE J = DPJ(uLengthA, uLengthB) + PB[uLengthB-1].m_scoreGapClose2; char cEdgeType = '?'; SCORE BestScore = M; cEdgeType = 'M'; if (D > BestScore) { cEdgeType = 'D'; BestScore = D; } if (E > BestScore) { cEdgeType = 'E'; BestScore = E; } if (I > BestScore) { cEdgeType = 'I'; BestScore = I; } if (J > BestScore) { cEdgeType = 'J'; BestScore = J; } #if TRACE Log("DA Simple: MAB=%.4g DAB=%.4g EAB=%.4g IAB=%.4g JAB=%.4g best=%c\n", M, D, E, I, J, cEdgeType); #endif unsigned PLA = uLengthA; unsigned PLB = uLengthB; for (;;) { PWEdge Edge; Edge.cType = XlatEdgeType(cEdgeType); Edge.uPrefixLengthA = PLA; Edge.uPrefixLengthB = PLB; #if TRACE Log("Prepend %c%d.%d\n", Edge.cType, PLA, PLB); #endif Path.PrependEdge(Edge); switch (cEdgeType) { case 'M': assert(PLA > 0); assert(PLB > 0); cEdgeType = TBM(PLA, PLB); --PLA; --PLB; break; case 'D': assert(PLA > 0); cEdgeType = TBD(PLA, PLB); --PLA; break; case 'E': assert(PLA > 0); cEdgeType = TBE(PLA, PLB); --PLA; break; case 'I': assert(PLB > 0); cEdgeType = TBI(PLA, PLB); --PLB; break; case 'J': assert(PLB > 0); cEdgeType = TBJ(PLA, PLB); --PLB; break; default: Quit("Invalid edge %c", cEdgeType); } if (0 == PLA && 0 == PLB) break; } Path.Validate(); // SCORE Score = TraceBack(PA, uLengthA, PB, uLengthB, DPM_, DPD_, DPI_, Path); #if TRACE SCORE scorePath = FastScorePath2(PA, uLengthA, PB, uLengthB, Path); Path.LogMe(); Log("Score = %s Path = %s\n", LocalScoreToStr(BestScore), LocalScoreToStr(scorePath)); #endif if (g_bKeepSimpleDP.get()) { g_DPM.get() = DPM_; g_DPD.get() = DPD_; g_DPE.get() = DPE_; g_DPI.get() = DPI_; g_DPJ.get() = DPJ_; g_TBM.get() = TBM_; g_TBD.get() = TBD_; g_TBE.get() = TBE_; g_TBI.get() = TBI_; g_TBJ.get() = TBJ_; } else { delete[] DPM_; delete[] DPD_; delete[] DPE_; delete[] DPI_; delete[] DPJ_; delete[] TBM_; delete[] TBD_; delete[] TBE_; delete[] TBI_; delete[] TBJ_; } return BestScore; }
static UINT16 i80286_far_return(i8086_state *cpustate, int iret, int bytes) { UINT16 sel, off, flags = 0; int spaddr; if (PM && NT && iret) { i80286_switch_task(cpustate, ReadWord(cpustate->tr.base+TSS_BACK*2), IRET); return cpustate->flags; } // must be restartable if(PM) i80286_check_permission(cpustate, SS, cpustate->regs.w[SP], (iret?6:4), I80286_READ); spaddr = (cpustate->base[SS] + cpustate->regs.w[SP]) & AMASK; off = ReadWord(spaddr); sel = ReadWord(spaddr+2); if(iret) flags = ReadWord(spaddr+4); if(PM) { UINT16 desc[3], newsp, newss; int addr, r; if ((addr = i80286_selector_address(cpustate,sel)) == -1) throw TRAP(GENERAL_PROTECTION_FAULT,IDXTBL(sel)); if (RPL(sel)<CPL) throw TRAP(GENERAL_PROTECTION_FAULT,IDXTBL(sel)); desc[0] = ReadWord(addr); desc[1] = ReadWord(addr+2); desc[2] = ReadWord(addr+4); r = RIGHTS(desc); if (!CODE(r) || !SEGDESC(r)) throw TRAP(GENERAL_PROTECTION_FAULT,IDXTBL(sel)); if (CONF(r)) { if(DPL(r)>RPL(sel)) throw TRAP(GENERAL_PROTECTION_FAULT,IDXTBL(sel)); } else if (DPL(r)!=RPL(sel)) throw TRAP(GENERAL_PROTECTION_FAULT,IDXTBL(sel)); if (!PRES(r)) throw TRAP(SEG_NOT_PRESENT,IDXTBL(sel)); if (off > LIMIT(desc)) throw TRAP(GENERAL_PROTECTION_FAULT,0); if (CPL<RPL(sel)) { i80286_check_permission(cpustate, SS, cpustate->regs.w[SP]+(iret?6:4)+bytes, 4, I80286_READ); newsp = ReadWord(spaddr+((iret?6:4)+bytes)); newss = ReadWord(spaddr+((iret?8:6)+bytes)); i80286_data_descriptor_full(cpustate, SS, newss, RPL(sel), TRAP(GENERAL_PROTECTION_FAULT,IDXTBL(newss)), 0, 0); cpustate->regs.w[SP] = newsp + bytes; } else cpustate->regs.w[SP] += (iret?6:4) + bytes; SET_ACC(desc); WriteWord(addr+4, desc[2]); cpustate->sregs[CS]=sel; cpustate->limit[CS]=LIMIT(desc); cpustate->base[CS]=BASE(desc); cpustate->rights[CS]=RIGHTS(desc); cpustate->pc=(cpustate->base[CS]+off)&AMASK; // docs say check rpl but windows doesn't like it r = cpustate->rights[DS]; if (i80286_verify(cpustate, cpustate->sregs[DS], I80286_READ, r, 0) || (CODE(r) && CONF(r) ? 0 : (DPL(r) < CPL))) i80286_data_descriptor(cpustate, DS, 0); r = cpustate->rights[ES]; if (i80286_verify(cpustate, cpustate->sregs[ES], I80286_READ, r, 0) || (CODE(r) && CONF(r) ? 0 : (DPL(r) < CPL))) i80286_data_descriptor(cpustate, ES, 0); } else { cpustate->regs.w[SP] += (iret?6:4) + bytes; cpustate->sregs[CS]=sel; cpustate->base[CS]=sel<<4; cpustate->rights[CS]=0x9a; cpustate->limit[CS]=0xffff; cpustate->pc=(cpustate->base[CS]+off)&AMASK; } CHANGE_PC(cpustate->pc); return flags; }
static void PREFIX286(_0fpre)(i8086_state *cpustate) { unsigned next = FETCHOP; UINT16 ModRM, desc[3]; UINT16 tmp, msw, sel; UINT8 r; UINT32 addr; switch (next) { case 0: if (!PM) throw TRAP(ILLEGAL_INSTRUCTION,-1); ModRM=FETCHOP; switch (ModRM&0x38) { case 0: /* sldt */ PutRMWord(ModRM, cpustate->ldtr.sel); break; case 8: /* str */ PutRMWord(ModRM, cpustate->tr.sel); break; case 0x10: /* lldt */ if (CPL!=0) throw TRAP(GENERAL_PROTECTION_FAULT,0); sel=GetRMWord(ModRM); if (TBL(sel)) throw TRAP(GENERAL_PROTECTION_FAULT,IDXTBL(sel)); if (IDXTBL(sel)) { if (IDX(sel)>=cpustate->gdtr.limit) throw TRAP(GENERAL_PROTECTION_FAULT,IDXTBL(sel)); addr = cpustate->gdtr.base + IDX(sel); desc[0] = ReadWord(addr); desc[1] = ReadWord(addr+2); desc[2] = ReadWord(addr+4); r = RIGHTS(desc); if (SEGDESC(r) || (GATE(r) != LDTDESC)) throw TRAP(GENERAL_PROTECTION_FAULT,IDXTBL(sel)); if (!PRES(r)) throw TRAP(SEG_NOT_PRESENT,IDXTBL(sel)); } else { desc[0] = 0; desc[1] = 0; desc[2] = 0; } cpustate->ldtr.sel=sel; cpustate->ldtr.limit=LIMIT(desc); cpustate->ldtr.base=BASE(desc); cpustate->ldtr.rights=RIGHTS(desc); break; case 0x18: /* ltr */ if (CPL!=0) throw TRAP(GENERAL_PROTECTION_FAULT,0); sel=GetRMWord(ModRM); if ((addr = i80286_selector_address(cpustate,sel)) == -1) throw TRAP(GENERAL_PROTECTION_FAULT,IDXTBL(sel)); desc[0] = ReadWord(addr); desc[1] = ReadWord(addr+2); desc[2] = ReadWord(addr+4); r = RIGHTS(desc); if (SEGDESC(r) || (GATE(r) != TSSDESCIDLE)) throw TRAP(GENERAL_PROTECTION_FAULT,IDXTBL(sel)); if (!PRES(r)) throw TRAP(SEG_NOT_PRESENT,IDXTBL(sel)); desc[2] |= 0x200; // mark busy WriteWord(addr+4, desc[2]); cpustate->tr.sel=sel; cpustate->tr.limit=LIMIT(desc); cpustate->tr.base=BASE(desc); cpustate->tr.rights=RIGHTS(desc); break; case 0x20: /* verr */ tmp=GetRMWord(ModRM); if ((addr = i80286_selector_address(cpustate,tmp)) == -1) cpustate->ZeroVal = 1; else { desc[2] = ReadWord(addr+4); r = RIGHTS(desc); cpustate->ZeroVal = i80286_verify(cpustate, tmp, I80286_READ, RIGHTS(desc), 0); cpustate->ZeroVal = cpustate->ZeroVal || (CODE(r) && CONF(r) ? 0 : (DPL(r)<PMAX(RPL(tmp),CPL))); } break; case 0x28: /* verw */ tmp=GetRMWord(ModRM); if ((addr = i80286_selector_address(cpustate,tmp)) == -1) cpustate->ZeroVal = 1; else { desc[2] = ReadWord(addr+4); r = RIGHTS(desc); cpustate->ZeroVal = i80286_verify(cpustate, tmp, I80286_WRITE, RIGHTS(desc), 0); cpustate->ZeroVal = cpustate->ZeroVal || (DPL(r)<PMAX(RPL(tmp),CPL)); } break; default: throw TRAP(ILLEGAL_INSTRUCTION,-1); break; } break; case 1: /* lgdt, lldt in protected mode privilege level 0 required else common protection failure 0xd */ ModRM = FETCHOP; switch (ModRM&0x38) { case 0: /* sgdt */ PutRMWord(ModRM,cpustate->gdtr.limit); PutRMWordOffset(2,cpustate->gdtr.base&0xffff); PutRMWordOffset(4,0xff00|cpustate->gdtr.base>>16); break; case 8: /* sidt */ PutRMWord(ModRM,cpustate->idtr.limit); PutRMWordOffset(2,cpustate->idtr.base&0xffff); PutRMWordOffset(4,0xff00|cpustate->idtr.base>>16); break; case 0x10: /* lgdt */ if (PM&&(CPL!=0)) throw TRAP(GENERAL_PROTECTION_FAULT,0); cpustate->gdtr.limit=GetRMWord(ModRM); cpustate->gdtr.base=GetRMWordOffset(2)|(GetRMByteOffset(4)<<16); break; case 0x18: /* lidt */ if (PM&&(CPL!=0)) throw TRAP(GENERAL_PROTECTION_FAULT,0); cpustate->idtr.limit=GetRMWord(ModRM); cpustate->idtr.base=GetRMWordOffset(2)|(GetRMByteOffset(4)<<16); break; case 0x20: /* smsw */ PutRMWord(ModRM, cpustate->msw); break; case 0x30: /* lmsw */ if (PM&&(CPL!=0)) throw TRAP(GENERAL_PROTECTION_FAULT,0); msw = GetRMWord(ModRM); if (!PM&&(msw&1)) cpustate->sregs[CS] = IDX(cpustate->sregs[CS]); // cheat and set cpl to 0 cpustate->msw=(cpustate->msw&1)|msw; break; default: throw TRAP(ILLEGAL_INSTRUCTION,-1); break; } break; case 2: /* LAR */ if (!PM) throw TRAP(ILLEGAL_INSTRUCTION,-1); ModRM = FETCHOP; tmp=GetRMWord(ModRM); if ((addr = i80286_selector_address(cpustate,tmp)) == -1) cpustate->ZeroVal = 1; else { desc[2] = ReadWord(addr+4); r = RIGHTS(desc); if (DPL(r)>=PMAX(RPL(tmp),CPL)) { cpustate->ZeroVal = 0; // rights are expected to be in upper byte RegWord(ModRM) = r << 8; } else cpustate->ZeroVal = 1; } break; case 3: /* LSL */ if (!PM) throw TRAP(ILLEGAL_INSTRUCTION,-1); ModRM = FETCHOP; tmp=GetRMWord(ModRM); if ((addr = i80286_selector_address(cpustate,tmp)) == -1) cpustate->ZeroVal = 1; else { desc[2] = ReadWord(addr+4); r = RIGHTS(desc); if (!SEGDESC(r) && (GATE(r) >= CALLGATE)) cpustate->ZeroVal = 1; // not valid for gates else if (DPL(r)>=PMAX(RPL(tmp),CPL)) { cpustate->ZeroVal = 0; RegWord(ModRM) = ReadWord(addr); } else cpustate->ZeroVal = 1; } break; case 5: /* loadall */ if (PM&&(CPL!=0)) throw TRAP(GENERAL_PROTECTION_FAULT,0); cpustate->msw = (cpustate->msw&1)|ReadWord(0x806); cpustate->tr.sel = ReadWord(0x816); tmp = ReadWord(0x818); ExpandFlags(tmp); cpustate->flags = tmp; cpustate->flags = CompressFlags(); cpustate->pc = ReadWord(0x81a); cpustate->ldtr.sel = ReadWord(0x81c); cpustate->sregs[DS] = ReadWord(0x81e); cpustate->sregs[SS] = ReadWord(0x820); cpustate->sregs[CS] = ReadWord(0x822); cpustate->sregs[ES] = ReadWord(0x824); cpustate->regs.w[DI] = ReadWord(0x826); cpustate->regs.w[SI] = ReadWord(0x828); cpustate->regs.w[BP] = ReadWord(0x82a); cpustate->regs.w[SP] = ReadWord(0x82c); cpustate->regs.w[BX] = ReadWord(0x82e); cpustate->regs.w[DX] = ReadWord(0x830); cpustate->regs.w[CX] = ReadWord(0x832); cpustate->regs.w[AX] = ReadWord(0x834); // loadall uses base-rights-limit order #define LOADDESC(addr, sreg) { desc[1] = ReadWord(addr); desc[2] = ReadWord(addr+2); desc[0] = ReadWord(addr+4); \ cpustate->base[sreg] = BASE(desc); cpustate->rights[sreg] = RIGHTS(desc); \ cpustate->limit[sreg] = LIMIT(desc); } LOADDESC(0x836, ES); LOADDESC(0x83C, CS); LOADDESC(0x842, SS); LOADDESC(0x848, DS); #undef LOADDESC // void cast supresses warning #define LOADDESC(addr, reg, r) { desc[1] = ReadWord(addr); desc[2] = ReadWord(addr+2); desc[0] = ReadWord(addr+4); \ cpustate->reg.base = BASE(desc); (void)(r); cpustate->reg.limit = LIMIT(desc); } LOADDESC(0x84e, gdtr, 1); LOADDESC(0x854, ldtr, cpustate->ldtr.rights = RIGHTS(desc)); LOADDESC(0x85a, idtr, 1); LOADDESC(0x860, tr, cpustate->tr.rights = RIGHTS(desc)); #undef LOADDESC cpustate->pc = (cpustate->pc + cpustate->base[CS]) & AMASK; CHANGE_PC(cpustate->pc); break; case 6: /* clts */ if (PM&&(CPL!=0)) throw TRAP(GENERAL_PROTECTION_FAULT,0); cpustate->msw&=~8; break; default: throw TRAP(ILLEGAL_INSTRUCTION,-1); break; } }
static void i80286_interrupt_descriptor(i80286_state *cpustate,UINT16 number, int hwint, int error) { UINT16 desc[3], gatedesc[3]={0,0,0}, gatesel; UINT8 r; UINT32 addr; if(!PM) return PREFIX86(_interrupt)(cpustate, number); if ((number<<3)>=cpustate->idtr.limit) throw TRAP(GENERAL_PROTECTION_FAULT,(number*8+2+(hwint&&1))); desc[0] = ReadWord(cpustate->idtr.base+(number<<3)); desc[1] = ReadWord(cpustate->idtr.base+(number<<3)+2); desc[2] = ReadWord(cpustate->idtr.base+(number<<3)+4); r = RIGHTS(desc); if (!hwint && (DPL(r)<CPL)) throw TRAP(GENERAL_PROTECTION_FAULT,(number*8+2+(hwint&&1))); if (!PRES(r)) throw TRAP(SEG_NOT_PRESENT,(number*8+2+(hwint&&1))); gatesel = GATESEL(desc); switch (GATE(r)) { case TASKGATE: i80286_switch_task(cpustate, gatesel, CALL); if((hwint == 1) && (error != -1)) PUSH(error); i80286_load_flags(cpustate, cpustate->flags, CPL); break; case INTGATE: case TRAPGATE: if ((addr = i80286_selector_address(cpustate,gatesel)) == -1) throw TRAP(GENERAL_PROTECTION_FAULT,(IDXTBL(gatesel)+(hwint&&1))); gatedesc[0] = ReadWord(addr); gatedesc[1] = ReadWord(addr+2); gatedesc[2] = ReadWord(addr+4); r = RIGHTS(gatedesc); if (!CODE(r) || !SEGDESC(r)) throw TRAP(GENERAL_PROTECTION_FAULT,(IDXTBL(gatesel)+(hwint&&1))); if (DPL(r)>CPL) throw TRAP(GENERAL_PROTECTION_FAULT,(IDXTBL(gatesel)+(hwint&&1))); if (!PRES(r)) throw TRAP(SEG_NOT_PRESENT,(IDXTBL(gatesel)+(hwint&&1))); if (GATEOFF(desc) > LIMIT(gatedesc)) throw TRAP(GENERAL_PROTECTION_FAULT,(int)(hwint&&1)); if (!CONF(r)&&(DPL(r)<CPL)) { // inner call UINT16 tss_ss, tss_sp, oldss, oldsp; tss_ss = ReadWord(cpustate->tr.base+TSS_SS0*2+(DPL(r)*4)); tss_sp = ReadWord(cpustate->tr.base+TSS_SP0*2+(DPL(r)*4)); oldss = cpustate->sregs[SS]; oldsp = cpustate->regs.w[SP]; i80286_data_descriptor_full(cpustate, SS, tss_ss, DPL(r), TRAP(INVALID_TSS,(IDXTBL(tss_ss)+(hwint&&1))), tss_sp-((error != -1)?12:10), (error != -1)?12:10); cpustate->regs.w[SP] = tss_sp; PUSH(oldss); PUSH(oldsp); } else i80286_check_permission(cpustate, SS, cpustate->regs.w[SP]-((error != -1)?8:6), (error != -1)?8:6, I80286_READ); SET_ACC(gatedesc); WriteWord(addr+4, gatedesc[2]); PREFIX(_pushf(cpustate)); PUSH(cpustate->sregs[CS]); PUSH(cpustate->pc-cpustate->base[CS]); if((hwint == 1) && (error != -1)) PUSH(error); cpustate->sregs[CS]=IDXTBL(gatesel) | DPL(r); cpustate->limit[CS]=LIMIT(gatedesc); cpustate->base[CS]=BASE(gatedesc); cpustate->rights[CS]=RIGHTS(gatedesc); cpustate->pc=(cpustate->base[CS]+GATEOFF(desc))&AMASK; cpustate->TF = 0; cpustate->flags &= ~0x4000; if (GATE(RIGHTS(desc)) == INTGATE) cpustate->IF = 0; CHANGE_PC(cpustate->pc); break; default: throw TRAP(GENERAL_PROTECTION_FAULT,(number*8+2+(hwint&&1))); } }
static void i80286_code_descriptor(i80286_state *cpustate, UINT16 selector, UINT16 offset, int gate) { if (PM) { UINT16 desc[3]; UINT8 r; UINT32 addr; /* selector format 15..3 number/address in descriptor table 2: 0 global, 1 local descriptor table 1,0: requested privileg level must be higher or same as current privileg level in code selector */ if ((addr = i80286_selector_address(cpustate,selector)) == -1) throw TRAP(GENERAL_PROTECTION_FAULT,IDXTBL(selector)); desc[0] = ReadWord(addr); desc[1] = ReadWord(addr+2); desc[2] = ReadWord(addr+4); r = RIGHTS(desc); if (SEGDESC(r)) { if (!CODE(r)) throw TRAP(GENERAL_PROTECTION_FAULT,IDXTBL(selector)); if (CONF(r)) { if(DPL(r)>CPL) throw TRAP(GENERAL_PROTECTION_FAULT,IDXTBL(selector)); } else if ((RPL(selector)>CPL) || (DPL(r)!=CPL)) throw TRAP(GENERAL_PROTECTION_FAULT,IDXTBL(selector)); if (!PRES(r)) throw TRAP(SEG_NOT_PRESENT,IDXTBL(selector)); // this order is important if (offset > LIMIT(desc)) throw TRAP(GENERAL_PROTECTION_FAULT, 0); SET_ACC(desc); WriteWord(addr+4, desc[2]); cpustate->sregs[CS]=IDXTBL(selector) | CPL; cpustate->limit[CS]=LIMIT(desc); cpustate->base[CS]=BASE(desc); cpustate->rights[CS]=RIGHTS(desc); cpustate->pc=cpustate->base[CS]+offset; } else { // systemdescriptor UINT16 gatedesc[3]={0,0,0}; UINT16 gatesel = GATESEL(desc); if (!gate) throw TRAP(GENERAL_PROTECTION_FAULT,IDXTBL(selector)); // tss cs must be segment if (DPL(r) < PMAX(CPL,RPL(selector))) throw TRAP(GENERAL_PROTECTION_FAULT,IDXTBL(selector)); if (!PRES(r)) throw TRAP(SEG_NOT_PRESENT, IDXTBL(selector)); switch (GATE(r)) { case CALLGATE: if ((addr = i80286_selector_address(cpustate,gatesel)) == -1) throw TRAP(GENERAL_PROTECTION_FAULT,IDXTBL(gatesel)); gatedesc[0] = ReadWord(addr); gatedesc[1] = ReadWord(addr+2); gatedesc[2] = ReadWord(addr+4); r = RIGHTS(gatedesc); if (!CODE(r) || !SEGDESC(r)) throw TRAP(GENERAL_PROTECTION_FAULT,IDXTBL(gatesel)); if (DPL(r)>CPL) throw TRAP(GENERAL_PROTECTION_FAULT,IDXTBL(gatesel)); if (!PRES(r)) throw TRAP(SEG_NOT_PRESENT,IDXTBL(gatesel)); if (GATEOFF(desc) > LIMIT(gatedesc)) throw TRAP(GENERAL_PROTECTION_FAULT,0); if (!CONF(r)&&(DPL(r)<CPL)) { // inner call UINT16 tss_ss, tss_sp, oldss, oldsp; UINT32 oldstk; int i; if(gate == JMP) throw TRAP(GENERAL_PROTECTION_FAULT,IDXTBL(gatesel)); // can't jmp to inner tss_ss = ReadWord(cpustate->tr.base+TSS_SS0*2+(DPL(r)*4)); tss_sp = ReadWord(cpustate->tr.base+TSS_SP0*2+(DPL(r)*4)); oldss = cpustate->sregs[SS]; oldsp = cpustate->regs.w[SP]; oldstk = cpustate->base[SS] + oldsp; i80286_data_descriptor_full(cpustate, SS, tss_ss, DPL(r), TRAP(INVALID_TSS,IDXTBL(tss_ss)), tss_sp-8-(GATECNT(desc)*2), 8+(GATECNT(desc)*2)); cpustate->regs.w[SP] = tss_sp; PUSH(oldss); PUSH(oldsp); for (i = GATECNT(desc)-1; i >= 0; i--) PUSH(ReadWord(oldstk+(i*2))); } else i80286_check_permission(cpustate, SS, cpustate->regs.w[SP]-4, 4, I80286_READ); SET_ACC(gatedesc); WriteWord(addr+4, gatedesc[2]); cpustate->sregs[CS]=IDXTBL(gatesel) | DPL(r); cpustate->limit[CS]=LIMIT(gatedesc); cpustate->base[CS]=BASE(gatedesc); cpustate->rights[CS]=RIGHTS(gatedesc); cpustate->pc=(cpustate->base[CS]+GATEOFF(desc))&AMASK; break; case TASKGATE: selector = gatesel; if ((addr = i80286_selector_address(cpustate,selector)) == -1) throw TRAP(GENERAL_PROTECTION_FAULT,IDXTBL(selector)); desc[2] = ReadWord(addr+4); r = RIGHTS(desc); if (SEGDESC(r) || (GATE(r) != TSSDESCIDLE)) throw TRAP(GENERAL_PROTECTION_FAULT,IDXTBL(selector)); case TSSDESCIDLE: i80286_switch_task(cpustate, selector, gate); i80286_load_flags(cpustate, cpustate->flags, CPL); break; default: throw TRAP(GENERAL_PROTECTION_FAULT,IDXTBL(selector)); } } } else { cpustate->sregs[CS]=selector; cpustate->base[CS]=selector<<4; cpustate->rights[CS]=0x9a; cpustate->limit[CS]=0xffff; cpustate->pc=(cpustate->base[CS]+offset)&AMASK; } }