From 9585dcbd5c13b6b27c4f117c44b3bd6e79f5b726 Mon Sep 17 00:00:00 2001 From: mintsuki Date: Sun, 22 May 2022 03:44:04 +0200 Subject: [PATCH] limine: Add new requests for terminal and framebuffer --- common/protos/limine.c | 114 +++++++++++++++++++++++++++++++++++++++-- limine.h | 79 +++++++++++++++++++++++++--- test/limine.c | 62 ++++++++++++++++++++++ 3 files changed, 244 insertions(+), 11 deletions(-) diff --git a/common/protos/limine.c b/common/protos/limine.c index 2e28519c..160f481c 100644 --- a/common/protos/limine.c +++ b/common/protos/limine.c @@ -472,8 +472,10 @@ FEAT_END struct fb_info fb; - // Terminal feature uint64_t *term_fb_ptr = NULL; + uint64_t *term_fb_legacy_ptr = NULL; + + // Terminal feature FEAT_START struct limine_terminal_request *terminal_request = get_request(LIMINE_TERMINAL_REQUEST); if (terminal_request == NULL) { @@ -534,19 +536,80 @@ FEAT_START goto skip_fb_init; FEAT_END - // Framebuffer feature + // Terminal feature (legacy) FEAT_START + struct limine_terminal_legacy_request *terminal_request = get_request(LIMINE_TERMINAL_LEGACY_REQUEST); + if (term_fb_ptr != NULL || terminal_request == NULL) { + break; // next feature + } + + struct limine_terminal_legacy_response *terminal_response = + ext_mem_alloc(sizeof(struct limine_terminal_legacy_response)); + + struct limine_terminal_legacy *terminal = ext_mem_alloc(sizeof(struct limine_terminal_legacy)); + + 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 (terminal_request->callback != 0) { +#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 + } + + term_arg = reported_addr(terminal); + +#if defined (__i386__) + if (stivale2_rt_stack == NULL) { + stivale2_rt_stack = ext_mem_alloc(16384) + 16384; + } + + stivale2_term_write_ptr = (uintptr_t)term_write_shim; + terminal_response->write = (uintptr_t)(void *)stivale2_term_write_entry; +#elif defined (__x86_64__) + terminal_response->write = (uintptr_t)term_write_shim; +#endif + + term_fb_legacy_ptr = &terminal->framebuffer; + + terminal->columns = term_cols; + terminal->rows = term_rows; + + uint64_t *term_list = ext_mem_alloc(1 * sizeof(uint64_t)); + term_list[0] = reported_addr(terminal); + + terminal_response->terminal_count = 1; + terminal_response->terminals = reported_addr(term_list); + + terminal_request->response = reported_addr(terminal_response); + + goto skip_fb_init; +FEAT_END + term_deinit(); if (!fb_init(&fb, req_width, req_height, req_bpp)) { panic(true, "limine: Could not acquire framebuffer"); } -skip_fb_init:; +skip_fb_init: memmap_alloc_range(fb.framebuffer_addr, (uint64_t)fb.framebuffer_pitch * fb.framebuffer_height, MEMMAP_FRAMEBUFFER, false, false, false, true); + // Framebuffer feature +FEAT_START // For now we only support 1 framebuffer struct limine_framebuffer *fbp = ext_mem_alloc(sizeof(struct limine_framebuffer)); @@ -587,6 +650,51 @@ skip_fb_init:; framebuffer_response->framebuffer_count = 1; framebuffer_response->framebuffers = reported_addr(fb_list); + framebuffer_request->response = reported_addr(framebuffer_response); +FEAT_END + + // Framebuffer feature (legacy) +FEAT_START + // For now we only support 1 framebuffer + struct limine_framebuffer_legacy *fbp = ext_mem_alloc(sizeof(struct limine_framebuffer_legacy)); + + if (term_fb_legacy_ptr != NULL) { + *term_fb_legacy_ptr = reported_addr(fbp); + } + + struct limine_framebuffer_legacy_request *framebuffer_request = get_request(LIMINE_FRAMEBUFFER_LEGACY_REQUEST); + if (framebuffer_request == NULL) { + break; // next feature + } + + struct limine_framebuffer_legacy_response *framebuffer_response = + ext_mem_alloc(sizeof(struct limine_framebuffer_legacy_response)); + + struct edid_info_struct *edid_info = get_edid_info(); + if (edid_info != NULL) { + fbp->edid_size = sizeof(struct edid_info_struct); + fbp->edid = reported_addr(edid_info); + } + + fbp->memory_model = LIMINE_FRAMEBUFFER_RGB; + fbp->address = reported_addr((void *)(uintptr_t)fb.framebuffer_addr); + fbp->width = fb.framebuffer_width; + fbp->height = fb.framebuffer_height; + fbp->bpp = fb.framebuffer_bpp; + fbp->pitch = fb.framebuffer_pitch; + fbp->red_mask_size = fb.red_mask_size; + fbp->red_mask_shift = fb.red_mask_shift; + fbp->green_mask_size = fb.green_mask_size; + fbp->green_mask_shift = fb.green_mask_shift; + fbp->blue_mask_size = fb.blue_mask_size; + fbp->blue_mask_shift = fb.blue_mask_shift; + + uint64_t *fb_list = ext_mem_alloc(1 * sizeof(uint64_t)); + fb_list[0] = reported_addr(fbp); + + framebuffer_response->framebuffer_count = 1; + framebuffer_response->framebuffers = reported_addr(fb_list); + framebuffer_request->response = reported_addr(framebuffer_response); FEAT_END diff --git a/limine.h b/limine.h index cea4c497..71c1b9ab 100644 --- a/limine.h +++ b/limine.h @@ -93,11 +93,45 @@ struct limine_hhdm_request { /* Framebuffer */ -#define LIMINE_FRAMEBUFFER_REQUEST { LIMINE_COMMON_MAGIC, 0xcbfe81d7dd2d1977, 0x063150319ebc9b71 } +#define LIMINE_FRAMEBUFFER_REQUEST { LIMINE_COMMON_MAGIC, 0x9d5827dcd881dd75, 0xa3148604f6fab11b } #define LIMINE_FRAMEBUFFER_RGB 1 struct limine_framebuffer { + LIMINE_PTR(void *) address; + uint64_t width; + uint64_t height; + uint64_t pitch; + uint16_t bpp; + uint8_t memory_model; + uint8_t red_mask_size; + uint8_t red_mask_shift; + uint8_t green_mask_size; + uint8_t green_mask_shift; + uint8_t blue_mask_size; + uint8_t blue_mask_shift; + uint8_t reserved[7]; + uint64_t edid_size; + LIMINE_PTR(void *) edid; +}; + +struct limine_framebuffer_response { + uint64_t revision; + uint64_t framebuffer_count; + LIMINE_PTR(struct limine_framebuffer **) framebuffers; +}; + +struct limine_framebuffer_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_framebuffer_response *) response; +}; + +/* Framebuffer (legacy) */ + +#define LIMINE_FRAMEBUFFER_LEGACY_REQUEST { LIMINE_COMMON_MAGIC, 0xcbfe81d7dd2d1977, 0x063150319ebc9b71 } + +struct limine_framebuffer_legacy { LIMINE_PTR(void *) address; uint16_t width; uint16_t height; @@ -115,21 +149,21 @@ struct limine_framebuffer { LIMINE_PTR(void *) edid; }; -struct limine_framebuffer_response { +struct limine_framebuffer_legacy_response { uint64_t revision; uint64_t framebuffer_count; - LIMINE_PTR(struct limine_framebuffer **) framebuffers; + LIMINE_PTR(struct limine_framebuffer_legacy **) framebuffers; }; -struct limine_framebuffer_request { +struct limine_framebuffer_legacy_request { uint64_t id[4]; uint64_t revision; - LIMINE_PTR(struct limine_framebuffer_response *) response; + LIMINE_PTR(struct limine_framebuffer_legacy_response *) response; }; /* Terminal */ -#define LIMINE_TERMINAL_REQUEST { LIMINE_COMMON_MAGIC, 0x0785a0aea5d0750f, 0x1c1936fee0d6cf6e } +#define LIMINE_TERMINAL_REQUEST { LIMINE_COMMON_MAGIC, 0xc8ac59310c2b0844, 0xa68d0c7265d38878 } #define LIMINE_TERMINAL_CB_DEC 10 #define LIMINE_TERMINAL_CB_BELL 20 @@ -151,8 +185,8 @@ typedef void (*limine_terminal_write)(struct limine_terminal *, const char *, ui typedef void (*limine_terminal_callback)(struct limine_terminal *, uint64_t, uint64_t, uint64_t, uint64_t); struct limine_terminal { - uint32_t columns; - uint32_t rows; + uint64_t columns; + uint64_t rows; LIMINE_PTR(struct limine_framebuffer *) framebuffer; }; @@ -170,6 +204,35 @@ struct limine_terminal_request { LIMINE_PTR(limine_terminal_callback) callback; }; +/* Terminal (legacy) */ + +#define LIMINE_TERMINAL_LEGACY_REQUEST { LIMINE_COMMON_MAGIC, 0x0785a0aea5d0750f, 0x1c1936fee0d6cf6e } + +struct limine_terminal_legacy; + +typedef void (*limine_terminal_legacy_write)(struct limine_terminal_legacy *, const char *, uint64_t); +typedef void (*limine_terminal_legacy_callback)(struct limine_terminal_legacy *, uint64_t, uint64_t, uint64_t, uint64_t); + +struct limine_terminal_legacy { + uint32_t columns; + uint32_t rows; + LIMINE_PTR(struct limine_framebuffer_legacy *) framebuffer; +}; + +struct limine_terminal_legacy_response { + uint64_t revision; + uint64_t terminal_count; + LIMINE_PTR(struct limine_terminal_legacy **) terminals; + LIMINE_PTR(limine_terminal_legacy_write) write; +}; + +struct limine_terminal_legacy_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_terminal_legacy_response *) response; + LIMINE_PTR(limine_terminal_legacy_callback) callback; +}; + /* 5-level paging */ #define LIMINE_5_LEVEL_PAGING_REQUEST { LIMINE_COMMON_MAGIC, 0x94469551da9b3192, 0xebe5e86db7382888 } diff --git a/test/limine.c b/test/limine.c index 839d8099..a559ca51 100644 --- a/test/limine.c +++ b/test/limine.c @@ -23,6 +23,14 @@ struct limine_framebuffer_request framebuffer_request = { __attribute__((section(".limine_reqs"))) void *framebuffer_req = &framebuffer_request; +struct limine_framebuffer_legacy_request framebuffer_legacy_request = { + .id = LIMINE_FRAMEBUFFER_LEGACY_REQUEST, + .revision = 0, .response = NULL +}; + +__attribute__((section(".limine_reqs"))) +void *framebuffer_legacy_req = &framebuffer_legacy_request; + struct limine_bootloader_info_request bootloader_info_request = { .id = LIMINE_BOOTLOADER_INFO_REQUEST, .revision = 0, .response = NULL @@ -119,6 +127,14 @@ struct limine_terminal_request _terminal_request = { __attribute__((section(".limine_reqs"))) void *terminal_req = &_terminal_request; +struct limine_terminal_legacy_request _terminal_legacy_request = { + .id = LIMINE_TERMINAL_LEGACY_REQUEST, + .revision = 0, .response = NULL +}; + +__attribute__((section(".limine_reqs"))) +void *terminal_legacy_req = &_terminal_legacy_request; + static char *get_memmap_type(uint64_t type) { switch (type) { case LIMINE_MEMMAP_USABLE: @@ -274,6 +290,34 @@ FEAT_START } FEAT_END +FEAT_START + e9_printf(""); + if (framebuffer_legacy_request.response == NULL) { + e9_printf("Framebuffer (legacy) not passed"); + break; + } + struct limine_framebuffer_legacy_response *fb_response = framebuffer_legacy_request.response; + e9_printf("Framebuffers feature (legacy), revision %d", fb_response->revision); + e9_printf("%d framebuffer(s)", fb_response->framebuffer_count); + for (size_t i = 0; i < fb_response->framebuffer_count; i++) { + struct limine_framebuffer_legacy *fb = fb_response->framebuffers[i]; + e9_printf("Address: %x", fb->address); + e9_printf("Width: %d", fb->width); + e9_printf("Height: %d", fb->height); + e9_printf("Pitch: %d", fb->pitch); + e9_printf("BPP: %d", fb->bpp); + e9_printf("Memory model: %d", fb->memory_model); + e9_printf("Red mask size: %d", fb->red_mask_size); + e9_printf("Red mask shift: %d", fb->red_mask_shift); + e9_printf("Green mask size: %d", fb->green_mask_size); + e9_printf("Green mask shift: %d", fb->green_mask_shift); + e9_printf("Blue mask size: %d", fb->blue_mask_size); + e9_printf("Blue mask shift: %d", fb->blue_mask_shift); + e9_printf("EDID size: %d", fb->edid_size); + e9_printf("EDID at: %x", fb->edid); + } +FEAT_END + FEAT_START e9_printf(""); if (kf_request.response == NULL) { @@ -382,5 +426,23 @@ FEAT_START e9_printf("Write function at: %x", term_response->write); FEAT_END +FEAT_START + e9_printf(""); + if (_terminal_legacy_request.response == NULL) { + e9_printf("Terminal (legacy) not passed"); + break; + } + struct limine_terminal_legacy_response *term_response = _terminal_legacy_request.response; + e9_printf("Terminal feature (legacy), revision %d", term_response->revision); + e9_printf("%d terminal(s)", term_response->terminal_count); + for (size_t i = 0; i < term_response->terminal_count; i++) { + struct limine_terminal_legacy *terminal = term_response->terminals[i]; + e9_printf("Columns: %d", terminal->columns); + e9_printf("Rows: %d", terminal->rows); + e9_printf("Using framebuffer: %x", terminal->framebuffer); + } + e9_printf("Write function at: %x", term_response->write); +FEAT_END + for (;;); }