Remove slicing again, doesn't do much/anything.
Also use size constants all over the place.
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
package li.cil.circuity;
|
||||
|
||||
import li.cil.circuity.api.vm.device.memory.PhysicalMemory;
|
||||
import li.cil.circuity.vm.device.memory.ByteBufferMemory;
|
||||
import li.cil.circuity.vm.device.memory.UnsafeMemory;
|
||||
import li.cil.circuity.vm.riscv.R5Board;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
@@ -9,8 +9,8 @@ import java.io.FileInputStream;
|
||||
|
||||
public final class Main {
|
||||
public static void main(final String[] args) throws Exception {
|
||||
final PhysicalMemory rom = new ByteBufferMemory(128 * 1024);
|
||||
final PhysicalMemory memory = new ByteBufferMemory(48 * 1014 * 1024);
|
||||
final PhysicalMemory rom = new UnsafeMemory(128 * 1024);
|
||||
final PhysicalMemory memory = new UnsafeMemory(128 * 1014 * 1024);
|
||||
final R5Board board = new R5Board();
|
||||
board.addDevice(0x80000000, rom);
|
||||
board.addDevice(0x80000000 + 0x400000, memory);
|
||||
@@ -31,9 +31,26 @@ public final class Main {
|
||||
|
||||
final long start = System.currentTimeMillis();
|
||||
|
||||
final int n = 40000;
|
||||
final long n = 400_000_000;
|
||||
final int stepn = 10_000;
|
||||
final int hz = 30_000_000;
|
||||
|
||||
long remaining = 0;
|
||||
for (int i = 0; i < n; i++) {
|
||||
board.step(10000);
|
||||
final long stepStart = System.currentTimeMillis();
|
||||
remaining += hz;
|
||||
while (remaining > 0) {
|
||||
board.step(stepn);
|
||||
remaining -= stepn;
|
||||
}
|
||||
|
||||
final long elapsed = System.currentTimeMillis() - stepStart;
|
||||
final long sleep = 1000 - elapsed;
|
||||
if (sleep > 0) {
|
||||
// Thread.sleep(sleep);
|
||||
} else {
|
||||
System.out.println("Running behind by " + (-sleep) + "ms...");
|
||||
}
|
||||
}
|
||||
|
||||
final long duration = System.currentTimeMillis() - start;
|
||||
|
||||
@@ -2,8 +2,6 @@ package li.cil.circuity.api.vm.device.memory;
|
||||
|
||||
import li.cil.circuity.api.vm.MemoryMap;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
/**
|
||||
* Instances marked with this interface can be treated as random-access memory.
|
||||
* <p>
|
||||
@@ -11,5 +9,4 @@ import java.nio.ByteBuffer;
|
||||
* region can be stored in a translation lookaside buffer.
|
||||
*/
|
||||
public interface PhysicalMemory extends MemoryMappedDevice {
|
||||
ByteBuffer slice(final int offset, final int length);
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import li.cil.circuity.api.vm.device.InterruptSource;
|
||||
import li.cil.circuity.api.vm.device.Resettable;
|
||||
import li.cil.circuity.api.vm.device.Steppable;
|
||||
import li.cil.circuity.api.vm.device.memory.MemoryMappedDevice;
|
||||
import li.cil.circuity.api.vm.device.memory.Sizes;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
@@ -221,7 +222,7 @@ public final class UART16550A implements Resettable, Steppable, MemoryMappedDevi
|
||||
|
||||
@Override
|
||||
public int load(final int offset, final int sizeLog2) {
|
||||
assert sizeLog2 == 0;
|
||||
assert sizeLog2 == Sizes.SIZE_8_LOG2;
|
||||
switch (offset) {
|
||||
// case UART_DLL_OFFSET:
|
||||
case UART_RBR_OFFSET: {
|
||||
@@ -318,7 +319,7 @@ public final class UART16550A implements Resettable, Steppable, MemoryMappedDevi
|
||||
|
||||
@Override
|
||||
public void store(final int offset, final int value, final int sizeLog2) {
|
||||
assert sizeLog2 == 0;
|
||||
assert sizeLog2 == Sizes.SIZE_8_LOG2;
|
||||
switch (offset) {
|
||||
// case UART_DLL_OFFSET:
|
||||
case UART_THR_OFFSET: {
|
||||
|
||||
@@ -62,14 +62,4 @@ public class ByteBufferMemory implements PhysicalMemory {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuffer slice(final int offset, final int length) {
|
||||
final int limit = data.limit();
|
||||
data.position(offset);
|
||||
data.limit(offset + length);
|
||||
final ByteBuffer result = data.slice();
|
||||
result.order(ByteOrder.LITTLE_ENDIAN);
|
||||
data.limit(limit);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1845,27 +1845,27 @@ public class R5CPU implements Steppable, InterruptController {
|
||||
}
|
||||
|
||||
private byte load8(final int address) throws MemoryAccessException {
|
||||
return (byte) load(address, 8, 0);
|
||||
return (byte) load(address, Sizes.SIZE_8, Sizes.SIZE_8_LOG2);
|
||||
}
|
||||
|
||||
private void store8(final int address, final byte value) throws MemoryAccessException {
|
||||
store(address, value, 8, 0);
|
||||
store(address, value, Sizes.SIZE_8, Sizes.SIZE_8_LOG2);
|
||||
}
|
||||
|
||||
private short load16(final int address) throws MemoryAccessException {
|
||||
return (short) load(address, 16, 1);
|
||||
return (short) load(address, Sizes.SIZE_16, Sizes.SIZE_16_LOG2);
|
||||
}
|
||||
|
||||
private void store16(final int address, final short value) throws MemoryAccessException {
|
||||
store(address, value, 16, 1);
|
||||
store(address, value, Sizes.SIZE_16, Sizes.SIZE_16_LOG2);
|
||||
}
|
||||
|
||||
private int load32(final int address) throws MemoryAccessException {
|
||||
return load(address, 32, 2);
|
||||
return load(address, Sizes.SIZE_32, Sizes.SIZE_32_LOG2);
|
||||
}
|
||||
|
||||
private void store32(final int address, final int value) throws MemoryAccessException {
|
||||
store(address, value, 32, 2);
|
||||
store(address, value, Sizes.SIZE_32, Sizes.SIZE_32_LOG2);
|
||||
}
|
||||
|
||||
private int fetch(final int address) throws MemoryAccessException {
|
||||
@@ -1890,16 +1890,7 @@ public class R5CPU implements Steppable, InterruptController {
|
||||
final int virtualAddress = address & ~(R5.PAGE_ADDRESS_MASK & ~alignmentMask);
|
||||
final TLBEntry entry = tlb_read[tlbIndex];
|
||||
if (entry.virtualAddress == virtualAddress) {
|
||||
switch (sizeLog2) {
|
||||
case 0:
|
||||
return entry.memory.get(address + entry.toLocal);
|
||||
case 1:
|
||||
return entry.memory.getShort(address + entry.toLocal);
|
||||
case 2:
|
||||
return entry.memory.getInt(address + entry.toLocal);
|
||||
default:
|
||||
throw new AssertionError();
|
||||
}
|
||||
return entry.device.load(address + entry.toOffset, sizeLog2);
|
||||
} else {
|
||||
return loadSlow(address, sizeLog2);
|
||||
}
|
||||
@@ -1912,19 +1903,7 @@ public class R5CPU implements Steppable, InterruptController {
|
||||
final int virtualAddress = address & ~(R5.PAGE_ADDRESS_MASK & ~alignmentMask);
|
||||
final TLBEntry entry = tlb_write[tlbIndex];
|
||||
if (entry.virtualAddress == virtualAddress) {
|
||||
switch (sizeLog2) {
|
||||
case 0:
|
||||
entry.memory.put(address + entry.toLocal, (byte) value);
|
||||
break;
|
||||
case 1:
|
||||
entry.memory.putShort(address + entry.toLocal, (short) value);
|
||||
break;
|
||||
case 2:
|
||||
entry.memory.putInt(address + entry.toLocal, value);
|
||||
break;
|
||||
default:
|
||||
throw new AssertionError();
|
||||
}
|
||||
entry.device.store(address + entry.toOffset, value, sizeLog2);
|
||||
} else {
|
||||
storeSlow(address, value, sizeLog2);
|
||||
}
|
||||
@@ -1954,17 +1933,7 @@ public class R5CPU implements Steppable, InterruptController {
|
||||
return 0;
|
||||
} else if (range.device instanceof PhysicalMemory) {
|
||||
final TLBEntry entry = updateTLB(tlb_read, address, physicalAddress, range);
|
||||
final int offset = address + entry.toLocal;
|
||||
switch (sizeLog2) {
|
||||
case 0:
|
||||
return entry.memory.get(offset);
|
||||
case 1:
|
||||
return entry.memory.getShort(offset);
|
||||
case 2:
|
||||
return entry.memory.getInt(offset);
|
||||
default:
|
||||
throw new AssertionError();
|
||||
}
|
||||
return entry.device.load(address + entry.toOffset, sizeLog2);
|
||||
} else {
|
||||
return range.device.load(physicalAddress - range.start, sizeLog2);
|
||||
}
|
||||
@@ -1983,21 +1952,8 @@ public class R5CPU implements Steppable, InterruptController {
|
||||
LOGGER.debug("Trying to store to invalid physical address [{}].", address);
|
||||
} else if (range.device instanceof PhysicalMemory) {
|
||||
final TLBEntry entry = updateTLB(tlb_write, address, physicalAddress, range);
|
||||
final int offset = address + entry.toLocal;
|
||||
switch (sizeLog2) {
|
||||
case 0:
|
||||
entry.memory.put(offset, (byte) value);
|
||||
break;
|
||||
case 1:
|
||||
entry.memory.putShort(offset, (short) value);
|
||||
break;
|
||||
case 2:
|
||||
entry.memory.putInt(offset, value);
|
||||
break;
|
||||
default:
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
final int offset = address + entry.toOffset;
|
||||
entry.device.store(offset, value, sizeLog2);
|
||||
physicalMemory.setDirty(range, offset);
|
||||
} else {
|
||||
range.device.store(physicalAddress - range.start, value, sizeLog2);
|
||||
@@ -2108,12 +2064,10 @@ public class R5CPU implements Steppable, InterruptController {
|
||||
final int tlbIndex = (address >>> R5.PAGE_ADDRESS_SHIFT) & (TLB_SIZE - 1);
|
||||
final int virtualAddress = address & ~R5.PAGE_ADDRESS_MASK;
|
||||
|
||||
// TODO Only grab a slice as big as the memory region covered by the TLB entry... I can't math right now.
|
||||
|
||||
final TLBEntry entry = tlb[tlbIndex];
|
||||
entry.virtualAddress = virtualAddress;
|
||||
entry.toLocal = physicalAddress - address - range.start;
|
||||
entry.memory = ((PhysicalMemory) range.device).slice(0, range.end - range.start + 1);
|
||||
entry.toOffset = physicalAddress - address - range.start;
|
||||
entry.device = range.device;
|
||||
|
||||
return entry;
|
||||
}
|
||||
@@ -2176,8 +2130,8 @@ public class R5CPU implements Steppable, InterruptController {
|
||||
|
||||
private static final class TLBEntry {
|
||||
public int virtualAddress = -1;
|
||||
public int toLocal;
|
||||
public ByteBuffer memory;
|
||||
public int toOffset;
|
||||
public MemoryMappedDevice device;
|
||||
}
|
||||
|
||||
public R5CPUStateSnapshot getState() {
|
||||
|
||||
@@ -4,6 +4,7 @@ import li.cil.circuity.api.vm.Interrupt;
|
||||
import li.cil.circuity.api.vm.device.InterruptSource;
|
||||
import li.cil.circuity.api.vm.device.Steppable;
|
||||
import li.cil.circuity.api.vm.device.memory.MemoryMappedDevice;
|
||||
import li.cil.circuity.api.vm.device.memory.Sizes;
|
||||
import li.cil.circuity.api.vm.device.rtc.RealTimeCounter;
|
||||
import li.cil.circuity.vm.riscv.R5;
|
||||
|
||||
@@ -56,7 +57,7 @@ public final class R5CoreLocalInterrupter implements Steppable, InterruptSource,
|
||||
|
||||
@Override
|
||||
public int load(final int offset, final int sizeLog2) {
|
||||
assert sizeLog2 == 2;
|
||||
assert sizeLog2 == Sizes.SIZE_32_LOG2;
|
||||
switch (offset) {
|
||||
case 0x4000: {
|
||||
return (int) mtimecmp;
|
||||
@@ -78,7 +79,7 @@ public final class R5CoreLocalInterrupter implements Steppable, InterruptSource,
|
||||
|
||||
@Override
|
||||
public void store(final int offset, final int value, final int sizeLog2) {
|
||||
assert sizeLog2 == 2;
|
||||
assert sizeLog2 == Sizes.SIZE_32_LOG2;
|
||||
switch (offset) {
|
||||
case 0x4000: {
|
||||
mtimecmp = (mtimecmp & ~0xFFFFFFFFL) | (value & 0xFFFFFFFFL);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package li.cil.circuity.vm.riscv.device;
|
||||
|
||||
import li.cil.circuity.api.vm.device.memory.MemoryMappedDevice;
|
||||
import li.cil.circuity.api.vm.device.memory.Sizes;
|
||||
|
||||
public final class R5HostTargetInterface implements MemoryMappedDevice {
|
||||
public static final int COMMAND_POWER_OFF = 1;
|
||||
@@ -14,7 +15,7 @@ public final class R5HostTargetInterface implements MemoryMappedDevice {
|
||||
|
||||
@Override
|
||||
public int load(final int offset, final int sizeLog2) {
|
||||
assert sizeLog2 == 2;
|
||||
assert sizeLog2 == Sizes.SIZE_32_LOG2;
|
||||
switch (offset) {
|
||||
case 0: {
|
||||
return (int) toHost;
|
||||
@@ -37,7 +38,7 @@ public final class R5HostTargetInterface implements MemoryMappedDevice {
|
||||
|
||||
@Override
|
||||
public void store(final int offset, final int value, final int sizeLog2) {
|
||||
assert sizeLog2 == 2;
|
||||
assert sizeLog2 == Sizes.SIZE_32_LOG2;
|
||||
switch (offset) {
|
||||
case 0: {
|
||||
toHost = (toHost & ~0xFFFFFFFFL) | value;
|
||||
|
||||
Reference in New Issue
Block a user