Gave up and accepted we need bootargs (for now), so those can be set on board now.
This commit is contained in:
@@ -12,10 +12,7 @@ import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.*;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public final class Main {
|
||||
@@ -35,25 +32,28 @@ public final class Main {
|
||||
}
|
||||
|
||||
private static void runEmulator() throws Exception {
|
||||
final String firmware = "buildroot/output/images/fw_jump.bin";
|
||||
final String kernel = "buildroot/output/images/Image";
|
||||
final File rootfsFile = new File("buildroot/output/images/rootfs.ext2");
|
||||
|
||||
final R5Board board = new R5Board();
|
||||
final PhysicalMemory rom = Memory.create(128 * 1024);
|
||||
final PhysicalMemory memory = Memory.create(32 * 1014 * 1024);
|
||||
final UART16550A uart = new UART16550A();
|
||||
final VirtIOBlockDevice hdd = new VirtIOBlockDevice(board.getMemoryMap(), ByteBufferBlockDevice.create(32 * 1024 * 1024, false));
|
||||
final VirtIOBlockDevice hdd = new VirtIOBlockDevice(board.getMemoryMap(), ByteBufferBlockDevice.createFromFile(rootfsFile, true));
|
||||
|
||||
uart.getInterrupt().set(0xA, board.getInterruptController());
|
||||
hdd.getInterrupt().set(0x1, board.getInterruptController());
|
||||
|
||||
board.addDevice(0x80000000, rom);
|
||||
board.addDevice(0x80000000 + 0x400000, memory);
|
||||
board.addDevice(uart);
|
||||
board.addDevice(hdd);
|
||||
|
||||
uart.getInterrupt().set(0xA, board.getInterruptController());
|
||||
hdd.getInterrupt().set(0x1, board.getInterruptController());
|
||||
board.setBootargs("console=ttyS0 root=/dev/vda ro");
|
||||
|
||||
board.reset();
|
||||
|
||||
final String firmware = "buildroot/fw_jump.bin";
|
||||
final String kernel = "buildroot/Image";
|
||||
|
||||
loadProgramFile(memory, 0, kernel);
|
||||
loadProgramFile(rom, 0, firmware);
|
||||
|
||||
@@ -105,8 +105,10 @@ public final class Main {
|
||||
board.addDevice(0x80000000, rom);
|
||||
board.addDevice(0x80000000 + 0x400000, memory);
|
||||
|
||||
final String firmware = "buildroot/fw_jump.bin";
|
||||
final String kernel = "buildroot/Image";
|
||||
board.setBootargs("console=ttyS0");
|
||||
|
||||
final String firmware = "buildroot/output/images/fw_jump.bin";
|
||||
final String kernel = "buildroot/output/images/Image_Benchmark";
|
||||
|
||||
LOGGER.info("Waiting for profiler...");
|
||||
Thread.sleep(5 * 1000);
|
||||
|
||||
@@ -7,8 +7,10 @@ import li.cil.circuity.api.vm.device.memory.Sizes;
|
||||
import li.cil.circuity.client.gui.terminal.Terminal;
|
||||
import li.cil.circuity.client.gui.terminal.TerminalInput;
|
||||
import li.cil.circuity.common.vm.VirtualMachineRunner;
|
||||
import li.cil.circuity.vm.device.ByteBufferBlockDevice;
|
||||
import li.cil.circuity.vm.device.UART16550A;
|
||||
import li.cil.circuity.vm.device.memory.Memory;
|
||||
import li.cil.circuity.vm.device.virtio.VirtIOBlockDevice;
|
||||
import li.cil.circuity.vm.device.virtio.VirtIOConsoleDevice;
|
||||
import li.cil.circuity.vm.device.virtio.VirtIOKeyboardDevice;
|
||||
import li.cil.circuity.vm.riscv.R5Board;
|
||||
@@ -19,6 +21,7 @@ import org.apache.logging.log4j.Logger;
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.util.Objects;
|
||||
|
||||
@@ -47,80 +50,16 @@ public final class RISCVTestScreen extends Screen {
|
||||
protected void init() {
|
||||
super.init();
|
||||
|
||||
final R5Board board = new R5Board();
|
||||
final PhysicalMemory rom = Memory.create(128 * 1024);
|
||||
final PhysicalMemory memory = Memory.create(128 * 1014 * 1024);
|
||||
|
||||
if (USE_VIRT_IO) {
|
||||
uart = new UART16550A();
|
||||
uart.getInterrupt().set(0xA, board.getInterruptController());
|
||||
|
||||
board.addDevice(uart);
|
||||
} else {
|
||||
console = new VirtIOConsoleDevice(board.getMemoryMap());
|
||||
console.getInterrupt().set(0x1, board.getInterruptController());
|
||||
|
||||
keyboard = new VirtIOKeyboardDevice(board.getMemoryMap());
|
||||
keyboard.getInterrupt().set(0x2, board.getInterruptController());
|
||||
|
||||
board.addDevice(console);
|
||||
board.addDevice(keyboard);
|
||||
try {
|
||||
createVirtualMachine();
|
||||
} catch (final Throwable e) {
|
||||
LOGGER.error(e);
|
||||
if (minecraft != null && minecraft.player != null) {
|
||||
minecraft.player.sendChatMessage("Failed creating VM: " + e.toString());
|
||||
minecraft.displayGuiScreen(null);
|
||||
}
|
||||
}
|
||||
|
||||
board.addDevice(0x80000000, rom);
|
||||
board.addDevice(0x80000000 + 0x400000, memory);
|
||||
board.reset();
|
||||
|
||||
final String firmware = "../buildroot/fw_jump.bin";
|
||||
final String kernel = "../buildroot/Image";
|
||||
|
||||
loadProgramFile(memory, kernel);
|
||||
loadProgramFile(rom, firmware);
|
||||
|
||||
runner = new VirtualMachineRunner(board) {
|
||||
// Thread-local buffers for lock-free read/writes in inner loop.
|
||||
private final ByteArrayFIFOQueue outputBuffer = new ByteArrayFIFOQueue(1024);
|
||||
private final ByteArrayFIFOQueue inputBuffer = new ByteArrayFIFOQueue(32);
|
||||
|
||||
@Override
|
||||
protected void handleBeforeRun() {
|
||||
int value;
|
||||
while ((value = terminal.readInput()) != -1) {
|
||||
inputBuffer.enqueue((byte) value);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void step() {
|
||||
if (USE_VIRT_IO) {
|
||||
boolean wrote = false;
|
||||
while (!inputBuffer.isEmpty() && console.canPutByte()) {
|
||||
wrote = true;
|
||||
console.putByte(inputBuffer.dequeueByte());
|
||||
}
|
||||
if (wrote) {
|
||||
console.flush();
|
||||
}
|
||||
} else {
|
||||
while (!inputBuffer.isEmpty() && uart.canPutByte()) {
|
||||
uart.putByte(inputBuffer.dequeueByte());
|
||||
}
|
||||
}
|
||||
|
||||
int value;
|
||||
while ((value = uart.read()) != -1) {
|
||||
outputBuffer.enqueue((byte) value);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void handleAfterRun() {
|
||||
while (!outputBuffer.isEmpty()) {
|
||||
terminal.putOutput(outputBuffer.dequeueByte());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if (minecraft != null) {
|
||||
minecraft.keyboardListener.enableRepeatEvents(true);
|
||||
}
|
||||
@@ -139,8 +78,10 @@ public final class RISCVTestScreen extends Screen {
|
||||
public void tick() {
|
||||
super.tick();
|
||||
|
||||
// Allow VM to run for the next second.
|
||||
runner.tick();
|
||||
if (runner != null) {
|
||||
// Allow VM to run for the next second.
|
||||
runner.tick();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -207,6 +148,56 @@ public final class RISCVTestScreen extends Screen {
|
||||
return super.keyReleased(keyCode, scanCode, modifiers);
|
||||
}
|
||||
|
||||
private void createVirtualMachine() throws Throwable {
|
||||
final String firmware = "../buildroot/output/images/fw_jump.bin";
|
||||
final String kernel = "../buildroot/output/images/Image";
|
||||
final File rootfsFile = new File("../buildroot/output/images/rootfs.ext2");
|
||||
|
||||
final R5Board board = new R5Board();
|
||||
final PhysicalMemory rom = Memory.create(128 * 1024);
|
||||
final PhysicalMemory memory = Memory.create(32 * 1014 * 1024);
|
||||
final VirtIOBlockDevice hdd = new VirtIOBlockDevice(board.getMemoryMap(), ByteBufferBlockDevice.createFromFile(rootfsFile, true));
|
||||
|
||||
final StringBuilder bootargs = new StringBuilder();
|
||||
bootargs.append("root=/dev/vda ro");
|
||||
|
||||
if (USE_VIRT_IO) {
|
||||
console = new VirtIOConsoleDevice(board.getMemoryMap());
|
||||
keyboard = new VirtIOKeyboardDevice(board.getMemoryMap());
|
||||
|
||||
console.getInterrupt().set(0x1, board.getInterruptController());
|
||||
keyboard.getInterrupt().set(0x2, board.getInterruptController());
|
||||
|
||||
board.addDevice(console);
|
||||
board.addDevice(keyboard);
|
||||
|
||||
bootargs.append(" console=hvc0");
|
||||
} else {
|
||||
uart = new UART16550A();
|
||||
|
||||
uart.getInterrupt().set(0xA, board.getInterruptController());
|
||||
|
||||
board.addDevice(uart);
|
||||
|
||||
bootargs.append(" console=ttyS0");
|
||||
}
|
||||
|
||||
hdd.getInterrupt().set(0x3, board.getInterruptController());
|
||||
|
||||
board.addDevice(hdd);
|
||||
board.addDevice(0x80000000, rom);
|
||||
board.addDevice(0x80000000 + 0x400000, memory);
|
||||
|
||||
board.setBootargs(bootargs.toString());
|
||||
|
||||
board.reset();
|
||||
|
||||
loadProgramFile(memory, kernel);
|
||||
loadProgramFile(rom, firmware);
|
||||
|
||||
runner = new ConsoleRunner(board);
|
||||
}
|
||||
|
||||
private static void loadProgramFile(final PhysicalMemory memory, final String path) {
|
||||
try {
|
||||
try (final FileInputStream is = new FileInputStream(path)) {
|
||||
@@ -219,4 +210,52 @@ public final class RISCVTestScreen extends Screen {
|
||||
LOGGER.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
private final class ConsoleRunner extends VirtualMachineRunner {
|
||||
// Thread-local buffers for lock-free read/writes in inner loop.
|
||||
private final ByteArrayFIFOQueue outputBuffer = new ByteArrayFIFOQueue(1024);
|
||||
private final ByteArrayFIFOQueue inputBuffer = new ByteArrayFIFOQueue(32);
|
||||
|
||||
public ConsoleRunner(final R5Board board) {
|
||||
super(board);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void handleBeforeRun() {
|
||||
int value;
|
||||
while ((value = terminal.readInput()) != -1) {
|
||||
inputBuffer.enqueue((byte) value);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void step() {
|
||||
if (USE_VIRT_IO) {
|
||||
boolean wrote = false;
|
||||
while (!inputBuffer.isEmpty() && console.canPutByte()) {
|
||||
wrote = true;
|
||||
console.putByte(inputBuffer.dequeueByte());
|
||||
}
|
||||
if (wrote) {
|
||||
console.flush();
|
||||
}
|
||||
} else {
|
||||
while (!inputBuffer.isEmpty() && uart.canPutByte()) {
|
||||
uart.putByte(inputBuffer.dequeueByte());
|
||||
}
|
||||
}
|
||||
|
||||
int value;
|
||||
while ((value = uart.read()) != -1) {
|
||||
outputBuffer.enqueue((byte) value);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void handleAfterRun() {
|
||||
while (!outputBuffer.isEmpty()) {
|
||||
terminal.putOutput(outputBuffer.dequeueByte());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,6 +48,8 @@ public final class R5Board implements Steppable, Resettable {
|
||||
private final List<MemoryMappedDevice> devices = new ArrayList<>();
|
||||
private final List<Steppable> steppableDevices = new ArrayList<>();
|
||||
|
||||
private String bootargs;
|
||||
|
||||
public R5Board() {
|
||||
memoryMap = new SimpleMemoryMap();
|
||||
rtc = cpu = new R5CPU(memoryMap);
|
||||
@@ -80,6 +82,13 @@ public final class R5Board implements Steppable, Resettable {
|
||||
return plic;
|
||||
}
|
||||
|
||||
public void setBootargs(final String value) {
|
||||
if (value != null && value.length() > 64) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
this.bootargs = value;
|
||||
}
|
||||
|
||||
public boolean addDevice(final int address, final MemoryMappedDevice device) {
|
||||
if (device.getLength() == 0) {
|
||||
return false;
|
||||
@@ -221,11 +230,10 @@ public final class R5Board implements Steppable, Resettable {
|
||||
DeviceTreeRegistry.visit(root, memoryMap, device);
|
||||
}
|
||||
|
||||
root.putChild("chosen", chosen -> chosen
|
||||
.addProp("bootargs", "console=ttyS0"));
|
||||
|
||||
// root.putChild("chosen", chosen -> chosen
|
||||
// .addProp("bootargs", "console=hvc0"));
|
||||
if (bootargs != null) {
|
||||
root.putChild("chosen", chosen -> chosen
|
||||
.addProp("bootargs", bootargs));
|
||||
}
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user