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/040/M68KPagingStructures040.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 // M68KPagingStructures040. 21 struct PagingStructuresGetLink { 22 private: 23 typedef SinglyLinkedListLink<M68KPagingStructures040> Link; 24 25 public: 26 inline Link* operator()(M68KPagingStructures040* element) const 27 { 28 return (Link*)element->GetSinglyLinkedListLink(); 29 } 30 31 inline const Link* operator()( 32 const M68KPagingStructures040* element) const 33 { 34 return (const Link*)element->GetSinglyLinkedListLink(); 35 } 36 }; 37 38 39 typedef SinglyLinkedList<M68KPagingStructures040, PagingStructuresGetLink> 40 PagingStructuresList; 41 42 43 static PagingStructuresList sPagingStructuresList; 44 static spinlock sPagingStructuresListLock; 45 46 47 M68KPagingStructures040::M68KPagingStructures040() 48 : 49 pgroot_virt(NULL) 50 { 51 } 52 53 54 M68KPagingStructures040::~M68KPagingStructures040() 55 { 56 // free the page dir 57 free(pgroot_virt); 58 } 59 60 61 void 62 M68KPagingStructures040::Init(page_root_entry* virtualPageRoot, 63 phys_addr_t physicalPageRoot, page_root_entry* kernelPageRoot) 64 { 65 pgroot_virt = virtualPageRoot; 66 pgroot_phys = physicalPageRoot; 67 68 // zero out the bottom portion of the new pgroot 69 memset(pgroot_virt + FIRST_USER_PGROOT_ENT, 0, 70 NUM_USER_PGROOT_ENTS * sizeof(page_root_entry)); 71 72 // insert this new map into the map list 73 { 74 int state = disable_interrupts(); 75 acquire_spinlock(&sPagingStructuresListLock); 76 77 // copy the top portion of the page dir from the kernel page dir 78 if (kernelPageRoot != NULL) { 79 memcpy(pgroot_virt + FIRST_KERNEL_PGROOT_ENT, 80 kernelPageRoot + FIRST_KERNEL_PGROOT_ENT, 81 NUM_KERNEL_PGROOT_ENTS * sizeof(page_root_entry)); 82 } 83 84 sPagingStructuresList.Add(this); 85 86 release_spinlock(&sPagingStructuresListLock); 87 restore_interrupts(state); 88 } 89 } 90 91 92 void 93 M68KPagingStructures040::Delete() 94 { 95 // remove from global list 96 InterruptsSpinLocker locker(sPagingStructuresListLock); 97 sPagingStructuresList.Remove(this); 98 locker.Unlock(); 99 100 #if 0 101 // this sanity check can be enabled when corruption due to 102 // overwriting an active page directory is suspected 103 uint32 activePageDirectory; 104 read_cr3(activePageDirectory); 105 if (activePageDirectory == pgdir_phys) 106 panic("deleting a still active page directory\n"); 107 #endif 108 109 if (are_interrupts_enabled()) 110 delete this; 111 else 112 deferred_delete(this); 113 } 114 115 116 /*static*/ void 117 M68KPagingStructures040::StaticInit() 118 { 119 B_INITIALIZE_SPINLOCK(&sPagingStructuresListLock); 120 new (&sPagingStructuresList) PagingStructuresList; 121 } 122 123 124 /*static*/ void 125 M68KPagingStructures040::UpdateAllPageDirs(int index, 126 page_root_entry entry) 127 { 128 #warning M68K: TODO: allocate all kernel pgdirs at boot and remove this (also dont remove them anymore from unmap) 129 #warning M68K:FIXME 130 InterruptsSpinLocker locker(sPagingStructuresListLock); 131 132 PagingStructuresList::Iterator it = sPagingStructuresList.GetIterator(); 133 while (M68KPagingStructures040* info = it.Next()) 134 info->pgroot_virt[index] = entry; 135 } 136