RESET and SYSRQ is now trapped by a hypervisor

This commit is contained in:
minjaesong
2024-09-14 12:23:52 +09:00
parent 8144dddb82
commit 8784b7f35c
6 changed files with 71 additions and 27 deletions

View File

@@ -37,7 +37,7 @@ function print_prompt_text() {
con.addch(16);con.curs_right()
con.color_pair(0,253)
print(" \\"+shell_pwd.join("\\").substring(1)+" ")
if (errorlevel != 0) {
if (errorlevel != 0 && errorlevel != "undefined" && errorlevel != undefined) {
con.color_pair(166,253)
print("["+errorlevel+"] ")
}
@@ -48,7 +48,7 @@ function print_prompt_text() {
}
else {
// con.color_pair(253,255)
if (errorlevel != 0)
if (errorlevel != 0 && errorlevel != "undefined" && errorlevel != undefined)
print(CURRENT_DRIVE + ":\\" + shell_pwd.join("\\") + " [" + errorlevel + "]" + PROMPT_TEXT)
else
print(CURRENT_DRIVE + ":\\" + shell_pwd.join("\\") + PROMPT_TEXT)

View File

@@ -9,8 +9,7 @@ hyve is a hypervisor for tsvm.
3. hands the control over to the TVDOS until SysRq sequence is struck
*/
let context = parallel.spawnNewContext()
let bios = `
const bios = `
// probe bootable device
var _BIOS = {};
@@ -24,8 +23,6 @@ _BIOS.FIRST_BOOTABLE_PORT = [0,1]; // ah screw it
Object.freeze(_BIOS);
///////////////////////////////////////////////////////////////////////////////
// load a bootsector using 'LOADBOOT'
let portNumber = 0;
let driveStatus = 0;
@@ -54,17 +51,46 @@ else {
printerrln("No bootable medium found.");
}
`
let runner = parallel.attachProgram("TVDOS", context, bios)
parallel.launch(runner)
sys.sleep(1000);
let runner = undefined
function startNewInstance() {
runner = parallel.attachProgram("TVDOS", parallel.spawnNewContext(), bios)
serial.println("Starting new instance "+runner)
parallel.launch(runner)
sys.sleep(1000)
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// initial kickstart
startNewInstance()
while (parallel.isRunning(runner)) {
graphics.plotPixel( // test fill the framebuffer to prove VM is shared
(Math.random() * 560) | 0,
(Math.random() * 448) | 0,
(Math.random() * 256) | 0
)
if (sys.peek(-49) >>> 7 == 1) {
sys.poke(-49, 0)
parallel.kill(runner)
graphics.clearText()
graphics.clearPixels(255)
startNewInstance()
}
else if (sys.peek(-49) >>> 6 == 1) {
sys.poke(-49, 0)
let threads = parallel.getThreadPool()
serial.println("======================")
for (let i = 0; i < threads.size; i++) {
serial.println(`Thread #${i+1}: ${threads[i]}`)
}
serial.println("======================")
sys.sleep(300)
}
sys.sleep(0)
}

View File

@@ -74,9 +74,10 @@ MMIO
stores keys that are held down. Can accomodate 8-key rollover (in keyboard geeks' terms)
0x0 is written for the empty area; numbers are always sorted
48..51 RO: System flags
48: 0b r000 000t
48: 0b rq00 000t
t: STOP button (should raise SIGTERM)
r: RESET button (should reset the system)
r: RESET button (hypervisor should reset the system)
q: SysRq button (hypervisor should respond to it)
64..67 RO: User area memory size in bytes
68 WO: Counter latch
@@ -104,10 +105,12 @@ MMIO
90 RO: BMS calculated battery percentage where 255 is 100%
91 RO: BMS battery voltage multiplied by 10 (127 = "12.7 V")
92..127 RW: Used by the hypervisor
1024..2047 RW: Reserved for integrated peripherals (e.g. built-in status display)
2048..4075 RW: Used by the hypervisor
2048..2051 RW: Status flags
4076..4079 RW: 8-bit status code for the port
4080..4083 RO: 8-bit status code for connected device

View File

@@ -103,7 +103,7 @@ class IOSpace(val vm: VM) : PeriBase("io"), InputProcessor {
38L -> keyboardInputRequested.toInt().toByte()
39L -> rawInputFunctionLatched.toInt().toByte()
in 40..47 -> keyEventBuffers[adi - 40]
48L -> ((vm.resetDown.toInt(7)) or (vm.stopDown.toInt())).toByte()
48L -> (vm.resetDown.toInt(7) or vm.sysrqDown.toInt(6) or vm.stopDown.toInt()).toByte()
in 64..67 -> vm.memsize.shr((adi - 64) * 8).toByte()
68L -> (uptimeCounterLatched.toInt() or RTClatched.toInt(1)).toByte()
@@ -116,7 +116,7 @@ class IOSpace(val vm: VM) : PeriBase("io"), InputProcessor {
89L -> ((acpiShutoff.toInt(7)) or (bmsIsBatteryOperated.toInt(3)) or (bmsHasBattery.toInt(1))
or bmsIsCharging.toInt()).toByte()
in 92L..127L -> hyveArea[addr.toInt()]
in 2048L..4075L -> hyveArea[addr.toInt() - 2048]
in 1024..2047 -> peripheralFast[addr - 1024]
@@ -160,7 +160,7 @@ class IOSpace(val vm: VM) : PeriBase("io"), InputProcessor {
}
}
private val hyveArea = ByteArray(128)
private val hyveArea = ByteArray(2048)
override fun mmio_write(addr: Long, byte: Byte) {
val adi = addr.toInt()
@@ -190,7 +190,7 @@ class IOSpace(val vm: VM) : PeriBase("io"), InputProcessor {
acpiShutoff = byte.and(-128).isNonZero()
}
in 92L..127L -> hyveArea[addr.toInt()] = byte
in 2048L..4075L -> hyveArea[addr.toInt() - 2048] = byte
in 1024..2047 -> peripheralFast[addr - 1024] = byte

View File

@@ -285,11 +285,13 @@ class VMEmuExecutable(val windowWidth: Int, val windowHeight: Int, var panelsX:
private fun reboot(profileName: String) {
val vm = currentlyLoadedProfiles[profileName]!!
vmRunners[vm.id]!!.close()
/*vmRunners[vm.id]!!.close()
coroutineJobs[vm.id]!!.interrupt()
vm.init()
initVMenv(vm, profileName)
initVMenv(vm, profileName)*/
// hypervisor will take over by monitoring MMIO addr 48
}
private fun updateGame(delta: Float) {

View File

@@ -59,6 +59,8 @@ class VMGUI(val loaderInfo: EmulInstance, val viewportWidth: Int, val viewportHe
private lateinit var crtShader: ShaderProgram
internal val whatToDoOnVmExceptionQueue = ArrayList<() -> Unit>()
fun loadShaderInline(frag0: String): ShaderProgram {
// insert version code
val frag: String
@@ -156,7 +158,7 @@ class VMGUI(val loaderInfo: EmulInstance, val viewportWidth: Int, val viewportHe
}
catch (e: Throwable) {
e.printStackTrace()
killVMenv()
whatToDoOnVmExceptionQueue.add { killVMenv() }
}
}, "VmRunner:${vm.id}")
coroutineJob.start()
@@ -192,10 +194,12 @@ class VMGUI(val loaderInfo: EmulInstance, val viewportWidth: Int, val viewportHe
private var rebootRequested = false
private fun reboot() {
vmRunner.close()
/*vmRunner.close()
coroutineJob.interrupt()
init()
init()*/
// hypervisor will take over by monitoring MMIO addr 48
}
private var updateAkku = 0.0
@@ -226,6 +230,15 @@ class VMGUI(val loaderInfo: EmulInstance, val viewportWidth: Int, val viewportHe
renderGame(dt)
vm.watchdogs.forEach { (_, watchdog) -> watchdog.update(dt) }
val vmExceptionHandlers = whatToDoOnVmExceptionQueue.toList()
vmExceptionHandlers.forEach { it.invoke() }
synchronized(whatToDoOnVmExceptionQueue) {
vmExceptionHandlers.forEach {
whatToDoOnVmExceptionQueue.remove(it)
}
}
}
private fun updateGame(delta: Float) {