xref: /haiku/src/system/kernel/arch/m68k/paging/040/M68KPagingStructures040.cpp (revision 778611c7e6a61b8ba072212756ce53eda826360a)
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