Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


cdb14f71e9f6a4ab98aa19c2709fd7b50c1c9c85
[palacios.git] / palacios / src / palacios / vmm_paging.c
1 /* 
2  * This file is part of the Palacios Virtual Machine Monitor developed
3  * by the V3VEE Project with funding from the United States National 
4  * Science Foundation and the Department of Energy.  
5  *
6  * The V3VEE Project is a joint project between Northwestern University
7  * and the University of New Mexico.  You can find out more at 
8  * http://www.v3vee.org
9  *
10  * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> 
11  * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org> 
12  * All rights reserved.
13  *
14  * Author: Jack Lange <jarusl@cs.northwestern.edu>
15  *
16  * This is free software.  You are permitted to use,
17  * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
18  */
19
20 #include <palacios/vmm_paging.h>
21
22 #include <palacios/vmm.h>
23
24 #include <palacios/vm_guest_mem.h>
25
26
27
28
29   
30
31
32 void delete_page_tables_pde32(pde32_t * pde) {
33   int i;//, j;
34
35   if (pde == NULL) { 
36     return;
37   }
38
39   for (i = 0; (i < MAX_PDE32_ENTRIES); i++) {
40     if (pde[i].present) {
41       // We double cast, first to an addr_t to handle 64 bit issues, then to the pointer
42       PrintDebug("PTE base addr %x \n", pde[i].pt_base_addr);
43       pte32_t * pte = (pte32_t *)((addr_t)(uint_t)(pde[i].pt_base_addr << PAGE_POWER));
44
45       /*
46         for (j = 0; (j < MAX_PTE32_ENTRIES); j++) {
47         if ((pte[j].present)) {
48         os_hooks->free_page((void *)(pte[j].page_base_addr << PAGE_POWER));
49         }
50         }
51       */
52       PrintDebug("Deleting PTE %d (%p)\n", i, pte);
53       V3_FreePage(pte);
54     }
55   }
56
57   PrintDebug("Deleting PDE (%p)\n", pde);
58   V3_FreePage(V3_PAddr(pde));
59 }
60
61
62
63
64
65 int pt32_lookup(pde32_t * pd, addr_t vaddr, addr_t * paddr) {
66   addr_t pde_entry;
67   pde32_entry_type_t pde_entry_type;
68
69   if (pd == 0) {
70     return -1;
71   }
72
73   pde_entry_type = pde32_lookup(pd, vaddr, &pde_entry);
74
75   if (pde_entry_type == PDE32_ENTRY_PTE32) {
76     return pte32_lookup((pte32_t *)pde_entry, vaddr, paddr);
77   } else if (pde_entry_type == PDE32_ENTRY_LARGE_PAGE) {
78     *paddr = pde_entry;
79     return 0;
80   }
81
82   return -1;
83 }
84
85
86
87 /* We can't do a full lookup because we don't know what context the page tables are in...
88  * The entry addresses could be pointing to either guest physical memory or host physical memory
89  * Instead we just return the entry address, and a flag to show if it points to a pte or a large page...
90  */
91 pde32_entry_type_t pde32_lookup(pde32_t * pd, addr_t addr, addr_t * entry) {
92   pde32_t * pde_entry = &(pd[PDE32_INDEX(addr)]);
93
94   if (!pde_entry->present) {
95     *entry = 0;
96     return PDE32_ENTRY_NOT_PRESENT;
97   } else  {
98
99     if (pde_entry->large_page) {
100       pde32_4MB_t * large_pde = (pde32_4MB_t *)pde_entry;
101
102       *entry = PDE32_4MB_T_ADDR(*large_pde);
103       *entry += PD32_4MB_PAGE_OFFSET(addr);
104       return PDE32_ENTRY_LARGE_PAGE;
105     } else {
106       *entry = PDE32_T_ADDR(*pde_entry);
107       return PDE32_ENTRY_PTE32;
108     }
109   }  
110   return PDE32_ENTRY_NOT_PRESENT;
111 }
112
113
114
115 /* Takes a virtual addr (addr) and returns the physical addr (entry) as defined in the page table
116  */
117 int pte32_lookup(pte32_t * pt, addr_t addr, addr_t * entry) {
118   pte32_t * pte_entry = &(pt[PTE32_INDEX(addr)]);
119
120   if (!pte_entry->present) {
121     *entry = 0;
122     PrintDebug("Lookup at non present page (index=%d)\n", PTE32_INDEX(addr));
123     return -1;
124   } else {
125     *entry = PTE32_T_ADDR(*pte_entry) + PT32_PAGE_OFFSET(addr);
126     return 0;
127   }
128
129   return -1;
130 }
131
132
133
134 pt_access_status_t can_access_pde32(pde32_t * pde, addr_t addr, pf_error_t access_type) {
135   pde32_t * entry = &pde[PDE32_INDEX(addr)];
136
137   if (entry->present == 0) {
138     return PT_ENTRY_NOT_PRESENT;
139   } else if ((entry->writable == 0) && (access_type.write == 1)) {
140     return PT_WRITE_ERROR;
141   } else if ((entry->user_page == 0) && (access_type.user == 1)) {
142     // Check CR0.WP?
143     return PT_USER_ERROR;
144   }
145
146   return PT_ACCESS_OK;
147 }
148
149
150 pt_access_status_t can_access_pte32(pte32_t * pte, addr_t addr, pf_error_t access_type) {
151   pte32_t * entry = &pte[PTE32_INDEX(addr)];
152
153   if (entry->present == 0) {
154     return PT_ENTRY_NOT_PRESENT;
155   } else if ((entry->writable == 0) && (access_type.write == 1)) {
156     return PT_WRITE_ERROR;
157   } else if ((entry->user_page == 0) && (access_type.user == 1)) {
158     // Check CR0.WP?
159     return PT_USER_ERROR;
160   }
161
162   return PT_ACCESS_OK;
163 }
164
165
166
167
168 /* We generate a page table to correspond to a given memory layout
169  * pulling pages from the mem_list when necessary
170  * If there are any gaps in the layout, we add them as unmapped pages
171  */
172 pde32_t * create_passthrough_pts_32(struct guest_info * guest_info) {
173   addr_t current_page_addr = 0;
174   int i, j;
175   struct shadow_map * map = &(guest_info->mem_map);
176
177   pde32_t * pde = V3_VAddr(V3_AllocPages(1));
178
179   for (i = 0; i < MAX_PDE32_ENTRIES; i++) {
180     int pte_present = 0;
181     pte32_t * pte = V3_VAddr(V3_AllocPages(1));
182     
183
184     for (j = 0; j < MAX_PTE32_ENTRIES; j++) {
185       struct shadow_region * region = get_shadow_region_by_addr(map, current_page_addr);
186
187       if (!region || 
188           (region->host_type == HOST_REGION_HOOK) || 
189           (region->host_type == HOST_REGION_UNALLOCATED) || 
190           (region->host_type == HOST_REGION_MEMORY_MAPPED_DEVICE) || 
191           (region->host_type == HOST_REGION_REMOTE) ||
192           (region->host_type == HOST_REGION_SWAPPED)) {
193         pte[j].present = 0;
194         pte[j].writable = 0;
195         pte[j].user_page = 0;
196         pte[j].write_through = 0;
197         pte[j].cache_disable = 0;
198         pte[j].accessed = 0;
199         pte[j].dirty = 0;
200         pte[j].pte_attr = 0;
201         pte[j].global_page = 0;
202         pte[j].vmm_info = 0;
203         pte[j].page_base_addr = 0;
204       } else {
205         addr_t host_addr;
206         pte[j].present = 1;
207         pte[j].writable = 1;
208         pte[j].user_page = 1;
209         pte[j].write_through = 0;
210         pte[j].cache_disable = 0;
211         pte[j].accessed = 0;
212         pte[j].dirty = 0;
213         pte[j].pte_attr = 0;
214         pte[j].global_page = 0;
215         pte[j].vmm_info = 0;
216
217         if (guest_pa_to_host_pa(guest_info, current_page_addr, &host_addr) == -1) {
218           // BIG ERROR
219           // PANIC
220           return NULL;
221         }
222         
223         pte[j].page_base_addr = host_addr >> 12;
224         
225         pte_present = 1;
226       }
227
228       current_page_addr += PAGE_SIZE;
229     }
230
231     if (pte_present == 0) { 
232       V3_FreePage(V3_PAddr(pte));
233
234       pde[i].present = 0;
235       pde[i].writable = 0;
236       pde[i].user_page = 0;
237       pde[i].write_through = 0;
238       pde[i].cache_disable = 0;
239       pde[i].accessed = 0;
240       pde[i].reserved = 0;
241       pde[i].large_page = 0;
242       pde[i].global_page = 0;
243       pde[i].vmm_info = 0;
244       pde[i].pt_base_addr = 0;
245     } else {
246       pde[i].present = 1;
247       pde[i].writable = 1;
248       pde[i].user_page = 1;
249       pde[i].write_through = 0;
250       pde[i].cache_disable = 0;
251       pde[i].accessed = 0;
252       pde[i].reserved = 0;
253       pde[i].large_page = 0;
254       pde[i].global_page = 0;
255       pde[i].vmm_info = 0;
256       pde[i].pt_base_addr = PAGE_ALIGNED_ADDR((addr_t)V3_PAddr(pte));
257     }
258
259   }
260
261   return pde;
262 }
263
264
265 /* We generate a page table to correspond to a given memory layout
266  * pulling pages from the mem_list when necessary
267  * If there are any gaps in the layout, we add them as unmapped pages
268  */
269 pdpe32pae_t * create_passthrough_pts_PAE32(struct guest_info * guest_info) {
270   addr_t current_page_addr = 0;
271   int i, j, k;
272   struct shadow_map * map = &(guest_info->mem_map);
273
274   pdpe32pae_t * pdpe = V3_VAddr(V3_AllocPages(1));
275   memset(pdpe, 0, PAGE_SIZE);
276
277   for (i = 0; i < MAX_PDPE32PAE_ENTRIES; i++) {
278     int pde_present = 0;
279     pde32pae_t * pde = V3_VAddr(V3_AllocPages(1));
280
281     for (j = 0; j < MAX_PDE32PAE_ENTRIES; j++) {
282
283
284       int pte_present = 0;
285       pte32pae_t * pte = V3_VAddr(V3_AllocPages(1));
286       
287       
288       for (k = 0; k < MAX_PTE32PAE_ENTRIES; k++) {
289         struct shadow_region * region = get_shadow_region_by_addr(map, current_page_addr);
290         
291         if (!region || 
292             (region->host_type == HOST_REGION_HOOK) || 
293             (region->host_type == HOST_REGION_UNALLOCATED) || 
294             (region->host_type == HOST_REGION_MEMORY_MAPPED_DEVICE) || 
295             (region->host_type == HOST_REGION_REMOTE) ||
296             (region->host_type == HOST_REGION_SWAPPED)) {
297           pte[k].present = 0;
298           pte[k].writable = 0;
299           pte[k].user_page = 0;
300           pte[k].write_through = 0;
301           pte[k].cache_disable = 0;
302           pte[k].accessed = 0;
303           pte[k].dirty = 0;
304           pte[k].pte_attr = 0;
305           pte[k].global_page = 0;
306           pte[k].vmm_info = 0;
307           pte[k].page_base_addr = 0;
308           pte[k].rsvd = 0;
309         } else {
310           addr_t host_addr;
311           pte[k].present = 1;
312           pte[k].writable = 1;
313           pte[k].user_page = 1;
314           pte[k].write_through = 0;
315           pte[k].cache_disable = 0;
316           pte[k].accessed = 0;
317           pte[k].dirty = 0;
318           pte[k].pte_attr = 0;
319           pte[k].global_page = 0;
320           pte[k].vmm_info = 0;
321           
322           if (guest_pa_to_host_pa(guest_info, current_page_addr, &host_addr) == -1) {
323             // BIG ERROR
324             // PANIC
325             return NULL;
326           }
327           
328           pte[k].page_base_addr = host_addr >> 12;
329           pte[k].rsvd = 0;
330
331           pte_present = 1;
332         }
333         
334         current_page_addr += PAGE_SIZE;
335       }
336       
337       if (pte_present == 0) { 
338         V3_FreePage(V3_PAddr(pte));
339         
340         pde[j].present = 0;
341         pde[j].writable = 0;
342         pde[j].user_page = 0;
343         pde[j].write_through = 0;
344         pde[j].cache_disable = 0;
345         pde[j].accessed = 0;
346         pde[j].avail = 0;
347         pde[j].large_page = 0;
348         pde[j].global_page = 0;
349         pde[j].vmm_info = 0;
350         pde[j].pt_base_addr = 0;
351         pde[j].rsvd = 0;
352       } else {
353         pde[j].present = 1;
354         pde[j].writable = 1;
355         pde[j].user_page = 1;
356         pde[j].write_through = 0;
357         pde[j].cache_disable = 0;
358         pde[j].accessed = 0;
359         pde[j].avail = 0;
360         pde[j].large_page = 0;
361         pde[j].global_page = 0;
362         pde[j].vmm_info = 0;
363         pde[j].pt_base_addr = PAGE_ALIGNED_ADDR((addr_t)V3_PAddr(pte));
364         pde[j].rsvd = 0;
365
366         pde_present = 1;
367       }
368       
369     }
370     
371     if (pde_present == 0) { 
372       V3_FreePage(V3_PAddr(pde));
373       
374       pdpe[i].present = 0;
375       pdpe[i].rsvd = 0;
376       pdpe[i].write_through = 0;
377       pdpe[i].cache_disable = 0;
378       pdpe[i].accessed = 0;
379       pdpe[i].avail = 0;
380       pdpe[i].rsvd2 = 0;
381       pdpe[i].vmm_info = 0;
382       pdpe[i].pd_base_addr = 0;
383       pdpe[i].rsvd3 = 0;
384     } else {
385       pdpe[i].present = 1;
386       pdpe[i].rsvd = 0;
387       pdpe[i].write_through = 0;
388       pdpe[i].cache_disable = 0;
389       pdpe[i].accessed = 0;
390       pdpe[i].avail = 0;
391       pdpe[i].rsvd2 = 0;
392       pdpe[i].vmm_info = 0;
393       pdpe[i].pd_base_addr = PAGE_ALIGNED_ADDR((addr_t)V3_PAddr(pde));
394       pdpe[i].rsvd3 = 0;
395     }
396     
397   }
398
399
400   return pdpe;
401 }
402
403
404
405
406
407
408 pml4e64_t * create_passthrough_pts_64(struct guest_info * info) {
409   addr_t current_page_addr = 0;
410   int i, j, k, m;
411   struct shadow_map * map = &(info->mem_map);
412   
413   pml4e64_t * pml = V3_VAddr(V3_AllocPages(1));
414
415   for (i = 0; i < 1; i++) {
416     int pdpe_present = 0;
417     pdpe64_t * pdpe = V3_VAddr(V3_AllocPages(1));
418
419     for (j = 0; j < 1; j++) {
420       int pde_present = 0;
421       pde64_t * pde = V3_VAddr(V3_AllocPages(1));
422
423       for (k = 0; k < MAX_PDE64_ENTRIES; k++) {
424         int pte_present = 0;
425         pte64_t * pte = V3_VAddr(V3_AllocPages(1));
426
427
428         for (m = 0; m < MAX_PTE64_ENTRIES; m++) {
429           struct shadow_region * region = get_shadow_region_by_addr(map, current_page_addr);
430           
431
432           
433           if (!region || 
434               (region->host_type == HOST_REGION_HOOK) || 
435               (region->host_type == HOST_REGION_UNALLOCATED) || 
436               (region->host_type == HOST_REGION_MEMORY_MAPPED_DEVICE) || 
437               (region->host_type == HOST_REGION_REMOTE) ||
438               (region->host_type == HOST_REGION_SWAPPED)) {
439             pte[m].present = 0;
440             pte[m].writable = 0;
441             pte[m].user_page = 0;
442             pte[m].write_through = 0;
443             pte[m].cache_disable = 0;
444             pte[m].accessed = 0;
445             pte[m].dirty = 0;
446             pte[m].pte_attr = 0;
447             pte[m].global_page = 0;
448             pte[m].vmm_info = 0;
449             pte[m].page_base_addr = 0;
450           } else {
451             addr_t host_addr;
452             pte[m].present = 1;
453             pte[m].writable = 1;
454             pte[m].user_page = 1;
455             pte[m].write_through = 0;
456             pte[m].cache_disable = 0;
457             pte[m].accessed = 0;
458             pte[m].dirty = 0;
459             pte[m].pte_attr = 0;
460             pte[m].global_page = 0;
461             pte[m].vmm_info = 0;
462             
463             if (guest_pa_to_host_pa(info, current_page_addr, &host_addr) == -1) {
464               // BIG ERROR
465               // PANIC
466               return NULL;
467             }
468
469             pte[m].page_base_addr = PTE64_BASE_ADDR(host_addr);
470
471             //PrintPTE64(current_page_addr, &(pte[m]));
472
473             pte_present = 1;      
474           }
475
476
477
478
479           current_page_addr += PAGE_SIZE;
480         }
481         
482         if (pte_present == 0) {
483           V3_FreePage(V3_PAddr(pte));
484
485           pde[k].present = 0;
486           pde[k].writable = 0;
487           pde[k].user_page = 0;
488           pde[k].write_through = 0;
489           pde[k].cache_disable = 0;
490           pde[k].accessed = 0;
491           pde[k].reserved = 0;
492           pde[k].large_page = 0;
493           //pde[k].global_page = 0;
494           pde[k].vmm_info = 0;
495           pde[k].pt_base_addr = 0;
496         } else {
497           pde[k].present = 1;
498           pde[k].writable = 1;
499           pde[k].user_page = 1;
500           pde[k].write_through = 0;
501           pde[k].cache_disable = 0;
502           pde[k].accessed = 0;
503           pde[k].reserved = 0;
504           pde[k].large_page = 0;
505           //pde[k].global_page = 0;
506           pde[k].vmm_info = 0;
507           pde[k].pt_base_addr = PAGE_ALIGNED_ADDR((addr_t)V3_PAddr(pte));
508
509           pde_present = 1;
510         }
511       }
512
513       if (pde_present == 0) {
514         V3_FreePage(V3_PAddr(pde));
515         
516         pdpe[j].present = 0;
517         pdpe[j].writable = 0;
518         pdpe[j].user_page = 0;
519         pdpe[j].write_through = 0;
520         pdpe[j].cache_disable = 0;
521         pdpe[j].accessed = 0;
522         pdpe[j].reserved = 0;
523         pdpe[j].large_page = 0;
524         //pdpe[j].global_page = 0;
525         pdpe[j].vmm_info = 0;
526         pdpe[j].pd_base_addr = 0;
527       } else {
528         pdpe[j].present = 1;
529         pdpe[j].writable = 1;
530         pdpe[j].user_page = 1;
531         pdpe[j].write_through = 0;
532         pdpe[j].cache_disable = 0;
533         pdpe[j].accessed = 0;
534         pdpe[j].reserved = 0;
535         pdpe[j].large_page = 0;
536         //pdpe[j].global_page = 0;
537         pdpe[j].vmm_info = 0;
538         pdpe[j].pd_base_addr = PAGE_ALIGNED_ADDR((addr_t)V3_PAddr(pde));
539
540
541         pdpe_present = 1;
542       }
543
544     }
545
546     PrintDebug("PML index=%d\n", i);
547
548     if (pdpe_present == 0) {
549       V3_FreePage(V3_PAddr(pdpe));
550       
551       pml[i].present = 0;
552       pml[i].writable = 0;
553       pml[i].user_page = 0;
554       pml[i].write_through = 0;
555       pml[i].cache_disable = 0;
556       pml[i].accessed = 0;
557       pml[i].reserved = 0;
558       //pml[i].large_page = 0;
559       //pml[i].global_page = 0;
560       pml[i].vmm_info = 0;
561       pml[i].pdp_base_addr = 0;
562     } else {
563       pml[i].present = 1;
564       pml[i].writable = 1;
565       pml[i].user_page = 1;
566       pml[i].write_through = 0;
567       pml[i].cache_disable = 0;
568       pml[i].accessed = 0;
569       pml[i].reserved = 0;
570       //pml[i].large_page = 0;
571       //pml[i].global_page = 0;
572       pml[i].vmm_info = 0;
573       pml[i].pdp_base_addr = PAGE_ALIGNED_ADDR((addr_t)V3_PAddr(pdpe));
574     }
575   }
576
577   return pml;
578 }
579
580
581
582
583
584 void PrintPDE32(addr_t virtual_address, pde32_t * pde)
585 {
586   PrintDebug("PDE %p -> %p : present=%x, writable=%x, user=%x, wt=%x, cd=%x, accessed=%x, reserved=%x, largePages=%x, globalPage=%x, kernelInfo=%x\n",
587              (void *)virtual_address,
588              (void *)(addr_t) (pde->pt_base_addr << PAGE_POWER),
589              pde->present,
590              pde->writable,
591              pde->user_page, 
592              pde->write_through,
593              pde->cache_disable,
594              pde->accessed,
595              pde->reserved,
596              pde->large_page,
597              pde->global_page,
598              pde->vmm_info);
599 }
600
601   
602 void PrintPTE32(addr_t virtual_address, pte32_t * pte)
603 {
604   PrintDebug("PTE %p -> %p : present=%x, writable=%x, user=%x, wt=%x, cd=%x, accessed=%x, dirty=%x, pteAttribute=%x, globalPage=%x, vmm_info=%x\n",
605              (void *)virtual_address,
606              (void*)(addr_t)(pte->page_base_addr << PAGE_POWER),
607              pte->present,
608              pte->writable,
609              pte->user_page,
610              pte->write_through,
611              pte->cache_disable,
612              pte->accessed,
613              pte->dirty,
614              pte->pte_attr,
615              pte->global_page,
616              pte->vmm_info);
617 }
618
619
620
621
622
623
624 void PrintPDE64(addr_t virtual_address, pde64_t * pde)
625 {
626   PrintDebug("PDE64 %p -> %p : present=%x, writable=%x, user=%x, wt=%x, cd=%x, accessed=%x, reserved=%x, largePages=%x, globalPage=%x, kernelInfo=%x\n",
627              (void *)virtual_address,
628              (void *)(addr_t) (pde->pt_base_addr << PAGE_POWER),
629              pde->present,
630              pde->writable,
631              pde->user_page, 
632              pde->write_through,
633              pde->cache_disable,
634              pde->accessed,
635              pde->reserved,
636              pde->large_page,
637              0,//pde->global_page,
638              pde->vmm_info);
639 }
640
641   
642 void PrintPTE64(addr_t virtual_address, pte64_t * pte)
643 {
644   PrintDebug("PTE64 %p -> %p : present=%x, writable=%x, user=%x, wt=%x, cd=%x, accessed=%x, dirty=%x, pteAttribute=%x, globalPage=%x, vmm_info=%x\n",
645              (void *)virtual_address,
646              (void*)(addr_t)(pte->page_base_addr << PAGE_POWER),
647              pte->present,
648              pte->writable,
649              pte->user_page,
650              pte->write_through,
651              pte->cache_disable,
652              pte->accessed,
653              pte->dirty,
654              pte->pte_attr,
655              pte->global_page,
656              pte->vmm_info);
657 }
658
659   
660
661
662
663
664 void PrintPD32(pde32_t * pde)
665 {
666   int i;
667
668   PrintDebug("Page Directory at %p:\n", pde);
669   for (i = 0; (i < MAX_PDE32_ENTRIES); i++) { 
670     if ( pde[i].present) {
671       PrintPDE32((addr_t)(PAGE_SIZE * MAX_PTE32_ENTRIES * i), &(pde[i]));
672     }
673   }
674 }
675
676 void PrintPT32(addr_t starting_address, pte32_t * pte) 
677 {
678   int i;
679
680   PrintDebug("Page Table at %p:\n", pte);
681   for (i = 0; (i < MAX_PTE32_ENTRIES) ; i++) { 
682     if (pte[i].present) {
683       PrintPTE32(starting_address + (PAGE_SIZE * i), &(pte[i]));
684     }
685   }
686 }
687
688
689
690
691
692
693
694 void PrintDebugPageTables(pde32_t * pde)
695 {
696   int i;
697   
698   PrintDebug("Dumping the pages starting with the pde page at %p\n", pde);
699
700   for (i = 0; (i < MAX_PDE32_ENTRIES); i++) { 
701     if (pde[i].present) {
702       PrintPDE32((addr_t)(PAGE_SIZE * MAX_PTE32_ENTRIES * i), &(pde[i]));
703       PrintPT32((addr_t)(PAGE_SIZE * MAX_PTE32_ENTRIES * i), (pte32_t *)V3_VAddr((void *)(addr_t)(pde[i].pt_base_addr << PAGE_POWER)));
704     }
705   }
706 }
707     
708
709
710
711
712
713
714
715 void PrintPDPE32PAE(addr_t virtual_address, pdpe32pae_t * pdpe)
716 {
717   PrintDebug("PDPE %p -> %p : present=%x, wt=%x, cd=%x, accessed=%x, kernelInfo=%x\n",
718              (void *)virtual_address,
719              (void *)(addr_t) (pdpe->pd_base_addr << PAGE_POWER),
720              pdpe->present,
721              pdpe->write_through,
722              pdpe->cache_disable,
723              pdpe->accessed,
724              pdpe->vmm_info);
725 }
726
727 void PrintPDE32PAE(addr_t virtual_address, pde32pae_t * pde)
728 {
729   PrintDebug("PDE %p -> %p : present=%x, writable=%x, user=%x, wt=%x, cd=%x, accessed=%x, largePages=%x, globalPage=%x, kernelInfo=%x\n",
730              (void *)virtual_address,
731              (void *)(addr_t) (pde->pt_base_addr << PAGE_POWER),
732              pde->present,
733              pde->writable,
734              pde->user_page, 
735              pde->write_through,
736              pde->cache_disable,
737              pde->accessed,
738              pde->large_page,
739              pde->global_page,
740              pde->vmm_info);
741 }
742
743   
744 void PrintPTE32PAE(addr_t virtual_address, pte32pae_t * pte)
745 {
746   PrintDebug("PTE %p -> %p : present=%x, writable=%x, user=%x, wt=%x, cd=%x, accessed=%x, dirty=%x, pteAttribute=%x, globalPage=%x, vmm_info=%x\n",
747              (void *)virtual_address,
748              (void*)(addr_t)(pte->page_base_addr << PAGE_POWER),
749              pte->present,
750              pte->writable,
751              pte->user_page,
752              pte->write_through,
753              pte->cache_disable,
754              pte->accessed,
755              pte->dirty,
756              pte->pte_attr,
757              pte->global_page,
758              pte->vmm_info);
759 }
760
761
762
763
764
765
766 void PrintDebugPageTables32PAE(pdpe32pae_t * pdpe)
767 {
768   int i, j, k;
769   pde32pae_t * pde;
770   pte32pae_t * pte;
771   addr_t virtual_addr = 0;
772
773   PrintDebug("Dumping the pages starting with the pde page at %p\n", pdpe);
774
775   for (i = 0; (i < MAX_PDPE32PAE_ENTRIES); i++) { 
776
777     if (pdpe[i].present) {
778       pde = (pde32pae_t *)V3_VAddr((void *)(addr_t)BASE_TO_PAGE_ADDR(pdpe[i].pd_base_addr));
779
780       PrintPDPE32PAE(virtual_addr, &(pdpe[i]));
781
782       for (j = 0; j < MAX_PDE32PAE_ENTRIES; j++) {
783
784         if (pde[j].present) {
785           pte = (pte32pae_t *)V3_VAddr((void *)(addr_t)BASE_TO_PAGE_ADDR(pde[j].pt_base_addr));
786
787           PrintPDE32PAE(virtual_addr, &(pde[j]));
788
789           for (k = 0; k < MAX_PTE32PAE_ENTRIES; k++) {
790             if (pte[k].present) {
791               PrintPTE32PAE(virtual_addr, &(pte[k]));
792             }
793
794             virtual_addr += PAGE_SIZE;
795           }
796         } else {
797           virtual_addr += PAGE_SIZE * MAX_PTE32PAE_ENTRIES;
798         }
799       }
800     } else {
801       virtual_addr += PAGE_SIZE * MAX_PDE32PAE_ENTRIES * MAX_PTE32PAE_ENTRIES;
802     }
803   }
804 }
805     
806