📄 linearaddressspace.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.memory;
import java.util.*;
import java.io.*;
import org.jpc.emulator.*;
import org.jpc.emulator.memory.codeblock.*;
import org.jpc.emulator.processor.*;
public final class LinearAddressSpace extends AddressSpace implements HardwareComponent
{
private static final PageFaultWrapper PF_NOT_PRESENT_RU = new PageFaultWrapper(4);
private static final PageFaultWrapper PF_NOT_PRESENT_RS = new PageFaultWrapper(0);
private static final PageFaultWrapper PF_NOT_PRESENT_WU = new PageFaultWrapper(6);
private static final PageFaultWrapper PF_NOT_PRESENT_WS = new PageFaultWrapper(2);
private static final PageFaultWrapper PF_PROTECTION_VIOLATION_RU = new PageFaultWrapper(5);
private static final PageFaultWrapper PF_PROTECTION_VIOLATION_RS = new PageFaultWrapper(1);
private static final PageFaultWrapper PF_PROTECTION_VIOLATION_WU = new PageFaultWrapper(7);
private static final PageFaultWrapper PF_PROTECTION_VIOLATION_WS = new PageFaultWrapper(3);
private static final byte FOUR_M_GLOBAL = (byte) 0x03;
private static final byte FOUR_M = (byte) 0x02;
private static final byte FOUR_K_GLOBAL = (byte) 0x01;
private static final byte FOUR_K = (byte) 0x00;
private static final byte IS_GLOBAL_MASK = (byte) 0x1;
private static final byte IS_4_M_MASK = (byte) 0x2;
private boolean isSupervisor, globalPagesEnabled, pagingDisabled, pageCacheEnabled, writeProtectUserPages, pageSizeExtensions;
private int baseAddress, lastAddress;
private AddressSpace target;
private byte[] pageFlags;
private Hashtable nonGlobalPages;
private Memory[] readUserIndex, readSupervisorIndex, writeUserIndex, writeSupervisorIndex, readIndex, writeIndex;
public LinearAddressSpace()
{
baseAddress = 0;
lastAddress = 0;
pagingDisabled = true;
globalPagesEnabled = false;
writeProtectUserPages = false;
pageSizeExtensions = false;
nonGlobalPages = new Hashtable();
pageFlags = new byte[INDEX_SIZE];
for (int i=0; i < INDEX_SIZE; i++)
pageFlags[i] = FOUR_K;
readUserIndex = null;
readSupervisorIndex = null;
writeUserIndex = null;
writeSupervisorIndex = null;
}
public void dumpState(DataOutput output) throws IOException
{
output.writeBoolean(isSupervisor);
output.writeBoolean(globalPagesEnabled);
output.writeBoolean(pagingDisabled);
output.writeBoolean(pageCacheEnabled);
output.writeBoolean(writeProtectUserPages);
output.writeBoolean(pageSizeExtensions);
output.writeInt(baseAddress);
output.writeInt(lastAddress);
output.writeInt(pageFlags.length);
output.write(pageFlags);
output.writeInt(nonGlobalPages.size());
Enumeration ee = nonGlobalPages.keys();
while (ee.hasMoreElements())
{
Integer key = (Integer) ee.nextElement();
Integer value = (Integer) nonGlobalPages.get(key);
output.writeInt(key.intValue());
output.writeInt(value.intValue());
}
dumpMemory(output, readUserIndex);
dumpMemory(output, readSupervisorIndex);
dumpMemory(output, writeUserIndex);
dumpMemory(output, writeSupervisorIndex);
}
private void dumpMemory(DataOutput output, Memory[] mem) throws IOException
{
long len;
byte[] temp = new byte[0];
if (mem == null)
output.writeInt(0);
else
{
output.writeInt(mem.length);
for (int i = 0; i< mem.length; i++)
{
if (mem[i] == null)
output.writeLong(-1);
else
{
len = mem[i].getSize();
if (temp.length < (int) len)
temp = new byte[(int) len];
if (mem[i].isAllocated())
{
try
{
mem[i].copyContentsInto(0, temp, 0, (int) len);
}
catch (IllegalStateException e)
{
len = 0;
}
output.writeLong(len);
if (len > 0 )
output.write(temp);
}
else
{
output.writeLong(0);
}
}
}
}
}
public void loadState(DataInput input) throws IOException
{
reset();
isSupervisor = input.readBoolean();
globalPagesEnabled = input.readBoolean();
pagingDisabled = input.readBoolean();
pageCacheEnabled = input.readBoolean();
writeProtectUserPages = input.readBoolean();
pageSizeExtensions = input.readBoolean();
baseAddress = input.readInt();
lastAddress = input.readInt();
int len = input.readInt();
pageFlags = new byte[len];
input.readFully(pageFlags,0,len);
nonGlobalPages.clear();
int count = input.readInt();
int key, value;
for (int i=0; i < count; i++)
{
key = input.readInt();
value = input.readInt();
nonGlobalPages.put(new Integer(key), new Integer(value));
}
len = input.readInt();
//debug and enable loadMemory() if loading speed becomes an issue
//loadMemory(input, readUserIndex, len);
len = input.readInt();
//loadMemory(input, readSupervisorIndex, len);
len = input.readInt();
//loadMemory(input, writeUserIndex, len);
len = input.readInt();
//loadMemory(input, writeSupervisorIndex, len);
setSupervisor(isSupervisor);
}
private void loadMemory(DataInput input, Memory[] mem, int size) throws IOException
{
long len;
byte[] temp;
for (int i = 0; i< size; i++)
{
len = input.readLong();
if (len >= 0)
{
System.out.println(len);
temp = new byte[(int) len];
input.readFully(temp, 0, (int) len);
//if (mem[i] == null)
// mem[i] = new ;
mem[i].copyContentsFrom(0, temp, 0, (int) len);
}
else
mem[i] = null;
}
}
private Memory[] getReadIndex()
{
if (isSupervisor)
return (readIndex = readSupervisorIndex = new Memory[INDEX_SIZE]);
else
return (readIndex = readUserIndex = new Memory[INDEX_SIZE]);
}
private Memory[] getWriteIndex()
{
if (isSupervisor)
return (writeIndex = writeSupervisorIndex = new Memory[INDEX_SIZE]);
else
return (writeIndex = writeUserIndex = new Memory[INDEX_SIZE]);
}
private void setReadIndexValue(int index, Memory value)
{
try {
readIndex[index] = value;
} catch (NullPointerException e) {
getReadIndex()[index] = value;
}
}
private Memory getReadIndexValue(int index)
{
try {
return readIndex[index];
} catch (NullPointerException e) {
return getReadIndex()[index];
}
}
private void setWriteIndexValue(int index, Memory value)
{
try {
writeIndex[index] = value;
} catch (NullPointerException e) {
getWriteIndex()[index] = value;
}
}
private Memory getWriteIndexValue(int index)
{
try {
return writeIndex[index];
} catch (NullPointerException e) {
return getWriteIndex()[index];
}
}
public int getLastWalkedAddress()
{
return lastAddress;
}
public boolean isSupervisor()
{
return isSupervisor;
}
public void setSupervisor(boolean value)
{
isSupervisor = value;
if (isSupervisor)
{
readIndex = readSupervisorIndex;
writeIndex = writeSupervisorIndex;
}
else
{
readIndex = readUserIndex;
writeIndex = writeUserIndex;
}
}
public boolean isPagingEnabled()
{
return !pagingDisabled;
}
public void setPagingEnabled(boolean value)
{
if (value) {
if (!((PhysicalAddressSpace)target).getGateA20State())
System.err.println("PAGING with GateA20 Masked!!!");
}
pagingDisabled = !value;
flush();
}
public void setPageCacheEnabled(boolean value)
{
pageCacheEnabled = value;
}
public void setPageSizeExtensionsEnabled(boolean value)
{
pageSizeExtensions = value;
flush();
}
public void setPageWriteThroughEnabled(boolean value)
{
//System.err.println("ERR: Write Through Caching enabled for TLBs");
}
public void setGlobalPagesEnabled(boolean value)
{
if (globalPagesEnabled == value)
return;
globalPagesEnabled = value;
flush();
}
public void setWriteProtectUserPages(boolean value)
{
if (value) {
for (int i=0; i<INDEX_SIZE; i++)
nullIndex(writeSupervisorIndex, i);
}
writeProtectUserPages = value;
}
public boolean pagingDisabled()
{
return pagingDisabled;
}
public void flush()
{
for (int i=0; i<INDEX_SIZE; i++)
{
pageFlags[i] = FOUR_K;
}
nonGlobalPages.clear();
readUserIndex = null;
writeUserIndex = null;
readSupervisorIndex = null;
writeSupervisorIndex = null;
}
private void partialFlush()
{
if (!globalPagesEnabled)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -