update main #1

Merged
Sinipelto merged 240 commits from Bananymous/banan-os:main into main 2023-11-20 13:20:51 +02:00
3 changed files with 74 additions and 0 deletions
Showing only changes of commit 211cad03ff - Show all commits

View File

@ -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

View File

@ -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;
};
}

View File

@ -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));
}
}