diff --git a/common/limine.h b/common/limine.h index 4d7f612d..99b44835 100644 --- a/common/limine.h +++ b/common/limine.h @@ -30,13 +30,30 @@ struct limine_boot_info_request { #define LIMINE_FRAMEBUFFER_REQUEST { LIMINE_COMMON_MAGIC, 0xcbfe81d7dd2d1977, 0x063150319ebc9b71 } -struct limine_framebuffer_response { - uint64_t flags; +#define LIMINE_FRAMEBUFFER_RGB 1 + +struct limine_framebuffer { + 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; }; -#define LIMINE_FRAMEBUFFER_PREFER_LFB 0 -#define LIMINE_FRAMEBUFFER_PREFER_TEXT 1 -#define LIMINE_FRAMEBUFFER_ENFORCE_PREFER (1 << 8) +struct limine_framebuffer_response { + uint64_t flags; + + uint64_t fbs_count; + LIMINE_PTR(struct limine_framebuffer *) fbs; +}; struct limine_framebuffer_request { uint64_t id[4]; diff --git a/common/protos/limine.c b/common/protos/limine.c index c5402573..020e998f 100644 --- a/common/protos/limine.c +++ b/common/protos/limine.c @@ -218,8 +218,50 @@ FEAT_END FEAT_START term_deinit(); - struct fb_info *fb = NULL; - fb_init(fb, 0, 0, 0); + size_t req_width = 0, req_height = 0, req_bpp = 0; + + char *resolution = config_get_value(config, 0, "RESOLUTION"); + if (resolution != NULL) { + parse_resolution(&req_width, &req_height, &req_bpp, resolution); + } + + struct fb_info fb; + + if (!fb_init(&fb, req_width, req_height, req_bpp)) { + panic(true, "limine: Could not acquire framebuffer"); + } + + struct limine_framebuffer_request *framebuffer_request = get_request(LIMINE_FRAMEBUFFER_REQUEST); + if (framebuffer_request == NULL) { + break; // next feature + } + + memmap_alloc_range(fb.framebuffer_addr, + (uint64_t)fb.framebuffer_pitch * fb.framebuffer_height, + MEMMAP_FRAMEBUFFER, false, false, false, true); + + struct limine_framebuffer_response *framebuffer_response = + ext_mem_alloc(sizeof(struct limine_framebuffer_response)); + + // For now we only support 1 framebuffer + struct limine_framebuffer *fbp = ext_mem_alloc(sizeof(struct limine_framebuffer)); + framebuffer_response->fbs = reported_addr(fbp); + framebuffer_response->fbs_count = 1; + + 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; + + framebuffer_request->response = reported_addr(framebuffer_response); FEAT_END // Wrap-up stuff before memmap close diff --git a/test/limine.c b/test/limine.c index dec6ed44..c1377def 100644 --- a/test/limine.c +++ b/test/limine.c @@ -8,8 +8,7 @@ static void limine_main(void); __attribute__((used)) static struct limine_framebuffer_request framebuffer_request = { .id = LIMINE_FRAMEBUFFER_REQUEST, - .flags = LIMINE_FRAMEBUFFER_PREFER_LFB | LIMINE_FRAMEBUFFER_ENFORCE_PREFER, - .response = NULL + .flags = 0, .response = NULL }; __attribute__((used)) @@ -84,5 +83,29 @@ FEAT_START } FEAT_END +FEAT_START + if (framebuffer_request.response == NULL) { + e9_printf("Framebuffer not passed"); + break; + } + struct limine_framebuffer_response *fb_response = framebuffer_request.response; + e9_printf("%d framebuffer(s)", fb_response->fbs_count); + for (size_t i = 0; i < fb_response->fbs_count; i++) { + struct limine_framebuffer *fb = &fb_response->fbs[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); + } +FEAT_END + for (;;); }