summaryrefslogtreecommitdiff
path: root/stage3/watchdog.lua
blob: dac4d57f0e882993e5cf2d3a77cdd0fd3ed60b17 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
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")