<commit_before>use spin::Mutex;

use memory::Frame;
use paging::{ActivePageTable, Page, PhysicalAddress, VirtualAddress};
use paging::entry::EntryFlags;

pub use self::debug::DebugDisplay;
use self::display::Display;
use self::mode_info::VBEModeInfo;
use self::primitive::fast_set64;

pub mod debug;
pub mod display;
pub mod mode_info;
pub mod primitive;

pub static FONT: &'static [u8] = include_bytes!("../../../../res/unifont.font");

pub static DEBUG_DISPLAY: Mutex<Option<DebugDisplay>> = Mutex::new(None);

pub fn init(active_table: &mut ActivePageTable) {
    println!("Starting graphical debug");

    let width;
    let height;
    let physbaseptr;

    {
        let mode_info_addr = 0x5200;

        {
            let page = Page::containing_address(VirtualAddress::new(mode_info_addr));
            let frame = Frame::containing_address(PhysicalAddress::new(page.start_address().get()));
            let result = active_table.map_to(page, frame, EntryFlags::PRESENT | EntryFlags::NO_EXECUTE);
            result.flush(active_table);
        }

        {
            let mode_info = unsafe { &*(mode_info_addr as *const VBEModeInfo) };

            width = mode_info.xresolution as usize;
            height = mode_info.yresolution as usize;
            physbaseptr = mode_info.physbaseptr as usize;
        }

        {
            let page = Page::containing_address(VirtualAddress::new(mode_info_addr));
            let result = active_table.unmap_return(page);
            result.flush(active_table);
        }
    }

    {
        let size = width * height;

        let onscreen = physbaseptr + ::KERNEL_OFFSET;
        {
            let start_page = Page::containing_address(VirtualAddress::new(onscreen));
            let end_page = Page::containing_address(VirtualAddress::new(onscreen + size * 4));
            for page in Page::range_inclusive(start_page, end_page) {
                let frame = Frame::containing_address(PhysicalAddress::new(page.start_address().get() - ::KERNEL_OFFSET));
                let flags = EntryFlags::PRESENT | EntryFlags::NO_EXECUTE | EntryFlags::WRITABLE | EntryFlags::HUGE_PAGE;
                let result = active_table.map_to(page, frame, flags);
                result.flush(active_table);
            }
        }

        unsafe { fast_set64(onscreen as *mut u64, 0, size/2) };

        let display = Display::new(width, height, onscreen);
        let debug_display = DebugDisplay::new(display);
        *DEBUG_DISPLAY.lock() = Some(debug_display);
    }
}

pub fn fini(active_table: &mut ActivePageTable) {
    if let Some(debug_display) = DEBUG_DISPLAY.lock().take() {
        let display = debug_display.into_display();
        let onscreen = display.onscreen.as_mut_ptr() as usize;
        let size = display.width * display.height;
        {
            let start_page = Page::containing_address(VirtualAddress::new(onscreen));
            let end_page = Page::containing_address(VirtualAddress::new(onscreen + size * 4));
            for page in Page::range_inclusive(start_page, end_page) {
                let result = active_table.unmap_return(page);
                result.flush(active_table);
            }
        }
    }

    println!("Finished graphical debug");
}<commit_msg>Fix mapping code for physbaseptr<commit_after>use spin::Mutex;

use memory::Frame;
use paging::{ActivePageTable, Page, PhysicalAddress, VirtualAddress};
use paging::entry::EntryFlags;
use paging::mapper::MapperFlushAll;

pub use self::debug::DebugDisplay;
use self::display::Display;
use self::mode_info::VBEModeInfo;
use self::primitive::fast_set64;

pub mod debug;
pub mod display;
pub mod mode_info;
pub mod primitive;

pub static FONT: &'static [u8] = include_bytes!("../../../../res/unifont.font");

pub static DEBUG_DISPLAY: Mutex<Option<DebugDisplay>> = Mutex::new(None);

pub fn init(active_table: &mut ActivePageTable) {
    println!("Starting graphical debug");

    let width;
    let height;
    let physbaseptr;

    {
        let mode_info_addr = 0x5200;

        {
            let page = Page::containing_address(VirtualAddress::new(mode_info_addr));
            let frame = Frame::containing_address(PhysicalAddress::new(page.start_address().get()));
            let result = active_table.map_to(page, frame, EntryFlags::PRESENT | EntryFlags::NO_EXECUTE);
            result.flush(active_table);
        }

        {
            let mode_info = unsafe { &*(mode_info_addr as *const VBEModeInfo) };

            width = mode_info.xresolution as usize;
            height = mode_info.yresolution as usize;
            physbaseptr = mode_info.physbaseptr as usize;
        }

        {
            let page = Page::containing_address(VirtualAddress::new(mode_info_addr));
            let (result, _frame) = active_table.unmap_return(page, false);
            result.flush(active_table);
        }
    }

    {
        let size = width * height;

        let onscreen = physbaseptr + ::KERNEL_OFFSET;
        {
            let mut flush_all = MapperFlushAll::new();
            let start_page = Page::containing_address(VirtualAddress::new(onscreen));
            let end_page = Page::containing_address(VirtualAddress::new(onscreen + size * 4));
            for page in Page::range_inclusive(start_page, end_page) {
                let frame = Frame::containing_address(PhysicalAddress::new(page.start_address().get() - ::KERNEL_OFFSET));
                let flags = EntryFlags::PRESENT | EntryFlags::NO_EXECUTE | EntryFlags::WRITABLE | EntryFlags::HUGE_PAGE;
                let result = active_table.map_to(page, frame, flags);
                flush_all.consume(result);
            }
            flush_all.flush(active_table);
        }

        unsafe { fast_set64(onscreen as *mut u64, 0, size/2) };

        let display = Display::new(width, height, onscreen);
        let debug_display = DebugDisplay::new(display);
        *DEBUG_DISPLAY.lock() = Some(debug_display);
    }
}

pub fn fini(active_table: &mut ActivePageTable) {
    if let Some(debug_display) = DEBUG_DISPLAY.lock().take() {
        let display = debug_display.into_display();
        let onscreen = display.onscreen.as_mut_ptr() as usize;
        let size = display.width * display.height;
        {
            let mut flush_all = MapperFlushAll::new();
            let start_page = Page::containing_address(VirtualAddress::new(onscreen));
            let end_page = Page::containing_address(VirtualAddress::new(onscreen + size * 4));
            for page in Page::range_inclusive(start_page, end_page) {
                let (result, _frame) = active_table.unmap_return(page, false);
                flush_all.consume(result);
            }
            flush_all.flush(active_table);
        }
    }

    println!("Finished graphical debug");
}
{'fraction_non_alphanumeric': 0.11723934522931721, 'fraction_numerical': 0.004719067984073145, 'mean_word_length': 2.8381437464629315, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4611514', 'n_tokens_mistral': 2030, 'n_tokens_neox': 1954, 'n_words': 408}