summaryrefslogtreecommitdiff
path: root/Kernel/Firmware/BIOS.cpp
blob: 0a1ee1be6406e6d7e90218f4cd513a25d1792621 (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
/*
 * Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
 * Copyright (c) 2022, Liav A. <liavalb@hotmail.co.il>
 *
 * SPDX-License-Identifier: BSD-2-Clause
 */

#include <Kernel/Firmware/BIOS.h>
#include <Kernel/Memory/MemoryManager.h>
#include <Kernel/Memory/TypedMapping.h>

namespace Kernel {

ErrorOr<Memory::MappedROM> map_bios()
{
    Memory::MappedROM mapping;
    mapping.size = 128 * KiB;
    mapping.paddr = PhysicalAddress(0xe0000);
    auto region_size = TRY(Memory::page_round_up(mapping.size));
    mapping.region = TRY(MM.allocate_kernel_region(mapping.paddr, region_size, {}, Memory::Region::Access::Read));
    return mapping;
}

ErrorOr<Memory::MappedROM> map_ebda()
{
    auto ebda_segment_ptr = TRY(Memory::map_typed<u16>(PhysicalAddress(0x40e)));
    PhysicalAddress ebda_paddr(PhysicalAddress(*ebda_segment_ptr).get() << 4);
    // The EBDA size is stored in the first byte of the EBDA in 1K units
    size_t ebda_size = *TRY(Memory::map_typed<u8>(ebda_paddr));
    ebda_size *= 1024;

    Memory::MappedROM mapping;
    auto region_size = TRY(Memory::page_round_up(ebda_size));
    mapping.region = TRY(MM.allocate_kernel_region(ebda_paddr.page_base(), region_size, {}, Memory::Region::Access::Read));
    mapping.offset = ebda_paddr.offset_in_page();
    mapping.size = ebda_size;
    mapping.paddr = ebda_paddr;
    return mapping;
}

}