Added more SharC annotations
[akaros.git] / kern / arch / i386 / env.c
1 /* See COPYRIGHT for copyright information. */
2 #ifdef __SHARC__
3 #pragma nosharc
4 #endif
5
6 #include <arch/trap.h>
7 #include <env.h>
8 #include <assert.h>
9 #include <pmap.h>
10
11 //
12 // This exits the kernel and starts executing some environment's code.
13 // This function does not return.
14 // Uses 'iret' or 'sysexit' depending on CS.
15 //
16 void env_pop_tf(trapframe_t *tf)
17 {
18         /*
19          * If the process entered the kernel via sysenter, we need to leave via
20          * sysexit.  sysenter trapframes have 0 for a CS, which is pushed in
21          * sysenter_handler.
22          */
23         if(tf->tf_cs) {
24                 /*
25                  * Restores the register values in the Trapframe with the 'iret'
26                  * instruction.  This exits the kernel and starts executing some
27                  * environment's code.  This function does not return.
28                  */
29                 asm volatile ("movl %0,%%esp;           "
30                               "popal;                   "
31                               "popl %%es;               "
32                               "popl %%ds;               "
33                               "addl $0x8,%%esp;         "
34                               "iret                     "
35                               : : "g" (tf) : "memory");
36                 panic("iret failed");  /* mostly to placate the compiler */
37         } else {
38                 /* Return path of sysexit.  See sysenter_handler's asm for details. */
39                 asm volatile ("movl %0,%%esp;           "
40                               "popal;                   "
41                               "popl %%es;               "
42                               "popl %%ds;               "
43                               "addl $0x10, %%esp;       "
44                               "popfl;                   "
45                               "movl %%ebp, %%ecx;       "
46                               "movl %%esi, %%edx;       "
47                               "sti;                     "
48                               "sysexit                  "
49                               : : "g" (tf) : "memory");
50                 panic("sysexit failed");  /* mostly to placate the compiler */
51         }
52 }
53
54 // Flush all mapped pages in the user portion of the address space
55 void
56 env_user_mem_free(env_t* e)
57 {
58         pte_t *pt;
59         uint32_t pdeno, pteno;
60         physaddr_t pa;
61
62         static_assert(UTOP % PTSIZE == 0);
63         for (pdeno = 0; pdeno < PDX(UTOP); pdeno++) {
64
65                 // only look at mapped page tables
66                 if (!(e->env_pgdir[pdeno] & PTE_P))
67                         continue;
68
69                 // find the pa and va of the page table
70                 pa = PTE_ADDR(e->env_pgdir[pdeno]);
71                 pt = (pte_t*COUNT(NPTENTRIES)) KADDR(pa);
72
73                 // unmap all PTEs in this page table 
74                 for (pteno = 0; pteno <= PTX(~0); pteno++) {
75                         if (pt[pteno] & PTE_P)
76                                 page_remove(e->env_pgdir, PGADDR(pdeno, pteno, 0));
77                 }
78
79                 // free the page table itself
80                 e->env_pgdir[pdeno] = 0;
81                 page_decref(pa2page(pa));
82         }
83 }