2 * Copyright 2008-2011, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Copyright 2002-2007, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
4 * Distributed under the terms of the MIT License.
6 * Copyright 2001-2002, Travis Geiselbrecht. All rights reserved.
7 * Distributed under the terms of the NewOS License.
11 #include "paging/X86VMTranslationMap.h"
16 #include "paging/X86PagingStructures.h"
19 //#define TRACE_X86_VM_TRANSLATION_MAP
20 #ifdef TRACE_X86_VM_TRANSLATION_MAP
21 # define TRACE(x...) dprintf(x)
23 # define TRACE(x...) ;
27 X86VMTranslationMap::X86VMTranslationMap()
35 X86VMTranslationMap::~X86VMTranslationMap()
41 X86VMTranslationMap::Init(bool kernel
)
43 fIsKernelMap
= kernel
;
48 /*! Acquires the map's recursive lock, and resets the invalidate pages counter
49 in case it's the first locking recursion.
52 X86VMTranslationMap::Lock()
54 TRACE("%p->X86VMTranslationMap::Lock()\n", this);
56 recursive_lock_lock(&fLock
);
57 if (recursive_lock_get_recursion(&fLock
) == 1) {
58 // we were the first one to grab the lock
59 TRACE("clearing invalidated page count\n");
60 fInvalidPagesCount
= 0;
67 /*! Unlocks the map, and, if we are actually losing the recursive lock,
68 flush all pending changes of this map (ie. flush TLB caches as
72 X86VMTranslationMap::Unlock()
74 TRACE("%p->X86VMTranslationMap::Unlock()\n", this);
76 if (recursive_lock_get_recursion(&fLock
) == 1) {
77 // we're about to release it for the last time
81 recursive_lock_unlock(&fLock
);
86 X86VMTranslationMap::MappedSize() const
93 X86VMTranslationMap::Flush()
95 if (fInvalidPagesCount
<= 0)
98 Thread
* thread
= thread_get_current_thread();
99 thread_pin_to_current_cpu(thread
);
101 if (fInvalidPagesCount
> PAGE_INVALIDATE_CACHE_SIZE
) {
102 // invalidate all pages
103 TRACE("flush_tmap: %d pages to invalidate, invalidate all\n",
107 arch_cpu_global_TLB_invalidate();
108 smp_send_broadcast_ici(SMP_MSG_GLOBAL_INVALIDATE_PAGES
, 0, 0, 0,
109 NULL
, SMP_MSG_FLAG_SYNC
);
111 cpu_status state
= disable_interrupts();
112 arch_cpu_user_TLB_invalidate();
113 restore_interrupts(state
);
115 int cpu
= smp_get_current_cpu();
116 CPUSet cpuMask
= PagingStructures()->active_on_cpus
;
117 cpuMask
.ClearBit(cpu
);
119 if (!cpuMask
.IsEmpty()) {
120 smp_send_multicast_ici(cpuMask
, SMP_MSG_USER_INVALIDATE_PAGES
,
121 0, 0, 0, NULL
, SMP_MSG_FLAG_SYNC
);
125 TRACE("flush_tmap: %d pages to invalidate, invalidate list\n",
128 arch_cpu_invalidate_TLB_list(fInvalidPages
, fInvalidPagesCount
);
131 smp_send_broadcast_ici(SMP_MSG_INVALIDATE_PAGE_LIST
,
132 (addr_t
)fInvalidPages
, fInvalidPagesCount
, 0, NULL
,
135 int cpu
= smp_get_current_cpu();
136 CPUSet cpuMask
= PagingStructures()->active_on_cpus
;
137 cpuMask
.ClearBit(cpu
);
139 if (!cpuMask
.IsEmpty()) {
140 smp_send_multicast_ici(cpuMask
, SMP_MSG_INVALIDATE_PAGE_LIST
,
141 (addr_t
)fInvalidPages
, fInvalidPagesCount
, 0, NULL
,
146 fInvalidPagesCount
= 0;
148 thread_unpin_from_current_cpu(thread
);