u32_t phys;
} sparepages[SPAREPAGES];
+#define MAX_KERNMAPPINGS 10
+PRIVATE struct {
+ phys_bytes phys_addr; /* Physical addr. */
+ phys_bytes len; /* Length in bytes. */
+ vir_bytes lin_addr; /* Offset in page table. */
+ int flags;
+} kern_mappings[MAX_KERNMAPPINGS];
+int kernmappings = 0;
+
/* Clicks must be pages, as
* - they must be page aligned to map them
* - they must be a multiple of the page size
/* Let other functions know VM now has a private page table. */
vmp->vm_flags |= VMF_HASPT;
+ /* Now reserve another pde for kernel's own mappings. */
+ {
+ int kernmap_pde;
+ phys_bytes addr, len;
+ int flags, index;
+ u32_t offset = 0;
+
+ kernmap_pde = free_pde++;
+ offset = kernmap_pde * I386_BIG_PAGE_SIZE;
+
+ while(sys_vmctl_get_mapping(index, &addr, &len,
+ &flags) == OK) {
+ vir_bytes vir;
+ if(index >= MAX_KERNMAPPINGS)
+ vm_panic("VM: too many kernel mappings", index);
+ kern_mappings[index].phys_addr = addr;
+ kern_mappings[index].len = len;
+ kern_mappings[index].flags = flags;
+ kern_mappings[index].lin_addr = offset;
+ kern_mappings[index].flags =
+ I386_VM_PRESENT | I386_VM_USER | I386_VM_WRITE;
+ if(flags & VMMF_UNCACHED)
+ kern_mappings[index].flags |=
+ I386_VM_PWT | I386_VM_PCD;
+ if(addr % I386_PAGE_SIZE)
+ vm_panic("VM: addr unaligned", addr);
+ if(len % I386_PAGE_SIZE)
+ vm_panic("VM: len unaligned", len);
+ vir = arch_map2vir(&vmproc[VMP_SYSTEM], offset);
+ printf("vir: 0x%lx\n", vir);
+ if(sys_vmctl_reply_mapping(index, vir) != OK)
+ vm_panic("VM: reply failed", NO_NUM);
+ offset += len;
+ index++;
+ kernmappings++;
+ }
+ }
+
/* Find a PDE below processes available for mapping in the
* page directories (readonly).
*/
*===========================================================================*/
PUBLIC int pt_mapkernel(pt_t *pt)
{
- int r;
+ int r, i;
static int printed = 0;
/* Any i386 page table needs to map in the kernel address space. */
pt->pt_dir[pagedir_pde] = pagedir_pde_val;
}
+ for(i = 0; i < kernmappings; i++) {
+ if(pt_writemap(pt,
+ kern_mappings[i].lin_addr,
+ kern_mappings[i].phys_addr,
+ kern_mappings[i].len,
+ kern_mappings[i].flags, 0) != OK) {
+ vm_panic("pt_mapkernel: pt_writemap failed", NO_NUM);
+ }
+ }
+
return OK;
}