#include "paging/X86VMTranslationMap.h"
#include <thread.h>
#include <smp.h>
#include "paging/X86PagingStructures.h"
#ifdef TRACE_X86_VM_TRANSLATION_MAP
# define TRACE(x...) dprintf(x)
#else
# define TRACE(x...) ;
#endif
X86VMTranslationMap::X86VMTranslationMap()
:
fPageMapper(NULL),
fInvalidPagesCount(0)
{
}
X86VMTranslationMap::~X86VMTranslationMap()
{
}
status_t
X86VMTranslationMap::Init(bool kernel)
{
fIsKernelMap = kernel;
return B_OK;
}
bool
X86VMTranslationMap::Lock()
{
TRACE("%p->X86VMTranslationMap::Lock()\n", this);
recursive_lock_lock(&fLock);
if (recursive_lock_get_recursion(&fLock) == 1) {
TRACE("clearing invalidated page count\n");
fInvalidPagesCount = 0;
}
return true;
}
void
X86VMTranslationMap::Unlock()
{
TRACE("%p->X86VMTranslationMap::Unlock()\n", this);
if (recursive_lock_get_recursion(&fLock) == 1) {
Flush();
}
recursive_lock_unlock(&fLock);
}
addr_t
X86VMTranslationMap::MappedSize() const
{
return fMapCount;
}
void
X86VMTranslationMap::Flush()
{
if (fInvalidPagesCount <= 0)
return;
Thread* thread = thread_get_current_thread();
thread_pin_to_current_cpu(thread);
if (fInvalidPagesCount > PAGE_INVALIDATE_CACHE_SIZE) {
TRACE("flush_tmap: %d pages to invalidate, invalidate all\n",
fInvalidPagesCount);
if (fIsKernelMap) {
smp_broadcast_ici(SMP_MSG_GLOBAL_INVALIDATE_PAGES, 0, 0, 0,
NULL, SMP_MSG_FLAG_SYNC);
} else {
InvalidateUserTLB(PagingStructures()->active_on_cpus, x86_read_cr3());
}
} else {
TRACE("flush_tmap: %d pages to invalidate, invalidate list\n",
fInvalidPagesCount);
if (fIsKernelMap) {
smp_broadcast_ici(SMP_MSG_INVALIDATE_PAGE_LIST,
0, (addr_t)fInvalidPages, fInvalidPagesCount, NULL,
SMP_MSG_FLAG_SYNC);
} else {
InvalidateTLBList(PagingStructures()->active_on_cpus, x86_read_cr3(),
fInvalidPages, fInvalidPagesCount);
}
}
fInvalidPagesCount = 0;
thread_unpin_from_current_cpu(thread);
}