:: commit 733865c9a63d6c9ba6b9827f7380cf04331b52e9

mintsuki <mintsuki@protonmail.com> — 2022-03-21 04:15

parents: 49cf4398da

limine: Add terminal request

diff --git a/common/limine.h b/common/limine.h
index 3c318f1c..64cc1168 100644
--- a/common/limine.h
+++ b/common/limine.h
@@ -98,6 +98,27 @@ struct limine_framebuffer_request {
     LIMINE_PTR(struct limine_framebuffer_response *) response;
 };
 
+// Terminal
+
+#define LIMINE_TERMINAL_REQUEST { LIMINE_COMMON_MAGIC, 0x0785a0aea5d0750f, 0x1c1936fee0d6cf6e }
+
+typedef void (*limine_terminal_write)(const char *, uint64_t);
+typedef void (*limine_terminal_callback)(uint64_t, uint64_t, uint64_t, uint64_t);
+
+struct limine_terminal_response {
+    uint64_t revision;
+    uint32_t columns;
+    uint32_t rows;
+    LIMINE_PTR(limine_terminal_write) write;
+};
+
+struct limine_terminal_request {
+    uint64_t id[4];
+    uint64_t revision;
+    LIMINE_PTR(struct limine_terminal_response *) response;
+    LIMINE_PTR(limine_terminal_callback) callback;
+};
+
 // 5-level paging
 
 #define LIMINE_5_LEVEL_PAGING_REQUEST { LIMINE_COMMON_MAGIC, 0x94469551da9b3192, 0xebe5e86db7382888 }
diff --git a/common/protos/limine.c b/common/protos/limine.c
index b481c7df..e3de994b 100644
--- a/common/protos/limine.c
+++ b/common/protos/limine.c
@@ -102,6 +102,13 @@ static void *_get_request(uint64_t id[4]) {
 #define FEAT_START do {
 #define FEAT_END } while (0);
 
+#if defined (__i386__)
+extern symbol stivale2_term_write_entry;
+extern void *stivale2_rt_stack;
+extern uint64_t stivale2_term_callback_ptr;
+void stivale2_term_callback(uint64_t, uint64_t, uint64_t, uint64_t);
+#endif
+
 bool limine_load(char *config, char *cmdline) {
     uint32_t eax, ebx, ecx, edx;
 
@@ -409,10 +416,6 @@ FEAT_START
     module_request->response = reported_addr(module_response);
 FEAT_END
 
-    // Framebuffer feature
-FEAT_START
-    term_deinit();
-
     size_t req_width = 0, req_height = 0, req_bpp = 0;
 
     char *resolution = config_get_value(config, 0, "RESOLUTION");
@@ -422,10 +425,61 @@ FEAT_START
 
     struct fb_info fb;
 
+    // Terminal feature
+FEAT_START
+    struct limine_terminal_request *terminal_request = get_request(LIMINE_TERMINAL_REQUEST);
+    if (terminal_request == NULL) {
+        break; // next feature
+    }
+
+    struct limine_terminal_response *terminal_response =
+        ext_mem_alloc(sizeof(struct limine_terminal_response));
+
+    quiet = false;
+    serial = false;
+
+    term_vbe(req_width, req_height);
+
+    if (current_video_mode < 0) {
+        panic(true, "limine: Failed to initialise terminal");
+    }
+
+    fb = fbinfo;
+
+#if defined (__i386__)
+    term_callback = stivale2_term_callback;
+    stivale2_term_callback_ptr = terminal_request->callback;
+#elif defined (__x86_64__)
+    term_callback = (void *)terminal_request->callback;
+#endif
+
+#if defined (__i386__)
+    if (stivale2_rt_stack == NULL) {
+        stivale2_rt_stack = ext_mem_alloc(8192);
+    }
+
+    terminal_response->write = (uintptr_t)(void *)stivale2_term_write_entry;
+#elif defined (__x86_64__)
+    terminal_response->write = (uintptr_t)term_write;
+#endif
+
+    terminal_response->columns = term_cols;
+    terminal_response->rows = term_rows;
+
+    terminal_request->response = reported_addr(terminal_response);
+
+    goto skip_fb_init;
+FEAT_END
+
+    // Framebuffer feature
+FEAT_START
+    term_deinit();
+
     if (!fb_init(&fb, req_width, req_height, req_bpp)) {
         panic(true, "limine: Could not acquire framebuffer");
     }
 
+skip_fb_init:;
     struct limine_framebuffer_request *framebuffer_request = get_request(LIMINE_FRAMEBUFFER_REQUEST);
     if (framebuffer_request == NULL) {
         break; // next feature
@@ -614,6 +668,11 @@ FEAT_START
     memmap_request->response = reported_addr(memmap_response);
 FEAT_END
 
+    // Clear terminal for kernels that will use the stivale2 terminal
+    term_write((uint64_t)(uintptr_t)("\e[2J\e[H"), 7);
+
+    term_runtime = true;
+
     stivale_spinup(64, want_5lv, &pagemap, entry_point, 0,
                    reported_addr(stack), true, (uintptr_t)local_gdt);
 
diff --git a/test/limine.c b/test/limine.c
index de430d13..99e5aa12 100644
--- a/test/limine.c
+++ b/test/limine.c
@@ -67,6 +67,11 @@ struct limine_smp_request _smp_request = {
     .revision = 0, .response = NULL
 };
 
+struct limine_terminal_request _terminal_request = {
+    .id = LIMINE_TERMINAL_REQUEST,
+    .revision = 0, .response = NULL
+};
+
 static char *get_memmap_type(uint64_t type) {
     switch (type) {
         case LIMINE_MEMMAP_USABLE:
@@ -123,6 +128,10 @@ static void print_file_loc(struct limine_file_location *file_location) {
 extern char kernel_start[];
 
 static void limine_main(void) {
+    if (_terminal_request.response) {
+        stivale2_print = _terminal_request.response->write;
+    }
+
     e9_printf("\nWe're alive");
 
     uint64_t kernel_slide = (uint64_t)kernel_start - 0xffffffff80000000;
@@ -291,5 +300,18 @@ FEAT_START
     }
 FEAT_END
 
+FEAT_START
+    e9_printf("");
+    if (_terminal_request.response == NULL) {
+        e9_printf("Terminal not passed");
+        break;
+    }
+    struct limine_terminal_response *term_response = _terminal_request.response;
+    e9_printf("Terminal feature, revision %d", term_response->revision);
+    e9_printf("Columns: %d", term_response->columns);
+    e9_printf("Rows: %d", term_response->rows);
+    e9_printf("Write function at: %x", term_response->write);
+FEAT_END
+
     for (;;);
 }
tab: 248 wrap: offon