mirror of
https://github.com/curioustorvald/tsvm.git
synced 2026-03-07 11:51:49 +09:00
RESET and SYSRQ is now trapped by a hypervisor
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user