📄 segmentfactory.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.memory.*;
import java.io.*;
public class SegmentFactory
{
private static final long DESCRIPTOR_TYPE = 0x100000000000l;
private static final long SEGMENT_TYPE = 0xf0000000000l;
public static final Segment NULL_SEGMENT = new NullSegment();
public static final int DESCRIPTOR_TYPE_CODE_DATA = 0x10;
public static final int TYPE_ACCESSED = 0x1;
public static final int TYPE_CODE = 0x8;
public static final int TYPE_DATA_WRITABLE = 0x2;
public static final int TYPE_DATA_EXPAND_DOWN = 0x4;
public static final int TYPE_CODE_READABLE = 0x2;
public static final int TYPE_CODE_CONFORMING = 0x4;
abstract static class DefaultSegment extends Segment
{
Memory memory;
public DefaultSegment(Memory memory)
{
this.memory = memory;
}
public void setAddressSpace(AddressSpace memory)
{
this.memory = memory;
}
public boolean isPresent()
{
return true;
}
public void invalidateAddress(int address) {}
public int getType()
{
throw new IllegalStateException(getClass().toString());
}
public boolean getDefaultSizeFlag()
{
throw new IllegalStateException(getClass().toString());
}
public int getLimit()
{
throw new IllegalStateException(getClass().toString());
}
public int getBase()
{
throw new IllegalStateException(getClass().toString());
}
public int getSelector()
{
throw new IllegalStateException(getClass().toString());
}
public boolean setSelector(int selector)
{
throw new IllegalStateException(getClass().toString());
}
public int getRPL()
{
throw new IllegalStateException(getClass().toString());
}
public void setRPL(int cpl)
{
throw new IllegalStateException(getClass().toString());
}
public int getDPL()
{
throw new IllegalStateException(getClass().toString());
}
public abstract void checkAddress(int offset);
public abstract int translateAddressRead(int offset);
public abstract int translateAddressWrite(int offset);
public byte getByte(int offset)
{
return memory.getByte(translateAddressRead(offset));
}
public short getWord(int offset)
{
return memory.getWord(translateAddressRead(offset));
}
public int getDoubleWord(int offset)
{
return memory.getDoubleWord(translateAddressRead(offset));
}
public long getQuadWord(int offset)
{
int off = translateAddressRead(offset);
long result = 0xFFFFFFFFl & memory.getDoubleWord(off);
off = translateAddressRead(offset+4);
result |= (((long) memory.getDoubleWord(off)) << 32);
return result;
}
public void setByte(int offset, byte data)
{
memory.setByte(translateAddressWrite(offset), data);
}
public void setWord(int offset, short data)
{
memory.setWord(translateAddressWrite(offset), data);
}
public void setDoubleWord(int offset, int data)
{
memory.setDoubleWord(translateAddressWrite(offset), data);
}
public void setQuadWord(int offset, long data)
{
int off = translateAddressWrite(offset);
memory.setDoubleWord(off, (int) data);
off = translateAddressWrite(offset+4);
memory.setDoubleWord(off, (int) (data >>> 32));
}
}
static final class RealModeSegment extends DefaultSegment
{
private int selector, base, limit;
public RealModeSegment(Memory memory, int selector)
{
super(memory);
this.selector = selector;
base = selector << 4;
limit = 0xffff;
}
public int dumpState(DataOutput output) throws IOException
{
output.writeInt(1);
output.writeInt(selector);
return 8;
}
public boolean getDefaultSizeFlag()
{
return false;
}
public int getLimit()
{
return limit;
}
public int getBase()
{
return base;
}
public int getSelector()
{
return selector;
}
public boolean setSelector(int selector)
{
this.selector = selector;
base = selector << 4;
return true;
}
public void checkAddress(int offset)
{
}
public int translateAddressRead(int offset)
{
return base + offset;
}
public int translateAddressWrite(int offset)
{
return base + offset;
}
public int getRPL()
{
return 0;
}
}
public static Segment createRealModeSegment(Memory memory, int selector)
{
if (memory == null)
throw new NullPointerException("Null reference to memory");
return new RealModeSegment(memory, selector);
}
static final class DescriptorTableSegment extends DefaultSegment
{
private int base;
private long limit;
public DescriptorTableSegment(Memory memory, int base, int limit)
{
super(memory);
this.base = base;
this.limit = 0xFFFFFFFFl & limit;
}
public int dumpState(DataOutput output) throws IOException
{
output.writeInt(2);
output.writeInt(base);
output.writeInt((int) limit);
return 12;
}
public int getLimit()
{
return (int) limit;
}
public int getBase()
{
return base;
}
public int getSelector()
{
throw new IllegalStateException("No selector for a descriptor table segment");
}
public boolean setSelector(int selector)
{
throw new IllegalStateException("Cannot set a selector for a descriptor table segment");
}
public void checkAddress(int offset)
{
if ((0xFFFFFFFFl & offset) > limit)
throw new ProcessorException(Processor.PROC_EXCEPTION_GP, offset, true);
}
public int translateAddressRead(int offset)
{
return base + offset;
}
public int translateAddressWrite(int offset)
{
return base + offset;
}
}
public static Segment createDescriptorTableSegment(Memory memory, int base, int limit)
{
if (memory == null)
throw new NullPointerException("Null reference to memory");
return new DescriptorTableSegment(memory, base, limit);
}
abstract static class DefaultProtectedModeSegment extends DefaultSegment
{
private boolean defaultSize, granularity, present;
private int selector, limit, base, rpl, dpl;
private long longLimit, descriptor;
public DefaultProtectedModeSegment(Memory memory, int selector, long descriptor)
{
super(memory);
this.selector = selector;
this.descriptor = descriptor;
granularity = (descriptor & 0x80000000000000l) != 0;
limit = (int)((descriptor & 0xffff) | ((descriptor >>> 32) & 0xf0000));
if (granularity)
limit = (limit << 12) | 0xfff;
longLimit = 0xffffffffl & limit;
base = (int) ((0xffffff & (descriptor >> 16)) | ((descriptor >> 32) & 0xFF000000));
rpl = selector & 0x3;
dpl = (int) ((descriptor >> 45) & 0x3);
defaultSize = (descriptor & (0x1l << 54)) != 0;
present = (descriptor & (0x1l << 47)) != 0;
}
public int dumpState(DataOutput output) throws IOException
{
output.writeInt(3);
output.writeInt(selector);
output.writeLong(descriptor);
return 12;
}
public boolean isPresent()
{
return present;
}
public final int translateAddressRead(int offset)
{
checkAddress(offset);
return base + offset;
}
public final int translateAddressWrite(int offset)
{
checkAddress(offset);
return base + offset;
}
public final void checkAddress(int offset)
{
if ((0xffffffffl & offset) > longLimit) {
System.err.println("Segment limit exceeded: " + Integer.toHexString(offset) + " > " + Integer.toHexString((int)longLimit));
throw new ProcessorException(Processor.PROC_EXCEPTION_GP, 0, true);
}
}
public boolean getDefaultSizeFlag()
{
return defaultSize;
}
public int getLimit()
{
return limit;
}
public int getBase()
{
return base;
}
public int getSelector()
{
return selector;
}
public int getRPL()
{
return rpl;
}
public int getDPL()
{
return dpl;
}
public void setRPL(int cpl)
{
rpl = cpl;
}
}
static abstract class ReadOnlyProtectedModeSegment extends DefaultProtectedModeSegment
{
public ReadOnlyProtectedModeSegment(Memory memory, int selector, long descriptor)
{
super(memory, selector, descriptor);
}
void writeAttempted()
{
throw new IllegalStateException();
}
public void setByte(int offset, byte data)
{
writeAttempted();
}
public void setWord(int offset, short data)
{
writeAttempted();
}
public void setDoubleWord(int offset, int data)
{
writeAttempted();
}
public void setQuadWord(int offset, long data)
{
writeAttempted();
}
}
static final class ReadOnlyDataSegment extends ReadOnlyProtectedModeSegment
{
public ReadOnlyDataSegment(Memory memory, int selector, long descriptor)
{
super(memory, selector, descriptor);
}
public int getType()
{
return DESCRIPTOR_TYPE_CODE_DATA;
}
void writeAttempted()
{
throw new ProcessorException(Processor.PROC_EXCEPTION_GP, 0, true);
}
}
static final class ReadOnlyAccessedDataSegment extends ReadOnlyProtectedModeSegment
{
public ReadOnlyAccessedDataSegment(Memory memory, int selector, long descriptor)
{
super(memory, selector, descriptor);
}
public int getType()
{
return DESCRIPTOR_TYPE_CODE_DATA | TYPE_ACCESSED;
}
void writeAttempted()
{
throw new ProcessorException(Processor.PROC_EXCEPTION_GP, 0, true);
}
}
static final class ReadWriteDataSegment extends DefaultProtectedModeSegment
{
public ReadWriteDataSegment(Memory memory, int selector, long descriptor)
{
super(memory, selector, descriptor);
}
public int getType()
{
return DESCRIPTOR_TYPE_CODE_DATA | TYPE_DATA_WRITABLE;
}
}
static final class ReadWriteAccessedDataSegment extends DefaultProtectedModeSegment
{
public ReadWriteAccessedDataSegment(Memory memory, int selector, long descriptor)
{
super(memory, selector, descriptor);
}
public int getType()
{
return DESCRIPTOR_TYPE_CODE_DATA | TYPE_DATA_WRITABLE | TYPE_ACCESSED;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -