#include "cpu.h"
#include "defs.h"
+extern void pg_fault_debug(pg_dir_t*, void*);
+
void sched_tick(void);
extern int sys_cxnet(long, long, long, long, long, long, long);
extern int sys_cxipc(long, long, long);
if(ctx.intn == EXC_PAGEFAULT) {
u32_t cr2;
+ pg_dir_t *pd;
asm volatile("movl %%cr2, %%eax; movl %%eax, %0" : "=r"(cr2));
dbg_printf("Page fault address: 0x%08x\n", cr2);
+
+ if(process_get_pagedir(cproc, &pd) == 0) {
+ pg_fault_debug(pd, (void*)cr2);
+ }
}
PANIC("Unhandled exception");
dir = (pg_dir_t*)data;
switch(reg->reg_type) {
+ case REGION_DATA:
+ ret_val = pg_dir_clone_region(dir, kdir, reg);
+ break;
+
case REGION_TEXT:
case REGION_RODATA:
case REGION_HEAP:
* directory since they cannot be modified or removed anyways.
*/
case REGION_BSS:
- case REGION_DATA:
/*
* The way the interrupt handling is currently implemented, accesses to the
* _cpu structure and _kernel_cr3 are made within the context (i.e. using
pd->pt_entries[pde] |= PAGE_ATTR_USER;
}
+ /* also make sure the page table is writable, if necessary */
+ if(flags & PAGE_ATTR_WRITABLE) {
+ pd->pt_entries[pde] |= PAGE_ATTR_WRITABLE;
+ }
+
if(pt->pt_entries[pte] & PAGE_ATTR_PRESENT) {
ret_val = -EALREADY;
break;
/* allocate new frames if caller didn't specify a physical address */
if(!paddr) {
pt->pt_entries[pte] = (u32_t)pg_frame_alloc_end();
- dbg_printf("Allocating page: %04u - 0x%08x\n", pte, pt->pt_entries[pte]);
} else {
pt->pt_entries[pte] = paddr;
paddr += PAGE_SIZE;
/* attempt to map the region */
ret_val = pg_dir_map(dpd, NULL, reg->reg_base,
- reg->reg_size, reg->reg_attrs);
+ reg->reg_size, reg->reg_attrs | PAGE_ATTR_USER);
if(ret_val < 0) {
goto gtfo;
if(ret_val >= 0) {
/* also keep track of the region */
ret_val = _pg_dir_add_region(dpd, reg->reg_base, reg->reg_size,
- reg->reg_type, reg->reg_attrs, reg->reg_flags);
+ reg->reg_type, reg->reg_attrs, reg->reg_flags | PAGE_ATTR_USER);
}
if(ret_val < 0) {
return(ret_val);
}
+
+void pg_fault_debug(pg_dir_t *pdir, void *addr)
+{
+ u64_t pde;
+ u64_t pte;
+ u32_t pdi;
+ u32_t pti;
+
+ switch(_pg_flags & PG_MODE_MASK) {
+ case PG_MODE_LEGACY:
+ pdi = ((u32_t)addr & 0xffc00000) >> 22;
+ pti = ((u32_t)addr & 0x003ff000) >> 12;
+
+ pde = ((page_table_t*)pdir->pd_base)->pt_entries[pdi];
+
+ dbg_printf("pdir[%03u] = 0x%08x\n", pdi, (u32_t)pde);
+
+ if(!(pde & PAGE_ATTR_SIZE)) {
+ pte = ((page_table_t*)(pde & 0xfffff000))->pt_entries[pti];
+ dbg_printf("pdir[%03u][%03u] = 0x%08x\n", pdi, pti, (u32_t)pte);
+ }
+
+ break;
+
+ case PG_MODE_PAE:
+ break;
+
+ default:
+ /* not handled yet */
+ break;
+ }
+
+ return;
+}