summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--Makefile7
-rw-r--r--stage3/shell.c35
-rw-r--r--stage3/watchdog.lua73
4 files changed, 113 insertions, 3 deletions
diff --git a/.gitignore b/.gitignore
index eb17186..273eb2f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,6 +7,7 @@
.version-*
bx_enh_dbg.ini
stage3/isr.asm
+stage3/watchdog.asm
fs.tar
stage3/version.c
stage3/font_builtin.c
diff --git a/Makefile b/Makefile
index 5a50a97..3b1a428 100644
--- a/Makefile
+++ b/Makefile
@@ -34,7 +34,8 @@ STAGE3_C = \
STAGE3 = $(STAGE3_C) \
stage3/isr.o \
stage3/yield.o \
- stage3/paging.o
+ stage3/paging.o \
+ stage3/watchdog.o
PAD_BOUNDARY = pad() { truncate -s $$(echo "($$(du -b $$1 | cut -f1)+$$2-1)/$$2*$$2" | bc) $$1; }; pad
DISAS = objdump -b binary -D -M intel -m i386:x86-64 stage3.bin --adjust-vma 0x9000
@@ -80,8 +81,8 @@ GIT_VERSION := $(shell git describe --tags 2>/dev/null || git rev-parse --short
stage3/version.c: .version-$(GIT_VERSION)
echo -e "#include \"def.h\"\nstr version = S(\"$(GIT_VERSION)\");" > $@
-stage3/isr.asm: stage3/isr.lua
- lua stage3/isr.lua > stage3/isr.asm
+stage3/%.asm: stage3/%.lua
+ lua $< > $@
stage3/font.c: stage3/font_builtin.c
diff --git a/stage3/shell.c b/stage3/shell.c
index 7341eea..5b79e58 100644
--- a/stage3/shell.c
+++ b/stage3/shell.c
@@ -267,6 +267,40 @@ void cmd_cheese(str arg)
free(texture);
}
+struct __attribute__((packed)) {
+ u64 reg;
+ u64 to;
+ u64 from;
+} watchdog_err;
+
+void watchdog();
+
+static void cmd_watchdog(str arg)
+{
+ (void) arg;
+
+ str regs[] = {
+ S("rax"), S("rbx"),
+ S("rcx"), S("rdx"),
+ S("rdi"), S("rsi"),
+ S("rbp"), S("rsp"),
+ S("r8"), S("r9"),
+ S("r10"), S("r11"),
+ S("r12"), S("r13"),
+ S("r14"), S("r15"),
+ };
+
+ watchdog();
+
+ print(S("watchdog: register "));
+ print(regs[watchdog_err.reg]);
+ print(S(" changed from "));
+ print_hex(watchdog_err.from);
+ print(S(" to "));
+ print_hex(watchdog_err.to);
+ print(S("\n"));
+}
+
typedef struct {
str name;
void (*fn)(str arg);
@@ -287,6 +321,7 @@ static command registry[] = {
{ S("ls"), &cmd_ls },
{ S("shutdown"), &cmd_shutdown },
{ S("cheese"), &cmd_cheese },
+ { S("watchdog"), &cmd_watchdog },
};
void shell_run_cmd(str cmd)
diff --git a/stage3/watchdog.lua b/stage3/watchdog.lua
new file mode 100644
index 0000000..dac4d57
--- /dev/null
+++ b/stage3/watchdog.lua
@@ -0,0 +1,73 @@
+local regs = {
+ "rax", "rbx",
+ "rcx", "rdx",
+ "rdi", "rsi",
+ "rbp", "rsp",
+ "r8", "r9",
+ "r10", "r11",
+ "r12", "r13",
+ "r14", "r15",
+}
+
+print("global watchdog")
+print("extern rand, watchdog_err")
+
+print("regs_backup: resq 16")
+print("regs_rand: resq 16")
+
+print("watchdog:")
+
+local function iter_regs(f)
+ for i, r in ipairs(regs) do
+ f(i-1, r)
+ end
+end
+
+-- backup registers
+iter_regs(function(i, r) print("mov [regs_backup+" .. (8*i) .. "], " .. r) end)
+
+-- populate random table
+iter_regs(function(i) print("xor rax, rax\ncall rand\nmov [regs_rand+" .. (8*i) .. "], rax") end)
+
+-- read registers from random table
+iter_regs(function(i, r)
+ if r == "rsp" then
+ print("mov [regs_rand+" .. (8*i) .. "], rsp")
+ else
+ print("mov " .. r .. ", [regs_rand+" .. (8*i) .. "]")
+ end
+end)
+
+print(".loop:")
+
+-- wait for interrupts
+print("hlt")
+
+-- check and jump if changed
+iter_regs(function(i, r)
+ print("cmp " .. r .. ", [regs_rand+" .. (8*i) .. "]")
+ print("jne .ch_" .. r)
+end)
+
+print("jmp .loop")
+
+-- write error and return
+iter_regs(function(i, r)
+ print(".ch_" .. r .. ":")
+ print("mov qword[watchdog_err], " .. i)
+ print("mov qword[watchdog_err+8], " .. r)
+ print("mov rax, [regs_rand+" .. (8*i) .. "]")
+ print("mov qword[watchdog_err+16], rax")
+ print("jmp .ret")
+end)
+
+print(".ret:")
+
+-- restore registers
+iter_regs(function(i, r)
+ if r ~= "rsp" then
+ print("mov " .. r .. ", [regs_backup+" .. (8*i) .. "]")
+ end
+end)
+
+print("ret")