summaryrefslogtreecommitdiff
path: root/Source/Kernel/Core/Sys.ns.cpp
blob: ab57589d792b5c3db9152101e79ba7cf3a36b75e (plain) (blame)
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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
//This automatically includes Sys.ns.h
#include <Core/common.wtf.h>
#include <VTManager/VirtualTerminal.class.h>
#include <SyscallManager/IDT.ns.h>

#define DEBUGVT(x) VirtualTerminal *x = new VirtualTerminal(4, 56, 0, 15); x->map(); x->put('\n');

using namespace CMem;

namespace Sys {

void outb (u16int port, u8int value) {
	asm volatile ("outb %1, %0" : : "dN" (port), "a" (value));
}

u8int inb (u16int port) {
	u8int ret;
	asm volatile ("inb %1, %0" : "=a" (ret) : "dN" (port));
	return ret;
}

u16int inw (u16int port) {
	u16int ret;
	asm volatile ("inw %1, %0" : "=a" (ret) : "dN" (port));
	return ret;
}

//Used by DEBUG() macro (see common.wtf.h)
void bochs_output(char *message, char *file, u32int line) {
	for (u32int i = 0; i < strlen(message); i++) {
		outb(0xE9, message[i]);
	}
	char* t = (char*)" (in ";
	for (u32int i = 0; i < strlen(t); i++) {
		outb(0xE9, t[i]);
	}
	for (u32int i = 0; i < strlen(file); i++) {
		outb(0xE9, file[i]);
	}
	outb(0xE9, ')');
	outb(0xE9, '\n');
} 

void bochs_output(String message, char *file, u32int line) {
	for (u32int i = 0; i < message.size(); i++) {
		outb(0xE9, message[i].toAscii());
	}
	char* t = (char*)" (in ";
	for (u32int i = 0; i < strlen(t); i++) {
		outb(0xE9, t[i]);
	}
	for (u32int i = 0; i < strlen(file); i++) {
		outb(0xE9, file[i]);
	}
	outb(0xE9, ')');
	outb(0xE9, '\n');
} 

void bochs_output_hex(u32int i) {
	char hexdigits[] = "0123456789ABCDEF";
	outb(0xE9, '0');
	outb(0xE9, 'x');
	for (u32int j = 0; j < 8; j++) {
		outb(0xE9, hexdigits[(i & 0xF0000000) >> 28]);
		i = i << 4;
	}
}

//Used by PANIC() macro (see common.wtf.h)
void panic(char *message, char *file, u32int line) {
	asm volatile("cli");

	DEBUGVT(vt);
	bochs_output("PANIC : ", file, line);
	bochs_output(message, file, 0);
	*vt << "  PANIC : " << message << "\n    In " << file << ":" << (s32int)line;

	while (1) asm volatile("hlt"); //Enter infinite loop for halt
}

void panic(char *message, registers_t *regs, char *file, u32int line) {
	asm volatile("cli");

	VirtualTerminal vt(20, 70, 7, 1);
	vt.map();

	vt << "PANIC : " << message << "\n => in " << file << " at " << (s32int)line << "\n\n";
	vt << "ds=" << (u32int)regs->ds << ", eip=" << (u32int)regs->eip << ", cs=" << (u32int)regs->cs << "\n";
	vt << "edi=" << (u32int)regs->edi << ", esi=" << (u32int)regs->esi << ", ebp=" << (u32int)regs->ebp <<
		", esp=" << (u32int)regs->esp << "\n";
	vt << "eax=" << (u32int)regs->eax << ", ebx=" << (u32int)regs->ebx << ", ecx=" << (u32int)regs->ecx <<
		", edx=" << (u32int)regs->edx << "\n";
	vt << "int_no=" << (s32int)regs->int_no << ", err_code=" << (u32int)regs->err_code << "\n";
	vt << "eflags=" << (u32int)regs->eflags << ", useresp=" << (u32int)regs->useresp << ", ss=" << (u32int)regs->ss << "\n\n";

	u32int *v = (u32int*)regs->ebp;
	for (int i = 0; i < 10; i++) {
		vt << "ebp=" << (u32int)v << ", value=" << (u32int)(v[1]) << "\n";
		v = (u32int*)(*v);
	}

	while (1) asm volatile("hlt");
}

//Used by ASSERT() macro (see common.wtf.h)
void panic_assert(char *file, u32int line, char *desc) {
	asm volatile("cli");

	DEBUGVT(vt);
	bochs_output("ASSERTION FAILED : ", file, line);
	bochs_output(desc, file, 0);
	*vt << "  ASSERTION FAILED : " << desc << "\n    In " << file << ":" << (s32int)line;

	while (1) asm volatile("hlt"); //Enter infinite loop for halt
}

void reboot() {
	outb(0x64, 0xFE);
}

}