verbose printing and sanity checking functions.

This commit is contained in:
Ben Gras 2009-09-27 12:36:48 +00:00
parent a02d9aae0a
commit 5cf59f9225
2 changed files with 94 additions and 10 deletions

View file

@ -414,7 +414,7 @@ PUBLIC int pt_writemap(pt_t *pt, vir_bytes v, phys_bytes physaddr,
{
/* Write mapping into page table. Allocate a new page table if necessary. */
/* Page directory and table entries for this virtual address. */
int p, pages, pde;
int p, pages, pdecheck;
int finalpde;
int verify = 0;
@ -446,21 +446,21 @@ PUBLIC int pt_writemap(pt_t *pt, vir_bytes v, phys_bytes physaddr,
* to undo our work properly. Walk the range in page-directory-entry
* sized leaps.
*/
for(pde = I386_VM_PDE(v); pde <= finalpde; pde++) {
vm_assert(pde >= 0 && pde < I386_VM_DIR_ENTRIES);
if(pt->pt_dir[pde] & I386_VM_BIGPAGE) {
for(pdecheck = I386_VM_PDE(v); pdecheck <= finalpde; pdecheck++) {
vm_assert(pdecheck >= 0 && pdecheck < I386_VM_DIR_ENTRIES);
if(pt->pt_dir[pdecheck] & I386_VM_BIGPAGE) {
printf("pt_writemap: trying to write 0x%lx into 0x%lx\n",
physaddr, v);
vm_panic("pt_writemap: BIGPAGE found", NO_NUM);
}
if(!(pt->pt_dir[pde] & I386_VM_PRESENT)) {
if(!(pt->pt_dir[pdecheck] & I386_VM_PRESENT)) {
int r;
if(verify) {
printf("pt_writemap verify: no pde %d\n", pde);
printf("pt_writemap verify: no pde %d\n", pdecheck);
return EFAULT;
}
vm_assert(!pt->pt_dir[pde]);
if((r=pt_ptalloc(pt, pde, flags)) != OK) {
vm_assert(!pt->pt_dir[pdecheck]);
if((r=pt_ptalloc(pt, pdecheck, flags)) != OK) {
/* Couldn't do (complete) mapping.
* Don't bother freeing any previously
* allocated page tables, they're
@ -468,11 +468,11 @@ PUBLIC int pt_writemap(pt_t *pt, vir_bytes v, phys_bytes physaddr,
* and pt_ptalloc leaves the directory
* and other data in a consistent state.
*/
printf("pt_writemap: pt_ptalloc failed\n", pde);
printf("pt_writemap: pt_ptalloc failed\n", pdecheck);
return r;
}
}
vm_assert(pt->pt_dir[pde] & I386_VM_PRESENT);
vm_assert(pt->pt_dir[pdecheck] & I386_VM_PRESENT);
}
/* Now write in them. */
@ -531,6 +531,50 @@ PUBLIC int pt_writemap(pt_t *pt, vir_bytes v, phys_bytes physaddr,
return OK;
}
/*===========================================================================*
* pt_checkrange *
*===========================================================================*/
PUBLIC int pt_checkrange(pt_t *pt, vir_bytes v, size_t bytes,
int write)
{
int p, pages, pde;
vm_assert(!(bytes % I386_PAGE_SIZE));
pages = bytes / I386_PAGE_SIZE;
for(p = 0; p < pages; p++) {
u32_t entry;
int pde = I386_VM_PDE(v);
int pte = I386_VM_PTE(v);
vm_assert(!(v % I386_PAGE_SIZE));
vm_assert(pte >= 0 && pte < I386_VM_PT_ENTRIES);
vm_assert(pde >= 0 && pde < I386_VM_DIR_ENTRIES);
/* Page table has to be there. */
if(!(pt->pt_dir[pde] & I386_VM_PRESENT))
return EFAULT;
/* Make sure page directory entry for this page table
* is marked present and page table entry is available.
*/
vm_assert((pt->pt_dir[pde] & I386_VM_PRESENT) && pt->pt_pt[pde]);
if(!(pt->pt_pt[pde][pte] & I386_VM_PRESENT)) {
return EFAULT;
}
if(write && !(pt->pt_pt[pde][pte] & I386_VM_WRITE)) {
return EFAULT;
}
v += I386_PAGE_SIZE;
}
return OK;
}
/*===========================================================================*
* pt_new *
*===========================================================================*/

View file

@ -40,6 +40,46 @@ PUBLIC vir_bytes arch_map2vir(struct vmproc *vmp, vir_bytes addr)
return addr - datastart;
}
/*===========================================================================*
* arch_map2str *
*===========================================================================*/
PUBLIC char *arch_map2str(struct vmproc *vmp, vir_bytes addr)
{
static char bufstr[100];
vir_bytes textstart = CLICK2ABS(vmp->vm_arch.vm_seg[T].mem_phys);
vir_bytes textend = textstart + CLICK2ABS(vmp->vm_arch.vm_seg[T].mem_len);
vir_bytes datastart = CLICK2ABS(vmp->vm_arch.vm_seg[D].mem_phys);
if(addr < textstart) {
sprintf(bufstr, "<lin:0x%lx>", addr);
} else if(addr < datastart) {
sprintf(bufstr, "0x%lx (codeseg)", addr - textstart);
} else {
sprintf(bufstr, "0x%lx (dataseg)", addr - datastart);
}
return bufstr;
}
/*===========================================================================*
* arch_addrok *
*===========================================================================*/
PUBLIC vir_bytes arch_addrok(struct vmproc *vmp, vir_bytes addr)
{
vir_bytes textstart = CLICK2ABS(vmp->vm_arch.vm_seg[T].mem_phys);
vir_bytes textend = CLICK2ABS(vmp->vm_arch.vm_seg[T].mem_phys +
vmp->vm_arch.vm_seg[T].mem_phys);
vir_bytes datastart = CLICK2ABS(vmp->vm_arch.vm_seg[D].mem_phys);
if(addr >= textstart && addr < textstart+textend)
return 1;
if(addr >= datastart && addr < VM_DATATOP)
return 1;
return 0;
}
/*===========================================================================*
* arch_vir2map *
*===========================================================================*/