Extend how interrupts are reported to the main execution loop

Some things that were previously hard VM-level errors are now handled by
interrupts. While this is relatively easy to handle, I was wanting a
little more structure for the error types - so, errors that should
invoke an interrupt are passed along in their own structure in a
VmError::Interrupt variant. If an error is raised during the tick()
phase of execution that would cause an interrupt, that interrupt is
intercepted and the VM continues.

The State::interrupt() function also will catch double faults and triple
faults, with a triple fault being its own variant in the VmError
structure (so it cannot be intercepted as an interrupt by accident).

Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
This commit is contained in:
2020-03-12 16:56:20 -04:00
parent cb75bf59e0
commit bff9220fb1
8 changed files with 146 additions and 52 deletions

View File

@@ -1,9 +1,15 @@
.section code 0x1000 {
main:
; Test that interrupts will not called when enabled flag is not set
int 0, 0
; (using 0x80 because anything below it is an error interrupt, and
; invoking an error interrupt when disabled will cascade to a triple
; fault)
mov %status, 1
int 0x80, 0
cmpeq (count), 0
jnz end
jz end
or %flags, 0b100
; Test divide by zero interrupts
@@ -20,6 +26,16 @@
cmpeq (count), 2
jz end
; Test illegal memory address interrupts
add %status, 1
; TODO - fix this bug, this line breaks because it's trying to
; calculate an address that's too large without using wrapping addition
; functions
;mov %status, (0xfffffffffffffff)
mov %status, (0xffffffff)
cmpeq (count), 3
jz end
mov %status, 0
end:
halt
@@ -37,7 +53,7 @@
ivt:
.interrupt 0, 0
.interrupt 0, 0
.interrupt 0, 0
.interrupt 1, generic_handler
.interrupt 1, generic_handler
.export ivt
}