forked from Bananymous/banan-os
update main #1
|
@ -34,6 +34,7 @@ set(KERNEL_SOURCES
|
|||
kernel/Input/PS2Keymap.cpp
|
||||
kernel/InterruptController.cpp
|
||||
kernel/kernel.cpp
|
||||
kernel/Memory/DMARegion.cpp
|
||||
kernel/Memory/FileBackedRegion.cpp
|
||||
kernel/Memory/GeneralAllocator.cpp
|
||||
kernel/Memory/Heap.cpp
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
#pragma once
|
||||
|
||||
#include <kernel/Memory/MemoryRegion.h>
|
||||
|
||||
namespace Kernel
|
||||
{
|
||||
|
||||
class DMARegion
|
||||
{
|
||||
public:
|
||||
BAN::ErrorOr<BAN::UniqPtr<DMARegion>> create(size_t size);
|
||||
~DMARegion();
|
||||
|
||||
size_t size() const { return m_size; }
|
||||
vaddr_t vaddr() const { return m_vaddr; }
|
||||
paddr_t paddr() const { return m_paddr; }
|
||||
|
||||
private:
|
||||
DMARegion(size_t size, vaddr_t vaddr, paddr_t paddr);
|
||||
|
||||
private:
|
||||
const size_t m_size;
|
||||
const vaddr_t m_vaddr;
|
||||
const paddr_t m_paddr;
|
||||
};
|
||||
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
#include <BAN/ScopeGuard.h>
|
||||
#include <kernel/Memory/DMARegion.h>
|
||||
#include <kernel/Memory/Heap.h>
|
||||
|
||||
namespace Kernel
|
||||
{
|
||||
|
||||
BAN::ErrorOr<BAN::UniqPtr<DMARegion>> DMARegion::create(size_t size)
|
||||
{
|
||||
size_t needed_pages = BAN::Math::div_round_up<size_t>(size, PAGE_SIZE);
|
||||
|
||||
vaddr_t vaddr = PageTable::kernel().reserve_free_contiguous_pages(needed_pages, KERNEL_OFFSET);
|
||||
if (vaddr == 0)
|
||||
return BAN::Error::from_errno(ENOMEM);
|
||||
BAN::ScopeGuard vaddr_guard([vaddr, size] { PageTable::kernel().unmap_range(vaddr, size); });
|
||||
|
||||
paddr_t paddr = Heap::get().take_free_contiguous_pages(needed_pages);
|
||||
if (paddr == 0)
|
||||
return BAN::Error::from_errno(ENOMEM);
|
||||
BAN::ScopeGuard paddr_guard([paddr, needed_pages] { Heap::get().release_contiguous_pages(paddr, needed_pages); });
|
||||
|
||||
auto* region_ptr = new DMARegion(size, vaddr, paddr);
|
||||
if (region_ptr == nullptr)
|
||||
return BAN::Error::from_errno(ENOMEM);
|
||||
|
||||
vaddr_guard.disable();
|
||||
paddr_guard.disable();
|
||||
|
||||
PageTable::kernel().map_range_at(paddr, vaddr, size, PageTable::Flags::CacheDisable | PageTable::Flags::ReadWrite | PageTable::Flags::Reserved);
|
||||
|
||||
return BAN::UniqPtr<DMARegion>::adopt(region_ptr);
|
||||
}
|
||||
|
||||
DMARegion::DMARegion(size_t size, vaddr_t vaddr, paddr_t paddr)
|
||||
: m_size(size)
|
||||
, m_vaddr(vaddr)
|
||||
, m_paddr(paddr)
|
||||
{ }
|
||||
|
||||
DMARegion::~DMARegion()
|
||||
{
|
||||
PageTable::kernel().unmap_range(m_vaddr, m_size);
|
||||
Heap::get().release_contiguous_pages(m_vaddr, BAN::Math::div_round_up<size_t>(m_size, PAGE_SIZE));
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue