summaryrefslogtreecommitdiff
path: root/Source/Kernel/Core/Sys.ns.cpp
blob: c5af3e87ff3cbf4cfeb62604515cfd34b7e6dd67 (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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
//This automatically includes Sys.ns.h
#include <common.h>
#include <Core/Log.ns.h>
#include <VTManager/SimpleVT.class.h>
#include <SyscallManager/IDT.ns.h>
#include <Sys.iface.h>
#include <UserManager/Usr.ns.h>
#include <MemoryManager/PhysMem.ns.h>
#include <DeviceManager/Time.ns.h>

#define DEBUGVT(x) SimpleVT *x = new SimpleVT(4, 56, PANIC_FGCOLOR, PANIC_BGCOLOR); 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));
}

void outw (u16int port, u16int value) {
	asm volatile ("outw %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;
	}
}

void dumpRegs(registers_t *regs, VirtualTerminal& vt) {
	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";
}

void stackTrace(u32int ebp, VirtualTerminal& vt, u32int maxframes) {
	u32int *stack = (u32int*)ebp;
	for (u32int i = 0; i < maxframes and (u32int)stack > 0xC0000000 and (u32int)stack < (ebp + 0x10000); i++) {
		vt << "Frame: " << (u32int)stack << " n:" << stack[0] << " r:" << stack[1] << "\n";
		stack = (u32int*)stack[0];
	}
}

//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");

	SimpleVT vt(15, 70, BSOD_FGCOLOR, BSOD_BGCOLOR);
	vt.map();
	vt.write("\n");

	vt << "PANIC : " << message << "\n => in " << file << " at " << (s32int)line << "\n\n";
	dumpRegs(regs, vt);

	if (regs->int_no == 14) {
		u32int cr2;
		asm volatile("mov %%cr2, %0" : "=r"(cr2));
		vt << "cr2=" << (u32int)cr2 << "\n";
	}
	vt << "\n";

	stackTrace(regs->ebp, vt, 5);

	while (1) asm volatile("cli; 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 shutdown_cleanup() {
	asm volatile("cli");
	Log::close();
}

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

void halt() {
	shutdown_cleanup();
	String message("MELON SEZ : KTHXBYE, U CAN NAOW TURNZ OFF UR COMPUTER.");
	SimpleVT vt(3, message.size() + 16, HALT_FGCOLOR, HALT_BGCOLOR);
	vt.map();
	vt << "\n\t" << message;
	while (1) asm volatile("cli; hlt");
}

u32int scall(u8int wat, u32int a, u32int b, u32int c, u32int d) {
	if (wat == SYIF_HALT && ISROOT) halt();
	if (wat == SYIF_REBOOT && ISROOT) reboot();
	if (wat == SYIF_UPTIME) return Time::uptime();
	if (wat == SYIF_TOTALRAM) return PhysMem::total() * 4;
	if (wat == SYIF_FREERAM) return PhysMem::free() * 4;
	return (u32int) - 1;
}

}