+
+// --- Hardware Mappings ---
+/**
+ * \brief Map a range of hardware pages
+ */
+tVAddr MM_MapHWPages(tPAddr PAddr, Uint Number)
+{
+ Log_KernelPanic("MM", "TODO: Implement MM_MapHWPages");
+ return 0;
+}
+
+/**
+ * \brief Free a range of hardware pages
+ */
+void MM_UnmapHWPages(tVAddr VAddr, Uint Number)
+{
+ Log_KernelPanic("MM", "TODO: Implement MM_UnmapHWPages");
+}
+
+// --- Tempory Mappings ---
+tVAddr MM_MapTemp(tPAddr PAddr)
+{
+ Log_KernelPanic("MM", "TODO: Implement MM_MapTemp");
+ return 0;
+}
+
+void MM_FreeTemp(tVAddr VAddr)
+{
+ Log_KernelPanic("MM", "TODO: Implement MM_FreeTemp");
+ return ;
+}
+
+
+// --- Address Space Clone --
+tPAddr MM_Clone(void)
+{
+ tPAddr ret;
+
+ // #1 Create a copy of the PML4
+ ret = MM_AllocPhys();
+ if(!ret) return 0;
+
+ Log_KernelPanic("MM", "TODO: Implement MM_Clone");
+
+ // #2 Alter the fractal pointer
+ // #3 Set Copy-On-Write to all user pages
+ // #4 Return
+ return 0;
+}
+
+void MM_ClearUser(void)
+{
+ tVAddr addr = 0;
+ // #1 Traverse the structure < 2^47, Deref'ing all pages
+ // #2 Free tables/dirs/pdps once they have been cleared
+
+ for( addr = 0; addr < 0x800000000000; )
+ {
+ if( PAGEMAPLVL4(addr >> PML4_SHIFT) & 1 )
+ {
+ if( PAGEDIRPTR(addr >> PDP_SHIFT) & 1 )
+ {
+ if( PAGEDIR(addr >> PDIR_SHIFT) & 1 )
+ {
+ // Page
+ if( PAGETABLE(addr >> PTAB_SHIFT) & 1 ) {
+ MM_DerefPhys( PAGETABLE(addr >> PTAB_SHIFT) & PADDR_MASK );
+ PAGETABLE(addr >> PTAB_SHIFT) = 0;
+ }
+ addr += 1 << PTAB_SHIFT;
+ // Dereference the PDIR Entry
+ if( (addr + (1 << PTAB_SHIFT)) >> PDIR_SHIFT != (addr >> PDIR_SHIFT) ) {
+ MM_DerefPhys( PAGEMAPLVL4(addr >> PDIR_SHIFT) & PADDR_MASK );
+ PAGEDIR(addr >> PDIR_SHIFT) = 0;
+ }
+ }
+ else {
+ addr += 1 << PDIR_SHIFT;
+ continue;
+ }
+ // Dereference the PDP Entry
+ if( (addr + (1 << PDIR_SHIFT)) >> PDP_SHIFT != (addr >> PDP_SHIFT) ) {
+ MM_DerefPhys( PAGEMAPLVL4(addr >> PDP_SHIFT) & PADDR_MASK );
+ PAGEDIRPTR(addr >> PDP_SHIFT) = 0;
+ }
+ }
+ else {
+ addr += 1 << PDP_SHIFT;
+ continue;
+ }
+ // Dereference the PML4 Entry
+ if( (addr + (1 << PDP_SHIFT)) >> PML4_SHIFT != (addr >> PML4_SHIFT) ) {
+ MM_DerefPhys( PAGEMAPLVL4(addr >> PML4_SHIFT) & PADDR_MASK );
+ PAGEMAPLVL4(addr >> PML4_SHIFT) = 0;
+ }
+ }
+ else {
+ addr += (tVAddr)1 << PML4_SHIFT;
+ continue;
+ }
+ }
+}
+
+tVAddr MM_NewWorkerStack(void)
+{
+ Log_KernelPanic("MM", "TODO: Implement MM_NewWorkerStack");
+ return 0;
+}
+
+/**
+ * \brief Allocate a new kernel stack
+ */
+tVAddr MM_NewKStack(void)
+{
+ tVAddr base = MM_KSTACK_BASE;
+ Uint i;
+ for( ; base < MM_KSTACK_TOP; base += KERNEL_STACK_SIZE )
+ {
+ if(MM_GetPhysAddr(base) != 0)
+ continue;
+
+ Log("MM_NewKStack: Found one at %p", base + KERNEL_STACK_SIZE);
+ for( i = 0; i < KERNEL_STACK_SIZE; i += 0x1000)
+ MM_Allocate(base+i);
+
+ return base + KERNEL_STACK_SIZE;
+ }
+ Log_Warning("MM", "MM_NewKStack - No address space left\n");
+ return 0;
+}