From 733865c9a63d6c9ba6b9827f7380cf04331b52e9 Mon Sep 17 00:00:00 2001 From: mintsuki Date: Mon, 21 Mar 2022 05:15:10 +0100 Subject: [PATCH] limine: Add terminal request --- common/limine.h | 21 +++++++++++++ common/protos/limine.c | 67 +++++++++++++++++++++++++++++++++++++++--- test/limine.c | 22 ++++++++++++++ 3 files changed, 106 insertions(+), 4 deletions(-) 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 (;;); }