stivale2: Implement MTRR Write Combining Framebuffer tag

This commit is contained in:
mintsuki 2021-01-03 02:43:27 +01:00
parent b63fad768a
commit 57496ad0c7
8 changed files with 68 additions and 1 deletions

View File

@ -210,6 +210,22 @@ struct stivale2_header_tag_framebuffer {
} __attribute__((packed));
```
#### Framebuffer MTRR write-combining header tag
The presence of this tag tells the bootloader to, in case a framebuffer was
requested, make that framebuffer's caching type write-combining using x86's
MTRR model specific registers. This caching type helps speed up framebuffer writes
on real hardware.
It is recommended to use this tag in conjunction with the SMP tag in order to
let the bootloader make the MTRR settings uniform across all CPUs.
If no framebuffer was requested, this tag has no effect.
Identifier: `0x4c7bb07731282e00`
This tag does not have extra members.
#### 5-level paging header tag
The presence of this tag enables support for 5-level paging, if available.
@ -345,6 +361,15 @@ struct stivale2_struct_tag_framebuffer {
} __attribute__((packed));
```
#### Framebuffer MTRR write-combining structure tag
This tag exists if MTRR write-combining for the framebuffer was requested and
successfully enabled.
Identifier: `0x6bc1a78ebe871172`
This tag does not have extra members.
#### Modules structure tag
This tag lists modules that the bootloader loaded alongside the kernel, if any.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -21,6 +21,7 @@
#include <sys/lapic.h>
#include <fs/file.h>
#include <mm/pmm.h>
#include <mm/mtrr.h>
#include <stivale/stivale2.h>
#include <pxe/tftp.h>
@ -274,6 +275,19 @@ void stivale2_load(char *config, char *cmdline, bool pxe) {
tag->blue_mask_shift = fbinfo.blue_mask_shift;
append_tag(&stivale2_struct, (struct stivale2_tag *)tag);
if (get_tag(&stivale2_hdr, STIVALE2_HEADER_TAG_FB_MTRR_ID) != NULL) {
mtrr_restore();
bool ret = mtrr_set_range(tag->framebuffer_addr,
(uint64_t)tag->framebuffer_pitch * tag->framebuffer_height,
MTRR_MEMORY_TYPE_WC);
if (ret) {
struct stivale2_tag *tag = ext_mem_alloc(sizeof(struct stivale2_tag));
tag->identifier = STIVALE2_STRUCT_TAG_FB_MTRR_ID;
append_tag(&stivale2_struct, (struct stivale2_tag *)tag);
}
mtrr_save();
}
}
}
}
@ -289,6 +303,8 @@ void stivale2_load(char *config, char *cmdline, bool pxe) {
// Create SMP struct tag
//////////////////////////////////////////////
{
mtrr_restore();
struct stivale2_header_tag_smp *smp_hdr_tag = get_tag(&stivale2_hdr, STIVALE2_HEADER_TAG_SMP_ID);
if (smp_hdr_tag != NULL) {
struct stivale2_struct_tag_smp *tag;

View File

@ -3,6 +3,14 @@ extern smp_tpl_booted_flag
extern smp_tpl_pagemap
extern smp_tpl_target_mode
extern mtrr_restore
section .bss
temp_stack:
resb 1024
.top:
section .realmode
global smp_trampoline
@ -46,6 +54,10 @@ smp_trampoline:
wrmsr
.nox2apic:
mov esp, temp_stack.top
call mtrr_restore
test dword [smp_tpl_target_mode], (1 << 0)
jz parking32

View File

@ -20,6 +20,8 @@ struct stivale2_header {
#define STIVALE2_HEADER_TAG_FRAMEBUFFER_ID 0x3ecc1bc43d0f7971
#define STIVALE2_HEADER_TAG_FB_MTRR_ID 0x4c7bb07731282e00
struct stivale2_header_tag_framebuffer {
struct stivale2_tag tag;
uint16_t framebuffer_width;
@ -103,6 +105,8 @@ struct stivale2_struct_tag_framebuffer {
uint8_t blue_mask_shift;
} __attribute__((packed));
#define STIVALE2_STRUCT_TAG_FB_MTRR_ID 0x6bc1a78ebe871172
#define STIVALE2_STRUCT_TAG_MODULES_ID 0x4b6fe466aade04ce
struct stivale2_module {

View File

@ -15,10 +15,15 @@ struct stivale2_header_tag_smp smp_request = {
.flags = 0
};
struct stivale2_tag fb_mtrr_request = {
.identifier = STIVALE2_HEADER_TAG_FB_MTRR_ID,
.next = (uint64_t)&smp_request
};
struct stivale2_header_tag_framebuffer framebuffer_request = {
.tag = {
.identifier = STIVALE2_HEADER_TAG_FRAMEBUFFER_ID,
.next = (uint64_t)&smp_request
.next = (uint64_t)&fb_mtrr_request
},
.framebuffer_width = 0,
.framebuffer_height = 0,
@ -82,6 +87,11 @@ void stivale2_main(struct stivale2_struct *info) {
e9_printf("\tBlue mask size: %d", f->blue_mask_shift);
break;
}
case STIVALE2_STRUCT_TAG_FB_MTRR_ID: {
e9_puts("Framebuffer WC MTRR tag:");
e9_puts("\tFramebuffer WC MTRR enabled");
break;
}
case STIVALE2_STRUCT_TAG_MODULES_ID: {
struct stivale2_struct_tag_modules *m = (struct stivale2_struct_tag_modules *)tag;
e9_puts("Modules tag:");