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:
2020-03-10 12:18:31 -04:00
parent 3522b3d0cd
commit 551bd2c3f4
8 changed files with 103 additions and 11 deletions

View File

@@ -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
} }

View File

@@ -24,5 +24,5 @@
} }
.meta { .meta {
entry: main ip: main
} }

View File

@@ -26,5 +26,5 @@
} }
.meta { .meta {
entry: main ip: main
} }

View File

@@ -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);
}
} }
} }
} }

View File

@@ -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
} }

View File

@@ -74,7 +74,7 @@
} }
.meta { .meta {
entry: main ip: main
} }

View File

@@ -31,6 +31,6 @@
} }
.meta { .meta {
entry: main ip: main
} }

52
tests/test_interrupts.asm Normal file
View 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
}