+/**
+ * \brief Deallocate an address space
+ */
+void MM_ClearSpace(Uint32 CR3)
+{
+ int i, j;
+
+ if(CR3 == (*gpPageCR3 & ~0xFFF)) {
+ Log_Error("MMVirt", "Can't clear current address space");
+ return ;
+ }
+
+ if( MM_GetRefCount(CR3) > 1 ) {
+ Log_Log("MMVirt", "CR3 %P is still referenced, not clearing", CR3);
+ return ;
+ }
+
+ Log_Debug("MMVirt", "Clearing out address space 0x%x from 0x%x", CR3, *gpPageCR3);
+
+ GET_TEMP_MAPPING(CR3);
+ INVLPG( gaTmpDir );
+
+ for( i = 0; i < 1024; i ++ )
+ {
+ Uint32 *table = &gaTmpTable[i*1024];
+ if( !(gaTmpDir[i] & PF_PRESENT) )
+ continue ;
+
+ INVLPG( table );
+
+ if( i < 768 || (i > MM_KERNEL_STACKS >> 22 && i < MM_KERNEL_STACKS_END >> 22) )
+ {
+ for( j = 0; j < 1024; j ++ )
+ {
+ if( !(table[j] & 1) )
+ continue;
+ MM_DerefPhys( table[j] & ~0xFFF );
+ }
+ }
+
+ if( i != (PAGE_TABLE_ADDR >> 22) )
+ {
+ MM_DerefPhys( gaTmpDir[i] & ~0xFFF );
+ }
+ }
+
+
+ MM_DerefPhys( CR3 );
+
+ REL_TEMP_MAPPING();
+}
+