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/classic/PPCPagingStructuresClassic.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 // PPCPagingStructuresClassic.
21 struct PagingStructuresGetLink {
22 private:
23 typedef SinglyLinkedListLink<PPCPagingStructuresClassic> Link;
24
25 public:
operator ()PagingStructuresGetLink26 inline Link* operator()(PPCPagingStructuresClassic* element) const
27 {
28 return (Link*)element->GetSinglyLinkedListLink();
29 }
30
operator ()PagingStructuresGetLink31 inline const Link* operator()(
32 const PPCPagingStructuresClassic* element) const
33 {
34 return (const Link*)element->GetSinglyLinkedListLink();
35 }
36 };
37
38
39 typedef SinglyLinkedList<PPCPagingStructuresClassic, PagingStructuresGetLink>
40 PagingStructuresList;
41
42
43 static PagingStructuresList sPagingStructuresList;
44 static spinlock sPagingStructuresListLock;
45
46
PPCPagingStructuresClassic()47 PPCPagingStructuresClassic::PPCPagingStructuresClassic()
48 /* :
49 pgdir_virt(NULL)*/
50 {
51 }
52
53
~PPCPagingStructuresClassic()54 PPCPagingStructuresClassic::~PPCPagingStructuresClassic()
55 {
56 #if 0//X86
57 // free the page dir
58 free(pgdir_virt);
59 #endif
60 }
61
62
63 void
Init(page_table_entry_group * pageTable)64 PPCPagingStructuresClassic::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
Delete()100 PPCPagingStructuresClassic::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
StaticInit()123 PPCPagingStructuresClassic::StaticInit()
124 {
125 B_INITIALIZE_SPINLOCK(&sPagingStructuresListLock);
126 new (&sPagingStructuresList) PagingStructuresList;
127 }
128
129
130 /*static*/ void
UpdateAllPageDirs(int index,page_table_entry_group entry)131 PPCPagingStructuresClassic::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 (PPCPagingStructuresClassic* info = it.Next())
139 info->pgdir_virt[index] = entry;
140 #endif
141 }
142