Files
rasp/tests/test_interrupts.asm
Alek Ratzloff bff9220fb1 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>
2020-03-12 16:56:20 -04:00

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
}