1 /* 2 * Copyright 2008-2010, 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. 5 * 6 * Copyright 2001-2002, Travis Geiselbrecht. All rights reserved. 7 * Distributed under the terms of the NewOS License. 8 */ 9 10 11 #include "paging/460/PPCPagingStructures460.h" 12 13 #include <stdlib.h> 14 15 #include <heap.h> 16 #include <util/AutoLock.h> 17 18 19 // Accessor class to reuse the SinglyLinkedListLink of DeferredDeletable for 20 // PPCPagingStructures460. 21 struct PagingStructuresGetLink { 22 private: 23 typedef SinglyLinkedListLink<PPCPagingStructures460> Link; 24 25 public: 26 inline Link* operator()(PPCPagingStructures460* element) const 27 { 28 return (Link*)element->GetSinglyLinkedListLink(); 29 } 30 31 inline const Link* operator()( 32 const PPCPagingStructures460* element) const 33 { 34 return (const Link*)element->GetSinglyLinkedListLink(); 35 } 36 }; 37 38 39 typedef SinglyLinkedList<PPCPagingStructures460, PagingStructuresGetLink> 40 PagingStructuresList; 41 42 43 static PagingStructuresList sPagingStructuresList; 44 static spinlock sPagingStructuresListLock; 45 46 47 PPCPagingStructures460::PPCPagingStructures460() 48 /* : 49 pgdir_virt(NULL)*/ 50 { 51 } 52 53 54 PPCPagingStructures460::~PPCPagingStructures460() 55 { 56 #if 0//X86 57 // free the page dir 58 free(pgdir_virt); 59 #endif 60 } 61 62 63 void 64 PPCPagingStructures460::Init(/*page_directory_entry* virtualPageDir, 65 phys_addr_t physicalPageDir, page_directory_entry* kernelPageDir*/ 66 page_table_entry_group *pageTable) 67 { 68 // pgdir_virt = virtualPageDir; 69 // pgdir_phys = physicalPageDir; 70 71 #if 0//X86 72 // zero out the bottom portion of the new pgdir 73 memset(pgdir_virt + FIRST_USER_PGDIR_ENT, 0, 74 NUM_USER_PGDIR_ENTS * sizeof(page_directory_entry)); 75 #endif 76 77 // insert this new map into the map list 78 { 79 int state = disable_interrupts(); 80 acquire_spinlock(&sPagingStructuresListLock); 81 82 #if 0//X86 83 // copy the top portion of the page dir from the kernel page dir 84 if (kernelPageDir != NULL) { 85 memcpy(pgdir_virt + FIRST_KERNEL_PGDIR_ENT, 86 kernelPageDir + FIRST_KERNEL_PGDIR_ENT, 87 NUM_KERNEL_PGDIR_ENTS * sizeof(page_directory_entry)); 88 } 89 #endif 90 91 sPagingStructuresList.Add(this); 92 93 release_spinlock(&sPagingStructuresListLock); 94 restore_interrupts(state); 95 } 96 } 97 98 99 void 100 PPCPagingStructures460::Delete() 101 { 102 // remove from global list 103 InterruptsSpinLocker locker(sPagingStructuresListLock); 104 sPagingStructuresList.Remove(this); 105 locker.Unlock(); 106 107 #if 0 108 // this sanity check can be enabled when corruption due to 109 // overwriting an active page directory is suspected 110 uint32 activePageDirectory = x86_read_cr3(); 111 if (activePageDirectory == pgdir_phys) 112 panic("deleting a still active page directory\n"); 113 #endif 114 115 if (are_interrupts_enabled()) 116 delete this; 117 else 118 deferred_delete(this); 119 } 120 121 122 /*static*/ void 123 PPCPagingStructures460::StaticInit() 124 { 125 B_INITIALIZE_SPINLOCK(&sPagingStructuresListLock); 126 new (&sPagingStructuresList) PagingStructuresList; 127 } 128 129 130 /*static*/ void 131 PPCPagingStructures460::UpdateAllPageDirs(int index, 132 page_table_entry_group entry) 133 //XXX:page_table_entry? 134 { 135 InterruptsSpinLocker locker(sPagingStructuresListLock); 136 #if 0//X86 137 PagingStructuresList::Iterator it = sPagingStructuresList.GetIterator(); 138 while (PPCPagingStructures460* info = it.Next()) 139 info->pgdir_virt[index] = entry; 140 #endif 141 } 142