summaryrefslogtreecommitdiff
path: root/include/mercury/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'include/mercury/kernel')
-rw-r--r--include/mercury/kernel/framebuffer.hpp27
-rw-r--r--include/mercury/kernel/paging.hpp34
-rw-r--r--include/mercury/kernel/terminal.hpp30
-rw-r--r--include/mercury/kernel/utility.hpp124
4 files changed, 215 insertions, 0 deletions
diff --git a/include/mercury/kernel/framebuffer.hpp b/include/mercury/kernel/framebuffer.hpp
new file mode 100644
index 0000000..5c6ca23
--- /dev/null
+++ b/include/mercury/kernel/framebuffer.hpp
@@ -0,0 +1,27 @@
+#ifndef MERCURY_KERNEL_FRAMEBUFFER_HPP
+#define MERCURY_KERNEL_FRAMEBUFFER_HPP
+
+#include <cstdint>
+
+namespace mercury::kernel::framebuffer {
+
+ extern int width;
+ extern int height;
+
+ void init_framebuffer(uint64_t vaddr, uint64_t width, uint64_t height, uint64_t pitch);
+
+ typedef uint32_t color;
+ color encode_color(uint8_t r, uint8_t g, uint8_t b);
+
+ void set_pixel(int x, int y, color c);
+
+ //[from_start_x, from_end_x) x [from_start_y, from_end_y) -> [to_start_x, ...) x [to_start_y, ...)
+ //we assume from_start_x < from_end_x and from_start_y < from_end_y
+ void move_region(int from_start_x, int from_start_y, int from_end_x, int from_end_y, int to_start_x, int to_start_y);
+
+ //[start_x, end_x) x [start_y, end_y)
+ void fill_region(int start_x, int start_y, int end_x, int end_y, color c);
+
+}
+
+#endif
diff --git a/include/mercury/kernel/paging.hpp b/include/mercury/kernel/paging.hpp
new file mode 100644
index 0000000..9627162
--- /dev/null
+++ b/include/mercury/kernel/paging.hpp
@@ -0,0 +1,34 @@
+#ifndef MERCURY_KERNEL_PAGING_HPP
+#define MERCURY_KERNEL_PAGING_HPP
+
+#include <cstdint>
+
+//in paging.asm
+extern "C" [[noreturn]] void switch_to_kernel_p4(void (*and_then_jump_to)());
+
+namespace mercury::kernel::paging {
+
+ void mark_all_pram_used();
+ void mark_all_vram_free();
+
+ //assumes page-alignment
+ void mark_pram_region_free(uint64_t start_addr, uint64_t end_addr);
+ //assumes page-alignment
+ void mark_vram_region_used(uint64_t start_addr, uint64_t end_addr);
+
+ uint64_t find_unmapped_vram_region(uint64_t page_count);
+
+ void init_kernel_page_tables(uint64_t kernel_offset);
+
+ void map_kernel_stack();
+
+ //assumes page-alignment
+ void map_kernel_page(
+ uint64_t paddr, uint64_t vaddr, bool write, bool execute);
+
+ uint64_t get_used_vram_page_count();
+ uint64_t get_free_pram_page_count();
+
+}
+
+#endif
diff --git a/include/mercury/kernel/terminal.hpp b/include/mercury/kernel/terminal.hpp
new file mode 100644
index 0000000..b9d9976
--- /dev/null
+++ b/include/mercury/kernel/terminal.hpp
@@ -0,0 +1,30 @@
+#ifndef MERCURY_KERNEL_TERMINAL_HPP
+#define MERCURY_KERNEL_TERMINAL_HPP
+
+#include <cstdint>
+
+namespace mercury::kernel::terminal {
+
+ extern uint8_t *termfont;
+ extern uint64_t termfont_len;
+
+ void init_terminal();
+
+ extern int width;
+ extern int height;
+
+ extern int cursor_x;
+ extern int cursor_y;
+
+ extern framebuffer::color bg_color;
+ extern framebuffer::color fg_color;
+
+ void put_char(char ch);
+
+ void put_string_sz(const char *str);
+
+ void put_int_decimal(uint64_t n, bool with_commas = true);
+
+}
+
+#endif
diff --git a/include/mercury/kernel/utility.hpp b/include/mercury/kernel/utility.hpp
new file mode 100644
index 0000000..dbf0cf9
--- /dev/null
+++ b/include/mercury/kernel/utility.hpp
@@ -0,0 +1,124 @@
+#ifndef MERCURY_KERNEL_UTILITY_HPP
+#define MERCURY_KERNEL_UTILITY_HPP
+
+#include <optional>
+#include <cstdint>
+
+namespace mercury::kernel::utility {
+
+ template <class t>
+ static inline t min(t a, t b) {
+ return a < b ? a : b;
+ }
+
+ //includes start_i, does not include end_i
+ void mark_bitmap_region_zero(uint64_t *bitmap, uint64_t start_i, uint64_t end_i);
+ //includes start_i, does not include end_i
+ void mark_bitmap_region_one(uint64_t *bitmap, uint64_t start_i, uint64_t end_i);
+
+ struct uuid {
+ uint8_t bytes[16];
+ };
+
+ template <class value_t>
+ struct string_tree {
+
+ std::optional<value_t> value_here = {};
+ string_tree<value_t> *parent = 0;
+ string_tree<value_t> *subtrees[256] = {};
+
+ //if there is a node whose key has a prefix in common with str, then this
+ //returns the deepest such node, and sets leftover_out to point to the
+ //character of str after the common prefix with that returned node. if
+ //there is no such node, this returns the current node and sets
+ //leftover_out to a null pointer.
+ string_tree &max_common_prefix(
+ const char *str, size_t str_len, const char *&leftover_out) {
+
+ string_tree<value_t> *last_with_value = 0;
+ const char *leftover_at_last_with_value = 0;
+ string_tree<value_t> *on = this;
+ size_t len_so_far = 0;
+
+ while (true) {
+
+ if (on->value_here) {
+ last_with_value = on;
+ leftover_at_last_with_value = str + len_so_far;
+ }
+
+ if (len_so_far == str_len)
+ break;
+
+ on = on->subtrees[(uint8_t)str[len_so_far]];
+ if (!on)
+ break;
+
+ ++len_so_far;
+
+ }
+
+ if (last_with_value) {
+ leftover_out = leftover_at_last_with_value;
+ return *last_with_value;
+ }
+
+ leftover_out = 0;
+ return *this;
+
+ }
+
+ bool try_insert(const char *str, size_t str_len, value_t value) {
+
+ string_tree<value_t> *on = this;
+ for (size_t i = 0; i < str_len; ++i) {
+ string_tree<value_t> *&subtree = on->subtrees[(uint8_t)str[i]];
+ if (!subtree) {
+ subtree = new string_tree<value_t>();
+ subtree->parent = on;
+ }
+ on = subtree;
+ }
+
+ if (on->value_here)
+ return false;
+ on->value_here = value;
+ return true;
+
+ }
+
+ };
+
+ //if c appears in str, this returns the index of the first time it appears.
+ //otherwise, this returns len.
+ static inline size_t find(const char *str, size_t len, char c) {
+ for (size_t i = 0; i < len; ++i)
+ if (str[i] == c)
+ return i;
+ return len;
+ }
+
+ template <class value_t>
+ struct flist {
+
+ struct node {
+ value_t value;
+ node *next;
+ };
+
+ node *first;
+
+ flist() : first(0) {}
+
+ void insert(value_t value) {
+ first = new node {
+ .value = value,
+ .next = first
+ };
+ }
+
+ };
+
+}
+
+#endif