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