5 * This file implements a local pagetable, to prevent IPC on physical
6 * address lookups. For now it's implement in a signle linked list.
8 * As soon as the DDE will use a premeptive thread mechanism access to
9 * the page table has to be sznchronized.
13 #include <ddekit/pgtab.h>
14 #include <ddekit/memory.h>
15 #include <ddekit/lock.h>
17 #ifdef DDEBUG_LEVEL_PGTAB
19 #define DDEBUG DDEBUG_LEVEL_PGTAB
26 static void lock_pgtab(void);
27 static void unlock_pgtab(void);
28 static struct dde_pgtab_region
* allocate_region(void);
29 static void free_region(struct dde_pgtab_region
*r
);
30 static void add_region(struct dde_pgtab_region
*r
);
31 static void rm_region(struct dde_pgtab_region
*r
);
32 static struct dde_pgtab_region
* find_region_virt(ddekit_addr_t va
);
33 static struct dde_pgtab_region
* find_region_phys(ddekit_addr_t pa
);
35 struct dde_pgtab_region
{
36 ddekit_addr_t vm_start
;
37 ddekit_addr_t phy_start
;
39 unsigned type
; /* do we really have to keep track of the type here? */
40 struct dde_pgtab_region
*next
;
41 struct dde_pgtab_region
*prev
;
44 static struct dde_pgtab_region head
= {0,0,0,0,&head
,&head
};
45 static ddekit_lock_t lock
;
51 /****************************************************************************/
53 /****************************************************************************/
54 static void lock_pgtab()
56 ddekit_lock_lock(&lock
);
60 /****************************************************************************/
62 /****************************************************************************/
63 static void unlock_pgtab()
65 ddekit_lock_unlock(&lock
);
68 /****************************************************************************/
69 /* dde_pgtab_region */
70 /****************************************************************************/
71 static struct dde_pgtab_region
* allocate_region()
73 struct dde_pgtab_region
* res
;
75 res
= (struct dde_pgtab_region
*)
76 ddekit_simple_malloc(sizeof(struct dde_pgtab_region
));
79 DDEBUG_MSG_ERR("Could not allocate region");
84 /****************************************************************************/
86 /****************************************************************************/
87 static void free_region(struct dde_pgtab_region
*r
)
89 ddekit_simple_free(r
);
92 /****************************************************************************/
94 /****************************************************************************/
95 static void add_region (struct dde_pgtab_region
*r
)
108 /****************************************************************************/
110 /****************************************************************************/
111 static void rm_region(struct dde_pgtab_region
*r
)
114 r
->next
->prev
= r
->prev
;
117 r
->prev
->next
= r
->next
;
124 /****************************************************************************/
125 /* find_region_virt */
126 /****************************************************************************/
127 static struct dde_pgtab_region
* find_region_virt(ddekit_addr_t va
)
129 struct dde_pgtab_region
* r
;
131 for( r
= head
.next
; r
!= &head
; r
= r
->next
) {
133 if ( (r
->vm_start
<= va
) && (va
< (r
->vm_start
+ r
->size
) ) ) {
139 DDEBUG_MSG_VERBOSE("No virt->phys mapping found for %x", va
);
146 /****************************************************************************/
147 /* find_region_phys */
148 /****************************************************************************/
149 static struct dde_pgtab_region
* find_region_phys(ddekit_addr_t pa
)
151 struct dde_pgtab_region
* r
;
153 for( r
= head
.next
; r
!= &head
; r
= r
->next
) {
154 if ( (r
->phy_start
<= pa
) && (pa
< (r
->phy_start
+ r
->size
) ) )
160 DDEBUG_MSG_VERBOSE("No phys->virt mapping found for %x", pa
);
166 /****************************************************************************/
167 /* ddekit_pgtab_do_fo_each_region */
168 /****************************************************************************/
169 void ddekit_pgtab_do_fo_each_region(void (*func
) (unsigned, unsigned)) {
170 struct dde_pgtab_region
* r
;
172 for( r
= head
.next
; r
!= &head
; r
= r
->next
) {
173 ddekit_printf("%p",r
->vm_start
);
174 func(r
->vm_start
, r
->size
);
179 * Interface implementation
182 /****************************************************************************/
183 /* ddekit_pgtab_set_region */
184 /****************************************************************************/
185 void ddekit_pgtab_set_region(void *virt
, ddekit_addr_t phys
, int pages
, int type
)
187 ddekit_pgtab_set_region_with_size(virt
, phys
, (4096)*pages
, type
);
190 /****************************************************************************/
191 /* ddekit_pgtab_set_region_with_size */
192 /****************************************************************************/
193 void ddekit_pgtab_set_region_with_size(void *virt
, ddekit_addr_t phys
, int size
, int type
)
195 struct dde_pgtab_region
* r
;
199 r
= allocate_region();
201 r
->vm_start
= (ddekit_addr_t
) virt
;
212 /****************************************************************************/
213 /* ddekit_pgtab_clear_region */
214 /****************************************************************************/
215 void ddekit_pgtab_clear_region(void *virt
, int type
) {
217 struct dde_pgtab_region
*r
;
221 r
= find_region_virt((ddekit_addr_t
)virt
);
234 /****************************************************************************/
235 /* ddekit_pgtab_get_physaddr */
236 /****************************************************************************/
237 ddekit_addr_t
ddekit_pgtab_get_physaddr(const void *virt
)
239 struct dde_pgtab_region
*r
;
240 ddekit_addr_t ret
= 0;
242 r
= find_region_virt((ddekit_addr_t
)virt
);
246 ret
= ((ddekit_addr_t
) virt
- r
->vm_start
) + r
->phy_start
;
247 DDEBUG_MSG_VERBOSE("pa: %p -> %p\n", virt
, ret
);
253 /****************************************************************************/
254 /* ddekit_pgtab_get_virtaddr */
255 /****************************************************************************/
256 ddekit_addr_t
ddekit_pgtab_get_virtaddr(const ddekit_addr_t physical
)
258 struct dde_pgtab_region
*r
;
260 r
= find_region_phys((ddekit_addr_t
)physical
);
264 return ((ddekit_addr_t
) physical
- r
->phy_start
) + r
->vm_start
;
270 /****************************************************************************/
271 /* ddekit_pgtab_get_size */
272 /****************************************************************************/
273 int ddekit_pgtab_get_type(const void *virt
)
276 * needed for dde fbsd
278 struct dde_pgtab_region
*r
;
281 r
= find_region_virt((ddekit_addr_t
)virt
);
287 /****************************************************************************/
288 /* ddekit_pgtab_get_size */
289 /****************************************************************************/
290 int ddekit_pgtab_get_size(const void *virt
)
295 struct dde_pgtab_region
*r
;
298 r
= find_region_virt((ddekit_addr_t
)virt
);
306 /****************************************************************************/
307 /* ddekit_pgtab_init */
308 /****************************************************************************/
309 void ddekit_pgtab_init() {
310 /* called by ddekit_init() */
311 ddekit_lock_init(&lock
);