map.c (2087B)
1 #include <os9/os9.h> 2 3 #include <libk.h> 4 5 #include <string.h> 6 7 Map * 8 newstack(Task *tp) 9 { 10 Map *mp = &tp->stack; 11 12 initref(&mp->ref); 13 mp->name = "stack"; 14 mp->perm = MW | MR; 15 16 mp->pa = -1; 17 mp->va = STACKADDR & (STACKADDR-1); 18 mp->siz = PAGESIZE; 19 20 if (mapseg(mp) < 0) 21 return NULL; 22 23 return mp; 24 } 25 26 Map * 27 newkstack(Task *tp) 28 { 29 Map *mp = &tp->kstack; 30 31 initref(&mp->ref); 32 mp->name = "kstack"; 33 mp->perm = MW | MR; 34 35 mp->pa = -1; 36 mp->va = KSTACKADDR & (STACKADDR-1); 37 mp->siz = PAGESIZE; 38 39 if (mapseg(mp) < 0) 40 return NULL; 41 42 return mp; 43 } 44 45 int 46 unmapseg(Map *mp) 47 { 48 Page *p; 49 50 dbg("unmap %s: %llx -> %llx\n", 51 (mp->name) ? mp->name : "unnamed", 52 mp->va, mp->pa); 53 54 for (p = mp->pages; p; p = p->next) { 55 vunmap(p->pa, p->va); 56 freep(p); 57 } 58 59 mp->pages = NULL; 60 61 return 0; 62 } 63 64 int 65 mapseg(Map *mp) 66 { 67 phyaddr_t pa; 68 uintptr_t va; 69 unsigned long i, n; 70 Page *p; 71 72 assert(mp->perm & MR); 73 74 dbg("map %s: %llx -> %llx %c %c%c%c (%llu)\n", 75 (mp->name) ? mp->name : "unnamed", 76 mp->va, mp->pa, 77 (mp->perm & MD) ? 'd' : 'n', 78 (mp->perm & MR) ? 'r' : '-', 79 (mp->perm & MW) ? 'w' : '-', 80 (mp->perm & MX) ? 'x' : '-', 81 mp->siz); 82 83 n = (mp->siz + PAGESIZE-1)/PAGESIZE; 84 va = mp->va; 85 pa = mp->pa; 86 87 for (i = 0; i < n; i++) { 88 if (mp->pa == -1) 89 pa = -1; 90 91 if ((p = allocp(pa)) == NULL) 92 goto err; 93 p->va = va; 94 p->next = mp->pages; 95 96 if (vmap(p->pa, va, mp->perm) < 0) { 97 freep(p); 98 goto err; 99 } 100 101 mp->pages = p; 102 pa += PAGESIZE; 103 va += PAGESIZE; 104 } 105 106 return 0; 107 108 err: 109 unmapseg(mp); 110 return -1; 111 } 112 113 void 114 delmap(Map *mp) 115 { 116 if (!decref(&mp->ref)) 117 return; 118 unmapseg(mp); 119 freemap(mp); 120 } 121 122 Map * 123 newmap(Map *from) 124 { 125 Map *mp; 126 Page *pfrom, *pto; 127 128 if ((mp = allocmap()) == NULL) 129 return NULL; 130 131 *mp = *from; 132 mp->pages = NULL; 133 mp->next = NULL; 134 initref(&mp->ref); 135 mapseg(mp); 136 137 pto = mp->pages; 138 for (pfrom = from->pages; pfrom; pfrom = pfrom->next) { 139 assert(pfrom->va == pto->va); 140 141 vmap(pto->pa, (uintptr_t) bufto, MW); 142 vmap(pfrom->pa, (uintptr_t) buffrom, MR); 143 144 memcpy(bufto, buffrom, PAGESIZE); 145 barrier(DATA); 146 147 pto = pto->next; 148 } 149 150 return mp; 151 }