⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 segmentfactory.java

📁 JPC: x86 PC Hardware Emulator. 牛津大学开发的一个纯JAVA的x86系统结构硬件模拟器。
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/*    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 + -