:: commit 9585dcbd5c13b6b27c4f117c44b3bd6e79f5b726

mintsuki <mintsuki@protonmail.com> — 2022-05-22 01:44

parents: 3d9737f5e6

limine: Add new requests for terminal and framebuffer

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,15 +93,15 @@ 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;
-    uint16_t width;
-    uint16_t height;
-    uint16_t pitch;
+    uint64_t width;
+    uint64_t height;
+    uint64_t pitch;
     uint16_t bpp;
     uint8_t memory_model;
     uint8_t red_mask_size;
@@ -110,7 +110,7 @@ struct limine_framebuffer {
     uint8_t green_mask_shift;
     uint8_t blue_mask_size;
     uint8_t blue_mask_shift;
-    uint8_t unused;
+    uint8_t reserved[7];
     uint64_t edid_size;
     LIMINE_PTR(void *) edid;
 };
@@ -127,9 +127,43 @@ struct limine_framebuffer_request {
     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;
+    uint16_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 unused;
+    uint64_t edid_size;
+    LIMINE_PTR(void *) edid;
+};
+
+struct limine_framebuffer_legacy_response {
+    uint64_t revision;
+    uint64_t framebuffer_count;
+    LIMINE_PTR(struct limine_framebuffer_legacy **) framebuffers;
+};
+
+struct limine_framebuffer_legacy_request {
+    uint64_t id[4];
+    uint64_t revision;
+    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 (;;);
 }
tab: 248 wrap: offon