+/*
+ * A.k.a MM_Unmap
+ */
+void MM_Deallocate(volatile void *VAddr)
+{
+ Uint pagenum = (tVAddr)VAddr >> 12;
+ if( gaPageDir[pagenum>>10] == 0 ) {
+ Warning("MM_Deallocate - Directory not mapped");
+ return;
+ }
+
+ if(gaPageTable[pagenum] == 0) {
+ Warning("MM_Deallocate - Page is not allocated");
+ return;
+ }
+
+ // Dereference and clear page
+ tPAddr paddr = gaPageTable[pagenum] & ~0xFFF;
+ gaPageTable[pagenum] = 0;
+ MM_DerefPhys( paddr );
+}
+
+/**
+ * \fn tPAddr MM_GetPhysAddr(tVAddr Addr)
+ * \brief Checks if the passed address is accesable
+ */
+tPAddr MM_GetPhysAddr(volatile const void *Addr)
+{
+ tVAddr addr = (tVAddr)Addr;
+ if( !(gaPageDir[addr >> 22] & 1) )
+ return 0;
+ if( !(gaPageTable[addr >> 12] & 1) )
+ return 0;
+ return (gaPageTable[addr >> 12] & ~0xFFF) | (addr & 0xFFF);
+}
+
+/**
+ * \brief Get the address of a page from another addres space
+ * \return Refenced physical address (or 0 on error)
+ */
+tPAddr MM_GetPageFromAS(tProcess *Process, volatile const void *Addr)
+{
+ tPAddr ret = 0;
+ GET_TEMP_MAPPING(Process->MemState.CR3);
+ tVAddr addr = (tVAddr)Addr;
+ if( (gaTmpDir[addr >> 22] & 1) && (gaTmpTable[addr >> 12] & 1) ) {
+ ret = (gaTmpTable[addr >> 12] & ~0xFFF) | (addr & 0xFFF);
+ MM_RefPhys( ret );
+ }
+ REL_TEMP_MAPPING();
+ return ret;
+}
+
+/**
+ * \fn void MM_SetCR3(Uint CR3)
+ * \brief Sets the current process space
+ */
+void MM_SetCR3(Uint CR3)
+{
+ __ASM__("mov %0, %%cr3"::"r"(CR3));
+}
+