aboutsummaryrefslogtreecommitdiff
path: root/src/arch/x86/common/boot/multiboot.rs
blob: 09789ceecfd05a24a388b536fba13d2d74573807 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
pub const MULTIBOOT2_BOOTLOADER_MAGIC: u32 = 0x36d76289;
pub const MULTIBOOT_TAG_TYPE_END: u32 = 0;
pub const MULTIBOOT_TAG_TYPE_MMAP: u32 = 6;
pub const MULTIBOOT_TAG_TYPE_FB: u32 = 8;

use crate::{print, println};

pub fn parse_fb_multiboot(mut mem: *mut u32) {
    let framebuffer_addr: u64 = unsafe { *(mem as *mut u64) };
    let framebuffer_pitch: u32 = unsafe { *mem.wrapping_add(2) };
    let framebuffer_width: u32 = unsafe { *mem.wrapping_add(3) };
    let framebuffer_height: u32 = unsafe { *mem.wrapping_add(4) };
    let framebuffer_bpp: u8 = unsafe { *(mem.wrapping_add(5) as *mut u8) };
    let framebuffer_type: u8 = unsafe { *(mem.wrapping_add(5) as *mut u8).wrapping_add(1) };
    let reserved: u8 = unsafe { *(mem.wrapping_add(5) as *mut u8).wrapping_add(1) };

    println!(
        "0x{:x} {:x} {:x} {:x}",
        framebuffer_addr, framebuffer_pitch, framebuffer_width, framebuffer_height
    );
}

pub fn parse_mem_multiboot(mut mem: *mut u32, _size: u32) {
    let mut curr_size: u32 = 16;

    while curr_size < _size {
        let base_addr: u64 = unsafe { *(mem as *mut u64) };
        let length: u64 = unsafe { *(mem.wrapping_add(2) as *mut u64) };
        let _type: u32 = unsafe { *mem.wrapping_add(4) };
        let reserved: u32 = unsafe { *mem.wrapping_add(5) };
        assert_eq!(reserved, 0, "reserved not 0");

        //println!("{:x} {:x} {:x}", base_addr, length, _type);

        mem = mem.wrapping_add(6);
        curr_size += 24;
    }
}

pub fn parse_multiboot(mut multiboot_bootinfo: *mut u32, multiboot_magic: u32) {
    assert_eq!(
        multiboot_magic, MULTIBOOT2_BOOTLOADER_MAGIC,
        "MULTIBOOT2_BOOTLOADER_MAGIC"
    );

    let total_size: u32 = unsafe { *multiboot_bootinfo };
    let mut size = 8;
    multiboot_bootinfo = multiboot_bootinfo.wrapping_add(2);

    while size < total_size {
        let _type: u32 = unsafe { *multiboot_bootinfo };
        let _size: u32 = unsafe { *(multiboot_bootinfo.wrapping_add(1)) };
        let mem: *mut u32 = multiboot_bootinfo.wrapping_add(4);
        let mem2: *mut u32 = multiboot_bootinfo.wrapping_add(2);

        match _type {
            MULTIBOOT_TAG_TYPE_FB => {
                parse_fb_multiboot(mem2);
            }
            MULTIBOOT_TAG_TYPE_MMAP => {
                parse_mem_multiboot(mem, _size);
            }
            _ => {}
        }

        let inc_size = (_size / 8 + (_size % 8 != 0) as u32) * 8;
        size += inc_size;

        println!("{} {} {}", _type, _size, inc_size);
        multiboot_bootinfo = multiboot_bootinfo.wrapping_add((inc_size / 4).try_into().unwrap());

        if _type == MULTIBOOT_TAG_TYPE_END {
            assert_eq!(_size, 8, "MULTIBOOT_TAG_TYPE_END");
            break;
        }
    }

    assert_eq!(total_size, size, "Multiboot");
}