summaryrefslogtreecommitdiff
path: root/kernel/main.c
blob: 8c120e91a80f91b80c211aa62ea256826f321c55 (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
#include <stdint.h>
#include "util.h"

#define VGA_WIDTH 80
#define VGA_HEIGHT 25

struct e820_entry {
	uint64_t base;
	uint64_t length;
	uint32_t type;
	uint32_t ext_attr;
};

static uint64_t *
memsetu64(uint64_t *const dst, const uint64_t c, const uint64_t n)
{
	for (uint64_t i = 0; i < n; ++i) dst[i] = c;
	return dst;
}

static uint16_t *
print_hex(uint16_t *dst, uint64_t num)
{
	dst[0] = 0x0f00 | '0';
	dst[1] = 0x0f00 | 'x';

	dst += 2;

	for (int i = 0; i < 16; ++i) {
		uint16_t x = (num >> 60);

		*(dst++) = 0x0f00 | (x < 0xa ? x+'0' : x+'a'-0xa);

		num <<= 4;
	}

	return dst;
}

static uint16_t *
puts(uint16_t *dst, const char *str)
{
	for (; *str; ++str, ++dst) *dst = 0x0f00|(*str);
	return dst;
}

static uint16_t *
print_e820_table(uint16_t *dst, const struct e820_entry *const entries, const uint16_t count)
{
	for (uint16_t i = 0; i < count; ++i, dst += VGA_WIDTH) {
		uint16_t *cursor;

		cursor = print_hex(dst, entries[i].base);

		*(cursor++) = 0x0f00 | '-';

		cursor = print_hex(cursor, entries[i].base + entries[i].length - 1);

		++cursor;
		cursor = puts(cursor, entries[i].type == 1 ? "available" : "reserved");
	}

	return dst;
}

void
kmain(void)
{
	vga_cursor_hide();

	uint16_t *const vga_memory = (uint16_t *)0xb8000;
	memsetu64((uint64_t *)vga_memory, 0x0f200f200f200f20, (VGA_WIDTH*VGA_HEIGHT*sizeof(uint16_t))/sizeof(uint64_t));

	puts(vga_memory, "ProvidenceOS v0.1");
	puts(vga_memory+VGA_WIDTH*2, "e820 memory map:");

	const uint16_t e820_size = *(uint16_t *)0xf000;
	const struct e820_entry *const e820_mmap = (struct e820_entry *)0xf008;

	print_e820_table(vga_memory+(VGA_WIDTH*3), e820_mmap, e820_size);

	halt();
}