Add initial register states to meta section; remove entry directive
It makes sense to allow users to set the initial register values. This allows someone to e.g. enable interrupts once the VM has started, or set the initial stack pointer value. Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
This commit is contained in:
@@ -40,6 +40,13 @@
|
|||||||
.export ivt
|
.export ivt
|
||||||
}
|
}
|
||||||
|
|
||||||
.meta {
|
.section stack $0x4000 .. $0x5000 {
|
||||||
entry: main
|
stack_base:
|
||||||
|
.export stack_base
|
||||||
|
}
|
||||||
|
|
||||||
|
.meta {
|
||||||
|
ip: main
|
||||||
|
sp: stack_base
|
||||||
|
ivt: ivt
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,5 +24,5 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.meta {
|
.meta {
|
||||||
entry: main
|
ip: main
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,5 +26,5 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.meta {
|
.meta {
|
||||||
entry: main
|
ip: main
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,13 @@
|
|||||||
use crate::{addr::*, error::*, flags::*, inst::*, interrupt::*, mem::*, obj::obj::*, reg::*};
|
use crate::{
|
||||||
|
addr::*,
|
||||||
|
error::*,
|
||||||
|
flags::*,
|
||||||
|
inst::*,
|
||||||
|
interrupt::*,
|
||||||
|
mem::*,
|
||||||
|
obj::{obj::*, syn::parser},
|
||||||
|
reg::*,
|
||||||
|
};
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
|
||||||
pub struct State {
|
pub struct State {
|
||||||
@@ -37,8 +46,32 @@ impl State {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Section::Meta(MetaSection { entries }) => {
|
Section::Meta(MetaSection { entries }) => {
|
||||||
if let Some(addr) = entries.get("entry") {
|
macro_rules! meta_addr {
|
||||||
self.set_reg_unchecked(IP, *addr);
|
($($name:expr, $reg:expr);* $(;)?) => {{
|
||||||
|
$(
|
||||||
|
if let Some(value) = entries.get($name) {
|
||||||
|
self.set_reg_unchecked($reg, *value);
|
||||||
|
}
|
||||||
|
)*
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
|
||||||
|
meta_addr!("ip", IP);
|
||||||
|
meta_addr!("sp", SP);
|
||||||
|
meta_addr!("flags", FLAGS);
|
||||||
|
meta_addr!("status", STATUS);
|
||||||
|
meta_addr!("ivt", IVT);
|
||||||
|
|
||||||
|
if let Some(value) = entries.get("fp") {
|
||||||
|
self.set_reg_unchecked(FP, *value);
|
||||||
|
} else {
|
||||||
|
self.set_reg_unchecked(FP, self.get_reg_unchecked(SP));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (reg, value) in entries.iter() {
|
||||||
|
if let Some(reg) = parser::parse_reg(reg) {
|
||||||
|
self.set_reg_unchecked(reg, *value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
.section data $0x0 {
|
.section data $0x1000 {
|
||||||
number: .u8 $10
|
number: .u8 $10
|
||||||
|
|
||||||
main:
|
main:
|
||||||
@@ -109,6 +109,6 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.meta {
|
.meta {
|
||||||
entry: main
|
ip: main
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -74,7 +74,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.meta {
|
.meta {
|
||||||
entry: main
|
ip: main
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -31,6 +31,6 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.meta {
|
.meta {
|
||||||
entry: main
|
ip: main
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
52
tests/test_interrupts.asm
Normal file
52
tests/test_interrupts.asm
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
.section code $0x0 {
|
||||||
|
main:
|
||||||
|
; Test divide by zero interrupts
|
||||||
|
|
||||||
|
; div
|
||||||
|
mov %status, $1
|
||||||
|
mov %r0, $1
|
||||||
|
div %r0, $0
|
||||||
|
cmpeq (count), $1
|
||||||
|
jz end
|
||||||
|
|
||||||
|
; idiv
|
||||||
|
mov %status, $2
|
||||||
|
idiv %r0, $0
|
||||||
|
cmpeq (count), $2
|
||||||
|
jz end
|
||||||
|
|
||||||
|
mov %status, $0
|
||||||
|
end:
|
||||||
|
halt
|
||||||
|
|
||||||
|
.align u64
|
||||||
|
divide_by_zero:
|
||||||
|
add (count), $1
|
||||||
|
iret
|
||||||
|
|
||||||
|
.export main
|
||||||
|
.export divide_by_zero
|
||||||
|
}
|
||||||
|
|
||||||
|
.section ivt $0x1000 {
|
||||||
|
ivt:
|
||||||
|
.interrupt $1, divide_by_zero
|
||||||
|
.export ivt
|
||||||
|
}
|
||||||
|
|
||||||
|
.section shared $0x2000 {
|
||||||
|
count: .u64 $0
|
||||||
|
.export count
|
||||||
|
}
|
||||||
|
|
||||||
|
.section stack $0x4000 .. $0x5000 {
|
||||||
|
stack_base:
|
||||||
|
.export stack_base
|
||||||
|
}
|
||||||
|
|
||||||
|
.meta {
|
||||||
|
ip: main
|
||||||
|
flags: $0b100
|
||||||
|
sp: stack_base
|
||||||
|
ivt: ivt
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user