From 73a182f80c601d8bd45ac6893439481371f44134 Mon Sep 17 00:00:00 2001 From: Jonas 'Sortie' Termansen Date: Sat, 17 Jan 2015 22:17:51 +0100 Subject: [PATCH] Add interface to get 32-bit pages. --- .../include/sortix/kernel/memorymanagement.h | 2 ++ kernel/x86-family/memorymanagement.cpp | 34 +++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/kernel/include/sortix/kernel/memorymanagement.h b/kernel/include/sortix/kernel/memorymanagement.h index 22da3ccf..953ce098 100644 --- a/kernel/include/sortix/kernel/memorymanagement.h +++ b/kernel/include/sortix/kernel/memorymanagement.h @@ -63,6 +63,8 @@ addr_t GetReserved(size_t* counter, enum page_usage usage); addr_t GetReservedUnlocked(size_t* counter, enum page_usage usage); addr_t Get(enum page_usage usage); addr_t GetUnlocked(enum page_usage usage); +addr_t Get32Bit(enum page_usage usage); +addr_t Get32BitUnlocked(enum page_usage usage); void Put(addr_t page, enum page_usage usage); void PutUnlocked(addr_t page, enum page_usage usage); void Lock(); diff --git a/kernel/x86-family/memorymanagement.cpp b/kernel/x86-family/memorymanagement.cpp index 5c953d72..56e23515 100644 --- a/kernel/x86-family/memorymanagement.cpp +++ b/kernel/x86-family/memorymanagement.cpp @@ -340,6 +340,40 @@ addr_t Get(enum page_usage usage) return GetUnlocked(usage); } +// TODO: This competes with the normal allocation for precious 32-bit pages, we +// should use different pools for this, and preferably preallocate some +// 32-bit pages exclusively for driver usage. Also, get proper hardware +// without these issues. +addr_t Get32BitUnlocked(enum page_usage usage) +{ + assert(stackreserved <= stackused); + if ( unlikely(stackreserved == stackused) ) + return errno = ENOMEM, 0; + for ( size_t ii = stackused; 0 < ii; ii-- ) + { + size_t i = ii - 1; + addr_t result = STACK[i]; + assert(result == AlignDown(result)); + if ( 4 < sizeof(void*) && UINT32_MAX < result ) + continue; + if ( i + 1 != stackused ) + { + STACK[i] = STACK[stackused - 1]; + STACK[stackused - 1] = result; + } + stackused--; + PageUsageRegisterUse(result, usage); + return result; + } + return errno = ENOMEM, 0; +} + +addr_t Get32Bit(enum page_usage usage) +{ + ScopedLock lock(&pagelock); + return Get32BitUnlocked(usage); +} + void PutUnlocked(addr_t page, enum page_usage usage) { assert(page == AlignDown(page));