#include "paging/ARMVMTranslationMap.h"
#include <thread.h>
#include <smp.h>
#include "paging/ARMPagingStructures.h"
#ifdef TRACE_ARM_VM_TRANSLATION_MAP
# define TRACE(x...) dprintf(x)
#else
# define TRACE(x...) ;
#endif
ARMVMTranslationMap::ARMVMTranslationMap()
:
fPageMapper(NULL),
fInvalidPagesCount(0)
{
}
ARMVMTranslationMap::~ARMVMTranslationMap()
{
}
status_t
ARMVMTranslationMap::Init(bool kernel)
{
fIsKernelMap = kernel;
return B_OK;
}
bool
ARMVMTranslationMap::Lock()
{
TRACE("%p->ARMVMTranslationMap::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
ARMVMTranslationMap::Unlock()
{
TRACE("%p->ARMVMTranslationMap::Unlock()\n", this);
if (recursive_lock_get_recursion(&fLock) == 1) {
Flush();
}
recursive_lock_unlock(&fLock);
}
addr_t
ARMVMTranslationMap::MappedSize() const
{
return fMapCount;
}
void
ARMVMTranslationMap::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, 0);
}
} 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, 0,
fInvalidPages, fInvalidPagesCount);
}
}
fInvalidPagesCount = 0;
thread_unpin_from_current_cpu(thread);
}