Prototype of env_user_mem_walk
authorAndrew Waterman <waterman@parcad.millennium.berkeley.edu>
Fri, 22 Jan 2010 00:33:17 +0000 (16:33 -0800)
committerAndrew Waterman <waterman@parcad.millennium.berkeley.edu>
Fri, 22 Jan 2010 00:33:17 +0000 (16:33 -0800)
This is a general mechanism to apply some operator to
all pages mapped into a process's address space.  for
example, env_user_mem_free can be implemented using
this plus a callback that does page_decref.  it will
be useful for implementing fork/exec "right".

kern/arch/sparc/env.c
kern/arch/sparc/process.c

index 3432eda..5f5ed39 100644 (file)
@@ -92,8 +92,11 @@ restore_fp_state(ancillary_state_t* silly)
 
 // Flush all mapped pages in the user portion of the address space
 // TODO: only supports L3 user pages
+
+typedef void (*env_user_mem_walk_t)(env_t* e, void* va, pte_t* pte, void* arg);
+
 void
-env_user_mem_free(env_t* e)
+env_user_mem_walk(env_t* e, env_user_mem_walk_t callback, void* arg)
 {
        pte_t *l1pt = e->env_pgdir, *l2pt, *l3pt;
        uint32_t l1x,l2x,l3x;
@@ -124,9 +127,8 @@ env_user_mem_free(env_t* e)
                        {
                                if(l3pt[l3x] & PTE_PTE)
                                {
-                                       page_pa = PTE_ADDR(l3pt[l3x]);
-                                       l3pt[l3x] = 0;
-                                       page_decref(pa2page(page_pa));
+                                       callback(e,PGADDR(l1x,l2x,l3x,0),
+                                                &l3pt[l3x],arg);
                                }
                        }
 
@@ -144,3 +146,16 @@ env_user_mem_free(env_t* e)
 
        tlbflush();
 }
+
+void
+env_user_mem_free(env_t* e)
+{
+       void mem_free_callback(env_t* e, void* va, pte_t* pte, void* arg)
+       {
+               page_t* page = ppn2page(PTE2PPN(*pte));
+               page_decref(page);
+               *pte = 0;
+       }
+       env_user_mem_walk(e,&mem_free_callback,NULL);
+}
+
index 04e3951..519619f 100644 (file)
@@ -35,19 +35,22 @@ proc_free_arch(struct proc *SAFE p)
 void
 proc_set_program_counter(trapframe_t *tf, uintptr_t pc)
 {
-        tf->pc = pc;
-        tf->npc = pc+4;
+       tf->pc = pc;
+       tf->npc = pc+4;
 }
 
 void
 proc_init_trapframe(trapframe_t *tf, uint32_t vcoreid)
 {
-        extern char trap_table;
+       extern char trap_table;
 
-        tf->gpr[14] = USTACKTOP-64;
-        tf->psr = PSR_S; // but PS = 0
-        tf->wim = 0;
-        tf->tbr = (uint32_t)&trap_table;
+       memset(tf,0,sizeof(*tf));
+       tf->gpr[14] = USTACKTOP-96;
+       tf->psr = PSR_S; // but PS = 0
+
+       // unused
+       //tf->wim = 0;
+       //tf->tbr = (uint32_t)&trap_table;
 
        proc_set_tfcoreid(tf,vcoreid);
 }