xref: /haiku/src/system/kernel/arch/ppc/paging/460/PPCPagingStructures460.cpp (revision 13581b3d2a71545960b98fefebc5225b5bf29072)
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