📄 processor.java
字号:
/* JPC: A x86 PC Hardware Emulator for a pure Java Virtual Machine Release Version 2.0 A project from the Physics Dept, The University of Oxford Copyright (C) 2007 Isis Innovation Limited This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Details (including contact information) can be found at: www.physics.ox.ac.uk/jpc*/package org.jpc.emulator.processor;import org.jpc.emulator.*;import org.jpc.emulator.motherboard.*;import org.jpc.emulator.memory.*;import org.jpc.emulator.processor.fpu64.*;import org.jpc.support.*;import java.io.*;import java.util.*;public class Processor implements HardwareComponent{ public static final int STATE_VERSION = 1; public static final int STATE_MINOR_VERSION = 0; public static final int CLOCK_SPEED = 50; //CPU "Clock Speed" in MHz public static final int IFLAGS_HARDWARE_INTERRUPT = 0x1; public static final int IFLAGS_PROCESSOR_EXCEPTION = 0x2; public static final int IFLAGS_RESET_REQUEST = 0x4; public static final int PROC_EXCEPTION_DE = 0x00; // Divide Error public static final int PROC_EXCEPTION_DB = 0x01; // Debug public static final int PROC_EXCEPTION_BP = 0x03; // Breakpoint public static final int PROC_EXCEPTION_OF = 0x04; // Overflow public static final int PROC_EXCEPTION_BR = 0x05; // BOUND Range Exceeded public static final int PROC_EXCEPTION_UD = 0x06; // Invalid Opcode (UnDefined) public static final int PROC_EXCEPTION_NM = 0x07; // Device Not Available (No Math Coprocessor) public static final int PROC_EXCEPTION_DF = 0x08; // Double Fault public static final int PROC_EXCEPTION_MF_09 = 0x09; // Coprocessor Segment Overrun public static final int PROC_EXCEPTION_TS = 0x0a; // Invalid TSS public static final int PROC_EXCEPTION_NP = 0x0b; // Segment Not Present public static final int PROC_EXCEPTION_SS = 0x0c; // Stack Segment Fault public static final int PROC_EXCEPTION_GP = 0x0d; // General Protection public static final int PROC_EXCEPTION_PF = 0x0e; // Page Fault public static final int PROC_EXCEPTION_MF_10 = 0x10; // Floating-Point Error public static final int PROC_EXCEPTION_AC = 0x11; // Alignment Check public static final int PROC_EXCEPTION_MC = 0x12; // Machine Check public static final int PROC_EXCEPTION_XF = 0x13; // SIMD Floating-Point Error public static final int PROC_EXCEPTION_MAX = 0x13; // Maximum exception vector value public static final int CR0_PROTECTION_ENABLE = 0x1; public static final int CR0_MONITOR_COPROCESSOR = 0x2; public static final int CR0_FPU_EMULATION = 0x4; public static final int CR0_TASK_SWITCHED = 0x8; public static final int CR0_NUMERIC_ERROR = 0x20; public static final int CR0_WRITE_PROTECT = 0x10000; public static final int CR0_ALIGNMENT_MASK = 0x40000; public static final int CR0_NOT_WRITETHROUGH = 0x20000000; public static final int CR0_CACHE_DISABLE = 0x40000000; public static final int CR0_PAGING = 0x80000000; public static final int CR3_PAGE_CACHE_DISABLE = 0x10; public static final int CR3_PAGE_WRITES_TRANSPARENT = 0x8; public static final int CR4_VIRTUAL8086_MODE_EXTENSIONS = 0x1; public static final int CR4_PROTECTED_MODE_VIRTUAL_INTERRUPTS = 0x2; public static final int CR4_TIME_STAMP_DISABLE = 0x4; public static final int CR4_DEBUGGING_EXTENSIONS = 0x8; public static final int CR4_PAGE_SIZE_EXTENSIONS = 0x10; public static final int CR4_PHYSICAL_ADDRESS_EXTENSION = 0x20; public static final int CR4_MACHINE_CHECK_ENABLE = 0x40; public static final int CR4_PAGE_GLOBAL_ENABLE = 0x80; public static final int CR4_PERFORMANCE_MONITORING_COUNTER_ENABLE = 0x100; public static final int CR4_OS_SUPPORT_FXSAVE_FXSTORE = 0x200; public static final int CR4_OS_SUPPORT_UNMASKED_SIMD_EXCEPTIONS = 0x400; public static final int SYSENTER_CS_MSR = 0x174; public static final int SYSENTER_ESP_MSR = 0x175; public static final int SYSENTER_EIP_MSR = 0x176; public int eax, ebx, edx, ecx; public int esi, edi, esp, ebp; public int eip; private int cr0, cr1, cr2, cr3, cr4; public int dr0, dr1, dr2, dr3, dr4, dr5, dr6, dr7; public Segment cs, ds, ss, es, fs, gs; public Segment idtr, gdtr, ldtr, tss; //protected int eflags; //program status and control register public boolean eflagsCarry; //done public boolean eflagsParity; //done public boolean eflagsAuxiliaryCarry; //done public boolean eflagsZero; //to do public boolean eflagsSign; //to do public boolean eflagsTrap; public boolean eflagsInterruptEnable; public boolean eflagsDirection; public boolean eflagsOverflow; //done public int eflagsIOPrivilegeLevel; public boolean eflagsNestedTask; public boolean eflagsResume; public boolean eflagsVirtual8086Mode; public boolean eflagsAlignmentCheck; public boolean eflagsVirtualInterrupt; public boolean eflagsVirtualInterruptPending; public boolean eflagsID; public boolean eflagsInterruptEnableSoon; public LinearAddressSpace linearMemory; public PhysicalAddressSpace physicalMemory; public AlignmentCheckedAddressSpace alignmentCheckedMemory; public IOPortHandler ioports; private int interruptFlags; private InterruptController interruptController; private Clock virtualClock; private boolean alignmentChecking; private Hashtable modelSpecificRegisters; private long resetTime; private int currentPrivilegeLevel; private boolean started = false; public FpuState fpu; public Processor() { fpu = new FpuState64(this); linearMemory = null; physicalMemory = null; alignmentCheckedMemory = null; ioports = null; alignmentChecking = false; modelSpecificRegisters = new Hashtable(); } public void dumpState(DataOutput output) throws IOException { output.writeInt(this.eax); output.writeInt(this.ebx); output.writeInt(this.edx); output.writeInt(this.ecx); output.writeInt(this.esi); output.writeInt(this.edi); output.writeInt(this.esp); output.writeInt(this.ebp); output.writeInt(this.eip); output.writeInt(this.dr0); output.writeInt(this.dr1); output.writeInt(this.dr2); output.writeInt(this.dr3); output.writeInt(this.dr4); output.writeInt(this.dr5); output.writeInt(this.dr6); output.writeInt(this.dr7); output.writeInt(this.cr0); output.writeInt(this.cr1); output.writeInt(this.cr2); output.writeInt(this.cr3); output.writeInt(this.cr4); output.writeBoolean(this.eflagsCarry); output.writeBoolean(this.eflagsParity); output.writeBoolean(this.eflagsAuxiliaryCarry); output.writeBoolean(this.eflagsZero); output.writeBoolean(this.eflagsSign); output.writeBoolean(this.eflagsTrap); output.writeBoolean(this.eflagsInterruptEnable); output.writeBoolean(this.eflagsDirection); output.writeBoolean(this.eflagsOverflow); output.writeInt(this.eflagsIOPrivilegeLevel); output.writeBoolean(this.eflagsNestedTask); output.writeBoolean(this.eflagsResume); output.writeBoolean(this.eflagsVirtual8086Mode); output.writeBoolean(this.eflagsAlignmentCheck); output.writeBoolean(this.eflagsVirtualInterrupt); output.writeBoolean(this.eflagsVirtualInterruptPending); output.writeBoolean(this.eflagsID); output.writeBoolean(this.eflagsInterruptEnableSoon); fpu.dumpState(output); output.writeInt(interruptFlags); output.writeBoolean(alignmentChecking); output.writeLong(resetTime); output.writeInt(currentPrivilegeLevel); //modelSpecificRegisters hashtable output.writeInt(modelSpecificRegisters.size()); Set entries = modelSpecificRegisters.entrySet(); Iterator itt = entries.iterator(); while (itt.hasNext()) { Map.Entry entry = (Map.Entry) itt.next(); output.writeInt(((Integer)entry.getKey()).intValue()); output.writeLong(((Long)entry.getValue()).longValue()); } cs.dumpState(output); ds.dumpState(output); ss.dumpState(output); es.dumpState(output); fs.dumpState(output); gs.dumpState(output); idtr.dumpState(output); gdtr.dumpState(output); ldtr.dumpState(output); tss.dumpState(output); } public void loadState(DataInput input) throws IOException { eax = input.readInt(); ebx = input.readInt(); edx = input.readInt(); ecx = input.readInt(); esi = input.readInt(); edi = input.readInt(); esp = input.readInt(); ebp = input.readInt(); eip = input.readInt(); dr0 = input.readInt(); dr1 = input.readInt(); dr2 = input.readInt(); dr3 = input.readInt(); dr4 = input.readInt(); dr5 = input.readInt(); dr6 = input.readInt(); dr7 = input.readInt(); cr0 = input.readInt(); cr1 = input.readInt(); cr2 = input.readInt(); cr3 = input.readInt(); cr4 = input.readInt(); eflagsCarry = input.readBoolean(); eflagsParity = input.readBoolean(); eflagsAuxiliaryCarry = input.readBoolean(); eflagsZero = input.readBoolean(); eflagsSign = input.readBoolean(); eflagsTrap = input.readBoolean(); eflagsInterruptEnable = input.readBoolean(); eflagsDirection = input.readBoolean(); eflagsOverflow = input.readBoolean(); eflagsIOPrivilegeLevel = input.readInt(); eflagsNestedTask = input.readBoolean(); eflagsResume = input.readBoolean(); eflagsVirtual8086Mode = input.readBoolean(); eflagsAlignmentCheck = input.readBoolean(); eflagsVirtualInterrupt = input.readBoolean(); eflagsVirtualInterruptPending = input.readBoolean(); eflagsID = input.readBoolean(); eflagsInterruptEnableSoon = input.readBoolean(); fpu.loadState(input); interruptFlags = input.readInt(); alignmentChecking = input.readBoolean(); resetTime = input.readLong(); currentPrivilegeLevel = input.readInt(); //modelSpecificRegisters hashtable int len = input.readInt(); modelSpecificRegisters = new Hashtable(); int key; long value; for (int i=0; i<len; i++) { key = input.readInt(); value = input.readLong(); modelSpecificRegisters.put(new Integer(key), new Long(value)); } cs = loadSegment(input); ds = loadSegment(input); ss = loadSegment(input); es = loadSegment(input); fs = loadSegment(input); gs = loadSegment(input); idtr = loadSegment(input); gdtr = loadSegment(input); ldtr = loadSegment(input); tss = loadSegment(input); } private Segment loadSegment(DataInput input) throws IOException { //isProtectedMode() //alignmentChecking int type = input.readInt(); if (type == 1) { int selector = input.readInt(); if (!isProtectedMode()) return SegmentFactory.createRealModeSegment(physicalMemory, selector); else { if (alignmentChecking) return SegmentFactory.createRealModeSegment(alignmentCheckedMemory, selector); else return SegmentFactory.createRealModeSegment(linearMemory, selector); } } else if (type == 2) { int base = input.readInt(); int limit = input.readInt(); if (!isProtectedMode()) return SegmentFactory.createDescriptorTableSegment(physicalMemory, base, limit); else { if (alignmentChecking) return SegmentFactory.createDescriptorTableSegment(alignmentCheckedMemory, base, limit); else return SegmentFactory.createDescriptorTableSegment(linearMemory, base, limit); } } else if (type == 3) { int selector = input.readInt(); long descriptor = input.readLong(); if (!isProtectedMode()) { System.out.println("tried to load a Protected Mode segment in Real Mode"); return null; //should never happen } else { if (alignmentChecking) return SegmentFactory.createProtectedModeSegment(alignmentCheckedMemory, selector, descriptor); else return SegmentFactory.createProtectedModeSegment(linearMemory, selector, descriptor); } } else if (type ==4) { return new SegmentFactory.NullSegment(); } else throw new IOException(); } public int getEFlags() { int result = 0x2; if (getCarryFlag()) result |= 0x1; if (getParityFlag()) result |= 0x4; if (getAuxiliaryCarryFlag()) result |= 0x10; if (getZeroFlag()) result |= 0x40; if (getSignFlag()) result |= 0x80; if (eflagsTrap) result |= 0x100; if (eflagsInterruptEnable) result |= 0x200; if (eflagsDirection) result |= 0x400; if (getOverflowFlag()) result |= 0x800; result |= (eflagsIOPrivilegeLevel << 12); if (eflagsNestedTask) result |= 0x4000; if (eflagsResume) result |= 0x10000; if (eflagsVirtual8086Mode) result |= 0x20000; if (eflagsAlignmentCheck) result |= 0x40000; if (eflagsVirtualInterrupt) result |= 0x80000; if (eflagsVirtualInterruptPending) result |= 0x100000;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -