mirror of
https://github.com/limine-bootloader/limine
synced 2025-01-24 05:22:04 +03:00
vbe: Implement more expressive framebuffer tag (fixes #37)
This commit is contained in:
parent
6d232193cf
commit
cfb1734f43
13
STIVALE2.md
13
STIVALE2.md
@ -323,10 +323,17 @@ struct stivale2_struct_tag_framebuffer {
|
||||
uint64_t identifier; // Identifier: 0x506461d2950408fa
|
||||
uint64_t next;
|
||||
uint64_t framebuffer_addr; // Address of the framebuffer and related info
|
||||
uint16_t framebuffer_width;
|
||||
uint16_t framebuffer_width; // Width and height in pixels
|
||||
uint16_t framebuffer_height;
|
||||
uint16_t framebuffer_pitch;
|
||||
uint16_t framebuffer_bpp;
|
||||
uint16_t framebuffer_pitch; // Pitch in bytes
|
||||
uint16_t framebuffer_bpp; // Bits per pixel
|
||||
uint8_t memory_model; // Memory model: 1=RGB, all other values undefined
|
||||
uint8_t red_mask_size; // RGB mask sizes and left shifts
|
||||
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;
|
||||
} __attribute__((packed));
|
||||
```
|
||||
|
||||
|
BIN
limine-pxe.bin
BIN
limine-pxe.bin
Binary file not shown.
BIN
limine.bin
BIN
limine.bin
Binary file not shown.
@ -31,11 +31,12 @@ static void vga_font_retrieve(void) {
|
||||
|
||||
static uint32_t ansi_colours[8];
|
||||
|
||||
static struct vbe_framebuffer_info fbinfo;
|
||||
static uint32_t *vbe_framebuffer;
|
||||
static uint16_t vbe_pitch;
|
||||
static uint16_t vbe_width = 0;
|
||||
static uint16_t vbe_height = 0;
|
||||
static uint16_t vbe_bpp = 0;
|
||||
static uint16_t vbe_width;
|
||||
static uint16_t vbe_height;
|
||||
static uint16_t vbe_bpp;
|
||||
|
||||
static int frame_height, frame_width;
|
||||
|
||||
@ -316,7 +317,13 @@ void vbe_putchar(char c) {
|
||||
}
|
||||
|
||||
void vbe_tty_init(int *_rows, int *_cols, uint32_t *_colours, int _margin, int _margin_gradient, struct image *_background) {
|
||||
init_vbe(&vbe_framebuffer, &vbe_pitch, &vbe_width, &vbe_height, &vbe_bpp);
|
||||
init_vbe(&fbinfo, 0, 0, 0);
|
||||
|
||||
vbe_framebuffer = (void *)fbinfo.framebuffer_addr;
|
||||
vbe_width = fbinfo.framebuffer_width;
|
||||
vbe_height = fbinfo.framebuffer_height;
|
||||
vbe_bpp = fbinfo.framebuffer_bpp;
|
||||
vbe_pitch = fbinfo.framebuffer_pitch;
|
||||
|
||||
mtrr_set_range((uint64_t)(size_t)vbe_framebuffer,
|
||||
(uint64_t)vbe_pitch * vbe_height, MTRR_MEMORY_TYPE_WC);
|
||||
@ -365,15 +372,55 @@ struct vbe_info_struct {
|
||||
} __attribute__((packed));
|
||||
|
||||
struct vbe_mode_info_struct {
|
||||
uint8_t pad0[16];
|
||||
uint16_t pitch;
|
||||
uint16_t mode_attributes;
|
||||
uint8_t wina_attributes;
|
||||
uint8_t winb_attributes;
|
||||
uint16_t win_granularity;
|
||||
uint16_t win_size;
|
||||
uint16_t wina_segment;
|
||||
uint16_t winb_segment;
|
||||
uint32_t win_farptr;
|
||||
uint16_t bytes_per_scanline;
|
||||
|
||||
uint16_t res_x;
|
||||
uint16_t res_y;
|
||||
uint8_t pad1[3];
|
||||
uint8_t bpp;
|
||||
uint8_t pad2[14];
|
||||
uint32_t framebuffer;
|
||||
uint8_t pad3[212];
|
||||
uint8_t charsize_x;
|
||||
uint8_t charsize_y;
|
||||
uint8_t plane_count;
|
||||
uint8_t bpp;
|
||||
uint8_t bank_count;
|
||||
uint8_t memory_model;
|
||||
uint8_t bank_size;
|
||||
uint8_t image_count;
|
||||
uint8_t reserved0;
|
||||
|
||||
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 rsvd_mask_size;
|
||||
uint8_t rsvd_mask_shift;
|
||||
uint8_t direct_color_info;
|
||||
|
||||
uint32_t framebuffer_addr;
|
||||
uint8_t reserved1[6];
|
||||
|
||||
uint16_t lin_bytes_per_scanline;
|
||||
uint8_t banked_image_count;
|
||||
uint8_t lin_image_count;
|
||||
uint8_t lin_red_mask_size;
|
||||
uint8_t lin_red_mask_shift;
|
||||
uint8_t lin_green_mask_size;
|
||||
uint8_t lin_green_mask_shift;
|
||||
uint8_t lin_blue_mask_size;
|
||||
uint8_t lin_blue_mask_shift;
|
||||
uint8_t lin_rsvd_mask_size;
|
||||
uint8_t lin_rsvd_mask_shift;
|
||||
uint32_t max_pixel_clock;
|
||||
|
||||
uint8_t reserved2[189];
|
||||
} __attribute__((packed));
|
||||
|
||||
static void get_vbe_info(struct vbe_info_struct *buf) {
|
||||
@ -394,12 +441,14 @@ static void get_vbe_mode_info(struct vbe_mode_info_struct *buf,
|
||||
rm_int(0x10, &r, &r);
|
||||
}
|
||||
|
||||
static void set_vbe_mode(uint16_t mode) {
|
||||
static int set_vbe_mode(uint16_t mode) {
|
||||
struct rm_regs r = {0};
|
||||
|
||||
r.eax = 0x4f02;
|
||||
r.ebx = (uint32_t)mode | (1 << 14);
|
||||
rm_int(0x10, &r, &r);
|
||||
|
||||
return r.eax & 0xff;
|
||||
}
|
||||
|
||||
struct edid_info_struct {
|
||||
@ -457,7 +506,8 @@ static struct resolution fallback_resolutions[] = {
|
||||
{ 640, 480, 32 }
|
||||
};
|
||||
|
||||
int init_vbe(uint32_t **framebuffer, uint16_t *pitch, uint16_t *target_width, uint16_t *target_height, uint16_t *target_bpp) {
|
||||
bool init_vbe(struct vbe_framebuffer_info *ret,
|
||||
uint16_t target_width, uint16_t target_height, uint16_t target_bpp) {
|
||||
print("vbe: Initialising...\n");
|
||||
|
||||
size_t current_fallback = 0;
|
||||
@ -466,31 +516,37 @@ int init_vbe(uint32_t **framebuffer, uint16_t *pitch, uint16_t *target_width, ui
|
||||
get_vbe_info(&vbe_info);
|
||||
|
||||
print("vbe: Version: %u.%u\n", vbe_info.version_maj, vbe_info.version_min);
|
||||
|
||||
if (vbe_info.version_maj < 3) {
|
||||
print("vbe: We do not support VBE versions older than 3.0\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
print("vbe: OEM: %s\n", (char *)rm_desegment(vbe_info.oem_seg, vbe_info.oem_off));
|
||||
print("vbe: Graphics vendor: %s\n", (char *)rm_desegment(vbe_info.vendor_seg, vbe_info.vendor_off));
|
||||
print("vbe: Product name: %s\n", (char *)rm_desegment(vbe_info.prod_name_seg, vbe_info.prod_name_off));
|
||||
print("vbe: Product revision: %s\n", (char *)rm_desegment(vbe_info.prod_rev_seg, vbe_info.prod_rev_off));
|
||||
|
||||
struct edid_info_struct edid_info;
|
||||
if (!*target_width || !*target_height || !*target_bpp) {
|
||||
*target_width = 1024;
|
||||
*target_height = 768;
|
||||
*target_bpp = 32;
|
||||
if (!target_width || !target_height || !target_bpp) {
|
||||
target_width = 1024;
|
||||
target_height = 768;
|
||||
target_bpp = 32;
|
||||
if (!get_edid_info(&edid_info)) {
|
||||
int edid_width = (int)edid_info.det_timing_desc1[2];
|
||||
edid_width += ((int)edid_info.det_timing_desc1[4] & 0xf0) << 4;
|
||||
int edid_height = (int)edid_info.det_timing_desc1[5];
|
||||
edid_height += ((int)edid_info.det_timing_desc1[7] & 0xf0) << 4;
|
||||
if (edid_width && edid_height) {
|
||||
*target_width = edid_width;
|
||||
*target_height = edid_height;
|
||||
target_width = edid_width;
|
||||
target_height = edid_height;
|
||||
print("vbe: EDID detected screen resolution of %ux%u\n",
|
||||
*target_width, *target_height);
|
||||
target_width, target_height);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
print("vbe: Requested resolution of %ux%ux%u\n",
|
||||
*target_width, *target_height, *target_bpp);
|
||||
target_width, target_height, target_bpp);
|
||||
}
|
||||
|
||||
retry:;
|
||||
@ -500,22 +556,38 @@ retry:;
|
||||
for (size_t i = 0; vid_modes[i] != 0xffff; i++) {
|
||||
struct vbe_mode_info_struct vbe_mode_info;
|
||||
get_vbe_mode_info(&vbe_mode_info, vid_modes[i]);
|
||||
if (vbe_mode_info.res_x == *target_width
|
||||
&& vbe_mode_info.res_y == *target_height
|
||||
&& vbe_mode_info.bpp == *target_bpp) {
|
||||
print("vbe: Found matching mode %x, attempting to set\n", vid_modes[i]);
|
||||
*framebuffer = (uint32_t *)vbe_mode_info.framebuffer;
|
||||
*pitch = (int)vbe_mode_info.pitch;
|
||||
print("vbe: Framebuffer address: %x\n", vbe_mode_info.framebuffer);
|
||||
set_vbe_mode(vid_modes[i]);
|
||||
return 0;
|
||||
if (vbe_mode_info.res_x == target_width
|
||||
&& vbe_mode_info.res_y == target_height
|
||||
&& vbe_mode_info.bpp == target_bpp) {
|
||||
// We only support RGB for now
|
||||
if (vbe_mode_info.memory_model != 0x06)
|
||||
continue;
|
||||
print("vbe: Found matching mode %x, attempting to set...\n", vid_modes[i]);
|
||||
if (set_vbe_mode(vid_modes[i]) == 0x01) {
|
||||
print("vbe: Failed to set video mode %x, moving on...\n", vid_modes[i]);
|
||||
continue;
|
||||
}
|
||||
print("vbe: Framebuffer address: %x\n", vbe_mode_info.framebuffer_addr);
|
||||
ret->memory_model = vbe_mode_info.memory_model;
|
||||
ret->framebuffer_addr = vbe_mode_info.framebuffer_addr;
|
||||
ret->framebuffer_pitch = vbe_mode_info.lin_bytes_per_scanline;
|
||||
ret->framebuffer_width = vbe_mode_info.res_x;
|
||||
ret->framebuffer_height = vbe_mode_info.res_y;
|
||||
ret->framebuffer_bpp = vbe_mode_info.bpp;
|
||||
ret->red_mask_size = vbe_mode_info.lin_red_mask_size;
|
||||
ret->red_mask_shift = vbe_mode_info.lin_red_mask_shift;
|
||||
ret->green_mask_size = vbe_mode_info.lin_green_mask_size;
|
||||
ret->green_mask_shift = vbe_mode_info.lin_green_mask_shift;
|
||||
ret->blue_mask_size = vbe_mode_info.lin_blue_mask_size;
|
||||
ret->blue_mask_shift = vbe_mode_info.lin_blue_mask_shift;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (current_fallback < SIZEOF_ARRAY(fallback_resolutions)) {
|
||||
*target_width = fallback_resolutions[current_fallback].width;
|
||||
*target_height = fallback_resolutions[current_fallback].height;
|
||||
*target_bpp = fallback_resolutions[current_fallback].bpp;
|
||||
target_width = fallback_resolutions[current_fallback].width;
|
||||
target_height = fallback_resolutions[current_fallback].height;
|
||||
target_bpp = fallback_resolutions[current_fallback].bpp;
|
||||
current_fallback++;
|
||||
goto retry;
|
||||
}
|
||||
|
@ -5,7 +5,23 @@
|
||||
#include <stdbool.h>
|
||||
#include <lib/image.h>
|
||||
|
||||
int init_vbe(uint32_t **framebuffer, uint16_t *pitch, uint16_t *target_width, uint16_t *target_height, uint16_t *target_bpp);
|
||||
struct vbe_framebuffer_info {
|
||||
uint8_t memory_model;
|
||||
uint32_t framebuffer_addr;
|
||||
uint16_t framebuffer_pitch;
|
||||
uint16_t framebuffer_width;
|
||||
uint16_t framebuffer_height;
|
||||
uint16_t framebuffer_bpp;
|
||||
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;
|
||||
};
|
||||
|
||||
bool init_vbe(struct vbe_framebuffer_info *ret,
|
||||
uint16_t target_width, uint16_t target_height, uint16_t target_bpp);
|
||||
|
||||
void vbe_tty_init(int *rows, int *cols, uint32_t *colours, int margin, int margin_gradient, struct image *background);
|
||||
|
||||
|
@ -173,13 +173,16 @@ void stivale_load(char *cmdline) {
|
||||
term_deinit();
|
||||
|
||||
if (stivale_hdr.flags & (1 << 0)) {
|
||||
uint32_t *fb32;
|
||||
init_vbe(&fb32,
|
||||
&stivale_struct.framebuffer_pitch,
|
||||
&stivale_struct.framebuffer_width,
|
||||
&stivale_struct.framebuffer_height,
|
||||
&stivale_struct.framebuffer_bpp);
|
||||
stivale_struct.framebuffer_addr = (uint64_t)(size_t)fb32;
|
||||
struct vbe_framebuffer_info fbinfo;
|
||||
init_vbe(&fbinfo,
|
||||
stivale_struct.framebuffer_width,
|
||||
stivale_struct.framebuffer_height,
|
||||
stivale_struct.framebuffer_bpp);
|
||||
stivale_struct.framebuffer_addr = (uint64_t)fbinfo.framebuffer_addr;
|
||||
stivale_struct.framebuffer_width = fbinfo.framebuffer_width;
|
||||
stivale_struct.framebuffer_height = fbinfo.framebuffer_height;
|
||||
stivale_struct.framebuffer_bpp = fbinfo.framebuffer_bpp;
|
||||
stivale_struct.framebuffer_pitch = fbinfo.framebuffer_pitch;
|
||||
}
|
||||
|
||||
bool want_5lv = level5pg && (stivale_hdr.flags & (1 << 1));
|
||||
|
@ -256,22 +256,28 @@ void stivale2_load(char *cmdline) {
|
||||
term_deinit();
|
||||
|
||||
if (hdrtag != NULL) {
|
||||
struct stivale2_struct_tag_framebuffer *tag = conv_mem_alloc(sizeof(struct stivale2_struct_tag_framebuffer));
|
||||
tag->tag.identifier = STIVALE2_STRUCT_TAG_FRAMEBUFFER_ID;
|
||||
struct vbe_framebuffer_info fbinfo;
|
||||
if (init_vbe(&fbinfo,
|
||||
hdrtag->framebuffer_width,
|
||||
hdrtag->framebuffer_height,
|
||||
hdrtag->framebuffer_bpp)) {
|
||||
struct stivale2_struct_tag_framebuffer *tag = conv_mem_alloc(sizeof(struct stivale2_struct_tag_framebuffer));
|
||||
tag->tag.identifier = STIVALE2_STRUCT_TAG_FRAMEBUFFER_ID;
|
||||
|
||||
tag->framebuffer_width = hdrtag->framebuffer_width;
|
||||
tag->framebuffer_height = hdrtag->framebuffer_height;
|
||||
tag->framebuffer_bpp = hdrtag->framebuffer_bpp;
|
||||
tag->memory_model = STIVALE2_FBUF_MMODEL_RGB;
|
||||
tag->framebuffer_width = fbinfo.framebuffer_width;
|
||||
tag->framebuffer_height = fbinfo.framebuffer_height;
|
||||
tag->framebuffer_bpp = fbinfo.framebuffer_bpp;
|
||||
tag->framebuffer_pitch = fbinfo.framebuffer_pitch;
|
||||
tag->red_mask_size = fbinfo.red_mask_size;
|
||||
tag->red_mask_shift = fbinfo.red_mask_shift;
|
||||
tag->green_mask_size = fbinfo.green_mask_size;
|
||||
tag->green_mask_shift = fbinfo.green_mask_shift;
|
||||
tag->blue_mask_size = fbinfo.blue_mask_size;
|
||||
tag->blue_mask_shift = fbinfo.blue_mask_shift;
|
||||
|
||||
uint32_t *fb32;
|
||||
init_vbe(&fb32,
|
||||
&tag->framebuffer_pitch,
|
||||
&tag->framebuffer_width,
|
||||
&tag->framebuffer_height,
|
||||
&tag->framebuffer_bpp);
|
||||
tag->framebuffer_addr = (uint64_t)(size_t)fb32;
|
||||
|
||||
append_tag(&stivale2_struct, (struct stivale2_tag *)tag);
|
||||
append_tag(&stivale2_struct, (struct stivale2_tag *)tag);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -83,6 +83,10 @@ struct stivale2_struct_tag_memmap {
|
||||
|
||||
#define STIVALE2_STRUCT_TAG_FRAMEBUFFER_ID 0x506461d2950408fa
|
||||
|
||||
enum {
|
||||
STIVALE2_FBUF_MMODEL_RGB = 1
|
||||
};
|
||||
|
||||
struct stivale2_struct_tag_framebuffer {
|
||||
struct stivale2_tag tag;
|
||||
uint64_t framebuffer_addr;
|
||||
@ -90,6 +94,13 @@ struct stivale2_struct_tag_framebuffer {
|
||||
uint16_t framebuffer_height;
|
||||
uint16_t framebuffer_pitch;
|
||||
uint16_t framebuffer_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;
|
||||
} __attribute__((packed));
|
||||
|
||||
#define STIVALE2_STRUCT_TAG_MODULES_ID 0x4b6fe466aade04ce
|
||||
|
@ -73,6 +73,13 @@ void stivale2_main(struct stivale2_struct *info) {
|
||||
e9_printf("\tHeight: %d", f->framebuffer_height);
|
||||
e9_printf("\tPitch: %d", f->framebuffer_pitch);
|
||||
e9_printf("\tBPP: %d", f->framebuffer_bpp);
|
||||
e9_printf("\tMemory model: %d", f->memory_model);
|
||||
e9_printf("\tRed mask size: %d", f->red_mask_size);
|
||||
e9_printf("\tRed mask size: %d", f->red_mask_shift);
|
||||
e9_printf("\tGreen mask size: %d", f->green_mask_size);
|
||||
e9_printf("\tGreen mask size: %d", f->green_mask_shift);
|
||||
e9_printf("\tBlue mask size: %d", f->blue_mask_size);
|
||||
e9_printf("\tBlue mask size: %d", f->blue_mask_shift);
|
||||
break;
|
||||
}
|
||||
case STIVALE2_STRUCT_TAG_MODULES_ID: {
|
||||
|
Loading…
Reference in New Issue
Block a user