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>
76 lines
1.5 KiB
NASM
76 lines
1.5 KiB
NASM
.section code 0x1000 {
|
|
main:
|
|
; Test that interrupts will not called when enabled flag is not set
|
|
; (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
|
|
jz end
|
|
|
|
or %flags, 0b100
|
|
|
|
; Test divide by zero interrupts
|
|
|
|
; div
|
|
add %status, 1
|
|
mov %r0, 1
|
|
div %r0, 0
|
|
cmpeq (count), 1
|
|
jz end
|
|
|
|
; idiv
|
|
add %status, 1
|
|
idiv %r0, 0
|
|
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
|
|
|
|
.align u64
|
|
generic_handler:
|
|
add (count), 1
|
|
iret
|
|
|
|
.export main
|
|
.export generic_handler
|
|
}
|
|
|
|
.section ivt 0x1800 {
|
|
ivt:
|
|
.interrupt 0, 0
|
|
.interrupt 0, 0
|
|
.interrupt 1, generic_handler
|
|
.interrupt 1, generic_handler
|
|
.export ivt
|
|
}
|
|
|
|
.section shared 0x2000 {
|
|
count: .u64 0
|
|
.export count
|
|
}
|
|
|
|
.section stack 0x4000 .. 0x5000 {
|
|
stack_base:
|
|
.export stack_base
|
|
}
|
|
|
|
.meta {
|
|
ip: main
|
|
sp: stack_base
|
|
ivt: ivt
|
|
}
|