The link to the entire repository: https://github.com/spatialflunky1/flosp-os
The specific line that causes the lockup (drivers/mem.c):
Code: Select all
(*page) |= flags;
Code: Select all
void set_mem_page_flags(void* addr, ui64_t flags) {
ui64_t* page = (ui64_t*)get_mem_page(addr);
blank_output();
// Address
kprint("\nAddress: ");
kprint_hex((ui64_t)addr, true);
// Page address
kprint("\nPage_Addr: ");
kprint_hex((ui64_t)page, true);
// Page
kprint("\nPage: ");
kprint_hex(*page, true);
// Flags
kprint("\nFlags: ");
kprint_hex(flags, true);
flush_framebuffer();
/*
No Need for the commented out code below as in this current test case the caching type (or memory type at all) does not change
*/
// // Remove previous mapping
// (*page) &= ~0x1;
// // Flush the TLB
// invlpg(addr);
// // Create a new mapping in the page tables
(*page) |= flags;
// (*page) |= 0x1;
// kprint("\nMapping created");
// flush_buffer();
kprint("\nPage(Post): ");
kprint_hex((*page), true);
flush_framebuffer();
blank_output();
flush_framebuffer();
}
void* get_mem_page(void* addr) {
// Indexing bits:
// ---------------
// 47-39: PML4 (9 bits)
// 38-30: PDPT (9 bits)
// 29-21: PD (9 bits)
// 20-12: PT (9 bits)
// 0-11: The page itself (12 bits)
map_table* PML4 = (map_table*)(read_cr3() & 0xFFFFFFFFFFFFF000); // First 12 bits are to be ignored
ui64_t PML4_index = ((ui64_t)addr >> 39) & 0b111111111;
map_table* PDP = (map_table*)(PML4->entries[PML4_index] & PAGE_ADDR_MASK);
ui64_t PDP_index = ((ui64_t)addr >> 30) & 0b111111111;
void* page = NULL;
//ui8_t page_offset_width = 0;
if ((PDP->entries[PDP_index] >> 7) & 0x1) {
// Pages are 1 GiB (ignore PD)
page = &PDP->entries[PDP_index];
//page_offset_width = 30;
}
else {
map_table* PD = (map_table*)(PDP->entries[PDP_index] & PAGE_ADDR_MASK);
ui64_t PD_index = ((ui64_t)addr >> 21) & 0b111111111;
if ((PD->entries[PD_index] >> 7) & 0x1) {
// Pages are 2 Mib (ignore PT)
page = &PD->entries[PD_index];
//page_offset_width = 21;
}
else {
// Pages are 4 Kib (use PT)
map_table* PT = (map_table*)(PD->entries[PD_index] & PAGE_ADDR_MASK);
ui64_t PT_index = ((ui64_t)addr >> 12) & 0b111111111;
page = &PT->entries[PT_index];
//page_offset_width = 12;
}
}
return page;
}
Code: Select all
void initialize_video(BOOT_VIDEO_MODE_INFO* VMI) {
VideoModeInfo = VMI;
framebuffer_info.width = VideoModeInfo->PixelsPerScanline;
framebuffer_info.height = VideoModeInfo->VerticalResolution;
framebuffer_info.pitch = VideoModeInfo->PixelsPerScanline * 4;
framebuffer_info.depth = 32;
max_text_line = (framebuffer_info.height / font_size) - 1;
// Set framebuffer page tables to look to PAT PA4 (instead of memory default PA0)
// THIS SHOULD WORK AS IS RIGHT NOW AS THE MEMORY MODE IS NOT CHANGING (PAT modification commented out below) (WB -> WB)
for (ui64_t i = 0; i < (framebuffer_info.width * framebuffer_info.height * 4); i++) {
set_mem_page_flags(
(void*)((ui64_t)VideoModeInfo->FramebufferPointer + i),
PFlag_PAT);
}
// // Set PAT PA4 to Write-Combining mode (mode 001)
// ui32_t low,high;
// rdmsr(0x277, &low, &high);
// low |= 0b00100000000000000000000000000000000; // Set bit 32
// low &= ~0b11000000000000000000000000000000000; // Clear bits 33 and 34
// wrmsr(0x277, low, high);
blank_output();
}
----------------------------------------------
Videos of the code working as intended:
https://drive.google.com/file/d/1m8b0AH ... drive_link (Lenovo IdeaPad Z580)
https://drive.google.com/file/d/1aos8Fz ... drive_link (QEMU)
Videos of the system lockup:
https://drive.google.com/file/d/1q1CEm1 ... drive_link (VBox)
https://drive.google.com/file/d/1LJNwr1 ... drive_link (Lenovo Thinkpad P16s)