summaryrefslogtreecommitdiffhomepage
path: root/dev/Kernel/src/Stop.cc
blob: b8bfdb1b15a93e622bcfbc41dd79e01304e310ba (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
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
/* -------------------------------------------

	Copyright (C) 2024, Theater Quality Inc, all rights reserved.

------------------------------------------- */

#include <NewKit/Stop.h>
#include <ArchKit/ArchKit.h>
#include <KernelKit/Timer.h>
#include <KernelKit/DebugOutput.h>
#include <NewKit/KString.h>
#include <FirmwareKit/Handover.h>
#include <KernelKit/FileMgr.h>
#include <Modules/FB/FB.h>
#include <Modules/FB/Text.h>

#define kWebsiteURL "https://el-mahrouss-logic.com/products/help/"

/* Each error code is attributed with an ID, which will prompt a string onto the
 * screen. Wait for debugger... */

namespace Kernel
{
	/***********************************************************************************/
	/// @brief Stops execution of the kernel.
	/// @param id kernel stop ID.
	/***********************************************************************************/
	Void ke_stop(const Kernel::Int32& id)
	{
		cg_init();

		auto panic_text = RGB(0xff, 0xff, 0xff);

		auto start_y = 50;
		auto x		 = 10;

		if (id != RUNTIME_CHECK_BOOTSTRAP)
			CGDrawString("Kernel Panic!", start_y, x, panic_text);
		else
			CGDrawString("Kernel Bootstrap:", start_y, x, panic_text);

		start_y += 10;

		cg_fini();

		// show text according to error id.

		switch (id)
		{
		case RUNTIME_CHECK_PROCESS: {
			CGDrawString("0x00000008: Invalid process behavior.", start_y, x, panic_text);
			break;
		}
		case RUNTIME_CHECK_ACPI: {
			CGDrawString("0x00000006: ACPI configuration error.", start_y, x, panic_text);
			break;
		}
		case RUNTIME_CHECK_PAGE: {
			CGDrawString("0x0000000B: Write/Read in non paged area.", start_y, x, panic_text);
			break;
		}
		case RUNTIME_CHECK_FILESYSTEM: {
			CGDrawString("0x0000000A: Filesystem driver error.", start_y, x, panic_text);
			break;
		}
		case RUNTIME_CHECK_POINTER: {
			CGDrawString("0x00000000: Kernel heap is corrupted.", start_y, x, panic_text);
			break;
		}
		case RUNTIME_CHECK_BAD_BEHAVIOR: {
			CGDrawString("0x00000009: Bad behavior.", start_y, x, panic_text);
			break;
		}
		case RUNTIME_CHECK_BOOTSTRAP: {
			CGDrawString("0x0000000A: Kernel has finished running, running OSLdr...", start_y, x, panic_text);
			return;
		}
		case RUNTIME_CHECK_HANDSHAKE: {
			CGDrawString("0x00000005: Handshake fault.", start_y, x, panic_text);
			break;
		}
		case RUNTIME_CHECK_IPC: {
			CGDrawString("0x00000003: Bad LPC message.", start_y, x, panic_text);
			break;
		}
		case RUNTIME_CHECK_INVALID_PRIVILEGE: {
			CGDrawString("0x00000007: Privilege access violation.", start_y, x, panic_text);
			break;
		case RUNTIME_CHECK_UNEXCPECTED: {
			CGDrawString("0x0000000B: Unexpected violation.", start_y, x, panic_text);
			break;
		}
		case RUNTIME_CHECK_VIRTUAL_OUT_OF_MEM: {
			CGDrawString("0x10000001: Out of virtual memory.", start_y, x, panic_text);

			break;
		}
		case RUNTIME_CHECK_FAILED: {
			CGDrawString("0x10000001: Kernel Bug check appears to have failed, a dump has been written to the storage.", start_y, x, panic_text);
			break;
		}
		default: {
			CGDrawString("0xFFFFFFFC: Unknown Kernel Error code.", start_y, x, panic_text);
			break;
		}
		}
		};

		RecoveryFactory::Recover();
	}

	Void RecoveryFactory::Recover() noexcept
	{
		while (YES)
		{
			HAL::rt_halt();
		}
	}

	void ke_runtime_check(bool expr, const Char* file, const Char* line)
	{
		if (!expr)
		{
			kcout << "FAILED: FILE: " << file << endl;
			kcout << "FAILED: LINE: " << line << endl;

			ke_stop(RUNTIME_CHECK_FAILED); // Runtime Check failed
		}
	}
} // namespace Kernel